1use {
3 crate::{assign::AssignIF, types::*},
4 std::fmt,
5};
6
7pub trait VarOrderIF {
8 fn clear(&mut self, asg: &mut impl AssignIF);
9 fn len(&self) -> usize;
10 fn insert(&mut self, occur: &[LitOccurs], vi: VarId, upward: bool);
11 fn is_empty(&self) -> bool;
12 fn select_var(&mut self, occur: &[LitOccurs], asg: &impl AssignIF) -> Option<VarId>;
13 fn rebuild(&mut self, asg: &impl AssignIF, occur: &[LitOccurs]);
14}
15
16#[derive(Clone, Debug, Default)]
18pub struct LitOccurs {
19 pub aborted: bool,
20 pub pos_occurs: Vec<ClauseId>,
21 pub neg_occurs: Vec<ClauseId>,
22}
23
24impl LitOccurs {
25 pub fn new(n: usize) -> Vec<LitOccurs> {
27 let mut vec = Vec::with_capacity(n + 1);
28 for _ in 0..=n {
29 vec.push(LitOccurs::default());
30 }
31 vec
32 }
33 pub fn clear(&mut self) {
34 self.aborted = false;
35 self.pos_occurs.clear();
36 self.neg_occurs.clear();
37 }
38 pub fn activity(&self) -> usize {
39 if self.aborted {
40 std::usize::MAX
41 } else {
42 self.pos_occurs.len().min(self.neg_occurs.len())
43 }
44 }
45 pub fn is_empty(&self) -> bool {
46 self.pos_occurs.is_empty() && self.neg_occurs.is_empty()
47 }
48 pub fn len(&self) -> usize {
49 self.pos_occurs.len() + self.neg_occurs.len()
50 }
51}
52
53#[derive(Clone, Debug)]
59pub struct VarOccHeap {
60 pub heap: Vec<u32>, pub idxs: Vec<u32>, }
63
64impl VarOccHeap {
65 pub fn new(n: usize, init: usize) -> Self {
66 let mut heap = Vec::with_capacity(n + 1);
67 let mut idxs = Vec::with_capacity(n + 1);
68 heap.push(0);
69 idxs.push(n as u32);
70 for i in 1..=n {
71 heap.push(i as u32);
72 idxs.push(i as u32);
73 }
74 idxs[0] = init as u32;
75 VarOccHeap { heap, idxs }
76 }
77}
78
79impl VarOrderIF for VarOccHeap {
80 fn insert(&mut self, occur: &[LitOccurs], vi: VarId, upward: bool) {
81 debug_assert!(vi < self.heap.len());
82 if self.contains(vi) {
83 let i = self.idxs[vi];
84 if upward {
85 self.percolate_up(occur, i);
86 } else {
87 self.percolate_down(occur, i);
88 }
89 return;
90 }
91 let i = self.idxs[vi];
92 let n = self.idxs[0] + 1;
93 let vn = self.heap[n as usize];
94 self.heap.swap(i as usize, n as usize);
95 self.idxs.swap(vi, vn as usize);
96 debug_assert!((n as usize) < self.heap.len());
97 self.idxs[0] = n;
98 self.percolate_up(occur, n);
99 }
100 fn clear(&mut self, asg: &mut impl AssignIF) {
101 for v in &mut self.heap[0..self.idxs[0] as usize] {
102 asg.var_mut(*v as usize).turn_off(FlagVar::ENQUEUED);
103 }
104 self.reset()
105 }
106 fn len(&self) -> usize {
107 self.idxs[0] as usize
108 }
109 fn is_empty(&self) -> bool {
110 self.idxs[0] == 0
111 }
112 fn select_var(&mut self, occur: &[LitOccurs], asg: &impl AssignIF) -> Option<VarId> {
113 loop {
114 let vi = self.get_root(occur);
115 if vi == 0 {
116 return None;
117 }
118 if !asg.var(vi).is(FlagVar::ELIMINATED) {
119 return Some(vi);
120 }
121 }
122 }
123 fn rebuild(&mut self, asg: &impl AssignIF, occur: &[LitOccurs]) {
124 self.reset();
125 for (vi, v) in asg.var_iter().enumerate().skip(1) {
126 if asg.assign(vi).is_none() && !v.is(FlagVar::ELIMINATED) {
127 self.insert(occur, vi, true);
128 }
129 }
130 }
131}
132
133impl VarOccHeap {
134 fn contains(&self, v: VarId) -> bool {
135 self.idxs[v] <= self.idxs[0]
136 }
137 fn reset(&mut self) {
138 for i in 0..self.idxs.len() {
139 self.idxs[i] = i as u32;
140 self.heap[i] = i as u32;
141 }
142 }
143 fn get_root(&mut self, occur: &[LitOccurs]) -> VarId {
144 let s = 1;
145 let vs = self.heap[s];
146 let n = self.idxs[0];
147 debug_assert!((n as usize) < self.heap.len());
148 if n == 0 {
149 return 0;
150 }
151 let vn = self.heap[n as usize];
152 debug_assert!(vn != 0, "Invalid VarId for heap");
153 debug_assert!(vs != 0, "Invalid VarId for heap");
154 self.heap.swap(n as usize, s);
155 self.idxs.swap(vn as usize, vs as usize);
156 self.idxs[0] -= 1;
157 if 1 < self.idxs[0] {
158 self.percolate_down(occur, 1);
159 }
160 vs as usize
161 }
162 fn percolate_up(&mut self, occur: &[LitOccurs], start: u32) {
163 let mut q = start;
164 let vq = self.heap[q as usize];
165 debug_assert!(0 < vq, "size of heap is too small");
166 let aq = occur[vq as usize].activity();
167 loop {
168 let p = q / 2;
169 if p == 0 {
170 self.heap[q as usize] = vq;
171 debug_assert!(vq != 0, "Invalid index in percolate_up");
172 self.idxs[vq as usize] = q;
173 return;
174 } else {
175 let vp = self.heap[p as usize];
176 let ap = occur[vp as usize].activity();
177 if ap > aq {
178 self.heap[q as usize] = vp;
180 debug_assert!(vq != 0, "Invalid index in percolate_up");
181 self.idxs[vp as usize] = q;
182 q = p;
183 } else {
184 self.heap[q as usize] = vq;
185 debug_assert!(vq != 0, "Invalid index in percolate_up");
186 self.idxs[vq as usize] = q;
187 return;
188 }
189 }
190 }
191 }
192 fn percolate_down(&mut self, occur: &[LitOccurs], start: u32) {
193 let n = self.len();
194 let mut i = start;
195 let vi = self.heap[i as usize];
196 let ai = occur[vi as usize].activity();
197 loop {
198 let l = 2 * i; if l < (n as u32) {
200 let vl = self.heap[l as usize];
201 let al = occur[vl as usize].activity();
202 let r = l + 1; let (target, vc, ac) =
204 if r < (n as u32) && al > occur[self.heap[r as usize] as usize].activity() {
205 let vr = self.heap[r as usize];
206 (r, vr, occur[vr as usize].activity())
207 } else {
208 (l, vl, al)
209 };
210 if ai > ac {
211 self.heap[i as usize] = vc;
212 self.idxs[vc as usize] = i;
213 i = target;
214 } else {
215 self.heap[i as usize] = vi;
216 debug_assert!(vi != 0, "invalid index");
217 self.idxs[vi as usize] = i;
218 return;
219 }
220 } else {
221 self.heap[i as usize] = vi;
222 debug_assert!(vi != 0, "invalid index");
223 self.idxs[vi as usize] = i;
224 return;
225 }
226 }
227 }
228 }
264
265impl fmt::Display for VarOccHeap {
266 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267 write!(
268 f,
269 " - seek pointer - nth -> var: {:?}\n - var -> nth: {:?}",
270 self.heap, self.idxs,
271 )
272 }
273}