可疑地使用'else'结合i / o,看到';' 'if'附近

时间:2014-02-22 14:09:01

标签: multithreading model-checking spin promela

以下是导致此问题的代码。

        if 
            :: ((fromProc[0] == MSG_SLEEP) && nempty(proc2clk[0])) -> 
              proc2clk[0] ? fromProc[0]; // Woke up
            :: (!(fromProc[0] == MSG_SLEEP) && !(fromProc[0] == MSG_FIN)) ->
              clk2proc[0] ! 0;  
            ::else -> 
              time = time + 1; // just for debugging
        fi; 

如果我在第一个条件中删除 nempty ,则错误消失。根据我的阅读,你不能使用else语句,如果你在条件中使用接收或发送语句,但据我所知, nempty 不是发送或接收语句,但是只是为了检查通道是否为空。那么,我在做什么错,我该怎么解决呢。

1 个答案:

答案 0 :(得分:8)

发生这种情况的原因是因为Spin编译器将else转换为所有if选项的否定,然后,因为您的一个选项有nempty(),翻译的{{ 1}}最终会被禁止if。例如:

!nempty()

被翻译为

if
:: (p1) -> …
:: (p2) -> … 
:: else -> … 
if

if :: (p1) -> … :: (p2) -> … :: (!p1 && !p2) -> … if p1包含p2full()nfull()empty() nempty()的任何内容时!p1!p1将否定其中一个队列满/空谓词。做这种否定是违法的。有关这些谓词的文档,请访问www.spinroot.com。

解决方案是自己进行else翻译,然后当你看到否定时用匹配的谓词替换它。例如,如果您想要:

if
:: a == b && nempty(q) -> …
:: else
fi

然后将else替换为(正在解决):

!(a==b &&  nempty(q))   => DeMorgan's Laws
 (a!=b || !nempty(q))   
 (a!=b ||  empty(q))

因此!nempty()不再存在于最终的“手动”翻译中:

if
:: a == b && nempty(q) -> …
:: a != b ||  empty(q))-> …
fi

如果你的案例有多个复杂的选项,那么else的“手动”翻译就容易出错。但是,这就是你需要做的。