\section{Encoding of \texorpdfstring{L\"ob}{Lӧb}'s Theorem for the Prisoner's Dilemma} \label{sec:prisoners-dilemma-lob-encoding}
\AgdaHide{
  \begin{code}
module prisoners-dilemma-lob where
 open import common
  \end{code}
}
\begin{code}
 module lob where
  infixl 2 _▻_
  infixl 3 _‘’_
  infixr 1 _‘→’_
  infixr 1 _‘‘→’’_
  infixr 1 _‘“→”’_
  infixl 3 _‘’ₐ_
  infixl 3 _w‘‘’’ₐ_
  infixr 2 _‘∘’_
  infixr 2 _‘×’_
  infixr 2 _‘‘×’’_
  infixr 2 _w‘‘×’’_

  mutual
   data Context : Set where
     ε : Context
     _▻_ : (Γ : Context)  Type Γ  Context

   data Type : Context  Set where
     ‘⊤’ :  {Γ}  Type Γ
     ‘⊥’ :  {Γ}  Type Γ
     _‘→’_ :  {Γ}  Type Γ  Type Γ  Type Γ
     _‘×’_ :  {Γ}  Type Γ  Type Γ  Type Γ
     ‘Type’ :  Γ  Type Γ
     ‘Term’ :  {Γ}  Type (Γ  ‘Type’ Γ)
     Quine :  {Γ}  Type (Γ  ‘Type’ Γ)  Type Γ
     W :  {Γ A}  Type Γ  Type (Γ  A)
     W₁ :  {Γ A B}
        Type (Γ  B)
        Type (Γ  A  W B)
     _‘’_ :  {Γ A}
        Type (Γ  A)
        Term A
        Type Γ

   data Term : {Γ : Context}  Type Γ  Set where
     ‘tt’ :  {Γ}  Term {Γ} ‘⊤’
     ‘λ’ :  {Γ A B}
        Term {Γ  A} (W B)
        Term (A ‘→’ B)
     ‘VAR₀’ :  {Γ T}  Term {Γ  T} (W T)
     ⌜_⌝ᵀ :  {Γ}
        Type Γ
        Term {Γ} (‘Type’ Γ)
     ⌜_⌝ᵗ :  {Γ T}
        Term {Γ} T
        Term {Γ} (‘Term’ ‘’  T ⌝ᵀ)
     ‘⌜‘VAR₀’⌝ᵗ’ :  {Γ T}
        Term {Γ  ‘Term’ ‘’  T ⌝ᵀ}
              (W (‘Term’ ‘’  ‘Term’ ‘’  T ⌝ᵀ ⌝ᵀ))
     ‘⌜‘VAR₀’⌝ᵀ’ :  {Γ}
        Term {Γ  ‘Type’ Γ}
              (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ))
     _‘’ₐ_ :  {Γ A B}
        Term {Γ} (A ‘→’ B)
        Term {Γ} A
        Term {Γ} B
     ‘‘×'’’ :  {Γ}
        Term {Γ} (‘Type’ Γ
                  ‘→’ ‘Type’ Γ
                  ‘→’ ‘Type’ Γ)
     quine→ :  {Γ φ}
        Term {Γ}
              (Quine φ           ‘→’ φ ‘’  Quine φ ⌝ᵀ)
     quine← :  {Γ φ}
        Term {Γ}
              (φ ‘’  Quine φ ⌝ᵀ ‘→’ Quine φ)
     SW :  {Γ X A} {a : Term A}
        Term {Γ} (W X ‘’ a)
        Term X
     →SW₁SV→W
       :  {Γ T X A B} {x : Term X}
        Term {Γ}
              (T ‘→’ (W₁ A ‘’ ‘VAR₀’ ‘→’ W B) ‘’ x)
        Term {Γ}
              (T ‘→’ A ‘’ x ‘→’ B)
     ←SW₁SV→W
       :  {Γ T X A B} {x : Term X}
        Term {Γ}
              ((W₁ A ‘’ ‘VAR₀’ ‘→’ W B) ‘’ x ‘→’ T)
        Term {Γ}
              ((A ‘’ x ‘→’ B) ‘→’ T)
     →SW₁SV→SW₁SV→W
       :  {Γ T X A B} {x : Term X}
        Term {Γ} (T ‘→’ (W₁ A ‘’ ‘VAR₀’
                         ‘→’ W₁ A ‘’ ‘VAR₀’
                         ‘→’ W B) ‘’ x)
        Term {Γ} (T ‘→’ A ‘’ x ‘→’ A ‘’ x ‘→’ B)
     ←SW₁SV→SW₁SV→W
       :  {Γ T X A B} {x : Term X}
        Term {Γ} ((W₁ A ‘’ ‘VAR₀’
                  ‘→’ W₁ A ‘’ ‘VAR₀’
                  ‘→’ W B) ‘’ x
                  ‘→’ T)
        Term {Γ} ((A ‘’ x ‘→’ A ‘’ x ‘→’ B) ‘→’ T)
     w :  {Γ A T}
        Term {Γ} A
        Term {Γ  T} (W A)
     w→ :  {Γ A B X}
        Term {Γ  X} (W (A ‘→’ B))
        Term {Γ  X} (W A ‘→’ W B)
     →w :  {Γ A B X}
        Term {Γ  X} (W A ‘→’ W B)
        Term {Γ  X} (W (A ‘→’ B))
     ww→ :  {Γ A B X Y}
        Term {Γ  X  Y} (W (W (A ‘→’ B)))
        Term {Γ  X  Y} (W (W A) ‘→’ W (W B))
     →ww :  {Γ A B X Y}
        Term {Γ  X  Y} (W (W A) ‘→’ W (W B))
        Term {Γ  X  Y} (W (W (A ‘→’ B)))
     _‘∘’_ :  {Γ A B C}
        Term {Γ} (B ‘→’ C)
        Term {Γ} (A ‘→’ B)
        Term {Γ} (A ‘→’ C)
     _w‘‘’’ₐ_ :  {Γ A B T}
        Term {Γ  T} (W (‘Term’ ‘’  A ‘→’ B ⌝ᵀ))
        Term {Γ  T} (W (‘Term’ ‘’  A ⌝ᵀ))
        Term {Γ  T} (W (‘Term’ ‘’  B ⌝ᵀ))
     ‘‘’ₐ’ :  {Γ A B}
        Term {Γ} (‘Term’ ‘’  A ‘→’ B ⌝ᵀ
                  ‘→’ ‘Term’ ‘’  A ⌝ᵀ
                  ‘→’ ‘Term’ ‘’  B ⌝ᵀ)
     ‘‘□’’ :  {Γ A B}
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))
        Term {Γ  A  B}
              (W (W (‘Type’ Γ)))
     _‘‘→’’_ :  {Γ}
        Term {Γ} (‘Type’ Γ)
        Term {Γ} (‘Type’ Γ)
        Term {Γ} (‘Type’ Γ)
     _‘“→”’_ :  {Γ A B}
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))
     _‘“×”’_ :  {Γ A B}
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))
        Term {Γ  A  B}
              (W (W (‘Term’ ‘’  ‘Type’ Γ ⌝ᵀ)))

   : Type ε  Set _
   = Term {ε}

  ‘□’ :  {Γ}  Type Γ  Type Γ
  ‘□’ T = ‘Term’ ‘’  T ⌝ᵀ

  _‘‘×’’_ :  {Γ}
     Term {Γ} (‘Type’ Γ)
     Term {Γ} (‘Type’ Γ)
     Term {Γ} (‘Type’ Γ)
  A ‘‘×’’ B = ‘‘×'’’ ‘’ₐ A ‘’ₐ B

  max-level : Level
  max-level = lzero

  mutual
   ⟦_⟧ᶜ : (Γ : Context)  Set (lsuc max-level)
    ε ⟧ᶜ = 
    Γ  T ⟧ᶜ = Σ  Γ ⟧ᶜ  T ⟧ᵀ

   ⟦_⟧ᵀ : {Γ : Context}
      Type Γ
       Γ ⟧ᶜ
      Set max-level
    W T ⟧ᵀ ⟦Γ⟧
     =  T ⟧ᵀ (Σ.fst ⟦Γ⟧)
    W₁ T ⟧ᵀ ⟦Γ⟧
     =  T ⟧ᵀ (Σ.fst (Σ.fst ⟦Γ⟧) , Σ.snd ⟦Γ⟧)
    T ‘’ x ⟧ᵀ ⟦Γ⟧ =  T ⟧ᵀ (⟦Γ⟧ ,  x ⟧ᵗ ⟦Γ⟧)
    ‘Type’ Γ ⟧ᵀ ⟦Γ⟧
     = Lifted (Type Γ)
    ‘Term’ ⟧ᵀ ⟦Γ⟧
     = Lifted (Term (lower (Σ.snd ⟦Γ⟧)))
    A ‘→’ B ⟧ᵀ ⟦Γ⟧ =  A ⟧ᵀ ⟦Γ⟧   B ⟧ᵀ ⟦Γ⟧
    A ‘×’ B ⟧ᵀ ⟦Γ⟧ =  A ⟧ᵀ ⟦Γ⟧ ×  B ⟧ᵀ ⟦Γ⟧
    ‘⊤’ ⟧ᵀ ⟦Γ⟧ = 
    ‘⊥’ ⟧ᵀ ⟦Γ⟧ = 
    Quine φ ⟧ᵀ ⟦Γ⟧ =  φ ⟧ᵀ (⟦Γ⟧ , (lift (Quine φ)))

   ⟦_⟧ᵗ :  {Γ : Context} {T : Type Γ}
      Term T
      (⟦Γ⟧ :  Γ ⟧ᶜ)
       T ⟧ᵀ ⟦Γ⟧
     x ⌝ᵀ ⟧ᵗ ⟦Γ⟧ = lift x
     x ⌝ᵗ ⟧ᵗ ⟦Γ⟧ = lift x
    ‘⌜‘VAR₀’⌝ᵗ’ ⟧ᵗ ⟦Γ⟧
     = lift  lower (Σ.snd ⟦Γ⟧) ⌝ᵗ
    ‘⌜‘VAR₀’⌝ᵀ’ ⟧ᵗ ⟦Γ⟧
     = lift  lower (Σ.snd ⟦Γ⟧) ⌝ᵀ
    f ‘’ₐ x ⟧ᵗ ⟦Γ⟧ =  f ⟧ᵗ ⟦Γ⟧ ( x ⟧ᵗ ⟦Γ⟧)
    ‘tt’ ⟧ᵗ ⟦Γ⟧ = tt
    quine→ {φ} ⟧ᵗ ⟦Γ⟧ x = x
    quine← {φ} ⟧ᵗ ⟦Γ⟧ x = x
    ‘λ’ f ⟧ᵗ ⟦Γ⟧ x =  f ⟧ᵗ (⟦Γ⟧ , x)
    ‘VAR₀’ ⟧ᵗ ⟦Γ⟧ = Σ.snd ⟦Γ⟧
    SW t ⟧ᵗ =  t ⟧ᵗ
    ←SW₁SV→W f ⟧ᵗ =  f ⟧ᵗ
    →SW₁SV→W f ⟧ᵗ =  f ⟧ᵗ
    ←SW₁SV→SW₁SV→W f ⟧ᵗ =  f ⟧ᵗ
    →SW₁SV→SW₁SV→W f ⟧ᵗ =  f ⟧ᵗ
    w x ⟧ᵗ ⟦Γ⟧ =  x ⟧ᵗ (Σ.fst ⟦Γ⟧)
    w→ f ⟧ᵗ ⟦Γ⟧ =  f ⟧ᵗ ⟦Γ⟧
    →w f ⟧ᵗ ⟦Γ⟧ =  f ⟧ᵗ ⟦Γ⟧
    ww→ f ⟧ᵗ ⟦Γ⟧ =  f ⟧ᵗ ⟦Γ⟧
    →ww f ⟧ᵗ ⟦Γ⟧ =  f ⟧ᵗ ⟦Γ⟧
    ‘‘×'’’ ⟧ᵗ ⟦Γ⟧ A B = lift (lower A ‘×’ lower B)
    g ‘∘’ f ⟧ᵗ ⟦Γ⟧ x =  g ⟧ᵗ ⟦Γ⟧ ( f ⟧ᵗ ⟦Γ⟧ x)
    f w‘‘’’ₐ x ⟧ᵗ ⟦Γ⟧
     = lift (lower ( f ⟧ᵗ ⟦Γ⟧) ‘’ₐ lower ( x ⟧ᵗ ⟦Γ⟧))
    ‘‘’ₐ’ ⟧ᵗ ⟦Γ⟧ f x
     = lift (lower f ‘’ₐ lower x)
    ‘‘□’’ {Γ} T ⟧ᵗ ⟦Γ⟧
     = lift (‘Term’ ‘’ lower ( T ⟧ᵗ ⟦Γ⟧))
    A ‘‘→’’ B ⟧ᵗ ⟦Γ⟧
     = lift
       (lower ( A ⟧ᵗ ⟦Γ⟧) ‘→’ lower ( B ⟧ᵗ ⟦Γ⟧))
    A ‘“→”’ B ⟧ᵗ ⟦Γ⟧
     = lift
       (lower ( A ⟧ᵗ ⟦Γ⟧) ‘‘→’’ lower ( B ⟧ᵗ ⟦Γ⟧))
    A ‘“×”’ B ⟧ᵗ ⟦Γ⟧
     = lift
       (lower ( A ⟧ᵗ ⟦Γ⟧) ‘‘×’’ lower ( B ⟧ᵗ ⟦Γ⟧))


  module inner (‘X’ : Type ε)
               (‘f’ : Term {ε} (‘□’ ‘X’ ‘→’ ‘X’))
         where
   ‘H’ : Type ε
   ‘H’ = Quine (W₁ ‘Term’ ‘’ ‘VAR₀’ ‘→’ W ‘X’)

   ‘toH’ :  ((‘□’ ‘H’ ‘→’ ‘X’) ‘→’ ‘H’)
   ‘toH’ = ←SW₁SV→W quine←

   ‘fromH’ :  (‘H’ ‘→’ (‘□’ ‘H’ ‘→’ ‘X’))
   ‘fromH’ = →SW₁SV→W quine→

   ‘□‘H’→□‘X’’ :  (‘□’ ‘H’ ‘→’ ‘□’ ‘X’)
   ‘□‘H’→□‘X’’
     = ‘λ’ (w  ‘fromH’ ⌝ᵗ
           w‘‘’’ₐ ‘VAR₀’
           w‘‘’’ₐ ‘⌜‘VAR₀’⌝ᵗ’)

   ‘h’ : Term ‘H’
   ‘h’ = ‘toH’ ‘’ₐ (‘f’ ‘∘’ ‘□‘H’→□‘X’’)

   Lӧb :  ‘X’
   Lӧb = ‘fromH’ ‘’ₐ ‘h’ ‘’ₐ  ‘h’ ⌝ᵗ

  Lӧb :  {X}
     Term {ε} (‘□’ X ‘→’ X)  Term {ε} X
  Lӧb {X} f = inner.Lӧb X f

  ⟦_⟧ : Type ε  Set _
   T  =  T ⟧ᵀ tt

  ‘¬’_ :  {Γ}  Type Γ  Type Γ
  ‘¬’ T = T ‘→’ ‘⊥’

  _w‘‘×’’_ :  {Γ X}
     Term {Γ  X} (W (‘Type’ Γ))
     Term {Γ  X} (W (‘Type’ Γ))
     Term {Γ  X} (W (‘Type’ Γ))
  A w‘‘×’’ B = w→ (w→ (w ‘‘×'’’) ‘’ₐ A) ‘’ₐ B

  lӧb :  {‘X’}   (‘□’ ‘X’ ‘→’ ‘X’)   ‘X’ 
  lӧb f =  Lӧb f ⟧ᵗ tt

  incompleteness : ¬  (‘¬’ (‘□’ ‘⊥’))
  incompleteness = lӧb

  soundness : ¬  ‘⊥’
  soundness x =  x ⟧ᵗ tt

  non-emptiness : Σ (Type ε)  T   T)
  non-emptiness = ‘⊤’ , ‘tt’
\end{code}