我有以下promela代码:
chan level = [0] of {int};
proctype Sensor (chan levelChan) {
int x;
do
:: true ->
levelChan ? x;
if
:: (x < 2) -> printf("low %d", x);
:: (x > 8) -> printf("high %d", x);
:: else -> printf("normal %d", x);
fi
od
}
init {
run Sensor(level);
int lvl = 5;
level ! lvl;
lvl = 0;
do
:: true ->
level ! lvl;
lvl++;
(lvl > 9) -> break;
od
}
我期望将电平(0-9)信息发送到通道,并根据该电平使传感器输出低|正常|高。它很简单。但是为什么SPIN一直在说它的超时?
0: proc - (:root:) creates proc 0 (:init:)
Starting Sensor with pid 1
1: proc 0 (:init:) creates proc 1 (Sensor)
1: proc 0 (:init:) 1.pml:18 (state 1) [(run Sensor(level))]
2: proc 1 (Sensor) 1.pml:6 (state 11) [(1)]
3: proc 0 (:init:) 1.pml:20 (state 2) [lvl = 5]
4: proc 0 (:init:) 1.pml:20 (state 3) [level!lvl]
4: proc 1 (Sensor) 1.pml:8 (state 2) [levelChan?x]
5: proc 1 (Sensor) 1.pml:9 (state 9) [else]
6: proc 0 (:init:) 1.pml:21 (state 4) [lvl = 0]
normal 5 8: proc 1 (Sensor) 1.pml:12 (state 8) [printf('normal %d',x)]
9: proc 0 (:init:) 1.pml:22 (state 10) [(1)]
12: proc 1 (Sensor) 1.pml:6 (state 11) [(1)]
13: proc 0 (:init:) 1.pml:24 (state 6) [level!lvl]
13: proc 1 (Sensor) 1.pml:8 (state 2) [levelChan?x]
14: proc 1 (Sensor) 1.pml:9 (state 9) [((x<2))]
low 0 15: proc 1 (Sensor) 1.pml:10 (state 4) [printf('low %d',x)]
17: proc 0 (:init:) 1.pml:25 (state 7) [lvl = (lvl+1)]
19: proc 1 (Sensor) 1.pml:6 (state 11) [(1)]
timeout
#processes: 2
19: proc 1 (Sensor) 1.pml:8 (state 2)
19: proc 0 (:init:) 1.pml:26 (state 8)
2 processes created
似乎只做了1次迭代的do循环为什么?
答案 0 :(得分:3)
init
进程的do循环中的语句按顺序运行。
do
:: true ->
level ! lvl;
lvl++;
(lvl > 9) -> break;
od
第一次运行do循环时,它会在lvl
频道上发送level
,增加lvl
(现在为1),然后测试{{1} }。这是假的,因此会阻止并导致超时。
要在do循环中有多个选项,您需要(lvl > 9)
来定义每个选项的开头:
::
然而,这仍然无法按预期执行。当do
:: true ->
level ! lvl;
lvl++;
:: (lvl > 9) -> break;
od
大于9时,do循环的两个选项都是有效的,并且可以选择其中一个,因此当lvl
可以选择继续发送lvl > 9
时,循环不一定会中断在lvl
频道上方,增加level
。
您需要在第一个选项和第二个选项上有条件:
lvl
在此示例中使用for循环语法可能更好:
do
:: (lvl <= 9) ->
level ! lvl;
lvl++;
:: (lvl > 9) -> break;
od
请注意,此示例仍会因init {
run Sensor(level);
int lvl = 5;
level ! lvl;
for (lvl : 0..9){
level ! lvl;
}
}
的循环导致超时错误,当Sensor
进程完成时init
仍会尝试从{{1}读取通道和超时。