org.ggp.base.util.statemachine.FailsafeStateMachine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alloy-ggp-base Show documentation
Show all versions of alloy-ggp-base Show documentation
A modified version of the GGP-Base library for Alloy.
The newest version!
package org.ggp.base.util.statemachine;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ggp.base.util.gdl.grammar.Gdl;
import org.ggp.base.util.gdl.grammar.GdlConstant;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.gdl.grammar.GdlTerm;
import org.ggp.base.util.logging.GamerLogger;
import org.ggp.base.util.propnet.architecture.Component;
import org.ggp.base.util.propnet.architecture.PropNet;
import org.ggp.base.util.statemachine.exceptions.GoalDefinitionException;
import org.ggp.base.util.statemachine.exceptions.MoveDefinitionException;
import org.ggp.base.util.statemachine.exceptions.TransitionDefinitionException;
import org.ggp.base.util.statemachine.implementation.prover.ProverStateMachine;
import com.google.common.collect.ImmutableList;
/**
* The FailsafeStateMachine is a wrapper around a particular state machine.
* It will catch errors/exceptions being thrown from that state machine, and
* fall back to a regular prover if the state machine fails. It's not totally
* clear that this is helpful, but it's an additional layer of bullet-proofing
* in case anything goes wrong.
*
* @author Sam Schreiber
*/
public class FailsafeStateMachine extends StateMachine
{
private StateMachine theBackingMachine = null;
private List gameDescription;
public FailsafeStateMachine (StateMachine theInitialMachine) {
theBackingMachine = theInitialMachine;
}
@Override
public String getName() {
if(theBackingMachine != null) {
return "Failsafe(" + theBackingMachine.getName() + ")";
}
return "Failsafe(null)";
}
@Override
public synchronized void initialize(List description) {
this.gameDescription = description;
if(attemptLoadingInitialMachine())
return;
GamerLogger.logError("StateMachine", "Failsafe Machine: failed to load initial state machine. Falling back...");
if(attemptLoadingProverMachine())
return;
GamerLogger.logError("StateMachine", "Failsafe Machine: catastrophic failure to load *any* state machine. Cannot recover.");
GamerLogger.logError("StateMachine", "Failsafe Machine: cannot recover from current state. Shutting down.");
theBackingMachine = null;
}
private void failGracefully(Exception e1, Error e2) {
if(e1 != null) GamerLogger.logStackTrace("StateMachine", e1);
if(e2 != null) GamerLogger.logStackTrace("StateMachine", e2);
GamerLogger.logError("StateMachine", "Failsafe Machine: graceful failure mode kicking in.");
if(theBackingMachine.getClass() != ProverStateMachine.class) {
GamerLogger.logError("StateMachine", "Failsafe Machine: online failure for " + theBackingMachine.getClass() + ". Attempting to restart with a standard prover.");
if(attemptLoadingProverMachine())
return;
}
theBackingMachine = null;
GamerLogger.logError("StateMachine", "Failsafe Machine: online failure for regular prover. Cannot recover.");
}
private boolean attemptLoadingInitialMachine() {
try {
theBackingMachine.initialize(gameDescription);
GamerLogger.log("StateMachine", "Failsafe Machine: successfully activated initial state machine for use!");
return true;
} catch(Exception e1) {
} catch(ThreadDeath d) {
throw d;
} catch(Error e2) {
}
return false;
}
private boolean attemptLoadingProverMachine() {
try {
StateMachine theStateMachine = new ProverStateMachine();
theStateMachine.initialize(gameDescription);
theBackingMachine = theStateMachine;
GamerLogger.log("StateMachine", "Failsafe Machine: successfully loaded traditional prover.");
return true;
} catch(Exception e1) {
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e2) {
}
return false;
}
@Override
public int getGoal(MachineState state, Role role) throws GoalDefinitionException {
if(theBackingMachine == null)
return 0;
try {
return theBackingMachine.getGoal(state, role);
} catch(GoalDefinitionException ge) {
throw ge;
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getGoal(state, role);
}
@Override
public MachineState getInitialState() {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getInitialState();
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getInitialState();
}
@Override
public List getLegalMoves(MachineState state, Role role) throws MoveDefinitionException {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getLegalMoves(state, role);
} catch(MoveDefinitionException me) {
throw me;
} catch(Exception e) {
failGracefully(e, null);
} catch(OutOfMemoryError e) {
throw e;
} catch(ThreadDeath d) {
throw d;
} catch(Error e) {
failGracefully(null, e);
}
return getLegalMoves(state, role);
}
@Override
public Move getRandomMove(MachineState state, Role role) throws MoveDefinitionException {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getRandomMove(state, role);
} catch(MoveDefinitionException me) {
throw me;
} catch(Exception e) {
failGracefully(e, null);
} catch(OutOfMemoryError e) {
throw e;
} catch(ThreadDeath d) {
throw d;
} catch(Error e) {
failGracefully(null, e);
}
return getRandomMove(state, role);
}
@Override
public MachineState getMachineStateFromSentenceList(Set sentenceList) {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getMachineStateFromSentenceList(sentenceList);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getMachineStateFromSentenceList(sentenceList);
}
@Override
public Move getMoveFromTerm(GdlTerm term) {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getMoveFromTerm(term);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getMoveFromTerm(term);
}
@Override
public MachineState getNextState(MachineState state, List moves) throws TransitionDefinitionException {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getNextState(state, moves);
} catch(TransitionDefinitionException te) {
throw te;
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getNextState(state, moves);
}
@Override
public MachineState getNextStateDestructively(MachineState state, List moves) throws TransitionDefinitionException {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getNextStateDestructively(state, moves);
} catch(TransitionDefinitionException te) {
throw te;
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getNextStateDestructively(state, moves);
}
@Override
public Role getRoleFromConstant(GdlConstant constant) {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getRoleFromConstant(constant);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getRoleFromConstant(constant);
}
@Override
public List getRoles() {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.getRoles();
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getRoles();
}
@Override
public boolean isTerminal(MachineState state) {
if(theBackingMachine == null)
return false;
try {
return theBackingMachine.isTerminal(state);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return isTerminal(state);
}
@Override
public Map getGebMoves(MachineState state) {
if(theBackingMachine == null)
return Collections.emptyMap();
try {
return theBackingMachine.getGebMoves(state);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return getGebMoves(state);
}
@Override
public ImmutableList performDepthCharge(MachineState state, int[] theDepth) throws TransitionDefinitionException, MoveDefinitionException {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.performDepthCharge(state, theDepth);
} catch (TransitionDefinitionException te) {
throw te;
} catch (MoveDefinitionException me) {
throw me;
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return performDepthCharge(state, theDepth);
}
@Override
public void getAverageDiscountedScoresFromRepeatedDepthCharges(MachineState state, double[] avgScores, double[] avgDepth, double discountFactor, int repetitions) throws TransitionDefinitionException, MoveDefinitionException, GoalDefinitionException {
if(theBackingMachine == null)
return;
try {
theBackingMachine.getAverageDiscountedScoresFromRepeatedDepthCharges(state, avgScores, avgDepth, discountFactor, repetitions);
return;
} catch (TransitionDefinitionException te) {
throw te;
} catch (MoveDefinitionException me) {
throw me;
} catch (GoalDefinitionException ge) {
throw ge;
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
getAverageDiscountedScoresFromRepeatedDepthCharges(state, avgScores, avgDepth, discountFactor, repetitions);
}
@Override
public void updateRoot(MachineState theState) {
if(theBackingMachine == null)
return;
try {
theBackingMachine.updateRoot(theState);
return;
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
updateRoot(theState);
}
public StateMachine getBackingMachine() {
return theBackingMachine;
}
@Override
public StateMachine getSynchronizedCopy() {
StateMachine copy = new FailsafeStateMachine(theBackingMachine.getSynchronizedCopy());
copy.initialize(gameDescription);
return copy;
}
@Override
public MachineState translateState(MachineState state) {
if(theBackingMachine == null)
return null;
try {
return theBackingMachine.translateState(state);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return translateState(state);
}
@Override
public boolean isNative(MachineState state) {
if(theBackingMachine == null)
return false;
try {
return theBackingMachine.isNative(state);
} catch(Exception e) {
failGracefully(e, null);
} catch(ThreadDeath d) {
throw d;
} catch(OutOfMemoryError e) {
throw e;
} catch(Error e) {
failGracefully(null, e);
}
return isNative(state);
}
@Override
public boolean isPropNetBased() {
return theBackingMachine.isPropNetBased();
}
@Override
public PropNet getPropNet() {
return theBackingMachine.getPropNet();
}
@Override
public boolean getComponentValue(MachineState state, Component component) {
return theBackingMachine.getComponentValue(state, component);
}
@Override
public int getComponentTrueInputsCount(MachineState state,
Component component) {
return theBackingMachine.getComponentTrueInputsCount(state, component);
}
}