-- File: lean/ExprSpec.lean -- Expression Evaluator Specification -- Agents migrate a C recursive-descent evaluator to Rust. -- Division by zero returns none (Option Int), not a panic. namespace ExprSpec inductive Op | Add | Sub | Mul | Div deriving BEq, DecidableEq, Repr inductive Expr | Lit (n : Int) | BinOp (op : Op) (l r : Expr) deriving BEq, DecidableEq, Repr -- Evaluate a binary operation; division by zero yields none def evalBinOp (op : Op) (a b : Int) : Option Int := match op with | .Add => some (a + b) | .Sub => some (a - b) | .Mul => some (a * b) | .Div => if b = 0 then none else some (a / b) -- Recursively evaluate an expression tree; propagate none on div-by-zero def evalExpr : Expr → Option Int | .Lit n => some n | .BinOp op l r => match evalExpr l, evalExpr r with | some a, some b => evalBinOp op a b | _, _ => none -- Division by zero always returns none theorem division_by_zero (a : Int) : evalBinOp .Div a 0 = none := by simp [evalBinOp] -- DRT checks example : evalBinOp .Add 3 4 = some 7 := by native_decide example : evalBinOp .Sub 10 3 = some 7 := by native_decide example : evalBinOp .Mul 3 4 = some 12 := by native_decide example : evalBinOp .Div 10 2 = some 5 := by native_decide example : evalBinOp .Div 10 0 = none := by native_decide example : evalExpr (.Lit 42) = some 42 := by native_decide example : evalExpr (.BinOp .Add (.Lit 1) (.Lit 2)) = some 3 := by native_decide example : evalExpr (.BinOp .Div (.Lit 5) (.Lit 0)) = none := by native_decide end ExprSpec