src/HOL/Tools/record_package.ML
changeset 4894 32187e0b8b48
parent 4890 f0a24bad990a
child 4895 0fad2acb45fb
equal deleted inserted replaced
4893:df9d6eef16d5 4894:32187e0b8b48
     5 Extensible records with structural subtyping in HOL.
     5 Extensible records with structural subtyping in HOL.
     6 
     6 
     7 TODO:
     7 TODO:
     8   - field types: typedef;
     8   - field types: typedef;
     9   - trfuns for record types;
     9   - trfuns for record types;
    10   - provide more operations and theorems: split, split_all/ex, ...;
    10   - operations and theorems: split, split_all/ex, ...;
    11   - field constructor: specific type for snd component;
    11   - field constructor: specific type for snd component (?);
       
    12   - update_more operation;
       
    13   - "..." for "... = more", "?..." for "?... = ?more";
    12 *)
    14 *)
    13 
    15 
    14 signature RECORD_PACKAGE =
    16 signature RECORD_PACKAGE =
    15 sig
    17 sig
    16   val moreS: sort
    18   val moreS: sort
    34 
    36 
    35 structure RecordPackage: RECORD_PACKAGE =
    37 structure RecordPackage: RECORD_PACKAGE =
    36 struct
    38 struct
    37 
    39 
    38 
    40 
       
    41 (*** utilities ***)
       
    42 
       
    43 (* string suffixes *)
       
    44 
       
    45 fun suffix sfx s = s ^ sfx;
       
    46 
       
    47 fun unsuffix sfx s =
       
    48   let
       
    49     val cs = explode s;
       
    50     val prfx_len = size s - size sfx;
       
    51   in
       
    52     if prfx_len >= 0 andalso implode (drop (prfx_len, cs)) = sfx then
       
    53       implode (take (prfx_len, cs))
       
    54     else raise LIST "unsuffix"
       
    55   end;
       
    56 
       
    57 
       
    58 (* definitions and equations *)
       
    59 
       
    60 infix 0 :== === ;
       
    61 
       
    62 val (op :==) = Logic.mk_defpair;
       
    63 val (op ===) = HOLogic.mk_Trueprop o HOLogic.mk_eq;
       
    64 
       
    65 fun get_defs thy specs = map (PureThy.get_tthm thy o fst) specs;
       
    66 fun add_simps ss simps = Simplifier.addsimps (ss, map Attribute.thm_of simps);
       
    67 
       
    68 
       
    69 (* proof by simplification *)
       
    70 
       
    71 fun prove_simp opt_ss simps =
       
    72   let
       
    73     val ss = add_simps (if_none opt_ss HOL_basic_ss) simps;
       
    74     fun prove thy goal =
       
    75       Attribute.tthm_of
       
    76         (Goals.prove_goalw_cterm [] (Thm.cterm_of (Theory.sign_of thy) goal)
       
    77           (K [ALLGOALS (Simplifier.simp_tac ss)])
       
    78         handle ERROR => error ("The error(s) above occurred while trying to prove "
       
    79           ^ quote (Sign.string_of_term (Theory.sign_of thy) goal)));
       
    80   in prove end;
       
    81 
       
    82 
       
    83 
    39 (*** syntax operations ***)
    84 (*** syntax operations ***)
    40 
    85 
    41 (** names **)
    86 (** name components **)
    42 
       
    43 (* name components *)
       
    44 
    87 
    45 val moreN = "more";
    88 val moreN = "more";
    46 val schemeN = "_scheme";
    89 val schemeN = "_scheme";
    47 val fieldN = "_field";
    90 val fieldN = "_field";
    48 val field_typeN = "_field_type";
    91 val field_typeN = "_field_type";
    51 val updateN = "_update";
    94 val updateN = "_update";
    52 val makeN = "make";
    95 val makeN = "make";
    53 val make_schemeN = "make_scheme";
    96 val make_schemeN = "make_scheme";
    54 
    97 
    55 
    98 
    56 (* suffixes *)
       
    57 
       
    58 fun suffix sfx s = s ^ sfx;
       
    59 
       
    60 fun unsuffix sfx s =
       
    61   let
       
    62     val cs = explode s;
       
    63     val prfx_len = size s - size sfx;
       
    64   in
       
    65     if prfx_len >= 0 andalso implode (drop (prfx_len, cs)) = sfx then
       
    66       implode (take (prfx_len, cs))
       
    67     else raise LIST "unsuffix"
       
    68   end;
       
    69 
       
    70 
       
    71 
       
    72 (** generic Pure / HOL **)		(* FIXME move(?) *)
       
    73 
       
    74 val mk_def = Logic.mk_defpair;
       
    75 val mk_eq = HOLogic.mk_Trueprop o HOLogic.mk_eq;
       
    76 
       
    77 
       
    78 
    99 
    79 (** tuple operations **)
   100 (** tuple operations **)
    80 
   101 
    81 (* more type class *)
   102 (* more type class *)
    82 
   103 
   147 fun mk_selC rT (c, T) = (c, rT --> T);
   168 fun mk_selC rT (c, T) = (c, rT --> T);
   148 
   169 
   149 fun mk_sel r c =
   170 fun mk_sel r c =
   150   let val rT = fastype_of r
   171   let val rT = fastype_of r
   151   in Const (mk_selC rT (c, find_fieldT c rT)) $ r end;
   172   in Const (mk_selC rT (c, find_fieldT c rT)) $ r end;
       
   173 
       
   174 val mk_moreC = mk_selC;
       
   175 
       
   176 fun mk_more r c =
       
   177   let val rT = fastype_of r
       
   178   in Const (mk_moreC rT (c, snd (dest_recordT rT))) $ r end;
   152 
   179 
   153 
   180 
   154 (* updates *)
   181 (* updates *)
   155 
   182 
   156 fun mk_updateC rT (c, T) = (suffix updateN c, T --> rT --> rT);
   183 fun mk_updateC rT (c, T) = (suffix updateN c, T --> rT --> rT);
   273     Records tab => tab
   300     Records tab => tab
   274   | _ => type_error recordsK);
   301   | _ => type_error recordsK);
   275 
   302 
   276 fun get_record thy name = Symtab.lookup (get_records thy, name);
   303 fun get_record thy name = Symtab.lookup (get_records thy, name);
   277 
   304 
   278 
       
   279 fun put_records tab thy =
   305 fun put_records tab thy =
   280   Theory.put_data (recordsK, Records tab) thy;
   306   Theory.put_data (recordsK, Records tab) thy;
   281 
   307 
   282 fun put_record name info thy =
   308 fun put_record name info thy =
   283   thy |> put_records (Symtab.update ((name, info), get_records thy));
   309   thy |> put_records (Symtab.update ((name, info), get_records thy));
   314 
   340 
   315 
   341 
   316 
   342 
   317 (** internal theory extenders **)
   343 (** internal theory extenders **)
   318 
   344 
   319 (* utils *)
   345 (* field_definitions *)
   320 
   346 
   321 fun get_defs thy specs = map (PureThy.get_tthm thy o fst) specs;
   347 (*theorems from Prod.thy*)
   322 
       
   323 (*proof by simplification*)
       
   324 fun prove_simp opt_ss simps =
       
   325   let
       
   326     val ss = if_none opt_ss HOL_basic_ss addsimps (map Attribute.thm_of simps);
       
   327     fun prove thy goal =
       
   328       Attribute.tthm_of
       
   329         (Goals.prove_goalw_cterm [] (Thm.cterm_of (Theory.sign_of thy) goal)
       
   330           (K [ALLGOALS (Simplifier.simp_tac ss)])
       
   331         handle ERROR => error ("The error(s) above occurred while trying to prove "
       
   332           ^ quote (Sign.string_of_term (Theory.sign_of thy) goal)));
       
   333   in prove end;
       
   334 
       
   335 (*thms from Prod.thy*)
       
   336 val prod_convs = map Attribute.tthm_of [fst_conv, snd_conv];
   348 val prod_convs = map Attribute.tthm_of [fst_conv, snd_conv];
   337 
   349 
   338 
   350 
   339 (* field_definitions *)		(* FIXME tune; actual typedefs! *)
   351 fun field_definitions fields names zeta moreT more vars named_vars thy =
   340 
       
   341 fun field_definitions fields names zeta moreT more vars thy =
       
   342   let
   352   let
   343     val base = Sign.base_name;
   353     val base = Sign.base_name;
   344 
   354 
   345 
   355 
   346     (* prepare declarations and definitions *)
   356     (* prepare declarations and definitions *)
   355     val field_decls = map (mk_fieldC moreT) fields;
   365     val field_decls = map (mk_fieldC moreT) fields;
   356     val dest_decls = map (mk_fstC moreT) fields @ map (mk_sndC moreT) fields;
   366     val dest_decls = map (mk_fstC moreT) fields @ map (mk_sndC moreT) fields;
   357 
   367 
   358     (*field constructors*)
   368     (*field constructors*)
   359     fun mk_field_spec (c, v) =
   369     fun mk_field_spec (c, v) =
   360       mk_def (mk_field ((c, v), more), HOLogic.mk_prod (v, more));
   370       mk_field ((c, v), more) :== HOLogic.mk_prod (v, more);
   361     val field_specs = ListPair.map mk_field_spec (names, vars);
   371     val field_specs = map mk_field_spec named_vars;
   362 
   372 
   363     (*field destructors*)
   373     (*field destructors*)
   364     fun mk_dest_spec dest dest' (c, T) =
   374     fun mk_dest_spec dest dest' (c, T) =
   365       let
   375       let
   366         val p = Free ("p",  mk_fieldT ((c, T), moreT));
   376         val p = Free ("p",  mk_fieldT ((c, T), moreT));
   367         val p' = Free ("p",  HOLogic.mk_prodT (T, moreT));  (*Note: field types are just abbreviations*)
   377         val p' = Free ("p",  HOLogic.mk_prodT (T, moreT));
   368       in mk_def (dest p, dest' p') end;
   378           (*note: field types are just abbreviations*)
       
   379       in dest p :== dest' p' end;
   369     val dest_specs =
   380     val dest_specs =
   370       map (mk_dest_spec mk_fst HOLogic.mk_fst) fields @
   381       map (mk_dest_spec mk_fst HOLogic.mk_fst) fields @
   371       map (mk_dest_spec mk_snd HOLogic.mk_snd) fields;
   382       map (mk_dest_spec mk_snd HOLogic.mk_snd) fields;
   372 
   383 
   373 
   384 
   374     (* prepare theorems *)
   385     (* prepare theorems *)
       
   386 
   375     fun mk_dest_prop dest dest' (c, v) =
   387     fun mk_dest_prop dest dest' (c, v) =
   376       mk_eq (dest (mk_field ((c, v), more)), dest' (v, more));
   388       dest (mk_field ((c, v), more)) === dest' (v, more);
   377     val dest_props =
   389     val dest_props =
   378       ListPair.map (mk_dest_prop mk_fst fst) (names, vars) @
   390       map (mk_dest_prop mk_fst fst) named_vars @ map (mk_dest_prop mk_snd snd) named_vars;
   379       ListPair.map (mk_dest_prop mk_snd snd) (names, vars);
       
   380 
   391 
   381 
   392 
   382     (* 1st stage: defs_thy *)
   393     (* 1st stage: defs_thy *)
   383 
   394 
   384     val defs_thy =
   395     val defs_thy =
   390         (field_specs @ dest_specs);
   401         (field_specs @ dest_specs);
   391 
   402 
   392     val field_defs = get_defs defs_thy field_specs;
   403     val field_defs = get_defs defs_thy field_specs;
   393     val dest_defs = get_defs defs_thy dest_specs;
   404     val dest_defs = get_defs defs_thy dest_specs;
   394 
   405 
       
   406 
       
   407     (* 2nd stage: thms_thy *)
       
   408 
   395     val dest_convs =
   409     val dest_convs =
   396       map (prove_simp None (prod_convs @ field_defs @ dest_defs) defs_thy) dest_props;
   410       map (prove_simp None (field_defs @ dest_defs @ prod_convs) defs_thy) dest_props;
   397 
       
   398 
       
   399     (* 2nd stage: thms_thy *)
       
   400 
   411 
   401     val thms_thy =
   412     val thms_thy =
   402       defs_thy
   413       defs_thy
   403       |> (PureThy.add_tthmss o map Attribute.none)
   414       |> (PureThy.add_tthmss o map Attribute.none)
   404         [("field_defs", field_defs),
   415         [("field_defs", field_defs),
   429     val parent_names = map fst parent_fields;
   440     val parent_names = map fst parent_fields;
   430     val parent_types = map snd parent_fields;
   441     val parent_types = map snd parent_fields;
   431     val parent_len = length parent_fields;
   442     val parent_len = length parent_fields;
   432     val parent_xs = variantlist (map (base o fst) parent_fields, [moreN]);
   443     val parent_xs = variantlist (map (base o fst) parent_fields, [moreN]);
   433     val parent_vars = ListPair.map Free (parent_xs, parent_types);
   444     val parent_vars = ListPair.map Free (parent_xs, parent_types);
       
   445     val parent_named_vars = parent_names ~~ parent_vars;
   434 
   446 
   435     val fields = map (apfst full) bfields;
   447     val fields = map (apfst full) bfields;
   436     val names = map fst fields;
   448     val names = map fst fields;
   437     val types = map snd fields;
   449     val types = map snd fields;
   438     val len = length fields;
   450     val len = length fields;
   439     val xs = variantlist (map fst bfields, moreN :: parent_xs);
   451     val xs = variantlist (map fst bfields, moreN :: parent_xs);
   440     val vars = ListPair.map Free (xs, types);
   452     val vars = ListPair.map Free (xs, types);
       
   453     val named_vars = names ~~ vars;
   441 
   454 
   442     val all_fields = parent_fields @ fields;
   455     val all_fields = parent_fields @ fields;
   443     val all_names = parent_names @ names;
   456     val all_names = parent_names @ names;
   444     val all_types = parent_types @ types;
   457     val all_types = parent_types @ types;
   445     val all_len = parent_len + len;
   458     val all_len = parent_len + len;
   446     val all_xs = parent_xs @ xs;
   459     val all_xs = parent_xs @ xs;
   447     val all_vars = parent_vars @ vars;
   460     val all_vars = parent_vars @ vars;
   448 
   461     val all_named_vars = parent_named_vars @ named_vars;
   449 
   462 
   450     val zeta = variant alphas "'z";
   463     val zeta = variant alphas "'z";
   451     val moreT = TFree (zeta, moreS);
   464     val moreT = TFree (zeta, moreS);
   452     val more = Free (variant xs moreN, moreT);
   465     val more = Free (variant xs moreN, moreT);
       
   466     fun more_part t = mk_more t (full moreN);
       
   467 
       
   468     val parent_more = funpow parent_len mk_snd;
       
   469     val idxs = 0 upto (len - 1);
   453 
   470 
   454     val rec_schemeT = mk_recordT (all_fields, moreT);
   471     val rec_schemeT = mk_recordT (all_fields, moreT);
       
   472     val rec_scheme = mk_record (all_named_vars, more);
       
   473     val r = Free ("r", rec_schemeT);
   455     val recT = mk_recordT (all_fields, HOLogic.unitT);
   474     val recT = mk_recordT (all_fields, HOLogic.unitT);
   456     val r = Free ("r", rec_schemeT);
       
   457 
       
   458     val parent_more = funpow parent_len mk_snd;
       
   459 
   475 
   460 
   476 
   461     (* prepare print translation functions *)
   477     (* prepare print translation functions *)
   462 
   478 
   463     val field_tr'_names =
   479     val field_tr'_names =
   466     val field_trfuns = ([], [], field_tr'_names ~~ map field_tr' field_tr'_names, []);
   482     val field_trfuns = ([], [], field_tr'_names ~~ map field_tr' field_tr'_names, []);
   467 
   483 
   468 
   484 
   469     (* prepare declarations *)
   485     (* prepare declarations *)
   470 
   486 
   471     val sel_decls = map (mk_selC rec_schemeT) fields;
   487     val sel_decls = map (mk_selC rec_schemeT) bfields @ [mk_moreC rec_schemeT (moreN, moreT)];
   472     val more_decl = (moreN, rec_schemeT --> moreT);
   488     val update_decls = map (mk_updateC rec_schemeT) bfields;
   473     val update_decls = map (mk_updateC rec_schemeT) fields;
       
   474     val make_decls =
   489     val make_decls =
   475       [(mk_makeC rec_schemeT (make_schemeN, all_types @ [moreT])),
   490       [(mk_makeC rec_schemeT (make_schemeN, all_types @ [moreT])),
   476        (mk_makeC recT (makeN, all_types))];
   491        (mk_makeC recT (makeN, all_types))];
   477 
   492 
   478 
   493 
   481     (* record (scheme) type abbreviation *)
   496     (* record (scheme) type abbreviation *)
   482     val recordT_specs =
   497     val recordT_specs =
   483       [(suffix schemeN bname, alphas @ [zeta], rec_schemeT, Syntax.NoSyn),
   498       [(suffix schemeN bname, alphas @ [zeta], rec_schemeT, Syntax.NoSyn),
   484         (bname, alphas, recT, Syntax.NoSyn)];
   499         (bname, alphas, recT, Syntax.NoSyn)];
   485 
   500 
   486     (*field selectors*)
   501     (*selectors*)
   487     fun mk_sel_spec (i, c) =
   502     fun mk_sel_spec (i, c) =
   488       mk_def (mk_sel r c, mk_fst (funpow i mk_snd (parent_more r)));
   503       mk_sel r c :== mk_fst (funpow i mk_snd (parent_more r));
   489     val sel_specs = ListPair.map mk_sel_spec (0 upto (len - 1), names);
   504     val sel_specs =
   490 
   505       ListPair.map mk_sel_spec (idxs, names) @
   491     (*more quasi-selector*)
   506         [more_part r :== funpow len mk_snd (parent_more r)];
   492     val more_part = Const (full moreN, rec_schemeT --> moreT) $ r;
   507 
   493     val more_spec = mk_def (more_part, funpow len mk_snd (parent_more r));
       
   494         
       
   495     (*updates*)
   508     (*updates*)
       
   509     val all_sels = all_names ~~ map (mk_sel r) all_names;
   496     fun mk_upd_spec (i, (c, x)) =
   510     fun mk_upd_spec (i, (c, x)) =
   497       let
   511       mk_update r (c, x) :==
   498         val prfx = map (mk_sel r) (parent_names @ take (i, names));
   512         mk_record (nth_update (c, x) (parent_len + i, all_sels), more_part r)
   499         val sffx = map (mk_sel r) (drop (i + 1, names));
   513     val update_specs = ListPair.map mk_upd_spec (idxs, named_vars);
   500       in mk_def (mk_update r (c, x), mk_record (all_names ~~ (prfx @ [x] @ sffx), more_part)) end;
       
   501     val update_specs = ListPair.map mk_upd_spec (0 upto (len - 1), names ~~ vars);
       
   502 
   514 
   503     (*makes*)
   515     (*makes*)
   504     val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT]));
   516     val make_scheme = Const (mk_makeC rec_schemeT (full make_schemeN, all_types @ [moreT]));
   505     val make = Const (mk_makeC recT (full makeN, all_types));
   517     val make = Const (mk_makeC recT (full makeN, all_types));
   506     val make_specs =
   518     val make_specs =
   507       map mk_def
   519       [list_comb (make_scheme, all_vars) $ more :== rec_scheme,
   508         [(list_comb (make_scheme, all_vars) $ more, mk_record (all_names ~~ all_vars, more)),
   520         list_comb (make, all_vars) :== mk_record (all_named_vars, HOLogic.unit)];
   509           (list_comb (make, all_vars), mk_record (all_names ~~ all_vars, HOLogic.unit))];
   521 
       
   522 
       
   523     (* prepare propositions *)
       
   524 
       
   525     (*selectors*)
       
   526     val sel_props =
       
   527       map (fn (c, x) => mk_sel rec_scheme c === x) named_vars @
       
   528         [more_part rec_scheme === more];
       
   529 
       
   530     (*updates*)
       
   531     fun mk_upd_prop (i, (c, T)) =
       
   532       let val x' = Free (variant all_xs (base c ^ "'"), T) in
       
   533         mk_update rec_scheme (c, x') ===
       
   534           mk_record (nth_update (c, x') (parent_len + i, all_named_vars), more)
       
   535       end;
       
   536     val update_props = ListPair.map mk_upd_prop (idxs, fields);
   510 
   537 
   511 
   538 
   512     (* 1st stage: fields_thy *)
   539     (* 1st stage: fields_thy *)
   513 
   540 
   514     val (fields_thy, field_simps) =
   541     val (fields_thy, field_simps) =
   515       thy
   542       thy
   516       |> Theory.add_path bname
   543       |> Theory.add_path bname
   517       |> field_definitions fields names zeta moreT more vars;
   544       |> field_definitions fields names zeta moreT more vars named_vars;
   518 
   545 
   519 
   546 
   520     (* 2nd stage: defs_thy *)
   547     (* 2nd stage: defs_thy *)
   521 
   548 
   522     val defs_thy =
   549     val defs_thy =
   523       fields_thy
   550       fields_thy
   524       |> Theory.parent_path
   551       |> Theory.parent_path
   525       |> Theory.add_tyabbrs_i recordT_specs	(*not made part of record name space!*)
   552       |> Theory.add_tyabbrs_i recordT_specs	(*not made part of record name space!*)
   526       |> Theory.add_path bname
   553       |> Theory.add_path bname
   527       |> Theory.add_trfuns field_trfuns
   554       |> Theory.add_trfuns field_trfuns
   528       |> (Theory.add_consts_i o map (Syntax.no_syn o apfst base))
   555       |> (Theory.add_consts_i o map Syntax.no_syn)
   529         (sel_decls @ [more_decl] @ update_decls @ make_decls)
   556         (sel_decls @ update_decls @ make_decls)
   530       |> (PureThy.add_defs_i o map Attribute.none)
   557       |> (PureThy.add_defs_i o map Attribute.none)
   531         (sel_specs @ [more_spec] @ update_specs @ make_specs);
   558         (sel_specs @ update_specs @ make_specs);
   532 
   559 
   533     val sel_defs = get_defs defs_thy sel_specs;
   560     val sel_defs = get_defs defs_thy sel_specs;
   534     val more_def = hd (get_defs defs_thy [more_spec]);
       
   535     val update_defs = get_defs defs_thy update_specs;
   561     val update_defs = get_defs defs_thy update_specs;
   536     val make_defs = get_defs defs_thy make_specs;
   562     val make_defs = get_defs defs_thy make_specs;
   537 
   563 
   538 
   564 
   539     (* 3rd stage: thms_thy *)
   565     (* 3rd stage: thms_thy *)
   541     val parent_simpset =
   567     val parent_simpset =
   542       (case parent of
   568       (case parent of
   543         None => HOL_basic_ss
   569         None => HOL_basic_ss
   544       | Some (_, pname) => #simpset (the (get_record thy pname)));
   570       | Some (_, pname) => #simpset (the (get_record thy pname)));
   545 
   571 
   546     val simpset = parent_simpset;	(* FIXME *)
   572     val pss = Some parent_simpset;
       
   573 
       
   574     val sel_convs = map (prove_simp pss (sel_defs @ field_simps) defs_thy) sel_props;
       
   575     val update_convs = map (prove_simp pss (update_defs @ sel_convs) defs_thy) update_props;
       
   576     val simps = field_simps @ sel_convs @ update_convs @ make_defs;
   547 
   577 
   548     val thms_thy =
   578     val thms_thy =
   549       defs_thy
   579       defs_thy
   550       |> (PureThy.add_tthmss o map Attribute.none)
   580       |> (PureThy.add_tthmss o map Attribute.none)
   551         [("sel_defs", sel_defs),
   581         [("selector_defs", sel_defs),
   552           ("update_defs", update_defs),
   582           ("update_defs", update_defs),
   553           ("make_defs", make_defs)];
   583           ("make_defs", make_defs),
   554 
   584           ("selector_convs", sel_convs),
   555 (*    |> record_theorems FIXME *)
   585           ("update_convs", update_convs)]
       
   586       |> PureThy.add_tthmss [(("simps", simps), [Simplifier.simp_add_global])];
   556 
   587 
   557 
   588 
   558     (* 4th stage: final_thy *)
   589     (* 4th stage: final_thy *)
       
   590 
       
   591     val simpset = add_simps parent_simpset simps;
   559 
   592 
   560     val final_thy =
   593     val final_thy =
   561       thms_thy
   594       thms_thy
   562       |> put_record name {args = args, parent = parent, fields = fields, simpset = simpset}
   595       |> put_record name {args = args, parent = parent, fields = fields, simpset = simpset}
   563       |> Theory.parent_path;
   596       |> Theory.parent_path;
   568 
   601 
   569 (** theory extender interface **)
   602 (** theory extender interface **)
   570 
   603 
   571 (* prepare arguments *)
   604 (* prepare arguments *)
   572 
   605 
   573 (*Note: read_raw_typ avoids expanding type abbreviations*)
   606 (*note: read_raw_typ avoids expanding type abbreviations*)
   574 fun read_raw_parent sign s =
   607 fun read_raw_parent sign s =
   575   (case Sign.read_raw_typ (sign, K None) s handle TYPE (msg, _, _) => error msg of
   608   (case Sign.read_raw_typ (sign, K None) s handle TYPE (msg, _, _) => error msg of
   576     Type (name, Ts) => (Ts, name)
   609     Type (name, Ts) => (Ts, name)
   577   | _ => error ("Bad parent record specification: " ^ quote s));
   610   | _ => error ("Bad parent record specification: " ^ quote s));
   578 
   611