1200 val ctor_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_ctor_thms; |
1200 val ctor_inject_thms = map (fn thm => thm RS @{thm inj_eq}) inj_ctor_thms; |
1201 val ctor_exhaust_thms = map (fn thm => thm RS exE) ctor_nchotomy_thms; |
1201 val ctor_exhaust_thms = map (fn thm => thm RS exE) ctor_nchotomy_thms; |
1202 |
1202 |
1203 val timer = time (timer "dtor definitions & thms"); |
1203 val timer = time (timer "dtor definitions & thms"); |
1204 |
1204 |
1205 val fst_rec_pair_thms = |
|
1206 let |
|
1207 val mor = mor_comp_thm OF [mor_fold_thm, mor_convol_thm]; |
|
1208 in |
|
1209 map2 (fn unique => fn fold_ctor => |
|
1210 trans OF [mor RS unique, fold_ctor]) fold_unique_mor_thms fold_ctor_thms |
|
1211 end; |
|
1212 |
|
1213 fun rec_bind i = nth external_bs (i - 1) |> Binding.prefix_name (ctor_recN ^ "_"); |
|
1214 val rec_def_bind = rpair [] o Binding.concealed o Thm.def_binding o rec_bind; |
|
1215 |
|
1216 fun mk_rec_strs rec_ss = |
|
1217 @{map 3} (fn ctor => fn prod_s => fn mapx => |
|
1218 mk_convol (HOLogic.mk_comp (ctor, Term.list_comb (mapx, passive_ids @ rec_fsts)), prod_s)) |
|
1219 ctors rec_ss rec_maps; |
|
1220 |
|
1221 fun rec_spec i T AT = |
|
1222 fold_rev (Term.absfree o Term.dest_Free) rec_ss |
|
1223 (HOLogic.mk_comp (snd_const (HOLogic.mk_prodT (T, AT)), mk_fold Ts (mk_rec_strs rec_ss) i)); |
|
1224 |
|
1225 val ((rec_frees, (_, rec_def_frees)), (lthy, lthy_old)) = |
|
1226 lthy |
|
1227 |> Local_Theory.open_target |> snd |
|
1228 |> @{fold_map 3} (fn i => fn T => fn AT => |
|
1229 Local_Theory.define ((rec_bind i, NoSyn), (rec_def_bind i, rec_spec i T AT))) ks Ts activeAs |
|
1230 |>> apsnd split_list o split_list |
|
1231 ||> `Local_Theory.close_target; |
|
1232 |
|
1233 val phi = Proof_Context.export_morphism lthy_old lthy; |
|
1234 val recs = map (Morphism.term phi) rec_frees; |
|
1235 val rec_names = map (fst o dest_Const) recs; |
|
1236 fun mk_recs Ts passives actives = |
|
1237 let val Tactives = map2 (curry HOLogic.mk_prodT) Ts actives; |
|
1238 in |
|
1239 @{map 3} (fn name => fn T => fn active => |
|
1240 Const (name, Library.foldr (op -->) |
|
1241 (map2 (curry op -->) (mk_FTs (passives @ Tactives)) actives, T --> active))) |
|
1242 rec_names Ts actives |
|
1243 end; |
|
1244 fun mk_rec ss i = Term.list_comb (Const (nth rec_names (i - 1), Library.foldr (op -->) |
|
1245 (map fastype_of ss, nth Ts (i - 1) --> range_type (fastype_of (nth ss (i - 1))))), ss); |
|
1246 val rec_defs = map (fn def => |
|
1247 mk_unabs_def n (Morphism.thm phi def RS meta_eq_to_obj_eq)) rec_def_frees; |
|
1248 |
|
1249 val (((((((((Izs, (Izs1, Izs1'))), (Izs2, Izs2')), xFs), yFs), fs), rec_ss), init_phis), _) = |
1205 val (((((((((Izs, (Izs1, Izs1'))), (Izs2, Izs2')), xFs), yFs), fs), rec_ss), init_phis), _) = |
1250 lthy |
1206 lthy |
1251 |> mk_Frees "z" Ts |
1207 |> mk_Frees "z" Ts |
1252 ||>> mk_Frees' "z1" Ts |
1208 ||>> mk_Frees' "z1" Ts |
1253 ||>> mk_Frees' "z2" Ts' |
1209 ||>> mk_Frees' "z2" Ts' |
1257 ||>> mk_Frees "s" rec_sTs |
1213 ||>> mk_Frees "s" rec_sTs |
1258 ||>> mk_Frees "P" (replicate n (mk_pred1T initT)); |
1214 ||>> mk_Frees "P" (replicate n (mk_pred1T initT)); |
1259 |
1215 |
1260 val phis = map2 retype_const_or_free (map mk_pred1T Ts) init_phis; |
1216 val phis = map2 retype_const_or_free (map mk_pred1T Ts) init_phis; |
1261 val phi2s = map2 retype_const_or_free (map2 mk_pred2T Ts Ts') init_phis; |
1217 val phi2s = map2 retype_const_or_free (map2 mk_pred2T Ts Ts') init_phis; |
1262 |
|
1263 val convols = map2 (fn T => fn i => mk_convol (HOLogic.id_const T, mk_rec rec_ss i)) Ts ks; |
|
1264 val ctor_rec_thms = |
|
1265 let |
|
1266 fun mk_goal i rec_s rec_map ctor x = |
|
1267 let |
|
1268 val lhs = mk_rec rec_ss i $ (ctor $ x); |
|
1269 val rhs = rec_s $ (Term.list_comb (rec_map, passive_ids @ convols) $ x); |
|
1270 in |
|
1271 mk_Trueprop_eq (lhs, rhs) |
|
1272 end; |
|
1273 val goals = @{map 5} mk_goal ks rec_ss rec_maps_rev ctors xFs; |
|
1274 in |
|
1275 map2 (fn goal => fn foldx => |
|
1276 Variable.add_free_names lthy goal [] |
|
1277 |> (fn vars => Goal.prove_sorry lthy vars [] goal |
|
1278 (fn {context = ctxt, prems = _} => mk_rec_tac ctxt rec_defs foldx fst_rec_pair_thms)) |
|
1279 |> Thm.close_derivation) |
|
1280 goals ctor_fold_thms |
|
1281 end; |
|
1282 |
|
1283 val rec_unique_mor_thm = |
|
1284 let |
|
1285 val id_fs = map2 (fn T => fn f => mk_convol (HOLogic.id_const T, f)) Ts fs; |
|
1286 val prem = HOLogic.mk_Trueprop (mk_mor UNIVs ctors rec_UNIVs (mk_rec_strs rec_ss) id_fs); |
|
1287 fun mk_fun_eq f i = HOLogic.mk_eq (f, mk_rec rec_ss i); |
|
1288 val unique = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj (map2 mk_fun_eq fs ks)); |
|
1289 val vars = fold (Variable.add_free_names lthy) [prem, unique] []; |
|
1290 in |
|
1291 Goal.prove_sorry lthy vars [] (Logic.mk_implies (prem, unique)) |
|
1292 (fn {context = ctxt, prems = _} => mk_rec_unique_mor_tac ctxt rec_defs fst_rec_pair_thms |
|
1293 fold_unique_mor_thm) |
|
1294 |> Thm.close_derivation |
|
1295 end; |
|
1296 |
|
1297 val (ctor_rec_unique_thms, ctor_rec_unique_thm) = |
|
1298 `split_conj_thm (split_conj_prems n |
|
1299 (mor_UNIV_thm RS iffD2 RS rec_unique_mor_thm) |
|
1300 |> unfold_thms lthy (@{thms convol_o comp_id id_comp comp_assoc fst_convol} @ |
|
1301 map_id0s @ sym_map_comps) OF replicate n @{thm arg_cong2[of _ _ _ _ convol, OF refl]}); |
|
1302 |
|
1303 val timer = time (timer "rec definitions & thms"); |
|
1304 |
1218 |
1305 val (ctor_induct_thm, induct_params) = |
1219 val (ctor_induct_thm, induct_params) = |
1306 let |
1220 let |
1307 fun mk_prem phi ctor sets x = |
1221 fun mk_prem phi ctor sets x = |
1308 let |
1222 let |
1907 ||>> mk_Frees "S" activephiTs |
1821 ||>> mk_Frees "S" activephiTs |
1908 ||>> mk_Frees "IR" activeIphiTs; |
1822 ||>> mk_Frees "IR" activeIphiTs; |
1909 |
1823 |
1910 val ctor_fold_o_Imap_thms = mk_xtor_co_iter_o_map_thms Least_FP false m ctor_fold_unique_thm |
1824 val ctor_fold_o_Imap_thms = mk_xtor_co_iter_o_map_thms Least_FP false m ctor_fold_unique_thm |
1911 ctor_Imap_o_thms (map (mk_pointfree lthy) ctor_fold_thms) sym_map_comps map_cong0s; |
1825 ctor_Imap_o_thms (map (mk_pointfree lthy) ctor_fold_thms) sym_map_comps map_cong0s; |
1912 val ctor_rec_o_Imap_thms = mk_xtor_co_iter_o_map_thms Least_FP true m ctor_rec_unique_thm |
|
1913 ctor_Imap_o_thms (map (mk_pointfree lthy) ctor_rec_thms) sym_map_comps map_cong0s; |
|
1914 |
1826 |
1915 val Irels = if m = 0 then map HOLogic.eq_const Ts |
1827 val Irels = if m = 0 then map HOLogic.eq_const Ts |
1916 else map (mk_rel_of_bnf deads passiveAs passiveBs) Ibnfs; |
1828 else map (mk_rel_of_bnf deads passiveAs passiveBs) Ibnfs; |
1917 val Irel_induct_thm = |
1829 val Irel_induct_thm = |
1918 mk_xtor_rel_co_induct_thm Least_FP rels activeIphis Irels Iphis xFs yFs ctors ctor's |
1830 mk_xtor_rel_co_induct_thm Least_FP rels activeIphis Irels Iphis xFs yFs ctors ctor's |
1925 (mk_folds passiveAs activeAs) (mk_folds passiveBs activeBs) |
1837 (mk_folds passiveAs activeAs) (mk_folds passiveBs activeBs) |
1926 (fn {context = ctxt, prems = _} => mk_fold_transfer_tac ctxt m Irel_induct_thm |
1838 (fn {context = ctxt, prems = _} => mk_fold_transfer_tac ctxt m Irel_induct_thm |
1927 (map map_transfer_of_bnf bnfs) ctor_fold_thms) |
1839 (map map_transfer_of_bnf bnfs) ctor_fold_thms) |
1928 lthy; |
1840 lthy; |
1929 |
1841 |
1930 val rec_allAs = passiveAs @ map2 (curry HOLogic.mk_prodT) Ts activeAs; |
|
1931 val rec_allBs = passiveBs @ map2 (curry HOLogic.mk_prodT) Ts' activeBs; |
|
1932 val rec_rels = map2 (fn Ds => mk_rel_of_bnf Ds rec_allAs rec_allBs) Dss bnfs; |
|
1933 val rec_activephis = |
|
1934 map2 (fn Irel => mk_rel_prod (Term.list_comb (Irel, Iphis))) Irels activephis; |
|
1935 val ctor_rec_transfer_thms = |
|
1936 mk_xtor_co_iter_transfer_thms Least_FP rec_rels rec_activephis activephis Irels Iphis |
|
1937 (mk_recs Ts passiveAs activeAs) (mk_recs Ts' passiveBs activeBs) |
|
1938 (fn {context = ctxt, prems = _} => mk_ctor_rec_transfer_tac ctxt n m rec_defs |
|
1939 ctor_fold_transfer_thms (map map_transfer_of_bnf bnfs) ctor_Irel_thms) |
|
1940 lthy; |
|
1941 |
|
1942 val timer = time (timer "relator induction"); |
1842 val timer = time (timer "relator induction"); |
|
1843 |
|
1844 fun mk_Ts As = map (typ_subst_atomic (passiveAs ~~ As)) Ts; |
|
1845 val export = map (Morphism.term (Local_Theory.target_morphism lthy)) |
|
1846 val ((recs, (ctor_rec_thms, ctor_rec_unique_thm, ctor_rec_o_Imap_thms, ctor_rec_transfer_thms)), |
|
1847 lthy) = lthy |
|
1848 |> derive_xtor_co_recs Least_FP external_bs mk_Ts (Dss, resDs) bnfs |
|
1849 (export ctors) (export folds) |
|
1850 ctor_fold_unique_thm ctor_fold_thms ctor_fold_transfer_thms ctor_Imap_thms ctor_Irel_thms; |
|
1851 |
|
1852 val timer = time (timer "recursor"); |
1943 |
1853 |
1944 val common_notes = |
1854 val common_notes = |
1945 [(ctor_inductN, [ctor_induct_thm]), |
1855 [(ctor_inductN, [ctor_induct_thm]), |
1946 (ctor_induct2N, [ctor_induct2_thm]), |
1856 (ctor_induct2N, [ctor_induct2_thm]), |
1947 (ctor_rel_inductN, [Irel_induct_thm])] |
1857 (ctor_rel_inductN, [Irel_induct_thm])] |
1953 (ctor_exhaustN, ctor_exhaust_thms), |
1863 (ctor_exhaustN, ctor_exhaust_thms), |
1954 (ctor_foldN, ctor_fold_thms), |
1864 (ctor_foldN, ctor_fold_thms), |
1955 (ctor_fold_o_mapN, ctor_fold_o_Imap_thms), |
1865 (ctor_fold_o_mapN, ctor_fold_o_Imap_thms), |
1956 (ctor_fold_transferN, ctor_fold_transfer_thms), |
1866 (ctor_fold_transferN, ctor_fold_transfer_thms), |
1957 (ctor_fold_uniqueN, ctor_fold_unique_thms), |
1867 (ctor_fold_uniqueN, ctor_fold_unique_thms), |
1958 (ctor_rec_o_mapN, ctor_rec_o_Imap_thms), |
|
1959 (ctor_rec_transferN, ctor_rec_transfer_thms), |
|
1960 (ctor_rec_uniqueN, ctor_rec_unique_thms), |
|
1961 (ctor_injectN, ctor_inject_thms), |
1868 (ctor_injectN, ctor_inject_thms), |
1962 (ctor_recN, ctor_rec_thms), |
|
1963 (dtor_ctorN, dtor_ctor_thms), |
1869 (dtor_ctorN, dtor_ctor_thms), |
1964 (dtor_exhaustN, dtor_exhaust_thms), |
1870 (dtor_exhaustN, dtor_exhaust_thms), |
1965 (dtor_injectN, dtor_inject_thms)] |
1871 (dtor_injectN, dtor_inject_thms)] |
1966 |> map (apsnd (map single)) |
1872 |> map (apsnd (map single)) |
1967 |> maps (fn (thmN, thmss) => |
1873 |> maps (fn (thmN, thmss) => |
1971 |
1877 |
1972 val lthy' = lthy |> internals ? snd o Local_Theory.notes (common_notes @ notes @ Ibnf_notes); |
1878 val lthy' = lthy |> internals ? snd o Local_Theory.notes (common_notes @ notes @ Ibnf_notes); |
1973 |
1879 |
1974 val fp_res = |
1880 val fp_res = |
1975 {Ts = Ts, bnfs = Ibnfs, pre_bnfs = bnfs, absT_infos = absT_infos, |
1881 {Ts = Ts, bnfs = Ibnfs, pre_bnfs = bnfs, absT_infos = absT_infos, |
1976 ctors = ctors, dtors = dtors, xtor_un_folds_legacy = folds, xtor_co_recs = recs, |
1882 ctors = ctors, dtors = dtors, xtor_un_folds_legacy = folds, xtor_co_recs = export recs, |
1977 xtor_co_induct = ctor_induct_thm, dtor_ctors = dtor_ctor_thms, |
1883 xtor_co_induct = ctor_induct_thm, dtor_ctors = dtor_ctor_thms, |
1978 ctor_dtors = ctor_dtor_thms, ctor_injects = ctor_inject_thms, |
1884 ctor_dtors = ctor_dtor_thms, ctor_injects = ctor_inject_thms, |
1979 dtor_injects = dtor_inject_thms, xtor_maps = ctor_Imap_thms, |
1885 dtor_injects = dtor_inject_thms, xtor_maps = ctor_Imap_thms, |
1980 xtor_map_unique = ctor_Imap_unique_thm, xtor_setss = ctor_Iset_thmss', |
1886 xtor_map_unique = ctor_Imap_unique_thm, xtor_setss = ctor_Iset_thmss', |
1981 xtor_rels = ctor_Irel_thms, xtor_un_fold_thms_legacy = ctor_fold_thms, |
1887 xtor_rels = ctor_Irel_thms, xtor_un_fold_thms_legacy = ctor_fold_thms, |