let replacement_visitor replace_pre fa_terms ret_opt = object
  (* for each term, replace each logic_variable which
     stems from a C variable by the term corresponding
     to the variable at this point iff it is a formal *)


  inherit nopCilVisitor

  method vterm_node t =
    match t with
      | TConst _ | TSizeOf _ | TSizeOfStr _
      | TAlignOf _ | Tnull | Ttype _ | Tempty_set -> SkipChildren

      | TLval tlval -> treat_tlval fa_terms ret_opt LvalOrig tlval
      | TAddrOf tlval -> treat_tlval fa_terms ret_opt AddrOfOrig tlval
      | TStartOf _ (* [VP] Neither parameters nor returned value can be
                      an array in a C function. Hence, TStartOf can not have
                      \result or a formal as base.
                   *)

      | _ -> DoChildren

  method vlogic_label l =
    match l with
      | StmtLabel _ -> DoChildren
      | LogicLabel _ 
          when Cil_datatype.Logic_label.equal l Logic_const.pre_label ->
        ChangeDoChildrenPost(replace_pre, fun x->x)
      | LogicLabel _ -> DoChildren

end