Chuangjie Xu, 2013

\begin{code}

module UniformContinuity where

open import MiniLibrary
open import Inequality
open import Sequence
open import not-not


constant : {X Y : Set}  (X  Y)  Set
constant {X} {Y} f = ∀(x x' : X)  f x  f x'

Lemma[∘-constant] : {X Y Z : Set}  (f : X  Y)  (g : Y  Z) 
                     constant f  constant (g  f)
Lemma[∘-constant] f g cf x x' = ap g (cf x x')

[constant] : {X Y : Set}  (X  Y)  Set
[constant] {X} {Y} f = ∀(x x' : X)  [ f x  f x' ]

Lemma[∘-[constant]] : {X Y Z : Set}  (f : X  Y)  (g : Y  Z) 
                       [constant] f  [constant] (g  f)
Lemma[∘-[constant]] f g cf x x' = [ap] g (cf x x')

∃-min : (  Set)  Set
∃-min P =  \(n : )  (P n)  (∀(n' : )  P n'  n  n')

locally-constant : {X : Set}  (₂ℕ  X)  Set
locally-constant p = ∃-min \(n : )  ∀(α β : ₂ℕ)  α ≣[ n ] β  p α  p β

\end{code}

Here we provide an algorithm to compute least moduli of uniform
continuity.

\begin{code}

uniformly-continuous-₂ℕ : (₂ℕ  ₂ℕ)  Set
uniformly-continuous-₂ℕ t = ∀(m : )  ∃-min \(n : )  ∀(α β : ₂ℕ)  α ≣[ n ] β  t α ≣[ m ] t β

Lemma[decidable-0̄-1̄] : {X : Set}  (_~_ : X  X  Set) 
         (∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
         (p : ₂ℕ  X)  (n : ) 
         decidable (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s ))
Lemma[decidable-0̄-1̄] _~_ dec p n = Lemma[₂Fin-decidability] P claim n
 where
  P : (n : )  ₂Fin n  Set
  P n s = p (cons s ) ~ p (cons s )
  claim : ∀(n : )  ∀(s : ₂Fin n)  decidable (P n s)
  claim n s = dec (p (cons s )) (p (cons s ))


LM : {X : Set}  (_~_ : X  X  Set)  (∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
     (₂ℕ  X)    
LM _~_ dec p 0        = 0
LM _~_ dec p (succ n) = case f₀ f₁ (Lemma[decidable-0̄-1̄] _~_ dec p n)
 where
  f₀ : (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s ))  
  f₀ _ = LM _~_ dec p n
  f₁ : ¬ (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s ))  
  f₁ _ = succ n


LM-₂ℕ : {m : }  (₂ℕ  ₂ℕ)    
LM-₂ℕ {m} = LM {₂ℕ}  α β  α ≣[ m ] β) Lemma[≣[]-decidable]

LM-ℕ : (₂ℕ  )    
LM-ℕ = LM {} _≡_ ℕ-discrete

LM-₂ : (₂ℕ  )    
LM-₂ = LM {} _≡_ ₂-discrete


Lemma[LM]₀ : {X : Set}  (_~_ : X  X  Set)  (dec : ∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
             (p : ₂ℕ  X)  (n : ) 
             (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s )) 
             LM _~_ dec p (succ n)  LM _~_ dec p n
Lemma[LM]₀ _~_ dec p n h = equality-cases (Lemma[decidable-0̄-1̄] _~_ dec p n) claim₀ claim₁
 where
  claim₀ :  h  Lemma[decidable-0̄-1̄] _~_ dec p n  in₀ h  LM _~_ dec p (succ n)  LM _~_ dec p n
  claim₀ _ r = ap (case _ _) r
  claim₁ :  f  Lemma[decidable-0̄-1̄] _~_ dec p n  in₁ f  LM _~_ dec p (succ n)  LM _~_ dec p n
  claim₁ f = ∅-elim(f h)

Lemma[LM]₁ : {X : Set}  (_~_ : X  X  Set)  (dec : ∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
             (p : ₂ℕ  X)  (n : ) 
             ¬ (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s )) 
             LM _~_ dec p (succ n)  succ n
Lemma[LM]₁ _~_ dec p n f = equality-cases (Lemma[decidable-0̄-1̄] _~_ dec p n) claim₀ claim₁
 where
  claim₀ :  h  Lemma[decidable-0̄-1̄] _~_ dec p n  in₀ h  LM _~_ dec p (succ n)  succ n
  claim₀ h = ∅-elim (f h)
  claim₁ :  f  Lemma[decidable-0̄-1̄] _~_ dec p n  in₁ f  LM _~_ dec p (succ n)  succ n
  claim₁ _ r = ap (case _ _) r


Lemma[succ-0̄-1̄] : {X : Set}  (_~_ : X  X  Set) 
        (∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
        ({x₀ x₁ : X}  x₀ ~ x₁  x₁ ~ x₀) 
        ({x₀ x₁ x₂ : X}  x₀ ~ x₁  x₁ ~ x₂  x₀ ~ x₂) 
        (p : ₂ℕ  X)  (n : ) 
        (∀(α β : ₂ℕ)  α ≣[ succ n ] β  p α ~ p β) 
        (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s )) 
         ∀(α β : ₂ℕ)  α ≣[ n ] β  p α ~ p β
Lemma[succ-0̄-1̄] {X} _~_ dec sy tr p n pr g α β en = tr eqα (sy eqβ)
 where
  s : ₂Fin n
  s = take n α
  eq : p (cons s ) ~ p (cons s )
  eq = g s
  eq0̄ : ∀{k : }  ∀(t : ₂Fin k)  cons t  k  
  eq0̄ ⟨⟩ = refl
  eq0̄ (b  s) = eq0̄ s
  eq1̄ : ∀{k : }  ∀(t : ₂Fin k)  cons t  k  
  eq1̄ ⟨⟩ = refl
  eq1̄ (b  s) = eq1̄ s
  subclaim₀ : α ≣[ succ n ] cons s   p α ~ p (cons s )
  subclaim₀ = pr α (cons s )
  subclaim₁ : α ≣[ succ n ] cons s   p α ~ p (cons s )
  subclaim₁ en' = tr (pr α (cons s ) en') (sy eq)
  subclaim₂ : (α ≣[ succ n ] cons s )  (α ≣[ succ n ] cons s )
  subclaim₂ = cases sclaim₀ sclaim₁ (Lemma[b≡₀∨b≡₁] (α n))
   where
    sclaim₀ : α n    α ≣[ succ n ] cons s 
    sclaim₀ αn₀ = ≣[succ]
                    (Lemma[cons-take-≣[]] n α ) (trans αn₀ (sym (eq0̄ s)))
    sclaim₁ : α n    α ≣[ succ n ] cons s 
    sclaim₁ αn₁ = ≣[succ]
                    (Lemma[cons-take-≣[]] n α ) (trans αn₁ (sym (eq1̄ s)))
  eqα : p α ~ p (cons s )
  eqα = case subclaim₀ subclaim₁ subclaim₂
  subclaim₃ : β ≣[ succ n ] cons s   p β ~ p (cons s )
  subclaim₃ = pr β (cons s )
  subclaim₄ : β ≣[ succ n ] cons s   p β ~ p (cons s )
  subclaim₄ aw' = tr (pr β (cons s ) aw') (sy eq)
  subclaim₅ : (β ≣[ succ n ] cons s )  (β ≣[ succ n ] cons s )
  subclaim₅ = transport {₂Fin n}  s  (β ≣[ succ n ] cons s )  (β ≣[ succ n ] cons s )}
                    (sym (Lemma[≣[]-take] en)) sclaim₂
   where
    s' : ₂Fin n
    s' = take n β
    sclaim₀ : β n    β ≣[ succ n ] cons s' 
    sclaim₀ βn₀ = ≣[succ] (Lemma[cons-take-≣[]] n β ) (trans βn₀ (sym (eq0̄ s')))
    sclaim₁ : β n    β ≣[ succ n ] cons s' 
    sclaim₁ βn₁ = ≣[succ] (Lemma[cons-take-≣[]] n β ) (trans βn₁ (sym (eq1̄ s')))
    sclaim₂ : (β ≣[ succ n ] cons s' )  (β ≣[ succ n ] cons s' )
    sclaim₂ = cases sclaim₀ sclaim₁ (Lemma[b≡₀∨b≡₁] (β n))
  eqβ : p β ~ p (cons s )
  eqβ = case subclaim₃ subclaim₄ subclaim₅


Lemma[LM-modulus] : {X : Set}  (_~_ : X  X  Set) 
        (dec : ∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
        ({x₀ x₁ : X}  x₀ ~ x₁  x₁ ~ x₀) 
        ({x₀ x₁ x₂ : X}  x₀ ~ x₁  x₁ ~ x₂  x₀ ~ x₂) 
        (p : ₂ℕ  X)  (n : ) 
        (∀(α β : ₂ℕ)  α ≣[ n ] β  p α ~ p β) 
         ∀(α β : ₂ℕ)  α ≣[ LM _~_ dec p n ] β  p α ~ p β
Lemma[LM-modulus] _~_ dec sy tr p 0        pr α β e = pr α β e
Lemma[LM-modulus] _~_ dec sy tr p (succ n) pr α β e =
      case claim₀ claim₁ (Lemma[decidable-0̄-1̄] _~_ dec p n)
 where
  claim₀ : (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s ))  p α ~ p β
  claim₀ h = Lemma[LM-modulus] _~_ dec sy tr p n pr' α β e'
   where
    fact : LM _~_ dec p (succ n)  LM _~_ dec p n
    fact = Lemma[LM]₀ _~_ dec p n h
    e' : α ≣[ LM _~_ dec p n ] β
    e' = transport {}  k  α ≣[ k ] β} fact e
    pr' : ∀(α β : ₂ℕ)  α ≣[ n ] β  p α ~ p β
    pr' = Lemma[succ-0̄-1̄] _~_ dec sy tr p n pr h
  claim₁ : ¬ (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s ))  p α ~ p β
  claim₁ f = pr α β e'
   where
    fact : LM _~_ dec p (succ n)  succ n
    fact = Lemma[LM]₁ _~_ dec p n f
    e' : α ≣[ succ n ] β
    e' = transport {}  k  α ≣[ k ] β} fact e


Lemma[LM-least] : {X : Set}  (_~_ : X  X  Set) 
        (dec : ∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
        ({x₀ x₁ : X}  x₀ ~ x₁  x₁ ~ x₀) 
        ({x₀ x₁ x₂ : X}  x₀ ~ x₁  x₁ ~ x₂  x₀ ~ x₂) 
        (p : ₂ℕ  X) 
        (n : )  (∀(α β : ₂ℕ)  α ≣[ n ] β  p α ~ p β) 
        (k : )  (∀(α β : ₂ℕ)  α ≣[ k ] β  p α ~ p β) 
         LM _~_ dec p n  k
Lemma[LM-least] _~_ dec sy tr p 0        prn k prk = ≤-zero
Lemma[LM-least] _~_ dec sy tr p (succ n) prn k prk = case claim₀ claim₁ claim₂
 where
  claim₀ : (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s )) 
            LM _~_ dec p (succ n)  k
  claim₀ h = transport {}  l  l  k} (sym fact) IH
   where
    fact : LM _~_ dec p (succ n)  LM _~_ dec p n
    fact = Lemma[LM]₀ _~_ dec p n h
    prn' : ∀(α β : ₂ℕ)  α ≣[ n ] β  p α ~ p β
    prn' = Lemma[succ-0̄-1̄] _~_ dec sy tr p n prn h
    IH : LM _~_ dec p n  k
    IH = Lemma[LM-least] _~_ dec sy tr p n prn' k prk
  claim₁ : ¬ (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s )) 
            LM _~_ dec p (succ n)   k
  claim₁ f = Lemma[m≮n→n≤m] goal
   where
    fact : LM _~_ dec p (succ n)  succ n
    fact = Lemma[LM]₁ _~_ dec p n f
    goal : k  LM _~_ dec p (succ n)
    goal r = f c₃
     where
      c₀ : k < succ n
      c₀ = transport {}  l  k < l} fact r
      c₁ : k  n
      c₁ = Lemma[m+1≤n+1→m≤n] c₀
      c₂ : ∀(s : ₂Fin n)  (cons s ) ≣[ k ] (cons s )
      c₂ s = Lemma[≣[]-≤] (Lemma[cons-≣[]] s  ) c₁
      c₃ : ∀(s : ₂Fin n)  p (cons s ) ~ p (cons s )
      c₃ s = prk (cons s ) (cons s ) (c₂ s)
  claim₂ : decidable (∀(s : ₂Fin n)  p (cons s ) ~ p (cons s ))
  claim₂ = Lemma[decidable-0̄-1̄] _~_ dec p n


Lemma[LM-least-modulus] : {X : Set}  (_~_ : X  X  Set) 
        (dec : ∀(x₀ x₁ : X)  decidable (x₀ ~ x₁)) 
        ({x₀ x₁ : X}  x₀ ~ x₁  x₁ ~ x₀) 
        ({x₀ x₁ x₂ : X}  x₀ ~ x₁  x₁ ~ x₂  x₀ ~ x₂) 
        (p : ₂ℕ  X) 
        (n : )  (∀(α β : ₂ℕ)  α ≣[ n ] β  p α ~ p β) 
        ∃-min \(k : )  (∀(α β : ₂ℕ)  α ≣[ k ] β  p α ~ p β)
Lemma[LM-least-modulus] _~_ dec sy tr p n pr =
  ∃-intro (LM _~_ dec p n) (∧-intro (Lemma[LM-modulus] _~_ dec sy tr p n pr)
                                    (Lemma[LM-least] _~_ dec sy tr p n pr))


Lemma[LM-₂ℕ-least-modulus] : {m : }  ∀(t : ₂ℕ  ₂ℕ) 
     (n : )  (∀(α β : ₂ℕ)  α ≣[ n ] β  t α ≣[ m ] t β) 
     ∃-min \(k : )  ∀(α β : ₂ℕ)  α ≣[ k ] β  t α ≣[ m ] t β
Lemma[LM-₂ℕ-least-modulus] {m} = Lemma[LM-least-modulus]  α β  α ≣[ m ] β) Lemma[≣[]-decidable] sym-≣[] trans-≣[]

Lemma[LM-ℕ-least-modulus] : ∀(p : ₂ℕ  ) 
     (n : )  (∀(α β : ₂ℕ)  α ≣[ n ] β  p α  p β) 
     ∃-min \(k : )  ∀(α β : ₂ℕ)  α ≣[ k ] β  p α  p β
Lemma[LM-ℕ-least-modulus] = Lemma[LM-least-modulus] _≡_ ℕ-discrete sym trans

Lemma[LM-₂-least-modulus] : ∀(p : ₂ℕ  ) 
     (n : )  (∀(α β : ₂ℕ)  α ≣[ n ] β  p α  p β) 
     ∃-min \(k : )  ∀(α β : ₂ℕ)  α ≣[ k ] β  p α  p β
Lemma[LM-₂-least-modulus] = Lemma[LM-least-modulus] _≡_ ₂-discrete sym trans


\end{code}

Identity map is uniformly continuous. Function composition preserves
uniform continuity.

\begin{code}

Lemma[id-UC] : uniformly-continuous-₂ℕ id
Lemma[id-UC] m = ∃-intro m (∧-intro prp min)
 where
  prp : ∀(α β : ₂ℕ)  α ≣[ m ] β  id α ≣[ m ] id β
  prp α β em = em
  min : ∀(n : )  (∀(α β : ₂ℕ)  α ≣[ n ] β  id α ≣[ m ] id β)  m  n
  min n prn = Lemma[m≮n→n≤m] claim
   where
    claim : n  m
    claim r = c₃ c₂
     where
      α : ₂ℕ
      α = 
      β : ₂ℕ
      β = overwrite  n 
      c₀ : α ≣[ n ] β
      c₀ = Lemma[overwrite-≣[]]  n 
      c₁ : α ≣[ succ n ] β
      c₁ = Lemma[≣[]-≤] (prn α β c₀) r
      c₂ : α n  β n
      c₂ = Lemma[≣[succ]]₁ c₁
      c₃ : α n  β n
      c₃ = transport {}  b    b} (sym (Lemma[overwrite]  n )) Lemma[₀≠₁]


Lemma[∘-UC] : ∀(t₀ : ₂ℕ  ₂ℕ)  uniformly-continuous-₂ℕ t₀ 
              ∀(t₁ : ₂ℕ  ₂ℕ)  uniformly-continuous-₂ℕ t₁ 
              uniformly-continuous-₂ℕ (t₀  t₁)
Lemma[∘-UC] t₀ uc₀ t₁ uc₁ m = Lemma[LM-₂ℕ-least-modulus] (t₀  t₁) n₁ pr
 where
  n₀ : 
  n₀ = ∃-witness (uc₀ m)
  pr₀ : ∀(α β : ₂ℕ)  α ≣[ n₀ ] β  t₀ α ≣[ m ] t₀ β
  pr₀ = ∧-elim₀ (∃-elim (uc₀ m))
  n₁ : 
  n₁ = ∃-witness (uc₁ n₀)
  pr₁ : ∀(α β : ₂ℕ)  α ≣[ n₁ ] β  t₁ α ≣[ n₀ ] t₁ β
  pr₁ = ∧-elim₀ (∃-elim (uc₁ n₀))
  pr : ∀(α β : ₂ℕ)  α ≣[ n₁ ] β  t₀ (t₁ α) ≣[ m ] t₀ (t₁ β)
  pr α β e = (pr₀ (t₁ α) (t₁ β)) (pr₁ α β e)


Lemma[cons-UC] : ∀{n : }  ∀(s : ₂Fin n)  uniformly-continuous-₂ℕ (cons s)
Lemma[cons-UC] ⟨⟩      m        = Lemma[id-UC] m
Lemma[cons-UC] (b  s) 0        = ∃-intro 0 ((λ _ _ _  ≣[zero]) ,  _ _  ≤-zero))
Lemma[cons-UC] (b  s) (succ m) = ∃-intro n (∧-intro prs mins)
 where
  IH : ∃-min \(n : )  ∀(α β : ₂ℕ)  α ≣[ n ] β  cons s α ≣[ m ] cons s β
  IH = Lemma[cons-UC] s m
  n : 
  n = ∃-witness IH
  prn : ∀(α β : ₂ℕ)  α ≣[ n ] β  cons s α ≣[ m ] cons s β
  prn = ∧-elim₀ (∃-elim IH)
  claim₀ : ∀(α β : ₂ℕ)  α ≣[ n ] β  cons s α ≣[ m ] cons s β 
            ∀(i : )  i < succ m  cons (b  s) α i  cons (b  s) β i
  claim₀ α β en em 0        r          = refl
  claim₀ α β en em (succ i) (≤-succ r) = Lemma[≣[]-<] em i r
  claim₁ : ∀(α β : ₂ℕ)  α ≣[ n ] β  cons s α ≣[ m ] cons s β 
            cons (b  s) α ≣[ succ m ] cons (b  s) β
  claim₁ α β en em = Lemma[<-≣[]] (claim₀ α β en em)
  prs : ∀(α β : ₂ℕ)  α ≣[ n ] β  cons (b  s) α ≣[ succ m ] cons (b  s) β
  prs α β en = claim₁ α β en (prn α β en)
  min : ∀(n' : )  (∀(α β : ₂ℕ)  α ≣[ n' ] β  cons s α ≣[ m ] cons s β)  n  n'
  min = ∧-elim₁ (∃-elim IH)
  lemma : ∀{n m : }{b : }{s : ₂Fin n}{α β : ₂ℕ} 
          cons (b  s) α ≣[ succ m ] cons (b  s) β  cons s α ≣[ m ] cons s β
  lemma {n} {m} {b} {s} {α} {β} esm = Lemma[<-≣[]] em'
   where
    esm' : ∀(i : )  i < succ m  cons (b  s) α i  cons (b  s) β i
    esm' = Lemma[≣[]-<] esm
    em' : ∀(i : )  i < m  cons s α i  cons s β i
    em' i r = esm' (succ i) (≤-succ r)
  mins : ∀(n' : )  (∀(α β : ₂ℕ)  α ≣[ n' ] β  cons (b  s) α ≣[ succ m ] cons (b  s) β)  n  n'
  mins n' pr' = min n'  α β en  lemma (pr' α β en))

\end{code}