-
Notifications
You must be signed in to change notification settings - Fork 2
/
caret_print.ml
283 lines (240 loc) · 6.73 KB
/
caret_print.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
open Atoms
open Formula_datatype
open Rsmast
(* let dkey = Caret_option.register_category "printer" *)
open Type_RState
open Type_Box
open Type_Rsm_module
let print_rsm_complete_state_info fmt rsm =
let print_state_info_caller fmt s =
match s.call with
Some (box,_) ->
Format.fprintf fmt "Calls the box %a\nAtomized by %a"
Box.pretty box
Atom.pretty box.box_atom
| None ->
match s.return with
Some(box,_) ->
Format.fprintf fmt "Returns from the box :%a\n"
Box.pretty box
| _ -> ()
in
let print_state fmt s =
Format.fprintf fmt
"State %a\nAtom: %a\n%s%a\n%a\n\n"
RState.pretty s
Atom.pretty s.s_atom
(if Id_Formula.Set.is_empty s.s_accept then "" else "Accepts:\n")
Atoms.pretty_raw_atom s.s_accept
print_state_info_caller s
in
Rsm_module.Set.iter
(fun rmod ->
Format.fprintf fmt "Module %a:\n" Rsm_module.pretty rmod;
RState.Set.iter
(fun state ->
Format.fprintf fmt "%a\n" print_state state)
rmod.states;
Format.fprintf fmt "%a represented by : \n"
Rsm_module.pretty rmod;
Box.Set.iter
(fun (b:Box.t) ->
Format.fprintf fmt "%a\n" Box.pretty_complete b)
rmod.box_repres)
rsm.rsm_mod
let print_rsm_simple_info fmt rsm =
let total_trans = ref 0 in
let print_mod_info r_mod =
let mod_trans =
RState.Set.fold
(fun state acc -> acc + RState.Set.cardinal state.s_succs)
r_mod.states
0
in
let () = total_trans := mod_trans + !total_trans in
Format.fprintf fmt "Module %s:\n%d entries\n%d exits\n%d states\n%d transitions/plugs\n\n"
r_mod.mod_name
(RState.Set.cardinal r_mod.entries)
(RState.Set.cardinal r_mod.exits)
(RState.Set.cardinal r_mod.states)
mod_trans
in
let number_state =
Rsm_module.Set.fold
(fun r_mod st ->
print_mod_info r_mod;
(st + (RState.Set.cardinal r_mod.states)))
rsm.rsm_mod
0
in
Format.fprintf fmt
"Number of states: %d\n\
Number of trans: %d\n\
Starts : \n%a\n\
Acceptance sets:\n Inf\n%a\n"
number_state
!total_trans
RState.pretty_state_set rsm.start
Atoms.pretty_raw_atom rsm.until_set
let deleteForbiddenDotChar str =
let isForb = function
| ':' | '|' | '"' -> true
| _ -> false
in
String.map
(fun c -> if isForb c then ' ' else c) str
let string_stmt (stmt:Cil_types.stmt) =
let orig_str =
String.trim
(Format.fprintf
Format.str_formatter
"@[%a@]"
Printer.pp_stmt
stmt;
Format.flush_str_formatter ()
)
in
if String.length orig_str > 15
then
String.sub orig_str 0 15
else
orig_str
let print_path fmt s_list =
Format.fprintf fmt "%a"
(Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt "\n") RState.pretty) s_list
(* | IProp atom -> string_atom atom *)
(** 1. Rsm print *)
(** RState printers *)
let short_state (state:state) =
deleteForbiddenDotChar
((string_stmt state.s_stmt)^ (string_of_int state.s_id))
let simple_box box =
"Box_" ^ box.b_name ^ (string_of_int box.b_id)
let string_state rsm ?(cex = RState.Set.empty) ?(boxes = ref Box.Set.empty) state =
let color =
if RState.Set.mem state cex
then ", color=red"
else ""
in
let id = string_of_int state.s_id in
match state.call with
Some (box, _) ->
if not (Box.Set.mem box !boxes )
then
begin
boxes := Box.Set.add box !boxes ;
(simple_box box) ^ " [shape=box]\n"
^ id ^ "[label = \"" ^ (short_state state) ^ "\",shape = rarrow];\n"
end
else
id ^ "[label = \"" ^ (short_state state) ^ "\",shape = rarrow ];\n"
| None -> match state.return with
Some (box, _) ->
if not (Box.Set.mem box !boxes)
then
begin
boxes := Box.Set.add box !boxes;
(simple_box box) ^ " [shape=box]\n"
^ id ^ "[label = \"" ^ (short_state state)
^ "\",shape = larrow];\n"
end
else
id ^ "[label = \"" ^ (short_state state) ^ "\",shape = larrow ];\n"
| None ->
let shape =
let card = Id_Formula.Set.cardinal state.s_accept in
if card = 0 then "octagon"
else if (Id_Formula.Set.cardinal rsm.until_set) = card
then "tripleoctagon"
else "doubleoctagon" in
id ^
"[label = \"" ^ (short_state state) ^ "\",shape = " ^ shape ^ color ^" ];\n"
let string_state_set rsm ?(cex = RState.Set.empty) s_set =
RState.Set.fold
(fun st acc -> acc ^ (string_state rsm ~cex st) )
s_set
""
(** Transition printers *)
let string_trans_from_end end_state =
let id = string_of_int end_state.s_id in
let trans_preds =
RState.Set.fold
(fun pred acc ->
acc ^ (string_of_int pred.s_id) ^ " -> " ^ id ^ ";\n"
)
end_state.s_preds
""
in
let trans_preds =
RState.Set.fold
(fun pred acc ->
acc
^ (string_of_int pred.s_id)
^ " -> "
^ id
^ " [style = dashed];\n"
)
end_state.summary_preds
trans_preds
in
begin
if end_state.call <> None
then
let box = fst (Extlib.the end_state.call) in
(trans_preds ^ id ^ " -> " ^
(simple_box box) ^ "\n")
else
if end_state.return <> None
then
let box = fst (Extlib.the end_state.return) in
(trans_preds ^ (simple_box box) ^ " -> " ^ id ^ "\n")
else
trans_preds
end
let string_tr_set_of_mod r_mod =
RState.Set.fold
(fun state acc -> acc ^ (string_trans_from_end state))
r_mod.states
""
(** Automaton printers *)
let string_rank r_mod =
let rec split_states states =
if RState.Set.is_empty states
then ""
else
let rand_state = RState.Set.choose states in
let is_call = rand_state.call <> None in
let is_ret = rand_state.return <> None in
let same,diff =
RState.Set.partition
(fun st ->
Cil_datatype.Stmt.equal st.s_stmt rand_state.s_stmt
&& (not(is_call) || st.call <> None)
&& (not(is_ret) || st.return <> None)
)
states
in
(RState.Set.fold
(fun st acc -> acc ^ " " ^ (string_of_int st.s_id))
same
"{rank = same")
^ "}\n"
^ (split_states diff)
in
split_states r_mod.states
let string_module rsm ?(cex = RState.Set.empty) r_mod =
"subgraph clustermod_" ^ (string_of_int r_mod.mid)
^ "{\nlabel = \"" ^ r_mod.mod_name ^ "\";\n" ^
(string_state_set rsm ~cex
(RState.Set.filter (fun s -> (not s.deleted)) r_mod.states) )
^ "\n\n"
^ (string_tr_set_of_mod r_mod) ^ "\n"
^ string_rank r_mod
^ "}"
let string_rsm ?(cex = RState.Set.empty ) rsm =
"digraph " ^ rsm.name ^ " {\nsplines=ortho\n"
^ (Rsm_module.Set.fold
(fun r_mod acc -> (string_module rsm ~cex r_mod) ^ acc)
rsm.rsm_mod)
""
^ "}\n"