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