let subst_havoc env assigned = match assigned with
      | D.Aloc(_t_elem,loc) ->
          let tau = D.tau_of_object _t_elem in
          let out = D.fresh "out" (Mdata.Vmodel tau) in
          let exp = F.term_of_var out in
          let m = mem_at env Clabels.Here in
          let x, _f_obj_n, f_mu = mk_mu m loc in
          let newterm (sigma : D.substitution) : Formula.abstract F.term =
            let obj_0 = D.apply sigma (var_data_term m x) in
            let obj_0 = F.data_of_term obj_0 in
            let obj_0 = f_mu obj_0 (Some exp) in
            let exp = match obj_0 with None -> assert false
              | Some exp -> exp
            in
            debug3 "[subst_havoc:newterm] = %a@." F.pp_term exp;
              exp
          in
          let x = get_var m x in
            [D.Fresh out ; D.Update (x,newterm)]
      | D.Arange (_t_elem, lval, rg) ->
            let m = mem_at env Clabels.Here in
            let t = ctype_of_data lval in
            let t = Ctypes.object_of t in
            let is_array = match Ctypes.object_of_pointed t with 
              | Ctypes.C_array _ -> true | _ -> false in
            let lval = if is_array then lval else F.addr_of_data lval in
            let x, f_obj_n, f_mu = mk_mu m lval in
            let upd_range x rg = 
              if is_array then F.mk_mu_range x (F.unwrap (D.interval rg))
              else F.mk_mu_range_indir x (F.unwrap (D.interval rg))
            in
            let newterm (sigma : D.substitution) : Formula.abstract F.term =
              let obj_0 = D.apply sigma (var_data_term m x) in
              let obj_0 = F.data_of_term obj_0 in
              let obj_n = f_obj_n obj_0 in
              let exp = upd_range obj_n rg in
              let exp = F.term_of_data exp in
              let exp = f_mu obj_0 (Some exp) in
                match exp with None -> assert false
                  | Some exp -> exp
            in
            let x = get_var m x in
              [D.Update(x,newterm)]