Upload
burton
View
119
Download
1
Embed Size (px)
DESCRIPTION
第 3 章 简单类型化 演算. 函数式程序设计语言 PCF 由三部分组成 代数数据类型:自然数类型和布尔类型等 带函数和积等类型的纯类型化 演算 不动点算子 第 2 章对代数数据类型进行了透彻的研究 本章研究简单类型化 演算 第 4 章研究不动点算子. 3 .1 引 言. 本章的系统是以后各章研究的所有其它演算的核心 抽象可用来定义新的函数,而代数数据类型只涉及到所声明的一阶函数的应用 在类型化 演算的指称语义中需要考虑函数类型的解释. 3 .1 引 言. 演算的历史 - PowerPoint PPT Presentation
Citation preview
第 3 章 简单类型化演算• 函数式程序设计语言 PCF 由三部分组成
– 代数数据类型:自然数类型和布尔类型等– 带函数和积等类型的纯类型化演算– 不动点算子
• 第 2 章对代数数据类型进行了透彻的研究• 本章研究简单类型化演算• 第 4 章研究不动点算子
3.1 引 言• 本章的系统是以后各章研究的所有其它演算的核心 抽象可用来定义新的函数,而代数数据类型只涉及到所声明的一阶函数的应用• 在类型化演算的指称语义中需要考虑函数类型的解释
3.1 引 言 演算的历史
– Church 在 20 世纪 30 年代研究的定义可计算函数的一种形式体系– Kleene 在 1936 年证明,可定义的所有自然数函数正好是所有的递归函数– Turing 在 1937 年证明,可定义的数值函数正好
是 Turing 机可计算的函数 演算一直影响着程序设计语言的研究
3.1 引 言 演算和程序设计语言
– 20 世纪 50 年代,无类型演算明显影响了 Lisp语言的研究– 20 世纪 60 年代认识到,程序设计语言的语义可以通过使用拓展的演算给出– 现代的观点认为,类型化演算引导对程序设计语言进行更加涉及本质的分析
让类型化演算的类型对应到程序设计语言中的类型,就可以忠实地为类型化程序设计语言的能力和局限性建模
3.1 引 言本章的主要内容• 提出使用定型公理和推理规则的上下文有关语法• 讨论类型化演算的等式证明系统 ( 公理语义) 和归约系统(操作语义)• 讨论类型化演算的通用模型(指称语义)及可靠性和完备性定理• 介绍 PCF 语言(递归函数留待下一章)及其公理语义和操作语义
3.2 类型和项3.2.1 类型的语法• 简单类型化演算的类型表达式文法
::= b | null | unit | | | b :类型常量null :初始类型unit :终结类型和、积与函数类型类型表达式中不含类型变量
• 用、和来命名所讨论的演算
3.2 类型和项3.2.2 上下文有关语法• 不存在上下文无关文法,它正好产生良类型的项• 用一种基于逻辑的形式系统来定义类型语言
– 用公理和推理规则来同时定义表达式及其类型– 定型公理 c :– 推理规则
– 定型断言 M : , 其中 {x1 :1 , …, xk:k }
M1:1 … Mk:k
N :1 M1:1 … k Mk:k
N :
3.2 类型和项3.2.3 项的语法• 一个基调 B, C 包含
– 一个集合 B ,其元素叫做基本类型或类型常量– 形式为 c 的项常量集合 C ,其中是 B 上的类型表达式
• 多类代数的基调 S, F 的基调很容易变换成基调 B, C– 令 B 就等于 S– 若 F 有 f : s1 … sk s ,则在 C 中包含项常量
f : s1 … sk s
3.2 类型和项• 项的语法及类型按如下方式描述
– 首先用 BNF 定义类型表达式的语法( 3.2.1 节)– 然后用定型公理和定型规则同时定义上的项和它们的类型(良形的项就是良类型的项)– 良形( well-formed )和良类型( well-typed )
良形的项 x + 3 在 x 是整型时才是良类型的• 定型公理
c (cst)– x x (var)
3.2 类型和项• 定型规则
(add var)
( Intro)
( Elim)
• 定型断言的证明叫做定型推导
M :
, x : M :
M : N :
MN :
, x : M : ( x : . M) :
3.2 类型和项• 例
y: (x:.x)y:是一个需要用到所有这些定型规则的项
– 从定型公理 x: x: 开始– 根据 ( Intro) 规则,得到 x:. x : – 再由( add var ),得到 y: x:. x : – 由公理 y: y: – 最后,由 ( Elim) 规则可知 y: (x:. x)y: 是良类型的
3.2 类型和项• 引理 3.1
– 如果 M: ,那么 M 中的每个自由变量都出现在中• 引理 3.2
– 如果 M: ,且包含 M 中所有的自由变量,那么 M:• 引理 3.3
– 如果 M: ,并且 y 不出现在中,那么 [y/x] [y/x]M:
3.2 类型和项• 引理 3.4
– 如果 1,x: M: 和 2N: 都是项,且 12是 良 形 的 类 型 指 派 , 那 么 代 换 实 例 12
[N/x]M: 是良形项– 证明
基于对定型断言 1 , x: M: 的证明的归纳
3.2 类型和项3.2.4 有积与和及相关类型的项1 、笛卡儿积(把扩展到 , )
( Intro)
( Elim)1
( Elim)2
M : N : M, N :
M :
Proj1, M:
M : Proj2
, M:
3.2 类型和项• 积的另一种表示
– 对所有的类型和,存在项常量Pair, : ( )Proj1
, : ( )
Proj2, : ( )
M, N, 看成 Pair, M N 的语法美化– 两种表示的主要区别第二种表示: Pair 、 Proj1 和 Proj2 都是项第一种表示: x:.y:.Pair x y 、 x: .Proj1x 和 x: .Proj2x 才是良形的项
3.2 类型和项2 、和
(+ Intro)1
(+ Intro)2
(+ Elim)
M : Inleft, M : +
M : Inright, M: +
M : + N : P : Case, , M N P :
3.2 类型和项• 初始类型和终结类型
– 与终结类型 unit 有关的唯一的项 : unit (unit Intro)终结类型也叫做单位类型C 语言的 void 类型就是单位类型,因为该类型的表达式没有能够引起兴趣的值(而不是没有值)
– 与初始类型 null 有关的项形式Zero : null (null Elim)若 null 类型有元素, 函数 Zero 给出使用方式
3.2 类型和项• 有了单位类型与和类型后, bool 类型可省略
– bool 类型可以定义成 bool unit + unit
– true 和 false 可以定义成true Inleft false Inright
– if … then … else 可以定义成if M then N else P Caseunit, unit, M (K, unit N) (K, unit P)其中 K, unit x:.y:unit.x
3.2 类型和项• 多元函数和高阶函数之间的关系
– Curry, f : .x:.y:.f x, y– add p:nat nat.(Proj1 p) + (Proj2 p)Curry(add)
(f:nat nat nat.x:nat.y:nat.f x, y) add = x:nat.y:nat.add x, y x:nat.y:nat.(p:nat nat.(Proj1 p) + (Proj2 p)) x, y = x:nat.y:nat.Proj1x, y + Proj2 x, y = x:nat.y:nat.x + y
3.2 类型和项3.2.5 定型算法
– 给定 , M, , M: 是否为可证明的定型断言– 给定, M ,判定是否存在一个,使得
M: 可证• 基调上预备项
– M ::= c | x | MM | x:.M– 该文法可以从定型公理和推理规则得到– 类型检查的输入是符合该文法的预备项
3.2 类型和项• 类型检查算法TC(, c) = 若 c: 是该基调的一个常量
fail 否则TC(, x) = 若 x: 否则 fail
TC(, MN) = 若 TC(, M) = 且 TC(, N) = 否则 fail
TC(, x:.M) = 若 TC((x:.M , x:), M) =
否则 fail
3.2 类型和项• 命题 3.5
– 算法 TC(, M) 终止且得到类型,当且仅当定型断言 M: 是可推导的– 若对于和 M ,不存在可推导的定型断言,则算法停机,报告失败
3.3 证明系统3.3.1 等式和理论• 等式
– 泛代数: M N [] ,只有平凡的永真等式– 类型化演算: M N ,有非平凡的永真等式,和代数不同的是,等式包含类型,它用于等式证明系统– 代数系统中和类型有关的规则(作为副条件)
P , Q Termss(, )
M = N , x : s P = Q P/xM = Q/xN
3.3 证明系统3.3.1 等式和理论• 等式
– 泛代数: M N [] ,只有平凡的永真等式– 类型化演算: M N ,有非平凡的永真等式,和代数不同的是,等式包含类型,它用于等式证明系统– 等式的另一种表示方式是
x1:1… xk:k.M N – 若某个类型为空,则该等式无意义地成立
3.3 证明系统• 公理和推理规则
(add var)
M = M : (ref)
(sym)
(trans)
M = N : , x : M = N :
M = N : N = M :
M = N : N = P : M = P :
3.3 证明系统• 公理和推理规则
()
()
x.M = y.[y/x]M : , 其中 y FV(M) () (x.M)N =[N/x]M : () x.(Mx) =M : , 其中 x FV(M) ()
, x: M = N : x:.M = x:.N :
M1 = M2 : N1 = N2 : M1 N1 = M2 N2 :
3.3 证明系统• 引理 3.6 如果 M = N : 并且包含
M 和 N 中所有的自由变量,那么 M = N:
• 基调的类型化理论 项之间的包含上述公理的一组良类型的等式,并且封闭于上述推理规则– M = N: 表示:等式 M = N: 是从公理
和的等式可证– 的理论 Th() 是指:从公理和的等式可证的等式集合
3.3 证明系统• 代数和简单类型化演算之间的联系
– 在类型化上可以增加代数公理,任何代数等式可以看成等式– 任何一个代数证明可以在中执行– 代数证明规则 (subst) 不在中,但可以证明它是的导出规则
P, Q Termss(, )
M = N , x : s P =Q P/xM = Q/xN
3.3 证明系统• 命题 3.8
令是代数基调上代数项之间的一组等式,令 E是单个这样的等式。若在代数证明系统中有 E ,则把和 E 都看成是基调上项之间的等式,在证明系统中也有 E
• 命题 3.9 (守恒性)令是代数基调上代数项之间的等式集合,并令 E是单个这样的等式。当把的等式和 E 都看成是基调上项之间的等式时,若在证明系统中有 E ,则在该代数证明系统中也有 E
3.3 证明系统• 命题 3.10
存在有类型化演算理论及没有 x 自由出现的项 M 和 N ,使得 , x: M = N : 但是 M = N :
– 表明等式中变量情况会影响可证明性
3.3 证明系统• 积类型
Proj1M, N = M : (proj1) Proj2M, N = N : (proj2) Proj1M, Proj2M = M : (sp)
• 和类型 Case, , (Inleft, M) N P = N M : (case)1
Case, , (Inright, M) N P = P M : (case)2
Case, , M (N Inleft, ) (N Inright, ) = N M : + (case)3仅 N:( +) ( +) 时, (case)3 的项才是良形的
3.3 证明系统• 终结类型
M = : unit– 对每个类型,存在唯一的函数 One : unit– 可以把 One写成 x:.
• 初始类型 M Zero : null – 对任何类型,存在唯一的函数 Zero : null
3.3 证明系统• 简单类型化演算版本之间的联系
逻辑系统或语言 2 在 1 上守恒,如果– 2 包含 1 ,并且– 对 1 的任意一组公式和任意一个公式 F ,若在 2的证明系统中有 F ,则在 1 的证明系统中也
有 F 在上守恒
3.3 证明系统3.3.2 归约规则• 归约规则
– (x:.M)N NxM ()red
x:.Mx M , xFV(M) ()red
• 引理 3.11– 如果 M : 并且 M N ,那么 N :
• 合流性和强范式化•预备项上的规则并不合流
x :.(y :.y)x 的范式有两个: x :.x 和 y :.y
3.3 证明系统• 在类型化项上的可变换关系
M N 当且仅当存在项 M0, …, Mk 且 Mi ( 0 i k ),使得M M0 M1 … Mk N
– 就纯 , 归约来说,对每个 i ,所做假设 Mi不是必要的• 推论 3.12
– 等式 M N 从的公理可以证明,当且仅当 M N ,当且仅当存在某个项 P ,使得 M P 并且 N P
3.3 证明系统•小结
– 带积、和、 unit 及 null 类型的类型化演算的归约公理都可以由从左向右定向相应的等式公理得到– 对简单类型化演算的所有版本,强范式化都成立,但是合流性却难以捉摸
3.3 证明系统3.3.3 有其它规则的归约• 每个代数基调都可以看成一个基调
– 代数项集可以看成是项的一个子集,并且– 代数重写规则可以应用到项
• 一些结论– 若代数基调的代数重写系统合流并终止,那么对上的项,,归约合流并终止– 若合流并左线性,那么对上项,,, fix归约是合流的
3.4 通用模型、可靠性和完备性• 模型概述
– 对于一个逻辑系统来说,模型提供一种机制,它给出每个良形表达式的数学含义,以确定该逻辑中的任何公式是否为真– 对于使用变量的逻辑系统,通常把给变量指派值(称为环境)从模型的一般概念中分离代数规范的模型是代数(类似的还有一阶逻辑)– 把类别解释为集合– 把函数符号解释为函数– 为代数项中变量指派值后,就可计算项的解释
3.4 通用模型、可靠性和完备性3.4.1 通用模型和项的含义• 类型化演算的模型类似于一个代数
– 每个类型需要一个值集– 每个常量符号解释到对应值集中的特定元素还必须使应用表达式和抽象表达式有意义– 假定 A 是类型的值集,则要求 A 为从 A
到 A 的一个函数集合– 每个可定义的函数必须处于适当的值集中
3.4 通用模型、可靠性和完备性3.4.1 通用模型和项的含义• 类型化演算的模型论比代数规范的模型论要复杂得多
– 上述简单扩展不能适应有不动点算子的情况(好在本章暂不关心)– 本章将采用比上述简单扩展的适应性更广一点的“通用模型”,它由三部分组成:
( 1 )类型化的应用结构( 2 )作为模型的外延性条件( 3 )作为模型的环境条件
3.4 通用模型、可靠性和完备性3.4.2 应用结构、外延性和框架 基调上的类型化应用结构:
{A}, {App, }, Const对其中每对和,假定满足下列条件:
– A 是一个集合– App, 是映射 App, : A A A
– Const 是从的项常量到所有 A 并集的成员的映射 , 使得若 c: ,则 Const(c) A
引入 App, 映射的目的是给 A 以宽松的解释
3.4 通用模型、可靠性和完备性•满足下列条件的应用结构是外延的
对任意的 f, gA ,若对所有的 dA ,都有 App f d = App g d ,则 f = g
函数外延性:若对任意 x 有 f(x)=g(x) ,则 f 和 g 相等• 可以用直接具有外延性的模型定义来代替应用结构
– 类型框架是一个应用结构{A}, {App, }, Const满足 A (A) 且 App, f d = f (d)
– 类型框架可简写成 {A}, Const ,甚至 {A}A
3.4 通用模型、可靠性和完备性• 例
一组基类型上完备的集合论函数层级( full set-theoretic function hierarchy )– = {A}, Const ,其中 A 包含从 A 到 A 的所有集合论函数
• 引理 3.13一个应用结构是外延的当且仅当存在同构的类型框架
3.4 通用模型、可靠性和完备性3.4.3 环境条件
环境 下的良型项 M: 的含义 M 由对定型推导子句进行归纳来定义– c: = Const(c)– x: x: = (x)– , x: M: = M:– MN: =
App, M: N:– x:.M: = 唯一 的 fA , 使 得 dA.App f d = , x: M: [x d]若定义了全函数,则说满足环境条件
3.4 通用模型、可靠性和完备性• 通用模型满足外延性和环境两条件的类型化应用结构– 外延性条件等价于 – 环境条件保证
有足够多的元素,使得每个可定义的函数都在这个模型中 使得 dA.App f d = , x: M: [x
d] 的 f A 可能不存在 外延性保证,若存在则唯一
3.4 通用模型、可靠性和完备性3.4.4 类型可靠性和等式可靠性• 两个证明系统:分别证明定型断言和等式• 引理 3.17 (类型可靠性)
令是基调的任意通用模型, M: 是可证明的定型断言,并且 是的一个环境,那么 M : A
• 良类型的项不包含类型错误
3.4 通用模型、可靠性和完备性等式可靠性• 引理 3.20 (代换引理)
令 , x: M : 和 N : 都是项, ,且 d = N: ,则 [Nx]M : = , x: M : [x
d]• 可满足性
若 M : = N : ,就说通用模型和环境 满足等式 M = N : ,写成, M = N :
3.4 通用模型、可靠性和完备性• 定理 3.21 (可靠性)
对任何类型化的等式集合,若 M = N : ,
则任何满足的通用模型也满足 M = N : ,
写成 M = N :
3.4 通用模型、可靠性和完备性3.4.5 没有空类型的通用模型的完备性• 多类代数中有两个完备性定理
– 一般情况下的演绎完备性– 空类别被略去时的最小模型完备性
演算– 没有空类型时的最小模型完备性(本小节)– 不扩展证明系统的话,通用模型没有演绎完备性(下一小节,课堂不介绍)– 考虑更一般的范畴模型的话,对给定的证明系统 ,有直截了当的最小模型完备性
3.4 通用模型、可靠性和完备性•非空类型的推理规则
x 在 M 和 N 中没有 自 由 出 现 (nonempty)
• 定理 3.22令是封闭于 (nonempty) 规则的任意理论。
那么,存在一个通用模型,它没有任何 A = ,并且它正好满足的等式
, x: M =N: M = N :
3.5 可计算函数编程语言3.5.1 概述
– 讨论代数数据类型和简单类型化演算在程序设计语言设计中的应用– 提出用于对可计算函数进行编程的函数式程序设计语言 PCF– 有关递归函数的部分推迟到第 4 章给出– PCF 的设计目的是便于本章和以后章节的分析和讨论– 本节还总结该语言的公理语义和操作语义
3.5 可计算函数编程语言3.5.2 PCF 的语法1 、布尔类型和自然数类型
– 布尔类型常量: true , false– 布尔类型条件表达式:
if bool_exp then bool_exp else bool_exp– 自然数类型常量 0, 1, 2, 3, … (数码 )– 自然数类型条件表达式
if bool_exp then nat_exp else nat_exp– 自然数相等测试: Eq? 如: Eq? 5 0
false– 并未列出基本类型的表达式的所有可能形式
3.5 可计算函数编程语言2 、其他类型
– 函数类型与积类型和简单类型化演算中的一样
– 不加入和类型、 unit 类型和 null 类型3 、条件表达式可定义在任意类型上
– 文法表示_exp::=… | if bool_exp then _exp else _exp 例:nat_exp ::= if bool_exp then nat_exp else nat_exp
3.5 可计算函数编程语言3.5.3 声明和语法美化 在 PCF 语言中引入 let 声明,相当于命令式语言的局部声明
– let x : = M in N– 表达的意思是,在声明体 N 中, x被约束到 M– 可以用 PCF 语言已有部分来严格定义
let x : = M in N (x : .N)M– 因此,把 let 看成一种缩写,或称为语法美化,而不把 let 声明直接加入 PCF– 这样,无须规定任何有关 let 的等式公理和归约规则
3.5 可计算函数编程语言• 例 1 :命令式语言的局部声明可用 let 形式表示
begin function f (x : nat) : nat; return x;end;body
end 对应的表达式
– let f : nat nat = x : nat.x in body– (f : nat nat . body) (x : nat.x)
3.5 可计算函数编程语言• 例 2 : let 可以嵌套(做两步消去两个 let )let compose : (nat nat) (nat nat) nat nat = f : nat nat.g : nat nat.x : nat.f(gx) in
let h : nat nat = x : nat.x + x incompose h h 5
let compose : (nat nat) (nat nat) nat nat = f : nat nat.g : nat nat.x : nat.f(gx) in
(h : nat nat. compose h h 5) x : nat.x + x)(compose : (nat nat) (nat nat) nat nat.
(h : nat nat. compose h h 5) x : nat.x + x) f : nat nat.g : nat nat.x : nat.f(gx)
3.5 可计算函数编程语言• 例 2 :完成化简演算(compose : (nat nat) (nat nat) nat nat.
(h : nat nat. compose h h 5) x : nat.x + x) f : nat nat.g : nat nat.x : nat.f(gx)
(h : nat nat.(f : nat nat.g : nat nat. x: nat.f (gx))h h 5) (x : nat.x + x)
(f : nat nat.g : nat nat.x : nat.f(gx)) (x : nat.x + x) (x : nat.x + x) 5
(x : nat.x + x) ((x : nat.x + x) 5) ((x : nat.x + x) 5) + ((x : nat.x + x) 5) (5 + 5) + (5 + 5) 20
3.5 可计算函数编程语言• 另一种语法美化
– let f (x : ) : = M in N let f : = x :.M in N ( f : .N) (x :.M)
3.5 可计算函数编程语言3.5.4 程序和结果PCF 语言有两个语法范畴:类型和项• 可观测类型:自然数类型和布尔类型
– 像 nat nat 这样的函数类型不是可观测的类型• 程序:良形的、可观测类型的闭项
– 注意: PCF 语言无输入和输出• 结果:执行程序的可观测的效果,应该是可观测类型的闭范式• 语义:程序集合和结果集合之间的一种关系
3.5 可计算函数编程语言3.5.5 公理语义• 公理语义是一个证明系统
– 可以推导程序及其组成部分的性质• 性质的表示
– 等式、给定输入下的输出断言、或其它形式• 等式公理语义
– 性质仅用等式表示• 两个程序在公理语义中等价
– 为它们推导出的断言正好完全相同
3.5 可计算函数编程语言公理• 自反
(ref) M = M• 基本类型 nat 和 bool
(add) 0 + 0 = 0, 0 + 1 = 1, … , 3 + 5 = 8, …(Eq?) Eq? n n = true, Eq? n m = false
( n 和 m 是不同的数码)(cond) if true then M else N = Mif false then M else N = N
3.5 可计算函数编程语言• 二元组
(proj) Proj1 M, N = M Proj2 M, N = N
(sp) Proj1 P, Proj2 P = P
• 重新命名约束变量( ) x:.M = y:.yxM
( y 在 M 中不是自由的)• 函数
( ) (x : .M)N = N/xM( ) x : .Mx = M
( x 在 M 中不是自由的)
3.5 可计算函数编程语言推理规则• 等价
(sym),(trans)
• 同余nat 和 bool
M = NN = M
M = N N = PM = P
M = N P = QM+P = N+Q
M = N P = QEQ? MP = EQ? NQ
M1 = M2 N1 = N2 P1 = P2
if M1 then N1 else P1 = if M2 then N2 else P2
3.5 可计算函数编程语言• 同余
序对
函数
M = NProji M = Proji N
M = N P = QM, P = N, Q
M = Nx:. M = x:. N
M = N P = QM P = N Q
3.5 可计算函数编程语言• 部分同余规则多余
抽象和应用必须有• 例: + 的同余规则多余
– 若 M=N 和 P=Q ,则由自反公理,有等式x : nat.y : nat.x y = x : nat.y : nat.x y– 由应用的同余规则可得 (x:nat.y:nat.x y)M = (x:nat.y:nat.x y)N – 由公理和传递性可得y : nat.M y = y : nat.N y
– 再次使用同余规则、公理和传递性可得M P = N Q
3.5 可计算函数编程语言• PCF 语言公理语义的特点
– 强到足以确定程序的含义– 证明不了加法可交换,也证明不了递归函数之间的许多有意义的等价– 这些性质需要用归纳法来证明
• PCF 语言对类型并不需要证明系统– 因为两个类型相同当且仅当它们在语法上相同
3.5 可计算函数编程语言3.5.6 操作语义• 基本特点
– 把等式规则定向为重写规则,以强调归约方向– eval (M) = N当且仅当M N
• 类型 nat 和 bool(add) 0 + 0 0, 0 +1 1, … , 3 +5 8, … (Eq?) Eq? n n true, Eq? n m false
(n 和 m 是不同的数码 )(cond ) if true then M else N M
if false then M else N N
3.5 可计算函数编程语言• 序对
(proj) Proj1 M, N M Proj2 M, N N
• 重新命名约束变量( ) x:.M = y:.yxM
(y 在 M 中不是自由的 )
用本规则进行约束变元改名,而不是化简• 函数
( ) (x:.M)N N/xM
3.5 可计算函数编程语言•该操作语义的特点
– 抽象:没有指定计算步骤 3.6 节用几种归约策略把它具体化
– 保留了重新命名约束变量的等式公理的形式 因而不是一个终止的重写系统
– 对于序对的满射配对公理 (sp) 和函数的外延公理() ,没有相应的归约规则
因为对于归约程序来说,这些规则多余• 定理 3.23
PCF 归约是合流的
3.5 可计算函数编程语言• 定理 3.24 PCF 语言是安全的安全语言:具有保持性和前进性的语言– 保持性
若 M: 且 M M' ,那么 M':– 前进性
若 M : 且是可观察类型,则 M 是闭范式,或者存在程序 M' ,使得 M M'– 前进性并不保证得到闭范式,但保证在未归约到闭范式时,还能继续归约
3.5 可计算函数编程语言3.5.7 由各种形式的语义定义的等价关系• 各种语义上的等价关系
– 公理等价: M = N 可证用 M =ax N 表示
– 指称等价: M 和 N 对自由变量的任何取值都有相同的指称用 M =den N 表示
– 操作等价: eval(M ) ≃ eval (N ) (程序 M 和 N求值的结果一样,或者都没有定义)用 M =op N 表示
3.5 可计算函数编程语言• 操作等价M =op N 的推广
– 上下文 C[ ] 是一个项,但其中有一个洞– 例:
若 C0[ ] x : nat.x + [ ]
则 C0[x] 是 x : nat.x + x– 操作等价可以从程序推广到一般项
如果对任意使得 C[M] 和 C[N] 都是程序的上下文 C[] ,都有 eval (C[ M ] ) ≃ eval (C[ N ] ),则项 M 和 N 操作等价
3.5 可计算函数编程语言• 等式证明系统的可靠性
如果在公理语义中能证明 M 和 N 相等,那么在指称语义中, M 和 N 应该有同样的含义– 即 =ax =den
– 这是判断公理系统正确性的基本标准– 对 PCF 语言而言,公理语义对指称语义是可靠的
3.5 可计算函数编程语言• 操作语义的计算适当性
– 若 M 是个程序,且 M 和作为结果的 N 有同样的指称,则在操作语义中,执行程序 M 的结果是 N– 计算适当性表明已有足够的归约规则去确定任何程序的值– 对 PCF 语言而言,操作语义有计算的适当性
3.5 可计算函数编程语言• PCF 等价性小结
对任意程序– (programs M )(results N ) M =ax N iff M =denN
iff M =op N对任意项– =ax =den =op
– 操作等价是三者中最粗糙的一个,和指称等价或可证明的等价相比,可能有更多的项操作等价– 若 =op =ax ,可能会出现不一致的证明系统
3.5 可计算函数编程语言3.5.8 记录和 n 元组• 记录类型– 记录是多个成分的聚集,每个成分有不同的标记– 类型写成 l1 : 1, …, l k : k
– 记录写成 l1 = M1, …, l k = Mk
– 记录 r 中的成分 li 的选择可用加点的记号 r.li 来表示– 等式公理
l1 = M1, …, l k = Mk .li = Mi
•优点– 成分次序无关紧要,选择助记忆的名字作为标记
3.5 可计算函数编程语言• 引入 n 元积记号
– n 元积1 … n 1 (2 … (n-1 n) … )
– n 元组M1, …, Mn M1, M2, … Mn-1, Mn …
– 很容易检查若 Mi : i ,则 M1, … , Mn : 1 … n
– 取 n 元组的成分 x:1 … n .Proj1( x) (i < n)
x:1 … n .( x)
i - 1Proj2n - 1Proj2
1 … nProji1 … nProjn
3.5 可计算函数编程语言• 记录翻译成 PCF 表达式
l1 : 1, …, l k : k 1 … k
l1 = M1, …, l k = Mk M1, …, M k
– M.li M
• 例: let r :A:int, B:bool = A = 5, B = false in if r.B then r.A else r.A + 1
去掉语法美化,得到: let r :int bool = 5, false in if Proj2 r then Proj1 r else (Proj1 r) +1
1 … nProji
3.6 各种归约策略3.6.1 归约策略• 归约策略 F– 项到项的部分函数 F ,如果 F(M) = N ,那么 MN
• 部分计算函数 evalF : PCF PCF M, F(M) 未定义evalF (M) =
N, F(M) = M 且 evalF(M) = N
– evalF 在数学上等价于遵循策略 F逐步进行归约,直到该策略不能再遵循为止
3.6 各种归约策略• 一步归约策略
– 只要有可能便进行一步归约的策略– 程序 M 的计算 eval(M) 是 M 的范式或者 eval(M)没有定义– 基于项本身的形式来选择一步归约
•先“优化”函数 x : .M • 最左归约(惰性归约)•急切归约
(x : .M)N
(x : .M)N (x : .M)N[N/x]M
3.6 各种归约策略3.6.2 最左归约和惰性归约• 最左归约:对项中尽可能左边的符号进行归约
– 遵循的是结构化操作语义的风格– 每条规则正好作用到一种形式的项– 考察项的结构就知道该用哪条规则
• 例 (x : nat.y : nat.x + y) ( (z : nat.z) 20)left y : nat.( (z : nat.z) 20) + y
left y : nat.20 + y
3.6 各种归约策略• 例
((x : nat.y : nat.x + y) 9) 7 + (x : nat.x) 5
left (y : nat.9+ y) 7 + (x : nat.x) 5left (9 + 7) + (x : nat.x) 5left 16 + (x : nat.x) 5left 16 + 5left 21
3.6 各种归约策略• PCF 的最左归约
公理M N 是归约公理
子项规则– nat 和 bool
N 是范式
M left M
M + N left M + N
M NM left N
M left M
N + M left N + M
3.6 各种归约策略
N 是范式
M left M
Eq? M N left Eq? M N
M left M
Eq? N M left Eq? N M
3.6 各种归约策略
M 是范式
M,N 是范式
M left M
if M then N else P left if M then N else P
N left N
if M then N else P left if M then N else P
P left P
if M then N else P left if M then N else P
3.6 各种归约策略– 序对
M 是范式
M left M
M, N left M, N
N left N
M, N left M, N
M left M
Proji M left Proji M
3.6 各种归约策略– 函数
M 是范式
M left M
M N left M N
N left N
M N left M N
M left M
x : . M left x : . M
3.6 各种归约策略• 命题 3.25
令 M 是任意类型的 PCF 项,则对任何范式 N , M left N当且仅当M N
• 命题 3.26 令 M 是任意类型的 PCF 项,则 evelleft(M)=N当且仅当M N 并且 N 是范式
– 若仅要求这两个命题对 PCF 程序成立,则可以采用惰性归约– 在实际实现中惰性归约比最左归约用得更普遍
3.6 各种归约策略• PCF 的惰性归约
公理M N 是归约公理
子项规则– nat 和 bool
n 是数码
M lazy M
M + N lazy M + N
M NM lazy N
M lazy M
n + M lazy n + M
3.6 各种归约策略
n 是数码
M lazy M
Eq? M N lazy Eq? M N
M lazy M
Eq? n M lazy Eq? n M
3.6 各种归约策略
下面两条规则不再需要
M 是范式
M, N 是范式
M lazy M
if M then N else P lazy if M then N else P
N left N
if M then N else P left if M then N else P
P left P
if M then N else P left if M then N else P
3.6 各种归约策略– 二元组前两条规则不再需要
M 是范式
M left M
M, N left M, N N left N
M, N left M, N M lazy M
Proji M lazy Proji M
3.6 各种归约策略– 函数
下面两条规则不再需要
M 是范式
M lazy M
M N lazy M N
N left N
M N left M N
M left M
x : . M left x : . M
3.6 各种归约策略• 命题 3.27
若 M 是 PCF闭项,但它不是 x:.M1 或 M1, M2的形式,则对任何项 N , M lazy N当且仅当M left N
• 推论 3.28如果 P 是 PCF 程序, R 是结果,那么 P lazy R当且仅当 P left R
•比较和最左归约相比,因惰性归约的规则集小一些,因此有可能得到一个效率相对较高的实现
3.6 各种归约策略3.6.3 并行归约
对 PCF 来说,当能独立地归约两个子表达式中的任意一个时,就应该可以同时归约它们
• 并行归约的特点– 在 PCF 中, M N当且仅当M N– 并行归约可以较快到达范式
M NM N
M1 N1, …, Mk Nk
C[M1, …, Mk] C[N1, …, Nk]
3.6 各种归约策略3.6.3 急切归约• 最左归约和急切归约
– 最左归约和 PCF 的公理语义一致,并且允许不确定地或并行地实现– 更常用的次序是急切归约,它和 PCF 的公理语义不一致– 下面的表达式在最左归约下终止,但在急切归约下不终止
let f(x : nat) : nat = 5 inletrec g(x : nat) : nat = g(x + x) in f(g 3)
3.6 各种归约策略• 值
指不能再进行急切归约的项,即已完全计算的项– 常量、变量和抽象都是值,值的序对也是值– 序对中至少有一元不是值,以及函数应用都不能称为值
•急切归约与其它归约策略的主要区别只有当函数变元是值时才能使用 归约,只有当序对的两个元素都是值时才能使用 Proji 归约
3.6 各种归约策略• PCF 的急切归约
值– 若 V 是常量、变量、抽象或值的二元组,则 V是一个值公理– (x : .M)V eager VxM V 是值– Proji(V1,V2) eager Vi V1, V2 是值– 0 + 0 eager 0, 0 +1 eager 1, …, 3 + 5 eager 8,… – Eq? n n eager true, Eq? n m eager false
3.6 各种归约策略– if true then M else N eager M– if false then M else N eager N x : .M = y : .yxM , y 在 M 中不是自由的子项规则
nat
n 是数码
M eager M
M + N eager M + N
M eager M
n + M eager n + M
3.6 各种归约策略– bool
n 是数码
M eager M
Eq? M N eager Eq? M N
M left M
Eq? n M left Eq? n M
M eager M
if M then N else P eager if M then N else P
3.6 各种归约策略– 序对
V 是值
M eager M
M, N eager M, N
N eager N
V, N eager V, N
M eager M
Proji M eager Proji M
3.6 各种归约策略– 函数
V 是值
下面一条规则不再需要
M eager M
M N eager M N
N eager N
V N eager V N
M left M
x : . M left x : . M
3.6 各种归约策略• 在实际中用急切计算而不用最左计算的原因
– 最左归约的实现通常是低效的。当像 fx 这样的变元传给函数 g 时( g(fx) ),必须传递 f 的代码的指针并记住适当的词法环境– 最左归约和赋值的组合令人混淆,副作用的出现使得最左计算与不确定计算和并行计算不一致
习 题第一次: 3.3(a) , 3.6(b) , 3.9(a)第二次: 3.12 , 3.14(a) , 3.21第 三 次 : 3.22 , 3.23 , 3.24 , 3.27(a)
(b) , 3.28