src/HOL/Codatatype/Tools/bnf_comp.ML
changeset 49303 c87930fb5b90
parent 49236 632f68beff2a
child 49304 6964373dd6ac
equal deleted inserted replaced
49302:f5bd87aac224 49303:c87930fb5b90
   123     val inner_setss = map3 mk_sets_of_bnf (map (replicate ilive) Dss) (replicate olive Ass) inners;
   123     val inner_setss = map3 mk_sets_of_bnf (map (replicate ilive) Dss) (replicate olive Ass) inners;
   124     val inner_bds = map3 mk_bd_of_bnf Dss Ass_repl inners;
   124     val inner_bds = map3 mk_bd_of_bnf Dss Ass_repl inners;
   125     val outer_bd = mk_bd_of_bnf oDs CAs outer;
   125     val outer_bd = mk_bd_of_bnf oDs CAs outer;
   126 
   126 
   127     (*%f1 ... fn. outer.map (inner_1.map f1 ... fn) ... (inner_m.map f1 ... fn)*)
   127     (*%f1 ... fn. outer.map (inner_1.map f1 ... fn) ... (inner_m.map f1 ... fn)*)
   128     val comp_map = fold_rev Term.abs fs'
   128     val mapx = fold_rev Term.abs fs'
   129       (Term.list_comb (mk_map_of_bnf oDs CAs CBs outer,
   129       (Term.list_comb (mk_map_of_bnf oDs CAs CBs outer,
   130         map2 (fn Ds => (fn f => Term.list_comb (f, map Bound ((ilive - 1) downto 0))) o
   130         map2 (fn Ds => (fn f => Term.list_comb (f, map Bound ((ilive - 1) downto 0))) o
   131           mk_map_of_bnf Ds As Bs) Dss inners));
   131           mk_map_of_bnf Ds As Bs) Dss inners));
   132 
   132 
   133     (*Union o collect {outer.set_1 ... outer.set_m} o outer.map inner_1.set_i ... inner_m.set_i*)
   133     (*Union o collect {outer.set_1 ... outer.set_m} o outer.map inner_1.set_i ... inner_m.set_i*)
   134     (*Union o collect {image inner_1.set_i o outer.set_1 ... image inner_m.set_i o outer.set_m}*)
   134     (*Union o collect {image inner_1.set_i o outer.set_1 ... image inner_m.set_i o outer.set_m}*)
   135     fun mk_comp_set i =
   135     fun mk_set i =
   136       let
   136       let
   137         val (setTs, T) = `(replicate olive o HOLogic.mk_setT) (nth As i);
   137         val (setTs, T) = `(replicate olive o HOLogic.mk_setT) (nth As i);
   138         val outer_set = mk_collect
   138         val outer_set = mk_collect
   139           (mk_sets_of_bnf (replicate olive oDs) (replicate olive setTs) outer)
   139           (mk_sets_of_bnf (replicate olive oDs) (replicate olive setTs) outer)
   140           (mk_T_of_bnf oDs setTs outer --> HOLogic.mk_setT T);
   140           (mk_T_of_bnf oDs setTs outer --> HOLogic.mk_setT T);
   147       in
   147       in
   148         (Library.foldl1 HOLogic.mk_comp [mk_Union T, outer_set, map_inner_sets],
   148         (Library.foldl1 HOLogic.mk_comp [mk_Union T, outer_set, map_inner_sets],
   149         HOLogic.mk_comp (mk_Union T, collect_image))
   149         HOLogic.mk_comp (mk_Union T, collect_image))
   150       end;
   150       end;
   151 
   151 
   152     val (comp_sets, comp_sets_alt) = map_split mk_comp_set (0 upto ilive - 1);
   152     val (sets, sets_alt) = map_split mk_set (0 upto ilive - 1);
   153 
   153 
   154     (*(inner_1.bd +c ... +c inner_m.bd) *c outer.bd*)
   154     (*(inner_1.bd +c ... +c inner_m.bd) *c outer.bd*)
   155     val comp_bd = Term.absdummy CCA (mk_cprod
   155     val bd = Term.absdummy CCA (mk_cprod (Library.foldr1 (uncurry mk_csum) inner_bds) outer_bd);
   156       (Library.foldr1 (uncurry mk_csum) inner_bds) outer_bd);
   156 
   157 
   157     fun map_id_tac {context = ctxt, ...} =
   158     fun comp_map_id_tac {context = ctxt, ...} =
       
   159       let
   158       let
   160         (*order the theorems by reverse size to prevent bad interaction with nonconfluent rewrite
   159         (*order the theorems by reverse size to prevent bad interaction with nonconfluent rewrite
   161           rules*)
   160           rules*)
   162         val thms = (map map_id_of_bnf inners
   161         val thms = (map map_id_of_bnf inners
   163           |> map (`(Term.size_of_term o Thm.prop_of))
   162           |> map (`(Term.size_of_term o Thm.prop_of))
   165           |> map snd) @ [map_id_of_bnf outer];
   164           |> map snd) @ [map_id_of_bnf outer];
   166       in
   165       in
   167         (EVERY' (map (fn thm => subst_tac ctxt [thm]) thms) THEN' rtac refl) 1
   166         (EVERY' (map (fn thm => subst_tac ctxt [thm]) thms) THEN' rtac refl) 1
   168       end;
   167       end;
   169 
   168 
   170     fun comp_map_comp_tac _ =
   169     fun map_comp_tac _ =
   171       mk_comp_map_comp_tac (map_comp_of_bnf outer) (map_cong_of_bnf outer)
   170       mk_comp_map_comp_tac (map_comp_of_bnf outer) (map_cong_of_bnf outer)
   172         (map map_comp_of_bnf inners);
   171         (map map_comp_of_bnf inners);
   173 
   172 
   174     fun mk_single_comp_set_natural_tac i _ =
   173     fun mk_single_set_natural_tac i _ =
   175       mk_comp_set_natural_tac (map_comp_of_bnf outer) (map_cong_of_bnf outer)
   174       mk_comp_set_natural_tac (map_comp_of_bnf outer) (map_cong_of_bnf outer)
   176         (collect_set_natural_of_bnf outer)
   175         (collect_set_natural_of_bnf outer)
   177         (map ((fn thms => nth thms i) o set_natural_of_bnf) inners);
   176         (map ((fn thms => nth thms i) o set_natural_of_bnf) inners);
   178 
   177 
   179     val comp_set_natural_tacs = map mk_single_comp_set_natural_tac (0 upto ilive - 1);
   178     val set_natural_tacs = map mk_single_set_natural_tac (0 upto ilive - 1);
   180 
   179 
   181     fun comp_bd_card_order_tac _ =
   180     fun bd_card_order_tac _ =
   182       mk_comp_bd_card_order_tac (map bd_card_order_of_bnf inners) (bd_card_order_of_bnf outer);
   181       mk_comp_bd_card_order_tac (map bd_card_order_of_bnf inners) (bd_card_order_of_bnf outer);
   183 
   182 
   184     fun comp_bd_cinfinite_tac _ =
   183     fun bd_cinfinite_tac _ =
   185       mk_comp_bd_cinfinite_tac (bd_cinfinite_of_bnf inner) (bd_cinfinite_of_bnf outer);
   184       mk_comp_bd_cinfinite_tac (bd_cinfinite_of_bnf inner) (bd_cinfinite_of_bnf outer);
   186 
   185 
   187     val comp_set_alt_thms =
   186     val set_alt_thms =
   188       if ! quick_and_dirty then
   187       if ! quick_and_dirty then
   189         replicate ilive no_thm
   188         replicate ilive no_thm
   190       else
   189       else
   191         map (fn goal =>
   190         map (fn goal =>
   192           Skip_Proof.prove lthy [] [] goal
   191           Skip_Proof.prove lthy [] [] goal
   193             (fn {context, ...} => (mk_comp_set_alt_tac context (collect_set_natural_of_bnf outer)))
   192             (fn {context, ...} => (mk_comp_set_alt_tac context (collect_set_natural_of_bnf outer)))
   194           |> Thm.close_derivation)
   193           |> Thm.close_derivation)
   195         (map2 (curry (HOLogic.mk_Trueprop o HOLogic.mk_eq)) comp_sets comp_sets_alt);
   194         (map2 (curry (HOLogic.mk_Trueprop o HOLogic.mk_eq)) sets sets_alt);
   196 
   195 
   197     fun comp_map_cong_tac _ =
   196     fun map_cong_tac _ =
   198       mk_comp_map_cong_tac comp_set_alt_thms (map_cong_of_bnf outer) (map map_cong_of_bnf inners);
   197       mk_comp_map_cong_tac set_alt_thms (map_cong_of_bnf outer) (map map_cong_of_bnf inners);
   199 
   198 
   200     val comp_set_bd_tacs =
   199     val set_bd_tacs =
   201       if ! quick_and_dirty then
   200       if ! quick_and_dirty then
   202         replicate (length comp_set_alt_thms) (K all_tac)
   201         replicate (length set_alt_thms) (K all_tac)
   203       else
   202       else
   204         let
   203         let
   205           val outer_set_bds = set_bd_of_bnf outer;
   204           val outer_set_bds = set_bd_of_bnf outer;
   206           val inner_set_bdss = map set_bd_of_bnf inners;
   205           val inner_set_bdss = map set_bd_of_bnf inners;
   207           val inner_bd_Card_orders = map bd_Card_order_of_bnf inners;
   206           val inner_bd_Card_orders = map bd_Card_order_of_bnf inners;
   208           fun comp_single_set_bd_thm i j =
   207           fun single_set_bd_thm i j =
   209             @{thm comp_single_set_bd} OF [nth inner_bd_Card_orders j, nth (nth inner_set_bdss j) i,
   208             @{thm comp_single_set_bd} OF [nth inner_bd_Card_orders j, nth (nth inner_set_bdss j) i,
   210               nth outer_set_bds j]
   209               nth outer_set_bds j]
   211           val single_set_bd_thmss =
   210           val single_set_bd_thmss =
   212             map ((fn f => map f (0 upto olive - 1)) o comp_single_set_bd_thm) (0 upto ilive - 1);
   211             map ((fn f => map f (0 upto olive - 1)) o single_set_bd_thm) (0 upto ilive - 1);
   213         in
   212         in
   214           map2 (fn comp_set_alt => fn single_set_bds => fn {context, ...} =>
   213           map2 (fn set_alt => fn single_set_bds => fn {context, ...} =>
   215             mk_comp_set_bd_tac context comp_set_alt single_set_bds)
   214             mk_comp_set_bd_tac context set_alt single_set_bds)
   216           comp_set_alt_thms single_set_bd_thmss
   215           set_alt_thms single_set_bd_thmss
   217         end;
   216         end;
   218 
   217 
   219     val comp_in_alt_thm =
   218     val in_alt_thm =
   220       let
   219       let
   221         val comp_in = mk_in Asets comp_sets CCA;
   220         val inx = mk_in Asets sets CCA;
   222         val comp_in_alt = mk_in (map2 (mk_in Asets) inner_setss CAs) outer_sets CCA;
   221         val in_alt = mk_in (map2 (mk_in Asets) inner_setss CAs) outer_sets CCA;
   223         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (comp_in, comp_in_alt));
   222         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (inx, in_alt));
   224       in
   223       in
   225         Skip_Proof.prove lthy [] [] goal
   224         Skip_Proof.prove lthy [] [] goal
   226           (fn {context, ...} => mk_comp_in_alt_tac context comp_set_alt_thms)
   225           (fn {context, ...} => mk_comp_in_alt_tac context set_alt_thms)
   227         |> Thm.close_derivation
   226         |> Thm.close_derivation
   228       end;
   227       end;
   229 
   228 
   230     fun comp_in_bd_tac _ =
   229     fun in_bd_tac _ =
   231       mk_comp_in_bd_tac comp_in_alt_thm (map in_bd_of_bnf inners) (in_bd_of_bnf outer)
   230       mk_comp_in_bd_tac in_alt_thm (map in_bd_of_bnf inners) (in_bd_of_bnf outer)
   232         (map bd_Cinfinite_of_bnf inners) (bd_Card_order_of_bnf outer);
   231         (map bd_Cinfinite_of_bnf inners) (bd_Card_order_of_bnf outer);
   233 
   232 
   234     fun comp_map_wpull_tac _ =
   233     fun map_wpull_tac _ =
   235       mk_map_wpull_tac comp_in_alt_thm (map map_wpull_of_bnf inners) (map_wpull_of_bnf outer);
   234       mk_map_wpull_tac in_alt_thm (map map_wpull_of_bnf inners) (map_wpull_of_bnf outer);
   236 
   235 
   237     val tacs = [comp_map_id_tac, comp_map_comp_tac, comp_map_cong_tac] @ comp_set_natural_tacs @
   236     val tacs = [map_id_tac, map_comp_tac, map_cong_tac] @ set_natural_tacs @ [bd_card_order_tac,
   238       [comp_bd_card_order_tac, comp_bd_cinfinite_tac] @ comp_set_bd_tacs @
   237       bd_cinfinite_tac] @ set_bd_tacs @ [in_bd_tac, map_wpull_tac];
   239       [comp_in_bd_tac, comp_map_wpull_tac];
       
   240 
   238 
   241     val outer_wits = mk_wits_of_bnf (replicate onwits oDs) (replicate onwits CAs) outer;
   239     val outer_wits = mk_wits_of_bnf (replicate onwits oDs) (replicate onwits CAs) outer;
   242 
   240 
   243     val inner_witss = map (map (fn (I, wit) => Term.list_comb (wit, map (nth xs) I)))
   241     val inner_witss = map (map (fn (I, wit) => Term.list_comb (wit, map (nth xs) I)))
   244       (map3 (fn Ds => fn n => mk_wits_of_bnf (replicate n Ds) (replicate n As))
   242       (map3 (fn Ds => fn n => mk_wits_of_bnf (replicate n Ds) (replicate n As))
   245         Dss inwitss inners);
   243         Dss inwitss inners);
   246 
   244 
   247     val inner_witsss = map (map (nth inner_witss) o fst) outer_wits;
   245     val inner_witsss = map (map (nth inner_witss) o fst) outer_wits;
   248 
   246 
   249     val comp_wits = (inner_witsss, (map (single o snd) outer_wits))
   247     val wits = (inner_witsss, (map (single o snd) outer_wits))
   250       |-> map2 (fold (map_product (fn iwit => fn owit => owit $ iwit)))
   248       |-> map2 (fold (map_product (fn iwit => fn owit => owit $ iwit)))
   251       |> flat
   249       |> flat
   252       |> map (`(fn t => Term.add_frees t []))
   250       |> map (`(fn t => Term.add_frees t []))
   253       |> minimize_wits
   251       |> minimize_wits
   254       |> map (fn (frees, t) => fold absfree frees t);
   252       |> map (fn (frees, t) => fold absfree frees t);
   257       mk_comp_wit_tac ctxt (wit_thms_of_bnf outer) (collect_set_natural_of_bnf outer)
   255       mk_comp_wit_tac ctxt (wit_thms_of_bnf outer) (collect_set_natural_of_bnf outer)
   258         (maps wit_thms_of_bnf inners);
   256         (maps wit_thms_of_bnf inners);
   259 
   257 
   260     val (bnf', lthy') =
   258     val (bnf', lthy') =
   261       bnf_def const_policy (K Derive_Some_Facts) qualify tacs wit_tac (SOME (oDs @ flat Dss))
   259       bnf_def const_policy (K Derive_Some_Facts) qualify tacs wit_tac (SOME (oDs @ flat Dss))
   262         ((((b, comp_map), comp_sets), comp_bd), comp_wits) lthy;
   260         ((((b, mapx), sets), bd), wits) lthy;
   263 
   261 
   264     val outer_rel_Gr = rel_Gr_of_bnf outer RS sym;
   262     val outer_rel_Gr = rel_Gr_of_bnf outer RS sym;
   265     val outer_rel_cong = rel_cong_of_bnf outer;
   263     val outer_rel_cong = rel_cong_of_bnf outer;
   266 
   264 
   267     val comp_rel_unfold_thm =
   265     val rel_unfold_thm =
   268       trans OF [rel_def_of_bnf bnf',
   266       trans OF [rel_def_of_bnf bnf',
   269         trans OF [comp_in_alt_thm RS @{thm subst_rel_def},
   267         trans OF [in_alt_thm RS @{thm subst_rel_def},
   270           trans OF [@{thm arg_cong2[of _ _ _ _ relcomp]} OF
   268           trans OF [@{thm arg_cong2[of _ _ _ _ relcomp]} OF
   271             [trans OF [outer_rel_Gr RS @{thm arg_cong[of _ _ converse]},
   269             [trans OF [outer_rel_Gr RS @{thm arg_cong[of _ _ converse]},
   272               rel_converse_of_bnf outer RS sym], outer_rel_Gr],
   270               rel_converse_of_bnf outer RS sym], outer_rel_Gr],
   273             trans OF [rel_O_of_bnf outer RS sym, outer_rel_cong OF
   271             trans OF [rel_O_of_bnf outer RS sym, outer_rel_cong OF
   274               (map (fn bnf => rel_def_of_bnf bnf RS sym) inners)]]]];
   272               (map (fn bnf => rel_def_of_bnf bnf RS sym) inners)]]]];
   275 
   273 
   276     val comp_pred_unfold_thm = Collect_split_box_equals OF [comp_rel_unfold_thm,
   274     val pred_unfold_thm = Collect_split_box_equals OF [rel_unfold_thm,
   277       pred_def_of_bnf bnf' RS abs_pred_sym,
   275       pred_def_of_bnf bnf' RS abs_pred_sym,
   278         trans OF [outer_rel_cong OF (map (fn bnf => pred_def_of_bnf bnf RS abs_pred_sym) inners),
   276         trans OF [outer_rel_cong OF (map (fn bnf => pred_def_of_bnf bnf RS abs_pred_sym) inners),
   279           pred_def_of_bnf outer RS abs_pred_sym]];
   277           pred_def_of_bnf outer RS abs_pred_sym]];
   280 
   278 
   281     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf')
   279     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf') rel_unfold_thm
   282       comp_rel_unfold_thm comp_pred_unfold_thm unfold;
   280       pred_unfold_thm unfold;
   283   in
   281   in
   284     (bnf', (unfold', lthy'))
   282     (bnf', (unfold', lthy'))
   285   end;
   283   end;
   286 
   284 
   287 (* Killing live variables *)
   285 (* Killing live variables *)
   308     val xs = map (fn T => HOLogic.choice_const T $ absdummy T @{term True}) killedAs @ lives;
   306     val xs = map (fn T => HOLogic.choice_const T $ absdummy T @{term True}) killedAs @ lives;
   309 
   307 
   310     val T = mk_T_of_bnf Ds As bnf;
   308     val T = mk_T_of_bnf Ds As bnf;
   311 
   309 
   312     (*bnf.map id ... id*)
   310     (*bnf.map id ... id*)
   313     val killN_map = Term.list_comb (mk_map_of_bnf Ds As Bs bnf, map HOLogic.id_const killedAs);
   311     val mapx = Term.list_comb (mk_map_of_bnf Ds As Bs bnf, map HOLogic.id_const killedAs);
   314 
   312 
   315     val bnf_sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf;
   313     val bnf_sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf;
   316     val killN_sets = drop n bnf_sets;
   314     val sets = drop n bnf_sets;
   317 
   315 
   318     (*(|UNIV :: A1 set| +c ... +c |UNIV :: An set|) *c bnf.bd*)
   316     (*(|UNIV :: A1 set| +c ... +c |UNIV :: An set|) *c bnf.bd*)
   319     val bnf_bd = mk_bd_of_bnf Ds As bnf;
   317     val bnf_bd = mk_bd_of_bnf Ds As bnf;
   320     val killN_bd = mk_cprod
   318     val bd = mk_cprod
   321       (Library.foldr1 (uncurry mk_csum) (map (mk_card_of o HOLogic.mk_UNIV) killedAs)) bnf_bd;
   319       (Library.foldr1 (uncurry mk_csum) (map (mk_card_of o HOLogic.mk_UNIV) killedAs)) bnf_bd;
   322 
   320 
   323     fun killN_map_id_tac _ = rtac (map_id_of_bnf bnf) 1;
   321     fun map_id_tac _ = rtac (map_id_of_bnf bnf) 1;
   324     fun killN_map_comp_tac {context, ...} =
   322     fun map_comp_tac {context, ...} =
   325       Local_Defs.unfold_tac context ((map_comp_of_bnf bnf RS sym) :: @{thms o_assoc id_o o_id}) THEN
   323       Local_Defs.unfold_tac context ((map_comp_of_bnf bnf RS sym) :: @{thms o_assoc id_o o_id}) THEN
   326       rtac refl 1;
   324       rtac refl 1;
   327     fun killN_map_cong_tac {context, ...} =
   325     fun map_cong_tac {context, ...} =
   328       mk_killN_map_cong_tac context n (live - n) (map_cong_of_bnf bnf);
   326       mk_killN_map_cong_tac context n (live - n) (map_cong_of_bnf bnf);
   329     val killN_set_natural_tacs =
   327     val set_natural_tacs = map (fn thm => fn _ => rtac thm 1) (drop n (set_natural_of_bnf bnf));
   330       map (fn thm => fn _ => rtac thm 1) (drop n (set_natural_of_bnf bnf));
   328     fun bd_card_order_tac _ = mk_killN_bd_card_order_tac n (bd_card_order_of_bnf bnf);
   331     fun killN_bd_card_order_tac _ = mk_killN_bd_card_order_tac n (bd_card_order_of_bnf bnf);
   329     fun bd_cinfinite_tac _ = mk_killN_bd_cinfinite_tac (bd_Cinfinite_of_bnf bnf);
   332     fun killN_bd_cinfinite_tac _ = mk_killN_bd_cinfinite_tac (bd_Cinfinite_of_bnf bnf);
   330     val set_bd_tacs =
   333     val killN_set_bd_tacs =
       
   334       map (fn thm => fn _ => mk_killN_set_bd_tac (bd_Card_order_of_bnf bnf) thm)
   331       map (fn thm => fn _ => mk_killN_set_bd_tac (bd_Card_order_of_bnf bnf) thm)
   335         (drop n (set_bd_of_bnf bnf));
   332         (drop n (set_bd_of_bnf bnf));
   336 
   333 
   337     val killN_in_alt_thm =
   334     val in_alt_thm =
   338       let
   335       let
   339         val killN_in = mk_in Asets killN_sets T;
   336         val inx = mk_in Asets sets T;
   340         val killN_in_alt = mk_in (map HOLogic.mk_UNIV killedAs @ Asets) bnf_sets T;
   337         val in_alt = mk_in (map HOLogic.mk_UNIV killedAs @ Asets) bnf_sets T;
   341         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (killN_in, killN_in_alt));
   338         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (inx, in_alt));
   342       in
   339       in
   343         Skip_Proof.prove lthy [] [] goal (K killN_in_alt_tac) |> Thm.close_derivation
   340         Skip_Proof.prove lthy [] [] goal (K killN_in_alt_tac) |> Thm.close_derivation
   344       end;
   341       end;
   345 
   342 
   346     fun killN_in_bd_tac _ =
   343     fun in_bd_tac _ =
   347       mk_killN_in_bd_tac n (live > n) killN_in_alt_thm (in_bd_of_bnf bnf)
   344       mk_killN_in_bd_tac n (live > n) in_alt_thm (in_bd_of_bnf bnf) (bd_Card_order_of_bnf bnf)
   348          (bd_Card_order_of_bnf bnf) (bd_Cinfinite_of_bnf bnf) (bd_Cnotzero_of_bnf bnf);
   345         (bd_Cinfinite_of_bnf bnf) (bd_Cnotzero_of_bnf bnf);
   349     fun killN_map_wpull_tac _ =
   346     fun map_wpull_tac _ = mk_map_wpull_tac in_alt_thm [] (map_wpull_of_bnf bnf);
   350       mk_map_wpull_tac killN_in_alt_thm [] (map_wpull_of_bnf bnf);
   347 
   351 
   348     val tacs = [map_id_tac, map_comp_tac, map_cong_tac] @ set_natural_tacs @ [bd_card_order_tac,
   352     val tacs = [killN_map_id_tac, killN_map_comp_tac, killN_map_cong_tac] @ killN_set_natural_tacs @
   349       bd_cinfinite_tac] @ set_bd_tacs @ [in_bd_tac, map_wpull_tac];
   353       [killN_bd_card_order_tac, killN_bd_cinfinite_tac] @ killN_set_bd_tacs @
   350 
   354       [killN_in_bd_tac, killN_map_wpull_tac];
   351     val bnf_wits = mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf;
   355 
   352 
   356     val wits = mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf;
   353     val wits = map (fn t => fold absfree (Term.add_frees t []) t)
   357 
   354       (map (fn (I, wit) => Term.list_comb (wit, map (nth xs) I)) bnf_wits);
   358     val killN_wits = map (fn t => fold absfree (Term.add_frees t []) t)
       
   359       (map (fn (I, wit) => Term.list_comb (wit, map (nth xs) I)) wits);
       
   360 
   355 
   361     fun wit_tac _ = mk_simple_wit_tac (wit_thms_of_bnf bnf);
   356     fun wit_tac _ = mk_simple_wit_tac (wit_thms_of_bnf bnf);
   362 
   357 
   363     val (bnf', lthy') =
   358     val (bnf', lthy') =
   364       bnf_def Smart_Inline (K Derive_Some_Facts) qualify tacs wit_tac (SOME (killedAs @ Ds))
   359       bnf_def Smart_Inline (K Derive_Some_Facts) qualify tacs wit_tac (SOME (killedAs @ Ds))
   365         ((((b, killN_map), killN_sets), Term.absdummy T killN_bd), killN_wits) lthy;
   360         ((((b, mapx), sets), Term.absdummy T bd), wits) lthy;
   366 
   361 
   367     val rel_Gr = rel_Gr_of_bnf bnf RS sym;
   362     val rel_Gr = rel_Gr_of_bnf bnf RS sym;
   368 
   363 
   369     val killN_rel_unfold_thm =
   364     val rel_unfold_thm =
   370       trans OF [rel_def_of_bnf bnf',
   365       trans OF [rel_def_of_bnf bnf',
   371         trans OF [killN_in_alt_thm RS @{thm subst_rel_def},
   366         trans OF [in_alt_thm RS @{thm subst_rel_def},
   372           trans OF [@{thm arg_cong2[of _ _ _ _ relcomp]} OF
   367           trans OF [@{thm arg_cong2[of _ _ _ _ relcomp]} OF
   373             [trans OF [rel_Gr RS @{thm arg_cong[of _ _ converse]}, rel_converse_of_bnf bnf RS sym],
   368             [trans OF [rel_Gr RS @{thm arg_cong[of _ _ converse]}, rel_converse_of_bnf bnf RS sym],
   374               rel_Gr],
   369               rel_Gr],
   375             trans OF [rel_O_of_bnf bnf RS sym, rel_cong_of_bnf bnf OF
   370             trans OF [rel_O_of_bnf bnf RS sym, rel_cong_of_bnf bnf OF
   376               (replicate n @{thm trans[OF Gr_UNIV_id[OF refl] Id_alt[symmetric]]} @
   371               (replicate n @{thm trans[OF Gr_UNIV_id[OF refl] Id_alt[symmetric]]} @
   377                replicate (live - n) @{thm Gr_fst_snd})]]]];
   372                replicate (live - n) @{thm Gr_fst_snd})]]]];
   378 
   373 
   379     val killN_pred_unfold_thm = Collect_split_box_equals OF
   374     val pred_unfold_thm = Collect_split_box_equals OF
   380       [Local_Defs.unfold lthy' @{thms Id_def'} killN_rel_unfold_thm,
   375       [Local_Defs.unfold lthy' @{thms Id_def'} rel_unfold_thm, pred_def_of_bnf bnf' RS abs_pred_sym,
   381         pred_def_of_bnf bnf' RS abs_pred_sym, pred_def_of_bnf bnf RS abs_pred_sym];
   376         pred_def_of_bnf bnf RS abs_pred_sym];
   382 
   377 
   383     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf')
   378     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf') rel_unfold_thm
   384       killN_rel_unfold_thm killN_pred_unfold_thm unfold;
   379       pred_unfold_thm unfold;
   385   in
   380   in
   386     (bnf', (unfold', lthy'))
   381     (bnf', (unfold', lthy'))
   387   end;
   382   end;
   388 
   383 
   389 (* Adding dummy live variables *)
   384 (* Adding dummy live variables *)
   408       |> mk_Frees "A" (map (HOLogic.mk_setT) (newAs @ As));
   403       |> mk_Frees "A" (map (HOLogic.mk_setT) (newAs @ As));
   409 
   404 
   410     val T = mk_T_of_bnf Ds As bnf;
   405     val T = mk_T_of_bnf Ds As bnf;
   411 
   406 
   412     (*%f1 ... fn. bnf.map*)
   407     (*%f1 ... fn. bnf.map*)
   413     val liftN_map =
   408     val mapx =
   414       fold_rev Term.absdummy (map2 (curry (op -->)) newAs newBs) (mk_map_of_bnf Ds As Bs bnf);
   409       fold_rev Term.absdummy (map2 (curry (op -->)) newAs newBs) (mk_map_of_bnf Ds As Bs bnf);
   415 
   410 
   416     val bnf_sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf;
   411     val bnf_sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf;
   417     val liftN_sets = map (fn A => absdummy T (HOLogic.mk_set A [])) newAs @ bnf_sets;
   412     val sets = map (fn A => absdummy T (HOLogic.mk_set A [])) newAs @ bnf_sets;
   418 
   413 
   419     val liftN_bd = mk_bd_of_bnf Ds As bnf;
   414     val bd = mk_bd_of_bnf Ds As bnf;
   420 
   415 
   421     fun liftN_map_id_tac _ = rtac (map_id_of_bnf bnf) 1;
   416     fun map_id_tac _ = rtac (map_id_of_bnf bnf) 1;
   422     fun liftN_map_comp_tac {context, ...} =
   417     fun map_comp_tac {context, ...} =
   423       Local_Defs.unfold_tac context ((map_comp_of_bnf bnf RS sym) :: @{thms o_assoc id_o o_id}) THEN
   418       Local_Defs.unfold_tac context ((map_comp_of_bnf bnf RS sym) :: @{thms o_assoc id_o o_id}) THEN
   424       rtac refl 1;
   419       rtac refl 1;
   425     fun liftN_map_cong_tac {context, ...} =
   420     fun map_cong_tac {context, ...} =
   426       rtac (map_cong_of_bnf bnf) 1 THEN REPEAT_DETERM_N live (Goal.assume_rule_tac context 1);
   421       rtac (map_cong_of_bnf bnf) 1 THEN REPEAT_DETERM_N live (Goal.assume_rule_tac context 1);
   427     val liftN_set_natural_tacs =
   422     val set_natural_tacs =
   428       if ! quick_and_dirty then
   423       if ! quick_and_dirty then
   429         replicate (n + live) (K all_tac)
   424         replicate (n + live) (K all_tac)
   430       else
   425       else
   431         replicate n (K empty_natural_tac) @
   426         replicate n (K empty_natural_tac) @
   432         map (fn thm => fn _ => rtac thm 1) (set_natural_of_bnf bnf);
   427         map (fn thm => fn _ => rtac thm 1) (set_natural_of_bnf bnf);
   433     fun liftN_bd_card_order_tac _ = rtac (bd_card_order_of_bnf bnf) 1;
   428     fun bd_card_order_tac _ = rtac (bd_card_order_of_bnf bnf) 1;
   434     fun liftN_bd_cinfinite_tac _ = rtac (bd_cinfinite_of_bnf bnf) 1;
   429     fun bd_cinfinite_tac _ = rtac (bd_cinfinite_of_bnf bnf) 1;
   435     val liftN_set_bd_tacs =
   430     val set_bd_tacs =
   436       if ! quick_and_dirty then
   431       if ! quick_and_dirty then
   437         replicate (n + live) (K all_tac)
   432         replicate (n + live) (K all_tac)
   438       else
   433       else
   439         replicate n (K (mk_liftN_set_bd_tac (bd_Card_order_of_bnf bnf))) @
   434         replicate n (K (mk_liftN_set_bd_tac (bd_Card_order_of_bnf bnf))) @
   440         (map (fn thm => fn _ => rtac thm 1) (set_bd_of_bnf bnf));
   435         (map (fn thm => fn _ => rtac thm 1) (set_bd_of_bnf bnf));
   441 
   436 
   442     val liftN_in_alt_thm =
   437     val in_alt_thm =
   443       let
   438       let
   444         val liftN_in = mk_in Asets liftN_sets T;
   439         val inx = mk_in Asets sets T;
   445         val liftN_in_alt = mk_in (drop n Asets) bnf_sets T;
   440         val in_alt = mk_in (drop n Asets) bnf_sets T;
   446         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (liftN_in, liftN_in_alt));
   441         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (inx, in_alt));
   447       in
   442       in
   448         Skip_Proof.prove lthy [] [] goal (K liftN_in_alt_tac) |> Thm.close_derivation
   443         Skip_Proof.prove lthy [] [] goal (K liftN_in_alt_tac) |> Thm.close_derivation
   449       end;
   444       end;
   450 
   445 
   451     fun liftN_in_bd_tac _ =
   446     fun in_bd_tac _ = mk_liftN_in_bd_tac n in_alt_thm (in_bd_of_bnf bnf) (bd_Card_order_of_bnf bnf);
   452       mk_liftN_in_bd_tac n liftN_in_alt_thm (in_bd_of_bnf bnf) (bd_Card_order_of_bnf bnf);
   447     fun map_wpull_tac _ = mk_map_wpull_tac in_alt_thm [] (map_wpull_of_bnf bnf);
   453     fun liftN_map_wpull_tac _ =
   448 
   454       mk_map_wpull_tac liftN_in_alt_thm [] (map_wpull_of_bnf bnf);
   449     val tacs = [map_id_tac, map_comp_tac, map_cong_tac] @ set_natural_tacs @ [bd_card_order_tac,
   455 
   450       bd_cinfinite_tac] @ set_bd_tacs @ [in_bd_tac, map_wpull_tac];
   456     val tacs = [liftN_map_id_tac, liftN_map_comp_tac, liftN_map_cong_tac] @ liftN_set_natural_tacs @
   451 
   457       [liftN_bd_card_order_tac, liftN_bd_cinfinite_tac] @ liftN_set_bd_tacs @
   452     val wits = map snd (mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf);
   458       [liftN_in_bd_tac, liftN_map_wpull_tac];
       
   459 
       
   460     val liftN_wits = map snd (mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf);
       
   461 
   453 
   462     fun wit_tac _ = mk_simple_wit_tac (wit_thms_of_bnf bnf);
   454     fun wit_tac _ = mk_simple_wit_tac (wit_thms_of_bnf bnf);
   463 
   455 
   464     val (bnf', lthy') =
   456     val (bnf', lthy') =
   465       bnf_def Smart_Inline (K Derive_Some_Facts) qualify tacs wit_tac (SOME Ds)
   457       bnf_def Smart_Inline (K Derive_Some_Facts) qualify tacs wit_tac (SOME Ds)
   466         ((((b, liftN_map), liftN_sets), Term.absdummy T liftN_bd), liftN_wits) lthy;
   458         ((((b, mapx), sets), Term.absdummy T bd), wits) lthy;
   467 
   459 
   468     val liftN_rel_unfold_thm =
   460     val rel_unfold_thm =
   469       trans OF [rel_def_of_bnf bnf',
   461       trans OF [rel_def_of_bnf bnf',
   470         trans OF [liftN_in_alt_thm RS @{thm subst_rel_def}, rel_def_of_bnf bnf RS sym]];
   462         trans OF [in_alt_thm RS @{thm subst_rel_def}, rel_def_of_bnf bnf RS sym]];
   471 
   463 
   472     val liftN_pred_unfold_thm = Collect_split_box_equals OF [liftN_rel_unfold_thm,
   464     val pred_unfold_thm = Collect_split_box_equals OF [rel_unfold_thm,
   473       pred_def_of_bnf bnf' RS abs_pred_sym, pred_def_of_bnf bnf RS abs_pred_sym];
   465       pred_def_of_bnf bnf' RS abs_pred_sym, pred_def_of_bnf bnf RS abs_pred_sym];
   474 
   466 
   475     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf')
   467     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf') rel_unfold_thm
   476       liftN_rel_unfold_thm liftN_pred_unfold_thm unfold;
   468       pred_unfold_thm unfold;
   477   in
   469   in
   478     (bnf', (unfold', lthy'))
   470     (bnf', (unfold', lthy'))
   479   end;
   471   end;
   480 
   472 
   481 (* Changing the order of live variables *)
   473 (* Changing the order of live variables *)
   500       |> mk_Frees "A" (map (HOLogic.mk_setT) (permute As));
   492       |> mk_Frees "A" (map (HOLogic.mk_setT) (permute As));
   501 
   493 
   502     val T = mk_T_of_bnf Ds As bnf;
   494     val T = mk_T_of_bnf Ds As bnf;
   503 
   495 
   504     (*%f(1) ... f(n). bnf.map f\<sigma>(1) ... f\<sigma>(n)*)
   496     (*%f(1) ... f(n). bnf.map f\<sigma>(1) ... f\<sigma>(n)*)
   505     val permute_map = fold_rev Term.absdummy (permute (map2 (curry op -->) As Bs))
   497     val mapx = fold_rev Term.absdummy (permute (map2 (curry op -->) As Bs))
   506       (Term.list_comb (mk_map_of_bnf Ds As Bs bnf,
   498       (Term.list_comb (mk_map_of_bnf Ds As Bs bnf,
   507         permute_rev (map Bound ((live - 1) downto 0))));
   499         permute_rev (map Bound ((live - 1) downto 0))));
   508 
   500 
   509     val bnf_sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf;
   501     val bnf_sets = mk_sets_of_bnf (replicate live Ds) (replicate live As) bnf;
   510     val permute_sets = permute bnf_sets;
   502     val sets = permute bnf_sets;
   511 
   503 
   512     val permute_bd = mk_bd_of_bnf Ds As bnf;
   504     val bd = mk_bd_of_bnf Ds As bnf;
   513 
   505 
   514     fun permute_map_id_tac _ = rtac (map_id_of_bnf bnf) 1;
   506     fun map_id_tac _ = rtac (map_id_of_bnf bnf) 1;
   515     fun permute_map_comp_tac _ = rtac (map_comp_of_bnf bnf) 1;
   507     fun map_comp_tac _ = rtac (map_comp_of_bnf bnf) 1;
   516     fun permute_map_cong_tac {context, ...} =
   508     fun map_cong_tac {context, ...} =
   517       rtac (map_cong_of_bnf bnf) 1 THEN REPEAT_DETERM_N live (Goal.assume_rule_tac context 1);
   509       rtac (map_cong_of_bnf bnf) 1 THEN REPEAT_DETERM_N live (Goal.assume_rule_tac context 1);
   518     val permute_set_natural_tacs =
   510     val set_natural_tacs = permute (map (fn thm => fn _ => rtac thm 1) (set_natural_of_bnf bnf));
   519       permute (map (fn thm => fn _ => rtac thm 1) (set_natural_of_bnf bnf));
   511     fun bd_card_order_tac _ = rtac (bd_card_order_of_bnf bnf) 1;
   520     fun permute_bd_card_order_tac _ = rtac (bd_card_order_of_bnf bnf) 1;
   512     fun bd_cinfinite_tac _ = rtac (bd_cinfinite_of_bnf bnf) 1;
   521     fun permute_bd_cinfinite_tac _ = rtac (bd_cinfinite_of_bnf bnf) 1;
   513     val set_bd_tacs = permute (map (fn thm => fn _ => rtac thm 1) (set_bd_of_bnf bnf));
   522     val permute_set_bd_tacs = permute (map (fn thm => fn _ => rtac thm 1) (set_bd_of_bnf bnf));
   514 
   523 
   515     val in_alt_thm =
   524     val permute_in_alt_thm =
       
   525       let
   516       let
   526         val permute_in = mk_in Asets permute_sets T;
   517         val inx = mk_in Asets sets T;
   527         val permute_in_alt = mk_in (permute_rev Asets) bnf_sets T;
   518         val in_alt = mk_in (permute_rev Asets) bnf_sets T;
   528         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (permute_in, permute_in_alt));
   519         val goal = fold_rev Logic.all Asets (mk_Trueprop_eq (inx, in_alt));
   529       in
   520       in
   530         Skip_Proof.prove lthy [] [] goal (K (mk_permute_in_alt_tac src dest))
   521         Skip_Proof.prove lthy [] [] goal (K (mk_permute_in_alt_tac src dest))
   531         |> Thm.close_derivation
   522         |> Thm.close_derivation
   532       end;
   523       end;
   533 
   524 
   534     fun permute_in_bd_tac _ =
   525     fun in_bd_tac _ =
   535       mk_permute_in_bd_tac src dest permute_in_alt_thm (in_bd_of_bnf bnf)
   526       mk_permute_in_bd_tac src dest in_alt_thm (in_bd_of_bnf bnf) (bd_Card_order_of_bnf bnf);
   536         (bd_Card_order_of_bnf bnf);
   527     fun map_wpull_tac _ = mk_map_wpull_tac in_alt_thm [] (map_wpull_of_bnf bnf);
   537     fun permute_map_wpull_tac _ =
   528 
   538       mk_map_wpull_tac permute_in_alt_thm [] (map_wpull_of_bnf bnf);
   529     val tacs = [map_id_tac, map_comp_tac, map_cong_tac] @ set_natural_tacs @ [bd_card_order_tac,
   539 
   530       bd_cinfinite_tac] @ set_bd_tacs @ [in_bd_tac, map_wpull_tac];
   540     val tacs = [permute_map_id_tac, permute_map_comp_tac, permute_map_cong_tac] @
   531 
   541       permute_set_natural_tacs @ [permute_bd_card_order_tac, permute_bd_cinfinite_tac] @
   532     val wits = map snd (mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf);
   542       permute_set_bd_tacs @ [permute_in_bd_tac, permute_map_wpull_tac];
       
   543 
       
   544     val permute_wits = map snd (mk_wits_of_bnf (replicate nwits Ds) (replicate nwits As) bnf);
       
   545 
   533 
   546     fun wit_tac _ = mk_simple_wit_tac (wit_thms_of_bnf bnf);
   534     fun wit_tac _ = mk_simple_wit_tac (wit_thms_of_bnf bnf);
   547 
   535 
   548     val (bnf', lthy') =
   536     val (bnf', lthy') =
   549       bnf_def Smart_Inline (K Derive_Some_Facts) qualify tacs wit_tac (SOME Ds)
   537       bnf_def Smart_Inline (K Derive_Some_Facts) qualify tacs wit_tac (SOME Ds)
   550         ((((b, permute_map), permute_sets), Term.absdummy T permute_bd), permute_wits) lthy;
   538         ((((b, mapx), sets), Term.absdummy T bd), wits) lthy;
   551 
   539 
   552     val permute_rel_unfold_thm =
   540     val rel_unfold_thm =
   553       trans OF [rel_def_of_bnf bnf',
   541       trans OF [rel_def_of_bnf bnf',
   554         trans OF [permute_in_alt_thm RS @{thm subst_rel_def}, rel_def_of_bnf bnf RS sym]];
   542         trans OF [in_alt_thm RS @{thm subst_rel_def}, rel_def_of_bnf bnf RS sym]];
   555 
   543 
   556     val permute_pred_unfold_thm = Collect_split_box_equals OF [permute_rel_unfold_thm,
   544     val pred_unfold_thm = Collect_split_box_equals OF [rel_unfold_thm,
   557       pred_def_of_bnf bnf' RS abs_pred_sym, pred_def_of_bnf bnf RS abs_pred_sym];
   545       pred_def_of_bnf bnf' RS abs_pred_sym, pred_def_of_bnf bnf RS abs_pred_sym];
   558 
   546 
   559     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf')
   547     val unfold' = add_to_unfold (map_def_of_bnf bnf') (set_defs_of_bnf bnf') rel_unfold_thm
   560       permute_rel_unfold_thm permute_pred_unfold_thm unfold;
   548       pred_unfold_thm unfold;
   561   in
   549   in
   562     (bnf', (unfold', lthy'))
   550     (bnf', (unfold', lthy'))
   563   end;
   551   end;
   564 
   552 
   565 (* Composition pipeline *)
   553 (* Composition pipeline *)