Source code on Github{-# OPTIONS --safe #-}
module Prelude.Lists.Membership where
open import Prelude.Init; open SetAsType
open L.Mem
open import Prelude.General
open import Prelude.InferenceRules
open import Prelude.Null
open import Prelude.Lists.Core
open import Prelude.Lists.Indexed
open import Prelude.Lists.Empty
private variable
A : Type ℓ; B : Type ℓ′; C : Type ℓ″
x x′ y : A; xs ys : List A
P Q : Pred A ℓ
module _ {A : Type ℓ} {P : Pred A ℓ′} {xs : List A} where
Is-here Is-there : Pred₀ (Any P xs)
Is-here = λ where
(here _) → ⊤
(there _) → ⊥
Is-there = λ where
(here _) → ⊥
(there _) → ⊤
Any-++⁻∘Any-++⁺ˡ : (x∈ : Any P xs)
→ L.Any.++⁻ xs {ys} (L.Any.++⁺ˡ {xs = xs}{ys} x∈)
≡ inj₁ x∈
Any-++⁻∘Any-++⁺ˡ (here _) = refl
Any-++⁻∘Any-++⁺ˡ {ys = ys} (there x∈) rewrite Any-++⁻∘Any-++⁺ˡ {ys = ys} x∈ = refl
Any-++⁻∘Any-++⁺ʳ : (y∈ : Any P ys)
→ L.Any.++⁻ xs {ys} (L.Any.++⁺ʳ xs {ys} y∈)
≡ inj₂ y∈
Any-++⁻∘Any-++⁺ʳ {xs = []} _ = refl
Any-++⁻∘Any-++⁺ʳ {xs = _ ∷ xs} y∈ rewrite Any-++⁻∘Any-++⁺ʳ {xs = xs} y∈ = refl
Any-++⁻⇒Any-++⁺ : ∀ {xs ys : List A}
→ (x∈ : Any P (xs ++ ys))
→ case L.Any.++⁻ xs {ys} x∈ of λ where
(inj₁ x∈ˡ) → x∈ ≡ L.Any.++⁺ˡ x∈ˡ
(inj₂ x∈ʳ) → x∈ ≡ L.Any.++⁺ʳ xs x∈ʳ
Any-++⁻⇒Any-++⁺ {xs = []} x∈ = refl
Any-++⁻⇒Any-++⁺ {xs = x ∷ xs} {ys} (here _) = refl
Any-++⁻⇒Any-++⁺ {xs = x ∷ xs} {ys} (there x∈)
with IH ← Any-++⁻⇒Any-++⁺ {xs = xs}{ys} x∈
with L.Any.++⁻ xs x∈
... | inj₁ x∈ˡ = cong there IH
... | inj₂ x∈ʳ = cong there IH
destruct-Any-++ : ∀ {xs ys : List A}
→ (x∈ : Any P (xs ++ ys))
→ (∃ λ (x∈ˡ : Any P xs) → x∈ ≡ L.Any.++⁺ˡ x∈ˡ)
⊎ (∃ λ (x∈ʳ : Any P ys) → x∈ ≡ L.Any.++⁺ʳ xs x∈ʳ)
destruct-Any-++ {xs = xs}{ys} x∈
with L.Any.++⁻ xs {ys} x∈ | Any-++⁻⇒Any-++⁺ {xs = xs}{ys} x∈
... | inj₁ x∈ˡ | refl = inj₁ $ -, refl
... | inj₂ x∈ʳ | refl = inj₂ $ -, refl
destruct-Any-++² : ∀ {xs ys zs : List A}
→ (x∈ : Any P (xs ++ ys ++ zs))
→ (∃ λ (x∈xs : Any P xs) → x∈ ≡ (L.Any.++⁺ˡ x∈xs))
⊎ (∃ λ (x∈ys : Any P ys) → x∈ ≡ (L.Any.++⁺ʳ xs $ L.Any.++⁺ˡ x∈ys))
⊎ (∃ λ (x∈zs : Any P zs) → x∈ ≡ (L.Any.++⁺ʳ xs $ L.Any.++⁺ʳ ys x∈zs))
destruct-Any-++² {xs = xs}{ys} x∈
with destruct-Any-++ {xs = xs} x∈
... | inj₁ (_ , refl) = inj₁ $ -, refl
... | inj₂ (x∈ʳ , refl)
with destruct-Any-++ {xs = ys} x∈ʳ
... | inj₁ (_ , refl) = inj₂ $ inj₁ $ -, refl
... | inj₂ (_ , refl) = inj₂ $ inj₂ $ -, refl
∈-++⁻∘∈-++⁺ˡ : (x∈ : x ∈ xs)
→ ∈-++⁻ xs {ys} (∈-++⁺ˡ {xs = xs}{ys} x∈)
≡ inj₁ x∈
∈-++⁻∘∈-++⁺ˡ = Any-++⁻∘Any-++⁺ˡ
∈-++⁻∘∈-++⁺ʳ : (y∈ : y ∈ ys)
→ ∈-++⁻ xs {ys} (∈-++⁺ʳ xs {ys} y∈)
≡ inj₂ y∈
∈-++⁻∘∈-++⁺ʳ = Any-++⁻∘Any-++⁺ʳ
∈-++⁻⇒∈-++⁺ˡ : ∀ {xs ys : List A}
→ (x∈ : x ∈ xs ++ ys)
→ case ∈-++⁻ xs {ys} x∈ of λ where
(inj₁ x∈ˡ) → x∈ ≡ ∈-++⁺ˡ x∈ˡ
(inj₂ x∈ʳ) → x∈ ≡ ∈-++⁺ʳ xs x∈ʳ
∈-++⁻⇒∈-++⁺ˡ {xs = xs} x∈ with ∈-++⁻ xs x∈ | Any-++⁻⇒Any-++⁺ {xs = xs} x∈
... | inj₁ _ | p = p
... | inj₂ _ | p = p
destruct-∈-++ : ∀ {xs ys : List A}
→ (x∈ : x ∈ xs ++ ys)
→ (∃ λ (x∈ˡ : x ∈ xs) → x∈ ≡ ∈-++⁺ˡ x∈ˡ)
⊎ (∃ λ (x∈ʳ : x ∈ ys) → x∈ ≡ ∈-++⁺ʳ xs x∈ʳ)
destruct-∈-++ = destruct-Any-++
destruct-∈-++² : ∀ {xs ys zs : List A}
→ (x∈ : x ∈ xs ++ ys ++ zs)
→ (∃ λ (x∈xs : x ∈ xs) → x∈ ≡ (∈-++⁺ˡ x∈xs))
⊎ (∃ λ (x∈ys : x ∈ ys) → x∈ ≡ (∈-++⁺ʳ xs $ ∈-++⁺ˡ x∈ys))
⊎ (∃ λ (x∈zs : x ∈ zs) → x∈ ≡ (∈-++⁺ʳ xs $ ∈-++⁺ʳ ys x∈zs))
destruct-∈-++² = destruct-Any-++²
⊆-tail : x ∷ xs ⊆ ys → xs ⊆ ys
⊆-tail = _∘ there
module _ {P : Pred A ℓ} (P? : Decidable¹ P) where
⊆-filter : xs ⊆ ys → filter P? xs ⊆ filter P? ys
⊆-filter {xs = xs}{ys} xs⊆ y∈ =
let x∈ , Px = ∈-filter⁻ P? y∈
in ∈-filter⁺ P? (xs⊆ x∈) Px
destruct-∈-filter : ∀ {x xs} (x∈ : x ∈ xs) (Px : P x) →
∈-filter⁻ P? (∈-filter⁺ P? x∈ Px) .proj₁ ≡ x∈
destruct-∈-filter {x} (here refl) Px rewrite dec-yes (P? x) Px .proj₂ = refl
destruct-∈-filter (there {x = y} x∈) Px
with IH ← destruct-∈-filter x∈ Px
with P? y
... | yes p = cong there IH
... | no ¬p = cong there IH
∈-map⁻inverseˡ : ∀ (f : A → B) (f⁻¹ : B → A) →
∙ Inverse≡ˡ {A = B} f⁻¹ f
∙ y ∈ map f xs
───────────────────────
f⁻¹ y ∈ xs
∈-map⁻inverseˡ {xs = xs} f f⁻¹ inv y∈ =
let x , x∈ , eq = ∈-map⁻ f y∈
in subst (_∈ xs) (sym $ trans (cong f⁻¹ eq) (inv _)) x∈
∈-mapWith∈⁻ : ∀ {xs : List A} {f : ∀ {x} → x ∈ xs → B} {y : B}
→ y ∈ mapWith∈ xs f
→ ∃ λ x → Σ (x ∈ xs) λ x∈ → y ≡ f {x} x∈
∈-mapWith∈⁻ {xs = x ∷ _} (here refl) = x , here refl , refl
∈-mapWith∈⁻ {xs = x ∷ xs} (there p) = let x , x∈ , y≡ = ∈-mapWith∈⁻ p in x , there x∈ , y≡
mapWith∈-∀ : ∀ {xs : List A} {f : ∀ {x : A} → x ∈ xs → B} {P : B → Type}
→ (∀ {x} x∈ → P (f {x} x∈))
→ (∀ {y} → y ∈ mapWith∈ xs f → P y)
mapWith∈-∀ {xs = x ∷ xs} ∀P {y} (here px) rewrite px = ∀P (L.Any.here refl)
mapWith∈-∀ {xs = x ∷ xs} ∀P {y} (there y∈) = mapWith∈-∀ (∀P ∘ L.Any.there) y∈
map∘mapWith∈ : ∀ {A B C : Type}
(g : B → C) (xs : List A) (f : ∀ {x} → x ∈ xs → B)
→ map g (mapWith∈ xs f) ≡ mapWith∈ xs (g ∘ f)
map∘mapWith∈ _ [] _ = refl
map∘mapWith∈ _ (_ ∷ _) f = cong (_ ∷_) $ map∘mapWith∈ _ _ (f ∘ there)
mapWith∈∘map : ∀ {A B C : Type}
(f : A → B) (xs : List A) (g : ∀ {x} → x ∈ map f xs → C)
→ mapWith∈ (map f xs) g ≡ mapWith∈ xs (g ∘ ∈-map⁺ f)
mapWith∈∘map _ [] _ = refl
mapWith∈∘map _ (_ ∷ _) g = cong (_ ∷_) $ mapWith∈∘map _ _ (g ∘ there)
unique-∈ : Unique (x ∷ xs) → x ∉ xs
unique-∈ {xs = []} u ()
unique-∈ {xs = x ∷ xs} ((x≢x ∷ _) ∷ _) (here refl) = x≢x refl
unique-∈ {xs = x ∷ xs} ((_ ∷ p) ∷ _) (there x∈) = L.All.All¬⇒¬Any p x∈
Unique-mapWith∈ : ∀ {A B : Type} {xs : List A} {f : ∀ {x} → x ∈ xs → B}
→ (∀ {x x′} {x∈ : x ∈ xs} {x∈′ : x′ ∈ xs} → f x∈ ≡ f x∈′ → L.Any.index x∈ ≡ L.Any.index x∈′)
→ Unique (mapWith∈ xs f)
Unique-mapWith∈ {xs = []} {f = f} f≡ = []
Unique-mapWith∈ {xs = x ∷ xs} {f = f} f≡
= L.All.tabulate (mapWith∈-∀ {P = f (L.Any.here refl) ≢_} λ _ eq → case f≡ eq of λ () )
∷ Unique-mapWith∈ {xs = xs} (F.suc-injective ∘ f≡)
All∉[] : All (_∉ []) ys
All∉[] {ys = []} = []
All∉[] {ys = y ∷ ys} = (λ ()) ∷ All∉[] {ys = ys}
Any-front : ∀ {P : Pred₀ A} {xs : List A} → Any P xs → List A
Any-front {xs = xs} x∈ = take (indexℕ x∈) xs
Any-tail : ∀ {P : Pred₀ A} {xs : List A} → Any P xs → List A
Any-tail {xs = xs} x∈ = drop (suc $ indexℕ x∈) xs
lookup∈ : (p : Any P xs) → L.Any.lookup p ∈ xs
lookup∈ = λ where
(here _) → here refl
(there p) → there $′ lookup∈ p
⊆-resp-Any : _⊆_ Respects˘ (Any P)
⊆-resp-Any xs⊆ = λ where
(here px) → L.Any.map (λ{ refl → px }) (xs⊆ $ here refl)
(there p) → ⊆-resp-Any (xs⊆ ∘ there) p
∈-drop⁻ : ∀ {n} {A : Type} {x : A} {xs : List A}
→ x ∈ drop n xs
→ x ∈ xs
∈-drop⁻ {n = 0} x∈ = x∈
∈-drop⁻ {n = suc n} {xs = _ ∷ xs} x∈ = there $ ∈-drop⁻ {n = n} x∈
splitAt-∈-++⁺ˡ :
(x∈ : x ∈ xs)
→ splitAtˡ (ys ++ xs) (index⁺ $ ∈-++⁺ʳ ys x∈)
≡ ys ++ splitAtˡ xs (index⁺ x∈)
splitAt-∈-++⁺ˡ {ys = []} _ = refl
splitAt-∈-++⁺ˡ {ys = y ∷ ys} x∈ = cong (y ∷_) (splitAt-∈-++⁺ˡ {ys = ys} x∈)
splitAt-∈-++⁺ʳ :
(x∈ : x ∈ xs)
→ splitAtʳ xs (index⁺ x∈)
≡ splitAtʳ (ys ++ xs) (index⁺ $ ∈-++⁺ʳ ys x∈)
splitAt-∈-++⁺ʳ {ys = []} _ = refl
splitAt-∈-++⁺ʳ {ys = _ ∷ ys} x∈ = splitAt-∈-++⁺ʳ {ys = ys} x∈
indexℕ-++⁺ˡ : (x∈ : x ∈ xs) → indexℕ (∈-++⁺ˡ {ys = ys} x∈) ≡ indexℕ x∈
indexℕ-++⁺ˡ = λ where
(here _) → refl
(there x∈) → cong suc (indexℕ-++⁺ˡ x∈)
LastAny : ∀ {A : Type ℓ} {P : Pred A ℓ′} {xs : List A} → Pred (Any P xs) ℓ
LastAny (there p) = LastAny p
LastAny {xs = _ ∷ xs} (here _) = Null xs
Last∈ : Pred (x ∈ xs) _
Last∈ = LastAny
Last∈-there⁺ : ∀ (x∈ : x ∈ xs) → Last∈ x∈ → Last∈ (there {x = x′} x∈)
Last∈-there⁺ _ = id
module _ (f : P ⊆¹ Q) where
LastAny-map⁺ :
(p : Any P xs)
→ LastAny p
→ LastAny (L.Any.map f p)
LastAny-map⁺ (here _) = id
LastAny-map⁺ (there p) = LastAny-map⁺ p
LastAny-map⁻ :
(p : Any P xs)
→ LastAny (L.Any.map f p)
→ LastAny p
LastAny-map⁻ (here _) = id
LastAny-map⁻ (there p) = LastAny-map⁻ p
module _ (f : A → B) (P : Pred B ℓ) where
LastAny-map⁺⁺ :
(p : Any (P ∘ f) xs)
→ LastAny p
→ LastAny (L.Any.map⁺ {P = P} p)
LastAny-map⁺⁺ (here _) refl = refl
LastAny-map⁺⁺ (there p) lp = LastAny-map⁺⁺ p lp
Last∈-map⁺ : ∀ (f : A → B) (x∈ : x ∈ xs) →
Last∈ x∈
───────────────────
Last∈ (∈-map⁺ f x∈)
Last∈-map⁺ f (here _) refl = refl
Last∈-map⁺ f (there p) lp = Last∈-map⁺ f p lp
∉-++⁻ :
x ∉ xs ++ ys
───────────────────
(x ∉ xs) × (x ∉ ys)
∉-++⁻ x∉ = (x∉ ∘ ∈-++⁺ˡ) , (x∉ ∘ ∈-++⁺ʳ _)
∉-++⁻ˡ : x ∉ xs ++ ys → x ∉ xs
∉-++⁻ˡ = proj₁ ∘ ∉-++⁻
∉-++⁻ʳ : x ∉ xs ++ ys → x ∉ ys
∉-++⁻ʳ = proj₂ ∘ ∉-++⁻
∉-++⁺ :
∙ x ∉ xs
∙ x ∉ ys
────────────
x ∉ xs ++ ys
∉-++⁺ x∉ˡ x∉ʳ = ∈-++⁻ _ >≡> Sum.[ x∉ˡ , x∉ʳ ]
∉-∷⁺ : y ≢ x → y ∉ xs → y ∉ x ∷ xs
∉-∷⁺ y≢ y∉ = λ where
(here refl) → y≢ refl
(there y∈) → y∉ y∈
∉-∷⁻ : y ∉ x ∷ xs → y ≢ x × y ∉ xs
∉-∷⁻ y∉ = (λ where refl → y∉ $ here refl) , y∉ ∘ there
module _ (P? : Decidable¹ P) where
∉-filter⁻ : x ∉ filter P? xs → P x → x ∉ xs
∉-filter⁻ x∉ px = x∉ ∘ flip (∈-filter⁺ P?) px
∉-filter⁺ : x ∉ xs → x ∉ filter P? xs
∉-filter⁺ = _∘ (proj₁ ∘ ∈-filter⁻ P?)
private variable
a : A; b : B
abs abs′ : List (A ⊎ B)
∈-partitionSums⁺ˡ ∈-lefts⁺ : inj₁ a ∈ abs → a ∈ lefts abs
∈-partitionSums⁺ˡ {abs = inj₁ _ ∷ _} (here refl) = here refl
∈-partitionSums⁺ˡ {abs = inj₁ _ ∷ _} (there a∈) = there $ ∈-partitionSums⁺ˡ a∈
∈-partitionSums⁺ˡ {abs = inj₂ _ ∷ _} (there a∈) = ∈-partitionSums⁺ˡ a∈
∈-lefts⁺ = ∈-partitionSums⁺ˡ
∈-partitionSums⁺ʳ ∈-rights⁺ : inj₂ b ∈ abs → b ∈ rights abs
∈-partitionSums⁺ʳ {abs = inj₂ _ ∷ _} (here refl) = here refl
∈-partitionSums⁺ʳ {abs = inj₁ _ ∷ _} (there b∈) = ∈-partitionSums⁺ʳ b∈
∈-partitionSums⁺ʳ {abs = inj₂ _ ∷ _} (there b∈) = there $ ∈-partitionSums⁺ʳ b∈
∈-rights⁺ = ∈-partitionSums⁺ʳ
∈-partitionSums⁻ˡ ∈-lefts⁻ : a ∈ lefts abs → inj₁ a ∈ abs
∈-partitionSums⁻ˡ {abs = inj₁ _ ∷ _} (here refl) = here refl
∈-partitionSums⁻ˡ {abs = inj₁ _ ∷ _} (there a∈) = there $′ ∈-partitionSums⁻ˡ a∈
∈-partitionSums⁻ˡ {abs = inj₂ _ ∷ _} a∈ = there $′ ∈-partitionSums⁻ˡ a∈
∈-lefts⁻ = ∈-partitionSums⁻ˡ
∈-partitionSums⁻ʳ ∈-rights⁻ : b ∈ rights abs → inj₂ b ∈ abs
∈-partitionSums⁻ʳ {abs = inj₁ _ ∷ _} b∈ = there $′ ∈-partitionSums⁻ʳ b∈
∈-partitionSums⁻ʳ {abs = inj₂ _ ∷ _} (here refl) = here refl
∈-partitionSums⁻ʳ {abs = inj₂ _ ∷ _} (there b∈) = there $′ ∈-partitionSums⁻ʳ b∈
∈-rights⁻ = ∈-partitionSums⁻ʳ