1use partial_ref::{partial, PartialRef};
4
5use varisat_formula::Lit;
6use varisat_internal_proof::ProofStep;
7
8use crate::{
9 context::{parts::*, Context},
10 proof,
11 state::SatState,
12};
13
14#[derive(Default)]
16pub struct Model {
17 assignment: Vec<Option<bool>>,
21}
22
23impl Model {
24 pub fn assignment(&self) -> &[Option<bool>] {
28 &self.assignment
29 }
30
31 pub fn lit_is_true(&self, global_lit: Lit) -> bool {
35 self.assignment[global_lit.index()] == Some(global_lit.is_positive())
36 }
37}
38
39pub fn reconstruct_global_model<'a>(
40 mut ctx: partial!(
41 Context<'a>,
42 mut ModelP,
43 mut ProofP<'a>,
44 mut SolverStateP,
45 mut TmpDataP,
46 AssignmentP,
47 VariablesP
48 ),
49) {
50 let (variables, mut ctx) = ctx.split_part(VariablesP);
51 let (model, mut ctx) = ctx.split_part_mut(ModelP);
52 let (tmp, mut ctx) = ctx.split_part_mut(TmpDataP);
53
54 let models_in_proof = ctx.part(ProofP).models_in_proof();
55
56 tmp.lits.clear();
57
58 model.assignment.clear();
59 model.assignment.resize(variables.global_watermark(), None);
60
61 for global_var in variables.global_var_iter() {
62 let value = if let Some(solver_var) = variables.solver_from_global().get(global_var) {
63 ctx.part(AssignmentP).var_value(solver_var)
64 } else {
65 Some(variables.var_data_global(global_var).unit.unwrap_or(false))
66 };
67
68 model.assignment[global_var.index()] = value;
69
70 if models_in_proof {
71 if let Some(value) = value {
72 tmp.lits.push(global_var.lit(value))
73 }
74 }
75 }
76
77 if models_in_proof {
78 proof::add_step(
79 ctx.borrow(),
80 false,
81 &ProofStep::Model {
82 assignment: &tmp.lits,
83 },
84 );
85 }
86 ctx.part_mut(SolverStateP).sat_state = SatState::Sat;
87}