Revision a56f563e
Added by LĂ©lio Brun over 3 years ago
src/backends/C/c_backend_spec.ml | ||
---|---|---|
89 | 89 |
|
90 | 90 |
let pp_var_decl fmt v = pp_print_string fmt v.var_id |
91 | 91 |
|
92 |
let pp_reg self fmt field = |
|
93 |
pp_access pp_indirect' pp_var_decl fmt ((self, "_reg"), field) |
|
94 |
|
|
95 | 92 |
let pp_true fmt () = pp_print_string fmt "\\true" |
96 | 93 |
|
97 | 94 |
let pp_cast pp_ty pp fmt (ty, x) = fprintf fmt "(%a) %a" pp_ty ty pp x |
... | ... | |
117 | 114 |
let find_machine f = List.find (fun m -> m.mname.node_id = f) |
118 | 115 |
|
119 | 116 |
let instances machines m = |
120 |
let open List in |
|
121 |
let grow paths i td mems = |
|
122 |
match paths with |
|
123 |
| [] -> |
|
124 |
[ [ i, (td, mems) ] ] |
|
125 |
| _ -> |
|
126 |
map (cons (i, (td, mems))) paths |
|
127 |
in |
|
128 |
let rec aux paths m = |
|
129 |
map |
|
130 |
(fun (i, (td, _)) -> |
|
131 |
try |
|
132 |
let m = find_machine (node_name td) machines in |
|
133 |
aux (grow paths i td m.mmemory) m |
|
134 |
with Not_found -> grow paths i td []) |
|
135 |
m.minstances |
|
136 |
|> flatten |
|
117 |
let rec aux m = |
|
118 |
List.(fold_left (fun insts (inst, (td, _)) -> |
|
119 |
let mems, insts' = |
|
120 |
try |
|
121 |
let m' = find_machine (node_name td) machines in |
|
122 |
m'.mmemory, aux m' |
|
123 |
with Not_found -> |
|
124 |
if Arrow.td_is_arrow td then arrow_machine.mmemory, [[]] else assert false |
|
125 |
in |
|
126 |
insts @ map (cons (inst, (td, mems))) insts') [[]] m.minstances) |
|
137 | 127 |
in |
138 |
aux [] m |> map rev |
|
139 |
|
|
140 |
let memories insts = |
|
141 |
List.( |
|
142 |
map |
|
143 |
(fun path -> |
|
144 |
let _, (_, mems) = hd (rev path) in |
|
145 |
map (fun mem -> path, mem) mems) |
|
146 |
insts |
|
147 |
|> flatten) |
|
148 |
|
|
149 |
let pp_instance ?(indirect = true) pp ptr = |
|
150 |
pp_print_list |
|
151 |
~pp_prologue:(fun fmt () -> fprintf fmt "%a->" pp ptr) |
|
152 |
~pp_sep:(fun fmt () -> pp_print_string fmt (if indirect then "->" else ".")) |
|
153 |
(fun fmt (i, _) -> pp_print_string fmt i) |
|
154 |
|
|
155 |
let pp_memory ?(indirect = true) ptr fmt (path, mem) = |
|
156 |
pp_access |
|
157 |
((if indirect then pp_indirect else pp_access) |
|
158 |
(pp_instance ~indirect pp_print_string ptr) |
|
159 |
pp_print_string) |
|
160 |
pp_var_decl |
|
161 |
fmt |
|
162 |
((path, "_reg"), mem) |
|
128 |
match aux m with |
|
129 |
| [] :: l -> l |
|
130 |
| l -> l |
|
163 | 131 |
|
164 |
let prefixes l = |
|
165 |
let rec pref acc = function |
|
166 |
| x :: l -> |
|
167 |
pref ([ x ] :: List.map (List.cons x) acc) l |
|
168 |
| [] -> |
|
169 |
acc |
|
170 |
in |
|
171 |
pref [] (List.rev l) |
|
132 |
let pp_instance ?(indirect = true) ?pp_epilogue fmt = |
|
133 |
pp_print_list |
|
134 |
~pp_sep:(fun fmt () -> pp_print_string fmt (if indirect then "->" else ".")) |
|
135 |
?pp_epilogue |
|
136 |
(fun fmt (i, _) -> pp_print_string fmt i) |
|
137 |
fmt |
|
172 | 138 |
|
173 |
let powerset_instances paths = |
|
174 |
List.map prefixes paths |> List.flatten |> remove_duplicates |
|
139 |
let pp_reg ?(indirect = true) self fmt paths = |
|
140 |
fprintf fmt "%s->%a%s" |
|
141 |
self |
|
142 |
(pp_instance |
|
143 |
~indirect |
|
144 |
~pp_epilogue:(fun fmt () -> pp_print_string fmt (if indirect then "->" else "."))) |
|
145 |
paths |
|
146 |
"_reg" |
|
175 | 147 |
|
176 | 148 |
let pp_separated pp_self pp_mem pp_ptr fmt (self, mem, paths, ptrs) = |
177 | 149 |
fprintf |
... | ... | |
181 | 153 |
self |
182 | 154 |
pp_mem |
183 | 155 |
mem |
184 |
(pp_comma_list ~pp_prologue:pp_print_comma (pp_instance pp_self self)) |
|
156 |
(pp_comma_list ~pp_prologue:pp_print_comma |
|
157 |
(fun fmt path -> pp_indirect pp_print_string pp_instance fmt (self, path))) |
|
185 | 158 |
paths |
186 | 159 |
(pp_comma_list ~pp_prologue:pp_print_comma pp_ptr) |
187 | 160 |
ptrs |
... | ... | |
707 | 680 |
~pp_epilogue:pp_print_cut |
708 | 681 |
~pp_open_box:pp_open_vbox0 |
709 | 682 |
(pp_memory_pack_def m)) |
710 |
m.mspec.mmemory_packs
|
|
683 |
(snd m.mspec.mmemory_packs)
|
|
711 | 684 |
|
712 | 685 |
let pp_transition_def m fmt t = |
713 | 686 |
let name = t.tname.node_id in |
... | ... | |
990 | 963 |
(name, mem, self) |
991 | 964 |
(pp_ensures |
992 | 965 |
(pp_memory_pack_aux |
993 |
~i:(List.length m.mspec.mmemory_packs - 2)
|
|
966 |
~i:(fst m.mspec.mmemory_packs)
|
|
994 | 967 |
pp_ptr |
995 | 968 |
pp_print_string)) |
996 | 969 |
(name, mem, self) |
... | ... | |
1493 | 1466 |
let pp_step_spec fmt machines self mem m = |
1494 | 1467 |
let name = m.mname.node_id in |
1495 | 1468 |
let insts = instances machines m in |
1496 |
let insts' = powerset_instances insts in |
|
1497 |
let insts'' = |
|
1498 |
List.( |
|
1499 |
filter |
|
1500 |
(fun l -> l <> []) |
|
1501 |
(map (filter (fun (_, (td, _)) -> not (Arrow.td_is_arrow td))) insts)) |
|
1469 |
let insts_no_arrow = |
|
1470 |
List.(filter |
|
1471 |
(fun path -> |
|
1472 |
let _, (td, _) = hd (rev path) in |
|
1473 |
not (Arrow.td_is_arrow td)) |
|
1474 |
insts) |
|
1475 |
in |
|
1476 |
let stateful_insts = |
|
1477 |
List.(filter |
|
1478 |
(fun path -> |
|
1479 |
let _, (_, mems) = hd (rev path) in |
|
1480 |
mems <> []) |
|
1481 |
insts) |
|
1502 | 1482 |
in |
1503 | 1483 |
let inputs = m.mstep.step_inputs in |
1504 | 1484 |
let outputs = m.mstep.step_outputs in |
... | ... | |
1596 | 1576 |
%a@,\ |
1597 | 1577 |
%a@,\ |
1598 | 1578 |
%a@,\ |
1599 |
%a@,\ |
|
1600 |
%a@,\ |
|
1601 | 1579 |
%a" |
1602 | 1580 |
(pp_if_outputs (pp_requires (pp_valid pp_var_decl))) |
1603 | 1581 |
outputs |
1604 | 1582 |
(pp_requires pp_mem_valid') |
1605 | 1583 |
(name, self) |
1606 | 1584 |
(pp_requires (pp_separated' self mem)) |
1607 |
(insts', outputs)
|
|
1585 |
(insts, outputs) |
|
1608 | 1586 |
(pp_requires (pp_memory_pack_aux pp_ptr pp_print_string)) |
1609 | 1587 |
(name, mem, self) |
1610 | 1588 |
(pp_ensures (pp_memory_pack_aux pp_ptr pp_print_string)) |
... | ... | |
1617 | 1595 |
c |
1618 | 1596 |
(pp_assigns pp_ptr_decl) |
1619 | 1597 |
outputs |
1620 |
(pp_assigns (pp_reg self)) |
|
1621 |
m.mmemory
|
|
1598 |
(if m.mmemory = [] then pp_print_nothing else pp_assigns (pp_reg self))
|
|
1599 |
[[]]
|
|
1622 | 1600 |
(pp_assigns pp_reset_flag') |
1623 | 1601 |
[ self ] |
1624 |
(pp_assigns (pp_memory self)) |
|
1625 |
(memories insts') |
|
1626 |
(pp_assigns (pp_register_chain self)) |
|
1627 |
insts |
|
1602 |
(pp_assigns (pp_reg self)) |
|
1603 |
stateful_insts |
|
1628 | 1604 |
(pp_assigns (pp_reset_flag_chain self)) |
1629 |
insts''
|
|
1630 |
(pp_assigns (pp_reg mem)) |
|
1631 |
m.mmemory
|
|
1605 |
insts_no_arrow
|
|
1606 |
(if m.mmemory = [] then pp_print_nothing else pp_assigns (pp_reg mem))
|
|
1607 |
[[]]
|
|
1632 | 1608 |
(pp_assigns pp_reset_flag') |
1633 | 1609 |
[ mem ] |
1634 |
(pp_assigns (pp_memory ~indirect:false mem)) |
|
1635 |
(memories insts') |
|
1636 |
(pp_assigns (pp_register_chain ~indirect:false mem)) |
|
1637 |
insts |
|
1610 |
(pp_assigns (pp_reg ~indirect:false mem)) |
|
1611 |
stateful_insts |
|
1638 | 1612 |
(pp_assigns (pp_reset_flag_chain ~indirect:false mem)) |
1639 |
insts'')
|
|
1613 |
insts_no_arrow)
|
|
1640 | 1614 |
fmt |
1641 | 1615 |
() |
1642 | 1616 |
|
... | ... | |
1737 | 1711 |
|
1738 | 1712 |
let pp_main_loop_invariants main_mem machines fmt m = |
1739 | 1713 |
let name = m.mname.node_id in |
1740 |
let insts = powerset_instances (instances machines m) in
|
|
1714 |
let insts = instances machines m in
|
|
1741 | 1715 |
pp_acsl_cut |
1742 | 1716 |
(fun fmt () -> |
1743 | 1717 |
fprintf |
... | ... | |
1937 | 1911 |
mpformula = sanitize_formula mp.mpformula |
1938 | 1912 |
} |
1939 | 1913 |
|
1940 |
let sanitize_memory_packs = List.map sanitize_memory_pack
|
|
1914 |
let sanitize_memory_packs (n, mps) = n, List.map sanitize_memory_pack mps
|
|
1941 | 1915 |
|
1942 | 1916 |
let sanitize_spec s = |
1943 | 1917 |
{ s with |
src/machine_code.ml | ||
---|---|---|
185 | 185 |
(* Step instructions *) |
186 | 186 |
s : instr_t list; |
187 | 187 |
(* Memory pack spec *) |
188 |
mp : mc_formula_t list;
|
|
188 |
mp : (int * mc_formula_t) list;
|
|
189 | 189 |
(* Transition spec *) |
190 | 190 |
t : |
191 | 191 |
(var_decl list |
... | ... | |
247 | 247 |
let outputs_pi = Lustre_live.inter_live_i_with id (i - 1) outputs in |
248 | 248 |
let locals_i = Lustre_live.inter_live_i_with id i locals in |
249 | 249 |
let outputs_i = Lustre_live.inter_live_i_with id i outputs in |
250 |
let pred_mp ctx a = And [ mk_memory_pack ~i:(i - 1) id; a ] :: ctx.mp in |
|
250 |
let pred_mp ctx a = |
|
251 |
let j = try fst (List.hd ctx.mp) with _ -> 0 in |
|
252 |
match a with |
|
253 |
| Some a -> (i, And [ mk_memory_pack ~i:j id; a ]) :: ctx.mp |
|
254 |
| None -> ctx.mp |
|
255 |
in |
|
251 | 256 |
let pred_t ctx a = |
252 | 257 |
( inputs @ locals_i @ outputs_i, |
253 | 258 |
ctx.m, |
... | ... | |
273 | 278 |
{ |
274 | 279 |
inst with |
275 | 280 |
instr_spec = |
276 |
(if fst (get_stateless_status_node nd) then [] |
|
281 |
(if fst (get_stateless_status_node nd) || spec_mp = None then []
|
|
277 | 282 |
else [ mk_memory_pack ~i id ]) |
278 | 283 |
@ [ |
279 | 284 |
mk_transition |
... | ... | |
308 | 313 |
let ctx = |
309 | 314 |
ctl |
310 | 315 |
(MStep ([ var_x ], inst, [ c1; c2 ])) |
311 |
(mk_memory_pack ~inst (node_name td))
|
|
316 |
(Some (mk_memory_pack ~inst (node_name td)))
|
|
312 | 317 |
(mk_transition ~inst false (node_name td) [ vdecl_to_val var_x ]) |
313 | 318 |
{ ctx with j = IMap.add inst (td, []) ctx.j } |
314 | 319 |
in |
... | ... | |
318 | 323 |
let e = translate_expr e in |
319 | 324 |
ctl |
320 | 325 |
(MStateAssign (var_x, e)) |
321 |
(mk_state_variable_pack var_x)
|
|
326 |
(Some (mk_state_variable_pack var_x))
|
|
322 | 327 |
(mk_state_assign_tr var_x e) |
323 | 328 |
{ ctx with m = ISet.add x ctx.m } |
324 | 329 |
| [ x ], Expr_fby (e1, e2) when env.is_local x -> |
... | ... | |
327 | 332 |
let ctx = |
328 | 333 |
ctl |
329 | 334 |
(MStateAssign (var_x, e2)) |
330 |
(mk_state_variable_pack var_x)
|
|
335 |
(Some (mk_state_variable_pack var_x))
|
|
331 | 336 |
(mk_state_assign_tr var_x e2) |
332 | 337 |
{ ctx with m = ISet.add x ctx.m } |
333 | 338 |
in |
... | ... | |
356 | 361 |
let stateless = Stateless.check_node node_f in |
357 | 362 |
let inst = if stateless then None else Some i in |
358 | 363 |
let mp = |
359 |
if stateless then True else mk_memory_pack ?inst (node_name node_f)
|
|
364 |
if stateless then None else Some (mk_memory_pack ?inst (node_name node_f))
|
|
360 | 365 |
in |
361 | 366 |
let ctx = |
362 | 367 |
ctl |
... | ... | |
387 | 392 |
try |
388 | 393 |
let var_x = env.get_var x in |
389 | 394 |
let instr, spec = translate_act (var_x, eq.eq_rhs) in |
390 |
control_on_clock eq.eq_rhs.expr_clock instr True spec ctx
|
|
395 |
control_on_clock eq.eq_rhs.expr_clock instr None spec ctx
|
|
391 | 396 |
with Not_found -> |
392 | 397 |
Format.eprintf "ERROR: node %s, eq %a@." id Printers.pp_node_eq eq; |
393 | 398 |
raise Not_found) |
... | ... | |
609 | 614 |
(* Build the machine *) |
610 | 615 |
let mmap = IMap.bindings ctx.j in |
611 | 616 |
let mmemory_packs = |
617 |
let i = try fst (List.hd ctx.mp) with _ -> 0 in |
|
618 |
i, |
|
612 | 619 |
memory_pack_0 nd |
613 |
:: List.mapi
|
|
614 |
(fun i f -> { mpname = nd; mpindex = Some (i + 1); mpformula = red f })
|
|
620 |
:: List.map |
|
621 |
(fun (i, f) -> { mpname = nd; mpindex = Some i; mpformula = red f })
|
|
615 | 622 |
(List.rev ctx.mp) |
616 |
@ [ memory_pack_toplevel nd (List.length ctx.mp) ]
|
|
623 |
@ [ memory_pack_toplevel nd i ]
|
|
617 | 624 |
in |
618 | 625 |
let mtransitions = |
619 | 626 |
transition_0 nd |
src/machine_code_common.ml | ||
---|---|---|
344 | 344 |
| Some (Contract spec) -> |
345 | 345 |
pp_mspec m fmt spec) |
346 | 346 |
(pp_memory_packs m) |
347 |
m.mspec.mmemory_packs
|
|
347 |
(snd m.mspec.mmemory_packs)
|
|
348 | 348 |
(pp_transitions m) |
349 | 349 |
m.mspec.mtransitions |
350 | 350 |
(pp_print_list Printers.pp_expr_annot) |
... | ... | |
449 | 449 |
]; |
450 | 450 |
step_asserts = []; |
451 | 451 |
}; |
452 |
mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = [] }; |
|
452 |
mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = -1, [] };
|
|
453 | 453 |
mannot = []; |
454 | 454 |
msch = None; |
455 | 455 |
mis_contract = false; |
... | ... | |
492 | 492 |
step_instrs = []; |
493 | 493 |
step_asserts = []; |
494 | 494 |
}; |
495 |
mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = [] }; |
|
495 |
mspec = { mnode_spec = None; mtransitions = []; mmemory_packs = -1, [] };
|
|
496 | 496 |
mannot = []; |
497 | 497 |
msch = None; |
498 | 498 |
mis_contract = false; |
src/machine_code_types.mli | ||
---|---|---|
66 | 66 |
type machine_spec = { |
67 | 67 |
mnode_spec : mc_contract_t node_spec_t option; |
68 | 68 |
mtransitions : mc_transition_t list; |
69 |
mmemory_packs : mc_memory_pack_t list; |
|
69 |
mmemory_packs : int * mc_memory_pack_t list;
|
|
70 | 70 |
} |
71 | 71 |
|
72 | 72 |
type machine_t = { |
Also available in: Unified diff
more compact assign clauses for state variables, and remove useless memory pack predicates and assertions