fix: grind internalization (#11318)
This PR fixes a local declaration internalization in `grind` that was exposed when using `grind -revert`. This bug was affecting a `grind` proof in Mathlib.
This commit is contained in:
parent
90389a8d90
commit
a0772dc82d
3 changed files with 56 additions and 10 deletions
|
|
@ -215,16 +215,7 @@ private def addHypotheses (goal : Goal) : GrindM Goal := GoalM.run' goal do
|
|||
| none => add r.expr localDecl.toExpr
|
||||
| some h => add r.expr <| mkApp4 (mkConst ``Eq.mp [0]) type r.expr h localDecl.toExpr
|
||||
else
|
||||
/-
|
||||
**Note**: We must internalize local variables because their types may be empty, and may not be
|
||||
referenced anywhere else. Example:
|
||||
```
|
||||
example (a : { x : Int // x < 0 ∧ x > 0 }) : False := by grind
|
||||
```
|
||||
-/
|
||||
let e ← shareCommon localDecl.toExpr
|
||||
internalize e 0
|
||||
processNewFacts
|
||||
internalizeLocalDecl localDecl
|
||||
|
||||
private def initCore (mvarId : MVarId) (params : Params) : GrindM Goal := do
|
||||
/-
|
||||
|
|
|
|||
|
|
@ -1288,6 +1288,23 @@ opaque internalize (e : Expr) (generation : Nat) (parent? : Option Expr := none)
|
|||
@[extern "lean_grind_process_new_facts"]
|
||||
opaque processNewFacts : GoalM Unit
|
||||
|
||||
/--
|
||||
Internalizes a local declaration which is not a proposition.
|
||||
**Note**: We must internalize local variables because their types may be empty, and may not be
|
||||
referenced anywhere else. Example:
|
||||
```
|
||||
example (a : { x : Int // x < 0 ∧ x > 0 }) : False := by grind
|
||||
```
|
||||
`etaStruct` may also be applicable.
|
||||
-/
|
||||
def internalizeLocalDecl (localDecl : LocalDecl) : GoalM Unit := do
|
||||
let e ← shareCommon localDecl.toExpr
|
||||
internalize e 0
|
||||
/-
|
||||
**Note**: `internalize` may add new facts (e.g., `etaStruct` equality)
|
||||
-/
|
||||
processNewFacts
|
||||
|
||||
/--
|
||||
Returns a proof that `a = b` if they have the same type. Otherwise, returns a proof of `a ≍ b`.
|
||||
It assumes `a` and `b` are in the same equivalence class.
|
||||
|
|
|
|||
38
tests/lean/run/grind_eta_struct_internalize.lean
Normal file
38
tests/lean/run/grind_eta_struct_internalize.lean
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
namespace List
|
||||
|
||||
/-
|
||||
This example exposed a bug in the `grind` internalizer when `grind -revert`
|
||||
is used.
|
||||
-/
|
||||
|
||||
variable {α : Type} {β : α → Type}
|
||||
|
||||
def keys : List (Sigma β) → List α :=
|
||||
map Sigma.fst
|
||||
|
||||
@[grind =]
|
||||
theorem keys_cons {s} {l : List (Sigma β)} : (s :: l).keys = s.1 :: l.keys :=
|
||||
rfl
|
||||
|
||||
variable [DecidableEq α]
|
||||
|
||||
def dlookup (a : α) : List (Sigma β) → Option (β a)
|
||||
| [] => none
|
||||
| ⟨a', b⟩ :: l => if h : a' = a then some (Eq.recOn h b) else dlookup a l
|
||||
|
||||
@[grind =]
|
||||
theorem dlookup_cons_eq (l) (a : α) (b : β a) : dlookup a (⟨a, b⟩ :: l) = some b :=
|
||||
dif_pos rfl
|
||||
|
||||
@[grind =]
|
||||
theorem dlookup_cons_ne (l) {a} : ∀ s : Sigma β, a ≠ s.1 → dlookup a (s :: l) = dlookup a l
|
||||
| ⟨_, _⟩, h => dif_neg h.symm
|
||||
|
||||
@[grind =]
|
||||
theorem dlookup_isSome {a : α} {l : List (Sigma β)} : (dlookup a l).isSome ↔ a ∈ l.keys := by
|
||||
induction l with
|
||||
| nil => sorry
|
||||
| cons s _ _ =>
|
||||
by_cases a = s.fst
|
||||
· grind
|
||||
· sorry
|
||||
Loading…
Add table
Reference in a new issue