let rec e_bind ?pool x e t =
let frec = e_bind ?pool x e in
match t with
| Tvar x0 -> if VAR.equal x0 x then e else t
| Ttrue | Tfalse | Tint _ | Treal _ -> t
| Tcall(f,ts) -> Tcall(f,List.map frec ts)
| Tprim(p,ts) -> e_prim p (List.map frec ts)
| Tif(a,b,c) -> e_cond (frec a) (frec b) (frec c)
| Tgetfield(r,f) -> e_getfield (frec r) f
| Tsetfield(r,f,v) -> e_setfield (frec r) f (frec v)
| Taccess(r,k) -> e_access (frec r) (frec k)
| Tupdate(r,k,v) -> e_update (frec r) (frec k) (frec v)
| Tlet(x0,a,b) ->
begin
if e_hasvar [x0] e then
match pool with
| None -> Tlet(x,e,t)
| Some thepool ->
let y = VAR.freshen thepool x in
let b = e_bind ?pool x0 (Tvar y) b in
e_let ?pool y (frec a) (frec b)
else
let b' = if VAR.equal x0 x then b else frec b in
e_let ?pool x0 (frec a) b'
end
and e_let ?pool x a b =
if e_hasvar [x] b then
if is_atomic a then e_bind ?pool x a b else Tlet(x,a,b)
else b