package LBJ2.infer;
import java.util.LinkedHashMap;
import LBJ2.learn.IdentityNormalizer;
import LBJ2.learn.Learner;
import LBJ2.learn.Normalizer;
/**
* An object of this class keeps track of all the information necessary to
* perform inference. Once that inference has been performed, constrained
* classifiers access the results through this class's interface to determine
* what their constrained predictions are.
*
* @author Nick Rizzolo
**/
public abstract class Inference
{
/**
* Produces a string representation of an example object. This method is
* used mainly for debugging messages.
*
* @param example The example object, which may be an array.
* @return A string representation of <code>example</code>.
**/
public static String exampleToString(Object example) {
String result = "";
if (example instanceof Object[]) {
Object[] array = (Object[]) example;
result += "[";
if (array.length > 0) result += array[0];
for (int k = 1; k < array.length; ++k) result += ", " + array[k];
result += "]";
}
else result += example;
return result;
}
/**
* The values of this map are the variables we perform inference over; they
* are the actual <code>FirstOrderVariable</code> objects found in this
* inference's constraints. The keys are also objects of type
* <code>FirstOrderVariable</code>, but they are not necessarily the actual
* objects found in the constraints. This map is populated by the first
* evaluation of the constraints.
**/
protected LinkedHashMap variables;
/** The constraints which must be satisfied by the inference algorithm. */
protected Constraint constraint;
/** Objects of this class are differentiated by their "head" objects. */
protected Object head;
/** Default constructor. */
public Inference() { this(null); }
/**
* Initializes the head object.
*
* @param h The head object.
**/
public Inference(Object h) {
head = h;
variables = new LinkedHashMap();
}
/** Retrieves the head object. */
public Object getHead() { return head; }
/**
* Derived classes implement this method to perform the inference, setting
* the values of the variables such that they maximize the objective
* function while satisfying the constraints. When implementing this
* method in a derived class <code>Foo</code>, it may be assumed that the
* <code>constraint</code> member field has already been filled in
* appropriately, since the LBJ compiler will generate a class extending
* <code>Foo</code> whose constructor does so.
**/
abstract protected void infer() throws Exception;
/**
* Retrieves the value of the specified variable as identified by the
* classifier and the object that produce that variable.
*
* @param c The classifier producing the variable.
* @param o The object from which the variable is produced.
* @return The current value of the requested variable.
**/
abstract public String valueOf(Learner c, Object o) throws Exception;
/**
* Returns the normalization function associated with the given classifier
* in this inference. Derived classes that implement an inference
* algorithm for use in an LBJ source file are required to call this method
* to normalize the scores produced by classifiers before making use of
* those scores. By default, this method returns the
* <code>IdentityNormalizer</code>.
*
* @param c The classifier.
* @return The normalization function associated with the classifier.
**/
public Normalizer getNormalizer(Learner c) {
return new IdentityNormalizer();
}
/**
* Returns the fully qualified name of the type of the head object for this
* inference. By default, this method returns
* <code>"java.lang.Object"</code>. It should be overridden by derived
* classes.
**/
public String getHeadType() { return "java.lang.Object"; }
/**
* Returns the fully qualified names of the types of objects for which head
* finder methods have been defined. This method must be overridden by
* derived classes, since by default it returns a 0-length array and every
* <code>Inference</code> is required to have at least one head finder.
* <code>Inference</code> classes written by the compiler automatically
* override this method appropriately.
**/
public String[] getHeadFinderTypes() { return new String[0]; }
/**
* Determines if the constraints are satisfied by the current variable
* assignments.
**/
public boolean satisfied() { return constraint.evaluate(); }
/**
* Retrieves the requested variable, creating it first if it doesn't yet
* exist.
*
* @param v A variable containing the same classifier, object, and
* prediction value as the desired variable.
* @return The Boolean variable corresponding to the event
* <i>classifier(object) == prediction</i>.
**/
public PropositionalVariable getVariable(PropositionalVariable v) {
PropositionalVariable variable = (PropositionalVariable) variables.get(v);
if (variable == null) {
variable = (PropositionalVariable) v.clone();
variables.put(variable, variable);
}
return variable;
}
/**
* Retrieves the requested variable, creating it first if it doesn't yet
* exist.
*
* @param v A variable containing the same classifier and object as the
* desired variable.
* @return The variable corresponding to the application of the classifier
* on the object.
**/
public FirstOrderVariable getVariable(FirstOrderVariable v) {
FirstOrderVariable variable = (FirstOrderVariable) variables.get(v);
if (variable == null) {
variable = (FirstOrderVariable) v.clone();
variables.put(variable, variable);
}
return variable;
}
/**
* The default method for visiting a constraint simply visits that
* constraint's children.
**/
public void visitAll(Constraint c) {
Constraint[] children = c.getChildren();
for (int i = 0; i < children.length; ++i) children[i].runVisit(this);
}
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderDoubleImplication c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderImplication c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderConjunction c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderDisjunction c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderEqualityTwoValues c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderEqualityWithValue c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderEqualityWithVariable c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderNegation c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(FirstOrderConstant c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(UniversalQuantifier c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(ExistentialQuantifier c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(AtLeastQuantifier c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(AtMostQuantifier c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(QuantifiedConstraintInvocation c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalDoubleImplication c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalImplication c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalConjunction c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalDisjunction c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalAtLeast c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalConstant c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalNegation c) { visitAll(c); }
/**
* Derived classes override this method to do some type of processing on
* constraints of the parameter's type.
*
* @param c The constraint to process.
**/
public void visit(PropositionalVariable c) { visitAll(c); }
}