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)]