let switch env e cases p_def =
let rec add_id ids new_id = match ids with [] -> [new_id]
| id::other_ids -> let cmp = WpPropId.compare_prop_id new_id id in
if cmp = 0 then ids
else if cmp < 0 then new_id::ids
else id::(add_id other_ids new_id)
in
let collect_id ids g = add_id ids g.g_id in
let collect_ids ids (_, lp) = List.fold_left collect_id ids lp in
let ids = List.map (fun g -> g.g_id) p_def in
let ids = List.fold_left collect_ids ids cases in
let get_p_id id goals =
try
let g =
List.find (fun g -> WpPropId.compare_prop_id id g.g_id = 0) goals
in g.g_prop
with Not_found -> W.empty
in
let get_descr_id id =
let add_goal acc g =
if WpPropId.compare_prop_id id g.g_id = 0 then g.g_descr::acc
else acc
in
let add_goals = List.fold_left add_goal in
let acc = add_goals [] p_def in
List.fold_left (fun acc (_, gs) -> add_goals acc gs) acc cases
in
let process_id id =
let id_p_def = get_p_id id p_def in
let id_cases =
List.map (fun (cond, lp) -> (cond, get_p_id id lp)) cases
in
let f () = W.switch env e id_cases id_p_def in
let d = get_descr_id id in
make_goal id f d
in List.map process_id ids