src/HOL/Tools/record_package.ML
changeset 14709 d01983034ded
parent 14702 64844b4cc107
child 14854 61bdf2ae4dc5
equal deleted inserted replaced
14708:c0a65132d79a 14709:d01983034ded
    37                     -> (string * typ * mixfix) list -> theory -> theory
    37                     -> (string * typ * mixfix) list -> theory -> theory
    38   val setup: (theory -> theory) list
    38   val setup: (theory -> theory) list
    39 end;
    39 end;
    40 
    40 
    41 
    41 
    42 structure RecordPackage :RECORD_PACKAGE =    
    42 structure RecordPackage :RECORD_PACKAGE =     
    43 struct
    43 struct
    44 
    44 
    45 val rec_UNIV_I = thm "rec_UNIV_I";
    45 val rec_UNIV_I = thm "rec_UNIV_I";
    46 val rec_True_simp = thm "rec_True_simp";
    46 val rec_True_simp = thm "rec_True_simp";
    47 val Pair_eq = thm "Product_Type.Pair_eq";
    47 val Pair_eq = thm "Product_Type.Pair_eq";
    58 val rN = "r";
    58 val rN = "r";
    59 val moreN = "more";
    59 val moreN = "more";
    60 val schemeN = "_scheme";
    60 val schemeN = "_scheme";
    61 val ext_typeN = "_ext_type"; 
    61 val ext_typeN = "_ext_type"; 
    62 val extN ="_ext";
    62 val extN ="_ext";
    63 val ext_dest = "_val";
    63 val ext_dest = "_sel";
    64 val updateN = "_update";
    64 val updateN = "_update";
    65 val schemeN = "_scheme";
    65 val schemeN = "_scheme";
    66 val makeN = "make";
    66 val makeN = "make";
    67 val fields_selN = "fields";
    67 val fields_selN = "fields";
    68 val extendN = "extend";
    68 val extendN = "extend";
    72 val RepN = "Rep_";
    72 val RepN = "Rep_";
    73 val AbsN = "Abs_";
    73 val AbsN = "Abs_";
    74 
    74 
    75 (*** utilities ***)
    75 (*** utilities ***)
    76 
    76 
    77 
    77 fun but_last xs = fst (split_last xs);
    78 fun last [] = error "RecordPackage.last: empty list"
       
    79   | last [x] = x
       
    80   | last (x::xs) = last xs;
       
    81 
       
    82 fun but_last [] = error "RecordPackage.but_last: empty list"
       
    83   | but_last [x] = []
       
    84   | but_last (x::xs) = x::but_last xs;
       
    85 
       
    86 fun remdups [] = []
       
    87   | remdups (x::xs) = x::remdups (filter_out (fn y => y=x) xs);
       
    88 
       
    89 fun is_suffix sfx s = is_some (try (unsuffix sfx) s);
       
    90 
    78 
    91 (* messages *)
    79 (* messages *)
    92 
    80 
    93 val quiet_mode = ref false;
    81 val quiet_mode = ref false;
    94 fun message s = if ! quiet_mode then () else writeln s;
    82 fun message s = if ! quiet_mode then () else writeln s;
   149 (* types *)
   137 (* types *)
   150 
   138 
   151 fun dest_recT (typ as Type (c_ext_type, Ts as (T::_))) =
   139 fun dest_recT (typ as Type (c_ext_type, Ts as (T::_))) =
   152       (case try (unsuffix ext_typeN) c_ext_type of
   140       (case try (unsuffix ext_typeN) c_ext_type of
   153         None => raise TYPE ("RecordPackage.dest_recT", [typ], [])
   141         None => raise TYPE ("RecordPackage.dest_recT", [typ], [])
   154       | Some c => ((c, Ts), last Ts))
   142       | Some c => ((c, Ts), last_elem Ts))
   155   | dest_recT typ = raise TYPE ("RecordPackage.dest_recT", [typ], []);
   143   | dest_recT typ = raise TYPE ("RecordPackage.dest_recT", [typ], []);
   156 
   144 
   157 fun is_recT T =
   145 fun is_recT T =
   158   (case try dest_recT T of None => false | Some _ => true); 
   146   (case try dest_recT T of None => false | Some _ => true); 
   159 
   147 
   219   equalities = equalities, splits = splits, 
   207   equalities = equalities, splits = splits, 
   220   extfields = extfields, fieldext = fieldext }: record_data;
   208   extfields = extfields, fieldext = fieldext }: record_data;
   221 
   209 
   222 structure RecordsArgs =
   210 structure RecordsArgs =
   223 struct
   211 struct
   224   val name = "HOL/records";    
   212   val name = "HOL/structures"; (* FIXME *)    
   225   type T = record_data;
   213   type T = record_data;
   226 
   214 
   227   val empty =
   215   val empty =
   228     make_record_data Symtab.empty
   216     make_record_data Symtab.empty
   229       {selectors = Symtab.empty, updates = Symtab.empty, simpset = HOL_basic_ss}
   217       {selectors = Symtab.empty, updates = Symtab.empty, simpset = HOL_basic_ss}
   437      else [dest_ext_field mark trm]
   425      else [dest_ext_field mark trm]
   438   | dest_ext_fields _ mark t = [dest_ext_field mark t]
   426   | dest_ext_fields _ mark t = [dest_ext_field mark t]
   439 
   427 
   440 fun gen_ext_fields_tr sep mark sfx more sg t =
   428 fun gen_ext_fields_tr sep mark sfx more sg t =
   441   let 
   429   let 
       
   430     val msg = "error in record input: ";
   442     val fieldargs = dest_ext_fields sep mark t; 
   431     val fieldargs = dest_ext_fields sep mark t; 
   443     fun splitargs (field::fields) ((name,arg)::fargs) =
   432     fun splitargs (field::fields) ((name,arg)::fargs) =
   444           if is_suffix name field
   433           if can (unsuffix name) field
   445           then let val (args,rest) = splitargs fields fargs
   434           then let val (args,rest) = splitargs fields fargs
   446                in (arg::args,rest) end
   435                in (arg::args,rest) end
   447           else raise TERM ("gen_ext_fields_tr: expecting field " ^ field ^ 
   436           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   448                            " but got " ^ name, [t])
       
   449       | splitargs [] (fargs as (_::_)) = ([],fargs)
   437       | splitargs [] (fargs as (_::_)) = ([],fargs)
   450       | splitargs (_::_) [] = raise TERM ("gen_ext_fields_tr: expecting more fields", [t])
   438       | splitargs (_::_) [] = raise TERM (msg ^ "expecting more fields", [t])
   451       | splitargs _ _ = ([],[]);
   439       | splitargs _ _ = ([],[]);
   452 
   440 
   453     fun mk_ext (fargs as (name,arg)::_) =
   441     fun mk_ext (fargs as (name,arg)::_) =
   454          (case get_fieldext sg (Sign.intern_const sg name) of
   442          (case get_fieldext sg (Sign.intern_const sg name) of
   455             Some (ext,_) => (case get_extfields sg ext of
   443             Some (ext,_) => (case get_extfields sg ext of
   457                                  => let val (args,rest) = 
   445                                  => let val (args,rest) = 
   458                                                splitargs (map fst (but_last flds)) fargs;
   446                                                splitargs (map fst (but_last flds)) fargs;
   459                                         val more' = mk_ext rest;  
   447                                         val more' = mk_ext rest;  
   460                                     in list_comb (Syntax.const (suffix sfx ext),args@[more'])
   448                                     in list_comb (Syntax.const (suffix sfx ext),args@[more'])
   461                                     end
   449                                     end
   462                              | None => raise TERM("gen_ext_fields_tr: no fields defined for "
   450                              | None => raise TERM(msg ^ "no fields defined for "
   463                                                    ^ ext,[t]))
   451                                                    ^ ext,[t]))
   464           | None => raise TERM ("gen_ext_fields_tr: "^ name ^" is no proper field",[t]))
   452           | None => raise TERM (msg ^ name ^" is no proper field",[t]))
   465       | mk_ext [] = more
   453       | mk_ext [] = more
   466 
   454 
   467   in mk_ext fieldargs end;   
   455   in mk_ext fieldargs end;   
   468 
   456 
   469 fun gen_ext_type_tr sep mark sfx more sg t =
   457 fun gen_ext_type_tr sep mark sfx more sg t =
   470   let 
   458   let 
       
   459     val msg = "error in record-type input: ";
   471     val fieldargs = dest_ext_fields sep mark t; 
   460     val fieldargs = dest_ext_fields sep mark t; 
   472     fun splitargs (field::fields) ((name,arg)::fargs) =
   461     fun splitargs (field::fields) ((name,arg)::fargs) =
   473           if is_suffix name field
   462           if can (unsuffix name) field
   474           then let val (args,rest) = splitargs fields fargs
   463           then let val (args,rest) = splitargs fields fargs
   475                in (arg::args,rest) end
   464                in (arg::args,rest) end
   476           else raise TERM ("gen_ext_type_tr: expecting field " ^ field ^ 
   465           else raise TERM (msg ^ "expecting field " ^ field ^ " but got " ^ name, [t])
   477                            " but got " ^ name, [t])
       
   478       | splitargs [] (fargs as (_::_)) = ([],fargs)
   466       | splitargs [] (fargs as (_::_)) = ([],fargs)
   479       | splitargs (_::_) [] = raise TERM ("gen_ext_type_tr: expecting more fields", [t])
   467       | splitargs (_::_) [] = raise TERM (msg ^ "expecting more fields", [t])
   480       | splitargs _ _ = ([],[]);
   468       | splitargs _ _ = ([],[]);
   481 
   469 
   482     fun get_sort xs n = (case assoc (xs,n) of 
   470     fun get_sort xs n = (case assoc (xs,n) of 
   483                                 Some s => s 
   471                                 Some s => s 
   484                               | None => Sign.defaultS sg);
   472                               | None => Sign.defaultS sg);
   505                                          (but_last alphas);
   493                                          (but_last alphas);
   506  
   494  
   507                        val more' = mk_ext rest;   
   495                        val more' = mk_ext rest;   
   508                      in list_comb (Syntax.const (suffix sfx ext),alphas'@[more']) 
   496                      in list_comb (Syntax.const (suffix sfx ext),alphas'@[more']) 
   509                      end handle TUNIFY => raise 
   497                      end handle TUNIFY => raise 
   510                            TERM ("gen_ext_type_tr: type is no proper record (extension)", [t]))
   498                            TERM (msg ^ "type is no proper record (extension)", [t]))
   511                | None => raise TERM ("gen_ext_fields_tr: no fields defined for " ^ ext,[t]))
   499                | None => raise TERM (msg ^ "no fields defined for " ^ ext,[t]))
   512           | None => raise TERM ("gen_ext_fields_tr: "^ name ^" is no proper field",[t]))
   500           | None => raise TERM (msg ^ name ^" is no proper field",[t]))
   513       | mk_ext [] = more
   501       | mk_ext [] = more
   514 
   502 
   515   in mk_ext fieldargs end;   
   503   in mk_ext fieldargs end;   
   516 
   504 
   517 fun gen_adv_record_tr sep mark sfx unit sg [t] = 
   505 fun gen_adv_record_tr sep mark sfx unit sg [t] = 
  1123     val dest_specs =
  1111     val dest_specs =
  1124       ListPair.map mk_dest_spec (idxms, fields_more);
  1112       ListPair.map mk_dest_spec (idxms, fields_more);
  1125 
  1113 
  1126     (* code generator data *)
  1114     (* code generator data *)
  1127         (* Representation as nested pairs is revealed for codegeneration *)
  1115         (* Representation as nested pairs is revealed for codegeneration *)
  1128     val [rep_code,abs_code] = map (Codegen.parse_mixfix (K (Bound 0))) ["I","I"];
  1116     val [rep_code,abs_code] = map (Codegen.parse_mixfix (K (Bound 0))) ["(_)","(_)"];
  1129     val ext_type_code = Codegen.parse_mixfix (K dummyT) "_";
  1117     val ext_type_code = Codegen.parse_mixfix (K dummyT) "(_)";
  1130     
  1118     
  1131     (* 1st stage: defs_thy *)
  1119     (* 1st stage: defs_thy *)
  1132     val (defs_thy, ([abs_inject, abs_inverse, abs_induct],ext_def::dest_defs)) =
  1120     val (defs_thy, ([abs_inject, abs_inverse, abs_induct],ext_def::dest_defs)) =
  1133         thy 
  1121         thy 
  1134         |> extension_typedef name repT (alphas@[zeta])
  1122         |> extension_typedef name repT (alphas@[zeta])
  1693 (* setup theory *)
  1681 (* setup theory *)
  1694 
  1682 
  1695 val setup =
  1683 val setup =
  1696  [RecordsData.init,
  1684  [RecordsData.init,
  1697   Theory.add_trfuns ([], parse_translation, [], []),
  1685   Theory.add_trfuns ([], parse_translation, [], []),
  1698   Theory.add_advanced_trfuns ([], adv_parse_translation, [], []),  
  1686   Theory.add_advanced_trfuns ([], adv_parse_translation, [], []),   
  1699   Simplifier.change_simpset_of Simplifier.addsimprocs
  1687   Simplifier.change_simpset_of Simplifier.addsimprocs
  1700     [record_simproc, record_eq_simproc]];
  1688     [record_simproc, record_upd_simproc, record_eq_simproc]];
  1701 
  1689 
  1702 (* outer syntax *)
  1690 (* outer syntax *)
  1703 
  1691 
  1704 local structure P = OuterParse and K = OuterSyntax.Keyword in
  1692 local structure P = OuterParse and K = OuterSyntax.Keyword in
  1705 
  1693 
  1706 val record_decl =
  1694 val record_decl =
  1707   P.type_args -- P.name --
  1695   P.type_args -- P.name --
  1708     (P.$$$ "=" |-- Scan.option (P.typ --| P.$$$ "+") -- Scan.repeat1 P.const);
  1696     (P.$$$ "=" |-- Scan.option (P.typ --| P.$$$ "+") -- Scan.repeat1 P.const);
  1709 
  1697 
  1710 val recordP =
  1698 val recordP =
  1711   OuterSyntax.command "record" "define extensible record" K.thy_decl   
  1699   OuterSyntax.command "record" "define extensible record" K.thy_decl  
  1712     (record_decl >> (fn (x, (y, z)) => Toplevel.theory (add_record x y z)));  
  1700     (record_decl >> (fn (x, (y, z)) => Toplevel.theory (add_record x y z)));  
  1713 
  1701 
  1714 val _ = OuterSyntax.add_parsers [recordP];
  1702 val _ = OuterSyntax.add_parsers [recordP];
  1715 
  1703 
  1716 end;
  1704 end;