package aima.test.core.unit.logic.fol; import java.util.HashSet; import java.util.Set; import org.junit.Assert; import org.junit.Test; import aima.core.logic.fol.CNFConverter; import aima.core.logic.fol.SubsumptionElimination; import aima.core.logic.fol.domain.FOLDomain; 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; /** * @author Ciaran O'Reilly * */ public class SubsumptionEliminationTest { @Test public void testFindSubsumedClauses() { // Taken from AIMA2e pg 679 FOLDomain domain = new FOLDomain(); domain.addPredicate("patrons"); domain.addPredicate("hungry"); domain.addPredicate("type"); domain.addPredicate("fri_sat"); domain.addPredicate("will_wait"); domain.addConstant("Some"); domain.addConstant("Full"); domain.addConstant("French"); domain.addConstant("Thai"); domain.addConstant("Burger"); FOLParser parser = new FOLParser(domain); 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 s = parser.parse(sh); CNFConverter cnfConv = new CNFConverter(parser); CNF cnf = cnfConv.convertToCNF(s); // Contains 9 duplicates Assert.assertEquals(40, cnf.getNumberOfClauses()); Set<Clause> clauses = new HashSet<Clause>(cnf.getConjunctionOfClauses()); // duplicates removed Assert.assertEquals(31, clauses.size()); clauses.removeAll(SubsumptionElimination.findSubsumedClauses(clauses)); // subsumed clauses removed Assert.assertEquals(8, clauses.size()); // Ensure only the 8 correct/expected clauses remain Clause cl1 = cnfConv .convertToCNF( parser.parse("(NOT(will_wait(v)) OR (patrons(v,Full) OR patrons(v,Some)))")) .getConjunctionOfClauses().get(0); Clause cl2 = cnfConv .convertToCNF( parser.parse("(NOT(will_wait(v)) OR (hungry(v) OR patrons(v,Some)))")) .getConjunctionOfClauses().get(0); Clause cl3 = cnfConv .convertToCNF( parser.parse("(NOT(will_wait(v)) OR (patrons(v,Some) OR (type(v,Burger) OR (type(v,French) OR type(v,Thai)))))")) .getConjunctionOfClauses().get(0); Clause cl4 = cnfConv .convertToCNF( parser.parse("(NOT(will_wait(v)) OR (fri_sat(v) OR (patrons(v,Some) OR (type(v,Burger) OR type(v,French)))))")) .getConjunctionOfClauses().get(0); Clause cl5 = cnfConv .convertToCNF( parser.parse("(NOT(patrons(v,Some)) OR will_wait(v))")) .getConjunctionOfClauses().get(0); Clause cl6 = cnfConv .convertToCNF( parser.parse("(NOT(hungry(v)) OR (NOT(patrons(v,Full)) OR (NOT(type(v,French)) OR will_wait(v))))")) .getConjunctionOfClauses().get(0); Clause cl7 = cnfConv .convertToCNF( parser.parse("(NOT(fri_sat(v)) OR (NOT(hungry(v)) OR (NOT(patrons(v,Full)) OR (NOT(type(v,Thai)) OR will_wait(v)))))")) .getConjunctionOfClauses().get(0); Clause cl8 = cnfConv .convertToCNF( parser.parse("(NOT(hungry(v)) OR (NOT(patrons(v,Full)) OR (NOT(type(v,Burger)) OR will_wait(v))))")) .getConjunctionOfClauses().get(0); Assert.assertTrue(clauses.contains(cl1)); Assert.assertTrue(clauses.contains(cl2)); Assert.assertTrue(clauses.contains(cl3)); Assert.assertTrue(clauses.contains(cl4)); Assert.assertTrue(clauses.contains(cl5)); Assert.assertTrue(clauses.contains(cl6)); Assert.assertTrue(clauses.contains(cl7)); Assert.assertTrue(clauses.contains(cl8)); } }