Nominal/nominal_dt_alpha.ML
changeset 2928 c537d43c09f1
parent 2927 116f9ba4f59f
child 2957 01ff621599bc
equal deleted inserted replaced
2927:116f9ba4f59f 2928:c537d43c09f1
     8 signature NOMINAL_DT_ALPHA =
     8 signature NOMINAL_DT_ALPHA =
     9 sig
     9 sig
    10   val comb_binders: Proof.context -> bmode -> term list -> (term option * int) list -> term
    10   val comb_binders: Proof.context -> bmode -> term list -> (term option * int) list -> term
    11 
    11 
    12   val define_raw_alpha: string list -> typ list -> cns_info list -> bn_info list -> 
    12   val define_raw_alpha: string list -> typ list -> cns_info list -> bn_info list -> 
    13     bclause list list list -> term list -> Proof.context -> 
    13     bclause list list list -> term list -> Proof.context -> alpha_result * local_theory
    14     term list * term list * thm list * thm list * thm * alpha_result * local_theory
       
    15 
    14 
    16   val induct_prove: typ list -> (typ * (term -> term)) list -> thm -> 
    15   val induct_prove: typ list -> (typ * (term -> term)) list -> thm -> 
    17     (Proof.context -> int -> tactic) -> Proof.context -> thm list
    16     (Proof.context -> int -> tactic) -> Proof.context -> thm list
    18   
    17   
    19   val alpha_prove: term list -> (term * ((term * term) -> term)) list -> thm -> 
    18   val alpha_prove: term list -> (term * ((term * term) -> term)) list -> thm -> 
    24   val raw_prove_refl: Proof.context -> alpha_result -> thm -> thm list
    23   val raw_prove_refl: Proof.context -> alpha_result -> thm -> thm list
    25   val raw_prove_sym: Proof.context -> alpha_result -> thm list -> thm list
    24   val raw_prove_sym: Proof.context -> alpha_result -> thm list -> thm list
    26   val raw_prove_trans: Proof.context -> alpha_result -> thm list -> thm list -> thm list
    25   val raw_prove_trans: Proof.context -> alpha_result -> thm list -> thm list -> thm list
    27   val raw_prove_equivp: Proof.context -> alpha_result -> thm list -> thm list -> thm list -> 
    26   val raw_prove_equivp: Proof.context -> alpha_result -> thm list -> thm list -> thm list -> 
    28     thm list * thm list
    27     thm list * thm list
    29   val raw_prove_bn_imp: term list -> term list -> thm list -> thm -> Proof.context -> thm list
    28   val raw_prove_bn_imp: Proof.context -> alpha_result -> thm list
    30   val raw_fv_bn_rsp_aux: term list -> term list -> term list -> term list -> 
    29   val raw_fv_bn_rsp_aux: Proof.context -> alpha_result -> term list -> term list -> term list -> 
    31     term list -> thm -> thm list -> Proof.context -> thm list
    30     thm list -> thm list
    32   val raw_size_rsp_aux: term list -> thm -> thm list -> Proof.context -> thm list
    31   val raw_size_rsp_aux: Proof.context -> alpha_result -> thm list -> thm list
    33   val raw_constrs_rsp: term list -> term list -> thm list -> thm list -> Proof.context -> thm list
    32   val raw_constrs_rsp: Proof.context -> alpha_result -> term list -> thm list -> thm list
    34   val raw_alpha_bn_rsp: term list -> thm list -> thm list -> thm list
    33   val raw_alpha_bn_rsp: alpha_result -> thm list -> thm list -> thm list
    35   val raw_perm_bn_rsp: term list -> term list -> thm -> thm list -> thm list -> 
    34   val raw_perm_bn_rsp: Proof.context -> alpha_result -> term list -> thm list -> thm list
    36     Proof.context -> thm list
       
    37   
    35   
    38   val mk_funs_rsp: thm -> thm
    36   val mk_funs_rsp: thm -> thm
    39   val mk_alpha_permute_rsp: thm -> thm 
    37   val mk_alpha_permute_rsp: thm -> thm 
    40 end
    38 end
    41 
    39 
   265     val alpha_raw_induct = Morphism.thm phi alpha_raw_induct_loc
   263     val alpha_raw_induct = Morphism.thm phi alpha_raw_induct_loc
   266     val alpha_intros = map (Morphism.thm phi) alpha_intros_loc
   264     val alpha_intros = map (Morphism.thm phi) alpha_intros_loc
   267     val alpha_cases = map (Morphism.thm phi) alpha_cases_loc
   265     val alpha_cases = map (Morphism.thm phi) alpha_cases_loc
   268 
   266 
   269     val (alpha_trms, alpha_bn_trms) = chop (length fvs) all_alpha_trms
   267     val (alpha_trms, alpha_bn_trms) = chop (length fvs) all_alpha_trms
   270     val alpha_tys = 
   268     
   271       alpha_trms
   269     val alpha_tys = map (domain_type o fastype_of) alpha_trms
   272       |> map fastype_of
   270     val alpha_bn_tys = map (domain_type o fastype_of) alpha_bn_trms
   273       |> map domain_type
       
   274 
       
   275     val alpha_bn_tys = 
       
   276       alpha_bn_trms
       
   277       |> map fastype_of
       
   278       |> map domain_type
       
   279 
   271 
   280     val alpha_names = map (fst o dest_Const) alpha_trms  
   272     val alpha_names = map (fst o dest_Const) alpha_trms  
   281     val alpha_bn_names = map (fst o dest_Const) alpha_bn_trms
   273     val alpha_bn_names = map (fst o dest_Const) alpha_bn_trms
   282 
   274   in
   283     val alpha_result = AlphaResult 
   275     (AlphaResult
   284       {alpha_names = alpha_names,
   276       {alpha_names = alpha_names,
   285        alpha_trms = alpha_trms,
   277        alpha_trms = alpha_trms,
   286        alpha_tys = alpha_tys,
   278        alpha_tys = alpha_tys,
   287        alpha_bn_names = alpha_bn_names, 
   279        alpha_bn_names = alpha_bn_names, 
   288        alpha_bn_trms = alpha_bn_trms,
   280        alpha_bn_trms = alpha_bn_trms,
   289        alpha_bn_tys = alpha_bn_tys, 
   281        alpha_bn_tys = alpha_bn_tys, 
   290        alpha_intros = alpha_intros,
   282        alpha_intros = alpha_intros,
   291        alpha_cases = alpha_cases,
   283        alpha_cases = alpha_cases,
   292        alpha_raw_induct = alpha_raw_induct}
   284        alpha_raw_induct = alpha_raw_induct}, lthy')
   293   in
       
   294     (alpha_trms, alpha_bn_trms, alpha_intros, alpha_cases, alpha_raw_induct, alpha_result, lthy')
       
   295   end
   285   end
   296 
   286 
   297 
   287 
   298 (** induction proofs **)
   288 (** induction proofs **)
   299 
   289 
   643   end
   633   end
   644 
   634 
   645 
   635 
   646 (* proves that alpha_raw implies alpha_bn *)
   636 (* proves that alpha_raw implies alpha_bn *)
   647 
   637 
   648 fun raw_prove_bn_imp_tac pred_names alpha_intros ctxt = 
   638 fun raw_prove_bn_imp_tac alpha_result ctxt = 
   649   SUBPROOF (fn {prems, context, ...} => 
   639   SUBPROOF (fn {prems, context, ...} => 
   650     let
   640     let
       
   641       val AlphaResult {alpha_names, alpha_intros, ...} = alpha_result 
       
   642 
   651       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
   643       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
   652       val prems'' = map (transform_prem1 context pred_names) prems'
   644       val prems'' = map (transform_prem1 context alpha_names) prems'
   653     in
   645     in
   654       HEADGOAL 
   646       HEADGOAL 
   655         (REPEAT_ALL_NEW 
   647         (REPEAT_ALL_NEW 
   656            (FIRST' [ rtac @{thm TrueI}, 
   648            (FIRST' [ rtac @{thm TrueI}, 
   657                      rtac @{thm conjI}, 
   649                      rtac @{thm conjI}, 
   658                      resolve_tac prems', 
   650                      resolve_tac prems', 
   659                      resolve_tac prems'',
   651                      resolve_tac prems'',
   660                      resolve_tac alpha_intros ]))
   652                      resolve_tac alpha_intros ]))
   661     end) ctxt
   653     end) ctxt
   662 
   654 
   663 fun raw_prove_bn_imp alpha_trms alpha_bn_trms alpha_intros alpha_induct ctxt =
   655 
   664   let
   656 fun raw_prove_bn_imp ctxt alpha_result =
       
   657   let
       
   658     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_raw_induct, ...} = alpha_result 
       
   659 
   665     val arg_ty = domain_type o fastype_of 
   660     val arg_ty = domain_type o fastype_of 
   666     val alpha_names =  map (fst o dest_Const) alpha_trms
   661     val ty_assoc = alpha_tys ~~ alpha_trms
   667     val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms
       
   668     val props = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => t $ x $ y)) alpha_bn_trms
   662     val props = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => t $ x $ y)) alpha_bn_trms
   669   in
   663   in
   670     alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_induct 
   664     alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_raw_induct 
   671       (raw_prove_bn_imp_tac alpha_names alpha_intros) ctxt
   665       (raw_prove_bn_imp_tac alpha_result) ctxt
   672   end
   666   end
   673 
   667 
   674 
   668 
   675 (* respectfulness for fv_raw / bn_raw *)
   669 (* respectfulness for fv_raw / bn_raw *)
   676 
   670 
   677 fun raw_fv_bn_rsp_aux alpha_trms alpha_bn_trms fvs bns fv_bns alpha_induct simps ctxt =
   671 fun raw_fv_bn_rsp_aux ctxt alpha_result fvs bns fv_bns simps =
   678   let
   672   let
   679     val arg_ty = fst o dest_Type o domain_type o fastype_of 
   673     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_raw_induct, ...} = alpha_result 
   680     val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms
   674 
       
   675     val arg_ty = domain_type o fastype_of 
       
   676     val ty_assoc = alpha_tys ~~ alpha_trms
   681     fun mk_eq' t x y = HOLogic.mk_eq (t $ x, t $ y)
   677     fun mk_eq' t x y = HOLogic.mk_eq (t $ x, t $ y)
   682 
   678 
   683     val prop1 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) fvs
   679     val prop1 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) fvs
   684     val prop2 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) (bns @ fv_bns)
   680     val prop2 = map (fn t => (lookup ty_assoc (arg_ty t), fn (x, y) => mk_eq' t x y)) (bns @ fv_bns)
   685     val prop3 = map2 (fn t1 => fn t2 => (t1, fn (x, y) => mk_eq' t2 x y)) alpha_bn_trms fv_bns
   681     val prop3 = map2 (fn t1 => fn t2 => (t1, fn (x, y) => mk_eq' t2 x y)) alpha_bn_trms fv_bns
   686 
   682 
   687     val ss = HOL_ss addsimps (simps @ @{thms alphas prod_fv.simps set.simps append.simps} 
   683     val ss = HOL_ss addsimps (simps @ @{thms alphas prod_fv.simps set.simps append.simps} 
   688       @ @{thms Un_assoc Un_insert_left Un_empty_right Un_empty_left}) 
   684       @ @{thms Un_assoc Un_insert_left Un_empty_right Un_empty_left}) 
   689   in
   685   in
   690     alpha_prove (alpha_trms @ alpha_bn_trms) (prop1 @ prop2 @ prop3) alpha_induct 
   686     alpha_prove (alpha_trms @ alpha_bn_trms) (prop1 @ prop2 @ prop3) alpha_raw_induct 
   691       (K (asm_full_simp_tac ss)) ctxt
   687       (K (asm_full_simp_tac ss)) ctxt
   692   end
   688   end
   693 
   689 
   694 
   690 
   695 (* respectfulness for size *)
   691 (* respectfulness for size *)
   696 
   692 
   697 fun raw_size_rsp_aux all_alpha_trms alpha_induct simps ctxt =
   693 fun raw_size_rsp_aux ctxt alpha_result simps =
   698   let
   694   let
   699     val arg_tys = map (domain_type o fastype_of) all_alpha_trms
   695     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_bn_tys, alpha_raw_induct, ...} = 
   700 
   696       alpha_result 
       
   697     
   701     fun mk_prop ty (x, y) = HOLogic.mk_eq 
   698     fun mk_prop ty (x, y) = HOLogic.mk_eq 
   702       (HOLogic.size_const ty $ x, HOLogic.size_const ty $ y)
   699       (HOLogic.size_const ty $ x, HOLogic.size_const ty $ y)
   703 
   700 
   704     val props = map2 (fn trm => fn ty => (trm, mk_prop ty)) all_alpha_trms arg_tys 
   701     val props = (alpha_trms @ alpha_bn_trms) ~~ (map mk_prop (alpha_tys @ alpha_bn_tys)) 
   705   
   702   
   706     val ss = HOL_ss addsimps (simps @ @{thms alphas prod_alpha_def prod_rel_def 
   703     val ss = HOL_ss addsimps (simps @ @{thms alphas prod_alpha_def prod_rel_def 
   707       permute_prod_def prod.cases prod.recs})
   704       permute_prod_def prod.cases prod.recs})
   708 
   705 
   709     val tac = (TRY o REPEAT o etac @{thm exE}) THEN' asm_full_simp_tac ss
   706     val tac = (TRY o REPEAT o etac @{thm exE}) THEN' asm_full_simp_tac ss
   710   in
   707   in
   711     alpha_prove all_alpha_trms props alpha_induct (K tac) ctxt
   708     alpha_prove (alpha_trms @ alpha_bn_trms) props alpha_raw_induct (K tac) ctxt
   712   end
   709   end
   713 
   710 
   714 
   711 
   715 (* respectfulness for constructors *)
   712 (* respectfulness for constructors *)
   716 
   713 
   724     THEN' REPEAT o (resolve_tac @{thms allI impI})
   721     THEN' REPEAT o (resolve_tac @{thms allI impI})
   725     THEN' resolve_tac alpha_intros
   722     THEN' resolve_tac alpha_intros
   726     THEN_ALL_NEW (TRY o (rtac exi_zero) THEN' asm_full_simp_tac post_ss)
   723     THEN_ALL_NEW (TRY o (rtac exi_zero) THEN' asm_full_simp_tac post_ss)
   727   end
   724   end
   728 
   725 
   729 fun raw_constrs_rsp constrs alpha_trms alpha_intros simps ctxt =
   726 fun raw_constrs_rsp ctxt alpha_result constrs simps =
   730   let
   727   let
   731     val alpha_arg_tys = map (domain_type o fastype_of) alpha_trms
   728     val AlphaResult {alpha_trms, alpha_tys, alpha_intros, ...} = alpha_result 
   732   
   729 
   733     fun lookup ty = 
   730     fun lookup ty = 
   734       case AList.lookup (op=) (alpha_arg_tys ~~ alpha_trms) ty of
   731       case AList.lookup (op=) (alpha_tys ~~ alpha_trms) ty of
   735         NONE => HOLogic.eq_const ty
   732         NONE => HOLogic.eq_const ty
   736       | SOME alpha => alpha 
   733       | SOME alpha => alpha 
   737   
   734   
   738     fun fun_rel_app (t1, t2) = 
   735     fun fun_rel_app (t1, t2) = 
   739       Const (@{const_name "fun_rel"}, dummyT) $ t1 $ t2
   736       Const (@{const_name "fun_rel"}, dummyT) $ t1 $ t2
   761     by (simp only: fun_rel_def equivp_def, metis)}
   758     by (simp only: fun_rel_def equivp_def, metis)}
   762 
   759 
   763 
   760 
   764 (* we have to reorder the alpha_bn_imps theorems in order
   761 (* we have to reorder the alpha_bn_imps theorems in order
   765    to be in order with alpha_bn_trms *)
   762    to be in order with alpha_bn_trms *)
   766 fun raw_alpha_bn_rsp alpha_bn_trms alpha_bn_equivp alpha_bn_imps =
   763 fun raw_alpha_bn_rsp alpha_result alpha_bn_equivp alpha_bn_imps =
   767   let
   764   let
       
   765     val AlphaResult {alpha_bn_trms, ...} = alpha_result 
       
   766 
   768     fun mk_map thm =
   767     fun mk_map thm =
   769       thm |> `prop_of
   768       thm |> `prop_of
   770           |>> List.last  o snd o strip_comb
   769           |>> List.last  o snd o strip_comb
   771           |>> HOLogic.dest_Trueprop
   770           |>> HOLogic.dest_Trueprop
   772           |>> head_of
   771           |>> head_of
   785 (* rsp for permute_bn functions *)
   784 (* rsp for permute_bn functions *)
   786 
   785 
   787 val perm_bn_rsp = @{lemma "(!x y p. R x y --> R (f p x) (f p y)) ==> (op= ===> R ===> R) f f"
   786 val perm_bn_rsp = @{lemma "(!x y p. R x y --> R (f p x) (f p y)) ==> (op= ===> R ===> R) f f"
   788  by (simp add: fun_rel_def)}
   787  by (simp add: fun_rel_def)}
   789 
   788 
   790 fun raw_prove_perm_bn_tac pred_names alpha_intros simps ctxt = 
   789 fun raw_prove_perm_bn_tac alpha_result simps ctxt = 
   791   SUBPROOF (fn {prems, context, ...} => 
   790   SUBPROOF (fn {prems, context, ...} => 
   792     let
   791     let
       
   792       val AlphaResult {alpha_names, alpha_bn_names, alpha_intros, ...} = alpha_result 
   793       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
   793       val prems' = flat (map Datatype_Aux.split_conj_thm prems)
   794       val prems'' = map (transform_prem1 context pred_names) prems'
   794       val prems'' = map (transform_prem1 context (alpha_names @ alpha_bn_names)) prems'
   795     in
   795     in
   796       HEADGOAL 
   796       HEADGOAL 
   797         (simp_tac (HOL_basic_ss addsimps (simps @ prems'))
   797         (simp_tac (HOL_basic_ss addsimps (simps @ prems'))
   798          THEN' TRY o REPEAT_ALL_NEW 
   798          THEN' TRY o REPEAT_ALL_NEW 
   799            (FIRST' [ rtac @{thm TrueI}, 
   799            (FIRST' [ rtac @{thm TrueI}, 
   802                      resolve_tac prems', 
   802                      resolve_tac prems', 
   803                      resolve_tac prems'',
   803                      resolve_tac prems'',
   804                      resolve_tac alpha_intros ]))
   804                      resolve_tac alpha_intros ]))
   805     end) ctxt
   805     end) ctxt
   806 
   806 
   807 fun raw_perm_bn_rsp alpha_trms perm_bns alpha_induct alpha_intros simps ctxt =
   807 fun raw_perm_bn_rsp ctxt alpha_result perm_bns simps =
   808   let
   808   let
   809     val arg_ty = domain_type o fastype_of
   809     val AlphaResult {alpha_trms, alpha_tys, alpha_bn_trms, alpha_bn_tys, alpha_raw_induct, ...} = 
       
   810       alpha_result 
       
   811 
   810     val perm_bn_ty = range_type o range_type o fastype_of
   812     val perm_bn_ty = range_type o range_type o fastype_of
   811     val ty_assoc = map (fn t => (arg_ty t, t)) alpha_trms
   813     val ty_assoc = (alpha_tys @ alpha_bn_tys) ~~ (alpha_trms @ alpha_bn_trms)
   812 
   814 
   813     val ([p], ctxt') = Variable.variant_fixes ["p"] ctxt		   
   815     val ([p], ctxt') = Variable.variant_fixes ["p"] ctxt		   
   814     val p = Free (p, @{typ perm})
   816     val p = Free (p, @{typ perm})
   815 
   817 
   816     fun mk_prop t =
   818     fun mk_prop t =
   818         val alpha_trm = lookup ty_assoc (perm_bn_ty t)
   820         val alpha_trm = lookup ty_assoc (perm_bn_ty t)
   819       in
   821       in
   820         (alpha_trm, fn (x, y) => alpha_trm $ (t $ p $ x) $ (t $ p $ y))
   822         (alpha_trm, fn (x, y) => alpha_trm $ (t $ p $ x) $ (t $ p $ y))
   821       end
   823       end
   822 
   824 
   823     val goals = map mk_prop perm_bns
   825     val goals = map mk_prop perm_bns    
   824     val alpha_names =  map (fst o dest_Const) alpha_trms       
   826   in
   825     
   827     alpha_prove (alpha_trms @ alpha_bn_trms) goals alpha_raw_induct 
   826   in
   828       (raw_prove_perm_bn_tac alpha_result simps) ctxt
   827     alpha_prove alpha_trms goals alpha_induct 
       
   828       (raw_prove_perm_bn_tac alpha_names alpha_intros simps) ctxt
       
   829      |> ProofContext.export ctxt' ctxt
   829      |> ProofContext.export ctxt' ctxt
   830      |> map atomize
   830      |> map atomize
   831      |> map single
   831      |> map single
   832      |> map (curry (op OF) perm_bn_rsp)
   832      |> map (curry (op OF) perm_bn_rsp)
   833   end
   833   end