前置知识: 计算机基础

编程语言理论

11 minAdvanced2026/6/14

编程语言理论:类型系统、Lambda演算、语义学与程序验证

1. 型系统

1.1 型系统分

维度说明
型检查时机静态/动态编译时/运行时
型转换强/弱隐式转换的严格程度
型推断显式/隐式是否需要声明

1.2 静态型系统

Hindley-Milner 类型推断

自动推断表达式的最一般型:

算法W(Γ,e)=(S,τ)\text{算法W}(\Gamma, e) = (S, \tau)

其中 Γ\Gamma型环境,SS 为替换,τ\tau型。

多态类型

id:α.ααid : \forall \alpha. \alpha \to \alpha

Let 多态

let id = λx.x in (id 1, id true)  -- 合法

而:

(λid.(id 1, id true))(λx.x)  -- 不合法(ML中)

1.3 子

子类型关系 S<:TS <: T 表示 SS 型的值可以用在期望 TT 型的地方。

函数子类型的协变与逆变

  • 参数型:逆变(contravariant)
  • 返回型:协变(covariant)

S1S2<:T1T2    T1<:S1S2<:T2S_1 \to S_2 <: T_1 \to T_2 \iff T_1 <: S_1 \wedge S_2 <: T_2

Liskov 替换原则(LSP)

S<:TS <: T,则 TT 型的对象可被 SS 型的对象替换,程序行为不变。

1.4 代数数据

积类型(Product)

A×B={(a,b)aA,bB}A \times B = \{(a, b) \mid a \in A, b \in B\}

和类型(Sum)

A+B=inl(a)inr(b)A + B = \text{inl}(a) \mid \text{inr}(b)

类型同构

型表达式等价于
A×1A \times 1AA
A+0A + 0AA
A×BA \times BB×AB \times A
A+BA + BB+AB + A
AB+CA^{B+C}AB×ACA^B \times A^C
(A×B)C(A \times B)^CAC×BCA^C \times B^C

2. Lambda 演算

2.1 无型 Lambda 演算

语法

e::=xλx.ee1 e2e ::= x \mid \lambda x.e \mid e_1\ e_2

β 归约

(λx.e1) e2e1[x:=e2](\lambda x.e_1)\ e_2 \to e_1[x := e_2]

α 转换

λx.eαλy.e[x:=y]\lambda x.e \equiv_\alpha \lambda y.e[x := y]

η 归约

λx.(f x)ηf(xFV(f))\lambda x.(f\ x) \to_\eta f \quad (x \notin FV(f))

2.2 归约策略

策略说明特点
正则序最左最外先归约可能重复计算
应用序最左最内先归约可能不终止
惰性求值仅在需要时归约避免不必要计算
急切求值参数先求值实用

2.3 Church 编码

Church 布尔值

true=λt.λf.t\text{true} = \lambda t.\lambda f.t

false=λt.λf.f\text{false} = \lambda t.\lambda f.f

Church 数

0=λf.λx.x0 = \lambda f.\lambda x.x

1=λf.λx.f x1 = \lambda f.\lambda x.f\ x

2=λf.λx.f (f x)2 = \lambda f.\lambda x.f\ (f\ x)

n=λf.λx.fn xn = \lambda f.\lambda x.f^n\ x

后继

succ=λn.λf.λx.f (n f x)\text{succ} = \lambda n.\lambda f.\lambda x.f\ (n\ f\ x)

加法

plus=λm.λn.λf.λx.m f (n f x)\text{plus} = \lambda m.\lambda n.\lambda f.\lambda x.m\ f\ (n\ f\ x)

2.4 Y 组合子

实现不动点,允许递归:

Y=λf.(λx.f (x x)) (λx.f (x x))Y = \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x))

Y f=f (Y f)Y\ f = f\ (Y\ f)

2.5 简单型 Lambda 演算(STLC)

类型语法

τ::=Bτ1τ2\tau ::= B \mid \tau_1 \to \tau_2

类型规则

x:τΓΓx:τ (Var)\frac{x:\tau \in \Gamma}{\Gamma \vdash x : \tau} \text{ (Var)}

Γ,x:τ1e:τ2Γλx:τ1.e:τ1τ2 (Abs)\frac{\Gamma, x:\tau_1 \vdash e : \tau_2}{\Gamma \vdash \lambda x:\tau_1.e : \tau_1 \to \tau_2} \text{ (Abs)}

Γe1:τ1τ2Γe2:τ1Γe1 e2:τ2 (App)\frac{\Gamma \vdash e_1 : \tau_1 \to \tau_2 \quad \Gamma \vdash e_2 : \tau_1}{\Gamma \vdash e_1\ e_2 : \tau_2} \text{ (App)}

类型安全 = 进展性 + 保持性

  • 进展性:良型的闭项要么是值,要么可以归约
  • 保持性:归约保持型不变

3. 操作语义

3.1 小步语义

定义单步归约关系 \to

e1e1e1 e2e1 e2\frac{e_1 \to e_1'}{e_1\ e_2 \to e_1'\ e_2}

v1 e2v1 e2e2e2\frac{v_1\ e_2 \to v_1\ e_2'}{e_2 \to e_2'}

(λx.e) ve[x:=v]\frac{}{(\lambda x.e)\ v \to e[x := v]}

3.2 大步语义

定义求值关系 \Downarrow

e1λx.ee2v2e[x:=v2]ve1 e2v\frac{e_1 \Downarrow \lambda x.e \quad e_2 \Downarrow v_2 \quad e[x:=v_2] \Downarrow v}{e_1\ e_2 \Downarrow v}

3.3 小步 vs 大步

特性小步语义大步语义
粒度单步归约直接到结果
非终止可描述无法描述
并发适合不适合
证明归纳简单可能更直观

4. 指称语义

4.1 基本思想

将程序映射到数学对象(域论中的元素):

e:EnvValue\llbracket e \rrbracket : \text{Env} \to \text{Value}

4.2 语义函数

xρ=ρ(x)\llbracket x \rrbracket \rho = \rho(x)

λx.eρ=λv.eρ[xv]\llbracket \lambda x.e \rrbracket \rho = \lambda v.\llbracket e \rrbracket \rho[x \mapsto v]

e1 e2ρ=(e1ρ)(e2ρ)\llbracket e_1\ e_2 \rrbracket \rho = (\llbracket e_1 \rrbracket \rho)(\llbracket e_2 \rrbracket \rho)

4.3 不动点语义

递归定义的语义通过域论中的最小不动点给出:

fix=lfp(F)=n=0Fn()\llbracket \text{fix} \rrbracket = \text{lfp}(F) = \bigsqcup_{n=0}^{\infty} F^n(\bot)

5. 程序验证

5.1 Hoare 逻辑

Hoare 三元组

{P} C {Q}\{P\}\ C\ \{Q\}

含义:若前置条件 PP 成立,执行命令 CC 后,后置条件 QQ 成立。

推理规则

{P} skip {P}\frac{}{\{P\}\ \text{skip}\ \{P\}}

{Q[x:=e]} x:=e {Q}\frac{}{\{Q[x:=e]\}\ x := e\ \{Q\}}

{P} C1 {R}{R} C2 {Q}{P} C1;C2 {Q}\frac{\{P\}\ C_1\ \{R\} \quad \{R\}\ C_2\ \{Q\}}{\{P\}\ C_1;C_2\ \{Q\}}

{Pb} C1 {Q}{P¬b} C2 {Q}{P} if b then C1 else C2 {Q}\frac{\{P \wedge b\}\ C_1\ \{Q\} \quad \{P \wedge \neg b\}\ C_2\ \{Q\}}{\{P\}\ \text{if } b \text{ then } C_1 \text{ else } C_2\ \{Q\}}

{Pb} C {P}{P} while b do C {P¬b}\frac{\{P \wedge b\}\ C\ \{P\}}{\{P\}\ \text{while } b \text{ do } C\ \{P \wedge \neg b\}}

5.2 循环不变式

循环不变式 II 必须满足:

  1. 初始化:循环开始前 II 成立
  2. 保持:每次迭代后 II 仍然成立
  3. 终止:循环结束时 I¬bI \wedge \neg b 可推出 QQ

5.3 最弱前置条件

wp(x:=e,Q)=Q[x:=e]\text{wp}(x := e, Q) = Q[x := e]

wp(C1;C2,Q)=wp(C1,wp(C2,Q))\text{wp}(C_1; C_2, Q) = \text{wp}(C_1, \text{wp}(C_2, Q))

wp(if b then C1 else C2,Q)=(bwp(C1,Q))(¬bwp(C2,Q))\text{wp}(\text{if } b \text{ then } C_1 \text{ else } C_2, Q) = (b \Rightarrow \text{wp}(C_1, Q)) \wedge (\neg b \Rightarrow \text{wp}(C_2, Q))

5.4 型系统与验证

型系统是一种轻量级程序验证:

验证级别方法保证
型检查编译器型安全
静态分析分析工具特定属性
程序证明证明助手完全正确性

依赖类型型可以依赖于值,允许在型层面表达更精细的属性。

Vec(A,n):Type\text{Vec}(A, n) : \text{Type}

长度为 nnAA 型向量,型检查器可验证列表操作的正确性。