使用 TLA+(动作的时间逻辑)指定多个步骤
Specifying multiple steps using TLA+ (Temporal Logic of Actions)
浏览 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)”。所以基本上,上面的函数设置了一些变量 "in the next state" .但是这一切本质上是一步到位的(至少在逻辑上是这样)
我想知道如何定义在多个步骤中发生的事情。说10步。
UpdateWithTenSteps(self) ==
/\ foo' = foo + 1
/\ bar'' = foo' + 1
/\ baz''' = bar'' + 1
/\ ...
....
所以"in the third state ahead of now, baz will be set to bar in the second state plus one."。像那样的东西。但这并没有什么意义。在命令式语言中,您只需执行以下操作:
function updateInTenSteps() {
incFoo()
incBar()
incBaz()
}
但这是有道理的,因为每个函数调用都发生在前一个函数调用之后。但是我不知道如何在 TLA+ 中表示它。
想知道在 Temporal Logic of Actions+ 中您应该如何完成需要多个步骤的事情。另一个例子是 while 循环。
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>>
如果您为此创建一个模型,设置由 Init
和 Next
定义的行为,然后检查不变量 baz = 0
,您将得到一条显示您的轨迹导致 baz 改变的状态(你的最后一个任务)。循环只是将后继标签分配为已经发生的标签(例如,而不是定义 baz' = "foo"
)。
Pluscal 转换为 TLA 的工作原理类似:每个标记的行都对应一个 id,从第 l 行到第 m 行的每个转换都会将下一状态的程序计数器从 l 更改为 m。
浏览 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)”。所以基本上,上面的函数设置了一些变量 "in the next state" .但是这一切本质上是一步到位的(至少在逻辑上是这样)
我想知道如何定义在多个步骤中发生的事情。说10步。
UpdateWithTenSteps(self) ==
/\ foo' = foo + 1
/\ bar'' = foo' + 1
/\ baz''' = bar'' + 1
/\ ...
....
所以"in the third state ahead of now, baz will be set to bar in the second state plus one."。像那样的东西。但这并没有什么意义。在命令式语言中,您只需执行以下操作:
function updateInTenSteps() {
incFoo()
incBar()
incBaz()
}
但这是有道理的,因为每个函数调用都发生在前一个函数调用之后。但是我不知道如何在 TLA+ 中表示它。
想知道在 Temporal Logic of Actions+ 中您应该如何完成需要多个步骤的事情。另一个例子是 while 循环。
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>>
如果您为此创建一个模型,设置由 Init
和 Next
定义的行为,然后检查不变量 baz = 0
,您将得到一条显示您的轨迹导致 baz 改变的状态(你的最后一个任务)。循环只是将后继标签分配为已经发生的标签(例如,而不是定义 baz' = "foo"
)。
Pluscal 转换为 TLA 的工作原理类似:每个标记的行都对应一个 id,从第 l 行到第 m 行的每个转换都会将下一状态的程序计数器从 l 更改为 m。