Definitions on lists
This file contains various definitions on lists. It does not contain
proofs about these definitions, those are contained in other files in data/list
Equations
- list.has_sdiff = {sdiff := list.diff (λ (a b : α), _inst_1 a b)}
Split a list at an index.
split_at 2 [a, b, c] = ([a, b], [c])
Equations
- list.split_at n.succ (x :: xs) = list.split_at._match_1 x (list.split_at n xs)
- list.split_at n.succ list.nil = (list.nil α, list.nil α)
- list.split_at 0 a = (list.nil α, a)
- list.split_at._match_1 x (l, r) = (x :: l, r)
An auxiliary function for split_on_p.
Equations
- list.split_on_p_aux P (h :: t) f = ite (P h) (f list.nil :: list.split_on_p_aux P t id) (list.split_on_p_aux P t (λ (l : list α), f (h :: l)))
- list.split_on_p_aux P list.nil f = [f list.nil]
Split a list at every element satisfying a predicate.
Equations
- list.split_on_p P l = list.split_on_p_aux P l id
Split a list at every occurrence of an element.
[1,1,2,3,2,4,4].split_on 2 = [[1,1],[3],[4,4]]
Equations
- list.split_on a as = list.split_on_p (λ (_x : α), _x = a) as
head' xs returns the first element of xs if xs is non-empty;
it returns none otherwise
Equations
- (a :: l).head' = option.some a
- list.nil.head' = option.none
Apply a function to the nth tail of l. Returns the input without
using f if the index is larger than the length of the list.
modify_nth_tail f 2 [a, b, c] = [a, b] ++ f [c]
Equations
- list.modify_nth_tail f (n + 1) (a :: l) = a :: list.modify_nth_tail f n l
- list.modify_nth_tail f (n + 1) list.nil = list.nil
- list.modify_nth_tail f 0 l = f l
Apply f to the head of the list, if it exists.
Equations
- list.modify_head f (a :: l) = f a :: l
- list.modify_head f list.nil = list.nil
Apply f to the nth element of the list, if it exists.
Equations
insert_nth n a l inserts a into the list l after the first n elements of l
insert_nth 2 1 [1, 2, 3, 4] = [1, 2, 1, 3, 4]
Equations
- list.insert_nth n a = list.modify_nth_tail (list.cons a) n
Take n elements from a list l. If l has less than n elements, append n - length l
elements default α.
Equations
- list.take' (n + 1) l = l.head :: list.take' n l.tail
- list.take' 0 l = list.nil
Get the longest initial segment of the list whose members all satisfy p.
take_while (λ x, x < 3) [0, 2, 5, 1] = [0, 2]
Equations
- list.take_while p (a :: l) = ite (p a) (a :: list.take_while p l) list.nil
- list.take_while p list.nil = list.nil
Fold a function f over the list from the left, returning the list
of partial results.
scanl (+) 0 [1, 2, 3] = [0, 1, 3, 6]
Equations
- list.scanl f a (b :: l) = a :: list.scanl f (f a b) l
- list.scanl f a list.nil = [a]
Auxiliary definition used to define scanr. If scanr_aux f b l = (b', l')
then scanr f b l = b' :: l'
Equations
- list.scanr_aux f b (a :: l) = list.scanr_aux._match_1 f a (list.scanr_aux f b l)
- list.scanr_aux f b list.nil = (b, list.nil β)
- list.scanr_aux._match_1 f a (b', l') = (f a b', b' :: l')
Fold a function f over the list from the right, returning the list
of partial results.
scanr (+) 0 [1, 2, 3] = [6, 5, 3, 0]
Equations
- list.scanr f b l = list.scanr._match_1 (list.scanr_aux f b l)
- list.scanr._match_1 (b', l') = b' :: l'
The alternating sum of a list.
Equations
- (g :: h :: t).alternating_sum = g + -h + t.alternating_sum
- [g].alternating_sum = g
- list.nil.alternating_sum = 0
The alternating product of a list.
Equations
- (g :: h :: t).alternating_prod = g * h⁻¹ * t.alternating_prod
- [g].alternating_prod = g
- list.nil.alternating_prod = 1
Given a function f : α → β ⊕ γ, partition_map f l maps the list by f
whilst partitioning the result it into a pair of lists, list β × list γ,
partitioning the sum.inl _ into the left list, and the sum.inr _ into the right list.
partition_map (id : ℕ ⊕ ℕ → ℕ ⊕ ℕ) [inl 0, inr 1, inl 2] = ([0,2], [1])
Equations
- list.partition_map f (x :: xs) = list.partition_map._match_1 (list.partition_map f xs) (list.partition_map f xs) (f x)
- list.partition_map f list.nil = (list.nil β, list.nil γ)
- list.partition_map._match_1 _f_1 _f_2 (sum.inr r) = prod.map id (list.cons r) _f_1
- list.partition_map._match_1 _f_1 _f_2 (sum.inl l) = prod.map (list.cons l) id _f_2
find p l is the first element of l satisfying p, or none if no such
element exists.
Equations
- list.find p (a :: l) = ite (p a) (option.some a) (list.find p l)
- list.find p list.nil = option.none
mfind tac l returns the first element of l on which tac succeeds, and
fails otherwise.
Equations
- list.mfind tac = list.mfirst (λ (a : α), tac a $> a)
mbfind' p l returns the first element a of l for which p a returns
true. mbfind' short-circuits, so p is not necessarily run on every a in
l. This is a monadic version of list.find.
Equations
- list.mbfind' p (x :: xs) = p x >>= λ (_p : ulift bool), list.mbfind'._match_1 x (list.mbfind' p xs) _p
- list.mbfind' p list.nil = has_pure.pure option.none
- list.mbfind'._match_1 x _f_1 {down := px} = ite ↥px (has_pure.pure (option.some x)) _f_1
A variant of mbfind' with more restrictive universe levels.
Equations
- list.mbfind p xs = list.mbfind' (functor.map ulift.up ∘ p) xs
many p as returns true iff p returns true for any element of l.
many short-circuits, so if p returns true for any element of l, later
elements are not checked. This is a monadic version of list.any.
mall p as returns true iff p returns true for all elements of l.
mall short-circuits, so if p returns false for any element of l, later
elements are not checked. This is a monadic version of list.all.
mbor xs runs the actions in xs, returning true if any of them returns
true. mbor short-circuits, so if an action returns true, later actions are
not run. This is a monadic version of list.bor.
mband xs runs the actions in xs, returning true if all of them return
true. mband short-circuits, so if an action returns false, later actions are
not run. This is a monadic version of list.band.
Equations
Auxiliary definition for foldl_with_index.
Equations
- list.foldl_with_index_aux f i a (b :: l) = list.foldl_with_index_aux f (i + 1) (f i a b) l
- list.foldl_with_index_aux f _x a list.nil = a
Fold a list from left to right as with foldl, but the combining function
also receives each element's index.
Equations
- list.foldl_with_index f a l = list.foldl_with_index_aux f 0 a l
Auxiliary definition for foldr_with_index.
Equations
- list.foldr_with_index_aux f i b (a :: l) = f i a (list.foldr_with_index_aux f (i + 1) b l)
- list.foldr_with_index_aux f _x b list.nil = b
Fold a list from right to left as with foldr, but the combining function
also receives each element's index.
Equations
- list.foldr_with_index f b l = list.foldr_with_index_aux f 0 b l
find_indexes p l is the list of indexes of elements of l that satisfy p.
Equations
- list.find_indexes p l = list.foldr_with_index (λ (i : ℕ) (a : α) (is : list ℕ), ite (p a) (i :: is) is) list.nil l
Returns the elements of l that satisfy p together with their indexes in
l. The returned list is ordered by index.
Equations
- list.indexes_values p l = list.foldr_with_index (λ (i : ℕ) (a : α) (l : list (ℕ × α)), ite (p a) ((i, a) :: l) l) list.nil l
indexes_of a l is the list of all indexes of a in l. For example:
indexes_of a [a, b, a, a] = [0, 2, 3]
Equations
- list.indexes_of a = list.find_indexes (eq a)
Monadic variant of foldl_with_index.
Equations
- list.mfoldl_with_index f b as = list.foldl_with_index (λ (i : ℕ) (ma : m β) (b : α), ma >>= λ (a : β), f i a b) (has_pure.pure b) as
Monadic variant of foldr_with_index.
Equations
- list.mfoldr_with_index f b as = list.foldr_with_index (λ (i : ℕ) (a : α) (mb : m β), mb >>= λ (b : β), f i a b) (has_pure.pure b) as
Auxiliary definition for mmap_with_index.
Equations
- list.mmap_with_index_aux f i (a :: as) = list.cons <$> f i a <*> list.mmap_with_index_aux f (i + 1) as
- list.mmap_with_index_aux f _x list.nil = has_pure.pure list.nil
Applicative variant of map_with_index.
Equations
- list.mmap_with_index f as = list.mmap_with_index_aux f 0 as
Auxiliary definition for mmap_with_index'.
Equations
- list.mmap_with_index'_aux f i (a :: as) = f i a *> list.mmap_with_index'_aux f (i + 1) as
- list.mmap_with_index'_aux f _x list.nil = has_pure.pure punit.star
A variant of mmap_with_index specialised to applicative actions which
return unit.
Equations
- list.mmap_with_index' f as = list.mmap_with_index'_aux f 0 as
lookmap is a combination of lookup and filter_map.
lookmap f l will apply f : α → option α to each element of the list,
replacing a → b at the first value a in the list such that f a = some b.
Equations
- list.lookmap f (a :: l) = list.lookmap._match_1 a l (list.lookmap f l) (f a)
- list.lookmap f list.nil = list.nil
- list.lookmap._match_1 a l _f_1 (option.some b) = b :: l
- list.lookmap._match_1 a l _f_1 option.none = a :: _f_1
countp p l is the number of elements of l that satisfy p.
Equations
- list.countp p (x :: xs) = ite (p x) (list.countp p xs).succ (list.countp p xs)
- list.countp p list.nil = 0
count a l is the number of occurrences of a in l.
Equations
- list.count a = list.countp (eq a)
Equations
- (a :: l).sublists'_aux f r = l.sublists'_aux f (l.sublists'_aux (f ∘ list.cons a) r)
- list.nil.sublists'_aux f r = f list.nil :: r
sublists' l is the list of all (non-contiguous) sublists of l.
It differs from sublists only in the order of appearance of the sublists;
sublists' uses the first element of the list as the MSB,
sublists uses the first element of the list as the LSB.
sublists' [1, 2, 3] = [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
Equations
Equations
- (a :: l).sublists_aux f = f [a] (l.sublists_aux (λ (ys : list α) (r : list β), f ys (f (a :: ys) r)))
- list.nil.sublists_aux f = list.nil
sublists l is the list of all (non-contiguous) sublists of l; cf. sublists'
for a different ordering.
sublists [1, 2, 3] = [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
Equations
- (a :: l).sublists_aux₁ f = f [a] ++ l.sublists_aux₁ (λ (ys : list α), f ys ++ f (a :: ys))
- list.nil.sublists_aux₁ f = list.nil
- nil : ∀ {α : Type u} {β : Type v} (R : α → β → Prop), list.forall₂ R list.nil list.nil
- cons : ∀ {α : Type u} {β : Type v} (R : α → β → Prop) {a : α} {b : β} {l₁ : list α} {l₂ : list β}, R a b → list.forall₂ R l₁ l₂ → list.forall₂ R (a :: l₁) (b :: l₂)
forall₂ R l₁ l₂ means that l₁ and l₂ have the same length,
and whenever a is the nth element of l₁, and b is the nth element of l₂,
then R a b is satisfied.
Auxiliary definition used to define transpose.
transpose_aux l L takes each element of l and appends it to the start of
each element of L.
transpose_aux [a, b, c] [l₁, l₂, l₃] = [a::l₁, b::l₂, c::l₃]
Equations
- (a :: i).transpose_aux (l :: ls) = (a :: l) :: i.transpose_aux ls
- (a :: i).transpose_aux list.nil = [a] :: i.transpose_aux list.nil
- list.nil.transpose_aux ls = ls
List of all sections through a list of lists. A section
of [L₁, L₂, ..., Lₙ] is a list whose first element comes from
L₁, whose second element comes from L₂, and so on.
Equations
- list.permutations_aux2 t ts r (y :: ys) f = list.permutations_aux2._match_1 t y f (list.permutations_aux2 t ts r ys (λ (x : list α), f (y :: x)))
- list.permutations_aux2 t ts r list.nil f = (ts, r)
- list.permutations_aux2._match_1 t y f (us, zs) = (y :: us, f (t :: y :: us) :: zs)
Equations
- list.permutations_aux.rec H0 H1 (t :: ts) is = H1 t ts is (list.permutations_aux.rec H0 H1 ts (t :: is)) (list.permutations_aux.rec H0 H1 is list.nil)
- list.permutations_aux.rec H0 H1 list.nil is = H0 is
Equations
- list.permutations_aux = list.permutations_aux.rec (λ (is : list α), list.nil) (λ (t : α) (ts is : list α) (IH1 : (λ (_x _x : list α), list (list α)) ts (t :: is)) (IH2 : (λ (_x _x : list α), list (list α)) is list.nil), list.foldr (λ (y : list α) (r : (λ (_x _x : list α), list (list α)) (t :: ts) is), (list.permutations_aux2 t ts r y id).snd) IH1 (is :: IH2))
List of all permutations of l.
permutations [1, 2, 3] =
[[1, 2, 3], [2, 1, 3], [3, 2, 1],
[2, 3, 1], [3, 1, 2], [1, 3, 2]]
Equations
- l.permutations = l :: l.permutations_aux list.nil
erase p l removes all elements of l satisfying the predicate p
Equations
- list.erasep p (a :: l) = ite (p a) l (a :: list.erasep p l)
- list.erasep p list.nil = list.nil
extractp p l returns a pair of an element a of l satisfying the predicate
p, and l, with a removed. If there is no such element a it returns (none, l).
Equations
- list.extractp p (a :: l) = ite (p a) (option.some a, l) (list.extractp._match_1 a (list.extractp p l))
- list.extractp p list.nil = (option.none α, list.nil α)
- list.extractp._match_1 a (a', l') = (a', a :: l')
sigma l₁ l₂ is the list of dependent pairs (a, b) where a ∈ l₁ and b ∈ l₂ a.
sigma [1, 2] (λ_, [(5 : ℕ), 6]) = [(1, 5), (1, 6), (2, 5), (2, 6)]
Auxliary definition used to define of_fn.
of_fn_aux f m h l returns the first m elements of of_fn f
appended to l
Equations
- list.of_fn_aux f m.succ h l = list.of_fn_aux f m _ (f ⟨m, h⟩ :: l)
- list.of_fn_aux f 0 h l = l
of_fn f with f : fin n → α returns the list whose ith element is f i
of_fun f = [f 0, f 1, ... , f(n - 1)]
Equations
- list.of_fn f = list.of_fn_aux f n list.of_fn._proof_1 list.nil
of_fn_nth_val f i returns some (f i) if i < n and none otherwise.
Equations
- list.of_fn_nth_val f i = dite (i < n) (λ (h : i < n), option.some (f ⟨i, h⟩)) (λ (h : ¬i < n), option.none)
- nil : ∀ {α : Type u} (R : α → α → Prop), list.pairwise R list.nil
- cons : ∀ {α : Type u} (R : α → α → Prop) {a : α} {l : list α}, (∀ (a' : α), a' ∈ l → R a a') → list.pairwise R l → list.pairwise R (a :: l)
pairwise R l means that all the elements with earlier indexes are
R-related to all the elements with later indexes.
pairwise R [1, 2, 3] ↔ R 1 2 ∧ R 1 3 ∧ R 2 3
For example if R = (≠) then it asserts l has no duplicates,
and if R = (<) then it asserts that l is (strictly) sorted.
Equations
- l.decidable_pairwise = list.rec (decidable.is_true list.pairwise.nil) (λ (hd : α) (tl : list α) (ih : decidable (list.pairwise R tl)), decidable_of_iff' ((∀ (a' : α), a' ∈ tl → R hd a') ∧ list.pairwise R tl) list.pairwise_cons) l
pw_filter R l is a maximal sublist of l which is pairwise R.
pw_filter (≠) is the erase duplicates function (cf. erase_dup), and pw_filter (<) finds
a maximal increasing subsequence in l. For example,
pw_filter (<) [0, 1, 5, 2, 6, 3, 4] = [0, 1, 2, 3, 4]
Equations
- list.pw_filter R (x :: xs) = let IH : list α := list.pw_filter R xs in ite (∀ (y : α), y ∈ IH → R x y) (x :: IH) IH
- list.pw_filter R list.nil = list.nil
- nil : ∀ {α : Type u} (R : α → α → Prop) {a : α}, list.chain R a list.nil
- cons : ∀ {α : Type u} (R : α → α → Prop) {a b : α} {l : list α}, R a b → list.chain R b l → list.chain R a (b :: l)
chain R a l means that R holds between adjacent elements of a::l.
chain R a [b, c, d] ↔ R a b ∧ R b c ∧ R c d
chain' R l means that R holds between adjacent elements of l.
chain' R [a, b, c, d] ↔ R a b ∧ R b c ∧ R c d
Equations
- list.chain' R (a :: l) = list.chain R a l
- list.chain' R list.nil = true
Equations
- list.decidable_chain a l = list.rec (λ (a : α), _.mpr decidable.true) (λ (l_hd : α) (l_tl : list α) (l_ih : Π (a : α), decidable (list.chain R a l_tl)) (a : α), _.mpr and.decidable) l a
Equations
- l.decidable_chain' = l.cases_on (id decidable.true) (λ (l_hd : α) (l_tl : list α), id (list.decidable_chain l_hd l_tl))
nodup l means that l has no duplicates, that is, any element appears at most
once in the list. It is defined as pairwise (≠).
Equations
Equations
erase_dup l removes duplicates from l (taking only the first occurrence).
Defined as pw_filter (≠).
erase_dup [1, 0, 2, 2, 1] = [0, 2, 1]
Equations
range' s n is the list of numbers [s, s+1, ..., s+n-1].
It is intended mainly for proving properties of range and iota.
Equations
- list.range' s (n + 1) = s :: list.range' (s + 1) n
- list.range' s 0 = list.nil
Drop nones from a list, and replace each remaining some a with a.
Equations
Apply f to the first element of l.
Equations
- list.map_head f (x :: xs) = f x :: xs
- list.map_head f list.nil = list.nil
Apply f to the last element of l.
Equations
- list.map_last f (x :: hd :: tl) = x :: list.map_last f (hd :: tl)
- list.map_last f [x] = [f x]
- list.map_last f list.nil = list.nil
ilast' x xs returns the last element of xs if xs is non-empty;
it returns x otherwise
Equations
- list.ilast' a (b :: l) = list.ilast' b l
- list.ilast' a list.nil = a
Given a decidable predicate p and a proof of existence of a ∈ l such that p a,
choose the first element with this property. This version returns both a and proofs
of a ∈ l and p a.
Equations
- list.choose_x p (l :: ls) hp = dite (p l) (λ (pl : p l), ⟨l, _⟩) (λ (pl : ¬p l), list.choose_x._match_2 p l ls (list.choose_x p ls _))
- list.choose_x p list.nil hp = _.elim
- list.choose_x._match_2 p l ls ⟨a, _⟩ = ⟨a, _⟩
Given a decidable predicate p and a proof of existence of a ∈ l such that p a,
choose the first element with this property. This version returns a : α, and properties
are given by choose_mem and choose_property.
Equations
- list.choose p l hp = ↑(list.choose_x p l hp)
Filters and maps elements of a list
Equations
- list.mmap_filter f (h :: t) = f h >>= λ (b : option β), list.mmap_filter f t >>= λ (t' : list β), return (list.mmap_filter._match_1 t' b)
- list.mmap_filter f list.nil = return list.nil
- list.mmap_filter._match_1 t' (option.some x) = x :: t'
- list.mmap_filter._match_1 t' option.none = t'
mmap_upper_triangle f l calls f on all elements in the upper triangular part of l × l.
That is, for each e ∈ l, it will run f e e and then f e e'
for each e' that appears after e in l.
Example: suppose l = [1, 2, 3]. mmap_upper_triangle f l will produce the list
[f 1 1, f 1 2, f 1 3, f 2 2, f 2 3, f 3 3].
mmap'_diag f l calls f on all elements in the upper triangular part of l × l.
That is, for each e ∈ l, it will run f e e and then f e e'
for each e' that appears after e in l.
Example: suppose l = [1, 2, 3]. mmap'_diag f l will evaluate, in this order,
f 1 1, f 1 2, f 1 3, f 2 2, f 2 3, f 3 3.
Equations
- list.mmap'_diag f (h :: t) = f h h >> list.mmap' (f h) t >> list.mmap'_diag f t
- list.mmap'_diag f list.nil = return ()
Equations
- list.traverse f (x :: xs) = list.cons <$> f x <*> list.traverse f xs
- list.traverse f list.nil = has_pure.pure list.nil
get_rest l l₁ returns some l₂ if l = l₁ ++ l₂.
If l₁ is not a prefix of l, returns none