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 List.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
a
relates tob
andb::l
is a chain, thena :: b :: l
is 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 none
s 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₃
Perm
is 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)