Kleene-Rosser悖论
构造出Y组合子几乎证明了lambda系统具有图灵完备性,尽管在当年这样的理论发展还不完善。
但是任何具有图灵完备性的系统必定会受到图灵停机问题的困扰,这个问题的lambda版本就是 Kleene-Rosser 悖论。
为了便于理解,这里我们不采用原版的构造方法,我们会引入一些简化的概念来构造Kleene-Rosser悖论。
我们以Y组合子构造一个函数f:
可以发现,我们使得一个递归函数返回自身的否定,那么将会得到一个自相矛盾的函数。
这就是 Kleene-Rosser 悖论,它的存在导致 lambda 系统自身的不一致性。也导致包括邱奇本人、Rosser、Haskell等诸多优秀的数学和逻辑学家投入大量精力致力于修复这个问题。
但是在学术研究领域,有问题不一定是坏事,解决问题的过程中,诞生的新方法、新理论,可能价值反而超过解决问题本身。
Kleene-Rosser 悖论就是一个典型的案例。
简单类型论
为了解决Kleene-Rosser悖论,邱奇提出了为lambda函数引入类型。我们简要描述如下:
- 基本类型:如 Integer、Boolean 这样的基本类型。其值可以自行定义,通常来自一些数学概念。
- 函数类型:如 A -> B 这样的函数类型,部分常量函数可以自行定义,通常来自一些数学概念,亦可能由已有的类型通过lambda运算构成。
- 类型运算:
- 乘法类型 A×B,可理解为元组
- 加法类型 A+B,可以理解为类型的或关系
在这样的定义下,任何lambda表达式都有确定的类型。
通过上述类型定义,一方面,lambda演算可以作为工具,给其它数学分支使用,另一方面因为无法构造不动点,不能产生递归类型,这也就解决了Kleene-Rosser悖论。但正因为无法构造不动点,带有简单类型的lambda演算不再是图灵完备的。后世又有诸多数学家、计算机学家尝试在简单类型论的基础上恢复图灵完备性,那是后话,暂且不表。
即使失去了图灵完备性,简单类型lambda演算也拥有巨大的潜力。由 Haskell Curry 提出,并由 Howard 发展的 Curry-Howard 同构,揭示了简单类型论与命题逻辑之间的深刻联系。
Curry-Howard 同构
为了理解 Curry-Howard 同构,我们首先来简单复习一下命题逻辑。
命题逻辑是一组基本的逻辑工具。它定义了“命题”、“与”、“或”、“蕴含”等概念。
例如,如果我们有三个命题A、B、C,现有两个证明
则可以构造出证明
而我们考虑在带类型的lambda中,如果有两个函数:
通过此二函数的复合运算可以构造出函数f
Haskell Curry 发现命题逻辑和类型构造之间具有一种奇妙的联系:
在一个简单类型系统中,我们有一组对应于公理的简单类型,如果我们能构造出构造出一些新类型的表达式,那么我们也能在命题逻辑中证明这些新类型对应的命题。
基本的命题逻辑符号和类型论符号的对应关系如下:
| 文字描述 | 数学符号 | 类型符号 | 编程语言(JavaScript) |
|---|---|---|---|
| 命题T | T | T | T |
| A且B (析取) | A | B | ||
| A或B (合取) | [A, B] | ||
| 若A则B(蕴含) | A => B |
lambda演算的β归约对应于逻辑系统的分离规则:
分离规则(MP) :如果有 和 ,那么有 。
简单类型论中的基本类型,对应于在逻辑系统中的公理。
简单类型论中构造一个新的类型,对应于在逻辑系统中推导出一个新的定理。
编写一个lambda演算的表达式,对应于在逻辑系统中进行推导。
Curry-Howard 同构揭示了命题逻辑与带类型lambda演算之间的深刻联系,它也为型论脱离lambda体系发展打下了基础。
带类型的组合子逻辑
我们前文已经证明了组合子逻辑与lambda演算的等价性,那么简单类型论应用于组合子逻辑,Curry-Howard 同构会展现出什么样的特性呢?
我们考虑SKI系统的类型:
若将SK的类型对应到命题逻辑,我们可以发现,它刚好是希尔伯特公理体系的两个公理。
我们前文已经讲到,I组合子可以由KS构造,这对应了希尔伯特公理体系中,命题等价于自身,可以由其它公理推导出来。
以此逻辑构造的逻辑公理体系被称作正蕴含逻辑(positive implicational logic),也译作蕴含命题演算。
我们亦可知,BCKW和X组合子逻辑,也可以对应到命题逻辑的一组公理,有兴趣可以参考前篇自行推导。
扩展的 Curry-Howard 同构
在数学领域,命题逻辑是多数逻辑系统的基础,若我们为类型系统添加真值和否定逻辑,则可以得到布尔运算逻辑
| 文字描述 | 数学符号 | 类型符号 | 编程语言(TypeScript) |
|---|---|---|---|
| 假 | false | (读作bottom) | void |
| 真 | true | (读作top) | any |
| 非T | T => void |
为了支持否定逻辑,必须要添加一条公理:
其对应的基本类型是
此公理即所谓的逆否命题公理。我们在初等数学中使用的反证法,就依赖此条公理。在希尔伯特公理体系中,也有此公理。
我们还可以继续根据命题逻辑的上位系统扩展简单类型系统,比如添加谓词和量词逻辑扩展到一阶逻辑。其对应了 和 类型。但是这样就超出了简单类型论的范围了,包含这两种类型的类型论被称为”依赖类型论“,我们留待后文讨论。
结语
基于Curry-Howard同构建立的类型论,与lambda演算逐渐走上了不同的道路,在类型论中,我们更关心lambda表达式本身的结构,而不是对它应用归约求得结果。
从这个时间点开始,类型论的发展与lambda已经实际形成了竞争关系。
对于一个实际问题,我们既可以从类型论的角度把它抽象为“构造lambda表达式成为特定类型”,也可以从lambda演算的角度抽象为“计算特定lambda表达式的结果”。
接下来的系列中我们仍然回到lambda演算的发展,更多关于类型论的发展留待其它系列讨论。