TLA+ 《Specifying Systems》翻译初稿——Chapter 9 Real Time Section 1 The Hour Clock Revisited

使用活性属性,我们可以指定系统最终必须响应一个请求,但不能指定它必须在未来100年内作出反应。要指定及时响应,必须使用real-time属性。

在我们的生命周期内没有响应的系统没有什么意义,我们可能期望real-time在 specification中是通用的,可惜不是。Formal specification通常用于描述系统做了什么,而不是用了多长时间。在一些场合,我们可以能需要用到real-time属性,下面的章节我们具体讨论下怎么用。

回顾第二章,HC specification,变量hr从1到12循环,现在加入一个需求:hr读数必须准时显示。几个世纪以来,科学家通过引入一个变量t来描述系统的real-time行为,t是一个表示时间的实数。state t=-17.15表示t=-17.15时刻系统的状态,可能是从美国时间2000-01-01 00:00:00开始, 以秒为单位计时。 在TLA+ specification中,我习惯用变量now代替变量t表示时间。方便起见,我们还是用秒做时间单位,尽管选择其他单位也可以。

与物理和化学等学科不同, 计算机科学将系统的行为用一系列离散的state来描述, 而不是随时间变化而连续变化的state。 例如认为hr读数改变是瞬时的(0秒内发生),直接从读数12跳到读数1, 而忽略在物理显示中用来过度的中间状态。所以,时钟的real-time specification可以定义为满足如下的step:

image.png

now的值在hr的变化间变化。如果我们想确定hr从12到1的变化花了多长时间, 则需要引入一个中间state来描述这个读数的变化过程——或是让hr增加一些中间值如12.5, 或是加入一个布尔值变量chg来表示读数是否发生变化。不过只要我们认为这种变化发生在一瞬之间,就可以满足要求而不用这么麻烦了。

now的值在hr的变化间变化。正如之前的章节中,我们将连续变化的时钟显示抽象成离散的hr读数变化,同样我们也让now的值在离散的step中变化,一个behavior中,变量now以飞秒为单位递增,对于我们的时钟specification来说,就可以视作是对连续变化的时间的足够精确的描述了。事实上,也没有必要指定任何特定的时间粒度,我们随时可以在hr读数变化之间让now以任意精度递增。(在很多step中hr读数不变而只有now值变化,如果now值改变过大,如远超3600秒,这种behavior不符合读数正确的需求,可以排除)。

时钟需要满足什么样的real-time条件呢?我们可以要求它在特定的ρ秒(ρ是一个实数)内改变正确就可以了。不过对一些要求精准的系统来说,这不是一个传统意义上的real-time需求。 实际上,我们只需要hr在每隔近似1小时变化就行了。更精确一点,我们需要的间隔是 1小时 ± ρ秒(其中ρ为正实数)。显然,这个需求允许时钟显示有一点时间偏差,实际上真实的时钟如果不reset的话也是会有一点偏差的。

下面我们将一点点构建real-time clock specification。

首先我们仍然希望新的real-time clock specification能满足第2章引入的HC specification,期待能只加入一个额外的real-time需求即可。所以,我们在image.png加入一个新Formula约束: 时钟在1小时 ± ρ秒变化一次。这个Formula 是两个独立条件的联合: hr读数改变最早发生在上次变化之后的3600 - ρ秒,最迟在上次变化之后的3600 + ρ秒。

为了满足这些条件,我们引入一个变量t(for timer)来记录从上次读数变化到现在为止过去了多少秒。t在每次hr读数变化的那个step中被重置为0, 我们将这个step叫做HCnxt step,接下来的step如果过了s秒,t就被置为t + s。 now的值发生了改变的 step被视为一个TNext step,这个step表示过去了 s = now’ - now 秒钟。 所以, timer t的变化可以用下面的 action 表示:

 image.png

我们让t初始化为0,可以认为其初始state为hr读数刚好变化过的state。因此timer specification可以用下列Formula 表示: t初始化为0,每一步都是一个TNext step或者其他相关变量都不变(t,hr,now):

 image.png

hr读数最迟3600 + ρ秒必须改变一次的需求可以翻译成:距离上个HCnxt step最多过去了3600 + ρ秒。既然t一直等于从上个读数改变之后过去的时间,那么这个约束可以表示成:

 image.png

(既然我们不能更精确的描述时间,所以在上述Formula 中用< 或 ≤都没有关系,方便起见用≤)。

hr读数最早3600 - ρ 秒变化一次的需求可以翻译成:不管HCnxt step什么时候发生,这个step距离上一个HCnxt step最少已经过去了3600 - ρ 秒,因此这个约束可以表示成

 image.png

上述不是一个合法的TLA+ Formula。一个TLA+ Formula 断言一个aciton永远为真的话需要用这种形式:image.png, 我们不需要关心hr不变的step,所以我们可以将上述式子表示成:

image.png

由上所述,我们需要的real-time clock specification可以用上述3个Formula 的交集来表示:

image.png

Formula HCTime包含了变量t,而real-time clock specification只需要涉及到hr(时钟读数)和now(时间)两个变量。我们需要隐藏t,在TLA+中隐藏某个变量,可以使用符号image.png,尽管如此,我们不能简单写成image.png, 我们需要在定义HCTime的module中声明t, 之后使用参数化初始化这个module。实际操作中,我们在RealTimeHourClock中定义一个子模块,名字叫Inner,在其中定义HCTime并申明变量t。 注意到其他所有的符号都在主module中声明和定义,这些符号也都可以在内嵌的子模块中使用。子模块Inner可以在主module中用下列语句初始化:image.png, 之后HCTime中的t就可以用后续式子隐藏:image.png

image.png描述hr可能的变化并关联这些变化到now。 但是上述公式并没有描述now是如何变化的。 举个例子,下面这样的behavior也是满足这个Formula的:

image.png

因为时间不能倒退,上述behavior没有实际的物理意义。但如果我们specification的目的只是描述时钟读数变化,因为每个人都知道时间只能递增,因此也没有必要禁止这种behavior。尽管如此,一个specification还是应该合理的描述一个系统。如果hr读数持续大约每小时变化一次,它不会停止。但是上面描述的behavior,Formula image.png是允许时钟停止的。为了确保时钟不会停止,我们需要描述now是如何变化的。

我们引入一个新的Formula RTnow来表示now的可能变化。 这个Formula 不需要指定now的变化单位,它允许now在每一步增加一个微秒或者一个世纪。尽管如此,我们还是约定在step中,如果hr变化,now必须保持不变;now变的话,则hr保持不变。 因此,描述now变化的Formula 可以表示为如下的action,其中Real表示实数集合。

image.png

Formula RTnow也容许now保持不变,初始时now可以为任意值(符合系统起始的真实情况),所以RTnow的Formula 可以表示成:

image.png

我们需要的liveness条件是now可以无上限的增长,但简单满足weak fairness条件的NowNext action不满足要求,可以找到下面的反例:

image.png

上述behavior,now值有上限1.  因此我们还需要引入一个限制:image.png这样,无论如何,最终会出现一个NowNext step, now 取值大于任意指定的实数r。(这个action是一直使能的,所以weak fairness implies会有无限个满足要求的aciton出现)。

最终的real-time clock specification如下:

TLA+ 《Specifying Systems》翻译初稿——Chapter 9 Real Time Section 1 The Hour Clock Revisited_第1张图片

 

你可能感兴趣的:(TLA+)