The general structure of an LTL formula for which
if some statement p is true
in statei, then some statement q is true
in the next state, statei+1
is the following one:
ltl p0 { [] (p -> X q) }
The formula p -> X q
is verified by
- any state Si s.t.
p
is false
in Si
- any state Si s.t.
p
is true
in Si and q
is true
in Si+1, where Si+1 is the successor of Si in the execution path currently being evaluated
The globally operator []
is required to make the Model Checker verify that the condition p -> X q
holds for any state in the execution path. If you omit it, then the property p -> X q
is only be checked for the initial state, which in the 99.99% of cases is not what you want.
EXAMPLE
In the following model, if cc
is even then process counter increases it by one, otherwise the process either terminates or decreases cc
by one in a non-deterministic fashion.
The property that we want to check is that, whenever counter reaches a given checkpoint state and cc
is even, after exactly 2 transitions cc
is odd.
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) }
The ltl property p0
is verified:
~$ 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
Things to note:
in this example, the use of the label checkpoint:
is completely optional. The same result could have been obtained using the ltl formula { [] ( even -> X X odd) }
. However, labels are quite frequently used in the context of formulas with the structure [] (p -> X g)
, so I thought it would be useful to push one inside my example with some empty pretext.
I would normally prefer the weaker F odd
condition to the stronger statement X X odd
, unless that isn't possible/advisable due to the nature of the property being verified. In fact, with Spin it is not easy to guess with a single glance how many transitions occur from one statement to the other, since AFAIK the model normally undergoes a number of optimisations to remove/merge states with one another.