use of edu.mit.csail.sdg.alloy4.SafeList 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;
}
use of edu.mit.csail.sdg.alloy4.SafeList in project org.alloytools.alloy by AlloyTools.
the class CompModule method populate.
/**
* Resolve the name based on the current context and this module.
*/
private Expr populate(TempList<Expr> ch, TempList<String> re, Decl rootfield, Sig rootsig, boolean rootfunparam, Func rootfunbody, Pos pos, String fullname, Expr THIS) {
// Return object can be Func(with > 0 arguments) or Expr
final String name = (fullname.charAt(0) == '@') ? fullname.substring(1) : fullname;
boolean fun = (rootsig != null && (rootfield == null || rootfield.expr.mult() == ExprUnary.Op.EXACTLYOF)) || (rootsig == null && !rootfunparam);
if (name.equals("univ"))
return ExprUnary.Op.NOOP.make(pos, UNIV);
if (name.equals("Int"))
return ExprUnary.Op.NOOP.make(pos, SIGINT);
if (name.equals("seq/Int"))
return ExprUnary.Op.NOOP.make(pos, SEQIDX);
if (name.equals("String"))
return ExprUnary.Op.NOOP.make(pos, STRING);
if (name.equals("none"))
return ExprUnary.Op.NOOP.make(pos, NONE);
if (name.equals("iden"))
return ExprConstant.Op.IDEN.make(pos, 0);
if (name.equals("sig$") || name.equals("field$"))
if (world != null) {
Sig s = world.sigs.get(name);
if (s != null)
return ExprUnary.Op.NOOP.make(pos, s);
}
final List<Object> ans = name.indexOf('/') >= 0 ? getRawQS(fun ? 5 : 1, name) : getRawNQS(this, fun ? 5 : 1, name);
final Sig param = params.get(name);
if (param != null && !ans.contains(param))
ans.add(param);
for (Object x : ans) {
if (x instanceof Sig) {
Sig y = (Sig) x;
ch.add(ExprUnary.Op.NOOP.make(pos, y, null, 0));
re.add("sig " + y.label);
} else if (x instanceof Func) {
Func f = (Func) x;
int fn = f.count();
int penalty = 0;
if (resolution == 1 && fn > 0 && rootsig != null && THIS != null && THIS.type().hasArity(1) && f.get(0).type().intersects(THIS.type())) {
// If we're inside a sig, and there is a unary variable
// bound to "this",
// we should consider it as a possible FIRST ARGUMENT of a
// fun/pred call
ConstList<Expr> t = Util.asList(THIS);
// penalty
ch.add(fn == 1 ? ExprCall.make(pos, null, f, t, 1 + penalty) : ExprBadCall.make(pos, null, f, t, 1 + penalty));
// of
// 1
re.add((f.isPred ? "pred this." : "fun this.") + f.label);
}
if (resolution == 1) {
ch.add(fn == 0 ? ExprCall.make(pos, null, f, null, penalty) : ExprBadCall.make(pos, null, f, null, penalty));
re.add((f.isPred ? "pred " : "fun ") + f.label);
}
if (resolution == 2 && f != rootfunbody && THIS != null && fullname.charAt(0) != '@' && fn > 0 && f.get(0).type().intersects(THIS.type())) {
// If there is some value bound to "this", we should
// consider it as a possible FIRST ARGUMENT of a fun/pred
// call
ConstList<Expr> t = Util.asList(THIS);
ch.add(fn == 1 ? ExprCall.make(pos, null, f, t, 0) : ExprBadCall.make(pos, null, f, t, 0));
re.add((f.isPred ? "pred this." : "fun this.") + f.label);
}
if (resolution != 1) {
ch.add(fn == 0 ? ExprCall.make(pos, null, f, null, 0) : ExprBadCall.make(pos, null, f, null, 0));
re.add((f.isPred ? "pred " : "fun ") + f.label);
}
}
}
// All else: we can call, and can refer to anything visible.
for (CompModule m : getAllNameableModules()) for (Sig s : m.sigs.values()) if (m == this || s.isPrivate == null)
for (Field f : s.getFields()) if (f.isMeta == null && (m == this || f.isPrivate == null) && f.label.equals(name))
if (resolution == 1) {
Expr x = null;
if (rootsig == null) {
x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
} else if (rootsig.isSameOrDescendentOf(f.sig)) {
x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
if (fullname.charAt(0) != '@')
x = THIS.join(x);
} else if (rootfield == null || rootfield.expr.mult() == ExprUnary.Op.EXACTLYOF) {
x = ExprUnary.Op.NOOP.make(pos, f, null, 1);
}
// penalty of 1
if (x != null) {
ch.add(x);
re.add("field " + f.sig.label + " <: " + f.label);
}
} else if (rootfield == null || rootsig.isSameOrDescendentOf(f.sig)) {
Expr x0 = ExprUnary.Op.NOOP.make(pos, f, null, 0);
if (resolution == 2 && THIS != null && fullname.charAt(0) != '@' && f.type().firstColumnOverlaps(THIS.type())) {
ch.add(THIS.join(x0));
re.add("field " + f.sig.label + " <: this." + f.label);
if (rootsig != null)
continue;
}
ch.add(x0);
re.add("field " + f.sig.label + " <: " + f.label);
}
if (metaSig() != null && (rootsig == null || rootfield == null)) {
SafeList<PrimSig> children = null;
try {
children = metaSig().children();
} catch (Err err) {
return null;
}
// exception NOT possible
for (PrimSig s : children) for (Field f : s.getFields()) if (f.label.equals(name)) {
Expr x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
ch.add(x);
re.add("field " + f.sig.label + " <: " + f.label);
}
}
if (metaField() != null && (rootsig == null || rootfield == null)) {
SafeList<PrimSig> children = null;
try {
children = metaField().children();
} catch (Err err) {
return null;
}
// exception NOT possible
for (PrimSig s : children) for (Field f : s.getFields()) if (f.label.equals(name)) {
Expr x = ExprUnary.Op.NOOP.make(pos, f, null, 0);
ch.add(x);
re.add("field " + f.sig.label + " <: " + f.label);
}
}
return null;
}
use of edu.mit.csail.sdg.alloy4.SafeList in project org.alloytools.alloy by AlloyTools.
the class Type method fold.
/**
* Merge "a" into the set of entries.
* <p>
* If {a}+this.entries contain a set of entries X1..Xn, such that <br>
* (1) For each X: X[j]==a[j] for i!=j, and X[i].super==a[i].super <br>
* (2) X1[i]..Xn[i] exhaust all the direct subsignatures of an abstract parent
* sig <br>
* THEN: <br>
* we remove X1..Xn, then return the merged result of X1..Xn <br>
* ELSE <br>
* we change nothing, and simply return null
* <p>
* <b>Precondition:</b> a[i] is not NONE, and a[i].parent is abstract, and
* a[i].parent!=UNIV
*/
private static List<PrimSig> fold(ArrayList<List<PrimSig>> entries, List<PrimSig> a, int i) {
PrimSig parent = a.get(i).parent;
SafeList<PrimSig> children;
try {
children = parent.children();
} catch (Err ex) {
return null;
}
// Exception only occurs if a[i].parent==UNIV
List<PrimSig> subs = children.makeCopy();
ArrayList<List<PrimSig>> toDelete = new ArrayList<List<PrimSig>>();
for (int bi = entries.size() - 1; bi >= 0; bi--) {
List<PrimSig> b = entries.get(bi);
if (b.size() == a.size()) {
for (int j = 0; ; j++) {
if (j >= b.size()) {
toDelete.add(b);
subs.remove(b.get(i));
break;
}
PrimSig bt1 = a.get(j), bt2 = b.get(j);
if (i == j && bt2.parent != parent)
break;
if (i != j && bt2 != bt1)
break;
}
}
}
subs.remove(a.get(i));
if (subs.size() != 0)
return null;
entries.removeAll(toDelete);
entries.remove(a);
a = new ArrayList<PrimSig>(a);
a.set(i, parent);
return a;
}
use of edu.mit.csail.sdg.alloy4.SafeList in project org.alloytools.alloy by AlloyTools.
the class InternalTest method test1.
public void test1() throws Exception {
XMLNode xml = new XMLNode(new StringReader("<alloy builddate='unknown'>" + "<instance bitwidth='2' maxseq='1' command='Run Deadlock' filename='dijkstra.als'>" + "<sig label='univ' ID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> <atom label='State$0'/> <atom label='State$1'/> <atom label='State$2'/> </sig>" + "<sig label='Int' ID='1' parentID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> </sig>" + "<sig label='seq/Int' ID='2' parentID='1' builtin='yes'> <atom label='0'/> </sig>" + "<sig label='State' ID='5' parentID='0'> <atom label='State$0'/> <atom label='State$1'/> <atom label='State$2'/> </sig>" + "<field label='len' parentID='5' ID='17'>" + " <tuple> <atom label='State$1'/> <atom label='-2'/> </tuple>" + " <tuple> <atom label='State$1'/> <atom label='-1'/> </tuple>" + " <types> <type ID='5'/> <type ID='1'/> </types>" + "</field>" + "<skolem label='$Deadlock_s' ID='16'>" + " <tuple> <atom label='State$0'/> </tuple>" + " <types> <type ID='5'/> </types>" + "</skolem>" + "</instance>" + "</alloy>"));
Sig state = new Sig.PrimSig("State");
A4Solution sol = A4SolutionReader.read(Arrays.asList(state), xml);
SafeList<ExprVar> skolems = new SafeList<ExprVar>(sol.getAllSkolems());
check(skolems.size() == 1);
check(skolems.get(0).label, "$Deadlock_s");
check(skolems.get(0).type(), state.type());
//
Sig state2 = new Sig.PrimSig("State");
Field field2 = state2.addField("len", Sig.SIGINT);
sol = A4SolutionReader.read(Arrays.asList(state2), xml);
SafeList<ExprVar> skolems2 = new SafeList<ExprVar>(sol.getAllSkolems());
check(skolems2.size() == 1);
check(skolems2.get(0).label, "$Deadlock_s");
check(skolems2.get(0).type(), state2.type());
check("" + sol.eval(field2.cardinality()), "-2");
}
use of edu.mit.csail.sdg.alloy4.SafeList in project org.alloytools.alloy by AlloyTools.
the class InternalTest method test2.
public void test2() throws Exception {
test1();
XMLNode xml = new XMLNode(new StringReader("<alloy builddate='unknown'>" + "<instance bitwidth='2' maxseq='1' command='Run Deadlock' filename='dijkstra.als'>" + "<sig label='univ' ID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> <atom label='State$0'/> <atom label='State$1'/> <atom label='State$2'/> </sig>" + "<sig label='Int' ID='1' parentID='0' builtin='yes'> <atom label='-2'/> <atom label='-1'/> <atom label='0'/> <atom label='1'/> </sig>" + "<sig label='seq/Int' ID='2' parentID='1' builtin='yes'> <atom label='0'/> </sig>" + "<sig label='Act' ID='5' parentID='0'> <atom label='Act$0'/> <atom label='Act$1'/> <atom label='Act$2'/> </sig>" + "<skolem label='$x' ID='16'>" + " <tuple> <atom label='0'/> <atom label='Act$1'/> </tuple>" + " <types> <type ID='2'/> <type ID='5'/> </types>" + "</skolem>" + "</instance>" + "</alloy>"));
Sig activity = new Sig.PrimSig("Act");
A4Solution sol = A4SolutionReader.read(Arrays.asList(activity), xml);
SafeList<ExprVar> skolems = new SafeList<ExprVar>(sol.getAllSkolems());
check(skolems.size() == 1);
check(skolems.get(0).label, "$x");
check(skolems.get(0).type(), Sig.SEQIDX.type().product(activity.type()));
}
Aggregations