New definitions #
Equations
- x✝.instDecidableRelSubsetOfDecidableEq_batteries x = List.decidableBAll (fun (a : α) => a ∈ x) x✝
Computes the "bag intersection" of l₁ and l₂, that is,
the collection of elements of l₁ which are also in l₂. As each element
is identified, it is removed from l₂, so elements are counted with multiplicity.
Equations
Instances For
Given a function f : Nat → α → β and as : list α, as = [a₀, a₁, ...], returns the list
[f 0 a₀, f 1 a₁, ...].
Equations
- List.mapIdx f as = List.mapIdx.go f as #[]
Instances For
Auxiliary for mapIdx:
mapIdx.go [a₀, a₁, ...] acc = acc.toList ++ [f acc.size a₀, f (acc.size + 1) a₁, ...]
Equations
- List.mapIdx.go f [] x = x.toList
- List.mapIdx.go f (a :: as) x = List.mapIdx.go f as (x.push (f x.size a))
Instances For
Auxiliary for mapIdxM:
mapIdxM.go as f acc = acc.toList ++ [← f acc.size a₀, ← f (acc.size + 1) a₁, ...]
Equations
- List.mapIdxM.go f [] x = pure x.toList
- List.mapIdxM.go f (a :: as) x = do let __do_lift ← f x.size a List.mapIdxM.go f as (x.push __do_lift)
Instances For
after p xs is the suffix of xs after the first element that satisfies
p, not including that element.
after (· == 1) [0, 1, 2, 3] = [2, 3]
drop_while (· != 1) [0, 1, 2, 3] = [1, 2, 3]
Equations
- List.after p [] = []
- List.after p (head :: as) = bif p head then as else List.after p as
Instances For
Returns the index of the first element satisfying p, or the length of the list otherwise.
Equations
- List.findIdx p l = List.findIdx.go p l 0
Instances For
Auxiliary for findIdx: findIdx.go p l n = findIdx p l + n
Equations
- List.findIdx.go p [] x = x
- List.findIdx.go p (a :: l) x = bif p a then x else List.findIdx.go p l (x + 1)
Instances For
Returns the index of the first element equal to a, or the length of the list otherwise.
Equations
- List.indexOf a = List.findIdx fun (x : α) => x == a
Instances For
Alias of List.eraseIdx.
O(i). eraseIdx l i removes the i'th element of the list l.
erase [a, b, c, d, e] 0 = [b, c, d, e]erase [a, b, c, d, e] 1 = [a, c, d, e]erase [a, b, c, d, e] 5 = [a, b, c, d, e]
Equations
Instances For
Alias of List.eraseIdxTR.
Tail recursive version of eraseIdx.
Equations
Instances For
Alias of List.eraseIdx_eq_eraseIdxTR.
Replaces the first element of the list for which f returns some with the returned value.
Equations
- List.replaceF f [] = []
- List.replaceF f (head :: as) = match f head with | none => head :: List.replaceF f as | some a => a :: as
Instances For
Tail-recursive version of replaceF.
Equations
- List.replaceFTR f l = List.replaceFTR.go f l #[]
Instances For
Auxiliary for replaceFTR: replaceFTR.go f xs acc = acc.toList ++ replaceF f xs.
Equations
- List.replaceFTR.go f [] x = x.toList
- List.replaceFTR.go f (x_2 :: xs) x = match f x_2 with | none => List.replaceFTR.go f xs (x.push x_2) | some a' => x.toListAppend (a' :: xs)
Instances For
Constructs the union of two lists, by inserting the elements of l₁ in reverse order to l₂.
As a result, l₂ will always be a suffix, but only the last occurrence of each element in l₁
will be retained (but order will otherwise be preserved).
Equations
- l₁.union l₂ = List.foldr List.insert l₂ l₁
Instances For
Constructs the intersection of two lists, by filtering the elements of l₁ that are in l₂.
Unlike bagInter this does not preserve multiplicity: [1, 1].inter [1] is [1, 1].
Equations
- l₁.inter l₂ = List.filter (fun (x : α) => List.elem x l₂) l₁
Instances For
l₁ <+ l₂, or Sublist l₁ l₂, says that l₁ is a (non-contiguous) subsequence of l₂.
- slnil: ∀ {α : Type u_1}, [].Sublist []
the base case:
[]is a sublist of[] - cons: ∀ {α : Type u_1} {l₁ l₂ : List α} (a : α), l₁.Sublist l₂ → l₁.Sublist (a :: l₂)
If
l₁is a subsequence ofl₂, then it is also a subsequence ofa :: l₂. - cons₂: ∀ {α : Type u_1} {l₁ l₂ : List α} (a : α), l₁.Sublist l₂ → (a :: l₁).Sublist (a :: l₂)
If
l₁is a subsequence ofl₂, thena :: l₁is a subsequence ofa :: l₂.
Instances For
l₁ <+ l₂, or Sublist l₁ l₂, says that l₁ is a (non-contiguous) subsequence of l₂.
Equations
- List.«term_<+_» = Lean.ParserDescr.trailingNode `List.term_<+_ 50 50 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " <+ ") (Lean.ParserDescr.cat `term 51))
Instances For
True if the first list is a potentially non-contiguous sub-sequence of the second list.
Equations
Instances For
Split a list at an index.
splitAt 2 [a, b, c] = ([a, b], [c])
Equations
- List.splitAt n l = List.splitAt.go l l n #[]
Instances For
Auxiliary for splitAt: splitAt.go l n xs acc = (acc.toList ++ take n xs, drop n xs)
if n < length xs, else (l, []).
Equations
- List.splitAt.go l [] x✝ x = (l, [])
- List.splitAt.go l (x_3 :: xs) n.succ x = List.splitAt.go l xs n (x.push x_3)
- List.splitAt.go l x✝¹ x✝ x = (x.toList, x✝¹)
Instances For
Split a list at an index. Ensures the left list always has the specified length by right padding with the provided default element.
splitAtD 2 [a, b, c] x = ([a, b], [c])
splitAtD 4 [a, b, c] x = ([a, b, c, x], [])
Equations
- List.splitAtD n l dflt = List.splitAtD.go dflt n l #[]
Instances For
Auxiliary for splitAtD: splitAtD.go dflt n l acc = (acc.toList ++ left, right)
if splitAtD n l dflt = (left, right).
Equations
- List.splitAtD.go dflt n.succ (x_3 :: xs) x = List.splitAtD.go dflt n xs (x.push x_3)
- List.splitAtD.go dflt 0 x✝ x = (x.toList, x✝)
- List.splitAtD.go dflt x✝ [] x = (x.toListAppend (List.replicate x✝ dflt), [])
Instances For
Split a list at every element satisfying a predicate. The separators are not in the result.
[1, 1, 2, 3, 2, 4, 4].splitOnP (· == 2) = [[1, 1], [3], [4, 4]]
Equations
- List.splitOnP P l = List.splitOnP.go P l []
Instances For
Auxiliary for splitOnP: splitOnP.go xs acc = res'
where res' is obtained from splitOnP P xs by prepending acc.reverse to the first element.
Equations
- List.splitOnP.go P [] x = [x.reverse]
- List.splitOnP.go P (a :: t) x = if P a = true then x.reverse :: List.splitOnP.go P t [] else List.splitOnP.go P t (a :: x)
Instances For
Tail recursive version of splitOnP.
Equations
- List.splitOnPTR P l = List.splitOnPTR.go P l #[] #[]
Instances For
Auxiliary for splitOnP: splitOnP.go xs acc r = r.toList ++ res'
where res' is obtained from splitOnP P xs by prepending acc.toList to the first element.
Equations
- List.splitOnPTR.go P [] x✝ x = x.toListAppend [x✝.toList]
- List.splitOnPTR.go P (a :: t) x✝ x = bif P a then List.splitOnPTR.go P t #[] (x.push x✝.toList) else List.splitOnPTR.go P t (x✝.push a) x
Instances For
Split a list at every occurrence of a separator element. The separators are not in the result.
[1, 1, 2, 3, 2, 4, 4].splitOn 2 = [[1, 1], [3], [4, 4]]
Equations
- List.splitOn a as = List.splitOnP (fun (x : α) => x == a) as
Instances For
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.
modifyNthTail f 2 [a, b, c] = [a, b] ++ f [c]
Equations
- List.modifyNthTail f 0 x = f x
- List.modifyNthTail f n.succ [] = []
- List.modifyNthTail f n.succ (a :: l) = a :: List.modifyNthTail f n l
Instances For
Apply f to the head of the list, if it exists.
Equations
- List.modifyHead f x = match x with | [] => [] | a :: l => f a :: l
Instances For
Apply f to the nth element of the list, if it exists.
Equations
Instances For
Tail-recursive version of modifyNth.
Equations
- List.modifyNthTR f n l = List.modifyNthTR.go f l n #[]
Instances For
Auxiliary for modifyNthTR: modifyNthTR.go f l n acc = acc.toList ++ modifyNth f n l.
Equations
- List.modifyNthTR.go f [] x✝ x = x.toList
- List.modifyNthTR.go f (a :: l) 0 x = x.toListAppend (f a :: l)
- List.modifyNthTR.go f (a :: l) n.succ x = List.modifyNthTR.go f l n (x.push a)
Instances For
Apply f to the last element of l, if it exists.
Equations
- List.modifyLast f l = List.modifyLast.go f l #[]
Instances For
Auxiliary for modifyLast: modifyLast.go f l acc = acc.toList ++ modifyLast f l.
Equations
- List.modifyLast.go f [] x = []
- List.modifyLast.go f [x_2] x = x.toListAppend [f x_2]
- List.modifyLast.go f (x_2 :: xs) x = List.modifyLast.go f xs (x.push x_2)
Instances For
insertNth n a l inserts a into the list l after the first n elements of l
insertNth 2 1 [1, 2, 3, 4] = [1, 2, 1, 3, 4]
Equations
- List.insertNth n a = List.modifyNthTail (List.cons a) n
Instances For
Tail-recursive version of insertNth.
Equations
- List.insertNthTR n a l = List.insertNthTR.go a n l #[]
Instances For
Auxiliary for insertNthTR: insertNthTR.go a n l acc = acc.toList ++ insertNth n a l.
Equations
- List.insertNthTR.go a 0 x✝ x = x.toListAppend (a :: x✝)
- List.insertNthTR.go a x✝ [] x = x.toList
- List.insertNthTR.go a n.succ (a_1 :: l) x = List.insertNthTR.go a n l (x.push a_1)
Instances For
Take n elements from a list l. If l has less than n elements, append n - length l
elements x.
Equations
- List.takeD 0 x✝ x = []
- List.takeD n.succ x✝ x = x✝.headD x :: List.takeD n x✝.tail x
Instances For
Tail-recursive version of takeD.
Equations
- List.takeDTR n l dflt = List.takeDTR.go dflt n l #[]
Instances For
Auxiliary for takeDTR: takeDTR.go dflt n l acc = acc.toList ++ takeD n l dflt.
Equations
- List.takeDTR.go dflt n.succ (x_3 :: xs) x = List.takeDTR.go dflt n xs (x.push x_3)
- List.takeDTR.go dflt 0 x✝ x = x.toList
- List.takeDTR.go dflt x✝ [] x = x.toListAppend (List.replicate x✝ dflt)
Instances For
Pads l : List α with repeated occurrences of a : α until it is of length n.
If l is initially larger than n, just return l.
Equations
- List.leftpad n a l = List.replicate (n - l.length) a ++ l
Instances For
Optimized version of leftpad.
Equations
- List.leftpadTR n a l = List.replicateTR.loop a (n - l.length) l
Instances For
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 [] = [a]
- List.scanl f a (head :: as) = a :: List.scanl f (f a head) as
Instances For
Tail-recursive version of scanl.
Equations
- List.scanlTR f a l = List.scanlTR.go f l a #[]
Instances For
Auxiliary for scanlTR: scanlTR.go f l a acc = acc.toList ++ scanl f a l.
Equations
- List.scanlTR.go f [] x✝ x = x.toListAppend [x✝]
- List.scanlTR.go f (b :: l) x✝ x = List.scanlTR.go f l (f x✝ b) (x.push x✝)
Instances For
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 = match List.foldr (fun (a : α) (x : β × List β) => match x with | (b', l') => (f a b', b' :: l')) (b, []) l with | (b', l') => b' :: l'
Instances For
Fold a list from left to right as with foldl, but the combining function
also receives each element's index.
Equations
- List.foldlIdx f init [] x = init
- List.foldlIdx f init (b :: l) x = List.foldlIdx f (f x init b) l (x + 1)
Instances For
Fold a list from right to left as with foldr, but the combining function
also receives each element's index.
Equations
- List.foldrIdx f init [] x = init
- List.foldrIdx f init (b :: l) x = f x b (List.foldrIdx f init l (x + 1))
Instances For
Returns the elements of l that satisfy p together with their indexes in
l. The returned list is ordered by index.
Equations
- List.indexesValues p l = List.foldrIdx (fun (i : Nat) (a : α) (l : List (Nat × α)) => if p a = true then (i, a) :: l else l) [] l
Instances For
indexesOf a l is the list of all indexes of a in l. For example:
indexesOf a [a, b, a, a] = [0, 2, 3]
Equations
- List.indexesOf a = List.findIdxs fun (x : α) => x == a
Instances For
Return the index of the first occurrence of an element satisfying p.
Equations
- List.findIdx? p [] x = none
- List.findIdx? p (b :: l) x = if p b = true then some x else List.findIdx? p l (x + 1)
Instances For
Return the index of the first occurrence of a in the list.
Equations
- List.indexOf? a✝ a = List.findIdx? (fun (x : α) => x == a✝) a
Instances For
lookmap is a combination of lookup and filterMap.
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 l = List.lookmap.go f l #[]
Instances For
Auxiliary for lookmap: lookmap.go f l acc = acc.toList ++ lookmap f l.
Equations
- List.lookmap.go f [] x = x.toList
- List.lookmap.go f (x_2 :: xs) x = match f x_2 with | some b => x.toListAppend (b :: xs) | none => List.lookmap.go f xs (x.push x_2)
Instances For
countP p l is the number of elements of l that satisfy p.
Equations
- List.countP p l = List.countP.go p l 0
Instances For
Auxiliary for countP: countP.go p l acc = countP p l + acc.
Equations
- List.countP.go p [] x = x
- List.countP.go p (a :: l) x = bif p a then List.countP.go p l (x + 1) else List.countP.go p l x
Instances For
count a l is the number of occurrences of a in l.
Equations
- List.count a = List.countP fun (x : α) => x == a
Instances For
IsPrefix l₁ l₂, or l₁ <+: l₂, means that l₁ is a prefix of l₂,
that is, l₂ has the form l₁ ++ t for some t.
Equations
- List.«term_<+:_» = Lean.ParserDescr.trailingNode `List.term_<+:_ 50 50 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " <+: ") (Lean.ParserDescr.cat `term 51))
Instances For
IsSuffix l₁ l₂, or l₁ <:+ l₂, means that l₁ is a suffix of l₂,
that is, l₂ has the form t ++ l₁ for some t.
Equations
- List.«term_<:+_» = Lean.ParserDescr.trailingNode `List.term_<:+_ 50 50 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " <:+ ") (Lean.ParserDescr.cat `term 51))
Instances For
IsInfix l₁ l₂, or l₁ <:+: l₂, means that l₁ is a contiguous
substring of l₂, that is, l₂ has the form s ++ l₁ ++ t for some s, t.
Equations
- List.«term_<:+:_» = Lean.ParserDescr.trailingNode `List.term_<:+:_ 50 50 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " <:+: ") (Lean.ParserDescr.cat `term 51))
Instances For
Auxiliary for tailsTR: tailsTR.go l acc = acc.toList ++ tails l.
Equations
- List.tailsTR.go [] acc = acc.toListAppend [[]]
- List.tailsTR.go (head :: as) acc = List.tailsTR.go as (acc.push (head :: as))
Instances For
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
- l.sublists' = let f := fun (a : α) (arr : Array (List α)) => Array.foldl (fun (r : Array (List α)) (l : List α) => r.push (a :: l)) arr arr 0; (List.foldr f #[[]] l).toList
Instances For
A version of List.sublists that has faster runtime performance but worse kernel performance
Equations
- One or more equations did not get rendered due to their size.
Instances For
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.
- nil: ∀ {α : Type u_1} {β : Type u_2} {R : α → β → Prop}, List.Forall₂ R [] []
Two nil lists are
Forall₂-related - cons: ∀ {α : Type u_1} {β : Type u_2} {R : α → β → Prop} {a : α} {b : β} {l₁ : List α} {l₂ : List β}, R a b → List.Forall₂ R l₁ l₂ → List.Forall₂ R (a :: l₁) (b :: l₂)
Instances For
Check for all elements a, b, where a and b are the nth element of the first and second
List respectively, that r a b = true.
Equations
Instances For
Transpose of a list of lists, treated as a matrix.
transpose [[1, 2], [3, 4], [5, 6]] = [[1, 3, 5], [2, 4, 6]]
Equations
- l.transpose = (List.foldr List.transpose.go #[] l).toList
Instances For
pop : List α → StateM (List α) (List α) transforms the input list old
by taking the head of the current state and pushing it on the head of old.
If the state list is empty, then old is left unchanged.
Equations
- List.transpose.pop old x = match x with | [] => (old, []) | a :: l => (a :: old, l)
Instances For
go : List α → Array (List α) → Array (List α) handles the insertion of
a new list into all the lists in the array:
go [a, b, c] #[l₁, l₂, l₃] = #[a::l₁, b::l₂, c::l₃].
If the new list is too short, the later lists are unchanged, and if it is too long
the array is extended:
go [a] #[l₁, l₂, l₃] = #[a::l₁, l₂, l₃]
go [a, b, c, d] #[l₁, l₂, l₃] = #[a::l₁, b::l₂, c::l₃, [d]]
Equations
- List.transpose.go l acc = match Array.mapM List.transpose.pop acc l with | (acc, l) => List.foldl (fun (arr : Array (List α)) (a : α) => arr.push [a]) acc l
Instances For
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
Instances For
Optimized version of sections.
Equations
- L.sectionsTR = bif L.any List.isEmpty then [] else (List.foldr List.sectionsTR.go #[[]] L).toList
Instances For
go : List α → Array (List α) → Array (List α) inserts one list into the accumulated
list of sections acc: go [a, b] #[l₁, l₂] = [a::l₁, b::l₁, a::l₂, b::l₂].
Equations
- List.sectionsTR.go l acc = Array.foldl (fun (acc' : Array (List α)) (l' : List α) => List.foldl (fun (acc' : Array (List α)) (a : α) => acc'.push (a :: l')) acc' l) #[] acc 0
Instances For
eraseP p l removes the first element of l satisfying the predicate p.
Equations
- List.eraseP p [] = []
- List.eraseP p (head :: as) = bif p head then as else head :: List.eraseP p as
Instances For
Tail-recursive version of eraseP.
Equations
- List.erasePTR p l = List.erasePTR.go p l l #[]
Instances For
Auxiliary for erasePTR: erasePTR.go p l xs acc = acc.toList ++ eraseP p xs,
unless xs does not contain any elements satisfying p, where it returns l.
Equations
- List.erasePTR.go p l [] x = l
- List.erasePTR.go p l (x_2 :: xs) x = bif p x_2 then x.toListAppend xs else List.erasePTR.go p l xs (x.push x_2)
Instances For
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 l = List.extractP.go p l l #[]
Instances For
Auxiliary for extractP:
extractP.go p l xs acc = (some a, acc.toList ++ out) if extractP p xs = (some a, out),
and extractP.go p l xs acc = (none, l) if extractP p xs = (none, _).
Equations
- List.extractP.go p l [] x = (none, l)
- List.extractP.go p l (x_2 :: xs) x = bif p x_2 then (some x_2, x.toListAppend xs) else List.extractP.go p l xs (x.push x_2)
Instances For
Optimized version of product.
Equations
- l₁.productTR l₂ = (List.foldl (fun (acc : Array (α × β)) (a : α) => List.foldl (fun (acc : Array (α × β)) (b : β) => acc.push (a, b)) acc l₂) #[] l₁).toList
Instances For
Optimized version of sigma.
Equations
- l₁.sigmaTR l₂ = (List.foldl (fun (acc : Array ((a : α) × σ a)) (a : α) => List.foldl (fun (acc : Array ((a : α) × σ a)) (b : σ a) => acc.push ⟨a, b⟩) acc (l₂ a)) #[] l₁).toList
Instances For
Auxiliary for List.ofFn. ofFn.go f i j _ = [f j, ..., f (n - 1)].
Equations
- List.ofFn.go f 0 x x_1 = []
- List.ofFn.go f i.succ x x_1 = f ⟨x, ⋯⟩ :: List.ofFn.go f i (x + 1) ⋯
Instances For
Tail-recursive version of ofFn.
Equations
- List.ofFnTR f = List.ofFnTR.go f n ⋯ []
Instances For
Auxiliary for List.ofFnTR. ofFnTR.go f i _ acc = f 0 :: ... :: f (i - 1) :: acc.
Equations
- List.ofFnTR.go f 0 x_3 x = x
- List.ofFnTR.go f i.succ h x = List.ofFnTR.go f i ⋯ (f ⟨i, h⟩ :: x)
Instances For
ofFnNthVal f i returns some (f i) if i < n and none otherwise.
Equations
- List.ofFnNthVal f i = if h : i < n then some (f ⟨i, h⟩) else none
Instances For
Returns the longest initial prefix of two lists such that they are pairwise related by R.
takeWhile₂ (· < ·) [1, 2, 4, 5] [5, 4, 3, 6] = ([1, 2], [5, 4])
Equations
- List.takeWhile₂ R (a :: as) (b :: bs) = if R a b = true then match List.takeWhile₂ R as bs with | (as', bs') => (a :: as', b :: bs') else ([], [])
- List.takeWhile₂ R x✝ x = ([], [])
Instances For
Tail-recursive version of takeWhile₂.
Equations
- List.takeWhile₂TR R as bs = List.takeWhile₂TR.go R as bs [] []
Instances For
Auxiliary for takeWhile₂TR:
takeWhile₂TR.go R as bs acca accb = (acca.reverse ++ as', acca.reverse ++ bs')
if takeWhile₂ R as bs = (as', bs').
Equations
- List.takeWhile₂TR.go R (a :: as) (b :: bs) x✝ x = bif R a b then List.takeWhile₂TR.go R as bs (a :: x✝) (b :: x) else (x✝.reverse, x.reverse)
- List.takeWhile₂TR.go R x✝² x✝¹ x✝ x = (x✝.reverse, x.reverse)
Instances For
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.
- nil: ∀ {α : Type u_1} {R : α → α → Prop}, List.Pairwise R []
All elements of the empty list are vacuously pairwise related.
- cons: ∀ {α : Type u_1} {R : α → α → Prop} {a : α} {l : List α}, (∀ (a' : α), a' ∈ l → R a a') → List.Pairwise R l → List.Pairwise R (a :: l)
Instances For
pwFilter R l is a maximal sublist of l which is Pairwise R.
pwFilter (·≠·) is the erase duplicates function (cf. eraseDup), and pwFilter (·<·) finds
a maximal increasing subsequence in l. For example,
pwFilter (·<·) [0, 1, 5, 2, 6, 3, 4] = [0, 1, 2, 3, 4]
Equations
- List.pwFilter R l = List.foldr (fun (x : α) (IH : List α) => if ∀ (y : α), y ∈ IH → R x y then x :: IH else IH) [] l
Instances For
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
- nil: ∀ {α : Type u_1} {R : α → α → Prop} {a : α}, List.Chain R a []
A chain of length 1 is trivially a chain.
- cons: ∀ {α : Type u_1} {R : α → α → Prop} {a b : α} {l : List α}, R a b → List.Chain R b l → List.Chain R a (b :: l)
If
arelates tobandb::lis a chain, thena :: b :: lis also a chain.
Instances For
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 x = match x with | [] => True | a :: l => List.Chain R a l
Instances For
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
- List.Nodup = List.Pairwise fun (x x_1 : α) => x ≠ x_1
Instances For
Equations
- List.nodupDecidable = List.instDecidablePairwise
range' start len step is the list of numbers [start, start+step, ..., start+(len-1)*step].
It is intended mainly for proving properties of range and iota.
Equations
- List.range' x✝ 0 x = []
- List.range' x✝ n.succ x = x✝ :: List.range' (x✝ + x) n x
Instances For
Optimized version of range'.
Equations
- List.range'TR s n step = List.range'TR.go step n (s + step * n) []
Instances For
Auxiliary for range'TR: range'TR.go n e = [e-n, ..., e-1] ++ acc.
Equations
- List.range'TR.go step 0 x✝ x = x
- List.range'TR.go step n.succ x✝ x = List.range'TR.go step n (x✝ - step) ((x✝ - step) :: x)
Instances For
Drop nones from a list, and replace each remaining some a with a.
Equations
- List.reduceOption = List.filterMap id
Instances For
ilast' x xs returns the last element of xs if xs is non-empty; it returns x otherwise.
Use List.getLastD instead.
Equations
- List.ilast' x [] = x
- List.ilast' x (b :: l) = List.ilast' b l
Instances For
mapDiagM 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.
mapDiagM f [1, 2, 3] =
return [← f 1 1, ← f 1 2, ← f 1 3, ← f 2 2, ← f 2 3, ← f 3 3]
Equations
- List.mapDiagM f l = List.mapDiagM.go f l #[]
Instances For
Auxiliary for mapDiagM: mapDiagM.go as f acc = (acc.toList ++ ·) <$> mapDiagM f as
Equations
- List.mapDiagM.go f [] x = pure x.toList
- List.mapDiagM.go f (a :: as) x = do let b ← f a a let acc ← List.foldlM (fun (x : Array β) (x_1 : α) => x.push <$> f a x_1) (x.push b) as List.mapDiagM.go f as acc
Instances For
forDiagM 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.
forDiagM f [1, 2, 3] = do f 1 1; f 1 2; f 1 3; f 2 2; f 2 3; f 3 3
Equations
- List.forDiagM f [] = pure PUnit.unit
- List.forDiagM f (head :: as) = do f head head as.forM (f head) List.forDiagM f as
Instances For
getRest l l₁ returns some l₂ if l = l₁ ++ l₂.
If l₁ is not a prefix of l, returns none
Equations
Instances For
List.dropSlice n m xs removes a slice of length m at index n in list xs.
Equations
- List.dropSlice x✝ x [] = []
- List.dropSlice 0 x✝ x = List.drop x✝ x
- List.dropSlice n.succ x (x_3 :: xs) = x_3 :: List.dropSlice n x xs
Instances For
Optimized version of dropSlice.
Equations
- List.dropSliceTR n m l = match m with | 0 => l | m.succ => List.dropSliceTR.go l m l n #[]
Instances For
Auxiliary for dropSliceTR: dropSliceTR.go l m xs n acc = acc.toList ++ dropSlice n m xs
unless n ≥ length xs, in which case it is l.
Equations
- List.dropSliceTR.go l m [] x✝ x = l
- List.dropSliceTR.go l m (a :: l_1) 0 x = x.toListAppend (List.drop m l_1)
- List.dropSliceTR.go l m (a :: l_1) n.succ x = List.dropSliceTR.go l m l_1 n (x.push a)
Instances For
Left-biased version of List.zipWith. zipWithLeft' f as bs applies f to each
pair of elements aᵢ ∈ as and bᵢ ∈ bs. If bs is shorter than as, f is
applied to none for the remaining aᵢ. Returns the results of the f
applications and the remaining bs.
zipWithLeft' prod.mk [1, 2] ['a'] = ([(1, some 'a'), (2, none)], [])
zipWithLeft' prod.mk [1] ['a', 'b'] = ([(1, some 'a')], ['b'])
Equations
- List.zipWithLeft' f [] x = ([], x)
- List.zipWithLeft' f (a :: as) [] = (List.map (fun (a : α) => f a none) (a :: as), [])
- List.zipWithLeft' f (a :: as) (b :: bs) = let r := List.zipWithLeft' f as bs; (f a (some b) :: r.fst, r.snd)
Instances For
Tail-recursive version of zipWithLeft'.
Equations
- List.zipWithLeft'TR f as bs = List.zipWithLeft'TR.go f as bs #[]
Instances For
Auxiliary for zipWithLeft'TR: zipWithLeft'TR.go l acc = acc.toList ++ zipWithLeft' l.
Equations
- List.zipWithLeft'TR.go f [] x✝ x = (x.toList, x✝)
- List.zipWithLeft'TR.go f x✝ [] x = ((List.foldl (fun (acc : Array γ) (a : α) => acc.push (f a none)) x x✝).toList, [])
- List.zipWithLeft'TR.go f (a :: as) (b :: bs) x = List.zipWithLeft'TR.go f as bs (x.push (f a (some b)))
Instances For
Right-biased version of List.zipWith. zipWithRight' f as bs applies f to each
pair of elements aᵢ ∈ as and bᵢ ∈ bs. If as is shorter than bs, f is
applied to none for the remaining bᵢ. Returns the results of the f
applications and the remaining as.
zipWithRight' prod.mk [1] ['a', 'b'] = ([(some 1, 'a'), (none, 'b')], [])
zipWithRight' prod.mk [1, 2] ['a'] = ([(some 1, 'a')], [2])
Equations
- List.zipWithRight' f as bs = List.zipWithLeft' (flip f) bs as
Instances For
Left-biased version of List.zip. zipLeft' as bs returns the list of
pairs (aᵢ, bᵢ) for aᵢ ∈ as and bᵢ ∈ bs. If bs is shorter than as, the
remaining aᵢ are paired with none. Also returns the remaining bs.
zipLeft' [1, 2] ['a'] = ([(1, some 'a'), (2, none)], [])
zipLeft' [1] ['a', 'b'] = ([(1, some 'a')], ['b'])
zipLeft' = zipWithLeft' prod.mk
Equations
- List.zipLeft' = List.zipWithLeft' Prod.mk
Instances For
Right-biased version of List.zip. zipRight' as bs returns the list of
pairs (aᵢ, bᵢ) for aᵢ ∈ as and bᵢ ∈ bs. If as is shorter than bs, the
remaining bᵢ are paired with none. Also returns the remaining as.
zipRight' [1] ['a', 'b'] = ([(some 1, 'a'), (none, 'b')], [])
zipRight' [1, 2] ['a'] = ([(some 1, 'a')], [2])
zipRight' = zipWithRight' prod.mk
Equations
- List.zipRight' = List.zipWithRight' Prod.mk
Instances For
Left-biased version of List.zipWith. zipWithLeft f as bs applies f to each pair
aᵢ ∈ as and bᵢ ∈ bs∈ bs. If bs is shorter than as, f is applied to none
for the remaining aᵢ.
zipWithLeft prod.mk [1, 2] ['a'] = [(1, some 'a'), (2, none)]
zipWithLeft prod.mk [1] ['a', 'b'] = [(1, some 'a')]
zipWithLeft f as bs = (zipWithLeft' f as bs).fst
Equations
- List.zipWithLeft f [] x = []
- List.zipWithLeft f (a :: as) [] = List.map (fun (a : α) => f a none) (a :: as)
- List.zipWithLeft f (a :: as) (b :: bs) = f a (some b) :: List.zipWithLeft f as bs
Instances For
Tail-recursive version of zipWithLeft.
Equations
- List.zipWithLeftTR f as bs = List.zipWithLeftTR.go f as bs #[]
Instances For
Auxiliary for zipWithLeftTR: zipWithLeftTR.go l acc = acc.toList ++ zipWithLeft l.
Equations
- List.zipWithLeftTR.go f [] x✝ x = x.toList
- List.zipWithLeftTR.go f x✝ [] x = (List.foldl (fun (acc : Array γ) (a : α) => acc.push (f a none)) x x✝).toList
- List.zipWithLeftTR.go f (a :: as) (b :: bs) x = List.zipWithLeftTR.go f as bs (x.push (f a (some b)))
Instances For
Right-biased version of List.zipWith. zipWithRight f as bs applies f to each
pair aᵢ ∈ as and bᵢ ∈ bs∈ bs. If as is shorter than bs, f is applied to
none for the remaining bᵢ.
zipWithRight prod.mk [1, 2] ['a'] = [(some 1, 'a')]
zipWithRight prod.mk [1] ['a', 'b'] = [(some 1, 'a'), (none, 'b')]
zipWithRight f as bs = (zipWithRight' f as bs).fst
Equations
- List.zipWithRight f as bs = List.zipWithLeft (flip f) bs as
Instances For
Left-biased version of List.zip. zipLeft as bs returns the list of pairs
(aᵢ, bᵢ) for aᵢ ∈ as and bᵢ ∈ bs. If bs is shorter than as, the
remaining aᵢ are paired with none.
zipLeft [1, 2] ['a'] = [(1, some 'a'), (2, none)]
zipLeft [1] ['a', 'b'] = [(1, some 'a')]
zipLeft = zipWithLeft prod.mk
Equations
- List.zipLeft = List.zipWithLeft Prod.mk
Instances For
Right-biased version of List.zip. zipRight as bs returns the list of pairs
(aᵢ, bᵢ) for aᵢ ∈ as and bᵢ ∈ bs. If as is shorter than bs, the
remaining bᵢ are paired with none.
zipRight [1, 2] ['a'] = [(some 1, 'a')]
zipRight [1] ['a', 'b'] = [(some 1, 'a'), (none, 'b')]
zipRight = zipWithRight prod.mk
Equations
- List.zipRight = List.zipWithRight Prod.mk
Instances For
Tail-recursive version of fillNones.
Equations
- as.fillNonesTR as' = List.fillNonesTR.go as as' #[]
Instances For
Auxiliary for fillNonesTR: fillNonesTR.go as as' acc = acc.toList ++ fillNones as as'.
Equations
- List.fillNonesTR.go [] x✝ x = x.toList
- List.fillNonesTR.go (some a :: as) x✝ x = List.fillNonesTR.go as x✝ (x.push a)
- List.fillNonesTR.go (none :: as) [] x = List.filterMapTR.go id as x
- List.fillNonesTR.go (none :: as) (a :: as') x = List.fillNonesTR.go as as' (x.push a)
Instances For
takeList as ns extracts successive sublists from as. For ns = n₁ ... nₘ,
it first takes the n₁ initial elements from as, then the next n₂ ones,
etc. It returns the sublists of as -- one for each nᵢ -- and the remaining
elements of as. If as does not have at least as many elements as the sum of
the nᵢ, the corresponding sublists will have less than nᵢ elements.
takeList ['a', 'b', 'c', 'd', 'e'] [2, 1, 1] = ([['a', 'b'], ['c'], ['d']], ['e'])
takeList ['a', 'b'] [3, 1] = ([['a', 'b'], []], [])
Equations
- x.takeList [] = ([], x)
- x.takeList (n :: ns) = match List.splitAt n x with | (xs₁, xs₂) => match xs₂.takeList ns with | (xss, rest) => (xs₁ :: xss, rest)
Instances For
Auxiliary for takeListTR: takeListTR.go as as' acc = acc.toList ++ takeList as as'.
Equations
- List.takeListTR.go [] x✝ x = (x.toList, x✝)
- List.takeListTR.go (n :: ns) x✝ x = match List.splitAt n x✝ with | (xs₁, xs₂) => List.takeListTR.go ns xs₂ (x.push xs₁)
Instances For
Auxliary definition used to define toChunks.
toChunksAux n xs i returns (xs.take i, (xs.drop i).toChunks (n+1)),
that is, the first i elements of xs, and the remaining elements chunked into
sublists of length n+1.
Equations
- List.toChunksAux n [] x = ([], [])
- List.toChunksAux n (x_2 :: xs) 0 = match List.toChunksAux n xs n with | (l, L) => ([], (x_2 :: l) :: L)
- List.toChunksAux n (x_2 :: xs) i.succ = match List.toChunksAux n xs i with | (l, L) => (x_2 :: l, L)
Instances For
xs.toChunks n splits the list into sublists of size at most n,
such that (xs.toChunks n).join = xs.
[1, 2, 3, 4, 5, 6, 7, 8].toChunks 10 = [[1, 2, 3, 4, 5, 6, 7, 8]]
[1, 2, 3, 4, 5, 6, 7, 8].toChunks 3 = [[1, 2, 3], [4, 5, 6], [7, 8]]
[1, 2, 3, 4, 5, 6, 7, 8].toChunks 2 = [[1, 2], [3, 4], [5, 6], [7, 8]]
[1, 2, 3, 4, 5, 6, 7, 8].toChunks 0 = [[1, 2, 3, 4, 5, 6, 7, 8]]
Equations
- List.toChunks x✝ x = match x✝, x with | x, [] => [] | 0, xs => [xs] | n, x :: xs => List.toChunks.go n xs #[x] #[]
Instances For
Auxliary definition used to define toChunks.
toChunks.go xs acc₁ acc₂ pushes elements into acc₁ until it reaches size n,
then it pushes the resulting list to acc₂ and continues until xs is exhausted.
Equations
- List.toChunks.go n [] x✝ x = (x.push x✝.toList).toList
- List.toChunks.go n (a :: t) x✝ x = if (x✝.size == n) = true then List.toChunks.go n t ((Array.mkEmpty n).push a) (x.push x✝.toList) else List.toChunks.go n t (x✝.push a) x
Instances For
We add some n-ary versions of List.zipWith for functions with more than two arguments.
These can also be written in terms of List.zip or List.zipWith.
For example, zipWith₃ f xs ys zs could also be written as
zipWith id (zipWith f xs ys) zs
or as
(zip xs <| zip ys zs).map fun ⟨x, y, z⟩ => f x y z.
Ternary version of List.zipWith.
Equations
- List.zipWith₃ f (x_3 :: xs) (y :: ys) (z :: zs) = f x_3 y z :: List.zipWith₃ f xs ys zs
- List.zipWith₃ f x✝¹ x✝ x = []
Instances For
Quaternary version of List.zipWith.
Equations
- List.zipWith₄ f (x_4 :: xs) (y :: ys) (z :: zs) (u :: us) = f x_4 y z u :: List.zipWith₄ f xs ys zs us
- List.zipWith₄ f x✝² x✝¹ x✝ x = []
Instances For
Quinary version of List.zipWith.
Equations
- List.zipWith₅ f (x_5 :: xs) (y :: ys) (z :: zs) (u :: us) (v :: vs) = f x_5 y z u v :: List.zipWith₅ f xs ys zs us vs
- List.zipWith₅ f x✝³ x✝² x✝¹ x✝ x = []
Instances For
An auxiliary function for List.mapWithPrefixSuffix.
Equations
- List.mapWithPrefixSuffixAux f x [] = []
- List.mapWithPrefixSuffixAux f x (a :: l₂) = f x a l₂ :: List.mapWithPrefixSuffixAux f (x.concat a) l₂
Instances For
List.mapWithPrefixSuffix f l maps f across a list l.
For each a ∈ l with l = pref ++ [a] ++ suff, a is mapped to f pref a suff.
Example: if f : list Nat → Nat → list Nat → β,
List.mapWithPrefixSuffix f [1, 2, 3] will produce the list
[f [] 1 [2, 3], f [1] 2 [3], f [1, 2] 3 []].
Equations
- List.mapWithPrefixSuffix f l = List.mapWithPrefixSuffixAux f [] l
Instances For
List.mapWithComplement f l is a variant of List.mapWithPrefixSuffix
that maps f across a list l.
For each a ∈ l with l = pref ++ [a] ++ suff, a is mapped to f a (pref ++ suff),
i.e., the list input to f is l with a removed.
Example: if f : Nat → list Nat → β, List.mapWithComplement f [1, 2, 3] will produce the list
[f 1 [2, 3], f 2 [1, 3], f 3 [1, 2]].
Equations
- List.mapWithComplement f = List.mapWithPrefixSuffix fun (pref : List α) (a : α) (suff : List α) => f a (pref ++ suff)
Instances For
Map each element of a List to an action, evaluate these actions in order,
and collect the results.
Equations
- List.traverse f [] = pure []
- List.traverse f (head :: as) = Seq.seq (List.cons <$> f head) fun (x : Unit) => List.traverse f as
Instances For
Perm l₁ l₂ or l₁ ~ l₂ asserts that l₁ and l₂ are permutations
of each other. This is defined by induction using pairwise swaps.
- nil: ∀ {α : Type u_1}, [].Perm []
[] ~ [] - cons: ∀ {α : Type u_1} (x : α) {l₁ l₂ : List α}, l₁.Perm l₂ → (x :: l₁).Perm (x :: l₂)
l₁ ~ l₂ → x::l₁ ~ x::l₂ - swap: ∀ {α : Type u_1} (x y : α) (l : List α), (y :: x :: l).Perm (x :: y :: l)
x::y::l ~ y::x::l - trans: ∀ {α : Type u_1} {l₁ l₂ l₃ : List α}, l₁.Perm l₂ → l₂.Perm l₃ → l₁.Perm l₃
Permis transitive.
Instances For
Perm l₁ l₂ or l₁ ~ l₂ asserts that l₁ and l₂ are permutations
of each other. This is defined by induction using pairwise swaps.
Equations
- List.«term_~_» = Lean.ParserDescr.trailingNode `List.term_~_ 50 50 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ~ ") (Lean.ParserDescr.cat `term 51))
Instances For
Subperm l₁ l₂, denoted l₁ <+~ l₂, means that l₁ is a sublist of
a permutation of l₂. This is an analogue of l₁ ⊆ l₂ which respects
multiplicities of elements, and is used for the ≤ relation on multisets.
Instances For
Subperm l₁ l₂, denoted l₁ <+~ l₂, means that l₁ is a sublist of
a permutation of l₂. This is an analogue of l₁ ⊆ l₂ which respects
multiplicities of elements, and is used for the ≤ relation on multisets.
Equations
- List.«term_<+~_» = Lean.ParserDescr.trailingNode `List.term_<+~_ 50 50 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " <+~ ") (Lean.ParserDescr.cat `term 51))
Instances For
O(|l₁| * (|l₁| + |l₂|)). Computes whether l₁ is a sublist of a permutation of l₂.
See isSubperm_iff for a characterization in terms of List.Subperm.
Equations
- l₁.isSubperm l₂ = decide (∀ (x : α), x ∈ l₁ → List.count x l₁ ≤ List.count x l₂)
Instances For
O(|l| + |r|). Merge two lists using s as a switch.
Equations
- List.merge s l r = List.merge.loop s l r []
Instances For
Inner loop for List.merge. Tail recursive.
Equations
- List.merge.loop s [] x✝ x = x.reverseAux x✝
- List.merge.loop s x✝ [] x = x.reverseAux x✝
- List.merge.loop s (a :: l) (b :: r) x = bif s a b then List.merge.loop s l (b :: r) (a :: x) else List.merge.loop s (a :: l) r (b :: x)