module InfinitePigeonOriginal where

open import Logic
open import LogicalFacts
open import Two
open import Naturals
open import Addition
open import Order
open import Cantor
open import JK-Monads
open import Equality
open import K-AC-N
open import JK-LogicalFacts

-- 6th May 2011.

-- We prove a theorem that involves the classical existential
-- quantifier K∃ (called pigeonhole below). The proof uses excluded
-- middle and classical countable choice (i.e. choice formulated with
-- the classical existential quantifier), which is implemented using
-- the K-shift (more commonly known as the double negation shift) in
-- the modules JK-Choice.agda and Infinite-JK-Shifts.agda.
--
-- In the module FinitePigeon.agda we derive a statement that uses the
-- intuitionistic quantifiers (and doesn't mention the double negation
-- modality K at all), using the classical result as a lemma. In the
-- module Examples.agda we run it.


-- Definition:

Pigeonhole : {R : Ω}  ₂ℕ  Ω
Pigeonhole {R} α =
   \(b : )   \(g :   ) 
  ∀(i : )  g i < g(i + 1)  K {R} (α(g i)  b)

-- Theorem:

pigeonhole : {R : Ω} 
----------

    ∀(α : ₂ℕ)  K(Pigeonhole α)

pigeonhole {R} α = K-∨-elim case₀ case₁ K-Excluded-Middle
 where
  A : Ω
  A = K∃ \(n : )  ∀(i : )  K(α(n + i + 1)  )

  case₀ : A  K(Pigeonhole α)
  case₀ a = K-functor lemma₁ a
   where
    lemma₁ : ( \(n : )  ∀(i : )  K(α(n + i + 1)  ))  Pigeonhole α
    lemma₁ (∃-intro n h) =
            ∃-intro  (∃-intro  i  n + i + 1)
                                λ i  (∧-intro (less-proof 0) (h i)))

  case₁ : (A  R)  K(Pigeonhole α)
  case₁ assumption =  K-functor lemma₇ lemma₆
   where
    lemma₂ : ∀(n : )  (∀(i : )  K(α(n + i + 1)  ))  R
    lemma₂ = not-exists-implies-forall-not(three-negations-imply-one assumption)

    lemma₃ : ∀(n : )  K∃ \(i : )  K(α(n + i + 1)  )
    lemma₃ = lemma₄ lemma₂
     where
      lemma₄ : (∀(n : )  (∀(i : )  K(α(n + i + 1)  ))  R) 
               (∀(n : )  K∃ \(i : )  K(α(n + i + 1)  ))
      lemma₄ h n = K-functor lemma₅ (not-forall-not-implies-K-exists(h n))
       where
        lemma₅ : ( \(i : )  α(n + i + 1)    R)   \(i : )  K(α(n + i + 1)  )
        lemma₅ (∃-intro i r) = (∃-intro i (two-equality-cases (α(n + i + 1)) r))

    lemma₆ : K∃ \(f :   )  ∀(n : )  K(α(n + f n + 1)  )
    lemma₆ = K-AC-ℕ  n  λ r  ∃-intro 0  p  r)) lemma₃

    lemma₇ : ( \(f :   )  ∀(n : )  K(α(n + f n + 1)  ))  Pigeonhole α
    lemma₇ (∃-intro f h) =
            ∃-intro  (∃-intro g λ i  (∧-intro (less-proof (f(g i))) (fact i)))
     where g :   
           g 0 = 0 + f 0 + 1
           g(succ n) = let m = g n in  m + f m + 1

           fact : ∀(n : )  K(α(g n)  )
           fact 0 = h 0
           fact (succ n) = h(g n)