Reputation: 1274
I'm running spin in validation mode with the code like below. Got a problem with function called 'never'. While execution it gives me an error that functions inc(), dec() and reset() have never been accomplished. But if i add a cycle, it works great. By documentation, 'never' checks the variables on every step. So, why it does not work without a cycle?
int x=0
proctype Inc(){
do
::true ->
if
::x<10->x=x+1
fi
od
}
proctype Dec(){
do
::true ->
if
::x>0->x=x-1
fi
od
}
proctype Reset(){
do
::true ->
if
::x==10->x=0
fi
od
}
never { // if I need this to work, i have to add
To_Init: // this line
if
:: (x<0) || (10<x) -> goto accept
:: else -> goto To_Init // and that line
fi;
accept:
}
init{
run Inc();
run Dec();
run Reset();
}
'Never' block, that gives me a warning
never {
if
:: (x<0) || (10<x) -> goto accept
fi;
accept:
}
actually, thats not an error, that's kind of warning, shows unreached in proctype Inc, Dec, Reset, Init. Full warning log is below.
warning: for p.o. reduction to be valid the never claim must be stutter-invariant
(never claims generated from LTL formulae are stutter-invariant)
(Spin Version 6.2.7 — 2 March 2014)
+ Partial Order Reduction
Full statespace search for:
never claim + (never_0)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 28 byte, depth reached 0, errors: 0
1 states, stored
0 states, matched
1 transitions (= stored+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 Inc
l31never-no-cycle:6, state 3, "x = (x+1)"
l31never-no-cycle:6, state 4, "((x<10))"
l31never-no-cycle:4, state 6, "(1)"
l31never-no-cycle:9, state 9, "-end-"
(4 of 9 states)
unreached in proctype Dec
l31never-no-cycle:15, state 3, "x = (x-1)"
l31never-no-cycle:15, state 4, "((x>0))"
l31never-no-cycle:13, state 6, "(1)"
l31never-no-cycle:18, state 9, "-end-"
(4 of 9 states)
unreached in proctype Reset
l31never-no-cycle:24, state 3, "x = 0"
l31never-no-cycle:24, state 4, "((x==10))"
l31never-no-cycle:22, state 6, "(1)"
l31never-no-cycle:27, state 9, "-end-"
(4 of 9 states)
unreached in claim never_0
l31never-no-cycle:35, state 6, "-end-"
(1 of 6 states)
unreached in init
l31never-no-cycle:39, state 2, "(run Dec())"
l31never-no-cycle:40, state 3, "(run Reset())"
l31never-no-cycle:41, state 4, "-end-"
(3 of 4 states)
Upvotes: 1
Views: 2338
Reputation: 70135
A never
claim reports an error in two case: 1) an 'accept' cycle is detected, or 2) the never claim completes. A third possibility is if the never
claim cannot take a step; this third possibility is the one your code is producing
When your claim was:
never {
if
:: (x<0) || (10<x) -> goto accept
fi;
accept:
}
the initial state has no possible step. That is, the never
claim start state is just before the if
; from that state where x==0
there is no possible next step.
When there is no possible step in a never
claim, the verifier backtracks to a state where a step can be taken. In your case, there is no place to back up to and your verification ends because there is nothing more to do. The verifier then notes that lots of code didn't execute (because, in fact, nothing executed in your model).
You can tell that this is not what you anticipated because of all the unexecuted code. But is it not reported as an error.
For your subsequent case, you added an else
. In this case the verifier can take a step in the never
claim and thus your verification proceeds.
Upvotes: 5