let fpp_term term pp_data fmt t =
  match t with
    | Tconst c -> constant fmt c
    | Tvar v -> pp_var fmt v
    | Tdata d -> pp_data fmt d
    | Tapp (id, []) -> pp_print_string fmt id
    | Tapp ("ite",[c;a;b]) | Tif (c,a,b) ->
        fprintf fmt "(@[<v 0>if %a@ then %a@ else %a@])"
          term c term a term b
    | Tapp ("add_int", ts) ->
        let xs = collect_assoc "add_int" [] ts in
        pp_flow fmt "0" "+" term xs
    | Tapp ("sub_int", [a;b]) ->
        fprintf fmt "@[<hov 1>(%a@,-%a)@]" term a term b
    | Tapp ("mul_int", ts) ->
        let xs = collect_assoc "mul_int" [] ts in
        pp_flow fmt "1" "*" term xs
    | Tapp (id, t::ts) ->
        fprintf fmt "@[<hov 2>%s(@,%a" id term t ;
        List.iter (fun t -> fprintf fmt ",@,%a" term t) ts ;
        fprintf fmt ")@]"
    | Tlet (x,v,t) ->
        fprintf fmt "(@[<v 0>let %a@ = %a@ in %a@])"
          pp_var x term v term t