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
Pigeonhole : {R : Ω} → ₂ℕ → Ω
Pigeonhole {R} α =
  ∃ \(b : ₂) → ∃ \(g : ℕ → ℕ) →
  ∀(i : ℕ) → g i < g(i + 1) ∧ K {R} (α(g i) ≡ b)
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)