【发布时间】:2017-11-02 19:01:52
【问题描述】:
我对 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.
第一个和第二个例子表明,当试图了解一个固定点是否正在终止时,Coq 能够解析记录访问器,基本上评估我们在 tree_P1 中写的内容与我们在 tree_P2 中写的内容。
但这似乎只有在本地构建记录 (let tree_C :=…) 时才有效,而不是在使用 Definition 定义时才有效。
但是Fixpoint 可以很好地查看其他定义,例如通过list_P。那么记录有什么特别之处,我可以让 Coq 接受tree_P3吗?
【问题讨论】:
标签: coq termination