let change_vars subst subst_res kf label pred =
  let add_label t = ChangeDoChildrenPost(t,fun t -> tat(t,label)) in
  let visitor =
    object
      inherit Visitor.frama_c_copy (Project.current())

      method vterm t =
        match t.term_node with
            TLval (TVar { lv_origin = Some v},_) when v.vglob -> add_label t
          | TLval (TMem _,_) -> add_label t
          | _ -> DoChildren

      method vterm_lhost = function
        | TResult ty ->
          (match kf with
              None -> Aorai_option.fatal
                "found \\result without being at a Return event"
            | Some kf ->
              (try
                 ChangeTo (TVar (Kernel_function.Hashtbl.find subst_res kf))
               with Not_found ->
                 let new_lv =
                   Cil_const.make_logic_var
                     ("__retres_" ^ (Kernel_function.get_name kf)) (Ctype ty)
                 in
                 Kernel_function.Hashtbl.add subst_res kf new_lv;
                 ChangeTo (TVar new_lv)))
        | TMem _ | TVar _ -> DoChildren

      method vlogic_var_use lv =
        match lv.lv_origin with
          | Some v when not v.vglob ->
            (try
               ChangeTo (Cil_datatype.Logic_var.Hashtbl.find subst lv)
             with Not_found ->
               let new_lv = Cil_const.make_logic_var lv.lv_name lv.lv_type in
               Cil_datatype.Logic_var.Hashtbl.add subst lv new_lv;
               ChangeTo new_lv)
          | Some _ | None -> DoChildren
    end
  in Visitor.visitFramacPredicate visitor pred