package LBJ2.infer;
/**
* Represents an implication between two propositional constraints.
*
* @author Nick Rizzolo
**/
public class PropositionalImplication extends PropositionalBinaryConstraint
{
/**
* Initializing constructor.
*
* @param l The constraint on the left of the operator.
* @param r The constraint on the right of the operator.
**/
public PropositionalImplication(PropositionalConstraint l,
PropositionalConstraint r) {
super(l, r);
}
/** Determines whether the constraint is satisfied. */
public boolean evaluate() { return !left.evaluate() || right.evaluate(); }
/**
* Produces a new, logically simplified version of this constraint,
* preserving variable consolidation.
*
* @see Constraint#consolidateVariables(java.util.AbstractMap)
* @return A logically simplified version of this constraint.
**/
public PropositionalConstraint simplify() {
return new PropositionalDisjunction(left.negate(), right).simplify();
}
/**
* Produces a new propositional constraint equivalent to this constraint
* and that contains no negated constraints other than variables.
*
* @return A constraint representing the negation of this constraint.
**/
public PropositionalConstraint negate() {
return new PropositionalConjunction(left, right.negate());
}
/**
* Produces a new, logically simplified version of this constraint in
* conjunctive normal form (CNF).
*
* @return The conjunctive normal form of this constraint.
**/
public PropositionalConstraint CNF() {
return
new PropositionalDisjunction(new PropositionalNegation(left), right)
.CNF();
}
/**
* Produces a new, logically simplified version of this constraint in
* disjunctive normal form (DNF).
*
* @return The disjunctive normal form of this constraint.
**/
public PropositionalConstraint DNF() {
return
new PropositionalDisjunction(new PropositionalNegation(left), right)
.DNF();
}
/**
* Compares topology to determine if this constraint is more general than
* the given constraint; <i>note: this method is not required to be correct
* when it answers <code>false</code></i>.
*
* @param c The given constraint.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more general than the given constraint.
**/
public boolean moreGeneralThan(PropositionalConstraint c) {
return c.moreSpecificThan(this);
}
/**
* Compares topology to determine if this constraint is more specific than
* the given implication; <i>note: this method is not required to be
* correct when it answers <code>false</code></i>.
*
* @param c The given implication.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given implication.
**/
public boolean moreSpecificThan(PropositionalImplication c) {
return false;
}
/**
* Compares topology to determine if this constraint is more specific than
* the given double implication; <i>note: this method is not required to be
* correct when it answers <code>false</code></i>.
*
* @param c The given double implication.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given double implication.
**/
public boolean moreSpecificThan(PropositionalDoubleImplication c) {
return false;
}
/**
* Compares topology to determine if this constraint is more specific than
* the given conjunction; <i>note: this method is not required to be
* correct when it answers <code>false</code></i>.
*
* @param c The given conjunction.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given conjunction.
**/
public boolean moreSpecificThan(PropositionalConjunction c) {
return false;
}
/**
* Compares topology to determine if this constraint is more specific than
* the given disjunction; <i>note: this method is not required to be
* correct when it answers <code>false</code></i>.
*
* @param c The given disjunction.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given disjunction.
**/
public boolean moreSpecificThan(PropositionalDisjunction c) {
return c.contains(new PropositionalNegation(left)) && c.contains(right)
|| c.contains(this);
}
/**
* Compares topology to determine if this constraint is more specific than
* the given at-least; <i>note: this method is not required to be correct
* when it answers <code>false</code></i>.
*
* @param c The given at-least.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given disjunction.
**/
public boolean moreSpecificThan(PropositionalAtLeast c) {
return false;
}
/**
* Compares topology to determine if this constraint is more specific than
* the given negation; <i>note: this method is not required to be correct
* when it answers <code>false</code></i>.
*
* @param c The given negation.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given negation.
**/
public boolean moreSpecificThan(PropositionalNegation c) { return false; }
/**
* Compares topology to determine if this constraint is more specific than
* the given variable; <i>note: this method is not required to be correct
* when it answers <code>false</code></i>.
*
* @param c The given variable.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given variable.
**/
public boolean moreSpecificThan(PropositionalVariable c) { return false; }
/**
* Compares topology to determine if this constraint is more specific than
* the given constant; <i>note: this method is not required to be correct
* when it answers <code>false</code></i>.
*
* @param c The given constant.
* @return <code>true</code> if a topological analysis determined that this
* constraint is more specific than the given constant.
**/
public boolean moreSpecificThan(PropositionalConstant c) {
return c.evaluate();
}
/**
* The hash code of a <code>PropositionalImplication</code> is the sum of
* the hash codes of its children plus two.
*
* @return The hash code for this <code>PropositionalImplication</code>.
**/
public int hashCode() { return left.hashCode() + right.hashCode() + 2; }
/**
* Two <code>PropositionalImplication</code>s are equivalent when they are
* topologically equivalent.
*
* @return <code>true</code> iff the argument is an equivalent
* <code>PropositionalImplication</code>.
**/
public boolean equals(Object o) {
if (!(o instanceof PropositionalImplication)) return false;
PropositionalImplication i = (PropositionalImplication) o;
return left.equals(i.left) && right.equals(i.right);
}
/**
* Calls the appropriate <code>visit(·)</code> method of the given
* <code>Inference</code> for this <code>Constraint</code>, as per the
* visitor pattern.
*
* @param infer The inference visiting this constraint.
**/
public void runVisit(Inference infer) { infer.visit(this); }
/**
* Creates a string respresentation of this constraint using the string
* representations of the objects involved.
*
* @param buffer The output of this method will be appended to this buffer.
**/
public void write(StringBuffer buffer) {
buffer.append("(");
left.write(buffer);
buffer.append(" => ");
right.write(buffer);
buffer.append(")");
}
}