src/HOL/Nominal/nominal_package.ML
changeset 19833 3a3f591c838d
parent 19710 ee9c7fa80d21
child 19851 10162c01bd78
equal deleted inserted replaced
19832:1a09f25410da 19833:3a3f591c838d
   179           Type ("fun", [T, Type ("Nominal.noption", [replace_types U])])
   179           Type ("fun", [T, Type ("Nominal.noption", [replace_types U])])
   180       | replace_types (Type (s, Ts)) =
   180       | replace_types (Type (s, Ts)) =
   181           Type (getOpt (AList.lookup op = ps s, s), map replace_types Ts)
   181           Type (getOpt (AList.lookup op = ps s, s), map replace_types Ts)
   182       | replace_types T = T;
   182       | replace_types T = T;
   183 
   183 
   184     fun replace_types' (Type (s, Ts)) =
       
   185           Type (getOpt (AList.lookup op = rps s, s), map replace_types' Ts)
       
   186       | replace_types' T = T;
       
   187 
       
   188     val dts'' = map (fn (tvs, tname, mx, constrs) => (tvs, tname ^ "_Rep", NoSyn,
   184     val dts'' = map (fn (tvs, tname, mx, constrs) => (tvs, tname ^ "_Rep", NoSyn,
   189       map (fn (cname, cargs, mx) => (cname,
   185       map (fn (cname, cargs, mx) => (cname ^ "_Rep",
   190         map (augment_sort_typ o replace_types) cargs, NoSyn)) constrs)) dts';
   186         map (augment_sort_typ o replace_types) cargs, NoSyn)) constrs)) dts';
   191 
   187 
   192     val new_type_names' = map (fn n => n ^ "_Rep") new_type_names;
   188     val new_type_names' = map (fn n => n ^ "_Rep") new_type_names;
   193     val full_new_type_names' = map (Sign.full_name (sign_of thy)) new_type_names';
   189     val full_new_type_names' = map (Sign.full_name (sign_of thy)) new_type_names';
   194 
   190 
   663       (fn (i, ("Nominal.noption", _, _)) => NONE
   659       (fn (i, ("Nominal.noption", _, _)) => NONE
   664         | (i, (s, dts, constrs)) =>
   660         | (i, (s, dts, constrs)) =>
   665              let
   661              let
   666                val SOME index = AList.lookup op = ty_idxs i;
   662                val SOME index = AList.lookup op = ty_idxs i;
   667                val (constrs1, constrs2) = ListPair.unzip
   663                val (constrs1, constrs2) = ListPair.unzip
   668                  (map (fn (cname, cargs) => apfst (pair (strip_nth_name 2 cname))
   664                  (map (fn (cname, cargs) => apfst (pair (strip_nth_name 2 (strip_nth_name 1 cname)))
   669                    (foldl_map (fn (dts, dt) =>
   665                    (foldl_map (fn (dts, dt) =>
   670                      let val (dts', dt') = strip_option dt
   666                      let val (dts', dt') = strip_option dt
   671                      in (dts @ dts' @ [reindex dt'], (length dts, length dts')) end)
   667                      in (dts @ dts' @ [reindex dt'], (length dts, length dts')) end)
   672                        ([], cargs))) constrs)
   668                        ([], cargs))) constrs)
   673              in SOME ((index, (strip_nth_name 1 s,  map reindex dts, constrs1)),
   669              in SOME ((index, (strip_nth_name 1 s,  map reindex dts, constrs1)),
   678     val descr' = [descr1, descr2];
   674     val descr' = [descr1, descr2];
   679 
   675 
   680     fun partition_cargs idxs xs = map (fn (i, j) =>
   676     fun partition_cargs idxs xs = map (fn (i, j) =>
   681       (List.take (List.drop (xs, i), j), List.nth (xs, i + j))) idxs;
   677       (List.take (List.drop (xs, i), j), List.nth (xs, i + j))) idxs;
   682 
   678 
   683     val typ_of_dtyp' = replace_types' o typ_of_dtyp descr sorts';
   679     val pdescr = map (fn ((i, (s, dts, constrs)), (_, idxss)) => (i, (s, dts,
       
   680       map (fn ((cname, cargs), idxs) => (cname, partition_cargs idxs cargs))
       
   681         (constrs ~~ idxss)))) (descr'' ~~ ndescr);
       
   682 
       
   683     fun nth_dtyp' i = typ_of_dtyp descr'' sorts' (DtRec i);
   684 
   684 
   685     val rep_names = map (fn s =>
   685     val rep_names = map (fn s =>
   686       Sign.intern_const thy7 ("Rep_" ^ s)) new_type_names;
   686       Sign.intern_const thy7 ("Rep_" ^ s)) new_type_names;
   687     val abs_names = map (fn s =>
   687     val abs_names = map (fn s =>
   688       Sign.intern_const thy7 ("Abs_" ^ s)) new_type_names;
   688       Sign.intern_const thy7 ("Abs_" ^ s)) new_type_names;
   694     val newTs' = Library.take (length new_type_names, recTs');
   694     val newTs' = Library.take (length new_type_names, recTs');
   695     val newTs = Library.take (length new_type_names, recTs);
   695     val newTs = Library.take (length new_type_names, recTs);
   696 
   696 
   697     val full_new_type_names = map (Sign.full_name (sign_of thy)) new_type_names;
   697     val full_new_type_names = map (Sign.full_name (sign_of thy)) new_type_names;
   698 
   698 
   699     fun make_constr_def tname T T' ((thy, defs, eqns), ((cname, cargs), (cname', mx))) =
   699     fun make_constr_def tname T T' ((thy, defs, eqns),
   700       let
   700         (((cname_rep, _), (cname, cargs)), (cname', mx))) =
   701         fun constr_arg (dt, (j, l_args, r_args)) =
   701       let
       
   702         fun constr_arg ((dts, dt), (j, l_args, r_args)) =
   702           let
   703           let
   703             val x' = mk_Free "x" (typ_of_dtyp' dt) j;
   704             val xs = map (fn (dt, i) => mk_Free "x" (typ_of_dtyp descr'' sorts' dt) i)
   704             val (dts, dt') = strip_option dt;
       
   705             val xs = map (fn (dt, i) => mk_Free "x" (typ_of_dtyp' dt) i)
       
   706               (dts ~~ (j upto j + length dts - 1))
   705               (dts ~~ (j upto j + length dts - 1))
   707             val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts)
   706             val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts)
   708             val (dts', dt'') = strip_dtyp dt'
       
   709           in
   707           in
   710             (j + length dts + 1,
   708             (j + length dts + 1,
   711              xs @ x :: l_args,
   709              xs @ x :: l_args,
   712              foldr mk_abs_fun
   710              foldr mk_abs_fun
   713                (case dt'' of
   711                (case dt of
   714                   DtRec k => if k < length new_type_names then
   712                   DtRec k => if k < length new_type_names then
   715                       list_abs (map (pair "z" o typ_of_dtyp') dts',
   713                       Const (List.nth (rep_names, k), typ_of_dtyp descr'' sorts' dt -->
   716                         Const (List.nth (rep_names, k), typ_of_dtyp' dt'' -->
   714                         typ_of_dtyp descr sorts' dt) $ x
   717                           typ_of_dtyp descr sorts' dt'') $ app_bnds x (length dts'))
       
   718                     else error "nested recursion not (yet) supported"
   715                     else error "nested recursion not (yet) supported"
   719                 | _ => x) xs :: r_args)
   716                 | _ => x) xs :: r_args)
   720           end
   717           end
   721 
   718 
   722         val (_, l_args, r_args) = foldr constr_arg (1, [], []) cargs;
   719         val (_, l_args, r_args) = foldr constr_arg (1, [], []) cargs;
   723         val abs_name = Sign.intern_const (Theory.sign_of thy) ("Abs_" ^ tname);
   720         val abs_name = Sign.intern_const (Theory.sign_of thy) ("Abs_" ^ tname);
   724         val rep_name = Sign.intern_const (Theory.sign_of thy) ("Rep_" ^ tname);
   721         val rep_name = Sign.intern_const (Theory.sign_of thy) ("Rep_" ^ tname);
   725         val constrT = map fastype_of l_args ---> T;
   722         val constrT = map fastype_of l_args ---> T;
   726         val lhs = list_comb (Const (Sign.full_name thy (Sign.base_name cname),
   723         val lhs = list_comb (Const (cname, constrT), l_args);
   727           constrT), l_args);
   724         val rhs = list_comb (Const (cname_rep, map fastype_of r_args ---> T'), r_args);
   728         val rhs = list_comb (Const (cname, map fastype_of r_args ---> T'), r_args);
       
   729         val def = Logic.mk_equals (lhs, Const (abs_name, T' --> T) $ rhs);
   725         val def = Logic.mk_equals (lhs, Const (abs_name, T' --> T) $ rhs);
   730         val eqn = HOLogic.mk_Trueprop (HOLogic.mk_eq
   726         val eqn = HOLogic.mk_Trueprop (HOLogic.mk_eq
   731           (Const (rep_name, T --> T') $ lhs, rhs));
   727           (Const (rep_name, T --> T') $ lhs, rhs));
   732         val def_name = (Sign.base_name cname) ^ "_def";
   728         val def_name = (Sign.base_name cname) ^ "_def";
   733         val ([def_thm], thy') = thy |>
   729         val ([def_thm], thy') = thy |>
   734           Theory.add_consts_i [(cname', constrT, mx)] |>
   730           Theory.add_consts_i [(cname', constrT, mx)] |>
   735           (PureThy.add_defs_i false o map Thm.no_attributes) [(def_name, def)]
   731           (PureThy.add_defs_i false o map Thm.no_attributes) [(def_name, def)]
   736       in (thy', defs @ [def_thm], eqns @ [eqn]) end;
   732       in (thy', defs @ [def_thm], eqns @ [eqn]) end;
   737 
   733 
   738     fun dt_constr_defs ((thy, defs, eqns, dist_lemmas),
   734     fun dt_constr_defs ((thy, defs, eqns, dist_lemmas), ((((((_, (_, _, constrs)),
   739         (((((_, (_, _, constrs)), tname), T), T'), constr_syntax)) =
   735         (_, (_, _, constrs'))), tname), T), T'), constr_syntax)) =
   740       let
   736       let
   741         val rep_const = cterm_of thy
   737         val rep_const = cterm_of thy
   742           (Const (Sign.intern_const thy ("Rep_" ^ tname), T --> T'));
   738           (Const (Sign.intern_const thy ("Rep_" ^ tname), T --> T'));
   743         val dist = standard (cterm_instantiate [(cterm_of thy distinct_f, rep_const)] distinct_lemma);
   739         val dist = standard (cterm_instantiate [(cterm_of thy distinct_f, rep_const)] distinct_lemma);
   744         val (thy', defs', eqns') = Library.foldl (make_constr_def tname T T')
   740         val (thy', defs', eqns') = Library.foldl (make_constr_def tname T T')
   745           ((Theory.add_path tname thy, defs, []), constrs ~~ constr_syntax)
   741           ((Theory.add_path tname thy, defs, []), constrs ~~ constrs' ~~ constr_syntax)
   746       in
   742       in
   747         (parent_path flat_names thy', defs', eqns @ [eqns'], dist_lemmas @ [dist])
   743         (parent_path flat_names thy', defs', eqns @ [eqns'], dist_lemmas @ [dist])
   748       end;
   744       end;
   749 
   745 
   750     val (thy8, constr_defs, constr_rep_eqns, dist_lemmas) = Library.foldl dt_constr_defs
   746     val (thy8, constr_defs, constr_rep_eqns, dist_lemmas) = Library.foldl dt_constr_defs
   751       ((thy7, [], [], []), List.take (descr, length new_type_names) ~~
   747       ((thy7, [], [], []), List.take (descr, length new_type_names) ~~
       
   748         List.take (pdescr, length new_type_names) ~~
   752         new_type_names ~~ newTs ~~ newTs' ~~ constr_syntax);
   749         new_type_names ~~ newTs ~~ newTs' ~~ constr_syntax);
   753 
   750 
   754     val abs_inject_thms = map (fn tname =>
   751     val abs_inject_thms = map (fn tname =>
   755       PureThy.get_thm thy8 (Name ("Abs_" ^ tname ^ "_inject"))) new_type_names;
   752       PureThy.get_thm thy8 (Name ("Abs_" ^ tname ^ "_inject"))) new_type_names;
   756 
   753 
   822     (** prove equations for permutation functions **)
   819     (** prove equations for permutation functions **)
   823 
   820 
   824     val abs_perm = PureThy.get_thms thy8 (Name "abs_perm"); (* FIXME *)
   821     val abs_perm = PureThy.get_thms thy8 (Name "abs_perm"); (* FIXME *)
   825 
   822 
   826     val perm_simps' = map (fn (((i, (_, _, constrs)), tname), constr_rep_thms) =>
   823     val perm_simps' = map (fn (((i, (_, _, constrs)), tname), constr_rep_thms) =>
   827       let val T = replace_types' (nth_dtyp i)
   824       let val T = nth_dtyp' i
   828       in List.concat (map (fn (atom, perm_closed_thms) =>
   825       in List.concat (map (fn (atom, perm_closed_thms) =>
   829           map (fn ((cname, dts), constr_rep_thm) => 
   826           map (fn ((cname, dts), constr_rep_thm) => 
   830         let
   827         let
   831           val cname = Sign.intern_const thy8
   828           val cname = Sign.intern_const thy8
   832             (NameSpace.append tname (Sign.base_name cname));
   829             (NameSpace.append tname (Sign.base_name cname));
   835 
   832 
   836           fun perm t =
   833           fun perm t =
   837             let val T = fastype_of t
   834             let val T = fastype_of t
   838             in Const ("Nominal.perm", permT --> T --> T) $ pi $ t end;
   835             in Const ("Nominal.perm", permT --> T --> T) $ pi $ t end;
   839 
   836 
   840           fun constr_arg (dt, (j, l_args, r_args)) =
   837           fun constr_arg ((dts, dt), (j, l_args, r_args)) =
   841             let
   838             let
   842               val x' = mk_Free "x" (typ_of_dtyp' dt) j;
   839               val Ts = map (typ_of_dtyp descr'' sorts') dts;
   843               val (dts, dt') = strip_option dt;
       
   844               val Ts = map typ_of_dtyp' dts;
       
   845               val xs = map (fn (T, i) => mk_Free "x" T i)
   840               val xs = map (fn (T, i) => mk_Free "x" T i)
   846                 (Ts ~~ (j upto j + length dts - 1))
   841                 (Ts ~~ (j upto j + length dts - 1))
   847               val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts);
   842               val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts)
   848               val (dts', dt'') = strip_dtyp dt';
       
   849             in
   843             in
   850               (j + length dts + 1,
   844               (j + length dts + 1,
   851                xs @ x :: l_args,
   845                xs @ x :: l_args,
   852                map perm (xs @ [x]) @ r_args)
   846                map perm (xs @ [x]) @ r_args)
   853             end
   847             end
   866                  (symmetric perm_fun_def :: abs_perm)) 1),
   860                  (symmetric perm_fun_def :: abs_perm)) 1),
   867                TRY (simp_tac (HOL_basic_ss addsimps
   861                TRY (simp_tac (HOL_basic_ss addsimps
   868                  (perm_fun_def :: perm_defs @ Rep_thms @ Abs_inverse_thms @
   862                  (perm_fun_def :: perm_defs @ Rep_thms @ Abs_inverse_thms @
   869                     perm_closed_thms)) 1)]))
   863                     perm_closed_thms)) 1)]))
   870         end) (constrs ~~ constr_rep_thms)) (atoms ~~ perm_closed_thmss))
   864         end) (constrs ~~ constr_rep_thms)) (atoms ~~ perm_closed_thmss))
   871       end) (List.take (descr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss);
   865       end) (List.take (pdescr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss);
   872 
   866 
   873     (** prove injectivity of constructors **)
   867     (** prove injectivity of constructors **)
   874 
   868 
   875     val rep_inject_thms' = map (fn th => th RS sym) rep_inject_thms;
   869     val rep_inject_thms' = map (fn th => th RS sym) rep_inject_thms;
   876     val alpha = PureThy.get_thms thy8 (Name "alpha");
   870     val alpha = PureThy.get_thms thy8 (Name "alpha");
   877     val abs_fresh = PureThy.get_thms thy8 (Name "abs_fresh");
   871     val abs_fresh = PureThy.get_thms thy8 (Name "abs_fresh");
   878     val fresh_def = PureThy.get_thm thy8 (Name "fresh_def");
   872     val fresh_def = PureThy.get_thm thy8 (Name "fresh_def");
   879     val supp_def = PureThy.get_thm thy8 (Name "supp_def");
   873     val supp_def = PureThy.get_thm thy8 (Name "supp_def");
   880 
   874 
   881     val inject_thms = map (fn (((i, (_, _, constrs)), tname), constr_rep_thms) =>
   875     val inject_thms = map (fn (((i, (_, _, constrs)), tname), constr_rep_thms) =>
   882       let val T = replace_types' (nth_dtyp i)
   876       let val T = nth_dtyp' i
   883       in List.mapPartial (fn ((cname, dts), constr_rep_thm) =>
   877       in List.mapPartial (fn ((cname, dts), constr_rep_thm) =>
   884         if null dts then NONE else SOME
   878         if null dts then NONE else SOME
   885         let
   879         let
   886           val cname = Sign.intern_const thy8
   880           val cname = Sign.intern_const thy8
   887             (NameSpace.append tname (Sign.base_name cname));
   881             (NameSpace.append tname (Sign.base_name cname));
   888 
   882 
   889           fun make_inj (dt, (j, args1, args2, eqs)) =
   883           fun make_inj ((dts, dt), (j, args1, args2, eqs)) =
   890             let
   884             let
   891               val x' = mk_Free "x" (typ_of_dtyp' dt) j;
   885               val Ts_idx = map (typ_of_dtyp descr'' sorts') dts ~~ (j upto j + length dts - 1);
   892               val y' = mk_Free "y" (typ_of_dtyp' dt) j;
       
   893               val (dts, dt') = strip_option dt;
       
   894               val Ts_idx = map typ_of_dtyp' dts ~~ (j upto j + length dts - 1);
       
   895               val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx;
   886               val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx;
   896               val ys = map (fn (T, i) => mk_Free "y" T i) Ts_idx;
   887               val ys = map (fn (T, i) => mk_Free "y" T i) Ts_idx;
   897               val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts);
   888               val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts);
   898               val y = mk_Free "y" (typ_of_dtyp' dt') (j + length dts);
   889               val y = mk_Free "y" (typ_of_dtyp descr'' sorts' dt) (j + length dts)
   899               val (dts', dt'') = strip_dtyp dt';
       
   900             in
   890             in
   901               (j + length dts + 1,
   891               (j + length dts + 1,
   902                xs @ (x :: args1), ys @ (y :: args2),
   892                xs @ (x :: args1), ys @ (y :: args2),
   903                HOLogic.mk_eq
   893                HOLogic.mk_eq
   904                  (foldr mk_abs_fun x xs, foldr mk_abs_fun y ys) :: eqs)
   894                  (foldr mk_abs_fun x xs, foldr mk_abs_fun y ys) :: eqs)
   918                   alpha @ abs_perm @ abs_fresh @ rep_inject_thms @
   908                   alpha @ abs_perm @ abs_fresh @ rep_inject_thms @
   919                   perm_rep_perm_thms)) 1),
   909                   perm_rep_perm_thms)) 1),
   920                 TRY (asm_full_simp_tac (HOL_basic_ss addsimps (perm_fun_def ::
   910                 TRY (asm_full_simp_tac (HOL_basic_ss addsimps (perm_fun_def ::
   921                   expand_fun_eq :: rep_inject_thms @ perm_rep_perm_thms)) 1)]))
   911                   expand_fun_eq :: rep_inject_thms @ perm_rep_perm_thms)) 1)]))
   922         end) (constrs ~~ constr_rep_thms)
   912         end) (constrs ~~ constr_rep_thms)
   923       end) (List.take (descr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss);
   913       end) (List.take (pdescr, length new_type_names) ~~ new_type_names ~~ constr_rep_thmss);
   924 
   914 
   925     (** equations for support and freshness **)
   915     (** equations for support and freshness **)
   926 
   916 
   927     val Un_assoc = PureThy.get_thm thy8 (Name "Un_assoc");
   917     val Un_assoc = PureThy.get_thm thy8 (Name "Un_assoc");
   928     val de_Morgan_conj = PureThy.get_thm thy8 (Name "de_Morgan_conj");
   918     val de_Morgan_conj = PureThy.get_thm thy8 (Name "de_Morgan_conj");
   929     val Collect_disj_eq = PureThy.get_thm thy8 (Name "Collect_disj_eq");
   919     val Collect_disj_eq = PureThy.get_thm thy8 (Name "Collect_disj_eq");
   930     val finite_Un = PureThy.get_thm thy8 (Name "finite_Un");
   920     val finite_Un = PureThy.get_thm thy8 (Name "finite_Un");
   931 
   921 
   932     val (supp_thms, fresh_thms) = ListPair.unzip (map ListPair.unzip
   922     val (supp_thms, fresh_thms) = ListPair.unzip (map ListPair.unzip
   933       (map (fn ((((i, (_, _, constrs)), tname), inject_thms'), perm_thms') =>
   923       (map (fn ((((i, (_, _, constrs)), tname), inject_thms'), perm_thms') =>
   934       let val T = replace_types' (nth_dtyp i)
   924       let val T = nth_dtyp' i
   935       in List.concat (map (fn (cname, dts) => map (fn atom =>
   925       in List.concat (map (fn (cname, dts) => map (fn atom =>
   936         let
   926         let
   937           val cname = Sign.intern_const thy8
   927           val cname = Sign.intern_const thy8
   938             (NameSpace.append tname (Sign.base_name cname));
   928             (NameSpace.append tname (Sign.base_name cname));
   939           val atomT = Type (atom, []);
   929           val atomT = Type (atom, []);
   940 
   930 
   941           fun process_constr (dt, (j, args1, args2)) =
   931           fun process_constr ((dts, dt), (j, args1, args2)) =
   942             let
   932             let
   943               val x' = mk_Free "x" (typ_of_dtyp' dt) j;
   933               val Ts_idx = map (typ_of_dtyp descr'' sorts') dts ~~ (j upto j + length dts - 1);
   944               val (dts, dt') = strip_option dt;
       
   945               val Ts_idx = map typ_of_dtyp' dts ~~ (j upto j + length dts - 1);
       
   946               val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx;
   934               val xs = map (fn (T, i) => mk_Free "x" T i) Ts_idx;
   947               val x = mk_Free "x" (typ_of_dtyp' dt') (j + length dts);
   935               val x = mk_Free "x" (typ_of_dtyp descr'' sorts' dt) (j + length dts)
   948               val (dts', dt'') = strip_dtyp dt';
       
   949             in
   936             in
   950               (j + length dts + 1,
   937               (j + length dts + 1,
   951                xs @ (x :: args1), foldr mk_abs_fun x xs :: args2)
   938                xs @ (x :: args1), foldr mk_abs_fun x xs :: args2)
   952             end;
   939             end;
   953 
   940 
   976                if null dts then HOLogic.true_const
   963                if null dts then HOLogic.true_const
   977                else foldr1 HOLogic.mk_conj (map fresh args2))))
   964                else foldr1 HOLogic.mk_conj (map fresh args2))))
   978              (fn _ =>
   965              (fn _ =>
   979                simp_tac (simpset_of thy8 addsimps [fresh_def, supp_thm]) 1)))
   966                simp_tac (simpset_of thy8 addsimps [fresh_def, supp_thm]) 1)))
   980         end) atoms) constrs)
   967         end) atoms) constrs)
   981       end) (List.take (descr, length new_type_names) ~~ new_type_names ~~ inject_thms ~~ perm_simps')));
   968       end) (List.take (pdescr, length new_type_names) ~~ new_type_names ~~ inject_thms ~~ perm_simps')));
   982 
   969 
   983     (**** weak induction theorem ****)
   970     (**** weak induction theorem ****)
   984 
       
   985     val arities = get_arities descr'';
       
   986 
       
   987     fun mk_funs_inv thm =
       
   988       let
       
   989         val {sign, prop, ...} = rep_thm thm;
       
   990         val _ $ (_ $ (Const (_, Type (_, [U, _])) $ _ $ S)) $
       
   991           (_ $ (_ $ (r $ (a $ _)) $ _)) = Type.freeze prop;
       
   992         val used = add_term_tfree_names (a, []);
       
   993 
       
   994         fun mk_thm i =
       
   995           let
       
   996             val Ts = map (TFree o rpair HOLogic.typeS)
       
   997               (variantlist (replicate i "'t", used));
       
   998             val f = Free ("f", Ts ---> U)
       
   999           in standard (Goal.prove sign [] [] (Logic.mk_implies
       
  1000             (HOLogic.mk_Trueprop (HOLogic.list_all
       
  1001                (map (pair "x") Ts, HOLogic.mk_mem (app_bnds f i, S))),
       
  1002              HOLogic.mk_Trueprop (HOLogic.mk_eq (list_abs (map (pair "x") Ts,
       
  1003                r $ (a $ app_bnds f i)), f))))
       
  1004             (fn _ => EVERY [REPEAT (rtac ext 1), REPEAT (etac allE 1), rtac thm 1, atac 1]))
       
  1005           end
       
  1006       in map (fn r => r RS subst) (thm :: map mk_thm arities) end;
       
  1007 
   971 
  1008     fun mk_indrule_lemma ((prems, concls), (((i, _), T), U)) =
   972     fun mk_indrule_lemma ((prems, concls), (((i, _), T), U)) =
  1009       let
   973       let
  1010         val Rep_t = Const (List.nth (rep_names, i), T --> U) $
   974         val Rep_t = Const (List.nth (rep_names, i), T --> U) $
  1011           mk_Free "x" T i;
   975           mk_Free "x" T i;
  1034     val frees = if length Ps = 1 then [Free ("P", snd (dest_Var (hd Ps)))] else
   998     val frees = if length Ps = 1 then [Free ("P", snd (dest_Var (hd Ps)))] else
  1035       map (Free o apfst fst o dest_Var) Ps;
   999       map (Free o apfst fst o dest_Var) Ps;
  1036     val indrule_lemma' = cterm_instantiate
  1000     val indrule_lemma' = cterm_instantiate
  1037       (map (cterm_of thy8) Ps ~~ map (cterm_of thy8) frees) indrule_lemma;
  1001       (map (cterm_of thy8) Ps ~~ map (cterm_of thy8) frees) indrule_lemma;
  1038 
  1002 
  1039     val Abs_inverse_thms' = List.concat (map mk_funs_inv Abs_inverse_thms);
  1003     val Abs_inverse_thms' = map (fn r => r RS subst) Abs_inverse_thms;
  1040 
  1004 
  1041     val dt_induct_prop = DatatypeProp.make_ind descr' sorts';
  1005     val dt_induct_prop = DatatypeProp.make_ind descr' sorts';
  1042     val dt_induct = standard (Goal.prove thy8 []
  1006     val dt_induct = standard (Goal.prove thy8 []
  1043       (Logic.strip_imp_prems dt_induct_prop) (Logic.strip_imp_concl dt_induct_prop)
  1007       (Logic.strip_imp_prems dt_induct_prop) (Logic.strip_imp_concl dt_induct_prop)
  1044       (fn prems => EVERY
  1008       (fn prems => EVERY