File: Mathlib/Data/List/Sigma.lean

full_name: List.keys
code: /-- List of keys from a list of key-value pairs -/
def keys : List (Sigma β) → List α 
goal: List (Sigma β) → List α

full_name: List.keys_nil
code: @[simp]
theorem keys_nil : @keys α β [] = [] 
goal: [].keys = []

full_name: List.keys_cons
code: @[simp]
theorem keys_cons {s} {l : List (Sigma β)} : (s :: l).keys = s.1 :: l.keys 
goal: (s :: l).keys = s.fst :: l.keys

full_name: List.mem_keys_of_mem
code: theorem mem_keys_of_mem {s : Sigma β} {l : List (Sigma β)} : s ∈ l → s.1 ∈ l.keys 
goal: s ∈ l → s.fst ∈ l.keys

full_name: List.exists_of_mem_keys
code: theorem exists_of_mem_keys {a} {l : List (Sigma β)} (h : a ∈ l.keys) :
    ∃ b : β a, Sigma.mk a b ∈ l 
goal: ∃ b, ⟨a, b⟩ ∈ l

full_name: List.mem_keys
code: theorem mem_keys {a} {l : List (Sigma β)} : a ∈ l.keys ↔ ∃ b : β a, Sigma.mk a b ∈ l 
goal: a ∈ l.keys ↔ ∃ b, ⟨a, b⟩ ∈ l

full_name: List.not_mem_keys
code: theorem not_mem_keys {a} {l : List (Sigma β)} : a ∉ l.keys ↔ ∀ b : β a, Sigma.mk a b ∉ l 
goal: a ∉ l.keys ↔ ∀ (b : β a), ⟨a, b⟩ ∉ l

full_name: List.not_eq_key
code: theorem not_eq_key {a} {l : List (Sigma β)} : a ∉ l.keys ↔ ∀ s : Sigma β, s ∈ l → a ≠ s.1 
goal: a ∉ l.keys ↔ ∀ s ∈ l, a ≠ s.fst

full_name: List.NodupKeys
code: /-- Determines whether the store uses a key several times. -/
def NodupKeys (l : List (Sigma β)) : Prop 
goal: Prop

full_name: List.nodupKeys_iff_pairwise
code: theorem nodupKeys_iff_pairwise {l} : NodupKeys l ↔ Pairwise (fun s s' : Sigma β => s.1 ≠ s'.1) l 
goal: l.NodupKeys ↔ List.Pairwise (fun s s' => s.fst ≠ s'.fst) l

full_name: List.NodupKeys.pairwise_ne
code: theorem NodupKeys.pairwise_ne {l} (h : NodupKeys l) :
    Pairwise (fun s s' : Sigma β => s.1 ≠ s'.1) l 
goal: List.Pairwise (fun s s' => s.fst ≠ s'.fst) l

full_name: List.nodupKeys_nil
code: @[simp]
theorem nodupKeys_nil : @NodupKeys α β [] 
goal: [].NodupKeys

full_name: List.nodupKeys_cons
code: @[simp]
theorem nodupKeys_cons {s : Sigma β} {l : List (Sigma β)} :
    NodupKeys (s :: l) ↔ s.1 ∉ l.keys ∧ NodupKeys l 
goal: (s :: l).NodupKeys ↔ s.fst ∉ l.keys ∧ l.NodupKeys

full_name: List.not_mem_keys_of_nodupKeys_cons
code: theorem not_mem_keys_of_nodupKeys_cons {s : Sigma β} {l : List (Sigma β)} (h : NodupKeys (s :: l)) :
    s.1 ∉ l.keys 
goal: s.fst ∉ l.keys

full_name: List.nodupKeys_of_nodupKeys_cons
code: theorem nodupKeys_of_nodupKeys_cons {s : Sigma β} {l : List (Sigma β)} (h : NodupKeys (s :: l)) :
    NodupKeys l 
goal: l.NodupKeys

full_name: List.NodupKeys.eq_of_fst_eq
code: theorem NodupKeys.eq_of_fst_eq {l : List (Sigma β)} (nd : NodupKeys l) {s s' : Sigma β} (h : s ∈ l)
    (h' : s' ∈ l) : s.1 = s'.1 → s = s' 
goal: s.fst = s'.fst → s = s'

full_name: List.NodupKeys.eq_of_mk_mem
code: theorem NodupKeys.eq_of_mk_mem {a : α} {b b' : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) (h' : Sigma.mk a b' ∈ l) : b = b' 
goal: b = b'

full_name: List.nodupKeys_singleton
code: theorem nodupKeys_singleton (s : Sigma β) : NodupKeys [s] 
goal: [s].NodupKeys

full_name: List.NodupKeys.sublist
code: theorem NodupKeys.sublist {l₁ l₂ : List (Sigma β)} (h : l₁ <+ l₂) : NodupKeys l₂ → NodupKeys l₁ 
goal: l₂.NodupKeys → l₁.NodupKeys

full_name: List.NodupKeys.nodup
code: protected theorem NodupKeys.nodup {l : List (Sigma β)} : NodupKeys l → Nodup l 
goal: l.NodupKeys → l.Nodup

full_name: List.perm_nodupKeys
code: theorem perm_nodupKeys {l₁ l₂ : List (Sigma β)} (h : l₁ ~ l₂) : NodupKeys l₁ ↔ NodupKeys l₂ 
goal: l₁.NodupKeys ↔ l₂.NodupKeys

full_name: List.nodupKeys_join
code: theorem nodupKeys_join {L : List (List (Sigma β))} :
    NodupKeys (join L) ↔ (∀ l ∈ L, NodupKeys l) ∧ Pairwise Disjoint (L.map keys) 
goal: L.join.NodupKeys ↔ (∀ l ∈ L, l.NodupKeys) ∧ List.Pairwise List.Disjoint (List.map List.keys L)

full_name: List.nodup_enum_map_fst
code: theorem nodup_enum_map_fst (l : List α) : (l.enum.map Prod.fst).Nodup 
goal: (List.map Prod.fst l.enum).Nodup

full_name: List.mem_ext
code: theorem mem_ext {l₀ l₁ : List (Sigma β)} (nd₀ : l₀.Nodup) (nd₁ : l₁.Nodup)
    (h : ∀ x, x ∈ l₀ ↔ x ∈ l₁) : l₀ ~ l₁ 
goal: l₀.Perm l₁

full_name: List.dlookup
code: /-- `dlookup a l` is the first value in `l` corresponding to the key `a`,
  or `none` if no such element exists. -/
def dlookup (a : α) : List (Sigma β) → Option (β a)
  
goal: List (Sigma β) → Option (β a)

full_name: List.dlookup_nil
code: @[simp]
theorem dlookup_nil (a : α) : dlookup a [] = @none (β a) 
goal: List.dlookup a [] = none

full_name: List.dlookup_cons_eq
code: @[simp]
theorem dlookup_cons_eq (l) (a : α) (b : β a) : dlookup a (⟨a, b⟩ :: l) = some b 
goal: List.dlookup a (⟨a, b⟩ :: l) = some b

full_name: List.dlookup_cons_ne
code: @[simp]
theorem dlookup_cons_ne (l) {a} : ∀ s : Sigma β, a ≠ s.1 → dlookup a (s :: l) = dlookup a l
  
goal: a ≠ s.fst → List.dlookup a (s :: l) = List.dlookup a l

full_name: List.dlookup_isSome
code: theorem dlookup_isSome {a : α} : ∀ {l : List (Sigma β)}, (dlookup a l).isSome ↔ a ∈ l.keys
  
goal: (List.dlookup a l).isSome = true ↔ a ∈ l.keys

full_name: List.dlookup_eq_none
code: theorem dlookup_eq_none {a : α} {l : List (Sigma β)} : dlookup a l = none ↔ a ∉ l.keys 
goal: List.dlookup a l = none ↔ a ∉ l.keys

full_name: List.of_mem_dlookup
code: theorem of_mem_dlookup {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ dlookup a l → Sigma.mk a b ∈ l
  
goal: b ∈ List.dlookup a l → ⟨a, b⟩ ∈ l

full_name: List.mem_dlookup
code: theorem mem_dlookup {a} {b : β a} {l : List (Sigma β)} (nd : l.NodupKeys) (h : Sigma.mk a b ∈ l) :
    b ∈ dlookup a l 
goal: b ∈ List.dlookup a l

full_name: List.map_dlookup_eq_find
code: theorem map_dlookup_eq_find (a : α) :
    ∀ l : List (Sigma β), (dlookup a l).map (Sigma.mk a) = find? (fun s => a = s.1) l
  
goal: Option.map (Sigma.mk a) (List.dlookup a l) = List.find? (fun s => decide (a = s.fst)) l

full_name: List.mem_dlookup_iff
code: theorem mem_dlookup_iff {a : α} {b : β a} {l : List (Sigma β)} (nd : l.NodupKeys) :
    b ∈ dlookup a l ↔ Sigma.mk a b ∈ l 
goal: b ∈ List.dlookup a l ↔ ⟨a, b⟩ ∈ l

full_name: List.perm_dlookup
code: theorem perm_dlookup (a : α) {l₁ l₂ : List (Sigma β)} (nd₁ : l₁.NodupKeys) (nd₂ : l₂.NodupKeys)
    (p : l₁ ~ l₂) : dlookup a l₁ = dlookup a l₂ 
goal: List.dlookup a l₁ = List.dlookup a l₂

full_name: List.lookup_ext
code: theorem lookup_ext {l₀ l₁ : List (Sigma β)} (nd₀ : l₀.NodupKeys) (nd₁ : l₁.NodupKeys)
    (h : ∀ x y, y ∈ l₀.dlookup x ↔ y ∈ l₁.dlookup x) : l₀ ~ l₁ 
goal: l₀.Perm l₁

full_name: List.lookupAll
code: /-- `lookup_all a l` is the list of all values in `l` corresponding to the key `a`. -/
def lookupAll (a : α) : List (Sigma β) → List (β a)
  
goal: List (Sigma β) → List (β a)

full_name: List.lookupAll_nil
code: @[simp]
theorem lookupAll_nil (a : α) : lookupAll a [] = @nil (β a) 
goal: List.lookupAll a [] = []

full_name: List.lookupAll_cons_eq
code: @[simp]
theorem lookupAll_cons_eq (l) (a : α) (b : β a) : lookupAll a (⟨a, b⟩ :: l) = b :: lookupAll a l 
goal: List.lookupAll a (⟨a, b⟩ :: l) = b :: List.lookupAll a l

full_name: List.lookupAll_cons_ne
code: @[simp]
theorem lookupAll_cons_ne (l) {a} : ∀ s : Sigma β, a ≠ s.1 → lookupAll a (s :: l) = lookupAll a l
  
goal: a ≠ s.fst → List.lookupAll a (s :: l) = List.lookupAll a l

full_name: List.lookupAll_eq_nil
code: theorem lookupAll_eq_nil {a : α} :
    ∀ {l : List (Sigma β)}, lookupAll a l = [] ↔ ∀ b : β a, Sigma.mk a b ∉ l
  
goal: List.lookupAll a l = [] ↔ ∀ (b : β a), ⟨a, b⟩ ∉ l

full_name: List.head?_lookupAll
code: theorem head?_lookupAll (a : α) : ∀ l : List (Sigma β), head? (lookupAll a l) = dlookup a l
  
goal: (List.lookupAll a l).head? = List.dlookup a l

full_name: List.mem_lookupAll
code: theorem mem_lookupAll {a : α} {b : β a} :
    ∀ {l : List (Sigma β)}, b ∈ lookupAll a l ↔ Sigma.mk a b ∈ l
  
goal: b ∈ List.lookupAll a l ↔ ⟨a, b⟩ ∈ l

full_name: List.lookupAll_sublist
code: theorem lookupAll_sublist (a : α) : ∀ l : List (Sigma β), (lookupAll a l).map (Sigma.mk a) <+ l
  
goal: (List.map (Sigma.mk a) (List.lookupAll a l)).Sublist l

full_name: List.lookupAll_length_le_one
code: theorem lookupAll_length_le_one (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    length (lookupAll a l) ≤ 1 
goal: (List.lookupAll a l).length ≤ 1

full_name: List.lookupAll_eq_dlookup
code: theorem lookupAll_eq_dlookup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) :
    lookupAll a l = (dlookup a l).toList 
goal: List.lookupAll a l = (List.dlookup a l).toList

full_name: List.lookupAll_nodup
code: theorem lookupAll_nodup (a : α) {l : List (Sigma β)} (h : l.NodupKeys) : (lookupAll a l).Nodup 
goal: (List.lookupAll a l).Nodup

full_name: List.perm_lookupAll
code: theorem perm_lookupAll (a : α) {l₁ l₂ : List (Sigma β)} (nd₁ : l₁.NodupKeys) (nd₂ : l₂.NodupKeys)
    (p : l₁ ~ l₂) : lookupAll a l₁ = lookupAll a l₂ 
goal: List.lookupAll a l₁ = List.lookupAll a l₂

full_name: List.kreplace
code: /-- Replaces the first value with key `a` by `b`. -/
def kreplace (a : α) (b : β a) : List (Sigma β) → List (Sigma β) 
goal: List (Sigma β) → List (Sigma β)

full_name: List.kreplace_of_forall_not
code: theorem kreplace_of_forall_not (a : α) (b : β a) {l : List (Sigma β)}
    (H : ∀ b : β a, Sigma.mk a b ∉ l) : kreplace a b l = l 
goal: List.kreplace a b l = l

full_name: List.kreplace_self
code: theorem kreplace_self {a : α} {b : β a} {l : List (Sigma β)} (nd : NodupKeys l)
    (h : Sigma.mk a b ∈ l) : kreplace a b l = l 
goal: List.kreplace a b l = l

full_name: List.keys_kreplace
code: theorem keys_kreplace (a : α) (b : β a) : ∀ l : List (Sigma β), (kreplace a b l).keys = l.keys 
goal: (List.kreplace a b l).keys = l.keys

full_name: List.kreplace_nodupKeys
code: theorem kreplace_nodupKeys (a : α) (b : β a) {l : List (Sigma β)} :
    (kreplace a b l).NodupKeys ↔ l.NodupKeys 
goal: (List.kreplace a b l).NodupKeys ↔ l.NodupKeys

full_name: List.Perm.kreplace
code: theorem Perm.kreplace {a : α} {b : β a} {l₁ l₂ : List (Sigma β)} (nd : l₁.NodupKeys) :
    l₁ ~ l₂ → kreplace a b l₁ ~ kreplace a b l₂ 
goal: l₁.Perm l₂ → (List.kreplace a b l₁).Perm (List.kreplace a b l₂)

full_name: List.kerase
code: /-- Remove the first pair with the key `a`. -/
def kerase (a : α) : List (Sigma β) → List (Sigma β) 
goal: List (Sigma β) → List (Sigma β)

full_name: List.kerase_nil
code: theorem kerase_nil {a} : @kerase _ β _ a [] = [] 
goal: List.kerase a [] = []

full_name: List.kerase_cons_eq
code: @[simp]
theorem kerase_cons_eq {a} {s : Sigma β} {l : List (Sigma β)} (h : a = s.1) :
    kerase a (s :: l) = l 
goal: List.kerase a (s :: l) = l

full_name: List.kerase_cons_ne
code: @[simp]
theorem kerase_cons_ne {a} {s : Sigma β} {l : List (Sigma β)} (h : a ≠ s.1) :
    kerase a (s :: l) = s :: kerase a l 
goal: List.kerase a (s :: l) = s :: List.kerase a l

full_name: List.kerase_of_not_mem_keys
code: @[simp]
theorem kerase_of_not_mem_keys {a} {l : List (Sigma β)} (h : a ∉ l.keys) : kerase a l = l 
goal: List.kerase a l = l

full_name: List.kerase_sublist
code: theorem kerase_sublist (a : α) (l : List (Sigma β)) : kerase a l <+ l 
goal: (List.kerase a l).Sublist l

full_name: List.kerase_keys_subset
code: theorem kerase_keys_subset (a) (l : List (Sigma β)) : (kerase a l).keys ⊆ l.keys 
goal: (List.kerase a l).keys ⊆ l.keys

full_name: List.mem_keys_of_mem_keys_kerase
code: theorem mem_keys_of_mem_keys_kerase {a₁ a₂} {l : List (Sigma β)} :
    a₁ ∈ (kerase a₂ l).keys → a₁ ∈ l.keys 
goal: a₁ ∈ (List.kerase a₂ l).keys → a₁ ∈ l.keys

full_name: List.exists_of_kerase
code: theorem exists_of_kerase {a : α} {l : List (Sigma β)} (h : a ∈ l.keys) :
    ∃ (b : β a) (l₁ l₂ : List (Sigma β)),
      a ∉ l₁.keys ∧ l = l₁ ++ ⟨a, b⟩ :: l₂ ∧ kerase a l = l₁ ++ l₂ 
goal: ∃ b l₁ l₂, a ∉ l₁.keys ∧ l = l₁ ++ ⟨a, b⟩ :: l₂ ∧ List.kerase a l = l₁ ++ l₂

full_name: List.mem_keys_kerase_of_ne
code: @[simp]
theorem mem_keys_kerase_of_ne {a₁ a₂} {l : List (Sigma β)} (h : a₁ ≠ a₂) :
    a₁ ∈ (kerase a₂ l).keys ↔ a₁ ∈ l.keys 
goal: a₁ ∈ (List.kerase a₂ l).keys ↔ a₁ ∈ l.keys

full_name: List.keys_kerase
code: theorem keys_kerase {a} {l : List (Sigma β)} : (kerase a l).keys = l.keys.erase a 
goal: (List.kerase a l).keys = l.keys.erase a

full_name: List.kerase_kerase
code: theorem kerase_kerase {a a'} {l : List (Sigma β)} :
    (kerase a' l).kerase a = (kerase a l).kerase a' 
goal: List.kerase a (List.kerase a' l) = List.kerase a' (List.kerase a l)

full_name: List.NodupKeys.kerase
code: theorem NodupKeys.kerase (a : α) : NodupKeys l → (kerase a l).NodupKeys 
goal: l.NodupKeys → (List.kerase a l).NodupKeys

full_name: List.Perm.kerase
code: theorem Perm.kerase {a : α} {l₁ l₂ : List (Sigma β)} (nd : l₁.NodupKeys) :
    l₁ ~ l₂ → kerase a l₁ ~ kerase a l₂ 
goal: l₁.Perm l₂ → (List.kerase a l₁).Perm (List.kerase a l₂)

full_name: List.not_mem_keys_kerase
code: @[simp]
theorem not_mem_keys_kerase (a) {l : List (Sigma β)} (nd : l.NodupKeys) :
    a ∉ (kerase a l).keys 
goal: a ∉ (List.kerase a l).keys

full_name: List.dlookup_kerase
code: @[simp]
theorem dlookup_kerase (a) {l : List (Sigma β)} (nd : l.NodupKeys) :
    dlookup a (kerase a l) = none 
goal: List.dlookup a (List.kerase a l) = none

full_name: List.dlookup_kerase_ne
code: @[simp]
theorem dlookup_kerase_ne {a a'} {l : List (Sigma β)} (h : a ≠ a') :
    dlookup a (kerase a' l) = dlookup a l 
goal: List.dlookup a (List.kerase a' l) = List.dlookup a l

full_name: List.kerase_append_left
code: theorem kerase_append_left {a} :
    ∀ {l₁ l₂ : List (Sigma β)}, a ∈ l₁.keys → kerase a (l₁ ++ l₂) = kerase a l₁ ++ l₂
  
goal: a ∈ l₁.keys → List.kerase a (l₁ ++ l₂) = List.kerase a l₁ ++ l₂

full_name: List.kerase_append_right
code: theorem kerase_append_right {a} :
    ∀ {l₁ l₂ : List (Sigma β)}, a ∉ l₁.keys → kerase a (l₁ ++ l₂) = l₁ ++ kerase a l₂
  
goal: a ∉ l₁.keys → List.kerase a (l₁ ++ l₂) = l₁ ++ List.kerase a l₂

full_name: List.kerase_comm
code: theorem kerase_comm (a₁ a₂) (l : List (Sigma β)) :
    kerase a₂ (kerase a₁ l) = kerase a₁ (kerase a₂ l) 
goal: List.kerase a₂ (List.kerase a₁ l) = List.kerase a₁ (List.kerase a₂ l)

full_name: List.sizeOf_kerase
code: theorem sizeOf_kerase [SizeOf (Sigma β)] (x : α)
    (xs : List (Sigma β)) : SizeOf.sizeOf (List.kerase x xs) ≤ SizeOf.sizeOf xs 
goal: sizeOf (List.kerase x xs) ≤ sizeOf xs

full_name: List.kinsert
code: /-- Insert the pair `⟨a, b⟩` and erase the first pair with the key `a`. -/
def kinsert (a : α) (b : β a) (l : List (Sigma β)) : List (Sigma β) 
goal: List (Sigma β)

full_name: List.kinsert_def
code: @[simp]
theorem kinsert_def {a} {b : β a} {l : List (Sigma β)} : kinsert a b l = ⟨a, b⟩ :: kerase a l 
goal: List.kinsert a b l = ⟨a, b⟩ :: List.kerase a l

full_name: List.mem_keys_kinsert
code: theorem mem_keys_kinsert {a a'} {b' : β a'} {l : List (Sigma β)} :
    a ∈ (kinsert a' b' l).keys ↔ a = a' ∨ a ∈ l.keys 
goal: a ∈ (List.kinsert a' b' l).keys ↔ a = a' ∨ a ∈ l.keys

full_name: List.kinsert_nodupKeys
code: theorem kinsert_nodupKeys (a) (b : β a) {l : List (Sigma β)} (nd : l.NodupKeys) :
    (kinsert a b l).NodupKeys 
goal: (List.kinsert a b l).NodupKeys

full_name: List.Perm.kinsert
code: theorem Perm.kinsert {a} {b : β a} {l₁ l₂ : List (Sigma β)} (nd₁ : l₁.NodupKeys) (p : l₁ ~ l₂) :
    kinsert a b l₁ ~ kinsert a b l₂ 
goal: (List.kinsert a b l₁).Perm (List.kinsert a b l₂)

full_name: List.dlookup_kinsert
code: theorem dlookup_kinsert {a} {b : β a} (l : List (Sigma β)) :
    dlookup a (kinsert a b l) = some b 
goal: List.dlookup a (List.kinsert a b l) = some b

full_name: List.dlookup_kinsert_ne
code: theorem dlookup_kinsert_ne {a a'} {b' : β a'} {l : List (Sigma β)} (h : a ≠ a') :
    dlookup a (kinsert a' b' l) = dlookup a l 
goal: List.dlookup a (List.kinsert a' b' l) = List.dlookup a l

full_name: List.kextract
code: /-- Finds the first entry with a given key `a` and returns its value (as an `Option` because there
might be no entry with key `a`) alongside with the rest of the entries. -/
def kextract (a : α) : List (Sigma β) → Option (β a) × List (Sigma β)
  
goal: List (Sigma β) → Option (β a) × List (Sigma β)

full_name: List.kextract_eq_dlookup_kerase
code: @[simp]
theorem kextract_eq_dlookup_kerase (a : α) :
    ∀ l : List (Sigma β), kextract a l = (dlookup a l, kerase a l)
  
goal: List.kextract a l = (List.dlookup a l, List.kerase a l)

full_name: List.dedupKeys
code: /-- Remove entries with duplicate keys from `l : List (Sigma β)`. -/
def dedupKeys : List (Sigma β) → List (Sigma β) 
goal: List (Sigma β) → List (Sigma β)

full_name: List.dedupKeys_cons
code: theorem dedupKeys_cons {x : Sigma β} (l : List (Sigma β)) :
    dedupKeys (x :: l) = kinsert x.1 x.2 (dedupKeys l) 
goal: (x :: l).dedupKeys = List.kinsert x.fst x.snd l.dedupKeys

full_name: List.nodupKeys_dedupKeys
code: theorem nodupKeys_dedupKeys (l : List (Sigma β)) : NodupKeys (dedupKeys l) 
goal: l.dedupKeys.NodupKeys

full_name: List.dlookup_dedupKeys
code: theorem dlookup_dedupKeys (a : α) (l : List (Sigma β)) : dlookup a (dedupKeys l) = dlookup a l 
goal: List.dlookup a l.dedupKeys = List.dlookup a l

full_name: List.sizeOf_dedupKeys
code: theorem sizeOf_dedupKeys [SizeOf (Sigma β)]
    (xs : List (Sigma β)) : SizeOf.sizeOf (dedupKeys xs) ≤ SizeOf.sizeOf xs 
goal: sizeOf xs.dedupKeys ≤ sizeOf xs

full_name: List.kunion
code: /-- `kunion l₁ l₂` is the append to l₁ of l₂ after, for each key in l₁, the
first matching pair in l₂ is erased. -/
def kunion : List (Sigma β) → List (Sigma β) → List (Sigma β)
  
goal: List (Sigma β) → List (Sigma β) → List (Sigma β)

full_name: List.nil_kunion
code: @[simp]
theorem nil_kunion {l : List (Sigma β)} : kunion [] l = l 
goal: [].kunion l = l

full_name: List.kunion_nil
code: @[simp]
theorem kunion_nil : ∀ {l : List (Sigma β)}, kunion l [] = l
  
goal: l.kunion [] = l

full_name: List.kunion_cons
code: @[simp]
theorem kunion_cons {s} {l₁ l₂ : List (Sigma β)} :
    kunion (s :: l₁) l₂ = s :: kunion l₁ (kerase s.1 l₂) 
goal: (s :: l₁).kunion l₂ = s :: l₁.kunion (List.kerase s.fst l₂)

full_name: List.mem_keys_kunion
code: @[simp]
theorem mem_keys_kunion {a} {l₁ l₂ : List (Sigma β)} :
    a ∈ (kunion l₁ l₂).keys ↔ a ∈ l₁.keys ∨ a ∈ l₂.keys 
goal: a ∈ (l₁.kunion l₂).keys ↔ a ∈ l₁.keys ∨ a ∈ l₂.keys

full_name: List.kunion_kerase
code: @[simp]
theorem kunion_kerase {a} :
    ∀ {l₁ l₂ : List (Sigma β)}, kunion (kerase a l₁) (kerase a l₂) = kerase a (kunion l₁ l₂)
  
goal: (List.kerase a l₁).kunion (List.kerase a l₂) = List.kerase a (l₁.kunion l₂)

full_name: List.NodupKeys.kunion
code: theorem NodupKeys.kunion (nd₁ : l₁.NodupKeys) (nd₂ : l₂.NodupKeys) : (kunion l₁ l₂).NodupKeys 
goal: (l₁.kunion l₂).NodupKeys

full_name: List.Perm.kunion_right
code: theorem Perm.kunion_right {l₁ l₂ : List (Sigma β)} (p : l₁ ~ l₂) (l) :
    kunion l₁ l ~ kunion l₂ l 
goal: (l₁.kunion l).Perm (l₂.kunion l)

full_name: List.Perm.kunion_left
code: theorem Perm.kunion_left :
    ∀ (l) {l₁ l₂ : List (Sigma β)}, l₁.NodupKeys → l₁ ~ l₂ → kunion l l₁ ~ kunion l l₂
  
goal: l₁.NodupKeys → l₁.Perm l₂ → (l.kunion l₁).Perm (l.kunion l₂)

full_name: List.Perm.kunion
code: theorem Perm.kunion {l₁ l₂ l₃ l₄ : List (Sigma β)} (nd₃ : l₃.NodupKeys) (p₁₂ : l₁ ~ l₂)
    (p₃₄ : l₃ ~ l₄) : kunion l₁ l₃ ~ kunion l₂ l₄ 
goal: (l₁.kunion l₃).Perm (l₂.kunion l₄)

full_name: List.dlookup_kunion_left
code: @[simp]
theorem dlookup_kunion_left {a} {l₁ l₂ : List (Sigma β)} (h : a ∈ l₁.keys) :
    dlookup a (kunion l₁ l₂) = dlookup a l₁ 
goal: List.dlookup a (l₁.kunion l₂) = List.dlookup a l₁

full_name: List.dlookup_kunion_right
code: @[simp]
theorem dlookup_kunion_right {a} {l₁ l₂ : List (Sigma β)} (h : a ∉ l₁.keys) :
    dlookup a (kunion l₁ l₂) = dlookup a l₂ 
goal: List.dlookup a (l₁.kunion l₂) = List.dlookup a l₂

full_name: List.mem_dlookup_kunion
code: theorem mem_dlookup_kunion {a} {b : β a} {l₁ l₂ : List (Sigma β)} :
    b ∈ dlookup a (kunion l₁ l₂) ↔ b ∈ dlookup a l₁ ∨ a ∉ l₁.keys ∧ b ∈ dlookup a l₂ 
goal: b ∈ List.dlookup a (l₁.kunion l₂) ↔ b ∈ List.dlookup a l₁ ∨ a ∉ l₁.keys ∧ b ∈ List.dlookup a l₂

full_name: List.dlookup_kunion_eq_some
code: @[simp]
theorem dlookup_kunion_eq_some {a} {b : β a} {l₁ l₂ : List (Sigma β)} :
    dlookup a (kunion l₁ l₂) = some b ↔
      dlookup a l₁ = some b ∨ a ∉ l₁.keys ∧ dlookup a l₂ = some b 
goal: List.dlookup a (l₁.kunion l₂) = some b ↔ List.dlookup a l₁ = some b ∨ a ∉ l₁.keys ∧ List.dlookup a l₂ = some b

full_name: List.mem_dlookup_kunion_middle
code: theorem mem_dlookup_kunion_middle {a} {b : β a} {l₁ l₂ l₃ : List (Sigma β)}
    (h₁ : b ∈ dlookup a (kunion l₁ l₃)) (h₂ : a ∉ keys l₂) :
    b ∈ dlookup a (kunion (kunion l₁ l₂) l₃) 
goal: b ∈ List.dlookup a ((l₁.kunion l₂).kunion l₃)