let wp_loop g annots res nloop e get_loop_head get_vloop_effects =
if WpAnnot.new_loop_computation annots.WpAnnot.info then
begin
let has_inv () =
let _loops, edges = Cil2cfg.loop_node_edges g nloop in
(*if loops <> [] then
(Wp_parameters.debug ~level:3 "Nested loop not handled yet"; (*TODO*)false)
else*)
let inv_edges = annots.WpAnnot.has_inv_prop in
let has_inv =
List.exists (fun e -> Cil2cfg.Eset.mem e edges) inv_edges
in if has_inv then
Wp_parameters.debug ~level:3 "Inv inside loop detected";
has_inv
in match res.mode, Cil2cfg.is_back_edge e with
| Pass1, false ->
let obj_loop_head = get_loop_head nloop in
let _ =
if has_inv () then
begin
let goal_edges = Cil2cfg.pred_e g nloop in
memo_goal_pass2 res obj_loop_head goal_edges;
(* let hyp_edges = Cil2cfg.succ_e g nloop in
memo_hyp_pass2 res obj_loop_head hyp_edges *)
end
else (* will be quantified *)
let loop_head_edges = Cil2cfg.succ_e g nloop in
memo_goal_pass2 res obj_loop_head loop_head_edges
in W.empty
| Pass1, true ->
(* back edge :
be careful not to use get_only_succ here
(infinite loop) *)
W.empty
| Pass2, false -> get_loop_head nloop
| Pass2, true -> W.empty
end
else (* old computation mode *)
if Cil2cfg.is_back_edge e then
(* back edge: nothing to compute,
* just propagate the invariant if any *)
(* be careful not to use get_only_succ here (infinite loop) *)
W.empty
else (* edge going into the loop from outside *)
let obj_loop_head = get_loop_head nloop in
match res.mode with
| Pass1 ->
(* take the property [obj] at loop head
* and put it as Goal to incoming edge and ad Hyp to the loop head edge.
* We can then continue with [empty].
* *)
let hyp_edges = Cil2cfg.succ_e g nloop in
memo_hyp_pass2 res obj_loop_head hyp_edges;
let goal_edges = Cil2cfg.pred_e g nloop in
let obj_loop_head = get_vloop_effects obj_loop_head in
memo_goal_pass2 res obj_loop_head goal_edges;
W.empty
| Pass2 -> (* just propagate *)
obj_loop_head