A proof of Higman’s lemma about finite sequences.
module Higman where import Relation.Binary.PropositionalEquality as Eq open Eq using (_≡_; refl; _≢_; sym; trans; subst) 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≤1+n) 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 (_∈_; _⊆_) open import Function using (_∘_; id) open import Data.List using (List; []; _∷_; _++_; length) open import Miscellaneous open import Classical open import WQO open import MinimalBadSeqSuffix relation, etc.
private variable
A B : Set
data _⊑_ : List A → List A → Set where
⊑-refl : {xs : List A} → xs ⊑ xs
_∷ʳ_ : {xs ys : List A} (y : A) → xs ⊑ ys → xs ⊑ (y ∷ ys)
⊑-reflexive : Reflexive (_⊑_ {A}) -- {xs : List A} → xs ⊑ xs
⊑-reflexive = ⊑-refl
⊑-transitive : {xs ys zs : List A} → xs ⊑ ys → ys ⊑ zs → xs ⊑ zs
⊑-transitive xs⊑ys ⊑-refl = xs⊑ys
⊑-transitive xs⊑ys (z ∷ʳ ys⊑zs) = z ∷ʳ (⊑-transitive xs⊑ys ys⊑zs)
⊑-length-≤ : {xs ys : List A} → xs ⊑ ys → length xs ≤ length ys
⊑-length-≤ ⊑-refl = ≤-refl
⊑-length-≤ (y ∷ʳ xs⊑ys) = m≤n⇒m≤1+n (⊑-length-≤ xs⊑ys)
⊏-length-< : {xs ys : List A} → (xs ⊑ ys × xs ≢ ys) → length xs < length ys
⊏-length-< (⊑-refl , xs≢xs) = ⊥-elim (xs≢xs refl)
⊏-length-< ((y ∷ʳ xs⊑ys) , xs≢ys) = s≤s (⊑-length-≤ xs⊑ys)
elem-⊑-elem : (x : A) (xs ys : List A) → x elem xs → xs ⊑ ys → x elem ys
elem-⊑-elem x xs .xs [x]elem[xs] ⊑-refl = [x]elem[xs]
elem-⊑-elem x xs (y ∷ ys) [x]elem[xs] (y ∷ʳ xs⊑ys) =
there (elem-⊑-elem x xs ys [x]elem[xs] xs⊑ys)
Sub-⊑-Sub-elem : (f g : ℕ → List A) (k : ℕ → A)
→ g ∈ Sub _⊑_ f
→ k ∈ Sub _elem_ g
----------------
→ k ∈ Sub _elem_ f
Sub-⊑-Sub-elem f g k (r , r-increasing , h₁) (s , s-increasing , h₂) =
r ∘ s ,
(subseq-increasing _<_ r s r-increasing s-increasing) ,
λ n → elem-⊑-elem (k n) (g (s n)) (f (r (s n))) (h₂ n) (h₁ (s n))
Subseq-mono : ((ℕ → B) → (ℕ → A) → Set) → Set
Subseq-mono P = ∀ f (r : ℕ → ℕ) (r-increasing : Increasing _<_ r)
→ P (f ∘ r) ⊆ P f
Sub-Sub-elem : Subseq-mono {B = List A} (Sub _elem_)
Sub-Sub-elem f r r-increasing (r₁ , r₁-increasing , h) =
r ∘ r₁ , (subseq-increasing _<_ r r₁ r-increasing r₁-increasing) , (λ n → h n)
The definition of the embedding relation.
The following definition from Data.List.Relation.Binary.Sublist.Heterogeneous.Core could be used instead.
data Sublist : REL (List A) (List B) (a ⊔ b ⊔ r) where
[] : Sublist [] []
_∷ʳ_ : ∀ {xs ys} → ∀ y → Sublist xs ys → Sublist xs (y ∷ ys)
_∷_ : ∀ {x xs y ys} → R x y → Sublist xs ys → Sublist (x ∷ xs) (y ∷ ys)
module _ (_≼_ : A → A → Set) where
infixr 5 _∷_ _∷ʳ_
data Embedding : List A → List A → Set where
[] : Embedding [] []
_∷ʳ_ : ∀ {xs ys} → ∀ y → Embedding xs ys → Embedding xs (y ∷ ys)
_∷_ : ∀ {x xs y ys} → x ≼ y → Embedding xs ys → Embedding (x ∷ xs) (y ∷ ys)
embedding-reflexive : Reflexive _≼_ → Reflexive Embedding
embedding-reflexive h {[]} = []
embedding-reflexive h {x ∷ xs} = h ∷ embedding-reflexive h
embedding-transitive : Transitive _≼_ → Transitive Embedding
embedding-transitive h xsys [] with xsys
... | [] = []
embedding-transitive h xsys (y ∷ʳ yszs) = y ∷ʳ embedding-transitive h xsys yszs
embedding-transitive h (_ ∷ʳ xsys) (_ ∷ yszs) = _ ∷ʳ embedding-transitive h xsys yszs
embedding-transitive h (x≼y ∷ xsys) (y≼z ∷ yszs) = h x≼y y≼z ∷ embedding-transitive h xsys yszs
[]-Embedding : ∀ xs → Embedding [] xs
[]-Embedding [] = []
[]-Embedding (x ∷ xs) = x ∷ʳ []-Embedding xs
embedding-⊑-embedding : ∀ {xs ys zs} → Embedding xs ys → ys ⊑ zs → Embedding xs zs
embedding-⊑-embedding h ⊑-refl = h
embedding-⊑-embedding h (y ∷ʳ ys⊑zs) = y ∷ʳ embedding-⊑-embedding h ys⊑zs
elem-embedding : ∀ {x xs ys} → x elem xs → Embedding xs ys → ∃[ y ] y elem ys × x ≼ y
elem-embedding h (y ∷ʳ h₁) with elem-embedding h h₁
... | z , h₂ , x≼z = z , there h₂ , x≼z
elem-embedding here (_∷_ {y = y} h₁ h₂) = y , here , h₁
elem-embedding (there h) (h₁ ∷ h₂) with elem-embedding h h₂
... | z , h₃ , x≼z = z , there h₃ , x≼z
tail-⊏ : {x : A} {xs : List A} → xs ⊑ (x ∷ xs) × xs ≢ x ∷ xs
tail-⊏ {x} {xs} = x ∷ʳ ⊑-refl , λ ()
-- ++-Embedding : ∀ {xs ys us vs}
-- → Embedding xs ys
-- → Embedding us vs
-- ---------------------------------
-- → Embedding (xs ++ us) (ys ++ vs)
-- ++-Embedding [] h₂ = h₂
-- ++-Embedding (y ∷ʳ h₁) h₂ = y ∷ʳ ++-Embedding h₁ h₂
-- ++-Embedding (xy ∷ h₁) h₂ = xy ∷ ++-Embedding h₁ h₂
embedding-isQO : IsQO _≼_ → IsQO Embedding
embedding-isQO h =
record
{ reflexive = embedding-reflexive (IsQO.reflexive h)
; transitive = embedding-transitive (IsQO.transitive h)
}
sub-elem-veryGood-good : (f : ℕ → List A)
→ ((g : ℕ → A) → g ∈ Sub _elem_ f → VeryGood _≼_ g)
→ Good Embedding f
sub-elem-veryGood-good f h = ¬¬-elim not-f-bad
where
not-f-bad : ¬ ¬ Good Embedding f
not-f-bad f-bad = contra
where
open MBS {List A} length Embedding _⊑_ ⊑-reflexive {f} f-bad
contra : ⊥
contra = case-⊎ h₁ h₂ (em {∃[ i ] mbs i ≡ []})
where
h₁ : ∃[ i ] mbs i ≡ [] → ⊥
h₁ (i , mbsi≡[]) =
mbs-bad (i , suc i , ≤-refl ,
subst (λ z → Embedding z (mbs (suc i)))
(sym mbsi≡[])
([]-Embedding (mbs (suc i))))
h₂ : ¬ (∃[ i ] mbs i ≡ []) → ⊥
h₂ ¬∃i = mbs-bad (i , j , i<j , emb-mbsi-mbsj)
where
h₃ : (i : ℕ) → mbs i ≢ []
h₃ i mbsi≡[] = ¬∃i (i , mbsi≡[])
h₄ : (i : ℕ) → ∃₂ (λ x xs → mbs i ≡ x ∷ xs)
h₄ i with mbs i in eq
... | [] = ⊥-elim (h₃ i eq)
... | x ∷ xs = x , xs , refl
g₁ : ℕ → A
g₁ n = proj₁ (h₄ n)
g₂ : ℕ → List A
g₂ n = proj₁ (proj₂ (h₄ n))
mbs≡g₁∷g₂ : (n : ℕ) → mbs n ≡ g₁ n ∷ g₂ n
mbs≡g₁∷g₂ n = proj₂ (proj₂ (h₄ n))
g₁∈Sub-elem-mbs : g₁ ∈ Sub _elem_ mbs
g₁∈Sub-elem-mbs = id , id-increasing , h₅
where
h₅ : (n : ℕ) → g₁ n elem mbs n
h₅ n = subst (λ z → (proj₁ (h₄ n)) elem z) (sym (mbs≡g₁∷g₂ n))
(here {x = proj₁ (h₄ n)} {xs = proj₁ (proj₂ (h₄ n))})
g₁∈Sub-elem-f : g₁ ∈ Sub _elem_ f
g₁∈Sub-elem-f = Sub-⊑-Sub-elem f mbs g₁ mbs-sub-⊑ g₁∈Sub-elem-mbs
g₁-veryGood : VeryGood _≼_ g₁
g₁-veryGood = h g₁ g₁∈Sub-elem-f
open Sub-⊑-⊏ ⊏-length-< embedding-⊑-embedding ⊑-transitive
g₂∈Sub-⊏-mbs : g₂ ∈ Sub _⊏_ mbs
g₂∈Sub-⊏-mbs =
id , id-increasing ,
λ n → subst (g₂ n ⊏_) (sym (mbs≡g₁∷g₂ n)) (tail-⊏ {x = g₁ n} {xs = g₂ n})
g₂-veryGood : VeryGood Embedding g₂
g₂-veryGood = Sub-⊏-mbs⇒VeryGood g₂ g₂∈Sub-⊏-mbs
g₁g₂-veryGood : VeryGood (prodOrder _≼_ Embedding) (λ n → g₁ n , g₂ n)
g₁g₂-veryGood =
prod-veryGood {A = A} {B = List A} {_≼₁_ = _≼_} {_≼₂_ = Embedding} {g₁} {g₂}
g₁-veryGood g₂-veryGood
g₁g₂-good : Good (prodOrder _≼_ Embedding) (prodSeq g₁ g₂)
g₁g₂-good = veryGood⇒good (prodOrder _≼_ Embedding) (λ n → g₁ n , g₂ n) g₁g₂-veryGood
i j : ℕ
i = proj₁ g₁g₂-good
j = proj₁ (proj₂ g₁g₂-good)
i<j : i < j
i<j = proj₁ (proj₂ (proj₂ g₁g₂-good))
g₁i≼g₁j : g₁ i ≼ g₁ j
g₁i≼g₁j = proj₁ (proj₂ (proj₂ (proj₂ g₁g₂-good)))
emb-g₂i-g₂j : Embedding (g₂ i) (g₂ j)
emb-g₂i-g₂j = proj₂ (proj₂ (proj₂ (proj₂ g₁g₂-good)))
emb-g₁ig₂i-g₁jg₂j : Embedding (g₁ i ∷ g₂ i) (g₁ j ∷ g₂ j)
emb-g₁ig₂i-g₁jg₂j = g₁i≼g₁j ∷ emb-g₂i-g₂j
emb-mbsi-mbsj : Embedding (mbs i) (mbs j)
emb-mbsi-mbsj =
subst (λ z → Embedding z (mbs j)) (sym (mbs≡g₁∷g₂ i))
(subst (Embedding (g₁ i ∷ g₂ i)) (sym (mbs≡g₁∷g₂ j)) emb-g₁ig₂i-g₁jg₂j)
sub-elem-veryGood-veryGood : (f : ℕ → List A)
→ ((g : ℕ → A) → g ∈ Sub _elem_ f → VeryGood _≼_ g)
→ VeryGood Embedding f
sub-elem-veryGood-veryGood f h =
lemma-good-veryGood {A = List A} {_≼_ = Embedding} P P-closed sub-elem-veryGood-good f h
where
P : (ℕ → List A) → Set
P z = (g : ℕ → A) → g ∈ Sub _elem_ z → VeryGood _≼_ g
P-closed : ClosedUnderSubseq P
P-closed f r r-increasing Pf g g∈Sub-elem-f∘r = Pf g (Sub-Sub-elem f r r-increasing g∈Sub-elem-f∘r)
embedding-isWQO : IsWQO _≼_ → IsWQO Embedding
embedding-isWQO ≼-isWQO =
record
{ isQO = embedding-isQO (IsWQO.isQO ≼-isWQO)
; almostFull = embedding-almostFull
}
where
embedding-almostFull : (f : ℕ → List A) → Good Embedding f
embedding-almostFull f =
sub-elem-veryGood-good f (λ g _ → almostFull-veryGood _≼_ g (IsWQO.almostFull ≼-isWQO))