module Antwerp.Minimum.Constructive ( : Set) where

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

¬_ : Set  Set
¬ X = X  

⊥-elim : {X : Set}    ¬ ¬ X
⊥-elim p = λ k  p

return : {X : Set}  X  ¬ ¬ X
return p = λ k  k p
-- Constructively, we do NOT have ¬ ¬ X → X.
-- That would be the principle of double negation elimination.

escape : ¬ ¬   
escape p = p  z  z)

oracle : (X : Set)  ¬ ¬ (X  ¬ X)
oracle X = λ k  k (inj₂  x  k (inj₁ x)))

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

module _ (α :   ) where
  {-# TERMINATING #-}
  go :   ¬ ¬ (Σ[ i   ] ((j : )  ¬ ¬ (α i  α j)))
  go i = oracle (Σ[ j   ] α j < α i) >>= g
    where
    g : ((Σ[ j   ] α j < α i)  ((Σ[ j   ] α j < α i)  )) 
      ¬ ¬ (Σ[ i   ] ((j : )  ¬ ¬ (α i  α j)))
    g (inj₁ (j , p)) = go j
    g (inj₂ q)       = return (i , h)
      where
      h : (j : )  ¬ ¬ (α i  α j)
      h j with ≤-<-connex (α i) (α j)
      ... | inj₁ αi≤αj = return αi≤αj
      ... | inj₂ αj<αi = ⊥-elim (q (j , αj<αi))

  minimum : ¬ ¬ (Σ[ i   ] ((j : )  ¬ ¬ (α i  α j)))
  minimum = go 0