自旋验证与通道相关的属性
Spin verifying properties related to channels
我在 Spin 中创建了一个简单的模型,其中两个进程 S 向另一个进程 R 发送消息。然后进程 R 向两个进程发送响应。我想定义 属性 "if process x sends a message, then process y eventually receives it",如下所示。问题在于,尽管模拟按预期工作,但验证并非如此。我在第 9 行定义的 属性 总是没有错误地通过,尽管我在第 17 行注入了一个应该使验证失败的错误。我在这里错过了什么吗?
1 byte r1PId;
2 byte s1PId;
3 byte s2PId;
4
5 byte nextM = 1;
6
7 chan toS[2] = [2] of {byte};
8
9 ltl p1 {[] ((s[s1PId]:m > 0) -> <>(s[s1PId]:m == r:m))}
10
11 proctype r(byte id; chan stoR)
12 {
13 do
14 :: true
15 byte c; byte m; byte m2;
16 stoR?c, m2;
17 m = 67; //should be m = m2
18
19 byte response = 50;
20
21 toS[c]!response;
22 od
23 }
24
25 proctype s(byte id; chan rtoS; chan stoR)
26 {
27 byte m;
28 atomic
29 {
30 m = nextM;
31 nextM = nextM+1;
32 }
33 stoR!id, m;
34 byte response;
35 rtoS?response;
36 }
37
38 init{
39 chan toR = [10] of {byte, byte};
40 r1PId = run r(10, toR);
41 s1PId = run s(0, toS[0], toR);
42 s2PId = run s(1, toS[1], toR);
43 }
似乎是范围问题。当进程 s
终止时,其局部变量将超出范围。在这种情况下,引用 s[s1PId]:m
将是 0
.
另一方面,在进程r
中,变量m
被声明在内部块中。每次在stoR?c, m2
之前初始化为0
。
因此,引用 r:m
将在收到两次消息后始终为 0
。
所以,<>(s[s1PId]:m == r:m)
将永远是 true
。
要快速修复此问题,您可以 (i) 将 r
中的声明 byte m
移到循环外;或 (ii) 在 s
中添加一个无限循环以防止其终止。
我在 Spin 中创建了一个简单的模型,其中两个进程 S 向另一个进程 R 发送消息。然后进程 R 向两个进程发送响应。我想定义 属性 "if process x sends a message, then process y eventually receives it",如下所示。问题在于,尽管模拟按预期工作,但验证并非如此。我在第 9 行定义的 属性 总是没有错误地通过,尽管我在第 17 行注入了一个应该使验证失败的错误。我在这里错过了什么吗?
1 byte r1PId;
2 byte s1PId;
3 byte s2PId;
4
5 byte nextM = 1;
6
7 chan toS[2] = [2] of {byte};
8
9 ltl p1 {[] ((s[s1PId]:m > 0) -> <>(s[s1PId]:m == r:m))}
10
11 proctype r(byte id; chan stoR)
12 {
13 do
14 :: true
15 byte c; byte m; byte m2;
16 stoR?c, m2;
17 m = 67; //should be m = m2
18
19 byte response = 50;
20
21 toS[c]!response;
22 od
23 }
24
25 proctype s(byte id; chan rtoS; chan stoR)
26 {
27 byte m;
28 atomic
29 {
30 m = nextM;
31 nextM = nextM+1;
32 }
33 stoR!id, m;
34 byte response;
35 rtoS?response;
36 }
37
38 init{
39 chan toR = [10] of {byte, byte};
40 r1PId = run r(10, toR);
41 s1PId = run s(0, toS[0], toR);
42 s2PId = run s(1, toS[1], toR);
43 }
似乎是范围问题。当进程 s
终止时,其局部变量将超出范围。在这种情况下,引用 s[s1PId]:m
将是 0
.
另一方面,在进程r
中,变量m
被声明在内部块中。每次在stoR?c, m2
之前初始化为0
。
因此,引用 r:m
将在收到两次消息后始终为 0
。
所以,<>(s[s1PId]:m == r:m)
将永远是 true
。
要快速修复此问题,您可以 (i) 将 r
中的声明 byte m
移到循环外;或 (ii) 在 s
中添加一个无限循环以防止其终止。