Anna Williams, 17 October 2025

Definition of Wild Category.

\begin{code}

{-# OPTIONS --safe --without-K #-}

open import MLTT.Spartan

module Categories.Wild where

\end{code}

We start by defining a wild category [1]. This consists of the usual components 
of a category, which is as follows.

 * A collection of objects, obj,

 * for each pair of objects, A B : obj, a homomorphism between A and B, hom A B,

 * for each object A : obj, an identity homomorphism id A : hom A A, and

 * a composition operation, ◦, which for objects A B C : obj and homomorphisms
   f : hom A B, g : hom B C gives a new homomorphism, g ◦ f : hom A C.

Such that the following axioms hold.

 * left-id: for objects A B : obj and morphism f : hom A B, f ◦ id = f,

 * right-id: for objects A B : obj and morphism f : hom A B, id ◦ f = f, and

 * associativity: for objects A B C D : obj and morphisms f : hom A B,
                  g : hom B C, h : hom C D, h ◦ (g ◦ f) = (h ◦ g) ◦ f.


[1] Capriotti, Paolo and Nicolai Kraus (2017). Univalent Higher Categories via
Complete Semi-Segal Type. https://arxiv.org/abs/1707.03693.

\begin{code}

record WildCategory (𝓤 𝓥 : Universe) : (𝓤 ⊔ 𝓥)⁺ ̇  where
 constructor wildcategory
 field
  obj : 𝓤 ̇
  hom : obj → obj → 𝓥 ̇
  𝒊𝒅 : {a : obj} → hom a a
  
  _◦_ : {a b c : obj} → hom b c → hom a b → hom a c

  𝒊𝒅-is-left-neutral : {a b : obj} (f : hom a b) → 𝒊𝒅 ◦ f = f
  
  𝒊𝒅-is-right-neutral : {a b : obj} (f : hom a b) → f ◦ 𝒊𝒅 = f

  assoc : {a b c d : obj}
          (f : hom a b)
          (g : hom b c)
          (h : hom c d)
        → h ◦ (g ◦ f) = (h ◦ g) ◦ f

\end{code}

An isomorphism in a category consists of a homomorphism, f : hom a b, and some
*inverse* homomorphism, g : hom b a, such that g ∘ f = id and f ∘ g = id.

We first define the property of being an isomorphism and then define the type of
isomorphisms between objects of a wild category.

\begin{code}

 inverse : {a b : obj} (f : hom a b) → 𝓥 ̇
 inverse {a} {b} f = Σ f⁻¹ ꞉ hom b a , (f⁻¹ ◦ f = 𝒊𝒅) × (f ◦ f⁻¹ = 𝒊𝒅)

 ⌞_⌟ : {a b : obj}
         {f : hom a b}
       → inverse f
       → hom b a
 ⌞_⌟ = pr₁

 ⌞_⌟-is-left-inverse : {a b : obj}
                         {f : hom a b}
                         (𝕗⁻¹ : inverse f)
                       → ⌞ 𝕗⁻¹ ⌟ ◦ f = 𝒊𝒅
 ⌞ 𝕗 ⌟-is-left-inverse = pr₁ (pr₂ 𝕗)

 ⌞_⌟-is-right-inverse : {a b : obj}
                          {f : hom a b}
                          (𝕗⁻¹ : inverse f)
                        → f ◦ ⌞ 𝕗⁻¹ ⌟ = 𝒊𝒅
 ⌞ 𝕗 ⌟-is-right-inverse = pr₂ (pr₂ 𝕗)

 _≅_ : (a b : obj) → 𝓥 ̇
 a ≅ b = Σ f ꞉ hom a b , inverse f

 ⌜_⌝ : {a b : obj}
     → a ≅ b
     → hom a b
 ⌜_⌝ = pr₁

 underlying-morphism-is-isomorphism
  : {a b : obj}
    (f : a ≅ b)
  → Σ f⁻¹ ꞉ hom b a , (f⁻¹ ◦ ⌜ f ⌝ = 𝒊𝒅) × (⌜ f ⌝ ◦ f⁻¹ = 𝒊𝒅)
 underlying-morphism-is-isomorphism = pr₂

\end{code}

We can show that two inverses for a given isomorphism must be equal.

\begin{code}

 at-most-one-inverse : {a b : obj}
                       {f : hom a b}
                       (g h : inverse f)
                     → ⌞ g ⌟ = ⌞ h ⌟
 at-most-one-inverse {a} {b} {f} g h = ⌞ g ⌟               =⟨ i ⟩
                                       ⌞ g ⌟ ◦ 𝒊𝒅           =⟨ ii ⟩
                                       ⌞ g ⌟ ◦ (f ◦ ⌞ h ⌟) =⟨ iii ⟩
                                       (⌞ g ⌟ ◦ f) ◦ ⌞ h ⌟ =⟨ iv ⟩
                                       𝒊𝒅 ◦ ⌞ h ⌟          =⟨ v ⟩
                                       ⌞ h ⌟               ∎
  where
   i   = (𝒊𝒅-is-right-neutral ⌞ g ⌟)⁻¹
   ii  = ap (⌞ g ⌟ ◦_) (⌞ h ⌟-is-right-inverse)⁻¹
   iii = assoc _ _ _
   iv  = ap (_◦ ⌞ h ⌟) ⌞ g ⌟-is-left-inverse
   v   = 𝒊𝒅-is-left-neutral ⌞ h ⌟

\end{code}

We can easily show that if a = b, then a ≅ b. This is because if a = b, then
by path induction we need to show that a ≅ a. This can be constructed as
follows.

\begin{code}

 id-to-iso : (a b : obj)
           → a = b
           → a ≅ b
 id-to-iso a b refl = 𝒊𝒅 , 𝒊𝒅 , 𝒊𝒅-is-left-neutral 𝒊𝒅 , 𝒊𝒅-is-left-neutral 𝒊𝒅

\end{code}