这些天,我已经开始学习NuSMV。我有以下代码:
SELECT code, MAX(start_date)
FROM movies
GROUP BY code
我想验证每次我们处于状态“ a”时,下一个状态将是状态“ b”。哪一个是正确的(即使我尝试了它们两个并且它们都给了我两个都是真的):
MODULE main
VAR
state: {a,b,c,d,e};
ASSIGN
init(state) := a;
next(state) := case
(state = a) : b;
(state = b) : c;
(state = c) : d;
(state = d) : e;
TRUE:Stages;
esac;
我的第二个问题是:在上面的模型中,没有从状态“ d”到状态“ a”的过渡,但是当我使用
进行验证时check_ctlspec -p "AG (state=a -> AX state=b)"
check_ctlspec -p "AF (state=a -> AX state=b)"
check_ctlspec -p "AF (state=a -> AF state=b)"
check_ctlspec -p "AF (state=a -> state=b)"
结果是正确的。为什么会这样?
答案 0 :(得分:0)
首先,让我在模型中将state
重命名为my_var
。这样可以避免将自动机的实际状态与您引入的state
变量混淆。
AG (my_var = a -> AX my_var = b)
在每个可能执行的每种状态下,如果
my_var
等于a
,那么在下一个状态my_var
等于b
的情况下必然是必须的
此 是您要验证的属性。
AF (my_var=a -> AX my_var=b)
或早或晚,如果
my_var
等于a
,那么在下一状态my_var
等于b
的情况下必然是必须的。
请注意,在两种情况下,隐含为 true :
因此,对于不验证前提my_var=a
的任何状态(即初始状态以外的任何状态),隐含意义都是成立的。由于您使用AF
,因此您只需要针对每个可能的执行路径在(至少)一个状态下验证含义。
从某种意义上说,对于您要验证的内容来说,这是“太弱了” 。
AF (my_var=a -> AF my_var=b)
迟早,如果
my_var
等于a
,那么将来的某个时候一定是这种情况(写成my_var
等于{ {1}})a
等于my_var
。
与上一个相似,它甚至更弱,因为它甚至没有指定b
在什么时候等于my_var
。
b
请注意,仅当AF (my_var=a -> my_var=b)
为假时,含义(my_var=a -> my_var=b)
才为true,因为不能同时将my_var=a
和my_var
分配给a
。但是,此条件可以通过初始状态以外的任何其他状态进行验证,因此再次对该属性进行了简单验证。
b
同样,这种情况太弱了,因为您使用的是AF (my_var=d -> AX my_var=a)
而不是AF
。对于AG
的任何状态,这种含义都是正确的,因此足以验证整个属性。
我邀请您查看stack-overflow Q/A或these slides,以了解有关该工具和语言的更多信息。