///////////////////////////////////////////////////////////////////////
// STANFORD LOGIC GROUP //
// General Game Playing Project //
// //
// Sample Player Implementation //
// //
// (c) 2007. See LICENSE and CONTRIBUTORS. //
///////////////////////////////////////////////////////////////////////
/**
*
*/
package stanfordlogic.test.prover;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import stanfordlogic.gdl.GdlExpression;
import stanfordlogic.gdl.GdlList;
import stanfordlogic.gdl.Parser;
import stanfordlogic.gdl.SymbolTable;
import stanfordlogic.knowledge.GameInformation;
import stanfordlogic.knowledge.KnowledgeBase;
import stanfordlogic.knowledge.BasicKB;
import stanfordlogic.knowledge.MetaGdl;
import stanfordlogic.knowledge.RelationNameProcessor;
import stanfordlogic.prover.AbstractReasoner;
import stanfordlogic.prover.BasicReasoner;
import stanfordlogic.prover.Expression;
import stanfordlogic.prover.Fact;
import stanfordlogic.prover.GroundFact;
import stanfordlogic.prover.ProofContext;
import stanfordlogic.prover.Implication;
import stanfordlogic.prover.VariableFact;
import stanfordlogic.game.GameManager;
import junit.framework.TestCase;
/**
*
*/
public class TestProver extends TestCase
{
KnowledgeBase kb_;
SymbolTable symbolTable_;
Parser parser_;
static TestProver currentProver;
public static SymbolTable getTable()
{
return currentProver.symbolTable_;
}
@Override
public void setUp() throws Exception
{
super.setUp();
parser_ = GameManager.getParser();
symbolTable_ = parser_.getSymbolTable();
currentProver = this;
kb_ = new BasicKB();
}
private void addFacts(GdlList facts)
{
for ( GdlExpression exp : facts )
kb_.setTrue( GroundFact.fromExpression(exp) );
}
private GroundFact getAnAnswer( AbstractReasoner r, Fact f )
{
return r.getAnAnswer( f, ProofContext.makeDummy(parser_));
}
private List<GroundFact> getAllAnswers( AbstractReasoner r, Fact f )
{
return r.getAllAnswers(f, ProofContext.makeDummy(parser_));
}
public void testGroundProof()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 3) (succ 3 4)");
addFacts(succs);
AbstractReasoner r = new BasicReasoner(kb_, new ArrayList<Implication>(), parser_ );
// Make sure we can prove all of our ground facts!
GroundFact answer1 = getAnAnswer( r, new GroundFact(symbolTable_, "succ", "1", "2") );
GroundFact answer2 = getAnAnswer( r, new GroundFact(symbolTable_, "succ", "2", "3") );
GroundFact answer3 = getAnAnswer( r, new GroundFact(symbolTable_, "succ", "3", "4") );
assertEquals( new GroundFact(symbolTable_, "succ", "1", "2"), answer1 );
assertEquals( new GroundFact(symbolTable_, "succ", "2", "3"), answer2 );
assertEquals( new GroundFact(symbolTable_, "succ", "3", "4"), answer3 );
}
public void testSingleGroundProofWithVars()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 3) (succ 3 4)");
addFacts(succs);
AbstractReasoner r = new BasicReasoner(kb_, new ArrayList<Implication>(), parser_ );
// See if we can get just one answer
GdlList questionList = parser_.parse("succ ?x 2");
Fact question = VariableFact.fromList(questionList);
GroundFact answer = getAnAnswer( r, question );
assertEquals( new GroundFact(symbolTable_, "succ", "1", "2"), answer);
questionList = parser_.parse("succ ?x 2");
question = VariableFact.fromList(questionList);
answer = getAnAnswer( r, question );
assertNotNull(answer);
assertEquals( new GroundFact(symbolTable_, "succ", "1", "2"), answer);
}
public void testMultiGroundProofWithVars()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 3) (succ 3 4)");
addFacts(succs);
AbstractReasoner r = new BasicReasoner(kb_, new ArrayList<Implication>(), parser_ );
// Now see if we can get *all* answers
GdlList questionList = parser_.parse("succ ?x ?y");
Fact question = VariableFact.fromList(questionList);
List<GroundFact> answers = getAllAnswers( r,question);
assertEquals( 3, answers.size() );
assertEquals( new GroundFact(symbolTable_, "succ", "1", "2"), answers.get(0) );
assertEquals( new GroundFact(symbolTable_, "succ", "2", "3"), answers.get(1) );
assertEquals( new GroundFact(symbolTable_, "succ", "3", "4"), answers.get(2) );
}
public void testGroundProofWithRule()
{
GdlList succs = parser_.parse("(succ 1 2)");
addFacts(succs);
Expression conjunct = GroundFact.fromList( parser_.parse("succ 1 2") );
Implication rule = new Implication( GroundFact.fromList(parser_.parse("gt 2 1")), conjunct);
ArrayList<Implication> rules = new ArrayList<Implication>();
rules.add(rule);
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_ );
// Make sure we can prove all of our ground facts!
GroundFact answer1 = getAnAnswer( r, new GroundFact(symbolTable_, "gt", "2", "1") );
assertEquals( new GroundFact(symbolTable_, "gt", "2", "1"), answer1 );
}
public void testGroundProofWithRuleAndVars()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 2) (succ 1 3)");
addFacts(succs);
Expression conjunct = VariableFact.fromList( parser_.parse("succ 1 ?x") );
Implication rule = new Implication( VariableFact.fromList(parser_.parse("gt ?x 1")), conjunct);
ArrayList<Implication> rules = new ArrayList<Implication>();
rules.add(rule);
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_ );
// Make sure we can prove all of our ground facts!
GroundFact answer1 = getAnAnswer( r, new GroundFact(symbolTable_, "gt", "2", "1") );
assertEquals( new GroundFact(symbolTable_, "gt", "2", "1"), answer1 );
// Do it again just for good measure
answer1 = getAnAnswer( r, new GroundFact(symbolTable_, "gt", "2", "1") );
assertEquals( new GroundFact(symbolTable_, "gt", "2", "1"), answer1 );
}
public void testGroundProofWithRulesAndVars()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 2) (succ 1 3)");
addFacts(succs);
Expression conjunct = VariableFact.fromList( parser_.parse("succ 2 ?x") );
Implication rule = new Implication( VariableFact.fromList(parser_.parse("gt ?x 1")), conjunct);
Expression conjunct2 = VariableFact.fromList( parser_.parse("succ ?y ?x") );
Implication rule2 = new Implication( VariableFact.fromList(parser_.parse("gt ?x ?y")), conjunct2);
ArrayList<Implication> rules = new ArrayList<Implication>();
rules.add(rule);
rules.add(rule2);
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_ );
// Make sure we can prove all of our ground facts!
List<GroundFact> answers = getAllAnswers( r, VariableFact.fromList(parser_.parse("gt ?x ?y")) );
// note: we'll see if we get (gt 2 1) twice
assertEquals( 3, answers.size() );
// Do it again, for good measure
answers = getAllAnswers( r, VariableFact.fromList(parser_.parse("gt ?x ?y")) );
// note: we'll see if we get (gt 2 1) twice
assertEquals( 3, answers.size() );
}
public void testGroundProofWithMultiConjunction()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 2) (succ 1 3) (succ 2 3) (succ 3 2)");
addFacts(succs);
Expression conjunct = VariableFact.fromList( parser_.parse("succ 2 ?x") );
Expression conjunct2 = VariableFact.fromList( parser_.parse("succ ?x 2") );
Implication rule = new Implication( VariableFact.fromList(parser_.parse("gt ?x")), conjunct, conjunct2);
ArrayList<Implication> rules = new ArrayList<Implication>();
rules.add(rule);
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_ );
// Make sure we can prove all of our ground facts!
List<GroundFact> answers = getAllAnswers( r, VariableFact.fromList(parser_.parse("gt ?y")) );
assertEquals( 2, answers.size() );
// Do it again
answers = getAllAnswers( r, VariableFact.fromList(parser_.parse("gt ?y")) );
assertEquals( 2, answers.size() );
}
public void testGroundProofWithLevels()
{
GdlList succs = parser_.parse("(succ 1 2) (succ 2 2) (succ 1 3) (succ 2 3) (succ 3 2) (succ 2 1)");
addFacts(succs);
Expression conjunct = VariableFact.fromList( parser_.parse("succ 2 ?x") );
Expression conjunct2 = VariableFact.fromList( parser_.parse("pop ?x") );
Implication rule = new Implication( VariableFact.fromList(parser_.parse("gt ?x")), conjunct, conjunct2);
Expression conjunct3 = VariableFact.fromList( parser_.parse("succ ?y 2") );
Implication rule2 = new Implication( VariableFact.fromList(parser_.parse("pop ?y")), conjunct3);
ArrayList<Implication> rules = new ArrayList<Implication>();
rules.add(rule);
rules.add(rule2);
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_ );
// Make sure we can prove all of our ground facts!
List<GroundFact> answers = getAllAnswers( r, VariableFact.fromList(parser_.parse("gt ?y")) );
assertEquals( 3, answers.size() );
// Do it again
answers = getAllAnswers( r, VariableFact.fromList(parser_.parse("gt ?y")) );
assertEquals( 3, answers.size() );
}
private List<Implication> getTicTacToeRules() throws IOException
{
return MetaGdl.examineGame("game-defs/tictactoe.kif", parser_).getRules();
}
public void testTicTacToeTerminal() throws IOException
{
List<Implication> rules = getTicTacToeRules();
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_);
GdlList facts = parser_.parse("(true (cell 1 1 b))(true (cell 1 2 b))(true (cell 1 3 b))(true (cell 2 1 b))(true (cell 2 2 b))(true (cell 2 3 b))(true (cell 3 1 b))(true (cell 3 2 b))(true (cell 3 3 b))(true (control xplayer))");
addFacts(facts);
Fact f = getAnAnswer( r, Fact.fromExpression( parser_.parse("terminal") ) );
assertNull(f);
// kb_.clear();
// facts = parser_
// .parse( "(true (cell 1 1 x)) (true (cell 1 2 o)) (true (cell 1 3 x)) (true (cell 2 1 o)) (true (cell 2 2 x)) (true (cell 2 2 x)) (true (cell 2 3 o)) (true (cell 3 1 b)) (true (cell 3 2 b)) (true (cell 3 3 b))" );
// addFacts(facts);
//
// f = getAnAnswer( r, Fact.fromExpression( parser_.parse("terminal") ) );
// assertNull(f);
}
public void testSpecificMove()
{
GameInformation info = MetaGdl.examineGame("game-defs/tictactoe.kif", parser_);
List<Implication> rules = info.getRules();
assertEquals(26, rules.size());
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_);
GdlList facts = parser_.parse( "(true (cell 1 1 x)) (true (cell 1 2 x)) (true (cell 1 3 o)) (true (cell 2 1 x)) (true (cell 2 2 o)) (true (cell 2 3 b)) (true (cell 3 1 o)) (true (cell 3 2 b)) (true (cell 3 3 b)) (true (control xplayer))" );
addFacts(facts);
List<GroundFact> results = getAllAnswers( r, Fact.fromExpression( parser_.parse("legal xplayer ?x") ) );
assertEquals(3, results.size());
}
public void testMoreTicTacToe() throws IOException
{
GameInformation info = MetaGdl.examineGame("game-defs/tictactoe.kif", parser_);
List<Implication> rules = info.getRules();
AbstractReasoner r = new BasicReasoner(kb_, rules, parser_);
GdlList facts = parser_.parse("(true (cell 1 1 x))(true (cell 1 2 o))(true (cell 1 3 x))(true (cell 2 1 o))(true (cell 2 2 x))(true (cell 2 3 b))(true (cell 3 1 b))(true (cell 3 2 b))(true (cell 3 3 b))(true (control oplayer))");
addFacts(facts);
// Get all next facts
GroundFact does = GroundFact.fromExpression( parser_.parse("does xplayer noop") );
GroundFact does2 = GroundFact.fromExpression( parser_.parse("does oplayer (mark 2 3)") );
Fact question = VariableFact.fromExpression( parser_.parse("next ?x") );
KnowledgeBase kb = new BasicKB();
kb.setTrue(does);
kb.setTrue(does2);
ProofContext context = new ProofContext(kb, parser_);
List<GroundFact> results = r.getAllAnswers( question, context );
assertEquals(10, results.size());
}
public void testTicTacToe() throws IOException
{
GameInformation info = MetaGdl.examineGame("game-defs/tictactoe.kif", parser_);
KnowledgeBase staticKb = new BasicKB();
staticKb.loadWithFacts(info.getAllGrounds());
AbstractReasoner r = new BasicReasoner(staticKb, info.getIndexedRules(), parser_);
Fact initQuestion = Fact.fromExpression(parser_.parse("init ?x"));
// Compute the initial state
List<GroundFact> inits = r.getAllAnswers(initQuestion);
KnowledgeBase currentState = new BasicKB();
RelationNameProcessor trueProcessor = new RelationNameProcessor(parser_.TOK_TRUE);
for (GroundFact init: inits) {
currentState.setTrue(trueProcessor.processFact(init));
}
assertEquals(10, currentState.getNumFacts());
GroundFact [] moves;
// Do some updates
moves = new GroundFact [] {
(GroundFact) makeFact("does xplayer (mark 1 1)"),
(GroundFact) makeFact("does oplayer noop"),
};
currentState = updateKbWithMoves(r, currentState, moves);
System.out.println(currentState.stateToGdl());
assertEquals(10, currentState.getNumFacts());
moves = new GroundFact [] {
(GroundFact) makeFact("does xplayer noop"),
(GroundFact) makeFact("does oplayer (mark 1 3)"),
};
currentState = updateKbWithMoves(r, currentState, moves);
System.out.println(currentState.stateToGdl());
assertEquals(10, currentState.getNumFacts());
}
private KnowledgeBase updateKbWithMoves(AbstractReasoner r, KnowledgeBase kb, GroundFact ... moves)
{
for (GroundFact move : moves) {
kb.setTrue(move);
}
Fact nextQuestion = Fact.fromExpression(parser_.parse("next ?x"));
ProofContext context = new ProofContext(kb, parser_);
List<GroundFact> nexts = r.getAllAnswers(nextQuestion, context);
KnowledgeBase newKb = new BasicKB();
RelationNameProcessor trueProcessor = new RelationNameProcessor(parser_.TOK_TRUE);
for (GroundFact next : nexts) {
newKb.setTrue(trueProcessor.processFact(next));
}
return newKb;
}
public void testBigMinichess() throws IOException
{
// Load the rules for mini-chess
GameInformation info = MetaGdl.examineGame("game-defs/minichess.kif", parser_);
KnowledgeBase staticKb = new BasicKB();
staticKb.loadWithFacts( info.getAllGrounds() );
List<Implication> rules = info.getRules();
KnowledgeBase volatileKb = new BasicKB();
AbstractReasoner reasoner = new BasicReasoner(staticKb, rules, parser_);
Fact question = VariableFact.fromList( parser_.parse("init ?x") );
ProofContext context = new ProofContext(volatileKb, parser_);
List<GroundFact> init = reasoner.getAllAnswers( question, context );
// Make sure that we have a cache for all the initial truths
assertEquals( 18, init.size() );
RelationNameProcessor processor = new RelationNameProcessor(parser_.TOK_TRUE);
for ( GroundFact f : init )
volatileKb.setTrue ( processor.processFact(f) );
// Find out how many legal moves there are
List<GroundFact> legal = reasoner.getAllAnswers( makeFact( "legal white ?x" ),
context );
// Make sure there's the right amount of legal moves
assertEquals( 7, legal.size() );
// Is the game terminal?
assertNull( reasoner.getAnAnswer( makeFact( "terminal" ), context ) );
// Make some move
GroundFact does1 = (GroundFact) makeFact( "does white (move wk c 1 c 2)" );
GroundFact does2 = (GroundFact) makeFact( "does black noop" );
volatileKb.setTrue( does1 );
volatileKb.setTrue( does2 );
// Find the next state.
List<GroundFact> nextTruths = reasoner.getAllAnswers( makeFact( "next ?x" ),
context );
assertEquals( 18, nextTruths.size() );
}
public void testChessLegalMoves()
{
// Load the rules for chess
GameInformation info = MetaGdl.examineGame("game-defs/chess.kif", parser_);
KnowledgeBase staticKb = new BasicKB();
staticKb.loadWithFacts( info.getAllGrounds() );
List<Implication> rules = info.getRules();
KnowledgeBase volatileKb = new BasicKB();
AbstractReasoner reasoner = new BasicReasoner(staticKb, rules, parser_);
Fact question = VariableFact.fromList( parser_.parse("init ?x") );
ProofContext context = new ProofContext(volatileKb, parser_);
List<GroundFact> init = reasoner.getAllAnswers( question, context );
assertEquals(66, init.size());
RelationNameProcessor processor = new RelationNameProcessor(parser_.TOK_TRUE);
for ( GroundFact f : init )
volatileKb.setTrue ( processor.processFact(f) );
// Find out how many legal moves there are
List<GroundFact> legal = reasoner.getAllAnswers( makeFact( "legal white ?x" ),
context );
// Make sure there's the right amount of legal moves
assertEquals( 20, legal.size() );
}
private Fact makeFact(String str)
{
return Fact.fromExpression( parser_.parse(str) );
}
}