rate_common/
clausedatabase.rs1use crate::{
4 clause::{puts_clause_with_id, Clause, ClauseIdentifierType},
5 literal::Literal,
6 memory::{HeapSpace, Offset, Vector},
7};
8
9use rate_macros::HeapSpace;
10use std::{
11 convert::TryFrom,
12 mem::size_of,
13 ops::{Index, IndexMut, Range},
14};
15
16pub trait ClauseStorage {
17 fn open_clause(&mut self) -> Clause;
22 fn push_literal(&mut self, literal: Literal, verbose: bool);
28}
29
30pub const PADDING_START: usize = 2;
32pub const FIELDS_OFFSET: usize = 1;
34pub const PADDING_END: usize = 1;
36
37#[derive(Debug, PartialEq, HeapSpace)]
39pub struct ClauseDatabase {
40 data: Vector<Literal>,
45 offset: Vector<usize>,
47 have_sentinel: bool,
50}
51
52impl ClauseStorage for ClauseDatabase {
53 fn open_clause(&mut self) -> Clause {
54 requires!(self.have_sentinel);
55 let id = self.number_of_clauses();
56 self.pop_sentinel();
57 let clause = Clause::new(id);
58 self.offset.push(self.data.len()); self.data.push(Literal::from_raw(id));
60 self.data.push(Literal::from_raw(0)); clause
62 }
63 fn push_literal(&mut self, literal: Literal, verbose: bool) {
64 if literal.is_zero() {
65 self.close_clause(verbose)
66 } else {
67 self.data.push(literal)
68 }
69 }
70}
71
72impl Default for ClauseDatabase {
73 fn default() -> ClauseDatabase {
75 let mut db = ClauseDatabase {
76 data: Vector::new(),
77 offset: Vector::new(),
78 have_sentinel: false,
79 };
80 db.push_sentinel(db.data.len());
81 db
82 }
83}
84
85impl ClauseDatabase {
86 #[cfg(test)]
88 pub fn from(data: Vector<Literal>, offset: Vector<usize>) -> ClauseDatabase {
89 let mut db = ClauseDatabase {
90 data,
91 offset,
92 have_sentinel: false,
93 };
94 db.push_sentinel(db.data.len());
95 db
96 }
97 pub fn number_of_clauses(&self) -> ClauseIdentifierType {
99 requires!(self.have_sentinel);
100 let sentinel_size = 1;
101 let number = self.offset.len() - sentinel_size;
102 requires!(ClauseIdentifierType::try_from(number).is_ok());
103 number as ClauseIdentifierType
104 }
105 pub fn last_clause(&self) -> Clause {
107 requires!(self.have_sentinel);
108 requires!(self.number_of_clauses() > 0);
109 Clause::new(self.number_of_clauses() - 1)
110 }
111 fn last_clause_no_sentinel(&self) -> Clause {
113 requires!(!self.have_sentinel);
114 let index = self.offset.len() - 1;
115 Clause::from_usize(index)
116 }
117 fn push_sentinel(&mut self, offset: usize) {
119 requires!(!self.have_sentinel);
120 self.offset.push(offset);
121 self.have_sentinel = true;
122 }
123 fn pop_sentinel(&mut self) {
125 requires!(self.have_sentinel);
126 self.offset.pop();
127 self.have_sentinel = false;
128 }
129 fn close_clause(&mut self, verbose: bool) {
131 requires!(!self.have_sentinel);
132 let clause = self.last_clause_no_sentinel();
133 let start = self.offset[clause.as_offset()] + PADDING_START;
134 let end = self.data.len();
135 sort_clause(&mut self.data[start..end]);
136 let mut duplicate = false;
137 let mut length = 0;
138 for i in start..end {
139 if i + 1 < end && self[i] == self[i + 1] {
140 duplicate = true;
141 } else {
142 self[start + length] = self[i];
143 length += 1;
144 }
145 }
146 self.data.truncate(start + length);
147 if length == 1 {
148 self.data.push(Literal::BOTTOM);
149 }
150 self.data.push(Literal::new(0));
151 self.push_sentinel(self.data.len());
152 if verbose && duplicate {
153 as_warning!({
154 puts!("c removed duplicate literals in ");
155 puts_clause_with_id(clause, self.clause(clause));
156 puts!("\n");
157 });
158 }
159 }
160 pub fn pop_clause(&mut self) {
162 requires!(self.have_sentinel);
163 let last_clause = self.last_clause();
164 let last_clause_offset = self.offset[last_clause.as_offset()];
165 self.data.truncate(last_clause_offset);
166 self.pop_sentinel();
167 self.offset.pop(); self.push_sentinel(last_clause_offset);
169 }
170 pub fn clause_to_string(&self, clause: Clause) -> String {
174 format!(
175 "[{}]{} 0",
176 clause,
177 self.clause(clause)
178 .iter()
179 .filter(|&literal| *literal != Literal::BOTTOM)
180 .map(|&literal| format!(" {}", literal))
181 .collect::<Vector<_>>()
182 .join("")
183 )
184 }
185 pub fn clause(&self, clause: Clause) -> &[Literal] {
187 &self.data[self.clause_range(clause)]
188 }
189 pub fn clause_range(&self, clause: Clause) -> Range<usize> {
191 requires!(self.have_sentinel);
192 self.offset[clause.as_offset()] + PADDING_START
193 ..self.offset[clause.as_offset() + 1] - PADDING_END
194 }
195 pub fn watches(&self, head: usize) -> [Literal; 2] {
197 [self[head], self[head + 1]]
198 }
199 pub fn clause2offset(&self, clause: Clause) -> usize {
201 self.clause_range(clause).start
202 }
203 pub fn offset2clause(&self, head: usize) -> Clause {
205 Clause::new(self[head - PADDING_START].encoding)
206 }
207 pub fn swap(&mut self, a: usize, b: usize) {
209 self.data.swap(a, b);
210 }
211 pub fn fields(&self, clause: Clause) -> &u32 {
213 &self.data[self.offset[clause.as_offset()] + FIELDS_OFFSET].encoding
214 }
215 pub fn fields_mut(&mut self, clause: Clause) -> &mut u32 {
217 &mut self.data[self.offset[clause.as_offset()] + FIELDS_OFFSET].encoding
218 }
219 pub fn fields_from_offset(&self, offset: usize) -> &u32 {
222 &self.data[offset - 1].encoding
223 }
224 pub fn fields_mut_from_offset(&mut self, offset: usize) -> &mut u32 {
227 &mut self.data[offset - 1].encoding
228 }
229 pub fn shrink_to_fit(&mut self) {
231 self.data.push(Literal::new(0));
233 self.data.shrink_to_fit();
234 self.data.pop();
235 self.offset.push(0);
236 self.offset.shrink_to_fit();
237 self.offset.pop();
238 }
239 #[allow(dead_code)]
241 fn metrics(&self) {
242 let _db_size = self.data.capacity() * size_of::<Literal>();
243 let _drat_trim_clause_db_size = size_of::<Literal>()
244 * (
245 self.data.capacity() - (0..self.number_of_clauses()).map(Clause::new).filter(|&c| is_size_1_clause(self.clause(c))).count()
248 + self.number_of_clauses() as usize - (2 + 1) + 1
251 );
253 }
254}
255
256impl Index<usize> for ClauseDatabase {
257 type Output = Literal;
258 fn index(&self, offset: usize) -> &Literal {
259 &self.data[offset]
260 }
261}
262
263impl IndexMut<usize> for ClauseDatabase {
264 fn index_mut(&mut self, offset: usize) -> &mut Literal {
265 &mut self.data[offset]
266 }
267}
268
269#[derive(Debug, PartialEq, HeapSpace)]
273pub struct WitnessDatabase {
274 data: Vector<Literal>,
275 offset: Vector<usize>,
276}
277
278impl ClauseStorage for WitnessDatabase {
279 fn open_clause(&mut self) -> Clause {
280 self.offset.pop();
281 let witness = Clause::from_usize(self.offset.len());
282 self.offset.push(self.data.len());
283 witness
284 }
285 fn push_literal(&mut self, literal: Literal, _verbose: bool) {
286 if literal.is_zero() {
287 self.close_witness();
288 } else {
289 self.data.push(literal);
290 }
291 }
292}
293
294impl Default for WitnessDatabase {
295 fn default() -> WitnessDatabase {
297 let mut db = WitnessDatabase {
298 data: Vector::new(),
299 offset: Vector::new(),
300 };
301 db.offset.push(0);
302 db
303 }
304}
305
306impl WitnessDatabase {
307 #[cfg(test)]
309 pub fn from(data: Vector<Literal>, offset: Vector<usize>) -> WitnessDatabase {
310 WitnessDatabase { data, offset }
311 }
312 fn close_witness(&mut self) {
315 self.offset.push(self.data.len())
316 }
317 pub fn witness_to_string(&self, clause: Clause) -> String {
321 format!(
322 "Witness for [{}]:{} 0",
323 clause,
324 self.witness(clause)
325 .iter()
326 .map(|&literal| format!(" {}", literal))
327 .collect::<Vec<_>>()
328 .join("")
329 )
330 }
331 pub fn witness(&self, clause: Clause) -> &[Literal] {
333 &self.data[self.witness_range(clause)]
334 }
335 pub fn witness_range(&self, clause: Clause) -> Range<usize> {
337 self.offset[clause.as_offset()]..self.offset[clause.as_offset() + 1]
338 }
339 pub fn shrink_to_fit(&mut self) {
341 self.data.push(Literal::new(0));
343 self.data.shrink_to_fit();
344 self.data.pop();
345 self.offset.push(0);
346 self.offset.shrink_to_fit();
347 self.offset.pop();
348 }
349}
350
351impl Index<usize> for WitnessDatabase {
352 type Output = Literal;
353 fn index(&self, offset: usize) -> &Literal {
354 &self.data[offset]
355 }
356}
357
358impl IndexMut<usize> for WitnessDatabase {
359 fn index_mut(&mut self, offset: usize) -> &mut Literal {
360 &mut self.data[offset]
361 }
362}
363
364fn is_size_1_clause(clause: &[Literal]) -> bool {
366 clause.len() == 2 && (clause[0] == Literal::BOTTOM || clause[1] == Literal::BOTTOM)
367}
368
369fn sort_clause(clause: &mut [Literal]) {
371 let _sort_literally = |&literal: &Literal| literal.decode();
372 let _sort_magnitude = |&literal: &Literal| literal.encoding;
373 clause.sort_unstable_by_key(_sort_literally);
374}