src/HOL/Lifting.thy
changeset 55945 e96383acecf9
parent 55737 84f6ac9f6e41
child 56517 7e8a369eb10d
equal deleted inserted replaced
55944:7ab8f003fe41 55945:e96383acecf9
    50 lemma left_unique_transfer [transfer_rule]:
    50 lemma left_unique_transfer [transfer_rule]:
    51   assumes [transfer_rule]: "right_total A"
    51   assumes [transfer_rule]: "right_total A"
    52   assumes [transfer_rule]: "right_total B"
    52   assumes [transfer_rule]: "right_total B"
    53   assumes [transfer_rule]: "bi_unique A"
    53   assumes [transfer_rule]: "bi_unique A"
    54   shows "((A ===> B ===> op=) ===> implies) left_unique left_unique"
    54   shows "((A ===> B ===> op=) ===> implies) left_unique left_unique"
    55 using assms unfolding left_unique_def[abs_def] right_total_def bi_unique_def fun_rel_def
    55 using assms unfolding left_unique_def[abs_def] right_total_def bi_unique_def rel_fun_def
    56 by metis
    56 by metis
    57 
    57 
    58 lemma bi_unique_iff: "bi_unique A = (right_unique A \<and> left_unique A)"
    58 lemma bi_unique_iff: "bi_unique A = (right_unique A \<and> left_unique A)"
    59 unfolding left_unique_def right_unique_def bi_unique_def by blast
    59 unfolding left_unique_def right_unique_def bi_unique_def by blast
    60 
    60 
    67 lemma left_uniqueD: "\<lbrakk> left_unique A; A x z; A y z \<rbrakk> \<Longrightarrow> x = y"
    67 lemma left_uniqueD: "\<lbrakk> left_unique A; A x z; A y z \<rbrakk> \<Longrightarrow> x = y"
    68 unfolding left_unique_def by blast
    68 unfolding left_unique_def by blast
    69 
    69 
    70 lemma left_total_fun:
    70 lemma left_total_fun:
    71   "\<lbrakk>left_unique A; left_total B\<rbrakk> \<Longrightarrow> left_total (A ===> B)"
    71   "\<lbrakk>left_unique A; left_total B\<rbrakk> \<Longrightarrow> left_total (A ===> B)"
    72   unfolding left_total_def fun_rel_def
    72   unfolding left_total_def rel_fun_def
    73   apply (rule allI, rename_tac f)
    73   apply (rule allI, rename_tac f)
    74   apply (rule_tac x="\<lambda>y. SOME z. B (f (THE x. A x y)) z" in exI)
    74   apply (rule_tac x="\<lambda>y. SOME z. B (f (THE x. A x y)) z" in exI)
    75   apply clarify
    75   apply clarify
    76   apply (subgoal_tac "(THE x. A x y) = x", simp)
    76   apply (subgoal_tac "(THE x. A x y) = x", simp)
    77   apply (rule someI_ex)
    77   apply (rule someI_ex)
    81   apply (simp add: left_unique_def)
    81   apply (simp add: left_unique_def)
    82   done
    82   done
    83 
    83 
    84 lemma left_unique_fun:
    84 lemma left_unique_fun:
    85   "\<lbrakk>left_total A; left_unique B\<rbrakk> \<Longrightarrow> left_unique (A ===> B)"
    85   "\<lbrakk>left_total A; left_unique B\<rbrakk> \<Longrightarrow> left_unique (A ===> B)"
    86   unfolding left_total_def left_unique_def fun_rel_def
    86   unfolding left_total_def left_unique_def rel_fun_def
    87   by (clarify, rule ext, fast)
    87   by (clarify, rule ext, fast)
    88 
    88 
    89 lemma left_total_eq: "left_total op=" unfolding left_total_def by blast
    89 lemma left_total_eq: "left_total op=" unfolding left_total_def by blast
    90 
    90 
    91 lemma left_unique_eq: "left_unique op=" unfolding left_unique_def by blast
    91 lemma left_unique_eq: "left_unique op=" unfolding left_unique_def by blast
   240 lemma fun_quotient:
   240 lemma fun_quotient:
   241   assumes 1: "Quotient R1 abs1 rep1 T1"
   241   assumes 1: "Quotient R1 abs1 rep1 T1"
   242   assumes 2: "Quotient R2 abs2 rep2 T2"
   242   assumes 2: "Quotient R2 abs2 rep2 T2"
   243   shows "Quotient (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2) (T1 ===> T2)"
   243   shows "Quotient (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2) (T1 ===> T2)"
   244   using assms unfolding Quotient_alt_def2
   244   using assms unfolding Quotient_alt_def2
   245   unfolding fun_rel_def fun_eq_iff map_fun_apply
   245   unfolding rel_fun_def fun_eq_iff map_fun_apply
   246   by (safe, metis+)
   246   by (safe, metis+)
   247 
   247 
   248 lemma apply_rsp:
   248 lemma apply_rsp:
   249   fixes f g::"'a \<Rightarrow> 'c"
   249   fixes f g::"'a \<Rightarrow> 'c"
   250   assumes q: "Quotient R1 Abs1 Rep1 T1"
   250   assumes q: "Quotient R1 Abs1 Rep1 T1"
   251   and     a: "(R1 ===> R2) f g" "R1 x y"
   251   and     a: "(R1 ===> R2) f g" "R1 x y"
   252   shows "R2 (f x) (g y)"
   252   shows "R2 (f x) (g y)"
   253   using a by (auto elim: fun_relE)
   253   using a by (auto elim: rel_funE)
   254 
   254 
   255 lemma apply_rsp':
   255 lemma apply_rsp':
   256   assumes a: "(R1 ===> R2) f g" "R1 x y"
   256   assumes a: "(R1 ===> R2) f g" "R1 x y"
   257   shows "R2 (f x) (g y)"
   257   shows "R2 (f x) (g y)"
   258   using a by (auto elim: fun_relE)
   258   using a by (auto elim: rel_funE)
   259 
   259 
   260 lemma apply_rsp'':
   260 lemma apply_rsp'':
   261   assumes "Quotient R Abs Rep T"
   261   assumes "Quotient R Abs Rep T"
   262   and "(R ===> S) f f"
   262   and "(R ===> S) f f"
   263   shows "S (f (Rep x)) (f (Rep x))"
   263   shows "S (f (Rep x)) (f (Rep x))"
   294 lemma invariant_to_eq:
   294 lemma invariant_to_eq:
   295   assumes "invariant P x y"
   295   assumes "invariant P x y"
   296   shows "x = y"
   296   shows "x = y"
   297 using assms by (simp add: invariant_def)
   297 using assms by (simp add: invariant_def)
   298 
   298 
   299 lemma fun_rel_eq_invariant: "(op= ===> Lifting.invariant P) = Lifting.invariant (\<lambda>f. \<forall>x. P(f x))"
   299 lemma rel_fun_eq_invariant: "(op= ===> Lifting.invariant P) = Lifting.invariant (\<lambda>f. \<forall>x. P(f x))"
   300 unfolding invariant_def fun_rel_def by auto
   300 unfolding invariant_def rel_fun_def by auto
   301 
   301 
   302 lemma fun_rel_invariant_rel:
   302 lemma rel_fun_invariant_rel:
   303   shows "((invariant R) ===> S) = (\<lambda>f g. \<forall>x. R x \<longrightarrow> S (f x) (g x))"
   303   shows "((invariant R) ===> S) = (\<lambda>f g. \<forall>x. R x \<longrightarrow> S (f x) (g x))"
   304 by (auto simp add: invariant_def fun_rel_def)
   304 by (auto simp add: invariant_def rel_fun_def)
   305 
   305 
   306 lemma invariant_same_args:
   306 lemma invariant_same_args:
   307   shows "invariant P x x \<equiv> P x"
   307   shows "invariant P x x \<equiv> P x"
   308 using assms by (auto simp add: invariant_def)
   308 using assms by (auto simp add: invariant_def)
   309 
   309 
   374 
   374 
   375 lemma Quotient_right_total: "right_total T"
   375 lemma Quotient_right_total: "right_total T"
   376   using 1 unfolding Quotient_alt_def right_total_def by metis
   376   using 1 unfolding Quotient_alt_def right_total_def by metis
   377 
   377 
   378 lemma Quotient_rel_eq_transfer: "(T ===> T ===> op =) R (op =)"
   378 lemma Quotient_rel_eq_transfer: "(T ===> T ===> op =) R (op =)"
   379   using 1 unfolding Quotient_alt_def fun_rel_def by simp
   379   using 1 unfolding Quotient_alt_def rel_fun_def by simp
   380 
   380 
   381 lemma Quotient_abs_induct:
   381 lemma Quotient_abs_induct:
   382   assumes "\<And>y. R y y \<Longrightarrow> P (Abs y)" shows "P x"
   382   assumes "\<And>y. R y y \<Longrightarrow> P (Abs y)" shows "P x"
   383   using 1 assms unfolding Quotient_def by metis
   383   using 1 assms unfolding Quotient_def by metis
   384 
   384 
   393 
   393 
   394 lemma Quotient_bi_total: "bi_total T"
   394 lemma Quotient_bi_total: "bi_total T"
   395   using 1 2 unfolding Quotient_alt_def bi_total_def reflp_def by auto
   395   using 1 2 unfolding Quotient_alt_def bi_total_def reflp_def by auto
   396 
   396 
   397 lemma Quotient_id_abs_transfer: "(op = ===> T) (\<lambda>x. x) Abs"
   397 lemma Quotient_id_abs_transfer: "(op = ===> T) (\<lambda>x. x) Abs"
   398   using 1 2 unfolding Quotient_alt_def reflp_def fun_rel_def by simp
   398   using 1 2 unfolding Quotient_alt_def reflp_def rel_fun_def by simp
   399 
   399 
   400 lemma Quotient_total_abs_induct: "(\<And>y. P (Abs y)) \<Longrightarrow> P x"
   400 lemma Quotient_total_abs_induct: "(\<And>y. P (Abs y)) \<Longrightarrow> P x"
   401   using 1 2 assms unfolding Quotient_alt_def reflp_def by metis
   401   using 1 2 assms unfolding Quotient_alt_def reflp_def by metis
   402 
   402 
   403 lemma Quotient_total_abs_eq_iff: "Abs x = Abs y \<longleftrightarrow> R x y"
   403 lemma Quotient_total_abs_eq_iff: "Abs x = Abs y \<longleftrightarrow> R x y"
   430 lemma typedef_right_total: "right_total T"
   430 lemma typedef_right_total: "right_total T"
   431   using T_def type Quotient_right_total typedef_to_Quotient 
   431   using T_def type Quotient_right_total typedef_to_Quotient 
   432   by blast
   432   by blast
   433 
   433 
   434 lemma typedef_rep_transfer: "(T ===> op =) (\<lambda>x. x) Rep"
   434 lemma typedef_rep_transfer: "(T ===> op =) (\<lambda>x. x) Rep"
   435   unfolding fun_rel_def T_def by simp
   435   unfolding rel_fun_def T_def by simp
   436 
   436 
   437 end
   437 end
   438 
   438 
   439 text {* Generating the correspondence rule for a constant defined with
   439 text {* Generating the correspondence rule for a constant defined with
   440   @{text "lift_definition"}. *}
   440   @{text "lift_definition"}. *}
   555 
   555 
   556 lemma fun_mono:
   556 lemma fun_mono:
   557   assumes "A \<ge> C"
   557   assumes "A \<ge> C"
   558   assumes "B \<le> D"
   558   assumes "B \<le> D"
   559   shows   "(A ===> B) \<le> (C ===> D)"
   559   shows   "(A ===> B) \<le> (C ===> D)"
   560 using assms unfolding fun_rel_def by blast
   560 using assms unfolding rel_fun_def by blast
   561 
   561 
   562 lemma pos_fun_distr: "((R ===> S) OO (R' ===> S')) \<le> ((R OO R') ===> (S OO S'))"
   562 lemma pos_fun_distr: "((R ===> S) OO (R' ===> S')) \<le> ((R OO R') ===> (S OO S'))"
   563 unfolding OO_def fun_rel_def by blast
   563 unfolding OO_def rel_fun_def by blast
   564 
   564 
   565 lemma functional_relation: "right_unique R \<Longrightarrow> left_total R \<Longrightarrow> \<forall>x. \<exists>!y. R x y"
   565 lemma functional_relation: "right_unique R \<Longrightarrow> left_total R \<Longrightarrow> \<forall>x. \<exists>!y. R x y"
   566 unfolding right_unique_def left_total_def by blast
   566 unfolding right_unique_def left_total_def by blast
   567 
   567 
   568 lemma functional_converse_relation: "left_unique R \<Longrightarrow> right_total R \<Longrightarrow> \<forall>y. \<exists>!x. R x y"
   568 lemma functional_converse_relation: "left_unique R \<Longrightarrow> right_total R \<Longrightarrow> \<forall>y. \<exists>!x. R x y"
   571 lemma neg_fun_distr1:
   571 lemma neg_fun_distr1:
   572 assumes 1: "left_unique R" "right_total R"
   572 assumes 1: "left_unique R" "right_total R"
   573 assumes 2: "right_unique R'" "left_total R'"
   573 assumes 2: "right_unique R'" "left_total R'"
   574 shows "(R OO R' ===> S OO S') \<le> ((R ===> S) OO (R' ===> S')) "
   574 shows "(R OO R' ===> S OO S') \<le> ((R ===> S) OO (R' ===> S')) "
   575   using functional_relation[OF 2] functional_converse_relation[OF 1]
   575   using functional_relation[OF 2] functional_converse_relation[OF 1]
   576   unfolding fun_rel_def OO_def
   576   unfolding rel_fun_def OO_def
   577   apply clarify
   577   apply clarify
   578   apply (subst all_comm)
   578   apply (subst all_comm)
   579   apply (subst all_conj_distrib[symmetric])
   579   apply (subst all_conj_distrib[symmetric])
   580   apply (intro choice)
   580   apply (intro choice)
   581   by metis
   581   by metis
   583 lemma neg_fun_distr2:
   583 lemma neg_fun_distr2:
   584 assumes 1: "right_unique R'" "left_total R'"
   584 assumes 1: "right_unique R'" "left_total R'"
   585 assumes 2: "left_unique S'" "right_total S'"
   585 assumes 2: "left_unique S'" "right_total S'"
   586 shows "(R OO R' ===> S OO S') \<le> ((R ===> S) OO (R' ===> S'))"
   586 shows "(R OO R' ===> S OO S') \<le> ((R ===> S) OO (R' ===> S'))"
   587   using functional_converse_relation[OF 2] functional_relation[OF 1]
   587   using functional_converse_relation[OF 2] functional_relation[OF 1]
   588   unfolding fun_rel_def OO_def
   588   unfolding rel_fun_def OO_def
   589   apply clarify
   589   apply clarify
   590   apply (subst all_comm)
   590   apply (subst all_comm)
   591   apply (subst all_conj_distrib[symmetric])
   591   apply (subst all_conj_distrib[symmetric])
   592   apply (intro choice)
   592   apply (intro choice)
   593   by metis
   593   by metis
   597 lemma composed_equiv_rel_invariant:
   597 lemma composed_equiv_rel_invariant:
   598   assumes "left_unique R"
   598   assumes "left_unique R"
   599   assumes "(R ===> op=) P P'"
   599   assumes "(R ===> op=) P P'"
   600   assumes "Domainp R = P''"
   600   assumes "Domainp R = P''"
   601   shows "(R OO Lifting.invariant P' OO R\<inverse>\<inverse>) = Lifting.invariant (inf P'' P)"
   601   shows "(R OO Lifting.invariant P' OO R\<inverse>\<inverse>) = Lifting.invariant (inf P'' P)"
   602 using assms unfolding OO_def conversep_iff Domainp_iff[abs_def] left_unique_def fun_rel_def invariant_def
   602 using assms unfolding OO_def conversep_iff Domainp_iff[abs_def] left_unique_def rel_fun_def invariant_def
   603 fun_eq_iff by blast
   603 fun_eq_iff by blast
   604 
   604 
   605 lemma composed_equiv_rel_eq_invariant:
   605 lemma composed_equiv_rel_eq_invariant:
   606   assumes "left_unique R"
   606   assumes "left_unique R"
   607   assumes "Domainp R = P"
   607   assumes "Domainp R = P"
   613   assumes "Domainp B = P"
   613   assumes "Domainp B = P"
   614   assumes "left_total A"
   614   assumes "left_total A"
   615   assumes "(A ===> op=) P' P"
   615   assumes "(A ===> op=) P' P"
   616   shows "Domainp (A OO B) = P'"
   616   shows "Domainp (A OO B) = P'"
   617 using assms
   617 using assms
   618 unfolding Domainp_iff[abs_def] OO_def bi_unique_def left_total_def fun_rel_def 
   618 unfolding Domainp_iff[abs_def] OO_def bi_unique_def left_total_def rel_fun_def 
   619 by (fast intro: fun_eq_iff)
   619 by (fast intro: fun_eq_iff)
   620 
   620 
   621 lemma pcr_Domainp_par:
   621 lemma pcr_Domainp_par:
   622 assumes "Domainp B = P2"
   622 assumes "Domainp B = P2"
   623 assumes "Domainp A = P1"
   623 assumes "Domainp A = P1"
   624 assumes "(A ===> op=) P2' P2"
   624 assumes "(A ===> op=) P2' P2"
   625 shows "Domainp (A OO B) = (inf P1 P2')"
   625 shows "Domainp (A OO B) = (inf P1 P2')"
   626 using assms unfolding fun_rel_def Domainp_iff[abs_def] OO_def
   626 using assms unfolding rel_fun_def Domainp_iff[abs_def] OO_def
   627 by (fast intro: fun_eq_iff)
   627 by (fast intro: fun_eq_iff)
   628 
   628 
   629 definition rel_pred_comp :: "('a => 'b => bool) => ('b => bool) => 'a => bool"
   629 definition rel_pred_comp :: "('a => 'b => bool) => ('b => bool) => 'a => bool"
   630 where "rel_pred_comp R P \<equiv> \<lambda>x. \<exists>y. R x y \<and> P y"
   630 where "rel_pred_comp R P \<equiv> \<lambda>x. \<exists>y. R x y \<and> P y"
   631 
   631