形式语义教材-Ch1 基本理论

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第一章理论基础

§ 1.1 引言

1941年Church创建了Lambda演算理论。它是一个形式系统,可作为计算模型,如同Turing机可作为计算模型一样。Lambda演算形式系统主要由两部分组成:其一是合法表达式的形式系统,其二是变换规则的形式系统.

Lambda演算系统可有多种。其主要区别在于构成Lambda演算形式系统的两个组成部分的具体定义上。不同的Lambda演算系统会得到一些不同的定理。Lambda演算系统如同Turing机系统一样,可描述任何一部分递归函数的计算过程。因此,Lambda演算系统也可视为一种算法语言系统。其中的Lambda表达式相当于语言的一个程序。程序如何执行,由Lambda演算系统的机制来确定。Lambda演算理论是函数式语言的基础,也是指称语义学的理论基础。

§1.2 Lambda 演算

纯Lambda表达式(以后简称λ表达式)是最小的一种表达式,主要由变量名和抽象符号λ以及括号等符号构成。若用X表示变量,用Exp表示纯Lambda表达式之集,则Exp 集的定义如下。

■定义 1.2.1.λ表达式

若用BNF表示法,则可描述如下(x ∈Var, E ∈Exp ):

从上述定义可知纯λ_表达式是非常小的表达式,以致于不能再小。但它将成为λ_演算系统的基础。那么一个作为计算模型的形式系统应具备什么样的条件呢?很显然它起码应具备二个条件:其一是它有很强的功能,以致于能够描述复杂的计算过程;其二是它应

非常小,以致于其语义是非常清楚的。当然实用性的系统,则应根据需求扩充相应的内容,但其前提是它们可变换为纯λ_表达式的形式。

在我们这里Lambda演算系统主要是作为函数式语言和指称语义描述语言的基础。设L为被描述的语言,L0为描述L语义的语言,则我们称L0为元语言。显然,元语言不能是很复杂的,否则又可提出L0语言的语义是什么?因此,元语言的基础应非常简单。而所使用的实际元语言则应从简单语言逐步扩充而来,而且其语义是很清楚的。

在我们的λ_表达式中没有常量部分,而且变量是广义的,即它代表的也可以是一函数。称形如(E1E2)的表达式为施用型表达式,称形如λ x .E的表达式为抽象型表达式。表达式(E1E2)相当于通常的函数调用f(E),其中f是函数名。现在不一样的是E1不一定是一个函数名,可以是复杂的表达式,但必须是抽象表达式或代表函数的变量名,如

(λX.f(X))((λY.Y)20 ),其中有三个施用型子表达式;

▢ (λY.Y)20 ▢ f(X) ▢ (λX.f(X))( (λY.Y)20 )

抽象表达式主要是用来表示无名函数。通常的方法是首先定义函数名,然后再使用它,因此函数都有名,而抽象表达式则表示一无名函数。假设有函数说明func f(X)=X+1,则显然也可把上述函数的定义写成:f=λX.X+1,并且也能方便地表示哪个是函数名,哪个是形参名,哪部分是函数体,其中λ表示其后的变量为形参变量。这种说明是定义了一个函数名f。如果不想定义函数名,那么应该怎么办?这好办,只要直接用表达式λX.X+1即可了。这就是抽象表达式的直接出因。我们称λx.E中的E表达式为上述抽象表达式的体部分。

为了简单起见,以后将(XY)简写成XY。严格说的话,不能写成XY形式,因为这种写法,使实现系统将无法识别XY是一个标识符还是两个标识符。但如果假设变量名均由一个字母组成,则写成XY形式也能够分辨出来是X和Y的两个名字。因此我们以后在一般情况下将写成XY的形式。

■定义 1.2.2. (记法约定)

例 1.2.1.下面是一些简单的λ_表达式例:

λx.λy.xy (λx.xy)y λx.x

λxy.x λxy.y (λx.xx)(λx.xx)

λxy.x(y) xy x(λx.xy )

单从表达式看,看不出任何意义,因为其中既没有常量也没有函数名,不知道是如何计

■定义 设E 是表达式,并用SUB(E)表示E 的子表达式集,则定义

SUB(x)={ x }

SUB(E1 E2)=SUB(E1) ⋃ SUB(E2)⋃{E1 E2}

SUB(λx.E)={λx.E} ⋃SUB(E)

SUB( (E) )={ E } ⋃ SUB(E)

■定义设有λ表达式λ的作用域为其中的体表达式E 部分。如若在E 中包含一个子表达式λx.E1,则外层λx 的作用域将不包含该子表达式部分。

■定义设x'是表达式,则称该出现为x 的一自由出现,如果在E 中没有一个子表达式λx.E1包含该x'出现。非自由出现称为约束出现。

■定义称变量x ,如果E 中至少有一个x 的自由出现。若用Free(E)表示E 的自由变量的集合,则E 的自由变量集的具体定义如下:

Free(x) 〒 { x }

Free(E1 E2) 〒 Free(E1)⋃Free(E2)

Free(λx .E) 〒 Free(E )-{ x }

Free( (E) ) 〒 Free(E)

如果表达式E 不包含自由变量,则称E 定义所谓的代换[E0/x]E,它表示用表达式E0去代换表达式E 中所有x 的自由出现。解释Lambda 演算系统的最基本的概念之一是这里所说的代换,因此,要确切地理解Lambda 演算系统必须要熟悉代换的精确概念.

■定义 1.2.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)时

x ∉Free(E')∨ y ∉Free(E0))时

给了一个表达式即可根据Lambda 演算系统所定义的变换规则进行一系列的变换,其结果有二种可能:一是不能进一步的归约;二是变换无终止地进行下去(相当于程序不终止)。Lambda 变换是保结构和保值的变换,其中保结构是指变换后得到的仍然是λ-表达式。

不同的Lambda 演算系统具有不同的变换规则,有的可能只有二个变换规则,有的可能有三个变换规则,有的甚至可能有更多的变换规则。有的具有相同个数的变换规则,但变换规则的内容可不一样。我们这里介绍的Lambda 变换规则只是其中的一种。

■定义1.2.8. α变换

设 E 是 λ-表达式,x 是变量,则称下面变换为 α变换( 其中Y 不在 Free( λx.E )中)。

从定义可看出α变换是保结构的一种变换,也是保值的。α变换后所得新表达式的区别仅在于更换了形参的名字。

例 1.2.2.

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.2.9. (β变换)

设 (λx.E)和E0为 λ-表达式,则称下面变换为β变换(称β变换规则的左部表达式为β基)。

β变换是最重要的一变换,可没有其他一些变换,但不能没有β变换。因此,所有不同 Lambda 演算系统都有这一β变换。β变换规则实际上是定义了函数调用的语义,因为β变换规则的左部是一"函数调用"部分。( λx.E)E0中的(λx.E )为被调用函数,x 为函数的形参,E0为实参。而[E0/x]E 则表示把实参E0代入到函数体E 中的形参x 中,这正是熟知的函数调用过程。

相关文档
最新文档