Skip to content

Commit f935700

Browse files
committed
kyle tips
1 parent 2c25e35 commit f935700

2 files changed

Lines changed: 14 additions & 47 deletions

File tree

Mathlib/Tactic/Setm.lean

Lines changed: 13 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,58 +14,34 @@ public meta import Lean.Elab.BuiltinTerm
1414
This module defines the `setm` tactic.
1515
-/
1616

17-
public meta section
17+
meta section
1818

1919
open Lean Elab Tactic Meta Term Syntax
2020

2121
namespace Mathlib.Tactic.SetM
2222

23-
/-- This parser is declared inside a hidden namespace and should never be used. Its
24-
purpose is to register the ``Hidden.setmSyntheticHole` syntaax node kind in
25-
the environment. -/
26-
scoped syntax:max (name := Hidden.setmSyntheticHole)
27-
"?" (ident <|> "_") : term
28-
29-
open Hidden in
30-
/-- We give a distinguished name to the named holes appearing in the `setm` match pattern,
31-
to avoid unifying them with other metavariables in the context which have the same name. The
32-
distinguished name is reused across all holes with the same name in the pattern. -/
33-
meta partial def wrapSyntheticHoles : Syntax → StateT (NameMap Name) TacticM Syntax :=
23+
partial def wrapSyntheticHoles : Syntax → StateT (NameMap MVarId) TacticM Syntax :=
3424
fun stx => do
3525
if stx.isOfKind ``Lean.Parser.Term.syntheticHole && stx[1].isIdent then
36-
let name
26+
let mvar
3727
if let .some old := (← get).get? stx[1].getId then
3828
pure old
3929
else
40-
let unique ← mkFreshUserName stx[1].getId
41-
modify (.insert · stx[1].getId unique)
42-
pure unique
43-
return stx.setKind ``setmSyntheticHole |>.setArg 1 (mkIdent name)
30+
let name ← mkFreshUserName stx[1].getId
31+
let mvar := (← mkFreshExprMVar .none (userName := name)).mvarId!
32+
modify (.insert · stx[1].getId mvar)
33+
pure mvar
34+
let ident : Ident := mkIdent (← mvar.getTag)
35+
return ← withRef stx <| `(? $ident)
4436
match stx with
4537
| .node info kind args => return .node info kind (← args.mapM wrapSyntheticHoles)
4638
| _ => return stx
4739

48-
open Hidden in
49-
/-- Elaborate the named `setm` holes, creating metavariables for them. -/
50-
@[term_elab Hidden.setmSyntheticHole]
51-
def elabSetmSyntheticHole : Term.TermElab := fun stx expectedType? => do
52-
unless stx.isOfKind ``setmSyntheticHole do
53-
throwUnsupportedSyntax
54-
if let .ident _ _ n _ := stx[1] then
55-
-- Reuse metavariables in the context who have the same name.
56-
-- nb: at this point, they already have the distinguished names, so this is safe.
57-
for (id, decl) in (← getMCtx).decls do
58-
if decl.userName == n then return .mvar id
59-
let mvar ← mkFreshExprMVar expectedType? (userName := n)
60-
registerMVarErrorHoleInfo mvar.mvarId! stx
61-
return mvar
62-
else elabHole stx expectedType?
63-
6440
syntax (name := setMStx) "setm " term (Parser.Tactic.location)? : tactic
6541

6642
-- This code was copied from the `change` tactic in core. I am not sure if in our context,
6743
-- all of it is necessary (could there be other synthetic opaque MVars that were not holes?).
68-
meta def elabSetM (e : Expr) (p : Syntax) : TacticM Expr := do
44+
def elabSetM (e : Expr) (p : Syntax) : TacticM Expr := do
6945
let p ← runTermElab do
7046
let p ← Term.elabTermEnsuringType p (← inferType e)
7147
unless ← isDefEq p e do
@@ -80,25 +56,16 @@ meta def elabSetM (e : Expr) (p : Syntax) : TacticM Expr := do
8056
return ← instantiateMVars p
8157

8258
@[tactic setMStx]
83-
meta def evalSetM : Tactic
59+
public def evalSetM : Tactic
8460
| `(tactic| setm $pat:term $[$loc:location]?) => withReducibleAndInstances do
85-
let (pat, names) ← StateT.run (wrapSyntheticHoles pat) .empty
61+
let (pat, mvars) ← StateT.run (wrapSyntheticHoles pat) .empty
8662
let locations := expandOptLocation (Lean.mkOptionalNode loc)
8763
-- First, unify the pattern with the target of each location.
8864
withLocation locations
8965
(atLocal := unify pat ∘ .some)
9066
(atTarget := unify pat .none)
9167
(failed := fun _ ↦ throwError "'setm' tactic failed")
92-
-- Now, make a mapping of hole names to the metavariables that appeared in the pattern.
93-
let mctx ← getMCtx
94-
let mvars : NameMap MVarId := mctx.decls.foldl (init := {}) fun acc id decl =>
95-
if let Option.some n := Id.run <| do
96-
for (n, un) in names do
97-
if un == decl.userName then return .some n
98-
return .none
99-
then acc.insert n id
100-
else acc
101-
-- Finally, for each metavariable...
68+
-- The, for each metavariable...
10269
for (n, m) in mvars do
10370
-- ... instantiate it and introduce a let into the context...
10471
let val ← instantiateMVars (.mvar m)

MathlibTest/Tactic/Setm.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ example {a b c : NotQuiteNat} (h : a + b = c) : True := by
5555

5656
/--
5757
error: setm: pattern
58-
@Eq Nat (?A✝ + ?B✝) ?m.11
58+
@Eq Nat (?A✝ + ?B✝) ?m.12
5959
is not defeq to goal
6060
@Eq NotQuiteNat (a + b) c
6161
-/

0 commit comments

Comments
 (0)