let switch env e wp_cases wp_def =
let cases = List.map (fun (es,wp) -> es , zip wp) wp_cases in
let p_def = zip wp_def in
let assigns =
List.fold_left
(fun ak (_es,wp) -> merge_assigns ak (fst wp))
(fst wp_def) wp_cases in
let wpe = assigns , { (snd empty) with property = p_def } in
on_context env "swith" wpe Keep_opened Keep_assigns
(fun env _assigns _true ->
let frame = L.get_frame env in
let m_here = WpModel.mem_at frame Clabels.Here in
let typ_e = Cil.typeOf e in
let int_e = case_of_exp m_here e in
let var_e = D.fresh "k" (Mdata.Vacsl(Ctype typ_e)) in
let val_e = F.var var_e in
let (default,cases) =
List.fold_left
(fun (default,cases) (es_case,p_case) ->
let ks = List.map (case_of_exp m_here) es_case in
let hs = F.p_disj (List.map (F.p_eq val_e) ks) in
let ds = F.p_conj (List.map (F.p_neq val_e) ks) in
F.p_and ds default ,
F.p_and (F.p_implies hs p_case) cases
) (F.p_true , F.p_true) cases
in
let wp_switch = F.p_and cases (F.p_implies default p_def) in
D.subst var_e int_e wp_switch)