use super::common::{SmtCheckResult, SmtChecker, SmtObligation};
use crate::verify::{contract::Property, helpers::Checkpoint, verifier::ForwardVisitResult};
pub(crate) fn check<'tcx>(
checker: &SmtChecker<'tcx>,
checkpoint: &Checkpoint<'tcx>,
property: &Property<'tcx>,
forward: &ForwardVisitResult<'tcx>,
) -> SmtCheckResult {
let Some(smt_predicates) =
checker.property_numeric_smt_predicates(checkpoint, property, Some(forward))
else {
return SmtCheckResult::unknown("ValidNum predicate could not be lowered to SMT");
};
if checker.validnum_is_slice_size_invariant(checkpoint, property, forward) {
return SmtCheckResult::proved(
"ValidNum proved: slice-size language invariant size_of(T) * slice.len() <= isize::MAX",
);
}
if checker.validnum_is_align_nonzero(checkpoint, property, forward) {
return SmtCheckResult::proved("ValidNum proved: align_of::<T>() >= 1 for every T");
}
if let Some(reason) = super::provenance::vec_from_raw_parts_roundtrip(checker, checkpoint) {
return SmtCheckResult::proved(format!("ValidNum proved: {reason}"));
}
checker.prove_obligation(
checkpoint,
forward,
SmtObligation::Predicate {
predicates: smt_predicates,
},
property.null_guard.as_ref(),
)
}