let subst_havoc (frame:frame) = function
    | D.Aloc(_,Path(_,x,[],_)) ->
        let x = get_funvar (env_at frame.fframe Clabels.Here) x in
        let v = D.fresh "v" (D.vkind_of_var x) in
        [D.Fresh v;D.Update(x,fun _ -> F.var v)]
    | D.Aloc(_,Path(_,x,path,ty)) ->
        let x = get_funvar (env_at frame.fframe Clabels.Here) x in
        let v = D.fresh "v" (Vmodel (D.tau_of_object ty)) in
        let newterm (sigma : D.substitution) : abstract F.term =
          F.wrap ( update (fun _ -> F.var v) (D.apply sigma (F.var x)) path )
        in
        [D.Fresh v;D.Update(x,newterm)]
    | D.Arange(_,Path(_,x,path,_),rg) ->
        let x = get_funvar (env_at frame.fframe Clabels.Here) x in
        let upd_range rg = fun array ->
          F.wrap (D.set_range_index (F.unwrap array) rg)
        in
        let newterm (sigma : D.substitution) : abstract F.term =
          F.wrap (update (upd_range rg) (D.apply sigma (F.var x)) path)
        in
        [D.Update(x,newterm)]
    | D.Aloc(te,Mloc l) -> M.subst_havoc frame.mframe (D.Aloc(te,l))
    | D.Arange(te,Mloc l,rg) -> M.subst_havoc frame.mframe (D.Arange(te,l,rg))