TLA+ 《Specifying Systems》翻译初稿——Section 3.0 An Asynchronous Interface

本节简述了一个用于在异步设备之间传输数据的接口,描述了在写作规约之前需要做的准备工作,并提出了对抽象的一些考虑:

  • 规约是一种必要的抽象,抽象会掩盖系统的某些细节,从而引入一些潜在的风险;
  • 编写规约最困难的部分是选择正确的抽象,抽象的能力只能从实践中来;
  • 在TLA+规约中,抽象意味着选择代表系统状态的变量,以及更改这些状态变量的步骤的粒度。

现在,我们指定一个用于在异步设备之间传输数据的接口,发送方 s e n d e r sender 和接收方 r e c e i v e r receiver 之间的连接关系如下图所示:
在这里插入图片描述
数据在 v a l val 上发送,并且 r d y rdy a c k ack 线用于同步。发送方必须等待接收方的确认( A c k Ack ),然后才能发送下一个数据项。该接口使用标准的两阶段握手协议,下面的示例行为描述了这个过程:
[ v a l = 26 r d y = 0 a c k = 0 ]   Send   37 [ v a l = 37 r d y = 1 a c k = 0 ]   Ack   [ v a l = 37 r d y = 1 a c k = 1 ]   Send   4 [ v a l = 4 r d y = 0 a c k = 1 ]   Ack   [ v a l = 4 r d y = 0 a c k = 0 ]   Send   19 [ v a l = 19 r d y = 1 a c k = 0 ]   Ack   \left[\begin{array}{l}{val=26} \\ {rdy=0} \\ {ack=0}\end{array}\right] \quad \underrightarrow{\scriptsize{\textit{ Send \;}37}} \left[\begin{array}{l}{val=37} \\ {rdy=1} \\ {ack=0}\end{array}\right] \quad \underrightarrow{\scriptsize{\textit{ Ack }}}\left[\begin{array}{l}{val=37} \\ {rdy=1} \\ {ack=1}\end{array}\right] \quad \underrightarrow{\scriptsize{\textit{ Send \;}4 }} \\ \qquad \left[\begin{array}{l}{val=4} \\ {rdy=0} \\ {ack=1}\end{array}\right] \quad \underrightarrow{\scriptsize{\textit{ Ack }}}\left[\begin{array}{l}{val=4} \\ {rdy=0} \\ {ack=0}\end{array}\right] \quad \underrightarrow{\scriptsize{\textit{ Send \;}19}}\left[\begin{array}{l}{val=19} \\ {rdy=1} \\ {ack=0}\end{array}\right] \quad \underrightarrow{\scriptsize{\textit{ Ack }}} \cdots
v a l val 在初始状态下取任意值都没有关系。)

从这个示例行为可以很容易地看出,一旦确定了待发的数据,所有可能的行为也确定了。但是,在编写描述这些行为的TLA+规约之前,让我们回顾一下刚刚做了什么。

在编写此行为时,我首先要决定 v a l val r d y rdy 的值是否应该在一个步骤中改变。变量 v a l val r d y rdy 的值表示在物理设备中的某些电线上的电压,实际上不同电线上的电压不会在同一瞬间发生变化,但我决定忽略物理系统的这个方面,假定 v a l val r d y rdy 表示的电压值会瞬间变化。这会简化规约,但可能会忽略系统的某些重要细节,事实上,直到 v a l val 线路上的电压稳定后, r d y rdy 线路上的电压才应发生改变。您将不会从我的规约中看到这一点,如果我希望规约传达这个要求,我会另写一个行为,其中 v a l val 的值和 r d y rdy 的值在不同的步骤中发生变化。

规约是一种抽象。它描述了系统的某些方面,而忽略了系统的其他方面。我们希望规约尽可能的简单,因此必然会忽略尽可能多的细节。每当在规约中忽略系统的某些方面时,我们要承认这会带来潜在的某些错误。我的规约可以验证使用此接口的系统的正确性,但在实际系统仍然可能会失败,因为实现者并不清楚在改变 r d y rdy 线之前 v a l val 线必须保持稳定。

编写规约最困难的部分是选择正确的抽象。我可以教给您有关TLA+的知识,因此将系统的抽象视图表示为TLA+规约会成为一项简单的任务。但是我不知道如何教你抽象,优秀的工程师知道如何抽象系统的本质,并在定义和设计系统时删减不重要的细节,抽象的能力只能从实践中得来。

编写规约时,必须首先选择抽象。在TLA+规约中,这意味着选择代表系统状态的变量,更改这些状态变量的步骤,以及步骤的粒度。 r d y rdy a c k ack 线应该表示为单独的变量还是同一变量? v a l val r d y rdy 是否应该在一步,两步或任意几步更改?为了帮助做出这些选择,建议您首先编写一两个示例行为的前几个步骤,就像我在本节开始时所做的一样。第7章对这些选择还有更多的话要说。

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

猜你喜欢

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