package aima.logic; import java.util.Hashtable; /** * The HashBindings class implements the Bindings interface * using a Hashtable. * *

* Note: This implementation may not be appropriate for the various * theorem provers which need an implementation of Bindings * that allow bindings to be cheaply extended in several different * directions. For that, consider using ListBindings. * * @author Michael S. Braverman * @see ListBindings */ public class HashBindings implements Bindings { /** * Obtains the Failure (representing no consistent Bindings) * object. * * @return The failure bindings object. * */ public Bindings getFailure() { return FAILURE; } /** * Obtains the Empty (representing no current bindings) object. * * @return The empty bindings object. * */ static public Bindings getEmpty() { return EMPTYBINDINGS; } /** * Determine if the given Variable is currently bound. * * @return true iff the Variable is bound. * @param var The variable to check. */ public boolean isBound(Variable var) { return (getBinding(var) != null); } /** * Determine if this HashBindings object represents the * Empty (no current bindings) object. * * @return true iff this object is the Empty bindings object. */ public boolean isEmpty() { return (this == EMPTYBINDINGS); } /** * Determine if this HashBindings object represents the * Failure (no consistent bindings) object. * * @return true iff this object is the Failure bindings object. */ public boolean isFailure() { return (this == FAILURE); } /** * Get the current binding of the given Variable. * * @return The value associated with the variable. * @param var The variable to look up. */ public Object getBinding(Variable var) { return theTable.get(var); } /** * Extends this HashBindings object with an association between * the given Variable and value. * *

* Note: This method changes the HashBindings * object on which it is invoked. This is fine, and efficient, for * simple unification applications, but will not work well for the * various theorem provers which may want to share a * Bindings instance (or part thereof) among many lines * of of reasoning. Instead, consider using a * ListBindings instance to manage * Bindings for such applications. * * @return An extended HashBindings object. * @param var The variable to bind. * @param val The value to which the Variable is to be bound. * @see ListBindings */ public Bindings extendBindings (Variable var, Object val) { HashBindings result = this; if (this == EMPTYBINDINGS) { result = new HashBindings(); } result.theTable.put(var,val); return result; } /** * Returns a String representation of this object. * * @return a String representation of this object. */ public String toString () { if (this == EMPTYBINDINGS) { return "[Bindings Empty]"; } else if (this == FAILURE) { return "[Bindings *FAILURE*]"; } else { return "[Bindings: "+ theTable.toString() +"]"; } } /** * Placeholder (private) so one can not create their own * HashBindings, and must instead start with the initial * bindings returned by getEmpty and extend from there. * * @see getEmpty */ private HashBindings() { theTable = new Hashtable(); } /** * Contains the Hashtable object the actually stores * the Variable bindings. */ private Hashtable theTable; /** * Indicates an empty set of bindings (indicating unification * success, with no variables) */ /* (defconstant +no-bindings+ '((nil)) "Indicates unification success, with no variables.") */ static private Bindings EMPTYBINDINGS = new HashBindings(); /** * Indicates no consistent binding (unification failure). * * @see getFailure() */ /* (defconstant +fail+ nil "Indicates unification failure") */ static private Bindings FAILURE = new HashBindings(); /** * Tests out the functionality of this class. * @param args Ignored. */ static public void main(String [] args) { System.err.println(FAILURE); System.err.println(EMPTYBINDINGS); Bindings b = HashBindings.getEmpty(); // test to make sure that variables with the same base name // (but maybe represented by different Variable instances) // refer to the same variable in the Bindings object. // (We need want this to be the case since it is difficult // to intern Variables, so we allow two Variables that just // "look alike" to be the same variable with respect to // the Bindings object) // Note that since this is a HashBindings object, only the final // bound value of a given variable will be present in the // final Bindings (compare with ListBindings) b = b.extendBindings(new Variable("x"), new Integer(1)); b = b.extendBindings(new Variable("y"), new Integer(2)); b = b.extendBindings(new Variable("y"), new Integer(3)); b = b.extendBindings(new Variable("y"), new Integer(4)); b = b.extendBindings(new Variable("z"), new Integer(5)); b = b.extendBindings(new Variable("x"), new Integer(5)); System.err.println(b); } }