001 package aima.test.logictest.foltest; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 import junit.framework.Assert; 007 008 import aima.logic.fol.CNFConverter; 009 import aima.logic.fol.domain.FOLDomain; 010 import aima.logic.fol.inference.FOLOTTERLikeTheoremProver; 011 import aima.logic.fol.inference.InferenceResult; 012 import aima.logic.fol.inference.InferenceResultPrinter; 013 import aima.logic.fol.inference.otter.defaultimpl.DefaultClauseSimplifier; 014 import aima.logic.fol.kb.FOLKnowledgeBase; 015 import aima.logic.fol.kb.data.CNF; 016 import aima.logic.fol.kb.data.Clause; 017 import aima.logic.fol.parsing.FOLParser; 018 import aima.logic.fol.parsing.ast.Sentence; 019 import aima.logic.fol.parsing.ast.TermEquality; 020 021 /** 022 * @author Ciaran O'Reilly 023 * 024 */ 025 public class FOLOTTERLikeTheoremProverTest extends 026 CommonFOLInferenceProcedureTests { 027 028 public void testDefaultClauseSimplifier() { 029 FOLDomain domain = new FOLDomain(); 030 domain.addConstant("ZERO"); 031 domain.addConstant("ONE"); 032 domain.addPredicate("P"); 033 domain.addFunction("Plus"); 034 domain.addFunction("Power"); 035 036 FOLParser parser = new FOLParser(domain); 037 038 List<TermEquality> rewrites = new ArrayList<TermEquality>(); 039 rewrites.add((TermEquality) parser.parse("Plus(x, ZERO) = x")); 040 rewrites.add((TermEquality) parser.parse("Plus(ZERO, x) = x")); 041 rewrites.add((TermEquality) parser.parse("Power(x, ONE) = x")); 042 rewrites.add((TermEquality) parser.parse("Power(x, ZERO) = ONE")); 043 DefaultClauseSimplifier simplifier = new DefaultClauseSimplifier( 044 rewrites); 045 046 Sentence s1 = parser 047 .parse("((P(Plus(y,ZERO),Plus(ZERO,y)) OR P(Power(y, ONE),Power(y,ZERO))) OR P(Power(y,ZERO),Plus(y,ZERO)))"); 048 049 CNFConverter cnfConverter = new CNFConverter(parser); 050 051 CNF cnf = cnfConverter.convertToCNF(s1); 052 053 assertEquals(1, cnf.getNumberOfClauses()); 054 055 Clause simplified = simplifier.simplify(cnf.getConjunctionOfClauses() 056 .get(0)); 057 058 assertEquals("[P(y,y), P(y,ONE), P(ONE,y)]", simplified.toString()); 059 } 060 061 // This tests to ensure the OTTERLike theorem prover 062 // uses subsumption correctly so that it exhausts 063 // its search space. 064 public void testExhaustsSearchSpace() { 065 // Taken from AIMA pg 679 066 FOLDomain domain = new FOLDomain(); 067 domain.addPredicate("alternate"); 068 domain.addPredicate("bar"); 069 domain.addPredicate("fri_sat"); 070 domain.addPredicate("hungry"); 071 domain.addPredicate("patrons"); 072 domain.addPredicate("price"); 073 domain.addPredicate("raining"); 074 domain.addPredicate("reservation"); 075 domain.addPredicate("type"); 076 domain.addPredicate("wait_estimate"); 077 domain.addPredicate("will_wait"); 078 domain.addConstant("Some"); 079 domain.addConstant("Full"); 080 domain.addConstant("French"); 081 domain.addConstant("Thai"); 082 domain.addConstant("Burger"); 083 domain.addConstant("$"); 084 domain.addConstant("_30_60"); 085 domain.addConstant("X0"); 086 FOLParser parser = new FOLParser(domain); 087 088 // The hypothesis 089 String c1 = "patrons(v,Some)"; 090 String c2 = "patrons(v,Full) AND (hungry(v) AND type(v,French))"; 091 String c3 = "patrons(v,Full) AND (hungry(v) AND (type(v,Thai) AND fri_sat(v)))"; 092 String c4 = "patrons(v,Full) AND (hungry(v) AND type(v,Burger))"; 093 String sh = "FORALL v (will_wait(v) <=> (" + c1 + " OR (" + c2 094 + " OR (" + c3 + " OR (" + c4 + ")))))"; 095 096 Sentence hypothesis = parser.parse(sh); 097 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))"); 098 Sentence classification = parser.parse("will_wait(X0)"); 099 100 FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, new FOLOTTERLikeTheoremProver(false)); 101 102 kb.tell(hypothesis); 103 kb.tell(desc); 104 105 InferenceResult ir = kb.ask(classification); 106 107 Assert.assertFalse(ir.isTrue()); 108 Assert.assertTrue(ir.isPossiblyFalse()); 109 Assert.assertFalse(ir.isUnknownDueToTimeout()); 110 Assert.assertFalse(ir.isPartialResultDueToTimeout()); 111 Assert.assertEquals(0, ir.getProofs().size()); 112 } 113 114 public void testDefiniteClauseKBKingsQueryCriminalXFalse() { 115 testDefiniteClauseKBKingsQueryCriminalXFalse(new FOLOTTERLikeTheoremProver( 116 false)); 117 } 118 119 public void testDefiniteClauseKBKingsQueryRichardEvilFalse() { 120 testDefiniteClauseKBKingsQueryRichardEvilFalse(new FOLOTTERLikeTheoremProver( 121 false)); 122 } 123 124 public void testDefiniteClauseKBKingsQueryJohnEvilSucceeds() { 125 testDefiniteClauseKBKingsQueryJohnEvilSucceeds(new FOLOTTERLikeTheoremProver( 126 false)); 127 } 128 129 public void testDefiniteClauseKBKingsQueryEvilXReturnsJohnSucceeds() { 130 testDefiniteClauseKBKingsQueryEvilXReturnsJohnSucceeds(new FOLOTTERLikeTheoremProver( 131 false)); 132 } 133 134 public void testDefiniteClauseKBKingsQueryKingXReturnsJohnAndRichardSucceeds() { 135 testDefiniteClauseKBKingsQueryKingXReturnsJohnAndRichardSucceeds(new FOLOTTERLikeTheoremProver( 136 false)); 137 } 138 139 public void testDefiniteClauseKBWeaponsQueryCriminalXReturnsWestSucceeds() { 140 testDefiniteClauseKBWeaponsQueryCriminalXReturnsWestSucceeds(new FOLOTTERLikeTheoremProver( 141 false)); 142 } 143 144 public void testHornClauseKBRingOfThievesQuerySkisXReturnsNancyRedBertDrew() { 145 // This KB ends up being infinite when resolving, however 2 146 // seconds is more than enough to extract the 4 answers 147 // that are expected 148 testHornClauseKBRingOfThievesQuerySkisXReturnsNancyRedBertDrew(new FOLOTTERLikeTheoremProver( 149 2 * 1000, false)); 150 } 151 152 public void testFullFOLKBLovesAnimalQueryKillsCuriosityTunaSucceeds() { 153 testFullFOLKBLovesAnimalQueryKillsCuriosityTunaSucceeds( 154 new FOLOTTERLikeTheoremProver(false), false); 155 } 156 157 public void testFullFOLKBLovesAnimalQueryNotKillsJackTunaSucceeds() { 158 testFullFOLKBLovesAnimalQueryNotKillsJackTunaSucceeds( 159 new FOLOTTERLikeTheoremProver(false), false); 160 } 161 162 public void testFullFOLKBLovesAnimalQueryKillsJackTunaFalse() { 163 // This query will not return using OTTER Like resolution 164 // as keep expanding clauses through resolution for this KB. 165 testFullFOLKBLovesAnimalQueryKillsJackTunaFalse( 166 new FOLOTTERLikeTheoremProver(false), true); 167 } 168 169 public void testEqualityAxiomsKBabcAEqualsCSucceeds() { 170 testEqualityAxiomsKBabcAEqualsCSucceeds(new FOLOTTERLikeTheoremProver( 171 false)); 172 } 173 174 public void testEqualityAndSubstitutionAxiomsKBabcdFFASucceeds() { 175 testEqualityAndSubstitutionAxiomsKBabcdFFASucceeds(new FOLOTTERLikeTheoremProver( 176 false)); 177 } 178 179 public void testEqualityAndSubstitutionAxiomsKBabcdPDSucceeds() { 180 xtestEqualityAndSubstitutionAxiomsKBabcdPDSucceeds(new FOLOTTERLikeTheoremProver( 181 false)); 182 } 183 184 public void testEqualityAndSubstitutionAxiomsKBabcdPFFASucceeds() { 185 testEqualityAndSubstitutionAxiomsKBabcdPFFASucceeds( 186 new FOLOTTERLikeTheoremProver(false), false); 187 } 188 189 public void testEqualityNoAxiomsKBabcAEqualsCSucceeds() { 190 testEqualityNoAxiomsKBabcAEqualsCSucceeds( 191 new FOLOTTERLikeTheoremProver(true), false); 192 } 193 194 public void testEqualityAndSubstitutionNoAxiomsKBabcdFFASucceeds() { 195 testEqualityAndSubstitutionNoAxiomsKBabcdFFASucceeds( 196 new FOLOTTERLikeTheoremProver(true), false); 197 } 198 199 public void testEqualityAndSubstitutionNoAxiomsKBabcdPDSucceeds() { 200 testEqualityAndSubstitutionNoAxiomsKBabcdPDSucceeds( 201 new FOLOTTERLikeTheoremProver(true), false); 202 } 203 204 public void testEqualityAndSubstitutionNoAxiomsKBabcdPFFASucceeds() { 205 testEqualityAndSubstitutionNoAxiomsKBabcdPFFASucceeds( 206 new FOLOTTERLikeTheoremProver(true), false); 207 } 208 }