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);
}
}