use of edu.mit.csail.sdg.alloy4.Pos 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 edu.mit.csail.sdg.alloy4.Pos in project org.alloytools.alloy by AlloyTools.
the class A4Solution method k2pos.
/**
* Associates the Kodkod formula to a particular Alloy Pos (if the Kodkod
* formula is not already associated with an Alloy Expr or Alloy Pos)
*/
Formula k2pos(Formula formula, Pos pos) throws Err {
if (solved)
throw new ErrorFatal("Cannot alter the k->pos mapping since solve() has completed.");
if (formula == null || pos == null || pos == Pos.UNKNOWN || k2pos.containsKey(formula))
return formula;
k2pos.put(formula, pos);
if (formula instanceof BinaryFormula) {
BinaryFormula b = (BinaryFormula) formula;
if (b.op() == FormulaOperator.AND) {
k2pos(b.left(), pos);
k2pos(b.right(), pos);
}
}
return formula;
}
use of edu.mit.csail.sdg.alloy4.Pos in project org.alloytools.alloy by AlloyTools.
the class CompLexer method alloy_num.
private final Symbol alloy_num(String txt) throws Err {
Pos p = alloy_here(txt);
int n = 0;
try {
txt = txt.replaceAll("_", "");
n = Integer.parseInt(txt);
} catch (NumberFormatException ex) {
throw new ErrorSyntax(p, "The number " + txt + " " + ex);
}
return new Symbol(CompSym.NUMBER, p, ExprConstant.Op.NUMBER.make(p, n));
}
use of edu.mit.csail.sdg.alloy4.Pos in project org.alloytools.alloy by AlloyTools.
the class CompLexer method alloy_hexnum.
private final Symbol alloy_hexnum(String txt) throws Err {
Pos p = alloy_here(txt);
int n = 0;
try {
txt = txt.substring(2).replaceAll("_", "");
n = Integer.parseInt(txt, 16);
} catch (NumberFormatException ex) {
throw new ErrorSyntax(p, "The hex number " + txt + " " + ex);
}
return new Symbol(CompSym.NUMBER, p, ExprConstant.Op.NUMBER.make(p, n));
}
use of edu.mit.csail.sdg.alloy4.Pos in project org.alloytools.alloy by AlloyTools.
the class CompModule method resolveMeta.
// ============================================================================================================================//
private static void resolveMeta(final CompModule root) throws Err {
// Now, add the meta sigs and fields if needed
Map<Sig, PrimSig> sig2meta = new LinkedHashMap<Sig, PrimSig>();
Map<Field, PrimSig> field2meta = new LinkedHashMap<Field, PrimSig>();
boolean hasMetaSig = false, hasMetaField = false;
root.new2old.put(root.metaSig, root.metaSig);
root.sigs.put(base(root.metaSig), root.metaSig);
root.new2old.put(root.metaField, root.metaField);
root.sigs.put(base(root.metaField), root.metaField);
for (CompModule m : root.allModules) for (Sig s : new ArrayList<Sig>(m.sigs.values())) if (m != root || (s != root.metaSig && s != root.metaField)) {
PrimSig ka = new PrimSig(s.label + "$", root.metaSig, Attr.ONE, PRIVATE.makenull(s.isPrivate), Attr.META);
sig2meta.put(s, ka);
ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", s);
m.new2old.put(ka, ka);
m.sigs.put(base(ka), ka);
hasMetaSig = true;
Expr allfields = ExprConstant.EMPTYNESS;
for (Field field : s.getFields()) {
Pos priv = field.isPrivate;
if (priv == null)
priv = s.isPrivate;
PrimSig kb = new PrimSig(s.label + "$" + field.label, root.metaField, Attr.ONE, PRIVATE.makenull(priv), Attr.META);
field2meta.put(field, kb);
m.new2old.put(kb, kb);
m.sigs.put(base(kb), kb);
hasMetaField = true;
kb.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "value", field);
if (allfields == ExprConstant.EMPTYNESS)
allfields = kb;
else
allfields = allfields.plus(kb);
}
ka.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "fields", allfields);
}
for (Map.Entry<Sig, PrimSig> e : sig2meta.entrySet()) {
Expr expr = null;
if ((e.getKey()) instanceof PrimSig) {
PrimSig a = (PrimSig) (e.getKey());
if (a.parent != null && a.parent != UNIV)
expr = sig2meta.get(a.parent);
}
e.getValue().addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "parent", (expr == null ? ExprConstant.EMPTYNESS : expr));
}
for (Map.Entry<Sig, PrimSig> e : sig2meta.entrySet()) {
Sig s = e.getKey();
PrimSig s2 = e.getValue();
Expr allfields = ExprConstant.EMPTYNESS;
for (Field f : s.getFields()) {
PrimSig metaF = field2meta.get(f);
if (allfields == ExprConstant.EMPTYNESS)
allfields = metaF;
else
allfields = allfields.plus(metaF);
}
if (s instanceof PrimSig)
for (Sig c : (((PrimSig) s).descendents())) for (Field f : c.getFields()) {
PrimSig metaF = field2meta.get(f);
if (allfields == ExprConstant.EMPTYNESS)
allfields = metaF;
else
allfields = allfields.plus(metaF);
}
s2.addDefinedField(Pos.UNKNOWN, null, Pos.UNKNOWN, "subfields", allfields);
}
if (hasMetaSig == false)
root.facts.add(new Pair<String, Expr>("sig$fact", root.metaSig.no().and(root.metaField.no())));
else if (hasMetaField == false)
root.facts.add(new Pair<String, Expr>("sig$fact", root.metaField.no()));
}
Aggregations