src/HOL/Tools/Datatype/datatype_abs_proofs.ML
changeset 45822 843dc212f69e
parent 45821 c2f6c50e3d42
child 45879 71b8d0d170b1
equal deleted inserted replaced
45821:c2f6c50e3d42 45822:843dc212f69e
     7 *)
     7 *)
     8 
     8 
     9 signature DATATYPE_ABS_PROOFS =
     9 signature DATATYPE_ABS_PROOFS =
    10 sig
    10 sig
    11   include DATATYPE_COMMON
    11   include DATATYPE_COMMON
    12   val prove_casedist_thms : config -> string list ->
    12   val prove_casedist_thms : config -> string list -> descr list -> thm ->
    13     descr list -> (string * sort) list -> thm ->
       
    14     attribute list -> theory -> thm list * theory
    13     attribute list -> theory -> thm list * theory
    15   val prove_primrec_thms : config -> string list ->
    14   val prove_primrec_thms : config -> string list -> descr list ->
    16     descr list -> (string * sort) list ->
    15     (string -> thm list) -> thm list list -> thm list list * thm list list ->
    17       (string -> thm list) -> thm list list -> thm list list * thm list list ->
    16       thm -> theory -> (string list * thm list) * theory
    18         thm -> theory -> (string list * thm list) * theory
    17   val prove_case_thms : config -> string list -> descr list ->
    19   val prove_case_thms : config -> string list ->
    18     string list -> thm list -> theory -> (thm list list * string list) * theory
    20     descr list -> (string * sort) list ->
    19   val prove_split_thms : config -> string list -> descr list ->
    21       string list -> thm list -> theory -> (thm list list * string list) * theory
    20     thm list list -> thm list list -> thm list -> thm list list -> theory ->
    22   val prove_split_thms : config -> string list ->
    21     (thm * thm) list * theory
    23     descr list -> (string * sort) list ->
       
    24       thm list list -> thm list list -> thm list -> thm list list -> theory ->
       
    25         (thm * thm) list * theory
       
    26   val prove_nchotomys : config -> string list -> descr list ->
    22   val prove_nchotomys : config -> string list -> descr list ->
    27     (string * sort) list -> thm list -> theory -> thm list * theory
    23     thm list -> theory -> thm list * theory
    28   val prove_weak_case_congs : string list -> descr list ->
    24   val prove_weak_case_congs : string list -> descr list -> theory -> thm list * theory
    29     (string * sort) list -> theory -> thm list * theory
    25   val prove_case_congs : string list -> descr list ->
    30   val prove_case_congs : string list ->
    26     thm list -> thm list list -> theory -> thm list * theory
    31     descr list -> (string * sort) list ->
       
    32       thm list -> thm list list -> theory -> thm list * theory
       
    33 end;
    27 end;
    34 
    28 
    35 structure Datatype_Abs_Proofs: DATATYPE_ABS_PROOFS =
    29 structure Datatype_Abs_Proofs: DATATYPE_ABS_PROOFS =
    36 struct
    30 struct
    37 
    31 
    38 (************************ case distinction theorems ***************************)
    32 (************************ case distinction theorems ***************************)
    39 
    33 
    40 fun prove_casedist_thms (config : Datatype_Aux.config)
    34 fun prove_casedist_thms (config : Datatype_Aux.config)
    41     new_type_names descr sorts induct case_names_exhausts thy =
    35     new_type_names descr induct case_names_exhausts thy =
    42   let
    36   let
    43     val _ = Datatype_Aux.message config "Proving case distinction theorems ...";
    37     val _ = Datatype_Aux.message config "Proving case distinction theorems ...";
    44 
    38 
    45     val descr' = flat descr;
    39     val descr' = flat descr;
    46     val recTs = Datatype_Aux.get_rec_types descr' sorts;
    40     val recTs = Datatype_Aux.get_rec_types descr';
    47     val newTs = take (length (hd descr)) recTs;
    41     val newTs = take (length (hd descr)) recTs;
    48 
    42 
    49     val maxidx = Thm.maxidx_of induct;
    43     val maxidx = Thm.maxidx_of induct;
    50     val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct)));
    44     val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct)));
    51 
    45 
    73                REPEAT ((rtac impI 1) THEN (eresolve_tac prems 1)),
    67                REPEAT ((rtac impI 1) THEN (eresolve_tac prems 1)),
    74                REPEAT (rtac TrueI 1)])
    68                REPEAT (rtac TrueI 1)])
    75       end;
    69       end;
    76 
    70 
    77     val casedist_thms =
    71     val casedist_thms =
    78       map_index prove_casedist_thm (newTs ~~ Datatype_Prop.make_casedists descr sorts);
    72       map_index prove_casedist_thm (newTs ~~ Datatype_Prop.make_casedists descr);
    79   in
    73   in
    80     thy
    74     thy
    81     |> Datatype_Aux.store_thms_atts "exhaust" new_type_names
    75     |> Datatype_Aux.store_thms_atts "exhaust" new_type_names
    82         (map single case_names_exhausts) casedist_thms
    76         (map single case_names_exhausts) casedist_thms
    83   end;
    77   end;
    84 
    78 
    85 
    79 
    86 (*************************** primrec combinators ******************************)
    80 (*************************** primrec combinators ******************************)
    87 
    81 
    88 fun prove_primrec_thms (config : Datatype_Aux.config) new_type_names descr sorts
    82 fun prove_primrec_thms (config : Datatype_Aux.config) new_type_names descr
    89     injects_of constr_inject (dist_rewrites, other_dist_rewrites) induct thy =
    83     injects_of constr_inject (dist_rewrites, other_dist_rewrites) induct thy =
    90   let
    84   let
    91     val _ = Datatype_Aux.message config "Constructing primrec combinators ...";
    85     val _ = Datatype_Aux.message config "Constructing primrec combinators ...";
    92 
    86 
    93     val big_name = space_implode "_" new_type_names;
    87     val big_name = space_implode "_" new_type_names;
    94     val thy0 = Sign.add_path big_name thy;
    88     val thy0 = Sign.add_path big_name thy;
    95 
    89 
    96     val descr' = flat descr;
    90     val descr' = flat descr;
    97     val recTs = Datatype_Aux.get_rec_types descr' sorts;
    91     val recTs = Datatype_Aux.get_rec_types descr';
    98     val used = fold Term.add_tfree_namesT recTs [];
    92     val used = fold Term.add_tfree_namesT recTs [];
    99     val newTs = take (length (hd descr)) recTs;
    93     val newTs = take (length (hd descr)) recTs;
   100 
    94 
   101     val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct)));
    95     val induct_Ps = map head_of (HOLogic.dest_conj (HOLogic.dest_Trueprop (concl_of induct)));
   102 
    96 
   104     val rec_set_names' =
    98     val rec_set_names' =
   105       if length descr' = 1 then [big_rec_name']
    99       if length descr' = 1 then [big_rec_name']
   106       else map (prefix (big_rec_name' ^ "_") o string_of_int) (1 upto length descr');
   100       else map (prefix (big_rec_name' ^ "_") o string_of_int) (1 upto length descr');
   107     val rec_set_names = map (Sign.full_bname thy0) rec_set_names';
   101     val rec_set_names = map (Sign.full_bname thy0) rec_set_names';
   108 
   102 
   109     val (rec_result_Ts, reccomb_fn_Ts) = Datatype_Prop.make_primrec_Ts descr sorts used;
   103     val (rec_result_Ts, reccomb_fn_Ts) = Datatype_Prop.make_primrec_Ts descr used;
   110 
   104 
   111     val rec_set_Ts =
   105     val rec_set_Ts =
   112       map (fn (T1, T2) => (reccomb_fn_Ts @ [T1, T2]) ---> HOLogic.boolT) (recTs ~~ rec_result_Ts);
   106       map (fn (T1, T2) => (reccomb_fn_Ts @ [T1, T2]) ---> HOLogic.boolT) (recTs ~~ rec_result_Ts);
   113 
   107 
   114     val rec_fns =
   108     val rec_fns =
   137                     free1 :: t1s, free2 :: t2s)
   131                     free1 :: t1s, free2 :: t2s)
   138                 end
   132                 end
   139             | _ => (j + 1, k, prems, free1 :: t1s, t2s))
   133             | _ => (j + 1, k, prems, free1 :: t1s, t2s))
   140           end;
   134           end;
   141 
   135 
   142         val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs;
   136         val Ts = map (Datatype_Aux.typ_of_dtyp descr') cargs;
   143         val (_, _, prems, t1s, t2s) = fold_rev mk_prem (cargs ~~ Ts) (1, 1, [], [], []);
   137         val (_, _, prems, t1s, t2s) = fold_rev mk_prem (cargs ~~ Ts) (1, 1, [], [], []);
   144 
   138 
   145       in
   139       in
   146         (rec_intr_ts @
   140         (rec_intr_ts @
   147           [Logic.list_implies (prems, HOLogic.mk_Trueprop
   141           [Logic.list_implies (prems, HOLogic.mk_Trueprop
   266             [rewrite_goals_tac reccomb_defs,
   260             [rewrite_goals_tac reccomb_defs,
   267              rtac @{thm the1_equality} 1,
   261              rtac @{thm the1_equality} 1,
   268              resolve_tac rec_unique_thms 1,
   262              resolve_tac rec_unique_thms 1,
   269              resolve_tac rec_intrs 1,
   263              resolve_tac rec_intrs 1,
   270              REPEAT (rtac allI 1 ORELSE resolve_tac rec_total_thms 1)]))
   264              REPEAT (rtac allI 1 ORELSE resolve_tac rec_total_thms 1)]))
   271       (Datatype_Prop.make_primrecs new_type_names descr sorts thy2);
   265        (Datatype_Prop.make_primrecs new_type_names descr thy2);
   272   in
   266   in
   273     thy2
   267     thy2
   274     |> Sign.add_path (space_implode "_" new_type_names)
   268     |> Sign.add_path (space_implode "_" new_type_names)
   275     |> Global_Theory.add_thmss [((Binding.name "recs", rec_thms), [Nitpick_Simps.add])]
   269     |> Global_Theory.add_thmss [((Binding.name "recs", rec_thms), [Nitpick_Simps.add])]
   276     ||> Sign.parent_path
   270     ||> Sign.parent_path
   280 
   274 
   281 
   275 
   282 (***************************** case combinators *******************************)
   276 (***************************** case combinators *******************************)
   283 
   277 
   284 fun prove_case_thms (config : Datatype_Aux.config)
   278 fun prove_case_thms (config : Datatype_Aux.config)
   285     new_type_names descr sorts reccomb_names primrec_thms thy =
   279     new_type_names descr reccomb_names primrec_thms thy =
   286   let
   280   let
   287     val _ = Datatype_Aux.message config "Proving characteristic theorems for case combinators ...";
   281     val _ = Datatype_Aux.message config "Proving characteristic theorems for case combinators ...";
   288 
   282 
   289     val thy1 = Sign.add_path (space_implode "_" new_type_names) thy;
   283     val thy1 = Sign.add_path (space_implode "_" new_type_names) thy;
   290 
   284 
   291     val descr' = flat descr;
   285     val descr' = flat descr;
   292     val recTs = Datatype_Aux.get_rec_types descr' sorts;
   286     val recTs = Datatype_Aux.get_rec_types descr';
   293     val used = fold Term.add_tfree_namesT recTs [];
   287     val used = fold Term.add_tfree_namesT recTs [];
   294     val newTs = take (length (hd descr)) recTs;
   288     val newTs = take (length (hd descr)) recTs;
   295     val T' = TFree (singleton (Name.variant_list used) "'t", HOLogic.typeS);
   289     val T' = TFree (singleton (Name.variant_list used) "'t", HOLogic.typeS);
   296 
   290 
   297     fun mk_dummyT dt = binder_types (Datatype_Aux.typ_of_dtyp descr' sorts dt) ---> T';
   291     fun mk_dummyT dt = binder_types (Datatype_Aux.typ_of_dtyp descr' dt) ---> T';
   298 
   292 
   299     val case_dummy_fns =
   293     val case_dummy_fns =
   300       map (fn (_, (_, _, constrs)) => map (fn (_, cargs) =>
   294       map (fn (_, (_, _, constrs)) => map (fn (_, cargs) =>
   301         let
   295         let
   302           val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs;
   296           val Ts = map (Datatype_Aux.typ_of_dtyp descr') cargs;
   303           val Ts' = map mk_dummyT (filter Datatype_Aux.is_rec_type cargs)
   297           val Ts' = map mk_dummyT (filter Datatype_Aux.is_rec_type cargs)
   304         in Const (@{const_name undefined}, Ts @ Ts' ---> T') end) constrs) descr';
   298         in Const (@{const_name undefined}, Ts @ Ts' ---> T') end) constrs) descr';
   305 
   299 
   306     val case_names = map (fn s => Sign.full_bname thy1 (s ^ "_case")) new_type_names;
   300     val case_names = map (fn s => Sign.full_bname thy1 (s ^ "_case")) new_type_names;
   307 
   301 
   310     val (case_defs, thy2) =
   304     val (case_defs, thy2) =
   311       fold (fn ((((i, (_, _, constrs)), T), name), recname) => fn (defs, thy) =>
   305       fold (fn ((((i, (_, _, constrs)), T), name), recname) => fn (defs, thy) =>
   312           let
   306           let
   313             val (fns1, fns2) = split_list (map (fn ((_, cargs), j) =>
   307             val (fns1, fns2) = split_list (map (fn ((_, cargs), j) =>
   314               let
   308               let
   315                 val Ts = map (Datatype_Aux.typ_of_dtyp descr' sorts) cargs;
   309                 val Ts = map (Datatype_Aux.typ_of_dtyp descr') cargs;
   316                 val Ts' = Ts @ map mk_dummyT (filter Datatype_Aux.is_rec_type cargs);
   310                 val Ts' = Ts @ map mk_dummyT (filter Datatype_Aux.is_rec_type cargs);
   317                 val frees' = map2 (Datatype_Aux.mk_Free "x") Ts' (1 upto length Ts');
   311                 val frees' = map2 (Datatype_Aux.mk_Free "x") Ts' (1 upto length Ts');
   318                 val frees = take (length cargs) frees';
   312                 val frees = take (length cargs) frees';
   319                 val free = Datatype_Aux.mk_Free "f" (Ts ---> T') j;
   313                 val free = Datatype_Aux.mk_Free "f" (Ts ---> T') j;
   320               in
   314               in
   342     val case_thms =
   336     val case_thms =
   343       (map o map) (fn t =>
   337       (map o map) (fn t =>
   344           Skip_Proof.prove_global thy2 [] [] t
   338           Skip_Proof.prove_global thy2 [] [] t
   345             (fn _ =>
   339             (fn _ =>
   346               EVERY [rewrite_goals_tac (case_defs @ map mk_meta_eq primrec_thms), rtac refl 1]))
   340               EVERY [rewrite_goals_tac (case_defs @ map mk_meta_eq primrec_thms), rtac refl 1]))
   347         (Datatype_Prop.make_cases new_type_names descr sorts thy2);
   341         (Datatype_Prop.make_cases new_type_names descr thy2);
   348   in
   342   in
   349     thy2
   343     thy2
   350     |> Context.theory_map ((fold o fold) Nitpick_Simps.add_thm case_thms)
   344     |> Context.theory_map ((fold o fold) Nitpick_Simps.add_thm case_thms)
   351     |> Sign.parent_path
   345     |> Sign.parent_path
   352     |> Datatype_Aux.store_thmss "cases" new_type_names case_thms
   346     |> Datatype_Aux.store_thmss "cases" new_type_names case_thms
   355 
   349 
   356 
   350 
   357 (******************************* case splitting *******************************)
   351 (******************************* case splitting *******************************)
   358 
   352 
   359 fun prove_split_thms (config : Datatype_Aux.config)
   353 fun prove_split_thms (config : Datatype_Aux.config)
   360     new_type_names descr sorts constr_inject dist_rewrites casedist_thms case_thms thy =
   354     new_type_names descr constr_inject dist_rewrites casedist_thms case_thms thy =
   361   let
   355   let
   362     val _ = Datatype_Aux.message config "Proving equations for case splitting ...";
   356     val _ = Datatype_Aux.message config "Proving equations for case splitting ...";
   363 
   357 
   364     val descr' = flat descr;
   358     val descr' = flat descr;
   365     val recTs = Datatype_Aux.get_rec_types descr' sorts;
   359     val recTs = Datatype_Aux.get_rec_types descr';
   366     val newTs = take (length (hd descr)) recTs;
   360     val newTs = take (length (hd descr)) recTs;
   367 
   361 
   368     fun prove_split_thms ((((((t1, t2), inject), dist_rewrites'), exhaustion), case_thms'), T) =
   362     fun prove_split_thms ((((((t1, t2), inject), dist_rewrites'), exhaustion), case_thms'), T) =
   369       let
   363       let
   370         val cert = cterm_of thy;
   364         val cert = cterm_of thy;
   378          Skip_Proof.prove_global thy [] [] t2 (K tac))
   372          Skip_Proof.prove_global thy [] [] t2 (K tac))
   379       end;
   373       end;
   380 
   374 
   381     val split_thm_pairs =
   375     val split_thm_pairs =
   382       map prove_split_thms
   376       map prove_split_thms
   383         ((Datatype_Prop.make_splits new_type_names descr sorts thy) ~~ constr_inject ~~
   377         (Datatype_Prop.make_splits new_type_names descr thy ~~ constr_inject ~~
   384           dist_rewrites ~~ casedist_thms ~~ case_thms ~~ newTs);
   378           dist_rewrites ~~ casedist_thms ~~ case_thms ~~ newTs);
   385 
   379 
   386     val (split_thms, split_asm_thms) = ListPair.unzip split_thm_pairs
   380     val (split_thms, split_asm_thms) = ListPair.unzip split_thm_pairs
   387 
   381 
   388   in
   382   in
   390     |> Datatype_Aux.store_thms "split" new_type_names split_thms
   384     |> Datatype_Aux.store_thms "split" new_type_names split_thms
   391     ||>> Datatype_Aux.store_thms "split_asm" new_type_names split_asm_thms
   385     ||>> Datatype_Aux.store_thms "split_asm" new_type_names split_asm_thms
   392     |-> (fn (thms1, thms2) => pair (thms1 ~~ thms2))
   386     |-> (fn (thms1, thms2) => pair (thms1 ~~ thms2))
   393   end;
   387   end;
   394 
   388 
   395 fun prove_weak_case_congs new_type_names descr sorts thy =
   389 fun prove_weak_case_congs new_type_names descr thy =
   396   let
   390   let
   397     fun prove_weak_case_cong t =
   391     fun prove_weak_case_cong t =
   398      Skip_Proof.prove_global thy [] (Logic.strip_imp_prems t) (Logic.strip_imp_concl t)
   392      Skip_Proof.prove_global thy [] (Logic.strip_imp_prems t) (Logic.strip_imp_concl t)
   399        (fn {prems, ...} => EVERY [rtac ((hd prems) RS arg_cong) 1]);
   393        (fn {prems, ...} => EVERY [rtac ((hd prems) RS arg_cong) 1]);
   400 
   394 
   401     val weak_case_congs =
   395     val weak_case_congs =
   402       map prove_weak_case_cong (Datatype_Prop.make_weak_case_congs new_type_names descr sorts thy);
   396       map prove_weak_case_cong (Datatype_Prop.make_weak_case_congs new_type_names descr thy);
   403 
   397 
   404   in thy |> Datatype_Aux.store_thms "weak_case_cong" new_type_names weak_case_congs end;
   398   in thy |> Datatype_Aux.store_thms "weak_case_cong" new_type_names weak_case_congs end;
   405 
   399 
   406 (************************* additional theorems for TFL ************************)
   400 (************************* additional theorems for TFL ************************)
   407 
   401 
   408 fun prove_nchotomys (config : Datatype_Aux.config)
   402 fun prove_nchotomys (config : Datatype_Aux.config) new_type_names descr casedist_thms thy =
   409     new_type_names descr sorts casedist_thms thy =
       
   410   let
   403   let
   411     val _ = Datatype_Aux.message config "Proving additional theorems for TFL ...";
   404     val _ = Datatype_Aux.message config "Proving additional theorems for TFL ...";
   412 
   405 
   413     fun prove_nchotomy (t, exhaustion) =
   406     fun prove_nchotomy (t, exhaustion) =
   414       let
   407       let
   422              Datatype_Aux.exh_tac (K exhaustion) 1,
   415              Datatype_Aux.exh_tac (K exhaustion) 1,
   423              ALLGOALS (fn i => tac i (i - 1))])
   416              ALLGOALS (fn i => tac i (i - 1))])
   424       end;
   417       end;
   425 
   418 
   426     val nchotomys =
   419     val nchotomys =
   427       map prove_nchotomy (Datatype_Prop.make_nchotomys descr sorts ~~ casedist_thms);
   420       map prove_nchotomy (Datatype_Prop.make_nchotomys descr ~~ casedist_thms);
   428 
   421 
   429   in thy |> Datatype_Aux.store_thms "nchotomy" new_type_names nchotomys end;
   422   in thy |> Datatype_Aux.store_thms "nchotomy" new_type_names nchotomys end;
   430 
   423 
   431 fun prove_case_congs new_type_names descr sorts nchotomys case_thms thy =
   424 fun prove_case_congs new_type_names descr nchotomys case_thms thy =
   432   let
   425   let
   433     fun prove_case_cong ((t, nchotomy), case_rewrites) =
   426     fun prove_case_cong ((t, nchotomy), case_rewrites) =
   434       let
   427       let
   435         val Const ("==>", _) $ tm $ _ = t;
   428         val Const ("==>", _) $ tm $ _ = t;
   436         val Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, _) $ _ $ Ma) = tm;
   429         val Const (@{const_name Trueprop}, _) $ (Const (@{const_name HOL.eq}, _) $ _ $ Ma) = tm;
   450             end)
   443             end)
   451       end;
   444       end;
   452 
   445 
   453     val case_congs =
   446     val case_congs =
   454       map prove_case_cong (Datatype_Prop.make_case_congs
   447       map prove_case_cong (Datatype_Prop.make_case_congs
   455         new_type_names descr sorts thy ~~ nchotomys ~~ case_thms);
   448         new_type_names descr thy ~~ nchotomys ~~ case_thms);
   456 
   449 
   457   in thy |> Datatype_Aux.store_thms "case_cong" new_type_names case_congs end;
   450   in thy |> Datatype_Aux.store_thms "case_cong" new_type_names case_congs end;
   458 
   451 
   459 
   452 
   460 open Datatype_Aux;
   453 open Datatype_Aux;