/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.constraint.xnative; import java.io.Serializable; import java.util.Collections; import java.util.List; import x10.constraint.XTerm; import x10.constraint.XVar; /** * Constraints constrain XTerms. Thus XTerms are the basic building blocks * of constraints.This class is the root class of constraint terms. * Class should not have any state. * * @author njnystrom * @author vj * */ public abstract class XNativeTerm implements XTerm, Serializable, Cloneable { private static final long serialVersionUID = -3094676101576926720L; public XNativeTerm() {super();} // The default is OBJECT. May be overridden by subclasses. public XTermKind kind() { return XTermKind.OBJECT;} /** * Return the result of substituting the term y for x in this. * Should be overridden in subtypes. * @param y * @param x * @return */ @Override public XNativeTerm subst(XTerm y, XVar x) { return subst(y, x, true); } /** * Returns true only if this term is allowed to occur inside a constraint. * Terms a&&b, a||b, a==b etc must return false. * @return */ @Override public abstract boolean okAsNestedTerm(); // int nextId = 0; /** * Return the result of substituting y for x in this. * * @param y -- * the value to be substituted * @param x -- * the variable which is being substituted for * @return the term with the substitution applied */ public XNativeTerm subst(XTerm y, final XVar x, boolean propagate) { XNativeTerm t = this; return t; } @Override public XNativeTerm clone() { try { XNativeTerm n = (XNativeTerm) super.clone(); return n; } catch (CloneNotSupportedException e) { return this; } } /** * Does this contain an existentially quantified variable? * Default no; should be overridden by subclasses representing eqvs. * @return true if it is, false if it isn't. */ @Override public boolean hasEQV() {return false;} /** * Is this itself an EQV? * Default no; should be overridden by subclasses representing eqvs. * @return */ public boolean isEQV() {return false;} public List<XNativeEQV> eqvs() {return Collections.emptyList();} /** * Is <code>this</code> a prefix of <code>term</code>, i.e. is * <code>term</code> of the form <code>this.f1...fn</code>? * Default no; should be overridden by subclasses. * @return */ /*public boolean prefixes(XTerm term) { return false; }*/ public static final int TERM_MUST_NOT_BE_BOUND=-1; public static final int TERM_PREFERS_BEING_BOUND=1; public static final int TERM_SHRUGS_ABOUT_BEING_BOUND=0; /** * 0 == dont care, bind me if you want * -1 == must not bind me! * If true, bind this variable when processing this=t, for * any term t. In case t also prefers being bound, choose any * one. * * @return true if this prefers being bound in a constraint this==t. */ public int prefersBeingBound() {return TERM_SHRUGS_ABOUT_BEING_BOUND;} /** * Returns true if this term is an atomic formula. * == constraints are represented specially, and not considered atomic formulas. * * @return true -- if this term represents an atomic formula */ @Override public boolean isAtomicFormula() {return false;} /** * Returns true if the variable v occurs in this term. * @param v -- the variable being checked. * @return true if v occurs in this */ @Override public boolean hasVar(XVar v) {return true;} /** Intern this term into constraint and return the promise representing the term. <p> Throw an XFailure if the resulting constraint is inconsistent. */ abstract XPromise internIntoConstraint(XNativeConstraint constraint, XPromise last); @Override public abstract int hashCode(); @Override public abstract boolean equals(Object o); /** * Given a visitor, we traverse the entire term (which is like a tree). * @param visitor * @return If the visitor didn't return any new child, then we return "this" * (otherwise we create a clone with the new children) */ @Override public XNativeTerm accept(TermVisitor visitor) { // The default implementation for "leave" terms (that do not have any children) XNativeTerm res = (XNativeTerm)visitor.visit(this); if (res!=null) return res; return this; } /** * Return the normal form for this term in this given constraint. * The normal form of a term t in a constraint c, t.nf(c), is a term * s with the property that * for all u: s=u.nf(c) iff c |- s=u * From this it follows that s=s.nf(c). * The normal form is computed as nfp(c).term(). * @param c * @return */ public final XNativeTerm nf(XNativeConstraint c) { assert c != null; return nfp(c).term(); } /** * Return the promise corresponding to the normal form of the term, * interning the term if it is not interned already. * If p is the return value, then guaranteed p!= null and p=p.lookup(). * @param c * @return */ public abstract XPromise nfp(XNativeConstraint c); @Override public boolean isLit() {return false;} @Override public boolean isSelf() {return false;} @Override public boolean isThis() {return false;} @Override public boolean isField() {return false;} @Override public boolean isBoolean() { return this == XNativeLit.TRUE || this == XNativeLit.FALSE; } @Override public String toString() { return "Native term !!"; } }