how to create a structure of kripke in NuSMV? - model-checking

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)].

Related

NuSMV: Initialising range constant with parameter

I'm new to NuSMV. I'm trying to define a module, where each state has a duration variable than can range from 0 to the specified bound.
MODULE state(inc, bound)
VAR
duration : 0..bound;
ASSIGN
init(duration) := 0;
next(duration) := inc ? (duration + 1) mod (bound+1) : duration ;
DEFINE limit := duration = bound;
However, this yields the syntax error: A variable is expected in left-hand-side of assignment: init(duration) := 0. I'm able to fix this by declaring duration to duration : 0..1+bound.
In my main module, I wish to calculate the total_duration (or actually calculate all possible combinations of state's duration and make sure that no combination exceeds e.i. 3 as in the SPEC) of running my model and make sure that variable does not succeed a specific limit.
Here's my main module:
MODULE main
VAR
s0 : state(TRUE, 0);
s1 : state(s0.limit, 0);
s2 : state(s1.limit, 3);
state : {s0, s1, s2};
DEFINE
max_duration := s0.bound + s1.bound + s2.bound;
VAR
total_duration : 0..max_duration;
ASSIGN
init(state) := s0;
next(state) :=
case
state = s0 : s1;
state = s1 : s2;
state = s2 : s2;
esac;
total_duration := s0.duration + s1.duration + s2.duration;
SPEC
AG (state = s2 -> AF total_duration <= 3);
My problem is: When I run the model, NuSMV keeps adding to the total_duration variable and thus fails with the message "line 39: cannot assign value 5 to variable total_duration". This is due to the declaration of duration : 0..1+bound, because, in the particular example of
s0.duration = 0, s1.duration = 0 and s2.duration = 3, it will try to add 1 + 1 + 4 to total_duration, as that is the state's bound + 1.
However, if I check the trace there's no point where total_duration exceed 3. I have checked the followed specs:
-- specification AG total_duration < 4 is true
-- specification F total_duration = 4 is false
-- specification EF total_duration >= 4 is false
How can I fix this? Either by declaring duration in another way or changing anything else?
The software does something very simple. It takes the domain of each addend, and checks whether the result variable would be able to hold the result of every possible combination of value. In this case:
the domain of s0.duration is 0..1
the domain of s1.duration is 0..1
the domain of s2.duration is 0..4
so, in principle, the maximum total_duration could be 6 and its domain should thus be 0..6. Therefore:
DEFINE
max_duration := s0.bound + s1.bound + s2.bound + 3
You may want to run NuSMV with the following option:
-keep_single_value_vars
Does not convert variables that have only one
single possible value into constant DEFINEs
In this way, you'll be able to run the model without having to add +1 to the domain of bound.

Ocaml - Check, given a list of transitions, the word is recognized

I created a function that returns a list of transitions. Transitions are of type int * char * int.
for example (0 'E' 1); (1 'A' 2). The valid alphabet for the transitions are A, C, G and T and the char 'E' represents epsilon.
type transition = int * char * int;;
let get_start (a,_,_) = a;;
let get_char (_,a,_) = a;;
let get_end (_,_,a) = a;;
The initial state and the final state are stored in the following variables.
...
let i_strt = ref !state_initial;;
let i_end = ref !state_end;;
exception Out_of_loop;;
let seq = read_line();;(* string to be tested *)
let len_seq = String.length seq -1;;
let lst_trs_length = List.length !aux_transitions -1;; (* aux_transitions -> all transitions*)
let i = ref 0;;
let f = ref 0;;
while !i <= len_seq do
let c_r = seq.[i]in (* c_r = 'A' seq = ACGT*)
try
while !j <= lst_trs_length do
let aux_trs = List.nth !aux_transitions !j in (* 0 'E' 1 -> 1 'A' 2 ....*)
if (get_start aux_trs) = !i_strt then (* *)
let aux_chr = get_char aux_trs in (* 'A' *)
if aux_chr = c_r then(
i_strt := get_end aux_trs; (* i_strt = 1*)
raise Out_of_loop
)
else if aux_chr = 'E' then(
i_strt := get_end aux_trs;
j := -1
);
j := !j+1
done;
with Out_of_loop ->();
i := !i +1
done;
I am trying to use these two cycles to check whether the string "seq" can be recognized or not by the list of transitions taking into account the initial state. I am having trouble writing this function ... I want a function that, given a list of transitions and a string, returns 'true' in case it is recognized or false in the negative case.

Vending Machine in NuSMV

I am new to NuSMV, I am trying to create Vending Machine implementation from Kripke structure, I have three boolean (coin, selection, brewing) as well as three states.However, When I compile the code I receive "Line 25: at token ":": syntax error" If anyone sees any errors in my code I would appreciate the help.
Kripke structure
my attempt to write the code is as follow:
MODULE main
VAR
location : {s1,s2,s3};
coin : boolean;
selection: boolean;
brweing: boolean;
ASSIGN
init(location) := s1;
init(coin) := FALSE;
init(selection) := FALSE;
init(brweing) := FALSE;
next(location) :=
case
location = s1 : s2;
TRUE: coin;
esac;
next(location) :=
case
location = (s2 : s3 & (TRUE: selection));
location = (s2 : s1 & (FALSE: selection) & (FALSE: coin));
esac;
next(location) :=
case
location = (s3 : s3 & (TRUE: brewing));
location = (s3 : s1 & (FALSE: selection) & (FALSE: coin) & (FALSE: brewing));
esac;
-- specification
• AG [s ⇒ b] whenever a selection is made coffee is brewed for sure.
• E [(¬s) U (b)] the coffee will not be brewed as no selection were made.
• EF[b] there is a state where coffee is brewed.
The line (among others)
location = (s2 : s3 & (TRUE: selection));
doesn't make much sense. You need only one next statement to assign the next location from all possible values of location. Also, you don't need to declare coin, selection, and brewing as variables. Use DEFINE to define their values based on location:
MODULE main
VAR
location : {s1,s2,s3};
ASSIGN
init(location) := s1;
next(location) :=
case
location = s1 : s2;
location = s2 : {s1,s3};
location = s3 : {s1,s3};
esac;
DEFINE
coin := location = s2 | location = s3;
-- similarly for selection and brewing
What I understand from the model is that coin, selection and brew are not only labels but events that trigger the transition. If so, I would write the model like this:
MODULE main
VAR
location: {s1, s2, s3};
coin: boolean;
selection: boolean;
brew: boolean;
abort: boolean;
INIT
!coin & !selection & !brew;
ASSIGN
init(location) := s1;
next(location) := case
location = s1 & next(coin) : s2;
location = s2 & next(selection) : s3;
location = s2 & next(abort) : s1;
location = s3 : {s1, s3};
TRUE : location;
esac;
next(brew) := (next(location) = s3);
next(coin) := case
next(state) = s1 : FALSE;
state = s1 : {TRUE, FALSE};
TRUE : coin;
esac;
next(selection) := case
state = s2 : {TRUE, FALSE};
next(state) = s1 : FALSE;
esac;

Ada case statement with strings

I'm trying to use a string in a case statement, however it is giving me expected a discrete type. Found type Standard.String I understand that strings are not discrete. I'm wondering if there is a work around or not. Here is my code:
function Is_Valid_Direction(Direction_To_Go : in String) return Integer is
Room : Integer := 0;
begin
--if (Direction_To_Go = "NORTH" or Direction_To_Go = "N") then
-- Room := Building(currentRoom).exits(NORTH);
--elsif (Direction_To_Go = "SOUTH" or Direction_To_Go = "S") then
-- Room := Building(currentRoom).exits(SOUTH);
--elsif (Direction_To_Go = "EAST" or Direction_To_Go = "E") then
-- Room := Building(currentRoom).exits(EAST);
--elsif (Direction_To_Go = "WEST" or Direction_To_Go = "W") then
-- Room := Building(currentRoom).exits(WEST);
--elsif (Direction_To_Go = "UP" or Direction_To_Go = "U") then
-- Room := Building(currentRoom).exits(UP);
--elsif (Direction_To_Go = "DOWN" or Direction_To_Go = "D") then
-- Room := Building(currentRoom).exits(DOWN);
--end if;
case Direction_To_Go is
when "NORTH" | "N" => Room := Building(currentRoom).exits(NORTH);
when "SOUTH" | "S" => Room := Building(currentRoom).exits(SOUTH);
when "EAST" | "E" => Room := Building(currentRoom).exits(EAST);
when "WEST" | "W" => Room := Building(currentRoom).exits(WEST);
when "UP" | "U" => Room := Building(currentRoom).exits(UP);
when "DOWN" | "D" => Room := Building(currentRoom).exits(DOWN);
when others => Room := 0;
end case;
return Room;
end Is_Valid_Direction;
The commented section is doing exactly what I want, but with if statements. I'm just trying to see if it's possible with a case statement.
You could map your strings to a discrete type. The easiest being an enumerated type:
procedure Light (Colour : in String) is
type Colours is (Red, Green, Blue);
begin
case Colours'Value (Colour) is -- ' <- magic ;-)
when Red =>
Switch_Red_LED;
when Green =>
Switch_Green_LED;
when Blue =>
Switch_Blue_LED;
end case;
exception
when Constraint_Error =>
raise Constraint_Error with "There is no " & Colour & " LED.";
end Light;
I frequently use an actual map to do this kind of mapping, as it gives you more flexibility than enumerations. Your "names" don't have to conform to enumeration syntax, and you can easily provide variations that all map to a single value.
For the desired function definition, as provided in a package:
package Case_Map is
function Is_Valid_Direction(Direction_To_Go : in String) return Integer;
end Case_Map;
This (non-compiling due to missing game-specific declarations) implementation uses a mapping of strings to an enum that is in turn the case expression:
with Ada.Characters.Handling;
with Ada.Containers.Indefinite_Ordered_Maps;
package body Case_Map is
use Ada.Characters.Handling;
type Directions is (Go_North, Go_South, Go_East, Go_West, Go_Up, Go_Down);
package Direction_Management is new Ada.Containers.Indefinite_Ordered_Maps
(String, Directions);
Direction_Map : Direction_Management.Map;
function Is_Valid_Direction(Direction_To_Go : in String) return Integer is
Room : Integer := 0;
begin
case Direction_Map(To_Upper(Direction_To_Go)) is
when Go_North => Room := Building(CurrentRoom).Exits(NORTH);
when Go_South => Room := Building(CurrentRoom).Exits(SOUTH);
when Go_East => Room := Building(CurrentRoom).Exits(EAST);
when Go_West => Room := Building(CurrentRoom).Exits(WEST);
when Go_Up => Room := Building(CurrentRoom).Exits(UP);
when Go_Down => Room := Building(CurrentRoom).Exits(DOWN);
end case;
return Room;
exception
when Constraint_Error =>
return 0;
end Is_Valid_Direction;
begin
Direction_Map.Insert("NORTH", Go_North);
Direction_Map.Insert("N", Go_North);
Direction_Map.Insert("SOUTH", Go_South);
Direction_Map.Insert("S", Go_South);
Direction_Map.Insert("EAST", Go_East);
Direction_Map.Insert("E", Go_East);
Direction_Map.Insert("WEST", Go_West);
Direction_Map.Insert("W", Go_West);
Direction_Map.Insert("UP", Go_Up);
Direction_Map.Insert("U", Go_Up);
Direction_Map.Insert("DOWN", Go_Down);
Direction_Map.Insert("D", Go_Down);
end Case_Map;
The GNAT compiler itself uses a hash table that maps strings (identifiers, keywords,...) to integer. This is the package namet.ads, and GNATCOLL.Symbolic provides a similar API. This simplifies a number of things (string comparison for instance is much faster), and allow the use of case statements as in your example. So if you are using a limited (or at least slow-growing) list of strings, GNATCOLL.Symbolic might be a suitable approach

Memory Issue in Alloy

I am new to Alloy. I am trying to find a solution for a model with 512 states. But it runs out of memory. I set the memory and stack to its maximum level, but it is not enough. Is there any other way I could use to increase the memory Alloy uses?
I appreciate your time and help.
Thanks a lot,
Fathiyeh
Hard to know where to start. Looks as if you're writing an Alloy model as if you're expecting it to be a model checker. But the point of Alloy is to allow you to analyze systems whose states have complex structure, with constraints written in a relational logic. You won't get very far doing a direct encoding of a low-level model into Alloy; for that kind of thing you'd do better to use a model checker.
module threeprocesses
abstract sig boolean {
}
one sig true,false extends boolean{}
sig state {
e1: boolean,
t1: boolean,
ready1: boolean,
e2: boolean,
t2: boolean,
ready2: boolean,
e3: boolean,
t3: boolean,
ready3: boolean
}
sig relation {
lambda : state -> one Int,
next1 : state -> state
}
pred LS (s : state) {
(((s.t1 =s.t3) and (s.t2 =s.t1) and (s.t3 =s.t2))
or ((s.t1 != s.t3) and (s.t2 !=s.t1) and (s.t3 =s.t2))
or ((s.t1 != s.t3) and (s.t2 =s.t1) and (s.t3 !=s.t2))) and
((s.e1 =s.e3) or (s.e2 !=s.e1) or (s.e3 !=s.e2))
}
pred show (r:relation) {
all s : state |
LS [s] implies LS [s.(r.next1)]
all s : state |
(not (LS [s])) implies not (s =s.(r.next1))
all s : state |
(not (LS [s])) implies (all s2 : (s.(r.next1)) | s2. (r.lambda) > s.(r.lambda))
all s : state,s2 : state |
((s.t1 = s2.t1) and (s.e1 = s2.e1) and (s.ready1 = s2.ready1) and (s.e3 = s2.e3)
and (s.t3 = s2.t3)) implies
( (((s2.(r.next1)).ready1)= ((s.(r.next1)).ready1)) and (((s2.(r.next1)).e1)= ((s.
(r.next1)).e1)) and
(((s2.(r.next1)).t1)= ((s.(r.next1)).t1)) )
all s : state,s2 : state |
((s.t2 = s2.t2) and (s.e2 = s2.e2) and (s.ready2 = s2.ready2) and (s.e1 = s2.e1)
and (s.t1 = s2.t1)) implies
( (((s2.(r.next1)).ready2)= ((s.(r.next1)).ready2)) and (((s2.(r.next1)).e2)= ((s.
(r.next1)).e2)) and
(((s2.(r.next1)).t2)= ((s.(r.next1)).t2)) )
all s : state,s2 : state |
((s.t3 = s2.t3) and (s.e3 = s2.e3) and (s.ready3 = s2.ready3) and (s.e2 = s2.e2)
and (s.t2 = s2.t2)) implies
( (((s2.(r.next1)).ready3)= ((s.(r.next1)).ready3)) and (((s2.(r.next1)).e3)= ((s.
(r.next1)).e3)) and
(((s2.(r.next1)).t3)= ((s.(r.next1)).t3)) )
all s : state |
(not ( (s.e1 = ((s.(r.next1)).e1)) and (s.t1 = ((s.(r.next1)).t1)) and (s.ready1
= ((s.(r.next1)).ready1)) ) ) implies
(s.e1 = s.e3)
all s : state |
(not ( (s.e2 = ((s.(r.next1)).e2)) and (s.t2 = ((s.(r.next1)).t2)) and (s.ready2
= ((s.(r.next1)).ready2)) ) ) implies
(not (s.e2 = s.e1))
all s : state |
(not ( (s.e3 = ((s.(r.next1)).e3)) and (s.t3 = ((s.(r.next1)).t3)) and (s.ready3
= ((s.(r.next1)).ready3)) ) ) implies
(not (s.e3 = s.e2))
all s : state ,s2:state |
(s != s2) implies (not ((s.e1 = s2.e1) and (s.e2 = s2.e2) and (s.e3 = s2.e3) and
(s.t1 = s2.t1) and (s.t2 = s2.t2) and (s.t3 = s2.t3) and
(s.ready1 = s2.ready1) and (s.ready2 = s2.ready2) and (s.ready3 = s2.ready3)))
}
run show for 3 but 1 relation, exactly 512 state

Resources