src/HOL/Transfer.thy
changeset 56518 beb3b6851665
parent 56085 3d11892ea537
child 56520 3373f5d1e074
--- a/src/HOL/Transfer.thy	Thu Apr 10 17:48:13 2014 +0200
+++ b/src/HOL/Transfer.thy	Thu Apr 10 17:48:14 2014 +0200
@@ -135,6 +135,12 @@
 
 subsection {* Predicates on relations, i.e. ``class constraints'' *}
 
+definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
+  where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)"
+
+definition left_unique :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
+  where "left_unique R \<longleftrightarrow> (\<forall>x y z. R x z \<longrightarrow> R y z \<longrightarrow> x = y)"
+
 definition right_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   where "right_total R \<longleftrightarrow> (\<forall>y. \<exists>x. R x y)"
 
@@ -149,6 +155,21 @@
     (\<forall>x y z. R x y \<longrightarrow> R x z \<longrightarrow> y = z) \<and>
     (\<forall>x y z. R x z \<longrightarrow> R y z \<longrightarrow> x = y)"
 
+lemma left_uniqueI: "(\<And>x y z. \<lbrakk> A x z; A y z \<rbrakk> \<Longrightarrow> x = y) \<Longrightarrow> left_unique A"
+unfolding left_unique_def by blast
+
+lemma left_uniqueD: "\<lbrakk> left_unique A; A x z; A y z \<rbrakk> \<Longrightarrow> x = y"
+unfolding left_unique_def by blast
+
+lemma left_totalI:
+  "(\<And>x. \<exists>y. R x y) \<Longrightarrow> left_total R"
+unfolding left_total_def by blast
+
+lemma left_totalE:
+  assumes "left_total R"
+  obtains "(\<And>x. \<exists>y. R x y)"
+using assms unfolding left_total_def by blast
+
 lemma bi_uniqueDr: "\<lbrakk> bi_unique A; A x y; A x z \<rbrakk> \<Longrightarrow> y = z"
 by(simp add: bi_unique_def)
 
@@ -192,12 +213,41 @@
   "bi_unique R \<longleftrightarrow> (R ===> R ===> op =) (op =) (op =)"
   unfolding bi_unique_def rel_fun_def by auto
 
+lemma [simp]:
+  shows left_unique_conversep: "left_unique A\<inverse>\<inverse> \<longleftrightarrow> right_unique A"
+  and right_unique_conversep: "right_unique A\<inverse>\<inverse> \<longleftrightarrow> left_unique A"
+by(auto simp add: left_unique_def right_unique_def)
+
+lemma [simp]:
+  shows left_total_conversep: "left_total A\<inverse>\<inverse> \<longleftrightarrow> right_total A"
+  and right_total_conversep: "right_total A\<inverse>\<inverse> \<longleftrightarrow> left_total A"
+by(simp_all add: left_total_def right_total_def)
+
 lemma bi_unique_conversep [simp]: "bi_unique R\<inverse>\<inverse> = bi_unique R"
 by(auto simp add: bi_unique_def)
 
 lemma bi_total_conversep [simp]: "bi_total R\<inverse>\<inverse> = bi_total R"
 by(auto simp add: bi_total_def)
 
+lemma bi_total_iff: "bi_total A = (right_total A \<and> left_total A)"
+unfolding left_total_def right_total_def bi_total_def by blast
+
+lemma bi_total_conv_left_right: "bi_total R \<longleftrightarrow> left_total R \<and> right_total R"
+by(simp add: left_total_def right_total_def bi_total_def)
+
+lemma bi_unique_iff: "bi_unique A  \<longleftrightarrow> right_unique A \<and> left_unique A"
+unfolding left_unique_def right_unique_def bi_unique_def by blast
+
+lemma bi_unique_conv_left_right: "bi_unique R \<longleftrightarrow> left_unique R \<and> right_unique R"
+by(auto simp add: left_unique_def right_unique_def bi_unique_def)
+
+lemma bi_totalI: "left_total R \<Longrightarrow> right_total R \<Longrightarrow> bi_total R"
+unfolding bi_total_iff ..
+
+lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R"
+unfolding bi_unique_iff ..
+
+
 text {* Properties are preserved by relation composition. *}
 
 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)"
@@ -217,21 +267,52 @@
   "\<lbrakk>right_unique A; right_unique B\<rbrakk> \<Longrightarrow> right_unique (A OO B)"
   unfolding right_unique_def OO_def by fast
 
+lemma left_total_OO: "left_total R \<Longrightarrow> left_total S \<Longrightarrow> left_total (R OO S)"
+unfolding left_total_def OO_def by fast
+
+lemma left_unique_OO: "left_unique R \<Longrightarrow> left_unique S \<Longrightarrow> left_unique (R OO S)"
+unfolding left_unique_def OO_def by blast
+
 
 subsection {* Properties of relators *}
 
-lemma right_total_eq [transfer_rule]: "right_total (op =)"
+lemma left_total_eq[transfer_rule]: "left_total op=" 
+  unfolding left_total_def by blast
+
+lemma left_unique_eq[transfer_rule]: "left_unique op=" 
+  unfolding left_unique_def by blast
+
+lemma right_total_eq [transfer_rule]: "right_total op="
   unfolding right_total_def by simp
 
-lemma right_unique_eq [transfer_rule]: "right_unique (op =)"
+lemma right_unique_eq [transfer_rule]: "right_unique op="
   unfolding right_unique_def by simp
 
-lemma bi_total_eq [transfer_rule]: "bi_total (op =)"
+lemma bi_total_eq[transfer_rule]: "bi_total (op =)"
   unfolding bi_total_def by simp
 
-lemma bi_unique_eq [transfer_rule]: "bi_unique (op =)"
+lemma bi_unique_eq[transfer_rule]: "bi_unique (op =)"
   unfolding bi_unique_def by simp
 
+lemma left_total_fun[transfer_rule]:
+  "\<lbrakk>left_unique A; left_total B\<rbrakk> \<Longrightarrow> left_total (A ===> B)"
+  unfolding left_total_def rel_fun_def
+  apply (rule allI, rename_tac f)
+  apply (rule_tac x="\<lambda>y. SOME z. B (f (THE x. A x y)) z" in exI)
+  apply clarify
+  apply (subgoal_tac "(THE x. A x y) = x", simp)
+  apply (rule someI_ex)
+  apply (simp)
+  apply (rule the_equality)
+  apply assumption
+  apply (simp add: left_unique_def)
+  done
+
+lemma left_unique_fun[transfer_rule]:
+  "\<lbrakk>left_total A; left_unique B\<rbrakk> \<Longrightarrow> left_unique (A ===> B)"
+  unfolding left_total_def left_unique_def rel_fun_def
+  by (clarify, rule ext, fast)
+
 lemma right_total_fun [transfer_rule]:
   "\<lbrakk>right_unique A; right_total B\<rbrakk> \<Longrightarrow> right_total (A ===> B)"
   unfolding right_total_def rel_fun_def
@@ -251,35 +332,15 @@
   unfolding right_total_def right_unique_def rel_fun_def
   by (clarify, rule ext, fast)
 
-lemma bi_total_fun [transfer_rule]:
+lemma bi_total_fun[transfer_rule]:
   "\<lbrakk>bi_unique A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A ===> B)"
-  unfolding bi_total_def rel_fun_def
-  apply safe
-  apply (rename_tac f)
-  apply (rule_tac x="\<lambda>y. SOME z. B (f (THE x. A x y)) z" in exI)
-  apply clarify
-  apply (subgoal_tac "(THE x. A x y) = x", simp)
-  apply (rule someI_ex)
-  apply (simp)
-  apply (rule the_equality)
-  apply assumption
-  apply (simp add: bi_unique_def)
-  apply (rename_tac g)
-  apply (rule_tac x="\<lambda>x. SOME z. B z (g (THE y. A x y))" in exI)
-  apply clarify
-  apply (subgoal_tac "(THE y. A x y) = y", simp)
-  apply (rule someI_ex)
-  apply (simp)
-  apply (rule the_equality)
-  apply assumption
-  apply (simp add: bi_unique_def)
-  done
+  unfolding bi_unique_iff bi_total_iff
+  by (blast intro: right_total_fun left_total_fun)
 
-lemma bi_unique_fun [transfer_rule]:
+lemma bi_unique_fun[transfer_rule]:
   "\<lbrakk>bi_total A; bi_unique B\<rbrakk> \<Longrightarrow> bi_unique (A ===> B)"
-  unfolding bi_total_def bi_unique_def rel_fun_def fun_eq_iff
-  by fast+
-
+  unfolding bi_unique_iff bi_total_iff
+  by (blast intro: right_unique_fun left_unique_fun)
 
 subsection {* Transfer rules *}
 
@@ -318,6 +379,16 @@
   "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)"
   unfolding right_unique_alt_def .
 
+text {* Transfer rules using equality. *}
+
+lemma left_unique_transfer [transfer_rule]:
+  assumes "right_total A"
+  assumes "right_total B"
+  assumes "bi_unique A"
+  shows "((A ===> B ===> op=) ===> implies) left_unique left_unique"
+using assms unfolding left_unique_def[abs_def] right_total_def bi_unique_def rel_fun_def
+by metis
+
 lemma eq_transfer [transfer_rule]:
   assumes "bi_unique A"
   shows "(A ===> A ===> op =) (op =) (op =)"