{-# OPTIONS --without-K --safe #-}
open import Categories.Category using (Category)
open import Categories.Category.Monoidal using (Monoidal)
module Categories.Category.Monoidal.Reasoning {o ℓ e} {C : Category o ℓ e} (M : Monoidal C) where
open import Data.Product using (_,_)
open import Categories.Functor using (Functor)
open Category C
private
variable
X Y : Obj
f g h i : X ⇒ Y
open Monoidal M using (_⊗₀_; _⊗₁_; ⊗)
open Functor ⊗ using (F-resp-≈; homomorphism)
open HomReasoning public
infixr 6 _⟩⊗⟨_ refl⟩⊗⟨_
infixl 7 _⟩⊗⟨refl
⊗-resp-≈ : f ≈ h → g ≈ i → (f ⊗₁ g) ≈ (h ⊗₁ i)
⊗-resp-≈ p q = F-resp-≈ (p , q)
⊗-resp-≈ˡ : f ≈ h → (f ⊗₁ g) ≈ (h ⊗₁ g)
⊗-resp-≈ˡ p = ⊗-resp-≈ p Equiv.refl
⊗-resp-≈ʳ : g ≈ i → (f ⊗₁ g) ≈ (f ⊗₁ i)
⊗-resp-≈ʳ p = ⊗-resp-≈ Equiv.refl p
_⟩⊗⟨_ : f ≈ h → g ≈ i → (f ⊗₁ g) ≈ (h ⊗₁ i)
_⟩⊗⟨_ = ⊗-resp-≈
refl⟩⊗⟨_ : g ≈ i → (f ⊗₁ g) ≈ (f ⊗₁ i)
refl⟩⊗⟨_ = ⊗-resp-≈ʳ
_⟩⊗⟨refl : f ≈ h → (f ⊗₁ g) ≈ (h ⊗₁ g)
_⟩⊗⟨refl = ⊗-resp-≈ˡ
⊗-distrib-over-∘ : ((f ∘ h) ⊗₁ (g ∘ i)) ≈ ((f ⊗₁ g) ∘ (h ⊗₁ i))
⊗-distrib-over-∘ = homomorphism
parallel : ∀ {X₁ X₂ Y₁ Y₂ Z₁ Z₂ W₁ W₂}
{f₁ : Y₁ ⇒ W₁} {f₂ : Z₁ ⇒ W₁} {g₁ : Y₂ ⇒ W₂} {g₂ : Z₂ ⇒ W₂}
{h₁ : X₁ ⇒ Y₁} {h₂ : X₁ ⇒ Z₁} {i₁ : X₂ ⇒ Y₂} {i₂ : X₂ ⇒ Z₂} →
f₁ ∘ h₁ ≈ f₂ ∘ h₂ → g₁ ∘ i₁ ≈ g₂ ∘ i₂ →
f₁ ⊗₁ g₁ ∘ h₁ ⊗₁ i₁ ≈ f₂ ⊗₁ g₂ ∘ h₂ ⊗₁ i₂
parallel {f₁ = f₁} {f₂} {g₁} {g₂} {h₁} {h₂} {i₁} {i₂} hyp₁ hyp₂ = begin
f₁ ⊗₁ g₁ ∘ h₁ ⊗₁ i₁ ≈˘⟨ ⊗-distrib-over-∘ ⟩
(f₁ ∘ h₁) ⊗₁ (g₁ ∘ i₁) ≈⟨ hyp₁ ⟩⊗⟨ hyp₂ ⟩
(f₂ ∘ h₂) ⊗₁ (g₂ ∘ i₂) ≈⟨ ⊗-distrib-over-∘ ⟩
f₂ ⊗₁ g₂ ∘ h₂ ⊗₁ i₂ ∎
serialize₁₂ : ∀ {X₁ Y₁ X₂ Y₂} {f : X₁ ⇒ Y₁} {g : X₂ ⇒ Y₂} →
f ⊗₁ g ≈ f ⊗₁ id ∘ id ⊗₁ g
serialize₁₂ {f = f} {g} = begin
f ⊗₁ g ≈˘⟨ identityʳ ⟩⊗⟨ identityˡ ⟩
(f ∘ id) ⊗₁ (id ∘ g) ≈⟨ ⊗-distrib-over-∘ ⟩
f ⊗₁ id ∘ id ⊗₁ g ∎
serialize₂₁ : ∀ {X₁ Y₁ X₂ Y₂} {f : X₁ ⇒ Y₁} {g : X₂ ⇒ Y₂} →
f ⊗₁ g ≈ id ⊗₁ g ∘ f ⊗₁ id
serialize₂₁ {f = f} {g} = begin
f ⊗₁ g ≈˘⟨ identityˡ ⟩⊗⟨ identityʳ ⟩
(id ∘ f) ⊗₁ (g ∘ id) ≈⟨ ⊗-distrib-over-∘ ⟩
id ⊗₁ g ∘ f ⊗₁ id ∎
split₁ʳ : ∀ {X₁ Y₁ Z₁ X₂ Y₂} {f : Y₁ ⇒ Z₁} {g : X₁ ⇒ Y₁} {h : X₂ ⇒ Y₂} →
(f ∘ g) ⊗₁ h ≈ f ⊗₁ h ∘ g ⊗₁ id
split₁ʳ {f = f} {g} {h} = begin
(f ∘ g) ⊗₁ h ≈˘⟨ refl⟩⊗⟨ identityʳ ⟩
(f ∘ g) ⊗₁ (h ∘ id) ≈⟨ ⊗-distrib-over-∘ ⟩
f ⊗₁ h ∘ g ⊗₁ id ∎
split₁ˡ : ∀ {X₁ Y₁ Z₁ X₂ Y₂} {f : Y₁ ⇒ Z₁} {g : X₁ ⇒ Y₁} {h : X₂ ⇒ Y₂} →
(f ∘ g) ⊗₁ h ≈ f ⊗₁ id ∘ g ⊗₁ h
split₁ˡ {f = f} {g} {h} = begin
(f ∘ g) ⊗₁ h ≈˘⟨ refl⟩⊗⟨ identityˡ ⟩
(f ∘ g) ⊗₁ (id ∘ h) ≈⟨ ⊗-distrib-over-∘ ⟩
f ⊗₁ id ∘ g ⊗₁ h ∎
split₂ʳ : ∀ {X₁ Y₁ X₂ Y₂ Z₂} {f : X₁ ⇒ Y₁} {g : Y₂ ⇒ Z₂} {h : X₂ ⇒ Y₂} →
f ⊗₁ (g ∘ h) ≈ f ⊗₁ g ∘ id ⊗₁ h
split₂ʳ {f = f} {g} {h} = begin
f ⊗₁ (g ∘ h) ≈˘⟨ identityʳ ⟩⊗⟨refl ⟩
(f ∘ id) ⊗₁ (g ∘ h) ≈⟨ ⊗-distrib-over-∘ ⟩
f ⊗₁ g ∘ id ⊗₁ h ∎
split₂ˡ : ∀ {X₁ Y₁ X₂ Y₂ Z₂} {f : X₁ ⇒ Y₁} {g : Y₂ ⇒ Z₂} {h : X₂ ⇒ Y₂} →
f ⊗₁ (g ∘ h) ≈ id ⊗₁ g ∘ f ⊗₁ h
split₂ˡ {f = f} {g} {h} = begin
f ⊗₁ (g ∘ h) ≈˘⟨ identityˡ ⟩⊗⟨refl ⟩
(id ∘ f) ⊗₁ (g ∘ h) ≈⟨ ⊗-distrib-over-∘ ⟩
id ⊗₁ g ∘ f ⊗₁ h ∎
merge₂ʳ : ∀ {X₁ Y₁ X₂ Y₂ Z₂} {f : X₁ ⇒ Y₁} {g : Y₂ ⇒ Z₂} {h : X₂ ⇒ Y₂} →
f ⊗₁ g ∘ id ⊗₁ h ≈ f ⊗₁ (g ∘ h)
merge₂ʳ = Equiv.sym split₂ʳ
merge₂ˡ : ∀ {X₁ Y₁ X₂ Y₂ Z₂} {f : X₁ ⇒ Y₁} {g : Y₂ ⇒ Z₂} {h : X₂ ⇒ Y₂} →
id ⊗₁ g ∘ f ⊗₁ h ≈ f ⊗₁ (g ∘ h)
merge₂ˡ = Equiv.sym split₂ˡ
module _ {X Y Z} {f : X ⇒ Z} {g : Y ⇒ Z} {h : X ⇒ Y} (f≈gh : f ≈ g ∘ h) where
infixr 4 split₁_⟩∘⟨_ split₂_⟩∘⟨_
infixl 5 _⟩∘⟨split₁_ _⟩∘⟨split₂_
split₁_⟩∘⟨_ : ∀ {V W} {i j : V ⇒ X ⊗₀ W} → i ≈ j →
f ⊗₁ id ∘ i ≈ g ⊗₁ id ∘ h ⊗₁ id ∘ j
split₁_⟩∘⟨_ {_} {_} {i} {j} i≈j = begin
f ⊗₁ id ∘ i ≈⟨ f≈gh ⟩⊗⟨refl ⟩∘⟨ i≈j ⟩
(g ∘ h) ⊗₁ id ∘ j ≈⟨ split₁ˡ ⟩∘⟨refl ⟩
(g ⊗₁ id ∘ h ⊗₁ id) ∘ j ≈⟨ assoc ⟩
g ⊗₁ id ∘ (h ⊗₁ id ∘ j) ∎
split₂_⟩∘⟨_ : ∀ {V W} {i j : V ⇒ W ⊗₀ X} → i ≈ j →
id ⊗₁ f ∘ i ≈ id ⊗₁ g ∘ id ⊗₁ h ∘ j
split₂_⟩∘⟨_ {_} {_} {i} {j} i≈j = begin
id ⊗₁ f ∘ i ≈⟨ refl⟩⊗⟨ f≈gh ⟩∘⟨ i≈j ⟩
id ⊗₁ (g ∘ h) ∘ j ≈⟨ split₂ˡ ⟩∘⟨refl ⟩
(id ⊗₁ g ∘ id ⊗₁ h) ∘ j ≈⟨ assoc ⟩
id ⊗₁ g ∘ (id ⊗₁ h ∘ j) ∎
_⟩∘⟨split₁_ : ∀ {V W} {i j : Z ⊗₀ W ⇒ V} → i ≈ j →
i ∘ f ⊗₁ id ≈ (j ∘ g ⊗₁ id) ∘ h ⊗₁ id
_⟩∘⟨split₁_ {_} {_} {i} {j} i≈j = begin
i ∘ f ⊗₁ id ≈⟨ i≈j ⟩∘⟨ f≈gh ⟩⊗⟨refl ⟩
j ∘ (g ∘ h) ⊗₁ id ≈⟨ refl⟩∘⟨ split₁ˡ ⟩
j ∘ (g ⊗₁ id ∘ h ⊗₁ id) ≈⟨ sym-assoc ⟩
(j ∘ g ⊗₁ id) ∘ h ⊗₁ id ∎
_⟩∘⟨split₂_ : ∀ {V W} {i j : W ⊗₀ Z ⇒ V} → i ≈ j →
i ∘ id ⊗₁ f ≈ (j ∘ id ⊗₁ g) ∘ id ⊗₁ h
_⟩∘⟨split₂_ {_} {_} {i} {j} i≈j = begin
i ∘ id ⊗₁ f ≈⟨ i≈j ⟩∘⟨ refl⟩⊗⟨ f≈gh ⟩
j ∘ id ⊗₁ (g ∘ h) ≈⟨ refl⟩∘⟨ split₂ˡ ⟩
j ∘ (id ⊗₁ g ∘ id ⊗₁ h) ≈⟨ sym-assoc ⟩
(j ∘ id ⊗₁ g) ∘ id ⊗₁ h ∎
module _ {X Y Z} {f : Y ⇒ Z} {g : X ⇒ Y} {h : X ⇒ Z} (fg≈h : f ∘ g ≈ h) where
infixr 4 merge₁_⟩∘⟨_ merge₂_⟩∘⟨_
infixl 5 _⟩∘⟨merge₁_ _⟩∘⟨merge₂_
merge₁_⟩∘⟨_ : ∀ {V W} {i j : V ⇒ X ⊗₀ W} → i ≈ j →
f ⊗₁ id ∘ g ⊗₁ id ∘ i ≈ h ⊗₁ id ∘ j
merge₁_⟩∘⟨_ i≈j = ⟺ (split₁ ⟺ fg≈h ⟩∘⟨ ⟺ i≈j)
merge₂_⟩∘⟨_ : ∀ {V W} {i j : V ⇒ W ⊗₀ X} → i ≈ j →
id ⊗₁ f ∘ id ⊗₁ g ∘ i ≈ id ⊗₁ h ∘ j
merge₂_⟩∘⟨_ i≈j = ⟺ (split₂ ⟺ fg≈h ⟩∘⟨ ⟺ i≈j)
_⟩∘⟨merge₁_ : ∀ {V W} {i j : Z ⊗₀ W ⇒ V} → i ≈ j →
(i ∘ f ⊗₁ id) ∘ g ⊗₁ id ≈ j ∘ h ⊗₁ id
_⟩∘⟨merge₁_ i≈j = ⟺ (⟺ fg≈h ⟩∘⟨split₁ ⟺ i≈j)
_⟩∘⟨merge₂_ : ∀ {V W} {i j : W ⊗₀ Z ⇒ V} → i ≈ j →
(i ∘ id ⊗₁ f) ∘ id ⊗₁ g ≈ j ∘ id ⊗₁ h
_⟩∘⟨merge₂_ i≈j = ⟺ (⟺ fg≈h ⟩∘⟨split₂ ⟺ i≈j)