src/HOL/Codatatype/Tools/bnf_lfp.ML
changeset 49501 acc9635a644a
parent 49498 acc583e14167
child 49502 92a7c1842c78
equal deleted inserted replaced
49500:3cb59fdd69a8 49501:acc9635a644a
   992 
   992 
   993     val Izs = map2 retype_free Ts zs;
   993     val Izs = map2 retype_free Ts zs;
   994     val phis = map2 retype_free (map mk_pred1T Ts) init_phis;
   994     val phis = map2 retype_free (map mk_pred1T Ts) init_phis;
   995     val phi2s = map2 retype_free (map2 mk_pred2T Ts Ts') init_phis;
   995     val phi2s = map2 retype_free (map2 mk_pred2T Ts Ts') init_phis;
   996 
   996 
   997     fun fld_bind i = Binding.suffix_name ("_" ^ fldN) (nth bs (i - 1));
   997     fun ctor_bind i = Binding.suffix_name ("_" ^ ctorN) (nth bs (i - 1));
   998     val fld_name = Binding.name_of o fld_bind;
   998     val ctor_name = Binding.name_of o ctor_bind;
   999     val fld_def_bind = rpair [] o Thm.def_binding o fld_bind;
   999     val ctor_def_bind = rpair [] o Thm.def_binding o ctor_bind;
  1000 
  1000 
  1001     fun fld_spec i abs str map_FT_init x x' =
  1001     fun ctor_spec i abs str map_FT_init x x' =
  1002       let
  1002       let
  1003         val fldT = nth FTs (i - 1) --> nth Ts (i - 1);
  1003         val ctorT = nth FTs (i - 1) --> nth Ts (i - 1);
  1004 
  1004 
  1005         val lhs = Free (fld_name i, fldT);
  1005         val lhs = Free (ctor_name i, ctorT);
  1006         val rhs = Term.absfree x' (abs $ (str $
  1006         val rhs = Term.absfree x' (abs $ (str $
  1007           (Term.list_comb (map_FT_init, map HOLogic.id_const passiveAs @ Rep_Ts) $ x)));
  1007           (Term.list_comb (map_FT_init, map HOLogic.id_const passiveAs @ Rep_Ts) $ x)));
  1008       in
  1008       in
  1009         mk_Trueprop_eq (lhs, rhs)
  1009         mk_Trueprop_eq (lhs, rhs)
  1010       end;
  1010       end;
  1011 
  1011 
  1012     val ((fld_frees, (_, fld_def_frees)), (lthy, lthy_old)) =
  1012     val ((ctor_frees, (_, ctor_def_frees)), (lthy, lthy_old)) =
  1013       lthy
  1013       lthy
  1014       |> fold_map6 (fn i => fn abs => fn str => fn mapx => fn x => fn x' =>
  1014       |> fold_map6 (fn i => fn abs => fn str => fn mapx => fn x => fn x' =>
  1015         Specification.definition
  1015         Specification.definition
  1016           (SOME (fld_bind i, NONE, NoSyn), (fld_def_bind i, fld_spec i abs str mapx x x')))
  1016           (SOME (ctor_bind i, NONE, NoSyn), (ctor_def_bind i, ctor_spec i abs str mapx x x')))
  1017           ks Abs_Ts str_inits map_FT_inits xFs xFs'
  1017           ks Abs_Ts str_inits map_FT_inits xFs xFs'
  1018       |>> apsnd split_list o split_list
  1018       |>> apsnd split_list o split_list
  1019       ||> `Local_Theory.restore;
  1019       ||> `Local_Theory.restore;
  1020 
  1020 
  1021     val phi = Proof_Context.export_morphism lthy_old lthy;
  1021     val phi = Proof_Context.export_morphism lthy_old lthy;
  1022     fun mk_flds passive =
  1022     fun mk_ctors passive =
  1023       map (Term.subst_atomic_types (map (Morphism.typ phi) params' ~~ (mk_params passive)) o
  1023       map (Term.subst_atomic_types (map (Morphism.typ phi) params' ~~ (mk_params passive)) o
  1024         Morphism.term phi) fld_frees;
  1024         Morphism.term phi) ctor_frees;
  1025     val flds = mk_flds passiveAs;
  1025     val ctors = mk_ctors passiveAs;
  1026     val fld's = mk_flds passiveBs;
  1026     val ctor's = mk_ctors passiveBs;
  1027     val fld_defs = map (Morphism.thm phi) fld_def_frees;
  1027     val ctor_defs = map (Morphism.thm phi) ctor_def_frees;
  1028 
  1028 
  1029     val (mor_Rep_thm, mor_Abs_thm) =
  1029     val (mor_Rep_thm, mor_Abs_thm) =
  1030       let
  1030       let
  1031         val copy = alg_init_thm RS copy_alg_thm;
  1031         val copy = alg_init_thm RS copy_alg_thm;
  1032         fun mk_bij inj Rep cases = @{thm bij_betwI'} OF [inj, Rep, cases];
  1032         fun mk_bij inj Rep cases = @{thm bij_betwI'} OF [inj, Rep, cases];
  1033         val bijs = map3 mk_bij Rep_injects Reps Rep_casess;
  1033         val bijs = map3 mk_bij Rep_injects Reps Rep_casess;
  1034         val mor_Rep =
  1034         val mor_Rep =
  1035           Skip_Proof.prove lthy [] []
  1035           Skip_Proof.prove lthy [] []
  1036             (HOLogic.mk_Trueprop (mk_mor UNIVs flds car_inits str_inits Rep_Ts))
  1036             (HOLogic.mk_Trueprop (mk_mor UNIVs ctors car_inits str_inits Rep_Ts))
  1037             (mk_mor_Rep_tac fld_defs copy bijs inver_Abss inver_Reps)
  1037             (mk_mor_Rep_tac ctor_defs copy bijs inver_Abss inver_Reps)
  1038           |> Thm.close_derivation;
  1038           |> Thm.close_derivation;
  1039 
  1039 
  1040         val inv = mor_inv_thm OF [mor_Rep, talg_thm, alg_init_thm];
  1040         val inv = mor_inv_thm OF [mor_Rep, talg_thm, alg_init_thm];
  1041         val mor_Abs =
  1041         val mor_Abs =
  1042           Skip_Proof.prove lthy [] []
  1042           Skip_Proof.prove lthy [] []
  1043             (HOLogic.mk_Trueprop (mk_mor car_inits str_inits UNIVs flds Abs_Ts))
  1043             (HOLogic.mk_Trueprop (mk_mor car_inits str_inits UNIVs ctors Abs_Ts))
  1044             (K (mk_mor_Abs_tac inv inver_Abss inver_Reps))
  1044             (K (mk_mor_Abs_tac inv inver_Abss inver_Reps))
  1045           |> Thm.close_derivation;
  1045           |> Thm.close_derivation;
  1046       in
  1046       in
  1047         (mor_Rep, mor_Abs)
  1047         (mor_Rep, mor_Abs)
  1048       end;
  1048       end;
  1049 
  1049 
  1050     val timer = time (timer "fld definitions & thms");
  1050     val timer = time (timer "ctor definitions & thms");
  1051 
  1051 
  1052     val iter_fun = Term.absfree iter_f'
  1052     val iter_fun = Term.absfree iter_f'
  1053       (mk_mor UNIVs flds active_UNIVs ss (map (mk_nthN n iter_f) ks));
  1053       (mk_mor UNIVs ctors active_UNIVs ss (map (mk_nthN n iter_f) ks));
  1054     val iter = HOLogic.choice_const iterT $ iter_fun;
  1054     val iter = HOLogic.choice_const iterT $ iter_fun;
  1055 
  1055 
  1056     fun iter_bind i = Binding.suffix_name ("_" ^ fld_iterN) (nth bs (i - 1));
  1056     fun iter_bind i = Binding.suffix_name ("_" ^ ctor_iterN) (nth bs (i - 1));
  1057     val iter_name = Binding.name_of o iter_bind;
  1057     val iter_name = Binding.name_of o iter_bind;
  1058     val iter_def_bind = rpair [] o Thm.def_binding o iter_bind;
  1058     val iter_def_bind = rpair [] o Thm.def_binding o iter_bind;
  1059 
  1059 
  1060     fun iter_spec i T AT =
  1060     fun iter_spec i T AT =
  1061       let
  1061       let
  1091         val cT = certifyT lthy iterT;
  1091         val cT = certifyT lthy iterT;
  1092         val ct = certify lthy iter_fun
  1092         val ct = certify lthy iter_fun
  1093       in
  1093       in
  1094         singleton (Proof_Context.export names_lthy lthy)
  1094         singleton (Proof_Context.export names_lthy lthy)
  1095           (Skip_Proof.prove lthy [] []
  1095           (Skip_Proof.prove lthy [] []
  1096             (HOLogic.mk_Trueprop (mk_mor UNIVs flds active_UNIVs ss (map (mk_iter Ts ss) ks)))
  1096             (HOLogic.mk_Trueprop (mk_mor UNIVs ctors active_UNIVs ss (map (mk_iter Ts ss) ks)))
  1097             (K (mk_mor_iter_tac cT ct iter_defs ex_mor (mor_comp RS mor_cong))))
  1097             (K (mk_mor_iter_tac cT ct iter_defs ex_mor (mor_comp RS mor_cong))))
  1098         |> Thm.close_derivation
  1098         |> Thm.close_derivation
  1099       end;
  1099       end;
  1100 
  1100 
  1101     val iter_thms = map (fn morE => rule_by_tactic lthy
  1101     val iter_thms = map (fn morE => rule_by_tactic lthy
  1102       ((rtac CollectI THEN' CONJ_WRAP' (K (rtac @{thm subset_UNIV})) (1 upto m + n)) 1)
  1102       ((rtac CollectI THEN' CONJ_WRAP' (K (rtac @{thm subset_UNIV})) (1 upto m + n)) 1)
  1103       (mor_iter_thm RS morE)) morE_thms;
  1103       (mor_iter_thm RS morE)) morE_thms;
  1104 
  1104 
  1105     val (iter_unique_mor_thms, iter_unique_mor_thm) =
  1105     val (iter_unique_mor_thms, iter_unique_mor_thm) =
  1106       let
  1106       let
  1107         val prem = HOLogic.mk_Trueprop (mk_mor UNIVs flds active_UNIVs ss fs);
  1107         val prem = HOLogic.mk_Trueprop (mk_mor UNIVs ctors active_UNIVs ss fs);
  1108         fun mk_fun_eq f i = HOLogic.mk_eq (f, mk_iter Ts ss i);
  1108         fun mk_fun_eq f i = HOLogic.mk_eq (f, mk_iter Ts ss i);
  1109         val unique = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_fun_eq fs ks));
  1109         val unique = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_fun_eq fs ks));
  1110         val unique_mor = Skip_Proof.prove lthy [] []
  1110         val unique_mor = Skip_Proof.prove lthy [] []
  1111           (fold_rev Logic.all (ss @ fs) (Logic.mk_implies (prem, unique)))
  1111           (fold_rev Logic.all (ss @ fs) (Logic.mk_implies (prem, unique)))
  1112           (K (mk_iter_unique_mor_tac type_defs init_unique_mor_thms Reps
  1112           (K (mk_iter_unique_mor_tac type_defs init_unique_mor_thms Reps
  1118 
  1118 
  1119     val iter_unique_thms =
  1119     val iter_unique_thms =
  1120       split_conj_thm (mk_conjIN n RS
  1120       split_conj_thm (mk_conjIN n RS
  1121         (mor_UNIV_thm RS @{thm ssubst[of _ _ "%x. x"]} RS iter_unique_mor_thm))
  1121         (mor_UNIV_thm RS @{thm ssubst[of _ _ "%x. x"]} RS iter_unique_mor_thm))
  1122 
  1122 
  1123     val iter_fld_thms =
  1123     val iter_ctor_thms =
  1124       map (fn thm => (mor_incl_thm OF replicate n @{thm subset_UNIV}) RS thm RS sym)
  1124       map (fn thm => (mor_incl_thm OF replicate n @{thm subset_UNIV}) RS thm RS sym)
  1125         iter_unique_mor_thms;
  1125         iter_unique_mor_thms;
  1126 
  1126 
  1127     val fld_o_iter_thms =
  1127     val ctor_o_iter_thms =
  1128       let
  1128       let
  1129         val mor = mor_comp_thm OF [mor_iter_thm, mor_str_thm];
  1129         val mor = mor_comp_thm OF [mor_iter_thm, mor_str_thm];
  1130       in
  1130       in
  1131         map2 (fn unique => fn iter_fld =>
  1131         map2 (fn unique => fn iter_ctor =>
  1132           trans OF [mor RS unique, iter_fld]) iter_unique_mor_thms iter_fld_thms
  1132           trans OF [mor RS unique, iter_ctor]) iter_unique_mor_thms iter_ctor_thms
  1133       end;
  1133       end;
  1134 
  1134 
  1135     val timer = time (timer "iter definitions & thms");
  1135     val timer = time (timer "iter definitions & thms");
  1136 
  1136 
  1137     val map_flds = map2 (fn Ds => fn bnf =>
  1137     val map_ctors = map2 (fn Ds => fn bnf =>
  1138       Term.list_comb (mk_map_of_bnf Ds (passiveAs @ FTs) (passiveAs @ Ts) bnf,
  1138       Term.list_comb (mk_map_of_bnf Ds (passiveAs @ FTs) (passiveAs @ Ts) bnf,
  1139         map HOLogic.id_const passiveAs @ flds)) Dss bnfs;
  1139         map HOLogic.id_const passiveAs @ ctors)) Dss bnfs;
  1140 
  1140 
  1141     fun unf_bind i = Binding.suffix_name ("_" ^ unfN) (nth bs (i - 1));
  1141     fun dtor_bind i = Binding.suffix_name ("_" ^ dtorN) (nth bs (i - 1));
  1142     val unf_name = Binding.name_of o unf_bind;
  1142     val dtor_name = Binding.name_of o dtor_bind;
  1143     val unf_def_bind = rpair [] o Thm.def_binding o unf_bind;
  1143     val dtor_def_bind = rpair [] o Thm.def_binding o dtor_bind;
  1144 
  1144 
  1145     fun unf_spec i FT T =
  1145     fun dtor_spec i FT T =
  1146       let
  1146       let
  1147         val unfT = T --> FT;
  1147         val dtorT = T --> FT;
  1148 
  1148 
  1149         val lhs = Free (unf_name i, unfT);
  1149         val lhs = Free (dtor_name i, dtorT);
  1150         val rhs = mk_iter Ts map_flds i;
  1150         val rhs = mk_iter Ts map_ctors i;
  1151       in
  1151       in
  1152         mk_Trueprop_eq (lhs, rhs)
  1152         mk_Trueprop_eq (lhs, rhs)
  1153       end;
  1153       end;
  1154 
  1154 
  1155     val ((unf_frees, (_, unf_def_frees)), (lthy, lthy_old)) =
  1155     val ((dtor_frees, (_, dtor_def_frees)), (lthy, lthy_old)) =
  1156       lthy
  1156       lthy
  1157       |> fold_map3 (fn i => fn FT => fn T =>
  1157       |> fold_map3 (fn i => fn FT => fn T =>
  1158         Specification.definition
  1158         Specification.definition
  1159           (SOME (unf_bind i, NONE, NoSyn), (unf_def_bind i, unf_spec i FT T))) ks FTs Ts
  1159           (SOME (dtor_bind i, NONE, NoSyn), (dtor_def_bind i, dtor_spec i FT T))) ks FTs Ts
  1160       |>> apsnd split_list o split_list
  1160       |>> apsnd split_list o split_list
  1161       ||> `Local_Theory.restore;
  1161       ||> `Local_Theory.restore;
  1162 
  1162 
  1163     val phi = Proof_Context.export_morphism lthy_old lthy;
  1163     val phi = Proof_Context.export_morphism lthy_old lthy;
  1164     fun mk_unfs params =
  1164     fun mk_dtors params =
  1165       map (Term.subst_atomic_types (map (Morphism.typ phi) params' ~~ params) o Morphism.term phi)
  1165       map (Term.subst_atomic_types (map (Morphism.typ phi) params' ~~ params) o Morphism.term phi)
  1166         unf_frees;
  1166         dtor_frees;
  1167     val unfs = mk_unfs params';
  1167     val dtors = mk_dtors params';
  1168     val unf_defs = map (Morphism.thm phi) unf_def_frees;
  1168     val dtor_defs = map (Morphism.thm phi) dtor_def_frees;
  1169 
  1169 
  1170     val fld_o_unf_thms = map2 (fold_defs lthy o single) unf_defs fld_o_iter_thms;
  1170     val ctor_o_dtor_thms = map2 (fold_defs lthy o single) dtor_defs ctor_o_iter_thms;
  1171 
  1171 
  1172     val unf_o_fld_thms =
  1172     val dtor_o_ctor_thms =
  1173       let
  1173       let
  1174         fun mk_goal unf fld FT = mk_Trueprop_eq (HOLogic.mk_comp (unf, fld), HOLogic.id_const FT);
  1174         fun mk_goal dtor ctor FT =
  1175         val goals = map3 mk_goal unfs flds FTs;
  1175           mk_Trueprop_eq (HOLogic.mk_comp (dtor, ctor), HOLogic.id_const FT);
  1176       in
  1176         val goals = map3 mk_goal dtors ctors FTs;
  1177         map5 (fn goal => fn unf_def => fn iter => fn map_comp_id => fn map_congL =>
  1177       in
       
  1178         map5 (fn goal => fn dtor_def => fn iter => fn map_comp_id => fn map_congL =>
  1178           Skip_Proof.prove lthy [] [] goal
  1179           Skip_Proof.prove lthy [] [] goal
  1179             (K (mk_unf_o_fld_tac unf_def iter map_comp_id map_congL fld_o_iter_thms))
  1180             (K (mk_dtor_o_ctor_tac dtor_def iter map_comp_id map_congL ctor_o_iter_thms))
  1180           |> Thm.close_derivation)
  1181           |> Thm.close_derivation)
  1181         goals unf_defs iter_thms map_comp_id_thms map_congL_thms
  1182         goals dtor_defs iter_thms map_comp_id_thms map_congL_thms
  1182       end;
  1183       end;
  1183 
  1184 
  1184     val unf_fld_thms = map (fn thm => thm RS @{thm pointfree_idE}) unf_o_fld_thms;
  1185     val dtor_ctor_thms = map (fn thm => thm RS @{thm pointfree_idE}) dtor_o_ctor_thms;
  1185     val fld_unf_thms = map (fn thm => thm RS @{thm pointfree_idE}) fld_o_unf_thms;
  1186     val ctor_dtor_thms = map (fn thm => thm RS @{thm pointfree_idE}) ctor_o_dtor_thms;
  1186 
  1187 
  1187     val bij_unf_thms =
  1188     val bij_dtor_thms =
  1188       map2 (fn thm1 => fn thm2 => @{thm o_bij} OF [thm1, thm2]) fld_o_unf_thms unf_o_fld_thms;
  1189       map2 (fn thm1 => fn thm2 => @{thm o_bij} OF [thm1, thm2]) ctor_o_dtor_thms dtor_o_ctor_thms;
  1189     val inj_unf_thms = map (fn thm => thm RS @{thm bij_is_inj}) bij_unf_thms;
  1190     val inj_dtor_thms = map (fn thm => thm RS @{thm bij_is_inj}) bij_dtor_thms;
  1190     val surj_unf_thms = map (fn thm => thm RS @{thm bij_is_surj}) bij_unf_thms;
  1191     val surj_dtor_thms = map (fn thm => thm RS @{thm bij_is_surj}) bij_dtor_thms;
  1191     val unf_nchotomy_thms = map (fn thm => thm RS @{thm surjD}) surj_unf_thms;
  1192     val dtor_nchotomy_thms = map (fn thm => thm RS @{thm surjD}) surj_dtor_thms;
  1192     val unf_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_unf_thms;
  1193     val dtor_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_dtor_thms;
  1193     val unf_exhaust_thms = map (fn thm => thm RS exE) unf_nchotomy_thms;
  1194     val dtor_exhaust_thms = map (fn thm => thm RS exE) dtor_nchotomy_thms;
  1194 
  1195 
  1195     val bij_fld_thms =
  1196     val bij_ctor_thms =
  1196       map2 (fn thm1 => fn thm2 => @{thm o_bij} OF [thm1, thm2]) unf_o_fld_thms fld_o_unf_thms;
  1197       map2 (fn thm1 => fn thm2 => @{thm o_bij} OF [thm1, thm2]) dtor_o_ctor_thms ctor_o_dtor_thms;
  1197     val inj_fld_thms = map (fn thm => thm RS @{thm bij_is_inj}) bij_fld_thms;
  1198     val inj_ctor_thms = map (fn thm => thm RS @{thm bij_is_inj}) bij_ctor_thms;
  1198     val surj_fld_thms = map (fn thm => thm RS @{thm bij_is_surj}) bij_fld_thms;
  1199     val surj_ctor_thms = map (fn thm => thm RS @{thm bij_is_surj}) bij_ctor_thms;
  1199     val fld_nchotomy_thms = map (fn thm => thm RS @{thm surjD}) surj_fld_thms;
  1200     val ctor_nchotomy_thms = map (fn thm => thm RS @{thm surjD}) surj_ctor_thms;
  1200     val fld_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_fld_thms;
  1201     val ctor_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_ctor_thms;
  1201     val fld_exhaust_thms = map (fn thm => thm RS exE) fld_nchotomy_thms;
  1202     val ctor_exhaust_thms = map (fn thm => thm RS exE) ctor_nchotomy_thms;
  1202 
  1203 
  1203     val timer = time (timer "unf definitions & thms");
  1204     val timer = time (timer "dtor definitions & thms");
  1204 
  1205 
  1205     val fst_rec_pair_thms =
  1206     val fst_rec_pair_thms =
  1206       let
  1207       let
  1207         val mor = mor_comp_thm OF [mor_iter_thm, mor_convol_thm];
  1208         val mor = mor_comp_thm OF [mor_iter_thm, mor_convol_thm];
  1208       in
  1209       in
  1209         map2 (fn unique => fn iter_fld =>
  1210         map2 (fn unique => fn iter_ctor =>
  1210           trans OF [mor RS unique, iter_fld]) iter_unique_mor_thms iter_fld_thms
  1211           trans OF [mor RS unique, iter_ctor]) iter_unique_mor_thms iter_ctor_thms
  1211       end;
  1212       end;
  1212 
  1213 
  1213     fun rec_bind i = Binding.suffix_name ("_" ^ fld_recN) (nth bs (i - 1));
  1214     fun rec_bind i = Binding.suffix_name ("_" ^ ctor_recN) (nth bs (i - 1));
  1214     val rec_name = Binding.name_of o rec_bind;
  1215     val rec_name = Binding.name_of o rec_bind;
  1215     val rec_def_bind = rpair [] o Thm.def_binding o rec_bind;
  1216     val rec_def_bind = rpair [] o Thm.def_binding o rec_bind;
  1216 
  1217 
  1217     fun rec_spec i T AT =
  1218     fun rec_spec i T AT =
  1218       let
  1219       let
  1219         val recT = Library.foldr (op -->) (rec_sTs, T --> AT);
  1220         val recT = Library.foldr (op -->) (rec_sTs, T --> AT);
  1220         val maps = map3 (fn fld => fn prod_s => fn mapx =>
  1221         val maps = map3 (fn ctor => fn prod_s => fn mapx =>
  1221           mk_convol (HOLogic.mk_comp (fld, Term.list_comb (mapx, passive_ids @ rec_fsts)), prod_s))
  1222           mk_convol (HOLogic.mk_comp (ctor, Term.list_comb (mapx, passive_ids @ rec_fsts)), prod_s))
  1222           flds rec_ss rec_maps;
  1223           ctors rec_ss rec_maps;
  1223 
  1224 
  1224         val lhs = Term.list_comb (Free (rec_name i, recT), rec_ss);
  1225         val lhs = Term.list_comb (Free (rec_name i, recT), rec_ss);
  1225         val rhs = HOLogic.mk_comp (snd_const (HOLogic.mk_prodT (T, AT)), mk_iter Ts maps i);
  1226         val rhs = HOLogic.mk_comp (snd_const (HOLogic.mk_prodT (T, AT)), mk_iter Ts maps i);
  1226       in
  1227       in
  1227         mk_Trueprop_eq (lhs, rhs)
  1228         mk_Trueprop_eq (lhs, rhs)
  1244     val rec_defs = map (Morphism.thm phi) rec_def_frees;
  1245     val rec_defs = map (Morphism.thm phi) rec_def_frees;
  1245 
  1246 
  1246     val convols = map2 (fn T => fn i => mk_convol (HOLogic.id_const T, mk_rec rec_ss i)) Ts ks;
  1247     val convols = map2 (fn T => fn i => mk_convol (HOLogic.id_const T, mk_rec rec_ss i)) Ts ks;
  1247     val rec_thms =
  1248     val rec_thms =
  1248       let
  1249       let
  1249         fun mk_goal i rec_s rec_map fld x =
  1250         fun mk_goal i rec_s rec_map ctor x =
  1250           let
  1251           let
  1251             val lhs = mk_rec rec_ss i $ (fld $ x);
  1252             val lhs = mk_rec rec_ss i $ (ctor $ x);
  1252             val rhs = rec_s $ (Term.list_comb (rec_map, passive_ids @ convols) $ x);
  1253             val rhs = rec_s $ (Term.list_comb (rec_map, passive_ids @ convols) $ x);
  1253           in
  1254           in
  1254             fold_rev Logic.all (x :: rec_ss) (mk_Trueprop_eq (lhs, rhs))
  1255             fold_rev Logic.all (x :: rec_ss) (mk_Trueprop_eq (lhs, rhs))
  1255           end;
  1256           end;
  1256         val goals = map5 mk_goal ks rec_ss rec_maps_rev flds xFs;
  1257         val goals = map5 mk_goal ks rec_ss rec_maps_rev ctors xFs;
  1257       in
  1258       in
  1258         map2 (fn goal => fn iter =>
  1259         map2 (fn goal => fn iter =>
  1259           Skip_Proof.prove lthy [] [] goal (mk_rec_tac rec_defs iter fst_rec_pair_thms)
  1260           Skip_Proof.prove lthy [] [] goal (mk_rec_tac rec_defs iter fst_rec_pair_thms)
  1260           |> Thm.close_derivation)
  1261           |> Thm.close_derivation)
  1261         goals iter_thms
  1262         goals iter_thms
  1262       end;
  1263       end;
  1263 
  1264 
  1264     val timer = time (timer "rec definitions & thms");
  1265     val timer = time (timer "rec definitions & thms");
  1265 
  1266 
  1266     val (fld_induct_thm, induct_params) =
  1267     val (ctor_induct_thm, induct_params) =
  1267       let
  1268       let
  1268         fun mk_prem phi fld sets x =
  1269         fun mk_prem phi ctor sets x =
  1269           let
  1270           let
  1270             fun mk_IH phi set z =
  1271             fun mk_IH phi set z =
  1271               let
  1272               let
  1272                 val prem = HOLogic.mk_Trueprop (HOLogic.mk_mem (z, set $ x));
  1273                 val prem = HOLogic.mk_Trueprop (HOLogic.mk_mem (z, set $ x));
  1273                 val concl = HOLogic.mk_Trueprop (phi $ z);
  1274                 val concl = HOLogic.mk_Trueprop (phi $ z);
  1274               in
  1275               in
  1275                 Logic.all z (Logic.mk_implies (prem, concl))
  1276                 Logic.all z (Logic.mk_implies (prem, concl))
  1276               end;
  1277               end;
  1277 
  1278 
  1278             val IHs = map3 mk_IH phis (drop m sets) Izs;
  1279             val IHs = map3 mk_IH phis (drop m sets) Izs;
  1279             val concl = HOLogic.mk_Trueprop (phi $ (fld $ x));
  1280             val concl = HOLogic.mk_Trueprop (phi $ (ctor $ x));
  1280           in
  1281           in
  1281             Logic.all x (Logic.list_implies (IHs, concl))
  1282             Logic.all x (Logic.list_implies (IHs, concl))
  1282           end;
  1283           end;
  1283 
  1284 
  1284         val prems = map4 mk_prem phis flds FTs_setss xFs;
  1285         val prems = map4 mk_prem phis ctors FTs_setss xFs;
  1285 
  1286 
  1286         fun mk_concl phi z = phi $ z;
  1287         fun mk_concl phi z = phi $ z;
  1287         val concl =
  1288         val concl =
  1288           HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_concl phis Izs));
  1289           HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_concl phis Izs));
  1289 
  1290 
  1290         val goal = Logic.list_implies (prems, concl);
  1291         val goal = Logic.list_implies (prems, concl);
  1291       in
  1292       in
  1292         (Skip_Proof.prove lthy [] []
  1293         (Skip_Proof.prove lthy [] []
  1293           (fold_rev Logic.all (phis @ Izs) goal)
  1294           (fold_rev Logic.all (phis @ Izs) goal)
  1294           (K (mk_fld_induct_tac m set_natural'ss init_induct_thm morE_thms mor_Abs_thm
  1295           (K (mk_ctor_induct_tac m set_natural'ss init_induct_thm morE_thms mor_Abs_thm
  1295             Rep_inverses Abs_inverses Reps))
  1296             Rep_inverses Abs_inverses Reps))
  1296         |> Thm.close_derivation,
  1297         |> Thm.close_derivation,
  1297         rev (Term.add_tfrees goal []))
  1298         rev (Term.add_tfrees goal []))
  1298       end;
  1299       end;
  1299 
  1300 
  1300     val cTs = map (SOME o certifyT lthy o TFree) induct_params;
  1301     val cTs = map (SOME o certifyT lthy o TFree) induct_params;
  1301 
  1302 
  1302     val weak_fld_induct_thms =
  1303     val weak_ctor_induct_thms =
  1303       let fun insts i = (replicate (i - 1) TrueI) @ (@{thm asm_rl} :: replicate (n - i) TrueI);
  1304       let fun insts i = (replicate (i - 1) TrueI) @ (@{thm asm_rl} :: replicate (n - i) TrueI);
  1304       in map (fn i => (fld_induct_thm OF insts i) RS mk_conjunctN n i) ks end;
  1305       in map (fn i => (ctor_induct_thm OF insts i) RS mk_conjunctN n i) ks end;
  1305 
  1306 
  1306     val (fld_induct2_thm, induct2_params) =
  1307     val (ctor_induct2_thm, induct2_params) =
  1307       let
  1308       let
  1308         fun mk_prem phi fld fld' sets sets' x y =
  1309         fun mk_prem phi ctor ctor' sets sets' x y =
  1309           let
  1310           let
  1310             fun mk_IH phi set set' z1 z2 =
  1311             fun mk_IH phi set set' z1 z2 =
  1311               let
  1312               let
  1312                 val prem1 = HOLogic.mk_Trueprop (HOLogic.mk_mem (z1, (set $ x)));
  1313                 val prem1 = HOLogic.mk_Trueprop (HOLogic.mk_mem (z1, (set $ x)));
  1313                 val prem2 = HOLogic.mk_Trueprop (HOLogic.mk_mem (z2, (set' $ y)));
  1314                 val prem2 = HOLogic.mk_Trueprop (HOLogic.mk_mem (z2, (set' $ y)));
  1315               in
  1316               in
  1316                 fold_rev Logic.all [z1, z2] (Logic.list_implies ([prem1, prem2], concl))
  1317                 fold_rev Logic.all [z1, z2] (Logic.list_implies ([prem1, prem2], concl))
  1317               end;
  1318               end;
  1318 
  1319 
  1319             val IHs = map5 mk_IH phi2s (drop m sets) (drop m sets') Izs1 Izs2;
  1320             val IHs = map5 mk_IH phi2s (drop m sets) (drop m sets') Izs1 Izs2;
  1320             val concl = HOLogic.mk_Trueprop (phi $ (fld $ x) $ (fld' $ y));
  1321             val concl = HOLogic.mk_Trueprop (phi $ (ctor $ x) $ (ctor' $ y));
  1321           in
  1322           in
  1322             fold_rev Logic.all [x, y] (Logic.list_implies (IHs, concl))
  1323             fold_rev Logic.all [x, y] (Logic.list_implies (IHs, concl))
  1323           end;
  1324           end;
  1324 
  1325 
  1325         val prems = map7 mk_prem phi2s flds fld's FTs_setss FTs'_setss xFs yFs;
  1326         val prems = map7 mk_prem phi2s ctors ctor's FTs_setss FTs'_setss xFs yFs;
  1326 
  1327 
  1327         fun mk_concl phi z1 z2 = phi $ z1 $ z2;
  1328         fun mk_concl phi z1 z2 = phi $ z1 $ z2;
  1328         val concl = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1329         val concl = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1329           (map3 mk_concl phi2s Izs1 Izs2));
  1330           (map3 mk_concl phi2s Izs1 Izs2));
  1330         fun mk_t phi (z1, z1') (z2, z2') =
  1331         fun mk_t phi (z1, z1') (z2, z2') =
  1332         val cts = map3 (SOME o certify lthy ooo mk_t) phi2s (Izs1 ~~ Izs1') (Izs2 ~~ Izs2');
  1333         val cts = map3 (SOME o certify lthy ooo mk_t) phi2s (Izs1 ~~ Izs1') (Izs2 ~~ Izs2');
  1333         val goal = Logic.list_implies (prems, concl);
  1334         val goal = Logic.list_implies (prems, concl);
  1334       in
  1335       in
  1335         (singleton (Proof_Context.export names_lthy lthy)
  1336         (singleton (Proof_Context.export names_lthy lthy)
  1336           (Skip_Proof.prove lthy [] [] goal
  1337           (Skip_Proof.prove lthy [] [] goal
  1337             (mk_fld_induct2_tac cTs cts fld_induct_thm weak_fld_induct_thms))
  1338             (mk_ctor_induct2_tac cTs cts ctor_induct_thm weak_ctor_induct_thms))
  1338           |> Thm.close_derivation,
  1339           |> Thm.close_derivation,
  1339         rev (Term.add_tfrees goal []))
  1340         rev (Term.add_tfrees goal []))
  1340       end;
  1341       end;
  1341 
  1342 
  1342     val timer = time (timer "induction");
  1343     val timer = time (timer "induction");
  1378 
  1379 
  1379         val map_FTFT's = map2 (fn Ds =>
  1380         val map_FTFT's = map2 (fn Ds =>
  1380           mk_map_of_bnf Ds (passiveAs @ Ts) (passiveBs @ Ts')) Dss bnfs;
  1381           mk_map_of_bnf Ds (passiveAs @ Ts) (passiveBs @ Ts')) Dss bnfs;
  1381         fun mk_passive_maps ATs BTs Ts =
  1382         fun mk_passive_maps ATs BTs Ts =
  1382           map2 (fn Ds => mk_map_of_bnf Ds (ATs @ Ts) (BTs @ Ts)) Dss bnfs;
  1383           map2 (fn Ds => mk_map_of_bnf Ds (ATs @ Ts) (BTs @ Ts)) Dss bnfs;
  1383         fun mk_map_iter_arg fs Ts fld fmap =
  1384         fun mk_map_iter_arg fs Ts ctor fmap =
  1384           HOLogic.mk_comp (fld, Term.list_comb (fmap, fs @ map HOLogic.id_const Ts));
  1385           HOLogic.mk_comp (ctor, Term.list_comb (fmap, fs @ map HOLogic.id_const Ts));
  1385         fun mk_map Ts fs Ts' flds mk_maps =
  1386         fun mk_map Ts fs Ts' ctors mk_maps =
  1386           mk_iter Ts (map2 (mk_map_iter_arg fs Ts') flds (mk_maps Ts'));
  1387           mk_iter Ts (map2 (mk_map_iter_arg fs Ts') ctors (mk_maps Ts'));
  1387         val pmapsABT' = mk_passive_maps passiveAs passiveBs;
  1388         val pmapsABT' = mk_passive_maps passiveAs passiveBs;
  1388         val fs_maps = map (mk_map Ts fs Ts' fld's pmapsABT') ks;
  1389         val fs_maps = map (mk_map Ts fs Ts' ctor's pmapsABT') ks;
  1389         val fs_copy_maps = map (mk_map Ts fs_copy Ts' fld's pmapsABT') ks;
  1390         val fs_copy_maps = map (mk_map Ts fs_copy Ts' ctor's pmapsABT') ks;
  1390         val Yflds = mk_flds passiveYs;
  1391         val Yctors = mk_ctors passiveYs;
  1391         val f1s_maps = map (mk_map Ts f1s YTs Yflds (mk_passive_maps passiveAs passiveYs)) ks;
  1392         val f1s_maps = map (mk_map Ts f1s YTs Yctors (mk_passive_maps passiveAs passiveYs)) ks;
  1392         val f2s_maps = map (mk_map Ts' f2s YTs Yflds (mk_passive_maps passiveBs passiveYs)) ks;
  1393         val f2s_maps = map (mk_map Ts' f2s YTs Yctors (mk_passive_maps passiveBs passiveYs)) ks;
  1393         val p1s_maps = map (mk_map XTs p1s Ts flds (mk_passive_maps passiveXs passiveAs)) ks;
  1394         val p1s_maps = map (mk_map XTs p1s Ts ctors (mk_passive_maps passiveXs passiveAs)) ks;
  1394         val p2s_maps = map (mk_map XTs p2s Ts' fld's (mk_passive_maps passiveXs passiveBs)) ks;
  1395         val p2s_maps = map (mk_map XTs p2s Ts' ctor's (mk_passive_maps passiveXs passiveBs)) ks;
  1395 
  1396 
  1396         val map_simp_thms =
  1397         val map_simp_thms =
  1397           let
  1398           let
  1398             fun mk_goal fs_map map fld fld' = fold_rev Logic.all fs
  1399             fun mk_goal fs_map map ctor ctor' = fold_rev Logic.all fs
  1399               (mk_Trueprop_eq (HOLogic.mk_comp (fs_map, fld),
  1400               (mk_Trueprop_eq (HOLogic.mk_comp (fs_map, ctor),
  1400                 HOLogic.mk_comp (fld', Term.list_comb (map, fs @ fs_maps))));
  1401                 HOLogic.mk_comp (ctor', Term.list_comb (map, fs @ fs_maps))));
  1401             val goals = map4 mk_goal fs_maps map_FTFT's flds fld's;
  1402             val goals = map4 mk_goal fs_maps map_FTFT's ctors ctor's;
  1402             val maps =
  1403             val maps =
  1403               map4 (fn goal => fn iter => fn map_comp_id => fn map_cong =>
  1404               map4 (fn goal => fn iter => fn map_comp_id => fn map_cong =>
  1404                 Skip_Proof.prove lthy [] [] goal (K (mk_map_tac m n iter map_comp_id map_cong))
  1405                 Skip_Proof.prove lthy [] [] goal (K (mk_map_tac m n iter map_comp_id map_cong))
  1405                 |> Thm.close_derivation)
  1406                 |> Thm.close_derivation)
  1406               goals iter_thms map_comp_id_thms map_congs;
  1407               goals iter_thms map_comp_id_thms map_congs;
  1408             map (fn thm => thm RS @{thm pointfreeE}) maps
  1409             map (fn thm => thm RS @{thm pointfreeE}) maps
  1409           end;
  1410           end;
  1410 
  1411 
  1411         val (map_unique_thms, map_unique_thm) =
  1412         val (map_unique_thms, map_unique_thm) =
  1412           let
  1413           let
  1413             fun mk_prem u map fld fld' =
  1414             fun mk_prem u map ctor ctor' =
  1414               mk_Trueprop_eq (HOLogic.mk_comp (u, fld),
  1415               mk_Trueprop_eq (HOLogic.mk_comp (u, ctor),
  1415                 HOLogic.mk_comp (fld', Term.list_comb (map, fs @ us)));
  1416                 HOLogic.mk_comp (ctor', Term.list_comb (map, fs @ us)));
  1416             val prems = map4 mk_prem us map_FTFT's flds fld's;
  1417             val prems = map4 mk_prem us map_FTFT's ctors ctor's;
  1417             val goal =
  1418             val goal =
  1418               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1419               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1419                 (map2 (curry HOLogic.mk_eq) us fs_maps));
  1420                 (map2 (curry HOLogic.mk_eq) us fs_maps));
  1420             val unique = Skip_Proof.prove lthy [] []
  1421             val unique = Skip_Proof.prove lthy [] []
  1421               (fold_rev Logic.all (us @ fs) (Logic.list_implies (prems, goal)))
  1422               (fold_rev Logic.all (us @ fs) (Logic.list_implies (prems, goal)))
  1453         val setss_by_range = map (fn cols => map (mk_iter Ts cols) ks) colss;
  1454         val setss_by_range = map (fn cols => map (mk_iter Ts cols) ks) colss;
  1454         val setss_by_bnf = transpose setss_by_range;
  1455         val setss_by_bnf = transpose setss_by_range;
  1455 
  1456 
  1456         val set_simp_thmss =
  1457         val set_simp_thmss =
  1457           let
  1458           let
  1458             fun mk_goal sets fld set col map =
  1459             fun mk_goal sets ctor set col map =
  1459               mk_Trueprop_eq (HOLogic.mk_comp (set, fld),
  1460               mk_Trueprop_eq (HOLogic.mk_comp (set, ctor),
  1460                 HOLogic.mk_comp (col, Term.list_comb (map, passive_ids @ sets)));
  1461                 HOLogic.mk_comp (col, Term.list_comb (map, passive_ids @ sets)));
  1461             val goalss =
  1462             val goalss =
  1462               map3 (fn sets => map4 (mk_goal sets) flds sets) setss_by_range colss map_setss;
  1463               map3 (fn sets => map4 (mk_goal sets) ctors sets) setss_by_range colss map_setss;
  1463             val setss = map (map2 (fn iter => fn goal =>
  1464             val setss = map (map2 (fn iter => fn goal =>
  1464               Skip_Proof.prove lthy [] [] goal (K (mk_set_tac iter)) |> Thm.close_derivation)
  1465               Skip_Proof.prove lthy [] [] goal (K (mk_set_tac iter)) |> Thm.close_derivation)
  1465               iter_thms) goalss;
  1466               iter_thms) goalss;
  1466 
  1467 
  1467             fun mk_simp_goal pas_set act_sets sets fld z set =
  1468             fun mk_simp_goal pas_set act_sets sets ctor z set =
  1468               Logic.all z (mk_Trueprop_eq (set $ (fld $ z),
  1469               Logic.all z (mk_Trueprop_eq (set $ (ctor $ z),
  1469                 mk_union (pas_set $ z,
  1470                 mk_union (pas_set $ z,
  1470                   Library.foldl1 mk_union (map2 (fn X => mk_UNION (X $ z)) act_sets sets))));
  1471                   Library.foldl1 mk_union (map2 (fn X => mk_UNION (X $ z)) act_sets sets))));
  1471             val simp_goalss =
  1472             val simp_goalss =
  1472               map2 (fn i => fn sets =>
  1473               map2 (fn i => fn sets =>
  1473                 map4 (fn Fsets => mk_simp_goal (nth Fsets (i - 1)) (drop m Fsets) sets)
  1474                 map4 (fn Fsets => mk_simp_goal (nth Fsets (i - 1)) (drop m Fsets) sets)
  1474                   FTs_setss flds xFs sets)
  1475                   FTs_setss ctors xFs sets)
  1475                 ls setss_by_range;
  1476                 ls setss_by_range;
  1476 
  1477 
  1477             val set_simpss = map3 (fn i => map3 (fn set_nats => fn goal => fn set =>
  1478             val set_simpss = map3 (fn i => map3 (fn set_nats => fn goal => fn set =>
  1478                 Skip_Proof.prove lthy [] [] goal
  1479                 Skip_Proof.prove lthy [] [] goal
  1479                   (K (mk_set_simp_tac set (nth set_nats (i - 1)) (drop m set_nats)))
  1480                   (K (mk_set_simp_tac set (nth set_nats (i - 1)) (drop m set_nats)))
  1509 
  1510 
  1510             val cphiss = map3 (fn f => fn sets => fn sets' =>
  1511             val cphiss = map3 (fn f => fn sets => fn sets' =>
  1511               (map4 (mk_cphi f) fs_maps Izs sets sets')) fs setss_by_range setss_by_range';
  1512               (map4 (mk_cphi f) fs_maps Izs sets sets')) fs setss_by_range setss_by_range';
  1512 
  1513 
  1513             val inducts = map (fn cphis =>
  1514             val inducts = map (fn cphis =>
  1514               Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm) cphiss;
  1515               Drule.instantiate' cTs (map SOME cphis @ cxs) ctor_induct_thm) cphiss;
  1515 
  1516 
  1516             val goals =
  1517             val goals =
  1517               map3 (fn f => fn sets => fn sets' =>
  1518               map3 (fn f => fn sets => fn sets' =>
  1518                 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1519                 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1519                   (map4 (mk_set_natural f) fs_maps Izs sets sets')))
  1520                   (map4 (mk_set_natural f) fs_maps Izs sets sets')))
  1537             fun mk_cphi z set = certify lthy (Term.absfree (dest_Free z) (mk_set_bd z set));
  1538             fun mk_cphi z set = certify lthy (Term.absfree (dest_Free z) (mk_set_bd z set));
  1538 
  1539 
  1539             val cphiss = map (map2 mk_cphi Izs) setss_by_range;
  1540             val cphiss = map (map2 mk_cphi Izs) setss_by_range;
  1540 
  1541 
  1541             val inducts = map (fn cphis =>
  1542             val inducts = map (fn cphis =>
  1542               Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm) cphiss;
  1543               Drule.instantiate' cTs (map SOME cphis @ cxs) ctor_induct_thm) cphiss;
  1543 
  1544 
  1544             val goals =
  1545             val goals =
  1545               map (fn sets =>
  1546               map (fn sets =>
  1546                 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1547                 HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1547                   (map2 mk_set_bd Izs sets))) setss_by_range;
  1548                   (map2 mk_set_bd Izs sets))) setss_by_range;
  1570             fun mk_cphi sets z fmap gmap =
  1571             fun mk_cphi sets z fmap gmap =
  1571               certify lthy (Term.absfree (dest_Free z) (mk_map_cong sets z fmap gmap));
  1572               certify lthy (Term.absfree (dest_Free z) (mk_map_cong sets z fmap gmap));
  1572 
  1573 
  1573             val cphis = map4 mk_cphi setss_by_bnf Izs fs_maps fs_copy_maps;
  1574             val cphis = map4 mk_cphi setss_by_bnf Izs fs_maps fs_copy_maps;
  1574 
  1575 
  1575             val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm;
  1576             val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) ctor_induct_thm;
  1576 
  1577 
  1577             val goal =
  1578             val goal =
  1578               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1579               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1579                 (map4 mk_map_cong setss_by_bnf Izs fs_maps fs_copy_maps));
  1580                 (map4 mk_map_cong setss_by_bnf Izs fs_maps fs_copy_maps));
  1580 
  1581 
  1590           let
  1591           let
  1591             fun mk_prem z sets =
  1592             fun mk_prem z sets =
  1592               HOLogic.mk_mem (z, mk_in As sets (fastype_of z));
  1593               HOLogic.mk_mem (z, mk_in As sets (fastype_of z));
  1593 
  1594 
  1594             fun mk_incl z sets i =
  1595             fun mk_incl z sets i =
  1595               HOLogic.mk_imp (mk_prem z sets, HOLogic.mk_mem (z, mk_min_alg As flds i));
  1596               HOLogic.mk_imp (mk_prem z sets, HOLogic.mk_mem (z, mk_min_alg As ctors i));
  1596 
  1597 
  1597             fun mk_cphi z sets i =
  1598             fun mk_cphi z sets i =
  1598               certify lthy (Term.absfree (dest_Free z) (mk_incl z sets i));
  1599               certify lthy (Term.absfree (dest_Free z) (mk_incl z sets i));
  1599 
  1600 
  1600             val cphis = map3 mk_cphi Izs setss_by_bnf ks;
  1601             val cphis = map3 mk_cphi Izs setss_by_bnf ks;
  1601 
  1602 
  1602             val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct_thm;
  1603             val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) ctor_induct_thm;
  1603 
  1604 
  1604             val goal =
  1605             val goal =
  1605               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1606               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
  1606                 (map3 mk_incl Izs setss_by_bnf ks));
  1607                 (map3 mk_incl Izs setss_by_bnf ks));
  1607 
  1608 
  1639 
  1640 
  1640             fun mk_cphi z1 z2 goal = certify lthy (Term.absfree z1 (Term.absfree z2 goal));
  1641             fun mk_cphi z1 z2 goal = certify lthy (Term.absfree z1 (Term.absfree z2 goal));
  1641 
  1642 
  1642             val cphis = map3 mk_cphi Izs1' Izs2' goals;
  1643             val cphis = map3 mk_cphi Izs1' Izs2' goals;
  1643 
  1644 
  1644             val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) fld_induct2_thm;
  1645             val induct = Drule.instantiate' cTs (map SOME cphis @ cxs) ctor_induct2_thm;
  1645 
  1646 
  1646             val goal = Logic.list_implies (map HOLogic.mk_Trueprop
  1647             val goal = Logic.list_implies (map HOLogic.mk_Trueprop
  1647                 (map8 mk_wpull AXs B1s B2s f1s f2s (replicate m NONE) p1s p2s),
  1648                 (map8 mk_wpull AXs B1s B2s f1s f2s (replicate m NONE) p1s p2s),
  1648               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj goals));
  1649               HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj goals));
  1649 
  1650 
  1650             val thm = singleton (Proof_Context.export names_lthy lthy)
  1651             val thm = singleton (Proof_Context.export names_lthy lthy)
  1651               (Skip_Proof.prove lthy [] [] goal
  1652               (Skip_Proof.prove lthy [] [] goal
  1652               (K (mk_lfp_map_wpull_tac m (rtac induct) map_wpulls map_simp_thms
  1653               (K (mk_lfp_map_wpull_tac m (rtac induct) map_wpulls map_simp_thms
  1653                 (transpose set_simp_thmss) Fset_set_thmsss fld_inject_thms)))
  1654                 (transpose set_simp_thmss) Fset_set_thmsss ctor_inject_thms)))
  1654               |> Thm.close_derivation;
  1655               |> Thm.close_derivation;
  1655           in
  1656           in
  1656             split_conj_thm thm
  1657             split_conj_thm thm
  1657           end;
  1658           end;
  1658 
  1659 
  1673         val rel_O_Gr_tacs = replicate n (simple_rel_O_Gr_tac o #context);
  1674         val rel_O_Gr_tacs = replicate n (simple_rel_O_Gr_tac o #context);
  1674 
  1675 
  1675         val tacss = map10 zip_axioms map_id_tacs map_comp_tacs map_cong_tacs set_nat_tacss
  1676         val tacss = map10 zip_axioms map_id_tacs map_comp_tacs map_cong_tacs set_nat_tacss
  1676           bd_co_tacs bd_cinf_tacs set_bd_tacss in_bd_tacs map_wpull_tacs rel_O_Gr_tacs;
  1677           bd_co_tacs bd_cinf_tacs set_bd_tacss in_bd_tacs map_wpull_tacs rel_O_Gr_tacs;
  1677 
  1678 
  1678         val fld_witss =
  1679         val ctor_witss =
  1679           let
  1680           let
  1680             val witss = map2 (fn Ds => fn bnf => mk_wits_of_bnf
  1681             val witss = map2 (fn Ds => fn bnf => mk_wits_of_bnf
  1681               (replicate (nwits_of_bnf bnf) Ds)
  1682               (replicate (nwits_of_bnf bnf) Ds)
  1682               (replicate (nwits_of_bnf bnf) (passiveAs @ Ts)) bnf) Dss bnfs;
  1683               (replicate (nwits_of_bnf bnf) (passiveAs @ Ts)) bnf) Dss bnfs;
  1683             fun close_wit (I, wit) = fold_rev Term.absfree (map (nth ys') I) wit;
  1684             fun close_wit (I, wit) = fold_rev Term.absfree (map (nth ys') I) wit;
  1684             fun wit_apply (arg_I, arg_wit) (fun_I, fun_wit) =
  1685             fun wit_apply (arg_I, arg_wit) (fun_I, fun_wit) =
  1685               (union (op =) arg_I fun_I, fun_wit $ arg_wit);
  1686               (union (op =) arg_I fun_I, fun_wit $ arg_wit);
  1686 
  1687 
  1687             fun gen_arg support i =
  1688             fun gen_arg support i =
  1688               if i < m then [([i], nth ys i)]
  1689               if i < m then [([i], nth ys i)]
  1689               else maps (mk_wit support (nth flds (i - m)) (i - m)) (nth support (i - m))
  1690               else maps (mk_wit support (nth ctors (i - m)) (i - m)) (nth support (i - m))
  1690             and mk_wit support fld i (I, wit) =
  1691             and mk_wit support ctor i (I, wit) =
  1691               let val args = map (gen_arg (nth_map i (remove (op =) (I, wit)) support)) I;
  1692               let val args = map (gen_arg (nth_map i (remove (op =) (I, wit)) support)) I;
  1692               in
  1693               in
  1693                 (args, [([], wit)])
  1694                 (args, [([], wit)])
  1694                 |-> fold (map_product wit_apply)
  1695                 |-> fold (map_product wit_apply)
  1695                 |> map (apsnd (fn t => fld $ t))
  1696                 |> map (apsnd (fn t => ctor $ t))
  1696                 |> minimize_wits
  1697                 |> minimize_wits
  1697               end;
  1698               end;
  1698           in
  1699           in
  1699             map3 (fn fld => fn i => map close_wit o minimize_wits o maps (mk_wit witss fld i))
  1700             map3 (fn ctor => fn i => map close_wit o minimize_wits o maps (mk_wit witss ctor i))
  1700               flds (0 upto n - 1) witss
  1701               ctors (0 upto n - 1) witss
  1701           end;
  1702           end;
  1702 
  1703 
  1703         fun wit_tac _ = mk_wit_tac n (flat set_simp_thmss) (maps wit_thms_of_bnf bnfs);
  1704         fun wit_tac _ = mk_wit_tac n (flat set_simp_thmss) (maps wit_thms_of_bnf bnfs);
  1704 
  1705 
  1705         val policy = user_policy Derive_All_Facts_Note_Most;
  1706         val policy = user_policy Derive_All_Facts_Note_Most;
  1707         val (Ibnfs, lthy) =
  1708         val (Ibnfs, lthy) =
  1708           fold_map6 (fn tacs => fn b => fn mapx => fn sets => fn T => fn wits => fn lthy =>
  1709           fold_map6 (fn tacs => fn b => fn mapx => fn sets => fn T => fn wits => fn lthy =>
  1709             bnf_def Dont_Inline policy I tacs wit_tac (SOME deads)
  1710             bnf_def Dont_Inline policy I tacs wit_tac (SOME deads)
  1710               (((((b, fold_rev Term.absfree fs' mapx), sets), absdummy T bd), wits), NONE) lthy
  1711               (((((b, fold_rev Term.absfree fs' mapx), sets), absdummy T bd), wits), NONE) lthy
  1711             |> register_bnf (Local_Theory.full_name lthy b))
  1712             |> register_bnf (Local_Theory.full_name lthy b))
  1712           tacss bs fs_maps setss_by_bnf Ts fld_witss lthy;
  1713           tacss bs fs_maps setss_by_bnf Ts ctor_witss lthy;
  1713 
  1714 
  1714         val fold_maps = fold_defs lthy (map (fn bnf =>
  1715         val fold_maps = fold_defs lthy (map (fn bnf =>
  1715           mk_unabs_def m (map_def_of_bnf bnf RS @{thm meta_eq_to_obj_eq})) Ibnfs);
  1716           mk_unabs_def m (map_def_of_bnf bnf RS @{thm meta_eq_to_obj_eq})) Ibnfs);
  1716 
  1717 
  1717         val fold_sets = fold_defs lthy (maps (fn bnf =>
  1718         val fold_sets = fold_defs lthy (maps (fn bnf =>
  1741         val folded_set_simp_thmss = map (map fold_sets) set_simp_thmss;
  1742         val folded_set_simp_thmss = map (map fold_sets) set_simp_thmss;
  1742         val folded_set_simp_thmss' = transpose folded_set_simp_thmss;
  1743         val folded_set_simp_thmss' = transpose folded_set_simp_thmss;
  1743 
  1744 
  1744         val Irel_simp_thms =
  1745         val Irel_simp_thms =
  1745           let
  1746           let
  1746             fun mk_goal xF yF fld fld' IrelR relR = fold_rev Logic.all (xF :: yF :: IRs)
  1747             fun mk_goal xF yF ctor ctor' IrelR relR = fold_rev Logic.all (xF :: yF :: IRs)
  1747               (mk_Trueprop_eq (HOLogic.mk_mem (HOLogic.mk_prod (fld $ xF, fld' $ yF), IrelR),
  1748               (mk_Trueprop_eq (HOLogic.mk_mem (HOLogic.mk_prod (ctor $ xF, ctor' $ yF), IrelR),
  1748                   HOLogic.mk_mem (HOLogic.mk_prod (xF, yF), relR)));
  1749                   HOLogic.mk_mem (HOLogic.mk_prod (xF, yF), relR)));
  1749             val goals = map6 mk_goal xFs yFs flds fld's IrelRs relRs;
  1750             val goals = map6 mk_goal xFs yFs ctors ctor's IrelRs relRs;
  1750           in
  1751           in
  1751             map12 (fn i => fn goal => fn in_rel => fn map_comp => fn map_cong =>
  1752             map12 (fn i => fn goal => fn in_rel => fn map_comp => fn map_cong =>
  1752               fn map_simp => fn set_simps => fn fld_inject => fn fld_unf =>
  1753               fn map_simp => fn set_simps => fn ctor_inject => fn ctor_dtor =>
  1753               fn set_naturals => fn set_incls => fn set_set_inclss =>
  1754               fn set_naturals => fn set_incls => fn set_set_inclss =>
  1754               Skip_Proof.prove lthy [] [] goal
  1755               Skip_Proof.prove lthy [] [] goal
  1755                (K (mk_rel_simp_tac in_Irels i in_rel map_comp map_cong map_simp set_simps
  1756                (K (mk_rel_simp_tac in_Irels i in_rel map_comp map_cong map_simp set_simps
  1756                  fld_inject fld_unf set_naturals set_incls set_set_inclss))
  1757                  ctor_inject ctor_dtor set_naturals set_incls set_set_inclss))
  1757               |> Thm.close_derivation)
  1758               |> Thm.close_derivation)
  1758             ks goals in_rels map_comp's map_congs folded_map_simp_thms folded_set_simp_thmss'
  1759             ks goals in_rels map_comp's map_congs folded_map_simp_thms folded_set_simp_thmss'
  1759               fld_inject_thms fld_unf_thms set_natural'ss set_incl_thmss set_set_incl_thmsss
  1760               ctor_inject_thms ctor_dtor_thms set_natural'ss set_incl_thmss set_set_incl_thmsss
  1760           end;
  1761           end;
  1761 
  1762 
  1762         val Ipred_simp_thms =
  1763         val Ipred_simp_thms =
  1763           let
  1764           let
  1764             fun mk_goal xF yF fld fld' Ipredphi predphi = fold_rev Logic.all (xF :: yF :: Iphis)
  1765             fun mk_goal xF yF ctor ctor' Ipredphi predphi = fold_rev Logic.all (xF :: yF :: Iphis)
  1765               (mk_Trueprop_eq (Ipredphi $ (fld $ xF) $ (fld' $ yF), predphi $ xF $ yF));
  1766               (mk_Trueprop_eq (Ipredphi $ (ctor $ xF) $ (ctor' $ yF), predphi $ xF $ yF));
  1766             val goals = map6 mk_goal xFs yFs flds fld's Ipredphis predphis;
  1767             val goals = map6 mk_goal xFs yFs ctors ctor's Ipredphis predphis;
  1767           in
  1768           in
  1768             map3 (fn goal => fn rel_def => fn Irel_simp =>
  1769             map3 (fn goal => fn rel_def => fn Irel_simp =>
  1769               Skip_Proof.prove lthy [] [] goal
  1770               Skip_Proof.prove lthy [] [] goal
  1770                 (mk_pred_simp_tac rel_def Ipred_defs Irel_defs Irel_simp)
  1771                 (mk_pred_simp_tac rel_def Ipred_defs Irel_defs Irel_simp)
  1771               |> Thm.close_derivation)
  1772               |> Thm.close_derivation)
  1795       in
  1796       in
  1796         timer; lthy |> Local_Theory.notes (Ibnf_common_notes @ Ibnf_notes) |> snd
  1797         timer; lthy |> Local_Theory.notes (Ibnf_common_notes @ Ibnf_notes) |> snd
  1797       end;
  1798       end;
  1798 
  1799 
  1799       val common_notes =
  1800       val common_notes =
  1800         [(fld_inductN, [fld_induct_thm]),
  1801         [(ctor_inductN, [ctor_induct_thm]),
  1801         (fld_induct2N, [fld_induct2_thm])]
  1802         (ctor_induct2N, [ctor_induct2_thm])]
  1802         |> map (fn (thmN, thms) =>
  1803         |> map (fn (thmN, thms) =>
  1803           ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), []), [(thms, [])]));
  1804           ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), []), [(thms, [])]));
  1804 
  1805 
  1805       val notes =
  1806       val notes =
  1806         [(fld_itersN, iter_thms),
  1807         [(ctor_dtorN, ctor_dtor_thms),
  1807         (fld_iter_uniqueN, iter_unique_thms),
  1808         (ctor_exhaustN, ctor_exhaust_thms),
  1808         (fld_recsN, rec_thms),
  1809         (ctor_injectN, ctor_inject_thms),
  1809         (unf_fldN, unf_fld_thms),
  1810         (ctor_iter_uniqueN, iter_unique_thms),
  1810         (fld_unfN, fld_unf_thms),
  1811         (ctor_itersN, iter_thms),
  1811         (unf_injectN, unf_inject_thms),
  1812         (ctor_recsN, rec_thms),
  1812         (unf_exhaustN, unf_exhaust_thms),
  1813         (dtor_ctorN, dtor_ctor_thms),
  1813         (fld_injectN, fld_inject_thms),
  1814         (dtor_exhaustN, dtor_exhaust_thms),
  1814         (fld_exhaustN, fld_exhaust_thms)]
  1815         (dtor_injectN, dtor_inject_thms)]
  1815         |> map (apsnd (map single))
  1816         |> map (apsnd (map single))
  1816         |> maps (fn (thmN, thmss) =>
  1817         |> maps (fn (thmN, thmss) =>
  1817           map2 (fn b => fn thms =>
  1818           map2 (fn b => fn thms =>
  1818             ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), []), [(thms, [])]))
  1819             ((Binding.qualify true (Binding.name_of b) (Binding.name thmN), []), [(thms, [])]))
  1819           bs thmss)
  1820           bs thmss)
  1820   in
  1821   in
  1821     ((unfs, flds, iters, recs, fld_induct_thm, unf_fld_thms, fld_unf_thms, fld_inject_thms,
  1822     ((dtors, ctors, iters, recs, ctor_induct_thm, dtor_ctor_thms, ctor_dtor_thms, ctor_inject_thms,
  1822       iter_thms, rec_thms),
  1823       iter_thms, rec_thms),
  1823      lthy |> Local_Theory.notes (common_notes @ notes) |> snd)
  1824      lthy |> Local_Theory.notes (common_notes @ notes) |> snd)
  1824   end;
  1825   end;
  1825 
  1826 
  1826 val _ =
  1827 val _ =