TLA+ 《Specifying Systems》翻译初稿——Section 3.4 Definitions(定义)

本节描述了TLA+中定义的含义及书写方式,及声明或定义的使用范围,着重指出在TLA+中,在有重叠的定义域下,不能重复声明或定义标识符

让我们研究一下定义的含义。如果 I d Id 是像 I n i t Init S p e c Spec 这样的简单标识符,则表达式 I d e x p Id \triangleq exp I d Id 定义为表达式 e x p exp ,在任何表达式中用 e x p exp 代替 I d Id 或者反过来,都不会改变该表达式的含义。我们必须在解析表达式之后而不是在“raw input”中执行此替换,例如,定义 x a + b x \triangleq a + b 使得 x c x*c 等于 ( a + b ) c (a + b)*c ,而不是 a + b c a+b*c (即 a + ( b c ) a+(b*c) )。

定义 S e n d Send 的形式为 I d ( p ) = e x p Id(p)= exp ,其中 I d Id p p 表都是标识符。对于任何表达式 e e I d ( e ) Id(e) 可以通过将 e x p exp 中的 p p 替换为 e e 得到。例如, C h a n n e l Channel 模块中 S e n d Send 定义 S e n d ( 5 ) 的Send(-5) 等于 c h a n . r d y = c h a . a c k c h a n = [ c h a n  EXCEPT  ! . v a l = 5 , ! . r d y = 1 @ ] \begin{aligned} &\land chan.rdy = cha.ack \\ &\land chan' = [chan \text{\footnotesize{ EXCEPT }} !.val = -5, !.rdy = 1- @] \end{aligned} 对于任何表达式 e e S e n d ( e ) Send(e) 也是一个表达式。因此,我们可以编写公式 S e n d ( 5 ) ( c h a n . a c k = 1 ) Send(-5)\land(chan.ack = 1) 。标识符 S e n d Send 本身不是表达式, S e n d ( c h a n . a c k = 1 ) Send\land(chan.ack = 1) 也不是完全符合语法的字符串,只是没有语义的废话,例如 a + b + a+*b+

S e n d Send 是一个带有单个入参的运算符。我们显式定义带多个入参的运算符,一般形式为
(3.1) I d ( p 1 , , p n ) e x p Id(p_{1},\ldots,p_{n})\triangleq exp
其中 p i p_{i} 是独立的标识符,而 e x p exp 是表达式。我们可以将已定义的诸如 I n i t Init S p e c Spec 之类的标识符视为不带任何参数的运算符,但是我们通常使用 o p e r a t o r operator 来表示带一个或多个参数的运算符。

我将使用“符号”一词来表示诸如 S e n d Send 之类的标识符或诸如“ + + ”之类的运算符。规约中使用的每个符号都必须是TLA+的内置运算符(如 \in ),或者必须被声明或定义。每个被声明或定义的符号都有其使用范围, VARIABLE \text{\footnotesize{VARIABLE}} CONSTANT \text{\footnotesize{CONSTANT}} 声明或定义,其使用范围是其后的整个模块。因此,在模块 C h a n n e l Channel 中, I n i t Init 定义语句之后,其他表达式都可以使用 I n i t Init EXENTNDS  N a t u r a l s \text{EXENTNDS } Naturals 语句会将在 N a t u r a l s Naturals 模块中定义的符号(如 + + )的使用范围扩展到 C h a n n e l Channel 模块。

运算符定义(3.1)隐式包含 p 1 , , p n p_{1},\ldots,p_{n} 这些标识符的使用范围为表达式 e x p exp 中。下面这种形式的表达式:
v S : e x p \exists v \in S: exp
中声明的标识符 v v ,也是如此,其范围是表达式 e x p exp 。因此,标识符 v v 在表达式 e x p exp 中有意义(但在表达式 S S 中没有意义)。

如果符号已经具有意义,则不能再声明或定义它,不过像这种表达式 ( v S : e x p 1 ) ( v S : e x p 2 ) (\exists v \in S: exp1) \land (\exists v \in S: exp2) 没关系,因为两个 v v 的声明范围不重合,同样, C h a n n e l Channel 模块中符号 d d 的两个声明(一个在 S e n d Send 的定义中,一个在 N e x t Next 的定义 d \exists d 中)具有不相交的范围。但是,下面表达式是非法的: ( v S : ( e x p 1 v T : e x p 2 ) ) (\exists v \in S:(exp1 \land \exists v \in T:exp2)) ,之所以是非法的,是因为第二个 v \exists v 中的 v v 声明位于第一个 v \exists v 的声明范围之内。尽管常规的数学和编程语言允许进行此类重复定义或声明,但在TLA+中是禁止,因为它们可能导致混淆和错误。

发布了4 篇原创文章 · 获赞 1 · 访问量 5511

猜你喜欢

转载自blog.csdn.net/robinhzp/article/details/103893151