Skip to content

Commit c811617

Browse files
committed
fix: internalize nested ground patterns when activating ematch theorems
This PR internalize nested ground patterns when activating ematch theorems in the (WIP) `grind` tactic.
1 parent 9b28c58 commit c811617

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

src/Lean/Meta/Tactic/Grind.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ builtin_initialize registerTraceClass `grind.congr
3737
builtin_initialize registerTraceClass `grind.proof
3838
builtin_initialize registerTraceClass `grind.proof.detail
3939
builtin_initialize registerTraceClass `grind.pattern
40+
builtin_initialize registerTraceClass `grind.internalize
4041

4142
end Lean

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,25 @@ private def isForbidden (declName : Name) := forbiddenDeclNames.contains declNam
6767

6868
private def dontCare := mkConst (Name.mkSimple "[grind_dontcare]")
6969

70-
private def mkGroundPattern (e : Expr) : Expr :=
70+
def mkGroundPattern (e : Expr) : Expr :=
7171
mkAnnotation `grind.ground_pat e
7272

73-
private def groundPattern? (e : Expr) : Option Expr :=
73+
def groundPattern? (e : Expr) : Option Expr :=
7474
annotation? `grind.ground_pat e
7575

7676
private def isGroundPattern (e : Expr) : Bool :=
7777
groundPattern? e |>.isSome
7878

79+
def isPatternDontCare (e : Expr) : Bool :=
80+
e == dontCare
81+
7982
private def isAtomicPattern (e : Expr) : Bool :=
80-
e.isBVar || e == dontCare || isGroundPattern e
83+
e.isBVar || isPatternDontCare e || isGroundPattern e
8184

8285
partial def ppPattern (pattern : Expr) : MessageData := Id.run do
8386
if let some e := groundPattern? pattern then
8487
return m!"`[{e}]"
85-
else if pattern == dontCare then
88+
else if isPatternDontCare pattern then
8689
return m!"?"
8790
else match pattern with
8891
| .bvar idx => return m!"#{idx}"

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ prelude
77
import Init.Grind.Util
88
import Lean.Meta.LitValues
99
import Lean.Meta.Tactic.Grind.Types
10+
import Lean.Meta.Tactic.Grind.Util
1011

1112
namespace Lean.Meta.Grind
1213

@@ -37,7 +38,19 @@ private def updateAppMap (e : Expr) : GoalM Unit := do
3738
s.appMap.insert key [e]
3839
}
3940

40-
private def activateTheoremPatterns (fName : Name) : GoalM Unit := do
41+
mutual
42+
/-- Internalizes the nested ground terms in the given pattern. -/
43+
private partial def internalizePattern (pattern : Expr) (generation : Nat) : GoalM Expr := do
44+
if pattern.isBVar || isPatternDontCare pattern then
45+
return pattern
46+
else if let some e := groundPattern? pattern then
47+
let e ← shareCommon (← canon (← normalizeLevels (← unfoldReducible e)))
48+
internalize e generation
49+
return mkGroundPattern e
50+
else pattern.withApp fun f args => do
51+
return mkAppN f (← args.mapM (internalizePattern · generation))
52+
53+
private partial def activateTheoremPatterns (fName : Name) (generation : Nat) : GoalM Unit := do
4154
if let some thms := (← get).thmMap.find? fName then
4255
modify fun s => { s with thmMap := s.thmMap.erase fName }
4356
let appMap := (← get).appMap
@@ -47,13 +60,15 @@ private def activateTheoremPatterns (fName : Name) : GoalM Unit := do
4760
match symbols with
4861
| [] =>
4962
trace[grind.pattern] "activated `{thm.origin.key}`"
63+
let thm := { thm with patterns := (← thm.patterns.mapM (internalizePattern · generation)) }
5064
modify fun s => { s with newThms := s.newThms.push thm }
5165
| _ =>
5266
trace[grind.pattern] "reinsert `{thm.origin.key}`"
5367
modify fun s => { s with thmMap := s.thmMap.insert thm }
5468

5569
partial def internalize (e : Expr) (generation : Nat) : GoalM Unit := do
5670
if (← alreadyInternalized e) then return ()
71+
trace[grind.internalize] "{e}"
5772
match e with
5873
| .bvar .. => unreachable!
5974
| .sort .. => return ()
@@ -79,7 +94,7 @@ partial def internalize (e : Expr) (generation : Nat) : GoalM Unit := do
7994
registerParent e c
8095
else
8196
if let .const fName _ := f then
82-
activateTheoremPatterns fName
97+
activateTheoremPatterns fName generation
8398
else
8499
internalize f generation
85100
registerParent e f
@@ -91,5 +106,6 @@ partial def internalize (e : Expr) (generation : Nat) : GoalM Unit := do
91106
addCongrTable e
92107
updateAppMap e
93108
propagateUp e
109+
end
94110

95111
end Lean.Meta.Grind

tests/lean/run/grind_pattern2.lean

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,37 @@ example [DecidableEq α] (s₁ s₂ : Set α) (a₁ a₂ : α) :
3737
¬ contains s₂ a₂ → s₂ = insertElem s₁ a₁ → a₁ = a₂ → False := by
3838
fail_if_success grind
3939
sorry
40+
41+
def a := 10
42+
def b := 20
43+
def foo (x : List Nat) (y : List Nat) := x ++ y ++ x
44+
45+
theorem fooThm : foo x [a, b] = x ++ [a, b] ++ x := rfl
46+
47+
/--
48+
info: [grind.pattern] fooThm: [foo #0 `[[a, b]]]
49+
-/
50+
#guard_msgs in
51+
grind_pattern fooThm => foo x [a, b]
52+
53+
54+
/--
55+
warning: declaration uses 'sorry'
56+
---
57+
info: [grind.internalize] foo x y
58+
[grind.pattern] activated `fooThm`
59+
[grind.internalize] [a, b]
60+
[grind.internalize] Nat
61+
[grind.internalize] a
62+
[grind.internalize] [b]
63+
[grind.internalize] b
64+
[grind.internalize] []
65+
[grind.internalize] x
66+
[grind.internalize] y
67+
[grind.internalize] z
68+
-/
69+
#guard_msgs in
70+
set_option trace.grind.internalize true in
71+
example : foo x y = z → False := by
72+
fail_if_success grind
73+
sorry

0 commit comments

Comments
 (0)