# Concatenation of lists ```agda module lists.concatenation-lists where ``` <details><summary>Imports</summary> ```agda open import elementary-number-theory.addition-natural-numbers open import elementary-number-theory.natural-numbers open import foundation.action-on-identifications-functions open import foundation.dependent-pair-types open import foundation.function-types open import foundation.identity-types open import foundation.sets open import foundation.universe-levels open import group-theory.monoids open import lists.lists ``` </details> ## Idea Two lists can be concatenated to form a single list. ## Definition ```agda concat-list : {l : Level} {A : UU l} → list A → (list A → list A) concat-list {l} {A} = fold-list id (λ a f → (cons a) ∘ f) ``` ## Properties ### List concatenation is associative and unital Concatenation of lists is an associative operation and nil is the unit for list concatenation. ```agda associative-concat-list : {l1 : Level} {A : UU l1} (x y z : list A) → Id (concat-list (concat-list x y) z) (concat-list x (concat-list y z)) associative-concat-list nil y z = refl associative-concat-list (cons a x) y z = ap (cons a) (associative-concat-list x y z) left-unit-law-concat-list : {l1 : Level} {A : UU l1} (x : list A) → Id (concat-list nil x) x left-unit-law-concat-list x = refl right-unit-law-concat-list : {l1 : Level} {A : UU l1} (x : list A) → Id (concat-list x nil) x right-unit-law-concat-list nil = refl right-unit-law-concat-list (cons a x) = ap (cons a) (right-unit-law-concat-list x) list-Monoid : {l : Level} (X : Set l) → Monoid l list-Monoid X = pair ( pair (list-Set X) (pair concat-list associative-concat-list)) ( pair nil (pair left-unit-law-concat-list right-unit-law-concat-list)) ``` ### `snoc`-law for list concatenation ```agda snoc-concat-list : {l1 : Level} {A : UU l1} (x y : list A) (a : A) → snoc (concat-list x y) a = concat-list x (snoc y a) snoc-concat-list nil y a = refl snoc-concat-list (cons b x) y a = ap (cons b) (snoc-concat-list x y a) ``` ### The length of a concatenation of two lists is the sum of the length of the two lists ```agda length-concat-list : {l1 : Level} {A : UU l1} (x y : list A) → Id (length-list (concat-list x y)) ((length-list x) +ℕ (length-list y)) length-concat-list nil y = inv (left-unit-law-add-ℕ (length-list y)) length-concat-list (cons a x) y = ( ap succ-ℕ (length-concat-list x y)) ∙ ( inv (left-successor-law-add-ℕ (length-list x) (length-list y))) ``` ### An `η`-rule for lists ```agda eta-list : {l1 : Level} {A : UU l1} (x : list A) → Id (concat-list (head-list x) (tail-list x)) x eta-list nil = refl eta-list (cons a x) = refl eta-list' : {l1 : Level} {A : UU l1} (x : list A) → Id (concat-list (remove-last-element-list x) (last-element-list x)) x eta-list' nil = refl eta-list' (cons a nil) = refl eta-list' (cons a (cons b x)) = ap (cons a) (eta-list' (cons b x)) ``` ### Heads and tails of concatenated lists ```agda head-concat-list : {l1 : Level} {A : UU l1} (x y : list A) → Id ( head-list (concat-list x y)) ( head-list (concat-list (head-list x) (head-list y))) head-concat-list nil nil = refl head-concat-list nil (cons x y) = refl head-concat-list (cons a x) y = refl tail-concat-list : {l1 : Level} {A : UU l1} (x y : list A) → Id ( tail-list (concat-list x y)) ( concat-list (tail-list x) (tail-list (concat-list (head-list x) y))) tail-concat-list nil y = refl tail-concat-list (cons a x) y = refl last-element-concat-list : {l1 : Level} {A : UU l1} (x y : list A) → Id ( last-element-list (concat-list x y)) ( last-element-list ( concat-list (last-element-list x) (last-element-list y))) last-element-concat-list nil nil = refl last-element-concat-list nil (cons b nil) = refl last-element-concat-list nil (cons b (cons c y)) = last-element-concat-list nil (cons c y) last-element-concat-list (cons a nil) nil = refl last-element-concat-list (cons a nil) (cons b nil) = refl last-element-concat-list (cons a nil) (cons b (cons c y)) = last-element-concat-list (cons a nil) (cons c y) last-element-concat-list (cons a (cons b x)) y = last-element-concat-list (cons b x) y remove-last-element-concat-list : {l1 : Level} {A : UU l1} (x y : list A) → Id ( remove-last-element-list (concat-list x y)) ( concat-list ( remove-last-element-list (concat-list x (head-list y))) ( remove-last-element-list y)) remove-last-element-concat-list nil nil = refl remove-last-element-concat-list nil (cons a nil) = refl remove-last-element-concat-list nil (cons a (cons b y)) = refl remove-last-element-concat-list (cons a nil) nil = refl remove-last-element-concat-list (cons a nil) (cons b y) = refl remove-last-element-concat-list (cons a (cons b x)) y = ap (cons a) (remove-last-element-concat-list (cons b x) y) tail-concat-list' : {l1 : Level} {A : UU l1} (x y : list A) → Id ( tail-list (concat-list x y)) ( concat-list ( tail-list x) ( tail-list (concat-list (last-element-list x) y))) tail-concat-list' nil y = refl tail-concat-list' (cons a nil) y = refl tail-concat-list' (cons a (cons b x)) y = ap (cons b) (tail-concat-list' (cons b x) y) ```