Theory CZH_DG_Rel

(* Copyright 2021 (C) Mihails Milehins *)

sectionRel› as a digraph›
theory CZH_DG_Rel
  imports CZH_DG_Small_DGHM
begin



subsection‹Background›


textRel› is usually defined as a category of sets and binary relations
(e.g., see Chapter I-7 in cite"mac_lane_categories_2010"). However, there
is little that can prevent one from exposing Rel› as a digraph and
provide additional structure gradually later. 
Thus, in this section, α›-Rel› is defined as a digraph of sets 
and binary relations in Vα.
›

named_theorems dg_Rel_shared_cs_simps
named_theorems dg_Rel_shared_cs_intros

named_theorems dg_Rel_cs_simps
named_theorems dg_Rel_cs_intros



subsection‹Canonical arrow for typV

named_theorems arr_field_simps

definition ArrVal :: V where [arr_field_simps]: "ArrVal = 0"
definition ArrDom :: V where [arr_field_simps]: "ArrDom = 1"
definition ArrCod :: V where [arr_field_simps]: "ArrCod = 2"

lemma ArrVal_eq_helper:
  assumes "f = g"
  shows "fArrVala = gArrVala"
  using assms by simp



subsection‹Arrow for Rel›


subsubsection‹Definition and elementary properties›

locale arr_Rel = 𝒵 α + vfsequence T + ArrVal: vbrelation TArrVal for α T +
  assumes arr_Rel_length[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: 
    "vcard T = 3" 
    and arr_Rel_ArrVal_vdomain: "𝒟 (TArrVal)  TArrDom"
    and arr_Rel_ArrVal_vrange: " (TArrVal)  TArrCod"
    and arr_Rel_ArrDom_in_Vset: "TArrDom  Vset α"
    and arr_Rel_ArrCod_in_Vset: "TArrCod  Vset α"

lemmas [dg_Rel_shared_cs_simps, dg_Rel_cs_simps] = arr_Rel.arr_Rel_length


text‹Components.›

lemma arr_Rel_components[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]:
  shows "[f, A, B]ArrVal = f"
    and "[f, A, B]ArrDom = A"
    and "[f, A, B]ArrCod = B"
  unfolding arr_field_simps by (simp_all add: nat_omega_simps)


text‹Rules.›

lemma (in arr_Rel) arr_Rel_axioms'[dg_cs_intros, dg_Rel_cs_intros]:
  assumes "α' = α"
  shows "arr_Rel α' T"
  unfolding assms by (rule arr_Rel_axioms)

mk_ide rf arr_Rel_def[unfolded arr_Rel_axioms_def]
  |intro arr_RelI|
  |dest arr_RelD[dest]|
  |elim arr_RelE[elim!]|

lemma (in 𝒵) arr_Rel_vfsequenceI: 
  assumes "vbrelation r" 
    and "𝒟 r  a"
    and " r  b"
    and "a  Vset α"
    and "b  Vset α"
  shows "arr_Rel α [r, a, b]"
  by (intro arr_RelI) 
    (insert assms, auto simp: nat_omega_simps arr_Rel_components)


text‹Elementary properties.›

lemma arr_Rel_eqI:
  assumes "arr_Rel α S" 
    and "arr_Rel α T"
    and "SArrVal = TArrVal"
    and "SArrDom = TArrDom"
    and "SArrCod = TArrCod"
  shows "S = T"
proof-
  interpret S: arr_Rel α S by (rule assms(1))
  interpret T: arr_Rel α T by (rule assms(2))
  show ?thesis
  proof(rule vsv_eqI)
    show "𝒟 S = 𝒟 T" 
      by (simp add: S.vfsequence_vdomain T.vfsequence_vdomain dg_Rel_cs_simps) 
    have dom_lhs: "𝒟 S = 3" 
      by (simp add: S.vfsequence_vdomain dg_Rel_cs_simps)
    show "a  𝒟 S  Sa = Ta" for a 
      by (unfold dom_lhs, elim_in_numeral, insert assms)
        (auto simp: arr_field_simps)
  qed auto
qed

lemma (in arr_Rel) arr_Rel_def: "T = [TArrVal, TArrDom, TArrCod]"
proof(rule vsv_eqI)
  have dom_lhs: "𝒟 T = 3" by (simp add: vfsequence_vdomain dg_Rel_cs_simps)
  have dom_rhs: "𝒟 [TArrVal, TArrDom, TArrCod] = 3"
    by (simp add: nat_omega_simps)
  then show "𝒟 T = 𝒟 [TArrVal, TArrDom, TArrCod]"
    unfolding dom_lhs dom_rhs by simp
  show "a  𝒟 T  Ta = [TArrVal, TArrDom, TArrCod]a" for a
    unfolding dom_lhs
    by elim_in_numeral (simp_all add: arr_field_simps nat_omega_simps)
qed (auto simp: vsv_axioms)


text‹Size.›

lemma (in arr_Rel) arr_Rel_ArrVal_in_Vset: "TArrVal  Vset α"
proof-
  from arr_Rel_ArrVal_vdomain arr_Rel_ArrDom_in_Vset have 
    "𝒟 (TArrVal)  Vset α"
    by auto
  moreover from arr_Rel_ArrVal_vrange arr_Rel_ArrCod_in_Vset have 
    " (TArrVal)  Vset α"
    by auto
  ultimately show "TArrVal  Vset α" 
    by (simp add: ArrVal.vbrelation_Limit_in_VsetI)
qed

lemma (in arr_Rel) arr_Rel_in_Vset: "T  Vset α"
proof-
  note [dg_Rel_cs_intros] = 
    arr_Rel_ArrVal_in_Vset arr_Rel_ArrDom_in_Vset arr_Rel_ArrCod_in_Vset
  show ?thesis
    by (subst arr_Rel_def)
      (cs_concl cs_shallow cs_intro: dg_Rel_cs_intros V_cs_intros) 
qed

lemma small_arr_Rel[simp]: "small {T. arr_Rel α T}"
  by (rule down[of _ Vset α]) (auto intro!: arr_Rel.arr_Rel_in_Vset)


text‹Other elementary properties.›

lemma set_Collect_arr_Rel[simp]: 
  "x  set (Collect (arr_Rel α))  arr_Rel α x" 
  by auto

lemma (in arr_Rel) arr_Rel_ArrVal_vsubset_ArrDom_ArrCod:
  "TArrVal  TArrDom × TArrCod"
proof
  fix ab assume "ab  TArrVal"
  then obtain a b where "ab = a, b" 
    and "a  𝒟 (TArrVal)" 
    and "b   (TArrVal)" 
    by (blast elim: ArrVal.vbrelation_vinE)
  with arr_Rel_ArrVal_vdomain arr_Rel_ArrVal_vrange show 
    "ab  TArrDom × TArrCod"
    by auto
qed


subsubsection‹Composition›


text‹See Chapter I-7 in cite"mac_lane_categories_2010".›

definition comp_Rel :: "V  V  V" (infixl Rel 55)
  where "comp_Rel S T = [SArrVal  TArrVal, TArrDom, SArrCod]"


text‹Components.›

lemma comp_Rel_components:
  shows "(S Rel T)ArrVal = SArrVal  TArrVal"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: 
      "(S Rel T)ArrDom = TArrDom"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]:
      "(S Rel T)ArrCod = SArrCod"
  unfolding comp_Rel_def arr_field_simps by (simp_all add: nat_omega_simps)


text‹Elementary properties.›

lemma comp_Rel_vsv[dg_Rel_shared_cs_intros, dg_Rel_cs_intros]: 
  "vsv (S Rel T)"
  unfolding comp_Rel_def by auto

lemma arr_Rel_comp_Rel[dg_Rel_cs_intros]:
  assumes "arr_Rel α S" and "arr_Rel α T"
  shows "arr_Rel α (S Rel T)"
proof-
  interpret S: arr_Rel α S by (rule assms(1))
  interpret T: arr_Rel α T by (rule assms(2))
  show ?thesis
  proof(intro arr_RelI)
    show "vfsequence (S Rel T)" unfolding comp_Rel_def by simp
    show "vcard (S Rel T) = 3"
      unfolding comp_Rel_def by (simp add: nat_omega_simps)
    from T.arr_Rel_ArrVal_vdomain show 
      "𝒟 ((S Rel T)ArrVal)  (S Rel T)ArrDom"
      unfolding comp_Rel_components by auto
    show " ((S Rel T)ArrVal)  (S Rel T)ArrCod"
      unfolding comp_Rel_components 
    proof(intro vsubsetI)
      fix z assume "z   (SArrVal  TArrVal)"
      then obtain x y where "y, z  SArrVal" and "x, y  TArrVal"
        by (meson vcomp_obtain_middle vrange_iff_vdomain)
      with S.arr_Rel_ArrVal_vrange show "z  SArrCod" by auto
    qed
  qed 
    (
      auto simp: 
        comp_Rel_components T.arr_Rel_ArrDom_in_Vset S.arr_Rel_ArrCod_in_Vset
    ) 
qed

lemma arr_Rel_comp_Rel_assoc[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]:
  "(H Rel G) Rel F = H Rel (G Rel F)" 
  by (simp add: comp_Rel_def vcomp_assoc arr_field_simps nat_omega_simps)


subsubsection‹Inclusion arrow›


text‹
The definition of the inclusion arrow is based on the concept of the 
inclusion map, e.g., see cite"noauthor_wikipedia_2001"\footnote{
\url{https://en.wikipedia.org/wiki/Inclusion_map}
}›

definition "incl_Rel A B = [vid_on A, A, B]"


text‹Components.›

lemma incl_Rel_components:
  shows "incl_Rel A BArrVal = vid_on A"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: "incl_Rel A BArrDom = A"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: "incl_Rel A BArrCod = B"
  unfolding incl_Rel_def arr_field_simps by (simp_all add: nat_omega_simps)


text‹Arrow value.›

lemma incl_Rel_ArrVal_vsv[dg_Rel_shared_cs_intros, dg_Rel_cs_intros]: 
  "vsv (incl_Rel A BArrVal)"
  unfolding incl_Rel_components by simp

lemma incl_Rel_ArrVal_vdomain[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]:
  "𝒟 (incl_Rel A BArrVal) = A"
  unfolding incl_Rel_components by simp

lemma incl_Rel_ArrVal_app[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]:
  assumes "a  A"
  shows "incl_Rel A BArrVala = a"
  using assms unfolding incl_Rel_components by simp


text‹Elementary properties.›

lemma incl_Rel_vfsequence[dg_Rel_shared_cs_intros, dg_Rel_cs_intros]: 
  "vfsequence (incl_Rel A B)" 
  unfolding incl_Rel_def by simp

lemma incl_Rel_vcard[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: 
  "vcard (incl_Rel A B) = 3" 
  unfolding incl_Rel_def incl_Rel_def by (simp add: nat_omega_simps)

lemma (in 𝒵) arr_Rel_incl_RelI:
  assumes "A  Vset α" and "B  Vset α" and "A  B"
  shows "arr_Rel α (incl_Rel A B)"
proof(intro arr_RelI)
  show "vfsequence (incl_Rel A B)" unfolding incl_Rel_def by simp
  show "vcard (incl_Rel A B) = 3" 
    unfolding incl_Rel_def by (simp add: nat_omega_simps)
qed (auto simp: incl_Rel_components assms)


subsubsection‹Identity›


text‹See Chapter I-7 in cite"mac_lane_categories_2010".›

definition id_Rel :: "V  V"
  where "id_Rel A = incl_Rel A A"


text‹Components.›

lemma id_Rel_components:
  shows "id_Rel AArrVal = vid_on A"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: "id_Rel AArrDom = A"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: "id_Rel AArrCod = A"
  unfolding id_Rel_def incl_Rel_components by simp_all


text‹Elementary properties.›

lemma id_Rel_vfsequence[dg_Rel_shared_cs_intros, dg_Rel_cs_intros]: 
  "vfsequence (id_Rel A)" 
  unfolding id_Rel_def by (simp add: dg_Rel_cs_intros)

lemma id_Rel_vcard[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: 
  "vcard (id_Rel A) = 3" 
  unfolding id_Rel_def by (simp add: dg_Rel_cs_simps)

lemma (in 𝒵) arr_Rel_id_RelI:
  assumes "A  Vset α"
  shows "arr_Rel α (id_Rel A)"
  by (intro arr_RelI)
    (auto simp: id_Rel_components(1) assms dg_Rel_cs_intros dg_Rel_cs_simps)

lemma id_Rel_ArrVal_app[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]:
  assumes "a  A"
  shows "id_Rel AArrVala = a"
  using assms unfolding id_Rel_components by simp

lemma arr_Rel_comp_Rel_id_Rel_left[dg_Rel_cs_simps]:
  assumes "arr_Rel α F" and "FArrCod = A"
  shows "id_Rel A Rel F = F"
proof(rule arr_Rel_eqI [of α])
  interpret F: arr_Rel α F by (rule assms(1))
  from assms(2) have "A  Vset α" by (auto intro: F.arr_Rel_ArrCod_in_Vset)
  with assms(1) show "arr_Rel α (id_Rel A Rel F)" 
    by (blast intro: F.arr_Rel_id_RelI intro!: arr_Rel_comp_Rel)
  from assms(2) F.arr_Rel_ArrVal_vrange show  
    "(id_Rel A Rel F)ArrVal = FArrVal"
    unfolding comp_Rel_components id_Rel_components by auto
qed 
  (
    use assms(2) in 
      auto simp: assms(1) comp_Rel_components id_Rel_components
  )

lemma arr_Rel_comp_Rel_id_Rel_right[dg_Rel_cs_simps]:
  assumes "arr_Rel α F" and "FArrDom = A"
  shows "F Rel id_Rel A = F"
proof(rule arr_Rel_eqI[of α])
  interpret F: arr_Rel α F by (rule assms(1))
  from assms(2) have "A  Vset α" by (auto intro: F.arr_Rel_ArrDom_in_Vset)
  with assms(1) show "arr_Rel α (F Rel id_Rel A)"
    by (blast intro: F.arr_Rel_id_RelI intro!: arr_Rel_comp_Rel)
  show "arr_Rel α F" by (simp add: assms(1))
  from assms(2) F.arr_Rel_ArrVal_vdomain show  
    "(F Rel id_Rel A)ArrVal = FArrVal"
    unfolding comp_Rel_components id_Rel_components by auto
qed (use assms(2) in auto simp: comp_Rel_components id_Rel_components)


subsubsection‹Converse›


text‹
As mentioned in Chapter I-7 in cite"mac_lane_categories_2010", the 
category Rel› is usually equipped with an additional structure that is
the operation of taking a converse of a relation.
The operation is meant to be used almost exclusively as part of 
the dagger functor for Rel›.
›

definition converse_Rel :: "V  V" ("(_¯Rel)" [1000] 999)
  where "converse_Rel T = [(TArrVal)¯, TArrCod, TArrDom]"

lemma converse_Rel_components:
  shows "T¯RelArrVal = (TArrVal)¯"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: "T¯RelArrDom = TArrCod"
    and [dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: "T¯RelArrCod = TArrDom"
  unfolding converse_Rel_def arr_field_simps by (simp_all add: nat_omega_simps)


text‹Elementary properties.›

lemma (in arr_Rel) arr_Rel_converse_Rel: "arr_Rel α (T¯Rel)"
proof(rule arr_RelI, unfold converse_Rel_components)
  show "vfsequence (T¯Rel)" unfolding converse_Rel_def by simp
  show "vcard (T¯Rel) = 3"
    unfolding converse_Rel_def by (simp add: nat_omega_simps)
qed 
  (
    auto simp: 
      converse_Rel_components(1)   
      arr_Rel_ArrDom_in_Vset 
      arr_Rel_ArrCod_in_Vset
      arr_Rel_ArrVal_vdomain
      arr_Rel_ArrVal_vrange
  )

lemmas [dg_Rel_cs_intros] = 
  arr_Rel.arr_Rel_converse_Rel

lemma (in arr_Rel) 
  arr_Rel_converse_Rel_converse_Rel[dg_Rel_shared_cs_simps, dg_Rel_cs_simps]: 
  "(T¯Rel)¯Rel = T"
proof(rule arr_Rel_eqI)
  from arr_Rel_axioms show "arr_Rel α ((T¯Rel)¯Rel)"
    by (cs_intro_step dg_Rel_cs_intros)+
qed (simp_all add: arr_Rel_axioms converse_Rel_components)

lemmas [dg_Rel_cs_simps] = 
  arr_Rel.arr_Rel_converse_Rel_converse_Rel

lemma arr_Rel_converse_Rel_eq_iff[dg_Rel_cs_simps]:
  assumes "arr_Rel α F" and "arr_Rel α G"
  shows "F¯Rel = G¯Rel  F = G"
proof(rule iffI)
  show "F¯Rel = G¯Rel  F = G"
    by (metis arr_Rel.arr_Rel_converse_Rel_converse_Rel assms)
qed simp

lemma arr_Rel_converse_Rel_comp_Rel[dg_Rel_cs_simps]:
  assumes "arr_Rel α G" and "arr_Rel α F"
  shows "(F Rel G)¯Rel = G¯Rel Rel F¯Rel"
proof(rule arr_Rel_eqI, unfold converse_Rel_components comp_Rel_components)
  from assms show "arr_Rel α (G¯Rel Rel F¯Rel)"
    by (cs_concl cs_shallow cs_intro: dg_Rel_cs_intros)
  from assms show "arr_Rel α ((F Rel G)¯Rel)"
    by (cs_intro_step dg_Rel_cs_intros)+
qed (simp_all add: vconverse_vcomp)

lemma (in 𝒵) arr_Rel_converse_Rel_id_Rel: 
  assumes "c  Vset α"
  shows "arr_Rel α ((id_Rel c)¯Rel)"
  using assms 𝒵_axioms 
  by (cs_concl cs_shallow cs_intro: dg_Rel_cs_intros arr_Rel_id_RelI)+

lemma (in 𝒵) arr_Rel_converse_Rel_id_Rel_eq_id_Rel[
    dg_Rel_shared_cs_simps, dg_Rel_cs_simps
    ]: 
  assumes "c  Vset α"
  shows "(id_Rel c)¯Rel = id_Rel c"
  by (rule arr_Rel_eqI[of α], unfold converse_Rel_components id_Rel_components)
    (simp_all add: assms arr_Rel_id_RelI arr_Rel_converse_Rel_id_Rel)

lemmas [dg_Rel_shared_cs_simps, dg_Rel_cs_simps] = 
  𝒵.arr_Rel_converse_Rel_id_Rel_eq_id_Rel

lemma arr_Rel_comp_Rel_converse_Rel_left_if_v11[dg_Rel_cs_simps]:
  assumes "arr_Rel α T" 
    and "𝒟 (TArrVal) = A"
    and "TArrDom = A"
    and "v11 (TArrVal)" 
    and "A  Vset α"
  shows "T¯Rel Rel T = id_Rel A"
proof-
  interpret T: arr_Rel α T by (rule assms(1))
  interpret v11: v11 TArrVal by (rule assms(4))
  show ?thesis
    by (rule arr_Rel_eqI[of α])
      (
        auto simp: 
          converse_Rel_components 
          comp_Rel_components 
          id_Rel_components 
          assms(1,3,5)
          arr_Rel.arr_Rel_converse_Rel 
          arr_Rel_comp_Rel  
          T.arr_Rel_id_RelI
          v11.v11_vcomp_vconverse[unfolded assms(2)] 
      )
qed

lemma arr_Rel_comp_Rel_converse_Rel_right_if_v11[dg_Rel_cs_simps]:
  assumes "arr_Rel α T" 
    and " (TArrVal) = A"
    and "TArrCod = A"
    and "v11 (TArrVal)" 
    and "A  Vset α"
  shows "T Rel T¯Rel = id_Rel A"
proof-
  interpret T: arr_Rel α T by (rule assms(1))
  interpret v11: v11 TArrVal by (rule assms(4))
  show ?thesis
    by (rule arr_Rel_eqI[of α])
      (
        auto simp: 
          assms(1,3,5)
          comp_Rel_components 
          converse_Rel_components 
          id_Rel_components 
          v11.v11_vcomp_vconverse'[unfolded assms(2)] 
          T.arr_Rel_id_RelI 
          arr_Rel.arr_Rel_converse_Rel
          arr_Rel_comp_Rel 
      )
qed



subsectionRel› as a digraph›


subsubsection‹Definition and elementary properties›

definition dg_Rel :: "V  V"
  where "dg_Rel α =
    [
      Vset α,
      set {T. arr_Rel α T},
      (λTset {T. arr_Rel α T}. TArrDom),
      (λTset {T. arr_Rel α T}. TArrCod)
    ]"


text‹Components.›

lemma dg_Rel_components:
  shows "dg_Rel αObj = Vset α"
    and "dg_Rel αArr = set {T. arr_Rel α T}"
    and "dg_Rel αDom = (λTset {T. arr_Rel α T}. TArrDom)"
    and "dg_Rel αCod = (λTset {T. arr_Rel α T}. TArrCod)"
  unfolding dg_Rel_def dg_field_simps by (simp_all add: nat_omega_simps)


subsubsection‹Object›

lemma dg_Rel_Obj_iff: "x  dg_Rel αObj  x  Vset α" 
  unfolding dg_Rel_components by auto


subsubsection‹Arrow›

lemma dg_Rel_Arr_iff[dg_Rel_cs_simps]: "x  dg_Rel αArr  arr_Rel α x" 
  unfolding dg_Rel_components by auto


subsubsection‹Domain›

mk_VLambda dg_Rel_components(3)
  |vsv dg_Rel_Dom_vsv[dg_Rel_cs_intros]|
  |vdomain dg_Rel_Dom_vdomain[dg_Rel_cs_simps]|
  |app dg_Rel_Dom_app[unfolded set_Collect_arr_Rel, dg_Rel_cs_simps]|

lemma dg_Rel_Dom_vrange: " (dg_Rel αDom)  dg_Rel αObj"
  unfolding dg_Rel_components
  by (rule vrange_VLambda_vsubset, unfold set_Collect_arr_Rel) auto


subsubsection‹Codomain›

mk_VLambda dg_Rel_components(4)
  |vsv dg_Rel_Cod_vsv[dg_Rel_cs_intros]|
  |vdomain dg_Rel_Cod_vdomain[dg_Rel_cs_simps]|
  |app dg_Rel_Cod_app[unfolded set_Collect_arr_Rel, dg_Rel_cs_simps]|

lemma dg_Rel_Cod_vrange: " (dg_Rel αCod)  dg_Rel αObj"
  unfolding dg_Rel_components
  by (rule vrange_VLambda_vsubset, unfold set_Collect_arr_Rel) auto


subsubsection‹Arrow with a domain and a codomain›


text‹Rules.›

lemma dg_Rel_is_arrI[dg_Rel_cs_intros]:
  assumes "arr_Rel α S" and "SArrDom = A" and "SArrCod = B"
  shows "S : A dg_Rel αB"
  using assms by (intro is_arrI, unfold dg_Rel_components) simp_all

lemma dg_Rel_is_arrD:
  assumes "S : A dg_Rel αB"
  shows "arr_Rel α S" 
    and [dg_cs_simps]: "SArrDom = A" 
    and [dg_cs_simps]: "SArrCod = B"
  using is_arrD[OF assms] unfolding dg_Rel_components by simp_all

lemma dg_Rel_is_arrE:
  assumes "S : A dg_Rel αB"
  obtains "arr_Rel α S" and "SArrDom = A" and "SArrCod = B"
  using is_arrD[OF assms] unfolding dg_Rel_components by simp_all


text‹Elementary properties.›

lemma (in 𝒵) dg_Rel_incl_Rel_is_arr:
  assumes "A  Vset α" and "B  Vset α" and "A  B"
  shows "incl_Rel A B : A dg_Rel αB"
proof(rule dg_Rel_is_arrI)
  show "arr_Rel α (incl_Rel A B)" by (intro arr_Rel_incl_RelI assms)
qed (simp_all add: incl_Rel_components)

lemma (in 𝒵) dg_Rel_incl_Rel_is_arr'[dg_Rel_cs_intros]:
  assumes "A  Vset α" 
    and "B  Vset α" 
    and "A  B"
    and "A' = A"
    and "B' = B"
  shows "incl_Rel A B : A' dg_Rel αB'"
  using assms(1-3) unfolding assms(4,5) by (rule dg_Rel_incl_Rel_is_arr)

lemmas [dg_Rel_cs_intros] = 𝒵.dg_Rel_incl_Rel_is_arr'

lemma dg_Rel_is_arr_ArrValE:
  assumes "T : A dg_Rel αB" and "ab  TArrVal"
  obtains a b 
    where "ab = a, b" and "a  𝒟 (TArrVal)" and "b   (TArrVal)"
proof-
  note T = dg_Rel_is_arrD[OF assms(1)]
  then interpret T: arr_Rel α T 
    rewrites "TArrDom = A" and "TArrCod = B"
    by simp_all
  from assms(2) obtain a b
    where "ab = a, b" and "a  𝒟 (TArrVal)" and "b   (TArrVal)"
    by (blast elim: T.ArrVal.vbrelation_vinE)
  with that show ?thesis by simp
qed


subsubsectionRel› is a digraph›

lemma (in 𝒵) dg_Rel_Hom_vifunion_in_Vset:
  assumes "X  Vset α" and "Y  Vset α"
  shows "(AX. BY. Hom (dg_Rel α) A B)  Vset α"
proof-
  define Q where
    "Q i = (if i = 0 then VPow (X × Y) else if i = 1 then X else Y)" 
    for i
  have 
    "{[r, A, B] |r A B. r  X × Y  A  X  B  Y} 
      elts (i set {0, 1, 2}. Q i)"
  proof(intro subsetI, unfold mem_Collect_eq, elim exE conjE)
    fix F r A B assume prems: 
      "F = [r, A, B]" 
      "r  X × Y"
      "A  X"
      "B  Y"
    show "F  (i set {0, 1, 2}. Q i)"
    proof(intro vproductI, unfold Ball_def; (intro allI impI)?)
      show "𝒟 F = set {0, 1, 2}" 
        by (simp add: three prems(1) nat_omega_simps)
      fix i assume "i  set {0, 1, 2}"
      then consider i = 0 | i = 1 | i = 2 by auto
      then show "Fi  Q i" by cases (auto simp: Q_def prems nat_omega_simps)
    qed (auto simp: prems(1))
  qed
  moreover then have small[simp]: 
    "small {[r, A, B] | r A B. r X × Y  A  X  B  Y}"
    by (rule down)
  ultimately have
    "set {[r, A, B] |r A B. r  X × Y  A  X  B  Y} 
      (i set {0, 1, 2}. Q i)"
    by auto
  moreover have "(i set {0, 1, 2}. Q i)  Vset α"
  proof(rule Limit_vproduct_in_VsetI)
    show "set {0, 1, 2}  Vset α"
      by (auto simp: three[symmetric] intro!: Axiom_of_Infinity)
    from assms(1,2) have "VPow (X × Y)  Vset α"
      by (intro Limit_VPow_in_VsetI Limit_vtimes_in_VsetI) auto
    then show "Q i  Vset α" if "i  set {0, 1, 2}" for i
      using that assms(1,2) unfolding Q_def by (auto simp: nat_omega_simps)
  qed auto
  moreover have
    "(AX. BY. Hom (dg_Rel α) A B) 
      set {[r, A, B] | r A B. r X × Y  A  X  B  Y}"
  proof(rule vsubsetI)
    fix F assume prems: "F  (AX. BY. Hom (dg_Rel α) A B)"
    then obtain A where A: "A  X" and F_b: "F  (BY. Hom (dg_Rel α) A B)" 
      unfolding vifunion_iff by auto
    then obtain B where B: "B  Y" and F_fba: "F  Hom (dg_Rel α) A B" 
      by fastforce
    then have "F : A dg_Rel αB" by simp
    note F = dg_Rel_is_arrD[OF this]
    interpret F: arr_Rel α F rewrites "FArrDom = A" and "FArrCod = B"
      by (intro F)+
    show "F  set {[r, A, B] | r A B. r X × Y  A  X  B  Y}"
    proof(intro in_set_CollectI small exI conjI)
      from F.arr_Rel_def show "F = [FArrVal, A, B]" unfolding F(2,3) by simp
      from A B have "A × B  X × Y" by auto
      moreover then have "FArrVal  A × B"
        by (auto simp: F.arr_Rel_ArrVal_vsubset_ArrDom_ArrCod)
      ultimately show "FArrVal  X × Y" by auto
    qed (intro A B)+
  qed
  ultimately show "(AX. BY. Hom (dg_Rel α) A B)  Vset α" by blast
qed

lemma (in 𝒵) digraph_dg_Rel: "digraph α (dg_Rel α)"
proof(intro digraphI)
  show "vfsequence (dg_Rel α)" unfolding dg_Rel_def by clarsimp
  show "vcard (dg_Rel α) = 4" 
    unfolding dg_Rel_def by (simp add: nat_omega_simps)
  show " (dg_Rel αDom)  dg_Rel αObj" by (simp add: dg_Rel_Dom_vrange)
  show " (dg_Rel αCod)  dg_Rel αObj" by (simp add: dg_Rel_Cod_vrange)
qed (auto simp: dg_Rel_components dg_Rel_Hom_vifunion_in_Vset dg_Rel_Dom_vrange)



subsection‹Canonical dagger for Rel›


text‹
Dagger categories are exposed explicitly later. 
In the context of this section, the ``dagger'' is viewed merely as 
an explicitly defined homomorphism. A definition of a dagger functor, upon
which the definition presented in this section is based, can be found in nLab 
cite"noauthor_nlab_nodate"\footnote{\url{https://ncatlab.org/nlab/show/Rel})}.
This reference also contains the majority of the results that are presented
in this subsection.
›


subsubsection‹Definition and elementary properties›

definition dghm_dag_Rel :: "V  V" (DG.Rel)
  where "DG.Rel α = 
    [
      vid_on (dg_Rel αObj), 
      VLambda (dg_Rel αArr) converse_Rel, 
      op_dg (dg_Rel α), 
      dg_Rel α
    ]"


text‹Components.›

lemma dghm_dag_Rel_components:
  shows "DG.Rel αObjMap = vid_on (dg_Rel αObj)"
    and "DG.Rel αArrMap = VLambda (dg_Rel αArr) converse_Rel"
    and "DG.Rel αHomDom = op_dg (dg_Rel α)"
    and "DG.Rel αHomCod = dg_Rel α"
  unfolding dghm_dag_Rel_def dghm_field_simps by (simp_all add: nat_omega_simps)


subsubsection‹Object map›

mk_VLambda dghm_dag_Rel_components(1)[folded VLambda_vid_on]
  |vsv dghm_dag_Rel_ObjMap_vsv[dg_Rel_cs_intros]|
  |vdomain 
    dghm_dag_Rel_ObjMap_vdomain[unfolded dg_Rel_components, dg_Rel_cs_simps]
  |
  |app dghm_dag_Rel_ObjMap_app[unfolded dg_Rel_components, dg_Rel_cs_simps]|

lemma dghm_dag_Rel_ObjMap_vrange[dg_cs_simps]: " (DG.Rel αObjMap) = Vset α"
  unfolding dghm_dag_Rel_components dg_Rel_components by simp


subsubsection‹Arrow map›

mk_VLambda dghm_dag_Rel_components(2)
  |vsv dghm_dag_Rel_ArrMap_vsv[dg_Rel_cs_intros]|
  |vdomain dghm_dag_Rel_ArrMap_vdomain[dg_Rel_cs_simps]|
  |app dghm_dag_Rel_ArrMap_app[unfolded dg_Rel_cs_simps, dg_Rel_cs_simps]|

lemma dghm_dag_Rel_ArrMap_app_vdomain[dg_cs_simps]:
  assumes "T : A dg_Rel αB"
  shows "𝒟 (DG.Rel αArrMapTArrVal) =  (TArrVal)"
proof-
  from assms interpret T: arr_Rel α T by (simp add: dg_Rel_is_arrD)
  from dg_Rel_is_arrD(1)[OF assms] show ?thesis
    by (cs_concl cs_simp: dg_Rel_cs_simps V_cs_simps converse_Rel_components(1))
qed

lemma dghm_dag_Rel_ArrMap_app_vrange[dg_cs_simps]:
  assumes "T : A dg_Rel αB"
  shows " (DG.Rel αArrMapTArrVal) = 𝒟 (TArrVal)"
proof-
  from assms interpret T: arr_Rel α T by (simp add: dg_Rel_is_arrD)
  from dg_Rel_is_arrD(1)[OF assms] show ?thesis
    by (cs_concl cs_simp: dg_Rel_cs_simps V_cs_simps converse_Rel_components(1))
qed

lemma dghm_dag_Rel_ArrMap_app_iff[dg_cs_simps]:
  assumes "T : A dg_Rel αB" 
  shows "a, b  DG.Rel αArrMapTArrVal  b, a  TArrVal"
proof-
  from assms interpret T: arr_Rel α T by (simp add: dg_Rel_is_arrD)
  note T = dg_Rel_is_arrD[OF assms]
  note [dg_Rel_cs_simps] = converse_Rel_components
  show ?thesis
  proof(intro iffI)
    assume prems: "a, b  DG.Rel αArrMapTArrVal"
    then have a: "a  𝒟 (DG.Rel αArrMapTArrVal)"
      and b: "b   (DG.Rel αArrMapTArrVal)"
      by auto
    with assms have a: "a   (TArrVal)" and b: "b  𝒟 (TArrVal)"
      by (simp_all add: dg_cs_simps)
    from prems T(1) have "a, b  (TArrVal)¯"
      by (cs_prems cs_shallow cs_simp: dg_Rel_cs_simps)
    then show "b, a  TArrVal" by clarsimp
  next
    assume "b, a  TArrVal"
    then have "a, b  (TArrVal)¯" by auto
    with T(1) show "a, b  DG.Rel αArrMapTArrVal"
      by (cs_concl cs_shallow cs_simp: dg_Rel_cs_simps)
  qed
qed


subsubsection‹Further properties›

lemma dghm_dag_Rel_ArrMap_vrange[dg_Rel_cs_simps]: 
  " (DG.Rel αArrMap) = dg_Rel αArr"
proof(intro vsubset_antisym vsubsetI)
  interpret ArrMap: vsv DG.Rel αArrMap 
    unfolding dghm_dag_Rel_components by simp
  fix T assume "T   (DG.Rel αArrMap)"
  then obtain S where T_def: "T = DG.Rel αArrMapS" 
    and S: "S  𝒟 (DG.Rel αArrMap)"
    by (blast dest: ArrMap.vrange_atD)
  from S show "T  dg_Rel αArr" 
    by 
      (
        simp add:
          T_def 
          dghm_dag_Rel_components 
          dg_Rel_components 
          arr_Rel.arr_Rel_converse_Rel
      )
next
  interpret ArrMap: vsv DG.Rel αArrMap 
    unfolding dghm_dag_Rel_components by simp
  fix T assume "T  dg_Rel αArr"
  then have "arr_Rel α T" by (simp add: dg_Rel_components)
  then have "(T¯Rel)¯Rel = T" and "arr_Rel α (T¯Rel)"
    by 
      (
        auto simp: 
          arr_Rel.arr_Rel_converse_Rel_converse_Rel arr_Rel.arr_Rel_converse_Rel
      )
  then have "DG.Rel αArrMapT¯Rel = T" "T¯Rel  𝒟 (DG.Rel αArrMap)"
    by (simp_all add: dg_Rel_components(2) dghm_dag_Rel_components(2))
  then show "T   (DG.Rel αArrMap)" by blast
qed

lemma dghm_dag_Rel_ArrMap_app_is_arr:
  assumes "T : b dg_Rel αa"
  shows 
    "DG.Rel αArrMapT : DG.Rel αObjMapa dg_Rel αDG.Rel αObjMapb"
proof(intro is_arrI)
  from assms have a: "a  Vset α" and b: "b  Vset α"
    unfolding dg_Rel_components by (fastforce simp: dg_Rel_components)+
  from assms have T: "arr_Rel α T" by (auto simp: dg_Rel_is_arrD(1))
  then show dag_T: "DG.Rel αArrMapT  dg_Rel αArr"
    by (cs_concl cs_shallow cs_simp: dg_Rel_cs_simps cs_intro: dg_Rel_cs_intros)
  from a assms T show "dg_Rel αDomDG.Rel αArrMapT = DG.Rel αObjMapa"
    by 
      (
        cs_concl cs_shallow 
          cs_simp: dg_cs_simps dg_Rel_cs_simps cs_intro: dg_Rel_cs_intros
      )
  from b assms T show "dg_Rel αCodDG.Rel αArrMapT = DG.Rel αObjMapb"
    by 
      (
        cs_concl cs_shallow 
          cs_simp: dg_cs_simps dg_Rel_cs_simps cs_intro: dg_Rel_cs_intros
      )
qed


subsubsection‹Canonical dagger for Rel› is a digraph isomorphism›

lemma (in 𝒵) dghm_dag_Rel_is_iso_dghm: 
  "DG.Rel α : op_dg (dg_Rel α) ↦↦DG.isoαdg_Rel α"
proof(rule is_iso_dghmI)
  interpret digraph α dg_Rel α by (simp add: digraph_dg_Rel)
  show "DG.Rel α : op_dg (dg_Rel α) ↦↦DGαdg_Rel α"
  proof(rule is_dghmI, unfold dg_op_simps dghm_dag_Rel_components(3,4))
    show "vfsequence (DG.Rel α)"
      unfolding dghm_dag_Rel_def by (simp add: nat_omega_simps)
    show "vcard (DG.Rel α) = 4"
      unfolding dghm_dag_Rel_def by (simp add: nat_omega_simps)
    fix T a b assume "T : b dg_Rel αa" 
    then show
      "DG.Rel αArrMapT : DG.Rel αObjMapa dg_Rel αDG.Rel αObjMapb"
      by (rule dghm_dag_Rel_ArrMap_app_is_arr)
  qed (auto simp: dghm_dag_Rel_components intro: dg_cs_intros dg_op_intros)
  show "v11 (DG.Rel αArrMap)"
  proof
    (
      intro vsv.vsv_valeq_v11I,
      unfold dghm_dag_Rel_ArrMap_vdomain dg_Rel_Arr_iff
    )
    fix S T assume prems: 
      "arr_Rel α S" 
      "arr_Rel α T" 
      "DG.Rel αArrMapS = DG.Rel αArrMapT" 
    from prems show "S = T"
      by 
        (
          auto simp: 
            dg_Rel_components 
            dg_Rel_cs_simps
            dghm_dag_Rel_ArrMap_app[OF prems(1)] 
            dghm_dag_Rel_ArrMap_app[OF prems(2)]
        )
  qed (auto intro: dg_Rel_cs_intros)
  show " (DG.Rel αArrMap) = dg_Rel αArr" by (simp add: dg_Rel_cs_simps)
qed (simp_all add: dghm_dag_Rel_components)


subsubsection‹Further properties of the canonical dagger›

lemma (in 𝒵) dghm_cn_comp_dghm_dag_Rel_dghm_dag_Rel: 
  "DG.Rel α DGHM DG.Rel α = dghm_id (dg_Rel α)"
proof-
  interpret digraph α dg_Rel α by (simp add: digraph_dg_Rel)
  from dghm_dag_Rel_is_iso_dghm have dag: 
    "DG.Rel α : dg_Rel α DG↦↦αdg_Rel α"
    by (simp add: is_iso_dghm_def)
  show ?thesis
  proof(rule dghm_eqI)
    show "(DG.Rel α DGHM DG.Rel α)ArrMap = dghm_id (dg_Rel α)ArrMap"
    proof(rule vsv_eqI)
      show "vsv ((DG.Rel α DGHM DG.Rel α)ArrMap)"
        by (auto simp: dghm_cn_comp_components dghm_dag_Rel_components)
      fix a assume "a  𝒟 ((DG.Rel α DGHM DG.Rel α)ArrMap)"
      then have a: "arr_Rel α a" 
        unfolding dg_Rel_cs_simps dghm_cn_comp_ArrMap_vdomain[OF dag dag] by simp
      from a dghm_dag_Rel_is_iso_dghm show 
        "(DG.Rel α DGHM DG.Rel α)ArrMapa = dghm_id (dg_Rel α)ArrMapa"
        by
          (
            cs_concl 
              cs_simp: dg_Rel_cs_simps dg_cs_simps dg_cn_cs_simps 
              cs_intro: dg_Rel_cs_intros dghm_cs_intros 
          )
    qed (simp_all add: dghm_cn_comp_components dghm_id_components dg_Rel_cs_simps)
    show "dghm_id (dg_Rel α) : dg_Rel α ↦↦DGαdg_Rel α"
      by (simp_all add: digraph.dg_dghm_id_is_dghm digraph_axioms)
  qed 
    (
      auto simp: 
        dghm_cn_comp_is_dghm[OF digraph_axioms dag dag] 
        dghm_cn_comp_components 
        dghm_dag_Rel_components 
        dghm_id_components
    )
qed

text‹\newpage›

end