logicaffeine_tv/
tensor.rs1use logicaffeine_compile::tensor_graph::smt::{Lemma, Obligation};
9use z3::{Params, SatResult, Solver};
10
11#[derive(Clone, Debug, PartialEq, Eq)]
13pub enum Verdict {
14 Proven,
16 Refuted(String),
18 Vacuous,
20 Unknown(String),
22}
23
24fn solver(text: &str, timeout_ms: u32) -> Solver {
25 let s = Solver::new();
26 let mut params = Params::new();
27 params.set_u32("timeout", timeout_ms);
28 s.set_params(¶ms);
29 s.from_string(text.to_string());
30 s
31}
32
33pub fn discharge(o: &Obligation, timeout_ms: u32) -> Verdict {
36 for lemma in &o.lemmas {
37 let verdict = lemma_verdict(lemma, timeout_ms);
38 if verdict != Verdict::Proven {
39 return verdict;
40 }
41 }
42 Verdict::Proven
43}
44
45fn lemma_verdict(lemma: &Lemma, timeout_ms: u32) -> Verdict {
46 let premises = solver(&lemma.premises, timeout_ms);
47 match premises.check() {
48 SatResult::Sat => {}
49 SatResult::Unsat => return Verdict::Vacuous,
50 SatResult::Unknown => return Verdict::Unknown(premises.get_reason_unknown().unwrap_or_default()),
51 }
52 let whole = solver(&lemma.text(), timeout_ms);
53 match whole.check() {
54 SatResult::Unsat => Verdict::Proven,
55 SatResult::Sat => Verdict::Refuted(whole.get_model().map(|m| m.to_string()).unwrap_or_default()),
56 SatResult::Unknown => Verdict::Unknown(whole.get_reason_unknown().unwrap_or_default()),
57 }
58}