module Dickson-pc2022 where

open import Data.Nat
open import Data.Nat.Properties
open import Data.Sum
open import Data.Product

module Classical where
  data  : Set where

  ⊥-elim : {X : Set}    X
  ⊥-elim ()

  postulate
    oracle : (A : Set)  A  (A  )

  module _ (α :   ) where
    {-# TERMINATING #-}
    go :   Σ[ a   ] ((b : )  α a  α b)
    go n with oracle (Σ[ m   ] α m < α n)
    ... | inj₁ (m , αm<αn) = go m
    ... | inj₂ f           = n , g
        where
        g : (b : )  α n  α b
        g b with ≤-<-connex (α n) (α b)
        ... | inj₁ αn≤αb = αn≤αb
        ... | inj₂ αb<αn = ⊥-elim (f (b , αb<αn))

    min : Σ[ a   ] ((b : )  α a  α b)
    min = go 0

    thm : Σ[ i   ] (α i  α (i + 1))
    thm with min
    ... | (i , f) = i , f (i + 1)

module ConstructiveButUninformative ( : Set) where
  ¬¬ : Set  Set
  ¬¬ X = (X  )  

  ⊥-elim : {X : Set}    ¬¬ X
  ⊥-elim r k = r

  oracle : (A : Set)  ¬¬ (A  (A  ))
  oracle A = λ k  k (inj₂  p  k (inj₁ p)))

  _⟫=_ : {A B : Set}  ¬¬ A  (A  ¬¬ B)  ¬¬ B
  m ⟫= f = λ k  m  x  f x k)

  pure : {A : Set}  A  ¬¬ A
  pure x = λ k  k x

  escape : ¬¬   
  escape m = m  p  p)

  module _ (α :   ) where
    Exists-Minimum : Set
    Exists-Minimum = Σ[ a   ] ((b : )  ¬¬ (α a  α b))

    {-# TERMINATING #-}
    go :   ¬¬ Exists-Minimum
    go n = oracle (Σ[ m   ] α m < α n) ⟫= g
      where
      g : (Σ[ m   ] α m < α n)  ((Σ[ m   ] α m < α n)  )  ¬¬ Exists-Minimum
      g (inj₁ (m , αm<αn)) = go m
      g (inj₂ f)           = λ k  k (n , h)
        where
        h : (b : )  ¬¬ (α n  α b)
        h b with ≤-<-connex (α n) (α b)
        ... | inj₁ αn≤αb = pure αn≤αb
        ... | inj₂ αb<αn = ⊥-elim (f (b , αb<αn))

    min : ¬¬ (Σ[ a   ] ((b : )  ¬¬ (α a  α b)))
    min = go 0

    thm : ¬¬ (Σ[ i   ] (α i  α (i + 1)))
    thm = min ⟫= λ (i , f)  f (i + 1) ⟫= λ p  pure (i , p)

example-sequence :   
example-sequence 0 = 6
example-sequence 1 = 3
example-sequence 2 = 9
example-sequence n = 10

module ConstructiveAndInformative where
  module _ (α :   ) where
    Dickson : Set
    Dickson = Σ[ i   ] (α i  α (i + 1))

    open ConstructiveButUninformative Dickson

    theorem : Dickson
    theorem = escape (thm α)