package LBJ2.infer; /** * Represents the negation operator applied to a propositional constraint. * * @author Nick Rizzolo **/ public class PropositionalNegation extends PropositionalConstraint { /** The constraint that the negation is applied to. */ protected PropositionalConstraint constraint; /** * Initializing constructor. * * @param c The constraint to negate. **/ public PropositionalNegation(PropositionalConstraint c) { constraint = c; } /** * Replaces all unquantified variables with the unique copy stored as a * value of the given map; also instantiates all quantified variables and * stores them in the given map. * * @param m The map in which to find unique copies of the variables. **/ public void consolidateVariables(java.util.AbstractMap m) { if (constraint instanceof PropositionalVariable) { if (m.containsKey(constraint)) constraint = (PropositionalVariable) m.get(constraint); else m.put(constraint, constraint); } else constraint.consolidateVariables(m); } /** Determines whether the constraint is satisfied. */ public boolean evaluate() { return !constraint.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() { if (constraint instanceof PropositionalVariable) return this; return constraint.negate().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 constraint; } /** * 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() { PropositionalConstraint simplified = simplify(); if (simplified instanceof PropositionalNegation) return simplified; return simplified.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() { PropositionalConstraint simplified = simplify(); if (simplified instanceof PropositionalNegation) return simplified; return simplified.DNF(); } /** * Returns the children of this constraint in an array. * * @return The children of this constraint in an array. **/ public Constraint[] getChildren() { return new PropositionalConstraint[]{ constraint }; } /** * 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) { PropositionalConstraint[] children = (PropositionalConstraint[]) c.getChildren(); return constraint.equals(children[0]) || equals(children[1]); } /** * 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.size() > 1 && 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>PropositionalNegation</code> is the hash code * of its child constraint plus 1. * * @return The hash code for this <code>PropositionalNegation</code>. **/ public int hashCode() { return constraint.hashCode() + 1; } /** * Two <code>PropositionalNegation</code>s are equivalent when their * constraints are equivalent. * * @return <code>true</code> iff the argument is a * <code>PropositionalNegation</code> of the same constraint. **/ public boolean equals(Object o) { if (!(o instanceof PropositionalNegation)) return false; PropositionalNegation n = (PropositionalNegation) o; return constraint.equals(n.constraint); } /** * 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("!"); constraint.write(buffer); } }