open import Level
open import Data.Nat
open import Data.Nat.Properties
open import Data.Nat.Induction
open import Data.Sum
open import Data.Unit
open import Data.Empty
open import Relation.Binary
open import Relation.Binary.Definitions
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
open import Relation.Unary
open import Data.Product
open import Relation.Binary.Structures
open import Function
open import Relation.Binary.Reasoning.Syntax
open import Eser.Aux
open import Eser.Stdlib using (∸-suc)
open ≡-Reasoning renaming (begin_ to ≡begin_ ; _∎ to _≡∎)
module Eser.Monotone where
ℕ<Monotone : (ℕ → ℕ) → Set
ℕ<Monotone = Monotonic₁ _<_ _<_
ℕInjective : (ℕ → ℕ) → Set
ℕInjective = Injective _≡_ _≡_
smallerToSum : {m n : ℕ} → m < n → Σ[ k ∈ ℕ ] n ≡ ℕ.suc k + m
smallerToSum {m} {n} m<n =
let k = n ∸ ℕ.suc m in
let Sk+m≡n : ℕ.suc k + m ≡ n
Sk+m≡n =
≡begin
ℕ.suc k + m
≡⟨⟩
ℕ.suc (n ∸ ℕ.suc m) + m
≡⟨ cong (_+ m) (sym $ ∸-suc m<n) ⟩
(n ∸ m) + m
≡⟨ m∸n+n≡m (<⇒≤ m<n) ⟩
n
≡∎
in (k , sym Sk+m≡n)
piecewiseIncrImplMonoLemma
: {f : ℕ → ℕ}
→ ((n : ℕ) → f n < f (ℕ.suc n))
→ ((n k : ℕ) → f n < f (ℕ.suc k + n))
piecewiseIncrImplMonoLemma {f} H n 0 = H n
piecewiseIncrImplMonoLemma {f} H n (ℕ.suc k) =
let fn<fSk+n = piecewiseIncrImplMonoLemma H n k
in
<-trans fn<fSk+n (H $ ℕ.suc k + n)
piecewiseIncrImplMono
: {f : ℕ → ℕ}
→ ((n : ℕ) → f n < f (ℕ.suc n))
→ ℕ<Monotone f
piecewiseIncrImplMono {f} H {m} {n} m<n =
let (k , n≡Sk+m) = smallerToSum m<n
in
let fm<fSk+m = piecewiseIncrImplMonoLemma H m k
in
subst (λ x → f m < f x) (sym n≡Sk+m) fm<fSk+m
a<b→fa≡fb→MonoF→⊥
: {a b : ℕ}
→ {f : ℕ → ℕ}
→ ℕ<Monotone f
→ a < b
→ f a ≡ f b
→ ⊥
a<b→fa≡fb→MonoF→⊥ {a} {b} {f} mono a<b fa≡fb = <⇒≢ (mono a<b) fa≡fb
monotoneImplInjective
: {f : ℕ → ℕ}
→ ℕ<Monotone f
→ ℕInjective f
monotoneImplInjective {f} mono {m} {n} fm≡fn with <-cmp m n
... | tri< m<n _ _ = ⊥-elim $ a<b→fa≡fb→MonoF→⊥ mono m<n fm≡fn
... | tri≈ _ m≡n _ = m≡n
... | tri> _ _ n<m = ⊥-elim $ a<b→fa≡fb→MonoF→⊥ mono n<m (sym fm≡fn)
ℕ<MonoImplIval
: (f : ℕ → ℕ)
→ ℕ<Monotone f
→ (w : ℕ)
→ f 0 ≤ w
→ Σ[ i ∈ ℕ ]( f i ≤ w × w < f (ℕ.suc i))
ℕ<MonoImplIval f mono 0 f0≤w =
let f0≡0 : f 0 ≡ 0
f0≡0 = n≤0⇒n≡0 (f0≤w)
in
let 0<f1 : 0 < f 1
0<f1 = subst (λ x → x < f 1) f0≡0 (mono $ s≤s z≤n)
in
(0 , f0≤w , 0<f1)
ℕ<MonoImplIval f mono (suc w) f0≤Sw with (m≤n⇒m<n∨m≡n f0≤Sw)
... | inj₂ f0≡Sw = (0
, subst (λ x → f 0 ≤ x) f0≡Sw ≤-refl
, subst (λ x → x < f 1) f0≡Sw (mono $ s≤s z≤n))
... | inj₁ f0<Sw =
let w≤Sw : w ≤ ℕ.suc w
w≤Sw = n≤1+n w
in
let (i , fi≤w , w<fSi) = ℕ<MonoImplIval f mono w (s≤s⁻¹ f0<Sw)
in
let Sw≤fSi : ℕ.suc w ≤ f (ℕ.suc i)
Sw≤fSi = w<fSi
in
caseDistinction i fi≤w $ m≤n⇒m<n∨m≡n Sw≤fSi
where
caseDistinction
: (i : ℕ)
→ f i ≤ w
→ (ℕ.suc w < f (ℕ.suc i)) ⊎ (ℕ.suc w ≡ f (ℕ.suc i))
→ Σ[ i ∈ ℕ ] (f i ≤ ℕ.suc w × ℕ.suc w < f (ℕ.suc i))
caseDistinction i fi≤w (inj₁ Sw<fSi) =
(i , ≤-trans fi≤w (n≤1+n w) , Sw<fSi)
caseDistinction i _ (inj₂ Sw≡fSi) =
(ℕ.suc i
, ≡→≤ (sym Sw≡fSi)
, subst (λ x → x < (f $ ℕ.suc $ ℕ.suc i))
(sym Sw≡fSi)
(mono $ n<1+n (ℕ.suc i))
)
firstOfIval
: {w a b : ℕ}
→ a ≤ w
→ w < b
→ (P : ℕ → Set)
→ ((ℓ : ℕ) → Between a b ℓ → ¬ P ℓ)
→ P w
→ w ≡ a
firstOfIval {w} {a} {b} a≤w w<b P H Pw with (m≤n⇒m<n∨m≡n a≤w)
... | inj₁ a<w = ⊥-elim (H w (a<w , w<b) Pw)
... | inj₂ a≡w = sym a≡w