Theorem: Batteries.HashMap.Imp.WF.mapVal
File: .lake/packages/batteries/Batteries/Data/HashMap/WF.lean

tactic: have ⟨h₁, h₂⟩ := H.out
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
⊢ (Imp.mapVal f m).WF
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ (Imp.mapVal f m).WF

tactic: simp only [Imp.mapVal, h₁, Buckets.mapVal, WF_iff]
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ (Imp.mapVal f m).WF
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ m.buckets.size = Buckets.size ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩ ∧
    Buckets.WF ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩

tactic: refine ⟨?_, ?_, fun i h => ?_⟩
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ m.buckets.size = Buckets.size ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩ ∧
    Buckets.WF ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩
state_after: case refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ m.buckets.size = Buckets.size ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩

case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α γ),
    bucket ∈ ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.data →
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList

case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
i : Nat
h : i < ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.size
⊢ AssocList.All (fun k x => ((hash k).toUSize % ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.size).toNat = i)
    ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val[i]

tactic: simp only [Buckets.size, Array.map_data, List.map_map]
state_before: case refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ m.buckets.size = Buckets.size ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩
state_after: case refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ Nat.sum (List.map (fun x => x.toList.length) m.buckets.val.data) =
    Nat.sum (List.map ((fun x => x.toList.length) ∘ AssocList.mapVal f) m.buckets.val.data)

tactic: congr
state_before: case refine_1
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ Nat.sum (List.map (fun x => x.toList.length) m.buckets.val.data) =
    Nat.sum (List.map ((fun x => x.toList.length) ∘ AssocList.mapVal f) m.buckets.val.data)
state_after: case refine_1.e_l.e_f
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ (fun x => x.toList.length) = (fun x => x.toList.length) ∘ AssocList.mapVal f

tactic: funext l
state_before: case refine_1.e_l.e_f
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ (fun x => x.toList.length) = (fun x => x.toList.length) ∘ AssocList.mapVal f
state_after: case refine_1.e_l.e_f.h
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
l : AssocList α β
⊢ l.toList.length = ((fun x => x.toList.length) ∘ AssocList.mapVal f) l

tactic: simp
state_before: case refine_1.e_l.e_f.h
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
l : AssocList α β
⊢ l.toList.length = ((fun x => x.toList.length) ∘ AssocList.mapVal f) l
state_after: no goals

tactic: simp only [Array.map_data, List.forall_mem_map_iff]
state_before: case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (bucket : AssocList α γ),
    bucket ∈ ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.data →
      List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) bucket.toList
state_after: case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (j : AssocList α β),
    j ∈ m.buckets.val.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) (AssocList.mapVal f j).toList

tactic: simp only [AssocList.toList_mapVal, List.pairwise_map]
state_before: case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (j : AssocList α β),
    j ∈ m.buckets.val.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) (AssocList.mapVal f j).toList
state_after: case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (j : AssocList α β),
    j ∈ m.buckets.val.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) j.toList

tactic: exact fun _ => h₂.1 _
state_before: case refine_2
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
⊢ ∀ [inst : LawfulHashable α] [inst : PartialEquivBEq α] (j : AssocList α β),
    j ∈ m.buckets.val.data → List.Pairwise (fun a b => ¬(a.fst == b.fst) = true) j.toList
state_after: no goals

tactic: simp only [Array.size_map, AssocList.All, Array.getElem_map, AssocList.toList_mapVal,
  List.mem_map, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] at h ⊢
state_before: case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
i : Nat
h : i < ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.size
⊢ AssocList.All (fun k x => ((hash k).toUSize % ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.size).toNat = i)
    ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val[i]
state_after: case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
i : Nat
h✝ : i < ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.size
h : i < m.buckets.val.size
⊢ ∀ (a : α × β), a ∈ m.buckets.val[i].toList → ((hash a.fst).toUSize % m.buckets.val.size).toNat = i

tactic: intro a m
state_before: case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m : Imp α β
H : m.WF
h₁ : m.size = m.buckets.size
h₂ : m.buckets.WF
i : Nat
h✝ : i < ⟨Array.map (AssocList.mapVal f) m.buckets.val, ⋯⟩.val.size
h : i < m.buckets.val.size
⊢ ∀ (a : α × β), a ∈ m.buckets.val[i].toList → ((hash a.fst).toUSize % m.buckets.val.size).toNat = i
state_after: case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m✝ : Imp α β
H : m✝.WF
h₁ : m✝.size = m✝.buckets.size
h₂ : m✝.buckets.WF
i : Nat
h✝ : i < ⟨Array.map (AssocList.mapVal f) m✝.buckets.val, ⋯⟩.val.size
h : i < m✝.buckets.val.size
a : α × β
m : a ∈ m✝.buckets.val[i].toList
⊢ ((hash a.fst).toUSize % m✝.buckets.val.size).toNat = i

tactic: apply h₂.2 _ _ _ m
state_before: case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
f : α → β → γ
inst✝¹ : BEq α
inst✝ : Hashable α
m✝ : Imp α β
H : m✝.WF
h₁ : m✝.size = m✝.buckets.size
h₂ : m✝.buckets.WF
i : Nat
h✝ : i < ⟨Array.map (AssocList.mapVal f) m✝.buckets.val, ⋯⟩.val.size
h : i < m✝.buckets.val.size
a : α × β
m : a ∈ m✝.buckets.val[i].toList
⊢ ((hash a.fst).toUSize % m✝.buckets.val.size).toNat = i
state_after: no goals