私は自分自身に説明できないCoqの終了チェッカーの動作につまづいています。考えてみましょう:いつ終了チェッカーがレコードアクセッサを減らすのですか
Require Import Coq.Lists.List.
Record C a := { P : a -> bool }.
Arguments P {_}.
Definition list_P {a} (a_C : C a) : list a -> bool := existsb (P a_C).
Definition list_C {a} (a_C : C a) : C (list a) := {| P := list_P a_C |}.
(* Note that *)
Eval cbn in fun a C => (P (list_C C)).
(* evaluates to: fun a C => list_P C *)
Inductive tree a := Node : a -> list (tree a) -> tree a.
(* Works, using a local record *)
Fixpoint tree_P1 {a} (a_C : C a) (t : tree a) : bool :=
let tree_C := Build_C _ (tree_P1 a_C) in
let list_C' := Build_C _ (list_P tree_C) in
match t with Node _ x ts => orb (P a_C x) (P list_C' ts) end.
(* Works too, using list_P directly *)
Fixpoint tree_P2 {a} (a_C : C a) (t : tree a) : bool :=
let tree_C := Build_C _ (tree_P2 a_C) in
match t with Node _ x ts => orb (P a_C x) (list_P tree_C ts) end.
(* Does not work, using a globally defined record. Why not? *)
Fixpoint tree_P3 {a} (a_C : C a) (t : tree a) : bool :=
let tree_C := Build_C _ (tree_P3 a_C) in
match t with Node _ x ts => orb (P a_C x) (P (list_C tree_C) ts) end.
第一及び第二の例不動点が終了しているかどうかを理解しようとしたときに、コックは基本的に、我々はtree_P2
に書いたものにtree_P1
に書いたものを評価し、記録アクセサを解決することができ、ことを示しています。
しかし、これは、レコードがローカルに構築されている場合(let tree_C :=…
)、Definition
を使用して定義されている場合にのみ機能します。
しかし、Fixpoint
は他の定義を見ても問題ありません。 list_P
までだから、レコードに関して特別なのは何ですか、私はCoqにtree_P3
を受け入れることができますか?