我正在尝试在以下 Promela模型上正式验证互斥:
/* Mutex with (bugged) Peterson algorithm */
bool flag[2];
int turn = -1;
active [2] proctype agent() {
bool in_cs;
int other = 1 - _pid;
do
:: true ->
/* trying section */
turn = other;
flag[_pid] = true;
!( flag[other] && (turn == other));
/* critical section */
in_cs = true;
printf("Agent %d in CS\n", _pid);
in_cs = false;
/* exit section */
flag[_pid] = false;
od;
}
ltl mutex { [] ! (agent[0]:in_cs && agent[1]:in_cs) }
为了验证它,我使用以下命令链:
~$ spin -a test.pml ; gcc -o run pan.c -DNOREDUCE ; ./run -a -N p1
打印以下输出:
...
Full statespace search for:
never claim + (mutex)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 40 byte, depth reached 53, errors: 0
...
问:我知道 Promela模型不满足互斥这一事实,但Spin
声称它确实。为什么?
注意:我在使用-DNOREDUCE
进行编译时添加了选项gcc
,因为Spin 6.4.8
会打印一条警告消息,要求我这样做,如果我不这样做的话:
~$ spin -a test.pml ; gcc -o run pan.c ; ./run -a -N p1
...
pan.c: In function ‘main’:
pan.c:9478:3: warning: #warning p.o. reduction not compatible with remote varrefs (use -DNOREDUCE) [-Wcpp]
#warning p.o. reduction not compatible with remote varrefs (use -DNOREDUCE)
^~~~~~~
...
答案 0 :(得分:0)
以下是解决方案:
这里的问题是禁用部分订单减少 只需要使用
-DNOREDUCE
进行编译,同时也可以生成模型 禁用语句合并(合并后续本地操作) - 这也是一种部分订单减少策略。所以,对于第二个 例如,如果你这样做,你也会得到反例:spin -o3 -a test.pml; gcc -DNOREDUCE -o pan pan.c; ./pan -a
[G。 H.,私人通讯]
建议的解决方案的输出符合我们的预期:
~$ spin -o3 -a test.pml ; gcc -o run pan.c -DNOREDUCE ; ./run -a -N p1
...
pan:1: assertion violated !( !( !((agent[0].in_cs&&agent[1].in_cs)))) (at depth 55)
pan: wrote test.pml.trail
...
Full statespace search for:
never claim + (mutex)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 40 byte, depth reached 69, errors: 1
...
或者,可以通过使用标签远程引用而不是可变远程引用来解决问题,例如:
/* Mutex with (bugged) Peterson algorithm */
bool flag[2];
int turn = -1;
active [2] proctype agent() {
int other = 1 - _pid;
do
:: true ->
/* trying section */
turn = other;
flag[_pid] = true;
!( flag[other] && (turn == other));
/* critical section */
cs:
printf("Agent %d in CS\n", _pid);
/* exit section */
flag[_pid] = false;
od;
}
ltl mutex { [] ! (agent[0]@cs && agent[1]@cs) }
使用此模型,我们找到了一个反例,正如预期的那样:
~$ spin -search test.pml
...
pan:1: assertion violated !( !( !(((agent[0]._p==cs)&&(agent[1]._p==cs))))) (at depth 28)
pan: wrote test.pml.trail
...