\begin{code}
module fair-bot-self-cooperates where
open import common
\end{code}
\begin{code}
_∘_ : ∀ {A : Set}
{B : A → Set}
{C : {x : A} → B x → Set}
→ ({x : A} (y : B x) → C y)
→ (g : (x : A) → B x) (x : A)
→ C (g x)
f ∘ g = λ x → f (g x)
infixl 8 _ˢ_
_ˢ_ : ∀ {A : Set}
{B : A → Set}
{C : (x : A) → B x → Set}
→ ((x : A) (y : B x) → C x y)
→ (g : (x : A) → B x) (x : A)
→ C x (g x)
f ˢ g = λ x → f x (g x)
ᵏ : {A B : Set} → A → B → A
ᵏ a b = a
^ : ∀ {S : Set} {T : S → Set} {P : Σ S T → Set}
→ ((σ : Σ S T) → P σ)
→ (s : S) (t : T s) → P (s , t)
^ f s t = f (s , t)
\end{code}
\begin{code}
infixr 5 _⊢_ _‘⊢’_
infixr 10 _‘→’_ _‘×’_
data Type : Set where
_‘⊢’_ : List Type → Type → Type
_‘→’_ _‘×’_ : Type → Type → Type
‘⊥’ ‘⊤’ : Type
Context = List Type
\end{code}
\begin{code}
data _∈_ (T : Type) : Context → Set where
\end{code}
\begin{code}
top : ∀ {Γ} → T ∈ (T :: Γ)
\end{code}
\begin{code}
pop : ∀ {Γ S} → T ∈ Γ → T ∈ (S :: Γ)
\end{code}
\begin{code}
data _⊢_ (Γ : Context) : Type → Set where
\end{code}
\begin{code}
var : ∀ {T} → T ∈ Γ → Γ ⊢ T
\end{code}
\begin{code}
<> : Γ ⊢ ‘⊤’
_,_ : ∀ {A B} → Γ ⊢ A → Γ ⊢ B → Γ ⊢ A ‘×’ B
‘⊥’-elim : ∀ {A} → Γ ⊢ ‘⊥’ → Γ ⊢ A
π₁ : ∀ {A B} → Γ ⊢ A ‘×’ B → Γ ⊢ A
π₂ : ∀ {A B} → Γ ⊢ A ‘×’ B → Γ ⊢ B
‘λ’ : ∀ {A B} → (A :: Γ) ⊢ B → Γ ⊢ (A ‘→’ B)
_‘’ₐ_ : ∀ {A B} → Γ ⊢ (A ‘→’ B) → Γ ⊢ A → Γ ⊢ B
\end{code}
\begin{code}
⌜_⌝ : ∀ {Δ A} → Δ ⊢ A → Γ ⊢ (Δ ‘⊢’ A)
\end{code}
\begin{code}
repr : ∀ {Δ A} → Γ ⊢ (Δ ‘⊢’ A) → Γ ⊢ (Δ ‘⊢’ (Δ ‘⊢’ A))
\end{code}
\begin{code}
dist : ∀ {Δ A B}
→ Γ ⊢ (Δ ‘⊢’ (A ‘→’ B))
→ Γ ⊢ (Δ ‘⊢’ A)
→ Γ ⊢ (Δ ‘⊢’ B)
\end{code}
\begin{code}
Lӧb : ∀ {Δ A}
→ Γ ⊢ (Δ ‘⊢’ ((Δ ‘⊢’ A) ‘→’ A))
→ Γ ⊢ (Δ ‘⊢’ A)
\end{code}
\begin{code}
infixl 50 _‘’ₐ_
\end{code}
\begin{code}
lӧb : ∀ {Γ A} → Γ ⊢ ((Γ ‘⊢’ A) ‘→’ A) → Γ ⊢ A
lӧb t = t ‘’ₐ Lӧb ⌜ t ⌝
\end{code}
\begin{code}
lift-var : ∀ {Γ A} T Δ → A ∈ (Δ ++ Γ) → A ∈ (Δ ++ (T :: Γ))
lift-var T ε v = pop v
lift-var T (A :: Δ) top = top
lift-var T (x :: Δ) (pop v) = pop (lift-var T Δ v)
\end{code}
\begin{code}
lift-tm
: ∀ {Γ A} T Δ → (Δ ++ Γ) ⊢ A → (Δ ++ (T :: Γ)) ⊢ A
\end{code}
\begin{code}
lift-tm T Δ (var x) = var (lift-var T Δ x)
lift-tm T Δ <> = <>
lift-tm T Δ (a , b) = lift-tm T Δ a , lift-tm T Δ b
lift-tm T Δ (‘⊥’-elim t) = ‘⊥’-elim (lift-tm T Δ t)
lift-tm T Δ (π₁ t) = π₁ (lift-tm T Δ t)
lift-tm T Δ (π₂ t) = π₂ (lift-tm T Δ t)
lift-tm T Δ (‘λ’ t) = ‘λ’ (lift-tm T (_ :: Δ) t)
lift-tm T Δ (t ‘’ₐ t₁) = lift-tm T Δ t ‘’ₐ lift-tm T Δ t₁
lift-tm T Δ ⌜ t ⌝ = ⌜ t ⌝
lift-tm T Δ (repr t) = repr (lift-tm T Δ t)
lift-tm T Δ (dist t t₁) = dist (lift-tm T Δ t) (lift-tm T Δ t₁)
lift-tm T Δ (Lӧb t) = Lӧb (lift-tm T Δ t)
\end{code}
\begin{code}
wk : ∀ {Γ A B} → Γ ⊢ A → (B :: Γ) ⊢ A
wk = lift-tm _ ε
\end{code}
\begin{code}
infixl 10 _∘'_
_∘'_ : ∀ {Γ A B C}
→ Γ ⊢ (B ‘→’ C)
→ Γ ⊢ (A ‘→’ B)
→ Γ ⊢ (A ‘→’ C)
f ∘' g = ‘λ’ (wk f ‘’ₐ (wk g ‘’ₐ var top))
\end{code}
\begin{code}
distf : ∀ {Γ Δ A B}
→ Γ ⊢ (Δ ‘⊢’ A ‘→’ B)
→ Γ ⊢ (Δ ‘⊢’ A) ‘→’ (Δ ‘⊢’ B)
distf bf = ‘λ’ (dist (wk bf) (var top))
evf : ∀ {Γ Δ A}
→ Γ ⊢ (Δ ‘⊢’ A) ‘→’ (Δ ‘⊢’ (Δ ‘⊢’ A))
evf = ‘λ’ (repr (var top))
fb-fb-cooperate : ∀ {Γ A B}
→ Γ ⊢ (Γ ‘⊢’ A) ‘→’ B
→ Γ ⊢(Γ ‘⊢’ B) ‘→’ A
→ Γ ⊢ (A ‘×’ B)
fb-fb-cooperate a b
= lӧb (b ∘' distf ⌜ a ⌝ ∘' evf)
, lӧb (a ∘' distf ⌜ b ⌝ ∘' evf)
\end{code}
\begin{code}
‘□’ = _‘⊢’_ ε
□ = _⊢_ ε
fb-fb-cooperate' : ∀ {A B}
→ □ (‘□’ A ‘→’ B)
→ □ (‘□’ B ‘→’ A)
→ □ (A ‘×’ B)
fb-fb-cooperate' = fb-fb-cooperate
\end{code}
\begin{code}
inhabited : Σ Type (λ T → ε ⊢ T)
inhabited = ‘⊤’ , <>
\end{code}
\begin{code}
⟦_⟧ᵀ : Type → Set
⟦ Δ ‘⊢’ T ⟧ᵀ = Δ ⊢ T
⟦ A ‘→’ B ⟧ᵀ = ⟦ A ⟧ᵀ → ⟦ B ⟧ᵀ
⟦ A ‘×’ B ⟧ᵀ = ⟦ A ⟧ᵀ × ⟦ B ⟧ᵀ
⟦ ‘⊥’ ⟧ᵀ = ⊥
⟦ ‘⊤’ ⟧ᵀ = ⊤
\end{code}
\begin{code}
⟦_⟧ᶜ : Context → Set
⟦ ε ⟧ᶜ = ⊤
⟦ x :: Γ ⟧ᶜ = ⟦ Γ ⟧ᶜ × ⟦ x ⟧ᵀ
\end{code}
\begin{code}
⟦_⟧v : ∀ {Γ A} → A ∈ Γ → ⟦ Γ ⟧ᶜ → ⟦ A ⟧ᵀ
⟦ top ⟧v = snd
⟦ pop v ⟧v = ⟦ v ⟧v ∘ fst
\end{code}
\begin{code}
⟦_⟧ᵗ : ∀ {Γ A} → Γ ⊢ A → ⟦ Γ ⟧ᶜ → ⟦ A ⟧ᵀ
⟦ var v ⟧ᵗ = ⟦ v ⟧v
⟦ <> ⟧ᵗ = ᵏ _
⟦ a , b ⟧ᵗ = ᵏ _,_ ˢ ⟦ a ⟧ᵗ ˢ ⟦ b ⟧ᵗ
⟦ ‘⊥’-elim t ⟧ᵗ = ᵏ (λ ()) ˢ ⟦ t ⟧ᵗ
⟦ π₁ t ⟧ᵗ = ᵏ fst ˢ ⟦ t ⟧ᵗ
⟦ π₂ t ⟧ᵗ = ᵏ snd ˢ ⟦ t ⟧ᵗ
⟦ ‘λ’ b ⟧ᵗ = ^ ⟦ b ⟧ᵗ
⟦ f ‘’ₐ x ⟧ᵗ = ⟦ f ⟧ᵗ ˢ ⟦ x ⟧ᵗ
⟦ ⌜ t ⌝ ⟧ᵗ = ᵏ t
⟦ repr t ⟧ᵗ = ᵏ ⌜_⌝ ˢ ⟦ t ⟧ᵗ
⟦ dist f x ⟧ᵗ = ᵏ _‘’ₐ_ ˢ ⟦ f ⟧ᵗ ˢ ⟦ x ⟧ᵗ
⟦ Lӧb l ⟧ᵗ = ᵏ lӧb ˢ ⟦ l ⟧ᵗ
\end{code}
\begin{code}
‘¬’_ : Type → Type
‘¬’ T = T ‘→’ ‘⊥’
consistency : ¬ (□ ‘⊥’)
consistency f = ⟦ f ⟧ᵗ tt
incompleteness : ¬ (□ (‘¬’ ‘□’ ‘⊥’))
incompleteness t = ⟦ lӧb t ⟧ᵗ tt
soundness : ∀ {A} → □ A → ⟦ A ⟧ᵀ
soundness a = ⟦ a ⟧ᵗ tt
\end{code}