///////////////////////////////////////////////////////////////////////
// STANFORD LOGIC GROUP //
// General Game Playing Project //
// //
// Sample Player Implementation //
// //
// (c) 2007. See LICENSE and CONTRIBUTORS. //
///////////////////////////////////////////////////////////////////////
/**
*
*/
package stanfordlogic.prover;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import stanfordlogic.gdl.SymbolTable;
/**
* An implication states that its <i>head</i> (consequent) is true when the
* <i>antecedents</i> are true.
*/
public class Implication extends Expression
{
private final Fact consequent_;
private final Conjunction antecedents_;
private static final Logger logger_ = Logger.getLogger("stanfordlogic.prover");
final static private Conjunction EMPTY_ANTECEDENTS = new Conjunction();
public Implication(Fact head, Expression ... conjuncts )
{
this(true, head, conjuncts);
}
public Implication(boolean clone, Fact head, Expression ... conjuncts)
{
consequent_ = head;
if ( conjuncts == null )
antecedents_ = EMPTY_ANTECEDENTS;
else
antecedents_ = new Conjunction(clone, conjuncts);
}
public Implication(Fact head, Conjunction conjuncts)
{
consequent_ = head;
if ( conjuncts == null )
antecedents_ = EMPTY_ANTECEDENTS;
else
antecedents_ = conjuncts;
}
/**
* Can this rule apply to a fact? True if the rule's consequent has the same
* fact name and the same arity. Note that a rule can apply to fact, without
* being unifiable with it.
*
* @param f The fact to check application for.
* @return True if this rule applies to the fact.
*/
public boolean canApplyTo(Fact f)
{
return consequent_.relationName_ == f.relationName_
&& consequent_.getArity() == f.getArity();
}
public Fact getConsequent()
{
return consequent_;
}
public Conjunction getAntecedents()
{
return antecedents_;
}
public int numAntecedents()
{
return antecedents_.numConjuncts();
}
public Implication uniquefy()
{
Map<TermVariable, TermVariable> varMap = new HashMap<TermVariable, TermVariable>();
Fact newHead = (Fact) consequent_.uniquefy(varMap);
Conjunction newConjuncts = (Conjunction) antecedents_.uniquefy(varMap);
return new Implication(newHead, newConjuncts);
}
@Override
public Expression applySubstitution(Substitution sigma)
{
Fact newHead = consequent_.applySubstitution(sigma);
Conjunction newConjuncts = antecedents_.applySubstitution(sigma);
return new Implication(false, newHead, newConjuncts);
}
@Override
public boolean canMapVariables(Expression other)
{
if (other instanceof Implication == false) {
return false;
}
Implication impl = (Implication) other;
if (impl.consequent_.relationName_ != consequent_.relationName_) {
return false;
}
if (impl.antecedents_.numConjuncts() != antecedents_.numConjuncts()) {
return false;
}
Map<TermVariable, TermVariable> varMappings = new HashMap<TermVariable, TermVariable>();
// First, check the heads' terms
for (int i = 0; i < consequent_.getArity(); i++)
{
Term t1 = consequent_.getTerm(i);
Term t2 = impl.consequent_.getTerm(i);
if ( t1.canMapVariables(t2, varMappings) == false )
return false;
}
// TODO: implement the rest of Implication.canMapVariables
// (we don't actually need to use this, I think)
logger_.severe("WARNING: Implication.canMapVariables not implemented");
return false;
}
@Override
public boolean hasTermFunction(int functionName)
{
if (consequent_.hasTermFunction(functionName)) {
return true;
}
for (Expression exp: antecedents_.getConjuncts()) {
if (exp.hasTermFunction(functionName)) {
return true;
}
}
return false;
}
@Override
public boolean hasTermVariable(int varName)
{
if (consequent_.hasTermVariable(varName)) {
return true;
}
for (Expression exp: antecedents_.getConjuncts()) {
if (exp.hasTermVariable(varName)) {
return true;
}
}
return false;
}
@Override
public void printToStream(PrintStream target, SymbolTable symtab)
{
target.print("(<= ");
consequent_.printToStream(target, symtab);
target.print(" ");
antecedents_.printToStream(target, symtab);
target.print(")");
}
@Override
public Expression uniquefy(Map<TermVariable, TermVariable> varMap)
{
Fact newHead = consequent_.uniquefy(varMap);
Conjunction newConjuncts = antecedents_.uniquefy(varMap);
return new Implication(false, newHead, newConjuncts);
}
}