Skip to content

Commit 030a15b

Browse files
committed
Try to not even get unwanted hyps into the context, using mvarId.intro1_
1 parent df73b3a commit 030a15b

File tree

2 files changed

+42
-37
lines changed

2 files changed

+42
-37
lines changed

src/Lean/Meta/Match/CaseValues.lean

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,14 @@ import Lean.Meta.Tactic.Subst
1212

1313
namespace Lean.Meta
1414

15-
structure CaseValueSubgoal where
16-
mvarId : MVarId
17-
newH : FVarId
18-
deriving Inhabited
19-
2015
/--
21-
Split goal `... |- C x` into two subgoals
22-
`..., (h : x = value) |- C x`
23-
`..., (h : x != value) |- C x`
24-
where `fvarId` is `x`s id.
16+
Split goal `... |- C x`,, where `fvarId` is `x`s id, into two subgoals
17+
`..., |- (h : x = value) → C x`
18+
`..., |- (h : x != value) → C x`
2519
The type of `x` must have decidable equality.
2620
-/
2721
def caseValue (mvarId : MVarId) (fvarId : FVarId) (value : Expr) (hName : Name := `h)
28-
: MetaM (CaseValueSubgoal × CaseValueSubgoal) :=
22+
: MetaM (MVarId × MVarId) :=
2923
mvarId.withContext do
3024
let tag ← mvarId.getTag
3125
mvarId.checkNotAssigned `caseValue
@@ -38,15 +32,7 @@ def caseValue (mvarId : MVarId) (fvarId : FVarId) (value : Expr) (hName : Name :
3832
let elseMVar ← mkFreshExprSyntheticOpaqueMVar elseTarget tag
3933
let val ← mkAppOptM `dite #[none, xEqValue, none, thenMVar, elseMVar]
4034
mvarId.assign val
41-
let (elseH, elseMVarId) ← elseMVar.mvarId!.intro1P
42-
let elseSubgoal := { mvarId := elseMVarId, newH := elseH }
43-
let (thenH, thenMVarId) ← thenMVar.mvarId!.intro1P
44-
thenMVarId.withContext do
45-
trace[Meta] "searching for decl"
46-
let _ ← thenH.getDecl
47-
trace[Meta] "found decl"
48-
let thenSubgoal := { mvarId := thenMVarId, newH := thenH }
49-
pure (thenSubgoal, elseSubgoal)
35+
return (thenMVar.mvarId!, elseMVar.mvarId!)
5036

5137
public structure CaseValuesSubgoal where
5238
mvarId : MVarId
@@ -55,41 +41,43 @@ public structure CaseValuesSubgoal where
5541
deriving Inhabited
5642

5743
/--
58-
Split goal `... |- C x` into values.size + 1 subgoals
59-
1) `..., (h_1 : x = value[0]) |- C value[0]`
44+
Split goal `... |- C x`, where `fvarId` is `x`s id, into `values.size + 1` subgoals
45+
1) `..., (h_1 : x = value[0]) |- C value[0]`
6046
...
61-
n) `..., (h_n : x = value[n - 1]) |- C value[n - 1]`
47+
n) `..., (h_n : x = value[n - 1]) |- C value[n - 1]`
6248
n+1) `..., (h_1 : x != value[0]) ... (h_n : x != value[n-1]) |- C x`
6349
where `n = values.size`
64-
where `fvarId` is `x`s id.
6550
The type of `x` must have decidable equality.
6651
6752
Remark: the last subgoal is for the "else" catchall case, and its `subst` is `{}`.
6853
Remark: the field `newHs` has size 1 forall but the last subgoal.
6954
70-
If `needsHyps = false` then the else case has the hypotheses cleared.
55+
If `needsHyps = false` then the else case comes without hypotheses.
7156
-/
7257
public def caseValues (mvarId : MVarId) (fvarId : FVarId) (values : Array Expr) (hNamePrefix := `h)
7358
(needHyps := true) : MetaM (Array CaseValuesSubgoal) :=
7459
let rec loop : Nat → MVarId → List Expr → Array FVarId → Array CaseValuesSubgoal → MetaM (Array CaseValuesSubgoal)
7560
| _, mvarId, [], _, _ => throwTacticEx `caseValues mvarId "list of values must not be empty"
7661
| i, mvarId, v::vs, hs, subgoals => do
77-
let (thenSubgoal, elseSubgoal) ← caseValue mvarId fvarId v (hNamePrefix.appendIndexAfter i)
78-
appendTagSuffix thenSubgoal.mvarId ((`case).appendIndexAfter i)
79-
let thenMVarId ← thenSubgoal.mvarId.tryClearMany hs
80-
let (subst, mvarId) ← substCore thenMVarId thenSubgoal.newH (symm := false) {} (clearH := true)
81-
let subgoals := subgoals.push { mvarId := mvarId, newHs := #[], subst := subst }
62+
let (thenMVarId, elseMVarId) ← caseValue mvarId fvarId v (hNamePrefix.appendIndexAfter i)
63+
appendTagSuffix thenMVarId ((`case).appendIndexAfter i)
64+
let thenMVarId ← thenMVarId.tryClearMany hs
65+
let (thenH, thenMVarId) ← thenMVarId.intro1P
66+
let (subst, thenMVarId) ← substCore thenMVarId thenH (symm := false) {} (clearH := true)
67+
let subgoals := subgoals.push { mvarId := thenMVarId, newHs := #[], subst := subst }
68+
let (hs', elseMVarId) ←
69+
if needHyps then
70+
let (elseH, elseMVarId) ← elseMVarId.intro1P
71+
pure (hs.push elseH, elseMVarId)
72+
else
73+
let elseMVarId ← elseMVarId.intro1_
74+
pure (hs, elseMVarId)
8275
match vs with
8376
| [] => do
84-
appendTagSuffix elseSubgoal.mvarId ((`case).appendIndexAfter (i+1))
85-
pure $ subgoals.push { mvarId := elseSubgoal.mvarId, newHs := hs.push elseSubgoal.newH, subst := {} }
77+
appendTagSuffix elseMVarId ((`case).appendIndexAfter (i+1))
78+
pure $ subgoals.push { mvarId := elseMVarId, newHs := hs', subst := {} }
8679
| vs =>
87-
let (mvarId', hs') ←
88-
if needHyps then
89-
pure (elseSubgoal.mvarId, hs.push elseSubgoal.newH)
90-
else
91-
pure (← elseSubgoal.mvarId.tryClear elseSubgoal.newH, hs)
92-
loop (i+1) mvarId' vs hs' subgoals
80+
loop (i+1) elseMVarId vs hs' subgoals
9381

9482
loop 1 mvarId values.toList #[] #[]
9583

src/Lean/Meta/Tactic/Intro.lean

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,23 @@ does not start with a forall, lambda or let. -/
161161
abbrev _root_.Lean.MVarId.intro1P (mvarId : MVarId) : MetaM (FVarId × MVarId) :=
162162
intro1Core mvarId true
163163

164+
/--
165+
Given a goal `... |- β → α`, returns a goal `... ⊢ α`.
166+
Like `intro h; clear h`, but without ever appending to the local context.
167+
-/
168+
def _root_.Lean.MVarId.intro1_ (mvarId : MVarId) : MetaM MVarId := do
169+
mvarId.withContext do
170+
let target ← mvarId.getType'
171+
match target with
172+
| .forallE n β α bi =>
173+
if α.hasLooseBVars then
174+
throwError "intro1_: expected arrow type\n{mvarId}"
175+
let tag ← mvarId.getTag
176+
let newMVar ← mkFreshExprSyntheticOpaqueMVar α tag
177+
mvarId.assign (.lam n β newMVar bi)
178+
return newMVar.mvarId!
179+
| _ => throwError "intro1_: expected arrow type\n{mvarId}"
180+
164181
/--
165182
Calculate the number of new hypotheses that would be created by `intros`,
166183
i.e. the number of binders which can be introduced without unfolding definitions.

0 commit comments

Comments
 (0)