src/HOL/Tools/BNF/bnf_fp_def_sugar.ML
changeset 63841 813a574da746
parent 63840 eb6d2aace13a
child 63842 f738df816abf
equal deleted inserted replaced
63840:eb6d2aace13a 63841:813a574da746
   828             |> fp = Greatest_FP ? curry (op $) ctor
   828             |> fp = Greatest_FP ? curry (op $) ctor
   829             |> Thm.cterm_of lthy
   829             |> Thm.cterm_of lthy
   830           end;
   830           end;
   831 
   831 
   832         val cxIns = map2 (mk_cIn ctor) ks xss;
   832         val cxIns = map2 (mk_cIn ctor) ks xss;
   833         val cyIns = map2 (mk_cIn (B_ify ctor)) ks yss;
       
   834 
   833 
   835         fun mk_set0_thm fp_set_thm ctr_def' cxIn =
   834         fun mk_set0_thm fp_set_thm ctr_def' cxIn =
   836           Local_Defs.fold lthy [ctr_def']
   835           Local_Defs.fold lthy [ctr_def']
   837             (unfold_thms lthy (pre_set_defs @ fp_nesting_set_maps @ live_nesting_set_maps @
   836             (unfold_thms lthy (pre_set_defs @ fp_nesting_set_maps @ live_nesting_set_maps @
   838                  (if fp = Least_FP then [] else [dtor_ctor]) @ basic_sumprod_thms_set @
   837                  (if fp = Least_FP then [] else [dtor_ctor]) @ basic_sumprod_thms_set @
   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