List operations
TheoremList positions agree with values of an increasing map#✓fully proved
In a list along which f increases, position order agrees with value order.
TheoremPairwise relations on list products in lexicographic order#✓fully proved
The Cartesian product of two pairwise-related lists is pairwise-related in lexicographic order.
TheoremStart position of a chunk in a split list#✓fully proved
A valid indexed chunk begins after the total length of the preceding chunks.
theorem getD_splitLengths {α : Type*} (xs : List α) (lengths : List ℕ) (fallback : List α)
{i : ℕ} (hi : i < lengths.length) :
(lengths.splitLengths xs).getD i fallback =
(xs.drop (lengths.take i).sum).take lengths[i]
Used by 2
TheoremNamed chunk lookup uses the first occurrence#✓fully proved
Looking up a named chunk uses the first occurrence of its name.
theorem getD_splitLengths_map {ι α : Type*} [BEq ι] [LawfulBEq ι]
(length : ι → ℕ) (names : List ι) (xs fallback : List α) {i : ι} (hi : i ∈ names) :
((names.map length).splitLengths xs).getD (names.idxOf i) fallback =
(xs.drop ((names.map length).take (names.idxOf i)).sum).take (length i)
Uses 1
TheoremSplitting a list at a repeated width#✓fully proved
Splitting at a repeated width recovers the corresponding uniform chunk.
theorem getD_splitLengths_replicate {α : Type*} (width count i : ℕ)
(xs fallback : List α) (hi : i < count) :
((List.replicate count width).splitLengths xs).getD i fallback =
(xs.drop (i * width)).take width
Uses 1
TheoremEquality of uniformly split lists from equal block extracts#✓fully proved
Lists of the same uniform-block length are equal when every block extract agrees.
theorem eq_of_extract_mul_eq {α : Type*} (width count : ℕ) (xs ys : List α)
(hxs : xs.length = count * width) (hys : ys.length = count * width)
(h : ∀ i < count,
xs.extract (i * width) (i * width + width) =
ys.extract (i * width) (i * width + width)) :
xs = ys
TheoremLength of a concatenation of equal-length lists#✓fully proved
Concatenating count lists of length width has length count * width.
theorem length_flatMap_range {α : Type*} (count width : ℕ) (blocks : ℕ → List α)
(hblocks : ∀ i < count, (blocks i).length = width) :
((List.range count).flatMap blocks).length = count * width
Used by 1
TheoremExtracting a member from a uniform-width concatenation#✓fully proved
A uniform-width extract of a concatenated family recovers that family member.
theorem extract_flatMap_range {α : Type*} (count width : ℕ) (blocks : ℕ → List α)
(hblocks : ∀ i < count, (blocks i).length = width) {i : ℕ} (hi : i < count) :
((List.range count).flatMap blocks).extract (i * width) (i * width + width) =
blocks i
Used by 1
TheoremEvery equal-length list family is realized by its concatenation#✓fully proved
Every finite family of equal-length lists is realized by their concatenation.
DefinitionInclusive first-hit prefix of a list#✓fully proved
The prefix through the first element satisfying p, including that element. If no element
satisfies p, this is the whole list.
Used by 15
TheoremInclusive first-hit prefix of the empty list#✓fully proved
The inclusive first-hit prefix of an empty list is empty.
@[simp] theorem takeThrough_nil {α : Type*} (p : α → Bool) : takeThrough p [] = []
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 1 · Used by 5
TheoremInclusive first-hit prefix when the head is a hit#✓fully proved
If the head satisfies the predicate, it is the whole inclusive first-hit prefix.
@[simp] theorem takeThrough_cons_of_pos {α : Type*} {p : α → Bool} {x : α}
(h : p x = true) (xs : List α) : takeThrough p (x :: xs) = [x]
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 1 · Used by 8
TheoremInclusive first-hit prefix when the head is not a hit#✓fully proved
If the head does not satisfy the predicate, the search continues through the tail.
@[simp] theorem takeThrough_cons_of_neg {α : Type*} {p : α → Bool} {x : α}
(h : p x = false) (xs : List α) :
takeThrough p (x :: xs) = x :: takeThrough p xs
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 1 · Used by 10
TheoremInclusive first-hit prefix of a singleton#✓fully proved
A singleton is its own inclusive first-hit prefix.
@[simp] theorem takeThrough_singleton {α : Type*} (p : α → Bool) (x : α) :
takeThrough p [x] = [x]
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
TheoremMembers of an inclusive first-hit prefix lie in the list#✓fully proved
Every member of an inclusive first-hit prefix belongs to the source list.
theorem mem_of_mem_takeThrough {α : Type*} {p : α → Bool} {xs : List α} {x : α}
(h : x ∈ takeThrough p xs) : x ∈ xs
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 1
TheoremInclusive first-hit prefix of a list with no hit#✓fully proved
If no element satisfies the predicate, the inclusive first-hit prefix is the whole list.
theorem takeThrough_eq_self_of_any_eq_false {α : Type*} {p : α → Bool} {xs : List α}
(h : xs.any p = false) : takeThrough p xs = xs
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 3
TheoremInclusive first-hit prefix of an append with a hit on the left#✓fully proved
Once the left list has a hit, appending another list does not change the prefix.
theorem takeThrough_append_of_any_eq_true {α : Type*} {p : α → Bool} {xs : List α}
(h : xs.any p = true) (ys : List α) : takeThrough p (xs ++ ys) = takeThrough p xs
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 3
TheoremInclusive first-hit prefix of an append with no hit on the left#✓fully proved
If the left list has no hit, the prefix contains all of it and continues into the right list.
theorem takeThrough_append_of_any_eq_false {α : Type*} {p : α → Bool} {xs : List α}
(h : xs.any p = false) (ys : List α) :
takeThrough p (xs ++ ys) = xs ++ takeThrough p ys
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 2
TheoremInclusive first-hit prefix has a hit iff the list does#✓fully proved
The inclusive first-hit prefix has a hit exactly when the source list has one.
theorem any_takeThrough {α : Type*} (p : α → Bool) (xs : List α) :
(takeThrough p xs).any p = xs.any p
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
TheoremInclusive first-hit prefix of a range of naturals#✓fully proved
On range n, the prefix ends one past the first hit, or at n if there is no hit.
theorem takeThrough_range (q : Nat → Bool) (n : Nat) :
takeThrough q (range n) =
range (match (range n).find? q with | some i => i + 1 | none => n)
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 1
TheoremInclusive first-hit prefix commutes with filter-map#✓fully proved
Filtering selected elements from an inclusive prefix commutes with taking the corresponding inclusive prefix of the selected elements.
theorem filterMap_takeThrough {α β : Type*} (sel : α → Option β) (p : β → Bool)
(xs : List α) :
(takeThrough (fun x => (sel x).any p) xs).filterMap sel =
takeThrough p (xs.filterMap sel)
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
DefinitionAccumulator-stopped inclusive prefix of a list#✓fully proved
The prefix through the first element after whose update the accumulator satisfies stop,
including that element. The initial accumulator is not tested. If no updated accumulator satisfies
stop, this is the whole list.
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
Used by 8
TheoremAccumulator-stopped prefix of the empty list#✓fully proved
An empty list has an empty accumulator-stopped prefix.
@[simp] theorem takeThroughAcc_nil {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool)
(c : γ) : takeThroughAcc f stop c [] = []
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
Uses 1
TheoremAccumulator-stopped prefix when the head update stops#✓fully proved
If the accumulator stops after the head update, the prefix contains only the head.
@[simp] theorem takeThroughAcc_cons_of_stop {α γ : Type*} {f : γ → α → γ}
{stop : γ → Bool} {c : γ} {x : α} (h : stop (f c x) = true) (xs : List α) :
takeThroughAcc f stop c (x :: xs) = [x]
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
Uses 1
TheoremAccumulator-stopped prefix when the head update continues#✓fully proved
If the accumulator continues after the head update, the same updated accumulator processes the tail.
@[simp] theorem takeThroughAcc_cons_of_continue {α γ : Type*} {f : γ → α → γ}
{stop : γ → Bool} {c : γ} {x : α} (h : stop (f c x) = false) (xs : List α) :
takeThroughAcc f stop c (x :: xs) = x :: takeThroughAcc f stop (f c x) xs
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
Uses 1
TheoremAccumulator-stopped list is a prefix of its source#✓fully proved
The accumulator-stopped list is a prefix of its source list.
theorem takeThroughAcc_prefix {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool)
(c : γ) (xs : List α) : takeThroughAcc f stop c xs <+: xs
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
Uses 1 · Used by 1
TheoremMembers of an accumulator-stopped prefix lie in the list#✓fully proved
Every member of an accumulator-stopped prefix belongs to the source list.
theorem mem_of_mem_takeThroughAcc {α γ : Type*} {f : γ → α → γ} {stop : γ → Bool}
{c : γ} {xs : List α} {x : α} (h : x ∈ takeThroughAcc f stop c xs) : x ∈ xs
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
Uses 2
TheoremDisjunction accumulator gives the inclusive first-hit prefix#✓fully proved
Accumulating disjunction from false gives the ordinary inclusive first-hit prefix.
theorem takeThroughAcc_or {α : Type*} (p : α → Bool) (xs : List α) :
takeThroughAcc (fun found x => found || p x) id false xs = takeThrough p xs
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
TheoremFirst-witness accumulator gives the inclusive first-hit prefix#✓fully proved
Accumulating a projection of the first witness in an Option gives the ordinary inclusive
first-hit prefix.
theorem takeThroughAcc_first {α β δ : Type*} (p : β → Bool) (v : α → β) (w : α → δ)
(xs : List α) :
takeThroughAcc (fun found x =>
match found with
| some old => some old
| none => if p (v x) then some (w x) else none)
Option.isSome none xs = takeThrough (fun x => p (v x)) xs
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
TheoremFirst-witness fold over the inclusive first-hit prefix#✓fully proved
Folding the first-witness update over the inclusive tested prefix returns the first witness in the whole source list.
theorem foldl_first_takeThrough {α β δ : Type*} (p : β → Bool) (v : α → β) (w : α → δ)
(xs : List α) :
(takeThrough (fun x => p (v x)) xs).foldl
(fun found x =>
match found with
| some old => some old
| none => if p (v x) then some (w x) else none) none =
(xs.find? fun x => p (v x)).map w
def takeThrough {α : Type*} (p : α → Bool) (xs : List α) : List α :=
xs.take (xs.findIdx p + 1)
MathlibExt/Data/List/TakeThrough.lean:29
Uses 3
TheoremAccumulator-stopped prefix as a first-hit prefix of a scan#✓fully proved
The recursive ETH operation is the ordinary inclusive first-hit prefix of the elements paired with their updated accumulators.
theorem takeThroughAcc_eq_map_takeThrough_scanl {α γ : Type*} (f : γ → α → γ)
(stop : γ → Bool) (c : γ) (xs : List α) :
takeThroughAcc f stop c xs =
((xs.zip (xs.scanl f c).tail).takeThrough (fun x => stop x.2)).map Prod.fst
def takeThroughAcc {α γ : Type*} (f : γ → α → γ) (stop : γ → Bool) :
γ → List α → List α
| _, [] => []
| c, x :: xs =>
let c' := f c x
if stop c' then [x] else x :: takeThroughAcc f stop c' xs
MathlibExt/Data/List/TakeThroughAcc.lean:34
TheoremChunks of a list have length at most the chunk size#✓fully proved
Let \(n > 0\) and let \(L\) be a list. Split \(L\) from left to right into consecutive chunks of size \(n\): elements go into the current chunk until it holds \(n\) elements, then a new chunk is started. Every chunk produced has at most \(n\) elements.
theorem length_le_of_mem_toChunks {α : Type u} (n : Nat) (xs : List α)
(hn : 0 < n) (chunk : List α) (hchunk : chunk ∈ toChunks n xs) :
chunk.length ≤ n
Used by 1
DefinitionOrdered insertion into a list#✓fully proved
For an element \(x\) of a linearly ordered type, the ordered insertion of \(x\) into the empty list is \([x]\). For a list with head \(a\) and tail \(\ell\), it is \(x\) followed by the whole list if \(x < a\); it is \(a\) followed by the ordered insertion of \(x\) into \(\ell\) if \(a < x\); and it is the list unchanged if \(a = x\).
On a strictly increasing list a key that is already present is therefore ignored. On an unsorted list a later duplicate is not detected: inserting \(2\) into \([3, 2]\) gives \([2, 3, 2]\).
public def orderedInsert [LinearOrder α] (x : α) : List α → List α
| [] => [x]
| a :: as =>
if x < a then x :: a :: as
else if a < x then a :: orderedInsert x as
else a :: as
Used by 13
TheoremMembers after ordered insertion#✓fully proved
Over a linearly ordered type, for all elements \(x\), \(y\) and every list \(\ell\), the element \(y\) belongs to the ordered insertion of \(x\) into \(\ell\) if and only if \(y = x\) or \(y\) belongs to \(\ell\).
public theorem mem_orderedInsert [LinearOrder α] {x y : α} {xs : List α} :
y ∈ orderedInsert x xs ↔ y = x ∨ y ∈ xs
public def orderedInsert [LinearOrder α] (x : α) : List α → List α
| [] => [x]
| a :: as =>
if x < a then x :: a :: as
else if a < x then a :: orderedInsert x as
else a :: as
CSLibExt/Algorithms/Lean/DataStructures/OrderedInsert.lean:44
Uses 1 · Used by 3
TheoremInserting a present element into a strictly increasing list#✓fully proved
Over a linearly ordered type, if every element of a list \(\ell\) is smaller than every later element of \(\ell\) and \(x\) belongs to \(\ell\), then the ordered insertion of \(x\) into \(\ell\) is \(\ell\) itself.
Without strict increase this fails: inserting \(2\) into \([3, 2]\) gives \([2, 3, 2]\).
public theorem orderedInsert_eq_of_mem [LinearOrder α] {x : α} {xs : List α}
(hSorted : xs.Pairwise (· < ·)) (hMem : x ∈ xs) :
orderedInsert x xs = xs
public def orderedInsert [LinearOrder α] (x : α) : List α → List α
| [] => [x]
| a :: as =>
if x < a then x :: a :: as
else if a < x then a :: orderedInsert x as
else a :: as
CSLibExt/Algorithms/Lean/DataStructures/OrderedInsert.lean:44
Uses 1 · Used by 3
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.