src/HOL/Tools/Datatype/datatype_data.ML
changeset 45701 615da8b8d758
parent 45700 9dcbf6a1829c
child 45738 0430f9123e43
equal deleted inserted replaced
45700:9dcbf6a1829c 45701:615da8b8d758
     5 *)
     5 *)
     6 
     6 
     7 signature DATATYPE_DATA =
     7 signature DATATYPE_DATA =
     8 sig
     8 sig
     9   include DATATYPE_COMMON
     9   include DATATYPE_COMMON
    10   val derive_datatype_props : config -> string list -> string list option
    10   val derive_datatype_props : config -> string list -> descr list -> (string * sort) list ->
    11     -> descr list -> (string * sort) list -> thm -> thm list list -> thm list list
    11     thm -> thm list list -> thm list list -> theory -> string list * theory
    12     -> theory -> string list * theory
    12   val rep_datatype : config -> (string list -> Proof.context -> Proof.context) ->
    13   val rep_datatype : config -> (string list -> Proof.context -> Proof.context)
    13     term list -> theory -> Proof.state
    14     -> string list option -> term list -> theory -> Proof.state
    14   val rep_datatype_cmd : string list -> theory -> Proof.state
    15   val rep_datatype_cmd : string list option -> string list -> theory -> Proof.state
       
    16   val get_info : theory -> string -> info option
    15   val get_info : theory -> string -> info option
    17   val the_info : theory -> string -> info
    16   val the_info : theory -> string -> info
    18   val the_descr : theory -> string list
    17   val the_descr : theory -> string list ->
    19     -> descr * (string * sort) list * string list
    18     descr * (string * sort) list * string list * string *
    20       * string * (string list * string list) * (typ list * typ list)
    19     (string list * string list) * (typ list * typ list)
    21   val the_spec : theory -> string -> (string * sort) list * (string * typ list) list
    20   val the_spec : theory -> string -> (string * sort) list * (string * typ list) list
    22   val all_distincts : theory -> typ list -> thm list list
    21   val all_distincts : theory -> typ list -> thm list list
    23   val get_constrs : theory -> string -> (string * typ) list option
    22   val get_constrs : theory -> string -> (string * typ) list option
    24   val get_all : theory -> info Symtab.table
    23   val get_all : theory -> info Symtab.table
    25   val info_of_constr : theory -> string * typ -> info option
    24   val info_of_constr : theory -> string * typ -> info option
   142         error ("Type constructors " ^ commas_quote raw_tycos ^
   141         error ("Type constructors " ^ commas_quote raw_tycos ^
   143           " do not belong exhaustively to one mutual recursive datatype");
   142           " do not belong exhaustively to one mutual recursive datatype");
   144 
   143 
   145     val (Ts, Us) = (pairself o map) Type protoTs;
   144     val (Ts, Us) = (pairself o map) Type protoTs;
   146 
   145 
   147     val names = map Long_Name.base_name (the_default tycos (#alt_names info));
   146     val names = map Long_Name.base_name tycos;
   148     val (auxnames, _) =
   147     val (auxnames, _) =
   149       Name.make_context names
   148       Name.make_context names
   150       |> fold_map (Name.variant o Datatype_Aux.name_of_typ) Us;
   149       |> fold_map (Name.variant o Datatype_Aux.name_of_typ) Us;
   151     val prefix = space_implode "_" names;
   150     val prefix = space_implode "_" names;
   152 
   151 
   282   type T = Datatype_Aux.config * string list;
   281   type T = Datatype_Aux.config * string list;
   283   val eq: T * T -> bool = eq_snd (op =);
   282   val eq: T * T -> bool = eq_snd (op =);
   284 );
   283 );
   285 fun interpretation f = Datatype_Interpretation.interpretation (uncurry f);
   284 fun interpretation f = Datatype_Interpretation.interpretation (uncurry f);
   286 
   285 
   287 fun make_dt_info alt_names descr sorts induct inducts rec_names rec_rewrites
   286 fun make_dt_info descr sorts induct inducts rec_names rec_rewrites
   288     (index, (((((((((((_, (tname, _, _))), inject), distinct),
   287     (index, (((((((((((_, (tname, _, _))), inject), distinct),
   289       exhaust), nchotomy), case_name), case_rewrites), case_cong), weak_case_cong),
   288       exhaust), nchotomy), case_name), case_rewrites), case_cong), weak_case_cong),
   290         (split, split_asm))) =
   289         (split, split_asm))) =
   291   (tname,
   290   (tname,
   292    {index = index,
   291    {index = index,
   293     alt_names = alt_names,
       
   294     descr = descr,
   292     descr = descr,
   295     sorts = sorts,
   293     sorts = sorts,
   296     inject = inject,
   294     inject = inject,
   297     distinct = distinct,
   295     distinct = distinct,
   298     induct = induct,
   296     induct = induct,
   306     case_cong = case_cong,
   304     case_cong = case_cong,
   307     weak_case_cong = weak_case_cong,
   305     weak_case_cong = weak_case_cong,
   308     split = split,
   306     split = split,
   309     split_asm = split_asm});
   307     split_asm = split_asm});
   310 
   308 
   311 fun derive_datatype_props config dt_names alt_names descr sorts
   309 fun derive_datatype_props config dt_names descr sorts
   312     induct inject distinct thy1 =
   310     induct inject distinct thy1 =
   313   let
   311   let
   314     val thy2 = thy1 |> Theory.checkpoint;
   312     val thy2 = thy1 |> Theory.checkpoint;
   315     val flat_descr = flat descr;
   313     val flat_descr = flat descr;
   316     val new_type_names = map Long_Name.base_name (the_default dt_names alt_names);
   314     val new_type_names = map Long_Name.base_name dt_names;
   317     val _ =
   315     val _ =
   318       Datatype_Aux.message config
   316       Datatype_Aux.message config
   319         ("Deriving properties for datatype(s) " ^ commas_quote new_type_names);
   317         ("Deriving properties for datatype(s) " ^ commas_quote new_type_names);
   320 
   318 
   321     val (exhaust, thy3) =
   319     val (exhaust, thy3) =
   341       Datatype_Abs_Proofs.prove_split_thms
   339       Datatype_Abs_Proofs.prove_split_thms
   342         config new_type_names descr sorts inject distinct exhaust case_rewrites thy8;
   340         config new_type_names descr sorts inject distinct exhaust case_rewrites thy8;
   343 
   341 
   344     val inducts = Project_Rule.projections (Proof_Context.init_global thy2) induct;
   342     val inducts = Project_Rule.projections (Proof_Context.init_global thy2) induct;
   345     val dt_infos = map_index
   343     val dt_infos = map_index
   346       (make_dt_info alt_names flat_descr sorts induct inducts rec_names rec_rewrites)
   344       (make_dt_info flat_descr sorts induct inducts rec_names rec_rewrites)
   347       (hd descr ~~ inject ~~ distinct ~~ exhaust ~~ nchotomys ~~
   345       (hd descr ~~ inject ~~ distinct ~~ exhaust ~~ nchotomys ~~
   348         case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits);
   346         case_names ~~ case_rewrites ~~ case_congs ~~ weak_case_congs ~~ splits);
   349     val dt_names = map fst dt_infos;
   347     val dt_names = map fst dt_infos;
   350     val prfx = Binding.qualify true (space_implode "_" new_type_names);
   348     val prfx = Binding.qualify true (space_implode "_" new_type_names);
   351     val simps = flat (inject @ distinct @ case_rewrites) @ rec_rewrites;
   349     val simps = flat (inject @ distinct @ case_rewrites) @ rec_rewrites;
   378 
   376 
   379 
   377 
   380 
   378 
   381 (** declare existing type as datatype **)
   379 (** declare existing type as datatype **)
   382 
   380 
   383 fun prove_rep_datatype config dt_names alt_names descr sorts
   381 fun prove_rep_datatype config dt_names descr sorts raw_inject half_distinct raw_induct thy1 =
   384     raw_inject half_distinct raw_induct thy1 =
       
   385   let
   382   let
   386     val raw_distinct = (map o maps) (fn thm => [thm, thm RS not_sym]) half_distinct;
   383     val raw_distinct = (map o maps) (fn thm => [thm, thm RS not_sym]) half_distinct;
   387     val new_type_names = map Long_Name.base_name (the_default dt_names alt_names);
   384     val new_type_names = map Long_Name.base_name dt_names;
   388     val prfx = Binding.qualify true (space_implode "_" new_type_names);
   385     val prfx = Binding.qualify true (space_implode "_" new_type_names);
   389     val (((inject, distinct), [induct]), thy2) =
   386     val (((inject, distinct), [induct]), thy2) =
   390       thy1
   387       thy1
   391       |> Datatype_Aux.store_thmss "inject" new_type_names raw_inject
   388       |> Datatype_Aux.store_thmss "inject" new_type_names raw_inject
   392       ||>> Datatype_Aux.store_thmss "distinct" new_type_names raw_distinct
   389       ||>> Datatype_Aux.store_thmss "distinct" new_type_names raw_distinct
   393       ||>> Global_Theory.add_thms
   390       ||>> Global_Theory.add_thms
   394         [((prfx (Binding.name "induct"), raw_induct),
   391         [((prfx (Binding.name "induct"), raw_induct),
   395           [mk_case_names_induct descr])];
   392           [mk_case_names_induct descr])];
   396   in
   393   in
   397     thy2
   394     thy2
   398     |> derive_datatype_props config dt_names alt_names [descr] sorts
   395     |> derive_datatype_props config dt_names [descr] sorts induct inject distinct
   399          induct inject distinct
       
   400  end;
   396  end;
   401 
   397 
   402 fun gen_rep_datatype prep_term config after_qed alt_names raw_ts thy =
   398 fun gen_rep_datatype prep_term config after_qed raw_ts thy =
   403   let
   399   let
   404     val ctxt = Proof_Context.init_global thy;
   400     val ctxt = Proof_Context.init_global thy;
   405 
   401 
   406     fun constr_of_term (Const (c, T)) = (c, T)
   402     fun constr_of_term (Const (c, T)) = (c, T)
   407       | constr_of_term t = error ("Not a constant: " ^ Syntax.string_of_term ctxt t);
   403       | constr_of_term t = error ("Not a constant: " ^ Syntax.string_of_term ctxt t);
   459         val [[[raw_induct]], raw_inject, half_distinct] =
   455         val [[[raw_induct]], raw_inject, half_distinct] =
   460           unflat rules (map Drule.zero_var_indexes_list raw_thms);
   456           unflat rules (map Drule.zero_var_indexes_list raw_thms);
   461             (*FIXME somehow dubious*)
   457             (*FIXME somehow dubious*)
   462       in
   458       in
   463         Proof_Context.background_theory_result  (* FIXME !? *)
   459         Proof_Context.background_theory_result  (* FIXME !? *)
   464           (prove_rep_datatype config dt_names alt_names descr vs
   460           (prove_rep_datatype config dt_names descr vs raw_inject half_distinct raw_induct)
   465             raw_inject half_distinct raw_induct)
       
   466         #-> after_qed
   461         #-> after_qed
   467       end;
   462       end;
   468   in
   463   in
   469     ctxt
   464     ctxt
   470     |> Proof.theorem NONE after_qed' ((map o map) (rpair []) (flat rules))
   465     |> Proof.theorem NONE after_qed' ((map o map) (rpair []) (flat rules))
   487 
   482 
   488 (* outer syntax *)
   483 (* outer syntax *)
   489 
   484 
   490 val _ =
   485 val _ =
   491   Outer_Syntax.command "rep_datatype" "represent existing types inductively" Keyword.thy_goal
   486   Outer_Syntax.command "rep_datatype" "represent existing types inductively" Keyword.thy_goal
   492     (Scan.option (Parse.$$$ "(" |-- Scan.repeat1 Parse.name --| Parse.$$$ ")") --
   487     (Scan.repeat1 Parse.term >> (fn ts =>
   493       Scan.repeat1 Parse.term
   488       Toplevel.print o Toplevel.theory_to_proof (rep_datatype_cmd ts)));
   494       >> (fn (alt_names, ts) =>
       
   495           Toplevel.print o Toplevel.theory_to_proof (rep_datatype_cmd alt_names ts)));
       
   496 
   489 
   497 
   490 
   498 open Datatype_Aux;
   491 open Datatype_Aux;
   499 
   492 
   500 end;
   493 end;