(* File: algdt_pp.ml AIFAD - Automated Induction of Functions over Algebraic Datatypes Author: Markus Mottl email: markus.mottl@gmail.com WWW: http://www.ocaml.info Copyright (C) 2002 Austrian Research Institute for Artificial Intelligence Copyright (C) 2003- Markus Mottl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) (* $Id: algdt_pp.ml,v 1.14 2006/01/17 00:23:37 mottl Exp $ *) open Format open Utils open Algdt_types (* Utility functions *) let pp_open_par_box ppf () = pp_print_char ppf '('; pp_open_box ppf 0 let pp_close_par_box ppf () = pp_close_box ppf (); pp_print_char ppf ')' let pp_par_left ppf is_arg = if is_arg then pp_print_char ppf '(' let pp_par_right ppf is_arg = if is_arg then pp_print_char ppf ')' (* Specification pretty-printer *) let rec pp_prod ppf p = fprintf ppf "@ *@ %a" pp_prod_el p and pp_prods ppf ps = array_iter1 (pp_prod ppf) ps and pp_prod_el ppf = function | TpVal tp_name -> pp_print_string ppf tp_name | ProdEls ps -> fprintf ppf "(@[%a%a@])" pp_prod_el ps.(0) pp_prods ps let pp_sum_el ppf = function | Atom tag -> pp_print_string ppf tag | Strct (tag, prod_el) -> fprintf ppf "%s@ @[%a@]" tag pp_prod_el prod_el let pp_sum ppf sum_el = fprintf ppf "@ @[|@ %a@]" pp_sum_el sum_el let pp_sums ppf sums = array_iter1 (pp_sum ppf) sums let pp_type_def ppf (lhs, rhs) = match rhs with | Prod prod_el -> fprintf ppf "@\n%s = @[%a@]." lhs pp_prod_el prod_el | Sums ss -> fprintf ppf "@\n%s @[= %a%a@]." lhs pp_sum_el ss.(0) pp_sums ss let pp_type_defs ppf type_defs = Array.iter (pp_type_def ppf) type_defs (* Generic data pretty-printer *) module type DATA_PP_SPEC = sig type tag val pp_tag : formatter -> tag -> unit end module type DATA_PP = sig type tag val pp_data_el : formatter -> tag data -> unit val pp_data : formatter -> tag data -> unit val pp_sum : formatter -> tag dsum -> unit val pp_sum_arg : formatter -> tag dsum -> unit val pp_prod_els : formatter -> tag dsum prod_els -> unit end module Make_Data (Spec : DATA_PP_SPEC) = struct type tag = Spec.tag let rec pp_dprod ppf d = fprintf ppf ",@ %a" pp_data_el d and pp_dprods ppf prod_els = array_iter1 (pp_dprod ppf) prod_els and pp_prod_els ppf prod_els = fprintf ppf "(@[%a%a@])" pp_data_el prod_els.(0) pp_dprods prod_els and pp_data_el ppf = pp_data_el_ false ppf and pp_arg ppf = pp_data_el_ true ppf and pp_sum ppf = pp_sum_ false ppf and pp_sum_arg ppf = pp_sum_ true ppf and pp_sum_ is_arg ppf = function | DAtom tag -> Spec.pp_tag ppf tag | DStrct (tag, arg) -> fprintf ppf "%a@[<2>%a@ %a@]%a" pp_par_left is_arg Spec.pp_tag tag pp_arg arg pp_par_right is_arg and pp_data_el_ is_arg ppf = function | TpVal sum -> pp_sum_ is_arg ppf sum | ProdEls prod_els -> pp_prod_els ppf prod_els let pp_data ppf d = fprintf ppf "@[<2>%a@]." pp_data_el d end let pp_sample dpp cpp ppf (d, c) = fprintf ppf "@[<2>%a ->@ %a@]." dpp d cpp c (* Data pretty-printer *) module Data_Spec = struct type tag = cnstr_name let pp_tag = pp_print_string end module Data = struct include Make_Data (Data_Spec) let pp_sample = pp_sample pp_data_el pp_data_el end (* Generic data pretty-printer (immediate representation) *) module type IDATA_META_SPEC = sig val cnstr_tbl : cnstr_tbl end module Make_IData_Spec (Spec : IDATA_META_SPEC) = struct type tag = tp * cnstr let pp_tag ppf (tp, cnstr) = pp_print_string ppf Spec.cnstr_tbl.(tp).(cnstr) end module Make_IData (IData_Meta_Spec : IDATA_META_SPEC) = Make_Data (Make_IData_Spec (IData_Meta_Spec)) module Make_IData2 (DIData_Meta_Spec : IDATA_META_SPEC) (CIData_Meta_Spec : IDATA_META_SPEC) = struct module D = Make_Data (Make_IData_Spec (DIData_Meta_Spec)) module C = Make_Data (Make_IData_Spec (CIData_Meta_Spec)) let pp_sample = pp_sample D.pp_data_el C.pp_data_el end