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 |
Also available in: Unified diff
more compact assign clauses for state variables, and remove useless memory pack predicates and assertions