use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class A4Solution method addSkolem.
/**
* Add a new skolem to this solution and associate it with the given expression.
* <br>
* The expression must contain only constant Relations or Relations that are
* already bound in this solution.
*/
private ExprVar addSkolem(String label, Type type, Expression expr) throws Err {
if (solved)
throw new ErrorFatal("Cannot add an additional skolem since solve() has completed.");
int a = type.arity();
if (a < 1)
throw new ErrorFatal("Skolem " + label + " must be associated with a relational value.");
if (a != expr.arity())
throw new ErrorFatal("Skolem " + label + " must be associated with an " + a + "-ary relational value.");
ExprVar v = ExprVar.make(Pos.UNKNOWN, label, type);
a2k.put(v, expr);
skolems.add(v);
return v;
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class A4Solution method rename.
/**
* Helper method that chooses a name for each atom based on its most specific
* sig; (external caller should call this method with s==null and nexts==null)
*/
private static void rename(A4Solution frame, PrimSig s, Map<Sig, List<Tuple>> nexts, UniqueNameGenerator un) throws Err {
if (s == null) {
for (ExprVar sk : frame.skolems) un.seen(sk.label);
// Store up the skolems
List<Object> skolems = new ArrayList<Object>();
for (Map.Entry<Relation, Type> e : frame.rel2type.entrySet()) {
Relation r = e.getKey();
if (!frame.eval.instance().contains(r))
continue;
Type t = e.getValue();
if (t.arity() > r.arity())
// Something is wrong; let's skip it
continue;
while (t.arity() < r.arity()) t = UNIV.type().product(t);
String n = Util.tail(r.name());
while (n.length() > 0 && n.charAt(0) == '$') n = n.substring(1);
skolems.add(n);
skolems.add(t);
skolems.add(r);
}
// Find all suitable "next" or "prev" relations
nexts = new LinkedHashMap<Sig, List<Tuple>>();
for (Sig sig : frame.sigs) for (Field f : sig.getFields()) if (f.label.compareToIgnoreCase("next") == 0) {
List<List<PrimSig>> fold = f.type().fold();
if (fold.size() == 1) {
List<PrimSig> t = fold.get(0);
if (t.size() == 3 && t.get(0).isOne != null && t.get(1) == t.get(2) && !nexts.containsKey(t.get(1))) {
TupleSet set = frame.eval.evaluate(frame.a2k(t.get(1)));
if (set.size() <= 1)
continue;
TupleSet next = frame.eval.evaluate(frame.a2k(t.get(0)).join(frame.a2k(f)));
List<Tuple> test = isOrder(next, set);
if (test != null)
nexts.put(t.get(1), test);
} else if (t.size() == 2 && t.get(0) == t.get(1) && !nexts.containsKey(t.get(0))) {
TupleSet set = frame.eval.evaluate(frame.a2k(t.get(0)));
if (set.size() <= 1)
continue;
TupleSet next = frame.eval.evaluate(frame.a2k(f));
List<Tuple> test = isOrder(next, set);
if (test != null)
nexts.put(t.get(1), test);
}
}
}
for (Sig sig : frame.sigs) for (Field f : sig.getFields()) if (f.label.compareToIgnoreCase("prev") == 0) {
List<List<PrimSig>> fold = f.type().fold();
if (fold.size() == 1) {
List<PrimSig> t = fold.get(0);
if (t.size() == 3 && t.get(0).isOne != null && t.get(1) == t.get(2) && !nexts.containsKey(t.get(1))) {
TupleSet set = frame.eval.evaluate(frame.a2k(t.get(1)));
if (set.size() <= 1)
continue;
TupleSet next = frame.eval.evaluate(frame.a2k(t.get(0)).join(frame.a2k(f)).transpose());
List<Tuple> test = isOrder(next, set);
if (test != null)
nexts.put(t.get(1), test);
} else if (t.size() == 2 && t.get(0) == t.get(1) && !nexts.containsKey(t.get(0))) {
TupleSet set = frame.eval.evaluate(frame.a2k(t.get(0)));
if (set.size() <= 1)
continue;
TupleSet next = frame.eval.evaluate(frame.a2k(f).transpose());
List<Tuple> test = isOrder(next, set);
if (test != null)
nexts.put(t.get(1), test);
}
}
}
// Assign atom->name and atom->MostSignificantSig
for (Tuple t : frame.eval.evaluate(Expression.INTS)) {
frame.atom2sig.put(t.atom(0), SIGINT);
}
for (Tuple t : frame.eval.evaluate(KK_SEQIDX)) {
frame.atom2sig.put(t.atom(0), SEQIDX);
}
for (Tuple t : frame.eval.evaluate(KK_STRING)) {
frame.atom2sig.put(t.atom(0), STRING);
}
for (Sig sig : frame.sigs) if (sig instanceof PrimSig && !sig.builtin && ((PrimSig) sig).isTopLevel())
rename(frame, (PrimSig) sig, nexts, un);
// These are redundant atoms that were not chosen to be in the final
// instance
int unused = 0;
for (Tuple tuple : frame.eval.evaluate(Expression.UNIV)) {
Object atom = tuple.atom(0);
if (!frame.atom2sig.containsKey(atom)) {
frame.atom2name.put(atom, "unused" + unused);
unused++;
}
}
// Add the skolems
for (int num = skolems.size(), i = 0; i < num - 2; i = i + 3) {
String n = (String) skolems.get(i);
while (n.length() > 0 && n.charAt(0) == '$') n = n.substring(1);
Type t = (Type) skolems.get(i + 1);
Relation r = (Relation) skolems.get(i + 2);
frame.addSkolem(un.make("$" + n), t, r);
}
return;
}
for (PrimSig c : s.children()) rename(frame, c, nexts, un);
String signame = un.make(s.label.startsWith("this/") ? s.label.substring(5) : s.label);
List<Tuple> list = new ArrayList<Tuple>();
for (Tuple t : frame.eval.evaluate(frame.a2k(s))) list.add(t);
List<Tuple> order = nexts.get(s);
if (order != null && order.size() == list.size() && order.containsAll(list)) {
list = order;
}
int i = 0;
for (Tuple t : list) {
if (frame.atom2sig.containsKey(t.atom(0)))
// This means one of the subsig has already claimed
continue;
// this atom.
String x = signame + "$" + i;
i++;
frame.atom2sig.put(t.atom(0), s);
frame.atom2name.put(t.atom(0), x);
ExprVar v = ExprVar.make(null, x, s.type());
TupleSet ts = t.universe().factory().range(t, t);
Relation r = Relation.unary(x);
frame.eval.instance().add(r, ts);
frame.a2k.put(v, r);
frame.atoms.add(v);
}
}
use of edu.mit.csail.sdg.alloy4.Err 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.Err in project org.alloytools.alloy by AlloyTools.
the class A4SolutionWriter method writeField.
/**
* Write the given Field.
*/
private void writeField(Field x) throws Err {
try {
if (sol == null && x.isMeta != null)
// when writing the metamodel, skip the metamodel
return;
// fields!
if (x.type().hasNoTuple())
// we do not allow "none" in the XML file's type
return;
// declarations
if (rep != null)
rep.write(x);
Util.encodeXMLs(out, "\n<field label=\"", x.label, "\" ID=\"", map(x), "\" parentID=\"", map(x.sig));
if (x.isPrivate != null)
out.print("\" private=\"yes");
if (x.isMeta != null)
out.print("\" meta=\"yes");
out.print("\">\n");
writeExpr("", x);
out.print("</field>\n");
} catch (Throwable ex) {
throw new ErrorFatal("Error evaluating field " + x.sig.label + "." + x.label, ex);
}
}
use of edu.mit.csail.sdg.alloy4.Err in project org.alloytools.alloy by AlloyTools.
the class A4SolutionWriter method writeInstance.
/**
* If this solution is a satisfiable solution, this method will write it out in
* XML format.
*/
static void writeInstance(A4Reporter rep, A4Solution sol, PrintWriter out, Iterable<Func> extraSkolems, Map<String, String> sources) throws Err {
if (!sol.satisfiable())
throw new ErrorAPI("This solution is unsatisfiable.");
try {
Util.encodeXMLs(out, "<alloy builddate=\"", Version.buildDate(), "\">\n\n");
new A4SolutionWriter(rep, sol, sol.getAllReachableSigs(), sol.getBitwidth(), sol.getMaxSeq(), sol.getOriginalCommand(), sol.getOriginalFilename(), out, extraSkolems);
if (sources != null)
for (Map.Entry<String, String> e : sources.entrySet()) {
Util.encodeXMLs(out, "\n<source filename=\"", e.getKey(), "\" content=\"", e.getValue(), "\"/>\n");
}
out.print("\n</alloy>\n");
} catch (Throwable ex) {
if (ex instanceof Err)
throw (Err) ex;
else
throw new ErrorFatal("Error writing the solution XML file.", ex);
}
if (out.checkError())
throw new ErrorFatal("Error writing the solution XML file.");
}
Aggregations