00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 #ifndef _cvc3__minisat__heap_h_
00041 #define _cvc3__minisat__heap_h_
00042 
00043 
00044 
00045 #include "debug.h"
00046 #include <iostream>
00047 
00048 
00049 
00050 namespace MiniSat {
00051 
00052 
00053 static inline int left  (int i) { return i+i; }
00054 static inline int right (int i) { return i+i + 1; }
00055 static inline int parent(int i) { return i >> 1; }
00056 
00057 template<class C>
00058 class Heap {
00059 public:
00060   C        comp;
00061   vec<int> heap;     
00062   vec<int> indices;  
00063   
00064   inline void percolateUp(int i)
00065   {
00066     int x = heap[i];
00067     while (parent(i) != 0 && comp(x,heap[parent(i)])){
00068       heap[i]          = heap[parent(i)];
00069       indices[heap[i]] = i;
00070       i                = parent(i);
00071     }
00072     heap   [i] = x;
00073     indices[x] = i;
00074   }
00075   
00076   inline void percolateDown(int i)
00077   {
00078     int x = heap[i];
00079     while (left(i) < heap.size()){
00080       int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i);
00081       if (!comp(heap[child],x)) break;
00082       heap[i]          = heap[child];
00083       indices[heap[i]] = i;
00084       i                = child;
00085     }
00086     heap   [i] = x;
00087     indices[x] = i;
00088     }
00089   
00090   bool ok(int n) { return n >= 0 && n < (int)indices.size(); }
00091 
00092 public:
00093   Heap(C c) : comp(c) { heap.push(-1); }
00094   
00095   void setBounds (int size) { DebugAssert(size >= 0, "MiniSat::Heap::setBounds"); indices.growTo(size,0); }
00096   bool inHeap    (int n)    { DebugAssert(ok(n), "MiniSat::Heap::inHeap"); return indices[n] != 0; }
00097 
00098   void increase  (int n){
00099     DebugAssert(ok(n), "MiniSat::Heap::increase: ok");
00100     DebugAssert(inHeap(n), "MiniSat::Heap::increase: inHeap");
00101     percolateUp(indices[n]);
00102   }
00103 
00104   bool empty     ()         { return heap.size() == 1; }
00105   
00106   void insert(int n) {
00107     DebugAssert(n > 0, "MiniSat::Heap::insert: inserting invalid var id");
00108     if (!inHeap(n)) {
00109       DebugAssert(ok(n), "MiniSat::Heap::insert: ok");
00110       indices[n] = heap.size();
00111       heap.push(n);
00112       percolateUp(indices[n]);
00113     }
00114   }
00115   
00116   int getMin() {
00117     int r            = heap[1];
00118     DebugAssert(r > 0, "MiniSatHeap:getmin: invalid var id");
00119     heap[1]          = heap.last();
00120     indices[heap[1]] = 1;
00121     indices[r]       = 0;
00122     heap.pop();
00123     if (heap.size() > 1)
00124       percolateDown(1);
00125     return r; }
00126   
00127   bool heapProperty() {
00128     return heapProperty(1); }
00129   
00130   bool heapProperty(int i) {
00131     return (size_t)i >= heap.size()
00132       || ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); }
00133 };
00134 
00135 }
00136 
00137 
00138 #endif