Exemple #1
0
 /** Allocate relations for SubsetSig top-down. */
 private Expression allocateSubsetSig(SubsetSig sig) throws Err {
   // We must not visit the same SubsetSig more than once, so if we've been here already, then
   // return the old value right away
   Expression sum = sol.a2k(sig);
   if (sum != null && sum != Expression.NONE) return sum;
   // Recursively form the union of all parent expressions
   TupleSet ts = factory.noneOf(1);
   for (Sig parent : sig.parents) {
     Expression p =
         (parent instanceof PrimSig) ? sol.a2k(parent) : allocateSubsetSig((SubsetSig) parent);
     ts.addAll(sol.query(true, p, false));
     if (sum == null) sum = p;
     else sum = sum.union(p);
   }
   // If subset is exact, then just use the "sum" as is
   if (sig.exact) {
     sol.addSig(sig, sum);
     return sum;
   }
   // Allocate a relation for this subset sig, then bound it
   rep.bound("Sig " + sig + " in " + ts + "\n");
   Relation r = sol.addRel(sig.label, null, ts);
   sol.addSig(sig, r);
   // Add a constraint that it is INDEED a subset of the union of its parents
   sol.addFormula(r.in(sum), sig.isSubset);
   return r;
 }
Exemple #2
0
 /** Allocate relations for nonbuiltin PrimSigs bottom-up. */
 private Expression allocatePrimSig(PrimSig sig) throws Err {
   // Recursively allocate all children expressions, and form the union of them
   Expression sum = null;
   for (PrimSig child : sig.children()) {
     Expression childexpr = allocatePrimSig(child);
     if (sum == null) {
       sum = childexpr;
       continue;
     }
     // subsigs are disjoint
     sol.addFormula(sum.intersection(childexpr).no(), child.isSubsig);
     sum = sum.union(childexpr);
   }
   TupleSet lower = lb.get(sig).clone(), upper = ub.get(sig).clone();
   if (sum == null) {
     // If sig doesn't have children, then sig should make a fresh relation for itself
     sum = sol.addRel(sig.label, lower, upper);
   } else if (sig.isAbstract == null) {
     // If sig has children, and sig is not abstract, then create a new relation to act as the
     // remainder.
     for (PrimSig child : sig.children()) {
       // Remove atoms that are KNOWN to be in a subsig;
       // it's okay to mistakenly leave some atoms in, since we will never solve for the
       // "remainder" relation directly;
       // instead, we union the remainder with the children, then solve for the combined solution.
       // (Thus, the more we can remove, the more efficient it gets, but it is not crucial for
       // correctness)
       TupleSet childTS = sol.query(false, sol.a2k(child), false);
       lower.removeAll(childTS);
       upper.removeAll(childTS);
     }
     sum = sum.union(sol.addRel(sig.label + " remainder", lower, upper));
   }
   sol.addSig(sig, sum);
   return sum;
 }