编程语言理论
00:00
编程语言理论:类型系统、Lambda演算、语义学与程序验证
1. 类型系统
1.1 类型系统分类
| 维度 | 分类 | 说明 |
|---|---|---|
| 类型检查时机 | 静态/动态 | 编译时/运行时 |
| 类型转换 | 强/弱 | 隐式转换的严格程度 |
| 类型推断 | 显式/隐式 | 是否需要声明类型 |
1.2 静态类型系统
Hindley-Milner 类型推断:
自动推断表达式的最一般类型:
其中 为类型环境, 为替换, 为类型。
多态类型:
Let 多态:
let id = λx.x in (id 1, id true) -- 合法
而:
(λid.(id 1, id true))(λx.x) -- 不合法(ML中)
1.3 子类型
子类型关系 表示 类型的值可以用在期望 类型的地方。
函数子类型的协变与逆变:
- 参数类型:逆变(contravariant)
- 返回类型:协变(covariant)
Liskov 替换原则(LSP):
若 ,则 类型的对象可被 类型的对象替换,程序行为不变。
1.4 代数数据类型
积类型(Product):
和类型(Sum):
类型同构:
| 类型表达式 | 等价于 |
|---|---|
2. Lambda 演算
2.1 无类型 Lambda 演算
语法:
β 归约:
α 转换:
η 归约:
2.2 归约策略
| 策略 | 说明 | 特点 |
|---|---|---|
| 正则序 | 最左最外先归约 | 可能重复计算 |
| 应用序 | 最左最内先归约 | 可能不终止 |
| 惰性求值 | 仅在需要时归约 | 避免不必要计算 |
| 急切求值 | 参数先求值 | 实用 |
2.3 Church 编码
Church 布尔值:
Church 数:
后继:
加法:
2.4 Y 组合子
实现不动点,允许递归:
2.5 简单类型 Lambda 演算(STLC)
类型语法:
类型规则:
类型安全 = 进展性 + 保持性:
- 进展性:良类型的闭项要么是值,要么可以归约
- 保持性:归约保持类型不变
3. 操作语义
3.1 小步语义
定义单步归约关系 :
3.2 大步语义
定义求值关系 :
3.3 小步 vs 大步
| 特性 | 小步语义 | 大步语义 |
|---|---|---|
| 粒度 | 单步归约 | 直接到结果 |
| 非终止 | 可描述 | 无法描述 |
| 并发 | 适合 | 不适合 |
| 证明 | 归纳简单 | 可能更直观 |
4. 指称语义
4.1 基本思想
将程序映射到数学对象(域论中的元素):
4.2 语义函数
4.3 不动点语义
递归定义的语义通过域论中的最小不动点给出:
5. 程序验证
5.1 Hoare 逻辑
Hoare 三元组:
含义:若前置条件 成立,执行命令 后,后置条件 成立。
推理规则:
5.2 循环不变式
循环不变式 必须满足:
- 初始化:循环开始前 成立
- 保持:每次迭代后 仍然成立
- 终止:循环结束时 可推出
5.3 最弱前置条件
5.4 类型系统与验证
类型系统是一种轻量级程序验证:
| 验证级别 | 方法 | 保证 |
|---|---|---|
| 类型检查 | 编译器 | 类型安全 |
| 静态分析 | 分析工具 | 特定属性 |
| 程序证明 | 证明助手 | 完全正确性 |
依赖类型:类型可以依赖于值,允许在类型层面表达更精细的属性。
长度为 的 类型向量,类型检查器可验证列表操作的正确性。