src/HOL/Transfer.thy
changeset 60758 d8d85a8172b5
parent 60229 4cd6462c1fda
child 61630 608520e0e8e2
equal deleted inserted replaced
60757:c09598a97436 60758:d8d85a8172b5
     1 (*  Title:      HOL/Transfer.thy
     1 (*  Title:      HOL/Transfer.thy
     2     Author:     Brian Huffman, TU Muenchen
     2     Author:     Brian Huffman, TU Muenchen
     3     Author:     Ondrej Kuncar, TU Muenchen
     3     Author:     Ondrej Kuncar, TU Muenchen
     4 *)
     4 *)
     5 
     5 
     6 section {* Generic theorem transfer using relations *}
     6 section \<open>Generic theorem transfer using relations\<close>
     7 
     7 
     8 theory Transfer
     8 theory Transfer
     9 imports Basic_BNF_LFPs Hilbert_Choice Metis
     9 imports Basic_BNF_LFPs Hilbert_Choice Metis
    10 begin
    10 begin
    11 
    11 
    12 subsection {* Relator for function space *}
    12 subsection \<open>Relator for function space\<close>
    13 
    13 
    14 locale lifting_syntax
    14 locale lifting_syntax
    15 begin
    15 begin
    16   notation rel_fun (infixr "===>" 55)
    16   notation rel_fun (infixr "===>" 55)
    17   notation map_fun (infixr "--->" 55)
    17   notation map_fun (infixr "--->" 55)
    36 lemma rel_fun_eq_rel:
    36 lemma rel_fun_eq_rel:
    37 shows "rel_fun (op =) R = (\<lambda>f g. \<forall>x. R (f x) (g x))"
    37 shows "rel_fun (op =) R = (\<lambda>f g. \<forall>x. R (f x) (g x))"
    38   by (simp add: rel_fun_def)
    38   by (simp add: rel_fun_def)
    39 
    39 
    40 
    40 
    41 subsection {* Transfer method *}
    41 subsection \<open>Transfer method\<close>
    42 
    42 
    43 text {* Explicit tag for relation membership allows for
    43 text \<open>Explicit tag for relation membership allows for
    44   backward proof methods. *}
    44   backward proof methods.\<close>
    45 
    45 
    46 definition Rel :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> bool"
    46 definition Rel :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> bool"
    47   where "Rel r \<equiv> r"
    47   where "Rel r \<equiv> r"
    48 
    48 
    49 text {* Handling of equality relations *}
    49 text \<open>Handling of equality relations\<close>
    50 
    50 
    51 definition is_equality :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool"
    51 definition is_equality :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool"
    52   where "is_equality R \<longleftrightarrow> R = (op =)"
    52   where "is_equality R \<longleftrightarrow> R = (op =)"
    53 
    53 
    54 lemma is_equality_eq: "is_equality (op =)"
    54 lemma is_equality_eq: "is_equality (op =)"
    55   unfolding is_equality_def by simp
    55   unfolding is_equality_def by simp
    56 
    56 
    57 text {* Reverse implication for monotonicity rules *}
    57 text \<open>Reverse implication for monotonicity rules\<close>
    58 
    58 
    59 definition rev_implies where
    59 definition rev_implies where
    60   "rev_implies x y \<longleftrightarrow> (y \<longrightarrow> x)"
    60   "rev_implies x y \<longleftrightarrow> (y \<longrightarrow> x)"
    61 
    61 
    62 text {* Handling of meta-logic connectives *}
    62 text \<open>Handling of meta-logic connectives\<close>
    63 
    63 
    64 definition transfer_forall where
    64 definition transfer_forall where
    65   "transfer_forall \<equiv> All"
    65   "transfer_forall \<equiv> All"
    66 
    66 
    67 definition transfer_implies where
    67 definition transfer_implies where
   103 lemma Rel_abs:
   103 lemma Rel_abs:
   104   assumes "\<And>x y. Rel A x y \<Longrightarrow> Rel B (f x) (g y)"
   104   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)"
   105   shows "Rel (A ===> B) (\<lambda>x. f x) (\<lambda>y. g y)"
   106   using assms unfolding Rel_def rel_fun_def by fast
   106   using assms unfolding Rel_def rel_fun_def by fast
   107 
   107 
   108 subsection {* Predicates on relations, i.e. ``class constraints'' *}
   108 subsection \<open>Predicates on relations, i.e. ``class constraints''\<close>
   109 
   109 
   110 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   110 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   111   where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)"
   111   where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)"
   112 
   112 
   113 definition left_unique :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   113 definition left_unique :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   227 lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R"
   227 lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R"
   228 unfolding bi_unique_alt_def ..
   228 unfolding bi_unique_alt_def ..
   229 
   229 
   230 end
   230 end
   231 
   231 
   232 subsection {* Equality restricted by a predicate *}
   232 subsection \<open>Equality restricted by a predicate\<close>
   233 
   233 
   234 definition eq_onp :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"
   234 definition eq_onp :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"
   235   where "eq_onp R = (\<lambda>x y. R x \<and> x = y)"
   235   where "eq_onp R = (\<lambda>x y. R x \<and> x = y)"
   236 
   236 
   237 lemma eq_onp_Grp: "eq_onp P = BNF_Def.Grp (Collect P) id"
   237 lemma eq_onp_Grp: "eq_onp P = BNF_Def.Grp (Collect P) id"
   259 
   259 
   260 context
   260 context
   261 begin
   261 begin
   262 interpretation lifting_syntax .
   262 interpretation lifting_syntax .
   263 
   263 
   264 text {* Handling of domains *}
   264 text \<open>Handling of domains\<close>
   265 
   265 
   266 lemma Domainp_iff: "Domainp T x \<longleftrightarrow> (\<exists>y. T x y)"
   266 lemma Domainp_iff: "Domainp T x \<longleftrightarrow> (\<exists>y. T x y)"
   267   by auto
   267   by auto
   268 
   268 
   269 lemma Domainp_refl[transfer_domain_rule]:
   269 lemma Domainp_refl[transfer_domain_rule]:
   273 
   273 
   274 lemma Domainp_prod_fun_eq[relator_domain]:
   274 lemma Domainp_prod_fun_eq[relator_domain]:
   275   "Domainp (op= ===> T) = (\<lambda>f. \<forall>x. (Domainp T) (f x))"
   275   "Domainp (op= ===> T) = (\<lambda>f. \<forall>x. (Domainp T) (f x))"
   276 by (auto intro: choice simp: Domainp_iff rel_fun_def fun_eq_iff)
   276 by (auto intro: choice simp: Domainp_iff rel_fun_def fun_eq_iff)
   277 
   277 
   278 text {* Properties are preserved by relation composition. *}
   278 text \<open>Properties are preserved by relation composition.\<close>
   279 
   279 
   280 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)"
   280 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)"
   281   by auto
   281   by auto
   282 
   282 
   283 lemma bi_total_OO: "\<lbrakk>bi_total A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A OO B)"
   283 lemma bi_total_OO: "\<lbrakk>bi_total A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A OO B)"
   299 
   299 
   300 lemma left_unique_OO: "left_unique R \<Longrightarrow> left_unique S \<Longrightarrow> left_unique (R OO S)"
   300 lemma left_unique_OO: "left_unique R \<Longrightarrow> left_unique S \<Longrightarrow> left_unique (R OO S)"
   301 unfolding left_unique_def OO_def by blast
   301 unfolding left_unique_def OO_def by blast
   302 
   302 
   303 
   303 
   304 subsection {* Properties of relators *}
   304 subsection \<open>Properties of relators\<close>
   305 
   305 
   306 lemma left_total_eq[transfer_rule]: "left_total op="
   306 lemma left_total_eq[transfer_rule]: "left_total op="
   307   unfolding left_total_def by blast
   307   unfolding left_total_def by blast
   308 
   308 
   309 lemma left_unique_eq[transfer_rule]: "left_unique op="
   309 lemma left_unique_eq[transfer_rule]: "left_unique op="
   382 ML_file "Tools/BNF/bnf_fp_rec_sugar_transfer.ML"
   382 ML_file "Tools/BNF/bnf_fp_rec_sugar_transfer.ML"
   383 
   383 
   384 declare pred_fun_def [simp]
   384 declare pred_fun_def [simp]
   385 declare rel_fun_eq [relator_eq]
   385 declare rel_fun_eq [relator_eq]
   386 
   386 
   387 subsection {* Transfer rules *}
   387 subsection \<open>Transfer rules\<close>
   388 
   388 
   389 context
   389 context
   390 begin
   390 begin
   391 interpretation lifting_syntax .
   391 interpretation lifting_syntax .
   392 
   392 
   396     (transfer_bforall (Domainp A)) transfer_forall"
   396     (transfer_bforall (Domainp A)) transfer_forall"
   397   using assms unfolding right_total_def
   397   using assms unfolding right_total_def
   398   unfolding transfer_forall_def transfer_bforall_def rel_fun_def Domainp_iff
   398   unfolding transfer_forall_def transfer_bforall_def rel_fun_def Domainp_iff
   399   by fast
   399   by fast
   400 
   400 
   401 text {* Transfer rules using implication instead of equality on booleans. *}
   401 text \<open>Transfer rules using implication instead of equality on booleans.\<close>
   402 
   402 
   403 lemma transfer_forall_transfer [transfer_rule]:
   403 lemma transfer_forall_transfer [transfer_rule]:
   404   "bi_total A \<Longrightarrow> ((A ===> op =) ===> op =) transfer_forall transfer_forall"
   404   "bi_total A \<Longrightarrow> ((A ===> op =) ===> op =) transfer_forall transfer_forall"
   405   "right_total A \<Longrightarrow> ((A ===> op =) ===> implies) transfer_forall transfer_forall"
   405   "right_total A \<Longrightarrow> ((A ===> op =) ===> implies) transfer_forall transfer_forall"
   406   "right_total A \<Longrightarrow> ((A ===> implies) ===> implies) transfer_forall transfer_forall"
   406   "right_total A \<Longrightarrow> ((A ===> implies) ===> implies) transfer_forall transfer_forall"
   423 
   423 
   424 lemma eq_imp_transfer [transfer_rule]:
   424 lemma eq_imp_transfer [transfer_rule]:
   425   "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)"
   425   "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)"
   426   unfolding right_unique_alt_def2 .
   426   unfolding right_unique_alt_def2 .
   427 
   427 
   428 text {* Transfer rules using equality. *}
   428 text \<open>Transfer rules using equality.\<close>
   429 
   429 
   430 lemma left_unique_transfer [transfer_rule]:
   430 lemma left_unique_transfer [transfer_rule]:
   431   assumes "right_total A"
   431   assumes "right_total A"
   432   assumes "right_total B"
   432   assumes "right_total B"
   433   assumes "bi_unique A"
   433   assumes "bi_unique A"
   585   {
   585   {
   586     assume "R\<^sup>*\<^sup>* x y" "A y y'"
   586     assume "R\<^sup>*\<^sup>* x y" "A y y'"
   587     thus "R'\<^sup>*\<^sup>* x' y'"
   587     thus "R'\<^sup>*\<^sup>* x' y'"
   588     proof(induction arbitrary: y')
   588     proof(induction arbitrary: y')
   589       case base
   589       case base
   590       with `bi_unique A` `A x x'` have "x' = y'" by(rule bi_uniqueDr)
   590       with \<open>bi_unique A\<close> \<open>A x x'\<close> have "x' = y'" by(rule bi_uniqueDr)
   591       thus ?case by simp
   591       thus ?case by simp
   592     next
   592     next
   593       case (step y z z')
   593       case (step y z z')
   594       from `bi_total A` obtain y' where "A y y'" unfolding bi_total_def by blast
   594       from \<open>bi_total A\<close> obtain y' where "A y y'" unfolding bi_total_def by blast
   595       hence "R'\<^sup>*\<^sup>* x' y'" by(rule step.IH)
   595       hence "R'\<^sup>*\<^sup>* x' y'" by(rule step.IH)
   596       moreover from R `A y y'` `A z z'` `R y z`
   596       moreover from R \<open>A y y'\<close> \<open>A z z'\<close> \<open>R y z\<close>
   597       have "R' y' z'" by(auto dest: rel_funD)
   597       have "R' y' z'" by(auto dest: rel_funD)
   598       ultimately show ?case ..
   598       ultimately show ?case ..
   599     qed
   599     qed
   600   next
   600   next
   601     assume "R'\<^sup>*\<^sup>* x' y'" "A y y'"
   601     assume "R'\<^sup>*\<^sup>* x' y'" "A y y'"
   602     thus "R\<^sup>*\<^sup>* x y"
   602     thus "R\<^sup>*\<^sup>* x y"
   603     proof(induction arbitrary: y)
   603     proof(induction arbitrary: y)
   604       case base
   604       case base
   605       with `bi_unique A` `A x x'` have "x = y" by(rule bi_uniqueDl)
   605       with \<open>bi_unique A\<close> \<open>A x x'\<close> have "x = y" by(rule bi_uniqueDl)
   606       thus ?case by simp
   606       thus ?case by simp
   607     next
   607     next
   608       case (step y' z' z)
   608       case (step y' z' z)
   609       from `bi_total A` obtain y where "A y y'" unfolding bi_total_def by blast
   609       from \<open>bi_total A\<close> obtain y where "A y y'" unfolding bi_total_def by blast
   610       hence "R\<^sup>*\<^sup>* x y" by(rule step.IH)
   610       hence "R\<^sup>*\<^sup>* x y" by(rule step.IH)
   611       moreover from R `A y y'` `A z z'` `R' y' z'`
   611       moreover from R \<open>A y y'\<close> \<open>A z z'\<close> \<open>R' y' z'\<close>
   612       have "R y z" by(auto dest: rel_funD)
   612       have "R y z" by(auto dest: rel_funD)
   613       ultimately show ?case ..
   613       ultimately show ?case ..
   614     qed
   614     qed
   615   }
   615   }
   616 qed
   616 qed