use super::AutoProof;
use super::aver_name_to_lean;
use crate::ast::{VerifyBlock, VerifyLaw};
use crate::codegen::CodegenContext;
pub(super) fn emit_nonlinear_nonneg_law(
vb: &VerifyBlock,
law: &VerifyLaw,
ctx: &CodegenContext,
) -> Option<AutoProof> {
let Some(crate::ir::ProofStrategy::NonlinearNonneg { unfold_fns }) =
super::law_strategy_for(ctx, &vb.fn_name, &law.name)
else {
return None;
};
let cone: Vec<String> = unfold_fns.iter().map(|f| aver_name_to_lean(f)).collect();
let mut bridge = cone;
if law.when.is_some() {
bridge.push("Bool.and_eq_true".to_string());
}
bridge.push("ge_iff_le".to_string());
bridge.push("gt_iff_lt".to_string());
bridge.push("decide_eq_true_eq".to_string());
let simp_set = bridge.join(", ");
let givens: Vec<String> = law
.givens
.iter()
.map(|g| aver_name_to_lean(&g.name))
.collect();
let (intro_names, branch) = if law.when.is_some() {
let mut names = givens;
names.push("h_when".to_string());
(
names,
format!("simp only [{simp_set}] at h_when ⊢ <;> aver_int_order"),
)
} else {
(givens, format!("simp only [{simp_set}] <;> aver_int_order"))
};
Some(AutoProof {
support_lines: Vec::new(),
body: super::intro_then_first(&intro_names, vec![branch]),
replaces_theorem: false,
})
}