Skip to content

Some lemmata for non-empty lists #2730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c6da092
[add]: map-id for Data.List.NonEmpty
pmbittner Jun 8, 2025
e5ac9d9
[changelog]: map-id for Data.List.NonEmpty
pmbittner Jun 8, 2025
dff840d
[add]: some lemmata for ⁺++⁺ of Data.List.NonEmpty
pmbittner Jun 8, 2025
ac94640
[changelog]: some lemmata for ⁺++⁺
pmbittner Jun 8, 2025
a4d2bdb
[add]: ∷→∷⁺ and ∷⁺→∷
pmbittner Jun 8, 2025
8141130
[changelog]: ∷→∷⁺ and ∷⁺→∷
pmbittner Jun 8, 2025
b92bc58
[add]: ⁺++⁺-assoc for Data.List.NonEmpty
pmbittner Jun 8, 2025
f308aeb
[changelog]: ⁺++⁺-assoc for Data.List.NonEmpty
pmbittner Jun 8, 2025
7870a46
[add]: ⁺++⁺-cancelˡ for Data.List.Empty
pmbittner Jun 8, 2025
5d295c8
[changelog]: ⁺++⁺-cancelˡ for Data.List.Empty
pmbittner Jun 8, 2025
aeaa101
[add]: ⁺++⁺-cancelʳ for Data.List.Empty
pmbittner Jun 8, 2025
27eb80f
[changelog]: ⁺++⁺-cancelʳ for Data.List.Empty
pmbittner Jun 8, 2025
ba58b75
[add]: ⁺++⁺-cancel for Data.List.NonEmpty
pmbittner Jun 8, 2025
2170c80
[changelog]: ⁺++⁺-cancel for Data.List.NonEmpty
pmbittner Jun 8, 2025
71d1c8c
[add]: map-⁺++⁺
pmbittner Jun 8, 2025
d232bb7
[changelog]: map-⁺++⁺
pmbittner Jun 8, 2025
84a8470
[changelog] remove implicit args in List.NonEmpty
pmbittner Jun 10, 2025
5a5219a
[changelog]: style adaptions for List.NonEmpty
pmbittner Jun 10, 2025
ac3603c
[add]: length-++-≤ in Data.List.Properties
pmbittner Jun 10, 2025
6592e8b
[changelog]: length-++-≤ in Data.List.Properties
pmbittner Jun 10, 2025
3ee0527
[refactor] avoid rewrite in length-⁺++⁺-≤
pmbittner Jun 10, 2025
3f93c6c
[add]: length-++-sucˡ, length-++-sucʳ
pmbittner Jun 15, 2025
d2fccba
[changelog]: length-++-sucˡ, length-++-sucʳ
pmbittner Jun 15, 2025
18a4366
[refactor]: rename length-++-≤ to length-++-≤ˡ
pmbittner Jun 15, 2025
20fd595
[refactor]: anon. modules Data.List.Properties
pmbittner Jun 15, 2025
c868134
[refactor]: move length-++ theorems
pmbittner Jun 15, 2025
4f0a5ea
[add]: length-++-comm
pmbittner Jun 15, 2025
a9827e6
[changelog]: length-++-comm
pmbittner Jun 15, 2025
1274d6a
[add]: length-++-≤ʳ
pmbittner Jun 15, 2025
843eef9
[changelog]: length-++-≤ʳ
pmbittner Jun 15, 2025
726883b
[add]: length-⁺++⁺-≤ʳ
pmbittner Jun 15, 2025
0a9db06
[changelog]: length-⁺++⁺-≤ʳ
pmbittner Jun 15, 2025
8669bad
[add]: length-⁺++⁺-comm
pmbittner Jun 15, 2025
15abb26
[changelog]: length-⁺++⁺-comm
pmbittner Jun 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ Additions to existing modules

* In `Data.List.Properties`:
```agda
length-++-sucˡ : ∀ (x : A) (xs ys : List A) → length (x ∷ xs ++ ys) ≡ suc (length (xs ++ ys))
length-++-sucʳ : ∀ (xs : List A) (y : A) (ys : List A) → length (xs ++ y ∷ ys) ≡ suc (length (xs ++ ys))
length-++-comm : ∀ (xs ys : List A) → length (xs ++ ys) ≡ length (ys ++ xs)
length-++-≤ˡ : ∀ (xs : List A) → length xs ≤ length (xs ++ ys)
length-++-≤ʳ : ∀ (ys : List A) → length ys ≤ length (xs ++ ys)
map-applyUpTo : ∀ (f : ℕ → A) (g : A → B) n → map g (applyUpTo f n) ≡ applyUpTo (g ∘ f) n
map-applyDownFrom : ∀ (f : ℕ → A) (g : A → B) n → map g (applyDownFrom f n) ≡ applyDownFrom (g ∘ f) n
map-upTo : ∀ (f : ℕ → A) n → map f (upTo n) ≡ applyUpTo f n
Expand All @@ -276,6 +281,24 @@ Additions to existing modules
filter-↭ : ∀ (P? : Pred.Decidable P) → xs ↭ ys → filter P? xs ↭ filter P? ys
```

* In `Data.List.NonEmpty.Properties`:
```agda
∷→∷⁺ : (x List.∷ xs) ≡ (y List.∷ ys) →
(x List⁺.∷ xs) ≡ (y List⁺.∷ ys)
∷⁺→∷ : (x List⁺.∷ xs) ≡ (y List⁺.∷ ys) →
(x List.∷ xs) ≡ (y List.∷ ys)
length-⁺++⁺ : (xs ys : List⁺ A) → length (xs ⁺++⁺ ys) ≡ length xs + length ys
length-⁺++⁺-comm : ∀ (xs ys : List⁺ A) → length (xs ⁺++⁺ ys) ≡ length (ys ⁺++⁺ xs)
length-⁺++⁺-≤ˡ : (xs ys : List⁺ A) → length xs ≤ length (xs ⁺++⁺ ys)
length-⁺++⁺-≤ʳ : (xs ys : List⁺ A) → length ys ≤ length (xs ⁺++⁺ ys)
map-⁺++⁺ : ∀ (f : A → B) xs ys → map f (xs ⁺++⁺ ys) ≡ map f xs ⁺++⁺ map f ys
⁺++⁺-assoc : Associative _⁺++⁺_
⁺++⁺-cancelˡ : LeftCancellative _⁺++⁺_
⁺++⁺-cancelʳ : RightCancellative _⁺++⁺_
⁺++⁺-cancel : Cancellative _⁺++⁺_
map-id : map id ≗ id {A = List⁺ A}
```

* In `Data.Product.Function.Dependent.Propositional`:
```agda
Σ-↪ : (I↪J : I ↪ J) → (∀ {j} → A (from I↪J j) ↪ B j) → Σ I A ↪ Σ J B
Expand Down
62 changes: 59 additions & 3 deletions src/Data/List/NonEmpty/Properties.agda
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,28 @@

module Data.List.NonEmpty.Properties where

import Algebra.Definitions as AlgebraicDefinitions
open import Effect.Monad using (RawMonad)
open import Data.Nat.Base using (suc; _+_)
open import Data.Nat.Base using (suc; _+_; _≤_; s≤s)
open import Data.Nat.Properties using (suc-injective)
open import Data.Maybe.Properties using (just-injective)
open import Data.Bool.Base using (Bool; true; false)
open import Data.List.Base as List using (List; []; _∷_; _++_)
open import Data.List.Effectful using () renaming (monad to listMonad)
open import Data.List.Properties using (length-++; length-++-comm; length-++-≤ˡ; length-++-≤ʳ; ++-assoc; map-++)
open import Data.List.NonEmpty.Effectful using () renaming (monad to list⁺Monad)
open import Data.List.NonEmpty
open import Data.List.NonEmpty as List⁺
using (List⁺; _∷_; tail; head; toList; _⁺++_; _⁺++⁺_; _++⁺_; length; fromList;
drop+; map; inits; tails; groupSeqs; ungroupSeqs)
open import Data.List.NonEmpty.Relation.Unary.All using (All; toList⁺; _∷_)
open import Data.List.Relation.Unary.All using ([]; _∷_) renaming (All to ListAll)
import Data.List.Properties as List
open import Data.Product.Base using (_,_)
open import Data.Sum.Base using (inj₁; inj₂)
open import Data.Sum.Relation.Unary.All using (inj₁; inj₂)
import Data.Sum.Relation.Unary.All as Sum using (All; inj₁; inj₂)
open import Level using (Level)
open import Function.Base using (_∘_; _$_)
open import Function.Base using (id; _∘_; _$_)
open import Relation.Binary.PropositionalEquality.Core
using (_≡_; refl; cong; cong₂; _≗_)
open import Relation.Binary.PropositionalEquality.Properties
Expand Down Expand Up @@ -69,6 +72,56 @@ toList->>= f (x ∷ xs) = begin
List.concat (List.map toList (List.map f (x ∷ xs)))

-- turning equalities of lists that are not empty to equalities on non-empty lists ...
∷→∷⁺ : ∀ {x y : A} {xs ys : List A} →
(x List.∷ xs) ≡ (y List.∷ ys) →
(x List⁺.∷ xs) ≡ (y List⁺.∷ ys)
∷→∷⁺ refl = refl

-- ... and vice versa
∷⁺→∷ : ∀ {x y : A} {xs ys : List A} →
(x List⁺.∷ xs) ≡ (y List⁺.∷ ys) →
(x List.∷ xs) ≡ (y List.∷ ys)
∷⁺→∷ refl = refl

------------------------------------------------------------------------
-- _⁺++⁺_

length-⁺++⁺ : (xs ys : List⁺ A) →
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor but can we have an empty line between this lemm and the section heading?

length (xs ⁺++⁺ ys) ≡ length xs + length ys
length-⁺++⁺ (x ∷ xs) (y ∷ ys) = length-++ (x ∷ xs)

length-⁺++⁺-comm : ∀ (xs ys : List⁺ A) →
length (xs ⁺++⁺ ys) ≡ length (ys ⁺++⁺ xs)
length-⁺++⁺-comm (x ∷ xs) (y ∷ ys) = length-++-comm (x ∷ xs) (y ∷ ys)

length-⁺++⁺-≤ˡ : (xs ys : List⁺ A) →
length xs ≤ length (xs ⁺++⁺ ys)
length-⁺++⁺-≤ˡ (x ∷ xs) (y ∷ ys) = s≤s (length-++-≤ˡ xs)

length-⁺++⁺-≤ʳ : (xs ys : List⁺ A) →
length ys ≤ length (xs ⁺++⁺ ys)
length-⁺++⁺-≤ʳ (x ∷ xs) (y ∷ ys) = length-++-≤ʳ (y ∷ ys) {x ∷ xs}

map-⁺++⁺ : ∀ (f : A → B) xs ys →
map f (xs ⁺++⁺ ys) ≡ map f xs ⁺++⁺ map f ys
map-⁺++⁺ f (x ∷ xs) (y ∷ ys) = ∷→∷⁺ (map-++ f (x ∷ xs) (y ∷ ys))

module _ {A : Set a} where
open AlgebraicDefinitions {A = List⁺ A} _≡_

⁺++⁺-assoc : Associative _⁺++⁺_
⁺++⁺-assoc (x ∷ xs) (y ∷ ys) (z ∷ zs) = cong (x ∷_) (++-assoc xs (y ∷ ys) (z ∷ zs))

⁺++⁺-cancelˡ : LeftCancellative _⁺++⁺_
⁺++⁺-cancelˡ (x ∷ xs) (y ∷ ys) (z ∷ zs) eq = ∷→∷⁺ (List.++-cancelˡ (x ∷ xs) (y ∷ ys) (z ∷ zs) (∷⁺→∷ eq))

⁺++⁺-cancelʳ : RightCancellative _⁺++⁺_
⁺++⁺-cancelʳ (x ∷ xs) (y ∷ ys) (z ∷ zs) eq = ∷→∷⁺ (List.++-cancelʳ (x ∷ xs) (y ∷ ys) (z ∷ zs) (∷⁺→∷ eq))

⁺++⁺-cancel : Cancellative _⁺++⁺_
⁺++⁺-cancel = ⁺++⁺-cancelˡ , ⁺++⁺-cancelʳ

------------------------------------------------------------------------
-- _++⁺_

Expand Down Expand Up @@ -118,6 +171,9 @@ map-cong f≗g (x ∷ xs) = cong₂ _∷_ (f≗g x) (List.map-cong f≗g xs)
map-∘ : {g : B → C} {f : A → B} → map (g ∘ f) ≗ map g ∘ map f
map-∘ (x ∷ xs) = cong (_ ∷_) (List.map-∘ xs)

map-id : map id ≗ id {A = List⁺ A}
map-id (x ∷ xs) = cong (x ∷_) (List.map-id xs)

------------------------------------------------------------------------
-- inits

Expand Down
42 changes: 41 additions & 1 deletion src/Data/List/Properties.agda
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ length-++ (x ∷ xs) = cong suc (length-++ xs)
module _ {A : Set a} where

open AlgebraicDefinitions {A = List A} _≡_
open AlgebraicStructures {A = List A} _≡_

++-assoc : Associative _++_
++-assoc [] ys zs = refl
Expand Down Expand Up @@ -190,6 +189,47 @@ module _ {A : Set a} where
++-conical : Conical [] _++_
++-conical = ++-conicalˡ , ++-conicalʳ

length-++-sucˡ : ∀ (x : A) (xs ys : List A) →
length (x ∷ xs ++ ys) ≡ suc (length (xs ++ ys))
length-++-sucˡ _ _ _ = refl

length-++-sucʳ : ∀ (xs : List A) (y : A) (ys : List A) →
length (xs ++ y ∷ ys) ≡ suc (length (xs ++ ys))
length-++-sucʳ [] _ _ = refl
length-++-sucʳ (_ ∷ xs) y ys = cong suc (length-++-sucʳ xs y ys)

length-++-comm : ∀ (xs ys : List A) →
length (xs ++ ys) ≡ length (ys ++ xs)
length-++-comm xs [] = cong length (++-identityʳ xs)
length-++-comm [] (y ∷ ys) = sym (cong length (++-identityʳ (y ∷ ys)))
length-++-comm (x ∷ xs) (y ∷ ys) =
begin
length (x ∷ xs ++ y ∷ ys)
≡⟨⟩
suc (length (xs ++ y ∷ ys))
≡⟨ cong suc (length-++-sucʳ xs y ys) ⟩
suc (suc (length (xs ++ ys)))
≡⟨ cong suc (cong suc (length-++-comm xs ys)) ⟩
suc (suc (length (ys ++ xs)))
≡⟨ cong suc (length-++-sucʳ ys x xs) ⟨
suc (length (ys ++ x ∷ xs))
≡⟨⟩
length (y ∷ ys ++ x ∷ xs)

length-++-≤ˡ : ∀ (xs : List A) {ys} →
length xs ≤ length (xs ++ ys)
length-++-≤ˡ [] = z≤n
length-++-≤ˡ (x ∷ xs) = s≤s (length-++-≤ˡ xs)

length-++-≤ʳ : ∀ (ys : List A) {xs} →
length ys ≤ length (xs ++ ys)
length-++-≤ʳ ys {xs} = ≤-trans (length-++-≤ˡ ys) (≤-reflexive (length-++-comm ys xs))

module _ {A : Set a} where

open AlgebraicStructures {A = List A} _≡_

++-isMagma : IsMagma _++_
++-isMagma = record
{ isEquivalence = isEquivalence
Expand Down