1mod build;
4mod conflict;
6pub mod restart;
8mod search;
10mod stage;
12mod validate;
14
15pub use self::{
16 build::SatSolverIF,
17 restart::{RestartIF, RestartManager},
18 search::SolveIF,
19 stage::StageManager,
20 validate::ValidateIF,
21};
22
23use crate::{assign::AssignStack, cdb::ClauseDB, state::*, types::*};
24
25#[derive(Debug, Eq, PartialEq)]
27pub enum Certificate {
28 SAT(Vec<i32>),
30 UNSAT,
32}
33
34pub type SolverResult = Result<Certificate, SolverError>;
40
41#[derive(Clone, Copy, Debug, Eq, PartialEq)]
43pub enum SolverEvent {
44 Assert(VarId),
46 Conflict,
48 Eliminate(VarId),
50 Instantiate,
52 NewVar,
54 Reinitialize,
56 Restart,
58 Stage(usize),
60
61 #[cfg(feature = "clause_vivification")]
62 Vivify(bool),
64}
65
66#[derive(Clone, Debug, Default)]
85pub struct Solver {
86 pub asg: AssignStack,
88 pub cdb: ClauseDB,
90 pub state: State,
92}
93
94impl<V: AsRef<[i32]>> TryFrom<Vec<V>> for Certificate {
115 type Error = SolverError;
116 fn try_from(vec: Vec<V>) -> SolverResult {
117 Solver::try_from((Config::default(), vec.as_ref())).map_or_else(
118 |e: SolverResult| match e {
119 Ok(cert) => Ok(cert),
120 Err(SolverError::EmptyClause) => Ok(Certificate::UNSAT),
121 Err(e) => Err(e),
122 },
123 |mut solver| solver.solve(),
124 )
125 }
126}
127
128#[cfg(feature = "incremental_solver")]
135pub struct SolverIter<'a> {
136 solver: &'a mut Solver,
137 refute: Option<Vec<i32>>,
138}
139
140#[cfg(feature = "incremental_solver")]
141impl Solver {
142 pub fn iter(&mut self) -> SolverIter {
152 SolverIter {
153 solver: self,
154 refute: None,
155 }
156 }
157}
158
159#[cfg(feature = "incremental_solver")]
160impl<'a> Iterator for SolverIter<'a> {
161 type Item = Vec<i32>;
162 fn next(&mut self) -> Option<Self::Item> {
163 if let Some(ref v) = self.refute {
164 debug_assert!(1 < v.len());
165 match self.solver.add_clause(v) {
166 Err(SolverError::Inconsistent) => return None,
167 Err(SolverError::EmptyClause) => return None,
168 Err(e) => panic!("s UNKNOWN: {:?} by adding {:?}", e, v),
169 Ok(_) => self.solver.reset(),
170 }
171 self.refute = None;
172 }
173 match self.solver.solve() {
174 Ok(Certificate::SAT(ans)) => {
175 let rft: Vec<i32> = ans.iter().map(|i| -i).collect::<Vec<i32>>();
176 self.refute = Some(rft);
177 Some(ans)
178 }
179 Ok(Certificate::UNSAT) => None,
180 e => panic!("s UNKNOWN: {:?}", e),
181 }
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188 use crate::assign;
189
190 #[cfg_attr(not(feature = "no_IO"), test)]
191 fn test_solver() {
192 let config = Config::from("cnfs/sample.cnf");
193 if let Ok(s) = Solver::build(&config) {
194 assert_eq!(s.asg.derefer(assign::property::Tusize::NumVar), 250);
195 assert_eq!(
196 s.asg.derefer(assign::property::Tusize::NumUnassertedVar),
197 250
198 );
199 } else {
200 panic!("failed to build a solver for cnfs/sample.cnf");
201 }
202 }
203
204 macro_rules! run {
205 ($vec: expr) => {
206 println!(
207 "{:>46} =| {:?}",
208 format!("{:?}", $vec),
209 match Solver::try_from((Config::default(), $vec.as_ref())).map(|mut s| s.solve()) {
210 Err(e) => e,
211 Ok(Ok(u @ Certificate::UNSAT)) => Ok(u),
212 Ok(s) => s,
213 }
214 );
215 };
216 }
217
218 macro_rules! sat {
219 ($vec: expr, $should_be: pat) => {
220 println!("{:>46} =| ", format!("{:?}", $vec));
221 let result = Certificate::try_from($vec);
222 println!("{:?}", result);
223 assert!(matches!(result, $should_be));
224 };
225 ($vec: expr) => {
226 println!(
227 "{:>46} =| {:?}",
228 format!("{:?}", $vec),
229 Certificate::try_from($vec)
230 );
231 };
232 }
233
234 #[test]
235 fn test_on_memory_solving() {
236 let mut v: Vec<Vec<i32>> = Vec::new();
237 run!(v);
238 v.push(Vec::new());
239 run!(v);
240 run!(vec![vec![1]]);
241 run!(vec![vec![1], vec![-1]]);
242 run!(vec![vec![1, 2], vec![-1, 3], vec![1, -3], vec![-1, 2]]);
243 run!(vec![
244 vec![1, 2],
245 vec![-1, 3],
246 vec![1, -3],
247 vec![-1, -2],
248 vec![-2, -3]
249 ]);
250 run!(vec![
251 vec![1, 2],
252 vec![-1, 3],
253 vec![-1, -3],
254 vec![-1, -2],
255 vec![1, -2]
256 ]);
257
258 let (v1, v2, v3, v4, v5) = (vec![1, 2], vec![-1, 3], vec![1, -3], vec![-1, 2], vec![-3]);
260 run!(vec![&v1, &v2, &v3, &v4, &v5]); run!([&v1, &v2, &v3, &v4, &v5]); let v0: Vec<Vec<i32>> = vec![];
271 sat!(v0, Ok(Certificate::SAT(_)));
272 let v1: Vec<Vec<i32>> = vec![vec![]];
273 sat!(v1, Ok(Certificate::UNSAT));
274 sat!(vec![vec![1i32]], Ok(Certificate::SAT(_)));
275 sat!(vec![vec![1i32], vec![-1]], Ok(Certificate::UNSAT));
276 sat!(vec![vec![1i32, 2], vec![-1, 3], vec![1, -3], vec![-1, 2]]);
277 sat!(vec![
278 vec![1i32, 2],
279 vec![-1, 3],
280 vec![1, -3],
281 vec![-1, -2],
282 vec![-2, -3]
283 ]);
284 sat!(vec![
285 vec![1i32, 2],
286 vec![-1, 3],
287 vec![-1, -3],
288 vec![-1, -2],
289 vec![1, -2]
290 ]);
291 let (v1, v2, v3, v4, v5) = (
292 vec![1i32, 2],
293 vec![-1i32, 3],
294 vec![1i32, -3],
295 vec![-1i32, 2],
296 vec![-3i32],
297 );
298 sat!(vec![&v1, &v2, &v3, &v4, &v5]); }
300
301 #[cfg(feature = "incremental_solver")]
302 #[test]
303 fn test_solver_iter() {
304 let mut slv = Solver::instantiate(
305 &Config::default(),
306 &CNFDescription {
307 num_of_variables: 8,
308 ..CNFDescription::default()
309 },
310 );
311 assert_eq!(slv.iter().count(), 256);
312 }
313 #[cfg(feature = "incremental_solver")]
314 #[test]
315 fn test_add_var_on_incremental_solver() {
316 let mut slv = Solver::instantiate(
317 &Config::default(),
318 &CNFDescription {
319 num_of_variables: 4,
320 ..CNFDescription::default()
321 },
322 );
323 assert!(slv.add_clause(vec![-1, -2]).is_ok());
324 assert!(slv.add_clause(vec![-3, -4]).is_ok());
325 assert!(slv.add_assignment(-2).is_ok());
326 let a = slv.add_var() as i32;
327 assert!(slv.add_clause(vec![1, 3, 4, -a]).is_ok());
328 assert!(slv.add_clause(vec![1, -3, -4, -a]).is_ok());
329 assert!(slv.add_clause(vec![-1, 3, -4, -a]).is_ok());
330 assert!(slv.add_clause(vec![-1, -3, 4, -a]).is_ok());
331 assert!(slv.add_clause(vec![-1, -3, -4, a]).is_ok());
332 assert!(slv.add_clause(vec![-1, 3, 4, a]).is_ok());
333 assert!(slv.add_clause(vec![1, -3, 4, a]).is_ok());
334 assert!(slv.add_clause(vec![1, 3, -4, a]).is_ok());
335 let b = slv.add_var() as i32;
336 assert!(slv.add_clause(vec![1, 3, -b]).is_ok());
337 assert!(slv.add_clause(vec![1, 4, -b]).is_ok());
338 assert!(slv.add_clause(vec![3, 4, -b]).is_ok());
339 assert!(slv.add_clause(vec![-1, -3, b]).is_ok());
340 assert!(slv.add_clause(vec![-1, -4, b]).is_ok());
341 assert!(slv.add_clause(vec![-3, -4, b]).is_ok());
342 assert!(slv.add_clause(vec![-1, -b]).is_ok());
343 assert!(slv.add_clause(vec![-a, -b]).is_ok());
344 assert_eq!(slv.iter().count(), 4);
348 }
349 #[cfg(feature = "incremental_solver")]
350 #[test]
351 fn test_add_var_and_add_assignment() {
353 let mut slv = Solver::instantiate(
354 &Config::default(),
355 &CNFDescription {
356 num_of_variables: 3 as usize,
357 ..CNFDescription::default()
358 },
359 );
360
361 slv.add_var();
362 assert!(slv.add_clause(vec![-1, 4]).is_ok());
363 slv.add_var();
364 assert!(slv.add_clause(vec![-2, 5]).is_ok());
365 slv.add_var();
366 assert!(slv.add_clause(vec![-1, -2, 6]).is_ok());
367 slv.add_var();
368 assert!(slv.add_clause(vec![-5, 7]).is_ok());
369 slv.add_var();
370 assert!(slv.add_clause(vec![-6, 8]).is_ok());
371 slv.add_var();
372 assert!(slv.add_clause(vec![-4, 9]).is_ok());
373 slv.add_var();
374 assert!(slv.add_clause(vec![-3, 10]).is_ok());
375 slv.add_var();
376 assert!(slv.add_clause(vec![-5, -3, 11]).is_ok());
377 assert!(slv.add_clause(vec![-6, -3, 11]).is_ok());
378 slv.add_var();
379 assert!(slv.add_clause(vec![-4, -3, 12]).is_ok());
380 assert!(slv.add_assignment(-11).is_ok());
381 assert!(slv.solve().is_ok());
382 }
383}