以下是导致此问题的代码。
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 不是发送或接收语句,但是只是为了检查通道是否为空。那么,我在做什么错,我该怎么解决呢。
答案 0 :(得分:8)
发生这种情况的原因是因为Spin编译器将else
转换为所有if
选项的否定,然后,因为您的一个选项有nempty()
,翻译的{{ 1}}最终会被禁止if
。例如:
!nempty()
被翻译为
if
:: (p1) -> …
:: (p2) -> …
:: else -> …
if
当if
:: (p1) -> …
:: (p2) -> …
:: (!p1 && !p2) -> …
if
或p1
包含p2
,full()
,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
的“手动”翻译就容易出错。但是,这就是你需要做的。