veripb 3.0.2

VeriPB is a proof checker for verifying pseudo-Boolean certificates of satisfiability, unsatisfiability, and optimality bounds.
Documentation
use std::{fmt::Display, rc::Rc};

use veripb_formula::prelude::DBConstraint;

use crate::prelude::*;

#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
pub enum ScopeId {
    LessEqual = 0,
    GreaterEqual = 1,
}

impl Display for ScopeId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ScopeId::LessEqual => write!(f, "leq"),
            ScopeId::GreaterEqual => write!(f, "geq"),
        }
    }
}

#[derive(Debug)]
pub struct ScopeRule {
    id: ScopeId,
}

impl ScopeRule {
    pub fn new(id: ScopeId) -> Self {
        Self { id }
    }
}

impl Rule for ScopeRule {
    #[inline]
    fn compute(
        &mut self,
        context: &mut Context,
        database: &mut Database,
    ) -> Result<Vec<Rc<DBConstraint>>, CheckingError> {
        if let Some(Subcontext::Subproof(subproof_context)) = context.subcontexts.last_mut() {
            let premises = if let Some(active_order) = &mut context.active_order {
                match self.id {
                    ScopeId::LessEqual => active_order.get_specification_less_equal(),
                    ScopeId::GreaterEqual => {
                        active_order.get_specification_greater_equal(&subproof_context.witness)
                    }
                }
            } else {
                vec![]
            };

            if subproof_context.current_scope.is_some() {
                return Err(CheckingError::StartScopeWhileOtherScopeOpen);
            }
            subproof_context.scope_start_id = database.len();
            subproof_context.current_scope = Some(self.id);

            Ok(premises)
        } else {
            Err(CheckingError::ScopeOutsideSubproof)
        }
    }

    #[inline]
    fn is_subproof_friendly(&self) -> bool {
        true
    }

    #[inline]
    fn elaborate(
        &self,
        context: &mut Context,
        _database: &Database,
    ) -> Result<(), ElaborationError> {
        let elaborator = context.elaborator.as_mut().unwrap();
        elaborator.write("\tscope ");
        elaborator.writeln(&self.id.to_string());
        Ok(())
    }
}