logo资料库

软件开发形式化方法教材.pdf

第1页 / 共142页
第2页 / 共142页
第3页 / 共142页
第4页 / 共142页
第5页 / 共142页
第6页 / 共142页
第7页 / 共142页
第8页 / 共142页
资料共142页,剩余部分请下载后查看
形式语义(第一章 理论基础).pdf
形式语义学(第二章 函数式抽象语言).pdf
形式语义学(操作语义).pdf
形式语义学(指称语义学).pdf
形式语义学(公理语义).pdf
第一章 理 论 基 础 本章的主要内容包括: [1] Lambda 演算基础 1.1 Lambda 演算基础 [2] 完全半序集 [3] 连续函数 [4] 最小不动点 1.1 Lambda 演算基础 1941 年 Church 创建了 Lambda 演算理论。它是一个形式系统,可作为计算模型,如同 Turing 机可作为计算模型一样。Lambda 演算系统主要由两部分组成:其一是表达式,其二 是变换规则。Lambda 演算系统可有多种,其主要区别就在于构成 Lambda 演算系统的两个 组成部分的具体定义上。我们将会看到 Lambda 演算系统可描述任何一部分递归函数的计 算过程。Lambda 演算理论是函数式语言的理论基础。 1.1.1 Lambda 表达式 定义 1.1.1 (表达式):若用 x 表示变量,用 Exp 表示纯 Lambda 表达式之集,则 Exp 的定义如下: (1) x ∈Exp ; (2) 若 E1∈Exp,E2∈Exp,则 E1E2 ∈Exp; (3) 若 E ∈Exp,则 λx.E∈Exp; (4) 若 E ∈Exp,则 (E)∈Exp。 其中形如 (E1E2) 的表达式被称为施用表达式,而称形如(λx.E)的表达式为抽象表达 式。施用表达式(E1E2)对应于通常的函数调用f(E),而抽象表达式(λx.E)则对应于函数 定义。若用BNF表示法,则表达式结构可描述如下(x∈Var,E∈Exp ): E ::= x | E1 E2 | λx.E | ( E ) 从上述定义可知道,Lambda 表达式是非常小的表达式,以至于不能再小。但它将成 为 Lambda 演算系统的基础。那么一个作为计算模型的形式系统应具备什么样的条件 ? 很 显然它起码应具备二个条件:其一是它有很强的功能,以至于能够描述复杂的计算过程; 其二是它应非常小,以至于其语义是非常清楚的。 抽象表达式λx.E 用来表示无名函数。通常的方法是首先定义函数名,然后再使用 它,因此函数都有名,而抽象表达式则表示一无名函数。假设有函数定义: - 1 -
func f(x)= x+1 则它定义了这样一个函数,既函数名是 f,自变量(形参)是 x,而函数值是 x+1 的值。当 然我们也可用别的方式定义出上述函数,例如 func f = λx.x+1 这种表示法也能方便地表示哪个是函数名,哪个是自变量名,哪部分是函数体,其中λ表 示其后的变量为自变量。 假设有 f(a*b),则它应等价于(λx.x+1)(a*b),而其中(λx.x+1)和(a*b)都是表达式,这 样在 Lambda 表达式的定义中出现了 E1E2 形式的表达式。从语义角度来说其中的 E1 必须 是函数,而 E1E2 的含义是把函数作用与表达式 E2。我们称λx.E 中的 E 表达式为函数λx.E 的体部分,而称 x 为该函数的自变量。 定义 1.1.2 (记法约定): 为了节省括弧做如下约定 (1) E1 E2 E3...En = (((E1 E2)E3)...)En (左结合规则) (2) λx1...λ.xn.E = λx1.(...(λxn.En)...)) (3) λx1 x2...xn.E = λx1.λx2....λ.xn.E (4) λx1...λ.xn.E1 E2...En = λx1...λ.xn.(E1 E2...En) 例 1.1.1 下面是一些简单的 Lambda 表达式例: λx.λy.xy λxy.x λxy.x(y) (λx.xy)y λx.x λxy.y xy (λx.xx)(λx.xx) x(λx.xy ) 单从 Lambda 表达式结构看,看不出任何意义,因为其中既没有常量也没有函数名, 不知道是如何计算的。究竟如何计算表达式值,将由 Lambda 演算的第二组成部分,即 Lambda 变换部分来决定。作个比喻的话 Lambda 表达式相当于程序,而 Lambda 变换部分 则相当于程序的解释系统。后面将逐步介绍 Lambda 变换部分。 定义 1.1.3 (子表达式):设 E 是表达式,并用 sub(E)表示 E 的子表达式集,则定义 sub(x)={x} sub(E1E2)= sub(E1)∪ sub(E2)∪{E1E2} sub(λx.E)= λx.E}∪ sub(E) sub((E))={E} ∪ sub(E) 定义 1.1.4 (作用域):设有表达式λx.E,则定义λx 的作用域为其中的体表达式 E。 如若在 E 中包含一个子表达式λx.E1,则外层λx 的作用域将不包含该子表达式 E1 部分, 即外层λx 对 E1 无效。 定义 1.1.5 (自由出现):设 x′是表达式 E 中 x 的一次出现,则称该出现为 x 的一自 由出现,如果在 E 中没有一个子表达式λx.E1 包含该 x′出现。称非自由出现为约束出现。 例如假设有 λx.x( λx.x y x)x x 定义 1.1.6 (自由变量):称变量 x 为表达式 E 的自由变量,如果 E 中至少有一个 x 的自由出现。若用 Free(E)表示 E 的自由变量之集,则 Free(E)的具体定义如下: - 2 -
Free(x) = {x} Free(E1E2)= Free(E1)∪Free(E2) Free(λx.E)= Free(E)-{x} Free((E))= Free(E) 下面将定义所谓的代换[E0/x]E,它表示用表达式 E0 去代换表达式 E 中所有 x 的自由 出现。解释 Lambda 演算系统的最基本的概念之一是这里所说的代换,因此,要确切地理 解 Lambda 演算系统必须要熟悉代换的精确概念. 定义 1.1.7 (代换[E0/x]E): (1) E ≡ x 情形 (2) E ≡ y 情形 (3) E ≡ E1 E2情形 (4) E ≡ λx.E′情形 (5) E ≡ λy.E′情形(x≠y): x∈ Free(E′)∧y∈Free(E0)时:[E0/x](λy.E′)= λz.[E0/x][z/y]E′ :[E0/x]x= E0 :[E0/x]y= y ,(x≠y) :[E0/x](E1 E2)=([E0/x]E1)([E0/x]E2) :[E0/x](λx.E′)=λx.E′ x∉Free(E′)∨y∉Free(E0))时:[E0/x](λy.E′)= λy.[E0/x]E′ 关于代换的符号表示法有多种,例如还有 E[E0/x],E[x←E0] ,E{E0/x} 等。 1.1.2 Lambda 变换 给了一个表达式即可根据 Lambda 演算系统所定义的变换规则进行一系列的变换,其 结果有两种可能:一是不能进一步的归约;二是变换无终止地进行下去(相当于程序不终 止)。不同的 Lambda 演算系统具有不同的变换规则,有的可能只有两个变换规则,有的可 能有三个变换规则,有的甚至可能有更多的变换规则。这里将介绍的 Lambda 变换规则是 最常见的一种。 定义 1.1.8 (α变换):设 E 是 Lambda 表达式,x 是变量,则称下面变换为 α变换 ( 其中 Y 不在 Free(λx.E)中)。 λx.E ⎯→⎯α λy.[y/x] E α变换后所得新表达式的区别仅在于更换了抽象表达式的λ变量名,因此通常也称α变换 为改名变换。 例 1.1.1 1. λx.(Zx) ⎯→⎯α λy.(Zy) 2. λx.((λY.Yx)x) ⎯→⎯α λz.((λY.Yz)z) 3. λx.(Z(λY.x)) ⎯→⎯α λy.(Z(λy.y)): 非法α变换 4. λx.(ZY) ⎯→⎯α λY.(ZY) : 非法α变换 定义 1.1.9 (β变换):设 (λx.E)和 E0 为 Lambda 表达式,则称下面变换为β变换: - 3 -
(λx.E)E0 称β变换规则的左部表达式为β基。从形式上看每个β变换归约掉 一个λ。 β⎯ →⎯ [E0/x] E β变换是最重要的一个变换,可没有其他一些变换,但不能没有β变换。因此,所 有不同 Lambda 演算系统都有这一β变换。β变换规则实际上是定义了函数调用的语义, 因为β变换规则的左部是一个"函数调用"部分。( λx.E)E0 中的(λx.E )为被调用函数,x 为函数的自变量,E0 为实参表达式,而[E0/x]E 则表示把实参 E0 代入到函数体 E 中的形 参 x 中,这正是熟知的函数调用过程。 例 1.1.2 β⎯ →⎯ Ay 1. (λx.xy)A β⎯ →⎯ Ax 2. (λy.yx)A β⎯ →⎯ AA 3. (λx.xx)A 4. (λx.(λy.(λz.xyz)))ABC β⎯ →⎯ (λy.(λz.Ayz)))BC β⎯ →⎯ (λz.ABz)))C β⎯ →⎯ ABC 定义 1.1.10 (η变换):假设 λx.Mx 是一个表达式,且满足条件 x∉Free(M),则称 下面变换为η变换: (λx.M x) η⎯ →⎯ M 不难看出η变换是一种简化规则,也是一种保值变换。保值的依据是函数的等价性 定义,即 ∀(x)[f(x)=h(x)]⊃f=h。事实上我们有 ∀(y)[(λx.Mx)y = My ] 故有(λx.Mx)=M,也就是说η变换规则的左右部表达式是等值表达式。有些Lambda演算系 统没有这一种变换规则,也就是说η变换不是演算系统所必需的变换规则。 例 1.1.3 λx .(λy.yyy)x λx .(λy.yyx)x η⎯ →⎯ (λy.yyy) η⎯ →⎯ (λy.yyx) 非法η变换 定义 1.1.11 (Lambda 归约): (1) 称β变换的左部施用表达式(λx.E)E0为β基。 (2) 称η变换的左部抽象表达式(λx.Mx)为η基。 (3) β基和η基统称为归约基。 (4) 对表达式中的某一归约基实施某种变换称之为归约。 定义 1.1.12 (范式):假设 E 是一个 Lambda 表达式,且其中没有任何一个归约 基,则称该表达式为范式。如果一个表达式经过有限次变换能归约成范式,则称该表达式 有范式,否则称无范式。 例 1.1.4 下面是范式和非范式例 (1) x (2)xx (3)λx.xx (4) x(λx.xx) …… 范式例 - 4 -
(1) λx.x((λy.x)y) (2)λx.x(λy.xy)…………… 非范式例 现在要考虑的问题是,表达式是否都有范式?若有,是否唯一?范式应该如何求?下面 将说明以下一些问题: (1) 归约过程不唯一; (2) 表达式不一定都有范式; (3) 如果有范式一定唯一; (4) 如果有范式则最左归约法一定能求出范式。 首先考虑归约过程问题。在一个表达式中可包含多个归约基,因此,归约过程不唯 一,而且不同的归约过程也可能得到不同的计算结果。当然也可能都得到同一个结果。图 1.1.1 是有多个归约过程,但得到同一结果的例子。 ( λy.y((x((λa.a)))(λb.b) ( λy.y((λa.xa)(λa.a)))(λb.b) ( λb.b((λa.xa)(λa.a)) (λb.b)(x (λa.a)) (λa.xa)(λa.a) (λb.b)(x(λa.a)) x(λ.aa) 考虑有多个归约过程,并且不同归约过程得到不同结果的例: 图 1.1.1 归约过程例图 (λx.y)((λx.xx)(λx.xx)) 如果先归约(λx.xx)(λx.xx),则将无休止地变换下去,但如果先归约(λx.y)(....)部分, 则归约一次即可得到范式 y。这个题的特点是函数(λx.y)并不真正用到实参值, 因此会 得到上述结论。如果一定要首先计算实参然后再计算函数体的值, 那么就会出现以上问 题。下面是无范式的例子: (1) (λx.xx)( λx.xx) β⎯ →⎯ (λx.xx)( λx.xx) β⎯ →⎯ ..(不终止) (2) (λx.xxx)(λx.xxx)(λx.xxx) β⎯ →⎯ (λx.xxx)(λx.xxx)(λx.xxx) β⎯ →⎯ ........(不终止) 定义 1.1.13 (变换符号约定): (1) x ⇒ y :经过有限次变换(α,β,η),x变换为y。 (2) x ⇒r y :经过有限次归约(β,η),x变换为y。 (3) x ⇒α y :经过有限次α变换,x变换为y。 定理 1.1.14 (Church-Rosser):如果 A⇒x 和 A⇒y 成立,则一定存在 z 使得 x⇒z 和 y⇒z 成立。 证明.(略) - 5 - 批注 [½ð³ÉÖ²1]:
定理 1.1.15 (范式唯一性):如果把通过α变换可互换的表达式视为一种表达式, 那么如果 Lambda 表达式 E 存在其范式,则其范式一定唯一。 证明:假设表达式 E 有两个范式 x 和 y,则根据 Church-Rosser 定理,一定存在表达 式 z,使得 x⇒z 和 y⇒z 成立。因为 x 和 y 是范式,只能 x⇒αz,y⇒αz 。而α变换是双 向的,因此有 x⇒αy,也就是说范式 x 和 y 是同一种 Lambda 表达式。 定义 1.1.16 (标准归约):如果每次归约最左的归约基,则称这种归约为标准归约。 定理 1.1.17 :如果表达式 E 有范式,则按标准归约一定能求到其范式。 证明:略。 1.1.3 Lambda 演算能力 前面介绍了 Lambda 演算系统的基本概念。Lambda 演算系统主要由 Lambda 表达式和 Lambda 变换规则组成。Lambda 变换的主要作用是用来导出表达式的范式。Turing 机系统 能够描述部分递归函数的计算过程的事实,在可计算理论里已得以证实。那么 Lambda 演 算系统有无同样的功能 ? 这就是将要回答的问题,其结论是能。 在 Turing 机系统里有所谓的"带",它是 Turing 机的操作对象,操作结果将改变带的 内容。带由很多有序方格组成,在每个方格里可写所允许的符号。带的内容究竟表示什么 意思?系统本身并不知道,系统只知道在什么状态下做什么动作。系统只提供一种用于演 算的形式规则,带的内容究竟表示什么意思只有用户自己才知道。 在 Lambda 演算系统中, Lambda 表达式相当于 Turing 机中的带,它们扮演着操作对 象的角色。Lambda 表达式的结构非常简单,但它的功能和当代计算机的功能是一样大。 我们将非严格地证明 Lambda 演算系统可模拟部分递归函数的计算过程,主要说明以下几 点:可模拟非负整数;可模拟函数 +、*、and、or、<、≤ 等; 可模拟复合函数; 可 模拟条件函数 if_then_else ;可模拟递归。 [模拟自然数] 在这里将用如下λ-表达式来模拟整数 n: λab.a(a(......(a(a(ab)))) 其中a的个数为n个。我们将它简写成λab.anb,注意anb是右结合的简写。若用 n 表示整数n 的相应模拟表达式(函数),则有 0 = λab.b 1 = λab.ab 2 = λab.a(ab) = λab.a2b (右结合) n = λab.(a(a(a...(ab)......)) = λab.anb (右结合) [模拟算术运算] 设 f 是给定 i 元函数,并且下式成立 - 6 -
f 1m 2m ... mi = ,m f(m 21 ,...,mi ) (*) 则称 f (Lambda 表达式)为 f 的模拟函数。假设用 PLUS 和 MULT 分别表示+和*的模拟函数, 则根据(*)的定义应分别满足条件: PLUS m n = nm + nm * MULT m n = 事实上,只要将模拟函数PLUS和 MULT分别定义为 PLUS = λxy.λab.(xa)((ya)b) MULT = λxy.λa.x(ya) 即可满足(*)条件,因为有 PLUS m n = (λy.λab.( m a)((ya)b)) n = λab.( m a)(( n a)b) = λab.(λb.amb)(an b) = λab.am+n b = nm + MULT m n = (λy. λa. m (ya)) n = λa. m ( n a) = λa.( λab.am b)( λb.an b) = λa.( λb.( λb.a n b)m b) = λab.am n b = nm × [模拟逻辑运算] 我们将逻辑运算 and、or 和 not 的模拟函数分别表示为 AND、OR 和 NOT。首先要模拟 逻辑值 true 和 false。若用 T 和 F 来表示相应模拟函数,则只要将它们定义为如下即可: T = λab.a (取第一个) F = λ ab.b (取第二个) 注意它们和整数的模拟数并不矛盾。其次,我们来构造逻辑运算and、or和not的模拟函数 AND、OR和NOT,它们需满足下面条件: AND x y = if x=T and y=T then T else F OR x y = if x=T or y=T then T then F NOT x = if x=F then T then F 事实上只要令 AND = λxy.(xyF) OR = λxy.(xTy) - 7 -
NOT = λx.(xFT) = (λy.TyF)T = (λy.y)T = T 即可满足上述条件,因为有 AND T T = (λxy.xyF)TT AND T F = (λxy.xyF)TF 同样可以证明有 (AND T F = F)。再考虑 OR 的问题,需要证明: AND F T = (λxy.xyF)FT AND F F = (λxy.xyF)FF = (λy.TyF)F = (λy.y)F = F = (λy.FyF)T = (λy.F)F = F = (λy.FyF)T = (λy.F)T = F OR T T=T, OR T F=T, OR F T=T, OR F F=F = (λy.TTy)T = (λy.T)T = T 事实上有 OR T T = (λxy.xTy)TT OR F T = (λxy.xTy)FT 用同样的方法可以证明有 (NOT T = F)(NOT F=T)。 = (λy.FTy)T = (λy.y)T = T = (λy.FTy)T = (λy.y)T = T OR F T = (λxy.xTy)FT OR F F = (λxy.xTy)FF = (λxy.xTy)FF = (λy.y)F = F [模拟关系运算] 最后考虑关系运算<和≤ 的模拟。为此首先定义一函数 ISZERO,它是一元函数,如果 自变元值为0 ,则回送 T 值,否则回送 F 值。该函数的具体定义如下: ISZERO = λx.x(TF)T 其中x取 0 或1 。事实上有 ISZERO 0 = 0 (TF)T=(λab.b)(TF)T=(λb.b)T=T ISZERO 1 = 1 (TF)T=(λab.ab)(TF)T=(λb.(TF)b)T=(TF)T=F 因此 ISZERO是0 的判定函数。另外再假定 MINUS 是减法运算的模拟函数,即有 MINUS 1n 2n = 2 1 n n − ,当 n1 ≤ n2 = 0 ,当 n1 < n2 若用LT和 LE分别表示 < 和 ≤ 的模拟函数,则只要利用 ISZERO 和 MINUS 把LT和 LE 定 义成如下即可: LE = λm n. ISZERO( MINUS( MINUS m n )( MINUS( MINUS m n )1 )) LT = λm n. AND( LE m n)( NOT (EQ m n)) - 8 -
分享到:
收藏