oxiz_solver/model/
builder.rs1#[allow(unused_imports)]
18use crate::prelude::*;
19use oxiz_sat::Lit;
20
21pub type VarId = u32;
23
24pub type SortId = u32;
26
27#[derive(Debug, Clone, PartialEq, Eq)]
29pub enum Value {
30 Bool(bool),
32 Int(i64),
34 Rational(i64, i64),
36 BitVec(u64, u32),
38 Uninterpreted(String),
40}
41
42#[derive(Debug, Clone)]
44pub struct Model {
45 pub bool_assignments: FxHashMap<Lit, bool>,
47 pub theory_assignments: FxHashMap<VarId, Value>,
49}
50
51impl Model {
52 pub fn new() -> Self {
54 Self {
55 bool_assignments: FxHashMap::default(),
56 theory_assignments: FxHashMap::default(),
57 }
58 }
59
60 pub fn assign_bool(&mut self, lit: Lit, value: bool) {
62 self.bool_assignments.insert(lit, value);
63 }
64
65 pub fn assign_theory(&mut self, var: VarId, value: Value) {
67 self.theory_assignments.insert(var, value);
68 }
69
70 pub fn get_bool(&self, lit: Lit) -> Option<bool> {
72 self.bool_assignments.get(&lit).copied()
73 }
74
75 pub fn get_theory(&self, var: VarId) -> Option<&Value> {
77 self.theory_assignments.get(&var)
78 }
79}
80
81impl Default for Model {
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87#[derive(Debug, Clone)]
89pub struct ModelBuilderConfig {
90 pub minimize: bool,
92 pub complete: bool,
94 pub default_int: i64,
96}
97
98impl Default for ModelBuilderConfig {
99 fn default() -> Self {
100 Self {
101 minimize: false,
102 complete: true,
103 default_int: 0,
104 }
105 }
106}
107
108#[derive(Debug, Clone, Default)]
110pub struct ModelBuilderStats {
111 pub models_built: u64,
113 pub vars_assigned: u64,
115 pub minimizations: u64,
117}
118
119pub struct ModelBuilder {
121 config: ModelBuilderConfig,
122 stats: ModelBuilderStats,
123}
124
125impl ModelBuilder {
126 pub fn new() -> Self {
128 Self::with_config(ModelBuilderConfig::default())
129 }
130
131 pub fn with_config(config: ModelBuilderConfig) -> Self {
133 Self {
134 config,
135 stats: ModelBuilderStats::default(),
136 }
137 }
138
139 pub fn stats(&self) -> &ModelBuilderStats {
141 &self.stats
142 }
143
144 pub fn build_model(
146 &mut self,
147 bool_assignment: &FxHashMap<Lit, bool>,
148 theory_models: Vec<FxHashMap<VarId, Value>>,
149 ) -> Model {
150 self.stats.models_built += 1;
151
152 let mut model = Model::new();
153
154 for (&lit, &value) in bool_assignment {
156 model.assign_bool(lit, value);
157 self.stats.vars_assigned += 1;
158 }
159
160 for theory_model in theory_models {
162 for (var, value) in theory_model {
163 if let Some(existing) = model.get_theory(var)
165 && existing != &value
166 {
167 continue;
169 }
170
171 model.assign_theory(var, value);
172 self.stats.vars_assigned += 1;
173 }
174 }
175
176 if self.config.complete {
178 self.complete_model(&mut model);
179 }
180
181 if self.config.minimize {
183 self.minimize_model(&mut model);
184 }
185
186 model
187 }
188
189 fn complete_model(&mut self, _model: &mut Model) {
191 }
194
195 fn minimize_model(&mut self, _model: &mut Model) {
197 self.stats.minimizations += 1;
198 }
201
202 pub fn validate(&self, _model: &Model) -> bool {
204 true
207 }
208}
209
210impl Default for ModelBuilder {
211 fn default() -> Self {
212 Self::new()
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn test_model_creation() {
222 let model = Model::new();
223 assert!(model.bool_assignments.is_empty());
224 assert!(model.theory_assignments.is_empty());
225 }
226
227 #[test]
228 fn test_bool_assignment() {
229 let mut model = Model::new();
230 let lit = Lit::from_dimacs(1);
231
232 model.assign_bool(lit, true);
233
234 assert_eq!(model.get_bool(lit), Some(true));
235 }
236
237 #[test]
238 fn test_theory_assignment() {
239 let mut model = Model::new();
240
241 model.assign_theory(0, Value::Int(42));
242
243 assert_eq!(model.get_theory(0), Some(&Value::Int(42)));
244 }
245
246 #[test]
247 fn test_builder_creation() {
248 let builder = ModelBuilder::new();
249 assert_eq!(builder.stats().models_built, 0);
250 }
251
252 #[test]
253 fn test_build_model() {
254 let mut builder = ModelBuilder::new();
255
256 let bool_map = FxHashMap::default();
257 let theory_models = vec![{
258 let mut m = FxHashMap::default();
259 m.insert(0, Value::Int(5));
260 m
261 }];
262
263 let model = builder.build_model(&bool_map, theory_models);
264
265 assert_eq!(model.get_theory(0), Some(&Value::Int(5)));
266 assert_eq!(builder.stats().models_built, 1);
267 }
268
269 #[test]
270 fn test_validate() {
271 let builder = ModelBuilder::new();
272 let model = Model::new();
273
274 assert!(builder.validate(&model));
275 }
276
277 #[test]
278 fn test_value_types() {
279 let mut model = Model::new();
280
281 model.assign_theory(0, Value::Bool(true));
282 model.assign_theory(1, Value::Int(42));
283 model.assign_theory(2, Value::Rational(3, 4));
284 model.assign_theory(3, Value::BitVec(0xFF, 8));
285
286 assert_eq!(model.get_theory(0), Some(&Value::Bool(true)));
287 assert_eq!(model.get_theory(1), Some(&Value::Int(42)));
288 assert_eq!(model.get_theory(2), Some(&Value::Rational(3, 4)));
289 assert_eq!(model.get_theory(3), Some(&Value::BitVec(0xFF, 8)));
290 }
291}