Documentation

BasicLeanDatastructures.List.Basic

This file contains a collection definitions and theorems about lists that are not part of Lean's standard library. At least when initially writing some of these, suitable variants did not exist or I simply did not find them.

Some cleanup is certainly needed here.

def List.toSet {α : Type u_1} (l : List α) :
Set α

We can convert a list to a set by defining membership in the set through membership in the list.

Equations
Instances For
    @[simp]
    theorem List.mem_toSet {α : Type u_1} {l : List α} {e : α} :
    e l.toSet e l

    Membership does not change across the toSet conversion.

    theorem List.getElem_mem_toSet {α : Type u_1} (l : List α) (i : Fin l.length) :

    For each valid index, the list element at that index is also in toSet.

    @[simp]
    theorem List.map_toSet_eq_toSet_map {α : Type u_1} {β : Type u_2} {l : List α} {f : αβ} :
    l.toSet.map f = (map f l).toSet

    Converting a list to a set and then applying a function to each element is the same as first applyign the function and then converting to the set.

    theorem List.mem_toSet_map_of_mem_toSet {α : Type u_1} {β : Type u_2} {l : List α} {e : α} {f : αβ} :
    e l.toSetf e (map f l).toSet

    For each element of l.toSet, the mapped version of that element is in the set obtained from the mapped list.

    theorem List.sum_take_le_sum (l : List Nat) (i : Fin (l.length + 1)) :
    (take (↑i) l).sum l.sum

    The sum of taking any number of elements from a list cannot exceed the sum over the whole list.

    def List.zipIdx_with_lt {α : Type u_1} (l : List α) :
    List (α × Fin l.length)

    This function is essentially List.zipIdx but the indices are associated with a proof that they are indeed smaller than the length of the list, represented as Fin.

    Equations
    Instances For
      @[simp]

      The length of zipIdx_with_lt is the original length.

      @[simp]
      theorem List.zipIdx_with_lt_getElem_fst_eq_getElem {α : Type u_1} {l : List α} {index : Nat} (h : index < l.length) :
      l.zipIdx_with_lt[index].fst = l[index]

      The first part of a pair at a given index in zipIdx_with_lt corresponds to the list element at the same index.

      @[simp]
      theorem List.zipIdx_with_lt_getElem_snd_eq_index {α : Type u_1} {l : List α} {index : Nat} (h : index < l.length) :
      l.zipIdx_with_lt[index].snd = index, h

      The second part of a pair at a given index in zipIdx_with_lt is exactly this index (represented as Fin).

      @[simp]
      theorem List.mem_zipIdx_with_lt_iff_mem_zipIdx {α : Type u_1} {l : List α} (i : Fin l.length) (el : α) :

      Membership in zipIdx_with_lt is equivalent to membership in List.zipIdx.

      theorem List.mk_mem_zipIdx_with_lt_iff_getElem {α : Type u_1} {l : List α} (i : Fin l.length) (el : α) :
      (el, i) l.zipIdx_with_lt l[i] = el

      A pair of an element el and an index i is in zipIdx_with_lt if and only if el is at index i in the underlying list.

      theorem List.neg_all_of_any_neg {α : Type u_1} (l : List α) (p : αBool) :
      (l.any fun (a : α) => decide ¬p a = true) = true¬l.all p = true

      Converts any with a negated predicate into a negated call to all with a positive predicate.

      theorem List.append_args_eq_of_append_eq_of_same_length {α : Type u_1} {as bs cs ds : List α} (h : as.length = cs.length) :
      as ++ bs = cs ++ dsas = cs bs = ds

      Components of two append calls are equal if the appended lists are equal and the first components have the same length.

      theorem List.append_eq_append_of_parts_eq {α : Type u_1} (as bs cs ds : List α) :
      as = csbs = dsas ++ bs = cs ++ ds

      Two lists resulting from append calls are equal if the individual components are equal.

      theorem List.append_left_same_length_of_append_eq_append_of_right_same_length {α : Type u_1} {as bs cs ds : List α} :
      as ++ bs = cs ++ dsbs.length = ds.lengthas.length = cs.length

      If two lists resulting from append calls are equal and the second components have the same length, then the first components also have the same length.

      theorem List.head_cons_tail_of_ne_nil {α : Type u_1} {l : List α} (h : l []) :
      l = l.head h :: l.tail

      A non-empty list can be split into its head and tail.

      theorem List.mem_iff_append_and_not_in_first {α : Type u_1} [DecidableEq α] (l : List α) (e : α) :
      e l (as : List α), (bs : List α), l = as ++ e :: bs ¬e as

      An element is in a list if and only if the list is composable such the element has its first occurrence in this composition.

      theorem List.map_id_of_id_on_all_mem {α : Type u_1} (l : List α) (f : αα) (id_on_all_mem : ∀ (e : α), e lf e = e) :
      map f l = l

      Mapping over list produces the same list if the mapping function maps each list member to itself. Note that this is very close to List.map_id'' but that List.map_id'' has a stronger assumption. Namely it requires the function to be the id not only on list elements but on every representant of the element type.

      theorem List.filter_eq_of_all_eq {α : Type u_1} (l : List α) (p q : αBool) :
      (∀ (e : α), e lp e = q e)filter p l = filter q l

      Filtering a list based on two predicates yields the same list if the predicates behave the same on all elements.

      @[simp]
      theorem List.eq_iff_unattach_eq {α : Type u} {p : αProp} {as bs : List { x : α // p x }} :
      as.unattach = bs.unattach as = bs

      Lists over subtypes are equal if and only if their unattached versions are equal.

      theorem List.contains_dup_of_exceeding_nodup_list_with_same_elements {α : Type u_1} [DecidableEq α] (as bs : List α) (nodup_as : as.Nodup) (len_lt : as.length < bs.length) (contains_all : bs as) :

      A list that is longer than a list without duplicates but only contains the same elements must have a duplicate.

      theorem List.filter_eq_of_eq {α : Type u_1} {as bs : List α} :
      as = bs∀ (f : αBool), filter f as = filter f bs

      For two equal lists, filter does the same.

      theorem List.map_eq_of_eq {α : Type u_1} {β : Type u_2} {as bs : List α} :
      as = bs∀ (f : αβ), map f as = map f bs

      For two equal lists, map does the same.

      theorem List.flatten_eq_of_eq {α : Type u_1} {as bs : List (List α)} :
      as = bsas.flatten = bs.flatten

      For two equal lists, flatten does the same.

      theorem List.getElem_eq_getElem_of_idx_eq {α : Type u_1} {l : List α} {i j : Nat} {i_lt : i < l.length} (idx_eq : i = j) :
      l[i] = l[j]

      Elements at equal indices are the same.

      theorem List.getElem_idxOf_of_mem {α : Type u_1} [BEq α] [LawfulBEq α] {l : List α} {e : α} (mem : e l) :
      l[idxOf e l] = e

      We getting the element at the index of a given element e, we obtain exactly e. Note that this depends on LawfulBEq.

      theorem List.idxOf_getElem {α : Type u_1} [DecidableEq α] {l : List α} {i : Nat} {lt : i < l.length} (nodup : l.Nodup) :
      idxOf l[i] l = i

      The index of an element that we get from given index is exactly this index. Note that this uses DecidableEq.