use of edu.mit.csail.sdg.alloy4.Env in project org.alloytools.alloy by AlloyTools.
the class SimInstance method visit.
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprCall x) throws Err {
final Func f = x.fun;
final int n = f.count();
final Object candidate = n == 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.");
for (Func ff : current_function) if (ff == f)
throw new ErrorSyntax(x.span(), "" + f + " cannot call itself recursively!");
Env<ExprVar, Object> newenv = new Env<ExprVar, Object>();
List<SimTupleset> list = new ArrayList<SimTupleset>(x.args.size());
for (int i = 0; i < n; i++) {
SimTupleset ts = cset(x.args.get(i));
newenv.put(f.get(i), ts);
list.add(ts);
}
final SimCallback cb = callbacks.get(f);
if (cb != null) {
try {
Object answer = cb.compute(f, list);
if (answer != null) {
if (x.args.size() == 0)
cacheForConstants.put(f, answer);
return answer;
}
} catch (Exception ex) {
// if the callback failed, we can just continue with our
// original attempt to evaluate this call
}
}
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 (f.count() == 0)
cacheForConstants.put(f, ans);
return ans;
}
use of edu.mit.csail.sdg.alloy4.Env in project org.alloytools.alloy by AlloyTools.
the class SimInstance method visit.
/**
* {@inheritDoc}
*/
@Override
public SimTupleset visit(Field x) throws Err {
if (x.defined) {
final ExprVar v = (ExprVar) (x.sig.decl.get());
final Expr b = x.decl().expr;
final Env<ExprVar, Object> oldenv = env;
env = new Env<ExprVar, Object>();
if (!b.hasVar(v)) {
SimTupleset ans = cset(x.sig).product(cset(b));
env = oldenv;
return ans;
}
SimTupleset ans = SimTupleset.EMPTY;
for (SimTuple a : visit(x.sig)) {
SimTupleset left = SimTupleset.make(a);
env.put(v, left);
SimTupleset right = cset(b);
env.remove(v);
ans = left.product(right).union(ans);
}
env = oldenv;
return ans;
}
Object ans = sfs.get(x);
if (ans instanceof SimTupleset)
return (SimTupleset) ans;
else
throw new ErrorFatal("Unknown field " + x + " encountered during evaluation.");
}
use of edu.mit.csail.sdg.alloy4.Env 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