Theory CZH_SMC_NTSMCF

(* Copyright 2021 (C) Mihails Milehins *)

section‹Natural transformation of a semifunctor›
theory CZH_SMC_NTSMCF
  imports 
    CZH_SMC_Semifunctor
    CZH_DG_TDGHM
begin



subsection‹Background›

named_theorems ntsmcf_cs_simps
named_theorems ntsmcf_cs_intros

lemmas [smc_cs_simps] = dg_shared_cs_simps
lemmas [smc_cs_intros] = dg_shared_cs_intros


subsubsection‹Slicing›

definition ntsmcf_tdghm :: "V  V"
  where "ntsmcf_tdghm 𝔑 = 
    [
      𝔑NTMap, 
      smcf_dghm (𝔑NTDom),
      smcf_dghm (𝔑NTCod),
      smc_dg (𝔑NTDGDom),
      smc_dg (𝔑NTDGCod)
    ]"


text‹Components.›

lemma ntsmcf_tdghm_components:
  shows [slicing_simps]: "ntsmcf_tdghm 𝔑NTMap = 𝔑NTMap"
    and [slicing_commute]: "ntsmcf_tdghm 𝔑NTDom = smcf_dghm (𝔑NTDom)"
    and [slicing_commute]: "ntsmcf_tdghm 𝔑NTCod = smcf_dghm (𝔑NTCod)"
    and [slicing_commute]: "ntsmcf_tdghm 𝔑NTDGDom = smc_dg (𝔑NTDGDom)"
    and [slicing_commute]: "ntsmcf_tdghm 𝔑NTDGCod = smc_dg (𝔑NTDGCod)"
  unfolding ntsmcf_tdghm_def nt_field_simps by (auto simp: nat_omega_simps)



subsection‹Definition and elementary properties›


text‹
A natural transformation of semifunctors, as presented in this work,
is a generalization of the concept of a natural transformation, as presented in
Chapter I-4 in cite"mac_lane_categories_2010", to semicategories and
semifunctors.
›

locale is_ntsmcf = 
  𝒵 α + 
  vfsequence 𝔑 + 
  NTDom: is_semifunctor α 𝔄 𝔅 𝔉 + 
  NTCod: is_semifunctor α 𝔄 𝔅 𝔊
  for α 𝔄 𝔅 𝔉 𝔊 𝔑 +
  assumes ntsmcf_length[smc_cs_simps]: "vcard 𝔑 = 5"  
    and ntsmcf_is_tdghm[slicing_intros]: "ntsmcf_tdghm 𝔑 :
      smcf_dghm 𝔉 DGHM smcf_dghm 𝔊 : smc_dg 𝔄 ↦↦DGαsmc_dg 𝔅"
    and ntsmcf_NTDom[smc_cs_simps]: "𝔑NTDom = 𝔉"
    and ntsmcf_NTCod[smc_cs_simps]: "𝔑NTCod = 𝔊"
    and ntsmcf_NTDGDom[smc_cs_simps]: "𝔑NTDGDom = 𝔄"
    and ntsmcf_NTDGCod[smc_cs_simps]: "𝔑NTDGCod = 𝔅"
    and ntsmcf_Comp_commute[smc_cs_intros]: "f : a 𝔄b 
      𝔑NTMapb A𝔅𝔉ArrMapf = 𝔊ArrMapf A𝔅𝔑NTMapa" 

syntax "_is_ntsmcf" :: "V  V  V  V  V  V  bool"
  ((_ :/ _ SMCF _ :/ _ ↦↦SMCı _) [51, 51, 51, 51, 51] 51)
translations "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"  
  "CONST is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑"

abbreviation all_ntsmcfs :: "V  V"
  where "all_ntsmcfs α  set {𝔑. 𝔉 𝔊 𝔄 𝔅. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}"

abbreviation ntsmcfs :: "V  V  V  V"
  where "ntsmcfs α 𝔄 𝔅  set {𝔑. 𝔉 𝔊. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}"

abbreviation these_ntsmcfs :: "V  V  V  V  V  V"
  where "these_ntsmcfs α 𝔄 𝔅 𝔉 𝔊  set {𝔑. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}"

lemmas [smc_cs_simps] =
  is_ntsmcf.ntsmcf_length
  is_ntsmcf.ntsmcf_NTDom
  is_ntsmcf.ntsmcf_NTCod
  is_ntsmcf.ntsmcf_NTDGDom
  is_ntsmcf.ntsmcf_NTDGCod
  is_ntsmcf.ntsmcf_Comp_commute

lemmas [smc_cs_intros] = is_ntsmcf.ntsmcf_Comp_commute

lemma (in is_ntsmcf) ntsmcf_is_tdghm':
  assumes "𝔉' = smcf_dghm 𝔉"
    and "𝔊' = smcf_dghm 𝔊"
    and "𝔄' = smc_dg 𝔄"
    and "𝔅' = smc_dg 𝔅"
  shows "ntsmcf_tdghm 𝔑 : 𝔉' DGHM 𝔊' : 𝔄' ↦↦DGα𝔅'"
  unfolding assms(1-4) by (rule ntsmcf_is_tdghm)

lemmas [slicing_intros] = is_ntsmcf.ntsmcf_is_tdghm'


text‹Rules.›

lemma (in is_ntsmcf) is_ntsmcf_axioms'[smc_cs_intros]:
  assumes "α' = α" and "𝔄' = 𝔄" and "𝔅' = 𝔅" and "𝔉' = 𝔉" and "𝔊' = 𝔊"
  shows "𝔑 : 𝔉' SMCF 𝔊' : 𝔄' ↦↦SMCα'𝔅'"
  unfolding assms by (rule is_ntsmcf_axioms)

mk_ide rf is_ntsmcf_def[unfolded is_ntsmcf_axioms_def]
  |intro is_ntsmcfI|
  |dest is_ntsmcfD[dest]|
  |elim is_ntsmcfE[elim]|

lemmas [smc_cs_intros] = 
  is_ntsmcfD(3,4)

lemma is_ntsmcfI':
  assumes "𝒵 α"
    and "vfsequence 𝔑"
    and "𝔉 : 𝔄 ↦↦SMCα𝔅"
    and "𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "vcard 𝔑 = 5"
    and "𝔑NTDom = 𝔉"
    and "𝔑NTCod = 𝔊"
    and "𝔑NTDGDom = 𝔄"
    and "𝔑NTDGCod = 𝔅"
    and "vsv (𝔑NTMap)"
    and "𝒟 (𝔑NTMap) = 𝔄Obj"
    and "a. a  𝔄Obj  𝔑NTMapa : 𝔉ObjMapa 𝔅𝔊ObjMapa"
    and "a b f. f : a 𝔄b 
      𝔑NTMapb A𝔅𝔉ArrMapf = 𝔊ArrMapf A𝔅𝔑NTMapa"
  shows "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  by (intro is_ntsmcfI is_tdghmI, unfold ntsmcf_tdghm_components slicing_simps)
    (
      simp_all add: 
        assms nat_omega_simps 
        ntsmcf_tdghm_def  
        is_semifunctorD(6)[OF assms(3)] 
        is_semifunctorD(6)[OF assms(4)]
    )

lemma is_ntsmcfD':
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "𝒵 α"
    and "vfsequence 𝔑"
    and "𝔉 : 𝔄 ↦↦SMCα𝔅"
    and "𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "vcard 𝔑 = 5"
    and "𝔑NTDom = 𝔉"
    and "𝔑NTCod = 𝔊"
    and "𝔑NTDGDom = 𝔄"
    and "𝔑NTDGCod = 𝔅"
    and "vsv (𝔑NTMap)"
    and "𝒟 (𝔑NTMap) = 𝔄Obj"
    and "a. a  𝔄Obj  𝔑NTMapa : 𝔉ObjMapa 𝔅𝔊ObjMapa"
    and "a b f. f : a 𝔄b 
      𝔑NTMapb A𝔅𝔉ArrMapf = 𝔊ArrMapf A𝔅𝔑NTMapa"
  by 
    (
      simp_all add: 
        is_ntsmcfD(2-11)[OF assms] 
        is_tdghmD[OF is_ntsmcfD(6)[OF assms], unfolded slicing_simps]
    )

lemma is_ntsmcfE':
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  obtains "𝒵 α"
    and "vfsequence 𝔑"
    and "𝔉 : 𝔄 ↦↦SMCα𝔅"
    and "𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "vcard 𝔑 = 5"
    and "𝔑NTDom = 𝔉"
    and "𝔑NTCod = 𝔊"
    and "𝔑NTDGDom = 𝔄"
    and "𝔑NTDGCod = 𝔅"
    and "vsv (𝔑NTMap)"
    and "𝒟 (𝔑NTMap) = 𝔄Obj"
    and "a. a  𝔄Obj  𝔑NTMapa : 𝔉ObjMapa 𝔅𝔊ObjMapa"
    and "a b f. f : a 𝔄b 
      𝔑NTMapb A𝔅𝔉ArrMapf = 𝔊ArrMapf A𝔅𝔑NTMapa"
  using assms by (simp add: is_ntsmcfD')


text‹Slicing.›

context is_ntsmcf
begin

interpretation tdghm: is_tdghm 
  α smc_dg 𝔄 smc_dg 𝔅 smcf_dghm 𝔉 smcf_dghm 𝔊 ntsmcf_tdghm 𝔑
  by (rule ntsmcf_is_tdghm)

lemmas_with [unfolded slicing_simps]:
  ntsmcf_NTMap_vsv = tdghm.tdghm_NTMap_vsv
  and ntsmcf_NTMap_vdomain[smc_cs_simps] = tdghm.tdghm_NTMap_vdomain
  and ntsmcf_NTMap_is_arr = tdghm.tdghm_NTMap_is_arr
  and ntsmcf_NTMap_is_arr'[smc_cs_intros]  = tdghm.tdghm_NTMap_is_arr'

sublocale NTMap: vsv 𝔑NTMap
  rewrites "𝒟 (𝔑NTMap) = 𝔄Obj"
  by (rule ntsmcf_NTMap_vsv) (simp add: smc_cs_simps)

lemmas_with [unfolded slicing_simps]:
  ntsmcf_NTMap_app_in_Arr[smc_cs_intros] = tdghm.tdghm_NTMap_app_in_Arr
  and ntsmcf_NTMap_vrange_vifunion = tdghm.tdghm_NTMap_vrange_vifunion
  and ntsmcf_NTMap_vrange = tdghm.tdghm_NTMap_vrange
  and ntsmcf_NTMap_vsubset_Vset = tdghm.tdghm_NTMap_vsubset_Vset
  and ntsmcf_NTMap_in_Vset = tdghm.tdghm_NTMap_in_Vset
  and ntsmcf_is_tdghm_if_ge_Limit = tdghm.tdghm_is_tdghm_if_ge_Limit

end

lemmas [smc_cs_intros] = is_ntsmcf.ntsmcf_NTMap_is_arr'

lemma (in is_ntsmcf) ntsmcf_Comp_commute':
  assumes "f : a 𝔄b" and "g : c 𝔅𝔉ObjMapa"
  shows 
    "𝔑NTMapb A𝔅(𝔉ArrMapf A𝔅g) =
      (𝔊ArrMapf A𝔅𝔑NTMapa) A𝔅g"
  using assms
  by 
    (
      cs_concl cs_shallow
        cs_simp: ntsmcf_Comp_commute semicategory.smc_Comp_assoc[symmetric] 
        cs_intro: smc_cs_intros
    )

lemma (in is_ntsmcf) ntsmcf_Comp_commute'':
  assumes "f : a 𝔄b" and "g : c 𝔅𝔉ObjMapa"
  shows 
    "𝔊ArrMapf A𝔅(𝔑NTMapa A𝔅g) =
      (𝔑NTMapb A𝔅𝔉ArrMapf) A𝔅g"
  using assms
  by 
    (
      cs_concl  
        cs_simp: ntsmcf_Comp_commute semicategory.smc_Comp_assoc[symmetric] 
        cs_intro: smc_cs_intros
    )


text‹Elementary properties.›

lemma ntsmcf_eqI:
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑' : 𝔉' SMCF 𝔊' : 𝔄' ↦↦SMCα𝔅'"
    and "𝔑NTMap = 𝔑'NTMap"
    and "𝔉 = 𝔉'"
    and "𝔊 = 𝔊'"
    and "𝔄 = 𝔄'"
    and "𝔅 = 𝔅'"
  shows "𝔑 = 𝔑'"
proof-
  interpret L: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(1))
  interpret R: is_ntsmcf α 𝔄' 𝔅' 𝔉' 𝔊' 𝔑' by (rule assms(2))
  show ?thesis
  proof(rule vsv_eqI)
    have dom: "𝒟 𝔑 = 5" 
      by (cs_concl cs_shallow cs_simp: smc_cs_simps V_cs_simps)
    show "𝒟 𝔑 = 𝒟 𝔑'" 
      by (cs_concl cs_shallow cs_simp: smc_cs_simps V_cs_simps)
    from assms(4-7) have sup: 
      "𝔑NTDom = 𝔑'NTDom" "𝔑NTCod = 𝔑'NTCod" 
      "𝔑NTDGDom = 𝔑'NTDGDom" "𝔑NTDGCod = 𝔑'NTDGCod" 
      by (simp_all add: smc_cs_simps)
    show "a  𝒟 𝔑  𝔑a = 𝔑'a" for a 
      by (unfold dom, elim_in_numeral, insert assms(3) sup)
        (auto simp: nt_field_simps)
  qed auto
qed

lemma ntsmcf_tdghm_eqI:
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑' : 𝔉' SMCF 𝔊' : 𝔄' ↦↦SMCα𝔅'"
    and "𝔉 = 𝔉'"
    and "𝔊 = 𝔊'"
    and "𝔄 = 𝔄'"
    and "𝔅 = 𝔅'"
    and "ntsmcf_tdghm 𝔑 = ntsmcf_tdghm 𝔑'"
  shows "𝔑 = 𝔑'"
proof(rule ntsmcf_eqI[of α])
  from assms(7) have "ntsmcf_tdghm 𝔑NTMap = ntsmcf_tdghm 𝔑'NTMap" by simp
  then show "𝔑NTMap = 𝔑'NTMap" unfolding slicing_simps by simp_all
  from assms(3-6) show "𝔉 = 𝔉'" "𝔊 = 𝔊'" "𝔄 = 𝔄'" "𝔅 = 𝔅'" by simp_all
qed (simp_all add: assms(1,2))

lemma (in is_ntsmcf) ntsmcf_def:
  "𝔑 = [𝔑NTMap, 𝔑NTDom, 𝔑NTCod, 𝔑NTDGDom, 𝔑NTDGCod]"
proof(rule vsv_eqI)
  have dom_lhs: "𝒟 𝔑 = 5" 
    by (cs_concl cs_shallow cs_simp: smc_cs_simps V_cs_simps)
  have dom_rhs:
    "𝒟 [𝔑NTMap, 𝔑NTDGDom, 𝔑NTDGCod, 𝔑NTDom, 𝔑NTCod] = 5"
    by (simp add: nat_omega_simps)
  then show "𝒟 𝔑 = 𝒟 [𝔑NTMap, 𝔑NTDom, 𝔑NTCod, 𝔑NTDGDom, 𝔑NTDGCod]"
    unfolding dom_lhs dom_rhs by (simp add: nat_omega_simps)
  show "a  𝒟 𝔑 
    𝔑a = [𝔑NTMap, 𝔑NTDom, 𝔑NTCod, 𝔑NTDGDom, 𝔑NTDGCod]a" 
    for a
    by (unfold dom_lhs, elim_in_numeral, unfold nt_field_simps)
      (simp_all add: nat_omega_simps)
qed (auto simp: vsv_axioms)


text‹Size.›

lemma (in is_ntsmcf) ntsmcf_in_Vset: 
  assumes "𝒵 β" and "α  β"
  shows "𝔑  Vset β"
proof-
  interpret β: 𝒵 β by (rule assms(1))
  note [smc_cs_intros] = 
    ntsmcf_NTMap_in_Vset
    NTDom.smcf_in_Vset
    NTCod.smcf_in_Vset
    NTDom.HomDom.smc_in_Vset
    NTDom.HomCod.smc_in_Vset
  from assms(2) show ?thesis
    by (subst ntsmcf_def) 
      (
        cs_concl cs_shallow 
          cs_simp: smc_cs_simps cs_intro: smc_cs_intros V_cs_intros
      )
qed

lemma (in is_ntsmcf) ntsmcf_is_ntsmcf_if_ge_Limit:
  assumes "𝒵 β" and "α  β"
  shows "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCβ𝔅"
proof(intro is_ntsmcfI )
  show "ntsmcf_tdghm 𝔑 :
    smcf_dghm 𝔉 DGHM smcf_dghm 𝔊 : smc_dg 𝔄 ↦↦DGβsmc_dg 𝔅"
    by (rule is_tdghm.tdghm_is_tdghm_if_ge_Limit[OF ntsmcf_is_tdghm assms])
  show "𝔑NTMapb A𝔅𝔉ArrMapf = 𝔊ArrMapf A𝔅𝔑NTMapa"
    if "f : a 𝔄b" for f a b
    by 
      (
        use that in 
          cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros
      )+
qed 
  (
    cs_concl cs_shallow
      cs_simp: smc_cs_simps 
      cs_intro:
        smc_cs_intros
        V_cs_intros
        assms 
        NTDom.smcf_is_semifunctor_if_ge_Limit
        NTCod.smcf_is_semifunctor_if_ge_Limit
   )+

lemma small_all_ntsmcfs[simp]: 
  "small {𝔑. 𝔉 𝔊 𝔄 𝔅. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}"
proof(cases 𝒵 α)
  case True
  from is_ntsmcf.ntsmcf_in_Vset show ?thesis
    by (intro down[of _ Vset (α + ω)]) 
      (auto simp: True 𝒵.𝒵_Limit_αω 𝒵.𝒵_ω_αω 𝒵.intro 𝒵.𝒵_α_αω)
next
  case False
  then have "{𝔑. 𝔉 𝔊 𝔄 𝔅. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅} = {}" by auto
  then show ?thesis by simp
qed

lemma small_ntsmcfs[simp]: "small {𝔑. 𝔉 𝔊. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}"
  by (rule down[of _ set {𝔑. 𝔉 𝔊 𝔄 𝔅. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}])
    auto

lemma small_these_ntcfs[simp]: "small {𝔑. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}"
  by (rule down[of _ set {𝔑. 𝔉 𝔊 𝔄 𝔅. 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅}]) 
    auto


text‹Further elementary results.›

lemma these_ntsmcfs_iff(*not simp*):  
  "𝔑  these_ntsmcfs α 𝔄 𝔅 𝔉 𝔊  𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  by auto



subsection‹Opposite natural transformation of semifunctors›


subsubsection‹Definition and elementary properties›


text‹See section 1.5 in cite"bodo_categories_1970".›

definition op_ntsmcf :: "V  V"
  where "op_ntsmcf 𝔑 =
    [
      𝔑NTMap,
      op_smcf (𝔑NTCod),
      op_smcf (𝔑NTDom),
      op_smc (𝔑NTDGDom),
      op_smc (𝔑NTDGCod)
    ]"


text‹Components.›

lemma op_ntsmcf_components[smc_op_simps]:
  shows "op_ntsmcf 𝔑NTMap = 𝔑NTMap"
    and "op_ntsmcf 𝔑NTDom = op_smcf (𝔑NTCod)"
    and "op_ntsmcf 𝔑NTCod = op_smcf (𝔑NTDom)"
    and "op_ntsmcf 𝔑NTDGDom = op_smc (𝔑NTDGDom)"
    and "op_ntsmcf 𝔑NTDGCod = op_smc (𝔑NTDGCod)"
  unfolding op_ntsmcf_def nt_field_simps by (auto simp: nat_omega_simps)


text‹Slicing.›

lemma op_tdghm_ntsmcf_tdghm[slicing_commute]: 
  "op_tdghm (ntsmcf_tdghm 𝔑) = ntsmcf_tdghm (op_ntsmcf 𝔑)"
proof(rule vsv_eqI)
  have dom_lhs: "𝒟 (op_tdghm (ntsmcf_tdghm 𝔑)) = 5"
    unfolding op_tdghm_def by (auto simp: nat_omega_simps)
  have dom_rhs: "𝒟 (ntsmcf_tdghm (op_ntsmcf 𝔑)) = 5"
    unfolding ntsmcf_tdghm_def by (auto simp: nat_omega_simps)
  show "𝒟 (op_tdghm (ntsmcf_tdghm 𝔑)) = 𝒟 (ntsmcf_tdghm (op_ntsmcf 𝔑))"
    unfolding dom_lhs dom_rhs by simp
  show "a  𝒟 (op_tdghm (ntsmcf_tdghm 𝔑))  
    op_tdghm (ntsmcf_tdghm 𝔑)a = ntsmcf_tdghm (op_ntsmcf 𝔑)a"
    for a
    by
      (
        unfold dom_lhs,
        elim_in_numeral,
        unfold ntsmcf_tdghm_def op_ntsmcf_def op_tdghm_def nt_field_simps
      )
      (auto simp: nat_omega_simps slicing_commute[symmetric])
qed (auto simp: ntsmcf_tdghm_def op_tdghm_def)


subsubsection‹Further properties›

lemma (in is_ntsmcf) is_ntsmcf_op: 
  "op_ntsmcf 𝔑 : op_smcf 𝔊 SMCF op_smcf 𝔉 : op_smc 𝔄 ↦↦SMCαop_smc 𝔅"
proof(rule is_ntsmcfI, unfold smc_op_simps)
  show "vfsequence (op_ntsmcf 𝔑)" by (simp add: op_ntsmcf_def)
  show "vcard (op_ntsmcf 𝔑) = 5" by (simp add: op_ntsmcf_def nat_omega_simps)
  fix f a b assume "f : b 𝔄a"
  with is_ntsmcf_axioms show 
    "𝔑NTMapb Aop_smc 𝔅𝔊ArrMapf =
      𝔉ArrMapf Aop_smc 𝔅𝔑NTMapa"
    by (cs_concl cs_simp: smc_cs_simps smc_op_simps cs_intro: smc_cs_intros)
qed
  (
    insert is_ntsmcf_axioms,
    (
      cs_concl cs_shallow 
        cs_simp: smc_cs_simps slicing_commute[symmetric]
        cs_intro: smc_cs_intros smc_op_intros dg_op_intros slicing_intros
    )+
  )

lemma (in is_ntsmcf) is_ntsmcf_op'[smc_op_intros]: 
  assumes "𝔊' = op_smcf 𝔊"
    and "𝔉' = op_smcf 𝔉"
    and "𝔄' = op_smc 𝔄"
    and "𝔅' = op_smc 𝔅"
  shows "op_ntsmcf 𝔑 : 𝔊' SMCF 𝔉' : 𝔄' ↦↦SMCα𝔅'"
  unfolding assms by (rule is_ntsmcf_op)

lemmas [smc_op_intros] = is_ntsmcf.is_ntsmcf_op'

lemma (in is_ntsmcf) ntsmcf_op_ntsmcf_op_ntsmcf[smc_op_simps]: 
  "op_ntsmcf (op_ntsmcf 𝔑) = 𝔑"
proof(rule ntsmcf_eqI[of α 𝔄 𝔅 𝔉 𝔊 _ 𝔄 𝔅 𝔉 𝔊], unfold smc_op_simps)
  interpret op: 
    is_ntsmcf α op_smc 𝔄 op_smc 𝔅 op_smcf 𝔊 op_smcf 𝔉 op_ntsmcf 𝔑
    by (rule is_ntsmcf_op)
  from op.is_ntsmcf_op show 
    "op_ntsmcf (op_ntsmcf 𝔑) : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    by (simp add: smc_op_simps)
qed (auto simp: smc_cs_intros)

lemmas ntsmcf_op_ntsmcf_op_ntsmcf[smc_op_simps] =
  is_ntsmcf.ntsmcf_op_ntsmcf_op_ntsmcf

lemma eq_op_ntsmcf_iff: 
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑' : 𝔉' SMCF 𝔊' : 𝔄' ↦↦SMCα𝔅'"
  shows "op_ntsmcf 𝔑 = op_ntsmcf 𝔑'  𝔑 = 𝔑'"
proof
  interpret L: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(1))
  interpret R: is_ntsmcf α 𝔄' 𝔅' 𝔉' 𝔊' 𝔑' by (rule assms(2))
  assume prems: "op_ntsmcf 𝔑 = op_ntsmcf 𝔑'"
  show "𝔑 = 𝔑'"
  proof(rule ntsmcf_eqI[OF assms])
    from prems L.ntsmcf_op_ntsmcf_op_ntsmcf R.ntsmcf_op_ntsmcf_op_ntsmcf show 
      "𝔑NTMap = 𝔑'NTMap"
      by metis+
    from prems L.ntsmcf_op_ntsmcf_op_ntsmcf R.ntsmcf_op_ntsmcf_op_ntsmcf 
    have "𝔑NTDom = 𝔑'NTDom" 
      and "𝔑NTCod = 𝔑'NTCod" 
      and "𝔑NTDGDom = 𝔑'NTDGDom" 
      and "𝔑NTDGCod = 𝔑'NTDGCod" 
      by metis+
    then show "𝔉 = 𝔉'" "𝔊 = 𝔊'" "𝔄 = 𝔄'" "𝔅 = 𝔅'" by (auto simp: smc_cs_simps)
  qed
qed auto



subsection‹Vertical composition of natural transformations›


subsubsection‹Definition and elementary properties›


text‹See Chapter II-4 in cite"mac_lane_categories_2010".›

definition ntsmcf_vcomp :: "V  V  V" (infixl NTSMCF 55)
  where "ntsmcf_vcomp 𝔐 𝔑 = 
    [
      (λa𝔑NTDGDomObj. (𝔐NTMapa) A𝔑NTDGCod(𝔑NTMapa)),
      𝔑NTDom,
      𝔐NTCod,
      𝔑NTDGDom,
      𝔐NTDGCod
    ]"


text‹Components.›

lemma ntsmcf_vcomp_components:
  shows
    "(𝔐 NTSMCF 𝔑)NTMap =
      (λa𝔑NTDGDomObj. (𝔐NTMapa) A𝔑NTDGCod(𝔑NTMapa))"
    and [dg_shared_cs_simps, smc_cs_simps]: "(𝔐 NTSMCF 𝔑)NTDom = 𝔑NTDom" 
    and [dg_shared_cs_simps, smc_cs_simps]: "(𝔐 NTSMCF 𝔑)NTCod = 𝔐NTCod"
    and [dg_shared_cs_simps, smc_cs_simps]: 
      "(𝔐 NTSMCF 𝔑)NTDGDom = 𝔑NTDGDom"
    and [dg_shared_cs_simps, smc_cs_simps]: 
      "(𝔐 NTSMCF 𝔑)NTDGCod = 𝔐NTDGCod"
  unfolding nt_field_simps ntsmcf_vcomp_def by (simp_all add: nat_omega_simps)


subsubsection‹Natural transformation map›

lemma ntsmcf_vcomp_NTMap_vsv[dg_shared_cs_intros, smc_cs_intros]: 
  "vsv ((𝔐 NTSMCF 𝔑)NTMap)"
  unfolding ntsmcf_vcomp_components by simp

lemma ntsmcf_vcomp_NTMap_vdomain[smc_cs_simps]:
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "𝒟 ((𝔐 NTSMCF 𝔑)NTMap) = 𝔄Obj"
proof-
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 using assms by auto
  show ?thesis unfolding ntsmcf_vcomp_components by (simp add: smc_cs_simps)
qed

lemma ntsmcf_vcomp_NTMap_app[smc_cs_simps]:
  assumes "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "a  𝔄Obj" 
  shows "(𝔐 NTSMCF 𝔑)NTMapa = 𝔐NTMapa A𝔅𝔑NTMapa"
proof-
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 using assms by auto
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 using assms by auto
  from assms show ?thesis 
    unfolding ntsmcf_vcomp_components by (simp add: smc_cs_simps)
qed

lemma ntsmcf_vcomp_NTMap_vrange:
  assumes "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows " ((𝔐 NTSMCF 𝔑)NTMap)  𝔅Arr"
  unfolding ntsmcf_vcomp_components
proof(rule vrange_VLambda_vsubset)
  fix x assume prems: "x  𝔑NTDGDomObj"
  from prems assms show "𝔐NTMapx A𝔑NTDGCod𝔑NTMapx  𝔅Arr"
    by (cs_prems cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
      (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
qed


subsubsection‹Further properties›

lemma ntsmcf_vcomp_composable_commute[smc_cs_simps]:
  ―‹See Chapter II-4 in \cite{mac_lane_categories_2010}).›
  assumes "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "f : a 𝔄b"
  shows 
    "(𝔐NTMapb A𝔅𝔑NTMapb) A𝔅𝔉ArrMapf = 
      ArrMapf A𝔅(𝔐NTMapa A𝔅𝔑NTMapa)"
    (is (?MC A𝔅?NC) A𝔅?R = ?T A𝔅(?MD A𝔅?ND))
proof-
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 by (rule assms(1)) 
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  from assms show ?thesis
    by (intro 𝔐.NTDom.HomCod.smc_pattern_rectangle_left)
      (cs_concl cs_intro: smc_cs_intros cs_simp: 𝔑.ntsmcf_Comp_commute)
qed 

lemma ntsmcf_vcomp_is_ntsmcf[smc_cs_intros]:
  ―‹See Chapter II-4 in \cite{mac_lane_categories_2010}.›
  assumes "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "𝔐 NTSMCF 𝔑 : 𝔉 SMCF  : 𝔄 ↦↦SMCα𝔅"
proof-
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  show ?thesis 
  proof(intro is_ntsmcfI')
    show "vfsequence (𝔐 NTSMCF 𝔑)" by (simp add: ntsmcf_vcomp_def)
    show "vcard (𝔐 NTSMCF 𝔑) = 5"
      by (auto simp: nat_omega_simps ntsmcf_vcomp_def)
    show "vsv ((𝔐 NTSMCF 𝔑)NTMap)"
      unfolding ntsmcf_vcomp_components by simp
    from assms show "(𝔐 NTSMCF 𝔑)NTMapa : 𝔉ObjMapa 𝔅ObjMapa"
      if "a  𝔄Obj" for a
      by 
        (
          use that in 
            cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros
        )
    fix f a b assume "f : a 𝔄b"
    with assms show 
      "(𝔐 NTSMCF 𝔑)NTMapb A𝔅𝔉ArrMapf =
        ArrMapf A𝔅(𝔐 NTSMCF 𝔑)NTMapa"
      by 
        (
          cs_concl  
            cs_simp: smc_cs_simps is_ntsmcf.ntsmcf_Comp_commute' 
            cs_intro: smc_cs_intros
        )
  qed (use assms in auto simp: smc_cs_simps ntsmcf_vcomp_NTMap_vrange)
qed

lemma ntsmcf_vcomp_assoc[smc_cs_simps]: 
  ―‹See Chapter II-4 in \cite{mac_lane_categories_2010}.›
  assumes "𝔏 :  SMCF 𝔎 : 𝔄 ↦↦SMCα𝔅" 
    and "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "(𝔏 NTSMCF 𝔐) NTSMCF 𝔑 = 𝔏 NTSMCF (𝔐 NTSMCF 𝔑)"
proof-
  interpret 𝔏: is_ntsmcf α 𝔄 𝔅  𝔎 𝔏 by (rule assms(1))
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 by (rule assms(2))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(3))
  show ?thesis
  proof(rule ntsmcf_eqI[of α])
    show "((𝔏 NTSMCF 𝔐) NTSMCF 𝔑)NTMap = (𝔏 NTSMCF (𝔐 NTSMCF 𝔑))NTMap"
    proof(rule vsv_eqI)
      fix a assume "a  𝒟 ((𝔏 NTSMCF 𝔐 NTSMCF 𝔑)NTMap)"
      then have "a  𝔄Obj" 
        unfolding ntsmcf_vcomp_components by (simp add: smc_cs_simps)
      with assms show 
        "((𝔏 NTSMCF 𝔐) NTSMCF 𝔑)NTMapa =
          (𝔏 NTSMCF (𝔐 NTSMCF 𝔑))NTMapa"
        by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
    qed (simp_all add: ntsmcf_vcomp_components)
  qed (auto intro: smc_cs_intros)
qed


subsubsection‹
Opposite of the vertical composition of natural transformations
of semifunctors
›

lemma op_ntsmcf_ntsmcf_vcomp[smc_op_simps]: 
  assumes "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "op_ntsmcf (𝔐 NTSMCF 𝔑) = op_ntsmcf 𝔑 NTSMCF op_ntsmcf 𝔐"
proof-
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 using assms(1) by auto
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 using assms(2) by auto
  show ?thesis
  proof(rule ntsmcf_eqI[of α]; (intro symmetric)?)
    show "op_ntsmcf (𝔐 NTSMCF 𝔑)NTMap = 
      (op_ntsmcf 𝔑 NTSMCF op_ntsmcf 𝔐)NTMap"
    proof(rule vsv_eqI)
      fix a assume "a  𝒟 (op_ntsmcf (𝔐 NTSMCF 𝔑)NTMap)"
      then have a: "a  𝔄Obj"
        unfolding smc_op_simps ntsmcf_vcomp_NTMap_vdomain[OF assms(2)] by simp
      with 
        𝔐.NTDom.HomCod.op_smc_Comp 
        𝔐.ntsmcf_NTMap_is_arr[OF a]
        𝔑.ntsmcf_NTMap_is_arr[OF a] 
      show "op_ntsmcf (𝔐 NTSMCF 𝔑)NTMapa =
        (op_ntsmcf 𝔑 NTSMCF op_ntsmcf 𝔐)NTMapa"
        unfolding smc_op_simps ntsmcf_vcomp_components 
        by (simp add: smc_cs_simps)
    qed (simp_all add: smc_op_simps smc_cs_simps ntsmcf_vcomp_components(1))
  qed (auto intro: smc_cs_intros smc_op_intros)
qed



subsection‹Horizontal composition of natural transformations›


subsubsection‹Definition and elementary properties›


text‹See Chapter II-5 in cite"mac_lane_categories_2010".›

definition ntsmcf_hcomp :: "V  V  V" (infixl NTSMCF 55)
  where "ntsmcf_hcomp 𝔐 𝔑 =
    [
      (
        λa𝔑NTDGDomObj.
          (
            𝔐NTCodArrMap𝔑NTMapa A𝔐NTDGCod𝔐NTMap𝔑NTDomObjMapa
          )
      ),
      (𝔐NTDom SMCF 𝔑NTDom),
      (𝔐NTCod SMCF 𝔑NTCod),
      (𝔑NTDGDom),
      (𝔐NTDGCod)
    ]"


text‹Components.›                                            

lemma ntsmcf_hcomp_components:
  shows 
    "(𝔐 NTSMCF 𝔑)NTMap = 
      (
        λa𝔑NTDGDomObj.
          (
            𝔐NTCodArrMap𝔑NTMapa A𝔐NTDGCod𝔐NTMap𝔑NTDomObjMapa
          )
      )"
    and [dg_shared_cs_simps, smc_cs_simps]:
      "(𝔐 NTSMCF 𝔑)NTDom = 𝔐NTDom SMCF 𝔑NTDom" 
    and [dg_shared_cs_simps, smc_cs_simps]:
      "(𝔐 NTSMCF 𝔑)NTCod = 𝔐NTCod SMCF 𝔑NTCod"
    and [dg_shared_cs_simps, smc_cs_simps]: 
      "(𝔐 NTSMCF 𝔑)NTDGDom = 𝔑NTDGDom"
    and [dg_shared_cs_simps, smc_cs_simps]:
      "(𝔐 NTSMCF 𝔑)NTDGCod = 𝔐NTDGCod"
  unfolding nt_field_simps ntsmcf_hcomp_def by (auto simp: nat_omega_simps)


subsubsection‹Natural transformation map›

lemma ntsmcf_hcomp_NTMap_vsv[smc_cs_intros]: "vsv ((𝔐 NTSMCF 𝔑)NTMap)"
  unfolding ntsmcf_hcomp_components by auto

lemma ntsmcf_hcomp_NTMap_vdomain[smc_cs_simps]: 
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "𝒟 ((𝔐 NTSMCF 𝔑)NTMap) = 𝔄Obj"
proof-
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(1))
  show ?thesis unfolding ntsmcf_hcomp_components by (simp add: smc_cs_simps)
qed

lemma ntsmcf_hcomp_NTMap_app[smc_cs_simps]:
  assumes "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "a  𝔄Obj" 
  shows "(𝔐 NTSMCF 𝔑)NTMapa = 
    𝔊'ArrMap𝔑NTMapa A𝔐NTMap𝔉ObjMapa"
proof-
  interpret 𝔐: is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  from assms(3) show ?thesis 
    unfolding ntsmcf_hcomp_components by (simp add: smc_cs_simps)
qed

lemma ntsmcf_hcomp_NTMap_vrange:
  assumes "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows " ((𝔐 NTSMCF 𝔑)NTMap)  Arr"
proof
  interpret 𝔐: is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  fix f assume "f   ((𝔐 NTSMCF 𝔑)NTMap)"
  with ntsmcf_hcomp_NTMap_vdomain obtain a 
    where a: "a  𝔄Obj" and f_def: "f = (𝔐 NTSMCF 𝔑)NTMapa"
    unfolding ntsmcf_hcomp_components by (force simp: smc_cs_simps)
  have 𝔉a: "𝔉ObjMapa  𝔅Obj" 
    by (simp add: 𝔑.NTDom.smcf_ObjMap_app_in_HomCod_Obj a)
  from 𝔑.ntsmcf_NTMap_is_arr[OF a] have "𝔊'ArrMap𝔑NTMapa :
    𝔊'ObjMap𝔉ObjMapa 𝔊'ObjMap𝔊ObjMapa"
    by (force intro: smc_cs_intros)
  then have "𝔊'ArrMap𝔑NTMapa A𝔐NTMap𝔉ObjMapa  Arr"
    by 
      (
        meson 
          𝔐.ntsmcf_NTMap_is_arr[OF 𝔉a] 
          𝔐.NTDom.HomCod.smc_is_arrE 
          𝔐.NTDom.HomCod.smc_Comp_is_arr
      )
  with a show "f  Arr" 
    unfolding f_def ntsmcf_hcomp_components by (simp add: smc_cs_simps)
qed


subsubsection‹Further properties›

lemma ntsmcf_hcomp_composable_commute:
  ―‹See Chapter II-5 in \cite{mac_lane_categories_2010}.›
  assumes "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "f : a 𝔄b" 
  shows 
    "(𝔐 NTSMCF 𝔑)NTMapb A(𝔉' SMCF 𝔉)ArrMapf = 
      (𝔊' SMCF 𝔊)ArrMapf A(𝔐 NTSMCF 𝔑)NTMapa"
proof-
  interpret 𝔐: is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  from assms(3) have [simp]: "b  𝔄Obj" and a: "a  𝔄Obj" by auto
  from 𝔐.is_ntsmcf_axioms 𝔑.is_ntsmcf_axioms have 𝔐𝔑b: 
    "(𝔐 NTSMCF 𝔑)NTMapb =
      (𝔊'ArrMap𝔑NTMapb) A(𝔐NTMap𝔉ObjMapb)"
    by (auto simp: smc_cs_simps)
  let ?𝔊'𝔉f = 𝔊'ArrMap𝔉ArrMapf
  from a 𝔐.is_ntsmcf_axioms 𝔑.is_ntsmcf_axioms have 𝔐𝔑a: 
    "(𝔐 NTSMCF 𝔑)NTMapa =
      𝔊'ArrMap𝔑NTMapa A𝔐NTMap𝔉ObjMapa"
    by (cs_concl cs_shallow cs_simp: smc_cs_simps)+
  note 𝔐.NTCod.smcf_ArrMap_Comp[smc_cs_simps del]
  from assms show ?thesis
    unfolding 𝔐𝔑b 𝔐𝔑a 
    by (intro 𝔐.NTDom.HomCod.smc_pattern_rectangle_left)
      (
        cs_concl  
          cs_simp: smc_cs_simps is_semifunctor.smcf_ArrMap_Comp[symmetric] 
          cs_intro: smc_cs_intros
      )+
qed

lemma ntsmcf_hcomp_is_ntsmcf:
  ―‹See Chapter II-5 in \cite{mac_lane_categories_2010}.›
  assumes "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "𝔐 NTSMCF 𝔑 : 𝔉' SMCF 𝔉 SMCF 𝔊' SMCF 𝔊 : 𝔄 ↦↦SMCα"
proof-
  interpret 𝔐: is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  show ?thesis
  proof(intro is_ntsmcfI', unfold ntsmcf_hcomp_components(3,4)) 
    show "vfsequence (𝔐 NTSMCF 𝔑)" unfolding ntsmcf_hcomp_def by auto
    show "vcard (𝔐 NTSMCF 𝔑) = 5"
      unfolding ntsmcf_hcomp_def by (simp add: nat_omega_simps)
    from assms show "(𝔐 NTSMCF 𝔑)NTMapa : 
      (𝔉' SMCF 𝔉)ObjMapa (𝔊' SMCF 𝔊)ObjMapa"
      if "a  𝔄Obj" for a
      by 
        (
          use that in 
            cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros
        )
    fix f a b assume "f : a 𝔄b"
    with ntsmcf_hcomp_composable_commute[OF assms] 
    show "(𝔐 NTSMCF 𝔑)NTMapb A(𝔉' SMCF 𝔉)ArrMapf = 
      (𝔊' SMCF 𝔊)ArrMapf A(𝔐 NTSMCF 𝔑)NTMapa"
      by auto
  qed (auto simp: ntsmcf_hcomp_components(1) smc_cs_simps intro: smc_cs_intros)
qed

lemma ntsmcf_hcomp_is_ntsmcf'[smc_cs_intros]:
  assumes "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "𝔖 = 𝔉' SMCF 𝔉"
    and "𝔖' = 𝔊' SMCF 𝔊"
  shows "𝔐 NTSMCF 𝔑 : 𝔖 SMCF 𝔖' : 𝔄 ↦↦SMCα"
  using assms(1,2) unfolding assms(3,4) by (rule ntsmcf_hcomp_is_ntsmcf)

lemma ntsmcf_hcomp_assoc[smc_cs_simps]: 
  ―‹See Chapter II-5 in \cite{mac_lane_categories_2010}.›
  assumes "𝔏 : 𝔉'' SMCF 𝔊'' :  ↦↦SMCα𝔇" 
    and "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "(𝔏 NTSMCF 𝔐) NTSMCF 𝔑 = 𝔏 NTSMCF (𝔐 NTSMCF 𝔑)"
proof-
  interpret 𝔏: is_ntsmcf α  𝔇 𝔉'' 𝔊'' 𝔏 by (rule assms(1))
  interpret 𝔐: is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔐  by (rule assms(2))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(3))
  interpret 𝔏𝔐: is_ntsmcf α 𝔅 𝔇 𝔉'' SMCF 𝔉' 𝔊'' SMCF 𝔊' 𝔏 NTSMCF 𝔐 
    by (auto intro: smc_cs_intros)
  interpret 𝔐𝔑: is_ntsmcf α 𝔄  𝔉' SMCF 𝔉 𝔊' SMCF 𝔊 𝔐 NTSMCF 𝔑 
    by (auto intro: smc_cs_intros)
  note smcf_axioms =
    𝔏.NTDom.is_semifunctor_axioms 
    𝔏.NTCod.is_semifunctor_axioms 
    𝔐.NTDom.is_semifunctor_axioms 
    𝔐.NTCod.is_semifunctor_axioms 
    𝔑.NTDom.is_semifunctor_axioms 
    𝔑.NTCod.is_semifunctor_axioms 
  show ?thesis
  proof(rule ntsmcf_eqI)
    from assms show 
      "𝔏 NTSMCF 𝔐 NTSMCF 𝔑 :
        (𝔉'' SMCF 𝔉') SMCF 𝔉 SMCF (𝔊'' SMCF 𝔊') SMCF 𝔊 :
        𝔄 ↦↦SMCα𝔇"
      by (auto intro: smc_cs_intros)
    from 𝔏𝔐.is_ntsmcf_axioms 𝔑.is_ntsmcf_axioms have dom_lhs:
      "𝒟 ((𝔏 NTSMCF 𝔐 NTSMCF 𝔑)NTMap) = 𝔄Obj"
      by (simp add: smc_cs_simps)
    from 𝔐𝔑.is_ntsmcf_axioms 𝔏.is_ntsmcf_axioms have dom_rhs:  
      "𝒟 ((𝔏 NTSMCF (𝔐 NTSMCF 𝔑))NTMap) = 𝔄Obj"
      by (simp add: smc_cs_simps)
    show "(𝔏 NTSMCF 𝔐 NTSMCF 𝔑)NTMap = (𝔏 NTSMCF (𝔐 NTSMCF 𝔑))NTMap"
    proof(rule vsv_eqI, unfold dom_lhs dom_rhs)
      fix a assume "a  𝔄Obj"
      with assms show
        "(𝔏 NTSMCF 𝔐 NTSMCF 𝔑)NTMapa =
          (𝔏 NTSMCF (𝔐 NTSMCF 𝔑))NTMapa"
        by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
    qed (simp_all add: ntsmcf_hcomp_components)
  qed 
    (
      insert smcf_axioms, 
      auto simp: smcf_comp_assoc intro!: smc_cs_intros
    )
qed


subsubsection‹Opposite of the horizontal composition of the 
natural transformation of semifunctors›

lemma op_ntsmcf_ntsmcf_hcomp[smc_op_simps]: 
  assumes "𝔐 : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows "op_ntsmcf (𝔐 NTSMCF 𝔑) = op_ntsmcf 𝔐 NTSMCF op_ntsmcf 𝔑"
proof-
  interpret 𝔐: is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  have op_𝔐: "op_ntsmcf 𝔐 :
    op_smcf 𝔊' SMCF op_smcf 𝔉' : op_smc 𝔅 ↦↦SMCαop_smc "
    and op_𝔑: "op_ntsmcf 𝔑 :
    op_smcf 𝔊 SMCF op_smcf 𝔉 : op_smc 𝔄 ↦↦SMCαop_smc 𝔅" 
    by 
      (
        cs_concl cs_shallow 
          cs_simp: smc_op_simps cs_intro: smc_cs_intros smc_op_intros
      )
  show ?thesis
  proof(rule sym, rule ntsmcf_eqI, unfold smc_op_simps slicing_simps)
    show 
      "op_ntsmcf 𝔐 NTSMCF op_ntsmcf 𝔑 :
        op_smcf 𝔊' SMCF op_smcf 𝔊 SMCF op_smcf 𝔉' SMCF op_smcf 𝔉 :
        op_smc 𝔄 ↦↦SMCαop_smc "
      by 
        (
          cs_concl cs_shallow 
            cs_simp: smc_op_simps cs_intro: smc_cs_intros smc_op_intros
        )
    show "op_ntsmcf (𝔐 NTSMCF 𝔑) :
      op_smcf 𝔊' SMCF op_smcf 𝔊 SMCF op_smcf 𝔉' SMCF op_smcf 𝔉 :
      op_smc 𝔄 ↦↦SMCαop_smc "
      by 
        (
          cs_concl cs_shallow 
            cs_simp: smc_op_simps cs_intro: smc_cs_intros smc_op_intros
        )
    show "(op_ntsmcf 𝔐 NTSMCF op_ntsmcf 𝔑)NTMap = (𝔐 NTSMCF 𝔑)NTMap"
    proof
      (
        rule vsv_eqI, 
        unfold 
          ntsmcf_hcomp_NTMap_vdomain[OF assms(2)]
          ntsmcf_hcomp_NTMap_vdomain[OF op_𝔑]
          smc_op_simps
      )
      fix a assume "a  𝔄Obj"
      with assms show 
        "(op_ntsmcf 𝔐 NTSMCF op_ntsmcf 𝔑)NTMapa = (𝔐 NTSMCF 𝔑)NTMapa"
        by 
          (
            cs_concl cs_shallow
              cs_simp: smc_cs_simps smc_op_simps 
              cs_intro: smc_cs_intros smc_op_intros
          )
    qed (auto simp: ntsmcf_hcomp_components)
  qed simp_all
qed 



subsection‹Interchange law›

lemma ntsmcf_comp_interchange_law:
  ―‹See Chapter II-5 in \cite{mac_lane_categories_2010}.›
  assumes "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "𝔐' : 𝔊' SMCF ℌ' : 𝔅 ↦↦SMCα"
    and "𝔑' : 𝔉' SMCF 𝔊' : 𝔅 ↦↦SMCα"
  shows 
    "((𝔐' NTSMCF 𝔑') NTSMCF (𝔐 NTSMCF 𝔑)) =
      (𝔐' NTSMCF 𝔐) NTSMCF (𝔑' NTSMCF 𝔑)"
proof-
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  interpret 𝔐': is_ntsmcf α 𝔅  𝔊' ℌ' 𝔐' by (rule assms(3))
  interpret 𝔑': is_ntsmcf α 𝔅  𝔉' 𝔊' 𝔑' by (rule assms(4))
  interpret 𝔑'𝔑: 
    is_ntsmcf α 𝔄  𝔉' SMCF 𝔉 𝔊' SMCF 𝔊 𝔑' NTSMCF 𝔑 
    by (auto intro: smc_cs_intros)
  interpret 𝔐𝔑: is_ntsmcf α 𝔄 𝔅 𝔉  𝔐 NTSMCF 𝔑 
    by (auto intro: smc_cs_intros)
  show ?thesis
  proof(rule ntsmcf_eqI[of α])
    show 
      "(𝔐' NTSMCF 𝔑' NTSMCF (𝔐 NTSMCF 𝔑))NTMap =
        (𝔐' NTSMCF 𝔐 NTSMCF (𝔑' NTSMCF 𝔑))NTMap"
    proof
      (
        rule vsv_eqI,
        unfold 
          ntsmcf_vcomp_NTMap_vdomain[OF 𝔑'𝔑.is_ntsmcf_axioms]
          ntsmcf_hcomp_NTMap_vdomain[OF 𝔐𝔑.is_ntsmcf_axioms]
      )
      fix a assume "a  𝔄Obj"
      with assms show
        "(𝔐' NTSMCF 𝔑' NTSMCF (𝔐 NTSMCF 𝔑))NTMapa =
          ((𝔐' NTSMCF 𝔐) NTSMCF (𝔑' NTSMCF 𝔑))NTMapa"
        by
          (
            cs_concl 
              cs_simp: smc_cs_simps is_ntsmcf.ntsmcf_Comp_commute' 
              cs_intro: smc_cs_intros
          )
    qed (auto intro: smc_cs_intros)
  qed (auto intro: smc_cs_intros)
qed



subsection‹
Composition of a natural transformation of semifunctors and a semifunctor
›


subsubsection‹Definition and elementary properties›

abbreviation (input) ntsmcf_smcf_comp :: "V  V  V" (infixl "NTSMCF-SMCF" 55)
  where "ntsmcf_smcf_comp  tdghm_dghm_comp"


text‹Slicing.›

lemma ntsmcf_tdghm_ntsmcf_smcf_comp[slicing_commute]: 
  "ntsmcf_tdghm 𝔑 TDGHM-DGHM smcf_dghm  = ntsmcf_tdghm (𝔑 NTSMCF-SMCF )"
  unfolding 
    tdghm_dghm_comp_def 
    dghm_comp_def 
    ntsmcf_tdghm_def 
    smcf_dghm_def 
    smc_dg_def
    dg_field_simps
    dghm_field_simps 
    nt_field_simps 
  by (simp add: nat_omega_simps) (*slow*)


subsubsection‹Natural transformation map›

mk_VLambda (in is_semifunctor) 
  tdghm_dghm_comp_components(1)[where=𝔉, unfolded smcf_HomDom]
  |vdomain ntsmcf_smcf_comp_NTMap_vdomain[smc_cs_simps]|
  |app ntsmcf_smcf_comp_NTMap_app[smc_cs_simps]|

lemmas [smc_cs_simps] = 
  is_semifunctor.ntsmcf_smcf_comp_NTMap_vdomain
  is_semifunctor.ntsmcf_smcf_comp_NTMap_app

lemma ntsmcf_smcf_comp_NTMap_vrange: 
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔅 ↦↦SMCα" and " : 𝔄 ↦↦SMCα𝔅"
  shows " ((𝔑 NTSMCF-SMCF )NTMap)  Arr"
proof-
  interpret 𝔑: is_ntsmcf α 𝔅  𝔉 𝔊 𝔑 by (rule assms(1))
  interpret: is_semifunctor α 𝔄 𝔅  by (rule assms(2))
  show ?thesis 
    unfolding tdghm_dghm_comp_components 
    by (auto simp: smc_cs_simps intro: smc_cs_intros)
qed


subsubsection‹
Opposite of the composition of a natural transformation of 
semifunctors and a semifunctor
›

lemma op_ntsmcf_ntsmcf_smcf_comp[smc_op_simps]: 
  "op_ntsmcf (𝔑 NTSMCF-SMCF ) = op_ntsmcf 𝔑 NTSMCF-SMCF op_smcf "
  unfolding 
    tdghm_dghm_comp_def 
    dghm_comp_def 
    op_ntsmcf_def 
    op_smcf_def 
    op_smc_def
    dg_field_simps
    dghm_field_simps
    nt_field_simps
  by (simp add: nat_omega_simps) (*slow*)


subsubsection‹
Composition of a natural transformation of semifunctors and a 
semifunctors is a natural transformation of semifunctors
›

lemma ntsmcf_smcf_comp_is_ntsmcf[intro]:
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔅 ↦↦SMCα" and " : 𝔄 ↦↦SMCα𝔅"
  shows "𝔑 NTSMCF-SMCF  : 𝔉 SMCF  SMCF 𝔊 SMCF  : 𝔄 ↦↦SMCα"
proof-
  interpret 𝔑: is_ntsmcf α 𝔅  𝔉 𝔊 𝔑 by (rule assms(1))
  interpret: is_semifunctor α 𝔄 𝔅  by (rule assms(2))
  show ?thesis
  proof(rule is_ntsmcfI)
    show "vfsequence (𝔑 NTSMCF-SMCF )"
      unfolding tdghm_dghm_comp_def by (simp add: nat_omega_simps)
    from assms show "𝔉 SMCF  : 𝔄 ↦↦SMCα"
      by (cs_concl cs_intro: smc_cs_intros)
    from assms show "𝔊 SMCF  : 𝔄 ↦↦SMCα" 
      by (cs_concl cs_intro: smc_cs_intros)
    show "vcard (𝔑 NTSMCF-SMCF ) = 5"
      unfolding tdghm_dghm_comp_def by (simp add: nat_omega_simps)
    from assms show 
      "ntsmcf_tdghm (𝔑 NTSMCF-SMCF ) :
        smcf_dghm (𝔉 SMCF ) DGHM smcf_dghm (𝔊 SMCF ) :
        smc_dg 𝔄 ↦↦DGαsmc_dg "
      by 
        (
          cs_concl 
            cs_simp: slicing_commute[symmetric] 
            cs_intro: slicing_intros dg_cs_intros
        )
    show 
      "(𝔑 NTSMCF-SMCF )NTMapb A(𝔉 SMCF )ArrMapf =
        (𝔊 SMCF )ArrMapf A(𝔑 NTSMCF-SMCF )NTMapa"
      if "f : a 𝔄b" for a b f
      using that by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  qed (auto simp: smc_cs_simps)
qed

lemma ntsmcf_smcf_comp_is_semifunctor'[smc_cs_intros]:
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔅 ↦↦SMCα" 
    and " : 𝔄 ↦↦SMCα𝔅"
    and "𝔉' = 𝔉 SMCF "
    and "𝔊' = 𝔊 SMCF "
  shows "𝔑 NTSMCF-SMCF  : 𝔉' SMCF 𝔊' : 𝔄 ↦↦SMCα"
  using assms(1,2) unfolding assms(3,4) ..


subsubsection‹Further properties›

lemma ntsmcf_smcf_comp_ntsmcf_smcf_comp_assoc:
  assumes "𝔑 :  SMCF ℌ' :  ↦↦SMCα𝔇" 
    and "𝔊 : 𝔅 ↦↦SMCα" 
    and "𝔉 : 𝔄 ↦↦SMCα𝔅"
  shows "(𝔑 NTSMCF-SMCF 𝔊) NTSMCF-SMCF 𝔉 = 𝔑 NTSMCF-SMCF (𝔊 SMCF 𝔉)"
proof-
  interpret 𝔑: is_ntsmcf α  𝔇  ℌ' 𝔑 by (rule assms(1))
  interpret 𝔊: is_semifunctor α 𝔅  𝔊 by (rule assms(2))
  interpret 𝔉: is_semifunctor α 𝔄 𝔅 𝔉 by (rule assms(3))
  show ?thesis  
  proof(rule ntsmcf_tdghm_eqI)
    from assms show 
      "(𝔑 NTSMCF-SMCF 𝔊) NTSMCF-SMCF 𝔉 :
         SMCF 𝔊 SMCF 𝔉 SMCF ℌ' SMCF 𝔊 SMCF 𝔉 :
        𝔄 ↦↦SMCα𝔇"
      by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
    show "𝔑 NTSMCF-SMCF (𝔊 SMCF 𝔉) :
       SMCF 𝔊 SMCF 𝔉 SMCF ℌ' SMCF 𝔊 SMCF 𝔉 :
      𝔄 ↦↦SMCα𝔇"
      by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
    from assms show 
      "ntsmcf_tdghm ((𝔑 NTSMCF-SMCF 𝔊) NTSMCF-SMCF 𝔉) =
        ntsmcf_tdghm (𝔑 NTSMCF-SMCF (𝔊 SMCF 𝔉))"
      by 
        (
          cs_concl 
            cs_simp: slicing_commute[symmetric] 
            cs_intro: slicing_intros tdghm_dghm_comp_tdghm_dghm_comp_assoc
        )
  qed simp_all
qed

lemma (in is_ntsmcf) ntsmcf_ntsmcf_smcf_comp_smcf_id[smc_cs_simps]:
  "𝔑 NTSMCF-SMCF smcf_id 𝔄 = 𝔑"
proof(rule ntsmcf_tdghm_eqI)
  show "𝔑 NTSMCF-SMCF smcf_id 𝔄 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  show "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  show "ntsmcf_tdghm (𝔑 NTSMCF-SMCF smcf_id 𝔄) = ntsmcf_tdghm 𝔑"
    by 
      (
        cs_concl cs_shallow
          cs_simp: slicing_simps slicing_commute[symmetric] 
          cs_intro: smc_cs_intros slicing_intros dg_cs_simps
      )
qed simp_all

lemmas [smc_cs_simps] = is_ntsmcf.ntsmcf_ntsmcf_smcf_comp_smcf_id

lemma ntsmcf_vcomp_ntsmcf_smcf_comp[smc_cs_simps]:
  assumes "𝔎 : 𝔄 ↦↦SMCα𝔅"
    and "𝔐 : 𝔊 SMCF  : 𝔅 ↦↦SMCα"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔅 ↦↦SMCα"
  shows 
    "(𝔐 NTSMCF-SMCF 𝔎) NTSMCF (𝔑 NTSMCF-SMCF 𝔎) = 
      (𝔐 NTSMCF 𝔑) NTSMCF-SMCF 𝔎"
proof(rule ntsmcf_eqI)
  from assms show "(𝔐 NTSMCF 𝔑) NTSMCF-SMCF 𝔎 : 
    𝔉 SMCF 𝔎 SMCF  SMCF 𝔎 : 𝔄 ↦↦SMCα"
    by (cs_concl cs_shallow cs_intro: smc_cs_intros)
  from assms show "𝔐 NTSMCF-SMCF 𝔎 NTSMCF (𝔑 NTSMCF-SMCF 𝔎) : 
    𝔉 SMCF 𝔎 SMCF  SMCF 𝔎 : 𝔄 ↦↦SMCα"
    by (cs_concl cs_shallow cs_intro: smc_cs_intros)
  from assms have dom_lhs: 
    "𝒟 ((𝔐 NTSMCF-SMCF 𝔎 NTSMCF (𝔑 NTSMCF-SMCF 𝔎))NTMap) = 𝔄Obj"
    by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  from assms have dom_rhs: "𝒟 ((𝔐 NTSMCF 𝔑 NTSMCF-SMCF 𝔎)NTMap) = 𝔄Obj"
    by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  show 
    "(𝔐 NTSMCF-SMCF 𝔎 NTSMCF (𝔑 NTSMCF-SMCF 𝔎))NTMap = 
      (𝔐 NTSMCF 𝔑 NTSMCF-SMCF 𝔎)NTMap"
  proof(rule vsv_eqI, unfold dom_lhs dom_rhs)
    fix a assume "a  𝔄Obj"
    with assms show 
      "(𝔐 NTSMCF-SMCF 𝔎 NTSMCF (𝔑 NTSMCF-SMCF 𝔎))NTMapa =
        (𝔐 NTSMCF 𝔑 NTSMCF-SMCF 𝔎)NTMapa"
      by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  qed (cs_concl cs_shallow cs_intro: smc_cs_intros)+
qed simp_all



subsection‹
Composition of a semifunctor and a natural transformation of semifunctors
›


subsubsection‹Definition and elementary properties›

abbreviation (input) smcf_ntsmcf_comp :: "V  V  V" (infixl "SMCF-NTSMCF" 55)
  where "smcf_ntsmcf_comp  dghm_tdghm_comp"


text‹Slicing.›

lemma ntsmcf_tdghm_smcf_ntsmcf_comp[slicing_commute]: 
  "smcf_dghm  DGHM-TDGHM ntsmcf_tdghm 𝔑 = ntsmcf_tdghm ( SMCF-NTSMCF 𝔑)"
  unfolding 
    dghm_tdghm_comp_def 
    dghm_comp_def 
    ntsmcf_tdghm_def 
    smcf_dghm_def 
    smc_dg_def
    dg_field_simps
    dghm_field_simps 
    nt_field_simps 
  by (simp add: nat_omega_simps) (*slow*)


subsubsection‹Natural transformation map›

mk_VLambda (in is_ntsmcf) 
  dghm_tdghm_comp_components(1)[where 𝔑=𝔑, unfolded ntsmcf_NTDGDom]
  |vdomain smcf_ntsmcf_comp_NTMap_vdomain[smc_cs_simps]|
  |app smcf_ntsmcf_comp_NTMap_app[smc_cs_simps]|

lemmas [smc_cs_simps] = 
  is_ntsmcf.smcf_ntsmcf_comp_NTMap_vdomain
  is_ntsmcf.smcf_ntsmcf_comp_NTMap_app

lemma smcf_ntsmcf_comp_NTMap_vrange: 
  assumes " : 𝔅 ↦↦SMCα" and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows " (( SMCF-NTSMCF 𝔑)NTMap)  Arr"
proof-
  interpret: is_semifunctor α 𝔅   by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  show ?thesis 
    unfolding dghm_tdghm_comp_components 
    by (auto simp: smc_cs_simps intro: smc_cs_intros)
qed


subsubsection‹
Opposite of the composition of a semifunctor
and a natural transformation of semifunctors 
›

lemma op_ntsmcf_smcf_ntsmcf_comp[smc_op_simps]: 
  "op_ntsmcf ( SMCF-NTSMCF 𝔑) = op_smcf  SMCF-NTSMCF op_ntsmcf 𝔑"
  unfolding 
    dghm_tdghm_comp_def
    dghm_comp_def
    op_ntsmcf_def
    op_smcf_def
    op_smc_def
    dg_field_simps
    dghm_field_simps
    nt_field_simps
  by (simp add: nat_omega_simps) (*slow*)


subsubsection‹
Composition of a semifunctor and a natural transformation of
semifunctors is a natural transformation of semifunctors
›

lemma smcf_ntsmcf_comp_is_ntsmcf[intro]:
  assumes " : 𝔅 ↦↦SMCα" and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows " SMCF-NTSMCF 𝔑 :  SMCF 𝔉 SMCF  SMCF 𝔊 : 𝔄 ↦↦SMCα"
proof-
  interpret: is_semifunctor α 𝔅   by (rule assms(1))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(2))
  show ?thesis
  proof(rule is_ntsmcfI)
    show "vfsequence ( SMCF-NTSMCF 𝔑)" unfolding dghm_tdghm_comp_def by simp
    from assms show " SMCF 𝔉 : 𝔄 ↦↦SMCα"
      by (cs_concl cs_intro: smc_cs_intros)
    from assms show " SMCF 𝔊 : 𝔄 ↦↦SMCα"
      by (cs_concl cs_intro: smc_cs_intros)
    show "vcard ( SMCF-NTSMCF 𝔑) = 5"
      unfolding dghm_tdghm_comp_def by (simp add: nat_omega_simps)
    from assms show "ntsmcf_tdghm ( SMCF-NTSMCF 𝔑) :
      smcf_dghm ( SMCF 𝔉) DGHM smcf_dghm ( SMCF 𝔊) :
      smc_dg 𝔄 ↦↦DGαsmc_dg "
      by 
        (
          cs_concl  
            cs_simp: slicing_commute[symmetric]  
            cs_intro: dg_cs_intros slicing_intros
        )
    have [smc_cs_simps]:  
      "ArrMap𝔑NTMapb AArrMap𝔉ArrMapf =
        ArrMap𝔊ArrMapf AArrMap𝔑NTMapa"
      if "f : a 𝔄b" for a b f
      using assms that 
      by 
        (
          cs_concl  
            cs_simp:
              is_ntsmcf.ntsmcf_Comp_commute 
              is_semifunctor.smcf_ArrMap_Comp[symmetric]
            cs_intro: smc_cs_intros
        )
    from assms show 
      "( SMCF-NTSMCF 𝔑)NTMapb A( SMCF 𝔉)ArrMapf =
        ( SMCF 𝔊)ArrMapf A( SMCF-NTSMCF 𝔑)NTMapa"
      if "f : a 𝔄b" for a b f
      using assms that
      by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  qed (auto simp: smc_cs_simps)
qed

lemma smcf_ntsmcf_comp_is_semifunctor'[smc_cs_intros]:
  assumes " : 𝔅 ↦↦SMCα"
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    and "𝔉' =  SMCF 𝔉"
    and "𝔊' =  SMCF 𝔊"
  shows " SMCF-NTSMCF 𝔑 : 𝔉' SMCF 𝔊' : 𝔄 ↦↦SMCα"
  using assms(1,2) unfolding assms(3,4) ..


subsubsection‹Further properties›

lemma smcf_comp_smcf_ntsmcf_comp_assoc:
  assumes "𝔑 :  SMCF ℌ' : 𝔄 ↦↦SMCα𝔅"
    and "𝔉 : 𝔅 ↦↦SMCα"
    and "𝔊 :  ↦↦SMCα𝔇"
  shows "(𝔊 SMCF 𝔉) SMCF-NTSMCF 𝔑 = 𝔊 SMCF-NTSMCF (𝔉 SMCF-NTSMCF 𝔑)"
proof(rule ntsmcf_tdghm_eqI)
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅  ℌ' 𝔑 by (rule assms(1))
  interpret 𝔉: is_semifunctor α 𝔅  𝔉 by (rule assms(2))
  interpret 𝔊: is_semifunctor α  𝔇 𝔊 by (rule assms(3))
  from assms show "(𝔊 SMCF 𝔉) SMCF-NTSMCF 𝔑 :
    𝔊 SMCF 𝔉 SMCF  SMCF 𝔊 SMCF 𝔉 SMCF ℌ' : 𝔄 ↦↦SMCα𝔇"
    by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  from assms show "𝔊 SMCF-NTSMCF (𝔉 SMCF-NTSMCF 𝔑) :
    𝔊 SMCF 𝔉 SMCF  SMCF 𝔊 SMCF 𝔉 SMCF ℌ' : 𝔄 ↦↦SMCα𝔇"
    by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  from assms show 
    "ntsmcf_tdghm (𝔊 SMCF 𝔉 SMCF-NTSMCF 𝔑) =
      ntsmcf_tdghm (𝔊 SMCF-NTSMCF (𝔉 SMCF-NTSMCF 𝔑))"
    by
      (
        cs_concl 
          cs_simp: slicing_commute[symmetric] 
          cs_intro: slicing_intros dghm_comp_dghm_tdghm_comp_assoc
      )
qed simp_all

lemma (in is_ntsmcf) ntsmcf_smcf_ntsmcf_comp_smcf_id[smc_cs_simps]:
  "smcf_id 𝔅 SMCF-NTSMCF 𝔑 = 𝔑"
proof(rule ntsmcf_tdghm_eqI)
  show "smcf_id 𝔅 SMCF-NTSMCF 𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  show "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
    by (cs_concl cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
  show "ntsmcf_tdghm (dghm_id 𝔅 DGHM-TDGHM 𝔑) = ntsmcf_tdghm 𝔑"
    by 
      (
        cs_concl cs_shallow
          cs_simp: slicing_simps slicing_commute[symmetric] 
          cs_intro: smc_cs_intros slicing_intros dg_cs_simps
      )
qed simp_all

lemmas [smc_cs_simps] = is_ntsmcf.ntsmcf_smcf_ntsmcf_comp_smcf_id

lemma smcf_ntsmcf_comp_ntsmcf_smcf_comp_assoc:
  assumes "𝔑 : 𝔉 SMCF 𝔊 : 𝔅 ↦↦SMCα"
    and " :  ↦↦SMCα𝔇"
    and "𝔎 : 𝔄 ↦↦SMCα𝔅"
  shows "( SMCF-NTSMCF 𝔑) NTSMCF-SMCF 𝔎 =  SMCF-NTSMCF (𝔑 NTSMCF-SMCF 𝔎)"
proof-
  interpret 𝔑: is_ntsmcf α 𝔅  𝔉 𝔊 𝔑 by (rule assms(1))
  interpret: is_semifunctor α  𝔇  by (rule assms(2))
  interpret 𝔎: is_semifunctor α 𝔄 𝔅 𝔎 by (rule assms(3))
  show ?thesis
    by (rule ntsmcf_tdghm_eqI)
      (
        use assms in
          cs_concl 
              cs_simp: smc_cs_simps slicing_commute[symmetric]
              cs_intro:
                smc_cs_intros
                slicing_intros
                dghm_tdghm_comp_tdghm_dghm_comp_assoc
      )+
qed

lemma smcf_ntsmcf_comp_ntsmcf_vcomp: 
  assumes "𝔎 : 𝔅 ↦↦SMCα"
    and "𝔐 : 𝔊 SMCF  : 𝔄 ↦↦SMCα𝔅" 
    and "𝔑 : 𝔉 SMCF 𝔊 : 𝔄 ↦↦SMCα𝔅"
  shows 
    "𝔎 SMCF-NTSMCF (𝔐 NTSMCF 𝔑) =
      (𝔎 SMCF-NTSMCF 𝔐) NTSMCF (𝔎 SMCF-NTSMCF 𝔑)"
proof-
  interpret 𝔎: is_semifunctor α 𝔅  𝔎 by (rule assms(1))
  interpret 𝔐: is_ntsmcf α 𝔄 𝔅 𝔊  𝔐 by (rule assms(2))
  interpret 𝔑: is_ntsmcf α 𝔄 𝔅 𝔉 𝔊 𝔑 by (rule assms(3))
  show 
    "𝔎 SMCF-NTSMCF (𝔐 NTSMCF 𝔑) = 𝔎 SMCF-NTSMCF 𝔐 NTSMCF (𝔎 SMCF-NTSMCF 𝔑)"
  proof(rule ntsmcf_eqI)
    have dom_lhs: "𝒟 ((𝔎 SMCF-NTSMCF (𝔐 NTSMCF 𝔑))NTMap) = 𝔄Obj"
      unfolding dghm_tdghm_comp_components smc_cs_simps by simp
    have dom_rhs: 
      "𝒟 ((𝔎 SMCF-NTSMCF 𝔐 NTSMCF (𝔎 SMCF-NTSMCF 𝔑))NTMap) = 𝔄Obj"
      unfolding ntsmcf_vcomp_components smc_cs_simps by simp
    show
      "(𝔎 SMCF-NTSMCF (𝔐 NTSMCF 𝔑))NTMap =
        (𝔎 SMCF-NTSMCF 𝔐 NTSMCF (𝔎 SMCF-NTSMCF 𝔑))NTMap"
    proof(rule vsv_eqI, unfold dom_lhs dom_rhs smc_cs_simps)
      fix a assume "a  𝔄Obj"
      then show 
        "(𝔎 SMCF-NTSMCF (𝔐 NTSMCF 𝔑))NTMapa =
          (𝔎 SMCF-NTSMCF 𝔐 NTSMCF (𝔎 SMCF-NTSMCF 𝔑))NTMapa"
        by (cs_concl cs_shallow cs_simp: smc_cs_simps cs_intro: smc_cs_intros)
    qed (cs_concl cs_shallow cs_intro: smc_cs_intros)+
  qed (cs_concl cs_shallow cs_intro: smc_cs_intros)+
qed

text‹\newpage›

end