model-checking - 模型检查:为什么 LTL 逻辑“<>”在 Spin 中没有产生正确的反例
问题描述
更新
我之前的尝试有两个问题。通过修复它们,我成功地得到了预期的答案。
-f
使用命令行选项指定的 LTL将被否定。相反,我通过添加ltl { <> p}
到 Promela 程序中来使用内联 LTL。其次,在执行时
pan
,似乎我们需要使用-a
“寻找接受周期”。我不完全确定这意味着什么,我的猜测是 Spin 将尝试识别无限的时间表。
原始问题
我是模型检查和旋转的新手。我在以下示例中遇到问题。
在我的情况下,我指定了
'<> p'
每个时间表最终都会导致的声明p
SUM > BOUND
在我的理解中,如果存在
p
一个总是错误的无限时间表,在我的情况下SUM
总是小于或等于BOUND
,spin 将报告它作为一个反例。但是,当我运行 spin 时,我得到的反例
p
是正确的。
具体而言,命令、Promela 代码和跟踪如下。
在这条线索中,结果是p
满意的,因为SUM
确实大于BOUND
。我不明白为什么 Spin 给我一个满足的反例p
?
./spin649_linux64 -f '<> p' -a sample.pml
gcc -o pan pan.c
./pan -i
./spin649_linux64 -p -t sample.pml
#define UPDATE(c) if :: ch[c]>sz[c] -> sz[c] = ch[c] :: else fi
#define PRODUCE(c, n) ch[c] = ch[c] + n; UPDATE(c)
#define CONSUME(c, n) ch[c] = ch[c] - n
#define WAIT(c, n) ch[c] >= n
int ch[2]; int sz[2];
#define BOUND 6
#define SUM (sz[0] + sz[1])
#define p (SUM > BOUND)
// Actor_a <==1==> Actor_b <==2==> Actor_c
// Actor_a produces 2 tokens to channel 1
// Actor_b consumes 3 tokens from channel 1 and produces 1 token to channel 2
// Actor_c consumes 2 tokens from channel 2
// sz[i] records the highest capacity seen for channel[i]
// There exist an infinite schedule that sz[0] + sz[1] is at most 6 at any moment
proctype Actor_a() {
do
:: atomic{ PRODUCE(0, 2); printf("a")}
od
}
proctype Actor_b() {
do :: atomic { WAIT(0,3) -> CONSUME(0, 3); PRODUCE(1, 1); printf("b") }
od
}
proctype Actor_c() {
do :: atomic {WAIT(1, 2) -> CONSUME(1, 2); printf("c")}
od
}
init {
atomic {
run Actor_a();
run Actor_b();
run Actor_c();
}
}
starting claim 4
spin: couldn't find claim 4 (ignored)
Starting Actor_a with pid 2
2: proc 0 (:init::1) sample.pml:30 (state 1) [(run Actor_a())]
Starting Actor_b with pid 3
3: proc 0 (:init::1) sample.pml:31 (state 2) [(run Actor_b())]
Starting Actor_c with pid 4
4: proc 0 (:init::1) sample.pml:32 (state 3) [(run Actor_c())]
6: proc 1 (Actor_a:1) sample.pml:14 (state 1) [ch[0] = (ch[0]+2)]
7: proc 1 (Actor_a:1) sample.pml:14 (state 2) [((ch[0]>sz[0]))]
7: proc 1 (Actor_a:1) sample.pml:14 (state 3) [sz[0] = ch[0]]
a 7: proc 1 (Actor_a:1) sample.pml:14 (state 7) [printf('a')]
9: proc 1 (Actor_a:1) sample.pml:14 (state 1) [ch[0] = (ch[0]+2)]
10: proc 1 (Actor_a:1) sample.pml:14 (state 2) [((ch[0]>sz[0]))]
10: proc 1 (Actor_a:1) sample.pml:14 (state 3) [sz[0] = ch[0]]
a 10: proc 1 (Actor_a:1) sample.pml:14 (state 7) [printf('a')]
12: proc 1 (Actor_a:1) sample.pml:14 (state 1) [ch[0] = (ch[0]+2)]
13: proc 1 (Actor_a:1) sample.pml:14 (state 2) [((ch[0]>sz[0]))]
13: proc 1 (Actor_a:1) sample.pml:14 (state 3) [sz[0] = ch[0]]
a 13: proc 1 (Actor_a:1) sample.pml:14 (state 7) [printf('a')]
15: proc 1 (Actor_a:1) sample.pml:14 (state 1) [ch[0] = (ch[0]+2)]
16: proc 1 (Actor_a:1) sample.pml:14 (state 2) [((ch[0]>sz[0]))]
16: proc 1 (Actor_a:1) sample.pml:14 (state 3) [sz[0] = ch[0]]
a 16: proc 1 (Actor_a:1) sample.pml:14 (state 7) [printf('a')]
spin: trail ends after 17 steps
#processes: 4
ch[0] = 8
ch[1] = 0
sz[0] = 8
sz[1] = 0
17: proc 3 (Actor_c:1) sample.pml:24 (state 5)
17: proc 2 (Actor_b:1) sample.pml:19 (state 11)
17: proc 1 (Actor_a:1) sample.pml:13 (state 9)
17: proc 0 (:init::1) sample.pml:34 (state 5) <valid end state>
4 processes created
如果您能提供帮助,非常感谢!
解决方案
最初的尝试有两个问题。通过修复它们,我成功地得到了预期的答案。
从命令行使用 -f 选项指定的 LTL 将被否定。相反,我通过将 ltl { <> p} 添加到 Promela 程序中来使用内联 LTL。
其次,在执行 pan 时,似乎我们需要使用 -a 来“查找接受周期”。我不完全确定这意味着什么,我的猜测是 Spin 将尝试识别无限的时间表。
推荐阅读
- java - Java中的Hangman游戏猜错了
- php - Laravel - 雄辩的关系不起作用
- tsql - TSQL 从 1 对 N 关系多次更新同一行
- c++ - 一个同时接受 std::vector 和 QVector 的函数模板?
- html - Karma 在 chrome 中启动和关闭自身
- go - 在 TFS 构建创建中找不到 Go 语言模板
- python - Python:识别按下了哪些键,处理所有按下的键,然后打印结果
- ocaml - OCaml 中的语法:修改后传递数组
- python - Python Pytest 解压夹具
- python-3.x - Tensorflow 和 Keras 中的相同(?)神经网络架构在相同数据上产生不同的准确性