use of kodkod.ast.Formula 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.Formula in project org.alloytools.alloy by AlloyTools.
the class StrategyUtils method roots.
/**
* Returns a map from variables to the corresponding roots of log.formula.
*
* @return
*
* <pre>
*
* { v: int, f: Formula | some r: log.records |
* r.translated in log.roots() and
* r.translated = f and
* r.env.isEmpty() and
* abs(r.literal) != Integer.MAX_VALUE and
* v = abs(r.literal) and
* no r': log.records | r'.node = r.node && log.replay.r' > log.replay.r }
* </pre>
*/
static SparseSequence<Formula> roots(TranslationLog log) {
final SparseSequence<Formula> rootVars = new TreeSequence<Formula>();
final Set<Formula> roots = log.roots();
final Map<Formula, int[]> maxRootVar = new IdentityHashMap<Formula, int[]>(roots.size());
final RecordFilter filter = new RecordFilter() {
@Override
public boolean accept(Node node, Formula translated, int literal, Map<Variable, TupleSet> env) {
return roots.contains(translated) && env.isEmpty();
}
};
for (Iterator<TranslationRecord> itr = log.replay(filter); itr.hasNext(); ) {
TranslationRecord record = itr.next();
int[] var = maxRootVar.get(record.translated());
if (var == null) {
var = new int[1];
maxRootVar.put(record.translated(), var);
}
var[0] = StrictMath.abs(record.literal());
}
for (Map.Entry<Formula, int[]> entry : maxRootVar.entrySet()) {
final int topVar = entry.getValue()[0];
if (// formula simplified to TRUE
topVar != Integer.MAX_VALUE)
rootVars.put(topVar, entry.getKey());
}
return rootVars;
}
use of kodkod.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class StrategyUtils method rootVars.
/**
* Returns the variables that correspond to the roots of log.formula.
*
* @return
*
* <pre>
*
* { v: int | some r: log.records |
* r.node in log.roots() and
* r.env.isEmpty() and
* abs(r.literal) != Integer.MAX_VALUE and
* v = abs(r.literal) and
* no r': log.records | r'.node = r.node && log.replay.r' > log.replay.r }
* </pre>
*/
public static IntSet rootVars(TranslationLog log) {
final IntSet rootVars = new IntTreeSet();
final Set<Formula> roots = log.roots();
final Map<Formula, int[]> maxRootVar = new LinkedHashMap<Formula, int[]>(roots.size());
final RecordFilter filter = new RecordFilter() {
@Override
public boolean accept(Node node, Formula translated, int literal, Map<Variable, TupleSet> env) {
return roots.contains(translated) && env.isEmpty();
}
};
for (Iterator<TranslationRecord> itr = log.replay(filter); itr.hasNext(); ) {
TranslationRecord record = itr.next();
int[] var = maxRootVar.get(record.translated());
if (var == null) {
var = new int[1];
maxRootVar.put(record.translated(), var);
}
var[0] = StrictMath.abs(record.literal());
}
for (int[] var : maxRootVar.values()) {
int topVar = var[0];
if (// formula simplified to TRUE
topVar != Integer.MAX_VALUE)
rootVars.add(var[0]);
}
return rootVars;
}
use of kodkod.ast.Formula in project org.alloytools.alloy by AlloyTools.
the class A4Solution method solve.
// ===================================================================================================//
/**
* Solve for the solution if not solved already; if cmd==null, we will simply
* use the lowerbound of each relation as its value.
*/
A4Solution solve(final A4Reporter rep, Command cmd, Simplifier simp, boolean tryBookExamples) throws Err, IOException {
// If already solved, then return this object as is
if (solved)
return this;
// the lower bound of each relation
if (cmd == null) {
Instance inst = new Instance(bounds.universe());
for (int max = max(), i = min(); i <= max; i++) {
Tuple it = factory.tuple("" + i);
inst.add(i, factory.range(it, it));
}
for (Relation r : bounds.relations()) inst.add(r, bounds.lowerBound(r));
eval = new Evaluator(inst, solver.options());
rename(this, null, null, new UniqueNameGenerator());
solved();
return this;
}
// Otherwise, prepare to do the solve...
final A4Options opt = originalOptions;
long time = System.currentTimeMillis();
rep.debug("Simplifying the bounds...\n");
if (opt.inferPartialInstance && simp != null && formulas.size() > 0 && !simp.simplify(rep, this, formulas))
addFormula(Formula.FALSE, Pos.UNKNOWN);
rep.translate(opt.solver.id(), bitwidth, maxseq, solver.options().skolemDepth(), solver.options().symmetryBreaking());
Formula fgoal = Formula.and(formulas);
rep.debug("Generating the solution...\n");
kEnumerator = null;
Solution sol = null;
final Reporter oldReporter = solver.options().reporter();
final boolean[] solved = new boolean[] { true };
solver.options().setReporter(new // Set up a
AbstractReporter() {
// reporter to
// catch the
// type+pos of
// skolems
@Override
public void skolemizing(Decl decl, Relation skolem, List<Decl> predecl) {
try {
Type t = kv2typepos(decl.variable()).a;
if (t == Type.EMPTY)
return;
for (int i = (predecl == null ? -1 : predecl.size() - 1); i >= 0; i--) {
Type pp = kv2typepos(predecl.get(i).variable()).a;
if (pp == Type.EMPTY)
return;
t = pp.product(t);
}
kr2type(skolem, t);
}// Exception here is not fatal
catch (Throwable ex) {
}
}
@Override
public void solvingCNF(int primaryVars, int vars, int clauses) {
if (solved[0])
return;
else
// initially solved[0] is true, so we
solved[0] = true;
// won't report the # of vars/clauses
if (rep != null)
rep.solve(primaryVars, vars, clauses);
}
});
if (!opt.solver.equals(SatSolver.CNF) && !opt.solver.equals(SatSolver.KK) && tryBookExamples) {
// try
// book
// examples
A4Reporter r = AlloyCore.isDebug() ? rep : null;
try {
sol = BookExamples.trial(r, this, fgoal, solver, cmd.check);
} catch (Throwable ex) {
sol = null;
}
}
// this allows the reporter to report the # of
solved[0] = false;
// vars/clauses
for (Relation r : bounds.relations()) {
formulas.add(r.eq(r));
}
// Without this, kodkod refuses to grow unmentioned relations
fgoal = Formula.and(formulas);
// Now pick the solver and solve it!
if (opt.solver.equals(SatSolver.KK)) {
File tmpCNF = File.createTempFile("tmp", ".java", new File(opt.tempDirectory));
String out = tmpCNF.getAbsolutePath();
Util.writeAll(out, debugExtractKInput());
rep.resultCNF(out);
return null;
}
if (opt.solver.equals(SatSolver.CNF)) {
File tmpCNF = File.createTempFile("tmp", ".cnf", new File(opt.tempDirectory));
String out = tmpCNF.getAbsolutePath();
solver.options().setSolver(WriteCNF.factory(out));
try {
sol = solver.solve(fgoal, bounds);
} catch (WriteCNF.WriteCNFCompleted ex) {
rep.resultCNF(out);
return null;
}
// The formula is trivial (otherwise, it would have thrown an
// exception)
// Since the user wants it in CNF format, we manually generate a
// trivially satisfiable (or unsatisfiable) CNF file.
Util.writeAll(out, sol.instance() != null ? "p cnf 1 1\n1 0\n" : "p cnf 1 2\n1 0\n-1 0\n");
rep.resultCNF(out);
return null;
}
if (!solver.options().solver().incremental()) /*
* || solver.options().solver()==SATFactory. ZChaffMincost
*/
{
if (sol == null)
sol = solver.solve(fgoal, bounds);
} else {
kEnumerator = new Peeker<Solution>(solver.solveAll(fgoal, bounds));
if (sol == null)
sol = kEnumerator.next();
}
if (!solved[0])
rep.solve(0, 0, 0);
final Instance inst = sol.instance();
// To ensure no more output during SolutionEnumeration
solver.options().setReporter(oldReporter);
// If unsatisfiable, then retreive the unsat core if desired
if (inst == null && solver.options().solver() == SATFactory.MiniSatProver) {
try {
lCore = new LinkedHashSet<Node>();
Proof p = sol.proof();
if (sol.outcome() == UNSATISFIABLE) {
// only perform the minimization if it was UNSATISFIABLE,
// rather than TRIVIALLY_UNSATISFIABLE
int i = p.highLevelCore().size();
rep.minimizing(cmd, i);
if (opt.coreMinimization == 0)
try {
p.minimize(new RCEStrategy(p.log()));
} catch (Throwable ex) {
}
if (opt.coreMinimization == 1)
try {
p.minimize(new HybridStrategy(p.log()));
} catch (Throwable ex) {
}
rep.minimized(cmd, i, p.highLevelCore().size());
}
for (Iterator<TranslationRecord> it = p.core(); it.hasNext(); ) {
Object n = it.next().node();
if (n instanceof Formula)
lCore.add((Formula) n);
}
Map<Formula, Node> map = p.highLevelCore();
hCore = new LinkedHashSet<Node>(map.keySet());
hCore.addAll(map.values());
} catch (Throwable ex) {
lCore = hCore = null;
}
}
// If satisfiable, then add/rename the atoms and skolems
if (inst != null) {
eval = new Evaluator(inst, solver.options());
rename(this, null, null, new UniqueNameGenerator());
}
// report the result
solved();
time = System.currentTimeMillis() - time;
if (inst != null)
rep.resultSAT(cmd, time, this);
else
rep.resultUNSAT(cmd, time, this);
return this;
}
use of kodkod.ast.Formula 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));
}
Aggregations