001    /*
002     * Created on Sep 18, 2004
003     *
004     */
005    package aima.test.logictest.foltest;
006    
007    import java.util.ArrayList;
008    import java.util.List;
009    
010    import junit.framework.TestCase;
011    import aima.logic.fol.domain.DomainFactory;
012    import aima.logic.fol.domain.FOLDomain;
013    import aima.logic.fol.parsing.FOLLexer;
014    import aima.logic.fol.parsing.FOLParser;
015    import aima.logic.fol.parsing.ast.ConnectedSentence;
016    import aima.logic.fol.parsing.ast.Constant;
017    import aima.logic.fol.parsing.ast.Function;
018    import aima.logic.fol.parsing.ast.NotSentence;
019    import aima.logic.fol.parsing.ast.Predicate;
020    import aima.logic.fol.parsing.ast.QuantifiedSentence;
021    import aima.logic.fol.parsing.ast.Sentence;
022    import aima.logic.fol.parsing.ast.Term;
023    import aima.logic.fol.parsing.ast.TermEquality;
024    import aima.logic.fol.parsing.ast.Variable;
025    
026    /**
027     * @author Ravi Mohan
028     * 
029     */
030    
031    public class FOLParserTest extends TestCase {
032            FOLLexer lexer;
033    
034            FOLParser parser;
035    
036            @Override
037            public void setUp() {
038                    FOLDomain domain = DomainFactory.crusadesDomain();
039    
040                    lexer = new FOLLexer(domain);
041                    parser = new FOLParser(lexer);
042    
043            }
044    
045            public void testParseSimpleVariable() {
046                    parser.setUpToParse("x");
047                    Term v = parser.parseVariable();
048                    assertEquals(v, new Variable("x"));
049            }
050    
051            public void testParseIndexedVariable() {
052                    parser.setUpToParse("x1");
053                    Term v = parser.parseVariable();
054                    assertEquals(v, new Variable("x1"));
055            }
056    
057            public void testNotAllowedParseLeadingIndexedVariable() {
058                    try {
059                            parser.setUpToParse("1x");
060                            parser.parseVariable();
061                            fail("A Runtime Exception should have been thrown, indicating '1x' is not a valid variable name.");
062                    } catch (RuntimeException rex) {
063                            // Ok, expected
064                    }
065            }
066    
067            public void testParseSimpleConstant() {
068                    parser.setUpToParse("John");
069                    Term c = parser.parseConstant();
070                    assertEquals(c, new Constant("John"));
071            }
072    
073            public void testParseFunction() {
074                    parser.setUpToParse("BrotherOf(John)");
075                    Term f = parser.parseFunction();
076                    assertEquals(f, getBrotherOfFunction(new Constant("John")));
077            }
078    
079            public void testParseMultiArityFunction() {
080                    parser.setUpToParse("LegsOf(John,Saladin,Richard)");
081                    Term f = parser.parseFunction();
082                    assertEquals(f, getLegsOfFunction());
083                    assertEquals(3, ((Function) f).getTerms().size());
084            }
085    
086            public void testPredicate() {
087                    // parser.setUpToParse("King(John)");
088                    Predicate p = (Predicate) parser.parse("King(John)");
089                    assertEquals(p, getKingPredicate(new Constant("John")));
090            }
091    
092            public void testTermEquality() {
093                    try {
094                            TermEquality te = (TermEquality) parser
095                                            .parse("BrotherOf(John) = EnemyOf(Saladin)");
096                            assertEquals(te, new TermEquality(
097                                            getBrotherOfFunction(new Constant("John")),
098                                            getEnemyOfFunction()));
099                    } catch (RuntimeException e) {
100    
101                    }
102    
103            }
104    
105            public void testTermEquality2() {
106                    try {
107                            TermEquality te = (TermEquality) parser
108                                            .parse("BrotherOf(John) = x)");
109                            assertEquals(te, new TermEquality(
110                                            getBrotherOfFunction(new Constant("John")), new Variable(
111                                                            "x")));
112                    } catch (RuntimeException e) {
113    
114                    }
115    
116            }
117    
118            public void testNotSentence() {
119    
120                    // parser.setUpToParse("NOT BrotherOf(John) = EnemyOf(Saladin)");
121                    NotSentence ns = (NotSentence) parser
122                                    .parse("NOT BrotherOf(John) = EnemyOf(Saladin)");
123                    assertEquals(ns.getNegated(), new TermEquality(
124                                    getBrotherOfFunction(new Constant("John")),
125                                    getEnemyOfFunction()));
126            }
127    
128            public void testSimpleParanthizedSentence() {
129                    Sentence ps = parser.parse("(NOT King(John))");
130                    assertEquals(ps,
131                                    new NotSentence(getKingPredicate(new Constant("John"))));
132            }
133    
134            public void testExtraParanthizedSentence() {
135                    Sentence ps = parser.parse("(((NOT King(John))))");
136                    assertEquals(ps,
137                                    new NotSentence(getKingPredicate(new Constant("John"))));
138            }
139    
140            public void testParseComplexParanthizedSentence() {
141                    Sentence ps = parser.parse("(NOT BrotherOf(John) = EnemyOf(Saladin))");
142                    assertEquals(ps, new NotSentence(new TermEquality(
143                                    getBrotherOfFunction(new Constant("John")),
144                                    getEnemyOfFunction())));
145            }
146    
147            public void testParseSimpleConnectedSentence() {
148                    Sentence ps = parser.parse("(King(John) AND NOT King(Richard))");
149    
150                    assertEquals(ps, new ConnectedSentence("AND",
151                                    getKingPredicate(new Constant("John")), new NotSentence(
152                                                    getKingPredicate(new Constant("Richard")))));
153    
154                    ps = parser.parse("(King(John) AND King(Saladin))");
155                    assertEquals(ps, new ConnectedSentence("AND",
156                                    getKingPredicate(new Constant("John")),
157                                    getKingPredicate(new Constant("Saladin"))));
158            }
159    
160            public void testComplexConnectedSentence1() {
161                    Sentence ps = parser
162                                    .parse("((King(John) AND NOT King(Richard)) OR King(Saladin))");
163                    // Sentence ps = parser.parse("(King(John) AND King(Saladin))");
164                    assertEquals(ps, new ConnectedSentence("OR", new ConnectedSentence(
165                                    "AND", getKingPredicate(new Constant("John")), new NotSentence(
166                                                    getKingPredicate(new Constant("Richard")))),
167                                    getKingPredicate(new Constant("Saladin"))));
168                    // assertEquals()
169            }
170    
171            public void testQuantifiedSentenceWithSingleVariable() {
172                    Sentence qs = parser.parse("FORALL x  King(x)");
173                    List<Variable> vars = new ArrayList<Variable>();
174                    vars.add(new Variable("x"));
175                    assertEquals(qs, new QuantifiedSentence("FORALL", vars,
176                                    getKingPredicate(new Variable("x"))));
177            }
178    
179            public void testQuantifiedSentenceWithTwoVariables() {
180                    Sentence qs = parser
181                                    .parse("EXISTS x,y  (King(x) AND BrotherOf(x) = y)");
182                    List<Variable> vars = new ArrayList<Variable>();
183                    vars.add(new Variable("x"));
184                    vars.add(new Variable("y"));
185                    ConnectedSentence cse = new ConnectedSentence("AND",
186                                    getKingPredicate(new Variable("x")), new TermEquality(
187                                                    getBrotherOfFunction(new Variable("x")), new Variable(
188                                                                    "y")));
189                    assertEquals(qs, new QuantifiedSentence("EXISTS", vars, cse));
190            }
191    
192            public void testQuantifiedSentenceWithPathologicalParanthising() {
193                    Sentence qs = parser
194                                    .parse("(( (EXISTS x,y  (King(x) AND (BrotherOf(x) = y)) ) ))");
195                    List<Variable> vars = new ArrayList<Variable>();
196                    vars.add(new Variable("x"));
197                    vars.add(new Variable("y"));
198                    ConnectedSentence cse = new ConnectedSentence("AND",
199                                    getKingPredicate(new Variable("x")), new TermEquality(
200                                                    getBrotherOfFunction(new Variable("x")), new Variable(
201                                                                    "y")));
202                    assertEquals(qs, new QuantifiedSentence("EXISTS", vars, cse));
203    
204            }
205    
206            public Function getBrotherOfFunction(Term t) {
207                    List<Term> l = new ArrayList<Term>();
208                    l.add(t);
209                    return new Function("BrotherOf", l);
210            }
211    
212            public Function getEnemyOfFunction() {
213                    List<Term> l = new ArrayList<Term>();
214                    l.add(new Constant("Saladin"));
215                    return new Function("EnemyOf", l);
216            }
217    
218            public Function getLegsOfFunction() {
219                    List<Term> l = new ArrayList<Term>();
220                    l.add(new Constant("John"));
221                    l.add(new Constant("Saladin"));
222                    l.add(new Constant("Richard"));
223                    return new Function("LegsOf", l);
224            }
225    
226            public Predicate getKingPredicate(Term t) {
227                    List<Term> l = new ArrayList<Term>();
228                    l.add(t);
229                    return new Predicate("King", l);
230            }
231    
232            public void testParseMultiArityFunctionEquality() {
233                    parser.setUpToParse("LegsOf(John,Saladin,Richard)");
234                    Term f = parser.parseFunction();
235    
236                    parser.setUpToParse("LegsOf(John,Saladin,Richard)");
237                    Term f2 = parser.parseFunction();
238                    assertEquals(f, f2);
239                    assertEquals(3, ((Function) f).getTerms().size());
240            }
241    
242            public void testConnectedImplication() {
243                    parser = new FOLParser(DomainFactory.weaponsDomain());
244                    Sentence s = parser
245                                    .parse("((Missile(m) AND Owns(Nono,m)) => Sells(West , m ,Nono))");
246            }
247    
248    }