use pumpkin_checking::BoxedChecker;
use pumpkin_checking::InferenceChecker;
use crate::predicates::Predicate;
use crate::proof::ConstraintTag;
use crate::proof::InferenceCode;
use crate::proof::InferenceLabel;
#[cfg(doc)]
use crate::propagation::PropagatorConstructor;
#[derive(Clone, Debug)]
pub struct RuntimeCheckers {
inference_checkers: Vec<(InferenceCode, BoxedChecker<Predicate>)>,
}
impl RuntimeCheckers {
pub fn empty() -> RuntimeCheckers {
RuntimeCheckers {
inference_checkers: vec![],
}
}
pub fn builder() -> RuntimeCheckersBuilder {
RuntimeCheckersBuilder {
checkers: RuntimeCheckers {
inference_checkers: vec![],
},
}
}
pub fn add_inference_checker(
&mut self,
constraint_tag: ConstraintTag,
inference_label: impl InferenceLabel,
checker: impl InferenceChecker<Predicate> + 'static,
) -> InferenceCode {
let inference_code = InferenceCode::new(constraint_tag, inference_label);
self.inference_checkers
.push((inference_code.clone(), BoxedChecker::new(Box::new(checker))));
inference_code
}
}
impl IntoIterator for RuntimeCheckers {
type Item = (InferenceCode, BoxedChecker<Predicate>);
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.inference_checkers.into_iter()
}
}
#[derive(Clone, Debug)]
pub struct RuntimeCheckersBuilder {
checkers: RuntimeCheckers,
}
impl RuntimeCheckersBuilder {
pub fn add_inference_checker(
&mut self,
constraint_tag: ConstraintTag,
inference_label: impl InferenceLabel,
checker: impl InferenceChecker<Predicate> + 'static,
) -> InferenceCode {
self.checkers
.add_inference_checker(constraint_tag, inference_label, checker)
}
pub fn build(self) -> RuntimeCheckers {
if cfg!(feature = "check-propagations") {
assert!(
!self.checkers.inference_checkers.is_empty(),
"did not register any inference checkers"
);
}
self.checkers
}
}