File: .lake/packages/batteries/Batteries/Data/AssocList.lean

full_name: Batteries.AssocList
code: /--
`AssocList α β` is "the same as" `List (α × β)`, but flattening the structure
leads to one fewer pointer indirection (in the current code generator).
It is mainly intended as a component of `HashMap`, but it can also be used as a plain
key-value map.
-/
inductive AssocList (α : Type u) (β : Type v) where
  /-- An empty list -/
  | nil
  /-- Add a `key, value` pair to the list -/
  | cons (key : α) (value : β) (tail : AssocList α β)
  deriving Inhabited
goal: Type (max u v)

full_name: Batteries.AssocList.cons
code: /--
`AssocList α β` is "the same as" `List (α × β)`, but flattening the structure
leads to one fewer pointer indirection (in the current code generator).
It is mainly intended as a component of `HashMap`, but it can also be used as a plain
key-value map.
-/
inductive AssocList (α : Type u) (β : Type v) where
  /-- An empty list -/
  | nil
  /-- Add a `key, value` pair to the list -/
  | cons (key : α) (value : β) (tail : AssocList α β)
  deriving Inhabited
goal: Batteries.AssocList α β

full_name: Batteries.AssocList.nil
code: /--
`AssocList α β` is "the same as" `List (α × β)`, but flattening the structure
leads to one fewer pointer indirection (in the current code generator).
It is mainly intended as a component of `HashMap`, but it can also be used as a plain
key-value map.
-/
inductive AssocList (α : Type u) (β : Type v) where
  /-- An empty list -/
  | nil
  /-- Add a `key, value` pair to the list -/
  | cons (key : α) (value : β) (tail : AssocList α β)
  deriving Inhabited
goal: Batteries.AssocList α β

full_name: Batteries.instInhabitedAssocList
code: /--
`AssocList α β` is "the same as" `List (α × β)`, but flattening the structure
leads to one fewer pointer indirection (in the current code generator).
It is mainly intended as a component of `HashMap`, but it can also be used as a plain
key-value map.
-/
inductive AssocList (α : Type u) (β : Type v) where
  /-- An empty list -/
  | nil
  /-- Add a `key, value` pair to the list -/
  | cons (key : α) (value : β) (tail : AssocList α β)
  deriving Inhabited
goal: {a : Type u_1} → {a_1 : Type u_2} → Inhabited (Batteries.AssocList a a_1)

full_name: Batteries.AssocList.toList
code: /--
`O(n)`. Convert an `AssocList α β` into the equivalent `List (α × β)`.
This is used to give specifications for all the `AssocList` functions
in terms of corresponding list functions.
-/
@[simp] def toList : AssocList α β → List (α × β)
  
goal: Batteries.AssocList α β → List (α × β)

full_name: Batteries.AssocList.instEmptyCollection
code: instance : EmptyCollection (AssocList α β) 
goal: EmptyCollection (Batteries.AssocList α β)

full_name: Batteries.AssocList.empty_eq
code: @[simp] theorem empty_eq : (∅ : AssocList α β) = nil 
goal: ∅ = Batteries.AssocList.nil

full_name: Batteries.AssocList.isEmpty
code: /-- `O(1)`. Is the list empty? -/
def isEmpty : AssocList α β → Bool
  
goal: Batteries.AssocList α β → Bool

full_name: Batteries.AssocList.isEmpty_eq
code: @[simp] theorem isEmpty_eq (l : AssocList α β) : isEmpty l = l.toList.isEmpty 
goal: l.isEmpty = l.toList.isEmpty

full_name: Batteries.AssocList.length
code: /-- The number of entries in an `AssocList`. -/
def length (L : AssocList α β) : Nat 
goal: Nat

full_name: Batteries.AssocList.length_nil
code: @[simp] theorem length_nil : length (nil : AssocList α β) = 0 
goal: Batteries.AssocList.nil.length = 0

full_name: Batteries.AssocList.length_cons
code: @[simp] theorem length_cons : length (cons a b t) = length t + 1 
goal: ∀ {α : Type u_1} {a : α} {β : Type u_2} {b : β} {t : Batteries.AssocList α β},
  (Batteries.AssocList.cons a b t).length = t.length + 1

full_name: Batteries.AssocList.length_toList
code: theorem length_toList (l : AssocList α β) : l.toList.length = l.length 
goal: l.toList.length = l.length

full_name: Batteries.AssocList.foldlM
code: /-- `O(n)`. Fold a monadic function over the list, from head to tail. -/
@[specialize] def foldlM [Monad m] (f : δ → α → β → m δ) : (init : δ) → AssocList α β → m δ
  
goal: Batteries.AssocList α β → m δ

full_name: Batteries.AssocList.foldlM_eq
code: @[simp] theorem foldlM_eq [Monad m] (f : δ → α → β → m δ) (init l) :
    foldlM f init l = l.toList.foldlM (fun d (a, b) => f d a b) init 
goal: Batteries.AssocList.foldlM f init l =
  List.foldlM
    (fun d x =>
      match x with
      | (a, b) => f d a b)
    init l.toList

full_name: Batteries.AssocList.foldl
code: /-- `O(n)`. Fold a function over the list, from head to tail. -/
@[inline] def foldl (f : δ → α → β → δ) (init : δ) (as : AssocList α β) : δ 
goal: δ

full_name: Batteries.AssocList.foldl_eq
code: @[simp] theorem foldl_eq (f : δ → α → β → δ) (init l) :
    foldl f init l = l.toList.foldl (fun d (a, b) => f d a b) init 
goal: Batteries.AssocList.foldl f init l =
  List.foldl
    (fun d x =>
      match x with
      | (a, b) => f d a b)
    init l.toList

full_name: Batteries.AssocList.toListTR
code: /-- Optimized version of `toList`. -/
def toListTR (as : AssocList α β) : List (α × β) 
goal: List (α × β)

full_name: Batteries.AssocList.toList_eq_toListTR
code: @[csimp] theorem toList_eq_toListTR : @toList = @toListTR 
goal: @Batteries.AssocList.toList = @Batteries.AssocList.toListTR

full_name: Batteries.AssocList.forM
code: /-- `O(n)`. Run monadic function `f` on all elements in the list, from head to tail. -/
@[specialize] def forM [Monad m] (f : α → β → m PUnit) : AssocList α β → m PUnit
  
goal: Batteries.AssocList α β → m PUnit

full_name: Batteries.AssocList.forM_eq
code: @[simp] theorem forM_eq [Monad m] (f : α → β → m PUnit) (l) :
    forM f l = l.toList.forM (fun (a, b) => f a b) 
goal: Batteries.AssocList.forM f l =
  l.toList.forM fun x =>
    match x with
    | (a, b) => f a b

full_name: Batteries.AssocList.mapKey
code: /-- `O(n)`. Map a function `f` over the keys of the list. -/
@[simp] def mapKey (f : α → δ) : AssocList α β → AssocList δ β
  
goal: Batteries.AssocList α β → Batteries.AssocList δ β

full_name: Batteries.AssocList.toList_mapKey
code: @[simp] theorem toList_mapKey (f : α → δ) (l : AssocList α β) :
    (mapKey f l).toList = l.toList.map (fun (a, b) => (f a, b)) 
goal: (Batteries.AssocList.mapKey f l).toList =
  List.map
    (fun x =>
      match x with
      | (a, b) => (f a, b))
    l.toList

full_name: Batteries.AssocList.length_mapKey
code: @[simp] theorem length_mapKey : (mapKey f l).length = l.length 
goal: ∀ {α : Type u_1} {α_1 : Type u_2} {f : α → α_1} {β : Type u_3} {l : Batteries.AssocList α β},
  (Batteries.AssocList.mapKey f l).length = l.length

full_name: Batteries.AssocList.mapVal
code: /-- `O(n)`. Map a function `f` over the values of the list. -/
@[simp] def mapVal (f : α → β → δ) : AssocList α β → AssocList α δ
  
goal: Batteries.AssocList α β → Batteries.AssocList α δ

full_name: Batteries.AssocList.toList_mapVal
code: @[simp] theorem toList_mapVal (f : α → β → δ) (l : AssocList α β) :
    (mapVal f l).toList = l.toList.map (fun (a, b) => (a, f a b)) 
goal: (Batteries.AssocList.mapVal f l).toList =
  List.map
    (fun x =>
      match x with
      | (a, b) => (a, f a b))
    l.toList

full_name: Batteries.AssocList.length_mapVal
code: @[simp] theorem length_mapVal : (mapVal f l).length = l.length 
goal: ∀ {α : Type u_1} {β : Type u_2} {β_1 : Type u_3} {f : α → β → β_1} {l : Batteries.AssocList α β},
  (Batteries.AssocList.mapVal f l).length = l.length

full_name: Batteries.AssocList.findEntryP?
code: /-- `O(n)`. Returns the first entry in the list whose entry satisfies `p`. -/
@[specialize] def findEntryP? (p : α → β → Bool) : AssocList α β → Option (α × β)
  
goal: Batteries.AssocList α β → Option (α × β)

full_name: Batteries.AssocList.findEntryP?_eq
code: @[simp] theorem findEntryP?_eq (p : α → β → Bool) (l : AssocList α β) :
    findEntryP? p l = l.toList.find? fun (a, b) => p a b 
goal: Batteries.AssocList.findEntryP? p l =
  List.find?
    (fun x =>
      match x with
      | (a, b) => p a b)
    l.toList

full_name: Batteries.AssocList.findEntry?
code: /-- `O(n)`. Returns the first entry in the list whose key is equal to `a`. -/
@[inline] def findEntry? [BEq α] (a : α) (l : AssocList α β) : Option (α × β) 
goal: Option (α × β)

full_name: Batteries.AssocList.findEntry?_eq
code: @[simp] theorem findEntry?_eq [BEq α] (a : α) (l : AssocList α β) :
    findEntry? a l = l.toList.find? (·.1 == a) 
goal: Batteries.AssocList.findEntry? a l = List.find? (fun x => x.fst == a) l.toList

full_name: Batteries.AssocList.find?
code: /-- `O(n)`. Returns the first value in the list whose key is equal to `a`. -/
def find? [BEq α] (a : α) : AssocList α β → Option β
  
goal: Batteries.AssocList α β → Option β

full_name: Batteries.AssocList.find?_eq_findEntry?
code: theorem find?_eq_findEntry? [BEq α] (a : α) (l : AssocList α β) :
    find? a l = (l.findEntry? a).map (·.2) 
goal: Batteries.AssocList.find? a l = Option.map (fun x => x.snd) (Batteries.AssocList.findEntry? a l)

full_name: Batteries.AssocList.find?_eq
code: @[simp] theorem find?_eq [BEq α] (a : α) (l : AssocList α β) :
    find? a l = (l.toList.find? (·.1 == a)).map (·.2) 
goal: Batteries.AssocList.find? a l = Option.map (fun x => x.snd) (List.find? (fun x => x.fst == a) l.toList)

full_name: Batteries.AssocList.any
code: /-- `O(n)`. Returns true if any entry in the list satisfies `p`. -/
@[specialize] def any (p : α → β → Bool) : AssocList α β → Bool
  
goal: Batteries.AssocList α β → Bool

full_name: Batteries.AssocList.any_eq
code: @[simp] theorem any_eq (p : α → β → Bool) (l : AssocList α β) :
    any p l = l.toList.any fun (a, b) => p a b 
goal: Batteries.AssocList.any p l =
  l.toList.any fun x =>
    match x with
    | (a, b) => p a b

full_name: Batteries.AssocList.all
code: /-- `O(n)`. Returns true if every entry in the list satisfies `p`. -/
@[specialize] def all (p : α → β → Bool) : AssocList α β → Bool
  
goal: Batteries.AssocList α β → Bool

full_name: Batteries.AssocList.all_eq
code: @[simp] theorem all_eq (p : α → β → Bool) (l : AssocList α β) :
    all p l = l.toList.all fun (a, b) => p a b 
goal: Batteries.AssocList.all p l =
  l.toList.all fun x =>
    match x with
    | (a, b) => p a b

full_name: Batteries.AssocList.All
code: /-- Returns true if every entry in the list satisfies `p`. -/
def All (p : α → β → Prop) (l : AssocList α β) : Prop 
goal: Prop

full_name: Batteries.AssocList.contains
code: /-- `O(n)`. Returns true if there is an element in the list whose key is equal to `a`. -/
@[inline] def contains [BEq α] (a : α) (l : AssocList α β) : Bool 
goal: Bool

full_name: Batteries.AssocList.contains_eq
code: @[simp] theorem contains_eq [BEq α] (a : α) (l : AssocList α β) :
    contains a l = l.toList.any (·.1 == a) 
goal: Batteries.AssocList.contains a l = l.toList.any fun x => x.fst == a

full_name: Batteries.AssocList.replace
code: /--
`O(n)`. Replace the first entry in the list
with key equal to `a` to have key `a` and value `b`.
-/
@[simp] def replace [BEq α] (a : α) (b : β) : AssocList α β → AssocList α β
  
goal: Batteries.AssocList α β → Batteries.AssocList α β

full_name: Batteries.AssocList.toList_replace
code: @[simp] theorem toList_replace [BEq α] (a : α) (b : β) (l : AssocList α β) :
    (replace a b l).toList =
    l.toList.replaceF (bif ·.1 == a then some (a, b) else none) 
goal: (Batteries.AssocList.replace a b l).toList = List.replaceF (fun x => bif x.fst == a then some (a, b) else none) l.toList

full_name: Batteries.AssocList.length_replace
code: @[simp] theorem length_replace [BEq α] {a : α} : (replace a b l).length = l.length 
goal: ∀ {β : Type u_2} {b : β} {l : Batteries.AssocList α β} [inst : BEq α] {a : α},
  (Batteries.AssocList.replace a b l).length = l.length

full_name: Batteries.AssocList.eraseP
code: /-- `O(n)`. Remove the first entry in the list with key equal to `a`. -/
@[specialize, simp] def eraseP (p : α → β → Bool) : AssocList α β → AssocList α β
  
goal: Batteries.AssocList α β → Batteries.AssocList α β

full_name: Batteries.AssocList.toList_eraseP
code: @[simp] theorem toList_eraseP (p) (l : AssocList α β) :
    (eraseP p l).toList = l.toList.eraseP fun (a, b) => p a b 
goal: (Batteries.AssocList.eraseP p l).toList =
  List.eraseP
    (fun x =>
      match x with
      | (a, b) => p a b)
    l.toList

full_name: Batteries.AssocList.erase
code: /-- `O(n)`. Remove the first entry in the list with key equal to `a`. -/
@[inline] def erase [BEq α] (a : α) (l : AssocList α β) : AssocList α β 
goal: Batteries.AssocList α β

full_name: Batteries.AssocList.toList_erase
code: @[simp] theorem toList_erase [BEq α] (a : α) (l : AssocList α β) :
    (erase a l).toList = l.toList.eraseP (·.1 == a) 
goal: (Batteries.AssocList.erase a l).toList = List.eraseP (fun x => x.fst == a) l.toList

full_name: Batteries.AssocList.modify
code: /--
`O(n)`. Replace the first entry `a', b` in the list
with key equal to `a` to have key `a` and value `f a' b`.
-/
@[simp] def modify [BEq α] (a : α) (f : α → β → β) : AssocList α β → AssocList α β
  
goal: Batteries.AssocList α β → Batteries.AssocList α β

full_name: Batteries.AssocList.toList_modify
code: @[simp] theorem toList_modify [BEq α] (a : α) (l : AssocList α β) :
    (modify a f l).toList =
    l.toList.replaceF fun (k, v) => bif k == a then some (a, f k v) else none 
goal: (Batteries.AssocList.modify a f l).toList =
  List.replaceF
    (fun x =>
      match x with
      | (k, v) => bif k == a then some (a, f k v) else none)
    l.toList

full_name: Batteries.AssocList.length_modify
code: @[simp] theorem length_modify [BEq α] {a : α} : (modify a f l).length = l.length 
goal: ∀ {β : Type u_2} {f : α → β → β} {l : Batteries.AssocList α β} [inst : BEq α] {a : α},
  (Batteries.AssocList.modify a f l).length = l.length

full_name: Batteries.AssocList.forIn
code: /-- The implementation of `ForIn`, which enables `for (k, v) in aList do ...` notation. -/
@[specialize] protected def forIn [Monad m]
    (as : AssocList α β) (init : δ) (f : (α × β) → δ → m (ForInStep δ)) : m δ 
goal: m δ

full_name: Batteries.AssocList.instForInProd
code: instance : ForIn m (AssocList α β) (α × β) 
goal: ForIn m (Batteries.AssocList α β) (α × β)

full_name: Batteries.AssocList.forIn_eq
code: @[simp] theorem forIn_eq [Monad m] (l : AssocList α β) (init : δ)
    (f : (α × β) → δ → m (ForInStep δ)) : forIn l init f = forIn l.toList init f 
goal: forIn l init f = forIn l.toList init f

full_name: Batteries.AssocList.pop?
code: /-- Split the list into head and tail, if possible. -/
def pop? : AssocList α β → Option ((α × β) × AssocList α β)
  
goal: Batteries.AssocList α β → Option ((α × β) × Batteries.AssocList α β)

full_name: Batteries.AssocList.instToStream
code: instance : ToStream (AssocList α β) (AssocList α β) 
goal: ToStream (Batteries.AssocList α β) (Batteries.AssocList α β)

full_name: Batteries.AssocList.instStreamProd
code: instance : Stream (AssocList α β) (α × β) 
goal: Stream (Batteries.AssocList α β) (α × β)

full_name: List.toAssocList
code: /-- Converts a list into an `AssocList`. This is the inverse function to `AssocList.toList`. -/
@[simp] def _root_.List.toAssocList : List (α × β) → AssocList α β
  
goal: List (α × β) → Batteries.AssocList α β

full_name: List.toList_toAssocList
code: @[simp] theorem _root_.List.toList_toAssocList (l : List (α × β)) : l.toAssocList.toList = l 
goal: l.toAssocList.toList = l

full_name: Batteries.AssocList.toList_toAssocList
code: @[simp] theorem toList_toAssocList (l : AssocList α β) : l.toList.toAssocList = l 
goal: l.toList.toAssocList = l

full_name: List.length_toAssocList
code: @[simp] theorem _root_.List.length_toAssocList (l : List (α × β)) :
    l.toAssocList.length = l.length 
goal: l.toAssocList.length = l.length

full_name: Batteries.AssocList.beq
code: /-- Implementation of `==` on `AssocList`. -/
protected def beq [BEq α] [BEq β] : AssocList α β → AssocList α β → Bool
  
goal: Batteries.AssocList α β → Batteries.AssocList α β → Bool

full_name: Batteries.AssocList.instBEq
code: /--
Boolean equality for `AssocList`.
(This relation cares about the ordering of the key-value pairs.)
-/
instance [BEq α] [BEq β] : BEq (AssocList α β) 
goal: BEq (Batteries.AssocList α β)

full_name: Batteries.AssocList.beq_nil₂
code: @[simp] theorem beq_nil₂ [BEq α] [BEq β] : ((.nil : AssocList α β) == .nil) = true 
goal: (Batteries.AssocList.nil == Batteries.AssocList.nil) = true

full_name: Batteries.AssocList.beq_nil_cons
code: @[simp] theorem beq_nil_cons [BEq α] [BEq β] : ((.nil : AssocList α β) == .cons a b t) = false 
goal: (Batteries.AssocList.nil == Batteries.AssocList.cons a b t) = false

full_name: Batteries.AssocList.beq_cons_nil
code: @[simp] theorem beq_cons_nil [BEq α] [BEq β] : ((.cons a b t : AssocList α β) == .nil) = false 
goal: (Batteries.AssocList.cons a b t == Batteries.AssocList.nil) = false

full_name: Batteries.AssocList.beq_cons₂
code: @[simp] theorem beq_cons₂ [BEq α] [BEq β] :
    ((.cons a b t : AssocList α β) == .cons a' b' t') = (a == a' && b == b' && t == t') 
goal: (Batteries.AssocList.cons a b t == Batteries.AssocList.cons a' b' t') = (a == a' && b == b' && t == t')

full_name: Batteries.AssocList.instLawfulBEq
code: instance [BEq α] [LawfulBEq α] [BEq β] [LawfulBEq β] : LawfulBEq (AssocList α β) 
goal: LawfulBEq (Batteries.AssocList α β)

full_name: Batteries.AssocList.beq_eq
code: protected theorem beq_eq [BEq α] [BEq β] {l m : AssocList α β} :
    (l == m) = (l.toList == m.toList) 
goal: (l == m) = (l.toList == m.toList)