TLA+ 《Specifying Systems》翻译初稿——Section 5.1 The Memory Interface(内存接口)

本节定义了一个内存系统的通用接口,给出了其设计考虑,并重点说明了为什么以及如何将一个表达式声明为常量参数。

  • 声明: CONSTANT  S e n d ( _ , _ , _ , _ ) \text{CONSTANT } Send(\_, \_, \_, \_)
  • 类型假设: ASSUME  p , d , m i O l d , m i N e w : S e n d ( p , d , m i O l d , m i N e w ) BOOLEAN \text{ASSUME } \forall p, d, miOld, miNew:\\\qquad \qquad \qquad Send (p, d, miOld, miNew) \in \text{BOOLEAN}

在第3章描述的异步接口中我们使用了握手协议,在发送下一个数据之前必须确认原先的数据已被接收。在本节的内存接口中,我们将这种细节抽象出来,并将数据的发送和接收都归入单个步骤。处理器将数据发送到内存中,我们称之为 S e n d Send 步骤,内存发送数据给处理器,称之为 R e p l y Reply 步骤。处理器之间不互相发送数据,内存一次只发送数据给一个处理器。

我们用变量 m e m I n t memInt 的值表示内存接口的状态。 S e n d Send 步骤用某种方式改变了 m e m I n t memInt ,但是我们不想具体说明它是如何改变的,这种情况下,我们将其设为规约的常量参数,就如在4.4节的有限制FIFO中,我们将缓冲区大小设为常量参数 N N 一样。

这样,我们希望声明一个参数 S e n d Send ,使得表达式 S e n d ( p , d ) Send(p, d) 是一个步骤,描述处理器 p p 向内存发送数据 d d 的操作是如何改变 m e m I n t memInt 的。但是, T L A + TLA^+ 只提供了 CONSTANT \text{CONSTANT} VARIABLE \text{VARIABLE} 参数,没有提供动作参数。因此,我们将 S e n d Send 声明为常量运算符,并记成 S e n d ( p , d , m e m I n t , m e m I n t ) Send(p, d, memInt, memInt') 而不是 S e n d ( p , d ) Send(p, d)

T L A + TLA^+ 中,我们这样将 S e n d Send 声明为一个常量运算符,携带四个入参:
CONSTANT  S e n d ( _ , _ , _ , _ ) \text{CONSTANT } Send(\_, \_, \_, \_)

这意味着对于任何表达式 p p , d d , m i O l d miOld ,和 m i N e w miNew , S e n d ( p , d , m i O l d , m i N e w ) Send(p, d, miOld, miNew) 也是一个表达式,不过这里还没有说明表达式的值是什么,我们希望它是一个布尔值,其值为真当且仅当 m e m I n t memInt 在第一个状态中等于 m i O l d miOld ,在第二个状态中等于 m i N e w miNew ,且是描述处理器 p p 将值 d d 发送到内存的步骤。我们可以通过下面这个假设来断言这个值是布尔值。
ASSUME  p , d , m i O l d , m i N e w : S e n d ( p , d , m i O l d , m i N e w ) BOOLEAN \text{ASSUME } \forall p, d, miOld, miNew:\\\qquad \qquad \qquad Send (p, d, miOld, miNew) \in \text{BOOLEAN}

上述语句表明对所有的 p p , d d , m i O l d miOld , m i N e w miNew 值, S e n d ( p , d , m i O l d , m i N e w ) BOOLEAN Send(p, d, miOld, miNew) \in \text{BOOLEAN} 为真,内置符号 BOOLEAN \text{BOOLEAN} 表示集合 { TRUE, FALSE } \{\text{TRUE, FALSE}\} ,它的元素是两个布尔值 TRUE \text{TRUE} FALSE \text{FALSE}

这个 ASSUME \text{ASSUME} 语句正式断言 S e n d ( p , d , m i O l d , m i N e w ) Send(p, d, miOld, miNew) 的值是一个布尔值。但是,正式断言该值含义的唯一方法是声明它真正是什么——也就是说,给出 S e n d Send 的定义而不是将其作为参数。我们不想那样做,所以这里我们只是非正式地声明了它的含义,它是表征我们的数学抽象与物理内存系统之间内在关系的非正式描述的一部分。

为了让读者理解规约,我们必须非正式地描述 S e n d Send 的含义,用 ASSUME \text{ASSUME} 语句断言 S e n d ( ) Send(…) 是一个布尔值,不管怎么说,把它包含进来是个不错的用法。

使用内存接口的规约可以使用 S e n d Send R e p l y Reply 运算符来描述变量 m e m I n t memInt 是如何改变的。此规约还必须给出 m e m I n t memInt 的初始值,这里我们声明一个常量参数 I n i t M e m I n t InitMemInt ,使其为 m e m I n t memInt 可取的初始值的集合。

我们还需要引入3个常量参数来定义此接口:

  • P r o c Proc 处理器标识符集合。(在提及 P r o c Proc 集合的元素时,我们通常将处理器标识符简称为处理器。)
  • A d r Adr 内存地址集
  • V a l Val 某个内存地址的合理取值集合

最后,我们定义处理器和内存通过接口互相发送的值的集合。处理器向内存发送一个请求,在 T L A + TLA^+ 中我们将其表示成一条记录,其中 o p op 字段指定请求的类型,其他字段指定请求的参数。本节定义的简单内存只允许读写请求。一条读请求的 o p op 字段为“ R d Rd ”,其 a d r adr 字段指定要读的地址。因此,所有读请求的集合就是:
[ o p : " R d " a d r : A d r ] [op: {"Rd"}, adr: Adr]

该集合所有元素的 o p op 字段等于“ R d Rd ”, a d r adr 字段是 A d r Adr 集合的一个元素。写请求必须指定要写的地址和要写的值,也由一条记录表示,其 o p op 字段等于“ W r Wr ”, a d r adr v a l val 字段分别指定地址和值。我们定义 M R e q MReq 为所有请求的集合,是读写请求两个集合的并集。(集合操作,包括并集,参见在第11页第1.2节。)

内存通过返回读取的内存值来响应读请求,那如何定义写请求的响应值呢?我们认为与读请求不同的话会比较清晰,这里设返回值为 N o V a l NoVal N o V a l NoVal 被声明为常量参数并假设 N o V a l V a l NoVal\notin Val ( \notin 符号在 A S C I l ASCIl 中键入为“\notin”)。不过最好尽可能避免引入参数,我们还可以这样定义 N o V a l NoVal
N o V a l CHOOSE  v : v V a l NoVal \triangleq \text{CHOOSE }v:v \notin Val

表达式 CHOOSE  x : F \text{CHOOSE }x:F 等于满足公式 F F 的任意值。(如果不存在这样的值,则该表达式是一个完全随机的值)。这个语句没有定义 V a l Val 是什么,只定义了它不是 V a l Val 的一个元素。 CHOOSE \text{CHOOSE} 运算符参见第73页的第6.6节。

在这里插入图片描述
完整的内存接口规约见上图5.1模块 M e m o r y I n t e r f a c e MemoryInterface

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

猜你喜欢

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