varisat 0.2.2

A CDCL based SAT solver (library)
Documentation
//! Global model reconstruction

use partial_ref::{partial, PartialRef};

use varisat_formula::Lit;
use varisat_internal_proof::ProofStep;

use crate::{
    context::{parts::*, Context},
    proof,
    state::SatState,
};

/// Global model reconstruction
#[derive(Default)]
pub struct Model {
    /// Assignment of the global model.
    ///
    /// Whenever the solver state is SAT this must be up to date.
    assignment: Vec<Option<bool>>,
}

impl Model {
    /// Assignment of the global model.
    ///
    /// Only valid if the solver state is SAT.
    pub fn assignment(&self) -> &[Option<bool>] {
        &self.assignment
    }

    /// Whether a given global literal is true in the model assignment.
    ///
    /// Only valid if the solver state is SAT.
    pub fn lit_is_true(&self, global_lit: Lit) -> bool {
        self.assignment[global_lit.index()] == Some(global_lit.is_positive())
    }
}

pub fn reconstruct_global_model<'a>(
    mut ctx: partial!(
        Context<'a>,
        mut ModelP,
        mut ProofP<'a>,
        mut SolverStateP,
        mut TmpDataP,
        AssignmentP,
        VariablesP
    ),
) {
    let (variables, mut ctx) = ctx.split_part(VariablesP);
    let (model, mut ctx) = ctx.split_part_mut(ModelP);
    let (tmp, mut ctx) = ctx.split_part_mut(TmpDataP);

    let models_in_proof = ctx.part(ProofP).models_in_proof();

    tmp.lits.clear();

    model.assignment.clear();
    model.assignment.resize(variables.global_watermark(), None);

    for global_var in variables.global_var_iter() {
        let value = if let Some(solver_var) = variables.solver_from_global().get(global_var) {
            ctx.part(AssignmentP).var_value(solver_var)
        } else {
            Some(variables.var_data_global(global_var).unit.unwrap_or(false))
        };

        model.assignment[global_var.index()] = value;

        if models_in_proof {
            if let Some(value) = value {
                tmp.lits.push(global_var.lit(value))
            }
        }
    }

    if models_in_proof {
        proof::add_step(
            ctx.borrow(),
            false,
            &ProofStep::Model {
                assignment: &tmp.lits,
            },
        );
    }
    ctx.part_mut(SolverStateP).sat_state = SatState::Sat;
}