use of edu.mit.csail.sdg.ast.Func 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.ast.Func in project org.alloytools.alloy by AlloyTools.
the class CompModule method unique.
/**
* Throw an exception if there are more than 1 match; return nonnull if only one
* match; return null if no match.
*/
private Object unique(Pos pos, String name, List<Object> objs) throws Err {
if (objs.size() == 0)
return null;
if (objs.size() == 1)
return objs.get(0);
StringBuilder msg = new StringBuilder("The name \"").append(name);
msg.append("\" is ambiguous.\n" + "There are ").append(objs.size()).append(" choices:");
for (int i = 0; i < objs.size(); i++) {
msg.append("\n\n#").append(i + 1).append(": ");
Object x = objs.get(i);
if (x instanceof Sig) {
Sig y = (Sig) x;
msg.append("sig ").append(y.label).append("\n" + "at ").append(y.pos.toShortString());
} else if (x instanceof Func) {
Func y = (Func) x;
msg.append(y.isPred ? "pred " : "fun ").append(y.label).append("\n" + "at ").append(y.pos.toShortString());
} else if (x instanceof Expr) {
Expr y = (Expr) x;
msg.append("assertion at ").append(y.pos.toShortString());
}
}
throw new ErrorSyntax(pos, msg.toString());
}
use of edu.mit.csail.sdg.ast.Func in project org.alloytools.alloy by AlloyTools.
the class A4Solution method highLevelCore.
/**
* If this solution is unsatisfiable and its unsat core is available, then
* return the core; else return an empty set.
*/
public Pair<Set<Pos>, Set<Pos>> highLevelCore() {
if (hCoreCache != null)
return hCoreCache;
Set<Pos> ans1 = new LinkedHashSet<Pos>(), ans2 = new LinkedHashSet<Pos>();
if (hCore != null)
for (Node f : hCore) {
Object x = k2pos(f);
if (x instanceof Pos) {
// System.out.println("F: "+f+" at "+x+"\n");
// System.out.flush();
ans1.add((Pos) x);
} else if (x instanceof Expr) {
Expr expr = (Expr) x;
Pos p = ((Expr) x).span();
ans1.add(p);
// System.out.flush();
for (Func func : expr.findAllFunctions()) ans2.add(func.getBody().span());
}
}
return hCoreCache = new Pair<Set<Pos>, Set<Pos>>(Collections.unmodifiableSet(ans1), Collections.unmodifiableSet(ans2));
}
use of edu.mit.csail.sdg.ast.Func in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method skolem.
// ==============================================================================================================//
/**
* Given a variable name "name", prepend the current function name to form a
* meaningful "skolem name". (Note: this function does NOT, and need NOT
* guarantee that the name it generates is unique)
*/
private String skolem(String name) {
if (current_function.size() == 0) {
if (cmd != null && cmd.label.length() > 0 && cmd.label.indexOf('$') < 0)
return cmd.label + "_" + name;
else
return name;
}
Func last = current_function.get(current_function.size() - 1);
String funcname = tail(last.label);
if (funcname.indexOf('$') < 0)
return funcname + "_" + name;
else
return name;
}
use of edu.mit.csail.sdg.ast.Func in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method visit.
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprCall x) throws Err {
final Func f = x.fun;
final Object candidate = f.count() == 0 ? cacheForConstants.get(f) : null;
if (candidate != null)
return candidate;
final Expr body = f.getBody();
if (body.type().arity() < 0 || body.type().arity() != f.returnDecl.type().arity())
throw new ErrorType(body.span(), "Function return value not fully resolved.");
final int n = f.count();
int maxRecursion = unrolls;
for (Func ff : current_function) if (ff == f) {
if (maxRecursion < 0) {
throw new ErrorSyntax(x.span(), "" + f + " cannot call itself recursively!");
}
if (maxRecursion == 0) {
Type t = f.returnDecl.type();
if (t.is_bool)
return Formula.FALSE;
if (t.is_int())
return IntConstant.constant(0);
int i = t.arity();
Expression ans = Expression.NONE;
while (i > 1) {
ans = ans.product(Expression.NONE);
i--;
}
return ans;
}
maxRecursion--;
}
Env<ExprVar, Object> newenv = new Env<ExprVar, Object>();
for (int i = 0; i < n; i++) newenv.put(f.get(i), cset(x.args.get(i)));
Env<ExprVar, Object> oldenv = env;
env = newenv;
current_function.add(f);
Object ans = visitThis(body);
env = oldenv;
current_function.remove(current_function.size() - 1);
if (ans instanceof Formula)
k2pos((Formula) ans, x);
if (f.count() == 0)
cacheForConstants.put(f, ans);
return ans;
}
Aggregations