Skip to content

Commit a08379c

Browse files
authored
fix: proof generation for grind tactic (#6502)
This PR fixes a bug in the proof assembly procedure utilized by the `grind` tactic.
1 parent f0c5936 commit a08379c

File tree

4 files changed

+48
-24
lines changed

4 files changed

+48
-24
lines changed

src/Lean/Meta/Tactic/Grind/Inv.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private def checkProofs : GoalM Unit := do
8080
for a in eqc do
8181
for b in eqc do
8282
unless isSameExpr a b do
83-
let p ← mkEqProof a b
83+
let p ← mkEqHEqProof a b
8484
trace[grind.debug.proofs] "{a} = {b}"
8585
check p
8686
trace[grind.debug.proofs] "checked: {← inferType p}"

src/Lean/Meta/Tactic/Grind/Proof.lean

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -198,42 +198,41 @@ mutual
198198
-- `h' : lhs = target`
199199
mkTrans' h' h heq
200200

201+
/--
202+
Returns a proof of `lhs = rhs` (`HEq lhs rhs`) if `heq = false` (`heq = true`).
203+
If `heq = false`, this function assumes that `lhs` and `rhs` have the same type.
204+
-/
201205
private partial def mkEqProofCore (lhs rhs : Expr) (heq : Bool) : GoalM Expr := do
202206
if isSameExpr lhs rhs then
203207
return (← mkRefl lhs heq)
208+
-- The equivalence class contains `HEq` proofs. So, we build a proof using HEq. Otherwise, we use `Eq`.
209+
let heqProofs := (← getRootENode lhs).heqProofs
204210
let n₁ ← getENode lhs
205211
let n₂ ← getENode rhs
206212
assert! isSameExpr n₁.root n₂.root
207213
let common ← findCommon lhs rhs
208-
let lhsEqCommon? ← mkProofTo lhs common none heq
209-
let some lhsEqRhs ← mkProofFrom rhs common lhsEqCommon? heq | unreachable!
210-
return lhsEqRhs
214+
let lhsEqCommon? ← mkProofTo lhs common none heqProofs
215+
let some lhsEqRhs ← mkProofFrom rhs common lhsEqCommon? heqProofs | unreachable!
216+
if heq == heqProofs then
217+
return lhsEqRhs
218+
else if heq then
219+
mkHEqOfEq lhsEqRhs
220+
else
221+
mkEqOfHEq lhsEqRhs
222+
211223
end
212224

213225
/--
214-
Returns a proof that `a = b` (or `HEq a b`).
226+
Returns a proof that `a = b`.
215227
It assumes `a` and `b` are in the same equivalence class.
216228
-/
217229
@[export lean_grind_mk_eq_proof]
218230
def mkEqProofImpl (a b : Expr) : GoalM Expr := do
219-
let p ← go
220-
trace[grind.debug.proof] "{p}"
221-
return p
222-
where
223-
go : GoalM Expr := do
224-
let n ← getRootENode a
225-
if !n.heqProofs then
226-
trace[grind.debug.proof] "{a} = {b}"
227-
mkEqProofCore a b (heq := false)
228-
else
229-
if (← hasSameType a b) then
230-
trace[grind.debug.proof] "{a} = {b}"
231-
mkEqOfHEq (← mkEqProofCore a b (heq := true))
232-
else
233-
trace[grind.debug.proof] "{a} ≡ {b}"
234-
mkEqProofCore a b (heq := true)
231+
assert! (← hasSameType a b)
232+
mkEqProofCore a b (heq := false)
235233

236-
def mkHEqProof (a b : Expr) : GoalM Expr :=
234+
@[export lean_grind_mk_heq_proof]
235+
def mkHEqProofImpl (a b : Expr) : GoalM Expr :=
237236
mkEqProofCore a b (heq := true)
238237

239238
end Lean.Meta.Grind

src/Lean/Meta/Tactic/Grind/Types.lean

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,13 +563,31 @@ def isInconsistent : GoalM Bool :=
563563
return (← get).inconsistent
564564

565565
/--
566-
Returns a proof that `a = b` (or `HEq a b`).
567-
It assumes `a` and `b` are in the same equivalence class.
566+
Returns a proof that `a = b`.
567+
It assumes `a` and `b` are in the same equivalence class, and have the same type.
568568
-/
569569
-- Forward definition
570570
@[extern "lean_grind_mk_eq_proof"]
571571
opaque mkEqProof (a b : Expr) : GoalM Expr
572572

573+
/--
574+
Returns a proof that `HEq a b`.
575+
It assumes `a` and `b` are in the same equivalence class.
576+
-/
577+
-- Forward definition
578+
@[extern "lean_grind_mk_heq_proof"]
579+
opaque mkHEqProof (a b : Expr) : GoalM Expr
580+
581+
/--
582+
Returns a proof that `a = b` if they have the same type. Otherwise, returns a proof of `HEq a b`.
583+
It assumes `a` and `b` are in the same equivalence class.
584+
-/
585+
def mkEqHEqProof (a b : Expr) : GoalM Expr := do
586+
if (← hasSameType a b) then
587+
mkEqProof a b
588+
else
589+
mkHEqProof a b
590+
573591
/--
574592
Returns a proof that `a = True`.
575593
It assumes `a` and `True` are in the same equivalence class.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def f (a : α) := a
2+
3+
example (a b : α) (x y : β) : HEq a x → x = y → HEq y b → f a = f b := by
4+
grind
5+
6+
example (a b : α) (x y : β) : x = y → HEq a x → HEq y b → f a = f b := by
7+
grind

0 commit comments

Comments
 (0)