/*
* 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.types.constraints;
import polyglot.util.InternalCompilerError;
import x10.constraint.XConstraint;
import x10.constraint.XFailure;
import x10.constraint.XTerm;
/**
* A representation of a constrained term: an XTerm t with a constraint c
* on the XTerm (and possibly other variables). c is required to have a bound self
* variable, and t cannot contain that variable.
*
* @author vj 09/02/09
*
*/
public class XConstrainedTerm {
XTerm term;
CConstraint constraint;
/**
* Return a (non-null) XConstrainedTerm built from t and c.
* c must have a bound self variable, and t cannot contain that variable.
* c is modified in place.
* @param t
* @param c
* @return
* @throws XFailure
*/
public static XConstrainedTerm make(XTerm t, CConstraint c) {
return new XConstrainedTerm(t, c);
}
/**
* Return a (non-null) XConstrainedTerm built from t and c. The constraint
* recorded with the returned value is c{self==t}.
* c is modified in place.
* @param t
* @param c
* @return
* @throws XFailure
*/
public static XConstrainedTerm instantiate(CConstraint c, XTerm t) throws XFailure {
c.addSelfBinding(t);
// the self variable in c is now bound.
return new XConstrainedTerm(t, c);
}
/**
* Return a (non-null) XConstrainedTerm built from t and {}.
* @param t
* @return
*/
public static XConstrainedTerm make(XTerm t) {
try {
return instantiate(ConstraintManager.getConstraintSystem().makeCConstraint(), t);
} catch (XFailure r) {
throw new InternalCompilerError("Cannot constrain " + t);
}
}
/**
* Returns a constrained term.
* @param t
* @param c
* @throws XFailure
*/
private XConstrainedTerm(XTerm t, CConstraint c) {
assert t!= null;
assert c!= null;
assert c.consistent();
this.term=t;
this.constraint=c;
}
public XTerm term(){return term;}
public CConstraint constraint() { return constraint;}
/**
* Returns true iff every value of term() (satisfying constraint()) is also a value of t.term(),
* and satisfies t.constraint().
* @param t
* @return
*/
public boolean entails(XConstrainedTerm t) {
assert t!= null;
return constraint.entails(term(), t.term()) && constraint.entails(t.constraint());
}
/**
* Add t1==t2 to the underlying constraint.
* @param t1
* @param t2
*/
public void addBinding(XTerm t1, XTerm t2) {
constraint.addBinding(t1, t2);
}
public XConstrainedTerm copy() {
return new XConstrainedTerm(term(), constraint().copy());
}
/**
* Return the constraint, instantiated with the term.
* @return
*/
public CConstraint xconstraint() {
CConstraint s = constraint();
s = s == null ? ConstraintManager.getConstraintSystem().makeCConstraint() : s.copy();
s = s.instantiateSelf(term());
return s;
}
public String toString() { return term.toString() + constraint.toString();}
}