Nominal/nominal_dt_alpha.ML
changeset 3239 67370521c09c
parent 3229 b52e8651591f
child 3243 c4f31f1564b7
equal deleted inserted replaced
3238:b2e1a7b83e05 3239:67370521c09c
   160   end
   160   end
   161 
   161 
   162 (* produces the introduction rule for an alpha rule *)
   162 (* produces the introduction rule for an alpha rule *)
   163 fun mk_alpha_intros lthy alpha_map alpha_bn_map (constr, ty, arg_tys, is_rec) bclauses = 
   163 fun mk_alpha_intros lthy alpha_map alpha_bn_map (constr, ty, arg_tys, is_rec) bclauses = 
   164   let
   164   let
   165     val arg_names = Datatype_Prop.make_tnames arg_tys
   165     val arg_names = Old_Datatype_Prop.make_tnames arg_tys
   166     val arg_names' = Name.variant_list arg_names arg_names
   166     val arg_names' = Name.variant_list arg_names arg_names
   167     val args = map Free (arg_names ~~ arg_tys)
   167     val args = map Free (arg_names ~~ arg_tys)
   168     val args' = map Free (arg_names' ~~ arg_tys)
   168     val args' = map Free (arg_names' ~~ arg_tys)
   169     val alpha = fst (lookup alpha_map ty)
   169     val alpha = fst (lookup alpha_map ty)
   170     val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args'))
   170     val concl = HOLogic.mk_Trueprop (alpha $ list_comb (constr, args) $ list_comb (constr, args'))
   203     | _ => mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause
   203     | _ => mk_alpha_prems lthy alpha_map alpha_bn_map is_rec (args, args') bclause
   204   end
   204   end
   205 
   205 
   206 fun mk_alpha_bn_intro lthy bn_trm alpha_map alpha_bn_map (bn_args, (constr, _, arg_tys, is_rec)) bclauses =
   206 fun mk_alpha_bn_intro lthy bn_trm alpha_map alpha_bn_map (bn_args, (constr, _, arg_tys, is_rec)) bclauses =
   207   let
   207   let
   208     val arg_names = Datatype_Prop.make_tnames arg_tys
   208     val arg_names = Old_Datatype_Prop.make_tnames arg_tys
   209     val arg_names' = Name.variant_list arg_names arg_names
   209     val arg_names' = Name.variant_list arg_names arg_names
   210     val args = map Free (arg_names ~~ arg_tys)
   210     val args = map Free (arg_names ~~ arg_tys)
   211     val args' = map Free (arg_names' ~~ arg_tys)
   211     val args' = map Free (arg_names' ~~ arg_tys)
   212     val alpha_bn = lookup alpha_bn_map bn_trm
   212     val alpha_bn = lookup alpha_bn_map bn_trm
   213     val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args'))
   213     val concl = HOLogic.mk_Trueprop (alpha_bn $ list_comb (constr, args) $ list_comb (constr, args'))
   313 
   313 
   314     fun tac ctxt =
   314     fun tac ctxt =
   315       HEADGOAL 
   315       HEADGOAL 
   316         (DETERM o (rtac induct_thm) 
   316         (DETERM o (rtac induct_thm) 
   317          THEN_ALL_NEW 
   317          THEN_ALL_NEW 
   318            (REPEAT_ALL_NEW (FIRST' [resolve_tac @{thms TrueI conjI}, cases_tac ctxt])))
   318            (REPEAT_ALL_NEW (FIRST' [resolve_tac ctxt @{thms TrueI conjI}, cases_tac ctxt])))
   319   in
   319   in
   320     Goal.prove ctxt' [] [] goals (fn {context, ...} => tac context)
   320     Goal.prove ctxt' [] [] goals (fn {context, ...} => tac context)
   321     |> singleton (Proof_Context.export ctxt' ctxt)
   321     |> singleton (Proof_Context.export ctxt' ctxt)
   322     |> Datatype_Aux.split_conj_thm
   322     |> Old_Datatype_Aux.split_conj_thm
   323     |> map Datatype_Aux.split_conj_thm
   323     |> map Old_Datatype_Aux.split_conj_thm
   324     |> flat
   324     |> flat
   325     |> filter_out (is_true o concl_of)
   325     |> filter_out (is_true o Thm.concl_of)
   326     |> map zero_var_indexes
   326     |> map zero_var_indexes
   327   end
   327   end
   328 
   328 
   329 (* proof by rule induction over the alpha-definitions *)
   329 (* proof by rule induction over the alpha-definitions *)
   330 
   330 
   363         (DETERM o (rtac alpha_induct_thm) 
   363         (DETERM o (rtac alpha_induct_thm) 
   364          THEN_ALL_NEW FIRST' [rtac @{thm TrueI}, cases_tac ctxt])
   364          THEN_ALL_NEW FIRST' [rtac @{thm TrueI}, cases_tac ctxt])
   365   in
   365   in
   366     Goal.prove ctxt' [] [] goals (fn {context, ...} => tac context)
   366     Goal.prove ctxt' [] [] goals (fn {context, ...} => tac context)
   367     |> singleton (Proof_Context.export ctxt' ctxt)
   367     |> singleton (Proof_Context.export ctxt' ctxt)
   368     |> Datatype_Aux.split_conj_thm
   368     |> Old_Datatype_Aux.split_conj_thm
   369     |> map (fn th => th RS mp) 
   369     |> map (fn th => th RS mp) 
   370     |> map Datatype_Aux.split_conj_thm
   370     |> map Old_Datatype_Aux.split_conj_thm
   371     |> flat
   371     |> flat
   372     |> filter_out (is_true o concl_of)
   372     |> filter_out (is_true o Thm.concl_of)
   373     |> map zero_var_indexes
   373     |> map zero_var_indexes
   374   end
   374   end
   375 
   375 
   376 
   376 
   377 
   377 
   390     |> HOLogic.mk_not
   390     |> HOLogic.mk_not
   391     |> HOLogic.mk_Trueprop
   391     |> HOLogic.mk_Trueprop
   392   end
   392   end
   393 
   393 
   394 fun distinct_tac ctxt cases_thms distinct_thms =
   394 fun distinct_tac ctxt cases_thms distinct_thms =
   395   rtac notI THEN' eresolve_tac cases_thms 
   395   rtac notI THEN' eresolve_tac ctxt cases_thms 
   396   THEN_ALL_NEW asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps distinct_thms)
   396   THEN_ALL_NEW asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps distinct_thms)
   397 
   397 
   398 fun raw_prove_alpha_distincts ctxt alpha_result raw_dt_info =
   398 fun raw_prove_alpha_distincts ctxt alpha_result raw_dt_info =
   399   let
   399   let
   400     val AlphaResult {alpha_names, alpha_cases, ...} = alpha_result
   400     val AlphaResult {alpha_names, alpha_cases, ...} = alpha_result
   408     in
   408     in
   409       Goal.prove ctxt [] [] goal 
   409       Goal.prove ctxt [] [] goal 
   410         (K (distinct_tac ctxt alpha_cases raw_distinct_thms 1))
   410         (K (distinct_tac ctxt alpha_cases raw_distinct_thms 1))
   411     end
   411     end
   412   in
   412   in
   413     map (mk_alpha_distinct o prop_of) raw_distinct_thms
   413     map (mk_alpha_distinct o Thm.prop_of) raw_distinct_thms
   414   end
   414   end
   415 
   415 
   416 
   416 
   417 
   417 
   418 (** produces the alpha_eq_iff simplification rules **)
   418 (** produces the alpha_eq_iff simplification rules **)
   419 
   419 
   420 (* in case a theorem is of the form (Rel Const Const), it will be
   420 (* in case a theorem is of the form (Rel Const Const), it will be
   421    rewritten to ((Rel Const = Const) = True) 
   421    rewritten to ((Rel Const = Const) = True) 
   422 *)
   422 *)
   423 fun mk_simp_rule thm =
   423 fun mk_simp_rule thm =
   424   case (prop_of thm) of
   424   case Thm.prop_of thm of
   425     @{term "Trueprop"} $ (_ $ Const _ $ Const _) => thm RS @{thm eqTrueI}
   425     @{term "Trueprop"} $ (_ $ Const _ $ Const _) => thm RS @{thm eqTrueI}
   426   | _ => thm
   426   | _ => thm
   427 
   427 
   428 fun alpha_eq_iff_tac ctxt dist_inj intros elims =
   428 fun alpha_eq_iff_tac ctxt dist_inj intros elims =
   429   SOLVED' (asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps intros)) ORELSE'
   429   SOLVED' (asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps intros)) ORELSE'
   430   (rtac @{thm iffI} THEN' 
   430   (rtac @{thm iffI} THEN' 
   431     RANGE [eresolve_tac elims THEN_ALL_NEW asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps dist_inj),
   431     RANGE [eresolve_tac ctxt elims THEN_ALL_NEW asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps dist_inj),
   432            asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps intros)])
   432            asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps intros)])
   433 
   433 
   434 fun mk_alpha_eq_iff_goal thm =
   434 fun mk_alpha_eq_iff_goal thm =
   435   let
   435   let
   436     val prop = prop_of thm;
   436     val prop = Thm.prop_of thm;
   437     val concl = HOLogic.dest_Trueprop (Logic.strip_imp_concl prop);
   437     val concl = HOLogic.dest_Trueprop (Logic.strip_imp_concl prop);
   438     val hyps = map HOLogic.dest_Trueprop (Logic.strip_imp_prems prop);
   438     val hyps = map HOLogic.dest_Trueprop (Logic.strip_imp_prems prop);
   439     fun list_conj l = foldr1 HOLogic.mk_conj l;
   439     fun list_conj l = foldr1 HOLogic.mk_conj l;
   440   in
   440   in
   441     if hyps = [] then HOLogic.mk_Trueprop concl
   441     if hyps = [] then HOLogic.mk_Trueprop concl
   461 
   461 
   462 val exi_zero = @{lemma "P (0::perm) ==> (? x. P x)" by auto}
   462 val exi_zero = @{lemma "P (0::perm) ==> (? x. P x)" by auto}
   463 
   463 
   464 fun cases_tac intros ctxt =
   464 fun cases_tac intros ctxt =
   465   let
   465   let
   466     val prod_simps = @{thms split_conv prod_alpha_def rel_prod_def}
   466     val prod_simps = @{thms split_conv prod_alpha_def rel_prod_conv}
   467 
   467 
   468     val unbound_tac = REPEAT o (etac @{thm conjE}) THEN' atac  
   468     val unbound_tac = REPEAT o (etac @{thm conjE}) THEN' assume_tac ctxt  
   469 
   469 
   470     val bound_tac = 
   470     val bound_tac = 
   471       EVERY' [ rtac exi_zero, 
   471       EVERY' [ rtac exi_zero, 
   472                resolve_tac @{thms alpha_refl}, 
   472                resolve_tac ctxt @{thms alpha_refl}, 
   473                asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps prod_simps) ]
   473                asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps prod_simps) ]
   474   in
   474   in
   475     resolve_tac intros THEN_ALL_NEW FIRST' [rtac @{thm refl}, unbound_tac, bound_tac]
   475     resolve_tac ctxt intros THEN_ALL_NEW FIRST' [rtac @{thm refl}, unbound_tac, bound_tac]
   476   end
   476   end
   477 
   477 
   478 fun raw_prove_refl ctxt alpha_result raw_dt_induct =
   478 fun raw_prove_refl ctxt alpha_result raw_dt_induct =
   479   let
   479   let
   480     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_bn_tys, alpha_intros, ...} = 
   480     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_bn_tys, alpha_intros, ...} = 
   500     fun trans_prem_tac pred_names ctxt = 
   500     fun trans_prem_tac pred_names ctxt = 
   501       SUBPROOF (fn {prems, context, ...} => 
   501       SUBPROOF (fn {prems, context, ...} => 
   502         let
   502         let
   503           val prems' = map (transform_prem1 context pred_names) prems
   503           val prems' = map (transform_prem1 context pred_names) prems
   504         in
   504         in
   505           resolve_tac prems' 1
   505           resolve_tac ctxt prems' 1
   506         end) ctxt
   506         end) ctxt
   507     val prod_simps = @{thms split_conv permute_prod.simps prod_alpha_def rel_prod_def alphas}
   507     val prod_simps = @{thms split_conv permute_prod.simps prod_alpha_def rel_prod_conv alphas}
   508   in
   508   in
   509     EVERY' 
   509     EVERY' 
   510       [ etac exi_neg,
   510       [ etac exi_neg,
   511         resolve_tac @{thms alpha_sym_eqvt},
   511         resolve_tac ctxt @{thms alpha_sym_eqvt},
   512         asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps prod_simps),
   512         asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps prod_simps),
   513         eqvt_tac ctxt (eqvt_relaxed_config addpres alpha_eqvt) THEN' rtac @{thm refl},
   513         eqvt_tac ctxt (eqvt_relaxed_config addpres alpha_eqvt) THEN' rtac @{thm refl},
   514         trans_prem_tac pred_names ctxt] 
   514         trans_prem_tac pred_names ctxt] 
   515   end
   515   end
   516 
   516 
   523     val alpha_names = alpha_names @ alpha_bn_names 
   523     val alpha_names = alpha_names @ alpha_bn_names 
   524 
   524 
   525     val props = map (fn t => fn (x, y) => t $ y $ x) alpha_trms
   525     val props = map (fn t => fn (x, y) => t $ y $ x) alpha_trms
   526 
   526 
   527     fun tac ctxt = 
   527     fun tac ctxt = 
   528       resolve_tac alpha_intros THEN_ALL_NEW 
   528       resolve_tac ctxt alpha_intros THEN_ALL_NEW 
   529       FIRST' [atac, rtac @{thm sym} THEN' atac, prem_bound_tac alpha_names alpha_eqvt ctxt]
   529       FIRST' [assume_tac ctxt,
       
   530         rtac @{thm sym} THEN' assume_tac ctxt,
       
   531         prem_bound_tac alpha_names alpha_eqvt ctxt]
   530   in
   532   in
   531     alpha_prove alpha_trms (alpha_trms ~~ props) alpha_raw_induct tac ctxt 
   533     alpha_prove alpha_trms (alpha_trms ~~ props) alpha_raw_induct tac ctxt 
   532   end
   534   end
   533 
   535 
   534 
   536 
   535 (** transitivity proof for alphas **)
   537 (** transitivity proof for alphas **)
   536 
   538 
   537 (* applies cases rules and resolves them with the last premise *)
   539 (* applies cases rules and resolves them with the last premise *)
   538 fun ecases_tac cases = 
   540 fun ecases_tac cases = 
   539   Subgoal.FOCUS (fn {prems, ...} =>
   541   Subgoal.FOCUS (fn {context = ctxt, prems, ...} =>
   540     HEADGOAL (resolve_tac cases THEN' rtac (List.last prems)))
   542     HEADGOAL (resolve_tac ctxt cases THEN' rtac (List.last prems)))
   541 
   543 
   542 fun aatac pred_names = 
   544 fun aatac pred_names = 
   543   SUBPROOF (fn {prems, context, ...} =>
   545   SUBPROOF (fn {context = ctxt, prems, ...} =>
   544     HEADGOAL (resolve_tac (map (transform_prem1 context pred_names) prems)))
   546     HEADGOAL (resolve_tac ctxt (map (transform_prem1 ctxt pred_names) prems)))
   545   
   547   
   546 (* instantiates exI with the permutation p + q *)
   548 (* instantiates exI with the permutation p + q *)
   547 val perm_inst_tac =
   549 val perm_inst_tac =
   548   Subgoal.FOCUS (fn {params, ...} => 
   550   Subgoal.FOCUS (fn {params, ...} => 
   549     let
   551     let
   550       val (p, q) = pairself snd (last2 params)
   552       val (p, q) = apply2 snd (last2 params)
   551       val pq_inst = foldl1 (uncurry Thm.apply) [@{cterm "plus::perm => perm => perm"}, p, q]
   553       val pq_inst = foldl1 (uncurry Thm.apply) [@{cterm "plus::perm => perm => perm"}, p, q]
   552       val exi_inst = Drule.instantiate' [SOME (@{ctyp "perm"})] [NONE, SOME pq_inst] @{thm exI}
   554       val exi_inst = Drule.instantiate' [SOME (@{ctyp "perm"})] [NONE, SOME pq_inst] @{thm exI}
   553     in
   555     in
   554       HEADGOAL (rtac exi_inst)
   556       HEADGOAL (rtac exi_inst)
   555     end)
   557     end)
   556 
   558 
   557 fun non_trivial_cases_tac pred_names intros alpha_eqvt ctxt = 
   559 fun non_trivial_cases_tac pred_names intros alpha_eqvt ctxt = 
   558   let
   560   let
   559     val prod_simps = @{thms split_conv alphas permute_prod.simps prod_alpha_def rel_prod_def}
   561     val prod_simps = @{thms split_conv alphas permute_prod.simps prod_alpha_def rel_prod_conv}
   560   in
   562   in
   561     resolve_tac intros
   563     resolve_tac ctxt intros
   562     THEN_ALL_NEW (asm_simp_tac (put_simpset HOL_basic_ss ctxt) THEN' 
   564     THEN_ALL_NEW (asm_simp_tac (put_simpset HOL_basic_ss ctxt) THEN' 
   563       TRY o EVERY'   (* if binders are present *)
   565       TRY o EVERY'   (* if binders are present *)
   564         [ etac @{thm exE},
   566         [ etac @{thm exE},
   565           etac @{thm exE},
   567           etac @{thm exE},
   566           perm_inst_tac ctxt, 
   568           perm_inst_tac ctxt, 
   567           resolve_tac @{thms alpha_trans_eqvt},
   569           resolve_tac ctxt @{thms alpha_trans_eqvt},
   568           atac,
   570           assume_tac ctxt,
   569           aatac pred_names ctxt, 
   571           aatac pred_names ctxt, 
   570           eqvt_tac ctxt (eqvt_relaxed_config addpres alpha_eqvt) THEN' rtac @{thm refl},
   572           eqvt_tac ctxt (eqvt_relaxed_config addpres alpha_eqvt) THEN' rtac @{thm refl},
   571           asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps prod_simps) ])
   573           asm_full_simp_tac (put_simpset HOL_ss ctxt addsimps prod_simps) ])
   572   end
   574   end
   573 
   575 
   628     val trans' = map (fold_rule ctxt [transp_def'] o atomize ctxt) trans
   630     val trans' = map (fold_rule ctxt [transp_def'] o atomize ctxt) trans
   629 
   631 
   630     fun prep_goal t = 
   632     fun prep_goal t = 
   631       HOLogic.mk_Trueprop (Const (@{const_name "equivp"}, fastype_of t --> @{typ bool}) $ t) 
   633       HOLogic.mk_Trueprop (Const (@{const_name "equivp"}, fastype_of t --> @{typ bool}) $ t) 
   632   in    
   634   in    
   633     Goal.prove_multi ctxt [] [] (map prep_goal (alpha_trms @ alpha_bn_trms))
   635     Goal.prove_common ctxt NONE [] [] (map prep_goal (alpha_trms @ alpha_bn_trms))
   634     (K (HEADGOAL (Goal.conjunction_tac THEN_ALL_NEW (rtac @{thm equivpI} THEN' 
   636     (K (HEADGOAL (Goal.conjunction_tac THEN_ALL_NEW (rtac @{thm equivpI} THEN' 
   635        RANGE [resolve_tac refl', resolve_tac symm', resolve_tac trans']))))
   637        RANGE [resolve_tac ctxt refl', resolve_tac ctxt symm', resolve_tac ctxt trans']))))
   636     |> chop (length alpha_trms)
   638     |> chop (length alpha_trms)
   637   end
   639   end
   638 
   640 
   639 
   641 
   640 (* proves that alpha_raw implies alpha_bn *)
   642 (* proves that alpha_raw implies alpha_bn *)
   642 fun raw_prove_bn_imp_tac alpha_result ctxt = 
   644 fun raw_prove_bn_imp_tac alpha_result ctxt = 
   643   SUBPROOF (fn {prems, context, ...} => 
   645   SUBPROOF (fn {prems, context, ...} => 
   644     let
   646     let
   645       val AlphaResult {alpha_names, alpha_intros, ...} = alpha_result 
   647       val AlphaResult {alpha_names, alpha_intros, ...} = alpha_result 
   646 
   648 
   647       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
   649       val prems' = flat (map Old_Datatype_Aux.split_conj_thm prems)
   648       val prems'' = map (transform_prem1 context alpha_names) prems'
   650       val prems'' = map (transform_prem1 context alpha_names) prems'
   649     in
   651     in
   650       HEADGOAL 
   652       HEADGOAL 
   651         (REPEAT_ALL_NEW 
   653         (REPEAT_ALL_NEW 
   652            (FIRST' [ rtac @{thm TrueI}, 
   654            (FIRST' [ rtac @{thm TrueI}, 
   653                      rtac @{thm conjI}, 
   655                      rtac @{thm conjI}, 
   654                      resolve_tac prems', 
   656                      resolve_tac ctxt prems', 
   655                      resolve_tac prems'',
   657                      resolve_tac ctxt prems'',
   656                      resolve_tac alpha_intros ]))
   658                      resolve_tac ctxt alpha_intros ]))
   657     end) ctxt
   659     end) ctxt
   658 
   660 
   659 
   661 
   660 fun raw_prove_bn_imp ctxt alpha_result =
   662 fun raw_prove_bn_imp ctxt alpha_result =
   661   let
   663   let
   704       (HOLogic.size_const ty $ x, HOLogic.size_const ty $ y)
   706       (HOLogic.size_const ty $ x, HOLogic.size_const ty $ y)
   705 
   707 
   706     val props = (alpha_trms @ alpha_bn_trms) ~~ (map mk_prop (alpha_tys @ alpha_bn_tys)) 
   708     val props = (alpha_trms @ alpha_bn_trms) ~~ (map mk_prop (alpha_tys @ alpha_bn_tys)) 
   707   
   709   
   708     val simpset =
   710     val simpset =
   709       put_simpset HOL_ss ctxt addsimps (simps @ @{thms alphas prod_alpha_def rel_prod_def 
   711       put_simpset HOL_ss ctxt addsimps (simps @ @{thms alphas prod_alpha_def rel_prod_conv 
   710       permute_prod_def prod.case prod.rec})
   712       permute_prod_def prod.case prod.rec})
   711 
   713 
   712     val tac = (TRY o REPEAT o etac @{thm exE}) THEN' asm_full_simp_tac simpset
   714     val tac = (TRY o REPEAT o etac @{thm exE}) THEN' asm_full_simp_tac simpset
   713   in
   715   in
   714     alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_raw_induct (K tac) ctxt
   716     alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_raw_induct (K tac) ctxt
   718 (* respectfulness for constructors *)
   720 (* respectfulness for constructors *)
   719 
   721 
   720 fun raw_constr_rsp_tac ctxt alpha_intros simps = 
   722 fun raw_constr_rsp_tac ctxt alpha_intros simps = 
   721   let
   723   let
   722     val pre_simpset = put_simpset HOL_ss ctxt addsimps @{thms rel_fun_def}
   724     val pre_simpset = put_simpset HOL_ss ctxt addsimps @{thms rel_fun_def}
   723     val post_simpset = put_simpset HOL_ss ctxt addsimps @{thms alphas prod_alpha_def rel_prod_def 
   725     val post_simpset = put_simpset HOL_ss ctxt addsimps @{thms alphas prod_alpha_def rel_prod_conv 
   724       prod_fv.simps fresh_star_zero permute_zero prod.case} @ simps
   726       prod_fv.simps fresh_star_zero permute_zero prod.case} @ simps
   725   in
   727   in
   726     asm_full_simp_tac pre_simpset
   728     asm_full_simp_tac pre_simpset
   727     THEN' REPEAT o (resolve_tac @{thms allI impI})
   729     THEN' REPEAT o (resolve_tac ctxt @{thms allI impI})
   728     THEN' resolve_tac alpha_intros
   730     THEN' resolve_tac ctxt alpha_intros
   729     THEN_ALL_NEW (TRY o (rtac exi_zero) THEN' asm_full_simp_tac post_simpset)
   731     THEN_ALL_NEW (TRY o (rtac exi_zero) THEN' asm_full_simp_tac post_simpset)
   730   end
   732   end
   731 
   733 
   732 fun raw_constrs_rsp ctxt alpha_result constrs simps =
   734 fun raw_constrs_rsp ctxt alpha_result constrs simps =
   733   let
   735   let
   750       |> (fn t => t $ trm $ trm)
   752       |> (fn t => t $ trm $ trm)
   751       |> Syntax.check_term ctxt
   753       |> Syntax.check_term ctxt
   752       |> HOLogic.mk_Trueprop
   754       |> HOLogic.mk_Trueprop
   753   in
   755   in
   754     map (fn constrs =>
   756     map (fn constrs =>
   755     Goal.prove_multi ctxt [] [] (map prep_goal constrs)
   757     Goal.prove_common ctxt NONE [] [] (map prep_goal constrs)
   756       (K (HEADGOAL 
   758       (K (HEADGOAL 
   757         (Goal.conjunction_tac THEN_ALL_NEW raw_constr_rsp_tac ctxt alpha_intros simps)))) constrs
   759         (Goal.conjunction_tac THEN_ALL_NEW raw_constr_rsp_tac ctxt alpha_intros simps)))) constrs
   758   end
   760   end
   759 
   761 
   760 
   762 
   770 fun raw_alpha_bn_rsp alpha_result alpha_bn_equivp alpha_bn_imps =
   772 fun raw_alpha_bn_rsp alpha_result alpha_bn_equivp alpha_bn_imps =
   771   let
   773   let
   772     val AlphaResult {alpha_bn_trms, ...} = alpha_result 
   774     val AlphaResult {alpha_bn_trms, ...} = alpha_result 
   773 
   775 
   774     fun mk_map thm =
   776     fun mk_map thm =
   775       thm |> `prop_of
   777       thm |> `Thm.prop_of
   776           |>> List.last  o snd o strip_comb
   778           |>> List.last  o snd o strip_comb
   777           |>> HOLogic.dest_Trueprop
   779           |>> HOLogic.dest_Trueprop
   778           |>> head_of
   780           |>> head_of
   779           |>> fst o dest_Const
   781           |>> fst o dest_Const
   780 
   782 
   795 
   797 
   796 fun raw_prove_perm_bn_tac alpha_result simps ctxt = 
   798 fun raw_prove_perm_bn_tac alpha_result simps ctxt = 
   797   SUBPROOF (fn {prems, context, ...} => 
   799   SUBPROOF (fn {prems, context, ...} => 
   798     let
   800     let
   799       val AlphaResult {alpha_names, alpha_bn_names, alpha_intros, ...} = alpha_result 
   801       val AlphaResult {alpha_names, alpha_bn_names, alpha_intros, ...} = alpha_result 
   800       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
   802       val prems' = flat (map Old_Datatype_Aux.split_conj_thm prems)
   801       val prems'' = map (transform_prem1 context (alpha_names @ alpha_bn_names)) prems'
   803       val prems'' = map (transform_prem1 context (alpha_names @ alpha_bn_names)) prems'
   802     in
   804     in
   803       HEADGOAL 
   805       HEADGOAL 
   804         (simp_tac (put_simpset HOL_basic_ss ctxt addsimps (simps @ prems'))
   806         (simp_tac (put_simpset HOL_basic_ss ctxt addsimps (simps @ prems'))
   805          THEN' TRY o REPEAT_ALL_NEW 
   807          THEN' TRY o REPEAT_ALL_NEW 
   806            (FIRST' [ rtac @{thm TrueI}, 
   808            (FIRST' [ rtac @{thm TrueI}, 
   807                      rtac @{thm conjI}, 
   809                      rtac @{thm conjI}, 
   808                      rtac @{thm refl},
   810                      rtac @{thm refl},
   809                      resolve_tac prems', 
   811                      resolve_tac ctxt prems', 
   810                      resolve_tac prems'',
   812                      resolve_tac ctxt prems'',
   811                      resolve_tac alpha_intros ]))
   813                      resolve_tac ctxt alpha_intros ]))
   812     end) ctxt
   814     end) ctxt
   813 
   815 
   814 fun raw_perm_bn_rsp ctxt alpha_result perm_bns simps =
   816 fun raw_perm_bn_rsp ctxt alpha_result perm_bns simps =
   815   let
   817   let
   816     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_bn_tys, alpha_raw_induct, ...} = 
   818     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_bn_tys, alpha_raw_induct, ...} =