src/HOL/Tools/BNF/bnf_lfp.ML
changeset 62905 52c5a25e0c96
parent 62863 e0b894bba6ff
child 62907 9ad0bac25a84
equal deleted inserted replaced
62904:94535e6dd168 62905:52c5a25e0c96
  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,