perf: encode `grind` ring certificate numerals as constructor applications This PR makes the `ToExpr` instances for the polynomials, monomials, and expressions of `Lean.Grind.CommRing` encode numerals as `Int.ofNat n`, `Int.negSucc n`, and raw `Nat` literals, so that the kernel no longer unfolds `OfNat.ofNat` and `Neg.neg` when it evaluates the certificates of the `grind` ring solver and of the `Sym.simp` arithmetic normalizer. Proof terms printed by `grind.debug.proof` now show these constructor applications. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
diff --git a/src/Lean/Meta/Sym/Arith/ToExpr.lean b/src/Lean/Meta/Sym/Arith/ToExpr.lean index 2467634..1b58e6a 100644 --- a/src/Lean/Meta/Sym/Arith/ToExpr.lean +++ b/src/Lean/Meta/Sym/Arith/ToExpr.lean
@@ -11,11 +11,19 @@ namespace Lean.Meta.Sym.Arith open Grind.CommRing /-! -`ToExpr` instances for `CommRing.Poly` types. +`ToExpr` instances for `CommRing.Poly` types. Numerals are constructor applications on raw +literals (`Int.ofNat n`, `Int.negSucc n`, and raw `Nat` literals), which the kernel evaluates +without unfolding `OfNat.ofNat` and `Neg.neg` when it checks certificates. -/ +/-- `k` as `Int.ofNat n` or `Int.negSucc n` on a raw literal. -/ +def mkIntLitK (k : Int) : Expr := + match k with + | .ofNat n => mkApp (mkConst ``Int.ofNat) (mkRawNatLit n) + | .negSucc n => mkApp (mkConst ``Int.negSucc) (mkRawNatLit n) + def ofPower (p : Power) : Expr := - mkApp2 (mkConst ``Power.mk) (toExpr p.x) (toExpr p.k) + mkApp2 (mkConst ``Power.mk) (mkRawNatLit p.x) (mkRawNatLit p.k) instance : ToExpr Power where toExpr := ofPower @@ -32,8 +40,8 @@ def ofPoly (p : Poly) : Expr := match p with - | .num k => mkApp (mkConst ``Poly.num) (toExpr k) - | .add k m p => mkApp3 (mkConst ``Poly.add) (toExpr k) (toExpr m) (ofPoly p) + | .num k => mkApp (mkConst ``Poly.num) (mkIntLitK k) + | .add k m p => mkApp3 (mkConst ``Poly.add) (mkIntLitK k) (toExpr m) (ofPoly p) instance : ToExpr Poly where toExpr := ofPoly @@ -43,15 +51,15 @@ def ofRingExpr (e : CommRing.Expr) : Expr := match e with - | .num k => mkApp (mkConst ``CommRing.Expr.num) (toExpr k) - | .intCast k => mkApp (mkConst ``CommRing.Expr.intCast) (toExpr k) - | .natCast k => mkApp (mkConst ``CommRing.Expr.natCast) (toExpr k) - | .var x => mkApp (mkConst ``CommRing.Expr.var) (toExpr x) + | .num k => mkApp (mkConst ``CommRing.Expr.num) (mkIntLitK k) + | .intCast k => mkApp (mkConst ``CommRing.Expr.intCast) (mkIntLitK k) + | .natCast k => mkApp (mkConst ``CommRing.Expr.natCast) (mkRawNatLit k) + | .var x => mkApp (mkConst ``CommRing.Expr.var) (mkRawNatLit x) | .add a b => mkApp2 (mkConst ``CommRing.Expr.add) (ofRingExpr a) (ofRingExpr b) | .mul a b => mkApp2 (mkConst ``CommRing.Expr.mul) (ofRingExpr a) (ofRingExpr b) | .sub a b => mkApp2 (mkConst ``CommRing.Expr.sub) (ofRingExpr a) (ofRingExpr b) | .neg a => mkApp (mkConst ``CommRing.Expr.neg) (ofRingExpr a) - | .pow a k => mkApp2 (mkConst ``CommRing.Expr.pow) (ofRingExpr a) (toExpr k) + | .pow a k => mkApp2 (mkConst ``CommRing.Expr.pow) (ofRingExpr a) (mkRawNatLit k) instance : ToExpr CommRing.Expr where toExpr := ofRingExpr
diff --git a/tests/elab/grind_guide_2.lean.out.expected b/tests/elab/grind_guide_2.lean.out.expected index 9fbefca..f4cee41 100644 --- a/tests/elab/grind_guide_2.lean.out.expected +++ b/tests/elab/grind_guide_2.lean.out.expected
@@ -10,12 +10,16 @@ let e_2 := Expr.zero; let e_3 := (Expr.intMul (-1) (Expr.var 1)).add (Expr.intMul 1 (Expr.var 0)); let rctx := RArray.leaf (f 2); - let rp_1 := CommRing.Poly.add 1 (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) (CommRing.Poly.num 0); + let rp_1 := + CommRing.Poly.add (Int.ofNat 1) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) + (CommRing.Poly.num (Int.ofNat 0)); let rp_2 := - CommRing.Poly.add (-1) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) (CommRing.Poly.num 1); + CommRing.Poly.add (Int.negSucc 0) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) + (CommRing.Poly.num (Int.ofNat 1)); let re_1 := CommRing.Expr.var 0; - let re_2 := CommRing.Expr.num 0; - let re_3 := ((CommRing.Expr.num 1).neg.mul (CommRing.Expr.var 0)).add (CommRing.Expr.num 1); + let re_2 := CommRing.Expr.num (Int.ofNat 0); + let re_3 := + ((CommRing.Expr.num (Int.ofNat 1)).neg.mul (CommRing.Expr.var 0)).add (CommRing.Expr.num (Int.ofNat 1)); lt_unsat ctx (le_lt_combine ctx p_3 p_5 p_1 (eagerReduce (Eq.refl true)) (le_le_combine ctx p_4 p_2 p_3 (eagerReduce (Eq.refl true))
diff --git a/tests/elab/grind_linarith_2.lean b/tests/elab/grind_linarith_2.lean index c48799b..e2dc134 100644 --- a/tests/elab/grind_linarith_2.lean +++ b/tests/elab/grind_linarith_2.lean
@@ -14,7 +14,7 @@ let e_1 := Expr.zero; let e_2 := Expr.intMul 0 (Expr.var 0); let rctx := RArray.branch 1 (RArray.leaf a) (RArray.leaf b); - let rp_1 := CommRing.Poly.num 0; + let rp_1 := CommRing.Poly.num (Int.ofNat 0); let re_1 := (CommRing.Expr.var 0).add (CommRing.Expr.var 1); let re_2 := (CommRing.Expr.var 1).add (CommRing.Expr.var 0); diseq_unsat ctx
diff --git a/tests/elab/grind_linarith_trim_context.lean b/tests/elab/grind_linarith_trim_context.lean index fdbeaf0..c969a0f 100644 --- a/tests/elab/grind_linarith_trim_context.lean +++ b/tests/elab/grind_linarith_trim_context.lean
@@ -12,12 +12,16 @@ let e_2 := Expr.zero; let e_3 := (Expr.intMul (-1) (Expr.var 1)).add (Expr.intMul 1 (Expr.var 0)); let rctx := RArray.leaf (f 2); - let rp_1 := CommRing.Poly.add 1 (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) (CommRing.Poly.num 0); + let rp_1 := + CommRing.Poly.add (Int.ofNat 1) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) + (CommRing.Poly.num (Int.ofNat 0)); let rp_2 := - CommRing.Poly.add (-1) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) (CommRing.Poly.num 1); + CommRing.Poly.add (Int.negSucc 0) (CommRing.Mon.mult { x := 0, k := 1 } CommRing.Mon.unit) + (CommRing.Poly.num (Int.ofNat 1)); let re_1 := CommRing.Expr.var 0; - let re_2 := CommRing.Expr.num 0; - let re_3 := ((CommRing.Expr.num 1).neg.mul (CommRing.Expr.var 0)).add (CommRing.Expr.num 1); + let re_2 := CommRing.Expr.num (Int.ofNat 0); + let re_3 := + ((CommRing.Expr.num (Int.ofNat 1)).neg.mul (CommRing.Expr.var 0)).add (CommRing.Expr.num (Int.ofNat 1)); lt_unsat ctx (le_lt_combine ctx p_3 p_5 p_1 (eagerReduce (Eq.refl true)) (le_le_combine ctx p_4 p_2 p_3 (eagerReduce (Eq.refl true))
diff --git a/tests/elab/grind_ring_trim_context.lean b/tests/elab/grind_ring_trim_context.lean index 7316771..48cccb5 100644 --- a/tests/elab/grind_ring_trim_context.lean +++ b/tests/elab/grind_ring_trim_context.lean
@@ -5,16 +5,18 @@ id (let ctx := RArray.branch 1 (RArray.leaf x) (RArray.leaf x⁻¹); let e_1 := (Expr.var 0).mul (Expr.var 1); - let e_2 := Expr.num 0; - let e_3 := Expr.num 1; + let e_2 := Expr.num (Int.ofNat 0); + let e_3 := Expr.num (Int.ofNat 1); let e_4 := (Expr.var 0).pow 2; let m_1 := Mon.mult (Power.mk 1 1) Mon.unit; let m_2 := Mon.mult (Power.mk 0 1) Mon.unit; - let p_1 := Poly.num (-1); - let p_2 := Poly.add (-1) (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num 0); - let p_3 := Poly.add 1 (Mon.mult (Power.mk 0 2) Mon.unit) (Poly.num 0); - let p_4 := Poly.add 1 (Mon.mult (Power.mk 0 1) (Mon.mult (Power.mk 1 1) Mon.unit)) (Poly.num (-1)); - let p_5 := Poly.add 1 (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num 0); + let p_1 := Poly.num (Int.negSucc 0); + let p_2 := Poly.add (Int.negSucc 0) (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num (Int.ofNat 0)); + let p_3 := Poly.add (Int.ofNat 1) (Mon.mult (Power.mk 0 2) Mon.unit) (Poly.num (Int.ofNat 0)); + let p_4 := + Poly.add (Int.ofNat 1) (Mon.mult (Power.mk 0 1) (Mon.mult (Power.mk 1 1) Mon.unit)) + (Poly.num (Int.negSucc 0)); + let p_5 := Poly.add (Int.ofNat 1) (Mon.mult (Power.mk 0 1) Mon.unit) (Poly.num (Int.ofNat 0)); one_eq_zero_unsat ctx p_1 (eagerReduce (Eq.refl true)) (Stepwise.simp ctx 1 p_4 (-1) m_1 p_5 p_1 (eagerReduce (Eq.refl true)) (Stepwise.core ctx e_1 e_3 p_4 (eagerReduce (Eq.refl true)) (diseq0_to_eq x h_4))
diff --git a/tests/elab/grind_semiring_norm.lean b/tests/elab/grind_semiring_norm.lean index ee475a2..026345d 100644 --- a/tests/elab/grind_semiring_norm.lean +++ b/tests/elab/grind_semiring_norm.lean
@@ -19,7 +19,7 @@ (CommRing.eq_normS (RArray.branch 1 (RArray.leaf a) (RArray.leaf b)) (((CommRing.Expr.var 0).add (CommRing.Expr.var 1)).pow 2) ((((CommRing.Expr.var 0).pow 2).add - (((CommRing.Expr.num 2).mul (CommRing.Expr.var 0)).mul (CommRing.Expr.var 1))).add + (((CommRing.Expr.num (Int.ofNat 2)).mul (CommRing.Expr.var 0)).mul (CommRing.Expr.var 1))).add ((CommRing.Expr.var 1).pow 2)) (eagerReduce (Eq.refl true)))) -/