Theorem: Std.HashMap.Imp.erase_size
File: Std/Data/HashMap/WF.lean

tactic: dsimp [erase, cond]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
⊢ (erase m k).size = Bucket.size (erase m k).buckets

tactic: split
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
⊢ (match
        AssocList.contains k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] with
      | true =>
        { size := m.size - 1,
          buckets :=
            Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.erase k
                m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
              (_ :
                USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                  Array.size m.buckets.val) }
      | false => m).size =
    Bucket.size
      (match
          AssocList.contains k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] with
        | true =>
          { size := m.size - 1,
            buckets :=
              Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                (AssocList.erase k
                  m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
                (_ :
                  USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                    Array.size m.buckets.val) }
        | false => m).buckets

tactic: next H =>
simp [h, Bucket.size]
refine have ⟨_, _, h₁, _, eq⟩ := Bucket.exists_of_update ..; eq ▸ ?_
simp [h, h₁, Bucket.size_eq]
rw [(_ : List.length _ = _ + 1), Nat.add_right_comm]; {rfl}
clear h₁ eq
simp [AssocList.contains_eq] at H
have ⟨a, h₁, h₂⟩ := H
refine have ⟨_, _, _, _, _, h, eq⟩ := List.exists_of_eraseP h₁ h₂; eq ▸ ?_
simp [h]; rfl
state_before: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
heq✝ :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
⊢ { size := m.size - 1,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.erase k
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
            (_ :
              USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                Array.size m.buckets.val) }.size =
    Bucket.size
      { size := m.size - 1,
          buckets :=
            Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.erase k
                m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
              (_ :
                USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                  Array.size m.buckets.val) }.buckets

tactic: simp [h, Bucket.size]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
⊢ { size := m.size - 1,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.erase k
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
            (_ :
              USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                Array.size m.buckets.val) }.size =
    Bucket.size
      { size := m.size - 1,
          buckets :=
            Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.erase k
                m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
              (_ :
                USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                  Array.size m.buckets.val) }.buckets

tactic: refine have ⟨_, _, h₁, _, eq⟩ := Bucket.exists_of_update ..; eq ▸ ?_
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
⊢ Nat.sum (List.map (fun x => List.length (AssocList.toList x)) m.buckets.val.data) - 1 =
    Nat.sum
      (List.map (fun x => List.length (AssocList.toList x))
        (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.erase k
                m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
              (_ :
                USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
                  Array.size m.buckets.val)).val.data)

tactic: simp [h, h₁, Bucket.size_eq]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
h₁ :
  m.buckets.val.data =
    w✝¹ ++ m.buckets.val[(mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] :: w✝
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
eq :
  (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.erase k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
          (_ :
            USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
              Array.size m.buckets.val)).val.data =
    w✝¹ ++
      AssocList.erase k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ Nat.sum (List.map (fun x => List.length (AssocList.toList x)) m.buckets.val.data) - 1 =
    Nat.sum
      (List.map (fun x => List.length (AssocList.toList x))
        (w✝¹ ++
          AssocList.erase k
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
            w✝))

tactic: rw [(_ : List.length _ = _ + 1), Nat.add_right_comm]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
h₁ :
  m.buckets.val.data =
    w✝¹ ++ m.buckets.val[(mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] :: w✝
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
eq :
  (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.erase k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
          (_ :
            USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
              Array.size m.buckets.val)).val.data =
    w✝¹ ++
      AssocList.erase k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝¹) +
        (List.length
            (AssocList.toList
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) +
          Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝)) -
      1 =
    Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝¹) +
      (List.length
          (List.eraseP (fun x => x.fst == k)
            (AssocList.toList
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])) +
        Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝))

tactic: {rfl}
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
h₁ :
  m.buckets.val.data =
    w✝¹ ++ m.buckets.val[(mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] :: w✝
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
eq :
  (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.erase k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
          (_ :
            USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
              Array.size m.buckets.val)).val.data =
    w✝¹ ++
      AssocList.erase k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝¹) +
        (?n + Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝) + 1) -
      1 =
    Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝¹) +
      (List.length
          (List.eraseP (fun x => x.fst == k)
            (AssocList.toList
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])) +
        Nat.sum (List.map (fun x => List.length (AssocList.toList x)) w✝))

case n
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
h₁ :
  m.buckets.val.data =
    w✝¹ ++ m.buckets.val[(mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] :: w✝
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
eq :
  (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.erase k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
          (_ :
            USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
              Array.size m.buckets.val)).val.data =
    w✝¹ ++
      AssocList.erase k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ Nat

α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
h₁ :
  m.buckets.val.data =
    w✝¹ ++ m.buckets.val[(mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] :: w✝
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
eq :
  (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.erase k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
          (_ :
            USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
              Array.size m.buckets.val)).val.data =
    w✝¹ ++
      AssocList.erase k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ List.length
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    ?n + 1

tactic: clear h₁ eq
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
h₁ :
  m.buckets.val.data =
    w✝¹ ++ m.buckets.val[(mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] :: w✝
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
eq :
  (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.erase k
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])
          (_ :
            USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val <
              Array.size m.buckets.val)).val.data =
    w✝¹ ++
      AssocList.erase k
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ List.length
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    List.length
        (List.eraseP (fun x => x.fst == k)
          (AssocList.toList
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])) +
      1

tactic: simp [AssocList.contains_eq] at H
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
H :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    true
w✝¹ w✝ : List (AssocList α β)
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
⊢ List.length
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    List.length
        (List.eraseP (fun x => x.fst == k)
          (AssocList.toList
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])) +
      1

tactic: have ⟨a, h₁, h₂⟩ := H
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
w✝¹ w✝ : List (AssocList α β)
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
H :
  ∃ x,
    x ∈
        AssocList.toList
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ∧
      (x.fst == k) = true
⊢ List.length
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    List.length
        (List.eraseP (fun x => x.fst == k)
          (AssocList.toList
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])) +
      1

tactic: refine have ⟨_, _, _, _, _, h, eq⟩ := List.exists_of_eraseP h₁ h₂; eq ▸ ?_
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
w✝¹ w✝ : List (AssocList α β)
left✝ : List.length w✝¹ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
H :
  ∃ x,
    x ∈
        AssocList.toList
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ∧
      (x.fst == k) = true
a : α × β
h₁ :
  a ∈
    AssocList.toList m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]
h₂ : (a.fst == k) = true
⊢ List.length
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    List.length
        (List.eraseP (fun x => x.fst == k)
          (AssocList.toList
            m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val])) +
      1

tactic: simp [h]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h✝ : m.size = Bucket.size m.buckets
c✝ : Bool
w✝⁴ w✝³ : List (AssocList α β)
left✝² : List.length w✝⁴ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
H :
  ∃ x,
    x ∈
        AssocList.toList
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ∧
      (x.fst == k) = true
a : α × β
h₁ :
  a ∈
    AssocList.toList m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]
h₂ : (a.fst == k) = true
w✝² : α × β
w✝¹ w✝ : List (α × β)
left✝¹ : ∀ (b : α × β), b ∈ w✝¹ → ¬(b.fst == k) = true
left✝ : (w✝².fst == k) = true
h :
  AssocList.toList m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    w✝¹ ++ w✝² :: w✝
eq :
  List.eraseP (fun x => x.fst == k)
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    w✝¹ ++ w✝
⊢ List.length
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    List.length (w✝¹ ++ w✝) + 1

tactic: rfl
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h✝ : m.size = Bucket.size m.buckets
c✝ : Bool
w✝⁴ w✝³ : List (AssocList α β)
left✝² : List.length w✝⁴ = USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
H :
  ∃ x,
    x ∈
        AssocList.toList
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ∧
      (x.fst == k) = true
a : α × β
h₁ :
  a ∈
    AssocList.toList m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]
h₂ : (a.fst == k) = true
w✝² : α × β
w✝¹ w✝ : List (α × β)
left✝¹ : ∀ (b : α × β), b ∈ w✝¹ → ¬(b.fst == k) = true
left✝ : (w✝².fst == k) = true
h :
  AssocList.toList m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    w✝¹ ++ w✝² :: w✝
eq :
  List.eraseP (fun x => x.fst == k)
      (AssocList.toList
        m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val]) =
    w✝¹ ++ w✝
⊢ List.length w✝¹ + Nat.succ (List.length w✝) = List.length w✝¹ + List.length w✝ + 1

tactic: exact h
state_before: case h_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
h : m.size = Bucket.size m.buckets
c✝ : Bool
heq✝ :
  AssocList.contains k
      m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] =
    false
⊢ m.size = Bucket.size m.buckets