use of kodkod.ast.Variable in project org.alloytools.alloy by AlloyTools.
the class Dijkstra method grabMutex.
/**
* Returns the GrabMutex predicate for states s1, s2, process p and mutex m.
*
* @return
*
* <pre>
* pred State.GrabMutex (p: Process, m: Mutex, s': State) {
* // a process can only act if it is not
* // waiting for a mutex
* !this::IsStalled(p)
* // can only grab a mutex we do not yet hold
* m !in p.(this.holds)
* this::IsFree (m) => {
* // if the mutex is free, we now hold it,
* // and do not become stalled
* p.(s'.holds) = p.(this.holds) + m
* no p.(s'.waits)
* } else {
* // if the mutex was not free,
* // we still hold the same mutexes we held,
* // and are now waiting on the mutex
* // that we tried to grab.
* p.(s'.holds) = p.(this.holds)
* p.(s'.waits) = m
* }
* all otherProc: Process - p | {
* otherProc.(s'.holds) = otherProc.(this.holds)
* otherProc.(s'.waits) = otherProc.(this.waits)
* }
* }
* </pre>
*/
public Formula grabMutex(Expression s1, Expression s2, Expression p, Expression m) {
final Formula f1 = isStalled(s1, p).not().and(m.in(p.join(s1.join(holds))).not());
final Formula isFree = isFree(s1, m);
final Formula f2 = p.join(s2.join(holds)).eq(p.join(s1.join(holds)).union(m));
final Formula f3 = p.join(s2.join(waits)).no();
final Formula f4 = isFree.implies(f2.and(f3));
final Formula f5 = p.join(s2.join(holds)).eq(p.join(s1.join(holds)));
final Formula f6 = p.join(s2.join(waits)).eq(m);
final Formula f7 = isFree.not().implies(f5.and(f6));
final Variable otherProc = Variable.unary("otherProc");
final Formula f8 = otherProc.join(s2.join(holds)).eq(otherProc.join(s1.join(holds)));
final Formula f9 = otherProc.join(s2.join(waits)).eq(otherProc.join(s1.join(waits)));
final Formula f10 = f8.and(f9).forAll(otherProc.oneOf(Process.difference(p)));
return Formula.and(f1, f4, f7, f10);
}
use of kodkod.ast.Variable in project org.alloytools.alloy by AlloyTools.
the class Dijkstra method deadlock.
/**
* Returns the Deadlock predicate.
*
* @return
*
* <pre>
*
* pred Deadlock () {
* some s: State | all p: Process | some p.(s.waits)
* }
* </pre>
*/
public Formula deadlock() {
final Variable s = Variable.unary("s");
final Variable p = Variable.unary("p");
return p.join(s.join(waits)).some().forAll(p.oneOf(Process)).forSome(s.oneOf(State));
}
use of kodkod.ast.Variable in project org.alloytools.alloy by AlloyTools.
the class Dijkstra method grabbedInOrder.
/**
* Returns the GrabbedInOrder predicate.
*
* @return
*
* <pre>
* pred GrabbedInOrder ( ) {
* all pre: State - so/last() |
* let post = so/next(pre) |
* let had = Process.(pre.holds), have = Process.(post.holds) |
* let grabbed = have - had |
* some grabbed => grabbed in mo/nexts(had)
* }
* </pre>
*/
public Formula grabbedInOrder() {
final Variable pre = Variable.unary("pre");
final Expression post = pre.join(sord);
final Expression had = Process.join(pre.join(holds));
final Expression have = Process.join(post.join(holds));
final Expression grabbed = have.difference(had);
return grabbed.some().implies(grabbed.in(had.join(mord.closure()))).forAll(pre.oneOf(State.difference(slast)));
}
use of kodkod.ast.Variable in project org.alloytools.alloy by AlloyTools.
the class BoundsComputer method size.
// ==============================================================================================================//
/**
* Helper method that returns the constraint that the sig has exactly "n"
* elements, or at most "n" elements
*/
private Formula size(Sig sig, int n, boolean exact) {
Expression a = sol.a2k(sig);
if (n <= 0)
return a.no();
if (n == 1)
return exact ? a.one() : a.lone();
Formula f = exact ? Formula.TRUE : null;
Decls d = null;
Expression sum = null;
while (n > 0) {
n--;
Variable v = Variable.unary("v" + Integer.toString(TranslateAlloyToKodkod.cnt++));
kodkod.ast.Decl dd = v.oneOf(a);
if (d == null)
d = dd;
else
d = dd.and(d);
if (sum == null)
sum = v;
else {
if (f != null)
f = v.intersection(sum).no().and(f);
sum = v.union(sum);
}
}
if (f != null)
return sum.eq(a).and(f).forSome(d);
else
return a.no().or(sum.eq(a).forSome(d));
}
use of kodkod.ast.Variable in project org.alloytools.alloy by AlloyTools.
the class TranslateAlloyToKodkod method isInBinary.
/**
* Helper method that translates the formula "r in (a ?->? b)" into a Kodkod
* formula.
*/
private Formula isInBinary(Expression r, ExprBinary ab) throws Err {
final Expression a = cset(ab.left), b = cset(ab.right);
Decls d = null, d2 = null;
Formula ans1, ans2;
// "R in A ->op B" means for each tuple a in A, there are "op" tuples in
// r that begins with a.
Expression atuple = null, ar = r;
for (int i = a.arity(); i > 0; i--) {
Variable v = Variable.unary("v" + Integer.toString(cnt++));
if (!am) {
if (a.arity() == 1)
d = v.oneOf(a);
else if (d == null)
d = v.oneOf(Expression.UNIV);
else
d = v.oneOf(Expression.UNIV).and(d);
} else {
d = am(a, d, i, v);
}
ar = v.join(ar);
if (atuple == null)
atuple = v;
else
atuple = atuple.product(v);
}
ans1 = isIn(ar, ab.right);
switch(ab.op) {
case ISSEQ_ARROW_LONE:
case ANY_ARROW_LONE:
case SOME_ARROW_LONE:
case ONE_ARROW_LONE:
case LONE_ARROW_LONE:
ans1 = ar.lone().and(ans1);
break;
case ANY_ARROW_ONE:
case SOME_ARROW_ONE:
case ONE_ARROW_ONE:
case LONE_ARROW_ONE:
ans1 = ar.one().and(ans1);
break;
case ANY_ARROW_SOME:
case SOME_ARROW_SOME:
case ONE_ARROW_SOME:
case LONE_ARROW_SOME:
ans1 = ar.some().and(ans1);
break;
}
if (a.arity() > 1) {
Formula tmp = isIn(atuple, ab.left);
if (tmp != Formula.TRUE)
ans1 = tmp.implies(ans1);
}
ans1 = ans1.forAll(d);
// "R in A op-> B" means for each tuple b in B, there are "op" tuples in
// r that end with b.
Expression btuple = null, rb = r;
for (int i = b.arity(); i > 0; i--) {
Variable v = Variable.unary("v" + Integer.toString(cnt++));
if (!am) {
if (b.arity() == 1)
d2 = v.oneOf(b);
else if (d2 == null)
d2 = v.oneOf(Expression.UNIV);
else
d2 = v.oneOf(Expression.UNIV).and(d2);
} else {
d2 = am(b, d2, i, v);
}
rb = rb.join(v);
if (btuple == null)
btuple = v;
else
btuple = v.product(btuple);
}
ans2 = isIn(rb, ab.left);
switch(ab.op) {
case LONE_ARROW_ANY:
case LONE_ARROW_SOME:
case LONE_ARROW_ONE:
case LONE_ARROW_LONE:
ans2 = rb.lone().and(ans2);
break;
case ONE_ARROW_ANY:
case ONE_ARROW_SOME:
case ONE_ARROW_ONE:
case ONE_ARROW_LONE:
ans2 = rb.one().and(ans2);
break;
case SOME_ARROW_ANY:
case SOME_ARROW_SOME:
case SOME_ARROW_ONE:
case SOME_ARROW_LONE:
ans2 = rb.some().and(ans2);
break;
}
if (b.arity() > 1) {
Formula tmp = isIn(btuple, ab.right);
if (tmp != Formula.TRUE)
ans2 = tmp.implies(ans2);
}
ans2 = ans2.forAll(d2);
// Now, put everything together
Formula ans = r.in(a.product(b)).and(ans1).and(ans2);
if (ab.op == ExprBinary.Op.ISSEQ_ARROW_LONE) {
Expression rr = r;
while (rr.arity() > 1) rr = rr.join(Expression.UNIV);
ans = rr.difference(rr.join(A4Solution.KK_NEXT)).in(A4Solution.KK_ZERO).and(ans);
}
return ans;
}
Aggregations