{-# OPTIONS --without-K #-}
open import Function.NP
open import Type
open import Level.NP
open import Data.Product.NP using (Σ; _×_; _,_) renaming (proj₁ to fst)
open import Data.One using (𝟙)
open import Relation.Binary.PropositionalEquality.NP using (_≡_; !_; _∙_; refl; ap; coe; coe!; subst)
open import Function.Extensionality
open import HoTT
open import Data.ShapePolymorphism
open Equivalences
open import Type
open import Control.Protocol.InOut
open import Control.Protocol.End
import Control.Protocol.Core as C
open C using (end;com)
module Control.Protocol.Alternate where
data Proto : InOut → ★₁ where
end : ∀ {io} → Proto io
com : (io : InOut){M : ★₀}(P : M → Proto (dualᴵᴼ io)) → Proto io
pattern recv P = com In P
pattern send P = com Out P
module _ {{_ : FunExt}} where
com= : ∀ io {M₀ M₁}(M= : M₀ ≡ M₁)
{P₀ P₁}(P= : ∀ m₀ → P₀ m₀ ≡ P₁ (coe M= m₀))
→ Proto.com io P₀ ≡ com io P₁
com= io refl P= = ap (com _) (λ= P=)
module _ io
{M₀ M₁}(M≃ : M₀ ≃ M₁)
{P₀ P₁}
(P= : ∀ m₀ → P₀ m₀ ≡ P₁ (–> M≃ m₀))
{{_ : UA}} where
com≃ : com io P₀ ≡ com io P₁
com≃ = com= io (ua M≃) λ m → P= m ∙ ap P₁ (! coe-β M≃ m)
send= = com= Out
send≃ = com≃ Out
recv= = com= In
recv≃ = com≃ In
com=′ : ∀ io {M}{P₀ P₁ : M → Proto _}(P= : ∀ m → P₀ m ≡ P₁ m) → com io P₀ ≡ com io P₁
com=′ io = com= io refl
send=′ : ∀ {M}{P₀ P₁ : M → Proto _}(P= : ∀ m → P₀ m ≡ P₁ m) → send P₀ ≡ send P₁
send=′ = send= refl
recv=′ : ∀ {M}{P₀ P₁ : M → Proto _}(P= : ∀ m → P₀ m ≡ P₁ m) → recv P₀ ≡ recv P₁
recv=′ = recv= refl
P⟦_⟧ : ∀ {io} → Proto io → C.Proto
P⟦ end ⟧ = end
P⟦ com io P ⟧ = com io λ m → P⟦ P m ⟧
⟦_⟧ : ∀ {io} → Proto io → ★
⟦ P ⟧ = C.⟦ P⟦ P ⟧ ⟧
dual : ∀ {io} → Proto io → Proto (dualᴵᴼ io)
dual end = end
dual (com io P) = com (dualᴵᴼ io) λ m → dual (P m)
module _ {io}(P : Proto io) where
⟦_⊥⟧ : ★
⟦_⊥⟧ = ⟦ dual P ⟧
Log : ★
Log = C.⟦ C.source-of P⟦ P ⟧ ⟧
module _ {{_ : FunExt}} where
P⟦_⊥⟧ : ∀ {io}(P : Proto io) → C.dual P⟦ P ⟧ ≡ P⟦ dual P ⟧
P⟦ end ⊥⟧ = refl
P⟦ com io P ⊥⟧ = C.com= refl refl λ m → P⟦ P m ⊥⟧
telecom : ∀ {io} (P : Proto io) → ⟦ P ⟧ → ⟦ P ⊥⟧ → Log P
telecom P t u = C.telecom P⟦ P ⟧ t (subst C.⟦_⟧ (! P⟦ P ⊥⟧) u)
send′ : ★ → Proto In → Proto Out
send′ M P = send λ (_ : M) → P
recv′ : ★ → Proto Out → Proto In
recv′ M P = recv λ (_ : M) → P
module _ {{_ : FunExt}} where
dual-involutive : ∀ {io} (P : Proto io) → subst Proto (dualᴵᴼ-involutive io) (dual (dual P)) ≡ P
dual-involutive {In} end = refl
dual-involutive {Out} end = refl
dual-involutive (send P) = com=′ _ λ m → dual-involutive (P m)
dual-involutive (recv P) = com=′ _ λ m → dual-involutive (P m)