let rec p_bind ?pool x e p =
let prec = p_bind ?pool x e in
let erec = e_bind ?pool x e in
match p with
| Ptrue | Pfalse -> p
| Prel(f,ts) -> p_prim f (List.map erec ts)
| Pcall(p,ts) -> Pcall(p,List.map erec ts)
| Pimplies(p,q) -> p_implies (prec p) (prec q)
| Pcond(a,p,q) -> p_cond (erec a) (prec p) (prec q)
| Pand(p,q) -> p_and (prec p) (prec q)
| Por(p,q) -> p_or (prec p) (prec q)
| Piff(p,q) -> p_iff (prec p) (prec q)
| Pnot(p) -> p_not (prec p)
| Pnamed(a,p) -> Pnamed(a,prec p)
| Pforall(x0,p) as p0 ->
begin
if VAR.equal x x0 then p0
else if e_hasvar [x0] e then
match pool with
| None -> Plet(x,e,p0)
| Some thepool ->
let y = VAR.freshen thepool x in
let py = p_bind ?pool x0 (Tvar y) p in
PRED.p_forall y (prec py)
else PRED.p_forall x0 (prec p)
end
| Pexists(x0,p) as p0 ->
begin
if VAR.equal x x0 then p0
else if e_hasvar [x0] e then
match pool with
| None -> Plet(x,e,p0)
| Some thepool ->
let y = VAR.freshen thepool x in
let py = p_bind ?pool x0 (Tvar y) p in
PRED.p_exists y (prec py)
else PRED.p_exists x0 (prec p)
end
| Plet(x0,t,p) as p0 ->
begin
if e_hasvar [x0] e then
match pool with
| None -> Plet(x,e,p0)
| Some thepool ->
let y = VAR.freshen thepool x in
let py = p_bind ?pool x0 (Tvar y) p in
p_let ?pool y (erec t) (prec py)
else
let p' = if VAR.equal x0 x then p else prec p in
p_let ?pool x0 (erec t) p'
end
and p_let ?pool x a p =
if p_hasvar [x] p then
if is_atomic a then p_bind ?pool x a p else Plet(x,a,p)
else p