LTL公式的一般结构
如果某个语句ptrue
处于状态i,那么某个语句q处于下一个状态,即状态i+1true
是以下一个:
ltl p0 { [] (p -> X q) }
该公式p -> X q
通过以下方式验证
- 任何状态S i st
p
在S ifalse
- 任何状态S i st
p
都true
在S iq
中并且true
在S i+1中,其中S i+1是当前正在评估的执行路径中S i的后继状态
全局运算符[]
需要使模型检查器验证条件是否p -> X q
适用于执行路径中的任何状态。如果您省略它,则p -> X q
仅检查该属性的初始状态,这在99.99%的情况下不是您想要的。
例子
在下面的模型中,如果cc
是偶数,则进程计数器将其加一,否则进程要么终止,要么cc
以不确定的方式减一。
我们要检查的属性是,每当计数器达到给定的检查点状态并且cc
是偶数时,恰好在 2 次转换之后cc
是奇数。
byte cc = 0;
active proctype counter()
{
checkpoint:
do
:: cc % 2 == 0 -> cc++;
:: else ->
if
:: cc--;
:: break;
fi;
od;
}
#define even ( cc % 2 == 0 )
#define odd ( cc % 2 == 1 )
ltl p0 { [] ( (counter[0]@checkpoint & even) -> X X odd) }
ltl 属性p0
已验证:
~$ spin -a test.pml
~$ gcc -DNXT -DNOREDUCE -o run pan.c
~$ ./run -a
(Spin Version 6.4.3 -- 16 December 2014)
Full statespace search for:
never claim + (p0)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 28 byte, depth reached 11, errors: 0
8 states, stored (10 visited)
2 states, matched
12 transitions (= visited+matched)
0 atomic steps
hash conflicts: 0 (resolved)
Stats on memory usage (in Megabytes):
0.000 equivalent memory usage for states (stored*(State-vector + overhead))
0.289 actual memory usage for states
128.000 memory used for hash table (-w24)
0.534 memory used for DFS stack (-m10000)
128.730 total actual memory usage
unreached in proctype counter
(0 of 11 states)
unreached in claim p0
_spin_nvr.tmp:16, state 20, "-end-"
(1 of 20 states)
pan: elapsed time 0 seconds
注意事项:
在这个例子中,标签 checkpoint:
的使用是完全可选的。使用ltl 公式 可以获得相同的结果{ [] ( even -> X X odd) }
。但是,标签在具有 结构的公式的上下文中经常使用[] (p -> X g)
,所以我认为在我的示例中插入一个带有一些空的借口的标签会很有用。
我通常更喜欢较弱的F odd
条件而不是更强的语句X X odd
,除非由于要验证的属性的性质而不可能/不建议这样做。事实上,对于Spin来说,一眼就能猜出从一个语句到另一个语句发生了多少次转换,因为AFAIK模型通常会经历许多优化以相互删除/合并状态。