Runs a term elaborator inside a tactic.
This function ensures that term elaboration fails when backtracking,
i.e., in first| tac term | other
.
タクティクは構文カテゴリ tactic
に含まれるプロダクションです。タクティクの構文が与えられると、タクティクのインタプリタはタクティクモナド TacticM
でアクションを実行します。これは Lean の項エラボレータのラッパーで、タクティクの実行にあたって追加で状態を追跡するものです。カスタムタクティクは tactic
カテゴリの拡張と、以下のいずれかから構成されます:
新しいタクティクを定義する最も簡単な方法は、 macro として既存のタクティクに展開することです。マクロ展開はタクティクの実行と同時に行われます。タクティクのインタプリタは、まずタクティクマクロを解釈する直前に展開します。タクティクマクロはタクティクスクリプトを実行する前に完全には展開されないため、再帰を使用することができます;マクロ構文の再帰的な出現が実行可能なタクティクの下にある限り、マクロの展開は無限に連鎖しません。
以下の repeat
に似たタクティクの再帰的な実装は、マクロ展開によって定義されます。引数 $t
が失敗した時、 rep
の再帰的な発生は絶対に呼び出されず、したがってマクロ展開も決して行われません。
syntax "rep" tactic : tactic
macro_rules
| `(tactic|rep $t) =>
`(tactic|
first
| $t; rep $t
| skip)
example : 0 ≤ 4 := ⊢ 0 ≤ 4
rep (⊢ Nat.le 0 0)
All goals completed! 🐙
他の Lean のマクロと同様に、タクティクマクロは hygienic です。グローバル名への参照はマクロが定義された時に解決され、タクティクマクロによって導入された名前はその呼び出しサイトから名前をキャプチャすることはできません。
タクティクマクロを定義するとき、パターンマッチと構成に用いられる構文が構文カテゴリ tactic
のものであることを指定することが重要です。そうでない場合、構文は項の構文として解釈され、タクティクのための正しくない AST とマッチしたり構成されたりします。
マクロの展開は失敗することがあるため、複数のマクロが同じ構文にマッチすることができ、バックトラックが可能になります。タクティクマクロはこれをさらに推し進めます:タクティクマクロの展開が成功しても解釈時に展開に失敗すると、タクティクのインタプリタは次の展開を試みます。これは Lean の多くの組み込みタクティクを拡張可能にするためにしようされます。 Lean.Parser.Command.macro_rules : command
macro_rules
宣言を追加することで新しい動作をタクティクに追加できます。
trivial
の拡張
trivial
はユーザを煩わせる価値のないサブゴールを素早くディスパッチするために、他の多くのタクティクから使用されますが、新しいマクロ展開によって拡張できるように設計されています。Lean のデフォルトの trivial
は IsEmpty []
ゴールを解決できません:
def IsEmpty (xs : List α) : Prop :=
¬ xs ≠ []
example (α : Type u) : IsEmpty (α := α) [] := α:Type u⊢ IsEmpty [] α:Type u⊢ IsEmpty []
このエラーメッセージは trivial
が最後に assumption
を試したことによるものです。ここで別の拡張を追加することで trivial
がこれらのゴールを対応するようにできます:
def emptyIsEmpty : IsEmpty (α := α) [] := α:Type u_1⊢ IsEmpty [] All goals completed! 🐙
macro_rules | `(tactic|trivial) => `(tactic|exact emptyIsEmpty)
example (α : Type u) : IsEmpty (α := α) [] := α:Type u⊢ IsEmpty []
All goals completed! 🐙
マクロ展開は、展開された構文のいずれかの部分で失敗した場合にバックトラックを引き起こす可能性があります。複数の展開を別々の Lean.Parser.Command.macro_rules : command
macro_rules
宣言で定義することで、 first
の中置バージョンを定義することができます:
syntax tactic "<|||>" tactic : tactic
macro_rules
| `(tactic|$t1 <|||> $t2) => pure t1
macro_rules
| `(tactic|$t1 <|||> $t2) => pure t2
example : 2 = 2 := ⊢ 2 = 2
All goals completed! 🐙 <|||> apply And.intro
example : 2 = 2 := ⊢ 2 = 2
apply And.intro <|||> All goals completed! 🐙
複数の Lean.Parser.Command.macro_rules : command
macro_rules
宣言は、それぞれがパターンマッチ関数を定義し、常に最初にマッチする選択肢を取ることができるようにするために必要です。バックトラックは Lean.Parser.Command.macro_rules : command
macro_rules
宣言の粒度であり、個々のケースではありません。
Relationship to Lean.Elab.Term.TermElabM
, Lean.Meta.MetaM
Overview of available effects
Checkpointing
Tracked at issue #67
Lean.Elab.Tactic.Tactic : Type
Lean.Elab.Tactic.TacticM (α : Type) : Type
Lean.Elab.Tactic.run (mvarId : Lean.MVarId) (x : TacticM Unit) : Lean.Elab.TermElabM (List Lean.MVarId)
Lean.Elab.Tactic.runTermElab {α : Type} (k : Lean.Elab.TermElabM α) (mayPostpone : Bool := false) : TacticM α
Runs a term elaborator inside a tactic.
This function ensures that term elaboration fails when backtracking,
i.e., in first| tac term | other
.
Lean.Elab.Tactic.ensureHasNoMVars (e : Lean.Expr) : TacticM Unit
Lean.Elab.Tactic.getFVarId (id : Lean.Syntax) : TacticM Lean.FVarId
Lean.Elab.Tactic.getFVarIds (ids : Array Lean.Syntax) : TacticM (Array Lean.FVarId)
Lean.Elab.Tactic.sortMVarIdsByIndex {m : Type → Type} [Lean.MonadMCtx m] [Monad m] (mvarIds : List Lean.MVarId) : m (List Lean.MVarId)
Lean.Elab.Tactic.withLocation (loc : Location) (atLocal : Lean.FVarId → TacticM Unit) (atTarget : TacticM Unit) (failed : Lean.MVarId → TacticM Unit) : TacticM Unit
Runs the given atLocal
and atTarget
methods on each of the locations selected by the given loc
.
If loc
is a list of locations, runs at each specified hypothesis (and finally the goal if ⊢
is included),
and fails if any of the tactic applications fail.
If loc
is *
, runs at the target first and then the hypotheses in reverse order.
If atTarget
closes the main goal, withLocation
does not run atLocal
.
If all tactic applications fail, withLocation
with call failed
with the main goal mvar.
Lean.Elab.Tactic.getGoals : TacticM (List Lean.MVarId)
Returns the list of goals. Goals may or may not already be assigned.
Lean.Elab.Tactic.setGoals (mvarIds : List Lean.MVarId) : TacticM Unit
Lean.Elab.Tactic.closeMainGoal (tacName : Lean.Name) (val : Lean.Expr) (checkUnassigned : Bool := true) : TacticM Unit
Closes main goal using the given expression.
If checkUnassigned == true
, then val
must not contain unassigned metavariables.
Returns true
if val
was successfully used to close the goal.
Lean.Elab.Tactic.tagUntaggedGoals (parentTag newSuffix : Lean.Name) (newGoals : List Lean.MVarId) : TacticM Unit
Use parentTag
to tag untagged goals at newGoals
.
If there are multiple new untagged goals, they are named using <parentTag>.<newSuffix>_<idx>
where idx > 0
.
If there is only one new untagged goal, then we just use parentTag
Lean.Elab.Tactic.getUnsolvedGoals : TacticM (List Lean.MVarId)
Lean.Elab.Tactic.pruneSolvedGoals : TacticM Unit
Lean.Elab.Tactic.appendGoals (mvarIds : List Lean.MVarId) : TacticM Unit
Add the given goals at the end of the current list of goals.
Lean.Elab.Tactic.closeMainGoalUsing (tacName : Lean.Name) (x : Lean.Expr → Lean.Name → TacticM Lean.Expr) (checkNewUnassigned : Bool := true) : TacticM Unit
Try to close main goal using x target tag
, where target
is the type of the main goal and tag
is its user name.
If checkNewUnassigned
is true, then throws an error if the resulting value has metavariables that were created during the execution of x
.
If it is false, then it is the responsibility of x
to add such metavariables to the goal list.
During the execution of x
:
The local context is that of the main goal.
The goal list has the main goal removed.
It is allowable to modify the goal list, for example with Lean.Elab.Tactic.pushGoals
.
On failure, the main goal remains at the front of the goal list.
Lean.Elab.Tactic.elabTerm (stx : Lean.Syntax) (expectedType? : Option Lean.Expr) (mayPostpone : Bool := false) : TacticM Lean.Expr
Elaborate stx
in the current MVarContext
. If given, the expectedType
will be used to help
elaboration but not enforced (use elabTermEnsuringType
to enforce an expected type).
Lean.Elab.Tactic.elabTermEnsuringType (stx : Lean.Syntax) (expectedType? : Option Lean.Expr) (mayPostpone : Bool := false) : TacticM Lean.Expr
Elaborate stx
in the current MVarContext
. If given, the expectedType
will be used to help
elaboration and then a TypeMismatchError
will be thrown if the elaborated type doesn't match.
Lean.Elab.Tactic.elabTermWithHoles (stx : Lean.Syntax) (expectedType? : Option Lean.Expr) (tagSuffix : Lean.Name) (allowNaturalHoles : Bool := false) (parentTag? : Option Lean.Name := none) : TacticM (Lean.Expr × List Lean.MVarId)
Elaborates stx
and collects the MVarId
s of any holes that were created during elaboration.
With allowNaturalHoles := false
(the default), any new natural holes (_
) which cannot
be synthesized during elaboration cause elabTermWithHoles
to fail. (Natural goals appearing in
stx
which were created prior to elaboration are permitted.)
Unnamed MVarId
s are renamed to share the tag parentTag?
(or the main goal's tag if parentTag?
is none
).
If multiple unnamed goals are encountered, tagSuffix
is appended to this tag along with a numerical index.
Note:
Previously-created MVarId
s which appear in stx
are not returned.
All parts of elabTermWithHoles
operate at the current MCtxDepth
, and therefore may assign
metavariables.
When allowNaturalHoles := true
, stx
is elaborated under withAssignableSyntheticOpaque
,
meaning that .syntheticOpaque
metavariables might be assigned during elaboration. This is a
consequence of the implementation.
これらの操作は主に TacticM
や特定のタクティクの実装の一部として使用されます。新しいタクティクを実装する際に役に立つことは稀です。
これらの操作は標準的な Lean のモナド型クラスを通して公開されます。
Lean.Elab.Tactic.tryCatch {α : Type} (x : TacticM α) (h : Lean.Exception → TacticM α) : TacticM α
Non-backtracking try
/catch
.
Lean.Elab.Tactic.liftMetaMAtMain {α : Type} (x : Lean.MVarId → Lean.MetaM α) : TacticM α
Lean.Elab.Tactic.getMainModule : TacticM Lean.Name
Lean.Elab.Tactic.getCurrMacroScope : TacticM Lean.MacroScope
Lean.Elab.Tactic.adaptExpander (exp : Lean.Syntax → TacticM Lean.Syntax) : Tactic
Adapt a syntax transformation to a regular tactic evaluator.
Lean.Elab.Tactic.elabCasesTargets (targets : Array Lean.Syntax) : TacticM (Array Lean.Expr × Array (Lean.Ident × Lean.FVarId))
Lean.Elab.Tactic.elabSimpArgs (stx : Lean.Syntax) (ctx : Lean.Meta.Simp.Context) (simprocs : Lean.Meta.Simp.SimprocsArray) (eraseLocal : Bool) (kind : SimpKind) : TacticM ElabSimpArgsResult
Elaborate extra simp theorems provided to simp
. stx
is of the form "[" simpTheorem,* "]"
If eraseLocal == true
, then we consider local declarations when resolving names for erased theorems (- id
),
this option only makes sense for simp_all
or *
is used.
When recover := true
, try to recover from errors as much as possible so that users keep seeing
the current goal.
Lean.Elab.Tactic.elabSimpConfig (optConfig : Lean.Syntax) (kind : SimpKind) : TacticM Lean.Meta.Simp.Config
Lean.Elab.Tactic.elabSimpConfigCtxCore : Lean.Syntax → TacticM Lean.Meta.Simp.ConfigCtx
Lean.Elab.Tactic.dsimpLocation' (ctx : Lean.Meta.Simp.Context) (simprocs : Lean.Meta.Simp.SimprocsArray) (loc : Location) : TacticM Lean.Meta.Simp.Stats
Implementation of dsimp?
.
Lean.Elab.Tactic.elabDSimpConfigCore : Lean.Syntax → TacticM Lean.Meta.DSimp.Config
Lean.Elab.Tactic.tacticElabAttribute : Lean.KeyedDeclsAttribute Tactic
Lean.Elab.Tactic.mkTacticAttribute : IO (Lean.KeyedDeclsAttribute Tactic)