{-# OPTIONS --without-K #-}
module Composition.Vertical where
open import Level
open import Type hiding (★)
open import Function
open import Data.One using (𝟙)
open import Composition.Horizontal using (ConstArr)
VComposition : ∀ {i j} {I : ★ i} (_×_ : I → I → I) (_↝_ : I → I → ★ j) → ★ (i ⊔ j)
VComposition _×_ _↝_ = ∀ {i₀ i₁ o₀ o₁} → i₀ ↝ o₀ → i₁ ↝ o₁ → (i₀ × i₁) ↝ (o₀ × o₁)
IVComposition : ∀ {i t a} {I : ★ i} {T : ★ t}
(_×ᵢ_ : I → I → I)
(_×_ : T → T → T)
(⟨_⟩_↝_ : I → T → T → ★ a) → ★ (a ⊔ t ⊔ i)
IVComposition _×ᵢ_ _×_ ⟨_⟩_↝_ =
∀ {j₀ j₁ i₀ i₁ o₀ o₁} → ⟨ j₀ ⟩ i₀ ↝ o₀ → ⟨ j₁ ⟩ i₁ ↝ o₁ → ⟨ j₀ ×ᵢ j₁ ⟩ (i₀ × i₁) ↝ (o₀ × o₁)
record IVComposable {i j t a} {I : ★ i} {_×ᵢ_ : I → I → I} {_↝ᵢ_ : I → I → ★ j} {T : I → ★ t}
(_·_ : VComposition _×ᵢ_ _↝ᵢ_)
(_×_ : ∀ {i₀ i₁} → T i₀ → T i₁ → T (i₀ ×ᵢ i₁))
(⟨_⟩_↝_ : ∀ {i₀ i₁} → i₀ ↝ᵢ i₁ → T i₀ → T i₁ → ★ a) : ★ (a ⊔ t ⊔ i ⊔ j) where
constructor mk
infixr 3 _***_
field
_***_ : ∀ {i₀ i₁ o₀ o₁} {j₀ : i₀ ↝ᵢ o₀} {j₁ : i₁ ↝ᵢ o₁} {A B C D}
→ ⟨ j₀ ⟩ A ↝ C → ⟨ j₁ ⟩ B ↝ D
→ ⟨ j₀ · j₁ ⟩ (A × B) ↝ (C × D)
vComposition : ∀ {t a} {T : ★ t} {_×_ : T → T → T} {_↝_ : T → T → ★ a}
→ IVComposable {I = 𝟙} {_↝ᵢ_ = λ _ _ → 𝟙} {T = const T} _ _×_ (const _↝_)
→ VComposition _×_ _↝_
vComposition (mk _***_) = _***_
vCIComposition : ∀ {i t a} {T : ★ t} {_×_ : T → T → T}
{I : ★ i} {_·_ : I → I → I}
{⟨_⟩_↝_ : I → T → T → ★ a}
→ IVComposable {I = 𝟙} _·_ _×_ ⟨_⟩_↝_
→ IVComposition _·_ _×_ ⟨_⟩_↝_
vCIComposition (mk _***_) = _***_
VComposable : ∀ {t a} {T : ★ t} (_×_ : T → T → T) (_↝_ : T → T → ★ a) → ★ (t ⊔ a)
VComposable _×_ _↝_ = IVComposable {i = zero} {_↝ᵢ_ = ConstArr 𝟙} _ _×_ (const _↝_)
module VComposable = IVComposable
open import Data.Nat
open import Data.Fin.NP as Fin using (Fin; inject+; raise; bound; free)
opVComp : ∀ {t a} {T : ★ t} {_×_ : T → T → T} {_↝_ : T → T → ★ a}
→ VComposable _×_ _↝_ → VComposable (flip _×_) (flip _↝_)
opVComp (mk _***_) = mk (flip _***_)
open import Data.Product
funVComp : ∀ {t} → VComposable _×_ (λ (A B : ★ t) → A → B)
funVComp {t} = mk _***_ where
_***_ : ∀ {A B C D : ★ t} → (A → B) → (C → D) → A × C → B × D
(f *** g) (x , y) = (f x , g y)
finFunVComp : VComposable _+_ (λ i o → Fin i → Fin o)
finFunVComp = mk _***_ where
C = λ i o → Fin i → Fin o
_***_ : ∀ {i₀ i₁ o₀ o₁} → C i₀ o₀ → C i₁ o₁ → C (i₀ + i₁) (o₀ + o₁)
_***_ {i} f g x with Fin.cmp i _ x
_***_ f _ ._ | Fin.bound x = inject+ _ (f x)
_***_ {o₀ = o} _ g ._ | Fin.free x = raise o (g x)
finFunOpVComp : VComposable _+_ (λ i o → Fin o → Fin i)
finFunOpVComp = mk _***_ where
C = λ i o → Fin o → Fin i
_***_ : ∀ {i₀ i₁ o₀ o₁} → C i₀ o₀ → C i₁ o₁ → C (i₀ + i₁) (o₀ + o₁)
_***_ {o₀ = o} f g x with Fin.cmp o _ x
_***_ f _ ._ | Fin.bound x = inject+ _ (f x)
_***_ {i} _ g ._ | Fin.free x = raise i (g x)
module _ {a} (A : ★ a) where
open import Data.Vec.NP
open FunVec {A = A}
vecFunVComp : VComposable _+_ _→ᵛ_
vecFunVComp = mk _***_ where
C = _→ᵛ_
_***_ : ∀ {i₀ i₁ o₀ o₁} → C i₀ o₀ → C i₁ o₁
→ C (i₀ + i₁) (o₀ + o₁)
(f *** g) xs with splitAt _ xs
... | ys , zs , _ = f ys ++ g zs
open import Data.Bit
open import Data.Bits
bitsFunVComp : VComposable _+_ _→ᵇ_
bitsFunVComp = vecFunVComp Bit
constVComp : ∀ {a} {A : ★ a} (_***_ : A → A → A) → VComposable _ (ConstArr A)
constVComp _***_ = mk _***_