1use crate::{Lit, LitVec};
2use std::{
3 ops::{Deref, DerefMut},
4 slice, vec,
5};
6
7#[derive(Debug, Clone, Default)]
8pub struct LitVvec {
9 vec: Vec<LitVec>,
10}
11
12impl LitVvec {
13 #[inline]
14 pub fn new() -> Self {
15 Self::default()
16 }
17
18 #[inline]
19 pub fn cnf_and(n: Lit, lits: &[Lit]) -> Self {
20 let mut vec = Vec::new();
21 let mut cls = LitVec::from([n]);
22 for l in lits.iter() {
23 vec.push(LitVec::from([!n, *l]));
24 cls.push(!*l);
25 }
26 vec.push(cls);
27 Self { vec }
28 }
29
30 #[inline]
31 pub fn cnf_or(n: Lit, lits: &[Lit]) -> Self {
32 let mut vec = Vec::new();
33 let mut cls = LitVec::from([!n]);
34 for l in lits.iter() {
35 vec.push(LitVec::from([n, !*l]));
36 cls.push(*l);
37 }
38 vec.push(cls);
39 Self { vec }
40 }
41
42 #[inline]
43 pub fn cnf_assign(n: Lit, s: Lit) -> Self {
44 Self {
45 vec: vec![LitVec::from([n, !s]), LitVec::from([!n, s])],
46 }
47 }
48
49 #[inline]
50 pub fn cnf_xor(n: Lit, x: Lit, y: Lit) -> Self {
51 Self {
52 vec: vec![
53 LitVec::from([!x, y, n]),
54 LitVec::from([x, !y, n]),
55 LitVec::from([x, y, !n]),
56 LitVec::from([!x, !y, !n]),
57 ],
58 }
59 }
60
61 #[inline]
62 pub fn cnf_xnor(n: Lit, x: Lit, y: Lit) -> Self {
63 Self {
64 vec: vec![
65 LitVec::from([!x, y, !n]),
66 LitVec::from([x, !y, !n]),
67 LitVec::from([x, y, n]),
68 LitVec::from([!x, !y, n]),
69 ],
70 }
71 }
72
73 #[inline]
74 pub fn cnf_ite(n: Lit, c: Lit, t: Lit, e: Lit) -> Self {
75 Self {
76 vec: vec![
77 LitVec::from([t, !c, !n]),
78 LitVec::from([!t, !c, n]),
79 LitVec::from([e, c, !n]),
80 LitVec::from([!e, c, n]),
81 ],
82 }
83 }
84
85 pub fn subsume_simplify(&mut self) {
86 self.sort_by_key(|l| l.len());
87 for c in self.iter_mut() {
88 c.sort();
89 }
90 let mut i = 0;
91 while i < self.len() {
92 if self[i].is_empty() {
93 i += 1;
94 continue;
95 }
96 let mut update = false;
97 for j in 0..self.len() {
98 if i == j {
99 continue;
100 }
101 if self[j].is_empty() {
102 continue;
103 }
104 let (res, diff) = self[i].ordered_subsume_execpt_one(&self[j]);
105 if res {
106 self[j] = Default::default();
107 continue;
108 } else if let Some(diff) = diff {
109 if self[i].len() == self[j].len() {
110 update = true;
111 self[i].retain(|l| *l != diff);
112 self[j] = Default::default();
113 } else {
114 self[j].retain(|l| *l != !diff);
115 }
116 }
117 }
118 if !update {
119 i += 1;
120 }
121 }
122 self.retain(|l| !l.is_empty());
123 }
124}
125
126impl Deref for LitVvec {
127 type Target = Vec<LitVec>;
128
129 #[inline]
130 fn deref(&self) -> &Self::Target {
131 &self.vec
132 }
133}
134
135impl DerefMut for LitVvec {
136 #[inline]
137 fn deref_mut(&mut self) -> &mut Self::Target {
138 &mut self.vec
139 }
140}
141
142impl IntoIterator for LitVvec {
143 type Item = LitVec;
144 type IntoIter = vec::IntoIter<LitVec>;
145
146 #[inline]
147 fn into_iter(self) -> Self::IntoIter {
148 self.vec.into_iter()
149 }
150}
151
152impl<'a> IntoIterator for &'a LitVvec {
153 type Item = &'a LitVec;
154 type IntoIter = slice::Iter<'a, LitVec>;
155
156 #[inline]
157 fn into_iter(self) -> Self::IntoIter {
158 self.vec.iter()
159 }
160}
161
162impl FromIterator<LitVec> for LitVvec {
163 #[inline]
164 fn from_iter<T: IntoIterator<Item = LitVec>>(iter: T) -> Self {
165 Self {
166 vec: Vec::from_iter(iter),
167 }
168 }
169}