2017 val ctor_dtor_corec_thms = |
2017 val ctor_dtor_corec_thms = |
2018 map3 mk_ctor_dtor_unfold_like_thm dtor_inject_thms dtor_ctor_thms dtor_corec_thms; |
2018 map3 mk_ctor_dtor_unfold_like_thm dtor_inject_thms dtor_ctor_thms dtor_corec_thms; |
2019 |
2019 |
2020 val timer = time (timer "corec definitions & thms"); |
2020 val timer = time (timer "corec definitions & thms"); |
2021 |
2021 |
2022 (* TODO: Get rid of strong versions (since these can easily be derived from the weak ones). *) |
2022 val (dtor_map_coinduct_thm, coinduct_params, dtor_coinduct_thm) = |
2023 val (dtor_map_coinduct_thm, coinduct_params, dtor_coinduct_thm, dtor_strong_coinduct_thm) = |
|
2024 let |
2023 let |
2025 val zs = Jzs1 @ Jzs2; |
2024 val zs = Jzs1 @ Jzs2; |
2026 val frees = phis @ zs; |
2025 val frees = phis @ zs; |
2027 |
|
2028 fun mk_phi strong_eq phi z1 z2 = if strong_eq |
|
2029 then Term.absfree (dest_Free z1) (Term.absfree (dest_Free z2) |
|
2030 (HOLogic.mk_disj (phi $ z1 $ z2, HOLogic.mk_eq (z1, z2)))) |
|
2031 else phi; |
|
2032 |
|
2033 fun phi_rels strong_eq = |
|
2034 map3 (fn phi => fn z1 => fn z2 => mk_phi strong_eq phi z1 z2) phis Jzs1 Jzs2; |
|
2035 |
2026 |
2036 val rels = map (Term.subst_atomic_types ((activeAs ~~ Ts) @ (activeBs ~~ Ts))) relsAsBs; |
2027 val rels = map (Term.subst_atomic_types ((activeAs ~~ Ts) @ (activeBs ~~ Ts))) relsAsBs; |
2037 |
2028 |
2038 fun mk_concl phi z1 z2 = HOLogic.mk_imp (phi $ z1 $ z2, HOLogic.mk_eq (z1, z2)); |
2029 fun mk_concl phi z1 z2 = HOLogic.mk_imp (phi $ z1 $ z2, HOLogic.mk_eq (z1, z2)); |
2039 val concl = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj |
2030 val concl = HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj |
2040 (map3 mk_concl phis Jzs1 Jzs2)); |
2031 (map3 mk_concl phis Jzs1 Jzs2)); |
2041 |
2032 |
2042 fun mk_rel_prem strong_eq phi dtor rel Jz Jz_copy = |
2033 fun mk_rel_prem phi dtor rel Jz Jz_copy = |
2043 let |
2034 let |
2044 val concl = Term.list_comb (rel, map HOLogic.eq_const passiveAs @ phi_rels strong_eq) $ |
2035 val concl = Term.list_comb (rel, map HOLogic.eq_const passiveAs @ phis) $ |
2045 (dtor $ Jz) $ (dtor $ Jz_copy); |
2036 (dtor $ Jz) $ (dtor $ Jz_copy); |
2046 in |
2037 in |
2047 HOLogic.mk_Trueprop |
2038 HOLogic.mk_Trueprop |
2048 (list_all_free [Jz, Jz_copy] (HOLogic.mk_imp (phi $ Jz $ Jz_copy, concl))) |
2039 (list_all_free [Jz, Jz_copy] (HOLogic.mk_imp (phi $ Jz $ Jz_copy, concl))) |
2049 end; |
2040 end; |
2050 |
2041 |
2051 val rel_prems = map5 (mk_rel_prem false) phis dtors rels Jzs Jzs_copy; |
2042 val rel_prems = map5 mk_rel_prem phis dtors rels Jzs Jzs_copy; |
2052 val rel_strong_prems = map5 (mk_rel_prem true) phis dtors rels Jzs Jzs_copy; |
|
2053 |
|
2054 val dtor_coinduct_goal = |
2043 val dtor_coinduct_goal = |
2055 fold_rev Logic.all frees (Logic.list_implies (rel_prems, concl)); |
2044 fold_rev Logic.all frees (Logic.list_implies (rel_prems, concl)); |
2056 val coinduct_params = rev (Term.add_tfrees dtor_coinduct_goal []); |
|
2057 |
2045 |
2058 val dtor_coinduct = |
2046 val dtor_coinduct = |
2059 Goal.prove_sorry lthy [] [] dtor_coinduct_goal |
2047 Goal.prove_sorry lthy [] [] dtor_coinduct_goal |
2060 (K (mk_dtor_coinduct_tac m raw_coind_thm bis_rel_thm rel_congs)) |
2048 (K (mk_dtor_coinduct_tac m raw_coind_thm bis_rel_thm rel_congs)) |
2061 |> Thm.close_derivation; |
2049 |> Thm.close_derivation; |
2062 |
2050 |
2063 fun mk_prem strong_eq phi dtor map_nth sets Jz Jz_copy FJz = |
2051 fun mk_prem phi dtor map_nth sets Jz Jz_copy FJz = |
2064 let |
2052 let |
2065 val xs = [Jz, Jz_copy]; |
2053 val xs = [Jz, Jz_copy]; |
2066 |
2054 |
2067 fun mk_map_conjunct nths x = |
2055 fun mk_map_conjunct nths x = |
2068 HOLogic.mk_eq (Term.list_comb (map_nth, passive_ids @ nths) $ FJz, dtor $ x); |
2056 HOLogic.mk_eq (Term.list_comb (map_nth, passive_ids @ nths) $ FJz, dtor $ x); |
2069 |
2057 |
2070 fun mk_set_conjunct set phi z1 z2 = |
2058 fun mk_set_conjunct set phi z1 z2 = |
2071 list_all_free [z1, z2] |
2059 list_all_free [z1, z2] |
2072 (HOLogic.mk_imp (HOLogic.mk_mem (HOLogic.mk_prod (z1, z2), set $ FJz), |
2060 (HOLogic.mk_imp (HOLogic.mk_mem (HOLogic.mk_prod (z1, z2), set $ FJz), |
2073 mk_phi strong_eq phi z1 z2 $ z1 $ z2)); |
2061 phi $ z1 $ z2)); |
2074 |
2062 |
2075 val concl = list_exists_free [FJz] (HOLogic.mk_conj |
2063 val concl = list_exists_free [FJz] (HOLogic.mk_conj |
2076 (Library.foldr1 HOLogic.mk_conj (map2 mk_map_conjunct [fstsTs, sndsTs] xs), |
2064 (Library.foldr1 HOLogic.mk_conj (map2 mk_map_conjunct [fstsTs, sndsTs] xs), |
2077 Library.foldr1 HOLogic.mk_conj |
2065 Library.foldr1 HOLogic.mk_conj |
2078 (map4 mk_set_conjunct (drop m sets) phis Jzs1 Jzs2))); |
2066 (map4 mk_set_conjunct (drop m sets) phis Jzs1 Jzs2))); |
2079 in |
2067 in |
2080 fold_rev Logic.all xs (Logic.mk_implies |
2068 fold_rev Logic.all xs (Logic.mk_implies |
2081 (HOLogic.mk_Trueprop (Term.list_comb (phi, xs)), HOLogic.mk_Trueprop concl)) |
2069 (HOLogic.mk_Trueprop (Term.list_comb (phi, xs)), HOLogic.mk_Trueprop concl)) |
2082 end; |
2070 end; |
2083 |
2071 |
2084 fun mk_prems strong_eq = |
2072 val prems = map7 mk_prem phis dtors map_FT_nths prodFT_setss Jzs Jzs_copy FJzs; |
2085 map7 (mk_prem strong_eq) phis dtors map_FT_nths prodFT_setss Jzs Jzs_copy FJzs; |
|
2086 |
|
2087 val prems = mk_prems false; |
|
2088 val strong_prems = mk_prems true; |
|
2089 |
2073 |
2090 val dtor_map_coinduct_goal = fold_rev Logic.all frees (Logic.list_implies (prems, concl)); |
2074 val dtor_map_coinduct_goal = fold_rev Logic.all frees (Logic.list_implies (prems, concl)); |
2091 val dtor_map_coinduct = |
2075 val dtor_map_coinduct = |
2092 Goal.prove_sorry lthy [] [] dtor_map_coinduct_goal |
2076 Goal.prove_sorry lthy [] [] dtor_map_coinduct_goal |
2093 (K (mk_dtor_map_coinduct_tac m ks raw_coind_thm bis_def)) |
2077 (K (mk_dtor_map_coinduct_tac m ks raw_coind_thm bis_def)) |
2094 |> Thm.close_derivation; |
2078 |> Thm.close_derivation; |
2095 |
2079 in |
2096 val cTs = map (SOME o certifyT lthy o TFree) coinduct_params; |
2080 (dtor_map_coinduct, rev (Term.add_tfrees dtor_map_coinduct_goal []), dtor_coinduct) |
2097 val cts = map3 (SOME o certify lthy ooo mk_phi true) phis Jzs1 Jzs2; |
2081 end; |
2098 |
2082 |
2099 val dtor_strong_coinduct = singleton (Proof_Context.export names_lthy lthy) |
2083 (* TODO: Get rid of strong versions (since these can easily be derived from the weak ones). *) |
2100 (Goal.prove_sorry lthy [] [] |
2084 val dtor_strong_coinduct_thm = |
2101 (fold_rev Logic.all zs (Logic.list_implies (rel_strong_prems, concl))) |
2085 mk_strong_coinduct_thm m dtor_coinduct_thm rel_eqs rel_monos lthy; |
2102 (K (mk_dtor_strong_coinduct_tac lthy m cTs cts dtor_coinduct rel_monos rel_eqs))) |
|
2103 |> Thm.close_derivation; |
|
2104 in |
|
2105 (dtor_map_coinduct, rev (Term.add_tfrees dtor_map_coinduct_goal []), |
|
2106 dtor_coinduct, dtor_strong_coinduct) |
|
2107 end; |
|
2108 |
2086 |
2109 val timer = time (timer "coinduction"); |
2087 val timer = time (timer "coinduction"); |
2110 |
2088 |
2111 fun mk_dtor_map_DEADID_thm dtor_inject map_id = |
2089 fun mk_dtor_map_DEADID_thm dtor_inject map_id = |
2112 trans OF [iffD2 OF [dtor_inject, id_apply], map_id RS sym]; |
2090 trans OF [iffD2 OF [dtor_inject, id_apply], map_id RS sym]; |