Coq 中内置策略(case、destruct、inversion 等)的确切定义
The exact definition of an in built Tactic (case, destruct, inversion etc.) in Coq
如何才能看到 Coq 中内置策略的准确实现?更具体地说,是否有替代 Print Ltac <user-defined-tactics>
的方法可以在 Coq 中找到内置策略的确切定义?
不,Print Ltac
没有其他选择。在某种程度上,这是因为内置策略是在 OCaml 中实现的,而构成它们的部分并不总是可以用 Ltac 中更原始的策略来表达(而且这种翻译几乎永远不会准确)。我知道找到定义的唯一方法是去源代码潜水。例如,如果您搜索 "destruct"
,您将在 plugins/ltac/g_tactic.ml4
中找到行
| IDENT "destruct"; icl = induction_clause_list ->
TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(false,false,icl))
表示 destruct
被解析为原子策略节点 TacInductionDestruct
。搜索 TacInductionDestruct
给出了 plugins/ltac/tacinterp.ml
:
中的实现
(* Derived basic tactics *)
| TacInductionDestruct (isrec,ev,(l,el)) ->
(* spiwack: some unknown part of destruct needs the goal to be
prenormalised. *)
Proofview.Goal.nf_enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = project gl in
let sigma,l =
List.fold_left_map begin fun sigma (c,(ipato,ipats),cls) ->
(* TODO: move sigma as a side-effect *)
(* spiwack: the [*p] variants are for printing *)
let cp = c in
let c = interp_destruction_arg ist gl c in
let ipato = interp_intro_pattern_naming_option ist env sigma ipato in
let ipatsp = ipats in
let sigma,ipats = interp_or_and_intro_pattern_option ist env sigma ipats in
let cls = Option.map (interp_clause ist env sigma) cls in
sigma,((c,(ipato,ipats),cls),(cp,(ipato,ipatsp),cls))
end sigma l
in
let l,lp = List.split l in
let sigma,el =
Option.fold_left_map (interp_open_constr_with_bindings ist env) sigma el in
Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
(name_atomic ~env
(TacInductionDestruct(isrec,ev,(lp,el)))
(Tactics.induction_destruct isrec ev (l,el)))
end
您可以在 tactics/tactics.ml
中找到 Tactics.induction_destruct
的实现。
大多数原始策略以两种方式之一开始:要么在 g_tactic.ml4
中有一个条目说明如何将该策略解析为原子策略节点,要么在某处有一个 TACTIC EXTEND
,例如,对于 revert
,我们有 plugins/ltac/coretactics.ml4
TACTIC EXTEND revert
[ "revert" ne_hyp_list(hl) ] -> [ Tactics.revert hl ]
END
如果定义为 Ltac AST 中的一个节点,那么要看的地方是 tacinterp.ml
,它描述了如何解释那些策略。无论哪种方式,您都可以继续追查 OCaml 定义以查看策略是如何实施的。
如何才能看到 Coq 中内置策略的准确实现?更具体地说,是否有替代 Print Ltac <user-defined-tactics>
的方法可以在 Coq 中找到内置策略的确切定义?
不,Print Ltac
没有其他选择。在某种程度上,这是因为内置策略是在 OCaml 中实现的,而构成它们的部分并不总是可以用 Ltac 中更原始的策略来表达(而且这种翻译几乎永远不会准确)。我知道找到定义的唯一方法是去源代码潜水。例如,如果您搜索 "destruct"
,您将在 plugins/ltac/g_tactic.ml4
中找到行
| IDENT "destruct"; icl = induction_clause_list ->
TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(false,false,icl))
表示 destruct
被解析为原子策略节点 TacInductionDestruct
。搜索 TacInductionDestruct
给出了 plugins/ltac/tacinterp.ml
:
(* Derived basic tactics *)
| TacInductionDestruct (isrec,ev,(l,el)) ->
(* spiwack: some unknown part of destruct needs the goal to be
prenormalised. *)
Proofview.Goal.nf_enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = project gl in
let sigma,l =
List.fold_left_map begin fun sigma (c,(ipato,ipats),cls) ->
(* TODO: move sigma as a side-effect *)
(* spiwack: the [*p] variants are for printing *)
let cp = c in
let c = interp_destruction_arg ist gl c in
let ipato = interp_intro_pattern_naming_option ist env sigma ipato in
let ipatsp = ipats in
let sigma,ipats = interp_or_and_intro_pattern_option ist env sigma ipats in
let cls = Option.map (interp_clause ist env sigma) cls in
sigma,((c,(ipato,ipats),cls),(cp,(ipato,ipatsp),cls))
end sigma l
in
let l,lp = List.split l in
let sigma,el =
Option.fold_left_map (interp_open_constr_with_bindings ist env) sigma el in
Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
(name_atomic ~env
(TacInductionDestruct(isrec,ev,(lp,el)))
(Tactics.induction_destruct isrec ev (l,el)))
end
您可以在 tactics/tactics.ml
中找到 Tactics.induction_destruct
的实现。
大多数原始策略以两种方式之一开始:要么在 g_tactic.ml4
中有一个条目说明如何将该策略解析为原子策略节点,要么在某处有一个 TACTIC EXTEND
,例如,对于 revert
,我们有 plugins/ltac/coretactics.ml4
TACTIC EXTEND revert
[ "revert" ne_hyp_list(hl) ] -> [ Tactics.revert hl ]
END
如果定义为 Ltac AST 中的一个节点,那么要看的地方是 tacinterp.ml
,它描述了如何解释那些策略。无论哪种方式,您都可以继续追查 OCaml 定义以查看策略是如何实施的。