package LBJ2.infer; import LBJ2.learn.Learner; /** * Every propositional variable is Boolean and represents one possible * prediction from a classifier application. If the variable is * <code>true</code>, then the classifier application did result in the * specified prediction value. * * @author Nick Rizzolo **/ public class PropositionalVariable extends PropositionalConstraint { /** The classifier being applied. */ protected Learner classifier; /** The classifier is applied to this example object. */ protected Object example; /** * The prediction that the classifier must produce for this variable to be * <code>true</code>. **/ protected String prediction; /** The value imposed on this variable. */ public boolean value; /** * Initializing constructor; the <code>value</code> member variable is set * to <code>false</code>. * * @param c The classifier being applied. * @param e The classifier is applied to this example object. * @param p The prediction associated with this variable. **/ public PropositionalVariable(Learner c, Object e, String p) { classifier = c; example = e; prediction = p; value = false; } /** * 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) { } /** Retrieves the classifier. */ public Learner getClassifier() { return classifier; } /** Retrieves the example object. */ public Object getExample() { return example; } /** Retrieves the prediction. */ public String getPrediction() { return prediction; } /** Determines whether the constraint is satisfied. */ public boolean evaluate() { return value; } /** * 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 this; } /** * 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 PropositionalNegation(this); } /** * 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 this; } /** * 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 this; } /** * Returns the children of this constraint in an array. * * @return The children of this constraint in an array. **/ public Constraint[] getChildren() { return new PropositionalConstraint[0]; } /** * 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 new PropositionalNegation(this).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>PropositionalVariable</code> is the hash code * of the string representation of the classifier plus the system's hash * code for the example object plus the hash code of the prediction. * * @return The hash code of this <code>PropositionalVariable</code>. **/ public int hashCode() { return classifier.toString().hashCode() + System.identityHashCode(example) + prediction.hashCode(); } /** * Two <code>PropositionalVariable</code>s are equivalent when the string * representations of their classifiers are equivalent, they store the * same example object, and their values are equivalent. * * @param o The object to test equivalence with. * @return <code>true</code> iff this object is equivalent to the argument * object. **/ public boolean equals(Object o) { if (!(o instanceof PropositionalVariable)) return false; PropositionalVariable v = (PropositionalVariable) o; return classifier.equals(v.classifier) && example == v.example && prediction.equals(v.prediction); } /** * 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(classifier); buffer.append("("); buffer.append(example); buffer.append(") :: "); buffer.append(prediction); } }