编程的实践理论 第五章 编程的语言

第五章 编程的语言 

我们已经使用了一个非常简单的编程语言,它仅由Ok,赋值,“if then else  fi ”
依赖(顺序性)组合,和已推导的规格。在这一章中,我们通过引入一些流行的
编程语言中的发现的一些记号来丰富我们的语言的范围。我们还没有考虑过加入
并发(独立的组合)和交互(输入和输出),它们在稍后有自己单独的一章。

5.0 作用域
    5.0.0 变量声明

声明一个新的有本地作用域的状态变量的能力是如此的有用,每一种流行的
编程语言都提供了它。一个声明可能看起来像是这样的:
var x:T
这里,x是被声明的变量,T叫做类型,它显示了x能够被赋值成什么样的值。
根据本书最后页的前提表,一个变量声明符合它的要求。在编程理论中,
我们的每一个记号都应用于规格,而不仅仅是程序,是很必要的。我们能够引入
一个本地的变量作为编程过程的一部分的方式 ,在它的作用域之前,被推导的。


我们能表达一个变量的声明结合着规格,这个规格应用于一个二进制的表达式。
这个表达式有初始状态和终止状态。
var x: T· P     =     ∃x, x′: T· P
规格P是一个表达式,它的初始和终止值都是已声明的,非本地化的变量,加上新
声明的本地的变量。规格 var x: T· P 是仅有的非本地化变量中一个表达式。
对于一个可实现的变量的声明,它的类型必须是非空的。
作为一个简单的例子,假定非本地化的变量是整数变量y,z。那么,
var x: int·  x:= 2.  y:= x+z
= ∃x, x′: int·  x′=2  ∧  y′ = 2+z  ∧  z′=z
= y′ = 2+z  ∧  z′=z

根据变量声明的定义,本地变量的初始值是一个它自己类型内的随意的值。
var x: int·  y:= x
= ∃x, x′: int·  x′=x ∧ y′=x ∧ z′=z
= z′=z
它说的是z是不变的。变量x没有提到,因为它是本地化的,变量y没有提到,因为
它的终止值是未知的。然而,
var x: int·  y:= x–x
= y′=0 ∧ z′=z

在一些语言里,一个新声明的变量有一个特殊的值,叫做未定义值,它不参与
任何表达式的计算。为了写这样的声明作为一个二进制的表达式,我们引入了
表达式 “未定义”,但是我们关于它没有给出任何公理,所以关于它的证明
是没有的。
var x: T· P     =     ∃x: undefined· ∃x′: T, undefined· P
关于这个类型的变量声明,类型非空的要求是不必要的。

一个初始化的赋值以相同的方式 是很容易定义的。
var x: T := e·  P     =     ∃x: e· ∃x′: T· P
假定e的类型是T。

如果我们统计空间的使用,一个变量的声明应该被涉及到。
在声明的作用域的开始处,空间变量s会增长,并且 在作用
域的结束处,s会相应地减少。

在许多的编程语言中,我们能在一个声明中,声明多个变量,例如
var x, y, z: T· P     =     ∃x, x′, y, y′, z, z′: T· P

声明变量尽可能地本地化,局部化是一个服务。这种方式,本地作用域之外的
状态空间没有被意外的变量污染。在本地作用域内,有所有的非本地化变量加
上本地化的一个,有更多的变量是本地化的。

    5.0.1 变量悬浮

我们能希望,临时性地,聚焦于状态空间的一部分。如果部分是x,y,
我们展示了这个记号
frame x,y
它的应用遵循着本书结尾处的优先表,正如var。 frame 记号是说其它的变量
都不改变的形式化方式。尽管不同,一些语言的“import”语言是相似的。如果
状态变量没有包括w,z 那么
frame x, y· P    =   P ∧ w′=w ∧ z′=z

P有状态变量x和y.  它允许P涉及到w和z,但是仅作为本地的常量
(数学变量,不是状态变量,这没有w'和z')。时间和空间变量
都是隐性地假定在所有的帧中,即使它们没有显性的列出来。

ok和赋值的定义使用了状态变量。
ok = x′=x ∧ y′=y ∧ ...
x:= e = x′=e ∧ y′=y ∧ ...

部分是非形式化的,使用了三个点,说的是与其它的状态变量的合取。
如果我们首先已经定义了帧,我们能形式化地定义它们如下:
ok = frame· T
x:= e = frame x· x′=e

我们在之前的章节中规定了列表 求和的问题为 s' = ΣL 。
我们以s为一个状态变量,L是一个常数。我们有一个规格
s = ΣL 说s有一个正确的终止值,其它的变量没有改变,但是
我们的解决方案包括了一个变量n,它开始于0,结束于#L。我们现在
有需要形式化的记号。
s:= ΣL   =   frame s·  var n: nat·  s′ = ΣL

首先,我们归结状态空间为s;如果L是一个状态变量,它现在
是一个常数。接下来,我们引入了本地变量n。那么,我们与
之前的做法一样。
 

你可能感兴趣的:(编程的实践理论,开发语言)