package de.tu_dresden.inf.ggp06_2.resolver; import java.util.ArrayList; import java.util.List; import de.tu_dresden.inf.ggp06_2.resolver.astvisitors.AbstractVisitor; import de.tu_dresden.inf.ggp06_2.resolver.fuzzy.FuzzyResolution; import de.tu_dresden.inf.ggp06_2.resolver.fuzzy.FuzzySubstitution; import de.tu_dresden.inf.ggp06_2.resolver.scope.GameStateScope; import de.tu_dresden.inf.ggp06_2.resolver.scope.RuleScope; import de.tu_dresden.inf.ggp06_2.simulator.flags.TimerFlag; /** * * @author Nick (initial author of JavaProver ) * @author Ingo Keller - General Game Playing course student at TUD * @author Arsen Kostenko - General Game Playing course student at TUD * */ public class Implication extends Expression { protected static final int IMP_HASH_SEED = 2147006989; /* content of the implication */ protected Expression consequence; protected ExpressionList premises; /** * Constructs a implication with an expression as consequence and an * expression list as the premises. * * @param consequence Consequence of the implication * @param premises List of premises is for implication */ public Implication(Expression consequence, ExpressionList premises) { this.consequence = consequence; this.premises = premises; } /** * Some implications could have just one premise. In case of hand-coding * rules such form is much more compact. * * @param consequence Consequence of the implication * @param premise1 Single and only premise */ public Implication(Expression consequence, Expression premise1) { this.consequence = consequence; this.premises = new ExpressionList(); this.premises.add( premise1 ); } /** * Sometimes even two-premise implications happen, and such form also * comes handy in case of hand-coding. * * @param consequence Consequence of the implication * @param premise1 First premise * @param premise2 Second premise */ public Implication(Expression consequence, Expression premise1, Expression premise2) { this.consequence = consequence; this.premises = new ExpressionList(); this.premises.add( premise1 ); this.premises.add( premise2 ); } /** * @return Returns whether the variable var occurs in this implication. */ @Override public boolean isPresent(Variable var) { return consequence.isPresent(var) && premises.isPresent(var); } /** * Implication is equal to another one, only in case * <ol> * <li>They have the same consequence</li> * <li>They also have the same premises</li> * </ol> * Everything else is false * * @param Object to compare to * @return */ @Override public boolean equals(Object obj) { if ( obj instanceof Implication ) { Implication other = (Implication) obj; if ( other.consequence.equals(consequence) ) return ( other.premises.equals(premises) ); } return false; } /** * Following form of string is produced: * <i>"( <= " + consequence + " " + premises + " )"</i> */ @Override public String toString() { return (toString == null) ? toString = "( <= " + consequence + " " + premises + " )" : toString; } /** * @return Returns the consequence of this implication. */ public Expression getConsequence() { return this.consequence; } /** * @return Returns the premises list of this implication. */ public ExpressionList getPremises() { return this.premises; } /** * @return Returns a new implication in which on both parts the substitution sigma * was applied. */ @Override public Expression apply(Substitution sigma) { return new Implication( consequence.apply(sigma), premises.apply(sigma) ); } /** * Simply ask for chaining of premises, which are stored as <code>ExpressionList</code> * * @see de.tu_dresden.inf.ggp06_2.resolver.Expression#chainBody(Substitution, RuleScope, TimerFlag) Expression.chainBody * @see de.tu_dresden.inf.ggp06_2.resolver.ExpressionList#chain(Substitution, RuleScope, TimerFlag) ExpressionList.chain * @param sigma Current state of resolution * @param scope Scope of GDL rules used for resolution * @param flag Timer flag, which is checked before every step of resolution. * @return Returns list of substitutions that were produced during resolution * procedure. * @throws InterruptedException This exception is thrown once time expires during * procedure. */ @Override protected List<Substitution> chainBody( Substitution sigma, RuleScope scope, TimerFlag flag) throws InterruptedException { return premises.chain(sigma, scope, flag); /* boolean proven = ( ( answers != null ) && ( ! answers.isEmpty() ) ); if (proven) return answers; return null; */ } /** * Simply ask for <code>chainOne</code> of premises, which are stored as <code>ExpressionList</code> * * @see de.tu_dresden.inf.ggp06_2.resolver.Expression#chainOneBody(Substitution, RuleScope, TimerFlag) Expression.chainOneBody * @see de.tu_dresden.inf.ggp06_2.resolver.ExpressionList#chainOne(Substitution, RuleScope, TimerFlag) ExpressionList.chainOne * @param sigma Current state of resolution * @param scope Scope of GDL rules used for resolution * @param flag Timer flag, which is checked before every step of resolution. * @return Returns one (first) substitution that was produced during resolution * procedure. * @throws InterruptedException This exception is thrown once time expires during * procedure. */ @Override protected Substitution chainOneBody( Substitution sigma, RuleScope scope, TimerFlag flag ) throws InterruptedException { return premises.chainOne( sigma, scope, flag ); } @Override protected FuzzyResolution fuzzyEvaluateBody( FuzzySubstitution sigma, GameStateScope scope, List<Expression> guard, TimerFlag flag) throws InterruptedException { return premises.fuzzyEvaluate(sigma, scope, guard, flag); } /** * The first operand is everytime the implication atom. */ @Override public Term firstOperand() { return Const.aImpOp; } /** * @return The second operand is the first operand of the consequence. */ @Override public Term secondOperand() { return this.consequence.firstOperand(); } /** * @return Returns all Variables occuring in this implication. */ @Override public List<Variable> getVariables() { List<Variable> allVars = new ArrayList<Variable>(); allVars.addAll( consequence.getVariables() ); allVars.addAll( premises.getVariables() ); return allVars; } /** * @return Returns the most general unification of this implication under * a given substitution. */ @Override public Substitution mgu(Expression target, Substitution sigma) { return target.mgu( consequence.apply(sigma), sigma); } @Override public boolean isGround() { for (Expression exp : premises) if (!exp.isGround()) return false; return true; } @Override public Atom getKeyAtom() { return consequence.getKeyAtom(); } @Override public int getOperandCount() { return consequence.getOperandCount(); } @Override public final void processVisitor(AbstractVisitor visitor) { visitor.visitImplication(this); } }