package aima.logic;

/**
 * The Bindings interface is the basis for associating individual 
 * <code>Variable</code>s with arbitrary JAVA <code>Object</code> values.
 *
 * <p>
 * It is expected that in addition to the dynamic methods required by
 * this interface, each implementation will also define a static
 * method <code>getEmpty()</code> which will return a unique object
 * representing a <code>Bindings</code> instance that contains no
 * actual <code>Variable</code> bindings.
 *
 * @author Michael S. Braverman
 * @see Variable
 */

public interface Bindings {
  /**
   * Obtains the Failure (representing no consistent <code>Bindings</code>)
   * object.
   *
   * @return The failure bindings object.
   *
   */
  public Bindings getFailure();

  /**
   * Determine if this <code>Bindings</code> object represents the
   * Failure (no consistent bindings) object.
   *
   * @return true iff this object is the Failure bindings object.
   */
  public boolean isFailure();

  /**
   * Determine if this <code>Bindings</code> object represents the
   * Empty (no current bindings) object.
   *
   * <p>
   * It is expected that all implementations of the <code>Bindings</code>
   * interface will provide a static method <code>getEmpty()</code> which
   * will return a unique (to the particular implementation) object
   * representing a <code>Bindings</code> instance that contains no actual
   * <code>Variable</code> bindings.
   * This <code>isEmpty</code> predicate is intended to test for that 
   * unique (to the implementation) object.
   *
   * @return true iff this object is the Empty bindings object.
   */
  public boolean isEmpty();

  /**
   * Determine if the given <code>Variable</code> is currently bound.
   *
   * @return true iff the <code>Variable</code> is bound.
   * @param var The variable to check.
   */
  public boolean isBound(Variable var);

  /**
   * Get the current binding of the given <code>Variable</code>.
   *
   * @return The value associated with the variable.
   * @param var The variable to look up.
   */
  public Object getBinding(Variable var);

  /**
   * Extends this <code>Bindings</code> object with an association between
   * the given <code>Variable</code> and value.
   *
   * <p>
   * Note:
   * A particular implementation is allowed, though not required, to change
   * the <code>Bindings</code> object on which it is invoked if the variable
   * is already bound in the <code>Bindings</code> object.
   *
   * @return An extended <code>Bindings</code> object.
   * @param var The variable to bind.
   * @param val The value to which the <code>Variable</code> is to be bound.
   */
   public Bindings extendBindings (Variable var, Object val);

}