Skip to content

Commit 5d6d81d

Browse files
committed
tests for simp_all
1 parent 5b78d4c commit 5d6d81d

File tree

3 files changed

+81
-9
lines changed

3 files changed

+81
-9
lines changed

src/Lean/Elab/Tactic/Simp.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,8 @@ def withSimpDiagnostics (x : TacticM Simp.Diagnostics) : TacticM Unit := do
657657
-/
658658
@[builtin_tactic Lean.Parser.Tactic.simp] def evalSimp : Tactic := fun stx => withMainContext do withSimpDiagnostics do
659659
let r@{ ctx, simprocs, dischargeWrapper, simpArgs } ← mkSimpContext stx (eraseLocal := false)
660+
if ctx.config.suggestions then
661+
throwError "+suggestions requires using simp? instead of simp"
660662
let stats ← dischargeWrapper.with fun discharge? =>
661663
withLoopChecking r do
662664
simpLocation ctx simprocs discharge? (expandOptLocation stx[5])
@@ -669,6 +671,8 @@ def withSimpDiagnostics (x : TacticM Simp.Diagnostics) : TacticM Unit := do
669671

670672
@[builtin_tactic Lean.Parser.Tactic.simpAll] def evalSimpAll : Tactic := fun stx => withMainContext do withSimpDiagnostics do
671673
let r@{ ctx, simprocs, dischargeWrapper := _, simpArgs } ← mkSimpContext stx (eraseLocal := true) (kind := .simpAll) (ignoreStarArg := true)
674+
if ctx.config.suggestions then
675+
throwError "+suggestions requires using simp_all? instead of simp_all"
672676
let (result?, stats) ←
673677
withLoopChecking r do
674678
simpAll (← getMainGoal) ctx (simprocs := simprocs)

src/Lean/Elab/Tactic/SimpTrace.lean

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ namespace Lean.Elab.Tactic
2222
open Lean Elab Parser Tactic Meta Simp Tactic.TryThis
2323

2424
/-- Filter out `+suggestions` from the config syntax -/
25-
def filterSuggestionsFromConfig (config : TSyntax ``Lean.Parser.Tactic.optConfig) : MetaM (TSyntax ``Lean.Parser.Tactic.optConfig) := do
25+
def filterSuggestionsFromConfig (cfg : TSyntax ``Lean.Parser.Tactic.optConfig) : MetaM (TSyntax ``Lean.Parser.Tactic.optConfig) := do
2626
-- The config has one arg: a null node containing configItem nodes
27-
let nullNode := config.raw.getArg 0
27+
let nullNode := cfg.raw.getArg 0
2828
let configItems := nullNode.getArgs
2929

3030
-- Filter out configItem nodes that contain +suggestions
@@ -38,7 +38,7 @@ def filterSuggestionsFromConfig (config : TSyntax ``Lean.Parser.Tactic.optConfig
3838

3939
-- Reconstruct the config with filtered items
4040
let newNullNode := nullNode.setArgs filteredItems
41-
returnconfig.raw.setArg 0 newNullNode⟩
41+
returncfg.raw.setArg 0 newNullNode⟩
4242

4343
open TSyntax.Compat in
4444
/-- Constructs the syntax for a simp call, for use with `simp?`. -/
@@ -85,18 +85,50 @@ def mkSimpCallStx (stx : Syntax) (usedSimps : UsedSimps) : MetaM (TSyntax `tacti
8585
@[builtin_tactic simpAllTrace] def evalSimpAllTrace : Tactic := fun stx => withMainContext do withSimpDiagnostics do
8686
match stx with
8787
| `(tactic| simp_all?%$tk $[!%$bang]? $cfg:optConfig $(discharger)? $[only%$o]? $[[$args,*]]?) =>
88-
let stx ← if bang.isSome then
89-
`(tactic| simp_all!%$tk $cfg:optConfig $(discharger)? $[only%$o]? $[[$args,*]]?)
90-
else
91-
`(tactic| simp_all%$tk $cfg:optConfig $(discharger)? $[only%$o]? $[[$args,*]]?)
92-
let { ctx, simprocs, .. } ← mkSimpContext stx (eraseLocal := true)
88+
-- Check if premise selection is enabled
89+
let config ← elabSimpConfig cfg (kind := .simpAll)
90+
let mut argsArray : TSyntaxArray [`Lean.Parser.Tactic.simpErase, `Lean.Parser.Tactic.simpLemma] :=
91+
if let some a := args then a.getElems else #[]
92+
if config.suggestions then
93+
-- Get premise suggestions from the premise selector
94+
let suggestions ← Lean.PremiseSelection.select (← getMainGoal)
95+
-- Convert suggestions to simp argument syntax and add them to the args
96+
for sugg in suggestions do
97+
let arg ← `(Parser.Tactic.simpLemma| $(mkIdent sugg.name):term)
98+
argsArray := argsArray.push arg
99+
-- Build the simp_all syntax with the updated arguments
100+
let stxForExecution ←
101+
if argsArray.isEmpty then
102+
if bang.isSome then
103+
`(tactic| simp_all!%$tk $cfg:optConfig $[$discharger]? $[only%$o]?)
104+
else
105+
`(tactic| simp_all%$tk $cfg:optConfig $[$discharger]? $[only%$o]?)
106+
else
107+
if bang.isSome then
108+
`(tactic| simp_all!%$tk $cfg:optConfig $[$discharger]? $[only%$o]? [$argsArray,*])
109+
else
110+
`(tactic| simp_all%$tk $cfg:optConfig $[$discharger]? $[only%$o]? [$argsArray,*])
111+
-- Build syntax for suggestion (without +suggestions config)
112+
let filteredCfg ← filterSuggestionsFromConfig cfg
113+
let stxForSuggestion ←
114+
if argsArray.isEmpty then
115+
if bang.isSome then
116+
`(tactic| simp_all!%$tk $filteredCfg:optConfig $[$discharger]? $[only%$o]?)
117+
else
118+
`(tactic| simp_all%$tk $filteredCfg:optConfig $[$discharger]? $[only%$o]?)
119+
else
120+
if bang.isSome then
121+
`(tactic| simp_all!%$tk $filteredCfg:optConfig $[$discharger]? $[only%$o]? [$argsArray,*])
122+
else
123+
`(tactic| simp_all%$tk $filteredCfg:optConfig $[$discharger]? $[only%$o]? [$argsArray,*])
124+
let { ctx, simprocs, .. } ← mkSimpContext stxForExecution (eraseLocal := true)
93125
(kind := .simpAll) (ignoreStarArg := true)
94126
let ctx := if bang.isSome then ctx.setAutoUnfold else ctx
95127
let (result?, stats) ← simpAll (← getMainGoal) ctx (simprocs := simprocs)
96128
match result? with
97129
| none => replaceMainGoal []
98130
| some mvarId => replaceMainGoal [mvarId]
99-
let stx ← mkSimpCallStx stx stats.usedTheorems
131+
let stx ← mkSimpCallStx stxForSuggestion stats.usedTheorems
100132
addSuggestion tk stx (origSpan? := ← getRef)
101133
return stats.diag
102134
| _ => throwUnsupportedSyntax

tests/lean/run/simp_suggestions.lean

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,39 @@ info: Try this:
2323
#guard_msgs in
2424
example (a b : Nat) : myCustomAdd a b = myCustomAdd b a := by
2525
simp? +suggestions
26+
27+
-- Test that simp +suggestions (without ?) gives a helpful error
28+
/--
29+
error: +suggestions requires using simp? instead of simp
30+
-/
31+
#guard_msgs in
32+
example (a b : Nat) : myCustomAdd a b = myCustomAdd b a := by
33+
simp +suggestions
34+
sorry
35+
36+
-- Test that simp_all? +suggestions works on the goal
37+
/--
38+
info: Try this:
39+
[apply] simp_all only [myCustomAdd_comm]
40+
-/
41+
#guard_msgs in
42+
example (a b : Nat) : myCustomAdd a b = myCustomAdd b a := by
43+
simp_all? +suggestions
44+
45+
-- Test that simp_all? +suggestions works on a hypothesis
46+
/--
47+
info: Try this:
48+
[apply] simp_all only [myCustomAdd_comm]
49+
-/
50+
#guard_msgs in
51+
example (a b c : Nat) (h : myCustomAdd a b = c) : myCustomAdd b a = c := by
52+
simp_all? +suggestions
53+
54+
-- Test that simp_all +suggestions (without ?) gives a helpful error
55+
/--
56+
error: +suggestions requires using simp_all? instead of simp_all
57+
-/
58+
#guard_msgs in
59+
example (a b : Nat) (h : myCustomAdd a b = myCustomAdd b a) : myCustomAdd a b = myCustomAdd b a := by
60+
simp_all +suggestions
61+
sorry

0 commit comments

Comments
 (0)