General properties of well-quasiorders.
module WQO where
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; _≢_; sym; trans; subst; cong; _≗_)
open Eq.≡-Reasoning
open import Data.Nat using (ℕ; zero; suc; _+_; _≤_; s≤s; z≤n; _<_; _⊔_)
open import Data.Nat.Properties
using (≤-refl; ≤-trans; <-trans; <-irrefl; m≤n+m; +-monoˡ-<; <-transʳ; <-transˡ; m≤m⊔n; m≤n⊔m; +-assoc; m≤n⇒m≤o+n; m≤n⇒m≤n+o)
open import Data.Product using (Σ; _×_; _,_; proj₁; proj₂ ; ∃; Σ-syntax; ∃-syntax; ∃₂)
open import Data.Sum using (_⊎_; inj₁; inj₂) renaming ([_,_]′ to case-⊎)
open import Relation.Nullary using (¬_)
open import Data.Unit using (⊤; tt)
open import Data.Empty using (⊥; ⊥-elim)
open import Relation.Unary using (_∈_; _⊆_; Satisfiable)
open import Function using (_∘_; id)
open import Data.Maybe using (Maybe; just; nothing)
open import Miscellaneous
open import Classical
private
variable
A B : Set
Definitions of quasiorder and well-quasiorder.
Reflexive : (A → A → Set) → Set
Reflexive _≼_ = ∀ {x} → x ≼ x
Transitive : (A → A → Set) → Set
Transitive _≼_ = ∀ {x y z} → x ≼ y → y ≼ z → x ≼ z
record IsQO (_≼_ : A → A → Set) : Set where
field
reflexive : Reflexive _≼_ -- (x : A) → x ≼ x
transitive : Transitive _≼_ -- {x y z : A} → x ≼ y → y ≼ z → x ≼ z
open IsQO
Good : (_≼_ : A → A → Set) → (ℕ → A) → Set
Good _≼_ f = ∃₂ (λ i j → i < j × f i ≼ f j)
good-extensional : {_≼_ : A → A → Set} (f g : ℕ → A) → ((n : ℕ) → f n ≡ g n) →
Good _≼_ f → Good _≼_ g
good-extensional {A} {_≼_} f g f≗g (i , j , i<j , f[i]≼f[j]) = i , j , i<j , g[i]≼g[j]
where
g[i]≼g[j] : g i ≼ g j
g[i]≼g[j] rewrite sym (f≗g i) | sym (f≗g j) = f[i]≼f[j]
A sequence is very good if every subsequence of it is good.
VeryGood : (_≼_ : A → A → Set) → (ℕ → A) → Set
VeryGood _≼_ f = (r : ℕ → ℕ) → Increasing _<_ r → Good _≼_ (f ∘ r)
veryGood-extensional : {_≼_ : A → A → Set} (f g : ℕ → A)
→ ((n : ℕ) → f n ≡ g n)
→ VeryGood _≼_ f
----------------
→ VeryGood _≼_ g
veryGood-extensional {A} {_≼_} f g f≗g f-veryGood r r-increasing = i , j , i<j , g∘r[i]≼g∘r[j]
where
h : ∃₂ (λ i j → i < j × f (r i) ≼ f (r j))
h = f-veryGood r r-increasing
i = proj₁ h
j = proj₁ (proj₂ h)
i<j = proj₁ (proj₂ (proj₂ h))
f∘r[i]≼f∘r[j] : f (r i) ≼ f (r j)
f∘r[i]≼f∘r[j] = proj₂ (proj₂ (proj₂ h))
g∘r[i]≼g∘r[j] : g (r i) ≼ g (r j)
g∘r[i]≼g∘r[j] = subst (λ z → z ≼ g (r j)) (f≗g (r i)) (subst (λ z → f (r i) ≼ z) (f≗g (r j)) f∘r[i]≼f∘r[j])
veryGood-mono : (_≼₁_ _≼₂_ : A → A → Set) (f : ℕ → A) →
((x y : A) → x ≼₁ y → x ≼₂ y) →
VeryGood _≼₁_ f → VeryGood _≼₂_ f
veryGood-mono _≼₁_ _≼₂_ f h₁ h₂ r r-increasing = i , j , i<j , f∘r[i]≼₂f∘r[j]
where
[1] : Good _≼₁_ (f ∘ r)
[1] = h₂ r r-increasing
i j : ℕ
i = proj₁ [1]
j = proj₁ (proj₂ [1])
i<j : i < j
i<j = proj₁ (proj₂ (proj₂ [1]))
f∘r[i]≼₁f∘r[j] : f (r i) ≼₁ f (r j)
f∘r[i]≼₁f∘r[j] = proj₂ (proj₂ (proj₂ [1]))
f∘r[i]≼₂f∘r[j] : f (r i) ≼₂ f (r j)
f∘r[i]≼₂f∘r[j] = h₁ (f (r i)) (f (r j)) f∘r[i]≼₁f∘r[j]
veryGood⇒good : (_≼_ : A → A → Set) (f : ℕ → A) → VeryGood _≼_ f → Good _≼_ f
veryGood⇒good _≼_ f f-veryGood = f-veryGood id id-increasing
subseq-veryGood : (_≼_ : A → A → Set) (f : ℕ → A) (r : ℕ → ℕ)
→ VeryGood _≼_ f
→ Increasing _<_ r
----------------------
→ VeryGood _≼_ (f ∘ r)
subseq-veryGood _≼_ f r f-veryGood r-increasing r₁ r₁-increasing
= f-veryGood (r ∘ r₁) r∘r₁-increasing
where
r∘r₁-increasing : Increasing _<_ (r ∘ r₁)
r∘r₁-increasing = subseq-increasing _<_ r r₁ r-increasing r₁-increasing
The following form of reasoning is used repeatedly, but it’s often
cumbersome to identify P and prove that it’s closed under subsequence,
so I usually won’t bother invoking this lemma.
ClosedUnderSubseq : (P : (ℕ → A) → Set) → Set
ClosedUnderSubseq {A} P = (f : ℕ → A) (r : ℕ → ℕ) → Increasing _<_ r → P f → P (f ∘ r)
lemma-good-veryGood : {_≼_ : A → A → Set} (P : (ℕ → A) → Set)
→ ClosedUnderSubseq P
→ ((f : ℕ → A) → P f → Good _≼_ f)
→ (f : ℕ → A)
→ P f
→ VeryGood _≼_ f
lemma-good-veryGood P P-closed h f Pf r r-increasing = h (f ∘ r) (P-closed f r r-increasing Pf)
AlmostFull : (_≼_ : A → A → Set) → Set
AlmostFull _≼_ = ∀ f → Good _≼_ f
almostFull-mon : (_≼₁_ _≼₂_ : A → A → Set)
→ ((x y : A) → (x ≼₁ y) → (x ≼₂ y))
→ AlmostFull _≼₁_
→ AlmostFull _≼₂_
almostFull-mon _≼₁_ _≼₂_ h ≼₁-almostFull f with ≼₁-almostFull f
... | i , j , i<j , fi≼₁fj = i , j , i<j , h (f i) (f j) fi≼₁fj
record IsWQO (_≼_ : A → A → Set) : Set where
field
isQO : IsQO _≼_
almostFull : AlmostFull _≼_
open IsWQO
Some consequences.
module _ (_≼_ : A → A → Set) where
module _ (f : ℕ → A) where
almostFull-veryGood : AlmostFull _≼_ → VeryGood _≼_ f
almostFull-veryGood h r r-increasing = h (f ∘ r)
An index m is a near-nonterminal if f m has only finitely
many ≼-successors in the sequence f.
NearTerminal : ℕ → Set
NearTerminal m = Finite (λ n → f m ≼ f n)
-- ∃[ k ] ((n : ℕ) → k < n → ¬ f m ≼ f n)
NonNearTerminal : ℕ → Set
NonNearTerminal m = Infinite (λ n → f m ≼ f n)
-- (k : ℕ) → ∃[ n ] (k < n × f m ≼ f n)
¬NearTerminal⇒NonNearTerminal : (m : ℕ) → ¬ NearTerminal m → NonNearTerminal m
¬NearTerminal⇒NonNearTerminal m h = ¬finite⇒infinite (λ n → f m ≼ f n) h
¬NonNearTerminal⇒NearTerminal : (m : ℕ) → ¬ NonNearTerminal m →
NearTerminal m
¬NonNearTerminal⇒NearTerminal m h = ¬infinite⇒finite (λ n → f m ≼ f n) h
Every very good sequence (w.r.t. ≼) has a near-nonterminal.
veryGood⇒nonNearTerminal : VeryGood _≼_ f → Satisfiable NonNearTerminal
veryGood⇒nonNearTerminal f-veryGood = ¬¬-elim [1]
where
[1] : ¬ (¬ Satisfiable NonNearTerminal)
[1] h₁ = f∘r-bad f∘r-good
where
[2] : (n : ℕ) → NearTerminal n
[2] n = ¬NonNearTerminal⇒NearTerminal n (¬∃⟶∀¬ h₁ n)
r : ℕ → ℕ
r zero = zero
r (suc n) = suc (k ⊔ r n)
where
[3] : ∃[ k ] ((m : ℕ) → k < m → ¬ f (r n) ≼ f m)
[3] = [2] (r n)
k = proj₁ [3]
r-step : (n : ℕ) → r n < r (suc n)
r-step n = s≤s (m≤n⊔m _ (r n))
r-increasing : Increasing _<_ r
r-increasing = step-increasing r r-step
r-spec : (n m : ℕ) → r (suc n) ≤ m → ¬ f (r n) ≼ f m
r-spec n m r[1+n]≤m f∘r[n]≼f[m] = proj₂ [4] m k<m f∘r[n]≼f[m]
where
[4] : ∃[ k ] ((m : ℕ) → k < m → ¬ f (r n) ≼ f m)
[4] = [2] (r n)
k = proj₁ [4]
k<m : k < m
k<m = <-transˡ (s≤s (m≤m⊔n k (r n))) r[1+n]≤m
f∘r-bad : ¬ Good _≼_ (f ∘ r)
f∘r-bad (i , j , i<j , f∘r[i]≼f∘r[j]) = r-spec i (r j) r[1+i]≤r[j] f∘r[i]≼f∘r[j]
where
r[1+i]≤r[j] : r (suc i) ≤ r j
r[1+i]≤r[j] = increasing-≤ r r-increasing (suc i) j i<j
f∘r-good : Good _≼_ (f ∘ r)
f∘r-good = f-veryGood r r-increasing
If the first term of a sequence is not a near-terminal, then that term
is a lower bound (w.r.t. ≼) of a subsequence of that sequence.
nonNearTerminal⇒LowerBoundSubseq :
NonNearTerminal zero →
Σ[ r ∈ (ℕ → ℕ) ] (Increasing _<_ r × zero < r zero × All (f zero ≼_) (f ∘ r))
nonNearTerminal⇒LowerBoundSubseq h = r , r-increasing , [1] , [2]
where
r : ℕ → ℕ
r zero = proj₁ (h zero)
r (suc n) = proj₁ (h (r n))
r-step : (n : ℕ) → r n < r (suc n)
r-step n = proj₁ (proj₂ (h (r n)))
r-increasing : Increasing _<_ r
r-increasing = step-increasing r r-step
[1] : zero < r zero
[1] = proj₁ (proj₂ (h zero))
[2] : (n : ℕ) → f zero ≼ f (r n)
[2] zero = proj₂ (proj₂ (h zero))
[2] (suc n) = proj₂ (proj₂ (h (r n)))
nonNearTerminal-tail : (f : ℕ → A) (x : ℕ) (y : ℕ) →
NonNearTerminal f (x + y) → NonNearTerminal (f ∘ (_+ y)) x
nonNearTerminal-tail f x y h k =
o + suc k , m≤n⇒m≤o+n o ≤-refl , subst (λ z → f (x + y) ≼ f z) [2] (proj₂ (proj₂ (h (k + y))))
where
-- h (k + y) : ∃[ l ] (k + y < l × f (x + y) ≼ f l)
l = proj₁ (h (k + y))
k+y<l : k + y < l
k+y<l = proj₁ (proj₂ (h (k + y)))
[1] : ∃[ o ] o + (suc k + y) ≡ l
[1] = m≤n⇒∃[o]o+m≡n k+y<l
o = proj₁ [1]
[2] : l ≡ (o + suc k) + y
[2] = sym (trans (+-assoc o (suc k) y) (proj₂ [1]))
We can now prove that every very good sequence has an ascending
subsequence.
veryGood⇒ascendingSubseq :
(f : ℕ → A) → VeryGood _≼_ f →
Σ[ r ∈ (ℕ → ℕ) ] (Increasing _<_ r × Increasing _≼_ (f ∘ r))
veryGood⇒ascendingSubseq f f-veryGood = r , r-increasing , [14]
where
[1] : Satisfiable (NonNearTerminal f)
[1] = veryGood⇒nonNearTerminal f f-veryGood
n₀ = proj₁ [1]
n₀-spec : NonNearTerminal f n₀
n₀-spec = proj₂ [1]
f′ : ℕ → A
f′ n = f (n + n₀)
+n₀-increasing : Increasing _<_ (_+ n₀)
+n₀-increasing m n m<n = +-monoˡ-< n₀ m<n
nonNearTerminal-f′ : NonNearTerminal f′ zero
nonNearTerminal-f′ = nonNearTerminal-tail f zero n₀ n₀-spec
f′-veryGood : VeryGood _≼_ f′
f′-veryGood = subseq-veryGood _≼_ f (_+ n₀) f-veryGood +n₀-increasing
We’re going to construct an infinite sequence of subsequences of f:
f ∘ (r′ 0) , f ∘ (r′ 1) , f ∘ (r′ 2) , ...
For each j, f ∘ (r′ (suc j)) is a subsequence of f ∘ (r′ j), i.e., there is an increasing sequence s′ j such that r′ (suc j) equals r′ j ∘ s′ j. This makes each r′ j an increasing function, so that f ∘ (r′ j) is a subsequence of f and is hence very good. Moreover, r′ j zero has the following properties:
r′ : ℕ → ℕ → ℕ
r′-spec₁ : (j : ℕ) → Increasing _<_ (r′ j)
r′-spec₂ : (j : ℕ) → NonNearTerminal (f ∘ r′ j) zero
r′-spec₃ : (j : ℕ) → r′ j zero < r′ (suc j) zero
r′-spec₄ : (j n : ℕ) → f (r′ j zero) ≼ f (r′ (suc j) n)
s : ℕ → ℕ → ℕ
s-spec₁ : (j : ℕ) → Increasing _<_ (s j)
s-spec₂ : (j : ℕ) → zero < s j zero
s-spec₃ : (j : ℕ) → All (f (r′ j zero) ≼_) (f ∘ r′ j ∘ s j)
s-spec₄ : (j : ℕ) → Satisfiable (NonNearTerminal (f ∘ (r′ j ∘ s j)))
r′-helper :
(j : ℕ) → Σ[ s ∈ (ℕ → ℕ) ] (Increasing _<_ s × zero < s zero ×
All (f (r′ j zero) ≼_) (f ∘ r′ j ∘ s))
s′ : ℕ → ℕ → ℕ
s′-increasing : (j : ℕ) → Increasing _<_ (s′ j)
r′ zero = _+ n₀
r′ (suc j) = r′ j ∘ s j ∘ (_+ n)
where
n = proj₁ (s-spec₄ j)
r′-spec₁ zero m n m<n = +-monoˡ-< n₀ m<n
r′-spec₁ (suc j) =
compose-increasing (compose-increasing (λ o p o<p → +-monoˡ-< n o<p) (s-spec₁ j)) (r′-spec₁ j)
where
n = proj₁ (s-spec₄ j)
r′-spec₂ zero = nonNearTerminal-f′
r′-spec₂ (suc j) = nonNearTerminal-tail (f ∘ (r′ j ∘ s j)) zero n n-spec
where
n = proj₁ (s-spec₄ j)
n-spec : NonNearTerminal (f ∘ (r′ j ∘ s j)) n
n-spec = proj₂ (s-spec₄ j)
r′-spec₃ j = <-transˡ (r′-spec₁ j zero (s j zero) (s-spec₂ j)) (r′[j]∘s[j]-nondecreasing zero n z≤n)
where
n = proj₁ (s-spec₄ j)
r′[j]∘s[j]-increasing : Increasing _<_ (r′ j ∘ s j)
r′[j]∘s[j]-increasing = compose-increasing (s-spec₁ j) (r′-spec₁ j)
r′[j]∘s[j]-nondecreasing : (o p : ℕ) → o ≤ p → (r′ j (s j o) ≤ r′ j (s j p))
r′[j]∘s[j]-nondecreasing = increasing-≤ (r′ j ∘ s j) r′[j]∘s[j]-increasing
r′-spec₄ j = all-compose {P = f (r′ j zero) ≼_} (_+ n) (s-spec₃ j)
where
n = proj₁ (s-spec₄ j)
r′-helper j = nonNearTerminal⇒LowerBoundSubseq (f ∘ r′ j) (r′-spec₂ j)
s j = proj₁ (r′-helper j)
s-spec₁ j = proj₁ (proj₂ (r′-helper j))
s-spec₂ j = proj₁ (proj₂ (proj₂ (r′-helper j)))
s-spec₃ j = proj₂ (proj₂ (proj₂ (r′-helper j)))
s-spec₄ j = veryGood⇒nonNearTerminal (f ∘ r′ j ∘ s j) f∘r′[j]∘s[j]-veryGood
where
r′[j]∘s[j]-increasing : Increasing _<_ (r′ j ∘ s j)
r′[j]∘s[j]-increasing = compose-increasing (s-spec₁ j) (r′-spec₁ j)
f∘r′[j]∘s[j]-veryGood : VeryGood _≼_ (f ∘ r′ j ∘ s j)
f∘r′[j]∘s[j]-veryGood = subseq-veryGood _≼_ f (r′ j ∘ s j) f-veryGood r′[j]∘s[j]-increasing
s′ j = s j ∘ (_+ proj₁ (s-spec₄ j))
s′-increasing j = compose-increasing (λ o p o<p → +-monoˡ-< n o<p) (s-spec₁ j)
where
n = proj₁ (s-spec₄ j)
[2] : (j : ℕ) → r′ j ∘ s′ j ≡ r′ (suc j)
[2] j = refl
[3] : (j p : ℕ) → Σ[ t ∈ (ℕ → ℕ) ] (Increasing _<_ t × r′ j ∘ t ≗ r′ (p + j))
[3] j zero = id , id-increasing , λ x → refl
[3] j (suc p) =
t ∘ s′ (p + j) ,
compose-increasing (s′-increasing (p + j)) t-increasing ,
λ x → trans ([4] (s′ (p + j) x)) ([5] x)
where
t = proj₁ ([3] j p)
t-increasing = proj₁ (proj₂ ([3] j p))
[4] : r′ j ∘ t ≗ r′ (p + j)
[4] = proj₂ (proj₂ ([3] j p))
[5] : r′ (p + j) ∘ s′ (p + j) ≗ r′ (suc p + j)
[5] x = subst (λ z → z x ≡ r′ (suc p + j) x) (sym ([2] (p + j))) refl
[6] : (j p o : ℕ) → f (r′ j zero) ≼ f (r′ (p + suc j) o)
[6] j p o = [13] o
where
t = proj₁ ([3] (suc j) p)
[7] : r′ (suc j) ∘ t ≗ r′ (p + suc j)
[7] = proj₂ (proj₂ ([3] (suc j) p))
[8] : All (f (r′ j zero) ≼_) (f ∘ r′ (suc j))
[8] = r′-spec₄ j
[9] : All (f (r′ j zero) ≼_) ((f ∘ r′ (suc j)) ∘ t)
[9] = all-compose {P = f (r′ j zero) ≼_} t [8]
[10] : (f ∘ r′ (suc j)) ∘ t ≗ f ∘ (r′ (suc j) ∘ t)
[10] = ∘-assoc t (r′ (suc j)) f
[11] : All (f (r′ j zero) ≼_) (f ∘ (r′ (suc j) ∘ t))
[11] = all-extensional {P = f (r′ j zero) ≼_} [10] [9]
[12] : f ∘ (r′ (suc j) ∘ t) ≗ f ∘ r′ (p + suc j)
[12] x = cong f ([7] x)
[13] : All (f (r′ j zero) ≼_) (f ∘ r′ (p + suc j))
[13] = all-extensional {P = f (r′ j zero) ≼_} [12] [11]
r : ℕ → ℕ
r i = r′ i zero
[14] : (i j : ℕ) → i < j → f (r i) ≼ f (r j)
[14] i j i<j = subst (λ z → f (r′ i zero) ≼ f (r′ z zero)) p+suc[i]≡j ([6] i p zero)
where
[15] : ∃[ p ] p + suc i ≡ j
[15] = m<n⇒∃[o]o+suc[m]≡n i<j
p = proj₁ [15]
p+suc[i]≡j : p + suc i ≡ j
p+suc[i]≡j = proj₂ [15]
r-step : (i : ℕ) → r i < r (suc i)
r-step i = r′-spec₃ i
r-increasing : Increasing _<_ r
r-increasing = step-increasing r r-step
-- ascendingSubseq : IsWQO _≼_
-- → Σ[ r ∈ (ℕ → ℕ) ] (Increasing _<_ r × Increasing _≼_ (f ∘ r))
-- ascendingSubseq h =
-- veryGood⇒ascendingSubseq (almostFull-veryGood (almostFull h))
Dickson’s lemma
prodSeq : (ℕ → A) → (ℕ → B) → (ℕ → A × B)
prodSeq f g n = f n , g n
prodOrder : (A → A → Set) → (B → B → Set) → A × B → A × B → Set
prodOrder _≼₁_ _≼₂_ x y = (proj₁ x ≼₁ proj₁ y) × (proj₂ x ≼₂ proj₂ y)
prod-reflexive : (_≼₁_ : A → A → Set) (_≼₂_ : B → B → Set)
→ Reflexive _≼₁_
→ Reflexive _≼₂_
→ Reflexive (prodOrder _≼₁_ _≼₂_)
prod-reflexive _≼₁_ _≼₂_ h₁ h₂ = h₁ , h₂
prod-transitive : (_≼₁_ : A → A → Set) (_≼₂_ : B → B → Set)
→ Transitive _≼₁_
→ Transitive _≼₂_
→ Transitive (prodOrder _≼₁_ _≼₂_)
prod-transitive _≼₁_ _≼₂_ h₁ h₂ xy yz = (h₁ (proj₁ xy) (proj₁ yz)) , h₂ (proj₂ xy) (proj₂ yz)
prod-isQO : (_≼₁_ : A → A → Set) (_≼₂_ : B → B → Set)
→ IsQO _≼₁_
→ IsQO _≼₂_
----------------------------
→ IsQO (prodOrder _≼₁_ _≼₂_)
prod-isQO _≼₁_ _≼₂_ h₁ h₂ =
record
{ reflexive = prod-reflexive _≼₁_ _≼₂_ (reflexive h₁) (reflexive h₂)
; transitive = prod-transitive _≼₁_ _≼₂_ (transitive h₁) (transitive h₂)
}
prod-veryGood : {_≼₁_ : A → A → Set} {_≼₂_ : B → B → Set}
{f : ℕ → A} {g : ℕ → B}
→ VeryGood _≼₁_ f
→ VeryGood _≼₂_ g
----------------------------------------------
→ VeryGood (prodOrder _≼₁_ _≼₂_) (prodSeq f g)
prod-veryGood {_≼₁_ = _≼₁_} {_≼₂_ = _≼₂_} {f = f} {g = g}
f-veryGood g-veryGood r r-increasing
= r₁ i , r₁ j , r₁-increasing i j i<j , ( frr₁i≼₁frr₁j , grr₁i≼₂grr₁j )
where
_≼_ = prodOrder _≼₁_ _≼₂_
f∘r-veryGood : VeryGood _≼₁_ (f ∘ r)
f∘r-veryGood = subseq-veryGood _≼₁_ f r f-veryGood r-increasing
f∘r-ascendingSubseq :
Σ[ r₁ ∈ (ℕ → ℕ) ] Increasing _<_ r₁ × Increasing _≼₁_ (f ∘ r ∘ r₁)
f∘r-ascendingSubseq =
veryGood⇒ascendingSubseq _≼₁_ (f ∘ r)
f∘r-veryGood
r₁ : ℕ → ℕ
r₁ = proj₁ f∘r-ascendingSubseq
r₁-increasing : Increasing _<_ r₁
r₁-increasing = proj₁ (proj₂ f∘r-ascendingSubseq)
f∘r∘r₁-increasing : Increasing _≼₁_ (f ∘ r ∘ r₁)
f∘r∘r₁-increasing = proj₂ (proj₂ f∘r-ascendingSubseq)
r∘r₁-increasing : Increasing _<_ (r ∘ r₁)
r∘r₁-increasing = subseq-increasing _<_ r r₁ r-increasing r₁-increasing
g∘r∘r₁-good : Good _≼₂_ (g ∘ r ∘ r₁)
g∘r∘r₁-good = g-veryGood (r ∘ r₁) r∘r₁-increasing
i j : ℕ
i = proj₁ g∘r∘r₁-good
j = proj₁ (proj₂ g∘r∘r₁-good)
i<j : i < j
i<j = proj₁ (proj₂ (proj₂ g∘r∘r₁-good))
grr₁i≼₂grr₁j : g (r (r₁ i)) ≼₂ g (r (r₁ j))
grr₁i≼₂grr₁j = proj₂ (proj₂ (proj₂ g∘r∘r₁-good))
frr₁i≼₁frr₁j : f (r (r₁ i)) ≼₁ f (r (r₁ j))
frr₁i≼₁frr₁j = f∘r∘r₁-increasing i j i<j
prod-isWQO : (_≼₁_ : A → A → Set) (_≼₂_ : B → B → Set)
→ IsWQO _≼₁_
→ IsWQO _≼₂_
-------------------------------------
→ IsWQO {A × B} (prodOrder _≼₁_ _≼₂_)
prod-isWQO {A = A} {B = B} _≼₁_ _≼₂_ h₁ h₂ =
record
{ isQO = prod-isQO _≼₁_ _≼₂_ (isQO h₁) (isQO h₂)
; almostFull = ≼-almostFull
}
where
_≼_ = prodOrder _≼₁_ _≼₂_
≼-almostFull : (f : ℕ → A × B) → Good _≼_ f
≼-almostFull f = f₁f₂-good
where
f₁ : ℕ → A
f₁ n = proj₁ (f n)
f₂ : ℕ → B
f₂ n = proj₂ (f n)
f₁-veryGood : VeryGood _≼₁_ f₁
f₁-veryGood = almostFull-veryGood _≼₁_ f₁ (almostFull h₁)
f₂-veryGood : VeryGood _≼₂_ f₂
f₂-veryGood = almostFull-veryGood _≼₂_ f₂ (almostFull h₂)
f₁f₂-veryGood : VeryGood (prodOrder _≼₁_ _≼₂_) (prodSeq f₁ f₂)
f₁f₂-veryGood =
prod-veryGood {_≼₁_ = _≼₁_} {_≼₂_ = _≼₂_} {f = f₁} {g = f₂}
-- (transitive (isQO h₁))
f₁-veryGood f₂-veryGood
f₁f₂-good : Good (prodOrder _≼₁_ _≼₂_) (prodSeq f₁ f₂)
f₁f₂-good = veryGood⇒good (prodOrder _≼₁_ _≼₂_) (prodSeq f₁ f₂) f₁f₂-veryGood
Maybe: maybe we should prove a more general lemma about unions?
module M (_≼_ : A → A → Set) where
_≼′_ : Maybe A → Maybe A → Set
just x ≼′ just y = x ≼ y
just x ≼′ nothing = ⊥
nothing ≼′ just y = ⊥
nothing ≼′ nothing = ⊤ -- ??
maybe-almostFull : AlmostFull _≼_ → AlmostFull _≼′_
maybe-almostFull ≼-almostFull f = f-good
where
Inf = (k : ℕ) → Σ[ l ∈ ℕ ] k < l × f l ≡ nothing
Cof = Σ[ k ∈ ℕ ] ((l : ℕ) → k < l → f l ≢ nothing)
h₁ : Inf ⊎ Cof
h₁ = infinite∨finite (λ z → f z ≡ nothing)
f-good : Good _≼′_ f
f-good with h₁
... | inj₁ inf = i , j , i<j , fi≼′fj
where
i j : ℕ
i = proj₁ (inf zero)
j = proj₁ (inf i)
i<j : i < j
i<j = proj₁ (proj₂ (inf i))
fi≡nothing : f i ≡ nothing
fi≡nothing = proj₂ (proj₂ (inf zero))
fj≡nothing : f j ≡ nothing
fj≡nothing = proj₂ (proj₂ (inf i))
fi≼′fj : f i ≼′ f j
fi≼′fj rewrite fi≡nothing | fj≡nothing = tt
... | inj₂ cof = i + suc k , j + suc k , i+1+k<j+1+k , fi+1+k≼′fj+1+k
where
k = proj₁ cof
cof′ : (l : ℕ) → k < l → ∃[ x ] f l ≡ just x
cof′ l k<l with f l in eq
... | just x = x , refl
... | nothing = ⊥-elim (proj₂ cof l k<l eq)
g : (n : ℕ) → ∃[ x ] f (n + suc k) ≡ just x
g n = cof′ (n + suc k) (m≤n+m (suc k) n)
f′ : ℕ → A
f′ n = proj₁ (g n)
f-f′ : (n : ℕ) → f (n + suc k) ≡ just (f′ n)
f-f′ n = proj₂ (g n)
f′-good : Good _≼_ f′
f′-good = ≼-almostFull f′
i j : ℕ
i = proj₁ f′-good
j = proj₁ (proj₂ f′-good)
i<j : i < j
i<j = proj₁ (proj₂ (proj₂ f′-good))
f′i≼f′j : f′ i ≼ f′ j
f′i≼f′j = proj₂ (proj₂ (proj₂ f′-good))
i+1+k<j+1+k : i + suc k < j + suc k
i+1+k<j+1+k = +-monoˡ-< (suc k) i<j
fi+1+k≼′fj+1+k : f (i + suc k) ≼′ f (j + suc k)
fi+1+k≼′fj+1+k rewrite f-f′ i | f-f′ j = f′i≼f′j