src/HOL/Transfer.thy
changeset 56524 f4ba736040fa
parent 56520 3373f5d1e074
child 56543 9bd56f2e4c10
equal deleted inserted replaced
56523:2ae16e3d8b6d 56524:f4ba736040fa
     4 *)
     4 *)
     5 
     5 
     6 header {* Generic theorem transfer using relations *}
     6 header {* Generic theorem transfer using relations *}
     7 
     7 
     8 theory Transfer
     8 theory Transfer
     9 imports Hilbert_Choice Basic_BNFs Metis
     9 imports Hilbert_Choice Basic_BNFs BNF_FP_Base Metis Option
    10 begin
    10 begin
       
    11 
       
    12 (* We include Option here altough it's not needed here. 
       
    13    By doing this, we avoid a diamond problem for BNF and 
       
    14    FP sugar interpretation defined in this file. *)
    11 
    15 
    12 subsection {* Relator for function space *}
    16 subsection {* Relator for function space *}
    13 
    17 
    14 locale lifting_syntax
    18 locale lifting_syntax
    15 begin
    19 begin
   103 lemma Rel_abs:
   107 lemma Rel_abs:
   104   assumes "\<And>x y. Rel A x y \<Longrightarrow> Rel B (f x) (g y)"
   108   assumes "\<And>x y. Rel A x y \<Longrightarrow> Rel B (f x) (g y)"
   105   shows "Rel (A ===> B) (\<lambda>x. f x) (\<lambda>y. g y)"
   109   shows "Rel (A ===> B) (\<lambda>x. f x) (\<lambda>y. g y)"
   106   using assms unfolding Rel_def rel_fun_def by fast
   110   using assms unfolding Rel_def rel_fun_def by fast
   107 
   111 
   108 end
       
   109 
       
   110 ML_file "Tools/transfer.ML"
       
   111 setup Transfer.setup
       
   112 
       
   113 declare refl [transfer_rule]
       
   114 
       
   115 declare rel_fun_eq [relator_eq]
       
   116 
       
   117 hide_const (open) Rel
       
   118 
       
   119 context
       
   120 begin
       
   121 interpretation lifting_syntax .
       
   122 
       
   123 text {* Handling of domains *}
       
   124 
       
   125 lemma Domainp_iff: "Domainp T x \<longleftrightarrow> (\<exists>y. T x y)"
       
   126   by auto
       
   127 
       
   128 lemma Domaimp_refl[transfer_domain_rule]:
       
   129   "Domainp T = Domainp T" ..
       
   130 
       
   131 lemma Domainp_prod_fun_eq[relator_domain]:
       
   132   "Domainp (op= ===> T) = (\<lambda>f. \<forall>x. (Domainp T) (f x))"
       
   133 by (auto intro: choice simp: Domainp_iff rel_fun_def fun_eq_iff)
       
   134 
       
   135 subsection {* Predicates on relations, i.e. ``class constraints'' *}
   112 subsection {* Predicates on relations, i.e. ``class constraints'' *}
   136 
   113 
   137 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   114 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   138   where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)"
   115   where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)"
   139 
   116 
   179 unfolding right_unique_def by fast
   156 unfolding right_unique_def by fast
   180 
   157 
   181 lemma right_uniqueD: "\<lbrakk> right_unique A; A x y; A x z \<rbrakk> \<Longrightarrow> y = z"
   158 lemma right_uniqueD: "\<lbrakk> right_unique A; A x y; A x z \<rbrakk> \<Longrightarrow> y = z"
   182 unfolding right_unique_def by fast
   159 unfolding right_unique_def by fast
   183 
   160 
   184 lemma right_total_alt_def:
   161 lemma right_total_alt_def2:
   185   "right_total R \<longleftrightarrow> ((R ===> op \<longrightarrow>) ===> op \<longrightarrow>) All All"
   162   "right_total R \<longleftrightarrow> ((R ===> op \<longrightarrow>) ===> op \<longrightarrow>) All All"
   186   unfolding right_total_def rel_fun_def
   163   unfolding right_total_def rel_fun_def
   187   apply (rule iffI, fast)
   164   apply (rule iffI, fast)
   188   apply (rule allI)
   165   apply (rule allI)
   189   apply (drule_tac x="\<lambda>x. True" in spec)
   166   apply (drule_tac x="\<lambda>x. True" in spec)
   190   apply (drule_tac x="\<lambda>y. \<exists>x. R x y" in spec)
   167   apply (drule_tac x="\<lambda>y. \<exists>x. R x y" in spec)
   191   apply fast
   168   apply fast
   192   done
   169   done
   193 
   170 
   194 lemma right_unique_alt_def:
   171 lemma right_unique_alt_def2:
   195   "right_unique R \<longleftrightarrow> (R ===> R ===> op \<longrightarrow>) (op =) (op =)"
   172   "right_unique R \<longleftrightarrow> (R ===> R ===> op \<longrightarrow>) (op =) (op =)"
   196   unfolding right_unique_def rel_fun_def by auto
   173   unfolding right_unique_def rel_fun_def by auto
   197 
   174 
   198 lemma bi_total_alt_def:
   175 lemma bi_total_alt_def2:
   199   "bi_total R \<longleftrightarrow> ((R ===> op =) ===> op =) All All"
   176   "bi_total R \<longleftrightarrow> ((R ===> op =) ===> op =) All All"
   200   unfolding bi_total_def rel_fun_def
   177   unfolding bi_total_def rel_fun_def
   201   apply (rule iffI, fast)
   178   apply (rule iffI, fast)
   202   apply safe
   179   apply safe
   203   apply (drule_tac x="\<lambda>x. \<exists>y. R x y" in spec)
   180   apply (drule_tac x="\<lambda>x. \<exists>y. R x y" in spec)
   206   apply (drule_tac x="\<lambda>x. True" in spec)
   183   apply (drule_tac x="\<lambda>x. True" in spec)
   207   apply (drule_tac x="\<lambda>y. \<exists>x. R x y" in spec)
   184   apply (drule_tac x="\<lambda>y. \<exists>x. R x y" in spec)
   208   apply fast
   185   apply fast
   209   done
   186   done
   210 
   187 
   211 lemma bi_unique_alt_def:
   188 lemma bi_unique_alt_def2:
   212   "bi_unique R \<longleftrightarrow> (R ===> R ===> op =) (op =) (op =)"
   189   "bi_unique R \<longleftrightarrow> (R ===> R ===> op =) (op =) (op =)"
   213   unfolding bi_unique_def rel_fun_def by auto
   190   unfolding bi_unique_def rel_fun_def by auto
   214 
   191 
   215 lemma [simp]:
   192 lemma [simp]:
   216   shows left_unique_conversep: "left_unique A\<inverse>\<inverse> \<longleftrightarrow> right_unique A"
   193   shows left_unique_conversep: "left_unique A\<inverse>\<inverse> \<longleftrightarrow> right_unique A"
   226 by(auto simp add: bi_unique_def)
   203 by(auto simp add: bi_unique_def)
   227 
   204 
   228 lemma bi_total_conversep [simp]: "bi_total R\<inverse>\<inverse> = bi_total R"
   205 lemma bi_total_conversep [simp]: "bi_total R\<inverse>\<inverse> = bi_total R"
   229 by(auto simp add: bi_total_def)
   206 by(auto simp add: bi_total_def)
   230 
   207 
   231 lemma bi_total_iff: "bi_total A = (right_total A \<and> left_total A)"
   208 lemma right_unique_alt_def: "right_unique R = (conversep R OO R \<le> op=)" unfolding right_unique_def by blast
       
   209 lemma left_unique_alt_def: "left_unique R = (R OO (conversep R) \<le> op=)" unfolding left_unique_def by blast
       
   210 
       
   211 lemma right_total_alt_def: "right_total R = (conversep R OO R \<ge> op=)" unfolding right_total_def by blast
       
   212 lemma left_total_alt_def: "left_total R = (R OO conversep R \<ge> op=)" unfolding left_total_def by blast
       
   213 
       
   214 lemma bi_total_alt_def: "bi_total A = (left_total A \<and> right_total A)"
   232 unfolding left_total_def right_total_def bi_total_def by blast
   215 unfolding left_total_def right_total_def bi_total_def by blast
   233 
   216 
   234 lemma bi_total_conv_left_right: "bi_total R \<longleftrightarrow> left_total R \<and> right_total R"
   217 lemma bi_unique_alt_def: "bi_unique A = (left_unique A \<and> right_unique A)"
   235 by(simp add: left_total_def right_total_def bi_total_def)
       
   236 
       
   237 lemma bi_unique_iff: "bi_unique A  \<longleftrightarrow> right_unique A \<and> left_unique A"
       
   238 unfolding left_unique_def right_unique_def bi_unique_def by blast
   218 unfolding left_unique_def right_unique_def bi_unique_def by blast
   239 
   219 
   240 lemma bi_unique_conv_left_right: "bi_unique R \<longleftrightarrow> left_unique R \<and> right_unique R"
       
   241 by(auto simp add: left_unique_def right_unique_def bi_unique_def)
       
   242 
       
   243 lemma bi_totalI: "left_total R \<Longrightarrow> right_total R \<Longrightarrow> bi_total R"
   220 lemma bi_totalI: "left_total R \<Longrightarrow> right_total R \<Longrightarrow> bi_total R"
   244 unfolding bi_total_iff ..
   221 unfolding bi_total_alt_def ..
   245 
   222 
   246 lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R"
   223 lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R"
   247 unfolding bi_unique_iff ..
   224 unfolding bi_unique_alt_def ..
   248 
   225 
       
   226 end
       
   227 
       
   228 subsection {* Equality restricted by a predicate *}
       
   229 
       
   230 definition eq_onp :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" 
       
   231   where "eq_onp R = (\<lambda>x y. R x \<and> x = y)"
       
   232 
       
   233 lemma eq_onp_Grp: "eq_onp P = BNF_Util.Grp (Collect P) id" 
       
   234 unfolding eq_onp_def Grp_def by auto 
       
   235 
       
   236 lemma eq_onp_to_eq:
       
   237   assumes "eq_onp P x y"
       
   238   shows "x = y"
       
   239 using assms by (simp add: eq_onp_def)
       
   240 
       
   241 lemma eq_onp_same_args:
       
   242   shows "eq_onp P x x = P x"
       
   243 using assms by (auto simp add: eq_onp_def)
       
   244 
       
   245 lemma Ball_Collect: "Ball A P = (A \<subseteq> (Collect P))"
       
   246 by (metis mem_Collect_eq subset_eq)
       
   247 
       
   248 ML_file "Tools/Transfer/transfer.ML"
       
   249 setup Transfer.setup
       
   250 declare refl [transfer_rule]
       
   251 
       
   252 ML_file "Tools/Transfer/transfer_bnf.ML" 
       
   253 
       
   254 declare pred_fun_def [simp]
       
   255 declare rel_fun_eq [relator_eq]
       
   256 
       
   257 hide_const (open) Rel
       
   258 
       
   259 context
       
   260 begin
       
   261 interpretation lifting_syntax .
       
   262 
       
   263 text {* Handling of domains *}
       
   264 
       
   265 lemma Domainp_iff: "Domainp T x \<longleftrightarrow> (\<exists>y. T x y)"
       
   266   by auto
       
   267 
       
   268 lemma Domaimp_refl[transfer_domain_rule]:
       
   269   "Domainp T = Domainp T" ..
       
   270 
       
   271 lemma Domainp_prod_fun_eq[relator_domain]:
       
   272   "Domainp (op= ===> T) = (\<lambda>f. \<forall>x. (Domainp T) (f x))"
       
   273 by (auto intro: choice simp: Domainp_iff rel_fun_def fun_eq_iff)
   249 
   274 
   250 text {* Properties are preserved by relation composition. *}
   275 text {* Properties are preserved by relation composition. *}
   251 
   276 
   252 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)"
   277 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)"
   253   by auto
   278   by auto
   331   unfolding right_total_def right_unique_def rel_fun_def
   356   unfolding right_total_def right_unique_def rel_fun_def
   332   by (clarify, rule ext, fast)
   357   by (clarify, rule ext, fast)
   333 
   358 
   334 lemma bi_total_fun[transfer_rule]:
   359 lemma bi_total_fun[transfer_rule]:
   335   "\<lbrakk>bi_unique A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A ===> B)"
   360   "\<lbrakk>bi_unique A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A ===> B)"
   336   unfolding bi_unique_iff bi_total_iff
   361   unfolding bi_unique_alt_def bi_total_alt_def
   337   by (blast intro: right_total_fun left_total_fun)
   362   by (blast intro: right_total_fun left_total_fun)
   338 
   363 
   339 lemma bi_unique_fun[transfer_rule]:
   364 lemma bi_unique_fun[transfer_rule]:
   340   "\<lbrakk>bi_total A; bi_unique B\<rbrakk> \<Longrightarrow> bi_unique (A ===> B)"
   365   "\<lbrakk>bi_total A; bi_unique B\<rbrakk> \<Longrightarrow> bi_unique (A ===> B)"
   341   unfolding bi_unique_iff bi_total_iff
   366   unfolding bi_unique_alt_def bi_total_alt_def
   342   by (blast intro: right_unique_fun left_unique_fun)
   367   by (blast intro: right_unique_fun left_unique_fun)
   343 
   368 
   344 subsection {* Transfer rules *}
   369 subsection {* Transfer rules *}
   345 
   370 
   346 lemma Domainp_forall_transfer [transfer_rule]:
   371 lemma Domainp_forall_transfer [transfer_rule]:
   374   "(op =        ===> op =        ===> rev_implies) transfer_implies transfer_implies"
   399   "(op =        ===> op =        ===> rev_implies) transfer_implies transfer_implies"
   375   unfolding transfer_implies_def rev_implies_def rel_fun_def by auto
   400   unfolding transfer_implies_def rev_implies_def rel_fun_def by auto
   376 
   401 
   377 lemma eq_imp_transfer [transfer_rule]:
   402 lemma eq_imp_transfer [transfer_rule]:
   378   "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)"
   403   "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)"
   379   unfolding right_unique_alt_def .
   404   unfolding right_unique_alt_def2 .
   380 
   405 
   381 text {* Transfer rules using equality. *}
   406 text {* Transfer rules using equality. *}
   382 
   407 
   383 lemma left_unique_transfer [transfer_rule]:
   408 lemma left_unique_transfer [transfer_rule]:
   384   assumes "right_total A"
   409   assumes "right_total A"
   488   assumes [transfer_rule]: "bi_unique B"
   513   assumes [transfer_rule]: "bi_unique B"
   489   shows "((A ===> B ===> op=) ===> implies) right_unique right_unique"
   514   shows "((A ===> B ===> op=) ===> implies) right_unique right_unique"
   490 using assms unfolding right_unique_def[abs_def] right_total_def bi_unique_def rel_fun_def
   515 using assms unfolding right_unique_def[abs_def] right_total_def bi_unique_def rel_fun_def
   491 by metis
   516 by metis
   492 
   517 
       
   518 lemma rel_fun_eq_eq_onp: "(op= ===> eq_onp P) = eq_onp (\<lambda>f. \<forall>x. P(f x))"
       
   519 unfolding eq_onp_def rel_fun_def by auto
       
   520 
       
   521 lemma rel_fun_eq_onp_rel:
       
   522   shows "((eq_onp R) ===> S) = (\<lambda>f g. \<forall>x. R x \<longrightarrow> S (f x) (g x))"
       
   523 by (auto simp add: eq_onp_def rel_fun_def)
       
   524 
       
   525 lemma eq_onp_transfer [transfer_rule]:
       
   526   assumes [transfer_rule]: "bi_unique A"
       
   527   shows "((A ===> op=) ===> A ===> A ===> op=) eq_onp eq_onp"
       
   528 unfolding eq_onp_def[abs_def] by transfer_prover
       
   529 
   493 end
   530 end
   494 
   531 
   495 end
   532 end