package aima.test.core.unit.logic.fol.parsing;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import aima.core.logic.fol.domain.DomainFactory;
import aima.core.logic.fol.domain.FOLDomain;
import aima.core.logic.fol.parsing.FOLLexer;
import aima.core.logic.fol.parsing.FOLParser;
import aima.core.logic.fol.parsing.ast.ConnectedSentence;
import aima.core.logic.fol.parsing.ast.Constant;
import aima.core.logic.fol.parsing.ast.Function;
import aima.core.logic.fol.parsing.ast.NotSentence;
import aima.core.logic.fol.parsing.ast.Predicate;
import aima.core.logic.fol.parsing.ast.QuantifiedSentence;
import aima.core.logic.fol.parsing.ast.Sentence;
import aima.core.logic.fol.parsing.ast.Term;
import aima.core.logic.fol.parsing.ast.TermEquality;
import aima.core.logic.fol.parsing.ast.Variable;
/**
* @author Ravi Mohan
*
*/
public class FOLParserTest {
FOLLexer lexer;
FOLParser parser;
@Before
public void setUp() {
FOLDomain domain = DomainFactory.crusadesDomain();
lexer = new FOLLexer(domain);
parser = new FOLParser(lexer);
}
@Test
public void testParseSimpleVariable() {
parser.setUpToParse("x");
Term v = parser.parseVariable();
Assert.assertEquals(v, new Variable("x"));
}
@Test
public void testParseIndexedVariable() {
parser.setUpToParse("x1");
Term v = parser.parseVariable();
Assert.assertEquals(v, new Variable("x1"));
}
@Test(expected = RuntimeException.class)
public void testNotAllowedParseLeadingIndexedVariable() {
parser.setUpToParse("1x");
parser.parseVariable();
}
@Test
public void testParseSimpleConstant() {
parser.setUpToParse("John");
Term c = parser.parseConstant();
Assert.assertEquals(c, new Constant("John"));
}
@Test
public void testParseFunction() {
parser.setUpToParse("BrotherOf(John)");
Term f = parser.parseFunction();
Assert.assertEquals(f, getBrotherOfFunction(new Constant("John")));
}
@Test
public void testParseMultiArityFunction() {
parser.setUpToParse("LegsOf(John,Saladin,Richard)");
Term f = parser.parseFunction();
Assert.assertEquals(f, getLegsOfFunction());
Assert.assertEquals(3, ((Function) f).getTerms().size());
}
@Test
public void testPredicate() {
// parser.setUpToParse("King(John)");
Predicate p = (Predicate) parser.parse("King(John)");
Assert.assertEquals(p, getKingPredicate(new Constant("John")));
}
@Test
public void testTermEquality() {
try {
TermEquality te = (TermEquality) parser
.parse("BrotherOf(John) = EnemyOf(Saladin)");
Assert.assertEquals(te, new TermEquality(
getBrotherOfFunction(new Constant("John")),
getEnemyOfFunction()));
} catch (RuntimeException e) {
Assert.fail("RuntimeException thrown");
}
}
@Test
public void testTermEquality2() {
try {
TermEquality te = (TermEquality) parser
.parse("BrotherOf(John) = x)");
Assert.assertEquals(te, new TermEquality(
getBrotherOfFunction(new Constant("John")), new Variable(
"x")));
} catch (RuntimeException e) {
Assert.fail("RuntimeException thrown");
}
}
@Test
public void testNotSentence() {
NotSentence ns = (NotSentence) parser
.parse("NOT BrotherOf(John) = EnemyOf(Saladin)");
Assert.assertEquals(ns.getNegated(), new TermEquality(
getBrotherOfFunction(new Constant("John")),
getEnemyOfFunction()));
}
@Test
public void testSimpleParanthizedSentence() {
Sentence ps = parser.parse("(NOT King(John))");
Assert.assertEquals(ps, new NotSentence(getKingPredicate(new Constant(
"John"))));
}
@Test
public void testExtraParanthizedSentence() {
Sentence ps = parser.parse("(((NOT King(John))))");
Assert.assertEquals(ps, new NotSentence(getKingPredicate(new Constant(
"John"))));
}
@Test
public void testParseComplexParanthizedSentence() {
Sentence ps = parser.parse("(NOT BrotherOf(John) = EnemyOf(Saladin))");
Assert.assertEquals(ps, new NotSentence(new TermEquality(
getBrotherOfFunction(new Constant("John")),
getEnemyOfFunction())));
}
@Test
public void testParseSimpleConnectedSentence() {
Sentence ps = parser.parse("(King(John) AND NOT King(Richard))");
Assert.assertEquals(ps, new ConnectedSentence("AND",
getKingPredicate(new Constant("John")), new NotSentence(
getKingPredicate(new Constant("Richard")))));
ps = parser.parse("(King(John) AND King(Saladin))");
Assert.assertEquals(ps, new ConnectedSentence("AND",
getKingPredicate(new Constant("John")),
getKingPredicate(new Constant("Saladin"))));
}
@Test
public void testComplexConnectedSentence1() {
Sentence ps = parser
.parse("((King(John) AND NOT King(Richard)) OR King(Saladin))");
Assert.assertEquals(ps, new ConnectedSentence("OR",
new ConnectedSentence("AND", getKingPredicate(new Constant(
"John")), new NotSentence(
getKingPredicate(new Constant("Richard")))),
getKingPredicate(new Constant("Saladin"))));
}
@Test
public void testQuantifiedSentenceWithSingleVariable() {
Sentence qs = parser.parse("FORALL x King(x)");
List<Variable> vars = new ArrayList<Variable>();
vars.add(new Variable("x"));
Assert.assertEquals(qs, new QuantifiedSentence("FORALL", vars,
getKingPredicate(new Variable("x"))));
}
@Test
public void testQuantifiedSentenceWithTwoVariables() {
Sentence qs = parser
.parse("EXISTS x,y (King(x) AND BrotherOf(x) = y)");
List<Variable> vars = new ArrayList<Variable>();
vars.add(new Variable("x"));
vars.add(new Variable("y"));
ConnectedSentence cse = new ConnectedSentence("AND",
getKingPredicate(new Variable("x")), new TermEquality(
getBrotherOfFunction(new Variable("x")), new Variable(
"y")));
Assert.assertEquals(qs, new QuantifiedSentence("EXISTS", vars, cse));
}
@Test
public void testQuantifiedSentenceWithPathologicalParanthising() {
Sentence qs = parser
.parse("(( (EXISTS x,y (King(x) AND (BrotherOf(x) = y)) ) ))");
List<Variable> vars = new ArrayList<Variable>();
vars.add(new Variable("x"));
vars.add(new Variable("y"));
ConnectedSentence cse = new ConnectedSentence("AND",
getKingPredicate(new Variable("x")), new TermEquality(
getBrotherOfFunction(new Variable("x")), new Variable(
"y")));
Assert.assertEquals(qs, new QuantifiedSentence("EXISTS", vars, cse));
}
@Test
public void testParseMultiArityFunctionEquality() {
parser.setUpToParse("LegsOf(John,Saladin,Richard)");
Term f = parser.parseFunction();
parser.setUpToParse("LegsOf(John,Saladin,Richard)");
Term f2 = parser.parseFunction();
Assert.assertEquals(f, f2);
Assert.assertEquals(3, ((Function) f).getTerms().size());
}
@Test
public void testConnectedImplication() {
parser = new FOLParser(DomainFactory.weaponsDomain());
parser.parse("((Missile(m) AND Owns(Nono,m)) => Sells(West , m ,Nono))");
}
//
// PRIVATE METHODS
//
private Function getBrotherOfFunction(Term t) {
List<Term> l = new ArrayList<Term>();
l.add(t);
return new Function("BrotherOf", l);
}
private Function getEnemyOfFunction() {
List<Term> l = new ArrayList<Term>();
l.add(new Constant("Saladin"));
return new Function("EnemyOf", l);
}
private Function getLegsOfFunction() {
List<Term> l = new ArrayList<Term>();
l.add(new Constant("John"));
l.add(new Constant("Saladin"));
l.add(new Constant("Richard"));
return new Function("LegsOf", l);
}
private Predicate getKingPredicate(Term t) {
List<Term> l = new ArrayList<Term>();
l.add(t);
return new Predicate("King", l);
}
}