使用TLA +(动作的时间逻辑)指定多个步骤

时间:2019-03-01 13:48:04

标签: logic specifications tla+

浏览here主要显示了操作规范的简单示例,其中您使用'引用下一个状态,如:

UponV1(self) ==                                 
  /\ pc[self] = "V1"                        
  /\ pc' = [pc EXCEPT ![self] = "AC"]       
  /\ sent' = sent \cup { <<self, "ECHO">> } 
  /\ nCrashed' = nCrashed
  /\ Corr' = Corr

例如,/\ nCrashed' = nCrashed是一个逻辑语句,它表示“ ... AND next(nCrashed)== this(nCrashed)`。因此,基本上,上述函数在“下一个状态”中设置了一些变量。但是,所有这些步骤基本上(至少在逻辑上)是一步完成的。

我想知道的是如何定义在多个步骤中发生的事情。说10个步骤。

UpdateWithTenSteps(self) ==                                 
  /\ foo' = foo + 1
  /\ bar'' = foo' + 1
  /\ baz''' = bar'' + 1
  /\ ...
  ....

因此“在现在的第三个状态下,将baz设置为第二个状态下的bar加一。”。这样的事情。但这真的没有道理。用命令式语言,您只需要执行以下操作:

function updateInTenSteps() {
  incFoo()
  incBar()
  incBaz()
}

但这很有意义,因为每个函数调用都发生在前一个函数之后。但是我看不到如何在TLA +中表示这一点。

想知道您应该如何完成在《行动的时空逻辑》中采取不止一个步骤的事情。另一个示例是while循环。

1 个答案:

答案 0 :(得分:0)

TLA被设计为仅考虑当前状态和后继状态(或整个行为)。您总是可以通过引入一个显式变量来告诉彼此已经完成的多个步骤,以相互依赖:

EXTENDS Naturals

Labels == { "foo", "bar", "baz", "fin" } (* just for documentation purposes *)
VARIABLE currstate, foo, baz, bar

Init == /\ currstate = "foo"
        /\ foo = 0
        /\ bar = 0
        /\ baz = 0

Next == \/ (currstate = "foo" /\ currstate' = "bar" /\ foo' = foo +1 /\ UNCHANGED <<bar,baz>>)       
        \/ (currstate = "bar" /\ currstate' = "baz" /\ bar' = foo +1 /\ UNCHANGED <<foo,baz>>)
        \/ (currstate = "baz" /\ currstate' = "fin" /\ baz' = bar +1 /\ UNCHANGED <<foo,bar>>)
        \/ (currstate = "fin" /\ UNCHANGED <<foo,bar,baz,currstate>>

如果为此创建一个模型,设置InitNext定义的行为,然后检查不变的baz = 0,您将得到一条跟踪,向您显示状态导致baz(您的上一个作业)发生变化。循环只会将后继标签分配为已经发生的标签(例如,而不是定义baz' = "foo")。

Pluscal转换为TLA的工作方式相似:每个标记行对应一个id,从l行到m行的每个转换都将在下一个状态下将程序计数器从l更改为m。