src/HOL/Tools/record_package.ML
changeset 5707 b0e631634b5a
parent 5698 2b5d9bdec5af
child 5713 27d4fcf5fe5f
equal deleted inserted replaced
5706:21706a735c8d 5707:b0e631634b5a
     7 
     7 
     8 signature BASIC_RECORD_PACKAGE =
     8 signature BASIC_RECORD_PACKAGE =
     9 sig
     9 sig
    10   val record_split_tac: int -> tactic
    10   val record_split_tac: int -> tactic
    11   val record_split_wrapper: string * wrapper
    11   val record_split_wrapper: string * wrapper
       
    12   val record_split_name: string
    12 end;
    13 end;
    13 
    14 
    14 signature RECORD_PACKAGE =
    15 signature RECORD_PACKAGE =
    15 sig
    16 sig
    16   include BASIC_RECORD_PACKAGE
    17   include BASIC_RECORD_PACKAGE
    44 
    45 
    45 val quiet_mode = ref false;
    46 val quiet_mode = ref false;
    46 fun message s = if ! quiet_mode then () else writeln s;
    47 fun message s = if ! quiet_mode then () else writeln s;
    47 
    48 
    48 
    49 
       
    50 (* attributes etc. *)        (* FIXME move to Provers *)
       
    51 
       
    52 fun add_iffs_global (thy, th) =
       
    53   let
       
    54     val ss = Simplifier.simpset_ref_of thy;
       
    55     val cs = Classical.claset_ref_of thy;
       
    56     val (cs', ss') = (! cs, ! ss) addIffs [Attribute.thm_of th];
       
    57   in ss := ss'; cs := cs'; (thy, th) end;
       
    58 
       
    59 fun add_wrapper wrapper thy =
       
    60   let val r = claset_ref_of thy
       
    61   in r := ! r addSWrapper wrapper; thy end;
       
    62 
       
    63 
    49 (* definitions and equations *)
    64 (* definitions and equations *)
    50 
    65 
    51 infix 0 :== ===;
    66 infix 0 :== ===;
    52 
    67 
    53 val (op :==) = Logic.mk_defpair;
    68 val (op :==) = Logic.mk_defpair;
    68         (Goals.prove_goalw_cterm [] (Thm.cterm_of sign goal)
    83         (Goals.prove_goalw_cterm [] (Thm.cterm_of sign goal)
    69           (K (tacs @ [ALLGOALS (Simplifier.simp_tac ss)]))
    84           (K (tacs @ [ALLGOALS (Simplifier.simp_tac ss)]))
    70         handle ERROR => error ("The error(s) above occurred while trying to prove "
    85         handle ERROR => error ("The error(s) above occurred while trying to prove "
    71           ^ quote (Sign.string_of_term sign goal)));
    86           ^ quote (Sign.string_of_term sign goal)));
    72   in prove end;
    87   in prove end;
       
    88 
       
    89 fun simp simps =
       
    90   let val ss = Simplifier.addsimps (HOL_basic_ss, map Attribute.thm_of simps)
       
    91   in apfst (Simplifier.full_simplify ss) end;
    73 
    92 
    74 
    93 
    75 
    94 
    76 (*** syntax operations ***)
    95 (*** syntax operations ***)
    77 
    96 
   317 
   336 
   318 structure RecordsArgs =
   337 structure RecordsArgs =
   319 struct
   338 struct
   320   val name = "HOL/records";
   339   val name = "HOL/records";
   321   type T =
   340   type T =
   322     record_info Symtab.table *				(*records*)
   341     record_info Symtab.table *                          (*records*)
   323       (thm Symtab.table * Simplifier.simpset);		(*field split rules*)
   342       (thm Symtab.table * Simplifier.simpset);          (*field split rules*)
   324 
   343 
   325   val empty = (Symtab.empty, (Symtab.empty, HOL_basic_ss));
   344   val empty = (Symtab.empty, (Symtab.empty, HOL_basic_ss));
   326   val prep_ext = I;
   345   val prep_ext = I;
   327   fun merge ((recs1, (sps1, ss1)), (recs2, (sps2, ss2))) =
   346   fun merge ((recs1, (sps1, ss1)), (recs2, (sps2, ss2))) =
   328     (Symtab.merge (K true) (recs1, recs2),
   347     (Symtab.merge (K true) (recs1, recs2),
   409   in
   428   in
   410     if exists is_fieldT params then Simplifier.full_simp_tac ss i st
   429     if exists is_fieldT params then Simplifier.full_simp_tac ss i st
   411     else Seq.empty
   430     else Seq.empty
   412   end handle Library.LIST _ => Seq.empty;
   431   end handle Library.LIST _ => Seq.empty;
   413 
   432 
   414 val record_split_wrapper = ("record_split_tac", fn tac => record_split_tac ORELSE' tac);
   433 val record_split_name = "record_split_tac";
       
   434 val record_split_wrapper = (record_split_name, fn tac => record_split_tac ORELSE' tac);
   415 
   435 
   416 
   436 
   417 
   437 
   418 (** internal theory extenders **)
   438 (** internal theory extenders **)
   419 
   439 
   420 (* field_type_defs *)
   440 (* field_type_defs *)
   421 
   441 
   422 fun field_type_def ((thy, simps), (name, tname, vs, T, U)) =
   442 fun field_type_def ((thy, simps, injects), (name, tname, vs, T, U)) =
   423   let
   443   let
   424     val full = Sign.full_name (sign_of thy);
   444     val full = Sign.full_name (sign_of thy);
   425     val (thy', {simps = simps', ...}) =
   445     val (thy', {simps = simps', inject, ...}) =
   426       thy
   446       thy
   427       |> setmp DatatypePackage.quiet_mode true
   447       |> setmp DatatypePackage.quiet_mode true
   428         (DatatypePackage.add_datatype_i true [tname]
   448         (DatatypePackage.add_datatype_i true [tname]
   429           [(vs, tname, Syntax.NoSyn, [(name, [T, U], Syntax.NoSyn)])]);
   449           [(vs, tname, Syntax.NoSyn, [(name, [T, U], Syntax.NoSyn)])]);
   430     val thy'' =
   450     val thy'' =
   431       thy'
   451       thy'
   432       |> setmp AxClass.quiet_mode true
   452       |> setmp AxClass.quiet_mode true
   433         (AxClass.add_inst_arity_i (full tname, [HOLogic.termS, moreS], moreS) [] [] None);
   453         (AxClass.add_inst_arity_i (full tname, [HOLogic.termS, moreS], moreS) [] [] None);
   434   in (thy'', simps' @ simps) end;
   454   in (thy'', simps' @ simps, flat inject @ injects) end;
   435 
   455 
   436 fun field_type_defs args thy = foldl field_type_def ((thy, []), args);
   456 fun field_type_defs args thy = foldl field_type_def ((thy, [], []), args);
   437 
   457 
   438 
   458 
   439 (* field_definitions *)
   459 (* field_definitions *)
   440 
   460 
   441 fun field_definitions fields names zeta moreT more vars named_vars thy =
   461 fun field_definitions fields names zeta moreT more vars named_vars thy =
   487     val surj_props = map mk_surj_prop fields;
   507     val surj_props = map mk_surj_prop fields;
   488 
   508 
   489 
   509 
   490     (* 1st stage: types_thy *)
   510     (* 1st stage: types_thy *)
   491 
   511 
   492     val (types_thy, simps) =
   512     val (types_thy, simps, raw_injects) =
   493       thy
   513       thy
   494       |> field_type_defs fieldT_specs;
   514       |> field_type_defs fieldT_specs;
   495 
   515 
   496     val datatype_simps = map Attribute.tthm_of simps;
   516     val datatype_simps = map Attribute.tthm_of simps;
   497 
   517 
   506          (field_specs @ dest_specs);
   526          (field_specs @ dest_specs);
   507 
   527 
   508     val field_defs = get_defs defs_thy field_specs;
   528     val field_defs = get_defs defs_thy field_specs;
   509     val dest_defs = get_defs defs_thy dest_specs;
   529     val dest_defs = get_defs defs_thy dest_specs;
   510 
   530 
       
   531     val injects = map (simp (map (apfst Thm.symmetric) field_defs))
       
   532       (map Attribute.tthm_of raw_injects);
       
   533 
   511 
   534 
   512     (* 3rd stage: thms_thy *)
   535     (* 3rd stage: thms_thy *)
   513 
   536 
   514     val prove = prove_simp defs_thy;
   537     val prove = prove_simp defs_thy;
   515 
   538 
   516     val dest_convs = map (prove [] (field_defs @ dest_defs @ datatype_simps)) dest_props;
   539     val dest_convs = map (prove [] (field_defs @ dest_defs @ datatype_simps)) dest_props;
   517     val surj_pairs = map (prove [DatatypePackage.induct_tac "p" 1]
   540     val surj_pairs = map (prove [DatatypePackage.induct_tac "p" 1]
   518       (map (apfst Thm.symmetric) field_defs @ dest_convs)) surj_props;
   541       (map (apfst Thm.symmetric) field_defs @ dest_convs)) surj_props;
   519 
   542 
   520     fun mk_split th = SplitPairedAll.rule (standard (th RS eq_reflection));
   543     fun mk_split th = SplitPairedAll.rule (th RS eq_reflection);
   521     val splits = map (fn (th, _) => Attribute.tthm_of (mk_split th)) surj_pairs;
   544     val splits = map (fn (th, _) => Attribute.tthm_of (mk_split th)) surj_pairs;
   522 
   545 
   523     val thms_thy =
   546     val thms_thy =
   524       defs_thy
   547       defs_thy
   525       |> (PureThy.add_tthmss o map Attribute.none)
   548       |> (PureThy.add_tthmss o map Attribute.none)
   527           ("dest_defs", dest_defs),
   550           ("dest_defs", dest_defs),
   528           ("dest_convs", dest_convs),
   551           ("dest_convs", dest_convs),
   529           ("surj_pairs", surj_pairs),
   552           ("surj_pairs", surj_pairs),
   530           ("splits", splits)];
   553           ("splits", splits)];
   531 
   554 
   532   in (thms_thy, dest_convs, splits) end;
   555   in (thms_thy, dest_convs, injects, splits) end;
   533 
   556 
   534 
   557 
   535 (* record_definition *)
   558 (* record_definition *)
   536 
   559 
   537 fun record_definition (args, bname) parent (parents: parent_info list) bfields thy =
   560 fun record_definition (args, bname) parent (parents: parent_info list) bfields thy =
   653         in [more_part_update rec_scheme more' === mk_record (all_named_vars, more')] end;
   676         in [more_part_update rec_scheme more' === mk_record (all_named_vars, more')] end;
   654 
   677 
   655 
   678 
   656     (* 1st stage: fields_thy *)
   679     (* 1st stage: fields_thy *)
   657 
   680 
   658     val (fields_thy, field_simps, splits) =
   681     val (fields_thy, field_simps, field_injects, splits) =
   659       thy
   682       thy
   660       |> Theory.add_path bname
   683       |> Theory.add_path bname
   661       |> field_definitions fields names zeta moreT more vars named_vars;
   684       |> field_definitions fields names zeta moreT more vars named_vars;
   662 
   685 
   663     val field_splits = map2 (fn (c, (th, _)) => (suffix field_typeN c, th)) (names, splits);
   686     val field_splits = map2 (fn (c, (th, _)) => (suffix field_typeN c, th)) (names, splits);
   698         [("select_defs", sel_defs),
   721         [("select_defs", sel_defs),
   699           ("update_defs", update_defs),
   722           ("update_defs", update_defs),
   700           ("make_defs", make_defs),
   723           ("make_defs", make_defs),
   701           ("select_convs", sel_convs),
   724           ("select_convs", sel_convs),
   702           ("update_convs", update_convs)]
   725           ("update_convs", update_convs)]
   703       |> PureThy.add_tthmss [(("simps", simps), [Simplifier.simp_add_global])];
   726       |> PureThy.add_tthmss
       
   727         [(("simps", simps), [Simplifier.simp_add_global]),
       
   728          (("injects", field_injects), [add_iffs_global])];
   704 
   729 
   705 
   730 
   706     (* 4th stage: final_thy *)
   731     (* 4th stage: final_thy *)
   707 
   732 
   708     val final_thy =
   733     val final_thy =
   827 
   852 
   828 
   853 
   829 
   854 
   830 (** setup theory **)
   855 (** setup theory **)
   831 
   856 
   832 fun add_wrapper wrapper thy =
       
   833   let val r = claset_ref_of thy
       
   834   in r := ! r addSWrapper wrapper; thy end;
       
   835 
       
   836 val setup =
   857 val setup =
   837  [RecordsData.init,
   858  [RecordsData.init,
   838   Theory.add_trfuns ([], parse_translation, [], []),
   859   Theory.add_trfuns ([], parse_translation, [], []),
   839   add_wrapper record_split_wrapper];
   860   add_wrapper record_split_wrapper];
   840 
   861