Exemplo n.º 1
0
 /**
  * Returns the declaration constraints.
  *
  * @return declaration constraints
  */
 public final Formula decls() {
   // File and Dir partition object
   final Formula f0 = Obj.eq(File.union(Dir)).and(File.intersection(Dir).no());
   // Root and Cur are in Dir and do not intersect
   final Formula f1 = Root.in(Dir).and(Cur.in(Dir)).and(Root.intersection(Cur).no());
   // don't need to specify that Dir, Name, and DirEntry are disjoint; implied by bounds
   final Formula f2 = entries.in(Dir.product(DirEntry));
   final Formula f3 = parent.partialFunction(Dir, Dir);
   final Formula f4 = name.function(DirEntry, Name);
   final Formula f5 = contents.function(DirEntry, Obj);
   return f0.and(f1).and(f2).and(f3).and(f4).and(f5);
 }
Exemplo n.º 2
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;
 }
Exemplo n.º 3
0
  /**
   * Returns all facts in the model.
   *
   * @return the facts.
   */
  public final Formula facts() {
    // sig File extends Object {} { some d: Dir | this in d.entries.contents }
    final Variable file = Variable.unary("this");
    final Variable d = Variable.unary("d");
    final Formula f0 =
        file.in(d.join(entries).join(contents)).forSome(d.oneOf(Dir)).forAll(file.oneOf(File));

    //		sig Dir extends Object {
    //			  entries: set DirEntry,
    //			  parent: lone Dir
    //			} {
    //			  parent = this.~@contents.~@entries
    //			  all e1, e2 : entries | e1.name = e2.name => e1 = e2
    //			  this !in this.^@parent
    //			  this != Root => Root in this.^@parent
    //			}

    final Variable dir = Variable.unary("this");
    final Variable e1 = Variable.unary("e1"), e2 = Variable.unary("e2");

    final Formula f1 =
        (dir.join(parent)).eq(dir.join(contents.transpose()).join(entries.transpose()));
    final Expression e0 = dir.join(entries);
    final Formula f2 =
        e1.join(name).eq(e2.join(name)).implies(e1.eq(e2)).forAll(e1.oneOf(e0).and(e2.oneOf(e0)));
    final Formula f3 = dir.in(dir.join(parent.closure())).not();
    final Formula f4 = dir.eq(Root).not().implies(Root.in(dir.join(parent.closure())));
    final Formula f5 = f1.and(f2).and(f3).and(f4).forAll(dir.oneOf(Dir));

    //		one sig Root extends Dir {} { no parent }
    final Formula f6 = Root.join(parent).no();

    //		sig DirEntry {
    //			  name: Name,
    //			  contents: Object
    //			} { one this.~entries }

    final Variable entry = Variable.unary("this");
    final Formula f7 = entry.join(entries.transpose()).one().forAll(entry.oneOf(DirEntry));

    //		fact OneParent {
    //		    // all directories besides root xhave one parent
    //		    all d: Dir - Root | one d.parent
    //		}

    final Formula f8 = d.join(parent).one().forAll(d.oneOf(Dir.difference(Root)));

    return f0.and(f5).and(f6).and(f7).and(f8);
  }