001    package aima.test.logictest.foltest;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    import java.util.List;
006    import java.util.Set;
007    
008    import junit.framework.TestCase;
009    import aima.logic.fol.domain.FOLDomain;
010    import aima.logic.fol.inference.Paramodulation;
011    import aima.logic.fol.kb.data.Clause;
012    import aima.logic.fol.kb.data.Literal;
013    import aima.logic.fol.parsing.FOLParser;
014    import aima.logic.fol.parsing.ast.AtomicSentence;
015    
016    /**
017     * @author Ciaran O'Reilly
018     * 
019     */
020    public class ParamodulationTest extends TestCase {
021    
022            private Paramodulation paramodulation = null;
023    
024            public void setUp() {
025                    paramodulation = new Paramodulation();
026            }
027    
028            // Note: Based on:
029            // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf
030            // Slide 31.
031            public void testSimpleExample() {
032                    FOLDomain domain = new FOLDomain();
033                    domain.addConstant("A");
034                    domain.addConstant("B");
035                    domain.addPredicate("P");
036                    domain.addPredicate("Q");
037                    domain.addPredicate("R");
038                    domain.addFunction("F");
039    
040                    FOLParser parser = new FOLParser(domain);
041    
042                    List<Literal> lits = new ArrayList<Literal>();
043                    AtomicSentence a1 = (AtomicSentence) parser.parse("P(F(x,B),x)");
044                    AtomicSentence a2 = (AtomicSentence) parser.parse("Q(x)");
045                    lits.add(new Literal(a1));
046                    lits.add(new Literal(a2));
047    
048                    Clause c1 = new Clause(lits);
049    
050                    lits.clear();
051                    a1 = (AtomicSentence) parser.parse("F(A,y) = y");
052                    a2 = (AtomicSentence) parser.parse("R(y)");
053                    lits.add(new Literal(a1));
054                    lits.add(new Literal(a2));
055    
056                    Clause c2 = new Clause(lits);
057    
058                    Set<Clause> paras = paramodulation.apply(c1, c2);
059                    assertEquals(2, paras.size());
060    
061                    Iterator<Clause> it = paras.iterator();
062                    assertEquals("[P(B,A), Q(A), R(B)]", it.next().toString());
063                    assertEquals("[P(F(A,F(x,B)),x), Q(x), R(F(x,B))]", it.next()
064                                    .toString());
065            }
066    
067            public void testMultipleTermEqualitiesInBothClausesExample() {
068                    FOLDomain domain = new FOLDomain();
069                    domain.addConstant("A");
070                    domain.addConstant("B");
071                    domain.addConstant("C");
072                    domain.addConstant("D");
073                    domain.addPredicate("P");
074                    domain.addPredicate("Q");
075                    domain.addPredicate("R");
076                    domain.addFunction("F");
077    
078                    FOLParser parser = new FOLParser(domain);
079    
080                    List<Literal> lits = new ArrayList<Literal>();
081                    AtomicSentence a1 = (AtomicSentence) parser.parse("F(C,x) = D");
082                    AtomicSentence a2 = (AtomicSentence) parser.parse("A = D");
083                    AtomicSentence a3 = (AtomicSentence) parser.parse("P(F(x,B),x)");
084                    AtomicSentence a4 = (AtomicSentence) parser.parse("Q(x)");
085                    AtomicSentence a5 = (AtomicSentence) parser.parse("R(C)");
086                    lits.add(new Literal(a1));
087                    lits.add(new Literal(a2));
088                    lits.add(new Literal(a3));
089                    lits.add(new Literal(a4));
090                    lits.add(new Literal(a5));
091    
092                    Clause c1 = new Clause(lits);
093    
094                    lits.clear();
095                    a1 = (AtomicSentence) parser.parse("F(A,y) = y");
096                    a2 = (AtomicSentence) parser.parse("F(B,y) = C");
097                    a3 = (AtomicSentence) parser.parse("R(y)");
098                    a4 = (AtomicSentence) parser.parse("R(A)");
099                    lits.add(new Literal(a1));
100                    lits.add(new Literal(a2));
101                    lits.add(new Literal(a3));
102                    lits.add(new Literal(a4));
103    
104                    Clause c2 = new Clause(lits);
105    
106                    Set<Clause> paras = paramodulation.apply(c1, c2);
107                    assertEquals(5, paras.size());
108    
109                    Iterator<Clause> it = paras.iterator();
110                    assertEquals(
111                                    "[F(B,B) = C, F(C,A) = D, A = D, P(B,A), Q(A), R(A), R(B), R(C)]",
112                                    it.next().toString());
113                    assertEquals(
114                                    "[F(A,F(C,x)) = D, F(B,F(C,x)) = C, A = D, P(F(x,B),x), Q(x), R(F(C,x)), R(A), R(C)]",
115                                    it.next().toString());
116                    assertEquals(
117                                    "[F(A,B) = B, F(C,B) = D, A = D, P(C,B), Q(B), R(A), R(B), R(C)]",
118                                    it.next().toString());
119                    assertEquals(
120                                    "[F(F(B,y),x) = D, F(A,y) = y, A = D, P(F(x,B),x), Q(x), R(y), R(A), R(C)]",
121                                    it.next().toString());
122                    assertEquals(
123                                    "[F(B,y) = C, F(C,x) = D, F(D,y) = y, P(F(x,B),x), Q(x), R(y), R(A), R(C)]",
124                                    it.next().toString());
125            }
126    
127            public void testBypassReflexivityAxiom() {
128                    FOLDomain domain = new FOLDomain();
129                    domain.addConstant("A");
130                    domain.addConstant("B");
131                    domain.addConstant("C");
132                    domain.addPredicate("P");
133                    domain.addFunction("F");
134    
135                    FOLParser parser = new FOLParser(domain);
136    
137                    List<Literal> lits = new ArrayList<Literal>();
138                    AtomicSentence a1 = (AtomicSentence) parser.parse("P(y, F(A,y))");
139                    lits.add(new Literal(a1));
140    
141                    Clause c1 = new Clause(lits);
142    
143                    lits.clear();
144                    a1 = (AtomicSentence) parser.parse("x = x");
145                    lits.add(new Literal(a1));
146    
147                    Clause c2 = new Clause(lits);
148    
149                    Set<Clause> paras = paramodulation.apply(c1, c2);
150                    assertEquals(0, paras.size());
151            }
152            
153            public void testNegativeTermEquality() {
154                    FOLDomain domain = new FOLDomain();
155                    domain.addConstant("A");
156                    domain.addConstant("B");
157                    domain.addConstant("C");
158                    domain.addPredicate("P");
159                    domain.addFunction("F");
160    
161                    FOLParser parser = new FOLParser(domain);
162    
163                    List<Literal> lits = new ArrayList<Literal>();
164                    AtomicSentence a1 = (AtomicSentence) parser.parse("P(y, F(A,y))");
165                    lits.add(new Literal(a1));
166    
167                    Clause c1 = new Clause(lits);
168    
169                    lits.clear();
170                    a1 = (AtomicSentence) parser.parse("F(x,B) = x");
171                    lits.add(new Literal(a1, true));
172    
173                    Clause c2 = new Clause(lits);
174    
175                    Set<Clause> paras = paramodulation.apply(c1, c2);
176                    assertEquals(0, paras.size());
177            }
178    }