void link(HeapNode y, HeapNode x) {
   // moves y to a child position of x
   rootList.remove(y);
   x.addChild(y);
   y.setParent(x);
   y.setMark(false);
 }
  /**
   * removes child node from tree and starts a new one with it.
   *
   * @param x
   * @param y
   */
  protected void cut(HeapNode x, HeapNode y) {
    // remove x from child list of y and decrement y.degree
    y.removeChild(x);

    // add x to root list
    rootList.insert(x);
    x.setParent(null);
    x.setMark(false);
  }
 /**
  * c*O(1)
  *
  * @param y
  */
 protected void cascadingCut(HeapNode y) {
   HeapNode z = y.getParent();
   if (z != null) {
     if (!y.isMark()) {
       y.setMark(true);
     } else {
       cut(y, z);
       cascadingCut(z);
     }
   }
 }
  /**
   * extract minimum from the heap.
   *
   * <p>minor differences from Cormen et al. pseudocode are present.
   *
   * @return
   */
  public HeapNode extractMin() {

    int sentinel = DoubleLinkedCircularList.sentinelKey;

    HeapNode z = minimumNode;

    if (z != null) {

      // detach each child and add it to heap
      HeapNode x = z.getChildren().getSentinel().getRight();

      // for each child x of z
      while (x.getKey() != sentinel) {
        HeapNode next = x.getRight();
        rootList.insert(x);
        x = next;
      }

      rootList.remove(z);

      if (z.getRight().getKey() == z.getKey()) {
        minimumNode = null;
      } else {
        minimumNode = z.getRight();
        consolidate();
      }

      n--;
    }

    return z;
  }
    /**
     * Creates a deep copy of this {@link HeapNode}. The clone is not reset from the current
     * position of the original.
     *
     * @return the cloned heap node
     */
    public HeapNode cloneHeapNode() {
      HeapNode clone;

      try {
        clone = (HeapNode) super.clone();
      } catch (CloneNotSupportedException e) {
        BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, e.toString());
        return null;
      }

      clone._node = _node;
      clone._markedNode = _node;

      return clone;
    }
Exemple #6
0
  @Override
  public void runAlgorithm() throws InterruptedException {
    final HeapNode v = new HeapNode(H, K, ZDepth.ACTIONNODE);
    addToScene(v);
    setHeader("insertion");
    if (H.getN() == 1000) {
      addStep("heapfull");
      removeFromScene(v);
      return;
    }
    HeapNode w;

    // link
    H.setN(H.getN() + 1);
    final int n = H.getN();
    int k = 1 << 10;
    if (n == 1) {
      H.setRoot(w = v);
      v.goToRoot();
      pause();
    } else {
      while ((k & n) == 0) {
        k >>= 1;
      }
      k >>= 1;
      w = H.getRoot();
      while (k > 1) {
        w = ((n & k) == 0) ? w.getLeft() : w.getRight();
        k >>= 1;
      }
      if ((k & n) == 0) {
        w.linkLeft(v);
      } else {
        w.linkRight(v);
      }
      v.mark();
      H.reposition();
      pause();
    }
    removeFromScene(v);
    v.unmark();

    // pause();
    bubbleup(v);
  }
  /**
   * a depth first search of all nodes (that is, it descends all children of a node before
   * proceeding to the next in the current doubly linked circular list).
   *
   * @param key
   * @return
   */
  HeapNode search(long key) {

    HeapNode node = rootList.getSentinel().getRight();

    int sentinel = DoubleLinkedCircularList.sentinelKey;

    Stack<HeapNode> stack = new Stack<HeapNode>();

    while (!stack.isEmpty() || (node.getKey() != sentinel)) {
      if (node.getKey() != sentinel) {

        stack.push(node);

        node = node.getRight();

      } else {

        node = stack.pop();

        // System.out.println(node.key);
        if (node.getKey() == key) {
          return node;
        }

        node = node.getChildren().getSentinel().getRight();
      }
    }

    return null;
  }
 /**
  * decrease key for node x
  *
  * <p>runtime is O(1)
  *
  * @param x
  * @param decreaseToThisKey
  */
 public void decreaseKey(HeapNode x, long decreaseToThisKey) {
   if (decreaseToThisKey > x.getKey()) {
     throw new IllegalArgumentException("key cannot be larger than x.key");
   }
   x.setKey(decreaseToThisKey);
   HeapNode y = x.getParent();
   if ((y != null) && (x.getKey() < y.getKey())) {
     cut(x, y);
     cascadingCut(y);
   }
   if (x.getKey() < minimumNode.getKey()) {
     minimumNode = x;
   }
 }
  /**
   * insert node into heap. runtime is O(1). makes no attempt to consolidate tree.
   *
   * @param node
   */
  public void insert(HeapNode node) {
    if (node.getKey() == DoubleLinkedCircularList.noValue) {
      throw new IllegalArgumentException("node.key must be set before insert into heap");
    }
    node.setNumberOfChildren(0);
    node.setParent(null);
    node.removeChildren();
    node.setLeft(node);
    node.setRight(node);
    node.setMark(false);

    // concatenate root list containing node with this.rootList
    rootList.insert(node);

    if ((minimumNode == null) || (node.getKey() < minimumNode.getKey())) {
      minimumNode = node;
    }

    n++;
  }
 protected void printRootList() {
   StringBuffer sb = new StringBuffer();
   HeapNode t = this.rootList.getSentinel().getRight();
   while (t.getKey() != DoubleLinkedCircularList.sentinelKey) {
     if ((minimumNode == null) || (t.getKey() < minimumNode.getKey())) {
       minimumNode = t;
     }
     String str = String.format("%d", t.getKey());
     if (sb.length() > 0) {
       sb.append(" ");
     }
     sb.append(str);
     t = t.getRight();
   }
   sb.insert(0, "Looking for " + minimumNode + " :");
   log.info(sb.toString());
 }
  void consolidate() {

    // D[n] = max degree of any node = lg_2(n) = lg_2(Integer.MAX) = 31
    // int maxDegree = (int) (Math.log(this.n)/Math.log(2));
    int maxDegree = 31;

    HeapNode[] a = new HeapNode[maxDegree];

    HeapNode w = rootList.getSentinel().getRight();

    // n*m*(constants)
    while (w.getKey() != DoubleLinkedCircularList.sentinelKey) {

      HeapNode x = w;

      // because the x.right gets changed in link(), nab the next
      // reference before link
      HeapNode next = w.getRight();

      int d = x.getNumberOfChildren();

      // is there another node of the same degree, that is, has the
      // same number of children?
      while ((d < a.length) && (a[d] != null)) {

        HeapNode y = a[d];

        if (x.getKey() > y.getKey()) {
          HeapNode tmp = x;
          x = y;
          y = tmp;
        }

        // link removes y (which has a key larger than x now) from
        // rootList and adds it as a child of x
        link(y, x);

        a[d] = null;
        d++;
      }
      if (d < a.length) {
        a[d] = x;
      } else {
        throw new IllegalStateException("maxDegree=" + maxDegree + " but d is " + d);
      }

      w = next;
    }

    minimumNode = null;

    for (int i = 0; i < a.length; i++) {
      if (a[i] != null) {

        rootList.remove(a[i]);
        rootList.insert(a[i]);

        // not changing the minimumNode because the rootList content
        // has not changed, so the minimum in that has not changed
        if ((minimumNode == null) || (a[i].getKey() < minimumNode.getKey())) {
          minimumNode = a[i];
        }
      }
    }
  }
Exemple #12
0
  public static int addNewHeapNode(
      ClassInfo typeClassInfo,
      ThreadInfo ti,
      Object attr,
      PathCondition pcHeap,
      SymbolicInputHeap symInputHeap,
      int numSymRefs,
      HeapNode[] prevSymRefs,
      boolean setShared) {
    int daIndex = ti.getHeap().newObject(typeClassInfo, ti).getObjectRef();
    ti.getHeap().registerPinDown(daIndex);
    String refChain =
        ((SymbolicInteger) attr)
            .getName(); // + "[" + daIndex + "]"; // do we really need to add daIndex here?
    SymbolicInteger newSymRef = new SymbolicInteger(refChain);
    ElementInfo eiRef =
        ti.getModifiableElementInfo(daIndex); // ti.getElementInfo(daIndex); // TODO to review!
    if (setShared) {
      eiRef.setShared(ti, true); // ??
    }
    // daIndex.getObjectRef() -> number

    // neha: this change allows all the fields in the class hierarchy of the
    // object to be initialized as symbolic and not just its instance fields

    int numOfFields = eiRef.getNumberOfFields();
    FieldInfo[] fields = new FieldInfo[numOfFields];
    for (int fieldIndex = 0; fieldIndex < numOfFields; fieldIndex++) {
      fields[fieldIndex] = eiRef.getFieldInfo(fieldIndex);
    }

    Helper.initializeInstanceFields(fields, eiRef, refChain);

    // neha: this change allows all the static fields in the class hierarchy
    // of the object to be initialized as symbolic and not just its immediate
    // static fields
    ClassInfo superClass = typeClassInfo;
    while (superClass != null) {
      FieldInfo[] staticFields = superClass.getDeclaredStaticFields();
      Helper.initializeStaticFields(staticFields, superClass, ti);
      superClass = superClass.getSuperClass();
    }

    // Put symbolic array in PC if we create a new array.
    if (typeClassInfo.isArray()) {
      String typeClass = typeClassInfo.getType();
      ArrayExpression arrayAttr = null;
      if (typeClass.charAt(1) != 'L') {
        arrayAttr = new ArrayExpression(eiRef.toString());
      } else {
        arrayAttr =
            new ArrayExpression(eiRef.toString(), typeClass.substring(2, typeClass.length() - 1));
      }
      ti.getVM()
          .getLastChoiceGeneratorOfType(PCChoiceGenerator.class)
          .getCurrentPC()
          .arrayExpressions
          .put(eiRef.toString(), arrayAttr);
    }

    // create new HeapNode based on above info
    // update associated symbolic input heap
    HeapNode n = new HeapNode(daIndex, typeClassInfo, newSymRef);
    symInputHeap._add(n);
    pcHeap._addDet(Comparator.NE, newSymRef, new IntegerConstant(-1));
    pcHeap._addDet(Comparator.EQ, newSymRef, new IntegerConstant(numSymRefs));
    for (int i = 0; i < numSymRefs; i++)
      pcHeap._addDet(Comparator.NE, n.getSymbolic(), prevSymRefs[i].getSymbolic());
    return daIndex;
  }