Recursion 构造演算中的递归

Recursion 构造演算中的递归,recursion,functional-programming,coq,lambda-calculus,typed-lambda-calculus,Recursion,Functional Programming,Coq,Lambda Calculus,Typed Lambda Calculus,如何在(纯)中定义递归函数?我没有看到任何定点组合器。中的人可能能够提供更多的见解,但这里有一个尝试 归纳数据类型在构造演算中定义为:数据类型是其折叠函数的类型。最基本的例子是自然数,使用类似Coq的表示法定义如下: nat := forall (T : Type), T -> (T -> T) -> T 这种编码产生两个结果:(1)用于构造自然数的术语zero:nat和succ:nat->nat,以及(2)用于编写递归函数的运算符nat\u rec zero : nat z

如何在(纯)中定义递归函数?我没有看到任何定点组合器。

中的人可能能够提供更多的见解,但这里有一个尝试

归纳数据类型在构造演算中定义为:数据类型是其折叠函数的类型。最基本的例子是自然数,使用类似Coq的表示法定义如下:

nat := forall (T : Type), T -> (T -> T) -> T
这种编码产生两个结果:(1)用于构造自然数的术语
zero:nat
succ:nat->nat
,以及(2)用于编写递归函数的运算符
nat\u rec

zero : nat
zero T x f := x

succ : nat -> nat
succ n T x f := f (n T x f)

nat_rec : forall T, T -> (T -> T) -> nat -> T
nat_rec T x f n := n T x f
如果我们对术语
x:T
F:T->T
提出
F:=nat\u rec T x F
,我们会发现以下等式是有效的:

F zero = x
F (succ n) = f (F n)
因此,
nat_rec
允许我们通过为基本情况指定返回值
x
和处理递归调用值的函数
f
来定义递归函数。请注意,这不允许我们对自然数定义任意递归函数,而只允许对其参数的前导执行递归调用的函数。允许任意递归将为部分函数打开大门,这将损害微积分的可靠性

这个例子可以推广到其他归纳数据类型。例如,我们可以将自然数列表的类型定义为其折叠权函数的类型:

list_nat := forall T, T -> (nat -> T -> T) -> T

函数f调用函数g是函数组合。如果f在调用它自己,那么你有一个包含相同函数的函数组合。在CoC中没有不动点组合子是可定义的。这将允许不终止,并且没有不终止的CoC术语。对严格较小的参数进行递归调用(根据有根据的关系)怎么样?Coq中有根据的递归也是根据结构递归实现的(在从有根据的关系派生的“可访问性谓词”上),因此,同样的技术也应该适用。实际上,我不确定Coq的不动点是否容易以这种方式编码,因为Coq的终止检查器所需的原语属性似乎相当重要:它不仅适用于直接子项(去掉一个构造函数后),而且适用于通过传递获得的子项,即使是通过嵌套的不动点来观察,那么对于CiC中Church编码的自然数,归纳原理是如何定义的呢?似乎说还需要其他东西,或者类型“太大”(=包含奇异、奇怪的元素)。@larsr您无法为Church编码类型的所有元素定义归纳原则,无论是在CoC还是在CiC中。归纳原则是引入归纳类型的原因之一。