Theory Reflexive_Relator

✐‹creator "Kevin Kappelmann"›
section ‹Reflexive Relator›
theory Reflexive_Relator
  imports
    Galois_Equivalences
    Galois_Relator
begin

definition "Refl_Rel R x y ≡ R x x ∧ R y y ∧ R x y"

open_bundle Refl_Rel_syntax
begin
notation Refl_Rel (‹_⊕› [1000])
end

lemma Refl_RelI [intro]:
  assumes "R x x"
  and "R y y"
  and "R x y"
  shows "R⊕ x y"
  using assms unfolding Refl_Rel_def by blast

lemma Refl_Rel_selfI [intro]:
  assumes "R x x"
  shows "R⊕ x x"
  using assms by blast

lemma Refl_RelE [elim]:
  assumes "R⊕ x y"
  obtains "R x x" "R y y" "R x y"
  using assms unfolding Refl_Rel_def by blast

lemma Refl_Rel_reflexive_on_in_field [iff]:
  "reflexive_on (in_field R⊕) R⊕"
  by (rule reflexive_onI) auto

lemma Refl_Rel_le_self [iff]: "R⊕ ≤ R" by blast

lemma Refl_Rel_eq_self_if_reflexive_on [simp]:
  assumes "reflexive_on (in_field R) R"
  shows "R⊕ = R"
  using assms by blast

lemma reflexive_on_in_field_if_Refl_Rel_eq_self:
  assumes "R⊕ = R"
  shows "reflexive_on (in_field R) R"
  by (fact Refl_Rel_reflexive_on_in_field[of R, simplified assms])

corollary Refl_Rel_eq_self_iff_reflexive_on:
  "R⊕ = R ⟷ reflexive_on (in_field R) R"
  using Refl_Rel_eq_self_if_reflexive_on reflexive_on_in_field_if_Refl_Rel_eq_self
  by blast

lemma Refl_Rel_Refl_Rel_eq [simp]: "(R⊕)⊕ = R⊕"
  by (intro ext) auto

lemma Refl_Rel_rel_inv_eq [simp]: "(R¯)⊕ = (R⊕)¯"
  by (intro ext iffI Refl_RelI rel_invI) auto

lemma Refl_Rel_transitive_onI [intro]:
  assumes "transitive_on (P :: 'a ⇒ bool) (R :: 'a ⇒ _)"
  shows "transitive_on P R⊕"
  using assms by (intro transitive_onI) (blast dest: transitive_onD)

corollary Refl_Rel_transitiveI [intro]:
  assumes "transitive R"
  shows "transitive R⊕"
  using assms by blast

corollary Refl_Rel_preorder_onI:
  assumes "transitive_on P R"
  and "P ≤ in_field R⊕"
  shows "preorder_on P R⊕"
  using assms by (intro preorder_onI
    reflexive_on_if_le_pred_if_reflexive_on[where ?P="in_field R⊕" and ?P'=P])
  auto

corollary Refl_Rel_preorder_on_in_fieldI [intro]:
  assumes "transitive R"
  shows "preorder_on (in_field R⊕) R⊕"
  using assms by (intro Refl_Rel_preorder_onI) auto

lemma Refl_Rel_symmetric_onI [intro]:
  assumes "symmetric_on (P :: 'a ⇒ bool) (R :: 'a ⇒ _)"
  shows "symmetric_on P R⊕"
  using assms by (intro symmetric_onI) (auto dest: symmetric_onD)

lemma Refl_Rel_symmetricI [intro]:
  assumes "symmetric R"
  shows "symmetric R⊕"
  by (urule symmetric_on_if_le_pred_if_symmetric_on)
  (use assms in ‹urule Refl_Rel_symmetric_onI›, simp)

lemma Refl_Rel_partial_equivalence_rel_onI [intro]:
  assumes "partial_equivalence_rel_on (P :: 'a ⇒ bool) (R :: 'a ⇒ _)"
  shows "partial_equivalence_rel_on P R⊕"
  using assms by (intro partial_equivalence_rel_onI Refl_Rel_transitive_onI
    Refl_Rel_symmetric_onI) auto

lemma Refl_Rel_partial_equivalence_relI [intro]:
  assumes "partial_equivalence_rel R"
  shows "partial_equivalence_rel R⊕"
  using assms
  by (intro partial_equivalence_relI Refl_Rel_transitiveI Refl_Rel_symmetricI) auto

lemma Refl_Rel_app_leftI:
  assumes "R (f x) y"
  and "in_field S⊕ x"
  and "in_field R⊕ y"
  and "(S ⇒ R) f"
  shows "R⊕ (f x) y"
proof (rule Refl_RelI)
  from ‹in_field R⊕ y› show "R y y" by blast
  from ‹in_field S⊕ x› have "S x x" by blast
  with ‹(S ⇒ R) f› show "R (f x) (f x)" by blast
qed fact

corollary Refl_Rel_app_rightI:
  assumes "R x (f y)"
  and "in_field S⊕ y"
  and "in_field R⊕ x"
  and "(S ⇒ R) f"
  shows "R⊕ x (f y)"
proof -
  from assms have "(R¯)⊕ (f y) x" by (intro Refl_Rel_app_leftI[where ?S="S¯"]) auto
  then show ?thesis by blast
qed

lemma mono_wrt_rel_Refl_Rel_Refl_Rel_if_mono_wrt_rel [intro]:
  assumes "(R ⇒ S) f"
  shows "(R⊕ ⇒ S⊕) f"
  using assms by (intro mono_wrt_relI) blast

context galois
begin

interpretation gR : galois "(≤L)⊕" "(≤R)⊕" l r .

lemma Galois_Refl_RelI:
  assumes "((≤R) ⇒ (≤L)) r"
  and "in_field (≤L)⊕ x"
  and "in_field (≤R)⊕ y"
  and "in_codom (≤R) y ⟹ x L⪅ y"
  shows "gR.Galois x y"
  using assms by (intro gR.left_GaloisI in_codomI Refl_Rel_app_rightI[where ?f=r])
  auto

lemma half_galois_prop_left_Refl_Rel_left_rightI:
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤L) h⊴ (≤R)) l r"
  shows "((≤L)⊕ h⊴ (≤R)⊕) l r"
  using assms by (intro gR.half_galois_prop_leftI Refl_RelI)
  (auto elim!: in_codomE gR.left_GaloisE Refl_RelE)

interpretation flip_inv : galois "(≥R)" "(≥L)" r l
  rewrites "((≥R) ⇒ (≥L)) ≡ ((≤R) ⇒ (≤L))"
  and "⋀R. (R¯)⊕ ≡ (R⊕)¯"
  and "⋀R S f g. (R¯ h⊴ S¯) f g ≡ (S ⊴h R) g f"
  by (simp_all add: galois_prop.half_galois_prop_left_rel_inv_eq_rel_inv_half_galois_prop_right
    mono_wrt_rel_eq_dep_mono_wrt_rel)

lemma half_galois_prop_right_Refl_Rel_right_leftI:
  assumes "((≤R) ⇒ (≤L)) r"
  and "((≤L) ⊴h (≤R)) l r"
  shows "((≤L)⊕ ⊴h (≤R)⊕) l r"
  using assms by (fact flip_inv.half_galois_prop_left_Refl_Rel_left_rightI)

corollary galois_prop_Refl_Rel_left_rightI:
  assumes "((≤L) ⊣ (≤R)) l r"
  shows "((≤L)⊕ ⊴ (≤R)⊕) l r"
  using assms
  by (intro gR.galois_propI half_galois_prop_left_Refl_Rel_left_rightI
    half_galois_prop_right_Refl_Rel_right_leftI) auto

lemma galois_connection_Refl_Rel_left_rightI:
  assumes "((≤L) ⊣ (≤R)) l r"
  shows "((≤L)⊕ ⊣ (≤R)⊕) l r"
  using assms
  by (intro gR.galois_connectionI galois_prop_Refl_Rel_left_rightI) auto

lemma galois_equivalence_Refl_RelI:
  assumes "((≤L) ≡G (≤R)) l r"
  shows "((≤L)⊕ ≡G (≤R)⊕) l r"
proof -
  interpret flip : galois R L r l .
  show ?thesis using assms by (intro gR.galois_equivalenceI
    galois_connection_Refl_Rel_left_rightI flip.galois_prop_Refl_Rel_left_rightI)
  auto
qed

end

context order_functors
begin

lemma inflationary_on_in_field_Refl_Rel_left:
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤R) ⇒ (≤L)) r"
  and "inflationary_on (in_dom (≤L)) (≤L) η"
  shows "inflationary_on (in_field (≤L)⊕) (≤L)⊕ η"
  using assms
  by (intro inflationary_onI Refl_RelI) (auto 0 3 elim!: in_fieldE Refl_RelE)

lemma inflationary_on_in_field_Refl_Rel_left':
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤R) ⇒ (≤L)) r"
  and "inflationary_on (in_codom (≤L)) (≤L) η"
  shows "inflationary_on (in_field (≤L)⊕) (≤L)⊕ η"
  using assms
  by (intro inflationary_onI Refl_RelI) (auto 0 3 elim!: in_fieldE Refl_RelE)

interpretation inv : galois "(≥L)" "(≥R)" l r
  rewrites "((≥L) ⇒ (≥R)) ≡ ((≤L) ⇒ (≤R))"
  and "((≥R) ⇒ (≥L)) ≡ ((≤R) ⇒ (≤L))"
  and "⋀R. (R¯)⊕ ≡ (R⊕)¯"
  and "⋀R. in_dom R¯ ≡ in_codom R"
  and "⋀R. in_codom R¯ ≡ in_dom R"
  and "⋀R. in_field R¯ ≡ in_field R"
  and "⋀(P :: 'c ⇒ bool) (R :: 'd ⇒ 'c ⇒ bool).
    (inflationary_on P R¯ :: ('c ⇒ 'd) ⇒ bool) ≡ deflationary_on P R"
  by (simp_all add: mono_wrt_rel_eq_dep_mono_wrt_rel)

lemma deflationary_on_in_field_Refl_Rel_leftI:
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤R) ⇒ (≤L)) r"
  and "deflationary_on (in_dom (≤L)) (≤L) η"
  shows "deflationary_on (in_field (≤L)⊕) (≤L)⊕ η"
  using assms by (fact inv.inflationary_on_in_field_Refl_Rel_left')

lemma deflationary_on_in_field_Refl_RelI_left':
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤R) ⇒ (≤L)) r"
  and "deflationary_on (in_codom (≤L)) (≤L) η"
  shows "deflationary_on (in_field (≤L)⊕) (≤L)⊕ η"
  using assms by (fact inv.inflationary_on_in_field_Refl_Rel_left)

lemma rel_equivalence_on_in_field_Refl_Rel_leftI:
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤R) ⇒ (≤L)) r"
  and "rel_equivalence_on (in_dom (≤L)) (≤L) η"
  shows "rel_equivalence_on (in_field (≤L)⊕) (≤L)⊕ η"
  using assms by (intro rel_equivalence_onI
    inflationary_on_in_field_Refl_Rel_left
    deflationary_on_in_field_Refl_Rel_leftI)
  auto

lemma rel_equivalence_on_in_field_Refl_Rel_leftI':
  assumes "((≤L) ⇒ (≤R)) l"
  and "((≤R) ⇒ (≤L)) r"
  and "rel_equivalence_on (in_codom (≤L)) (≤L) η"
  shows "rel_equivalence_on (in_field (≤L)⊕) (≤L)⊕ η"
  using assms by (intro rel_equivalence_onI
    inflationary_on_in_field_Refl_Rel_left'
    deflationary_on_in_field_Refl_RelI_left')
  auto

interpretation oR : order_functors "(≤L)⊕" "(≤R)⊕" l r .

lemma order_equivalence_Refl_RelI:
  assumes "((≤L) ≡o (≤R)) l r"
  shows "((≤L)⊕ ≡o (≤R)⊕) l r"
proof -
  interpret flip : galois R L r l
    rewrites "flip.unit ≡ ε"
    by (simp only: flip_unit_eq_counit)
  show ?thesis using assms by (intro oR.order_equivalenceI
    mono_wrt_rel_Refl_Rel_Refl_Rel_if_mono_wrt_rel
    rel_equivalence_on_in_field_Refl_Rel_leftI
    flip.rel_equivalence_on_in_field_Refl_Rel_leftI)
    (auto intro: rel_equivalence_on_if_le_pred_if_rel_equivalence_on
      in_field_if_in_dom)
qed

end


end