DomainVector.java :  » Scripting » Nice » mlsub » typing » lowlevel » Java Open Source

Java Open Source » Scripting » Nice 
Nice » mlsub » typing » lowlevel » DomainVector.java
package mlsub.typing.lowlevel;

/**
 * A DomainVector maintains an upper approximation of the set of solutions of
 * a constraint. What is handled dynamically : constraints between rigid and
 * soft variables. Constraints between soft variables are handled in gfp().
 *
 * RMK: only garbage indexes can have null domains
 *
 * @version $OrigRevision: 1.9 $, $OrigDate: 1999/10/03 17:37:05 $
 * @author Alexandre Frey
 **/
final class DomainVector extends java.util.ArrayList {
  int offset;                 // offset
  int width;                  // size of domains
  
  public DomainVector(DomainVector old) {
    super(old.size());
    this.offset = old.offset;
    this.width = old.width;
    for (int i = 0; i < old.size(); i++) {
      Domain d = ((Domain)old.get(i));
      if (d != null)
        add(new Domain(d));
      else
        add(null);
    }
  }

  public DomainVector(int offset, int width) {
    this.offset = offset;
    this.width = width;
  }
  public DomainVector(int offset, int width, int n) {
    super(n);
    //if (width > 0) {
      for (int i = 0; i < n; i++) {
        add(new Domain(width));
      }
      //} 
    this.offset = offset;
    this.width = width;
  }
  public Domain getDomain(int x) {
    return (Domain)get(x - offset);
  }

  void truncate(int x)
  {
    removeRange(x, size());
  }

  private boolean isValidSoft(int x) {
    return x>=offset && x-offset<size() && getDomain(x)!=null;
  }
  private boolean isGarbage(int x) {
    return x>=offset && x-offset<size() && getDomain(x)==null;
  }
  
  public void clear(int x) {
    set(x - offset, null);
  }
  public void reduce(int x, boolean unit, BitVector domain)
  throws LowlevelUnsatisfiable {
    S.assume(S.a&& isValidSoft(x));
    Domain d = getDomain(x);
    d.reduce(unit, domain);
  }
  public void exclude(int x, BitVector domain)
  throws LowlevelUnsatisfiable {
    S.assume(S.a&& isValidSoft(x));
    Domain d = getDomain(x);
    d.exclude(domain);
  }

  public void merge(int src, int dest) throws LowlevelUnsatisfiable {
    S.assume(S.a&& isValidSoft(src));
    Domain srcDomain = getDomain(src);
    if (dest >= offset) {
      // don't forget unit !
      reduce(dest, srcDomain.containsUnit(), srcDomain);
    }
    else {
      // dest is rigid
      S.assume(S.a&& srcDomain.get(dest),src+" merged with "+dest);
    }
    clear(src);
  }

  public void exclude(int value) throws LowlevelUnsatisfiable {
    for (int i = 0; i < size(); i++) {
      Domain d = (Domain)get(i);
      if (d != null) {
        d.exclude(value);
      }
    }
  }
  public void move(int src, int dest) {
    S.assume(S.a&& isValidSoft(src));
    S.assume(S.a&& isGarbage(dest));
    set(dest - offset, getDomain(src));
    clear(src);
  }
  public void extend() {
    // if (width > 0) {
    add(new Domain(width));
    //} else {
    //addElement(null);
    //}
  }

  /***********************************************************************
   * Fix-point computations
   ***********************************************************************/
  private boolean gfpSweep(BitMatrix R, BitMatrix C, 
                           int[] strategy, int dS,
                           int direction)
    throws LowlevelUnsatisfiable {
    boolean changed = false;
    BitVector ideal = new BitVector(width);
    boolean idealContainsUnit = false;
    int length = strategy.length;
    for (int s = (dS > 0 ? 0 : length - 1); s >= 0 && s < length; s += dS) {
      int x = strategy[s];
      Domain dx = getDomain(x);
      if (dx != null) {
        // XXX: already tested ??
        if (dx.isEmpty()) {
          throw LowlevelUnsatisfiable.instance;
        }
        if (dx.needPropagation(direction)) {
          changed = true;
          // compute the ideal of dx
          // the ideal may contain unit !
          ideal.clearAll();
          idealContainsUnit = dx.containsUnit();
          ideal.addProduct(R, dx);
          
          // and intersect the domain of all element j above x with ideal
          for (int j = offset; j < offset + size(); j++) {
            Domain dj = getDomain(j);
            if (dj != null && C.get(x, j)) {
        if(K0.debugK0){
    S.dbg.println("Reducing domain of "+j);
    S.dbg.println("from "+dj);
    S.dbg.println("with ideal of "+x+": "+ideal);
        }
              dj.reduce(idealContainsUnit, ideal);
              // XXX: not necessary to test emptyness ??
            }
            // emptyness of dj will normally be tested later on
            // XXX: this comment correct ?
          }
        }
      }
    }
    return changed;
  }
  
  /**
   * Reduce this domain vector to  the greatest fixed-point of a constraint.
   * @param R constraint on the rigid constants (in [0, width[)
   * @param Rt its transpose
   * @param C constraint on [0, offset + size()[
   * @param Ct its tranpose
   * @param strategy an iteration strategy: topological sort of C
   **/
  public void gfp(BitMatrix R, BitMatrix Rt,
                  BitMatrix C, BitMatrix Ct,
                  int[] strategy)
  throws LowlevelUnsatisfiable {
    boolean changed;
    do {
      changed = gfpSweep(R, C, strategy, +1, Domain.UP);
      changed = gfpSweep(Rt, Ct, strategy, -1, Domain.DOWN) || changed;
    } while (changed);
  }

  void initGfpCardinals() {
    for (int i = 0; i < size(); i++) {
      Domain d = (Domain)get(i);
      if (d != null) {
        d.initGfpCardinals();
      }
    }
  }
  
  /**
   * Choose a non-null, non-singleton, domain and return its index. Return -1
   * if all the domains are instantiated. 
   **/
  public int chooseDomain() {
    return chooseDomain(null);
  }

  /**
   * ditto but choose a domain whose index i is in set
   **/
  public int chooseDomain(BitVector set) {
    /*
     * Choose the domain of least cardinal (first-fail heuristic)
     */
    int leastCard = Integer.MAX_VALUE;
    int least = Integer.MIN_VALUE;
    for (int i = 0; i < size(); i++) {
      if (set == null || set.get(i + offset)) {
        Domain d = (Domain)get(i);
        if (d != null){
          int card = d.cardinal();
    if (card < leastCard && card > 1) {
            least = i + offset;
            leastCard = card;
          }
        }
      }
    }
    return least;
  }


  // toString is final in class java.util.Vector...
  public String dump() {
    Separator sep = new Separator(", ");
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < size(); i++) {
      if (get(i) != null) {
        sb.append(sep)
          .append("D(")
          .append(i + offset)
          .append(") = ")
          .append(get(i));
      }
    }
    return sb.toString();
  }
}   

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.