Theorem: Batteries.HashMap.Imp.insert_WF
File: .lake/packages/batteries/Batteries/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.buckets.WF
⊢ (m.insert k v).buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
⊢ (match AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] with
      | true =>
        { size := m.size,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      | false =>
        if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
          { size := m.size + 1,
            buckets :=
              m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
                (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
        else
          expand (m.size + 1)
            (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF

tactic: split
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
⊢ (match AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] with
      | true =>
        { size := m.size,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      | false =>
        if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
          { size := m.size + 1,
            buckets :=
              m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
                (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
        else
          expand (m.size + 1)
            (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF
state_after: case h_1
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
⊢ { size := m.size,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF

case h_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
heq✝ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = false
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF

tactic: simp only [AssocList.contains_eq, List.any_eq_true] at h₁
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = true
⊢ { size := m.size,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
⊢ { size := m.size,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF

tactic: have ⟨x, hx₁, hx₂⟩ := h₁
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
⊢ { size := m.size,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
⊢ { size := m.size,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF

tactic: refine h.update (fun H => ?_) (fun H a h => ?_)
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
⊢ { size := m.size,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF
state_after: case refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
H : List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList
⊢ List.Pairwise (fun a b => ¬(a.fst == b.fst) = true)
    (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]).toList

case refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : a ∈ (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]).toList
⊢ (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat) a.fst a.snd

tactic: simp only [AssocList.toList_replace]
state_before: case refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
H : List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList
⊢ List.Pairwise (fun a b => ¬(a.fst == b.fst) = true)
    (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]).toList
state_after: case refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
H : List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList
⊢ List.Pairwise (fun a b => ¬(a.fst == b.fst) = true)
    (List.replaceF (fun x => bif x.fst == k then some (k, v) else none)
      m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList)

tactic: exact pairwise_replaceF H
state_before: case refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
H : List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList
⊢ List.Pairwise (fun a b => ¬(a.fst == b.fst) = true)
    (List.replaceF (fun x => bif x.fst == k then some (k, v) else none)
      m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList)
state_after: no goals

tactic: simp only [AssocList.All, Array.ugetElem_eq_getElem, AssocList.toList_replace] at H h ⊢
state_before: case refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : a ∈ (AssocList.replace k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]).toList
⊢ (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat) a.fst a.snd
state_after: case refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
H :
  ∀ (a : α × β),
    a ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList →
      ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
a : α × β
h :
  a ∈
    List.replaceF (fun x => bif x.fst == k then some (k, v) else none)
      m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat

tactic: match mem_replaceF h with
| .inl rfl => rfl
| .inr h => exact H _ h
state_before: case refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
x : α × β
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
H :
  ∀ (a : α × β),
    a ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList →
      ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
a : α × β
h :
  a ∈
    List.replaceF (fun x => bif x.fst == k then some (k, v) else none)
      m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
state_after: no goals

tactic: rfl
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
v : β
h✝ : m.buckets.WF
c✝ : Bool
x a : α × β
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash a.fst).toUSize).val.toNat].toList ∧ (x.fst == a.fst) = true
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash a.fst).toUSize).val.toNat].toList
hx₂ : (x.fst == a.fst) = true
H :
  ∀ (a_1 : α × β),
    a_1 ∈ m.buckets.val[(mkIdx ⋯ (hash a.fst).toUSize).val.toNat].toList →
      ((hash a_1.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash a.fst).toUSize).val.toNat
h :
  a ∈
    List.replaceF (fun x => bif x.fst == a.fst then some (a.fst, v) else none)
      m.buckets.val[(mkIdx ⋯ (hash a.fst).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash a.fst).toUSize).val.toNat
state_after: no goals

tactic: exact H _ h
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
v : β
h✝¹ : m.buckets.WF
c✝ : Bool
x a : α × β
k : α
h : a ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
h₁ : ∃ x, x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList ∧ (x.fst == k) = true
hx₁ : x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
hx₂ : (x.fst == k) = true
H :
  ∀ (a : α × β),
    a ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList →
      ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
h✝ :
  a ∈
    List.replaceF (fun x => bif x.fst == k then some (k, v) else none)
      m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
state_after: no goals

tactic: rw [Bool.eq_false_iff] at h₁
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] = false
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] ≠ true
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF

tactic: simp only [AssocList.contains_eq, ne_eq, List.any_eq_true, not_exists, not_and] at h₁
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : AssocList.contains k m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat] ≠ true
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF

tactic: suffices _ by split <;> [exact this; refine expand_WF this]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF
state_after: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
⊢ { size := m.size + 1,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF

tactic: refine h.update (.cons ?_) (fun H a h => ?_)
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
⊢ { size := m.size + 1,
        buckets :=
          m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }.buckets.WF
state_after: case refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
⊢ ∀ (a' : α × β), a' ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList → ¬((k, v).fst == a'.fst) = true

case refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : a ∈ (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]).toList
⊢ (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat) a.fst a.snd

tactic: split <;> [exact this; refine expand_WF this]
state_before: α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
this : ?m.56580
⊢ (if numBucketsForCapacity (m.size + 1) ≤ m.buckets.val.size then
        { size := m.size + 1,
          buckets :=
            m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
              (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯ }
      else
        expand (m.size + 1)
          (m.buckets.update (mkIdx ⋯ (hash k).toUSize).val
            (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]) ⋯)).buckets.WF
state_after: no goals

tactic: exact fun a h h' => h₁ a h (PartialEquivBEq.symm h')
state_before: case refine_1
α : Type u_1
β : Type u_2
inst✝³ : BEq α
inst✝² : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
inst✝¹ : PartialEquivBEq α
inst✝ : LawfulHashable α
⊢ ∀ (a' : α × β), a' ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val].toList → ¬((k, v).fst == a'.fst) = true
state_after: no goals

tactic: cases h with
| head => rfl
| tail _ h => exact H _ h
state_before: case refine_2
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : a ∈ (AssocList.cons k v m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat]).toList
⊢ (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat) a.fst a.snd
state_after: no goals

tactic: rfl
state_before: case refine_2.head
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
⊢ ((hash (k, v).fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
state_after: no goals

tactic: exact H _ h
state_before: case refine_2.tail
α : Type u_1
β : Type u_2
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
k : α
v : β
h✝ : m.buckets.WF
c✝ : Bool
h₁ : ∀ (x : α × β), x ∈ m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList → ¬(x.fst == k) = true
H :
  AssocList.All (fun k_1 x => ((hash k_1).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat)
    m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val]
a : α × β
h : List.Mem a m.buckets.val[(mkIdx ⋯ (hash k).toUSize).val.toNat].toList
⊢ ((hash a.fst).toUSize % m.buckets.val.size).toNat = (mkIdx ⋯ (hash k).toUSize).val.toNat
state_after: no goals