Skip to content

Commit

Permalink
fix: internalize nested ground patterns when activating ematch theore…
Browse files Browse the repository at this point in the history
…ms (#6478)

This PR internalize nested ground patterns when activating ematch
theorems in the (WIP) `grind` tactic.
  • Loading branch information
leodemoura authored Dec 30, 2024
1 parent 9b28c58 commit 7e8e22e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/Lean/Meta/Tactic/Grind.lean
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,6 @@ builtin_initialize registerTraceClass `grind.congr
builtin_initialize registerTraceClass `grind.proof
builtin_initialize registerTraceClass `grind.proof.detail
builtin_initialize registerTraceClass `grind.pattern
builtin_initialize registerTraceClass `grind.internalize

end Lean
11 changes: 7 additions & 4 deletions src/Lean/Meta/Tactic/Grind/EMatchTheorem.lean
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,25 @@ private def isForbidden (declName : Name) := forbiddenDeclNames.contains declNam

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

private def mkGroundPattern (e : Expr) : Expr :=
def mkGroundPattern (e : Expr) : Expr :=
mkAnnotation `grind.ground_pat e

private def groundPattern? (e : Expr) : Option Expr :=
def groundPattern? (e : Expr) : Option Expr :=
annotation? `grind.ground_pat e

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

def isPatternDontCare (e : Expr) : Bool :=
e == dontCare

private def isAtomicPattern (e : Expr) : Bool :=
e.isBVar || e == dontCare || isGroundPattern e
e.isBVar || isPatternDontCare e || isGroundPattern e

partial def ppPattern (pattern : Expr) : MessageData := Id.run do
if let some e := groundPattern? pattern then
return m!"`[{e}]"
else if pattern == dontCare then
else if isPatternDontCare pattern then
return m!"?"
else match pattern with
| .bvar idx => return m!"#{idx}"
Expand Down
20 changes: 18 additions & 2 deletions src/Lean/Meta/Tactic/Grind/Internalize.lean
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ prelude
import Init.Grind.Util
import Lean.Meta.LitValues
import Lean.Meta.Tactic.Grind.Types
import Lean.Meta.Tactic.Grind.Util

namespace Lean.Meta.Grind

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

private def activateTheoremPatterns (fName : Name) : GoalM Unit := do
mutual
/-- Internalizes the nested ground terms in the given pattern. -/
private partial def internalizePattern (pattern : Expr) (generation : Nat) : GoalM Expr := do
if pattern.isBVar || isPatternDontCare pattern then
return pattern
else if let some e := groundPattern? pattern then
let e ← shareCommon (← canon (← normalizeLevels (← unfoldReducible e)))
internalize e generation
return mkGroundPattern e
else pattern.withApp fun f args => do
return mkAppN f (← args.mapM (internalizePattern · generation))

private partial def activateTheoremPatterns (fName : Name) (generation : Nat) : GoalM Unit := do
if let some thms := (← get).thmMap.find? fName then
modify fun s => { s with thmMap := s.thmMap.erase fName }
let appMap := (← get).appMap
Expand All @@ -47,13 +60,15 @@ private def activateTheoremPatterns (fName : Name) : GoalM Unit := do
match symbols with
| [] =>
trace[grind.pattern] "activated `{thm.origin.key}`"
let thm := { thm with patterns := (← thm.patterns.mapM (internalizePattern · generation)) }
modify fun s => { s with newThms := s.newThms.push thm }
| _ =>
trace[grind.pattern] "reinsert `{thm.origin.key}`"
modify fun s => { s with thmMap := s.thmMap.insert thm }

partial def internalize (e : Expr) (generation : Nat) : GoalM Unit := do
if (← alreadyInternalized e) then return ()
trace[grind.internalize] "{e}"
match e with
| .bvar .. => unreachable!
| .sort .. => return ()
Expand All @@ -79,7 +94,7 @@ partial def internalize (e : Expr) (generation : Nat) : GoalM Unit := do
registerParent e c
else
if let .const fName _ := f then
activateTheoremPatterns fName
activateTheoremPatterns fName generation
else
internalize f generation
registerParent e f
Expand All @@ -91,5 +106,6 @@ partial def internalize (e : Expr) (generation : Nat) : GoalM Unit := do
addCongrTable e
updateAppMap e
propagateUp e
end

end Lean.Meta.Grind
34 changes: 34 additions & 0 deletions tests/lean/run/grind_pattern2.lean
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,37 @@ example [DecidableEq α] (s₁ s₂ : Set α) (a₁ a₂ : α) :
¬ contains s₂ a₂ → s₂ = insertElem s₁ a₁ → a₁ = a₂ → False := by
fail_if_success grind
sorry

def a := 10
def b := 20
def foo (x : List Nat) (y : List Nat) := x ++ y ++ x

theorem fooThm : foo x [a, b] = x ++ [a, b] ++ x := rfl

/--
info: [grind.pattern] fooThm: [foo #0 `[[a, b]]]
-/
#guard_msgs in
grind_pattern fooThm => foo x [a, b]


/--
warning: declaration uses 'sorry'
---
info: [grind.internalize] foo x y
[grind.pattern] activated `fooThm`
[grind.internalize] [a, b]
[grind.internalize] Nat
[grind.internalize] a
[grind.internalize] [b]
[grind.internalize] b
[grind.internalize] []
[grind.internalize] x
[grind.internalize] y
[grind.internalize] z
-/
#guard_msgs in
set_option trace.grind.internalize true in
example : foo x y = z → False := by
fail_if_success grind
sorry

0 comments on commit 7e8e22e

Please sign in to comment.