Theory Transfer_Ext

(* Title: Examples/SML_Relativization/Foundations/Transfer_Ext.thy
   Author: Mihails Milehins
   Copyright 2021 (C) Mihails Milehins
*)
section‹Extension of the theory text‹Transfer››
theory Transfer_Ext
  imports Main
begin

lemma bi_unique_intersect_r:
  assumes "bi_unique T" 
    and "rel_set T a a'" 
    and "rel_set T b b'" 
    and "rel_set T (a ∩ b) xr" 
  shows "a' ∩ b' = xr"
proof -
  {
    fix x assume "x ∈ a ∩ b"
    then have "x ∈ a" and "x ∈ b" by simp+
    from assms(2) ‹x ∈ a› have "∃y ∈ a'. T x y" by (rule rel_setD1)
    moreover from assms(3) ‹x ∈ b› have "∃y ∈ b'. T x y" by (rule rel_setD1)
    ultimately have "∃y ∈ a' ∩ b'. T x y" 
      using assms(1) by (auto dest: bi_uniqueDr)
  }
  note unique_r = this
  {
    fix x assume "x ∈ a' ∩ b'"
    then have "x ∈ a'" and "x ∈ b'" by simp+
    from assms(2) ‹x ∈ a'› have "∃y ∈ a. T y x" by (rule rel_setD2)
    moreover from assms(3) ‹x ∈ b'› have "∃y ∈ b. T y x" by (rule rel_setD2)
    ultimately have "∃y ∈ a ∩ b. T y x" 
      using assms(1) by (auto dest: bi_uniqueDl)
  }
  with unique_r have "rel_set T (a ∩ b) (a' ∩ b')" using rel_setI by blast 
  with assms(1,4) show ?thesis by (auto dest: bi_uniqueDr bi_unique_rel_set)
qed

lemma bi_unique_intersect_l:
  assumes "bi_unique T" 
    and "rel_set T a a'" 
    and "rel_set T b b'" 
    and "rel_set T xl (a' ∩ b')" 
  shows "a ∩ b = xl"
proof -
  let ?T' = "λ y x. T x y"
  from assms(1) have "bi_unique ?T'" unfolding bi_unique_def by simp
  moreover from assms(2) have "rel_set ?T' a' a" unfolding rel_set_def by simp
  moreover from assms(3) have "rel_set ?T' b' b" unfolding rel_set_def by simp
  moreover from assms(4) have "rel_set ?T' (a' ∩ b') xl" 
    unfolding rel_set_def by simp
  ultimately show ?thesis by (rule bi_unique_intersect_r)
qed

lemma bi_unique_intersect:
  assumes "bi_unique T" and "rel_set T a a'" and "rel_set T b b'" 
  shows "rel_set T (a ∩ b) (a' ∩ b')" 
proof -
  {
    fix xl assume "xl ∈ a ∩ b"
    then have "xl ∈ a" and "xl ∈ b" by simp+
    with assms(3) obtain xr where "T xl xr" unfolding rel_set_def by auto
    with assms(1,2) ‹xl ∈ a› have "xr ∈ a'"
      by (auto dest: bi_uniqueDr rel_setD1)
    moreover with assms(1,3) ‹xl ∈ b› ‹T xl xr› have "xr ∈ b'" 
      by (auto dest: bi_uniqueDr rel_setD1)
    ultimately have "xr ∈ a' ∩ b'" by simp
    with ‹T xl xr› have "∃xr. xr ∈ a' ∩ b' ∧ T xl xr" by auto
  }
  then have prem_lhs: "∀xl ∈ a ∩ b. ∃xr. xr ∈ a' ∩ b' ∧ T xl xr" by simp  
  {
    fix xr
    assume "xr ∈ a' ∩ b'"
    then have "xr ∈ a'" and "xr ∈ b'" by simp+
    with assms(3) obtain xl where "T xl xr" unfolding rel_set_def by auto
    with assms(1,2) ‹xr ∈ a'› have "xl ∈ a" 
      by (auto dest: bi_uniqueDl rel_setD2)
    moreover with assms(1,3) ‹xr ∈ b'› ‹T xl xr› have "xl ∈ b" 
      by (auto dest: bi_uniqueDl rel_setD2)
    ultimately have "xl ∈ a ∩ b" by simp
    with ‹T xl xr› have "∃xl. xl ∈ a ∩ b ∧ T xl xr" by auto
  }
  then have prem_rhs: "∀xr ∈ a' ∩ b'. ∃xl. xl ∈ a ∩ b ∧ T xl xr" by simp
  from prem_lhs prem_rhs show ?thesis unfolding rel_set_def by auto
qed

lemma bi_unique_union_r:
  assumes "bi_unique T" 
    and "rel_set T a a'" 
    and "rel_set T b b'" 
    and "rel_set T (a ∪ b) xr" 
  shows "a' ∪ b' = xr"
proof -
  {
    fix x assume "x ∈ a ∪ b"
    then have "x ∈ a ∨ x ∈ b" by simp
    from assms(2) have "∃y ∈ a'. T x y" if "x ∈ a" 
      using that by (rule rel_setD1)
    moreover from assms(3) have "∃y ∈ b'. T x y" if "x ∈ b" 
      using that by (rule rel_setD1)
    ultimately have "∃y ∈ a' ∪ b'. T x y" using ‹x ∈ a ∨ x ∈ b› by auto
  }
  note unique_r = this
  {
    fix x assume "x ∈ a' ∪ b'"
    then have "x ∈ a' ∨ x ∈ b'" by simp
    from assms(2) have "∃y ∈ a. T y x" if "x ∈ a'" 
      using that by (rule rel_setD2)
    moreover from assms(3) have "∃y ∈ b. T y x" if "x ∈ b'" 
      using that by (rule rel_setD2)
    ultimately have "∃y ∈ a ∪ b. T y x" using ‹x ∈ a' ∨ x ∈ b'› by auto
  }
  with unique_r have "rel_set T (a ∪ b) (a' ∪ b')" by (auto intro: rel_setI) 
  with assms(1,4) show ?thesis by (auto dest: bi_uniqueDr bi_unique_rel_set)
qed

lemma bi_unique_union_l:
  assumes "bi_unique T" 
    and "rel_set T a a'" 
    and "rel_set T b b'" 
    and "rel_set T xl (a' ∪ b')" 
  shows "a ∪ b = xl"
proof -
  let ?T' = "λy x. T x y"
  from assms(1) have "bi_unique ?T'" unfolding bi_unique_def by simp
  moreover from assms(2) have "rel_set ?T' a' a" unfolding rel_set_def by simp
  moreover from assms(3) have "rel_set ?T' b' b" unfolding rel_set_def by simp
  moreover from assms(4) have "rel_set ?T' (a' ∪ b') xl" 
    unfolding rel_set_def by simp
  ultimately show ?thesis by (rule bi_unique_union_r)
qed

lemma bi_unique_union:
  assumes "bi_unique T" and "rel_set T a a'" and "rel_set T b b'" 
  shows "rel_set T (a ∪ b) (a' ∪ b')" 
proof -
  {
    fix xl assume "xl ∈ a ∪ b"
    with assms(2,3) obtain xr where "T xl xr" unfolding rel_set_def by auto
    with assms ‹xl ∈ a ∪ b› have "xr ∈ a' ∪ b'"
      unfolding bi_unique_def using Un_iff by (metis Un_iff rel_setD1)
    with ‹T xl xr› have "∃xr. xr ∈ a' ∪ b' ∧ T xl xr" by auto
  }
  then have prem_lhs: "∀xl ∈ a ∪ b. ∃xr. xr ∈ a' ∪ b' ∧ T xl xr" by simp  
  {
    fix xr assume "xr ∈ a' ∪ b'"
    with assms(2,3) obtain xl where "T xl xr" unfolding rel_set_def by auto
    with assms ‹xr ∈ a' ∪ b'› have "xl ∈ a ∪ b"
      unfolding bi_unique_def by (metis Un_iff rel_setD2)
    with ‹T xl xr› have "∃xl. xl ∈ a ∪ b ∧ T xl xr" by auto
  }
  then have prem_rhs: "∀xr ∈ a' ∪ b'. ∃xl. xl ∈ a ∪ b ∧ T xl xr" by simp
  from prem_lhs prem_rhs show ?thesis unfolding rel_set_def by auto
qed

lemma bi_unique_Union_r:
  fixes T :: "['a, 'b] ⇒ bool" and K
  defines K':  "K' ≡ {(x, y). rel_set T x y} `` K"
  assumes "bi_unique T" 
    and "⋃K ⊆ Collect (Domainp T)" 
    and "rel_set T (⋃K) xr" 
  shows "⋃K' = xr"
proof -
  {
    fix x assume "x ∈ ⋃K"
    then obtain k where "x ∈ k" and "k ∈ K" by clarsimp
    from assms have ex_k'_prem: "∀k ∈ K. ∀x ∈ k. ∃x'. T x x'" by auto
    define k' where k': "k' = {x'. ∃x ∈ k. T x x'}" 
    have "rel_set T k k'" 
      unfolding rel_set_def Bex_def k' 
      using ‹k ∈ K› by (blast dest: ex_k'_prem[rule_format])
    with ‹k ∈ K› have "k' ∈ K'" unfolding K' by auto
    from ‹rel_set T k k'› ‹x ∈ k› obtain y where "y ∈ k' ∧ T x y" 
      by (auto dest: rel_setD1)
    then have "∃y ∈ ⋃K'. T x y" using ‹k' ∈ K'› by auto
  }
  note unique_r = this
  {
    fix x' assume "x' ∈ ⋃K'"
    then obtain k' where "x' ∈ k'" and "k' ∈ K'" by clarsimp
    then have ex_k_prem: "∀k' ∈ K'. ∀x ∈ k'. ∃x. T x x'" 
      unfolding K' by (auto dest: rel_setD2)
    define k where k: "k = {x. ∃x' ∈ k'. T x x'}"
    have "rel_set T k k'" 
      unfolding rel_set_def Bex_def k 
      using ‹k' ∈ K'› K' by (blast dest: rel_setD2)
    from assms(2) have "bi_unique (rel_set T)" by (rule bi_unique_rel_set)
    with ‹rel_set T k k'› have "∃!k. rel_set T k k'" by (auto dest: bi_uniqueDl)
    with ‹rel_set T k k'› K' ‹k' ∈ K'› have "k ∈ K" by auto
    from ‹rel_set T k k'› ‹x' ∈ k'› obtain y where "y ∈ k ∧ T y x'" 
      by (auto dest: rel_setD2)
    then have "∃y ∈ ⋃K. T y x'" using ‹k ∈ K› by auto
  }
  with unique_r have "rel_set T (⋃K) (⋃K')" by (intro rel_setI) 
  with assms(2,4) show ?thesis by (auto dest: bi_uniqueDr bi_unique_rel_set)
qed

lemma bi_unique_Union_l:
  fixes T :: "['a, 'b] ⇒ bool" and K'
  defines K: "K ≡ {(x, y). rel_set (λ y x. T x y) x y} `` K'"
  assumes "bi_unique T" 
    and "⋃K' ⊆ Collect (Rangep T)" 
    and "rel_set T xl (⋃K')" 
  shows "⋃K = xl"
proof -
  let ?T' = "λ y x. T x y"
  from assms(2) have "bi_unique ?T'" unfolding bi_unique_def by simp
  moreover from assms(3) have "⋃K' ⊆ Collect (Domainp ?T')" by blast
  moreover from assms(4) have "rel_set ?T' (⋃K') xl" 
    unfolding rel_set_def by simp
  ultimately have "⋃({(x, y). rel_set ?T' x y} `` K') = xl" 
    by (rule bi_unique_Union_r)
  thus ?thesis using K by simp
qed

context
  includes lifting_syntax
begin

text‹
The lemma text‹Domainp_applyI› was adopted from the lemma with the 
identical name in the theory text‹Types_To_Sets/Group_on_With.thy›.
›
lemma Domainp_applyI:
  includes lifting_syntax
  shows "(A ===> B) f g ⟹ A x y ⟹ Domainp B (f x)"
  by (auto simp: rel_fun_def)

lemma Domainp_fun:
  assumes "left_unique A" 
  shows 
    "Domainp (rel_fun A B) = 
      (λf. f ` (Collect (Domainp A)) ⊆ (Collect (Domainp B)))"
proof-
  have 
    "pred_fun (Domainp A) (Domainp B) = 
      (λf. f ` (Collect (Domainp A)) ⊆ (Collect (Domainp B)))"
    by (simp add: image_subset_iff)
  from Domainp_pred_fun_eq[OF ‹left_unique A›, of B, unfolded this]
  show ?thesis .  
qed

lemma Bex_fun_transfer[transfer_rule]:
  assumes "bi_unique A" "right_total B"
  shows 
    "(((A ===> B) ===> (=)) ===> (=)) 
      (Bex (Collect (λf. f ` (Collect (Domainp A)) ⊆ (Collect (Domainp B))))) 
      Ex"
proof-
  from assms(1) have "left_unique A" by (simp add: bi_unique_alt_def)
  note right_total_BA[transfer_rule] = 
    right_total_fun[
      OF conjunct2[OF bi_unique_alt_def[THEN iffD1, OF assms(1)]] assms(2)
      ]
  show ?thesis 
    unfolding Domainp_fun[OF ‹left_unique A›, symmetric]
    by transfer_prover
qed

end

text‹\newpage›

end