let fpp_pred predicate pp_tau pp_term fmt p =
  match p with
    | Fol.Ptrue -> Format.fprintf fmt "true"
    | Fol.Pfalse -> Format.fprintf fmt "false"
    | Fol.Papp (id, [])-> Format.fprintf fmt "%s" id
    | Fol.Papp ("eq", [t1; t2]) -> Format.fprintf fmt "(%a =@ %a)" pp_term t1 pp_term t2
    | Fol.Papp ("neq", [t1; t2]) -> Format.fprintf fmt "(%a <>@ %a)" pp_term t1 pp_term t2
    | Fol.Papp (id, l) -> Format.fprintf fmt "@[%s(%a)@]" id (pp_list pp_term) l
    | Fol.Pimplies (a, b) -> Format.fprintf fmt "(@[%a ->@ %a@])" predicate a predicate b
    | Fol.Piff (a, b) -> Format.fprintf fmt "(@[%a <->@ %a@])" predicate a predicate b
    | Fol.Pand (a, b) -> Format.fprintf fmt "(@[%a and@ %a@])" predicate a predicate b
    | Fol.Por (a, b) -> Format.fprintf fmt "(@[%a or@ %a@])" predicate a predicate b
    | Fol.Pnot a -> Format.fprintf fmt "(not %a)" predicate a
    | Fol.Pif (a, b, c) ->
        Format.fprintf fmt "(@[if %a then@ %a else@ %a@])"
          pp_term a predicate b predicate c
    | Fol.Pforall (v,p) ->
        Format.fprintf fmt "@[<hov 0>(forall %a:%a.@ %a@])"
          pp_var v pp_tau (Fol.Var.var_type v) predicate p
    | Fol.Pexists (v,p) ->
        Format.fprintf fmt "@[<hov 0>(exists %a:%a.@ %a@])"
          pp_var v  pp_tau (Fol.Var.var_type v) predicate p
    | Fol.Plet (x,v,p) ->
        Format.fprintf fmt "@[<hov 0>(let %a =@[<hov 2>@ %a@ in@]@ %a@])"
          pp_var x pp_term v predicate p
    | Fol.Pnamed (n, p) ->
        Format.fprintf fmt "@[%s: %a@]" (tag_named n) predicate p