Error: Impossible to build a BDD FSM with infinite precision variables - nusmv

I just installed nuXmv and wanted to try out the example growing-counter-integer from the examples folder. When I try to run the command: build_model, I get the error message:
file growing-counter-integer.smv: line 30: Impossible to build a BDD FSM with infinite precision variables
Does somebody know how to fix this error? Thanks in advance.
growing-counter-integer.smv file:
MODULE main
VAR state : { s0, s1, s2, s3 };
VAR c : integer;
VAR lim : real;
ASSIGN
init(state) := s0;
next(state) :=
case
state = s0 : s1;
state = s1 : s2;
state = s2 & c < lim : s2;
state = s2 & c >= lim : s3;
state = s3 : s1;
TRUE : state;
esac;
init(c) := 0;
next(c) := (state = s2 & next(state) = s2)?(c+1):(0);
init(lim) := 2;
next(lim) := (state = s3 & next(state) = s1)?(lim + 1):(lim);
INVARSPEC c < 3;
INVARSPEC c < 4;
INVARSPEC c < 5;
INVARSPEC c < 6;
INVARSPEC c < 20;
LTLSPEC G F (state = s3);

When the input model contains some infinite-domain variable, like the real and integer types in your model, the end-user is supposed to use the MathSAT5 engine back-end instead of the regular approaches (like, e.g., those based on BDDs).
The commands based on MathSAT5 are easily identifiable in the nuXmv manual by the fact that they have the keyword msat in them. In this case, you are limited to invariant and LTL Bounded Model Checking. There are special commands also for simulating the system (i.e. msat_pick_state and msat_simulate).
After read_model -i <file.smv>, one would typically use the command go_msat and then select the appropriate approach for checking the given properties.
(slide taken from here)

Related

nuXmv how does it know in initial state that (AF p) & (AF w) is false

I have a question concerning nuXmv solution. I have a simple graph where the initial state is s1 and there are two arcs from s1, one leads to s2, the other to s3. From s2 and s3 there is one arc leading to s1. This is the program in nuXmv which describes the situaiton.
MODULE main
VAR
s : {s1, s2, s3};
p : boolean;
q : boolean;
w : boolean;
ASSIGN
init(s) := {s1};
next(s) := case
s = s1 : {s2, s3};
s = s2 : s1;
s = s3 : s1;
esac;
p := case
s = s2 : TRUE;
TRUE : FALSE;
esac;
q := case
s = s1 : TRUE;
TRUE : FALSE;
esac;
w := case
s = s3 : TRUE;
TRUE : FALSE;
esac;
CTLSPEC (AF p) & (AF w);
CTLSPEC AG (AF p) & AG (AF w);
I do not understand how nuXmv already in the initial state s1 knows that the formula is false. It does not give a counterexample based on the loop, just immediately in s1 it says that the formula is wrong based on s1.
My idea of explanation is that without justice assumptions nuXmv immediately assumes that one of the paths can be never executed. But should it not give a loop as an example? If I only left "CTLSPEC AF p;" nuXmv returns a loop as a counterexample. So why for "AF p & AF w" it only shows state s1 as counterexample?
-- specification (AF p & AF w) is false
-- as demonstrated by the following execution sequence
Trace Description: CTL Counterexample
Trace Type: Counterexample
-> State: 1.1 <-
s = s1
p = FALSE
q = TRUE
w = FALSE

Digicode in Nusmv

i am new with NUSMV i am trying to modelise a digicode for reconize 41708 but user can't do more 3 error.
if you enter more 3 error the system go to state bloked to wait when you enter special code to be unblocked.
it is my code if you cant help me with idea and suggest code to finish .
MODULE main
VAR
val1 : {0,1,2,3,4,5,6,7,8};
location : {E1,E2,E3,E4,E5,succes,blocked,unblocked,verified};
cpt : 0..3;
block : boolean;
NumberEnter : 0..5 ;
ASSIGN
init(cpt):=0;
init(block):=FALSE;
init(location):=E1;
next(location):= case
(location=E1) &(cpt!=3) & (block!=TRUE) :E2 ;
(location=E2) & (cpt!=3) & (block!=TRUE) :{E3,E1,blocked};
(location=E3) & (cpt!=3) & (block!=TRUE) :{E2,E1,blocked} ;
(location=E4) & (cpt!=3) & (block!=TRUE) :{E1,E5,blocked} ;
(location=E5) & (cpt!=3) & (block!=TRUE) :{E1,blocked} ;
TRUE:blocked;
esac;
next(pas):= case
NumberEnter<5 :NumberEnter+ 1 ;
TRUE:0;
esac;
Image of Model
One possible solution is:
MODULE main()
VAR
in_digit : 0 .. 9;
in_signal : boolean;
dc : digicode(in_digit, in_signal);
MODULE digicode(in_digit, in_signal)
VAR
state : { RUN, OK, ERROR };
idx : 0 .. 4;
counter : 0 .. 3;
DEFINE
pwd := [4, 1, 7, 0, 8];
INIT state = RUN & idx = 0 & counter = 0;
ASSIGN
next(state) := case
state = RUN & pwd[idx] = in_digit & idx < 4 : RUN;
state = RUN & pwd[idx] = in_digit : OK;
state = RUN & pwd[idx] != in_digit & counter < 3 : RUN;
state = RUN & pwd[idx] != in_digit : ERROR;
state = ERROR & in_signal : RUN;
TRUE : state;
esac;
next(counter) := case
state = RUN & pwd[idx] != in_digit & counter < 3 : counter + 1;
state = RUN & pwd[idx] = in_digit : counter;
TRUE : 0;
esac;
next(idx) := case
state = RUN & pwd[idx] = in_digit & idx < 4 : idx + 1;
state = RUN & pwd[idx] != in_digit : 0;
TRUE : 0;
esac;
--
-- the following invariants nicely restrict the set of viable
-- transitions when inputs can be ignored
--
INVAR
in_signal -> state = ERROR;
INVAR
state = ERROR -> in_digit = 0;
INVAR
state = OK -> in_digit = 0;
The solutions assumes that one can only enter one digit at a time, through input in_digit, and that there is a separate control signal in_signal to reset the device.
The device has three possible states:
RUN: the device reads an input digit from in_digit, and compares it with a fixed password sequence
OK: the device recognized the input sequence some time in the past, and it is now ignoring any further input
ERROR: the user made too many incorrect input attempts, and the device is ignoring any input digit until in_signal is true.
At the end of the model, I added three INVAR constraints which prune the transition space from edges that are not relevant to us because of some inputs being ignored at certain moments. Ignoring those inputs makes it much easier to simulate the system by hand.
The run the example, use NuSMV:
~$ NuSMV -int
~$ reset; read_model -i digicode.smv; go; pick_state -iv; simulate -iv -k 30
~$ quit
An alternative, and much simpler approach, would be to provide digicode with 5 input digits all at once. In this way, one can remove idx and pwd from the model, making it much simpler.

Intersection of two BDDs using CUDD

I would like to find intersection of two BDDs for the following two Boolean functions:
F=A'B'C'D'=1
G=A XOR B XOR C XOR D=1
Here is my code:
int main (int argc, char *argv[])
{
char filename[30];
DdManager *gbm; /* Global BDD manager. */
gbm = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); /* Initialize a new BDD manager. */
DdNode *bdd, *var, *tmp_neg, *tmp,*f,*g;
int i;
bdd = Cudd_ReadOne(gbm); /*Returns the logic one constant of the manager*/
Cudd_Ref(bdd); /*Increases the reference count of a node*/
for (i = 3; i >= 0; i--) {
var = Cudd_bddIthVar(gbm,i); /*Create a new BDD variable*/
tmp_neg = Cudd_Not(var); /*Perform NOT Boolean operation*/
tmp = Cudd_bddAnd(gbm, tmp_neg, bdd); /*Perform AND Boolean operation*/
Cudd_Ref(tmp);
Cudd_RecursiveDeref(gbm,bdd);
f = tmp;
}
for (i = 3; i >= 0; i--) {
var = Cudd_bddIthVar(gbm,i); /*Create a new BDD variable*/
tmp = Cudd_bddXor(gbm, var, bdd); /*Perform AND Boolean operation*/
Cudd_Ref(tmp);
Cudd_RecursiveDeref(gbm,bdd);
g = tmp;
}
bdd= Cudd_bddIntersect(gbm,f,g);/*Intersection between F and G */
bdd = Cudd_BddToAdd(gbm, bdd); /*Convert BDD to ADD for display purpose*/
print_dd (gbm, bdd, 2,4); /*Print the dd to standard output*/
sprintf(filename, "./bdd/graph.dot"); /*Write .dot filename to a string*/
write_dd(gbm, bdd, filename); /*Write the resulting cascade dd to a file*/
Cudd_Quit(gbm);
return 0;
}
And here is the result I got:
DdManager nodes: 7 | DdManager vars: 4 | DdManager reorderings: 0 | DdManager memory: 8949888
: 3 nodes 2 leaves 2 minterms
ID = 0xaa40f index = 0 T = 0 E = 1
0--- 1
As you can see here the intersection gives A=0 and don't cares for B,C and D. I was expecting values of A,B,C and D that satifies both F and G. But clearly A=0 is not the solution for both F and G. For example someone can choose A=0,B=1 which gives 0 for function F. What is wrong here?
This reply comes awfully late, but just to close the issue, the problem is that the last operand to both Cudd_bddAnd and Cudd_bddXor is bdd instead of f or g. Of course, both f and g should be properly initialized (the way bdd is currently initialized). Fixing the code this way will also take care of the multiple dereferences of bdd, which are going to cause grief should garbage collection kick in.
Also, Cudd_bddIntersect does not compute the AND of two BDDs, but a function that implies the AND. It's used when one wants a witness to the nonemptiness of the conjunction of two BDDs without computing the whole result (and then possibly extracting a witness from it).
Finally, bdd is used as both operand to Cudd_BddToAdd and as destination for the return value. This is guaranteed to "leak" BDD nodes.

satisfying the LTL formula in model

Is AG(~q ∨ Fp) LTL formula satisfy in model below? why or why not?
model?
First of all AG(~q ∨ Fp) is not an LTL formula, because the operator AG does not belong to LTL. I assume you meant G(~q v Fp).
Modeling: let's encode the system in NuSMV:
MODULE main ()
VAR
state : { S0, S1, S2, S3 };
p : boolean;
q : boolean;
ASSIGN
init(state) := S0;
next(state) := case
state = S0 : {S1, S2};
state = S1 : {S0, S3};
state = S2 : {S0};
state = S3 : {S3};
esac;
INVAR state = S0 <-> (!p & !q);
INVAR state = S1 <-> ( p & q);
INVAR state = S2 <-> (!p & q);
INVAR state = S3 <-> ( p & !q);
LTLSPEC G(!q | F p)
And verify it:
~$ NuSMV -int
NuSMV > reset; read_model -i f.smv; go; check_property
-- specification G (!q | F p) is false
-- as demonstrated by the following execution sequence
Trace Description: LTL Counterexample
Trace Type: Counterexample
-- Loop starts here
-> State: 2.1 <-
state = S0
p = FALSE
q = FALSE
-> State: 2.2 <-
state = S2
q = TRUE
-> State: 2.3 <-
state = S0
q = FALSE
Explanation: So the LTL formula is not satisfied by the model. Why?
G means that the formula is satisfied only if ~q v F p is verified by every reachable state.
State S2 is s.t. ~q is FALSE, so in order to satisfy ~q v F p it must necessarily hold that F p is TRUE, that is it is necessarily the case that sooner or later p becomes TRUE.
There exists an infinite path starting from S2 s.t. p is always FALSE: the path that jumps from S2 to S0 and back and never touches either S1 or S3.
Contradiction: the LTL formula is not satisfied.

how to create a structure of kripke in NuSMV?

i must to create a structure of Kripke in NuSMV and i must to check some properties.
Anybody help me? The structure and the properties(LTL, CTL and CTL*) are in the pictures.
Here there is a structure and properties:
http://cl.ly/image/1x0b1v3E0P0D/Screen%20Shot%202014-10-16%20at%2016.52.34.png
I found a simpler and seemingly more reliable NuSMV code for your Kripke Structure. Thanks to dejvuth for his answer to my question. The code is as follows
MODULE main
VAR
state : {s0,s1,s2,s3,s4};
ASSIGN
init(state) := s0;
next(state):=
case
state = s0 : {s1,s2};
state = s1 : {s1,s2};
state = s2 : {s1,s2,s3};
state = s3 : {s1,s4};
state = s4 : {s4};
esac;
DEFINE
p := state = s1 | state = s2 | state = s3 | state = s4;
q := state = s1 | state = s2;
r := state = s3;
SPEC
EG p;
SPEC
AG p;
SPEC
EF (AG p);
As far as I know NuSMV only handles LTL and CTL formulas (see NuSMV in Wikipedia). The formulas in problem 1-3 are CTL formulas, hence it can be model-checked by NuSMV. However the formulas in problem 4 & 5 are CTL* formulas, and thus we cannot straightforwardly use them as an input to NuSMV. You also need to understand that the set of all CTL* formulas is the proper superset of the union of all LTL and CTL formulas. This conditions implies that some CTL* formulas do not have their equivalent LTL or CTL formulas (see CTL* in Wikipedia). Your Kripke structure can be defined in NuSMV by following code:
MODULE main
VAR
p : boolean;
q : boolean;
r : boolean;
state : {s0,s1,s2,s3,s4};
ASSIGN
init (state) := s0;
next (state) :=
case
state = s0 : {s1, s2};
state = s1 : {s1, s2};
state = s2 : {s1, s2, s3};
state = s3 : {s1, s4};
state = s4 : {s4};
TRUE : state;
esac;
init (p) := FALSE;
init (q) := FALSE;
init (r) := FALSE;
next(p) :=
case
state = s1 | state = s2 | state = s3 | state = s4 : TRUE;
TRUE : p;
esac;
next(q) :=
case
state = s1 | state = s2 : TRUE;
state = s3 | state = s4 : FALSE;
TRUE : q;
esac;
next(r) :=
case
state = s3 : TRUE;
state = s1 | state = s2 | state = s4 : FALSE;
TRUE : r;
esac;
SPEC
EG p;
SPEC
AG p;
SPEC
EF (AG p);
Of course, there is another way to define your Kripke structure in NuSMV, but I think this is one of the easiest. (Anyway, thanks for helping me with my problem).
As for the formulas in problem 4 & 5, here is my answer.
The formula AF [p U EG ( p -> q)] is of the form AF [\phi], where \phi is an LTL formula p U EG (p->q). Since the LTL formula \phi is satisfied in a Kripke model if for every path starting at s0 we have the satisfaction of \phi, then we translate AF [p U EG ( p -> q)] into AF A[p U EG ( p -> q)].
By similar argument, we translate EG[(( p & q ) | r) U ( r U AG p)] into EG[A(( p & q ) | r) U A( r U AG p)].

Resources