package LBJ2.infer; import java.util.AbstractMap; import java.util.Collection; import java.util.Iterator; import java.util.Vector; /** * A quantifier is a first order constraint parameterized by an object taken * from a Java <code>Collection</code> of objects. * * @author Nick Rizzolo **/ public abstract class Quantifier extends FirstOrderConstraint { /** The name of the quantification variable. */ protected String quantificationVariable; /** The collection of objects to iterate over. */ protected Collection collection; /** The constraint being quantified. */ protected FirstOrderConstraint constraint; /** * A list of the objects stored in the quantification variables of * enclosing quantifiers. **/ protected Vector enclosingQuantificationSettings; /** * The implementation of the functions that compute any parameters this * quantifier may have. **/ protected QuantifierArgumentReplacer replacer; /** * Initializing constructor. * * @param q The name of the quantification variable. * @param col The collection of objects to iterate over. * @param con The constraint being quantified. **/ public Quantifier(String q, Collection col, FirstOrderConstraint con) { this(q, col, con, null); } /** * This constructor specifies a variable setter for when this quantifier is * itself quantified. * * @param q The name of the quantification variable. * @param col The collection of objects to iterate over. * @param con The constraint being quantified. * @param qar The variable setter. **/ public Quantifier(String q, Collection col, FirstOrderConstraint con, QuantifierArgumentReplacer qar) { quantificationVariable = q; collection = col; constraint = con; replacer = qar; } /** * Returns the children of this constraint in an array. * * @return The children of this constraint in an array. **/ public Constraint[] getChildren() { return new FirstOrderConstraint[]{ constraint }; } /** * Makes sure that the <code>enclosingQuantificationSettings</code> vector * exists, then adds a place holder for this quantifier's quantification * variable setting. * * @return The index of this quantifier's quantification variable. **/ protected int initialize() { if (enclosingQuantificationSettings == null) enclosingQuantificationSettings = new Vector(); enclosingQuantificationSettings.add(null); return enclosingQuantificationSettings.size() - 1; } /** * Sets the variable map object stored in this object to the given * argument; also instantiates all quantified variables and stores them in * the map. * * @param m The map in which to find unique copies of the variables. **/ public void consolidateVariables(AbstractMap m) { int index = initialize(); for (Iterator I = collection.iterator(); I.hasNext(); ) { enclosingQuantificationSettings.set(index, I.next()); constraint.setQuantificationVariables(enclosingQuantificationSettings); constraint.consolidateVariables(m); } enclosingQuantificationSettings.removeElementAt(index); } /** * The hash code of a <code>Quantifier</code> is the sum of the hash codes * of its children plus three. * * @return The hash code for this <code>Quantifier</code>. **/ public int hashCode() { int result = constraint.hashCode(); if (replacer != null) result += replacer.hashCode(); else result += collection.hashCode(); return result; } /** * Two <code>Quantifier</code>s are equivalent when their children are * equivalent. * * @return <code>true</code> iff the argument is an equivalent * <code>Quantifier</code>. **/ public boolean equals(Object o) { if (!(o instanceof Quantifier)) return false; Quantifier q = (Quantifier) o; return replacer == q.replacer && (replacer != null || replacer == null && collection.equals(q.collection)) && constraint.equals(q.constraint); } }