let fpp_pred predicate pp_term pp_type fmt p =
  match p with
    | Ptrue -> fprintf fmt "True"
    | Pfalse -> fprintf fmt "False"
    | 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 (pp_list pp_term) l
    | Pimplies (a, b) -> fprintf fmt "(@[%a ->@ %a@])" predicate a predicate b
    | Piff (a, b) -> fprintf fmt "(@[%a <->@ %a@])" predicate a predicate b
    | Pand (a, b) -> fprintf fmt "(@[%a /\\ @ %a@])" predicate a predicate b
    | Por (a, b) -> fprintf fmt "(@[%a \\/ @ %a@])" predicate a predicate b
    | Pnot a -> fprintf fmt "(~ %a)" predicate a
    | Pif (a, b, c) ->
        fprintf fmt "(@[if %a then@ %a else@ %a@])"
          pp_term a predicate b predicate c
    | Pforall (v,p) ->
        fprintf fmt "@[<hov 0>(forall (%a:%a),@ %a@])"
          pp_var v pp_type (Var.var_type v) predicate p
    | Pexists (v,p) ->
        fprintf fmt "@[<hov 0>(exists %a:%a,@ %a@])"
          pp_var v pp_type (Var.var_type v) predicate p
    | Plet (x,v,p) ->
        fprintf fmt "@[<hov 0>(let %a :=@[<hov 2>@ %a@ in@]@ %a@])"
          pp_var x pp_term v predicate p
    | Pnamed (n, p) ->
        fprintf fmt "@[(*%s:*) %a@]" n predicate p