package util.statemachine.implementation.prover;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import util.gdl.grammar.Gdl;
import util.gdl.grammar.GdlConstant;
import util.gdl.grammar.GdlProposition;
import util.gdl.grammar.GdlRelation;
import util.gdl.grammar.GdlSentence;
import util.logging.GamerLogger;
import util.prover.Prover;
import util.prover.aima.AimaProver;
import util.statemachine.MachineState;
import util.statemachine.Move;
import util.statemachine.Role;
import util.statemachine.StateMachine;
import util.statemachine.exceptions.GoalDefinitionException;
import util.statemachine.exceptions.MoveDefinitionException;
import util.statemachine.exceptions.TransitionDefinitionException;
import util.statemachine.implementation.prover.query.ProverQueryBuilder;
import util.statemachine.implementation.prover.result.ProverResultParser;
public class ProverStateMachine extends StateMachine
{
private MachineState initialState;
private Prover prover;
private List<Role> roles;
/**
* Initialize must be called before using the StateMachine
*/
public ProverStateMachine()
{
}
public void initialize(List<Gdl> description)
{
prover = new AimaProver(new HashSet<Gdl>(description));
roles = Role.computeRoles(description);
initialState = computeInitialState();
}
private MachineState computeInitialState()
{
Set<GdlSentence> results = prover.askAll(ProverQueryBuilder.getInitQuery(), new HashSet<GdlSentence>());
return new ProverResultParser().toState(results);
}
@Override
public int getGoal(MachineState state, Role role) throws GoalDefinitionException
{
Set<GdlSentence> results = prover.askAll(ProverQueryBuilder.getGoalQuery(role), ProverQueryBuilder.getContext(state));
if (results.size() != 1)
{
GamerLogger.logError("StateMachine", "Got goal results of size: " + results.size() + " when expecting size one.");
throw new GoalDefinitionException(state, role);
}
try
{
GdlRelation relation = (GdlRelation) results.iterator().next();
GdlConstant constant = (GdlConstant) relation.get(1);
return Integer.parseInt(constant.toString());
}
catch (Exception e)
{
throw new GoalDefinitionException(state, role);
}
}
@Override
public MachineState getInitialState()
{
return initialState;
}
@Override
public List<Move> getLegalMoves(MachineState state, Role role) throws MoveDefinitionException
{
Set<GdlSentence> results = prover.askAll(ProverQueryBuilder.getLegalQuery(role), ProverQueryBuilder.getContext(state));
if (results.size() == 0)
{
throw new MoveDefinitionException(state, role);
}
return new ProverResultParser().toMoves(results);
}
@Override
public MachineState getNextState(MachineState state, List<Move> moves) throws TransitionDefinitionException
{
Set<GdlSentence> results = prover.askAll(ProverQueryBuilder.getNextQuery(), ProverQueryBuilder.getContext(state, getRoles(), moves));
for (GdlSentence sentence : results)
{
if (!sentence.isGround())
{
throw new TransitionDefinitionException(state, moves);
}
}
return new ProverResultParser().toState(results);
}
@Override
public List<Role> getRoles()
{
return roles;
}
@Override
public boolean isTerminal(MachineState state)
{
return prover.prove(ProverQueryBuilder.getTerminalQuery(), ProverQueryBuilder.getContext(state));
}
@Override
public MachineState getMachineStateFromSentenceList(Set<GdlSentence> sentenceList) {
return new ProverMachineState(sentenceList);
}
@Override
public Move getMoveFromSentence(GdlSentence sentence) {
return new ProverMove(sentence);
}
@Override
public Role getRoleFromProp(GdlProposition proposition) {
return new ProverRole(proposition);
}
}