src/Tools/Code/code_ml.ML
changeset 82380 ceb4f33d3073
parent 81870 a4c0f9d12440
child 82447 741f6f6df144
equal deleted inserted replaced
82379:3f875966c3e1 82380:ceb4f33d3073
    40   | ML_Datas of (string * (vname list * ((string * vname list) * itype list) list)) list
    40   | ML_Datas of (string * (vname list * ((string * vname list) * itype list) list)) list
    41   | ML_Class of string * (vname * ((class * class) list * (string * itype) list));
    41   | ML_Class of string * (vname * ((class * class) list * (string * itype) list));
    42 
    42 
    43 fun print_product _ [] = NONE
    43 fun print_product _ [] = NONE
    44   | print_product print [x] = SOME (print x)
    44   | print_product print [x] = SOME (print x)
    45   | print_product print xs = (SOME o enum " *" "" "") (map print xs);
    45   | print_product print xs = (SOME o Pretty.enum " *" "" "") (map print xs);
    46 
    46 
    47 fun tuplify _ _ [] = NONE
    47 fun tuplify _ _ [] = NONE
    48   | tuplify print fxy [x] = SOME (print fxy x)
    48   | tuplify print fxy [x] = SOME (print fxy x)
    49   | tuplify print _ xs = SOME (enum "," "(" ")" (map (print NOBR) xs));
    49   | tuplify print _ xs = SOME (Pretty.enum "," "(" ")" (map (print NOBR) xs));
    50 
    50 
    51 
    51 
    52 (** SML serializer **)
    52 (** SML serializer **)
    53 
    53 
    54 fun print_sml_char c =
    54 fun print_sml_char c =
    63 fun print_sml_stmt tyco_syntax const_syntax reserved is_constr deresolve =
    63 fun print_sml_stmt tyco_syntax const_syntax reserved is_constr deresolve =
    64   let
    64   let
    65     val deresolve_const = deresolve o Constant;
    65     val deresolve_const = deresolve o Constant;
    66     val deresolve_classrel = deresolve o Class_Relation;
    66     val deresolve_classrel = deresolve o Class_Relation;
    67     val deresolve_inst = deresolve o Class_Instance;
    67     val deresolve_inst = deresolve o Class_Instance;
    68     fun print_tyco_expr (sym, []) = (str o deresolve) sym
    68     fun print_tyco_expr (sym, []) = (Pretty.str o deresolve) sym
    69       | print_tyco_expr (sym, [ty]) =
    69       | print_tyco_expr (sym, [ty]) =
    70           concat [print_typ BR ty, (str o deresolve) sym]
    70           concat [print_typ BR ty, (Pretty.str o deresolve) sym]
    71       | print_tyco_expr (sym, tys) =
    71       | print_tyco_expr (sym, tys) =
    72           concat [enum "," "(" ")" (map (print_typ BR) tys), (str o deresolve) sym]
    72           concat [Pretty.enum "," "(" ")" (map (print_typ BR) tys), (Pretty.str o deresolve) sym]
    73     and print_typ fxy (tyco `%% tys) = (case tyco_syntax tyco
    73     and print_typ fxy (tyco `%% tys) = (case tyco_syntax tyco
    74          of NONE => print_tyco_expr (Type_Constructor tyco, tys)
    74          of NONE => print_tyco_expr (Type_Constructor tyco, tys)
    75           | SOME (_, print) => print print_typ fxy tys)
    75           | SOME (_, print) => print print_typ fxy tys)
    76       | print_typ fxy (ITyVar v) = str ("'" ^ v);
    76       | print_typ fxy (ITyVar v) = Pretty.str ("'" ^ v);
    77     fun print_dicttyp (class, ty) = print_tyco_expr (Type_Class class, [ty]);
    77     fun print_dicttyp (class, ty) = print_tyco_expr (Type_Class class, [ty]);
    78     fun print_typscheme_prefix (vs, p) = enum " ->" "" ""
    78     fun print_typscheme_prefix (vs, p) = Pretty.enum " ->" "" ""
    79       (map_filter (fn (v, sort) =>
    79       (map_filter (fn (v, sort) =>
    80         (print_product (fn class => print_dicttyp (class, ITyVar v)) sort)) vs @| p);
    80         (print_product (fn class => print_dicttyp (class, ITyVar v)) sort)) vs @| p);
    81     fun print_typscheme (vs, ty) = print_typscheme_prefix (vs, print_typ NOBR ty);
    81     fun print_typscheme (vs, ty) = print_typscheme_prefix (vs, print_typ NOBR ty);
    82     fun print_dicttypscheme (vs, class_ty) = print_typscheme_prefix (vs, print_dicttyp class_ty);
    82     fun print_dicttypscheme (vs, class_ty) = print_typscheme_prefix (vs, print_dicttyp class_ty);
    83     fun print_classrels fxy [] ps = brackify fxy ps
    83     fun print_classrels fxy [] ps = brackify fxy ps
    84       | print_classrels fxy [classrel] ps = brackify fxy [(str o deresolve_classrel) classrel, brackify BR ps]
    84       | print_classrels fxy [classrel] ps = brackify fxy [(Pretty.str o deresolve_classrel) classrel, brackify BR ps]
    85       | print_classrels fxy classrels ps =
    85       | print_classrels fxy classrels ps =
    86           brackify fxy [enum " o" "(" ")" (map (str o deresolve_classrel) classrels), brackify BR ps]
    86           brackify fxy [Pretty.enum " o" "(" ")" (map (Pretty.str o deresolve_classrel) classrels), brackify BR ps]
    87     fun print_dict is_pseudo_fun fxy (Dict (classrels, x)) =
    87     fun print_dict is_pseudo_fun fxy (Dict (classrels, x)) =
    88       print_classrels fxy classrels (print_plain_dict is_pseudo_fun fxy x)
    88       print_classrels fxy classrels (print_plain_dict is_pseudo_fun fxy x)
    89     and print_plain_dict is_pseudo_fun fxy (Dict_Const (inst, dss)) =
    89     and print_plain_dict is_pseudo_fun fxy (Dict_Const (inst, dss)) =
    90           ((str o deresolve_inst) inst ::
    90           ((Pretty.str o deresolve_inst) inst ::
    91             (if is_pseudo_fun (Class_Instance inst) then [str "()"]
    91             (if is_pseudo_fun (Class_Instance inst) then [Pretty.str "()"]
    92             else map_filter (print_dicts is_pseudo_fun BR o snd) dss))
    92             else map_filter (print_dicts is_pseudo_fun BR o snd) dss))
    93       | print_plain_dict is_pseudo_fun fxy (Dict_Var { var, index, length, ... }) =
    93       | print_plain_dict is_pseudo_fun fxy (Dict_Var { var, index, length, ... }) =
    94           [str (if length = 1 then Name.enforce_case true var ^ "_"
    94           [Pretty.str (if length = 1 then Name.enforce_case true var ^ "_"
    95             else Name.enforce_case true var ^ string_of_int (index + 1) ^ "_")]
    95             else Name.enforce_case true var ^ string_of_int (index + 1) ^ "_")]
    96     and print_dicts is_pseudo_fun = tuplify (print_dict is_pseudo_fun);
    96     and print_dicts is_pseudo_fun = tuplify (print_dict is_pseudo_fun);
    97     val print_dict_args = map_filter (fn (v, sort) => print_dicts (K false) BR
    97     val print_dict_args = map_filter (fn (v, sort) => print_dicts (K false) BR
    98       (map_index (fn (i, _) => Dict ([],
    98       (map_index (fn (i, _) => Dict ([],
    99          Dict_Var { var = v, index = i, length = length sort, class = nth sort i, unique = true })) sort));
    99          Dict_Var { var = v, index = i, length = length sort, class = nth sort i, unique = true })) sort));
   100     fun print_term is_pseudo_fun some_thm vars fxy (IConst const) =
   100     fun print_term is_pseudo_fun some_thm vars fxy (IConst const) =
   101           print_app is_pseudo_fun some_thm vars fxy (const, [])
   101           print_app is_pseudo_fun some_thm vars fxy (const, [])
   102       | print_term is_pseudo_fun some_thm vars fxy (IVar NONE) =
   102       | print_term is_pseudo_fun some_thm vars fxy (IVar NONE) =
   103           str "_"
   103           Pretty.str "_"
   104       | print_term is_pseudo_fun some_thm vars fxy (IVar (SOME v)) =
   104       | print_term is_pseudo_fun some_thm vars fxy (IVar (SOME v)) =
   105           str (lookup_var vars v)
   105           Pretty.str (lookup_var vars v)
   106       | print_term is_pseudo_fun some_thm vars fxy (t as t1 `$ t2) =
   106       | print_term is_pseudo_fun some_thm vars fxy (t as t1 `$ t2) =
   107           (case Code_Thingol.unfold_const_app t
   107           (case Code_Thingol.unfold_const_app t
   108            of SOME app => print_app is_pseudo_fun some_thm vars fxy app
   108            of SOME app => print_app is_pseudo_fun some_thm vars fxy app
   109             | NONE => brackify fxy [print_term is_pseudo_fun some_thm vars NOBR t1,
   109             | NONE => brackify fxy [print_term is_pseudo_fun some_thm vars NOBR t1,
   110                 print_term is_pseudo_fun some_thm vars BR t2])
   110                 print_term is_pseudo_fun some_thm vars BR t2])
   111       | print_term is_pseudo_fun some_thm vars fxy (t as _ `|=> _) =
   111       | print_term is_pseudo_fun some_thm vars fxy (t as _ `|=> _) =
   112           let
   112           let
   113             val (binds, t') = Code_Thingol.unfold_pat_abs t;
   113             val (binds, t') = Code_Thingol.unfold_pat_abs t;
   114             fun print_abs (pat, ty) =
   114             fun print_abs (pat, ty) =
   115               print_bind is_pseudo_fun some_thm NOBR pat
   115               print_bind is_pseudo_fun some_thm NOBR pat
   116               #>> (fn p => concat [str "fn", p, str "=>"]);
   116               #>> (fn p => concat [Pretty.str "fn", p, Pretty.str "=>"]);
   117             val (ps, vars') = fold_map print_abs binds vars;
   117             val (ps, vars') = fold_map print_abs binds vars;
   118           in brackets (ps @ [print_term is_pseudo_fun some_thm vars' NOBR t']) end
   118           in brackets (ps @ [print_term is_pseudo_fun some_thm vars' NOBR t']) end
   119       | print_term is_pseudo_fun some_thm vars fxy (ICase case_expr) =
   119       | print_term is_pseudo_fun some_thm vars fxy (ICase case_expr) =
   120           (case Code_Thingol.unfold_const_app (#primitive case_expr)
   120           (case Code_Thingol.unfold_const_app (#primitive case_expr)
   121            of SOME (app as ({ sym = Constant const, ... }, _)) =>
   121            of SOME (app as ({ sym = Constant const, ... }, _)) =>
   125             | NONE => print_case is_pseudo_fun some_thm vars fxy case_expr)
   125             | NONE => print_case is_pseudo_fun some_thm vars fxy case_expr)
   126     and print_app_expr is_pseudo_fun some_thm vars (app as ({ sym, dicts, dom, ... }, ts)) =
   126     and print_app_expr is_pseudo_fun some_thm vars (app as ({ sym, dicts, dom, ... }, ts)) =
   127       if is_constr sym then
   127       if is_constr sym then
   128         let val wanted = length dom in
   128         let val wanted = length dom in
   129           if wanted < 2 orelse length ts = wanted
   129           if wanted < 2 orelse length ts = wanted
   130           then (str o deresolve) sym
   130           then (Pretty.str o deresolve) sym
   131             :: the_list (tuplify (print_term is_pseudo_fun some_thm vars) BR ts)
   131             :: the_list (tuplify (print_term is_pseudo_fun some_thm vars) BR ts)
   132           else [print_term is_pseudo_fun some_thm vars BR (Code_Thingol.saturated_application wanted app)]
   132           else [print_term is_pseudo_fun some_thm vars BR (Code_Thingol.saturated_application wanted app)]
   133         end
   133         end
   134       else if is_pseudo_fun sym
   134       else if is_pseudo_fun sym
   135         then (str o deresolve) sym @@ str "()"
   135         then (Pretty.str o deresolve) sym @@ Pretty.str "()"
   136       else (str o deresolve) sym :: map_filter (print_dicts is_pseudo_fun BR) dicts
   136       else (Pretty.str o deresolve) sym :: map_filter (print_dicts is_pseudo_fun BR) dicts
   137         @ map (print_term is_pseudo_fun some_thm vars BR) ts
   137         @ map (print_term is_pseudo_fun some_thm vars BR) ts
   138     and print_app is_pseudo_fun some_thm vars = gen_print_app (print_app_expr is_pseudo_fun)
   138     and print_app is_pseudo_fun some_thm vars = gen_print_app (print_app_expr is_pseudo_fun)
   139       (print_term is_pseudo_fun) const_syntax some_thm vars
   139       (print_term is_pseudo_fun) const_syntax some_thm vars
   140     and print_bind is_pseudo_fun = gen_print_bind (print_term is_pseudo_fun)
   140     and print_bind is_pseudo_fun = gen_print_bind (print_term is_pseudo_fun)
   141     and print_case is_pseudo_fun some_thm vars fxy { clauses = [], ... } =
   141     and print_case is_pseudo_fun some_thm vars fxy { clauses = [], ... } =
   142           (concat o map str) ["raise", "Fail", "\"empty case\""]
   142           (concat o map Pretty.str) ["raise", "Fail", "\"empty case\""]
   143       | print_case is_pseudo_fun some_thm vars fxy (case_expr as { clauses = [_], ... }) =
   143       | print_case is_pseudo_fun some_thm vars fxy (case_expr as { clauses = [_], ... }) =
   144           let
   144           let
   145             val (binds, body) = Code_Thingol.unfold_let (ICase case_expr);
   145             val (binds, body) = Code_Thingol.unfold_let (ICase case_expr);
   146             fun print_match ((pat, _), t) vars =
   146             fun print_match ((pat, _), t) vars =
   147               vars
   147               vars
   148               |> print_bind is_pseudo_fun some_thm NOBR pat
   148               |> print_bind is_pseudo_fun some_thm NOBR pat
   149               |>> (fn p => semicolon [str "val", p, str "=",
   149               |>> (fn p => semicolon [Pretty.str "val", p, Pretty.str "=",
   150                     print_term is_pseudo_fun some_thm vars NOBR t])
   150                     print_term is_pseudo_fun some_thm vars NOBR t])
   151             val (ps, vars') = fold_map print_match binds vars;
   151             val (ps, vars') = fold_map print_match binds vars;
   152           in
   152           in
   153             Pretty.chunks [
   153             Pretty.chunks [
   154               Pretty.block [str "let", Pretty.fbrk, Pretty.chunks ps],
   154               Pretty.block [Pretty.str "let", Pretty.fbrk, Pretty.chunks ps],
   155               Pretty.block [str "in", Pretty.fbrk, print_term is_pseudo_fun some_thm vars' NOBR body],
   155               Pretty.block [Pretty.str "in", Pretty.fbrk, print_term is_pseudo_fun some_thm vars' NOBR body],
   156               str "end"
   156               Pretty.str "end"
   157             ]
   157             ]
   158           end
   158           end
   159       | print_case is_pseudo_fun some_thm vars fxy { term = t, typ = ty, clauses = clause :: clauses, ... } =
   159       | print_case is_pseudo_fun some_thm vars fxy { term = t, typ = ty, clauses = clause :: clauses, ... } =
   160           let
   160           let
   161             fun print_select delim (pat, body) =
   161             fun print_select delim (pat, body) =
   162               let
   162               let
   163                 val (p, vars') = print_bind is_pseudo_fun some_thm NOBR pat vars;
   163                 val (p, vars') = print_bind is_pseudo_fun some_thm NOBR pat vars;
   164               in
   164               in
   165                 concat [str delim, p, str "=>", print_term is_pseudo_fun some_thm vars' NOBR body]
   165                 concat [Pretty.str delim, p, Pretty.str "=>", print_term is_pseudo_fun some_thm vars' NOBR body]
   166               end;
   166               end;
   167           in
   167           in
   168             brackets (
   168             brackets (
   169               str "case"
   169               Pretty.str "case"
   170               :: print_term is_pseudo_fun some_thm vars NOBR t
   170               :: print_term is_pseudo_fun some_thm vars NOBR t
   171               :: print_select "of" clause
   171               :: print_select "of" clause
   172               :: map (print_select "|") clauses
   172               :: map (print_select "|") clauses
   173             )
   173             )
   174           end;
   174           end;
   175     fun print_val_decl print_typscheme (sym, typscheme) = concat
   175     fun print_val_decl print_typscheme (sym, typscheme) = concat
   176       [str "val", str (deresolve sym), str ":", print_typscheme typscheme];
   176       [Pretty.str "val", Pretty.str (deresolve sym), Pretty.str ":", print_typscheme typscheme];
   177     fun print_datatype_decl definer (tyco, (vs, cos)) =
   177     fun print_datatype_decl definer (tyco, (vs, cos)) =
   178       let
   178       let
   179         fun print_co ((co, _), []) = str (deresolve_const co)
   179         fun print_co ((co, _), []) = Pretty.str (deresolve_const co)
   180           | print_co ((co, _), tys) = concat [str (deresolve_const co), str "of",
   180           | print_co ((co, _), tys) = concat [Pretty.str (deresolve_const co), Pretty.str "of",
   181               enum " *" "" "" (map (print_typ (INFX (2, X))) tys)];
   181               Pretty.enum " *" "" "" (map (print_typ (INFX (2, X))) tys)];
   182       in
   182       in
   183         concat (
   183         concat (
   184           str definer
   184           Pretty.str definer
   185           :: print_tyco_expr (Type_Constructor tyco, map ITyVar vs)
   185           :: print_tyco_expr (Type_Constructor tyco, map ITyVar vs)
   186           :: str "="
   186           :: Pretty.str "="
   187           :: separate (str "|") (map print_co cos)
   187           :: separate (Pretty.str "|") (map print_co cos)
   188         )
   188         )
   189       end;
   189       end;
   190     fun print_def is_pseudo_fun needs_typ definer
   190     fun print_def is_pseudo_fun needs_typ definer
   191           (ML_Function (const, (vs_ty as (vs, ty), eq :: eqs))) =
   191           (ML_Function (const, (vs_ty as (vs, ty), eq :: eqs))) =
   192           let
   192           let
   195                 val vars = reserved
   195                 val vars = reserved
   196                   |> intro_base_names_for (is_none o const_syntax)
   196                   |> intro_base_names_for (is_none o const_syntax)
   197                        deresolve (t :: ts)
   197                        deresolve (t :: ts)
   198                   |> intro_vars (build (fold Code_Thingol.add_varnames ts));
   198                   |> intro_vars (build (fold Code_Thingol.add_varnames ts));
   199                 val prolog = if needs_typ then
   199                 val prolog = if needs_typ then
   200                   concat [str definer, (str o deresolve_const) const, str ":", print_typ NOBR ty]
   200                   concat [Pretty.str definer, (Pretty.str o deresolve_const) const, Pretty.str ":", print_typ NOBR ty]
   201                     else (concat o map str) [definer, deresolve_const const];
   201                     else (concat o map Pretty.str) [definer, deresolve_const const];
   202               in
   202               in
   203                 concat (
   203                 concat (
   204                   prolog
   204                   prolog
   205                   :: (if is_pseudo_fun (Constant const) then [str "()"]
   205                   :: (if is_pseudo_fun (Constant const) then [Pretty.str "()"]
   206                       else print_dict_args vs
   206                       else print_dict_args vs
   207                         @ map (print_term is_pseudo_fun some_thm vars BR) ts)
   207                         @ map (print_term is_pseudo_fun some_thm vars BR) ts)
   208                   @ str "="
   208                   @ Pretty.str "="
   209                   @@ print_term is_pseudo_fun some_thm vars NOBR t
   209                   @@ print_term is_pseudo_fun some_thm vars NOBR t
   210                 )
   210                 )
   211               end
   211               end
   212             val shift = if null eqs then I else
   212             val shift = if null eqs then I else
   213               map (Pretty.block o single o Pretty.block o single);
   213               map (Pretty.block o single o Pretty.block o single);
   221       | print_def is_pseudo_fun _ definer
   221       | print_def is_pseudo_fun _ definer
   222           (ML_Instance (inst as (tyco, class), { vs, superinsts, inst_params, ... })) =
   222           (ML_Instance (inst as (tyco, class), { vs, superinsts, inst_params, ... })) =
   223           let
   223           let
   224             fun print_super_instance (super_class, x) =
   224             fun print_super_instance (super_class, x) =
   225               concat [
   225               concat [
   226                 (str o Long_Name.base_name o deresolve_classrel) (class, super_class),
   226                 (Pretty.str o Long_Name.base_name o deresolve_classrel) (class, super_class),
   227                 str "=",
   227                 Pretty.str "=",
   228                 print_dict is_pseudo_fun NOBR (Dict ([], Dict_Const ((tyco, super_class), x)))
   228                 print_dict is_pseudo_fun NOBR (Dict ([], Dict_Const ((tyco, super_class), x)))
   229               ];
   229               ];
   230             fun print_classparam_instance ((classparam, (const, _)), (thm, _)) =
   230             fun print_classparam_instance ((classparam, (const, _)), (thm, _)) =
   231               concat [
   231               concat [
   232                 (str o Long_Name.base_name o deresolve_const) classparam,
   232                 (Pretty.str o Long_Name.base_name o deresolve_const) classparam,
   233                 str "=",
   233                 Pretty.str "=",
   234                 print_app (K false) (SOME thm) reserved NOBR (const, [])
   234                 print_app (K false) (SOME thm) reserved NOBR (const, [])
   235               ];
   235               ];
   236           in pair
   236           in pair
   237             (print_val_decl print_dicttypscheme
   237             (print_val_decl print_dicttypscheme
   238               (Class_Instance inst, (vs, (class, tyco `%% map (ITyVar o fst) vs))))
   238               (Class_Instance inst, (vs, (class, tyco `%% map (ITyVar o fst) vs))))
   239             (concat (
   239             (concat (
   240               str definer
   240               Pretty.str definer
   241               :: (str o deresolve_inst) inst
   241               :: (Pretty.str o deresolve_inst) inst
   242               :: (if is_pseudo_fun (Class_Instance inst) then [str "()"]
   242               :: (if is_pseudo_fun (Class_Instance inst) then [Pretty.str "()"]
   243                   else print_dict_args vs)
   243                   else print_dict_args vs)
   244               @ str "="
   244               @ Pretty.str "="
   245               :: enum "," "{" "}"
   245               :: Pretty.enum "," "{" "}"
   246                 (map print_super_instance superinsts
   246                 (map print_super_instance superinsts
   247                   @ map print_classparam_instance inst_params)
   247                   @ map print_classparam_instance inst_params)
   248               :: str ":"
   248               :: Pretty.str ":"
   249               @@ print_dicttyp (class, tyco `%% map (ITyVar o fst) vs)
   249               @@ print_dicttyp (class, tyco `%% map (ITyVar o fst) vs)
   250             ))
   250             ))
   251           end;
   251           end;
   252     fun print_stmt _ (ML_Exc (const, (vs_ty, n))) = pair
   252     fun print_stmt _ (ML_Exc (const, (vs_ty, n))) = pair
   253           [print_val_decl print_typscheme (Constant const, vs_ty)]
   253           [print_val_decl print_typscheme (Constant const, vs_ty)]
   254           ((semicolon o map str) (
   254           ((semicolon o map Pretty.str) (
   255             (if n = 0 then "val" else "fun")
   255             (if n = 0 then "val" else "fun")
   256             :: deresolve_const const
   256             :: deresolve_const const
   257             :: replicate n "_"
   257             :: replicate n "_"
   258             @ "="
   258             @ "="
   259             :: "raise"
   259             :: "raise"
   269           end
   269           end
   270       | print_stmt _ (ML_Funs ((export, binding) :: exports_bindings, pseudo_funs)) =
   270       | print_stmt _ (ML_Funs ((export, binding) :: exports_bindings, pseudo_funs)) =
   271           let
   271           let
   272             val print_def' = print_def (member (op =) pseudo_funs) false;
   272             val print_def' = print_def (member (op =) pseudo_funs) false;
   273             fun print_pseudo_fun sym = concat [
   273             fun print_pseudo_fun sym = concat [
   274                 str "val",
   274                 Pretty.str "val",
   275                 (str o deresolve) sym,
   275                 (Pretty.str o deresolve) sym,
   276                 str "=",
   276                 Pretty.str "=",
   277                 (str o deresolve) sym,
   277                 (Pretty.str o deresolve) sym,
   278                 str "();"
   278                 Pretty.str "();"
   279               ];
   279               ];
   280             val (sig_ps, (ps, p)) = (apsnd split_last o split_list)
   280             val (sig_ps, (ps, p)) = (apsnd split_last o split_list)
   281               (print_def' "fun" binding :: map (print_def' "and" o snd) exports_bindings);
   281               (print_def' "fun" binding :: map (print_def' "and" o snd) exports_bindings);
   282             val pseudo_ps = map print_pseudo_fun pseudo_funs;
   282             val pseudo_ps = map print_pseudo_fun pseudo_funs;
   283           in pair
   283           in pair
   288      | print_stmt _ (ML_Datas [(tyco, (vs, []))]) =
   288      | print_stmt _ (ML_Datas [(tyco, (vs, []))]) =
   289           let
   289           let
   290             val ty_p = print_tyco_expr (Type_Constructor tyco, map ITyVar vs);
   290             val ty_p = print_tyco_expr (Type_Constructor tyco, map ITyVar vs);
   291           in
   291           in
   292             pair
   292             pair
   293             [concat [str "type", ty_p]]
   293             [concat [Pretty.str "type", ty_p]]
   294             (semicolon [str "datatype", ty_p, str "=", str "EMPTY__"])
   294             (semicolon [Pretty.str "datatype", ty_p, Pretty.str "=", Pretty.str "EMPTY__"])
   295           end
   295           end
   296      | print_stmt export (ML_Datas (data :: datas)) = 
   296      | print_stmt export (ML_Datas (data :: datas)) = 
   297           let
   297           let
   298             val decl_ps = print_datatype_decl "datatype" data
   298             val decl_ps = print_datatype_decl "datatype" data
   299               :: map (print_datatype_decl "and") datas;
   299               :: map (print_datatype_decl "and") datas;
   300             val (ps, p) = split_last decl_ps;
   300             val (ps, p) = split_last decl_ps;
   301           in pair
   301           in pair
   302             (if Code_Namespace.is_public export
   302             (if Code_Namespace.is_public export
   303               then decl_ps
   303               then decl_ps
   304               else map (fn (tyco, (vs, _)) =>
   304               else map (fn (tyco, (vs, _)) =>
   305                 concat [str "type", print_tyco_expr (Type_Constructor tyco, map ITyVar vs)])
   305                 concat [Pretty.str "type", print_tyco_expr (Type_Constructor tyco, map ITyVar vs)])
   306                 (data :: datas))
   306                 (data :: datas))
   307             (Pretty.chunks (ps @| semicolon [p]))
   307             (Pretty.chunks (ps @| semicolon [p]))
   308           end
   308           end
   309      | print_stmt export (ML_Class (class, (v, (classrels, classparams)))) =
   309      | print_stmt export (ML_Class (class, (v, (classrels, classparams)))) =
   310           let
   310           let
   311             fun print_field s p = concat [str s, str ":", p];
   311             fun print_field s p = concat [Pretty.str s, Pretty.str ":", p];
   312             fun print_proj s p = semicolon
   312             fun print_proj s p = semicolon
   313               (map str ["val", s, "=", "#" ^ s, ":"] @| p);
   313               (map Pretty.str ["val", s, "=", "#" ^ s, ":"] @| p);
   314             fun print_super_class_decl (classrel as (_, super_class)) =
   314             fun print_super_class_decl (classrel as (_, super_class)) =
   315               print_val_decl print_dicttypscheme
   315               print_val_decl print_dicttypscheme
   316                 (Class_Relation classrel, ([(v, [class])], (super_class, ITyVar v)));
   316                 (Class_Relation classrel, ([(v, [class])], (super_class, ITyVar v)));
   317             fun print_super_class_field (classrel as (_, super_class)) =
   317             fun print_super_class_field (classrel as (_, super_class)) =
   318               print_field (deresolve_classrel classrel) (print_dicttyp (super_class, ITyVar v));
   318               print_field (deresolve_classrel classrel) (print_dicttyp (super_class, ITyVar v));
   326               print_field (deresolve_const classparam) (print_typ NOBR ty);
   326               print_field (deresolve_const classparam) (print_typ NOBR ty);
   327             fun print_classparam_proj (classparam, ty) =
   327             fun print_classparam_proj (classparam, ty) =
   328               print_proj (deresolve_const classparam)
   328               print_proj (deresolve_const classparam)
   329                 (print_typscheme ([(v, [class])], ty));
   329                 (print_typscheme ([(v, [class])], ty));
   330           in pair
   330           in pair
   331             (concat [str "type", print_dicttyp (class, ITyVar v)]
   331             (concat [Pretty.str "type", print_dicttyp (class, ITyVar v)]
   332               :: (if Code_Namespace.is_public export
   332               :: (if Code_Namespace.is_public export
   333                  then map print_super_class_decl classrels
   333                  then map print_super_class_decl classrels
   334                    @ map print_classparam_decl classparams
   334                    @ map print_classparam_decl classparams
   335                  else []))
   335                  else []))
   336             (Pretty.chunks (
   336             (Pretty.chunks (
   337               concat [
   337               concat [
   338                 str "type",
   338                 Pretty.str "type",
   339                 print_dicttyp (class, ITyVar v),
   339                 print_dicttyp (class, ITyVar v),
   340                 str "=",
   340                 Pretty.str "=",
   341                 enum "," "{" "};" (
   341                 Pretty.enum "," "{" "};" (
   342                   map print_super_class_field classrels
   342                   map print_super_class_field classrels
   343                   @ map print_classparam_field classparams
   343                   @ map print_classparam_field classparams
   344                 )
   344                 )
   345               ]
   345               ]
   346               :: map print_super_class_proj classrels
   346               :: map print_super_class_proj classrels
   350   in print_stmt end;
   350   in print_stmt end;
   351 
   351 
   352 fun print_sml_module name decls body =
   352 fun print_sml_module name decls body =
   353   Pretty.chunks2 (
   353   Pretty.chunks2 (
   354     Pretty.chunks [
   354     Pretty.chunks [
   355       str ("structure " ^ name ^ " : sig"),
   355       Pretty.str ("structure " ^ name ^ " : sig"),
   356       (indent 2 o Pretty.chunks) decls,
   356       (Pretty.indent 2 o Pretty.chunks) decls,
   357       str "end = struct"
   357       Pretty.str "end = struct"
   358     ]
   358     ]
   359     :: body
   359     :: body
   360     @| str ("end; (*struct " ^ name ^ "*)")
   360     @| Pretty.str ("end; (*struct " ^ name ^ "*)")
   361   );
   361   );
   362 
   362 
   363 val literals_sml = Literals {
   363 val literals_sml = Literals {
   364   literal_string = print_sml_string,
   364   literal_string = print_sml_string,
   365   literal_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
   365   literal_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
   366   literal_list = enum "," "[" "]",
   366   literal_list = Pretty.enum "," "[" "]",
   367   infix_cons = (7, "::")
   367   infix_cons = (7, "::")
   368 };
   368 };
   369 
   369 
   370 
   370 
   371 (** OCaml serializer **)
   371 (** OCaml serializer **)
   390 fun print_ocaml_stmt tyco_syntax const_syntax reserved is_constr deresolve =
   390 fun print_ocaml_stmt tyco_syntax const_syntax reserved is_constr deresolve =
   391   let
   391   let
   392     val deresolve_const = deresolve o Constant;
   392     val deresolve_const = deresolve o Constant;
   393     val deresolve_classrel = deresolve o Class_Relation;
   393     val deresolve_classrel = deresolve o Class_Relation;
   394     val deresolve_inst = deresolve o Class_Instance;
   394     val deresolve_inst = deresolve o Class_Instance;
   395     fun print_tyco_expr (sym, []) = (str o deresolve) sym
   395     fun print_tyco_expr (sym, []) = (Pretty.str o deresolve) sym
   396       | print_tyco_expr (sym, [ty]) =
   396       | print_tyco_expr (sym, [ty]) =
   397           concat [print_typ BR ty, (str o deresolve) sym]
   397           concat [print_typ BR ty, (Pretty.str o deresolve) sym]
   398       | print_tyco_expr (sym, tys) =
   398       | print_tyco_expr (sym, tys) =
   399           concat [enum "," "(" ")" (map (print_typ BR) tys), (str o deresolve) sym]
   399           concat [Pretty.enum "," "(" ")" (map (print_typ BR) tys), (Pretty.str o deresolve) sym]
   400     and print_typ fxy (tyco `%% tys) = (case tyco_syntax tyco
   400     and print_typ fxy (tyco `%% tys) = (case tyco_syntax tyco
   401          of NONE => print_tyco_expr (Type_Constructor tyco, tys)
   401          of NONE => print_tyco_expr (Type_Constructor tyco, tys)
   402           | SOME (_, print) => print print_typ fxy tys)
   402           | SOME (_, print) => print print_typ fxy tys)
   403       | print_typ fxy (ITyVar v) = str ("'" ^ v);
   403       | print_typ fxy (ITyVar v) = Pretty.str ("'" ^ v);
   404     fun print_dicttyp (class, ty) = print_tyco_expr (Type_Class class, [ty]);
   404     fun print_dicttyp (class, ty) = print_tyco_expr (Type_Class class, [ty]);
   405     fun print_typscheme_prefix (vs, p) = enum " ->" "" ""
   405     fun print_typscheme_prefix (vs, p) = Pretty.enum " ->" "" ""
   406       (map_filter (fn (v, sort) =>
   406       (map_filter (fn (v, sort) =>
   407         (print_product (fn class => print_dicttyp (class, ITyVar v)) sort)) vs @| p);
   407         (print_product (fn class => print_dicttyp (class, ITyVar v)) sort)) vs @| p);
   408     fun print_typscheme (vs, ty) = print_typscheme_prefix (vs, print_typ NOBR ty);
   408     fun print_typscheme (vs, ty) = print_typscheme_prefix (vs, print_typ NOBR ty);
   409     fun print_dicttypscheme (vs, class_ty) = print_typscheme_prefix (vs, print_dicttyp class_ty);
   409     fun print_dicttypscheme (vs, class_ty) = print_typscheme_prefix (vs, print_dicttyp class_ty);
   410     val print_classrels =
   410     val print_classrels =
   411       fold_rev (fn classrel => fn p => Pretty.block [p, str ".", (str o deresolve_classrel) classrel])
   411       fold_rev (fn classrel => fn p => Pretty.block [p, Pretty.str ".", (Pretty.str o deresolve_classrel) classrel])
   412     fun print_dict is_pseudo_fun fxy (Dict (classrels, x)) =
   412     fun print_dict is_pseudo_fun fxy (Dict (classrels, x)) =
   413       print_plain_dict is_pseudo_fun fxy x
   413       print_plain_dict is_pseudo_fun fxy x
   414       |> print_classrels classrels
   414       |> print_classrels classrels
   415     and print_plain_dict is_pseudo_fun fxy (Dict_Const (inst, dss)) =
   415     and print_plain_dict is_pseudo_fun fxy (Dict_Const (inst, dss)) =
   416           brackify BR ((str o deresolve_inst) inst ::
   416           brackify BR ((Pretty.str o deresolve_inst) inst ::
   417             (if is_pseudo_fun (Class_Instance inst) then [str "()"]
   417             (if is_pseudo_fun (Class_Instance inst) then [Pretty.str "()"]
   418             else map_filter (print_dicts is_pseudo_fun BR o snd) dss))
   418             else map_filter (print_dicts is_pseudo_fun BR o snd) dss))
   419       | print_plain_dict is_pseudo_fun fxy (Dict_Var { var, index, length, ... }) =
   419       | print_plain_dict is_pseudo_fun fxy (Dict_Var { var, index, length, ... }) =
   420           str (if length = 1 then "_" ^ Name.enforce_case true var
   420           Pretty.str (if length = 1 then "_" ^ Name.enforce_case true var
   421             else "_" ^ Name.enforce_case true var ^ string_of_int (index + 1))
   421             else "_" ^ Name.enforce_case true var ^ string_of_int (index + 1))
   422     and print_dicts is_pseudo_fun = tuplify (print_dict is_pseudo_fun);
   422     and print_dicts is_pseudo_fun = tuplify (print_dict is_pseudo_fun);
   423     val print_dict_args = map_filter (fn (v, sort) => print_dicts (K false) BR
   423     val print_dict_args = map_filter (fn (v, sort) => print_dicts (K false) BR
   424       (map_index (fn (i, _) => Dict ([],
   424       (map_index (fn (i, _) => Dict ([],
   425          Dict_Var { var = v, index = i, length = length sort, class = nth sort i, unique = true })) sort));
   425          Dict_Var { var = v, index = i, length = length sort, class = nth sort i, unique = true })) sort));
   426     fun print_term is_pseudo_fun some_thm vars fxy (IConst const) =
   426     fun print_term is_pseudo_fun some_thm vars fxy (IConst const) =
   427           print_app is_pseudo_fun some_thm vars fxy (const, [])
   427           print_app is_pseudo_fun some_thm vars fxy (const, [])
   428       | print_term is_pseudo_fun some_thm vars fxy (IVar NONE) =
   428       | print_term is_pseudo_fun some_thm vars fxy (IVar NONE) =
   429           str "_"
   429           Pretty.str "_"
   430       | print_term is_pseudo_fun some_thm vars fxy (IVar (SOME v)) =
   430       | print_term is_pseudo_fun some_thm vars fxy (IVar (SOME v)) =
   431           str (lookup_var vars v)
   431           Pretty.str (lookup_var vars v)
   432       | print_term is_pseudo_fun some_thm vars fxy (t as t1 `$ t2) =
   432       | print_term is_pseudo_fun some_thm vars fxy (t as t1 `$ t2) =
   433           (case Code_Thingol.unfold_const_app t
   433           (case Code_Thingol.unfold_const_app t
   434            of SOME app => print_app is_pseudo_fun some_thm vars fxy app
   434            of SOME app => print_app is_pseudo_fun some_thm vars fxy app
   435             | NONE => brackify fxy [print_term is_pseudo_fun some_thm vars NOBR t1,
   435             | NONE => brackify fxy [print_term is_pseudo_fun some_thm vars NOBR t1,
   436                 print_term is_pseudo_fun some_thm vars BR t2])
   436                 print_term is_pseudo_fun some_thm vars BR t2])
   437       | print_term is_pseudo_fun some_thm vars fxy (t as _ `|=> _) =
   437       | print_term is_pseudo_fun some_thm vars fxy (t as _ `|=> _) =
   438           let
   438           let
   439             val (binds, t') = Code_Thingol.unfold_pat_abs t;
   439             val (binds, t') = Code_Thingol.unfold_pat_abs t;
   440             val (ps, vars') = fold_map (print_bind is_pseudo_fun some_thm BR o fst) binds vars;
   440             val (ps, vars') = fold_map (print_bind is_pseudo_fun some_thm BR o fst) binds vars;
   441           in brackets (str "fun" :: ps @ str "->" @@ print_term is_pseudo_fun some_thm vars' NOBR t') end
   441           in brackets (Pretty.str "fun" :: ps @ Pretty.str "->" @@ print_term is_pseudo_fun some_thm vars' NOBR t') end
   442       | print_term is_pseudo_fun some_thm vars fxy (ICase case_expr) =
   442       | print_term is_pseudo_fun some_thm vars fxy (ICase case_expr) =
   443           (case Code_Thingol.unfold_const_app (#primitive case_expr)
   443           (case Code_Thingol.unfold_const_app (#primitive case_expr)
   444            of SOME (app as ({ sym = Constant const, ... }, _)) =>
   444            of SOME (app as ({ sym = Constant const, ... }, _)) =>
   445                 if is_none (const_syntax const)
   445                 if is_none (const_syntax const)
   446                 then print_case is_pseudo_fun some_thm vars fxy case_expr
   446                 then print_case is_pseudo_fun some_thm vars fxy case_expr
   448             | NONE => print_case is_pseudo_fun some_thm vars fxy case_expr)
   448             | NONE => print_case is_pseudo_fun some_thm vars fxy case_expr)
   449     and print_app_expr is_pseudo_fun some_thm vars (app as ({ sym, dicts, dom, ... }, ts)) =
   449     and print_app_expr is_pseudo_fun some_thm vars (app as ({ sym, dicts, dom, ... }, ts)) =
   450       if is_constr sym then
   450       if is_constr sym then
   451         let val wanted = length dom in
   451         let val wanted = length dom in
   452           if length ts = wanted
   452           if length ts = wanted
   453           then (str o deresolve) sym
   453           then (Pretty.str o deresolve) sym
   454             :: the_list (tuplify (print_term is_pseudo_fun some_thm vars) BR ts)
   454             :: the_list (tuplify (print_term is_pseudo_fun some_thm vars) BR ts)
   455           else [print_term is_pseudo_fun some_thm vars BR (Code_Thingol.saturated_application wanted app)]
   455           else [print_term is_pseudo_fun some_thm vars BR (Code_Thingol.saturated_application wanted app)]
   456         end
   456         end
   457       else if is_pseudo_fun sym
   457       else if is_pseudo_fun sym
   458         then (str o deresolve) sym @@ str "()"
   458         then (Pretty.str o deresolve) sym @@ Pretty.str "()"
   459       else (str o deresolve) sym :: map_filter (print_dicts is_pseudo_fun BR) dicts
   459       else (Pretty.str o deresolve) sym :: map_filter (print_dicts is_pseudo_fun BR) dicts
   460         @ map (print_term is_pseudo_fun some_thm vars BR) ts
   460         @ map (print_term is_pseudo_fun some_thm vars BR) ts
   461     and print_app is_pseudo_fun some_thm vars = gen_print_app (print_app_expr is_pseudo_fun)
   461     and print_app is_pseudo_fun some_thm vars = gen_print_app (print_app_expr is_pseudo_fun)
   462       (print_term is_pseudo_fun) const_syntax some_thm vars
   462       (print_term is_pseudo_fun) const_syntax some_thm vars
   463     and print_bind is_pseudo_fun = gen_print_bind (print_term is_pseudo_fun)
   463     and print_bind is_pseudo_fun = gen_print_bind (print_term is_pseudo_fun)
   464     and print_case is_pseudo_fun some_thm vars fxy { clauses = [], ... } =
   464     and print_case is_pseudo_fun some_thm vars fxy { clauses = [], ... } =
   465           (concat o map str) ["failwith", "\"empty case\""]
   465           (concat o map Pretty.str) ["failwith", "\"empty case\""]
   466       | print_case is_pseudo_fun some_thm vars fxy (case_expr as { clauses = [_], ... }) =
   466       | print_case is_pseudo_fun some_thm vars fxy (case_expr as { clauses = [_], ... }) =
   467           let
   467           let
   468             val (binds, body) = Code_Thingol.unfold_let (ICase case_expr);
   468             val (binds, body) = Code_Thingol.unfold_let (ICase case_expr);
   469             fun print_let ((pat, _), t) vars =
   469             fun print_let ((pat, _), t) vars =
   470               vars
   470               vars
   471               |> print_bind is_pseudo_fun some_thm NOBR pat
   471               |> print_bind is_pseudo_fun some_thm NOBR pat
   472               |>> (fn p => concat
   472               |>> (fn p => concat
   473                   [str "let", p, str "=", print_term is_pseudo_fun some_thm vars NOBR t, str "in"])
   473                   [Pretty.str "let", p, Pretty.str "=", print_term is_pseudo_fun some_thm vars NOBR t, Pretty.str "in"])
   474             val (ps, vars') = fold_map print_let binds vars;
   474             val (ps, vars') = fold_map print_let binds vars;
   475           in
   475           in
   476             brackets [Pretty.chunks ps, print_term is_pseudo_fun some_thm vars' NOBR body]
   476             brackets [Pretty.chunks ps, print_term is_pseudo_fun some_thm vars' NOBR body]
   477           end
   477           end
   478       | print_case is_pseudo_fun some_thm vars fxy { term = t, typ = ty, clauses = clause :: clauses, ... } =
   478       | print_case is_pseudo_fun some_thm vars fxy { term = t, typ = ty, clauses = clause :: clauses, ... } =
   479           let
   479           let
   480             fun print_select delim (pat, body) =
   480             fun print_select delim (pat, body) =
   481               let
   481               let
   482                 val (p, vars') = print_bind is_pseudo_fun some_thm NOBR pat vars;
   482                 val (p, vars') = print_bind is_pseudo_fun some_thm NOBR pat vars;
   483               in concat [str delim, p, str "->", print_term is_pseudo_fun some_thm vars' NOBR body] end;
   483               in concat [Pretty.str delim, p, Pretty.str "->", print_term is_pseudo_fun some_thm vars' NOBR body] end;
   484           in
   484           in
   485             brackets (
   485             brackets (
   486               str "match"
   486               Pretty.str "match"
   487               :: print_term is_pseudo_fun some_thm vars NOBR t
   487               :: print_term is_pseudo_fun some_thm vars NOBR t
   488               :: print_select "with" clause
   488               :: print_select "with" clause
   489               :: map (print_select "|") clauses
   489               :: map (print_select "|") clauses
   490             )
   490             )
   491           end;
   491           end;
   492     fun print_val_decl print_typscheme (sym, typscheme) = concat
   492     fun print_val_decl print_typscheme (sym, typscheme) = concat
   493       [str "val", str (deresolve sym), str ":", print_typscheme typscheme];
   493       [Pretty.str "val", Pretty.str (deresolve sym), Pretty.str ":", print_typscheme typscheme];
   494     fun print_datatype_decl definer (tyco, (vs, cos)) =
   494     fun print_datatype_decl definer (tyco, (vs, cos)) =
   495       let
   495       let
   496         fun print_co ((co, _), []) = str (deresolve_const co)
   496         fun print_co ((co, _), []) = Pretty.str (deresolve_const co)
   497           | print_co ((co, _), tys) = concat [str (deresolve_const co), str "of",
   497           | print_co ((co, _), tys) = concat [Pretty.str (deresolve_const co), Pretty.str "of",
   498               enum " *" "" "" (map (print_typ (INFX (2, X))) tys)];
   498               Pretty.enum " *" "" "" (map (print_typ (INFX (2, X))) tys)];
   499       in
   499       in
   500         concat (
   500         concat (
   501           str definer
   501           Pretty.str definer
   502           :: print_tyco_expr (Type_Constructor tyco, map ITyVar vs)
   502           :: print_tyco_expr (Type_Constructor tyco, map ITyVar vs)
   503           :: str "="
   503           :: Pretty.str "="
   504           :: separate (str "|") (map print_co cos)
   504           :: separate (Pretty.str "|") (map print_co cos)
   505         )
   505         )
   506       end;
   506       end;
   507     fun print_def is_pseudo_fun needs_typ definer
   507     fun print_def is_pseudo_fun needs_typ definer
   508           (ML_Function (const, (vs_ty as (vs, ty), eqs))) =
   508           (ML_Function (const, (vs_ty as (vs, ty), eqs))) =
   509           let
   509           let
   512                 val vars = reserved
   512                 val vars = reserved
   513                   |> intro_base_names_for (is_none o const_syntax)
   513                   |> intro_base_names_for (is_none o const_syntax)
   514                       deresolve (t :: ts)
   514                       deresolve (t :: ts)
   515                   |> intro_vars (build (fold Code_Thingol.add_varnames ts));
   515                   |> intro_vars (build (fold Code_Thingol.add_varnames ts));
   516               in concat [
   516               in concat [
   517                 (Pretty.block o commas)
   517                 (Pretty.block o Pretty.commas)
   518                   (map (print_term is_pseudo_fun some_thm vars NOBR) ts),
   518                   (map (print_term is_pseudo_fun some_thm vars NOBR) ts),
   519                 str "->",
   519                 Pretty.str "->",
   520                 print_term is_pseudo_fun some_thm vars NOBR t
   520                 print_term is_pseudo_fun some_thm vars NOBR t
   521               ] end;
   521               ] end;
   522             fun print_eqns is_pseudo [((ts, t), (some_thm, _))] =
   522             fun print_eqns is_pseudo [((ts, t), (some_thm, _))] =
   523                   let
   523                   let
   524                     val vars = reserved
   524                     val vars = reserved
   525                       |> intro_base_names_for (is_none o const_syntax)
   525                       |> intro_base_names_for (is_none o const_syntax)
   526                           deresolve (t :: ts)
   526                           deresolve (t :: ts)
   527                       |> intro_vars (build (fold Code_Thingol.add_varnames ts));
   527                       |> intro_vars (build (fold Code_Thingol.add_varnames ts));
   528                   in
   528                   in
   529                     concat (
   529                     concat (
   530                       (if is_pseudo then [str "()"]
   530                       (if is_pseudo then [Pretty.str "()"]
   531                         else map (print_term is_pseudo_fun some_thm vars BR) ts)
   531                         else map (print_term is_pseudo_fun some_thm vars BR) ts)
   532                       @ str "="
   532                       @ Pretty.str "="
   533                       @@ print_term is_pseudo_fun some_thm vars NOBR t
   533                       @@ print_term is_pseudo_fun some_thm vars NOBR t
   534                     )
   534                     )
   535                   end
   535                   end
   536               | print_eqns _ ((eq as (([_], _), _)) :: eqs) =
   536               | print_eqns _ ((eq as (([_], _), _)) :: eqs) =
   537                   Pretty.block (
   537                   Pretty.block (
   538                     str "="
   538                     Pretty.str "="
   539                     :: Pretty.brk 1
   539                     :: Pretty.brk 1
   540                     :: str "function"
   540                     :: Pretty.str "function"
   541                     :: Pretty.brk 1
   541                     :: Pretty.brk 1
   542                     :: print_eqn eq
   542                     :: print_eqn eq
   543                     :: maps (append [Pretty.fbrk, str "|", Pretty.brk 1]
   543                     :: maps (append [Pretty.fbrk, Pretty.str "|", Pretty.brk 1]
   544                           o single o print_eqn) eqs
   544                           o single o print_eqn) eqs
   545                   )
   545                   )
   546               | print_eqns _ (eqs as eq :: eqs') =
   546               | print_eqns _ (eqs as eq :: eqs') =
   547                   let
   547                   let
   548                     val vars = reserved
   548                     val vars = reserved
   549                       |> intro_base_names_for (is_none o const_syntax)
   549                       |> intro_base_names_for (is_none o const_syntax)
   550                            deresolve (map (snd o fst) eqs)
   550                            deresolve (map (snd o fst) eqs)
   551                     val dummy_parms = (map str o aux_params vars o map (fst o fst)) eqs;
   551                     val dummy_parms = (map Pretty.str o aux_params vars o map (fst o fst)) eqs;
   552                   in
   552                   in
   553                     Pretty.block (
   553                     Pretty.block (
   554                       Pretty.breaks dummy_parms
   554                       Pretty.breaks dummy_parms
   555                       @ Pretty.brk 1
   555                       @ Pretty.brk 1
   556                       :: str "="
   556                       :: Pretty.str "="
   557                       :: Pretty.brk 1
   557                       :: Pretty.brk 1
   558                       :: str "match"
   558                       :: Pretty.str "match"
   559                       :: Pretty.brk 1
   559                       :: Pretty.brk 1
   560                       :: (Pretty.block o commas) dummy_parms
   560                       :: (Pretty.block o Pretty.commas) dummy_parms
   561                       :: Pretty.brk 1
   561                       :: Pretty.brk 1
   562                       :: str "with"
   562                       :: Pretty.str "with"
   563                       :: Pretty.brk 1
   563                       :: Pretty.brk 1
   564                       :: print_eqn eq
   564                       :: print_eqn eq
   565                       :: maps (append [Pretty.fbrk, str "|", Pretty.brk 1]
   565                       :: maps (append [Pretty.fbrk, Pretty.str "|", Pretty.brk 1]
   566                            o single o print_eqn) eqs'
   566                            o single o print_eqn) eqs'
   567                     )
   567                     )
   568                   end;
   568                   end;
   569             val prolog = if needs_typ then
   569             val prolog = if needs_typ then
   570               concat [str definer, (str o deresolve_const) const, str ":", print_typ NOBR ty]
   570               concat [Pretty.str definer, (Pretty.str o deresolve_const) const, Pretty.str ":", print_typ NOBR ty]
   571                 else (concat o map str) [definer, deresolve_const const];
   571                 else (concat o map Pretty.str) [definer, deresolve_const const];
   572           in pair
   572           in pair
   573             (print_val_decl print_typscheme (Constant const, vs_ty))
   573             (print_val_decl print_typscheme (Constant const, vs_ty))
   574             (concat (
   574             (concat (
   575               prolog
   575               prolog
   576               :: print_dict_args vs
   576               :: print_dict_args vs
   580       | print_def is_pseudo_fun _ definer
   580       | print_def is_pseudo_fun _ definer
   581           (ML_Instance (inst as (tyco, class), { vs, superinsts, inst_params, ... })) =
   581           (ML_Instance (inst as (tyco, class), { vs, superinsts, inst_params, ... })) =
   582           let
   582           let
   583             fun print_super_instance (super_class, dss) =
   583             fun print_super_instance (super_class, dss) =
   584               concat [
   584               concat [
   585                 (str o deresolve_classrel) (class, super_class),
   585                 (Pretty.str o deresolve_classrel) (class, super_class),
   586                 str "=",
   586                 Pretty.str "=",
   587                 print_dict is_pseudo_fun NOBR (Dict ([], Dict_Const ((tyco, super_class), dss)))
   587                 print_dict is_pseudo_fun NOBR (Dict ([], Dict_Const ((tyco, super_class), dss)))
   588               ];
   588               ];
   589             fun print_classparam_instance ((classparam, (const, _)), (thm, _)) =
   589             fun print_classparam_instance ((classparam, (const, _)), (thm, _)) =
   590               concat [
   590               concat [
   591                 (str o deresolve_const) classparam,
   591                 (Pretty.str o deresolve_const) classparam,
   592                 str "=",
   592                 Pretty.str "=",
   593                 print_app (K false) (SOME thm) reserved NOBR (const, [])
   593                 print_app (K false) (SOME thm) reserved NOBR (const, [])
   594               ];
   594               ];
   595           in pair
   595           in pair
   596             (print_val_decl print_dicttypscheme
   596             (print_val_decl print_dicttypscheme
   597               (Class_Instance inst, (vs, (class, tyco `%% map (ITyVar o fst) vs))))
   597               (Class_Instance inst, (vs, (class, tyco `%% map (ITyVar o fst) vs))))
   598             (concat (
   598             (concat (
   599               str definer
   599               Pretty.str definer
   600               :: (str o deresolve_inst) inst
   600               :: (Pretty.str o deresolve_inst) inst
   601               :: (if is_pseudo_fun (Class_Instance inst) then [str "()"]
   601               :: (if is_pseudo_fun (Class_Instance inst) then [Pretty.str "()"]
   602                   else print_dict_args vs)
   602                   else print_dict_args vs)
   603               @ str "="
   603               @ Pretty.str "="
   604               @@ brackets [
   604               @@ brackets [
   605                 enum_default "()" ";" "{" "}" (map print_super_instance superinsts
   605                 enum_default "()" ";" "{" "}" (map print_super_instance superinsts
   606                   @ map print_classparam_instance inst_params),
   606                   @ map print_classparam_instance inst_params),
   607                 str ":",
   607                 Pretty.str ":",
   608                 print_dicttyp (class, tyco `%% map (ITyVar o fst) vs)
   608                 print_dicttyp (class, tyco `%% map (ITyVar o fst) vs)
   609               ]
   609               ]
   610             ))
   610             ))
   611           end;
   611           end;
   612      fun print_stmt _ (ML_Exc (const, (vs_ty, n))) = pair
   612      fun print_stmt _ (ML_Exc (const, (vs_ty, n))) = pair
   613           [print_val_decl print_typscheme (Constant const, vs_ty)]
   613           [print_val_decl print_typscheme (Constant const, vs_ty)]
   614           ((doublesemicolon o map str) (
   614           ((doublesemicolon o map Pretty.str) (
   615             "let"
   615             "let"
   616             :: deresolve_const const
   616             :: deresolve_const const
   617             :: replicate n "_"
   617             :: replicate n "_"
   618             @ "="
   618             @ "="
   619             :: "failwith"
   619             :: "failwith"
   628           end
   628           end
   629       | print_stmt _ (ML_Funs ((export, binding) :: exports_bindings, pseudo_funs)) =
   629       | print_stmt _ (ML_Funs ((export, binding) :: exports_bindings, pseudo_funs)) =
   630           let
   630           let
   631             val print_def' = print_def (member (op =) pseudo_funs) false;
   631             val print_def' = print_def (member (op =) pseudo_funs) false;
   632             fun print_pseudo_fun sym = concat [
   632             fun print_pseudo_fun sym = concat [
   633                 str "let",
   633                 Pretty.str "let",
   634                 (str o deresolve) sym,
   634                 (Pretty.str o deresolve) sym,
   635                 str "=",
   635                 Pretty.str "=",
   636                 (str o deresolve) sym,
   636                 (Pretty.str o deresolve) sym,
   637                 str "();;"
   637                 Pretty.str "();;"
   638               ];
   638               ];
   639             val (sig_ps, (ps, p)) = (apsnd split_last o split_list)
   639             val (sig_ps, (ps, p)) = (apsnd split_last o split_list)
   640               (print_def' "let rec" binding :: map (print_def' "and" o snd) exports_bindings);
   640               (print_def' "let rec" binding :: map (print_def' "and" o snd) exports_bindings);
   641             val pseudo_ps = map print_pseudo_fun pseudo_funs;
   641             val pseudo_ps = map print_pseudo_fun pseudo_funs;
   642           in pair
   642           in pair
   647      | print_stmt _ (ML_Datas [(tyco, (vs, []))]) =
   647      | print_stmt _ (ML_Datas [(tyco, (vs, []))]) =
   648           let
   648           let
   649             val ty_p = print_tyco_expr (Type_Constructor tyco, map ITyVar vs);
   649             val ty_p = print_tyco_expr (Type_Constructor tyco, map ITyVar vs);
   650           in
   650           in
   651             pair
   651             pair
   652             [concat [str "type", ty_p]]
   652             [concat [Pretty.str "type", ty_p]]
   653             (doublesemicolon [str "type", ty_p, str "=", str "EMPTY__"])
   653             (doublesemicolon [Pretty.str "type", ty_p, Pretty.str "=", Pretty.str "EMPTY__"])
   654           end
   654           end
   655      | print_stmt export (ML_Datas (data :: datas)) = 
   655      | print_stmt export (ML_Datas (data :: datas)) = 
   656           let
   656           let
   657             val decl_ps = print_datatype_decl "type" data
   657             val decl_ps = print_datatype_decl "type" data
   658               :: map (print_datatype_decl "and") datas;
   658               :: map (print_datatype_decl "and") datas;
   659             val (ps, p) = split_last decl_ps;
   659             val (ps, p) = split_last decl_ps;
   660           in pair
   660           in pair
   661             (if Code_Namespace.is_public export
   661             (if Code_Namespace.is_public export
   662               then decl_ps
   662               then decl_ps
   663               else map (fn (tyco, (vs, _)) =>
   663               else map (fn (tyco, (vs, _)) =>
   664                 concat [str "type", print_tyco_expr (Type_Constructor tyco, map ITyVar vs)])
   664                 concat [Pretty.str "type", print_tyco_expr (Type_Constructor tyco, map ITyVar vs)])
   665                 (data :: datas))
   665                 (data :: datas))
   666             (Pretty.chunks (ps @| doublesemicolon [p]))
   666             (Pretty.chunks (ps @| doublesemicolon [p]))
   667           end
   667           end
   668      | print_stmt export (ML_Class (class, (v, (classrels, classparams)))) =
   668      | print_stmt export (ML_Class (class, (v, (classrels, classparams)))) =
   669           let
   669           let
   670             fun print_field s p = concat [str s, str ":", p];
   670             fun print_field s p = concat [Pretty.str s, Pretty.str ":", p];
   671             fun print_super_class_field (classrel as (_, super_class)) =
   671             fun print_super_class_field (classrel as (_, super_class)) =
   672               print_field (deresolve_classrel classrel) (print_dicttyp (super_class, ITyVar v));
   672               print_field (deresolve_classrel classrel) (print_dicttyp (super_class, ITyVar v));
   673             fun print_classparam_decl (classparam, ty) =
   673             fun print_classparam_decl (classparam, ty) =
   674               print_val_decl print_typscheme
   674               print_val_decl print_typscheme
   675                 (Constant classparam, ([(v, [class])], ty));
   675                 (Constant classparam, ([(v, [class])], ty));
   676             fun print_classparam_field (classparam, ty) =
   676             fun print_classparam_field (classparam, ty) =
   677               print_field (deresolve_const classparam) (print_typ NOBR ty);
   677               print_field (deresolve_const classparam) (print_typ NOBR ty);
   678             val w = "_" ^ Name.enforce_case true v;
   678             val w = "_" ^ Name.enforce_case true v;
   679             fun print_classparam_proj (classparam, _) =
   679             fun print_classparam_proj (classparam, _) =
   680               (concat o map str) ["let", deresolve_const classparam, w, "=",
   680               (concat o map Pretty.str) ["let", deresolve_const classparam, w, "=",
   681                 w ^ "." ^ deresolve_const classparam ^ ";;"];
   681                 w ^ "." ^ deresolve_const classparam ^ ";;"];
   682             val type_decl_p = concat [
   682             val type_decl_p = concat [
   683                 str "type",
   683                 Pretty.str "type",
   684                 print_dicttyp (class, ITyVar v),
   684                 print_dicttyp (class, ITyVar v),
   685                 str "=",
   685                 Pretty.str "=",
   686                 enum_default "unit" ";" "{" "}" (
   686                 enum_default "unit" ";" "{" "}" (
   687                   map print_super_class_field classrels
   687                   map print_super_class_field classrels
   688                   @ map print_classparam_field classparams
   688                   @ map print_classparam_field classparams
   689                 )
   689                 )
   690               ];
   690               ];
   691           in pair
   691           in pair
   692            (if Code_Namespace.is_public export
   692            (if Code_Namespace.is_public export
   693               then type_decl_p :: map print_classparam_decl classparams
   693               then type_decl_p :: map print_classparam_decl classparams
   694               else if null classrels andalso null classparams
   694               else if null classrels andalso null classparams
   695               then [type_decl_p] (*work around weakness in export calculation*)
   695               then [type_decl_p] (*work around weakness in export calculation*)
   696               else [concat [str "type", print_dicttyp (class, ITyVar v)]])
   696               else [concat [Pretty.str "type", print_dicttyp (class, ITyVar v)]])
   697             (Pretty.chunks (
   697             (Pretty.chunks (
   698               doublesemicolon [type_decl_p]
   698               doublesemicolon [type_decl_p]
   699               :: map print_classparam_proj classparams
   699               :: map print_classparam_proj classparams
   700             ))
   700             ))
   701           end;
   701           end;
   702   in print_stmt end;
   702   in print_stmt end;
   703 
   703 
   704 fun print_ocaml_module name decls body =
   704 fun print_ocaml_module name decls body =
   705   Pretty.chunks2 (
   705   Pretty.chunks2 (
   706     Pretty.chunks [
   706     Pretty.chunks [
   707       str ("module " ^ name ^ " : sig"),
   707       Pretty.str ("module " ^ name ^ " : sig"),
   708       (indent 2 o Pretty.chunks) decls,
   708       (Pretty.indent 2 o Pretty.chunks) decls,
   709       str "end = struct"
   709       Pretty.str "end = struct"
   710     ]
   710     ]
   711     :: body
   711     :: body
   712     @| str ("end;; (*struct " ^ name ^ "*)")
   712     @| Pretty.str ("end;; (*struct " ^ name ^ "*)")
   713   );
   713   );
   714 
   714 
   715 val literals_ocaml = let
   715 val literals_ocaml = let
   716   fun numeral_ocaml k = if k < 0
   716   fun numeral_ocaml k = if k < 0
   717     then "(Z.neg " ^ numeral_ocaml (~ k) ^ ")"
   717     then "(Z.neg " ^ numeral_ocaml (~ k) ^ ")"
   719       then "(Z.of_int " ^ string_of_int k ^ ")"
   719       then "(Z.of_int " ^ string_of_int k ^ ")"
   720       else "(Z.of_string " ^ quote (string_of_int k) ^ ")"
   720       else "(Z.of_string " ^ quote (string_of_int k) ^ ")"
   721 in Literals {
   721 in Literals {
   722   literal_string = print_ocaml_string,
   722   literal_string = print_ocaml_string,
   723   literal_numeral = numeral_ocaml,
   723   literal_numeral = numeral_ocaml,
   724   literal_list = enum ";" "[" "]",
   724   literal_list = Pretty.enum ";" "[" "]",
   725   infix_cons = (6, "::")
   725   infix_cons = (6, "::")
   726 } end;
   726 } end;
   727 
   727 
   728 
   728 
   729 
   729 
   866 (** Isar setup **)
   866 (** Isar setup **)
   867 
   867 
   868 fun fun_syntax print_typ fxy [ty1, ty2] =
   868 fun fun_syntax print_typ fxy [ty1, ty2] =
   869   brackify_infix (1, R) fxy (
   869   brackify_infix (1, R) fxy (
   870     print_typ (INFX (1, X)) ty1,
   870     print_typ (INFX (1, X)) ty1,
   871     str "->",
   871     Pretty.str "->",
   872     print_typ (INFX (1, R)) ty2
   872     print_typ (INFX (1, R)) ty2
   873   );
   873   );
   874 
   874 
   875 val _ = Theory.setup
   875 val _ = Theory.setup
   876   (Code_Target.add_language
   876   (Code_Target.add_language