/aima-core/src/test/java/aima/test/core/unit/logic/fol/kb/data/ClauseTest.java
Java | 891 lines | 655 code | 146 blank | 90 comment | 7 complexity | 145b70147ed77c8b80f47aaeb7782f27 MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0
- package aima.test.core.unit.logic.fol.kb.data;
-
- import java.util.ArrayList;
- import java.util.LinkedHashSet;
- import java.util.List;
- import java.util.Set;
-
- import org.junit.Assert;
- import org.junit.Before;
- import org.junit.Test;
-
- import aima.core.logic.fol.CNFConverter;
- import aima.core.logic.fol.StandardizeApartIndexicalFactory;
- import aima.core.logic.fol.domain.DomainFactory;
- import aima.core.logic.fol.domain.FOLDomain;
- 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.kb.data.Literal;
- import aima.core.logic.fol.parsing.FOLParser;
- import aima.core.logic.fol.parsing.ast.AtomicSentence;
- import aima.core.logic.fol.parsing.ast.Constant;
- import aima.core.logic.fol.parsing.ast.Function;
- import aima.core.logic.fol.parsing.ast.Predicate;
- import aima.core.logic.fol.parsing.ast.Sentence;
- import aima.core.logic.fol.parsing.ast.Term;
- import aima.core.logic.fol.parsing.ast.Variable;
-
- /**
- * @author Ciaran O'Reilly
- *
- */
- public class ClauseTest {
-
- @Before
- public void setUp() {
- StandardizeApartIndexicalFactory.flush();
- }
-
- @Test
- public void testImmutable() {
- Clause c = new Clause();
-
- Assert.assertFalse(c.isImmutable());
-
- c.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
-
- c.setImmutable();
-
- Assert.assertTrue(c.isImmutable());
-
- try {
- c.addNegativeLiteral(new Predicate("Pred3", new ArrayList<Term>()));
-
- Assert.fail("Should have thrown an IllegalStateException");
- } catch (IllegalStateException ise) {
- // Ok, Expected
- }
-
- try {
- c.addPositiveLiteral(new Predicate("Pred3", new ArrayList<Term>()));
-
- Assert.fail("Should have thrown an IllegalStateException");
- } catch (IllegalStateException ise) {
- // Ok, Expected
- }
- }
-
- @Test
- public void testIsEmpty() {
- Clause c1 = new Clause();
- Assert.assertTrue(c1.isEmpty());
-
- c1.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertFalse(c1.isEmpty());
-
- Clause c2 = new Clause();
- Assert.assertTrue(c2.isEmpty());
-
- c2.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertFalse(c2.isEmpty());
-
- Clause c3 = new Clause();
- Assert.assertTrue(c3.isEmpty());
-
- c3.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c3.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- // Should be empty as they resolved with each other
- Assert.assertFalse(c3.isEmpty());
-
- c3.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c3.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertFalse(c3.isEmpty());
- }
-
- @Test
- public void testIsHornClause() {
- Clause c1 = new Clause();
- Assert.assertFalse(c1.isHornClause());
-
- c1.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertTrue(c1.isHornClause());
-
- c1.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertTrue(c1.isHornClause());
-
- c1.addNegativeLiteral(new Predicate("Pred3", new ArrayList<Term>()));
- Assert.assertTrue(c1.isHornClause());
- c1.addNegativeLiteral(new Predicate("Pred4", new ArrayList<Term>()));
- Assert.assertTrue(c1.isHornClause());
-
- c1.addPositiveLiteral(new Predicate("Pred5", new ArrayList<Term>()));
- Assert.assertFalse(c1.isHornClause());
- }
-
- @Test
- public void testIsDefiniteClause() {
- Clause c1 = new Clause();
- Assert.assertFalse(c1.isDefiniteClause());
-
- c1.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertFalse(c1.isDefiniteClause());
-
- c1.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertTrue(c1.isDefiniteClause());
-
- c1.addNegativeLiteral(new Predicate("Pred3", new ArrayList<Term>()));
- Assert.assertTrue(c1.isDefiniteClause());
- c1.addNegativeLiteral(new Predicate("Pred4", new ArrayList<Term>()));
- Assert.assertTrue(c1.isDefiniteClause());
-
- c1.addPositiveLiteral(new Predicate("Pred5", new ArrayList<Term>()));
- Assert.assertFalse(c1.isDefiniteClause());
- }
-
- @Test
- public void testIsUnitClause() {
- Clause c1 = new Clause();
- Assert.assertFalse(c1.isUnitClause());
-
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertTrue(c1.isUnitClause());
-
- c1.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertFalse(c1.isUnitClause());
-
- c1 = new Clause();
- Assert.assertFalse(c1.isUnitClause());
-
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertTrue(c1.isUnitClause());
-
- c1.addNegativeLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertFalse(c1.isUnitClause());
-
- c1 = new Clause();
- Assert.assertFalse(c1.isUnitClause());
-
- c1.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertTrue(c1.isUnitClause());
-
- c1.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertFalse(c1.isUnitClause());
- }
-
- @Test
- public void testIsImplicationDefiniteClause() {
- Clause c1 = new Clause();
- Assert.assertFalse(c1.isImplicationDefiniteClause());
-
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertFalse(c1.isImplicationDefiniteClause());
-
- c1.addNegativeLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertTrue(c1.isImplicationDefiniteClause());
- c1.addNegativeLiteral(new Predicate("Pred3", new ArrayList<Term>()));
- Assert.assertTrue(c1.isImplicationDefiniteClause());
-
- c1.addPositiveLiteral(new Predicate("Pred4", new ArrayList<Term>()));
- Assert.assertFalse(c1.isImplicationDefiniteClause());
- }
-
- @Test
- public void testBinaryResolvents() {
- FOLDomain domain = new FOLDomain();
- domain.addPredicate("Pred1");
- domain.addPredicate("Pred2");
- domain.addPredicate("Pred3");
- domain.addPredicate("Pred4");
-
- Clause c1 = new Clause();
-
- // Ensure that resolving to self when empty returns an empty clause
- Assert.assertNotNull(c1.binaryResolvents(c1));
- Assert.assertEquals(1, c1.binaryResolvents(c1).size());
- Assert.assertTrue(c1.binaryResolvents(c1).iterator().next().isEmpty());
-
- // Check if resolve with self to an empty clause
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c1.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertNotNull(c1.binaryResolvents(c1));
- Assert.assertEquals(1, c1.binaryResolvents(c1).size());
- // i.e. resolving a tautology with a tautology gives you
- // back a tautology.
- Assert.assertEquals("[~Pred1(), Pred1()]", c1.binaryResolvents(c1)
- .iterator().next().toString());
-
- // Check if try to resolve with self and no resolvents
- c1 = new Clause();
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertEquals(0, c1.binaryResolvents(c1).size());
-
- c1 = new Clause();
- Clause c2 = new Clause();
- // Ensure that two empty clauses resolve to an empty clause
- Assert.assertNotNull(c1.binaryResolvents(c2));
- Assert.assertEquals(1, c1.binaryResolvents(c2).size());
- Assert.assertTrue(c1.binaryResolvents(c2).iterator().next().isEmpty());
- Assert.assertNotNull(c2.binaryResolvents(c1));
- Assert.assertEquals(1, c2.binaryResolvents(c1).size());
- Assert.assertTrue(c2.binaryResolvents(c1).iterator().next().isEmpty());
-
- // Enusre the two complementary clauses resolve
- // to the empty clause
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c2.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- Assert.assertNotNull(c1.binaryResolvents(c2));
- Assert.assertEquals(1, c1.binaryResolvents(c2).size());
- Assert.assertTrue(c1.binaryResolvents(c2).iterator().next().isEmpty());
- Assert.assertNotNull(c2.binaryResolvents(c1));
- Assert.assertEquals(1, c2.binaryResolvents(c1).size());
- Assert.assertTrue(c2.binaryResolvents(c1).iterator().next().isEmpty());
-
- // Ensure that two clauses that have two complementaries
- // resolve with two resolvents
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c2.addNegativeLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c1.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- c2.addNegativeLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertNotNull(c1.binaryResolvents(c2));
- Assert.assertEquals(2, c1.binaryResolvents(c2).size());
- Assert.assertNotNull(c2.binaryResolvents(c1));
- Assert.assertEquals(2, c2.binaryResolvents(c1).size());
-
- // Ensure two clauses that factor are not
- // considered resolved
- c1 = new Clause();
- c2 = new Clause();
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c1.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- c1.addNegativeLiteral(new Predicate("Pred3", new ArrayList<Term>()));
- c1.addNegativeLiteral(new Predicate("Pred4", new ArrayList<Term>()));
- c2.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- c2.addNegativeLiteral(new Predicate("Pred4", new ArrayList<Term>()));
- Assert.assertNotNull(c1.binaryResolvents(c2));
- Assert.assertEquals(0, c1.binaryResolvents(c2).size());
- Assert.assertNotNull(c2.binaryResolvents(c1));
- Assert.assertEquals(0, c2.binaryResolvents(c1).size());
-
- // Ensure the resolvent is a subset of the originals
- c1 = new Clause();
- c2 = new Clause();
- c1.addPositiveLiteral(new Predicate("Pred1", new ArrayList<Term>()));
- c1.addNegativeLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- c1.addNegativeLiteral(new Predicate("Pred3", new ArrayList<Term>()));
- c2.addPositiveLiteral(new Predicate("Pred2", new ArrayList<Term>()));
- Assert.assertNotNull(c1.binaryResolvents(c2));
- Assert.assertNotNull(c2.binaryResolvents(c1));
- Assert.assertEquals(1, c1.binaryResolvents(c2).iterator().next()
- .getNumberPositiveLiterals());
- Assert.assertEquals(1, c1.binaryResolvents(c2).iterator().next()
- .getNumberNegativeLiterals());
- Assert.assertEquals(1, c2.binaryResolvents(c1).iterator().next()
- .getNumberPositiveLiterals());
- Assert.assertEquals(1, c2.binaryResolvents(c1).iterator().next()
- .getNumberNegativeLiterals());
- }
-
- @Test
- public void testBinaryResolventsOrderDoesNotMatter() {
- // This is a regression test, to ensure
- // the ordering of resolvents does not matter.
- // If the order ends up mattering, then likely
- // a problem was introduced in the Clause class
- // unifier, or related class.
-
- // Set up the initial set of clauses based on the
- // loves animal domain as it contains functions
- // new clauses will always be created (i.e. is an
- // infinite universe of discourse).
- FOLKnowledgeBase kb = new FOLKnowledgeBase(
- DomainFactory.lovesAnimalDomain());
-
- kb.tell("FORALL x (FORALL y (Animal(y) => Loves(x, y)) => EXISTS y Loves(y, x))");
- kb.tell("FORALL x (EXISTS y (Animal(y) AND Kills(x, y)) => FORALL z NOT(Loves(z, x)))");
- kb.tell("FORALL x (Animal(x) => Loves(Jack, x))");
- kb.tell("(Kills(Jack, Tuna) OR Kills(Curiosity, Tuna))");
- kb.tell("Cat(Tuna)");
- kb.tell("FORALL x (Cat(x) => Animal(x))");
-
- Set<Clause> clauses = new LinkedHashSet<Clause>();
- clauses.addAll(kb.getAllClauses());
-
- Set<Clause> newClauses = new LinkedHashSet<Clause>();
- long maxRunTime = 30 * 1000; // 30 seconds
- long finishTime = System.currentTimeMillis() + maxRunTime;
- do {
- clauses.addAll(newClauses);
- newClauses.clear();
- Clause[] clausesA = new Clause[clauses.size()];
- clauses.toArray(clausesA);
- for (int i = 0; i < clausesA.length; i++) {
- Clause cI = clausesA[i];
- for (int j = 0; j < clausesA.length; j++) {
- Clause cJ = clausesA[j];
-
- newClauses.addAll(cI.getFactors());
- newClauses.addAll(cJ.getFactors());
-
- Set<Clause> cIresolvents = cI.binaryResolvents(cJ);
- Set<Clause> cJresolvents = cJ.binaryResolvents(cI);
- if (!cIresolvents.equals(cJresolvents)) {
- System.err.println("cI=" + cI);
- System.err.println("cJ=" + cJ);
- System.err.println("cIR=" + cIresolvents);
- System.err.println("cJR=" + cJresolvents);
- Assert.fail("Ordering of binary resolvents has become important, which should not be the case");
- }
-
- for (Clause r : cIresolvents) {
- newClauses.addAll(r.getFactors());
- }
-
- if (System.currentTimeMillis() > finishTime) {
- break;
- }
- }
- if (System.currentTimeMillis() > finishTime) {
- break;
- }
- }
- } while (System.currentTimeMillis() < finishTime);
- }
-
- @Test
- public void testEqualityBinaryResolvents() {
- FOLDomain domain = new FOLDomain();
- domain.addConstant("A");
- domain.addConstant("B");
-
- FOLParser parser = new FOLParser(domain);
-
- // B = A
- Clause c1 = new Clause();
- c1.addPositiveLiteral((AtomicSentence) parser.parse("B = A"));
-
- Clause c2 = new Clause();
- c2.addNegativeLiteral((AtomicSentence) parser.parse("B = A"));
- c2.addPositiveLiteral((AtomicSentence) parser.parse("B = A"));
-
- Set<Clause> resolvents = c1.binaryResolvents(c2);
-
- Assert.assertEquals(1, resolvents.size());
- Assert.assertEquals("[[B = A]]", resolvents.toString());
- }
-
- @Test
- public void testHashCode() {
- Term cons1 = new Constant("C1");
- Term cons2 = new Constant("C2");
- Term var1 = new Variable("v1");
- List<Term> pts1 = new ArrayList<Term>();
- List<Term> pts2 = new ArrayList<Term>();
- pts1.add(cons1);
- pts1.add(cons2);
- pts1.add(var1);
- pts2.add(cons2);
- pts2.add(cons1);
- pts2.add(var1);
-
- Clause c1 = new Clause();
- Clause c2 = new Clause();
- Assert.assertEquals(c1.hashCode(), c2.hashCode());
-
- c1.addNegativeLiteral(new Predicate("Pred1", pts1));
- Assert.assertNotSame(c1.hashCode(), c2.hashCode());
- c2.addNegativeLiteral(new Predicate("Pred1", pts1));
- Assert.assertEquals(c1.hashCode(), c2.hashCode());
-
- c1.addPositiveLiteral(new Predicate("Pred1", pts1));
- Assert.assertNotSame(c1.hashCode(), c2.hashCode());
- c2.addPositiveLiteral(new Predicate("Pred1", pts1));
- Assert.assertEquals(c1.hashCode(), c2.hashCode());
- }
-
- @Test
- public void testSimpleEquals() {
- Term cons1 = new Constant("C1");
- Term cons2 = new Constant("C2");
- Term var1 = new Variable("v1");
- List<Term> pts1 = new ArrayList<Term>();
- List<Term> pts2 = new ArrayList<Term>();
- pts1.add(cons1);
- pts1.add(cons2);
- pts1.add(var1);
- pts2.add(cons2);
- pts2.add(cons1);
- pts2.add(var1);
-
- Clause c1 = new Clause();
- Clause c2 = new Clause();
- Assert.assertTrue(c1.equals(c1));
- Assert.assertTrue(c2.equals(c2));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
-
- // Check negatives
- c1.addNegativeLiteral(new Predicate("Pred1", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addNegativeLiteral(new Predicate("Pred1", pts1));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
-
- c1.addNegativeLiteral(new Predicate("Pred2", pts2));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addNegativeLiteral(new Predicate("Pred2", pts2));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
- // Check same but added in different order
- c1.addNegativeLiteral(new Predicate("Pred3", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c1.addNegativeLiteral(new Predicate("Pred4", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addNegativeLiteral(new Predicate("Pred4", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addNegativeLiteral(new Predicate("Pred3", pts1));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
-
- // Check positives
- c1.addPositiveLiteral(new Predicate("Pred1", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addPositiveLiteral(new Predicate("Pred1", pts1));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
-
- c1.addPositiveLiteral(new Predicate("Pred2", pts2));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addPositiveLiteral(new Predicate("Pred2", pts2));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
- // Check same but added in different order
- c1.addPositiveLiteral(new Predicate("Pred3", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c1.addPositiveLiteral(new Predicate("Pred4", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addPositiveLiteral(new Predicate("Pred4", pts1));
- Assert.assertFalse(c1.equals(c2));
- Assert.assertFalse(c2.equals(c1));
- c2.addPositiveLiteral(new Predicate("Pred3", pts1));
- Assert.assertTrue(c1.equals(c2));
- Assert.assertTrue(c2.equals(c1));
- }
-
- @Test
- public void testComplexEquals() {
- FOLDomain domain = new FOLDomain();
- domain.addConstant("A");
- domain.addConstant("B");
- domain.addConstant("C");
- domain.addConstant("D");
- domain.addPredicate("P");
- domain.addPredicate("Animal");
- domain.addPredicate("Kills");
- domain.addFunction("F");
- domain.addFunction("SF0");
-
- FOLParser parser = new FOLParser(domain);
-
- CNFConverter cnfConverter = new CNFConverter(parser);
- Sentence s1 = parser.parse("((x1 = y1 AND y1 = z1) => x1 = z1)");
- Sentence s2 = parser.parse("((x2 = y2 AND F(y2) = z2) => F(x2) = z2)");
- CNF cnf1 = cnfConverter.convertToCNF(s1);
- CNF cnf2 = cnfConverter.convertToCNF(s2);
-
- Clause c1 = cnf1.getConjunctionOfClauses().get(0);
- Clause c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertFalse(c1.equals(c2));
-
- s1 = parser.parse("((x1 = y1 AND y1 = z1) => x1 = z1)");
- s2 = parser.parse("((x2 = y2 AND y2 = z2) => x2 = z2)");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertTrue(c1.equals(c2));
-
- s1 = parser.parse("((x1 = y1 AND y1 = z1) => x1 = z1)");
- s2 = parser.parse("((y2 = z2 AND x2 = y2) => x2 = z2)");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertTrue(c1.equals(c2));
-
- s1 = parser.parse("(((x1 = y1 AND y1 = z1) AND z1 = r1) => x1 = r1)");
- s2 = parser.parse("(((x2 = y2 AND y2 = z2) AND z2 = r2) => x2 = r2)");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertTrue(c1.equals(c2));
-
- s1 = parser.parse("(((x1 = y1 AND y1 = z1) AND z1 = r1) => x1 = r1)");
- s2 = parser.parse("(((z2 = r2 AND y2 = z2) AND x2 = y2) => x2 = r2)");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertTrue(c1.equals(c2));
-
- s1 = parser.parse("(((x1 = y1 AND y1 = z1) AND z1 = r1) => x1 = r1)");
- s2 = parser.parse("(((x2 = y2 AND y2 = z2) AND z2 = y2) => x2 = r2)");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertFalse(c1.equals(c2));
-
- s1 = parser
- .parse("(((((x1 = y1 AND y1 = z1) AND z1 = r1) AND r1 = q1) AND q1 = s1) => x1 = r1)");
- s2 = parser
- .parse("(((((x2 = y2 AND y2 = z2) AND z2 = r2) AND r2 = q2) AND q2 = s2) => x2 = r2)");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertTrue(c1.equals(c2));
-
- s1 = parser
- .parse("((((NOT(Animal(c1920)) OR NOT(Animal(c1921))) OR NOT(Kills(c1922,c1920))) OR NOT(Kills(c1919,c1921))) OR NOT(Kills(SF0(c1922),SF0(c1919))))");
- s2 = parser
- .parse("((((NOT(Animal(c1929)) OR NOT(Animal(c1928))) OR NOT(Kills(c1927,c1929))) OR NOT(Kills(c1930,c1928))) OR NOT(Kills(SF0(c1930),SF0(c1927))))");
- cnf1 = cnfConverter.convertToCNF(s1);
- cnf2 = cnfConverter.convertToCNF(s2);
-
- c1 = cnf1.getConjunctionOfClauses().get(0);
- c2 = cnf2.getConjunctionOfClauses().get(0);
-
- Assert.assertTrue(c1.equals(c2));
- }
-
- @Test
- public void testNonTrivialFactors() {
- FOLDomain domain = new FOLDomain();
- domain.addConstant("A");
- domain.addConstant("B");
- domain.addFunction("F");
- domain.addFunction("G");
- domain.addFunction("H");
- domain.addPredicate("P");
- domain.addPredicate("Q");
-
- FOLParser parser = new FOLParser(domain);
-
- // p(x,y), q(a,b), p(b,a), q(y,x)
- Clause c = new Clause();
- c.addPositiveLiteral((Predicate) parser.parse("P(x,y)"));
- c.addPositiveLiteral((Predicate) parser.parse("Q(A,B)"));
- c.addNegativeLiteral((Predicate) parser.parse("P(B,A)"));
- c.addPositiveLiteral((Predicate) parser.parse("Q(y,x)"));
-
- Assert.assertEquals("[[~P(B,A), P(B,A), Q(A,B)]]", c
- .getNonTrivialFactors().toString());
-
- // p(x,y), q(a,b), p(b,a), q(y,x)
- c = new Clause();
- c.addPositiveLiteral((Predicate) parser.parse("P(x,y)"));
- c.addPositiveLiteral((Predicate) parser.parse("Q(A,B)"));
- c.addNegativeLiteral((Predicate) parser.parse("P(B,A)"));
- c.addNegativeLiteral((Predicate) parser.parse("Q(y,x)"));
-
- Assert.assertEquals("[]", c.getNonTrivialFactors().toString());
-
- // p(x,f(y)), p(g(u),x), p(f(y),u)
- c = new Clause();
- c.addPositiveLiteral((Predicate) parser.parse("P(x,F(y))"));
- c.addPositiveLiteral((Predicate) parser.parse("P(G(u),x)"));
- c.addPositiveLiteral((Predicate) parser.parse("P(F(y),u)"));
-
- // Should be: [{P(F(c#),F(c#)),P(G(F(c#)),F(c#))}]
- c = c.getNonTrivialFactors().iterator().next();
- Literal p = c.getPositiveLiterals().get(0);
- Assert.assertEquals("P", p.getAtomicSentence().getSymbolicName());
- Function f = (Function) p.getAtomicSentence().getArgs().get(0);
- Assert.assertEquals("F", f.getFunctionName());
- Variable v = (Variable) f.getTerms().get(0);
- f = (Function) p.getAtomicSentence().getArgs().get(1);
- Assert.assertEquals("F", f.getFunctionName());
- Assert.assertEquals(v, f.getTerms().get(0));
-
- //
- p = c.getPositiveLiterals().get(1);
- f = (Function) p.getAtomicSentence().getArgs().get(0);
- Assert.assertEquals("G", f.getFunctionName());
- f = (Function) f.getTerms().get(0);
- Assert.assertEquals("F", f.getFunctionName());
- Assert.assertEquals(v, f.getTerms().get(0));
- f = (Function) p.getAtomicSentence().getArgs().get(1);
- Assert.assertEquals("F", f.getFunctionName());
- Assert.assertEquals(v, f.getTerms().get(0));
-
- // p(g(x)), q(x), p(f(a)), p(x), p(g(f(x))), q(f(a))
- c = new Clause();
- c.addPositiveLiteral((Predicate) parser.parse("P(G(x))"));
- c.addPositiveLiteral((Predicate) parser.parse("Q(x)"));
- c.addPositiveLiteral((Predicate) parser.parse("P(F(A))"));
- c.addPositiveLiteral((Predicate) parser.parse("P(x)"));
- c.addPositiveLiteral((Predicate) parser.parse("P(G(F(x)))"));
- c.addPositiveLiteral((Predicate) parser.parse("Q(F(A))"));
-
- Assert.assertEquals("[[P(F(A)), P(G(F(F(A)))), P(G(F(A))), Q(F(A))]]",
- c.getNonTrivialFactors().toString());
- }
-
- // Note: Tests derived from:
- // http://logic.stanford.edu/classes/cs157/2008/notes/chap09.pdf
- // page 16.
- @Test
- public void testIsTautology() {
- FOLDomain domain = new FOLDomain();
- domain.addConstant("A");
- domain.addPredicate("P");
- domain.addPredicate("Q");
- domain.addPredicate("R");
- domain.addFunction("F");
-
- FOLParser parser = new FOLParser(domain);
-
- // {p(f(a)),~p(f(a))}
- Clause c = new Clause();
- c.addPositiveLiteral((Predicate) parser.parse("P(F(A))"));
- Assert.assertFalse(c.isTautology());
- c.addNegativeLiteral((Predicate) parser.parse("P(F(A))"));
- Assert.assertTrue(c.isTautology());
-
- // {p(x),q(y),~q(y),r(z)}
- c = new Clause();
- c.addPositiveLiteral((Predicate) parser.parse("P(x)"));
- Assert.assertFalse(c.isTautology());
- c.addPositiveLiteral((Predicate) parser.parse("Q(y)"));
- Assert.assertFalse(c.isTautology());
- c.addNegativeLiteral((Predicate) parser.parse("Q(y)"));
- Assert.assertTrue(c.isTautology());
- c.addPositiveLiteral((Predicate) parser.parse("R(z)"));
- Assert.assertTrue(c.isTautology());
-
- // {~p(a),p(x)}
- c = new Clause();
- c.addNegativeLiteral((Predicate) parser.parse("P(A)"));
- Assert.assertFalse(c.isTautology());
- c.addPositiveLiteral((Predicate) parser.parse("P(x)"));
- Assert.assertFalse(c.isTautology());
- }
-
- // Note: Tests derived from:
- // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture12.pdf
- // slides 17 and 18.
- @Test
- public void testSubsumes() {
- FOLDomain domain = new FOLDomain();
- domain.addConstant("A");
- domain.addConstant("B");
- domain.addConstant("C");
- domain.addConstant("D");
- domain.addConstant("E");
- domain.addConstant("F");
- domain.addConstant("G");
- domain.addConstant("H");
- domain.addConstant("I");
- domain.addConstant("J");
- domain.addPredicate("P");
- domain.addPredicate("Q");
-
- FOLParser parser = new FOLParser(domain);
-
- // Example
- // {~p(a,b),q(c)}
- Clause psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(x,y)}
- Clause phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(x,y)"));
-
- Assert.assertTrue(phi.subsumes(psi));
- // Non-Example
- // {~p(x,b),q(x)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(x,B)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(x)"));
- // {~p(a,y)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,y)"));
- // Reason for Non-Example:
- // {p(b,b)}
- // {~q(b)}
- Assert.assertFalse(phi.subsumes(psi));
-
- //
- // Additional Examples
-
- // Non-Example
- // {~p(x,b),q(z)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(x,B)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(z)"));
- // {~p(a,y)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,y)"));
-
- Assert.assertFalse(phi.subsumes(psi));
-
- // Example
- // {~p(a,b),~p(w,z),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(w,z)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(x,y),~p(a,b)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(x,y)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
-
- Assert.assertTrue(phi.subsumes(psi));
-
- // Non-Example
- // {~p(v,b),~p(w,z),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(v,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(w,z)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(x,y),~p(a,b)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(x,y)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
-
- Assert.assertFalse(phi.subsumes(psi));
-
- // Example
- // {~p(a,b),~p(c,d),~p(e,f),~p(g,h),~p(i,j),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(G,H)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(i,j)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
-
- Assert.assertTrue(phi.subsumes(psi));
-
- // Example
- // {~p(a,b),~p(c,d),~p(e,f),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(e,f),~p(a,b),~p(c,d)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
-
- Assert.assertTrue(phi.subsumes(psi));
-
- // Example
- // {~p(a,b),~p(c,d),~p(e,f),~p(g,h),~p(i,j),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(G,H)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(i,j),~p(c,d)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
-
- Assert.assertTrue(phi.subsumes(psi));
-
- // Non-Example
- // {~p(a,b),~p(x,d),~p(e,f),~p(g,h),~p(i,j),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(x,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(G,H)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(i,j),~p(c,d)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
-
- Assert.assertFalse(phi.subsumes(psi));
-
- // Example
- // {~p(a,b),~p(c,d),~p(e,f),~p(g,h),~p(i,j),q(c)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(G,H)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C)"));
- // {~p(i,j),~p(a,x)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,x)"));
-
- Assert.assertTrue(phi.subsumes(psi));
-
- // Example
- // {~p(a,b),~p(c,d),~p(e,f),~p(g,h),~p(i,j),q(a,b),q(c,d),q(e,f)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(G,H)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(A,B)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C,D)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(E,F)"));
- // {~p(i,j),~p(a,b),q(e,f),q(a,b)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- phi.addPositiveLiteral((Predicate) parser.parse("Q(E,F)"));
- phi.addPositiveLiteral((Predicate) parser.parse("Q(A,B)"));
-
- Assert.assertTrue(phi.subsumes(psi));
-
- // Non-Example
- // {~p(a,b),~p(c,d),~p(e,f),~p(g,h),~p(i,j),q(a,b),q(c,d),q(e,f)}
- psi = new Clause();
- psi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(C,D)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(E,F)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(G,H)"));
- psi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(A,B)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(C,D)"));
- psi.addPositiveLiteral((Predicate) parser.parse("Q(E,F)"));
- // {~p(i,j),~p(a,b),q(e,f),q(a,b)}
- phi = new Clause();
- phi.addNegativeLiteral((Predicate) parser.parse("P(I,J)"));
- phi.addNegativeLiteral((Predicate) parser.parse("P(A,B)"));
- phi.addPositiveLiteral((Predicate) parser.parse("Q(E,A)"));
- phi.addPositiveLiteral((Predicate) parser.parse("Q(A,B)"));
-
- Assert.assertFalse(phi.subsumes(psi));
- }
- }