use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class Type method make.
/**
* Create the type list[start]->list[start+1]->..->list[end-1] (If start<0,
* end<0, end>list.size(), or start>=end, this method will return EMPTY)
*/
static Type make(List<PrimSig> list, int start, int end) {
if (start < 0 || end < 0 || start >= end || end > list.size())
return EMPTY;
PrimSig[] newlist = new PrimSig[end - start];
for (int i = start, j = 0; i < end; i++, j++) {
PrimSig x = list.get(i);
if (x == NONE) {
for (i = 0; i < newlist.length; i++) newlist[i] = x;
break;
}
newlist[j] = x;
}
return make(new ProductType(newlist));
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveMeta.
// ============================================================================================================================//
private static void resolveMeta(final CompModule root) throws Err {
// Now, add the meta sigs and fields if needed
Map<Sig, PrimSig> sig2meta = new LinkedHashMap<Sig, PrimSig>();
Map<Field, PrimSig> field2meta = new LinkedHashMap<Field, PrimSig>();
boolean hasMetaSig = false, hasMetaField = false;
root.new2old.put(root.metaSig, root.metaSig);
root.sigs.put(base(root.metaSig), root.metaSig);
root.new2old.put(root.metaField, root.metaField);
root.sigs.put(base(root.metaField), root.metaField);
for (CompModule m : root.allModules) for (Sig s : new ArrayList<Sig>(m.sigs.values())) if (m != root || (s != root.metaSig && s != root.metaField)) {
PrimSig ka = new PrimSig(s.label + "$", root.metaSig, Attr.ONE, PRIVATE.makenull(s.isPrivate), Attr.META);
sig2meta.put(s, ka);
ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", s);
m.new2old.put(ka, ka);
m.sigs.put(base(ka), ka);
hasMetaSig = true;
Expr allfields = ExprConstant.EMPTYNESS;
for (Field field : s.getFields()) {
Pos priv = field.isPrivate;
if (priv == null)
priv = s.isPrivate;
PrimSig kb = new PrimSig(s.label + "$" + field.label, root.metaField, Attr.ONE, PRIVATE.makenull(priv), Attr.META);
field2meta.put(field, kb);
m.new2old.put(kb, kb);
m.sigs.put(base(kb), kb);
hasMetaField = true;
kb.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", field);
if (allfields == ExprConstant.EMPTYNESS)
allfields = kb;
else
allfields = allfields.plus(kb);
}
ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "fields", allfields);
}
for (Map.Entry<Sig, PrimSig> e : sig2meta.entrySet()) {
Expr expr = null;
if ((e.getKey()) instanceof PrimSig) {
PrimSig a = (PrimSig) (e.getKey());
if (a.parent != null && a.parent != UNIV)
expr = sig2meta.get(a.parent);
}
e.getValue().addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "parent", (expr == null ? ExprConstant.EMPTYNESS : expr));
}
for (Map.Entry<Sig, PrimSig> e : sig2meta.entrySet()) {
Sig s = e.getKey();
PrimSig s2 = e.getValue();
Expr allfields = ExprConstant.EMPTYNESS;
for (Field f : s.getFields()) {
PrimSig metaF = field2meta.get(f);
if (allfields == ExprConstant.EMPTYNESS)
allfields = metaF;
else
allfields = allfields.plus(metaF);
}
if (s instanceof PrimSig)
for (Sig c : (((PrimSig) s).descendents())) for (Field f : c.getFields()) {
PrimSig metaF = field2meta.get(f);
if (allfields == ExprConstant.EMPTYNESS)
allfields = metaF;
else
allfields = allfields.plus(metaF);
}
s2.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "subfields", allfields);
}
if (hasMetaSig == false)
root.facts.add(new Pair<String, Expr>("sig$fact", root.metaSig.no().and(root.metaField.no())));
else if (hasMetaField == false)
root.facts.add(new Pair<String, Expr>("sig$fact", root.metaField.no()));
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method computeLowerBound.
// ==============================================================================================================//
/**
* Computes the lowerbound from bottom-up; it will also set a suitable initial
* value for each sig's upperbound. Precondition: sig is not a builtin sig
*/
private TupleSet computeLowerBound(List<Tuple> atoms, final PrimSig sig) throws Err {
int n = sc.sig2scope(sig);
TupleSet lower = factory.noneOf(1);
for (PrimSig c : sig.children()) lower.addAll(computeLowerBound(atoms, c));
TupleSet upper = lower.clone();
boolean isExact = sc.isExact(sig);
if (isExact || sig.isTopLevel())
for (n = n - upper.size(); n > 0; n--) {
Tuple atom = atoms.remove(atoms.size() - 1);
// atoms to the UPPERBOUND.
if (isExact)
lower.add(atom);
upper.add(atom);
}
lb.put(sig, lower);
ub.put(sig, upper);
return lower;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method allocateSubsetSig.
// ==============================================================================================================//
/**
* Allocate relations for SubsetSig top-down.
*/
private Expression allocateSubsetSig(SubsetSig sig) throws Err {
// We must not visit the same SubsetSig more than once, so if we've been
// here already, then return the old value right away
Expression sum = sol.a2k(sig);
if (sum != null && sum != Expression.NONE)
return sum;
// Recursively form the union of all parent expressions
TupleSet ts = factory.noneOf(1);
for (Sig parent : sig.parents) {
Expression p = (parent instanceof PrimSig) ? sol.a2k(parent) : allocateSubsetSig((SubsetSig) parent);
ts.addAll(sol.query(true, p, false));
if (sum == null)
sum = p;
else
sum = sum.union(p);
}
// If subset is exact, then just use the "sum" as is
if (sig.exact) {
sol.addSig(sig, sum);
return sum;
}
// Allocate a relation for this subset sig, then bound it
rep.bound("Sig " + sig + " in " + ts + "\n");
Relation r = sol.addRel(sig.label, null, ts);
sol.addSig(sig, r);
// Add a constraint that it is INDEED a subset of the union of its
// parents
sol.addFormula(r.in(sum), sig.isSubset);
return r;
}
use of edu.mit.csail.sdg.ast.Sig.PrimSig in project org.alloytools.alloy by AlloyTools.
the class ScopeComputer method derive_abstract_scope.
// ===========================================================================================================================//
/**
* If A is abstract, unscoped, and all children are scoped, then set A's scope
* to be the sum; if A is abstract, scoped, and every child except one is
* scoped, then set that child's scope to be the difference.
*/
private boolean derive_abstract_scope(Iterable<Sig> sigs) throws Err {
boolean changed = false;
again: for (Sig s : sigs) if (!s.builtin && (s instanceof PrimSig) && s.isAbstract != null) {
SafeList<PrimSig> subs = ((PrimSig) s).children();
if (subs.size() == 0)
continue;
Sig missing = null;
int sum = 0;
for (Sig c : subs) {
int cn = sig2scope(c);
if (cn < 0) {
if (missing == null) {
missing = c;
continue;
} else {
continue again;
}
}
sum = sum + cn;
if (sum < 0)
throw new ErrorSyntax(cmd.pos, "The number of atoms exceeds the internal limit of " + Integer.MAX_VALUE);
}
int sn = sig2scope(s);
if (sn < 0) {
if (missing != null)
continue;
sig2scope(s, sum);
changed = true;
} else if (missing != null) {
sig2scope(missing, (sn < sum) ? 0 : sn - sum);
changed = true;
}
}
return changed;
}
Aggregations