lean4-htt/src/Lean/Meta/Tactic/Constructor.lean
2021-05-06 10:40:56 -07:00

44 lines
1.7 KiB
Text

/-
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
import Lean.Meta.Check
import Lean.Meta.Tactic.Util
import Lean.Meta.Tactic.Apply
namespace Lean.Meta
def constructor (mvarId : MVarId) : MetaM (List MVarId) := do
withMVarContext mvarId do
checkNotAssigned mvarId `constructor
let target ← getMVarType' mvarId
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 ← apply mvarId (Lean.mkConst ctor us)
catch _ =>
pure ()
throwTacticEx `constructor mvarId "no applicable constructor found"
def existsIntro (mvarId : MVarId) (w : Expr) : MetaM MVarId := do
withMVarContext mvarId do
checkNotAssigned mvarId `exists
let target ← getMVarType' mvarId
matchConstStruct target.getAppFn
(fun _ => throwTacticEx `exists mvarId "target is not an inductive datatype with one constructor")
fun ival 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] ← apply mvarId <| mkApp f w
| throwTacticEx `exists mvarId "unexpected number of subgoals"
pure mvarId
end Lean.Meta