/
Constructor.lean
57 lines (51 loc) · 2.11 KB
/
Constructor.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import Lean.Meta.Check
import Lean.Meta.Tactic.Util
import Lean.Meta.Tactic.Apply
namespace Lean.Meta
/--
When the goal `mvarId` type is an inductive datatype,
`constructor` calls `apply` with the first matching constructor.
-/
def _root_.Lean.MVarId.constructor (mvarId : MVarId) (cfg : ApplyConfig := {}) : MetaM (List MVarId) := do
mvarId.withContext do
mvarId.checkNotAssigned `constructor
let target ← mvarId.getType'
matchConstInduct target.getAppFn
(fun _ => throwTacticEx `constructor mvarId "target is not an inductive datatype")
fun ival us => do
for ctor in ival.ctors do
try
return ← mvarId.apply (Lean.mkConst ctor us) cfg
catch _ =>
pure ()
throwTacticEx `constructor mvarId "no applicable constructor found"
@[deprecated MVarId.constructor]
def constructor (mvarId : MVarId) (cfg : ApplyConfig := {}) : MetaM (List MVarId) := do
mvarId.constructor cfg
def _root_.Lean.MVarId.existsIntro (mvarId : MVarId) (w : Expr) : MetaM MVarId := do
mvarId.withContext do
mvarId.checkNotAssigned `exists
let target ← mvarId.getType'
matchConstStruct target.getAppFn
(fun _ => throwTacticEx `exists mvarId "target is not an inductive datatype with one constructor")
fun _ us cval => do
if cval.numFields < 2 then
throwTacticEx `exists mvarId "constructor must have at least two fields"
let ctor := mkAppN (Lean.mkConst cval.name us) target.getAppArgs[:cval.numParams]
let ctorType ← inferType ctor
let (mvars, _, _) ← forallMetaTelescopeReducing ctorType (some (cval.numFields-2))
let f := mkAppN ctor mvars
checkApp f w
let [mvarId] ← mvarId.apply <| mkApp f w
| throwTacticEx `exists mvarId "unexpected number of subgoals"
pure mvarId
@[deprecated MVarId.existsIntro]
def existsIntro (mvarId : MVarId) (w : Expr) : MetaM MVarId := do
mvarId.existsIntro w
end Lean.Meta