let rec pp_pred pp_term fmt p = 
  let predicate = pp_pred pp_term in
    match p with
  | Pvar id | Papp (id, [])->
      fprintf fmt "%s" id
  | Papp ("eq", [t1; t2]) ->
      fprintf fmt "(%a =@ %a)" pp_term t1 pp_term t2
  | Papp ("neq", [t1; t2]) ->
      fprintf fmt "(%a <>@ %a)" pp_term t1 pp_term t2
  | Papp (id, l) ->
      fprintf fmt "%s(%a)" id (print_list comma pp_term) l
  | Ptrue ->
      fprintf fmt "true"
  | Pfalse ->
      fprintf fmt "false"
  | Pimplies (a, b) ->
      fprintf fmt "(@[%a ->@ %a@])" predicate a predicate b
  | Piff (a, b) ->
      fprintf fmt "(@[%a <->@ %a@])" predicate a predicate b
  | Pif (a, b, c) ->
      fprintf fmt "(@[if %a then@ %a else@ %a@])"
        pp_term a predicate b predicate c
  | Pand (a, b) ->
      fprintf fmt "(@[%a and@ %a@])" predicate a predicate b
  | Por (a, b) ->
      fprintf fmt "(@[%a or@ %a@])" predicate a predicate b
  | Pxor (_a,_b) -> assert false (* writeme *)
  | Pnot a ->
      fprintf fmt "(not %a)" predicate a
  | Pforall (v,p) ->
      fprintf fmt "@[<hov 2>(forall %a:%a.@ %a)@]"
        pp_var v pp_var_type v predicate p
  | Pexists (v,p) ->
      fprintf fmt "@[<hov 2>(exists %a:%a.@ %a)@]"
        pp_var v pp_var_type v predicate p
  | Plet (x,v,p) ->
      fprintf fmt "@[<hov 2>(let %a@ = %a in@ %a)@]"
        pp_var x pp_term v predicate p
  | Pnamed (n, p) ->
      fprintf fmt "@[%s: %a@]" n predicate p