Skip to content

Commit 081b41a

Browse files
committed
feat: allow naming the hypothesis generated by have? (#9454)
Previously, there was no way to specify the name for a hypothesis generated by `have?` (and if it suggested a let, it used an inaccessible `this`). (Also, fixes a problem with `observe?`, that the suggestion was not respecting the requested name.) Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent 3d1cf78 commit 081b41a

File tree

5 files changed

+20
-15
lines changed

5 files changed

+20
-15
lines changed

Mathlib/Tactic/Observe.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ elab_rules : tactic |
4141
else
4242
let v := (← instantiateMVars (mkMVar goal)).headBeta
4343
if trace.isSome then
44-
-- TODO: we should be allowed to pass an identifier to `addHaveSuggestion`.
45-
addHaveSuggestion tk type v
44+
addHaveSuggestion tk (some name) type v
4645
let (_, newGoal) ← (← getMainGoal).note name v
4746
replaceMainGoal [newGoal]
4847

Mathlib/Tactic/Propose.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ only the types of the lemmas in the `using` clause.
113113
114114
Suggestions are printed as `have := f a b c`.
115115
-/
116-
syntax (name := propose') "have?" "!"? (" : " term)? " using " (colGt term),+ : tactic
116+
syntax (name := propose') "have?" "!"? (ident)? (" : " term)? " using " (colGt term),+ : tactic
117117

118118
open Elab.Tactic Elab Tactic in
119119
elab_rules : tactic
120-
| `(tactic| have?%$tk $[!%$lucky]? $[ : $type:term]? using $[$terms:term],*) => do
120+
| `(tactic| have?%$tk $[!%$lucky]? $[$h:ident]? $[ : $type:term]? using $[$terms:term],*) => do
121121
let stx ← getRef
122122
let goal ← getMainGoal
123123
goal.withContext do
@@ -130,7 +130,7 @@ elab_rules : tactic
130130
throwError "propose could not find any lemmas using the given hypotheses"
131131
-- TODO we should have `proposals` return a lazy list, to avoid unnecessary computation here.
132132
for p in proposals.toList.take 10 do
133-
addHaveSuggestion tk (← inferType p.2) p.2 stx
133+
addHaveSuggestion tk (h.map (·.getId)) (← inferType p.2) p.2 stx
134134
if lucky.isSome then
135135
let mut g := goal
136136
for p in proposals.toList.take 10 do

Mathlib/Tactic/TryThis.lean

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,25 @@ This file could be upstreamed to `Std`.
1515
open Lean Elab Elab.Tactic PrettyPrinter Meta Std.Tactic.TryThis
1616

1717
/-- Add a suggestion for `have : t := e`. -/
18-
def addHaveSuggestion (ref : Syntax) (t? : Option Expr) (e : Expr)
18+
def addHaveSuggestion (ref : Syntax) (h? : Option Name) (t? : Option Expr) (e : Expr)
1919
(origSpan? : Option Syntax := none) : TermElabM Unit := do
2020
let estx ← delabToRefinableSyntax e
2121
let prop ← isProp (← inferType e)
2222
let tac ← if let some t := t? then
2323
let tstx ← delabToRefinableSyntax t
2424
if prop then
25-
`(tactic| have : $tstx := $estx)
25+
match h? with
26+
| some h => `(tactic| have $(mkIdent h) : $tstx := $estx)
27+
| none => `(tactic| have : $tstx := $estx)
2628
else
27-
`(tactic| let this : $tstx := $estx)
29+
`(tactic| let $(mkIdent (h?.getD `_)) : $tstx := $estx)
2830
else
2931
if prop then
30-
`(tactic| have := $estx)
32+
match h? with
33+
| some h => `(tactic| have $(mkIdent h) := $estx)
34+
| none => `(tactic| have := $estx)
3135
else
32-
`(tactic| let this := $estx)
36+
`(tactic| let $(mkIdent (h?.getD `_)) := $estx)
3337
addSuggestion ref tac origSpan?
3438

3539
open Lean.Parser.Tactic

test/LibrarySearch/observe.lean

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import Mathlib.Tactic.Observe
2+
import Std.Tactic.GuardMsgs
23

4+
/-- info: Try this: have h : x + y = y + x := Nat.add_comm x y -/
5+
#guard_msgs in
36
example (x y : Nat) : True := by
4-
observe h : x + y = y + x
7+
observe? h : x + y = y + x
58
guard_hyp h : x + y = y + x
69
trivial

test/propose.lean

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,15 @@ example (K L M : List α) (w : L.Disjoint M) (m : K ⊆ L) : True := by
4141

4242
def bar (n : Nat) (x : String) : Nat × String := (n + x.length, x)
4343

44-
-- FIXME notice a bug here: should not generate `let this✝` with an inaccessible name.
4544
/--
46-
info: Try this: let this✝ : ℕ × String := bar p.1 p.2
45+
info: Try this: let a : ℕ × String := bar p.1 p.2
4746
---
48-
info: Try this: let this✝ : ℕ × String := bar p.1 p.2
47+
info: Try this: let _ : ℕ × String := bar p.1 p.2
4948
-/
5049
#guard_msgs in
5150
example (p : Nat × String) : True := by
5251
fail_if_success have? using p
53-
have? : Nat × String using p.1, p.2
52+
have? a : Nat × String using p.1, p.2
5453
have? : Nat × _ using p.1, p.2
5554
trivial
5655

0 commit comments

Comments
 (0)