oxiz_solver/solver/
config.rs1use oxiz_core::ast::{TermId, TermKind, TermManager};
8use oxiz_theories::arithmetic::ArithSolver;
9
10use super::Solver;
11use super::types::Polarity;
12
13impl Solver {
14 pub fn set_logic(&mut self, logic: &str) {
16 self.logic = Some(logic.to_string());
17
18 if logic.contains("NIA") {
21 #[cfg(feature = "std")]
23 {
24 self.nlsat = Some(oxiz_theories::nlsat::NlsatTheory::new(true));
25 }
26 self.arith = ArithSolver::lia(); #[cfg(feature = "tracing")]
28 tracing::info!("Using NLSAT solver for QF_NIA (nonlinear integer arithmetic)");
29 } else if logic.contains("NRA") {
30 #[cfg(feature = "std")]
32 {
33 self.nlsat = Some(oxiz_theories::nlsat::NlsatTheory::new(false));
34 }
35 self.arith = ArithSolver::lra(); #[cfg(feature = "tracing")]
37 tracing::info!("Using NLSAT solver for QF_NRA (nonlinear real arithmetic)");
38 } else if logic.contains("LIA") || logic.contains("IDL") {
39 self.arith = ArithSolver::lia();
41 } else if logic.contains("LRA") || logic.contains("RDL") {
42 self.arith = ArithSolver::lra();
44 } else if logic.contains("BV") {
45 self.arith = ArithSolver::lia();
48 }
49 }
51
52 pub(super) fn extract_dt_var_constructor(
55 &self,
56 lhs: TermId,
57 rhs: TermId,
58 manager: &TermManager,
59 ) -> Option<(TermId, oxiz_core::interner::Spur)> {
60 let lhs_term = manager.get(lhs)?;
61 let rhs_term = manager.get(rhs)?;
62
63 if matches!(lhs_term.kind, TermKind::Var(_)) {
65 if let TermKind::DtConstructor { constructor, .. } = &rhs_term.kind {
66 return Some((lhs, *constructor));
67 }
68 }
69 if matches!(rhs_term.kind, TermKind::Var(_)) {
71 if let TermKind::DtConstructor { constructor, .. } = &lhs_term.kind {
72 return Some((rhs, *constructor));
73 }
74 }
75 None
76 }
77
78 pub(super) fn collect_polarities(
81 &mut self,
82 term: TermId,
83 polarity: Polarity,
84 manager: &TermManager,
85 ) {
86 let current = self.polarities.get(&term).copied();
88 let new_polarity = match (current, polarity) {
89 (Some(Polarity::Both), _) | (_, Polarity::Both) => Polarity::Both,
90 (Some(Polarity::Positive), Polarity::Negative)
91 | (Some(Polarity::Negative), Polarity::Positive) => Polarity::Both,
92 (Some(p), _) => p,
93 (None, p) => p,
94 };
95 self.polarities.insert(term, new_polarity);
96
97 if current == Some(Polarity::Both) {
99 return;
100 }
101
102 let Some(t) = manager.get(term) else {
104 return;
105 };
106
107 match &t.kind {
108 TermKind::Not(arg) => {
109 let neg_polarity = match polarity {
110 Polarity::Positive => Polarity::Negative,
111 Polarity::Negative => Polarity::Positive,
112 Polarity::Both => Polarity::Both,
113 };
114 self.collect_polarities(*arg, neg_polarity, manager);
115 }
116 TermKind::And(args) | TermKind::Or(args) => {
117 for &arg in args {
118 self.collect_polarities(arg, polarity, manager);
119 }
120 }
121 TermKind::Implies(lhs, rhs) => {
122 let neg_polarity = match polarity {
123 Polarity::Positive => Polarity::Negative,
124 Polarity::Negative => Polarity::Positive,
125 Polarity::Both => Polarity::Both,
126 };
127 self.collect_polarities(*lhs, neg_polarity, manager);
128 self.collect_polarities(*rhs, polarity, manager);
129 }
130 TermKind::Ite(cond, then_br, else_br) => {
131 self.collect_polarities(*cond, Polarity::Both, manager);
132 self.collect_polarities(*then_br, polarity, manager);
133 self.collect_polarities(*else_br, polarity, manager);
134 }
135 TermKind::Xor(lhs, rhs) | TermKind::Eq(lhs, rhs) => {
136 self.collect_polarities(*lhs, Polarity::Both, manager);
138 self.collect_polarities(*rhs, Polarity::Both, manager);
139 }
140 _ => {
141 }
143 }
144 }
145}