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

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

tactic: split
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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,
          buckets :=
            Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.replace k v
                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 =>
        if numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val then
          { size := m.size + 1,
            buckets :=
              Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                (AssocList.cons k v
                  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) }
        else
          expand (m.size + 1)
            (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.cons k v
                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
      (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,
            buckets :=
              Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                (AssocList.replace k v
                  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 =>
          if numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val then
            { size := m.size + 1,
              buckets :=
                Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                  (AssocList.cons k v
                    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) }
          else
            expand (m.size + 1)
              (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                (AssocList.cons k v
                  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: split
state_before: case h_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
⊢ (if numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val then
        { size := m.size + 1,
          buckets :=
            Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.cons k v
                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) }
      else
        expand (m.size + 1)
          (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.cons k v
              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
      (if numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val then
          { size := m.size + 1,
            buckets :=
              Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                (AssocList.cons k v
                  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) }
        else
          expand (m.size + 1)
            (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.cons k v
                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: unfold Bucket.size
state_before: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.replace k v
              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,
          buckets :=
            Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
              (AssocList.replace k v
                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: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.replace k v
              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 =
    Nat.sum
      (List.map (fun x => List.length (AssocList.toList x))
        { size := m.size,
                buckets :=
                  Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                    (AssocList.replace k v
                      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.val.data)

tactic: simp [h, h₁, Bucket.size_eq]
state_before: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
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.replace k v
            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.replace k v
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ { size := m.size,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.replace k v
              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 =
    Nat.sum
      (List.map (fun x => List.length (AssocList.toList x))
        (w✝¹ ++
          AssocList.replace k v
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
            w✝))

tactic: unfold Bucket.size
state_before: case h_2.inl
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
⊢ { size := m.size + 1,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.cons k v
              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.cons k v
                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: case h_2.inl
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
⊢ { size := m.size + 1,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.cons k v
              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 =
    Nat.sum
      (List.map (fun x => List.length (AssocList.toList x))
        { size := m.size + 1,
                buckets :=
                  Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
                    (AssocList.cons k v
                      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.val.data)

tactic: simp [h, h₁, Bucket.size_eq, Nat.succ_add]
state_before: case h_2.inl
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
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.cons k v
            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.cons k v
          m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
        w✝
⊢ { size := m.size + 1,
        buckets :=
          Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.cons k v
              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 =
    Nat.sum
      (List.map (fun x => List.length (AssocList.toList x))
        (w✝¹ ++
          AssocList.cons k v
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
            w✝))

tactic: rfl
state_before: case h_2.inl
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
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.cons k v
            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.cons k v
          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✝¹) +
      Nat.succ
        (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✝))

tactic: rw [expand_size]
state_before: case h_2.inr
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : ¬numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
⊢ (expand (m.size + 1)
        (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.cons k v
            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
      (expand (m.size + 1)
          (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
            (AssocList.cons k v
              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, expand, Bucket.size]
state_before: case h_2.inr
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : ¬numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
⊢ (expand (m.size + 1)
        (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
          (AssocList.cons k v
            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
      (Bucket.update m.buckets (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val
        (AssocList.cons k v
          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))

tactic: refine have ⟨_, _, h₁, _, eq⟩ := Bucket.exists_of_update ..; eq ▸ ?_
state_before: case h_2.inr
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : ¬numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
⊢ 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.cons k v
                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₁, Bucket.size_eq, Nat.succ_add]
state_before: case h_2.inr
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : ¬numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
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.cons k v
            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.cons k v
          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.cons k v
              m.buckets.val[USize.toNat (mkIdx (_ : 0 < Array.size m.buckets.val) (UInt64.toUSize (hash k))).val] ::
            w✝))

tactic: rfl
state_before: case h_2.inr
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
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
h✝ : ¬numBucketsForCapacity (m.size + 1) ≤ Array.size m.buckets.val
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.cons k v
            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.cons k v
          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✝¹) +
      Nat.succ
        (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✝))