Theory Transport_Galois_Relator_Properties

✐‹creator "Kevin Kappelmann"›
✐‹creator "Nils Harmsen"›
section ‹Properties of Galois Relator for White-Box Transport Side Conditions›
theory Transport_Galois_Relator_Properties
  imports
    Binary_Relations_Bi_Total
    Binary_Relations_Bi_Unique
    Galois_Connections
    Galois_Relator
begin

paragraph ‹Summary›
text ‹Properties of Galois relator arising as side conditions for white-box transport.›

context galois
begin

paragraph ‹Right-Uniqueness›

context
  fixes P :: "'a  bool" and Q :: "'b  bool"
begin

lemma right_unique_at_left_Galois_if_right_unique_at_rightI:
  assumes "right_unique_at Q (≤R)"
  and "((≤L) h (≤R)) l r"
  shows "right_unique_at Q (L⪅)"
  using assms by (auto dest: right_unique_atD)

lemma right_unique_at_right_if_right_unique_at_left_GaloisI:
  assumes "right_unique_at Q (L⪅)"
  and "((≤R)  (≤L)) r"
  shows "right_unique_at Q (≤R)"
  using assms by (blast dest: right_unique_atD)

corollary right_unique_at_left_Galois_iff_right_unique_at_rightI:
  assumes "((≤L) h (≤R)) l r"
  and "((≤R)  (≤L)) r"
  shows "right_unique_at Q (L⪅)  right_unique_at Q (≤R)"
  using assms right_unique_at_left_Galois_if_right_unique_at_rightI
    right_unique_at_right_if_right_unique_at_left_GaloisI
  by blast

corollary right_unique_on_left_Galois_if_right_unique_at_rightI:
  assumes "right_unique_at Q (≤R)"
  and "((L⪅)  (⟶)) P Q"
  and "((≤L) h (≤R)) l r"
  shows "right_unique_on P (L⪅)"
  using assms by (intro right_unique_on_if_Fun_Rel_imp_if_right_unique_at)
  (blast intro: right_unique_at_left_Galois_if_right_unique_at_rightI)

corollary right_unique_at_right_if_right_unique_on_left_GaloisI:
  assumes "right_unique_on P (L⪅)"
  and "((L⪅)  (⟵)) P Q"
  and "((≤R)  (≤L)) r"
  shows "right_unique_at Q (≤R)"
  using assms by (intro right_unique_at_right_if_right_unique_at_left_GaloisI
    right_unique_at_if_Fun_Rel_rev_imp_if_right_unique_on)

corollary right_unique_on_left_Galois_iff_right_unique_at_rightI:
  assumes "((L⪅)  (⟷)) P Q"
  and "((≤L) h (≤R)) l r"
  and "((≤R)  (≤L)) r"
  shows "right_unique_on P (L⪅)  right_unique_at Q (≤R)"
  using assms right_unique_on_left_Galois_if_right_unique_at_rightI
    right_unique_at_right_if_right_unique_on_left_GaloisI
  by blast

end

corollary right_unique_left_Galois_if_right_unique_rightI:
  assumes "right_unique (≤R)"
  and "((≤L) h (≤R)) l r"
  shows "right_unique (L⪅)"
  using assms by (urule right_unique_at_left_Galois_if_right_unique_at_rightI)

corollary right_unique_right_if_right_unique_left_GaloisI:
  assumes "right_unique (L⪅)"
  and "((≤R)  (≤L)) r"
  shows "right_unique (≤R)"
  using assms by (urule right_unique_at_right_if_right_unique_at_left_GaloisI)

corollary right_unique_left_Galois_iff_right_unique_rightI:
  assumes "((≤L) h (≤R)) l r"
  and "((≤R)  (≤L)) r"
  shows "right_unique (L⪅)  right_unique (≤R)"
  using assms right_unique_left_Galois_if_right_unique_rightI
    right_unique_right_if_right_unique_left_GaloisI
  by blast


paragraph ‹Injectivity›

context
  fixes P :: "'a  bool" and Q :: "'b  bool"
begin

lemma injective_on_left_Galois_if_rel_injective_on_left:
  assumes "rel_injective_on P (≤L)"
  shows "rel_injective_on P (L⪅)"
  using assms by (auto dest: rel_injective_onD)

lemma rel_injective_on_left_if_injective_on_left_GaloisI:
  assumes "rel_injective_on P (L⪅)"
  and "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective_on P (≤L)"
  using assms by (intro rel_injective_onI) (blast dest!: rel_injective_onD)

corollary injective_on_left_Galois_iff_rel_injective_on_leftI:
  assumes "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective_on P (L⪅)  rel_injective_on P (≤L)"
  using assms injective_on_left_Galois_if_rel_injective_on_left
    rel_injective_on_left_if_injective_on_left_GaloisI
  by blast

corollary injective_at_left_Galois_if_rel_injective_on_leftI:
  assumes "rel_injective_on P (≤L)"
  and "((L⪅)  (⟵)) P Q"
  shows "rel_injective_at Q (L⪅)"
  using assms by (intro rel_injective_at_if_Fun_Rel_rev_imp_if_rel_injective_on)
  (blast intro: injective_on_left_Galois_if_rel_injective_on_left)

corollary rel_injective_on_left_if_injective_at_left_GaloisI:
  assumes "rel_injective_at Q (L⪅)"
  and "((L⪅)  (⟶)) P Q"
  and "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective_on P (≤L)"
  using assms by (intro rel_injective_on_left_if_injective_on_left_GaloisI
    rel_injective_on_if_Fun_Rel_imp_if_rel_injective_at)

corollary injective_at_left_Galois_iff_rel_injective_on_leftI:
  assumes "((L⪅)  (⟷)) P Q"
  and "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective_at Q (L⪅)  rel_injective_on P (≤L)"
  using assms injective_at_left_Galois_if_rel_injective_on_leftI
    rel_injective_on_left_if_injective_at_left_GaloisI
  by blast

end

corollary injective_left_Galois_if_rel_injective_left:
  assumes "rel_injective (≤L)"
  shows "rel_injective (L⪅)"
  using assms by (urule injective_on_left_Galois_if_rel_injective_on_left)

corollary rel_injective_left_if_injective_left_GaloisI:
  assumes "rel_injective (L⪅)"
  and "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows  "rel_injective (≤L)"
  using assms by (urule rel_injective_on_left_if_injective_on_left_GaloisI)

corollary rel_injective_left_Galois_iff_rel_injective_leftI:
  assumes "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective (L⪅)  rel_injective (≤L)"
  using assms injective_left_Galois_if_rel_injective_left
    rel_injective_left_if_injective_left_GaloisI
  by blast


paragraph ‹Bi-Uniqueness›

context
  fixes P :: "'a  bool" and Q :: "'b  bool"
begin

corollary bi_unique_on_left_Galois_if_right_unique_at_right_if_rel_injective_on_leftI:
  assumes "rel_injective_on P (≤L)"
  and "right_unique_at Q (≤R)"
  and "((L⪅)  (⟶)) P Q"
  and "((≤L) h (≤R)) l r"
  shows "bi_unique_on P (L⪅)"
  using assms
  by (intro bi_unique_onI right_unique_on_left_Galois_if_right_unique_at_rightI
    injective_on_left_Galois_if_rel_injective_on_left)

corollary rel_injective_on_left_and_right_unique_at_right_if_bi_unique_on_left_GaloisI:
  assumes "bi_unique_on P (L⪅)"
  and "((L⪅)  (⟵)) P Q"
  and "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective_on P (≤L)  right_unique_at Q (≤R)"
  using assms by (intro conjI rel_injective_on_left_if_injective_on_left_GaloisI
    right_unique_at_right_if_right_unique_on_left_GaloisI)
  auto

corollary bi_unique_on_left_Galois_iff_rel_injective_on_left_and_right_unique_at_rightI:
  assumes "((L⪅)  (⟷)) P Q"
  and "((≤L)  (≤R)) l r"
  shows "bi_unique_on P (L⪅)  rel_injective_on P (≤L)  right_unique_at Q (≤R)"
  using assms bi_unique_on_left_Galois_if_right_unique_at_right_if_rel_injective_on_leftI
    rel_injective_on_left_and_right_unique_at_right_if_bi_unique_on_left_GaloisI
  by blast

end

corollary bi_unique_left_Galois_if_right_unique_right_if_rel_injective_leftI:
  assumes "rel_injective (≤L)"
  and "right_unique (≤R)"
  and "((≤L) h (≤R)) l r"
  shows "bi_unique (L⪅)"
  by (urule (rr) bi_unique_on_left_Galois_if_right_unique_at_right_if_rel_injective_on_leftI assms)
  auto

corollary rel_injective_left_and_right_unique_right_if_bi_unique_left_GaloisI:
  assumes "bi_unique (L⪅)"
  and "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  shows "rel_injective (≤L)  right_unique (≤R)"
  by (urule (rr) rel_injective_on_left_and_right_unique_at_right_if_bi_unique_on_left_GaloisI assms)
  auto

corollary bi_unique_left_Galois_iff_rel_injective_left_and_right_unique_rightI:
  assumes "((≤L)  (≤R)) l r"
  shows "bi_unique (L⪅)  rel_injective (≤L)  right_unique (≤R)"
  using assms bi_unique_left_Galois_if_right_unique_right_if_rel_injective_leftI
    rel_injective_left_and_right_unique_right_if_bi_unique_left_GaloisI
  by blast


paragraph ‹Surjectivity›

context
  fixes Q :: "'b  bool"
begin

lemma surjective_at_left_Galois_if_rel_surjective_at_rightI:
  assumes "rel_surjective_at Q (≤R)"
  and "((≤R)  (≤L)) r"
  shows "rel_surjective_at Q (L⪅)"
  using assms by (intro rel_surjective_atI) fast

lemma rel_surjective_at_right_if_surjective_at_left_Galois:
  assumes "rel_surjective_at Q (L⪅)"
  shows "rel_surjective_at Q (≤R)"
  using assms by (intro rel_surjective_atI) (auto)

corollary rel_surjective_at_right_iff_surjective_at_left_GaloisI:
  assumes "((≤R)  (≤L)) r"
  shows "rel_surjective_at Q (L⪅)  rel_surjective_at Q (≤R)"
  using assms surjective_at_left_Galois_if_rel_surjective_at_rightI
    rel_surjective_at_right_if_surjective_at_left_Galois
  by blast

end

corollary surjective_left_Galois_if_rel_surjective_rightI:
  assumes "rel_surjective (≤R)"
  and "((≤R)  (≤L)) r"
  shows "rel_surjective (L⪅)"
  using assms by (urule surjective_at_left_Galois_if_rel_surjective_at_rightI)

corollary rel_surjective_right_if_surjective_left_Galois:
  assumes "rel_surjective (L⪅)"
  shows "rel_surjective (≤R)"
  using assms by (urule rel_surjective_at_right_if_surjective_at_left_Galois)

corollary rel_surjective_right_iff_surjective_left_GaloisI:
  assumes "((≤R)  (≤L)) r"
  shows "rel_surjective (L⪅)  rel_surjective (≤R)"
  using assms surjective_left_Galois_if_rel_surjective_rightI
    rel_surjective_right_if_surjective_left_Galois
  by blast


paragraph ‹Left-Totality›

context
  fixes P :: "'a  bool"
begin

lemma left_total_on_left_Galois_if_left_total_on_leftI:
  assumes "left_total_on P (≤L)"
  and "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "left_total_on P (L⪅)"
  using assms by (intro left_total_onI) force

lemma left_total_on_left_if_left_total_on_left_GaloisI:
  assumes "left_total_on P (L⪅)"
  shows "left_total_on P (≤L)"
  using assms by (intro left_total_onI) auto

corollary left_total_on_left_Galois_iff_left_total_on_leftI:
  assumes "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "left_total_on P (L⪅)  left_total_on P (≤L)"
  using assms left_total_on_left_Galois_if_left_total_on_leftI
    left_total_on_left_if_left_total_on_left_GaloisI
  by blast

end

corollary left_total_left_Galois_if_left_total_leftI:
  assumes "left_total (≤L)"
  and "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "left_total (L⪅)"
  using assms by (urule left_total_on_left_Galois_if_left_total_on_leftI)

corollary left_total_left_if_left_total_left_Galois:
  assumes "left_total (L⪅)"
  shows "left_total (≤L)"
  using assms by (urule left_total_on_left_if_left_total_on_left_GaloisI)

corollary left_total_left_Galois_iff_left_total_leftI:
  assumes "((≤L)  (≤R)) l"
  and "((≤L) h (≤R)) l r"
  shows "left_total (L⪅)  left_total (≤L)"
  using assms left_total_left_Galois_if_left_total_leftI
    left_total_left_if_left_total_left_Galois
  by blast


paragraph ‹Bi-Totality›

context
  fixes P :: "'a  bool" and Q :: "'b  bool"
begin

lemma bi_total_on_left_GaloisI:
  assumes "left_total_on P (≤L)"
  and "rel_surjective_at Q (≤R)"
  and "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  shows "bi_total_on P Q (L⪅)"
  using assms surjective_at_left_Galois_if_rel_surjective_at_rightI
    left_total_on_left_Galois_if_left_total_on_leftI
  by blast

lemma left_total_on_left_rel_surjective_at_right_if_bi_total_on_left_GaloisE:
  assumes "bi_total_on P Q (L⪅)"
  obtains "left_total_on P (≤L)" "rel_surjective_at Q (≤R)"
  using assms rel_surjective_at_right_if_surjective_at_left_Galois
    left_total_on_left_if_left_total_on_left_GaloisI
  by auto

corollary bi_total_on_left_Galois_iff_left_total_on_left_and_rel_surjective_on_rightI:
  assumes "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  shows "bi_total_on P Q (L⪅)  left_total_on P (≤L)  rel_surjective_at Q (≤R)"
  using assms bi_total_on_left_GaloisI
    left_total_on_left_rel_surjective_at_right_if_bi_total_on_left_GaloisE
  by blast

end

corollary bi_total_left_GaloisI:
  assumes "left_total (≤L)"
  and "rel_surjective (≤R)"
  and "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  shows "bi_total (L⪅)"
  using assms by (urule bi_total_on_left_GaloisI)

corollary left_total_left_rel_surjective_right_if_bi_total_left_GaloisE:
  assumes "bi_total (L⪅)"
  obtains "left_total (≤L)" "rel_surjective (≤R)"
  using assms by (urule (e) left_total_on_left_rel_surjective_at_right_if_bi_total_on_left_GaloisE)

corollary bi_total_left_Galois_iff_left_total_left_and_rel_surjective_rightI:
  assumes "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  shows "bi_total (L⪅)  left_total (≤L)  rel_surjective (≤R)"
  using assms bi_total_left_GaloisI
    left_total_left_rel_surjective_right_if_bi_total_left_GaloisE
  by blast


paragraph ‹Function Relator›

lemma Fun_Rel_left_Galois_left_Galois_imp_left_rightI:
  assumes monol: "((≤L)  (≤R)) l"
  and half_gal: "((≤L) h (≤R)) l r"
  and perR: "partial_equivalence_rel (≤R)"
  shows "((L⪅)  (L⪅)  (⟶)) (≤L) (≤R)"
proof (intro Fun_Rel_relI impI)
  fix x y x' y'
  assume "x Ly" "x' Ly'" "xL x'"
  with half_gal have "l x'R y'" by auto
  with xL x' monol perR have "l xR y'" by blast
  with x Ly half_gal perR have "yR l x" by (blast dest: symmetricD)
  with perR l xR y' show "yR y'" by blast
qed

lemma Fun_Rel_left_Galois_left_Galois_rev_imp_left_rightI:
  assumes monor: "((≤R)  (≤L)) r"
  and perL: "partial_equivalence_rel (≤L)"
  shows "((L⪅)  (L⪅)  (⟵)) (≤L) (≤R)"
proof (intro Fun_Rel_relI rev_impI)
  fix x y x' y'
  assume "x Ly" and "x' Ly'" and "yR y'"
  with monor perL have "xL r y'" by fastforce
  with  x' Ly' have "x'L r y'" by auto
  with perL xL r y' show "xL x'" by (blast dest: symmetricD)
qed

corollary Fun_Rel_left_Galois_left_Galois_iff_left_rightI:
  assumes "((≤L)  (≤R)) l"
  and "((≤R)  (≤L)) r"
  and "((≤L) h (≤R)) l r"
  and "partial_equivalence_rel (≤L)"
  and "partial_equivalence_rel (≤R)"
  shows "((L⪅)  (L⪅)  (⟷)) (≤L) (≤R)"
  using assms Fun_Rel_left_Galois_left_Galois_imp_left_rightI
    Fun_Rel_left_Galois_left_Galois_rev_imp_left_rightI
  by (intro Fun_Rel_relI) blast

end


end