module Uniform.Examples where
open import Prelude.Basic
open import Prelude.Equality
open import Prelude.Equivalences
open import Prelude.Fam
open import Data.Fin hiding (_+_; lift)
open import Uniform.IR
open import Uniform.Initial
open import Uniform.Coproduct
open import Uniform.Coproduct.Maps
open import Uniform.Composition using (_○_)
module _ (S : Set)(P : S -> Set) where
cW₀ : {D : Set1} -> Uni D
cW₀ = δ (σ ι (λ _ → S)) (λ { (_ , s) → P s })
cW⊤ : UF {lsuc lzero} (Lift ⊤) (Lift ⊤)
cW⊤ = (cW₀ , λ _ → _)
W : Set
W = U {c = cW⊤}
sup : (s : S) -> (P s -> W) -> W
sup s f = intro ((tt , s) , f)
cW : UF {lsuc lzero} Set Set
cW = cW₀ , (λ { ((_ , s) , Tf) → (x : P s) -> Tf x })
cUΣΠW : UF Set Set
cUΣΠW = (cUB UF-+ cUΣ) UF-+ (cUΠ UF-+ cUW)
module UU where
cUB = (ι , λ _ → Bool)
cUΣ = (δ (δ ι (λ _ → ⊤)) (λ { (_ , A) → A _ }) ,
(λ { ((_ , A) , B) → Σ (A _) B }))
cUΠ = (δ (δ ι (λ _ → ⊤)) (λ { (_ , A) → A _ }) ,
(λ { ((_ , A) , B) → (x : A _) -> B x }))
cUW = (δ (δ ι (λ _ → ⊤)) (λ { (_ , A) → A _ }) ,
(λ { ((_ , A) , B) → W (A _) B }))
UΣΠW : Set
UΣΠW = U {c = cUΣΠW}
TΣΠW : UΣΠW -> Set
TΣΠW x = T x
iso : (⟦ UU.cUB ⟧₀ (UΣΠW , TΣΠW) ⊎ ⟦ UU.cUΣ ⟧₀ (UΣΠW , TΣΠW))
⊎ (⟦ UU.cUΠ ⟧₀ (UΣΠW , TΣΠW) ⊎ ⟦ UU.cUW ⟧₀ (UΣΠW , TΣΠW))
-> ⟦ cUΣΠW ⟧₀ (UΣΠW , TΣΠW)
iso = right (UU.cUB UF-+ UU.cUΣ) (UU.cUΠ UF-+ UU.cUW)
∘ ⊎-map (right UU.cUB UU.cUΣ) (right UU.cUΠ UU.cUW)
where right : (R Q : UF Set Set) ->
⟦ R ⟧₀ (UΣΠW , TΣΠW) ⊎ ⟦ Q ⟧₀ (UΣΠW , TΣΠW) ->
⟦ R UF-+ Q ⟧₀ (UΣΠW , TΣΠW)
right R Q = (_Fam⇒_.indmor (_≃_.right (coprodEq R Q {Z = (UΣΠW , TΣΠW)})))
bool : UΣΠW
bool = intro (iso (inj₁ (inj₁ tt)))
sig : (a : UΣΠW) -> (b : TΣΠW a -> UΣΠW) -> UΣΠW
sig a b = intro (iso (inj₁ (inj₂ ((tt , (λ _ → a)) , b))))
pi : (a : UΣΠW) -> (b : TΣΠW a -> UΣΠW) -> UΣΠW
pi a b = intro (iso (inj₂ (inj₁ ((tt , (λ _ → a)) , b))))
w : (a : UΣΠW) -> (b : TΣΠW a -> UΣΠW) -> UΣΠW
w a b = intro (iso (inj₂ (inj₂ ((tt , (λ _ → a)) , b))))
sumFin : (n : ℕ) -> (Fin n -> ℕ) -> ℕ
sumFin zero f = 0
sumFin (suc n) f = f (fromℕ n) + sumFin n (f ∘ inject₁)
prodFin : (n : ℕ) -> (Fin n -> ℕ) -> ℕ
prodFin zero f = 1
prodFin (suc n) f = f (fromℕ n) * prodFin n (f ∘ inject₁)
cArith : UF {lsuc lzero} (Lift ℕ) (Lift ℕ)
cArith = cFin UF-+ cSum UF-+ cProd
module Ar where
cFin = (σ ι (λ _ → ℕ)) , (λ { (_ , n) → lift n })
cSum = δ (δ ι (λ _ → ⊤)) (λ { (_ , n) → Fin (lower (n _)) }) ,
(λ { ((_ , n) , f) → lift (sumFin (lower (n _)) (lower ∘ f)) })
cProd = δ (δ ι (λ _ → ⊤)) (λ { (_ , n) → Fin (lower (n _)) }) ,
(λ { ((_ , n) , f) → lift (prodFin (lower (n _)) (lower ∘ f)) })
Arith : Set
Arith = U {c = cArith}
eval : Arith -> ℕ
eval = lower ∘ T
isoA : (⟦ Ar.cFin ⟧₀ (Arith , T)
⊎ ⟦ Ar.cSum ⟧₀ (Arith , T))
⊎ ⟦ Ar.cProd ⟧₀ (Arith , T) -> ⟦ cArith ⟧₀ (Arith , T)
isoA = right (Ar.cFin UF-+ Ar.cSum) Ar.cProd ∘ ⊎-map (right Ar.cFin Ar.cSum) id
where right : (R Q : UF (Lift ℕ) (Lift ℕ)) ->
⟦ R ⟧₀ (Arith , T) ⊎ ⟦ Q ⟧₀ (Arith , T) ->
⟦ R UF-+ Q ⟧₀ (Arith , T)
right R Q = (_Fam⇒_.indmor (_≃_.right (coprodEq R Q {Z = (Arith , T)})))
fin : ℕ -> Arith
fin n = intro (isoA (inj₁ (inj₁ (tt , n))))
sum : (n : Arith) -> (Fin (eval n) -> Arith) -> Arith
sum n f = intro (isoA (inj₁ (inj₂ ((tt , (λ _ → n)) , f) )))
prod : (n : Arith) -> (Fin (eval n) -> Arith) -> Arith
prod n f = intro (isoA (inj₂ ((tt , (λ _ → n)) , f) ))
fac : ℕ -> Arith
fac n = prod (fin n) (λ x → fin (suc (toℕ x)))
_ : eval (fac 5) ≡ 120
_ = refl
cUList : UF Set Set
cUList = (UU.cUB UF-+ UU.cUΣ) ○ (cW ℕ Fin)
compCode : let
cUΣ-composed
= (δ (σ (cW₀ ℕ Fin)
(λ { ((_ , s) , Tf) → ((x : Fin s) → Tf x) → ℕ}))
((λ { (((_ , s) , Tf) , e) →
Σ[ y ∈ ((x : Fin s) → Tf x) ] (Fin (e y))}))) ,
(λ { ((((_ , s) , Tf) , e) , B) →
Σ[ y ∈ ((x : Fin s) -> Tf x) ] ((w : Fin (e y)) -> B (y , w)) })
in {Z : Fam Set} ->
⟦ cUList ⟧₀ Z ->
⟦ UU.cUB UF-+ cUΣ-composed ⟧₀ Z
compCode (((((((((_ , true) , _) , _) , _) , _) , _) , _) , _) , _)
= ((((((((((tt , true) , ⊥-elim) , lift tt) , ⊥-elim) , lift tt) , ⊥-elim) , lift tt) , ⊥-elim) , lift tt) , ⊥-elim)
compCode (((((((((_ , false) , _) , _) , _) , n) , f) , _) , e) , y)
= ((((((((((tt , false) , ⊥-elim) , n _) , ⊥-elim) , tt) , (λ x → f (_ , x))) , e) , ⊥-elim) , tt) , y)