package aima.test.core.unit.logic.fol.inference; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Test; import aima.core.logic.fol.CNFConverter; import aima.core.logic.fol.domain.FOLDomain; import aima.core.logic.fol.inference.FOLOTTERLikeTheoremProver; import aima.core.logic.fol.inference.InferenceResult; import aima.core.logic.fol.inference.otter.defaultimpl.DefaultClauseSimplifier; import aima.core.logic.fol.kb.FOLKnowledgeBase; import aima.core.logic.fol.kb.data.CNF; import aima.core.logic.fol.kb.data.Clause; import aima.core.logic.fol.parsing.FOLParser; import aima.core.logic.fol.parsing.ast.Sentence; import aima.core.logic.fol.parsing.ast.TermEquality; import aima.test.core.unit.logic.fol.CommonFOLInferenceProcedureTests; /** * @author Ciaran O'Reilly * */ public class FOLOTTERLikeTheoremProverTest extends CommonFOLInferenceProcedureTests { @Test public void testDefaultClauseSimplifier() { FOLDomain domain = new FOLDomain(); domain.addConstant("ZERO"); domain.addConstant("ONE"); domain.addPredicate("P"); domain.addFunction("Plus"); domain.addFunction("Power"); FOLParser parser = new FOLParser(domain); List<TermEquality> rewrites = new ArrayList<TermEquality>(); rewrites.add((TermEquality) parser.parse("Plus(x, ZERO) = x")); rewrites.add((TermEquality) parser.parse("Plus(ZERO, x) = x")); rewrites.add((TermEquality) parser.parse("Power(x, ONE) = x")); rewrites.add((TermEquality) parser.parse("Power(x, ZERO) = ONE")); DefaultClauseSimplifier simplifier = new DefaultClauseSimplifier( rewrites); Sentence s1 = parser .parse("((P(Plus(y,ZERO),Plus(ZERO,y)) OR P(Power(y, ONE),Power(y,ZERO))) OR P(Power(y,ZERO),Plus(y,ZERO)))"); CNFConverter cnfConverter = new CNFConverter(parser); CNF cnf = cnfConverter.convertToCNF(s1); Assert.assertEquals(1, cnf.getNumberOfClauses()); Clause simplified = simplifier.simplify(cnf.getConjunctionOfClauses() .get(0)); Assert.assertEquals("[P(y,y), P(y,ONE), P(ONE,y)]", simplified.toString()); } // This tests to ensure the OTTERLike theorem prover // uses subsumption correctly so that it exhausts // its search space. @Test public void testExhaustsSearchSpace() { // Taken from AIMA pg 679 FOLDomain domain = new FOLDomain(); domain.addPredicate("alternate"); domain.addPredicate("bar"); domain.addPredicate("fri_sat"); domain.addPredicate("hungry"); domain.addPredicate("patrons"); domain.addPredicate("price"); domain.addPredicate("raining"); domain.addPredicate("reservation"); domain.addPredicate("type"); domain.addPredicate("wait_estimate"); domain.addPredicate("will_wait"); domain.addConstant("Some"); domain.addConstant("Full"); domain.addConstant("French"); domain.addConstant("Thai"); domain.addConstant("Burger"); domain.addConstant("$"); domain.addConstant("_30_60"); domain.addConstant("X0"); FOLParser parser = new FOLParser(domain); // The hypothesis String c1 = "patrons(v,Some)"; String c2 = "patrons(v,Full) AND (hungry(v) AND type(v,French))"; String c3 = "patrons(v,Full) AND (hungry(v) AND (type(v,Thai) AND fri_sat(v)))"; String c4 = "patrons(v,Full) AND (hungry(v) AND type(v,Burger))"; String sh = "FORALL v (will_wait(v) <=> (" + c1 + " OR (" + c2 + " OR (" + c3 + " OR (" + c4 + ")))))"; Sentence hypothesis = parser.parse(sh); Sentence desc = parser .parse("(((((((((alternate(X0) AND NOT(bar(X0))) AND NOT(fri_sat(X0))) AND hungry(X0)) AND patrons(X0,Full)) AND price(X0,$)) AND NOT(raining(X0))) AND NOT(reservation(X0))) AND type(X0,Thai)) AND wait_estimate(X0,_30_60))"); Sentence classification = parser.parse("will_wait(X0)"); FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, new FOLOTTERLikeTheoremProver(false)); kb.tell(hypothesis); kb.tell(desc); InferenceResult ir = kb.ask(classification); Assert.assertFalse(ir.isTrue()); Assert.assertTrue(ir.isPossiblyFalse()); Assert.assertFalse(ir.isUnknownDueToTimeout()); Assert.assertFalse(ir.isPartialResultDueToTimeout()); Assert.assertEquals(0, ir.getProofs().size()); } @Test public void testDefiniteClauseKBKingsQueryCriminalXFalse() { testDefiniteClauseKBKingsQueryCriminalXFalse(new FOLOTTERLikeTheoremProver( false)); } @Test public void testDefiniteClauseKBKingsQueryRichardEvilFalse() { testDefiniteClauseKBKingsQueryRichardEvilFalse(new FOLOTTERLikeTheoremProver( false)); } @Test public void testDefiniteClauseKBKingsQueryJohnEvilSucceeds() { testDefiniteClauseKBKingsQueryJohnEvilSucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testDefiniteClauseKBKingsQueryEvilXReturnsJohnSucceeds() { testDefiniteClauseKBKingsQueryEvilXReturnsJohnSucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testDefiniteClauseKBKingsQueryKingXReturnsJohnAndRichardSucceeds() { testDefiniteClauseKBKingsQueryKingXReturnsJohnAndRichardSucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testDefiniteClauseKBWeaponsQueryCriminalXReturnsWestSucceeds() { testDefiniteClauseKBWeaponsQueryCriminalXReturnsWestSucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testHornClauseKBRingOfThievesQuerySkisXReturnsNancyRedBertDrew() { // This KB ends up being infinite when resolving, however 2 // seconds is more than enough to extract the 4 answers // that are expected testHornClauseKBRingOfThievesQuerySkisXReturnsNancyRedBertDrew(new FOLOTTERLikeTheoremProver( 2 * 1000, false)); } @Test public void testFullFOLKBLovesAnimalQueryKillsCuriosityTunaSucceeds() { testFullFOLKBLovesAnimalQueryKillsCuriosityTunaSucceeds( new FOLOTTERLikeTheoremProver(false), false); } @Test public void testFullFOLKBLovesAnimalQueryNotKillsJackTunaSucceeds() { testFullFOLKBLovesAnimalQueryNotKillsJackTunaSucceeds( new FOLOTTERLikeTheoremProver(false), false); } @Test public void testFullFOLKBLovesAnimalQueryKillsJackTunaFalse() { // This query will not return using OTTER Like resolution // as keep expanding clauses through resolution for this KB. testFullFOLKBLovesAnimalQueryKillsJackTunaFalse( new FOLOTTERLikeTheoremProver(false), true); } @Test public void testEqualityAxiomsKBabcAEqualsCSucceeds() { testEqualityAxiomsKBabcAEqualsCSucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testEqualityAndSubstitutionAxiomsKBabcdFFASucceeds() { testEqualityAndSubstitutionAxiomsKBabcdFFASucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testEqualityAndSubstitutionAxiomsKBabcdPDSucceeds() { testEqualityAndSubstitutionAxiomsKBabcdPDSucceeds(new FOLOTTERLikeTheoremProver( false)); } @Test public void testEqualityAndSubstitutionAxiomsKBabcdPFFASucceeds() { testEqualityAndSubstitutionAxiomsKBabcdPFFASucceeds( new FOLOTTERLikeTheoremProver(false), false); } @Test public void testEqualityNoAxiomsKBabcAEqualsCSucceeds() { testEqualityNoAxiomsKBabcAEqualsCSucceeds( new FOLOTTERLikeTheoremProver(true), false); } @Test public void testEqualityAndSubstitutionNoAxiomsKBabcdFFASucceeds() { testEqualityAndSubstitutionNoAxiomsKBabcdFFASucceeds( new FOLOTTERLikeTheoremProver(true), false); } @Test public void testEqualityAndSubstitutionNoAxiomsKBabcdPDSucceeds() { testEqualityAndSubstitutionNoAxiomsKBabcdPDSucceeds( new FOLOTTERLikeTheoremProver(true), false); } @Test public void testEqualityAndSubstitutionNoAxiomsKBabcdPFFASucceeds() { testEqualityAndSubstitutionNoAxiomsKBabcdPFFASucceeds( new FOLOTTERLikeTheoremProver(true), false); } }