module GenericConvergentSequence where

open import Logic
open import Equality
open import Naturals
open import Two
open import Cantor
open import Subset

-- Definition (The generic convergent sequence).
-- We use u,v to range over ℕ∞ and α,β to range over ₂ℕ.

decreasing : ₂ℕ  Prp
decreasing α = ∀(i : )  α i  α(succ i)

ℕ∞ : Set
ℕ∞ =  α  ₂ℕ  decreasing α 


-- Definition (Extensional equality on ℕ∞):

_≣_ : (u v : ℕ∞)   Prp
u  v =  i  incl u i  incl v i

-- Definition (Extensional functions on ℕ∞).
extensional : {Z : Set}  (ℕ∞  Z)  Prp
extensional f = ∀{u v : ℕ∞}  u  v  f u  f v


-- We now describe the elements of ℕ∞ explicitly.  
--
-- First the curried characteristic function of the (>) relation on ℕ,
-- seen as a function into the Cantor space.

bigger :   ₂ℕ
bigger 0 i = 
bigger (succ n) 0 = 
bigger (succ n) (succ i) = bigger n i


Lemma[bigger-0] :
---------------------------
  ∀(n : )  bigger n n  
---------------------------
Lemma[bigger-0] 0 = refl
Lemma[bigger-0] (succ n) = Lemma[bigger-0] n


Lemma[bigger-1] :
---------------------------------
  ∀(n : )  bigger(succ n) n  
---------------------------------
Lemma[bigger-1] 0 = refl
Lemma[bigger-1] (succ n) = Lemma[bigger-1] n


-- Definition (Embedding of ℕ into ℕ∞).
under :   ℕ∞
under n = bigger n || m n
 where
  m :  ∀(n : )  decreasing(bigger n)
  m 0 i r = ⊥-elim(Lemma[b≡₁→b≠₀] r refl)
  m (succ n) 0 r = refl
  m (succ n) (succ i) r = m n i r


-- Definition (Point at infinity).
 : ℕ∞
 =  i  ) || λ i r  refl


Lemma[under0] :
-------------------------------------------------------
  ∀{u : ℕ∞}  incl u 0    u  under 0
-------------------------------------------------------
Lemma[under0] {α || m} base = by-induction
 where
  by-induction : ∀(i : )  α i  
  by-induction 0 = base
  by-induction (succ i) =
    Lemma[[a≡₁→b≡₁]→b≡₀→a≡₀] (m i) (by-induction i)


Lemma[under1] :
--------------------------------------------------------------
  ∀(u : ℕ∞)  ∀(n : ) 
    incl u n    incl u(succ n)    u  under(succ n)
--------------------------------------------------------------
Lemma[under1] (α || m) n r s =
 by-induction n α m r s
 where
  by-induction :
   ∀(n : )  ∀(α : ₂ℕ)  decreasing α 
                α n    α(succ n)     i  α i  bigger(succ n) i
  by-induction 0 α m r s i = by-cases i
   where
    by-cases :  i  α i  bigger 1 i
    by-cases 0 = r
    by-cases (succ i) = by-nested-induction i
     where by-nested-induction : ∀(i : )  α(succ i)  
           by-nested-induction 0 = s
           by-nested-induction (succ i) =
            Lemma[[a≡₁→b≡₁]→b≡₀→a≡₀] (m (succ i)) (by-nested-induction i)
  by-induction (succ n) α m r s 0 = by-nested-induction (succ n) r
   where
    by-nested-induction : ∀(n : )  α n    α 0  
    by-nested-induction 0 t = t
    by-nested-induction (succ n) t =
     by-nested-induction n (m n t)
  by-induction (succ n) α m r s (succ i) =
   by-induction n (α  succ) (m  succ) r s i


Lemma[ℕ∞∖under[ℕ]⊆[∞]] :
------------------------------------------------------
  ∀(u : ℕ∞)  (∀(n : )  ¬(u  under n))  u  
------------------------------------------------------
Lemma[ℕ∞∖under[ℕ]⊆[∞]] u f = Lemma
 where
  Lemma : ∀(n : )  incl u n  
  Lemma 0 = Lemma[b≠₀→b≡₁] claim
   where
    claim : incl u 0  
    claim r = f 0 (Lemma[under0] {u} r)
  Lemma (succ n) = Lemma[b≠₀→b≡₁] claim
   where
    IH : incl u n  
    IH = Lemma n

    claim : incl u(succ n)  
    claim r = f(succ n)(Lemma[under1] u n IH r)


Lemma[density] :
-----------------------------------------------------------------------------
  ∀(p : ℕ∞  )  extensional p  (∀(n : )  p(under n)  )  p    
  ∀(u : ℕ∞)  p u  
-----------------------------------------------------------------------------
Lemma[density] p extensionality-of-p f r u =
 Lemma[b≠₀→b≡₁] Lemma
  where
   Claim : ∀(n : )  p u    ¬(u  under n)
   Claim n = (contra-positive
                s  transitivity(extensionality-of-p s) (f n)))
             Lemma[b≡₀→b≠₁]

   Claim' : p u    ∀(n : )  ¬(u  under n)
   Claim' g n = Claim n g

   Claim-∞ : p u    ¬(u  )
   Claim-∞ = (contra-positive
                s  transitivity(extensionality-of-p s) r))
             Lemma[b≡₀→b≠₁]

   Lemma : p u  
   Lemma t = (Claim-∞ t)(Lemma[ℕ∞∖under[ℕ]⊆[∞]] u (Claim' t))