Theory CZH_SMC_Par

(* Copyright 2021 (C) Mihails Milehins *)

sectionPar› as a semicategory›
theory CZH_SMC_Par
  imports 
    CZH_DG_Par
    CZH_SMC_Rel
    CZH_SMC_Subsemicategory
begin



subsection‹Background›


text‹
The methodology chosen for the exposition 
of Par› as a semicategory is analogous to the 
one used in the previous chapter for the exposition of Par› as a digraph. 
›

named_theorems smc_Par_cs_simps
named_theorems smc_Par_cs_intros

lemmas (in arr_Par) [smc_Par_cs_simps] = 
  dg_Rel_shared_cs_simps

lemmas (in arr_Par) [smc_cs_intros, smc_Par_cs_intros] = 
  arr_Par_axioms'

lemmas [smc_Par_cs_simps] = 
  dg_Rel_shared_cs_simps
  arr_Par.arr_Par_length
  arr_Par_comp_Par_id_Par_left
  arr_Par_comp_Par_id_Par_right

lemmas [smc_Par_cs_intros] = 
  dg_Rel_shared_cs_intros
  arr_Par_comp_Par



subsectionPar› as a semicategory›


subsubsection‹Definition and elementary properties›

definition smc_Par :: "V  V"
  where "smc_Par α =
    [
      Vset α,
      set {T. arr_Par α T},
      (λTset {T. arr_Par α T}. TArrDom),
      (λTset {T. arr_Par α T}. TArrCod),
      (λSTcomposable_arrs (dg_Par α). ST0 Rel ST1)
    ]"


text‹Components.›

lemma smc_Par_components:
  shows "smc_Par αObj = Vset α"
    and "smc_Par αArr = set {T. arr_Par α T}"
    and "smc_Par αDom = (λTset {T. arr_Par α T}. TArrDom)"
    and "smc_Par αCod = (λTset {T. arr_Par α T}. TArrCod)"
    and "smc_Par αComp = (λSTcomposable_arrs (dg_Par α). ST0 Rel ST1)"
  unfolding smc_Par_def dg_field_simps by (simp_all add: nat_omega_simps)


text‹Slicing.›

lemma smc_dg_smc_Par: "smc_dg (smc_Par α) = dg_Par α"
proof(rule vsv_eqI)
  have dom_lhs: "𝒟 (smc_dg (smc_Par α)) = 4" 
    unfolding smc_dg_def by (simp add: nat_omega_simps)
  have dom_rhs: "𝒟 (dg_Par α) = 4"
    unfolding dg_Par_def by (simp add: nat_omega_simps)
  show "𝒟 (smc_dg (smc_Par α)) = 𝒟 (dg_Par α)"
    unfolding dom_lhs dom_rhs by simp
  show "a  𝒟 (smc_dg (smc_Par α))  smc_dg (smc_Par α)a = dg_Par αa"
    for a
    by 
      (
        unfold dom_lhs, 
        elim_in_numeral, 
        unfold smc_dg_def dg_field_simps smc_Par_def dg_Par_def
      )
      (auto simp: nat_omega_simps)
qed (auto simp: dg_Par_def smc_dg_def)

lemmas_with [folded smc_dg_smc_Par, unfolded slicing_simps]: 
  smc_Par_Obj_iff = dg_Par_Obj_iff
  and smc_Par_Arr_iff[smc_Par_cs_simps] = dg_Par_Arr_iff
  and smc_Par_Dom_vsv[smc_Par_cs_intros] = dg_Par_Dom_vsv
  and smc_Par_Dom_vdomain[smc_Par_cs_simps] = dg_Par_Dom_vdomain
  and smc_Par_Dom_vrange = dg_Par_Dom_vrange
  and smc_Par_Dom_app[smc_Par_cs_simps] = dg_Par_Dom_app
  and smc_Par_Cod_vsv[smc_Par_cs_intros] = dg_Par_Cod_vsv
  and smc_Par_Cod_vdomain[smc_Par_cs_simps] = dg_Par_Cod_vdomain
  and smc_Par_Cod_vrange = dg_Par_Cod_vrange
  and smc_Par_Cod_app[smc_Par_cs_simps] = dg_Par_Cod_app
  and smc_Par_is_arrI = dg_Par_is_arrI
  and smc_Par_is_arrD = dg_Par_is_arrD
  and smc_Par_is_arrE = dg_Par_is_arrE

lemmas [smc_cs_simps] = smc_Par_is_arrD(2,3)

lemmas [smc_Par_cs_intros] = smc_Par_is_arrI

lemmas_with (in 𝒵) [folded smc_dg_smc_Par, unfolded slicing_simps]: 
  smc_Par_Hom_vifunion_in_Vset = dg_Par_Hom_vifunion_in_Vset
  and smc_Par_incl_Par_is_arr = dg_Par_incl_Par_is_arr
  and smc_Par_incl_Par_is_arr'[smc_Par_cs_intros] = dg_Par_incl_Par_is_arr'

lemmas [smc_Par_cs_intros] = 𝒵.smc_Par_incl_Par_is_arr'


subsubsection‹Composable arrows›

lemma smc_Par_composable_arrs_dg_Par: 
  "composable_arrs (dg_Par α) = composable_arrs (smc_Par α)"
  unfolding composable_arrs_def smc_dg_smc_Par[symmetric] slicing_simps by simp

lemma smc_Par_Comp: 
  "smc_Par αComp = (λSTcomposable_arrs (smc_Par α). ST0 Rel ST1)"
  unfolding smc_Par_components smc_Par_composable_arrs_dg_Par ..


subsubsection‹Composition›

lemma smc_Par_Comp_app[smc_Par_cs_simps]:
  assumes "S : B smc_Par αC" and "T : A smc_Par αB"
  shows "S Asmc_Par αT = S Rel T"
proof-
  from assms have "[S, T]  composable_arrs (smc_Par α)" 
    by (auto simp: smc_cs_intros)
  then show "S Asmc_Par αT = S Rel T"
    unfolding smc_Par_Comp by (simp add: nat_omega_simps)
qed 

lemma smc_Par_Comp_vdomain: "𝒟 (smc_Par αComp) = composable_arrs (smc_Par α)" 
  unfolding smc_Par_Comp by simp

lemma (in 𝒵) smc_Par_Comp_vrange: " (smc_Par αComp)  set {T. arr_Par α T}"
proof(rule vsubsetI)
  interpret digraph α smc_dg (smc_Par α)
    unfolding smc_dg_smc_Par by (simp add: digraph_dg_Par)
  fix R assume "R   (smc_Par αComp)"
  then obtain ST 
    where R_def: "R = smc_Par αCompST"
      and "ST  𝒟 (smc_Par αComp)"
    unfolding smc_Par_components by (blast dest: rel_VLambda.vrange_atD)
  then obtain S T A B C 
    where "ST = [S, T]" 
      and S: "S : B smc_Par αC" 
      and T: "T : A smc_Par αB"
    by (auto simp: smc_Par_Comp_vdomain)
  with R_def have R_def': "R = S Asmc_Par αT" by simp
  note S_D = dg_is_arrD(1)[unfolded slicing_simps, OF S]
    and T_D = dg_is_arrD(1)[unfolded slicing_simps, OF T]
  from S_D T_D have "arr_Par α S" "arr_Par α T" 
    by (simp_all add: smc_Par_components)
  from this show "R  set {T. arr_Par α T}" 
    unfolding R_def' smc_Par_Comp_app[OF S T] by (auto simp: arr_Par_comp_Par)
qed


subsubsectionPar› is a semicategory›

lemma (in 𝒵) semicategory_smc_Par: "semicategory α (smc_Par α)"
proof(intro semicategoryI, unfold smc_dg_smc_Par)
  show "vfsequence (smc_Par α)" unfolding smc_Par_def by simp
  show "vcard (smc_Par α) = 5"
    unfolding smc_Par_def by (simp add: nat_omega_simps)
  show "(GF  𝒟 (smc_Par αComp)) 
    (G F B C A. GF = [G, F]  G : B smc_Par αC  F : A smc_Par αB)"
    for GF
    unfolding smc_Par_Comp_vdomain by (auto intro: composable_arrsI)
  show [intro]: "G Asmc_Par αF : A smc_Par αC"
    if "G : B smc_Par αC" and "F : A smc_Par αB" for G B C F A
  proof-
    from that have "arr_Par α G" "arr_Par α F" by (auto elim: smc_Par_is_arrE)
    with that show ?thesis
      by 
        (
          cs_concl cs_shallow
            cs_simp: smc_cs_simps smc_Par_cs_simps 
            cs_intro: smc_Par_cs_intros
        )
  qed 
  show "H Asmc_Par αG Asmc_Par αF = H Asmc_Par α(G Asmc_Par αF)"
    if "H : C smc_Par αD" 
      and "G : B smc_Par αC"
      and "F : A smc_Par αB"
    for H C D G B F A
  proof-
    from that have "arr_Par α H" "arr_Par α G" "arr_Par α F" 
      by (auto simp: smc_Par_is_arrD)
    with that show ?thesis
      by 
        (
          cs_concl cs_shallow
            cs_simp: smc_cs_simps smc_Par_cs_simps 
            cs_intro: smc_Par_cs_intros
        )
  qed
qed (auto simp: digraph_dg_Par smc_Par_components)


subsubsectionPar› is a wide subsemicategory of Rel›

lemma (in 𝒵) wide_subsemicategory_smc_Par_smc_Rel: 
  "smc_Par α SMC.wideαsmc_Rel α"
proof-
  interpret Rel: semicategory α smc_Rel α by (rule semicategory_smc_Rel)
  interpret Par: semicategory α smc_Par α by (rule semicategory_smc_Par)
  show ?thesis
  proof
    (
      intro wide_subsemicategoryI subsemicategoryI,
      unfold smc_dg_smc_Par smc_dg_smc_Rel
    )
    from wide_subdigraph_dg_Par_dg_Rel show wsd:
      "dg_Par α DGαdg_Rel α" "dg_Par α DG.wideαdg_Rel α"
      by auto
    interpret wide_subdigraph α dg_Par α dg_Rel α by (rule wsd(2))
    show "G Asmc_Par αF = G Asmc_Rel αF"
      if "G : B smc_Par αC" and "F : A smc_Par αB" for G B C F A
    proof-
      from that have "G : B dg_Par αC" and "F : A dg_Par αB" 
        by 
          (
            cs_concl cs_shallow 
              cs_simp: smc_dg_smc_Par[symmetric] cs_intro: slicing_intros
          )+
      then have "G : B dg_Rel αC" and "F : A dg_Rel αB" 
        by (cs_concl cs_shallow cs_intro: dg_sub_fw_cs_intros)+
      then have "G : B smc_Rel αC" and "F : A smc_Rel αB" 
        unfolding smc_dg_smc_Rel[symmetric] slicing_simps by simp_all
      from that this show "G Asmc_Par αF = G Asmc_Rel αF"
        by (cs_concl cs_shallow cs_simp: smc_Par_cs_simps smc_Rel_cs_simps)
    qed
  qed (auto simp: smc_cs_intros)
qed



subsection‹Monic arrow and epic arrow›

lemma smc_Par_is_monic_arrI[intro]:
  assumes "T : A smc_Par αB" and "v11 (TArrVal)" and "𝒟 (TArrVal) = A"
  shows "T : A monsmc_Par αB"
proof(intro is_monic_arrI)

  interpret T: arr_Par α T by (intro smc_Par_is_arrD(1)[OF assms(1)])
  interpret Par_Rel: wide_subsemicategory α smc_Par α smc_Rel α
    by (rule T.wide_subsemicategory_smc_Par_smc_Rel)
  interpret v11: v11 TArrVal by (rule assms(2))

  show T: "T : A smc_Par αB" by (rule assms(1))
  fix S R A'
  assume S: "S : A' smc_Par αA" 
    and R: "R : A' smc_Par αA"
    and TS_TR: "T Asmc_Par αS = T Asmc_Par αR"
  from assms(3) T Par_Rel.subsemicategory_axioms have "T : A monsmc_Rel αB"
    by (intro smc_Rel_is_monic_arrI)
      (auto dest: v11.v11_vimage_vpsubset_neq elim!: smc_sub_fw_cs_intros)
  moreover from S Par_Rel.subsemicategory_axioms have "S : A' smc_Rel αA"
    by (cs_concl cs_shallow cs_intro: smc_sub_fw_cs_intros)
  moreover from R Par_Rel.subsemicategory_axioms have "R : A' smc_Rel αA" 
    by (cs_concl cs_shallow cs_intro: smc_sub_fw_cs_intros)
  moreover from T S R TS_TR Par_Rel.subsemicategory_axioms have 
    "T Asmc_Rel αS = T Asmc_Rel αR" 
    by (auto simp: smc_sub_bw_cs_simps)
  ultimately show "S = R" by (rule is_monic_arrD(2))
qed

lemma smc_Par_is_monic_arrD:
  assumes "T : A monsmc_Par αB"
  shows "T : A smc_Par αB" and "v11 (TArrVal)" and "𝒟 (TArrVal) = A"
proof-

  from assms show T: "T : A smc_Par αB" by auto
  interpret T: arr_Par α T 
    rewrites [simp]: "TArrDom = A" and [simp]: "TArrCod = B"
    using T by (auto dest: smc_Par_is_arrD)

  show "v11 (TArrVal)"
  proof(intro v11I)

    show "vsv ((TArrVal)¯)"
    proof(intro vsvI)

      fix a b c assume "a, b  (TArrVal)¯" and "a, c  (TArrVal)¯"

      then have bar: "b, a  TArrVal" and car: "c, a  TArrVal" by auto
      with T.arr_Rel_ArrVal_vdomain have [intro]: "b  A" "c  A" by auto

      define R where "R = [set {0, b}, set {0}, A]"
      define S where "S = [set {0, c}, set {0}, A]"

      have R_components: 
        "RArrVal = set {0, b}" "RArrDom = set {0}" "RArrCod = A"
        unfolding R_def by (simp_all add: arr_Rel_components)

      have S_components: 
        "SArrVal = set {0, c}" "SArrDom = set {0}" "SArrCod = A"
        unfolding S_def by (simp_all add: arr_Rel_components)

      have R: "R : set {0} smc_Par αA"
      proof(rule smc_Par_is_arrI)
        show "arr_Par α R"
          unfolding R_def
          by (rule T.arr_Par_vfsequenceI) (auto simp: T.arr_Rel_ArrDom_in_Vset)
      qed (simp_all add: R_components)

      have S: "S : set {0} smc_Par αA"
      proof(rule smc_Par_is_arrI)
        show "arr_Par α S"
          unfolding S_def
          by (rule T.arr_Par_vfsequenceI) (auto simp: T.arr_Rel_ArrDom_in_Vset)
      qed (simp_all add: S_components)

      have "T Asmc_Par αR = [set {0, a}, set {0}, B]"
        unfolding smc_Par_Comp_app[OF T R]
      proof
        (
          rule arr_Par_eqI[of α],
          unfold comp_Rel_components arr_Rel_components R_components
        )
        from R T show "arr_Par α (T Rel R)"
          by (intro arr_Par_comp_Par) (auto elim!: smc_Par_is_arrE)
        show "arr_Par α [set {0, a}, set {0}, B]"
        proof(rule T.arr_Par_vfsequenceI)
          from T.arr_Rel_ArrVal_vrange bar show " (set {0, a})  B" by auto
        qed (auto simp: T.arr_Rel_ArrCod_in_Vset T.Axiom_of_Powers)
        show "TArrVal  set {0, b} = set {0, a}"
        proof(rule vsv_eqI, unfold vdomain_vsingleton)
          from bar show "𝒟 (TArrVal  set {0, b}) = set {0}" by auto
          with bar show 
            "a'  𝒟 (TArrVal  set {0, b}) 
              (TArrVal  set {0, b})a' = set {0, a}a'"
            for a'
            by auto
        qed (auto intro: vsv_vcomp)
      qed simp_all

      moreover have "T Asmc_Par αS = [set {0, a}, set {0}, B]" 
        unfolding smc_Par_Comp_app[OF T S]
      proof
        (
          rule arr_Par_eqI[of α],
          unfold comp_Rel_components arr_Rel_components S_components
        )
        from T S show "arr_Par α (T Rel S)"
          by (intro arr_Par_comp_Par) (auto elim!: smc_Par_is_arrE)
        show "arr_Par α [set {0, a}, set {0}, B]"
        proof(rule T.arr_Par_vfsequenceI)
          from T.arr_Rel_ArrVal_vrange bar show " (set {0, a})  B" by auto
        qed (auto simp: T.arr_Rel_ArrCod_in_Vset T.Axiom_of_Powers)
        show "TArrVal  set {0, c} = set {0, a}"
        proof(rule vsv_eqI, unfold vdomain_vsingleton)
          from car show "𝒟 (TArrVal  set {0, c}) = set {0}" by auto
          with car show "a'  𝒟 (TArrVal  set {0, c})  
            (TArrVal  set {0, c})a' = set {0, a}a'"
            for a'
            by auto
        qed (auto intro: vsv_vcomp)
      qed simp_all
      ultimately have "T Asmc_Par αR = T Asmc_Par αS" by simp
      from assms R S this have "R = S" by blast
      with R_components(1) S_components(1) show "b = c" by simp
    qed auto

  qed auto

  show "𝒟 (TArrVal) = A"
  proof(intro vsubset_antisym vsubsetI)
    from T.arr_Rel_ArrVal_vdomain show "x  𝒟 (TArrVal)  x  A" for x
      by auto
    fix a assume [simp]: "a  A" show "a  𝒟 (TArrVal)"
    proof(rule ccontr)
      assume a: "a  𝒟 (TArrVal)"
      define R where "R = [set {0, a}, set {0, 1}, A]"
      define S where "S = [set {1, a}, set {0, 1}, A]"
      have R: "R : set {0, 1} smc_Par αA"
      proof(rule smc_Par_is_arrI)
        show "arr_Par α R"
          unfolding R_def
        proof(rule T.arr_Par_vfsequenceI)
          from T.Axiom_of_Infinity vone_in_omega show "set {0, 1}  Vset α" 
            by blast
        qed (auto simp: T.arr_Rel_ArrDom_in_Vset)
      qed (auto simp: R_def arr_Rel_components)
      have S: "S : set {0, 1} smc_Par αA"
      proof(rule smc_Par_is_arrI)
        show "arr_Par α S"
          unfolding S_def
        proof(rule T.arr_Par_vfsequenceI)
          from T.Axiom_of_Infinity vone_in_omega show "set {0, 1}  Vset α" 
            by blast
        qed (auto simp: T.arr_Rel_ArrDom_in_Vset)
      qed (auto simp: S_def arr_Rel_components)
      with a have "TArrVal  RArrVal = 0" 
        unfolding R_def arr_Rel_components
        by (intro vsubset_antisym vsubsetI) auto
      moreover with a have "TArrVal  SArrVal = 0" 
        unfolding S_def arr_Rel_components
        by (intro vsubset_antisym vsubsetI) auto
      ultimately have "T Asmc_Par αR = T Asmc_Par αS" 
        using R T S
        by
          (
            intro arr_Par_eqI[of α T Asmc_Par αR T Asmc_Par αS]; 
            elim smc_Par_is_arrE
          )
          (
            auto simp:
              dg_Par_cs_intros
              smc_Par_Comp_app[OF T R] 
              smc_Par_Comp_app[OF T S] 
              comp_Rel_components
          )
      from R S this assms have "R = S" by blast
      then show False unfolding R_def S_def by simp
    qed 
  qed

qed 

lemma smc_Par_is_monic_arr: 
  "T : A monsmc_Par αB 
    T : A smc_Par αB  v11 (TArrVal)  𝒟 (TArrVal) = A"
  by (intro iffI) (auto simp: smc_Par_is_monic_arrD smc_Par_is_monic_arrI)

context
begin

private lemma smc_Par_is_epic_arr_vsubset:
  assumes "T : A smc_Par αB"
    and " (TArrVal) = B"
    and "R : B smc_Par αC" 
    and "S : B smc_Par αC" 
    and "R Asmc_Par αT = S Asmc_Par αT" 
  shows "RArrVal  SArrVal"
proof
  interpret T: arr_Par α T
    rewrites [simp]: "TArrDom = A" and [simp]: "TArrCod = B"
    using assms smc_Par_is_arrD by auto
  interpret R: arr_Par α R 
    rewrites [simp]: "RArrDom = B" and [simp]: "RArrCod = C"
    using assms smc_Par_is_arrD by auto
  from assms(5) have "(R Asmc_Par αT)ArrVal = (S Asmc_Par αT)ArrVal"
    by simp
  then have eq: "RArrVal  TArrVal = SArrVal  TArrVal" 
    unfolding 
      smc_Par_Comp_app[OF assms(3,1)] 
      smc_Par_Comp_app[OF assms(4,1)]
      comp_Rel_components
    by simp
  fix bc assume prems: "bc  RArrVal"
  moreover with R.ArrVal.vbrelation obtain b c where bc_def: "bc = b, c" by auto
  ultimately have [simp]: "b  B" and "c  C"
    using R.arr_Rel_ArrVal_vdomain R.arr_Rel_ArrVal_vrange by auto
  note [intro] = prems[unfolded bc_def]
  have "b   (TArrVal)" by (simp add: assms(2))
  then obtain a where ab: "a, b  TArrVal" by auto
  then have "a, c  SArrVal  TArrVal" unfolding eq[symmetric] by auto
  then obtain b' where ab': "b', c  SArrVal" and "a, b'  TArrVal" 
    by clarsimp
  with ab ab' T.vsv T.ArrVal.vsv show "bc  SArrVal" unfolding bc_def by blast
qed

lemma smc_Par_is_epic_arrI:
  assumes "T : A smc_Par αB" and " (TArrVal) = B"
  shows "T : A epismc_Par αB"
  unfolding is_epic_arr_def
proof
  (
    intro is_monic_arrI[
      of op_smc (smc_Par α), unfolded smc_op_simps, OF assms(1)
      ]
  )

  interpret T: arr_Par α T
    rewrites [simp]: "TArrDom = A" and [simp]: "TArrCod = B"
    using assms smc_Par_is_arrD by auto

  interpret semicategory α smc_Par α by (rule T.semicategory_smc_Par)

  fix R S a 
  assume prems: 
    "R : B smc_Par αa" 
    "S : B smc_Par αa" 
    "T Aop_smc (smc_Par α)R = T Aop_smc (smc_Par α)S"

  from prems(3) have RT_ST: "R Asmc_Par αT = S Asmc_Par αT"
    unfolding 
      op_smc_Comp[OF prems(1) assms(1)]
      op_smc_Comp[OF prems(2) assms(1)]
    by simp
  from smc_Par_is_epic_arr_vsubset[OF assms(1,2) prems(1,2) this] 
  have RS: "RArrVal  SArrVal".

  from smc_Par_is_epic_arr_vsubset[OF assms(1,2) prems(2,1) RT_ST[symmetric]]
  have SR: "SArrVal  RArrVal".
  
  from prems show "R = S"    
    by (intro arr_Par_eqI[of α R S])
      (auto simp: RS SR vsubset_antisym elim!: smc_Par_is_arrE)

qed

lemma smc_Par_is_epic_arrD:
  assumes "T : A epismc_Par αB"
  shows "T : A smc_Par αB" and " (TArrVal) = B"
proof-

  from assms show T: "T : A smc_Par αB" 
    unfolding is_epic_arr_def by (auto simp: op_smc_is_arr)

  interpret T: arr_Par α T
    rewrites [simp]: "TArrDom = A" and [simp]: "TArrCod = B"
    using T by (auto elim: smc_Par_is_arrE)

  interpret semicategory α smc_Par α by (rule T.semicategory_smc_Par)

  show " (TArrVal) = B"
  proof(intro vsubset_antisym vsubsetI)
    from T.arr_Rel_ArrVal_vrange show "y   (TArrVal)  y  B" for y
      by auto
    fix b assume [intro]: "b  B" show "b   (TArrVal)"
    proof(rule ccontr)
      assume prems: "b   (TArrVal)"
      define R where "R = [set {b, 0}, B, set {0, 1}]"
      define S where "S = [set {b, 1}, B, set {0, 1}]"
      have R: "R : B smc_Par αset {0, 1}" 
        unfolding R_def
      proof
        (
          intro smc_Par_is_arrI T.arr_Par_vfsequenceI, 
          unfold arr_Rel_components
        )
        from T.Axiom_of_Infinity vone_in_omega show "set {0, 1}  Vset α" 
          by blast
      qed (auto simp: T.arr_Rel_ArrCod_in_Vset)
      have S: "S : B smc_Par αset {0, 1}"
        unfolding S_def
      proof
        (
          intro smc_Par_is_arrI T.arr_Par_vfsequenceI, 
          unfold arr_Rel_components
        )
        from T.Axiom_of_Infinity vone_in_omega show "set {0, 1}  Vset α" 
          by blast
      qed (auto simp: T.arr_Rel_ArrCod_in_Vset)
      from prems have "RArrVal  TArrVal = 0"
        unfolding R_def arr_Rel_components
        by (auto intro!: vsubset_antisym vsubsetI)
      moreover from prems have "SArrVal  TArrVal = 0" 
        unfolding S_def arr_Rel_components
        by (auto intro!: vsubset_antisym vsubsetI)
      ultimately have "R Asmc_Par αT = S Asmc_Par αT" 
        unfolding smc_Par_Comp_app[OF R T] smc_Par_Comp_app[OF S T]
        by (simp add: R_def S_def arr_Rel_components comp_Rel_def)
      from is_epic_arrD(2)[OF assms R S this] show False 
        unfolding R_def S_def by simp
    qed
  qed

qed

end

lemma smc_Par_is_epic_arr: 
  "T : A epismc_Par αB  T : A smc_Par αB   (TArrVal) = B" 
  by (intro iffI) (simp_all add: smc_Par_is_epic_arrD smc_Par_is_epic_arrI)



subsection‹Terminal object, initial object and null object›

lemma (in 𝒵) smc_Par_obj_terminal: "obj_terminal (smc_Par α) A  A = 0"
proof-

  interpret semicategory α smc_Par α by (rule semicategory_smc_Par)

  have "(AVset α. ∃!T. T : A smc_Par αB)  B = 0" for B
  proof(intro iffI allI ballI)

    assume prems[rule_format]: "AVset α. ∃!T. T : A smc_Par αB" 
    
    then obtain T where "T : 0 smc_Par αB" by (meson vempty_is_zet)
    then have [simp]: "B  Vset α" by (fastforce simp: smc_Par_components(1))
    
    show "B = 0"
    proof(rule ccontr)
      assume "B  0"
      then obtain b where "b  B" using trad_foundation by auto
      have "[set {0, b}, set {0}, B] : set {0} smc_Par αB"
        by (intro smc_Par_is_arrI arr_Par_vfsequenceI, unfold arr_Rel_components)
          (auto simp: b  B vsubset_vsingleton_leftI)
      moreover have "[0, set {0}, B] : set {0} smc_Par αB"
        by (intro smc_Par_is_arrI arr_Par_vfsequenceI, unfold arr_Rel_components)
          (auto simp: b  B vsubset_vsingleton_leftI)
      moreover have "[set {0, b}, set {0}, B]  [0, set {0}, B]" by simp
      ultimately show False
        by (metis prems smc_is_arrE smc_Par_components(1))
    qed

  next

    fix A assume [simp]: "B = 0" "A  Vset α"
    show "∃!T. T : A smc_Par αB"
    proof(intro ex1I [of _ [0, A, 0]])
      show zAz: "[0, A, 0] : A smc_Par αB"
        by 
          ( 
            intro smc_Par_is_arrI arr_Par_vfsequenceI, 
            unfold arr_Rel_components
          ) 
          simp_all
      show "T = [0, A, 0]" if "T : A smc_Par αB" for T
      proof(rule arr_Par_eqI[of α], unfold arr_Rel_components)
        interpret arr_Par α T using that by (simp add: smc_Par_is_arrD(1))
        from zAz show "arr_Par α [0, A, 0]" by (auto elim: smc_Par_is_arrE)
        from arr_Par_axioms that show "TArrVal = 0"
          by (clarsimp simp: vsv.vsv_vrange_vempty smc_Par_is_arrD(3))
      qed (use that in auto dest: smc_Par_is_arrD)
    qed

  qed

  then show ?thesis
    apply(intro iffI obj_terminalI)
    subgoal by (metis smc_is_arrD(2) obj_terminalE)
    subgoal by blast
    subgoal by (metis smc_Par_components(1))
    done

qed

lemma (in 𝒵) smc_Par_obj_initial: "obj_initial (smc_Par α) A  A = 0"
proof-

  interpret Par: semicategory α smc_Par α by (rule semicategory_smc_Par)

  have "(BVset α. ∃!T. T : A smc_Par αB)  (A = 0)" for A
  proof(intro iffI allI ballI)

    assume prems[rule_format]: "BVset α. ∃!T. T : A smc_Par αB" 

    then obtain T where "T : A smc_Par α0" 
      by (meson vempty_is_zet)
    then have [simp]: "A  Vset α" by (fastforce simp: smc_Par_components(1))

    show "A = 0"
    proof(rule ccontr)
      assume "A  0"
      then obtain a where "a  A" using trad_foundation by auto
      have "[set {a, 0}, A, set {0}] : A smc_Par αset {0}"
        by (intro smc_Par_is_arrI arr_Par_vfsequenceI, unfold arr_Rel_components)
          (auto simp: a  A vsubset_vsingleton_leftI)
      moreover have "[0, A, set {0}] : A smc_Par αset {0}"
        by (intro smc_Par_is_arrI arr_Par_vfsequenceI, unfold arr_Rel_components)
          (auto simp: a  A vsubset_vsingleton_leftI)
      moreover have "[set {a, 0}, A, set {0}]  [0, A, set {0}]" by simp
      ultimately show False 
        by (metis prems Par.smc_is_arrE smc_Par_components(1))
    qed

  next

    fix B assume prems[simp]: "A = 0" "B  Vset α"

    show "∃!T. T : A smc_Par αB"
    proof(intro ex1I[of _ [0, 0, B]])
      show zzB: "[0, 0, B] : A smc_Par αB"
        by 
          ( 
            intro smc_Par_is_arrI arr_Par_vfsequenceI, 
            unfold arr_Rel_components
          ) 
          simp_all
      show "T = [0, 0, B]" if "T : A smc_Par αB" for T
      proof(rule arr_Par_eqI[of α], unfold arr_Rel_components)
        interpret arr_Par α T using that by (simp add: smc_Par_is_arrD(1))
        show "arr_Par α T" by (rule arr_Par_axioms)
        from zzB show "arr_Par α [0, 0, B]" by (auto elim: smc_Par_is_arrE)
        from arr_Par_axioms that show "TArrVal = 0"
          by (elim smc_Par_is_arrE arr_ParE)
            (
              auto 
                intro: ArrVal.vsv_vrange_vempty 
                simp: ArrVal.vdomain_vrange_is_vempty
            )
      qed (use that in auto dest: smc_Par_is_arrD)
    qed
  qed

  then show ?thesis
    unfolding obj_initial_def
    apply(intro iffI obj_terminalI, elim obj_terminalE, unfold smc_op_simps)
    subgoal by (metis smc_Par_components(1))
    subgoal by (simp add: smc_Par_components(1))
    subgoal by (metis smc_Par_components(1))
    done

qed

lemma (in 𝒵) smc_Par_obj_terminal_obj_initial:
  "obj_initial (smc_Par α) A  obj_terminal (smc_Par α) A"
  unfolding smc_Par_obj_initial smc_Par_obj_terminal by simp

lemma (in 𝒵) smc_Par_obj_null: "obj_null (smc_Par α) A  A = 0"
  unfolding obj_null_def smc_Par_obj_terminal smc_Par_obj_initial by simp



subsection‹Zero arrow›

lemma (in 𝒵) smc_Par_is_zero_arr: 
  assumes "A  smc_Par αObj" and "B  smc_Par αObj"
  shows "T : A 0smc_Par αB  T = [0, A, B]"
proof(intro HOL.ext iffI)
  interpret Par: semicategory α smc_Par α by (rule semicategory_smc_Par)
  fix T A B assume "T : A 0smc_Par αB"
  with smc_Par_is_arrD(1) obtain R S 
    where T_def: "T = R Asmc_Par αS" 
      and S: "S : A smc_Par α0" 
      and R: "R : 0 smc_Par αB"
    by (auto simp: arr_Par_def 𝒵.smc_Par_obj_initial obj_null_def) 
  interpret S: arr_Par α S
    rewrites [simp]: "SArrDom = A" and [simp]: "SArrCod = 0"
    using S smc_Par_is_arrD by auto
  interpret R: arr_Par α R
    rewrites [simp]: "RArrDom = 0" and [simp]: "RArrCod = B"
    using R smc_Par_is_arrD by auto
  have S_def: "S = [0, A, 0]"
    by 
      (
        rule arr_Rel_eqI[of α], 
        unfold arr_Rel_components,
        insert S.arr_Rel_ArrVal_vrange S.ArrVal.vbrelation_vintersection_vrange
      )
      (
        auto simp: 
        S.arr_Rel_axioms 
        S.arr_Rel_ArrDom_in_Vset 
        arr_Rel_vfsequenceI vbrelationI
      )
  show "T = [0, A, B]" 
     unfolding T_def smc_Par_Comp_app[OF R S] 
     by (rule arr_Rel_eqI[of α], unfold comp_Rel_components)
       (
         auto simp: 
          𝒵_axioms
          S_def
          R.arr_Rel_axioms 
          S.arr_Rel_axioms 
          arr_Rel_comp_Rel
          arr_Rel_components
          R.arr_Rel_ArrCod_in_Vset 
          S.arr_Rel_ArrDom_in_Vset 
          𝒵.arr_Rel_vfsequenceI 
          vbrelation_vempty
       )
next
  fix T assume prems: "T = [0, A, B]"
  let ?S = [0, A, 0] and ?R = [0, 0, B]
  have S: "arr_Par α ?S" and R: "arr_Par α ?R"  
    by (allintro arr_Par_vfsequenceI)
      (simp_all add: assms[unfolded smc_Par_components])
  have SA0: "?S : A smc_Par α0"
    by (intro smc_Par_is_arrI) (simp_all add: S arr_Rel_components)
  moreover have R0B: "?R : 0 smc_Par αB"
    by (intro smc_Par_is_arrI) (simp_all add: R arr_Rel_components)
  moreover have "T = ?R Asmc_Par α?S" 
    unfolding smc_Par_Comp_app[OF R0B SA0]
  proof
    (
      rule arr_Par_eqI[of α],
      unfold comp_Rel_components arr_Rel_components prems
    )
    show "arr_Par α [0, A, B]"
      unfolding prems 
      by (intro arr_Par_vfsequenceI) 
        (auto simp: assms[unfolded smc_Par_components])
  qed (use R S in auto simp: smc_Par_cs_intros)
  ultimately show "T : A 0smc_Par αB" 
    by (simp add: is_zero_arrI smc_Par_obj_null)
qed

text‹\newpage›

end