875 mk_map_tac ctxt abs_inverses pre_map_def dtor_ctor fp_map_thm' ctr_defs') |
874 mk_map_tac ctxt abs_inverses pre_map_def dtor_ctor fp_map_thm' ctr_defs') |
876 |> Thm.close_derivation |
875 |> Thm.close_derivation |
877 |> Conjunction.elim_balanced (length goals) |
876 |> Conjunction.elim_balanced (length goals) |
878 end; |
877 end; |
879 |
878 |
880 fun mk_rel_thm postproc ctr_defs' cxIn cyIn = |
879 val rel_inject_thms = |
881 Local_Defs.fold lthy ctr_defs' |
880 let |
882 (unfold_thms lthy (pre_rel_def :: abs_inverses @ |
881 fun mk_goal ctrA ctrB xs ys = |
883 (if fp = Least_FP then [] else [dtor_ctor]) @ sumprod_thms_rel @ |
882 let |
884 @{thms vimage2p_def sum.inject sum.distinct(1)[THEN eq_False[THEN iffD2]]}) |
883 val rel = mk_rel live As Bs (rel_of_bnf fp_bnf); |
885 (infer_instantiate' lthy (map (SOME o Thm.cterm_of lthy) Rs @ [SOME cxIn, SOME cyIn]) |
884 val Rrel = list_comb (rel, Rs); |
886 fp_rel_thm)) |
885 |
887 |> postproc |
886 val lhs = Rrel $ list_comb (ctrA, xs) $ list_comb (ctrB, ys); |
888 |> singleton (Proof_Context.export names_lthy lthy); |
887 val conjuncts = map2 (build_rel_app lthy Rs []) xs ys; |
889 |
888 in |
890 fun mk_rel_inject_thm ((ctr_def', cxIn), (_, cyIn)) = |
889 HOLogic.mk_Trueprop |
891 mk_rel_thm (unfold_thms lthy @{thms eq_sym_Unity_conv}) [ctr_def'] cxIn cyIn; |
890 (if null conjuncts then lhs |
892 |
891 else HOLogic.mk_eq (lhs, Library.foldr1 HOLogic.mk_conj conjuncts)) |
893 fun mk_half_rel_distinct_thm ((xctr_def', cxIn), (yctr_def', cyIn)) = |
892 end; |
894 mk_rel_thm (fn thm => thm RS @{thm eq_False[THEN iffD1]}) [xctr_def', yctr_def'] |
893 |
895 cxIn cyIn; |
894 val goals = @{map 4} mk_goal ctrAs ctrBs xss yss; |
896 |
895 val goal = Logic.mk_conjunction_balanced goals; |
897 fun mk_rel_intro_thm m thm = |
896 val vars = Variable.add_free_names lthy goal []; |
898 uncurry_thm m (thm RS iffD2) handle THM _ => thm; |
897 in |
|
898 Goal.prove_sorry lthy vars [] goal (fn {context = ctxt, prems = _} => |
|
899 mk_rel_tac ctxt abs_inverses pre_rel_def dtor_ctor fp_rel_thm ctr_defs') |
|
900 |> Thm.close_derivation |
|
901 |> Conjunction.elim_balanced (length goals) |
|
902 end; |
|
903 |
|
904 val half_rel_distinct_thmss = |
|
905 let |
|
906 fun mk_goal ((ctrA, xs), (ctrB, ys)) = |
|
907 let |
|
908 val rel = mk_rel live As Bs (rel_of_bnf fp_bnf); |
|
909 val Rrel = list_comb (rel, Rs); |
|
910 in |
|
911 HOLogic.mk_Trueprop (HOLogic.mk_not |
|
912 (Rrel $ list_comb (ctrA, xs) $ list_comb (ctrB, ys))) |
|
913 end; |
|
914 |
|
915 val rel_infos = (ctrAs ~~ xss, ctrBs ~~ yss); |
|
916 |
|
917 val goalss = map (map mk_goal) (mk_half_pairss rel_infos); |
|
918 val goals = flat goalss; |
|
919 in |
|
920 unflat goalss |
|
921 (if null goals then [] |
|
922 else |
|
923 let |
|
924 val goal = Logic.mk_conjunction_balanced goals; |
|
925 val vars = Variable.add_free_names lthy goal []; |
|
926 in |
|
927 Goal.prove_sorry lthy vars [] goal (fn {context = ctxt, prems = _} => |
|
928 mk_rel_tac ctxt abs_inverses pre_rel_def dtor_ctor fp_rel_thm ctr_defs') |
|
929 |> Thm.close_derivation |
|
930 |> Conjunction.elim_balanced (length goals) |
|
931 end) |
|
932 end; |
899 |
933 |
900 val rel_flip = rel_flip_of_bnf fp_bnf; |
934 val rel_flip = rel_flip_of_bnf fp_bnf; |
901 |
935 |
902 fun mk_other_half_rel_distinct_thm thm = |
936 fun mk_other_half_rel_distinct_thm thm = |
903 flip_rels lthy live thm RS (rel_flip RS sym RS @{thm arg_cong[of _ _ Not]} RS iffD2); |
937 flip_rels lthy live thm RS (rel_flip RS sym RS @{thm arg_cong[of _ _ Not]} RS iffD2); |
904 |
938 |
905 val rel_infos = (ctr_defs' ~~ cxIns, ctr_defs' ~~ cyIns); |
|
906 |
|
907 val rel_inject_thms = map mk_rel_inject_thm (op ~~ rel_infos); |
|
908 val rel_intro_thms = map2 mk_rel_intro_thm ms rel_inject_thms; |
|
909 |
|
910 val half_rel_distinct_thmss = map (map mk_half_rel_distinct_thm) (mk_half_pairss rel_infos); |
|
911 val other_half_rel_distinct_thmss = |
939 val other_half_rel_distinct_thmss = |
912 map (map mk_other_half_rel_distinct_thm) half_rel_distinct_thmss; |
940 map (map mk_other_half_rel_distinct_thm) half_rel_distinct_thmss; |
913 val (rel_distinct_thms, _) = |
941 val (rel_distinct_thms, _) = |
914 join_halves n half_rel_distinct_thmss other_half_rel_distinct_thmss; |
942 join_halves n half_rel_distinct_thmss other_half_rel_distinct_thmss; |
|
943 |
|
944 fun mk_rel_intro_thm m thm = |
|
945 uncurry_thm m (thm RS iffD2) handle THM _ => thm; |
|
946 |
|
947 val rel_intro_thms = map2 mk_rel_intro_thm ms rel_inject_thms; |
915 |
948 |
916 val rel_code_thms = |
949 val rel_code_thms = |
917 map (fn thm => thm RS @{thm eq_False[THEN iffD2]}) rel_distinct_thms @ |
950 map (fn thm => thm RS @{thm eq_False[THEN iffD2]}) rel_distinct_thms @ |
918 map2 (fn thm => fn 0 => thm RS @{thm eq_True[THEN iffD2]} | _ => thm) rel_inject_thms ms; |
951 map2 (fn thm => fn 0 => thm RS @{thm eq_True[THEN iffD2]} | _ => thm) rel_inject_thms ms; |
919 |
952 |