let rec e_rename s t =
  match t with
    | Fol.Tconst _ -> t
    | Fol.Tvar x ->
        ( match apply s x with
            | None -> t
            | Some y -> Fol.e_var y )
    | Fol.Tapp(f,ts) -> Fol.e_app f (List.map (e_rename s) ts)
    | Fol.Taccess(t,i) -> e_access (e_rename s t) (e_rename s i)
    | Fol.Tupdate(t,i,v) -> e_update (e_rename s t) (e_rename s i) (e_rename s v)
    | Fol.Tgetfield(f,r) -> e_getfield f (e_rename s r)
    | Fol.Tsetfield(f,r,v) -> e_setfield f (e_rename s r) (e_rename s v)
    | Fol.Tif(a,b,c) -> Fol.e_if (e_rename s a) (e_rename s b) (e_rename s c)
    | Fol.Tlet(y,a,b) ->
        let a' = e_rename s a in
        let s' = (y,y)::s in (* defensive ! *)
        Fol.e_let y a' (e_rename s' b)