{-# OPTIONS --cubical --safe #-}
module Container.Polynomial where
open import Prelude hiding (id; const; _×_; Π; _⊎_; Σ; _∘_; ⊤; ⊥)
open import Data.Unit.UniversePolymorphic
open import Data.Empty.UniversePolymorphic
import Prelude as P
open import Container
id : Container
id .fst = ⊤
id .snd _ = ⊤
const : Type → Container
const X .fst = X
const X .snd _ = ⊥
infixr 9 _∘_
_∘_ : Container → Container →
Container
(C₁ ∘ C₂) .fst = ⟦ C₁ ⟧ (fst C₂)
(C₁ ∘ C₂) .snd cx = ∃ x × (snd C₂ P.∘ snd cx) x
infixr 2 _×_
_×_ : Container → Container → Container
(C₁ × C₂) .fst = fst C₁ P.× fst C₂
(C₁ × C₂) .snd = P.uncurry λ s₁ s₂ → (snd C₁ s₁) P.⊎ (snd C₂ s₂)
Π : (I : Type) → (I → Container ) → Container
Π I C .fst = ∀ i → fst (C i)
Π I C .snd = λ s → ∃ i × snd (C i) (s i)
infix 0 const[_]⟶_
const[_]⟶_ : Type → Container → Container
const[ X ]⟶ C = Π X (P.const C)
infixr 1 _⊎_
_⊎_ : Container → Container → Container
(C₁ ⊎ C₂) .fst = (fst C₁ P.⊎ fst C₂)
(C₁ ⊎ C₂) .snd = either (snd C₁) (snd C₂)
Σ : (I : Type) → (I → Container) → Container
Σ I C .fst = ∃ i × fst (C i)
Σ I C .snd s = snd (C (fst s)) (snd s)