1use warp_types_sat::literal::Lit;
11
12#[derive(Debug, Clone)]
21pub struct Frame {
22 clauses: Vec<Vec<Lit>>,
24}
25
26impl Frame {
27 pub fn new() -> Self {
29 Frame {
30 clauses: Vec::new(),
31 }
32 }
33
34 pub fn from_clauses(clauses: Vec<Vec<Lit>>) -> Self {
36 Frame { clauses }
37 }
38
39 pub fn add_clause(&mut self, clause: Vec<Lit>) {
41 let mut sorted: Vec<u32> = clause.iter().map(|l| l.code()).collect();
43 sorted.sort();
44
45 let is_dup = self.clauses.iter().any(|existing| {
47 let mut ex_sorted: Vec<u32> = existing.iter().map(|l| l.code()).collect();
48 ex_sorted.sort();
49 ex_sorted == sorted
50 });
51
52 if !is_dup {
53 self.clauses.push(clause);
54 }
55 }
56
57 pub fn clauses(&self) -> &[Vec<Lit>] {
59 &self.clauses
60 }
61
62 pub fn len(&self) -> usize {
64 self.clauses.len()
65 }
66
67 pub fn is_empty(&self) -> bool {
69 self.clauses.is_empty()
70 }
71}
72
73impl Default for Frame {
74 fn default() -> Self {
75 Self::new()
76 }
77}
78
79pub struct FrameSequence {
88 frames: Vec<Frame>,
89}
90
91impl FrameSequence {
92 pub fn new() -> Self {
94 FrameSequence {
95 frames: Vec::new(),
96 }
97 }
98
99 pub fn push(&mut self, frame: Frame) {
101 self.frames.push(frame);
102 }
103
104 pub fn frontier(&self) -> usize {
106 self.frames.len().saturating_sub(1)
107 }
108
109 pub fn len(&self) -> usize {
111 self.frames.len()
112 }
113
114 pub fn frame(&self, level: usize) -> &Frame {
116 &self.frames[level]
117 }
118
119 pub fn frame_mut(&mut self, level: usize) -> &mut Frame {
121 &mut self.frames[level]
122 }
123
124 pub fn add_blocked_clause(&mut self, level: usize, clause: Vec<Lit>) {
127 for i in 1..=level {
128 if i < self.frames.len() {
129 self.frames[i].add_clause(clause.clone());
130 }
131 }
132 }
133
134 pub fn check_convergence(&self) -> Option<usize> {
138 if self.frames.len() < 3 {
139 return None; }
141 for i in 1..self.frames.len() - 1 {
142 if frames_equal(&self.frames[i], &self.frames[i + 1]) {
143 return Some(i);
144 }
145 }
146 None
147 }
148}
149
150impl Default for FrameSequence {
151 fn default() -> Self {
152 Self::new()
153 }
154}
155
156fn frames_equal(a: &Frame, b: &Frame) -> bool {
158 if a.len() != b.len() {
159 return false;
160 }
161 let normalize = |f: &Frame| -> Vec<Vec<u32>> {
163 let mut clauses: Vec<Vec<u32>> = f
164 .clauses()
165 .iter()
166 .map(|c| {
167 let mut sorted: Vec<u32> = c.iter().map(|l| l.code()).collect();
168 sorted.sort();
169 sorted
170 })
171 .collect();
172 clauses.sort();
173 clauses
174 };
175 normalize(a) == normalize(b)
176}
177
178#[cfg(test)]
183mod tests {
184 use super::*;
185
186 #[test]
187 fn frame_add_and_read() {
188 let mut frame = Frame::new();
189 frame.add_clause(vec![Lit::pos(0), Lit::neg(1)]);
190 assert_eq!(frame.len(), 1);
191 assert_eq!(frame.clauses()[0].len(), 2);
192 }
193
194 #[test]
195 fn frames_equal_order_independent() {
196 let mut a = Frame::new();
197 a.add_clause(vec![Lit::pos(0)]);
198 a.add_clause(vec![Lit::neg(1)]);
199
200 let mut b = Frame::new();
201 b.add_clause(vec![Lit::neg(1)]);
202 b.add_clause(vec![Lit::pos(0)]);
203
204 assert!(frames_equal(&a, &b));
205 }
206
207 #[test]
208 fn convergence_detected() {
209 let mut seq = FrameSequence::new();
210 seq.push(Frame::new()); let mut f1 = Frame::new();
213 f1.add_clause(vec![Lit::neg(0)]);
214 seq.push(f1); let mut f2 = Frame::new();
217 f2.add_clause(vec![Lit::neg(0)]);
218 seq.push(f2); assert_eq!(seq.check_convergence(), Some(1));
221 }
222
223 #[test]
224 fn no_convergence_when_different() {
225 let mut seq = FrameSequence::new();
226 seq.push(Frame::new()); let mut f1 = Frame::new();
229 f1.add_clause(vec![Lit::neg(0)]);
230 seq.push(f1);
231
232 let f2 = Frame::new(); seq.push(f2);
234
235 assert_eq!(seq.check_convergence(), None);
236 }
237}