fix: handle heterogeneous equality in closeGoalWithValuesEq (#12477)
This PR fixes an internal `grind` error where `mkEqProof` is invoked with terms of different types. When equivalence classes contain heterogeneous equalities (e.g., `0 : Fin 3` and `0 : Fin 2` merged via `HEq`), `closeGoalWithValuesEq` would call `mkEqProof` on terms with incompatible types, triggering an internal error. Closes #12140 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d77efe6a5f
commit
57a2dc0146
2 changed files with 58 additions and 2 deletions
|
|
@ -73,7 +73,10 @@ private def closeGoalWithTrueEqFalse : GoalM Unit := do
|
|||
let falseProof := mkApp4 (mkConst ``Eq.mp [levelZero]) (← getTrueExpr) (← getFalseExpr) trueEqFalse (mkConst ``True.intro)
|
||||
closeGoal falseProof
|
||||
|
||||
/-- Closes the goal when `lhs` and `rhs` are both literal values and belong to the same equivalence class. -/
|
||||
/--
|
||||
Closes the goal when `lhs` and `rhs` are both literal values and belong to the same equivalence class,
|
||||
and have the same type.
|
||||
-/
|
||||
private def closeGoalWithValuesEq (lhs rhs : Expr) : GoalM Unit := do
|
||||
let p ← mkEq lhs rhs
|
||||
let hp ← mkEqProof lhs rhs
|
||||
|
|
@ -168,7 +171,10 @@ private partial def addEqStep (lhs rhs proof : Expr) (isHEq : Bool) : GoalM Unit
|
|||
markAsInconsistent
|
||||
trueEqFalse := true
|
||||
else
|
||||
valueInconsistency := true
|
||||
let hasHEq := isHEq || lhsRoot.heqProofs || rhsRoot.heqProofs
|
||||
-- **Note**: We only have to check the types if there are heterogenous equalities.
|
||||
if (← pure !hasHEq <||> hasSameType lhsRoot.self rhsRoot.self) then
|
||||
valueInconsistency := true
|
||||
if (lhsRoot.interpreted && !rhsRoot.interpreted)
|
||||
|| (lhsRoot.ctor && !rhsRoot.ctor)
|
||||
|| (lhsRoot.size > rhsRoot.size && !rhsRoot.interpreted && !rhsRoot.ctor) then
|
||||
|
|
|
|||
50
tests/lean/run/grind_12140.lean
Normal file
50
tests/lean/run/grind_12140.lean
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
inductive Foo (α : Type) (x : α) where
|
||||
| c1 : Foo α x
|
||||
| c2 : Foo α x
|
||||
|
||||
def Foo.mk (n : Nat) : Foo (Fin (n + 1)) 0 :=
|
||||
match n with
|
||||
| .zero => .c1
|
||||
| .succ _ => .c1
|
||||
|
||||
def Foo.num {α : Type} {x : α} (f : Foo α x) : Nat :=
|
||||
0
|
||||
|
||||
/-
|
||||
Issue #12140: `closeGoalWithValuesEq` must check that the two interpreted values
|
||||
have the same type before calling `mkEqProof`. When equivalence classes contain
|
||||
heterogeneous equalities (e.g., `0 : Fin 3` and `0 : Fin 2` merged via `HEq`),
|
||||
`mkEqProof` would fail with an internal error.
|
||||
-/
|
||||
|
||||
/--
|
||||
error: `grind` failed
|
||||
case grind.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1
|
||||
n : Nat
|
||||
ih : (Foo.mk n).num = 0
|
||||
h : ¬(Foo.mk (n + 1)).num = 0
|
||||
h_1 : n + 1 = Nat.zero + 1
|
||||
h_2 : 1 = Nat.zero + 1
|
||||
h_3 : 1 = Nat.zero.succ + 1
|
||||
h_4 : 1 = (n + 1).succ + 1
|
||||
h_5 : 1 = (Nat.zero + 2).succ + 1
|
||||
h_6 : (n + 2).succ + 1 = (Nat.zero + 2).succ + 1
|
||||
h_7 : 2 = Nat.zero + 2
|
||||
h_8 : 1 = (Nat.zero + 3).succ + 1
|
||||
h_9 : (n + 3).succ + 1 = (Nat.zero + 3).succ + 1
|
||||
h_10 : 3 = Nat.zero + 3
|
||||
h_11 : 1 = (Nat.zero + 4).succ + 1
|
||||
h_12 : (n + 4).succ + 1 = (Nat.zero + 4).succ + 1
|
||||
h_13 : 4 = Nat.zero + 4
|
||||
h_14 : 1 = (Nat.zero + 5).succ + 1
|
||||
h_15 : (n + 5).succ + 1 = (Nat.zero + 5).succ + 1
|
||||
h_16 : 5 = Nat.zero + 5
|
||||
h_17 : 1 = (Nat.zero + 6).succ + 1
|
||||
⊢ False
|
||||
-/
|
||||
#guard_msgs in
|
||||
theorem foo (n : Nat) : (Foo.mk n).num = 0 := by
|
||||
induction n with
|
||||
| zero => rfl
|
||||
| succ n ih =>
|
||||
grind -verbose [Foo.mk]
|
||||
Loading…
Add table
Reference in a new issue