|
1050
|
1 |
|
|
|
2 |
|
|
1138
|
3 |
|
|
|
4 |
(* ----------------------------------------------------------------
|
|
|
5 |
P r o t o t y p e M o d e l C h e c k e r
|
|
|
6 |
----------------------------------------------------------------*)
|
|
1050
|
7 |
|
|
|
8 |
fun check(extacts,intacts,string_of_a,startsI,string_of_s,
|
|
|
9 |
nexts,hom,transA,startsS) =
|
|
|
10 |
let fun check_s(s,unchecked,checked) =
|
|
|
11 |
let fun check_sa(unchecked,a) =
|
|
|
12 |
let fun check_sas(unchecked,t) =
|
|
|
13 |
(if a mem extacts then
|
|
1138
|
14 |
(if transA(hom s,a,hom t) then ( )
|
|
1050
|
15 |
else (writeln("Error: Mapping of Externals!");
|
|
|
16 |
string_of_s s; writeln"";
|
|
|
17 |
string_of_a a; writeln"";
|
|
1138
|
18 |
string_of_s t;writeln"";writeln"" ))
|
|
|
19 |
else (if hom(s)=hom(t) then ( )
|
|
1050
|
20 |
else (writeln("Error: Mapping of Internals!");
|
|
1138
|
21 |
string_of_s s; writeln"";
|
|
|
22 |
string_of_a a; writeln"";
|
|
|
23 |
string_of_s t;writeln"";writeln"" ));
|
|
1050
|
24 |
if t mem checked then unchecked else t ins unchecked)
|
|
|
25 |
in foldl check_sas (unchecked,nexts s a) end;
|
|
|
26 |
val unchecked' = foldl check_sa (unchecked,extacts @ intacts)
|
|
|
27 |
in (if s mem startsI then
|
|
|
28 |
(if hom(s) mem startsS then ()
|
|
|
29 |
else writeln("Error: At start states!"))
|
|
|
30 |
else ();
|
|
|
31 |
checks(unchecked',s::checked)) end
|
|
|
32 |
and checks([],_) = ()
|
|
|
33 |
| checks(s::unchecked,checked) = check_s(s,unchecked,checked)
|
|
|
34 |
in checks(startsI,[]) end;
|
|
|
35 |
|
|
|
36 |
|
|
1138
|
37 |
(* ------------------------------------------------------
|
|
|
38 |
A B P E x a m p l e
|
|
|
39 |
-------------------------------------------------------*)
|
|
1050
|
40 |
|
|
1138
|
41 |
datatype msg = m | n | l;
|
|
1050
|
42 |
datatype act = Next | S_msg of msg | R_msg of msg
|
|
|
43 |
| S_pkt of bool * msg | R_pkt of bool * msg
|
|
|
44 |
| S_ack of bool | R_ack of bool;
|
|
|
45 |
|
|
1138
|
46 |
(* -------------------- Transition relation of Specification -----------*)
|
|
|
47 |
|
|
1050
|
48 |
fun transA((u,s),a,(v,t)) =
|
|
|
49 |
(case a of
|
|
|
50 |
Next => v andalso t = s |
|
|
1138
|
51 |
S_msg(q) => u andalso not(v) andalso t = s@[q] |
|
|
|
52 |
R_msg(q) => u = v andalso s = (q::t) |
|
|
|
53 |
S_pkt(b,q) => false |
|
|
|
54 |
R_pkt(b,q) => false |
|
|
1050
|
55 |
S_ack(b) => false |
|
|
|
56 |
R_ack(b) => false);
|
|
|
57 |
|
|
1138
|
58 |
|
|
|
59 |
(* ---------------------- Abstraction function --------------------------*)
|
|
|
60 |
|
|
1050
|
61 |
fun hom((env,p,a,q,b,_,_)) = (env,q@(if (a=b) then tl(p) else p));
|
|
|
62 |
|
|
1138
|
63 |
|
|
|
64 |
(* --------------------- Transition relation of Implementation ----------*)
|
|
|
65 |
|
|
1050
|
66 |
fun nexts (s as (env,p,a,q,b,ch1,ch2)) action =
|
|
|
67 |
(case action of
|
|
|
68 |
Next => if p=[] then [(true,p,a,q,b,ch1,ch2)] else [] |
|
|
1138
|
69 |
S_msg(mornorl) => if env then [(false,p@[mornorl],a,q,b,ch1,ch2)] else [] |
|
|
|
70 |
R_msg(mornorl) => if (q<>[] andalso mornorl=hd(q))
|
|
1050
|
71 |
then [(env,p,a,tl(q),b,ch1,ch2)]
|
|
|
72 |
else [] |
|
|
1138
|
73 |
S_pkt(h,mornorl) => if (p<>[] andalso mornorl=hd(p) andalso h=a)
|
|
|
74 |
then (if (ch1<>[] andalso hd(rev(ch1))=(h,mornorl))
|
|
1050
|
75 |
then [s]
|
|
1138
|
76 |
else [s,(env,p,a,q,b,ch1@[(h,mornorl)],ch2)])
|
|
1050
|
77 |
else [] |
|
|
1138
|
78 |
R_pkt(h,mornorl) => if (ch1<>[] andalso hd(ch1)=(h,mornorl))
|
|
1050
|
79 |
then (if (h<>b andalso q=[])
|
|
1138
|
80 |
then [(env,p,a,q@[mornorl],not(b),ch1,ch2),
|
|
|
81 |
(env,p,a,q@[mornorl],not(b),tl(ch1),ch2)]
|
|
1050
|
82 |
else [s,(env,p,a,q,b,tl(ch1),ch2)])
|
|
|
83 |
else [] |
|
|
|
84 |
S_ack(h) => if (h=b)
|
|
|
85 |
then (if (ch2<>[] andalso h=hd(rev(ch2)))
|
|
|
86 |
then [s]
|
|
|
87 |
else [s,(env,p,a,q,b,ch1,ch2@[h])])
|
|
|
88 |
else [] |
|
|
|
89 |
R_ack(h) => if (ch2<>[] andalso hd(ch2)=h)
|
|
|
90 |
then (if h=a
|
|
|
91 |
then [(env,tl(p),not(a),q,b,ch1,ch2),
|
|
|
92 |
(env,tl(p),not(a),q,b,ch1,tl(ch2))]
|
|
|
93 |
else [s,(env,p,a,q,b,ch1,tl(ch2))])
|
|
|
94 |
else [])
|
|
|
95 |
|
|
|
96 |
|
|
1138
|
97 |
val extactions = [Next,S_msg(m),R_msg(m),S_msg(n),R_msg(n),S_msg(l),R_msg(l)];
|
|
1050
|
98 |
val intactions = [S_pkt(true,m),R_pkt(true,m),S_ack(true),R_ack(true),
|
|
1138
|
99 |
S_pkt(false,m),R_pkt(false,m),S_ack(false),R_ack(false),
|
|
|
100 |
S_pkt(true,n),R_pkt(true,n),S_pkt(true,l),R_pkt(true,l),
|
|
|
101 |
S_pkt(false,n),R_pkt(false,n),S_pkt(false,l),R_pkt(false,l)];
|
|
|
102 |
|
|
1050
|
103 |
|
|
1138
|
104 |
(* ------------------------------------
|
|
|
105 |
Input / Output utilities
|
|
|
106 |
------------------------------------*)
|
|
1050
|
107 |
|
|
1138
|
108 |
fun print_list (lpar, rpar, pre: 'a -> unit) (lll : 'a list) =
|
|
1050
|
109 |
let fun prec x = (prs ","; pre x)
|
|
|
110 |
in
|
|
1138
|
111 |
(case lll of
|
|
1050
|
112 |
[] => (prs lpar; prs rpar)
|
|
1138
|
113 |
| x::lll => (prs lpar; pre x; seq prec lll; prs rpar))
|
|
1050
|
114 |
end;
|
|
|
115 |
|
|
|
116 |
fun pr_bool true = output(std_out,"true")
|
|
|
117 |
| pr_bool false = output(std_out,"false");
|
|
|
118 |
|
|
1138
|
119 |
fun pr_msg m = output(std_out,"m")
|
|
|
120 |
| pr_msg n = output(std_out,"n")
|
|
|
121 |
| pr_msg l = output(std_out,"l");
|
|
1050
|
122 |
|
|
|
123 |
fun pr_act a = output(std_out, case a of
|
|
|
124 |
Next => "Next"|
|
|
1138
|
125 |
S_msg(ma) => "S_msg(ma)" |
|
|
|
126 |
R_msg(ma) => "R_msg(ma)" |
|
|
|
127 |
S_pkt(b,ma) => "S_pkt(b,ma)" |
|
|
|
128 |
R_pkt(b,ma) => "R_pkt(b,ma)" |
|
|
1050
|
129 |
S_ack(b) => "S_ack(b)" |
|
|
|
130 |
R_ack(b) => "R_ack(b)");
|
|
|
131 |
|
|
1138
|
132 |
fun pr_pkt (b,ma) = (prs "<"; pr_bool b;prs ", "; pr_msg ma; prs ">");
|
|
1050
|
133 |
|
|
|
134 |
val pr_bool_list = print_list("[","]",pr_bool);
|
|
|
135 |
val pr_msg_list = print_list("[","]",pr_msg);
|
|
|
136 |
val pr_pkt_list = print_list("[","]",pr_pkt);
|
|
|
137 |
|
|
|
138 |
fun pr_tuple (env,p,a,q,b,ch1,ch2) =
|
|
|
139 |
(prs "{"; pr_bool env; prs ", "; pr_msg_list p; prs ", ";
|
|
|
140 |
pr_bool a; prs ", "; pr_msg_list q; prs ", ";
|
|
|
141 |
pr_bool b; prs ", "; pr_pkt_list ch1; prs ", ";
|
|
|
142 |
pr_bool_list ch2; prs "}");
|
|
|
143 |
|
|
1138
|
144 |
|
|
1050
|
145 |
|
|
1138
|
146 |
(* ---------------------------------
|
|
|
147 |
Main function call
|
|
|
148 |
---------------------------------*)
|
|
|
149 |
|
|
|
150 |
(*
|
|
1050
|
151 |
check(extactions,intactions,pr_act, [(true,[],true,[],false,[],[])],
|
|
|
152 |
pr_tuple, nexts, hom, transA, [(true,[])]);
|
|
1138
|
153 |
*)
|
|
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
1050
|
157 |
|
|
|
158 |
|
|
1138
|
159 |
(*
|
|
|
160 |
Little test example
|
|
|
161 |
|
|
|
162 |
datatype act = A;
|
|
|
163 |
fun transA(s,a,t) = (not(s)=t);
|
|
|
164 |
fun hom(i) = i mod 2 = 0;
|
|
|
165 |
fun nexts s A = [(s+1) mod 4];
|
|
|
166 |
check([A],[],K"A", [0], string_of_int, nexts, hom, transA, [true]);
|
|
|
167 |
|
|
|
168 |
fun nexts s A = [(s+1) mod 5];
|
|
|
169 |
|
|
1465
|
170 |
*)
|