let rec term_lval_substitution ((host,offset):term_lval) (removel:string list) (addl:Cil_types.term_lhost list) =
  match host with
    | TVar(lv) ->
        let res= ref (host,offset) in
        List.iter2
          (fun r a -> if (String.compare r lv.lv_name)=0 then res:= (a,offset) )
          removel
          addl;
        !res
    | _  -> (host,offset)


and term_substitution (t:term) (removel:string list) (addl:Cil_types.term_lhost list) =
  let node = match t.term_node with
    |         TLval (tl)                   -> TLval          (term_lval_substitution tl removel addl)


    |         TSizeOfE t                   -> TSizeOfE       (term_substitution t removel addl)
    |         TAlignOfE t                  -> TAlignOfE      (term_substitution t removel addl)
    |         TUnOp (o,t)                  -> TUnOp          (o,term_substitution t removel addl)
    |         TBinOp (o,t1,t2)             -> TBinOp         (o,
                                                        term_substitution t1 removel addl,
                                                        term_substitution t2 removel addl)
    |         TCastE (ty,t)                -> TCastE         (ty,term_substitution t removel addl)
    |         TAddrOf tl                   -> TAddrOf        (term_lval_substitution tl removel addl)
    |         TStartOf tl                  -> TStartOf       (term_lval_substitution tl removel addl)
    |         Tapp (li,lll,tl)             -> Tapp           (li,lll,term_list_substitution tl removel addl)
    |         Tlambda(q,t)                 -> Tlambda        (q,term_substitution t removel addl)
    |         TDataCons (l,tl)             -> TDataCons      (l,term_list_substitution tl removel addl)
    |         Tif (t1,t2,t3)               -> Tif            (term_substitution t1 removel addl,
                                                        term_substitution t2 removel addl,
                                                        term_substitution t3 removel addl)
    |         Told (t)                     -> Told           (term_substitution t removel addl)
    |         Tat (t,ll)                   -> Tat            (term_substitution t removel addl,ll)
    |         Tbase_addr (t)               -> Tbase_addr     (term_substitution t removel addl)
    |         Tblock_length (t)            -> Tblock_length  (term_substitution t removel addl)
    |         TCoerce (t,ty)               -> TCoerce        (term_substitution t removel addl,ty)
    |         TCoerceE (t1,t2)             -> TCoerceE       (term_substitution t1 removel addl,
                                                        term_substitution t2 removel addl)
    |         TUpdate (t1,fi,t2)           -> TUpdate        (term_substitution t1 removel addl,
                                                        fi,
                                                        term_substitution t2 removel addl)
    |         Ttypeof (t)                  -> Ttypeof        (term_substitution t removel addl)
    |         Tunion (tl)                  -> Tunion         (term_list_substitution tl removel addl)
    |         Tinter (tl)                  -> Tinter         (term_list_substitution tl removel addl)
    |         Tcomprehension (t,q,Some(p)) -> Tcomprehension (term_substitution t removel addl,
                                                        q,
                                                        Some(named_predicate_substitution p removel addl))
    |         Tcomprehension (t,q,None)    -> Tcomprehension (term_substitution t removel addl,
                                                        q,
                                                        None)
    |         Trange (Some(t),None)        -> Trange         (Some(term_substitution t removel addl),
                                                        None)
    |         Trange (None,Some(t))        -> Trange         (None,
                                                        Some(term_substitution t removel addl))
    |         Trange (None,None)           -> Trange         (None,None)
    |         Trange (Some(t1),Some(t2))   -> Trange         (Some(term_substitution t1 removel addl),
                                                        Some(term_substitution t2 removel addl))

    |         Tlet (li,t)                  -> Tlet           (li,term_substitution t removel addl)


    |         TConst _
    |         TSizeOfStr _
    |         TAlignOf _
    |         Tnull
    |         Ttype _
    |         Tempty_set
    |         TSizeOf _ as c               -> c

  in
  {term_node=node ; term_loc=t.term_loc ; term_type=t.term_type ; term_name=t.term_name}


and term_list_substitution (tl:term list) (removel:string list) (addl:Cil_types.term_lhost list) =
  List.fold_left
    (fun lt t -> (term_substitution t removel addl)::lt)
    []
    tl


and named_predicate_substitution (npred:predicate named) (removel:string list) (addl:Cil_types.term_lhost list) =
  { name    = npred.name ;
    loc     = npred.loc ;
    content = predicate_substitution npred.content removel addl}


and predicate_substitution (pred:predicate) (removel:string list) (addl:Cil_types.term_lhost list) =
  match pred with
    |         Pfalse
    |         Ptrue as p -> p

    |         Papp (li, l, term_list) -> Papp         (li, l,(term_list_substitution term_list removel addl))
    |         Pseparated term_list    -> Pseparated   (term_list_substitution term_list removel addl)
    |         Prel (relation,t1,t2)   -> Prel         (relation,
                                                 term_substitution t1 removel addl,
                                                 term_substitution t2 removel addl)

    |         Pand     (p1,p2)        -> Pand         (named_predicate_substitution p1 removel addl,
                                                 named_predicate_substitution p2 removel addl)
    |         Por      (p1,p2)        -> Por          (named_predicate_substitution p1 removel addl,
                                                 named_predicate_substitution p2 removel addl)
    |         Pxor     (p1,p2)        -> Pxor         (named_predicate_substitution p1 removel addl,
                                                 named_predicate_substitution p2 removel addl)
    |         Pimplies (p1,p2)        -> Pimplies     (named_predicate_substitution p1 removel addl,
                                                 named_predicate_substitution p2 removel addl)
    |         Piff     (p1,p2)        -> Piff         (named_predicate_substitution p1 removel addl,
                                                 named_predicate_substitution p2 removel addl)

    |         Pnot (p)                -> Pnot         (named_predicate_substitution p removel addl)

    |         Pif (t,p1,p2)           -> Pif          (term_substitution t removel addl,
                                                 named_predicate_substitution p1 removel addl,
                                                 named_predicate_substitution p2 removel addl)


    |         Plet (li,p)             -> Plet         (li,
                                                 named_predicate_substitution p removel addl)
    |         Pforall (q,p)           -> Pforall      (q,
                                                  named_predicate_substitution p removel addl)
    |         Pexists (q,p)           -> Pexists      (q,
                                                  named_predicate_substitution p removel addl)
    |         Pold (p)                -> Pold         (named_predicate_substitution p removel addl)

    |         Pat (p,l)               -> Pat          (named_predicate_substitution p removel addl,l)
    |         Pvalid (t)              -> Pvalid       (term_substitution t removel addl)
    |         Pvalid_index (t1,t2)    -> Pvalid_index (term_substitution t1 removel addl,
                                                  term_substitution t2 removel addl)
    |         Pvalid_range (t1,t2,t3) -> Pvalid_range (term_substitution t1 removel addl,
                                                 term_substitution t2 removel addl,
                                                 term_substitution t3 removel addl)

    |         Pfresh (t)              -> Pfresh       (term_substitution t removel addl)
    |         Psubtype (t1,t2)        -> Psubtype     (term_substitution t1 removel addl,
                                                  term_substitution t2 removel addl)