use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class ALG195_1 method decls.
/**
* Returns the relation constraints.
*
* @returns the relation constraints.
*/
public final Formula decls() {
Formula f = function(s1, op1).and(function(s2, op2));
for (Relation x : h) {
f = f.and(x.function(s1, s2));
}
for (int i = 0; i < 7; i++) {
f = f.and(h[i].function(s1, s2));
f = f.and(e1[i].one()).and(e2[i].one());
}
return f;
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class A4Solution method query.
/**
* Query the Bounds object to find the lower/upper bound; throws ErrorFatal if
* expr is not Relation, nor a {union, product} of Relations.
*/
TupleSet query(boolean findUpper, Expression expr, boolean makeMutable) throws ErrorFatal {
if (expr == Expression.NONE)
return factory.noneOf(1);
if (expr == Expression.INTS)
return makeMutable ? sigintBounds.clone() : sigintBounds;
if (expr == KK_SEQIDX)
return makeMutable ? seqidxBounds.clone() : seqidxBounds;
if (expr == KK_STRING)
return makeMutable ? stringBounds.clone() : stringBounds;
if (expr instanceof Relation) {
TupleSet ans = findUpper ? bounds.upperBound((Relation) expr) : bounds.lowerBound((Relation) expr);
if (ans != null)
return makeMutable ? ans.clone() : ans;
} else if (expr instanceof BinaryExpression) {
BinaryExpression b = (BinaryExpression) expr;
if (b.op() == ExprOperator.UNION) {
TupleSet left = query(findUpper, b.left(), true);
TupleSet right = query(findUpper, b.right(), false);
left.addAll(right);
return left;
} else if (b.op() == ExprOperator.PRODUCT) {
TupleSet left = query(findUpper, b.left(), true);
TupleSet right = query(findUpper, b.right(), false);
return left.product(right);
}
}
throw new ErrorFatal("Unknown expression encountered during bounds computation: " + expr);
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method visit.
/**
* {@inheritDoc}
*/
@Override
public Object visit(ExprList x) throws Err {
if (x.op == ExprList.Op.AND || x.op == ExprList.Op.OR) {
if (x.args.size() == 0)
return (x.op == ExprList.Op.AND) ? Formula.TRUE : Formula.FALSE;
Formula answer = getSingleFormula(x.op == ExprList.Op.AND, 1, x.args);
return k2pos(answer, x);
}
if (x.op == ExprList.Op.TOTALORDER) {
Expression elem = cset(x.args.get(0)), first = cset(x.args.get(1)), next = cset(x.args.get(2));
if (elem instanceof Relation && first instanceof Relation && next instanceof Relation) {
Relation lst = frame.addRel("", null, frame.query(true, elem, false));
totalOrderPredicates.add((Relation) elem);
totalOrderPredicates.add((Relation) first);
totalOrderPredicates.add(lst);
totalOrderPredicates.add((Relation) next);
return k2pos(((Relation) next).totalOrder((Relation) elem, (Relation) first, lst), x);
}
// every
Formula f1 = elem.in(first.join(next.reflexiveClosure()));
// element
// is in
// the
// total
// order
// first element has no
Formula f2 = next.join(first).no();
// predecessor
Variable e = Variable.unary("v" + Integer.toString(cnt++));
// each element
Formula f3 = e.eq(first).or(next.join(e).one());
// (except the
// first) has
// one
// predecessor
// each
Formula f4 = e.eq(elem.difference(next.join(elem))).or(e.join(next).one());
// element
// (except
// the
// last)
// has
// one
// successor
// there are no
Formula f5 = e.in(e.join(next.closure())).not();
// cycles
return k2pos(f3.and(f4).and(f5).forAll(e.oneOf(elem)).and(f1).and(f2), x);
}
// This says no(a&b) and no((a+b)&c) and no((a+b+c)&d)...
// Empirically this seems to be more efficient than "no(a&b) and no(a&c)
// and no(b&c)"
Formula answer = null;
Expression a = null;
for (Expr arg : x.args) {
Expression b = cset(arg);
if (a == null) {
a = b;
continue;
}
if (answer == null)
answer = a.intersection(b).no();
else
answer = a.intersection(b).no().and(answer);
a = a.union(b);
}
if (answer != null)
return k2pos(answer, x);
else
return Formula.TRUE;
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class AbstractReplacer method visit.
/**
* Calls lookup(pred) and returns the cached value, if any. If a replacement has
* not been cached, visits the formula's children. If nothing changes, the
* argument is cached and returned, otherwise a replacement formula is cached
* and returned.
*
* @return { p: RelationPredicate | p.name = pred.name && p.relation =
* pred.relation.accept(delegate) && p.name = FUNCTION => p.targetMult =
* pred.targetMult && p.domain = pred.domain.accept(delegate) && p.range
* = pred.range.accept(delegate), p.name = TOTAL_ORDERING => p.ordered =
* pred.ordered.accept(delegate) && p.first =
* pred.first.accept(delegate) && p.last = pred.last.accept(delegate) }
*/
@Override
public Formula visit(RelationPredicate pred) {
Formula ret = lookup(pred);
if (ret != null)
return ret;
final Relation r = (Relation) pred.relation().accept(delegate);
switch(pred.name()) {
case ACYCLIC:
ret = (r == pred.relation()) ? pred : r.acyclic();
break;
case FUNCTION:
final RelationPredicate.Function fp = (RelationPredicate.Function) pred;
final Expression domain = fp.domain().accept(delegate);
final Expression range = fp.range().accept(delegate);
ret = (r == fp.relation() && domain == fp.domain() && range == fp.range()) ? fp : (fp.targetMult() == Multiplicity.ONE ? r.function(domain, range) : r.partialFunction(domain, range));
break;
case TOTAL_ORDERING:
final RelationPredicate.TotalOrdering tp = (RelationPredicate.TotalOrdering) pred;
final Relation ordered = (Relation) tp.ordered().accept(delegate);
final Relation first = (Relation) tp.first().accept(delegate);
final Relation last = (Relation) tp.last().accept(delegate);
ret = (r == tp.relation() && ordered == tp.ordered() && first == tp.first() && last == tp.last()) ? tp : r.totalOrder(ordered, first, last);
break;
default:
throw new IllegalArgumentException("unknown relation predicate: " + pred.name());
}
return cache(pred, ret);
}
use of kodkod.ast.Relation in project org.alloytools.alloy by AlloyTools.
the class BookExamples method trial.
/**
* This tries a particular solution against the formula.
*/
private static Solution trial(A4Reporter rep, TupleFactory fac, Solver solver, Iterable<Sig> sigs, Formula f, A4Solution frame, Object[] t) {
try {
frame.kr2typeCLEAR();
Bounds b = null;
TupleSet ts = null;
for (int i = 1; i < t.length; i++) {
Object x = t[i];
if (x == null)
return null;
if (x instanceof String && ((String) x).length() > 0) {
// This
// means
// it's
// a
// unary
// Tuple
// containing
// the
// given
// atom
Tuple xx = fac.tuple((String) x);
if (ts == null)
ts = fac.noneOf(1);
ts.add(xx);
continue;
}
if (x instanceof Tuple) {
// This means it's a Tuple
Tuple xx = (Tuple) x;
if (ts == null)
ts = fac.noneOf(xx.arity());
ts.add(xx);
continue;
}
if (x instanceof String) {
// The empty string means the sig
// name follows here
i++;
if (i >= t.length - 1 || !(t[i] instanceof String) || !(t[i + 1] instanceof String))
return null;
String sigName = (String) (t[i]);
i++;
String fieldName = (String) (t[i]);
Sig first = hasSig(sigs, sigName);
if (first == null)
return null;
Expression expr = null;
if (fieldName.length() == 0) {
expr = frame.a2k(first);
} else {
for (Field field : first.getFields()) if (field.label.equals(fieldName)) {
expr = frame.a2k(field);
while (expr instanceof BinaryExpression) expr = ((BinaryExpression) expr).right();
break;
}
}
if (!(expr instanceof Relation))
return null;
if (b == null)
// We delay the expansive
b = frame.getBounds();
// really find a possible match
if (ts == null)
ts = fac.noneOf(expr.arity());
if (!ts.containsAll(b.lowerBound((Relation) expr)))
// Sanity check
return null;
if (!b.upperBound((Relation) expr).containsAll(ts))
// Sanity check
return null;
b.boundExactly((Relation) expr, ts);
ts = null;
continue;
}
}
SATFactory sat = solver.options().solver();
Solution sol;
try {
solver.options().setSolver(SATFactory.DefaultSAT4J);
sol = solver.solve(f, b);
} finally {
solver.options().setSolver(sat);
}
if (sol == null || (sol.outcome() != SATISFIABLE && sol.outcome() != TRIVIALLY_SATISFIABLE))
return null;
if (rep != null)
rep.debug("Comment: " + t[0] + "\n");
return sol;
} catch (Throwable ex) {
return null;
}
}
Aggregations