为什么Coq递归原则同时传递子结构和递归调用的结果?
在检查了为不同递归数据类型生成的几个不同的递归原则之后,我注意到在递归情况下,子结构与子结构上递归调用的结果一起传递 例如,执行为什么Coq递归原则同时传递子结构和递归调用的结果?,coq,Coq,在检查了为不同递归数据类型生成的几个不同的递归原则之后,我注意到在递归情况下,子结构与子结构上递归调用的结果一起传递 例如,执行Print list_rect可提供: list_rect = fun (A : Type) (P : list A -> Type) (f : P nil) (f0 : forall (a : A) (l : list A), P l -> P (a :: l)%list) => fix F (l : list A) : P l := mat
Print list_rect
可提供:
list_rect =
fun (A : Type) (P : list A -> Type) (f : P nil)
(f0 : forall (a : A) (l : list A), P l -> P (a :: l)%list) =>
fix F (l : list A) : P l :=
match l as l0 return (P l0) with
| nil => f
| (y :: l0)%list => f0 y l0 (F l0)
end
: forall (A : Type) (P : list A -> Type),
P nil ->
(forall (a : A) (l : list A), P l -> P (a :: l)%list) ->
forall l : list A, P l
在模式匹配中,cons的大小写看起来像
(y::l0)%list=>f0 y l0(F l0)
。为什么f0
同时接受l0
和递归调用F
的l0
的结果?当您已经计算了调用F
的结果时,您需要访问列表尾部的情况是什么 一旦你需要归纳假设,你就需要列表的尾部,因为它以其类型出现:pl
,l
需要在范围内
现在,如果您不担心类型,那么同时拥有列表尾部和递归调用的一个很好的理由是效率:计算尾部在列表大小上是线性的,但在途中获取它是恒定的时间。这类问题的典型示例是当您只能访问迭代器而不能访问递归器时。有关递归器与迭代器的更多信息,请参见,第节。9.1(系统T)。在不需要折叠尾部的特殊情况下,是否合适?你只需要尾巴的特殊情况有名字吗?