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 m_here = L.mem_at env Clabels.Here in
         let typ_e = Cil.typeOf e in
         let int_e = case_of_exp m_here e in
         let t = WpModel.tau_of_object (Ctypes.object_of typ_e) in
         let var_e = D.fresh "k" (Formula.Acsl(t,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)