module Antwerp.Minimum.Classical where

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

data  : Set where

-- "ex falso quodlibet"
-- "from a contradiction, anything follows"
⊥-elim : {X : Set}    X
⊥-elim ()

postulate
  oracle : (X : Set)  X  (X  )
  -- Logical reading: X holds, or not X holds.
  -- (Recall: The negation of X is defined as "X → ⊥".)
  -- Computational reading: "oracle" is a function which
  -- reads an arbitrary X as input and outputs a witness
  -- of either X or of X → ⊥.

module _ (α :   ) where
  {-# TERMINATING #-}
  go :   Σ[ i   ] ((j : )  α i  α j)
  go i with oracle (Σ[ j   ] α j < α i)
  ... | inj₁ (j , p) = go j
  -- In this case, there is some value α j which is strictly smaller (<) than α i.
  -- So α i is not the absolute minimal value. So we need to continue searching
  -- for the minimal value.

  ... | inj₂ q = i , h
  -- In this case, there is no value α j which would be strictly smaller than α i.
  -- So we are done searching for the minimal value.
    where
    h : (j : )  α i  α j
    h j with ≤-<-connex (α i) (α j)
    ... | inj₁ αi≤αj = αi≤αj
    ... | inj₂ αj<αi = ⊥-elim (q (j , αj<αi))

  -- Logical reading: There is a number i such that for every number j,
  -- it holds that α i ≤ α j.
  -- Computational reading: "minimum" is a pair consisting of a number i
  -- and a function which reads as input a number j and which outputs
  -- a witness that α i ≤ α j.
  minimum : Σ[ i   ] ((j : )  α i  α j)
  minimum = go 0