src/HOL/Tools/BNF/bnf_gfp_tactics.ML
changeset 59498 50b60f501b05
parent 58634 9f10d82e8188
child 60728 26ffdb966759
equal deleted inserted replaced
59497:0c5cd369a643 59498:50b60f501b05
    54   val mk_mor_beh_tac: Proof.context -> int -> thm -> thm -> thm list -> thm list -> thm list ->
    54   val mk_mor_beh_tac: Proof.context -> int -> thm -> thm -> thm list -> thm list -> thm list ->
    55     thm list -> thm list list -> thm list list -> thm list -> thm list -> thm list -> thm list ->
    55     thm list -> thm list list -> thm list list -> thm list -> thm list -> thm list -> thm list ->
    56     thm list -> thm list -> thm list list -> thm list list list -> thm list list list ->
    56     thm list -> thm list -> thm list list -> thm list list list -> thm list list list ->
    57     thm list list -> thm list -> thm list -> tactic
    57     thm list list -> thm list -> thm list -> tactic
    58   val mk_mor_case_sum_tac: 'a list -> thm -> tactic
    58   val mk_mor_case_sum_tac: 'a list -> thm -> tactic
    59   val mk_mor_comp_tac: thm -> thm list -> thm list -> thm list -> tactic
    59   val mk_mor_comp_tac: Proof.context -> thm -> thm list -> thm list -> thm list -> tactic
    60   val mk_mor_elim_tac: thm -> tactic
    60   val mk_mor_elim_tac: thm -> tactic
    61   val mk_mor_col_tac: int -> int -> cterm option list -> int -> thm list -> thm list ->
    61   val mk_mor_col_tac: int -> int -> cterm option list -> int -> thm list -> thm list ->
    62     thm list -> thm list list -> thm list list -> tactic
    62     thm list -> thm list list -> thm list list -> tactic
    63   val mk_mor_incl_tac: thm -> thm list -> tactic
    63   val mk_mor_incl_tac: thm -> thm list -> tactic
    64   val mk_mor_str_tac: 'a list -> thm -> tactic
    64   val mk_mor_str_tac: 'a list -> thm -> tactic
   114 
   114 
   115 fun mk_coalg_set_tac coalg_def =
   115 fun mk_coalg_set_tac coalg_def =
   116   dtac (coalg_def RS iffD1) 1 THEN
   116   dtac (coalg_def RS iffD1) 1 THEN
   117   REPEAT_DETERM (etac conjE 1) THEN
   117   REPEAT_DETERM (etac conjE 1) THEN
   118   EVERY' [dtac rev_bspec, atac] 1 THEN
   118   EVERY' [dtac rev_bspec, atac] 1 THEN
   119   REPEAT_DETERM (eresolve_tac [CollectE, conjE] 1) THEN atac 1;
   119   REPEAT_DETERM (eresolve0_tac [CollectE, conjE] 1) THEN atac 1;
   120 
   120 
   121 fun mk_mor_elim_tac mor_def =
   121 fun mk_mor_elim_tac mor_def =
   122   (dtac (mor_def RS iffD1) THEN'
   122   (dtac (mor_def RS iffD1) THEN'
   123   REPEAT o etac conjE THEN'
   123   REPEAT o etac conjE THEN'
   124   TRY o rtac @{thm image_subsetI} THEN'
   124   TRY o rtac @{thm image_subsetI} THEN'
   131   CONJ_WRAP' (K (EVERY' [rtac ballI, etac set_mp, etac (id_apply RS @{thm ssubst_mem})]))
   131   CONJ_WRAP' (K (EVERY' [rtac ballI, etac set_mp, etac (id_apply RS @{thm ssubst_mem})]))
   132     map_ids THEN'
   132     map_ids THEN'
   133   CONJ_WRAP' (fn thm =>
   133   CONJ_WRAP' (fn thm =>
   134     (EVERY' [rtac ballI, rtac (thm RS trans), rtac sym, rtac (id_apply RS arg_cong)])) map_ids) 1;
   134     (EVERY' [rtac ballI, rtac (thm RS trans), rtac sym, rtac (id_apply RS arg_cong)])) map_ids) 1;
   135 
   135 
   136 fun mk_mor_comp_tac mor_def mor_images morEs map_comp_ids =
   136 fun mk_mor_comp_tac ctxt mor_def mor_images morEs map_comp_ids =
   137   let
   137   let
   138     fun fbetw_tac image = EVERY' [rtac ballI, rtac (o_apply RS @{thm ssubst_mem}), etac image,
   138     fun fbetw_tac image = EVERY' [rtac ballI, rtac (o_apply RS @{thm ssubst_mem}), etac image,
   139       etac image, atac];
   139       etac image, atac];
   140     fun mor_tac ((mor_image, morE), map_comp_id) =
   140     fun mor_tac ((mor_image, morE), map_comp_id) =
   141       EVERY' [rtac ballI, stac o_apply, rtac trans, rtac (map_comp_id RS sym), rtac trans,
   141       EVERY' [rtac ballI, stac ctxt o_apply, rtac trans, rtac (map_comp_id RS sym), rtac trans,
   142         etac (morE RS arg_cong), atac, etac morE, etac mor_image, atac];
   142         etac (morE RS arg_cong), atac, etac morE, etac mor_image, atac];
   143   in
   143   in
   144     (rtac (mor_def RS iffD2) THEN' rtac conjI THEN'
   144     (rtac (mor_def RS iffD2) THEN' rtac conjI THEN'
   145     CONJ_WRAP' fbetw_tac mor_images THEN'
   145     CONJ_WRAP' fbetw_tac mor_images THEN'
   146     CONJ_WRAP' mor_tac ((mor_images ~~ morEs) ~~ map_comp_ids)) 1
   146     CONJ_WRAP' mor_tac ((mor_images ~~ morEs) ~~ map_comp_ids)) 1
   181     CONJ_WRAP' (fn rec_Suc => EVERY'
   181     CONJ_WRAP' (fn rec_Suc => EVERY'
   182       [rtac ord_eq_le_trans, rtac rec_Suc,
   182       [rtac ord_eq_le_trans, rtac rec_Suc,
   183         if m = 0 then K all_tac
   183         if m = 0 then K all_tac
   184         else (rtac @{thm Un_least} THEN' Goal.assume_rule_tac ctxt),
   184         else (rtac @{thm Un_least} THEN' Goal.assume_rule_tac ctxt),
   185         CONJ_WRAP_GEN' (rtac (Thm.permute_prems 0 1 @{thm Un_least}))
   185         CONJ_WRAP_GEN' (rtac (Thm.permute_prems 0 1 @{thm Un_least}))
   186           (K (EVERY' [rtac @{thm UN_least}, REPEAT_DETERM o eresolve_tac [allE, conjE],
   186           (K (EVERY' [rtac @{thm UN_least}, REPEAT_DETERM o eresolve_tac ctxt [allE, conjE],
   187             rtac subset_trans, atac, Goal.assume_rule_tac ctxt])) rec_0s])
   187             rtac subset_trans, atac, Goal.assume_rule_tac ctxt])) rec_0s])
   188       rec_Sucs] 1;
   188       rec_Sucs] 1;
   189 
   189 
   190 fun mk_Jset_minimal_tac ctxt n col_minimal =
   190 fun mk_Jset_minimal_tac ctxt n col_minimal =
   191   (CONJ_WRAP' (K (EVERY' [rtac @{thm UN_least}, rtac rev_mp, rtac col_minimal,
   191   (CONJ_WRAP' (K (EVERY' [rtac @{thm UN_least}, rtac rev_mp, rtac col_minimal,
   192     EVERY' (replicate ((n + 1) * n) (Goal.assume_rule_tac ctxt)), rtac impI,
   192     EVERY' (replicate ((n + 1) * n) (Goal.assume_rule_tac ctxt)), rtac impI,
   193     REPEAT_DETERM o eresolve_tac [allE, conjE], atac])) (1 upto n)) 1
   193     REPEAT_DETERM o eresolve_tac ctxt [allE, conjE], atac])) (1 upto n)) 1
   194 
   194 
   195 fun mk_mor_col_tac m n cts j rec_0s rec_Sucs morEs set_map0ss coalg_setss =
   195 fun mk_mor_col_tac m n cts j rec_0s rec_Sucs morEs set_map0ss coalg_setss =
   196   EVERY' [rtac (Drule.instantiate' [] cts nat_induct),
   196   EVERY' [rtac (Drule.instantiate' [] cts nat_induct),
   197     REPEAT_DETERM o rtac allI,
   197     REPEAT_DETERM o rtac allI,
   198     CONJ_WRAP' (fn thm => EVERY' (map rtac [impI, thm RS trans, thm RS sym])) rec_0s,
   198     CONJ_WRAP' (fn thm => EVERY' (map rtac [impI, thm RS trans, thm RS sym])) rec_0s,
   220     val thms = ((1 upto n) ~~ map_comp0s ~~ map_cong0s ~~ set_map0ss ~~ in_rels);
   220     val thms = ((1 upto n) ~~ map_comp0s ~~ map_cong0s ~~ set_map0ss ~~ in_rels);
   221 
   221 
   222     fun mk_if_tac ((((i, map_comp0), map_cong0), set_map0s), in_rel) =
   222     fun mk_if_tac ((((i, map_comp0), map_cong0), set_map0s), in_rel) =
   223       EVERY' [rtac allI, rtac allI, rtac impI, dtac (mk_conjunctN n i),
   223       EVERY' [rtac allI, rtac allI, rtac impI, dtac (mk_conjunctN n i),
   224         etac allE, etac allE, etac impE, atac, etac bexE,
   224         etac allE, etac allE, etac impE, atac, etac bexE,
   225         REPEAT_DETERM o eresolve_tac [CollectE, conjE],
   225         REPEAT_DETERM o eresolve0_tac [CollectE, conjE],
   226         rtac (in_rel RS iffD2), rtac exI, rtac (Drule.rotate_prems 1 conjI),
   226         rtac (in_rel RS iffD2), rtac exI, rtac (Drule.rotate_prems 1 conjI),
   227         CONJ_WRAP' (fn thm => EVERY' [rtac trans, rtac trans, rtac map_comp0, rtac map_cong0,
   227         CONJ_WRAP' (fn thm => EVERY' [rtac trans, rtac trans, rtac map_comp0, rtac map_cong0,
   228           REPEAT_DETERM_N m o rtac thm, REPEAT_DETERM_N n o rtac (@{thm comp_id} RS fun_cong),
   228           REPEAT_DETERM_N m o rtac thm, REPEAT_DETERM_N n o rtac (@{thm comp_id} RS fun_cong),
   229           atac])
   229           atac])
   230         @{thms fst_diag_id snd_diag_id},
   230         @{thms fst_diag_id snd_diag_id},
   240 
   240 
   241     fun mk_only_if_tac ((((i, map_comp0), map_cong0), set_map0s), in_rel) =
   241     fun mk_only_if_tac ((((i, map_comp0), map_cong0), set_map0s), in_rel) =
   242       EVERY' [dtac (mk_conjunctN n i), rtac allI, rtac allI, rtac impI,
   242       EVERY' [dtac (mk_conjunctN n i), rtac allI, rtac allI, rtac impI,
   243         etac allE, etac allE, etac impE, atac,
   243         etac allE, etac allE, etac impE, atac,
   244         dtac (in_rel RS @{thm iffD1}),
   244         dtac (in_rel RS @{thm iffD1}),
   245         REPEAT_DETERM o eresolve_tac ([CollectE, conjE, exE] @
   245         REPEAT_DETERM o eresolve0_tac ([CollectE, conjE, exE] @
   246           @{thms CollectE Collect_split_in_rel_leE}),
   246           @{thms CollectE Collect_split_in_rel_leE}),
   247         rtac bexI, rtac conjI, rtac trans, rtac map_comp0, rtac trans, rtac map_cong0,
   247         rtac bexI, rtac conjI, rtac trans, rtac map_comp0, rtac trans, rtac map_cong0,
   248         REPEAT_DETERM_N m o rtac (@{thm id_comp} RS fun_cong),
   248         REPEAT_DETERM_N m o rtac (@{thm id_comp} RS fun_cong),
   249         REPEAT_DETERM_N n o rtac (@{thm comp_id} RS fun_cong),
   249         REPEAT_DETERM_N n o rtac (@{thm comp_id} RS fun_cong),
   250         atac, rtac trans, rtac map_comp0, rtac trans, rtac map_cong0,
   250         atac, rtac trans, rtac map_comp0, rtac trans, rtac map_cong0,
   325 fun mk_sbis_lsbis_tac ctxt lsbis_defs bis_Union bis_cong =
   325 fun mk_sbis_lsbis_tac ctxt lsbis_defs bis_Union bis_cong =
   326   let
   326   let
   327     val n = length lsbis_defs;
   327     val n = length lsbis_defs;
   328   in
   328   in
   329     EVERY' [rtac (Thm.permute_prems 0 1 bis_cong), EVERY' (map rtac lsbis_defs),
   329     EVERY' [rtac (Thm.permute_prems 0 1 bis_cong), EVERY' (map rtac lsbis_defs),
   330       rtac bis_Union, rtac ballI, REPEAT_DETERM o eresolve_tac [CollectE, conjE, exE],
   330       rtac bis_Union, rtac ballI, REPEAT_DETERM o eresolve_tac ctxt [CollectE, conjE, exE],
   331       hyp_subst_tac ctxt, etac bis_cong, EVERY' (map (rtac o mk_nth_conv n) (1 upto n))] 1
   331       hyp_subst_tac ctxt, etac bis_cong, EVERY' (map (rtac o mk_nth_conv n) (1 upto n))] 1
   332   end;
   332   end;
   333 
   333 
   334 fun mk_incl_lsbis_tac n i lsbis_def =
   334 fun mk_incl_lsbis_tac n i lsbis_def =
   335   EVERY' [rtac @{thm xt1(3)}, rtac lsbis_def, rtac @{thm SUP_upper2}, rtac CollectI,
   335   EVERY' [rtac @{thm xt1(3)}, rtac lsbis_def, rtac @{thm SUP_upper2}, rtac CollectI,
   355 fun mk_coalgT_tac ctxt m defs strT_defs set_map0ss =
   355 fun mk_coalgT_tac ctxt m defs strT_defs set_map0ss =
   356   let
   356   let
   357     val n = length strT_defs;
   357     val n = length strT_defs;
   358     val ks = 1 upto n;
   358     val ks = 1 upto n;
   359     fun coalg_tac (i, (active_sets, def)) =
   359     fun coalg_tac (i, (active_sets, def)) =
   360       EVERY' [rtac ballI, REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE],
   360       EVERY' [rtac ballI, REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE],
   361         hyp_subst_tac ctxt, rtac (def RS trans RS @{thm ssubst_mem}), etac (arg_cong RS trans),
   361         hyp_subst_tac ctxt, rtac (def RS trans RS @{thm ssubst_mem}), etac (arg_cong RS trans),
   362         rtac (mk_sum_caseN n i), rtac CollectI,
   362         rtac (mk_sum_caseN n i), rtac CollectI,
   363         REPEAT_DETERM_N m o EVERY' [rtac conjI, rtac subset_UNIV],
   363         REPEAT_DETERM_N m o EVERY' [rtac conjI, rtac subset_UNIV],
   364         CONJ_WRAP' (fn (i, thm) => EVERY' [rtac (thm RS ord_eq_le_trans),
   364         CONJ_WRAP' (fn (i, thm) => EVERY' [rtac (thm RS ord_eq_le_trans),
   365           rtac @{thm image_subsetI}, rtac CollectI, rtac exI, rtac exI, rtac conjI, rtac refl,
   365           rtac @{thm image_subsetI}, rtac CollectI, rtac exI, rtac exI, rtac conjI, rtac refl,
   368             etac equalityD1, etac CollectD,
   368             etac equalityD1, etac CollectD,
   369           rtac ballI,
   369           rtac ballI,
   370             CONJ_WRAP' (fn i => EVERY' [rtac ballI, etac CollectE, dtac @{thm ShiftD},
   370             CONJ_WRAP' (fn i => EVERY' [rtac ballI, etac CollectE, dtac @{thm ShiftD},
   371               dtac bspec, etac thin_rl, atac, dtac (mk_conjunctN n i),
   371               dtac bspec, etac thin_rl, atac, dtac (mk_conjunctN n i),
   372               dtac bspec, rtac CollectI, etac @{thm set_mp[OF equalityD1[OF Succ_Shift]]},
   372               dtac bspec, rtac CollectI, etac @{thm set_mp[OF equalityD1[OF Succ_Shift]]},
   373               REPEAT_DETERM o eresolve_tac [exE, conjE], rtac exI,
   373               REPEAT_DETERM o eresolve_tac ctxt [exE, conjE], rtac exI,
   374               rtac conjI, rtac (@{thm shift_def} RS fun_cong RS trans),
   374               rtac conjI, rtac (@{thm shift_def} RS fun_cong RS trans),
   375               rtac (@{thm append_Cons} RS sym RS arg_cong RS trans), atac,
   375               rtac (@{thm append_Cons} RS sym RS arg_cong RS trans), atac,
   376               CONJ_WRAP' (K (EVERY' [etac trans, rtac @{thm Collect_cong},
   376               CONJ_WRAP' (K (EVERY' [etac trans, rtac @{thm Collect_cong},
   377                 rtac @{thm eqset_imp_iff}, rtac sym, rtac trans, rtac @{thm Succ_Shift},
   377                 rtac @{thm eqset_imp_iff}, rtac sym, rtac trans, rtac @{thm Succ_Shift},
   378                 rtac (@{thm append_Cons} RS sym RS arg_cong)])) ks]) ks,
   378                 rtac (@{thm append_Cons} RS sym RS arg_cong)])) ks]) ks,
   379           dtac bspec, atac, dtac (mk_conjunctN n i), dtac bspec,
   379           dtac bspec, atac, dtac (mk_conjunctN n i), dtac bspec,
   380           etac @{thm set_mp[OF equalityD1]}, atac,
   380           etac @{thm set_mp[OF equalityD1]}, atac,
   381           REPEAT_DETERM o eresolve_tac [exE, conjE], rtac exI,
   381           REPEAT_DETERM o eresolve_tac ctxt [exE, conjE], rtac exI,
   382           rtac conjI, rtac (@{thm shift_def} RS fun_cong RS trans),
   382           rtac conjI, rtac (@{thm shift_def} RS fun_cong RS trans),
   383           etac (@{thm append_Nil} RS sym RS arg_cong RS trans),
   383           etac (@{thm append_Nil} RS sym RS arg_cong RS trans),
   384           REPEAT_DETERM_N m o (rtac conjI THEN' atac),
   384           REPEAT_DETERM_N m o (rtac conjI THEN' atac),
   385           CONJ_WRAP' (K (EVERY' [etac trans, rtac @{thm Collect_cong},
   385           CONJ_WRAP' (K (EVERY' [etac trans, rtac @{thm Collect_cong},
   386             rtac @{thm eqset_imp_iff}, rtac sym, rtac trans, rtac @{thm Succ_Shift},
   386             rtac @{thm eqset_imp_iff}, rtac sym, rtac trans, rtac @{thm Succ_Shift},
   403       REPEAT_DETERM o rtac allI,
   403       REPEAT_DETERM o rtac allI,
   404       CONJ_WRAP' (fn Lev_Suc =>
   404       CONJ_WRAP' (fn Lev_Suc =>
   405         EVERY' [rtac impI, dtac (Lev_Suc RS equalityD1 RS set_mp),
   405         EVERY' [rtac impI, dtac (Lev_Suc RS equalityD1 RS set_mp),
   406           CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   406           CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   407             (fn i =>
   407             (fn i =>
   408               EVERY' [REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE], hyp_subst_tac ctxt,
   408               EVERY' [REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE], hyp_subst_tac ctxt,
   409                 rtac trans, rtac @{thm length_Cons}, rtac @{thm arg_cong[of _ _ Suc]},
   409                 rtac trans, rtac @{thm length_Cons}, rtac @{thm arg_cong[of _ _ Suc]},
   410                 REPEAT_DETERM o etac allE, dtac (mk_conjunctN n i), etac mp, atac]) ks])
   410                 REPEAT_DETERM o etac allE, dtac (mk_conjunctN n i), etac mp, atac]) ks])
   411       Lev_Sucs] 1
   411       Lev_Sucs] 1
   412   end;
   412   end;
   413 
   413 
   465       REPEAT_DETERM o rtac allI,
   465       REPEAT_DETERM o rtac allI,
   466       CONJ_WRAP' (fn ((Lev_Suc, rv_Cons), from_to_sbds) =>
   466       CONJ_WRAP' (fn ((Lev_Suc, rv_Cons), from_to_sbds) =>
   467         EVERY' [rtac impI, dtac (Lev_Suc RS equalityD1 RS set_mp),
   467         EVERY' [rtac impI, dtac (Lev_Suc RS equalityD1 RS set_mp),
   468           CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   468           CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   469             (fn (i, from_to_sbd) =>
   469             (fn (i, from_to_sbd) =>
   470               EVERY' [REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE], hyp_subst_tac ctxt,
   470               EVERY' [REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE], hyp_subst_tac ctxt,
   471                 CONJ_WRAP' (fn i' => rtac impI THEN'
   471                 CONJ_WRAP' (fn i' => rtac impI THEN'
   472                   CONJ_WRAP' (fn i'' =>
   472                   CONJ_WRAP' (fn i'' =>
   473                     EVERY' [rtac impI, rtac (Lev_Suc RS equalityD2 RS set_mp),
   473                     EVERY' [rtac impI, rtac (Lev_Suc RS equalityD2 RS set_mp),
   474                       rtac @{thm ssubst_mem[OF append_Cons]}, rtac (mk_UnIN n i),
   474                       rtac @{thm ssubst_mem[OF append_Cons]}, rtac (mk_UnIN n i),
   475                       rtac CollectI, REPEAT_DETERM o rtac exI, rtac conjI, rtac refl,
   475                       rtac CollectI, REPEAT_DETERM o rtac exI, rtac conjI, rtac refl,
   500               (if i = i''
   500               (if i = i''
   501               then EVERY' [dtac @{thm ssubst_mem[OF sym[OF append_Nil]]},
   501               then EVERY' [dtac @{thm ssubst_mem[OF sym[OF append_Nil]]},
   502                 dtac (Lev_Suc RS equalityD1 RS set_mp), dtac (mk_InN_inject n i),
   502                 dtac (Lev_Suc RS equalityD1 RS set_mp), dtac (mk_InN_inject n i),
   503                 hyp_subst_tac ctxt,
   503                 hyp_subst_tac ctxt,
   504                 CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   504                 CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   505                   (fn k => REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE] THEN'
   505                   (fn k => REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE] THEN'
   506                     dtac list_inject_iffD1 THEN' etac conjE THEN'
   506                     dtac list_inject_iffD1 THEN' etac conjE THEN'
   507                     (if k = i'
   507                     (if k = i'
   508                     then EVERY' [dtac (mk_InN_inject n k), hyp_subst_tac ctxt, etac imageI]
   508                     then EVERY' [dtac (mk_InN_inject n k), hyp_subst_tac ctxt, etac imageI]
   509                     else etac (mk_InN_not_InM i' k RS notE)))
   509                     else etac (mk_InN_not_InM i' k RS notE)))
   510                 (rev ks)]
   510                 (rev ks)]
   515       REPEAT_DETERM o rtac allI,
   515       REPEAT_DETERM o rtac allI,
   516       CONJ_WRAP' (fn ((Lev_Suc, rv_Cons), (from_to_sbds, to_sbd_injs)) =>
   516       CONJ_WRAP' (fn ((Lev_Suc, rv_Cons), (from_to_sbds, to_sbd_injs)) =>
   517         EVERY' [rtac impI, dtac (Lev_Suc RS equalityD1 RS set_mp),
   517         EVERY' [rtac impI, dtac (Lev_Suc RS equalityD1 RS set_mp),
   518           CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   518           CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE))
   519             (fn (i, (from_to_sbd, to_sbd_inj)) =>
   519             (fn (i, (from_to_sbd, to_sbd_inj)) =>
   520               REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE] THEN' hyp_subst_tac ctxt THEN'
   520               REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE] THEN' hyp_subst_tac ctxt THEN'
   521               CONJ_WRAP' (fn i' => rtac impI THEN'
   521               CONJ_WRAP' (fn i' => rtac impI THEN'
   522                 dtac @{thm ssubst_mem[OF sym[OF append_Cons]]} THEN'
   522                 dtac @{thm ssubst_mem[OF sym[OF append_Cons]]} THEN'
   523                 dtac (Lev_Suc RS equalityD1 RS set_mp) THEN'
   523                 dtac (Lev_Suc RS equalityD1 RS set_mp) THEN'
   524                 CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE)) (fn k =>
   524                 CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE)) (fn k =>
   525                   REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE] THEN'
   525                   REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE] THEN'
   526                   dtac list_inject_iffD1 THEN' etac conjE THEN'
   526                   dtac list_inject_iffD1 THEN' etac conjE THEN'
   527                   (if k = i
   527                   (if k = i
   528                   then EVERY' [dtac (mk_InN_inject n i),
   528                   then EVERY' [dtac (mk_InN_inject n i),
   529                     dtac (Thm.permute_prems 0 2 (to_sbd_inj RS iffD1)),
   529                     dtac (Thm.permute_prems 0 2 (to_sbd_inj RS iffD1)),
   530                     atac, atac, hyp_subst_tac ctxt] THEN'
   530                     atac, atac, hyp_subst_tac ctxt] THEN'
   561         (**)
   561         (**)
   562           rtac ballI, etac @{thm UN_E},
   562           rtac ballI, etac @{thm UN_E},
   563           CONJ_WRAP' (fn (i, (rv_last, (isNode_def, (set_map0s,
   563           CONJ_WRAP' (fn (i, (rv_last, (isNode_def, (set_map0s,
   564             (set_Levs, set_image_Levs))))) =>
   564             (set_Levs, set_image_Levs))))) =>
   565             EVERY' [rtac ballI,
   565             EVERY' [rtac ballI,
   566               REPEAT_DETERM o eresolve_tac [CollectE, @{thm SuccE}, @{thm UN_E}],
   566               REPEAT_DETERM o eresolve_tac ctxt [CollectE, @{thm SuccE}, @{thm UN_E}],
   567               rtac (rev_mp OF [rv_last, impI]), etac exE, rtac (isNode_def RS iffD2),
   567               rtac (rev_mp OF [rv_last, impI]), etac exE, rtac (isNode_def RS iffD2),
   568               rtac exI, rtac conjI,
   568               rtac exI, rtac conjI,
   569               if n = 1 then rtac refl
   569               if n = 1 then rtac refl
   570               else etac (sum_case_cong_weak RS trans) THEN' rtac (mk_sum_caseN n i),
   570               else etac (sum_case_cong_weak RS trans) THEN' rtac (mk_sum_caseN n i),
   571               CONJ_WRAP' (fn (set_map0, (set_Lev, set_image_Lev)) =>
   571               CONJ_WRAP' (fn (set_map0, (set_Lev, set_image_Lev)) =>
   572                 EVERY' [rtac (set_map0 RS trans), rtac equalityI, rtac @{thm image_subsetI},
   572                 EVERY' [rtac (set_map0 RS trans), rtac equalityI, rtac @{thm image_subsetI},
   573                   rtac CollectI, rtac @{thm SuccI}, rtac @{thm UN_I}, rtac UNIV_I, etac set_Lev,
   573                   rtac CollectI, rtac @{thm SuccI}, rtac @{thm UN_I}, rtac UNIV_I, etac set_Lev,
   574                   if n = 1 then rtac refl else atac, atac, rtac subsetI,
   574                   if n = 1 then rtac refl else atac, atac, rtac subsetI,
   575                   REPEAT_DETERM o eresolve_tac [CollectE, @{thm SuccE}, @{thm UN_E}],
   575                   REPEAT_DETERM o eresolve_tac ctxt [CollectE, @{thm SuccE}, @{thm UN_E}],
   576                   REPEAT_DETERM_N 4 o etac thin_rl,
   576                   REPEAT_DETERM_N 4 o etac thin_rl,
   577                   rtac set_image_Lev,
   577                   rtac set_image_Lev,
   578                   atac, dtac length_Lev, hyp_subst_tac ctxt, dtac length_Lev',
   578                   atac, dtac length_Lev, hyp_subst_tac ctxt, dtac length_Lev',
   579                   etac @{thm set_mp[OF equalityD1[OF arg_cong[OF length_append_singleton]]]},
   579                   etac @{thm set_mp[OF equalityD1[OF arg_cong[OF length_append_singleton]]]},
   580                   if n = 1 then rtac refl else atac])
   580                   if n = 1 then rtac refl else atac])
   589           CONJ_WRAP' (fn (set_map0, (set_Lev, set_image_Lev)) =>
   589           CONJ_WRAP' (fn (set_map0, (set_Lev, set_image_Lev)) =>
   590             EVERY' [rtac (set_map0 RS trans), rtac equalityI, rtac @{thm image_subsetI},
   590             EVERY' [rtac (set_map0 RS trans), rtac equalityI, rtac @{thm image_subsetI},
   591               rtac CollectI, rtac @{thm SuccI}, rtac @{thm UN_I}, rtac UNIV_I, rtac set_Lev,
   591               rtac CollectI, rtac @{thm SuccI}, rtac @{thm UN_I}, rtac UNIV_I, rtac set_Lev,
   592               rtac (Lev_0 RS equalityD2 RS set_mp), rtac @{thm singletonI}, rtac rv_Nil,
   592               rtac (Lev_0 RS equalityD2 RS set_mp), rtac @{thm singletonI}, rtac rv_Nil,
   593               atac, rtac subsetI,
   593               atac, rtac subsetI,
   594               REPEAT_DETERM o eresolve_tac [CollectE, @{thm SuccE}, @{thm UN_E}],
   594               REPEAT_DETERM o eresolve_tac ctxt [CollectE, @{thm SuccE}, @{thm UN_E}],
   595               rtac set_image_Lev, rtac (Lev_0 RS equalityD2 RS set_mp),
   595               rtac set_image_Lev, rtac (Lev_0 RS equalityD2 RS set_mp),
   596               rtac @{thm singletonI}, dtac length_Lev',
   596               rtac @{thm singletonI}, dtac length_Lev',
   597               etac @{thm set_mp[OF equalityD1[OF arg_cong[OF
   597               etac @{thm set_mp[OF equalityD1[OF arg_cong[OF
   598                 trans[OF length_append_singleton arg_cong[of _ _ Suc, OF list.size(3)]]]]]},
   598                 trans[OF length_append_singleton arg_cong[of _ _ Suc, OF list.size(3)]]]]]},
   599               rtac rv_Nil])
   599               rtac rv_Nil])
   610         rtac (map_comp_id RS trans), rtac (map_cong0 OF replicate m refl),
   610         rtac (map_comp_id RS trans), rtac (map_cong0 OF replicate m refl),
   611         EVERY' (@{map 3} (fn i' => fn to_sbd_inj => fn from_to_sbd =>
   611         EVERY' (@{map 3} (fn i' => fn to_sbd_inj => fn from_to_sbd =>
   612           DETERM o EVERY' [rtac trans, rtac o_apply, rtac prod_injectI, rtac conjI,
   612           DETERM o EVERY' [rtac trans, rtac o_apply, rtac prod_injectI, rtac conjI,
   613             rtac trans, rtac @{thm Shift_def},
   613             rtac trans, rtac @{thm Shift_def},
   614             rtac equalityI, rtac subsetI, etac thin_rl,
   614             rtac equalityI, rtac subsetI, etac thin_rl,
   615             REPEAT_DETERM o eresolve_tac [CollectE, @{thm UN_E}], dtac length_Lev', dtac asm_rl,
   615             REPEAT_DETERM o eresolve_tac ctxt [CollectE, @{thm UN_E}], dtac length_Lev', dtac asm_rl,
   616             etac thin_rl, dtac @{thm set_rev_mp[OF _ equalityD1]},
   616             etac thin_rl, dtac @{thm set_rev_mp[OF _ equalityD1]},
   617             rtac (@{thm length_Cons} RS arg_cong RS trans), rtac Lev_Suc,
   617             rtac (@{thm length_Cons} RS arg_cong RS trans), rtac Lev_Suc,
   618             CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE)) (fn i'' =>
   618             CONJ_WRAP_GEN' (etac (Thm.permute_prems 1 1 UnE)) (fn i'' =>
   619               EVERY' [REPEAT_DETERM o eresolve_tac [CollectE, exE, conjE],
   619               EVERY' [REPEAT_DETERM o eresolve_tac ctxt [CollectE, exE, conjE],
   620                 dtac list_inject_iffD1, etac conjE,
   620                 dtac list_inject_iffD1, etac conjE,
   621                 if i' = i'' then EVERY' [dtac (mk_InN_inject n i'),
   621                 if i' = i'' then EVERY' [dtac (mk_InN_inject n i'),
   622                   dtac (Thm.permute_prems 0 2 (to_sbd_inj RS iffD1)),
   622                   dtac (Thm.permute_prems 0 2 (to_sbd_inj RS iffD1)),
   623                   atac, atac, hyp_subst_tac ctxt, etac @{thm UN_I[OF UNIV_I]}]
   623                   atac, atac, hyp_subst_tac ctxt, etac @{thm UN_I[OF UNIV_I]}]
   624                 else etac (mk_InN_not_InM i' i'' RS notE)])
   624                 else etac (mk_InN_not_InM i' i'' RS notE)])
   646           (length_Lev's ~~ (from_to_sbdss ~~ to_sbd_injss))))))) 1
   646           (length_Lev's ~~ (from_to_sbdss ~~ to_sbd_injss))))))) 1
   647   end;
   647   end;
   648 
   648 
   649 fun mk_congruent_str_final_tac m lsbisE map_comp_id map_cong0 equiv_LSBISs =
   649 fun mk_congruent_str_final_tac m lsbisE map_comp_id map_cong0 equiv_LSBISs =
   650   EVERY' [rtac @{thm congruentI}, dtac lsbisE,
   650   EVERY' [rtac @{thm congruentI}, dtac lsbisE,
   651     REPEAT_DETERM o eresolve_tac [CollectE, conjE, bexE], rtac (o_apply RS trans),
   651     REPEAT_DETERM o eresolve0_tac [CollectE, conjE, bexE], rtac (o_apply RS trans),
   652     etac (sym RS arg_cong RS trans), rtac (map_comp_id RS trans),
   652     etac (sym RS arg_cong RS trans), rtac (map_comp_id RS trans),
   653     rtac (map_cong0 RS trans), REPEAT_DETERM_N m o rtac refl,
   653     rtac (map_cong0 RS trans), REPEAT_DETERM_N m o rtac refl,
   654     EVERY' (map (fn equiv_LSBIS =>
   654     EVERY' (map (fn equiv_LSBIS =>
   655       EVERY' [rtac @{thm equiv_proj}, rtac equiv_LSBIS, etac set_mp, atac])
   655       EVERY' [rtac @{thm equiv_proj}, rtac equiv_LSBIS, etac set_mp, atac])
   656     equiv_LSBISs), rtac sym, rtac (o_apply RS trans),
   656     equiv_LSBISs), rtac sym, rtac (o_apply RS trans),
   816     val ks = 1 upto n;
   816     val ks = 1 upto n;
   817   in
   817   in
   818     EVERY' ([rtac rev_mp, coinduct_tac] @
   818     EVERY' ([rtac rev_mp, coinduct_tac] @
   819       maps (fn ((((((map_comp_trans, dtor_maps_trans), map_cong0), set_map0s), set_Jsets),
   819       maps (fn ((((((map_comp_trans, dtor_maps_trans), map_cong0), set_map0s), set_Jsets),
   820         set_Jset_Jsetss), in_rel) =>
   820         set_Jset_Jsetss), in_rel) =>
   821         [REPEAT_DETERM o resolve_tac [allI, impI, in_rel RS iffD2],
   821         [REPEAT_DETERM o resolve_tac ctxt [allI, impI, in_rel RS iffD2],
   822          REPEAT_DETERM o eresolve_tac [exE, conjE], hyp_subst_tac ctxt, rtac exI,
   822          REPEAT_DETERM o eresolve_tac ctxt [exE, conjE], hyp_subst_tac ctxt, rtac exI,
   823          rtac (Drule.rotate_prems 1 conjI),
   823          rtac (Drule.rotate_prems 1 conjI),
   824          rtac conjI, rtac map_comp_trans, rtac sym, rtac dtor_maps_trans, rtac map_cong0,
   824          rtac conjI, rtac map_comp_trans, rtac sym, rtac dtor_maps_trans, rtac map_cong0,
   825          REPEAT_DETERM_N m o (rtac o_apply_trans_sym THEN' rtac @{thm fst_conv}),
   825          REPEAT_DETERM_N m o (rtac o_apply_trans_sym THEN' rtac @{thm fst_conv}),
   826          REPEAT_DETERM_N n o rtac fst_convol_fun_cong_sym,
   826          REPEAT_DETERM_N n o rtac fst_convol_fun_cong_sym,
   827          rtac map_comp_trans, rtac sym, rtac dtor_maps_trans, rtac map_cong0,
   827          rtac map_comp_trans, rtac sym, rtac dtor_maps_trans, rtac map_cong0,
   908       rtac @{thm relcomppI}, etac Jrel_imp_rel, etac Jrel_imp_rel]
   908       rtac @{thm relcomppI}, etac Jrel_imp_rel, etac Jrel_imp_rel]
   909     end)
   909     end)
   910   rel_Jrels le_rel_OOs) 1;
   910   rel_Jrels le_rel_OOs) 1;
   911 
   911 
   912 fun mk_wit_tac ctxt n dtor_ctors dtor_set wit coind_wits =
   912 fun mk_wit_tac ctxt n dtor_ctors dtor_set wit coind_wits =
   913   ALLGOALS (TRY o (eresolve_tac coind_wits THEN' rtac refl)) THEN
   913   ALLGOALS (TRY o (eresolve_tac ctxt coind_wits THEN' rtac refl)) THEN
   914   REPEAT_DETERM (atac 1 ORELSE
   914   REPEAT_DETERM (atac 1 ORELSE
   915     EVERY' [dtac set_rev_mp, rtac equalityD1, resolve_tac dtor_set,
   915     EVERY' [dtac set_rev_mp, rtac equalityD1, resolve_tac ctxt dtor_set,
   916     K (unfold_thms_tac ctxt dtor_ctors),
   916     K (unfold_thms_tac ctxt dtor_ctors),
   917     REPEAT_DETERM_N n o etac UnE,
   917     REPEAT_DETERM_N n o etac UnE,
   918     REPEAT_DETERM o
   918     REPEAT_DETERM o
   919       (TRY o REPEAT_DETERM o etac UnE THEN' TRY o etac @{thm UN_E} THEN'
   919       (TRY o REPEAT_DETERM o etac UnE THEN' TRY o etac @{thm UN_E} THEN'
   920         (eresolve_tac wit ORELSE'
   920         (eresolve_tac ctxt wit ORELSE'
   921         (dresolve_tac wit THEN'
   921         (dresolve_tac ctxt wit THEN'
   922           (etac FalseE ORELSE'
   922           (etac FalseE ORELSE'
   923           EVERY' [hyp_subst_tac ctxt, dtac set_rev_mp, rtac equalityD1, resolve_tac dtor_set,
   923           EVERY' [hyp_subst_tac ctxt, dtac set_rev_mp, rtac equalityD1, resolve_tac ctxt dtor_set,
   924             K (unfold_thms_tac ctxt dtor_ctors), REPEAT_DETERM_N n o etac UnE]))))] 1);
   924             K (unfold_thms_tac ctxt dtor_ctors), REPEAT_DETERM_N n o etac UnE]))))] 1);
   925 
   925 
   926 fun mk_coind_wit_tac ctxt induct unfolds set_nats wits =
   926 fun mk_coind_wit_tac ctxt induct unfolds set_nats wits =
   927   rtac induct 1 THEN ALLGOALS (TRY o rtac impI THEN' TRY o hyp_subst_tac ctxt) THEN
   927   rtac induct 1 THEN ALLGOALS (TRY o rtac impI THEN' TRY o hyp_subst_tac ctxt) THEN
   928   unfold_thms_tac ctxt (unfolds @ set_nats @ @{thms image_id id_apply}) THEN
   928   unfold_thms_tac ctxt (unfolds @ set_nats @ @{thms image_id id_apply}) THEN
   929   ALLGOALS (REPEAT_DETERM o etac imageE THEN' TRY o hyp_subst_tac ctxt) THEN
   929   ALLGOALS (REPEAT_DETERM o etac imageE THEN' TRY o hyp_subst_tac ctxt) THEN
   930   ALLGOALS (TRY o
   930   ALLGOALS (TRY o
   931     FIRST' [rtac TrueI, rtac refl, etac (refl RSN (2, mp)), dresolve_tac wits THEN' etac FalseE]);
   931     FIRST' [rtac TrueI, rtac refl, etac (refl RSN (2, mp)), dresolve_tac ctxt wits THEN' etac FalseE]);
   932 
   932 
   933 fun mk_dtor_corec_transfer_tac ctxt n m dtor_corec_defs dtor_unfold_transfer pre_T_map_transfers
   933 fun mk_dtor_corec_transfer_tac ctxt n m dtor_corec_defs dtor_unfold_transfer pre_T_map_transfers
   934     dtor_rels =
   934     dtor_rels =
   935   CONJ_WRAP (fn (dtor_corec_def, dtor_unfold_transfer) =>
   935   CONJ_WRAP (fn (dtor_corec_def, dtor_unfold_transfer) =>
   936       REPEAT_DETERM (HEADGOAL (rtac rel_funI)) THEN
   936       REPEAT_DETERM (HEADGOAL (rtac rel_funI)) THEN
   953     val m = length dtor_set_incls;
   953     val m = length dtor_set_incls;
   954     val n = length dtor_set_set_inclss;
   954     val n = length dtor_set_set_inclss;
   955     val (passive_set_map0s, active_set_map0s) = chop m set_map0s;
   955     val (passive_set_map0s, active_set_map0s) = chop m set_map0s;
   956     val in_Jrel = nth in_Jrels (i - 1);
   956     val in_Jrel = nth in_Jrels (i - 1);
   957     val if_tac =
   957     val if_tac =
   958       EVERY' [dtac (in_Jrel RS iffD1), REPEAT_DETERM o eresolve_tac [exE, conjE, CollectE],
   958       EVERY' [dtac (in_Jrel RS iffD1), REPEAT_DETERM o eresolve_tac ctxt [exE, conjE, CollectE],
   959         rtac (in_rel RS iffD2), rtac exI, rtac conjI, rtac CollectI,
   959         rtac (in_rel RS iffD2), rtac exI, rtac conjI, rtac CollectI,
   960         EVERY' (map2 (fn set_map0 => fn set_incl =>
   960         EVERY' (map2 (fn set_map0 => fn set_incl =>
   961           EVERY' [rtac conjI, rtac ord_eq_le_trans, rtac set_map0,
   961           EVERY' [rtac conjI, rtac ord_eq_le_trans, rtac set_map0,
   962             rtac ord_eq_le_trans, rtac trans_fun_cong_image_id_id_apply,
   962             rtac ord_eq_le_trans, rtac trans_fun_cong_image_id_id_apply,
   963             etac (set_incl RS @{thm subset_trans})])
   963             etac (set_incl RS @{thm subset_trans})])
   973           REPEAT_DETERM_N m o rtac @{thm fun_cong[OF comp_id]},
   973           REPEAT_DETERM_N m o rtac @{thm fun_cong[OF comp_id]},
   974           REPEAT_DETERM_N n o EVERY' (map rtac [trans, o_apply, conv]),
   974           REPEAT_DETERM_N n o EVERY' (map rtac [trans, o_apply, conv]),
   975           rtac trans, rtac sym, rtac dtor_map, rtac (dtor_inject RS iffD2), atac])
   975           rtac trans, rtac sym, rtac dtor_map, rtac (dtor_inject RS iffD2), atac])
   976         @{thms fst_conv snd_conv}];
   976         @{thms fst_conv snd_conv}];
   977     val only_if_tac =
   977     val only_if_tac =
   978       EVERY' [dtac (in_rel RS iffD1), REPEAT_DETERM o eresolve_tac [exE, conjE, CollectE],
   978       EVERY' [dtac (in_rel RS iffD1), REPEAT_DETERM o eresolve_tac ctxt [exE, conjE, CollectE],
   979         rtac (in_Jrel RS iffD2), rtac exI, rtac conjI, rtac CollectI,
   979         rtac (in_Jrel RS iffD2), rtac exI, rtac conjI, rtac CollectI,
   980         CONJ_WRAP' (fn (dtor_set, passive_set_map0) =>
   980         CONJ_WRAP' (fn (dtor_set, passive_set_map0) =>
   981           EVERY' [rtac ord_eq_le_trans, rtac dtor_set, rtac @{thm Un_least},
   981           EVERY' [rtac ord_eq_le_trans, rtac dtor_set, rtac @{thm Un_least},
   982             rtac ord_eq_le_trans, rtac @{thm box_equals}, rtac passive_set_map0,
   982             rtac ord_eq_le_trans, rtac @{thm box_equals}, rtac passive_set_map0,
   983             rtac (dtor_ctor RS sym RS arg_cong), rtac trans_fun_cong_image_id_id_apply, atac,
   983             rtac (dtor_ctor RS sym RS arg_cong), rtac trans_fun_cong_image_id_id_apply, atac,
   985               (fn (active_set_map0, in_Jrel) => EVERY' [rtac ord_eq_le_trans,
   985               (fn (active_set_map0, in_Jrel) => EVERY' [rtac ord_eq_le_trans,
   986                 rtac @{thm SUP_cong[OF _ refl]}, rtac @{thm box_equals[OF _ _ refl]},
   986                 rtac @{thm SUP_cong[OF _ refl]}, rtac @{thm box_equals[OF _ _ refl]},
   987                 rtac active_set_map0, rtac (dtor_ctor RS sym RS arg_cong), rtac @{thm UN_least},
   987                 rtac active_set_map0, rtac (dtor_ctor RS sym RS arg_cong), rtac @{thm UN_least},
   988                 dtac set_rev_mp, etac @{thm image_mono}, etac imageE,
   988                 dtac set_rev_mp, etac @{thm image_mono}, etac imageE,
   989                 dtac @{thm ssubst_mem[OF pair_collapse]},
   989                 dtac @{thm ssubst_mem[OF pair_collapse]},
   990                 REPEAT_DETERM o eresolve_tac (CollectE :: conjE ::
   990                 REPEAT_DETERM o eresolve_tac ctxt (CollectE :: conjE ::
   991                   @{thms case_prodE iffD1[OF prod.inject, elim_format]}),
   991                   @{thms case_prodE iffD1[OF prod.inject, elim_format]}),
   992                 hyp_subst_tac ctxt,
   992                 hyp_subst_tac ctxt,
   993                 dtac (in_Jrel RS iffD1),
   993                 dtac (in_Jrel RS iffD1),
   994                 dtac @{thm someI_ex}, REPEAT_DETERM o etac conjE,
   994                 dtac @{thm someI_ex}, REPEAT_DETERM o etac conjE,
   995                 REPEAT_DETERM o eresolve_tac [CollectE, conjE], atac])
   995                 REPEAT_DETERM o eresolve_tac ctxt [CollectE, conjE], atac])
   996             (rev (active_set_map0s ~~ in_Jrels))])
   996             (rev (active_set_map0s ~~ in_Jrels))])
   997         (dtor_sets ~~ passive_set_map0s),
   997         (dtor_sets ~~ passive_set_map0s),
   998         rtac conjI,
   998         rtac conjI,
   999         REPEAT_DETERM_N 2 o EVERY'[rtac (dtor_inject RS iffD1), rtac trans, rtac dtor_map,
   999         REPEAT_DETERM_N 2 o EVERY'[rtac (dtor_inject RS iffD1), rtac trans, rtac dtor_map,
  1000           rtac @{thm box_equals}, rtac map_comp0, rtac (dtor_ctor RS sym RS arg_cong), rtac trans,
  1000           rtac @{thm box_equals}, rtac map_comp0, rtac (dtor_ctor RS sym RS arg_cong), rtac trans,
  1001           rtac map_cong0, REPEAT_DETERM_N m o rtac @{thm fun_cong[OF comp_id]},
  1001           rtac map_cong0, REPEAT_DETERM_N m o rtac @{thm fun_cong[OF comp_id]},
  1002           EVERY' (map (fn in_Jrel => EVERY' [rtac trans, rtac o_apply, dtac set_rev_mp, atac,
  1002           EVERY' (map (fn in_Jrel => EVERY' [rtac trans, rtac o_apply, dtac set_rev_mp, atac,
  1003             dtac @{thm ssubst_mem[OF pair_collapse]},
  1003             dtac @{thm ssubst_mem[OF pair_collapse]},
  1004             REPEAT_DETERM o eresolve_tac (CollectE :: conjE ::
  1004             REPEAT_DETERM o eresolve_tac ctxt (CollectE :: conjE ::
  1005               @{thms case_prodE iffD1[OF prod.inject, elim_format]}),
  1005               @{thms case_prodE iffD1[OF prod.inject, elim_format]}),
  1006             hyp_subst_tac ctxt, dtac (in_Jrel RS iffD1),
  1006             hyp_subst_tac ctxt, dtac (in_Jrel RS iffD1),
  1007             dtac @{thm someI_ex}, REPEAT_DETERM o etac conjE, atac]) in_Jrels),
  1007             dtac @{thm someI_ex}, REPEAT_DETERM o etac conjE, atac]) in_Jrels),
  1008           atac]]
  1008           atac]]
  1009   in
  1009   in
  1018     val snd_diag_nth = if fst then @{thm snd_diag_fst} else @{thm snd_diag_snd};
  1018     val snd_diag_nth = if fst then @{thm snd_diag_fst} else @{thm snd_diag_snd};
  1019   in
  1019   in
  1020     EVERY' [rtac coinduct,
  1020     EVERY' [rtac coinduct,
  1021       EVERY' (@{map 8} (fn i => fn map_comp0 => fn map_cong => fn map_arg_cong => fn set_map0s =>
  1021       EVERY' (@{map 8} (fn i => fn map_comp0 => fn map_cong => fn map_arg_cong => fn set_map0s =>
  1022           fn dtor_unfold => fn dtor_map => fn in_rel =>
  1022           fn dtor_unfold => fn dtor_map => fn in_rel =>
  1023         EVERY' [REPEAT_DETERM o resolve_tac [allI, impI, in_rel RS iffD2],
  1023         EVERY' [REPEAT_DETERM o resolve_tac ctxt [allI, impI, in_rel RS iffD2],
  1024           REPEAT_DETERM o eresolve_tac [exE, conjE],
  1024           REPEAT_DETERM o eresolve_tac ctxt [exE, conjE],
  1025           select_prem_tac (length ks) (dtac @{thm spec2}) i, dtac mp, atac,
  1025           select_prem_tac (length ks) (dtac @{thm spec2}) i, dtac mp, atac,
  1026           REPEAT_DETERM o eresolve_tac [CollectE, conjE], hyp_subst_tac ctxt,
  1026           REPEAT_DETERM o eresolve_tac ctxt [CollectE, conjE], hyp_subst_tac ctxt,
  1027           rtac exI, rtac (Drule.rotate_prems 1 conjI), rtac conjI,
  1027           rtac exI, rtac (Drule.rotate_prems 1 conjI), rtac conjI,
  1028           rtac (map_comp0 RS trans), rtac (dtor_map RS trans RS sym),
  1028           rtac (map_comp0 RS trans), rtac (dtor_map RS trans RS sym),
  1029           rtac (dtor_unfold RS map_arg_cong RS trans), rtac (trans OF [map_comp0, map_cong]),
  1029           rtac (dtor_unfold RS map_arg_cong RS trans), rtac (trans OF [map_comp0, map_cong]),
  1030           REPEAT_DETERM_N m o rtac (fst_diag_nth RS @{thm fun_cong[OF trans[OF o_id sym]]}),
  1030           REPEAT_DETERM_N m o rtac (fst_diag_nth RS @{thm fun_cong[OF trans[OF o_id sym]]}),
  1031           REPEAT_DETERM_N n o (rtac @{thm sym[OF trans[OF o_apply]]} THEN' rtac @{thm fst_conv}),
  1031           REPEAT_DETERM_N n o (rtac @{thm sym[OF trans[OF o_apply]]} THEN' rtac @{thm fst_conv}),
  1049 fun mk_rel_coinduct_ind_tac ctxt m ks unfolds set_map0ss j set_induct =
  1049 fun mk_rel_coinduct_ind_tac ctxt m ks unfolds set_map0ss j set_induct =
  1050   let val n = length ks;
  1050   let val n = length ks;
  1051   in
  1051   in
  1052     rtac set_induct 1 THEN
  1052     rtac set_induct 1 THEN
  1053     EVERY' (@{map 3} (fn unfold => fn set_map0s => fn i =>
  1053     EVERY' (@{map 3} (fn unfold => fn set_map0s => fn i =>
  1054       EVERY' [REPEAT_DETERM o resolve_tac [allI, impI], etac conjE,
  1054       EVERY' [REPEAT_DETERM o resolve_tac ctxt [allI, impI], etac conjE,
  1055         select_prem_tac n (dtac @{thm spec2}) i, dtac mp, atac,
  1055         select_prem_tac n (dtac @{thm spec2}) i, dtac mp, atac,
  1056         REPEAT_DETERM o eresolve_tac [CollectE, conjE, Collect_splitD_set_mp, set_rev_mp],
  1056         REPEAT_DETERM o eresolve_tac ctxt [CollectE, conjE, Collect_splitD_set_mp, set_rev_mp],
  1057         hyp_subst_tac ctxt,
  1057         hyp_subst_tac ctxt,
  1058         SELECT_GOAL (unfold_thms_tac ctxt ([unfold, nth set_map0s (j - 1)] @ split_id_unfolds)),
  1058         SELECT_GOAL (unfold_thms_tac ctxt ([unfold, nth set_map0s (j - 1)] @ split_id_unfolds)),
  1059         rtac subset_refl])
  1059         rtac subset_refl])
  1060     unfolds set_map0ss ks) 1 THEN
  1060     unfolds set_map0ss ks) 1 THEN
  1061     EVERY' (@{map 3} (fn unfold => fn set_map0s => fn i =>
  1061     EVERY' (@{map 3} (fn unfold => fn set_map0s => fn i =>
  1062       EVERY' (map (fn set_map0 =>
  1062       EVERY' (map (fn set_map0 =>
  1063         EVERY' [REPEAT_DETERM o resolve_tac [allI, impI], etac conjE,
  1063         EVERY' [REPEAT_DETERM o resolve_tac ctxt [allI, impI], etac conjE,
  1064         select_prem_tac n (dtac @{thm spec2}) i, dtac mp, atac,
  1064         select_prem_tac n (dtac @{thm spec2}) i, dtac mp, atac,
  1065         REPEAT_DETERM o eresolve_tac [CollectE, conjE], hyp_subst_tac ctxt,
  1065         REPEAT_DETERM o eresolve_tac ctxt [CollectE, conjE], hyp_subst_tac ctxt,
  1066         SELECT_GOAL (unfold_thms_tac ctxt ([unfold, set_map0] @ split_id_unfolds)),
  1066         SELECT_GOAL (unfold_thms_tac ctxt ([unfold, set_map0] @ split_id_unfolds)),
  1067         etac imageE, hyp_subst_tac ctxt, REPEAT_DETERM o eresolve_tac [allE, mp],
  1067         etac imageE, hyp_subst_tac ctxt, REPEAT_DETERM o eresolve_tac ctxt [allE, mp],
  1068         rtac conjI, etac Collect_splitD_set_mp, atac, rtac (@{thm surjective_pairing} RS arg_cong)])
  1068         rtac conjI, etac Collect_splitD_set_mp, atac, rtac (@{thm surjective_pairing} RS arg_cong)])
  1069       (drop m set_map0s)))
  1069       (drop m set_map0s)))
  1070     unfolds set_map0ss ks) 1
  1070     unfolds set_map0ss ks) 1
  1071   end;
  1071   end;
  1072 
  1072 
  1081         if null helper_inds then rtac UNIV_I
  1081         if null helper_inds then rtac UNIV_I
  1082         else rtac CollectI THEN'
  1082         else rtac CollectI THEN'
  1083           CONJ_WRAP' (fn helper_ind =>
  1083           CONJ_WRAP' (fn helper_ind =>
  1084             EVERY' [rtac (helper_ind RS rev_mp), REPEAT_DETERM_N n o atac,
  1084             EVERY' [rtac (helper_ind RS rev_mp), REPEAT_DETERM_N n o atac,
  1085               REPEAT_DETERM_N n o etac thin_rl, rtac impI,
  1085               REPEAT_DETERM_N n o etac thin_rl, rtac impI,
  1086               REPEAT_DETERM o resolve_tac [subsetI, CollectI, @{thm iffD2[OF split_beta]}],
  1086               REPEAT_DETERM o resolve_tac ctxt [subsetI, CollectI, @{thm iffD2[OF split_beta]}],
  1087               dtac bspec, atac, REPEAT_DETERM o eresolve_tac [allE, mp, conjE],
  1087               dtac bspec, atac, REPEAT_DETERM o eresolve_tac ctxt [allE, mp, conjE],
  1088               etac (refl RSN (2, conjI))])
  1088               etac (refl RSN (2, conjI))])
  1089           helper_inds,
  1089           helper_inds,
  1090         rtac conjI,
  1090         rtac conjI,
  1091         rtac (helper_coind1 RS rev_mp), REPEAT_DETERM_N n o atac, REPEAT_DETERM_N n o etac thin_rl,
  1091         rtac (helper_coind1 RS rev_mp), REPEAT_DETERM_N n o atac, REPEAT_DETERM_N n o etac thin_rl,
  1092         rtac impI, etac mp, rtac exI, etac (refl RSN (2, conjI)),
  1092         rtac impI, etac mp, rtac exI, etac (refl RSN (2, conjI)),
  1101   in
  1101   in
  1102     unfold_thms_tac ctxt
  1102     unfold_thms_tac ctxt
  1103       @{thms rel_fun_def_butlast all_conj_distrib[symmetric] imp_conjR[symmetric]} THEN
  1103       @{thms rel_fun_def_butlast all_conj_distrib[symmetric] imp_conjR[symmetric]} THEN
  1104     unfold_thms_tac ctxt @{thms rel_fun_iff_geq_image2p} THEN
  1104     unfold_thms_tac ctxt @{thms rel_fun_iff_geq_image2p} THEN
  1105     HEADGOAL (EVERY'
  1105     HEADGOAL (EVERY'
  1106       [REPEAT_DETERM o resolve_tac [allI, impI], rtac ctor_rel_coinduct,
  1106       [REPEAT_DETERM o resolve_tac ctxt [allI, impI], rtac ctor_rel_coinduct,
  1107       EVERY' (map (fn map_transfer => EVERY'
  1107       EVERY' (map (fn map_transfer => EVERY'
  1108         [REPEAT_DETERM o resolve_tac [allI, impI], etac @{thm image2pE}, hyp_subst_tac ctxt,
  1108         [REPEAT_DETERM o resolve_tac ctxt [allI, impI], etac @{thm image2pE}, hyp_subst_tac ctxt,
  1109         SELECT_GOAL (unfold_thms_tac ctxt unfolds),
  1109         SELECT_GOAL (unfold_thms_tac ctxt unfolds),
  1110         rtac (funpow (m + n + 1) (fn thm => thm RS rel_funD) map_transfer),
  1110         rtac (funpow (m + n + 1) (fn thm => thm RS rel_funD) map_transfer),
  1111         REPEAT_DETERM_N m o rtac @{thm id_transfer},
  1111         REPEAT_DETERM_N m o rtac @{thm id_transfer},
  1112         REPEAT_DETERM_N n o rtac @{thm rel_fun_image2p},
  1112         REPEAT_DETERM_N n o rtac @{thm rel_fun_image2p},
  1113         etac @{thm predicate2D}, etac @{thm image2pI}])
  1113         etac @{thm predicate2D}, etac @{thm image2pI}])