lean4-htt/tests/lean/run/grind_som1.lean
Leonardo de Moura d64ae32965
feat: generate Nullstellensatz proof terms in grind (#8122)
This PR implements the generation of compact proof terms for
Nullstellensatz certificates in the new commutative ring procedure in
`grind`. Some examples:
```lean
example [CommRing α] (x y : α) : x = 1 → y = 2 → 2*x + y = 4 := by
  grind +ring

example [CommRing α] [IsCharP α 7] (x y : α) : 3*x = 1 → 3*y = 2 → x + y = 1 := by
  grind +ring

example [CommRing α] [NoZeroNatDivisors α] (x y : α) : 3*x = 1 → 3*y = 2 → x + y = 1 := by
  grind +ring

example (x y z : BitVec 8) : z = y → (x + 1)*(x - 1)*y + y = z*x^2 + 1 → False := by
  grind +ring
```
2025-04-26 22:52:00 +00:00

40 lines
1.5 KiB
Text

import Lean
open Lean.Grind
open Lean.Grind.CommRing
-- Convenient RArray literals
elab tk:"#R[" ts:term,* "]" : term => do
let ts : Array Lean.Syntax := ts
let es ← ts.mapM fun stx => Lean.Elab.Term.elabTerm stx none
if h : 0 < es.size then
Lean.RArray.toExpr (← Lean.Meta.inferType es[0]!) id (Lean.RArray.ofArray es h)
else
throwErrorAt tk "RArray cannot be empty"
example (x y : Int) : (x + y) * (x + y + 1) = x * (1 + y + x) + (y + 1 + x) * y :=
let ctx := #R[x, y]
let lhs : Expr := .mul (.add (.var 0) (.var 1)) (.add (.add (.var 0) (.var 1)) (.num 1))
let rhs : Expr := .add (.mul (.var 0) (.add (.add (.num 1) (.var 1)) (.var 0)))
(.mul (.add (.add (.var 1) (.num 1)) (.var 0)) (.var 1))
Expr.eq_of_toPoly_eq ctx lhs rhs (Eq.refl true)
example (x y : UInt8) : (128 * x + y) * 2 = y + y :=
let ctx := #R[x, y]
let lhs : Expr := .mul (.add (.mul (.num 128) (.var 0)) (.var 1)) (.num 2)
let rhs : Expr := .add (.var 1) (.var 1)
Expr.eq_of_toPolyC_eq ctx lhs rhs (Eq.refl true)
def q₁ : Poly := Expr.toPoly (.var 1)
def lhs₁ : Expr := .var 0
def rhs₁ : Expr := .var 1
def q₂ : Poly := Expr.toPoly (.num 1)
def lhs₂ : Expr := .add (.sub (.var 1) (.mul (.var 0) (.var 1))) (.pow (.var 1) 2)
def rhs₂ : Expr := .num 1
def lhs : Expr := .var 1
def rhs : Expr := .num 1
def nc : NullCert := .add q₁ lhs₁ rhs₁ (.add q₂ lhs₂ rhs₂ .empty)
example (x y : Int) : x = y → y - x*y + y^2 = 1 → y = 1 :=
let ctx := #R[x, y]
nc.eq ctx (lhs := lhs) (rhs := rhs) (Eq.refl true)