예제 #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);
 }
예제 #2
0
  /**
   * Returns a relational encoding of the problem.
   *
   * @return a relational encoding of the problem.
   */
  public Formula rules() {
    final List<Formula> rules = new ArrayList<Formula>();

    rules.add(x.function(queen, num));
    rules.add(y.function(queen, num));

    final Variable i = Variable.unary("n");
    final Variable q1 = Variable.unary("q1"), q2 = Variable.unary("q2");

    // at most one queen in each row: all i: num | lone x.i

    rules.add(x.join(i).lone().forAll(i.oneOf(num)));

    // at most one queen in each column: all i: num | lone y.i
    rules.add(y.join(i).lone().forAll(i.oneOf(num)));

    // no queen in a blocked position:  all q: Queen | q.x->q.y !in blocked
    rules.add(q1.join(x).product(q1.join(y)).intersection(blocked).no().forAll(q1.oneOf(queen)));

    // at most one queen on each diagonal
    //		all q1: Queen, q2: Queen - q1 |
    //		let xu = prevs[q2.x] + prevs[q1.x],
    //		     xi =  prevs[q2.x] & prevs[q1.x],
    //                yu = prevs[q2.y] + prevs[q1.y],
    //                yi = prevs[q2.y] & prevs[q1.y] |
    //		#(xu - xi) != #(yu - yi)
    final Expression ordClosure = ord.closure();
    final Expression q2xPrevs = ordClosure.join(q2.join(x)), q1xPrevs = ordClosure.join(q1.join(x));
    final Expression q2yPrevs = ordClosure.join(q2.join(y)), q1yPrevs = ordClosure.join(q1.join(y));

    final IntExpression xDiff =
        (q2xPrevs.union(q1xPrevs)).difference(q2xPrevs.intersection(q1xPrevs)).count();
    final IntExpression yDiff =
        (q2yPrevs.union(q1yPrevs)).difference(q2yPrevs.intersection(q1yPrevs)).count();

    rules.add(xDiff.eq(yDiff).not().forAll(q1.oneOf(queen).and(q2.oneOf(queen.difference(q1)))));

    return Formula.and(rules);
  }