mirror of
https://github.com/leanprover/lean4.git
synced 2026-03-28 15:54:08 +00:00
Compare commits
16 Commits
align_flat
...
mkArray_re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c2b7832c | ||
|
|
80ddbf45eb | ||
|
|
3a6c5cf4f1 | ||
|
|
af4a7d7e98 | ||
|
|
6259b4742c | ||
|
|
0050e9369c | ||
|
|
64cf5e5e6a | ||
|
|
127b3f9191 | ||
|
|
65175dc7d4 | ||
|
|
54f06ccd64 | ||
|
|
b3f8feffd3 | ||
|
|
6665837232 | ||
|
|
c7fd873333 | ||
|
|
a10ce9492f | ||
|
|
838ad281f2 | ||
|
|
a1ef26bd8b |
@@ -161,7 +161,10 @@ def pop (a : Array α) : Array α where
|
||||
| ⟨[]⟩ => rfl
|
||||
| ⟨a::as⟩ => simp [pop, Nat.succ_sub_succ_eq_sub, size]
|
||||
|
||||
@[extern "lean_mk_array"]
|
||||
def replicate {α : Type u} (n : Nat) (v : α) : Array α where
|
||||
toList := List.replicate n v
|
||||
|
||||
@[extern "lean_mk_array", deprecated replicate (since := "2025-01-16")]
|
||||
def mkArray {α : Type u} (n : Nat) (v : α) : Array α where
|
||||
toList := List.replicate n v
|
||||
|
||||
|
||||
@@ -98,21 +98,26 @@ theorem back?_flatten {L : Array (Array α)} :
|
||||
cases L using array₂_induction
|
||||
simp [List.getLast?_flatten, ← List.map_reverse, List.findSome?_map, Function.comp_def]
|
||||
|
||||
theorem findSome?_mkArray : findSome? f (mkArray n a) = if n = 0 then none else f a := by
|
||||
theorem findSome?_replicate : findSome? f (replicate n a) = if n = 0 then none else f a := by
|
||||
simp [← List.toArray_replicate, List.findSome?_replicate]
|
||||
|
||||
@[simp] theorem findSome?_mkArray_of_pos (h : 0 < n) : findSome? f (mkArray n a) = f a := by
|
||||
simp [findSome?_mkArray, Nat.ne_of_gt h]
|
||||
@[simp] theorem findSome?_replicate_of_pos (h : 0 < n) : findSome? f (replicate n a) = f a := by
|
||||
simp [findSome?_replicate, Nat.ne_of_gt h]
|
||||
|
||||
-- Argument is unused, but used to decide whether `simp` should unfold.
|
||||
@[simp] theorem findSome?_mkArray_of_isSome (_ : (f a).isSome) :
|
||||
findSome? f (mkArray n a) = if n = 0 then none else f a := by
|
||||
simp [findSome?_mkArray]
|
||||
@[simp] theorem findSome?_replicate_of_isSome (_ : (f a).isSome) :
|
||||
findSome? f (replicate n a) = if n = 0 then none else f a := by
|
||||
simp [findSome?_replicate]
|
||||
|
||||
@[simp] theorem findSome?_mkArray_of_isNone (h : (f a).isNone) :
|
||||
findSome? f (mkArray n a) = none := by
|
||||
@[simp] theorem findSome?_replicate_of_isNone (h : (f a).isNone) :
|
||||
findSome? f (replicate n a) = none := by
|
||||
rw [Option.isNone_iff_eq_none] at h
|
||||
simp [findSome?_mkArray, h]
|
||||
simp [findSome?_replicate, h]
|
||||
|
||||
@[deprecated findSome?_replicate (since := "2025-01-16")] abbrev findSome?_mkArray := @findSome?_replicate
|
||||
@[deprecated findSome?_replicate_of_pos (since := "2025-01-16")] abbrev findSome?_mkArray_of_pos := @findSome?_replicate_of_pos
|
||||
@[deprecated findSome?_replicate_of_isSome (since := "2025-01-16")] abbrev findSome?_mkArray_of_isSome := @findSome?_replicate_of_isSome
|
||||
@[deprecated findSome?_replicate_of_isNone (since := "2025-01-16")] abbrev findSome?_mkArray_of_isNone := @findSome?_replicate_of_isNone
|
||||
|
||||
/-! ### find? -/
|
||||
|
||||
@@ -244,34 +249,42 @@ theorem find?_flatMap_eq_none {xs : Array α} {f : α → Array β} {p : β →
|
||||
(xs.flatMap f).find? p = none ↔ ∀ x ∈ xs, ∀ y ∈ f x, !p y := by
|
||||
simp
|
||||
|
||||
theorem find?_mkArray :
|
||||
find? p (mkArray n a) = if n = 0 then none else if p a then some a else none := by
|
||||
theorem find?_replicate :
|
||||
find? p (replicate n a) = if n = 0 then none else if p a then some a else none := by
|
||||
simp [← List.toArray_replicate, List.find?_replicate]
|
||||
|
||||
@[simp] theorem find?_mkArray_of_length_pos (h : 0 < n) :
|
||||
find? p (mkArray n a) = if p a then some a else none := by
|
||||
simp [find?_mkArray, Nat.ne_of_gt h]
|
||||
@[simp] theorem find?_replicate_of_length_pos (h : 0 < n) :
|
||||
find? p (replicate n a) = if p a then some a else none := by
|
||||
simp [find?_replicate, Nat.ne_of_gt h]
|
||||
|
||||
@[simp] theorem find?_mkArray_of_pos (h : p a) :
|
||||
find? p (mkArray n a) = if n = 0 then none else some a := by
|
||||
simp [find?_mkArray, h]
|
||||
@[simp] theorem find?_replicate_of_pos (h : p a) :
|
||||
find? p (replicate n a) = if n = 0 then none else some a := by
|
||||
simp [find?_replicate, h]
|
||||
|
||||
@[simp] theorem find?_mkArray_of_neg (h : ¬ p a) : find? p (mkArray n a) = none := by
|
||||
simp [find?_mkArray, h]
|
||||
@[simp] theorem find?_replicate_of_neg (h : ¬ p a) : find? p (replicate n a) = none := by
|
||||
simp [find?_replicate, h]
|
||||
|
||||
-- This isn't a `@[simp]` lemma since there is already a lemma for `l.find? p = none` for any `l`.
|
||||
theorem find?_mkArray_eq_none {n : Nat} {a : α} {p : α → Bool} :
|
||||
(mkArray n a).find? p = none ↔ n = 0 ∨ !p a := by
|
||||
theorem find?_replicate_eq_none {n : Nat} {a : α} {p : α → Bool} :
|
||||
(replicate n a).find? p = none ↔ n = 0 ∨ !p a := by
|
||||
simp [← List.toArray_replicate, List.find?_replicate_eq_none, Classical.or_iff_not_imp_left]
|
||||
|
||||
@[simp] theorem find?_mkArray_eq_some {n : Nat} {a b : α} {p : α → Bool} :
|
||||
(mkArray n a).find? p = some b ↔ n ≠ 0 ∧ p a ∧ a = b := by
|
||||
@[simp] theorem find?_replicate_eq_some {n : Nat} {a b : α} {p : α → Bool} :
|
||||
(replicate n a).find? p = some b ↔ n ≠ 0 ∧ p a ∧ a = b := by
|
||||
simp [← List.toArray_replicate]
|
||||
|
||||
@[simp] theorem get_find?_mkArray (n : Nat) (a : α) (p : α → Bool) (h) :
|
||||
((mkArray n a).find? p).get h = a := by
|
||||
@[simp] theorem get_find?_replicate (n : Nat) (a : α) (p : α → Bool) (h) :
|
||||
((replicate n a).find? p).get h = a := by
|
||||
simp [← List.toArray_replicate]
|
||||
|
||||
@[deprecated find?_replicate (since := "2025-01-16")] abbrev find?_mkArray := @find?_replicate
|
||||
@[deprecated find?_replicate_of_length_pos (since := "2025-01-16")] abbrev find?_mkArray_of_length_pos := @find?_replicate_of_length_pos
|
||||
@[deprecated find?_replicate_of_pos (since := "2025-01-16")] abbrev find?_mkArray_of_pos := @find?_replicate_of_pos
|
||||
@[deprecated find?_replicate_of_neg (since := "2025-01-16")] abbrev find?_mkArray_of_neg := @find?_replicate_of_neg
|
||||
@[deprecated find?_replicate_eq_none (since := "2025-01-16")] abbrev find?_mkArray_eq_none := @find?_replicate_eq_none
|
||||
@[deprecated find?_replicate_eq_some (since := "2025-01-16")] abbrev find?_mkArray_eq_some := @find?_replicate_eq_some
|
||||
@[deprecated get_find?_mkArray (since := "2025-01-16")] abbrev get_find?_mkArray := @get_find?_replicate
|
||||
|
||||
theorem find?_pmap {P : α → Prop} (f : (a : α) → P a → β) (xs : Array α)
|
||||
(H : ∀ (a : α), a ∈ xs → P a) (p : β → Bool) :
|
||||
(xs.pmap f H).find? p = (xs.attach.find? (fun ⟨a, m⟩ => p (f a (H a m)))).map fun ⟨a, m⟩ => f a (H a m) := by
|
||||
|
||||
@@ -160,31 +160,38 @@ theorem exists_push_of_size_eq_add_one {xs : Array α} (h : xs.size = n + 1) :
|
||||
theorem singleton_inj : #[a] = #[b] ↔ a = b := by
|
||||
simp
|
||||
|
||||
/-! ### mkArray -/
|
||||
/-! ### replicate -/
|
||||
|
||||
@[simp] theorem size_mkArray (n : Nat) (v : α) : (mkArray n v).size = n :=
|
||||
@[simp] theorem size_replicate (n : Nat) (v : α) : (replicate n v).size = n :=
|
||||
List.length_replicate ..
|
||||
|
||||
@[simp] theorem toList_mkArray : (mkArray n a).toList = List.replicate n a := by
|
||||
simp only [mkArray]
|
||||
@[simp] theorem toList_replicate : (replicate n a).toList = List.replicate n a := by
|
||||
simp only [replicate]
|
||||
|
||||
@[simp] theorem mkArray_zero : mkArray 0 a = #[] := rfl
|
||||
@[simp] theorem replicate_zero : replicate 0 a = #[] := rfl
|
||||
|
||||
theorem mkArray_succ : mkArray (n + 1) a = (mkArray n a).push a := by
|
||||
theorem replicate_succ : replicate (n + 1) a = (replicate n a).push a := by
|
||||
apply toList_inj.1
|
||||
simp [List.replicate_succ']
|
||||
|
||||
theorem mkArray_inj : mkArray n a = mkArray m b ↔ n = m ∧ (n = 0 ∨ a = b) := by
|
||||
theorem replicate_inj : replicate n a = replicate m b ↔ n = m ∧ (n = 0 ∨ a = b) := by
|
||||
rw [← List.replicate_inj, ← toList_inj]
|
||||
simp
|
||||
|
||||
@[simp] theorem getElem_mkArray (n : Nat) (v : α) (h : i < (mkArray n v).size) :
|
||||
(mkArray n v)[i] = v := by simp [← getElem_toList]
|
||||
@[simp] theorem getElem_replicate (n : Nat) (v : α) (h : i < (replicate n v).size) :
|
||||
(replicate n v)[i] = v := by simp [← getElem_toList]
|
||||
|
||||
theorem getElem?_mkArray (n : Nat) (v : α) (i : Nat) :
|
||||
(mkArray n v)[i]? = if i < n then some v else none := by
|
||||
theorem getElem?_replicate (n : Nat) (v : α) (i : Nat) :
|
||||
(replicate n v)[i]? = if i < n then some v else none := by
|
||||
simp [getElem?_def]
|
||||
|
||||
@[deprecated size_replicate (since := "2025-01-16")] abbrev size_mkArray := @size_replicate
|
||||
@[deprecated replicate_zero (since := "2025-01-16")] abbrev replicate_mkArray_zero := @replicate_zero
|
||||
@[deprecated replicate_succ (since := "2025-01-16")] abbrev replicate_mkArray_succ := @replicate_succ
|
||||
@[deprecated replicate_inj (since := "2025-01-16")] abbrev replicate_mkArray_inj := @replicate_inj
|
||||
@[deprecated getElem_replicate (since := "2025-01-16")] abbrev getElem_mkArray := @getElem_replicate
|
||||
@[deprecated getElem?_replicate (since := "2025-01-16")] abbrev getElem?_mkArray := @getElem?_replicate
|
||||
|
||||
/-! ## L[i] and L[i]? -/
|
||||
|
||||
@[simp] theorem getElem?_eq_none_iff {a : Array α} : a[i]? = none ↔ a.size ≤ i := by
|
||||
@@ -962,15 +969,17 @@ theorem size_eq_of_beq [BEq α] {xs ys : Array α} (h : xs == ys) : xs.size = ys
|
||||
cases ys
|
||||
simp [List.length_eq_of_beq (by simpa using h)]
|
||||
|
||||
@[simp] theorem mkArray_beq_mkArray [BEq α] {a b : α} {n : Nat} :
|
||||
(mkArray n a == mkArray n b) = (n == 0 || a == b) := by
|
||||
@[simp] theorem replicate_beq_replicate [BEq α] {a b : α} {n : Nat} :
|
||||
(replicate n a == replicate n b) = (n == 0 || a == b) := by
|
||||
cases n with
|
||||
| zero => simp
|
||||
| succ n =>
|
||||
rw [mkArray_succ, mkArray_succ, push_beq_push, mkArray_beq_mkArray]
|
||||
rw [replicate_succ, replicate_succ, push_beq_push, replicate_beq_replicate]
|
||||
rw [Bool.eq_iff_iff]
|
||||
simp +contextual
|
||||
|
||||
@[deprecated replicate_beq_replicate (since := "2025-01-16")] abbrev mkArray_beq_mkArray := @replicate_beq_replicate
|
||||
|
||||
private theorem beq_of_beq_singleton [BEq α] {a b : α} : #[a] == #[b] → a == b := by
|
||||
intro h
|
||||
have : isEqv #[a] #[b] BEq.beq = true := h
|
||||
@@ -3182,42 +3191,48 @@ theorem sum_eq_sum_toList [Add α] [Zero α] (as : Array α) : as.sum = as.toLis
|
||||
cases as
|
||||
simp [Array.sum, List.sum]
|
||||
|
||||
/-! ### mkArray -/
|
||||
/-! ### replicate -/
|
||||
|
||||
theorem eq_mkArray_of_mem {a : α} {l : Array α} (h : ∀ (b) (_ : b ∈ l), b = a) : l = mkArray l.size a := by
|
||||
theorem eq_replicate_of_mem {a : α} {l : Array α} (h : ∀ (b) (_ : b ∈ l), b = a) : l = replicate l.size a := by
|
||||
rcases l with ⟨l⟩
|
||||
have := List.eq_replicate_of_mem (by simpa using h)
|
||||
rw [this]
|
||||
simp
|
||||
|
||||
theorem eq_mkArray_iff {a : α} {n} {l : Array α} :
|
||||
l = mkArray n a ↔ l.size = n ∧ ∀ (b) (_ : b ∈ l), b = a := by
|
||||
theorem eq_replicate_iff {a : α} {n} {l : Array α} :
|
||||
l = replicate n a ↔ l.size = n ∧ ∀ (b) (_ : b ∈ l), b = a := by
|
||||
rcases l with ⟨l⟩
|
||||
simp [← List.eq_replicate_iff, toArray_eq]
|
||||
|
||||
theorem map_eq_mkArray_iff {l : Array α} {f : α → β} {b : β} :
|
||||
l.map f = mkArray l.size b ↔ ∀ x ∈ l, f x = b := by
|
||||
simp [eq_mkArray_iff]
|
||||
theorem map_eq_replicate_iff {l : Array α} {f : α → β} {b : β} :
|
||||
l.map f = replicate l.size b ↔ ∀ x ∈ l, f x = b := by
|
||||
simp [eq_replicate_iff]
|
||||
|
||||
@[simp] theorem mem_mkArray (a : α) (n : Nat) : b ∈ mkArray n a ↔ n ≠ 0 ∧ b = a := by
|
||||
rw [mkArray, mem_toArray]
|
||||
@[simp] theorem mem_replicate (a : α) (n : Nat) : b ∈ replicate n a ↔ n ≠ 0 ∧ b = a := by
|
||||
rw [replicate, mem_toArray]
|
||||
simp
|
||||
|
||||
@[simp] theorem map_const (l : Array α) (b : β) : map (Function.const α b) l = mkArray l.size b :=
|
||||
map_eq_mkArray_iff.mpr fun _ _ => rfl
|
||||
@[simp] theorem map_const (l : Array α) (b : β) : map (Function.const α b) l = replicate l.size b :=
|
||||
map_eq_replicate_iff.mpr fun _ _ => rfl
|
||||
|
||||
@[simp] theorem map_const_fun (x : β) : map (Function.const α x) = (mkArray ·.size x) := by
|
||||
@[simp] theorem map_const_fun (x : β) : map (Function.const α x) = (replicate ·.size x) := by
|
||||
funext l
|
||||
simp
|
||||
|
||||
/-- Variant of `map_const` using a lambda rather than `Function.const`. -/
|
||||
-- This can not be a `@[simp]` lemma because it would fire on every `Array.map`.
|
||||
theorem map_const' (l : Array α) (b : β) : map (fun _ => b) l = mkArray l.size b :=
|
||||
theorem map_const' (l : Array α) (b : β) : map (fun _ => b) l = replicate l.size b :=
|
||||
map_const l b
|
||||
|
||||
@[simp] theorem sum_mkArray_nat (n : Nat) (a : Nat) : (mkArray n a).sum = n * a := by
|
||||
@[simp] theorem sum_replicate_nat (n : Nat) (a : Nat) : (replicate n a).sum = n * a := by
|
||||
simp [sum_eq_sum_toList, List.sum_replicate_nat]
|
||||
|
||||
@[deprecated eq_replicate_of_mem (since := "2025-01-16")] abbrev eq_mkArray_of_mem := @eq_replicate_of_mem
|
||||
@[deprecated eq_replicate_iff (since := "2025-01-16")] abbrev eq_mkArray_iff := @eq_replicate_iff
|
||||
@[deprecated map_eq_replicate_iff (since := "2025-01-16")] abbrev map_eq_mkArray_iff := @map_eq_replicate_iff
|
||||
@[deprecated mem_replicate (since := "2025-01-16")] abbrev mem_mkArray := @mem_replicate
|
||||
@[deprecated sum_replicate_nat (since := "2025-01-16")] abbrev sum_mkArray_nat := @sum_replicate_nat
|
||||
|
||||
/-! ### reverse -/
|
||||
|
||||
@[simp] theorem mem_reverse {x : α} {as : Array α} : x ∈ as.reverse ↔ x ∈ as := by
|
||||
|
||||
@@ -392,7 +392,7 @@ theorem takeWhile_go_toArray (p : α → Bool) (l : List α) (i : Nat) :
|
||||
· simp
|
||||
· simp_all [List.set_eq_of_length_le]
|
||||
|
||||
@[simp] theorem toArray_replicate (n : Nat) (v : α) : (List.replicate n v).toArray = mkArray n v := rfl
|
||||
@[simp] theorem toArray_replicate (n : Nat) (v : α) : (List.replicate n v).toArray = Array.replicate n v := rfl
|
||||
|
||||
@[deprecated toArray_replicate (since := "2024-12-13")]
|
||||
abbrev _root_.Array.mkArray_eq_toArray_replicate := @toArray_replicate
|
||||
|
||||
@@ -13,17 +13,17 @@ macro "declare_bitwise_uint_theorems" typeName:ident bits:term:arg : command =>
|
||||
`(
|
||||
namespace $typeName
|
||||
|
||||
@[simp] protected theorem toBitVec_add {a b : $typeName} : (a + b).toBitVec = a.toBitVec + b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_sub {a b : $typeName} : (a - b).toBitVec = a.toBitVec - b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_mul {a b : $typeName} : (a * b).toBitVec = a.toBitVec * b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_div {a b : $typeName} : (a / b).toBitVec = a.toBitVec / b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_mod {a b : $typeName} : (a % b).toBitVec = a.toBitVec % b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_not {a : $typeName} : (~~~a).toBitVec = ~~~a.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_and (a b : $typeName) : (a &&& b).toBitVec = a.toBitVec &&& b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_or (a b : $typeName) : (a ||| b).toBitVec = a.toBitVec ||| b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_xor (a b : $typeName) : (a ^^^ b).toBitVec = a.toBitVec ^^^ b.toBitVec := rfl
|
||||
@[simp] protected theorem toBitVec_shiftLeft (a b : $typeName) : (a <<< b).toBitVec = a.toBitVec <<< (b.toBitVec % $bits) := rfl
|
||||
@[simp] protected theorem toBitVec_shiftRight (a b : $typeName) : (a >>> b).toBitVec = a.toBitVec >>> (b.toBitVec % $bits) := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_add {a b : $typeName} : (a + b).toBitVec = a.toBitVec + b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_sub {a b : $typeName} : (a - b).toBitVec = a.toBitVec - b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_mul {a b : $typeName} : (a * b).toBitVec = a.toBitVec * b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_div {a b : $typeName} : (a / b).toBitVec = a.toBitVec / b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_mod {a b : $typeName} : (a % b).toBitVec = a.toBitVec % b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_not {a : $typeName} : (~~~a).toBitVec = ~~~a.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_and (a b : $typeName) : (a &&& b).toBitVec = a.toBitVec &&& b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_or (a b : $typeName) : (a ||| b).toBitVec = a.toBitVec ||| b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_xor (a b : $typeName) : (a ^^^ b).toBitVec = a.toBitVec ^^^ b.toBitVec := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_shiftLeft (a b : $typeName) : (a <<< b).toBitVec = a.toBitVec <<< (b.toBitVec % $bits) := rfl
|
||||
@[simp, int_toBitVec] protected theorem toBitVec_shiftRight (a b : $typeName) : (a >>> b).toBitVec = a.toBitVec >>> (b.toBitVec % $bits) := rfl
|
||||
|
||||
@[simp] protected theorem toNat_and (a b : $typeName) : (a &&& b).toNat = a.toNat &&& b.toNat := by simp [toNat]
|
||||
@[simp] protected theorem toNat_or (a b : $typeName) : (a ||| b).toNat = a.toNat ||| b.toNat := by simp [toNat]
|
||||
@@ -44,27 +44,27 @@ declare_bitwise_uint_theorems UInt32 32
|
||||
declare_bitwise_uint_theorems UInt64 64
|
||||
declare_bitwise_uint_theorems USize System.Platform.numBits
|
||||
|
||||
@[simp]
|
||||
@[simp, int_toBitVec]
|
||||
theorem Bool.toBitVec_toUInt8 {b : Bool} :
|
||||
b.toUInt8.toBitVec = (BitVec.ofBool b).setWidth 8 := by
|
||||
cases b <;> simp [toUInt8]
|
||||
|
||||
@[simp]
|
||||
@[simp, int_toBitVec]
|
||||
theorem Bool.toBitVec_toUInt16 {b : Bool} :
|
||||
b.toUInt16.toBitVec = (BitVec.ofBool b).setWidth 16 := by
|
||||
cases b <;> simp [toUInt16]
|
||||
|
||||
@[simp]
|
||||
@[simp, int_toBitVec]
|
||||
theorem Bool.toBitVec_toUInt32 {b : Bool} :
|
||||
b.toUInt32.toBitVec = (BitVec.ofBool b).setWidth 32 := by
|
||||
cases b <;> simp [toUInt32]
|
||||
|
||||
@[simp]
|
||||
@[simp, int_toBitVec]
|
||||
theorem Bool.toBitVec_toUInt64 {b : Bool} :
|
||||
b.toUInt64.toBitVec = (BitVec.ofBool b).setWidth 64 := by
|
||||
cases b <;> simp [toUInt64]
|
||||
|
||||
@[simp]
|
||||
@[simp, int_toBitVec]
|
||||
theorem Bool.toBitVec_toUSize {b : Bool} :
|
||||
b.toUSize.toBitVec = (BitVec.ofBool b).setWidth System.Platform.numBits := by
|
||||
cases b
|
||||
|
||||
@@ -41,9 +41,9 @@ macro "declare_uint_theorems" typeName:ident bits:term:arg : command => do
|
||||
theorem toNat_ofNat_of_lt {n : Nat} (h : n < size) : (ofNat n).toNat = n := by
|
||||
rw [toNat, toBitVec_eq_of_lt h]
|
||||
|
||||
theorem le_def {a b : $typeName} : a ≤ b ↔ a.toBitVec ≤ b.toBitVec := .rfl
|
||||
@[int_toBitVec] theorem le_def {a b : $typeName} : a ≤ b ↔ a.toBitVec ≤ b.toBitVec := .rfl
|
||||
|
||||
theorem lt_def {a b : $typeName} : a < b ↔ a.toBitVec < b.toBitVec := .rfl
|
||||
@[int_toBitVec] theorem lt_def {a b : $typeName} : a < b ↔ a.toBitVec < b.toBitVec := .rfl
|
||||
|
||||
theorem le_iff_toNat_le {a b : $typeName} : a ≤ b ↔ a.toNat ≤ b.toNat := .rfl
|
||||
|
||||
@@ -74,6 +74,11 @@ macro "declare_uint_theorems" typeName:ident bits:term:arg : command => do
|
||||
protected theorem toBitVec_inj {a b : $typeName} : a.toBitVec = b.toBitVec ↔ a = b :=
|
||||
Iff.intro eq_of_toBitVec_eq toBitVec_eq_of_eq
|
||||
|
||||
open $typeName (eq_of_toBitVec_eq toBitVec_eq_of_eq) in
|
||||
@[int_toBitVec]
|
||||
protected theorem eq_iff_toBitVec_eq {a b : $typeName} : a = b ↔ a.toBitVec = b.toBitVec :=
|
||||
Iff.intro toBitVec_eq_of_eq eq_of_toBitVec_eq
|
||||
|
||||
open $typeName (eq_of_toBitVec_eq) in
|
||||
protected theorem eq_of_val_eq {a b : $typeName} (h : a.val = b.val) : a = b := by
|
||||
rcases a with ⟨⟨_⟩⟩; rcases b with ⟨⟨_⟩⟩; simp_all [val]
|
||||
@@ -82,10 +87,19 @@ macro "declare_uint_theorems" typeName:ident bits:term:arg : command => do
|
||||
protected theorem val_inj {a b : $typeName} : a.val = b.val ↔ a = b :=
|
||||
Iff.intro eq_of_val_eq (congrArg val)
|
||||
|
||||
open $typeName (eq_of_toBitVec_eq) in
|
||||
protected theorem toBitVec_ne_of_ne {a b : $typeName} (h : a ≠ b) : a.toBitVec ≠ b.toBitVec :=
|
||||
fun h' => h (eq_of_toBitVec_eq h')
|
||||
|
||||
open $typeName (toBitVec_eq_of_eq) in
|
||||
protected theorem ne_of_toBitVec_ne {a b : $typeName} (h : a.toBitVec ≠ b.toBitVec) : a ≠ b :=
|
||||
fun h' => absurd (toBitVec_eq_of_eq h') h
|
||||
|
||||
open $typeName (ne_of_toBitVec_ne toBitVec_ne_of_ne) in
|
||||
@[int_toBitVec]
|
||||
protected theorem ne_iff_toBitVec_ne {a b : $typeName} : a ≠ b ↔ a.toBitVec ≠ b.toBitVec :=
|
||||
Iff.intro toBitVec_ne_of_ne ne_of_toBitVec_ne
|
||||
|
||||
open $typeName (ne_of_toBitVec_ne) in
|
||||
protected theorem ne_of_lt {a b : $typeName} (h : a < b) : a ≠ b := by
|
||||
apply ne_of_toBitVec_ne
|
||||
@@ -159,7 +173,7 @@ macro "declare_uint_theorems" typeName:ident bits:term:arg : command => do
|
||||
@[simp]
|
||||
theorem val_ofNat (n : Nat) : val (no_index (OfNat.ofNat n)) = OfNat.ofNat n := rfl
|
||||
|
||||
@[simp]
|
||||
@[simp, int_toBitVec]
|
||||
theorem toBitVec_ofNat (n : Nat) : toBitVec (no_index (OfNat.ofNat n)) = BitVec.ofNat _ n := rfl
|
||||
|
||||
@[simp]
|
||||
|
||||
@@ -52,13 +52,15 @@ def elimAsList {motive : Vector α n → Sort u}
|
||||
@[inline] def mkEmpty (capacity : Nat) : Vector α 0 := ⟨.mkEmpty capacity, rfl⟩
|
||||
|
||||
/-- Makes a vector of size `n` with all cells containing `v`. -/
|
||||
@[inline] def mkVector (n) (v : α) : Vector α n := ⟨mkArray n v, by simp⟩
|
||||
@[inline] def replicate (n) (v : α) : Vector α n := ⟨Array.replicate n v, by simp⟩
|
||||
|
||||
@[deprecated replicate (since := "2025-01-16")] abbrev mkVector := @replicate
|
||||
|
||||
/-- Returns a vector of size `1` with element `v`. -/
|
||||
@[inline] def singleton (v : α) : Vector α 1 := ⟨#[v], rfl⟩
|
||||
|
||||
instance [Inhabited α] : Inhabited (Vector α n) where
|
||||
default := mkVector n default
|
||||
default := replicate n default
|
||||
|
||||
/-- Get an element of a vector using a `Fin` index. -/
|
||||
@[inline] def get (v : Vector α n) (i : Fin n) : α :=
|
||||
|
||||
@@ -269,7 +269,9 @@ theorem toArray_mk (a : Array α) (h : a.size = n) : (Vector.mk a h).toArray = a
|
||||
cases v
|
||||
simp
|
||||
|
||||
@[simp] theorem toArray_mkVector : (mkVector n a).toArray = mkArray n a := rfl
|
||||
@[simp] theorem toArray_replicate : (replicate n a).toArray = Array.replicate n a := rfl
|
||||
|
||||
@[deprecated toArray_replicate (since := "2025-01-16")] abbrev toArray_mkVector := @toArray_replicate
|
||||
|
||||
@[simp] theorem toArray_inj {v w : Vector α n} : v.toArray = w.toArray ↔ v = w := by
|
||||
cases v
|
||||
@@ -389,7 +391,9 @@ theorem toList_swap (a : Vector α n) (i j) (hi hj) :
|
||||
cases v
|
||||
simp
|
||||
|
||||
@[simp] theorem toList_mkVector : (mkVector n a).toList = List.replicate n a := rfl
|
||||
@[simp] theorem toList_replicate : (replicate n a).toList = List.replicate n a := rfl
|
||||
|
||||
@[deprecated toList_replicate (since := "2025-01-16")] abbrev toList_mkVector := @toList_replicate
|
||||
|
||||
theorem toList_inj {v w : Vector α n} : v.toList = w.toList ↔ v = w := by
|
||||
cases v
|
||||
@@ -468,15 +472,19 @@ theorem exists_push {xs : Vector α (n + 1)} :
|
||||
theorem singleton_inj : #v[a] = #v[b] ↔ a = b := by
|
||||
simp
|
||||
|
||||
/-! ### mkVector -/
|
||||
/-! ### replicate -/
|
||||
|
||||
@[simp] theorem mkVector_zero : mkVector 0 a = #v[] := rfl
|
||||
@[simp] theorem replicate_zero : replicate 0 a = #v[] := rfl
|
||||
|
||||
theorem mkVector_succ : mkVector (n + 1) a = (mkVector n a).push a := by
|
||||
simp [mkVector, Array.mkArray_succ]
|
||||
theorem replicate_succ : replicate (n + 1) a = (replicate n a).push a := by
|
||||
simp [replicate, Array.replicate_succ]
|
||||
|
||||
theorem mkVector_inj : mkVector n a = mkVector n b ↔ n = 0 ∨ a = b := by
|
||||
simp [← toArray_inj, toArray_mkVector, Array.mkArray_inj]
|
||||
theorem replicate_inj : replicate n a = replicate n b ↔ n = 0 ∨ a = b := by
|
||||
simp [← toArray_inj, toArray_replicate, Array.replicate_inj]
|
||||
|
||||
@[deprecated replicate_zero (since := "2025-01-16")] abbrev mkVector_zero := @replicate_zero
|
||||
@[deprecated replicate_succ (since := "2025-01-16")] abbrev mkVector_succ := @replicate_succ
|
||||
@[deprecated replicate_inj (since := "2025-01-16")] abbrev mkVector_inj := @replicate_inj
|
||||
|
||||
/-! ## L[i] and L[i]? -/
|
||||
|
||||
@@ -1005,15 +1013,17 @@ theorem mem_setIfInBounds (v : Vector α n) (i : Nat) (hi : i < n) (a : α) :
|
||||
cases w
|
||||
simp
|
||||
|
||||
@[simp] theorem mkVector_beq_mkVector [BEq α] {a b : α} {n : Nat} :
|
||||
(mkVector n a == mkVector n b) = (n == 0 || a == b) := by
|
||||
@[simp] theorem replicate_beq_replicate [BEq α] {a b : α} {n : Nat} :
|
||||
(replicate n a == replicate n b) = (n == 0 || a == b) := by
|
||||
cases n with
|
||||
| zero => simp
|
||||
| succ n =>
|
||||
rw [mkVector_succ, mkVector_succ, push_beq_push, mkVector_beq_mkVector]
|
||||
rw [replicate_succ, replicate_succ, push_beq_push, replicate_beq_replicate]
|
||||
rw [Bool.eq_iff_iff]
|
||||
simp +contextual
|
||||
|
||||
@[deprecated replicate_beq_replicate (since := "2025-01-16")] abbrev mkVector_beq_mkVector := @replicate_beq_replicate
|
||||
|
||||
@[simp] theorem reflBEq_iff [BEq α] [NeZero n] : ReflBEq (Vector α n) ↔ ReflBEq α := by
|
||||
match n, NeZero.ne n with
|
||||
| n + 1, _ =>
|
||||
@@ -1021,8 +1031,8 @@ theorem mem_setIfInBounds (v : Vector α n) (i : Nat) (hi : i < n) (a : α) :
|
||||
· intro h
|
||||
constructor
|
||||
intro a
|
||||
suffices (mkVector (n + 1) a == mkVector (n + 1) a) = true by
|
||||
rw [mkVector_succ, push_beq_push, Bool.and_eq_true] at this
|
||||
suffices (replicate (n + 1) a == replicate (n + 1) a) = true by
|
||||
rw [replicate_succ, push_beq_push, Bool.and_eq_true] at this
|
||||
exact this.2
|
||||
simp
|
||||
· intro h
|
||||
@@ -1037,15 +1047,15 @@ theorem mem_setIfInBounds (v : Vector α n) (i : Nat) (hi : i < n) (a : α) :
|
||||
· intro h
|
||||
constructor
|
||||
· intro a b h
|
||||
have := mkVector_inj (n := n+1) (a := a) (b := b)
|
||||
have := replicate_inj (n := n+1) (a := a) (b := b)
|
||||
simp only [Nat.add_one_ne_zero, false_or] at this
|
||||
rw [← this]
|
||||
apply eq_of_beq
|
||||
rw [mkVector_beq_mkVector]
|
||||
rw [replicate_beq_replicate]
|
||||
simpa
|
||||
· intro a
|
||||
suffices (mkVector (n + 1) a == mkVector (n + 1) a) = true by
|
||||
rw [mkVector_beq_mkVector] at this
|
||||
suffices (replicate (n + 1) a == replicate (n + 1) a) = true by
|
||||
rw [replicate_beq_replicate] at this
|
||||
simpa
|
||||
simp
|
||||
· intro h
|
||||
@@ -1131,8 +1141,8 @@ theorem map_inj [NeZero n] : map (n := n) f = map g ↔ f = g := by
|
||||
constructor
|
||||
· intro h
|
||||
ext a
|
||||
replace h := congrFun h (mkVector n a)
|
||||
simp only [mkVector, map_mk, mk.injEq, Array.map_inj_left, Array.mem_mkArray, and_imp,
|
||||
replace h := congrFun h (replicate n a)
|
||||
simp only [replicate, map_mk, mk.injEq, Array.map_inj_left, Array.mem_replicate, and_imp,
|
||||
forall_eq_apply_imp_iff] at h
|
||||
exact h (NeZero.ne n)
|
||||
· intro h; subst h; rfl
|
||||
|
||||
@@ -45,6 +45,10 @@ structure Config where
|
||||
If `splitIndPred` is `true`, `grind` performs case-splitting on inductive predicates.
|
||||
Otherwise, it performs case-splitting only on types marked with `[grind_split]` attribute. -/
|
||||
splitIndPred : Bool := true
|
||||
/-- By default, `grind` halts as soon as it encounters a sub-goal where no further progress can be made. -/
|
||||
failures : Nat := 1
|
||||
/-- Maximum number of heartbeats (in thousands) the canonicalizer can spend per definitional equality test. -/
|
||||
canonHeartbeats : Nat := 1000
|
||||
deriving Inhabited, BEq
|
||||
|
||||
end Lean.Grind
|
||||
|
||||
@@ -85,7 +85,7 @@ partial def eraseProjIncForAux (y : VarId) (bs : Array FnBody) (mask : Mask) (ke
|
||||
/-- Try to erase `inc` instructions on projections of `y` occurring in the tail of `bs`.
|
||||
Return the updated `bs` and a bit mask specifying which `inc`s have been removed. -/
|
||||
def eraseProjIncFor (n : Nat) (y : VarId) (bs : Array FnBody) : Array FnBody × Mask :=
|
||||
eraseProjIncForAux y bs (mkArray n none) #[]
|
||||
eraseProjIncForAux y bs (Array.replicate n none) #[]
|
||||
|
||||
/-- Replace `reuse x ctor ...` with `ctor ...`, and remove `dec x` -/
|
||||
partial def reuseToCtor (x : VarId) : FnBody → FnBody
|
||||
|
||||
@@ -169,7 +169,7 @@ def mkFixedParamsMap (decls : Array Decl) : NameMap (Array Bool) := Id.run do
|
||||
for decl in decls do
|
||||
let values := mkInitialValues decl.params.size
|
||||
let assignment := mkAssignment decl values
|
||||
let fixed := Array.mkArray decl.params.size true
|
||||
let fixed := Array.replicate decl.params.size true
|
||||
match decl.value with
|
||||
| .code c =>
|
||||
match evalCode c |>.run { main := decl, decls, assignment } |>.run { fixed } with
|
||||
|
||||
@@ -98,7 +98,7 @@ where
|
||||
return { ctx with discrCtorMap := ctx.discrCtorMap.insert discr ctorInfo, ctorDiscrMap := ctx.ctorDiscrMap.insert ctor.toExpr discr }
|
||||
else
|
||||
-- For the discrCtor map, the constructor parameters are irrelevant for optimizations that use this information
|
||||
let ctorInfo := .ctor ctorVal (mkArray ctorVal.numParams Arg.erased ++ fieldArgs)
|
||||
let ctorInfo := .ctor ctorVal (Array.replicate ctorVal.numParams Arg.erased ++ fieldArgs)
|
||||
return { ctx with discrCtorMap := ctx.discrCtorMap.insert discr ctorInfo }
|
||||
|
||||
@[inline, inherit_doc withDiscrCtorImp] def withDiscrCtor [MonadFunctorT DiscrM m] (discr : FVarId) (ctorName : Name) (ctorFields : Array Param) : m α → m α :=
|
||||
|
||||
@@ -147,7 +147,7 @@ def saveSpecParamInfo (decls : Array Decl) : CompilerM Unit := do
|
||||
let mut declsInfo := #[]
|
||||
for decl in decls do
|
||||
if hasNospecializeAttribute (← getEnv) decl.name then
|
||||
declsInfo := declsInfo.push (mkArray decl.params.size .other)
|
||||
declsInfo := declsInfo.push (Array.replicate decl.params.size .other)
|
||||
else
|
||||
let specArgs? := getSpecializationArgs? (← getEnv) decl.name
|
||||
let contains (i : Nat) : Bool := specArgs?.getD #[] |>.contains i
|
||||
|
||||
@@ -24,7 +24,7 @@ order, exists in the array.
|
||||
-/
|
||||
def filterPairsM {m} [Monad m] {α} (a : Array α) (f : α → α → m (Bool × Bool)) :
|
||||
m (Array α) := do
|
||||
let mut removed := Array.mkArray a.size false
|
||||
let mut removed := Array.replicate a.size false
|
||||
let mut numRemoved := 0
|
||||
for h1 : i in [:a.size] do for h2 : j in [i+1:a.size] do
|
||||
unless removed[i]! || removed[j]! do
|
||||
|
||||
@@ -99,11 +99,11 @@ private def fuzzyMatchCore (pattern word : String) (patternRoles wordRoles : Arr
|
||||
between the substrings pattern[:i+1] and word[:j+1] assuming that pattern[i] misses at word[j] (k = 0, i.e.
|
||||
it was matched earlier), or matches at word[j] (k = 1). A value of `none` corresponds to a score of -∞, and is used
|
||||
where no such match/miss is possible or for unneeded parts of the table. -/
|
||||
let mut result : Array (Option Int) := Array.mkArray (pattern.length * word.length * 2) none
|
||||
let mut runLengths : Array Int := Array.mkArray (pattern.length * word.length) 0
|
||||
let mut result : Array (Option Int) := Array.replicate (pattern.length * word.length * 2) none
|
||||
let mut runLengths : Array Int := Array.replicate (pattern.length * word.length) 0
|
||||
|
||||
-- penalty for starting a consecutive run at each index
|
||||
let mut startPenalties : Array Int := Array.mkArray word.length 0
|
||||
let mut startPenalties : Array Int := Array.replicate word.length 0
|
||||
|
||||
let mut lastSepIdx := 0
|
||||
let mut penaltyNs : Int := 0
|
||||
@@ -124,8 +124,8 @@ private def fuzzyMatchCore (pattern word : String) (patternRoles wordRoles : Arr
|
||||
`word.length - pattern.length` at each index (because at the very end, we can only consider fuzzy matches
|
||||
of `pattern` with a longer substring of `word`). -/
|
||||
for wordIdx in [patternIdx:word.length-(pattern.length - patternIdx - 1)] do
|
||||
let missScore? :=
|
||||
if wordIdx >= 1 then
|
||||
let missScore? :=
|
||||
if wordIdx >= 1 then
|
||||
selectBest
|
||||
(getMiss result patternIdx (wordIdx - 1))
|
||||
(getMatch result patternIdx (wordIdx - 1))
|
||||
@@ -134,7 +134,7 @@ private def fuzzyMatchCore (pattern word : String) (patternRoles wordRoles : Arr
|
||||
let mut matchScore? := none
|
||||
|
||||
if allowMatch (pattern.get ⟨patternIdx⟩) (word.get ⟨wordIdx⟩) (patternRoles.get! patternIdx) (wordRoles.get! wordIdx) then
|
||||
if patternIdx >= 1 then
|
||||
if patternIdx >= 1 then
|
||||
let runLength := runLengths.get! (getIdx (patternIdx - 1) (wordIdx - 1)) + 1
|
||||
runLengths := runLengths.set! (getIdx patternIdx wordIdx) runLength
|
||||
|
||||
@@ -213,7 +213,7 @@ private def fuzzyMatchCore (pattern word : String) (patternRoles wordRoles : Arr
|
||||
/- Consecutive character match. -/
|
||||
if let some bonus := consecutive then
|
||||
/- consecutive run bonus -/
|
||||
score := score + bonus
|
||||
score := score + bonus
|
||||
return score
|
||||
|
||||
/-- Match the given pattern with the given word using a fuzzy matching
|
||||
|
||||
@@ -32,7 +32,7 @@ private def numBucketsForCapacity (capacity : Nat) : Nat :=
|
||||
def mkHashMapImp {α : Type u} {β : Type v} (capacity := 8) : HashMapImp α β :=
|
||||
{ size := 0
|
||||
buckets :=
|
||||
⟨mkArray (numBucketsForCapacity capacity).nextPowerOfTwo AssocList.nil,
|
||||
⟨Array.replicate (numBucketsForCapacity capacity).nextPowerOfTwo AssocList.nil,
|
||||
by simp; apply Nat.isPowerOfTwo_nextPowerOfTwo⟩ }
|
||||
|
||||
namespace HashMapImp
|
||||
@@ -101,7 +101,7 @@ decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
def expand [Hashable α] (size : Nat) (buckets : HashMapBucket α β) : HashMapImp α β :=
|
||||
let bucketsNew : HashMapBucket α β := ⟨
|
||||
mkArray (buckets.val.size * 2) AssocList.nil,
|
||||
Array.replicate (buckets.val.size * 2) AssocList.nil,
|
||||
by simp; apply Nat.mul2_isPowerOfTwo_of_isPowerOfTwo buckets.property
|
||||
⟩
|
||||
{ size := size,
|
||||
|
||||
@@ -28,7 +28,7 @@ structure HashSetImp (α : Type u) where
|
||||
def mkHashSetImp {α : Type u} (capacity := 8) : HashSetImp α :=
|
||||
{ size := 0
|
||||
buckets :=
|
||||
⟨mkArray ((capacity * 4) / 3).nextPowerOfTwo [],
|
||||
⟨Array.replicate ((capacity * 4) / 3).nextPowerOfTwo [],
|
||||
by simp; apply Nat.isPowerOfTwo_nextPowerOfTwo⟩ }
|
||||
|
||||
namespace HashSetImp
|
||||
@@ -92,7 +92,7 @@ decreasing_by simp_wf; decreasing_trivial_pre_omega
|
||||
|
||||
def expand [Hashable α] (size : Nat) (buckets : HashSetBucket α) : HashSetImp α :=
|
||||
let bucketsNew : HashSetBucket α := ⟨
|
||||
mkArray (buckets.val.size * 2) [],
|
||||
Array.replicate (buckets.val.size * 2) [],
|
||||
by simp; apply Nat.mul2_isPowerOfTwo_of_isPowerOfTwo buckets.property
|
||||
⟩
|
||||
{ size := size,
|
||||
|
||||
@@ -39,7 +39,7 @@ abbrev maxDepth : USize := 7
|
||||
abbrev maxCollisions : Nat := 4
|
||||
|
||||
def mkEmptyEntriesArray {α β} : Array (Entry α β (Node α β)) :=
|
||||
(Array.mkArray PersistentHashMap.branching.toNat PersistentHashMap.Entry.null)
|
||||
(Array.replicate PersistentHashMap.branching.toNat PersistentHashMap.Entry.null)
|
||||
|
||||
end PersistentHashMap
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ declare_config_elab elabBVDecideConfig Lean.Elab.Tactic.BVDecide.Frontend.BVDeci
|
||||
builtin_initialize bvNormalizeExt : Meta.SimpExtension ←
|
||||
Meta.registerSimpAttr `bv_normalize "simp theorems used by bv_normalize"
|
||||
|
||||
builtin_initialize intToBitVecExt : Meta.SimpExtension ←
|
||||
Meta.registerSimpAttr `int_toBitVec "simp theorems used to convert UIntX/IntX statements into BitVec ones"
|
||||
|
||||
/-- Builtin `bv_normalize` simprocs. -/
|
||||
builtin_initialize builtinBVNormalizeSimprocsRef : IO.Ref Meta.Simp.Simprocs ← IO.mkRef {}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ def passPipeline : PreProcessM (List Pass) := do
|
||||
|
||||
def bvNormalize (g : MVarId) (cfg : BVDecideConfig) : MetaM (Option MVarId) := do
|
||||
withTraceNode `bv (fun _ => return "Preprocessing goal") do
|
||||
(go g).run cfg
|
||||
(go g).run cfg g
|
||||
where
|
||||
go (g : MVarId) : PreProcessM (Option MVarId) := do
|
||||
let some g ← g.falseOrByContra | return none
|
||||
|
||||
@@ -19,6 +19,11 @@ namespace Frontend.Normalize
|
||||
|
||||
open Lean.Meta
|
||||
|
||||
structure AndFlattenState where
|
||||
hypsToDelete : Array FVarId := #[]
|
||||
hypsToAdd : Array Hypothesis := #[]
|
||||
cache : Std.HashSet Expr := {}
|
||||
|
||||
/--
|
||||
Flatten out ands. That is look for hypotheses of the form `h : (x && y) = true` and replace them
|
||||
with `h.left : x = true` and `h.right : y = true`. This can enable more fine grained substitutions
|
||||
@@ -27,59 +32,67 @@ in embedded constraint substitution.
|
||||
partial def andFlatteningPass : Pass where
|
||||
name := `andFlattening
|
||||
run' goal := do
|
||||
let (_, { hypsToDelete, hypsToAdd, .. }) ← processGoal goal |>.run {}
|
||||
if hypsToAdd.isEmpty then
|
||||
return goal
|
||||
else
|
||||
let (_, goal) ← goal.assertHypotheses hypsToAdd
|
||||
-- Given that we collected the hypotheses in the correct order above the invariant is given
|
||||
let goal ← goal.tryClearMany hypsToDelete
|
||||
return goal
|
||||
where
|
||||
processGoal (goal : MVarId) : StateRefT AndFlattenState MetaM Unit := do
|
||||
goal.withContext do
|
||||
let hyps ← goal.getNondepPropHyps
|
||||
let mut newHyps := #[]
|
||||
let mut oldHyps := #[]
|
||||
for fvar in hyps do
|
||||
let hyp : Hypothesis := {
|
||||
userName := (← fvar.getDecl).userName
|
||||
type := ← fvar.getType
|
||||
value := mkFVar fvar
|
||||
}
|
||||
let sizeBefore := newHyps.size
|
||||
newHyps ← splitAnds hyp newHyps
|
||||
if newHyps.size > sizeBefore then
|
||||
oldHyps := oldHyps.push fvar
|
||||
if newHyps.size == 0 then
|
||||
return goal
|
||||
else
|
||||
let (_, goal) ← goal.assertHypotheses newHyps
|
||||
-- Given that we collected the hypotheses in the correct order above the invariant is given
|
||||
let goal ← goal.tryClearMany oldHyps
|
||||
return goal
|
||||
where
|
||||
splitAnds (hyp : Hypothesis) (hyps : Array Hypothesis) (first : Bool := true) :
|
||||
MetaM (Array Hypothesis) := do
|
||||
match ← trySplit hyp with
|
||||
| some (left, right) =>
|
||||
let hyps ← splitAnds left hyps false
|
||||
splitAnds right hyps false
|
||||
| none =>
|
||||
if first then
|
||||
return hyps
|
||||
else
|
||||
return hyps.push hyp
|
||||
hyps.forM processFVar
|
||||
|
||||
trySplit (hyp : Hypothesis) : MetaM (Option (Hypothesis × Hypothesis)) := do
|
||||
processFVar (fvar : FVarId) : StateRefT AndFlattenState MetaM Unit := do
|
||||
let type ← fvar.getType
|
||||
if (← get).cache.contains type then
|
||||
modify (fun s => { s with hypsToDelete := s.hypsToDelete.push fvar })
|
||||
else
|
||||
let hyp := {
|
||||
userName := (← fvar.getDecl).userName
|
||||
type := type
|
||||
value := mkFVar fvar
|
||||
}
|
||||
let some (lhs, rhs) ← trySplit hyp | return ()
|
||||
modify (fun s => { s with hypsToDelete := s.hypsToDelete.push fvar })
|
||||
splitAnds [lhs, rhs]
|
||||
|
||||
splitAnds (worklist : List Hypothesis) : StateRefT AndFlattenState MetaM Unit := do
|
||||
match worklist with
|
||||
| [] => return ()
|
||||
| hyp :: worklist =>
|
||||
match ← trySplit hyp with
|
||||
| some (left, right) => splitAnds <| left :: right :: worklist
|
||||
| none =>
|
||||
modify (fun s => { s with hypsToAdd := s.hypsToAdd.push hyp })
|
||||
splitAnds worklist
|
||||
|
||||
trySplit (hyp : Hypothesis) :
|
||||
StateRefT AndFlattenState MetaM (Option (Hypothesis × Hypothesis)) := do
|
||||
let typ := hyp.type
|
||||
let_expr Eq α eqLhs eqRhs := typ | return none
|
||||
let_expr Bool.and lhs rhs := eqLhs | return none
|
||||
let_expr Bool.true := eqRhs | return none
|
||||
let_expr Bool := α | return none
|
||||
let mkEqTrue (lhs : Expr) : Expr :=
|
||||
mkApp3 (mkConst ``Eq [1]) (mkConst ``Bool) lhs (mkConst ``Bool.true)
|
||||
let leftHyp : Hypothesis := {
|
||||
userName := hyp.userName,
|
||||
type := mkEqTrue lhs,
|
||||
value := mkApp3 (mkConst ``Std.Tactic.BVDecide.Normalize.Bool.and_left) lhs rhs hyp.value
|
||||
}
|
||||
let rightHyp : Hypothesis := {
|
||||
userName := hyp.userName,
|
||||
type := mkEqTrue rhs,
|
||||
value := mkApp3 (mkConst ``Std.Tactic.BVDecide.Normalize.Bool.and_right) lhs rhs hyp.value
|
||||
}
|
||||
return some (leftHyp, rightHyp)
|
||||
if (← get).cache.contains typ then
|
||||
return none
|
||||
else
|
||||
modify (fun s => { s with cache := s.cache.insert typ })
|
||||
let_expr Eq _ eqLhs eqRhs := typ | return none
|
||||
let_expr Bool.and lhs rhs := eqLhs | return none
|
||||
let_expr Bool.true := eqRhs | return none
|
||||
let mkEqTrue (lhs : Expr) : Expr :=
|
||||
mkApp3 (mkConst ``Eq [1]) (mkConst ``Bool) lhs (mkConst ``Bool.true)
|
||||
let leftHyp : Hypothesis := {
|
||||
userName := hyp.userName,
|
||||
type := mkEqTrue lhs,
|
||||
value := mkApp3 (mkConst ``Std.Tactic.BVDecide.Normalize.Bool.and_left) lhs rhs hyp.value
|
||||
}
|
||||
let rightHyp : Hypothesis := {
|
||||
userName := hyp.userName,
|
||||
type := mkEqTrue rhs,
|
||||
value := mkApp3 (mkConst ``Std.Tactic.BVDecide.Normalize.Bool.and_right) lhs rhs hyp.value
|
||||
}
|
||||
return some (leftHyp, rightHyp)
|
||||
|
||||
|
||||
end Frontend.Normalize
|
||||
|
||||
@@ -16,14 +16,33 @@ namespace Frontend.Normalize
|
||||
|
||||
open Lean.Meta
|
||||
|
||||
abbrev PreProcessM : Type → Type := ReaderT BVDecideConfig MetaM
|
||||
structure PreProcessState where
|
||||
/--
|
||||
Contains `FVarId` that we already know are in `bv_normalize` simp normal form and thus don't
|
||||
need to be processed again when we visit the next time.
|
||||
-/
|
||||
rewriteCache : Std.HashSet FVarId := {}
|
||||
|
||||
abbrev PreProcessM : Type → Type := ReaderT BVDecideConfig <| StateRefT PreProcessState MetaM
|
||||
|
||||
namespace PreProcessM
|
||||
|
||||
def getConfig : PreProcessM BVDecideConfig := read
|
||||
|
||||
def run (cfg : BVDecideConfig) (x : PreProcessM α) : MetaM α :=
|
||||
ReaderT.run x cfg
|
||||
@[inline]
|
||||
def checkRewritten (fvar : FVarId) : PreProcessM Bool := do
|
||||
let val := (← get).rewriteCache.contains fvar
|
||||
trace[Meta.Tactic.bv] m!"{mkFVar fvar} was already rewritten? {val}"
|
||||
return val
|
||||
|
||||
@[inline]
|
||||
def rewriteFinished (fvar : FVarId) : PreProcessM Unit := do
|
||||
trace[Meta.Tactic.bv] m!"Adding {mkFVar fvar} to the rewritten set"
|
||||
modify (fun s => { s with rewriteCache := s.rewriteCache.insert fvar })
|
||||
|
||||
def run (cfg : BVDecideConfig) (goal : MVarId) (x : PreProcessM α) : MetaM α := do
|
||||
let hyps ← goal.getNondepPropHyps
|
||||
ReaderT.run x cfg |>.run' { rewriteCache := Std.HashSet.empty hyps.size }
|
||||
|
||||
end PreProcessM
|
||||
|
||||
|
||||
@@ -33,26 +33,26 @@ def embeddedConstraintPass : Pass where
|
||||
let mut duplicates : Array FVarId := #[]
|
||||
for hyp in hyps do
|
||||
let typ ← hyp.getType
|
||||
let_expr Eq α lhs rhs := typ | continue
|
||||
let_expr Eq _ lhs rhs := typ | continue
|
||||
let_expr Bool.true := rhs | continue
|
||||
let_expr Bool := α | continue
|
||||
if seen.contains lhs then
|
||||
-- collect and later remove duplicates on the fly
|
||||
duplicates := duplicates.push hyp
|
||||
else
|
||||
seen := seen.insert lhs
|
||||
let localDecl ← hyp.getDecl
|
||||
let proof := localDecl.toExpr
|
||||
let proof := localDecl.toExpr
|
||||
relevantHyps ← relevantHyps.addTheorem (.fvar hyp) proof
|
||||
|
||||
let goal ← goal.tryClearMany duplicates
|
||||
let cfg ← PreProcessM.getConfig
|
||||
|
||||
if relevantHyps.isEmpty then
|
||||
return goal
|
||||
|
||||
let cfg ← PreProcessM.getConfig
|
||||
let simpCtx ← Simp.mkContext
|
||||
(config := { failIfUnchanged := false, maxSteps := cfg.maxSteps })
|
||||
(simpTheorems := relevantHyps)
|
||||
(congrTheorems := (← getSimpCongrTheorems))
|
||||
|
||||
let ⟨result?, _⟩ ← simpGoal goal (ctx := simpCtx) (fvarIdsToSimp := ← goal.getNondepPropHyps)
|
||||
let some (_, newGoal) := result? | return none
|
||||
return newGoal
|
||||
|
||||
@@ -35,13 +35,27 @@ def rewriteRulesPass : Pass where
|
||||
(simpTheorems := #[bvThms, sevalThms])
|
||||
(congrTheorems := (← getSimpCongrTheorems))
|
||||
|
||||
let hyps ← goal.getNondepPropHyps
|
||||
let ⟨result?, _⟩ ← simpGoal goal
|
||||
(ctx := simpCtx)
|
||||
(simprocs := #[bvSimprocs, sevalSimprocs])
|
||||
(fvarIdsToSimp := hyps)
|
||||
let some (_, newGoal) := result? | return none
|
||||
return newGoal
|
||||
let hyps ← getHyps goal
|
||||
if hyps.isEmpty then
|
||||
return goal
|
||||
else
|
||||
let ⟨result?, _⟩ ← simpGoal goal
|
||||
(ctx := simpCtx)
|
||||
(simprocs := #[bvSimprocs, sevalSimprocs])
|
||||
(fvarIdsToSimp := hyps)
|
||||
|
||||
let some (_, newGoal) := result? | return none
|
||||
newGoal.withContext do
|
||||
(← newGoal.getNondepPropHyps).forM PreProcessM.rewriteFinished
|
||||
return newGoal
|
||||
where
|
||||
getHyps (goal : MVarId) : PreProcessM (Array FVarId) := do
|
||||
goal.withContext do
|
||||
let mut hyps ← goal.getNondepPropHyps
|
||||
let filter hyp := do
|
||||
return !(← PreProcessM.checkRewritten hyp)
|
||||
hyps.filterM filter
|
||||
|
||||
|
||||
end Frontend.Normalize
|
||||
end Lean.Elab.Tactic.BVDecide
|
||||
|
||||
@@ -37,7 +37,7 @@ def elabGrindPattern : CommandElab := fun stx => do
|
||||
def grind (mvarId : MVarId) (config : Grind.Config) (mainDeclName : Name) (fallback : Grind.Fallback) : MetaM Unit := do
|
||||
let goals ← Grind.main mvarId config mainDeclName fallback
|
||||
unless goals.isEmpty do
|
||||
throwError "`grind` failed\n{← Grind.goalsToMessageData goals}"
|
||||
throwError "`grind` failed\n{← Grind.goalsToMessageData goals config}"
|
||||
|
||||
private def elabFallback (fallback? : Option Term) : TermElabM (Grind.GoalM Unit) := do
|
||||
let some fallback := fallback? | return (pure ())
|
||||
|
||||
@@ -735,7 +735,7 @@ private def setImportedEntries (env : Environment) (mods : Array ModuleData) (st
|
||||
let extDescrs ← persistentEnvExtensionsRef.get
|
||||
/- For extensions starting at `startingAt`, ensure their `importedEntries` array have size `mods.size`. -/
|
||||
for extDescr in extDescrs[startingAt:] do
|
||||
env := extDescr.toEnvExtension.modifyState env fun s => { s with importedEntries := mkArray mods.size #[] }
|
||||
env := extDescr.toEnvExtension.modifyState env fun s => { s with importedEntries := Array.replicate mods.size #[] }
|
||||
/- For each module `mod`, and `mod.entries`, if the extension name is one of the extensions after `startingAt`, set `entries` -/
|
||||
let extNameIdx ← mkExtNameMap startingAt
|
||||
for h : modIdx in [:mods.size] do
|
||||
|
||||
@@ -1127,7 +1127,7 @@ private def getAppArgsAux : Expr → Array Expr → Nat → Array Expr
|
||||
@[inline] def getAppArgs (e : Expr) : Array Expr :=
|
||||
let dummy := mkSort levelZero
|
||||
let nargs := e.getAppNumArgs
|
||||
getAppArgsAux e (mkArray nargs dummy) (nargs-1)
|
||||
getAppArgsAux e (Array.replicate nargs dummy) (nargs-1)
|
||||
|
||||
private def getBoundedAppArgsAux : Expr → Array Expr → Nat → Array Expr
|
||||
| app f a, as, i + 1 => getBoundedAppArgsAux f (as.set! i a) i
|
||||
@@ -1142,7 +1142,7 @@ where `k` is minimal such that the size of this array is at most `maxArgs`.
|
||||
@[inline] def getBoundedAppArgs (maxArgs : Nat) (e : Expr) : Array Expr :=
|
||||
let dummy := mkSort levelZero
|
||||
let nargs := min maxArgs e.getAppNumArgs
|
||||
getBoundedAppArgsAux e (mkArray nargs dummy) nargs
|
||||
getBoundedAppArgsAux e (Array.replicate nargs dummy) nargs
|
||||
|
||||
private def getAppRevArgsAux : Expr → Array Expr → Array Expr
|
||||
| app f a, as => getAppRevArgsAux f (as.push a)
|
||||
@@ -1160,7 +1160,7 @@ private def getAppRevArgsAux : Expr → Array Expr → Array Expr
|
||||
@[inline] def withApp (e : Expr) (k : Expr → Array Expr → α) : α :=
|
||||
let dummy := mkSort levelZero
|
||||
let nargs := e.getAppNumArgs
|
||||
withAppAux k e (mkArray nargs dummy) (nargs-1)
|
||||
withAppAux k e (Array.replicate nargs dummy) (nargs-1)
|
||||
|
||||
/-- Return the function (name) and arguments of an application. -/
|
||||
def getAppFnArgs (e : Expr) : Name × Array Expr :=
|
||||
@@ -1173,7 +1173,7 @@ The resulting array has size `n` even if `f.getAppNumArgs < n`.
|
||||
-/
|
||||
@[inline] def getAppArgsN (e : Expr) (n : Nat) : Array Expr :=
|
||||
let dummy := mkSort levelZero
|
||||
loop n e (mkArray n dummy)
|
||||
loop n e (Array.replicate n dummy)
|
||||
where
|
||||
loop : Nat → Expr → Array Expr → Array Expr
|
||||
| 0, _, as => as
|
||||
|
||||
@@ -196,7 +196,7 @@ def mkSizeOfSpecLemmaInstance (ctorApp : Expr) : MetaM Expr :=
|
||||
let lemmaInfo ← getConstInfo lemmaName
|
||||
let lemmaArity ← forallTelescopeReducing lemmaInfo.type fun xs _ => return xs.size
|
||||
let lemmaArgMask := ctorParams.toArray.map some
|
||||
let lemmaArgMask := lemmaArgMask ++ mkArray (lemmaArity - ctorInfo.numParams - ctorInfo.numFields) (none (α := Expr))
|
||||
let lemmaArgMask := lemmaArgMask ++ Array.replicate (lemmaArity - ctorInfo.numParams - ctorInfo.numFields) (none (α := Expr))
|
||||
let lemmaArgMask := lemmaArgMask ++ ctorFields.toArray.map some
|
||||
mkAppOptM lemmaName lemmaArgMask
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import Lean.Meta.FunInfo
|
||||
import Lean.Util.FVarSubset
|
||||
import Lean.Util.PtrSet
|
||||
import Lean.Util.FVarSubset
|
||||
import Lean.Meta.Tactic.Grind.Types
|
||||
|
||||
namespace Lean.Meta.Grind
|
||||
namespace Canon
|
||||
@@ -40,42 +41,37 @@ additions will still use structurally different (and definitionally different) i
|
||||
Furthermore, `grind` will not be able to infer that `HEq (a + a) (b + b)` even if we add the assumptions `n = m` and `HEq a b`.
|
||||
-/
|
||||
|
||||
structure State where
|
||||
argMap : PHashMap (Expr × Nat) (List Expr) := {}
|
||||
canon : PHashMap Expr Expr := {}
|
||||
proofCanon : PHashMap Expr Expr := {}
|
||||
deriving Inhabited
|
||||
@[inline] private def get' : GoalM State :=
|
||||
return (← get).canon
|
||||
|
||||
inductive CanonElemKind where
|
||||
| /--
|
||||
Type class instances are canonicalized using `TransparencyMode.instances`.
|
||||
-/
|
||||
instance
|
||||
| /--
|
||||
Types and Type formers are canonicalized using `TransparencyMode.default`.
|
||||
Remark: propositions are just visited. We do not invoke `canonElemCore` for them.
|
||||
-/
|
||||
type
|
||||
| /--
|
||||
Implicit arguments that are not types, type formers, or instances, are canonicalized
|
||||
using `TransparencyMode.reducible`
|
||||
-/
|
||||
implicit
|
||||
deriving BEq
|
||||
@[inline] private def modify' (f : State → State) : GoalM Unit :=
|
||||
modify fun s => { s with canon := f s.canon }
|
||||
|
||||
def CanonElemKind.explain : CanonElemKind → String
|
||||
| .instance => "type class instances"
|
||||
| .type => "types (or type formers)"
|
||||
| .implicit => "implicit arguments (which are not type class instances or types)"
|
||||
/--
|
||||
Helper function for `canonElemCore`. It tries `isDefEq a b` with default transparency, but using
|
||||
at most `canonHeartbeats` heartbeats. It reports an issue if the threshold is reached.
|
||||
Remark: `parent` is use only to report an issue
|
||||
-/
|
||||
private def isDefEqBounded (a b : Expr) (parent : Expr) : GoalM Bool := do
|
||||
withCurrHeartbeats do
|
||||
let config ← getConfig
|
||||
tryCatchRuntimeEx
|
||||
(withTheReader Core.Context (fun ctx => { ctx with maxHeartbeats := config.canonHeartbeats }) do
|
||||
withDefault <| isDefEq a b)
|
||||
fun ex => do
|
||||
if ex.isRuntime then
|
||||
let curr := (← getConfig).canonHeartbeats
|
||||
reportIssue m!"failed to show that{indentExpr a}\nis definitionally equal to{indentExpr b}\nwhile canonicalizing{indentExpr parent}\nusing `{curr}*1000` heartbeats, `(canonHeartbeats := {curr})`"
|
||||
return false
|
||||
else
|
||||
throw ex
|
||||
|
||||
/--
|
||||
Helper function for canonicalizing `e` occurring as the `i`th argument of an `f`-application.
|
||||
|
||||
Thus, if diagnostics are enabled, we also re-check them using `TransparencyMode.default`. If the result is different
|
||||
we report to the user.
|
||||
If `useIsDefEqBounded` is `true`, we try `isDefEqBounded` before returning false
|
||||
-/
|
||||
def canonElemCore (f : Expr) (i : Nat) (e : Expr) (kind : CanonElemKind) : StateT State MetaM Expr := do
|
||||
let s ← get
|
||||
def canonElemCore (parent : Expr) (f : Expr) (i : Nat) (e : Expr) (useIsDefEqBounded : Bool) : GoalM Expr := do
|
||||
let s ← get'
|
||||
if let some c := s.canon.find? e then
|
||||
return c
|
||||
let key := (f, i)
|
||||
@@ -87,20 +83,21 @@ def canonElemCore (f : Expr) (i : Nat) (e : Expr) (kind : CanonElemKind) : State
|
||||
-- However, we don't revert previously canonicalized elements in the `grind` tactic.
|
||||
-- Moreover, we store the canonicalizer state in the `Goal` because we case-split
|
||||
-- and different locals are added in different branches.
|
||||
modify fun s => { s with canon := s.canon.insert e c }
|
||||
trace[grind.debug.canon] "found {e} ===> {c}"
|
||||
modify' fun s => { s with canon := s.canon.insert e c }
|
||||
trace[grind.debugn.canon] "found {e} ===> {c}"
|
||||
return c
|
||||
if kind != .type then
|
||||
if (← isTracingEnabledFor `grind.issues <&&> (withDefault <| isDefEq e c)) then
|
||||
-- TODO: consider storing this information in some structure that can be browsed later.
|
||||
trace[grind.issues] "the following {kind.explain} are definitionally equal with `default` transparency but not with a more restrictive transparency{indentExpr e}\nand{indentExpr c}"
|
||||
if useIsDefEqBounded then
|
||||
if (← isDefEqBounded e c parent) then
|
||||
modify' fun s => { s with canon := s.canon.insert e c }
|
||||
trace[grind.debugn.canon] "found using `isDefEqBounded`: {e} ===> {c}"
|
||||
return c
|
||||
trace[grind.debug.canon] "({f}, {i}) ↦ {e}"
|
||||
modify fun s => { s with canon := s.canon.insert e e, argMap := s.argMap.insert key (e::cs) }
|
||||
modify' fun s => { s with canon := s.canon.insert e e, argMap := s.argMap.insert key (e::cs) }
|
||||
return e
|
||||
|
||||
abbrev canonType (f : Expr) (i : Nat) (e : Expr) := withDefault <| canonElemCore f i e .type
|
||||
abbrev canonInst (f : Expr) (i : Nat) (e : Expr) := withReducibleAndInstances <| canonElemCore f i e .instance
|
||||
abbrev canonImplicit (f : Expr) (i : Nat) (e : Expr) := withReducible <| canonElemCore f i e .implicit
|
||||
abbrev canonType (parent f : Expr) (i : Nat) (e : Expr) := withDefault <| canonElemCore parent f i e (useIsDefEqBounded := false)
|
||||
abbrev canonInst (parent f : Expr) (i : Nat) (e : Expr) := withReducibleAndInstances <| canonElemCore parent f i e (useIsDefEqBounded := true)
|
||||
abbrev canonImplicit (parent f : Expr) (i : Nat) (e : Expr) := withReducible <| canonElemCore parent f i e (useIsDefEqBounded := true)
|
||||
|
||||
/--
|
||||
Return type for the `shouldCanon` function.
|
||||
@@ -148,10 +145,10 @@ def shouldCanon (pinfos : Array ParamInfo) (i : Nat) (arg : Expr) : MetaM Should
|
||||
else
|
||||
return .visit
|
||||
|
||||
unsafe def canonImpl (e : Expr) : StateT State MetaM Expr := do
|
||||
unsafe def canonImpl (e : Expr) : GoalM Expr := do
|
||||
visit e |>.run' mkPtrMap
|
||||
where
|
||||
visit (e : Expr) : StateRefT (PtrMap Expr Expr) (StateT State MetaM) Expr := do
|
||||
visit (e : Expr) : StateRefT (PtrMap Expr Expr) GoalM Expr := do
|
||||
unless e.isApp || e.isForall do return e
|
||||
-- Check whether it is cached
|
||||
if let some r := (← get).find? e then
|
||||
@@ -161,11 +158,11 @@ where
|
||||
if f.isConstOf ``Lean.Grind.nestedProof && args.size == 2 then
|
||||
let prop := args[0]!
|
||||
let prop' ← visit prop
|
||||
if let some r := (← getThe State).proofCanon.find? prop' then
|
||||
if let some r := (← get').proofCanon.find? prop' then
|
||||
pure r
|
||||
else
|
||||
let e' := if ptrEq prop prop' then e else mkAppN f (args.set! 0 prop')
|
||||
modifyThe State fun s => { s with proofCanon := s.proofCanon.insert prop' e' }
|
||||
modify' fun s => { s with proofCanon := s.proofCanon.insert prop' e' }
|
||||
pure e'
|
||||
else
|
||||
let pinfos := (← getFunInfo f).paramInfo
|
||||
@@ -175,9 +172,9 @@ where
|
||||
let arg := args[i]
|
||||
trace[grind.debug.canon] "[{repr (← shouldCanon pinfos i arg)}]: {arg} : {← inferType arg}"
|
||||
let arg' ← match (← shouldCanon pinfos i arg) with
|
||||
| .canonType => canonType f i arg
|
||||
| .canonInst => canonInst f i arg
|
||||
| .canonImplicit => canonImplicit f i (← visit arg)
|
||||
| .canonType => canonType e f i arg
|
||||
| .canonInst => canonInst e f i arg
|
||||
| .canonImplicit => canonImplicit e f i (← visit arg)
|
||||
| .visit => visit arg
|
||||
unless ptrEq arg arg' do
|
||||
args := args.set i arg'
|
||||
@@ -193,11 +190,11 @@ where
|
||||
modify fun s => s.insert e e'
|
||||
return e'
|
||||
|
||||
/-- Canonicalizes nested types, type formers, and instances in `e`. -/
|
||||
def canon (e : Expr) : StateT State MetaM Expr := do
|
||||
trace[grind.debug.canon] "{e}"
|
||||
unsafe canonImpl e
|
||||
|
||||
end Canon
|
||||
|
||||
/-- Canonicalizes nested types, type formers, and instances in `e`. -/
|
||||
def canon (e : Expr) : GoalM Expr := do
|
||||
trace[grind.debug.canon] "{e}"
|
||||
unsafe Canon.canonImpl e
|
||||
|
||||
end Lean.Meta.Grind
|
||||
|
||||
@@ -20,7 +20,7 @@ private partial def propagateInjEqs (eqs : Expr) (proof : Expr) : GoalM Unit :=
|
||||
| HEq _ lhs _ rhs =>
|
||||
pushHEq (← shareCommon lhs) (← shareCommon rhs) proof
|
||||
| _ =>
|
||||
trace_goal[grind.issues] "unexpected injectivity theorem result type{indentExpr eqs}"
|
||||
reportIssue m!"unexpected injectivity theorem result type{indentExpr eqs}"
|
||||
return ()
|
||||
|
||||
/--
|
||||
|
||||
@@ -129,6 +129,16 @@ private partial def matchArgs? (c : Choice) (p : Expr) (e : Expr) : OptionT Goal
|
||||
let c ← matchArg? c pArg eArg
|
||||
matchArgs? c p.appFn! e.appFn!
|
||||
|
||||
/-- Similar to `matchArgs?` but if `p` has fewer arguments than `e`, we match `p` with a prefix of `e`. -/
|
||||
private partial def matchArgsPrefix? (c : Choice) (p : Expr) (e : Expr) : OptionT GoalM Choice := do
|
||||
let pn := p.getAppNumArgs
|
||||
let en := e.getAppNumArgs
|
||||
guard (pn <= en)
|
||||
if pn == en then
|
||||
matchArgs? c p e
|
||||
else
|
||||
matchArgs? c p (e.getAppPrefix pn)
|
||||
|
||||
/--
|
||||
Matches pattern `p` with term `e` with respect to choice `c`.
|
||||
We traverse the equivalence class of `e` looking for applications compatible with `p`.
|
||||
@@ -194,7 +204,7 @@ private def processContinue (c : Choice) (p : Expr) : M Unit := do
|
||||
let n ← getENode app
|
||||
if n.generation < maxGeneration
|
||||
&& (n.heqProofs || n.isCongrRoot) then
|
||||
if let some c ← matchArgs? c p app |>.run then
|
||||
if let some c ← matchArgsPrefix? c p app |>.run then
|
||||
let gen := n.generation
|
||||
let c := { c with gen := Nat.max gen c.gen }
|
||||
modify fun s => { s with choiceStack := c :: s.choiceStack }
|
||||
@@ -240,7 +250,7 @@ private partial def instantiateTheorem (c : Choice) : M Unit := withDefault do w
|
||||
assert! c.assignment.size == numParams
|
||||
let (mvars, bis, _) ← forallMetaBoundedTelescope (← inferType proof) numParams
|
||||
if mvars.size != thm.numParams then
|
||||
trace_goal[grind.issues] "unexpected number of parameters at {← thm.origin.pp}"
|
||||
reportIssue m!"unexpected number of parameters at {← thm.origin.pp}"
|
||||
return ()
|
||||
-- Apply assignment
|
||||
for h : i in [:mvars.size] do
|
||||
@@ -250,14 +260,14 @@ private partial def instantiateTheorem (c : Choice) : M Unit := withDefault do w
|
||||
let mvarIdType ← mvarId.getType
|
||||
let vType ← inferType v
|
||||
unless (← isDefEq mvarIdType vType <&&> mvarId.checkedAssign v) do
|
||||
trace_goal[grind.issues] "type error constructing proof for {← thm.origin.pp}\nwhen assigning metavariable {mvars[i]} with {indentExpr v}\n{← mkHasTypeButIsExpectedMsg vType mvarIdType}"
|
||||
reportIssue m!"type error constructing proof for {← thm.origin.pp}\nwhen assigning metavariable {mvars[i]} with {indentExpr v}\n{← mkHasTypeButIsExpectedMsg vType mvarIdType}"
|
||||
return ()
|
||||
-- Synthesize instances
|
||||
for mvar in mvars, bi in bis do
|
||||
if bi.isInstImplicit && !(← mvar.mvarId!.isAssigned) then
|
||||
let type ← inferType mvar
|
||||
unless (← synthesizeInstance mvar type) do
|
||||
trace_goal[grind.issues] "failed to synthesize instance when instantiating {← thm.origin.pp}{indentExpr type}"
|
||||
reportIssue m!"failed to synthesize instance when instantiating {← thm.origin.pp}{indentExpr type}"
|
||||
return ()
|
||||
let proof := mkAppN proof mvars
|
||||
if (← mvars.allM (·.mvarId!.isAssigned)) then
|
||||
@@ -265,7 +275,7 @@ private partial def instantiateTheorem (c : Choice) : M Unit := withDefault do w
|
||||
else
|
||||
let mvars ← mvars.filterM fun mvar => return !(← mvar.mvarId!.isAssigned)
|
||||
if let some mvarBad ← mvars.findM? fun mvar => return !(← isProof mvar) then
|
||||
trace_goal[grind.issues] "failed to instantiate {← thm.origin.pp}, failed to instantiate non propositional argument with type{indentExpr (← inferType mvarBad)}"
|
||||
reportIssue m!"failed to instantiate {← thm.origin.pp}, failed to instantiate non propositional argument with type{indentExpr (← inferType mvarBad)}"
|
||||
let proof ← mkLambdaFVars (binderInfoForMVars := .default) mvars (← instantiateMVars proof)
|
||||
addNewInstance thm.origin proof c.gen
|
||||
where
|
||||
@@ -300,7 +310,7 @@ private def main (p : Expr) (cnstrs : List Cnstr) : M Unit := do
|
||||
if (n.heqProofs || n.isCongrRoot) &&
|
||||
(!useMT || n.mt == gmt) then
|
||||
withInitApp app do
|
||||
if let some c ← matchArgs? { cnstrs, assignment, gen := n.generation } p app |>.run then
|
||||
if let some c ← matchArgsPrefix? { cnstrs, assignment, gen := n.generation } p app |>.run then
|
||||
modify fun s => { s with choiceStack := [c] }
|
||||
processChoices
|
||||
|
||||
@@ -360,7 +370,4 @@ def ematchAndAssert : GrindTactic := fun goal => do
|
||||
return none
|
||||
assertAll goal
|
||||
|
||||
def ematchStar : GrindTactic :=
|
||||
ematchAndAssert.iterate
|
||||
|
||||
end Lean.Meta.Grind
|
||||
|
||||
@@ -269,19 +269,36 @@ private def getPatternFn? (pattern : Expr) : Option Expr :=
|
||||
|
||||
/--
|
||||
Returns a bit-mask `mask` s.t. `mask[i]` is true if the corresponding argument is
|
||||
- a type (that is not a proposition) or type former, or
|
||||
- a type (that is not a proposition) or type former (which has forward dependencies) or
|
||||
- a proof, or
|
||||
- an instance implicit argument
|
||||
|
||||
When `mask[i]`, we say the corresponding argument is a "support" argument.
|
||||
-/
|
||||
def getPatternSupportMask (f : Expr) (numArgs : Nat) : MetaM (Array Bool) := do
|
||||
let pinfos := (← getFunInfoNArgs f numArgs).paramInfo
|
||||
forallBoundedTelescope (← inferType f) numArgs fun xs _ => do
|
||||
xs.mapM fun x => do
|
||||
xs.mapIdxM fun idx x => do
|
||||
if (← isProp x) then
|
||||
return false
|
||||
else if (← isTypeFormer x <||> isProof x) then
|
||||
else if (← isProof x) then
|
||||
return true
|
||||
else if (← isTypeFormer x) then
|
||||
if h : idx < pinfos.size then
|
||||
/-
|
||||
We originally wanted to ignore types and type formers in `grind` and treat them as supporting elements.
|
||||
Thus, we would always return `true`. However, we changed our heuristic because of the following example:
|
||||
```
|
||||
example {α} (f : α → Type) (a : α) (h : ∀ x, Nonempty (f x)) : Nonempty (f a) := by
|
||||
grind
|
||||
```
|
||||
In this example, we are reasoning about types. Therefore, we adjusted the heuristic as follows:
|
||||
a type or type former is considered a supporting element only if it has forward dependencies.
|
||||
Note that this is not the case for `Nonempty`.
|
||||
-/
|
||||
return pinfos[idx].hasFwdDeps
|
||||
else
|
||||
return true
|
||||
else
|
||||
return (← x.fvarId!.getDecl).binderInfo matches .instImplicit
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ private def addLocalEMatchTheorems (e : Expr) : GoalM Unit := do
|
||||
if let some thm ← mkEMatchTheoremWithKind'? origin proof .default then
|
||||
activateTheorem thm gen
|
||||
if (← get).newThms.size == size then
|
||||
trace[grind.issues] "failed to create E-match local theorem for{indentExpr e}"
|
||||
reportIssue m!"failed to create E-match local theorem for{indentExpr e}"
|
||||
|
||||
def propagateForallPropDown (e : Expr) : GoalM Unit := do
|
||||
let .forallE n a b bi := e | return ()
|
||||
|
||||
@@ -11,6 +11,7 @@ import Lean.Meta.Match.MatcherInfo
|
||||
import Lean.Meta.Match.MatchEqsExt
|
||||
import Lean.Meta.Tactic.Grind.Types
|
||||
import Lean.Meta.Tactic.Grind.Util
|
||||
import Lean.Meta.Tactic.Grind.Canon
|
||||
import Lean.Meta.Tactic.Grind.Arith.Internalize
|
||||
|
||||
namespace Lean.Meta.Grind
|
||||
@@ -24,7 +25,7 @@ def addCongrTable (e : Expr) : GoalM Unit := do
|
||||
let g := e'.getAppFn
|
||||
unless isSameExpr f g do
|
||||
unless (← hasSameType f g) do
|
||||
trace_goal[grind.issues] "found congruence between{indentExpr e}\nand{indentExpr e'}\nbut functions have different types"
|
||||
reportIssue m!"found congruence between{indentExpr e}\nand{indentExpr e'}\nbut functions have different types"
|
||||
return ()
|
||||
trace_goal[grind.debug.congr] "{e} = {e'}"
|
||||
pushEqHEq e e' congrPlaceholderProof
|
||||
@@ -98,13 +99,16 @@ private def pushCastHEqs (e : Expr) : GoalM Unit := do
|
||||
| f@Eq.recOn α a motive b h v => pushHEq e v (mkApp6 (mkConst ``Grind.eqRecOn_heq f.constLevels!) α a motive b h v)
|
||||
| _ => return ()
|
||||
|
||||
private def preprocessGroundPattern (e : Expr) : GoalM Expr := do
|
||||
shareCommon (← canon (← normalizeLevels (← unfoldReducible e)))
|
||||
|
||||
mutual
|
||||
/-- Internalizes the nested ground terms in the given pattern. -/
|
||||
private partial def internalizePattern (pattern : Expr) (generation : Nat) : GoalM Expr := do
|
||||
if pattern.isBVar || isPatternDontCare pattern then
|
||||
return pattern
|
||||
else if let some e := groundPattern? pattern then
|
||||
let e ← shareCommon (← canon (← normalizeLevels (← unfoldReducible e)))
|
||||
let e ← preprocessGroundPattern e
|
||||
internalize e generation none
|
||||
return mkGroundPattern e
|
||||
else pattern.withApp fun f args => do
|
||||
@@ -168,7 +172,7 @@ partial def internalize (e : Expr) (generation : Nat) (parent? : Option Expr :=
|
||||
| .mvar ..
|
||||
| .mdata ..
|
||||
| .proj .. =>
|
||||
trace_goal[grind.issues] "unexpected term during internalization{indentExpr e}"
|
||||
reportIssue m!"unexpected kernel projection term during internalization{indentExpr e}\n`grind` uses a pre-processing step that folds them as projection applications, the pre-processor should have failed to fold this term"
|
||||
mkENodeCore e (ctor := false) (interpreted := false) (generation := generation)
|
||||
| .app .. =>
|
||||
if (← isLitValue e) then
|
||||
|
||||
@@ -15,6 +15,7 @@ import Lean.Meta.Tactic.Grind.Inv
|
||||
import Lean.Meta.Tactic.Grind.Intro
|
||||
import Lean.Meta.Tactic.Grind.EMatch
|
||||
import Lean.Meta.Tactic.Grind.Split
|
||||
import Lean.Meta.Tactic.Grind.Solve
|
||||
import Lean.Meta.Tactic.Grind.SimpUtil
|
||||
|
||||
namespace Lean.Meta.Grind
|
||||
@@ -68,17 +69,10 @@ private def initCore (mvarId : MVarId) : GrindM (List Goal) := do
|
||||
goals.forM (·.checkInvariants (expensive := true))
|
||||
return goals.filter fun goal => !goal.inconsistent
|
||||
|
||||
def all (goals : List Goal) (f : Goal → GrindM (List Goal)) : GrindM (List Goal) := do
|
||||
goals.foldlM (init := []) fun acc goal => return acc ++ (← f goal)
|
||||
|
||||
/-- A very simple strategy -/
|
||||
private def simple (goals : List Goal) : GrindM (List Goal) := do
|
||||
applyToAll (assertAll >> ematchStar >> (splitNext >> assertAll >> ematchStar).iterate) goals
|
||||
|
||||
def main (mvarId : MVarId) (config : Grind.Config) (mainDeclName : Name) (fallback : Fallback) : MetaM (List Goal) := do
|
||||
let go : GrindM (List Goal) := do
|
||||
let goals ← initCore mvarId
|
||||
let goals ← simple goals
|
||||
let goals ← solve goals
|
||||
let goals ← goals.filterMapM fun goal => do
|
||||
if goal.inconsistent then return none
|
||||
let goal ← GoalM.run' goal fallback
|
||||
|
||||
@@ -76,10 +76,16 @@ private def ppExprArray (cls : Name) (header : String) (es : Array Expr) (clsEle
|
||||
let es := es.map fun e => .trace { cls := clsElem} m!"{e}" #[]
|
||||
.trace { cls } header es
|
||||
|
||||
private def ppEqcs (goal : Goal) : MetaM (Array MessageData) := do
|
||||
private abbrev M := ReaderT Goal (StateT (Array MessageData) MetaM)
|
||||
|
||||
private def pushMsg (m : MessageData) : M Unit :=
|
||||
modify fun s => s.push m
|
||||
|
||||
private def ppEqcs : M Unit := do
|
||||
let mut trueEqc? : Option MessageData := none
|
||||
let mut falseEqc? : Option MessageData := none
|
||||
let mut otherEqcs : Array MessageData := #[]
|
||||
let goal ← read
|
||||
for eqc in goal.getEqcs do
|
||||
if Option.isSome <| eqc.find? (·.isTrue) then
|
||||
let eqc := eqc.filter fun e => !e.isTrue
|
||||
@@ -93,44 +99,68 @@ private def ppEqcs (goal : Goal) : MetaM (Array MessageData) := do
|
||||
-- We may want to add a flag to pretty print equivalence classes of nested proofs
|
||||
unless (← isProof e) do
|
||||
otherEqcs := otherEqcs.push <| .trace { cls := `eqc } (.group ("{" ++ (MessageData.joinSep (eqc.map toMessageData) ("," ++ Format.line)) ++ "}")) #[]
|
||||
let mut result := #[]
|
||||
if let some trueEqc := trueEqc? then result := result.push trueEqc
|
||||
if let some falseEqc := falseEqc? then result := result.push falseEqc
|
||||
if let some trueEqc := trueEqc? then pushMsg trueEqc
|
||||
if let some falseEqc := falseEqc? then pushMsg falseEqc
|
||||
unless otherEqcs.isEmpty do
|
||||
result := result.push <| .trace { cls := `eqc } "Equivalence classes" otherEqcs
|
||||
return result
|
||||
pushMsg <| .trace { cls := `eqc } "Equivalence classes" otherEqcs
|
||||
|
||||
private def ppEMatchTheorem (thm : EMatchTheorem) : MetaM MessageData := do
|
||||
let m := m!"{← thm.origin.pp}\n{← inferType thm.proof}\npatterns: {thm.patterns.map ppPattern}"
|
||||
let m := m!"{← thm.origin.pp}:\n{← inferType thm.proof}\npatterns: {thm.patterns.map ppPattern}"
|
||||
return .trace { cls := `thm } m #[]
|
||||
|
||||
private def ppActiveTheorems (goal : Goal) : MetaM MessageData := do
|
||||
let m ← goal.thms.toArray.mapM ppEMatchTheorem
|
||||
let m := m ++ (← goal.newThms.toArray.mapM ppEMatchTheorem)
|
||||
if m.isEmpty then
|
||||
return ""
|
||||
else
|
||||
return .trace { cls := `ematch } "E-matching" m
|
||||
private def ppActiveTheorems : M Unit := do
|
||||
let goal ← read
|
||||
let m ← goal.thms.toArray.mapM fun thm => ppEMatchTheorem thm
|
||||
let m := m ++ (← goal.newThms.toArray.mapM fun thm => ppEMatchTheorem thm)
|
||||
unless m.isEmpty do
|
||||
pushMsg <| .trace { cls := `ematch } "E-matching" m
|
||||
|
||||
def ppOffset (goal : Goal) : MetaM MessageData := do
|
||||
private def ppOffset : M Unit := do
|
||||
let goal ← read
|
||||
let s := goal.arith.offset
|
||||
let nodes := s.nodes
|
||||
if nodes.isEmpty then return ""
|
||||
if nodes.isEmpty then return ()
|
||||
let model ← Arith.Offset.mkModel goal
|
||||
let mut ms := #[]
|
||||
for (e, val) in model do
|
||||
ms := ms.push <| .trace { cls := `assign } m!"{e} := {val}" #[]
|
||||
return .trace { cls := `offset } "Assignment satisfying offset contraints" ms
|
||||
pushMsg <| .trace { cls := `offset } "Assignment satisfying offset contraints" ms
|
||||
|
||||
def goalToMessageData (goal : Goal) : MetaM MessageData := goal.mvarId.withContext do
|
||||
let mut m : Array MessageData := #[.ofGoal goal.mvarId]
|
||||
m := m.push <| ppExprArray `facts "Asserted facts" goal.facts.toArray `prop
|
||||
m := m ++ (← ppEqcs goal)
|
||||
m := m.push (← ppActiveTheorems goal)
|
||||
m := m.push (← ppOffset goal)
|
||||
addMessageContextFull <| MessageData.joinSep m.toList ""
|
||||
private def ppIssues : M Unit := do
|
||||
let issues := (← read).issues
|
||||
unless issues.isEmpty do
|
||||
pushMsg <| .trace { cls := `issues } "Issues" issues.reverse.toArray
|
||||
|
||||
def goalsToMessageData (goals : List Goal) : MetaM MessageData :=
|
||||
return MessageData.joinSep (← goals.mapM goalToMessageData) m!"\n"
|
||||
private def ppThresholds (c : Grind.Config) : M Unit := do
|
||||
let goal ← read
|
||||
let maxGen := goal.enodes.foldl (init := 0) fun g _ n => Nat.max g n.generation
|
||||
let mut msgs := #[]
|
||||
if goal.numInstances ≥ c.instances then
|
||||
msgs := msgs.push <| .trace { cls := `limit } m!"maximum number of instances generated by E-matching has been reached, threshold: `(instances := {c.instances})`" #[]
|
||||
if goal.numEmatch ≥ c.ematch then
|
||||
msgs := msgs.push <| .trace { cls := `limit } m!"maximum number of E-matching rounds has been reached, threshold: `(ematch := {c.ematch})`" #[]
|
||||
if goal.numSplits ≥ c.splits then
|
||||
msgs := msgs.push <| .trace { cls := `limit } m!"maximum number of case-splits has been reached, threshold: `(splits := {c.splits})`" #[]
|
||||
if maxGen ≥ c.gen then
|
||||
msgs := msgs.push <| .trace { cls := `limit } m!"maximum term generation has been reached, threshold: `(gen := {c.gen})`" #[]
|
||||
unless msgs.isEmpty do
|
||||
pushMsg <| .trace { cls := `limits } "Thresholds reached" msgs
|
||||
|
||||
def goalToMessageData (goal : Goal) (config : Grind.Config) : MetaM MessageData := goal.mvarId.withContext do
|
||||
let (_, m) ← go goal |>.run #[]
|
||||
let gm := MessageData.trace { cls := `grind, collapsed := false } "Diagnostics" m
|
||||
let r := m!"{.ofGoal goal.mvarId}\n{gm}"
|
||||
addMessageContextFull r
|
||||
where
|
||||
go : M Unit := do
|
||||
pushMsg <| ppExprArray `facts "Asserted facts" goal.facts.toArray `prop
|
||||
ppEqcs
|
||||
ppActiveTheorems
|
||||
ppOffset
|
||||
ppThresholds config
|
||||
ppIssues
|
||||
|
||||
def goalsToMessageData (goals : List Goal) (config : Grind.Config) : MetaM MessageData :=
|
||||
return MessageData.joinSep (← goals.mapM (goalToMessageData · config)) m!"\n"
|
||||
|
||||
end Lean.Meta.Grind
|
||||
|
||||
@@ -11,6 +11,7 @@ import Lean.Meta.Tactic.Grind.Util
|
||||
import Lean.Meta.Tactic.Grind.Types
|
||||
import Lean.Meta.Tactic.Grind.DoNotSimp
|
||||
import Lean.Meta.Tactic.Grind.MarkNestedProofs
|
||||
import Lean.Meta.Tactic.Grind.Canon
|
||||
|
||||
namespace Lean.Meta.Grind
|
||||
/-- Simplifies the given expression using the `grind` simprocs and normalization theorems. -/
|
||||
@@ -28,9 +29,9 @@ def simp (e : Expr) : GoalM Simp.Result := do
|
||||
let e ← instantiateMVars e
|
||||
let r ← simpCore e
|
||||
let e' := r.expr
|
||||
let e' ← unfoldReducible e'
|
||||
let e' ← abstractNestedProofs e'
|
||||
let e' ← markNestedProofs e'
|
||||
let e' ← unfoldReducible e'
|
||||
let e' ← eraseIrrelevantMData e'
|
||||
let e' ← foldProjs e'
|
||||
let e' ← normalizeLevels e'
|
||||
|
||||
92
src/Lean/Meta/Tactic/Grind/Solve.lean
Normal file
92
src/Lean/Meta/Tactic/Grind/Solve.lean
Normal file
@@ -0,0 +1,92 @@
|
||||
/-
|
||||
Copyright (c) 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import Lean.Meta.Tactic.Grind.Combinators
|
||||
import Lean.Meta.Tactic.Grind.Split
|
||||
import Lean.Meta.Tactic.Grind.EMatch
|
||||
|
||||
namespace Lean.Meta.Grind
|
||||
|
||||
namespace Solve
|
||||
|
||||
structure State where
|
||||
todo : List Goal
|
||||
failures : List Goal := []
|
||||
stop : Bool := false
|
||||
|
||||
private abbrev M := StateRefT State GrindM
|
||||
|
||||
def getNext? : M (Option Goal) := do
|
||||
let goal::todo := (← get).todo | return none
|
||||
modify fun s => { s with todo }
|
||||
return some goal
|
||||
|
||||
def pushGoal (goal : Goal) : M Unit :=
|
||||
modify fun s => { s with todo := goal :: s.todo }
|
||||
|
||||
def pushGoals (goals : List Goal) : M Unit :=
|
||||
modify fun s => { s with todo := goals ++ s.todo }
|
||||
|
||||
def pushFailure (goal : Goal) : M Unit := do
|
||||
modify fun s => { s with failures := goal :: s.failures }
|
||||
if (← get).failures.length ≥ (← getConfig).failures then
|
||||
modify fun s => { s with stop := true }
|
||||
|
||||
@[inline] def stepGuard (x : Goal → M Bool) (goal : Goal) : M Bool := do
|
||||
try
|
||||
x goal
|
||||
catch ex =>
|
||||
if ex.isMaxHeartbeat || ex.isMaxRecDepth then
|
||||
let goal ← goal.reportIssue ex.toMessageData
|
||||
pushFailure goal
|
||||
return true
|
||||
else
|
||||
throw ex
|
||||
|
||||
def applyTac (x : GrindTactic) (goal : Goal) : M Bool := do
|
||||
let go (goal : Goal) : M Bool := do
|
||||
let some goals ← x goal | return false
|
||||
pushGoals goals
|
||||
return true
|
||||
stepGuard go goal
|
||||
|
||||
def tryAssertNext : Goal → M Bool := applyTac assertNext
|
||||
|
||||
def tryEmatch : Goal → M Bool := applyTac ematchAndAssert
|
||||
|
||||
def trySplit : Goal → M Bool := applyTac splitNext
|
||||
|
||||
def maxNumFailuresReached : M Bool := do
|
||||
return (← get).failures.length ≥ (← getConfig).failures
|
||||
|
||||
partial def main : M Unit := do
|
||||
repeat do
|
||||
if (← get).stop then
|
||||
return ()
|
||||
let some goal ← getNext? |
|
||||
return ()
|
||||
if goal.inconsistent then
|
||||
continue
|
||||
if (← tryAssertNext goal) then
|
||||
continue
|
||||
if (← tryEmatch goal) then
|
||||
continue
|
||||
if (← trySplit goal) then
|
||||
continue
|
||||
pushFailure goal
|
||||
|
||||
end Solve
|
||||
|
||||
/--
|
||||
Try to solve/close the given goals, and returns the ones that could not be solved.
|
||||
-/
|
||||
def solve (goals : List Goal) : GrindM (List Goal) := do
|
||||
let (_, s) ← Solve.main.run { todo := goals }
|
||||
let todo ← s.todo.mapM fun goal => do
|
||||
goal.reportIssue m!"this goal was not fully processed due to previous failures, threshold: `(failures := {(← getConfig).failures})`"
|
||||
return s.failures.reverse ++ todo
|
||||
|
||||
end Lean.Meta.Grind
|
||||
@@ -74,6 +74,14 @@ private def checkIffStatus (e a b : Expr) : GoalM CaseSplitStatus := do
|
||||
else
|
||||
return .notReady
|
||||
|
||||
/-- Returns `true` is `c` is congruent to a case-split that was already performed. -/
|
||||
private def isCongrToPrevSplit (c : Expr) : GoalM Bool := do
|
||||
(← get).resolvedSplits.foldM (init := false) fun flag { expr := c' } => do
|
||||
if flag then
|
||||
return true
|
||||
else
|
||||
return isCongruent (← get).enodes c c'
|
||||
|
||||
private def checkCaseSplitStatus (e : Expr) : GoalM CaseSplitStatus := do
|
||||
match_expr e with
|
||||
| Or a b => checkDisjunctStatus e a b
|
||||
@@ -85,6 +93,8 @@ private def checkCaseSplitStatus (e : Expr) : GoalM CaseSplitStatus := do
|
||||
if (← isResolvedCaseSplit e) then
|
||||
trace[grind.debug.split] "split resolved: {e}"
|
||||
return .resolved
|
||||
if (← isCongrToPrevSplit e) then
|
||||
return .resolved
|
||||
if let some info := isMatcherAppCore? (← getEnv) e then
|
||||
return .ready info.numAlts
|
||||
let .const declName .. := e.getAppFn | unreachable!
|
||||
@@ -163,6 +173,7 @@ def splitNext : GrindTactic := fun goal => do
|
||||
| return none
|
||||
let gen ← getGeneration c
|
||||
let genNew := if numCases > 1 || isRec then gen+1 else gen
|
||||
markCaseSplitAsResolved c
|
||||
trace_goal[grind.split] "{c}, generation: {gen}"
|
||||
let mvarIds ← if (← isMatcherApp c) then
|
||||
casesMatch (← get).mvarId c
|
||||
|
||||
@@ -14,7 +14,6 @@ import Lean.Meta.AbstractNestedProofs
|
||||
import Lean.Meta.Tactic.Simp.Types
|
||||
import Lean.Meta.Tactic.Util
|
||||
import Lean.Meta.Tactic.Grind.ENodeKey
|
||||
import Lean.Meta.Tactic.Grind.Canon
|
||||
import Lean.Meta.Tactic.Grind.Attr
|
||||
import Lean.Meta.Tactic.Grind.Arith.Types
|
||||
import Lean.Meta.Tactic.Grind.EMatchTheorem
|
||||
@@ -333,6 +332,13 @@ structure NewFact where
|
||||
generation : Nat
|
||||
deriving Inhabited
|
||||
|
||||
/-- Canonicalizer state. See `Canon.lean` for additional details. -/
|
||||
structure Canon.State where
|
||||
argMap : PHashMap (Expr × Nat) (List Expr) := {}
|
||||
canon : PHashMap Expr Expr := {}
|
||||
proofCanon : PHashMap Expr Expr := {}
|
||||
deriving Inhabited
|
||||
|
||||
structure Goal where
|
||||
mvarId : MVarId
|
||||
canon : Canon.State := {}
|
||||
@@ -378,12 +384,17 @@ structure Goal where
|
||||
splitCandidates : List Expr := []
|
||||
/-- Number of splits performed to get to this goal. -/
|
||||
numSplits : Nat := 0
|
||||
/-- Case-splits that do not have to be performed anymore. -/
|
||||
/-- Case-splits that have already been performed, or that do not have to be performed anymore. -/
|
||||
resolvedSplits : PHashSet ENodeKey := {}
|
||||
/-- Next local E-match theorem idx. -/
|
||||
nextThmIdx : Nat := 0
|
||||
/-- Asserted facts -/
|
||||
facts : PArray Expr := {}
|
||||
/--
|
||||
Issues found during the proof search in this goal. This issues are reported to
|
||||
users when `grind` fails.
|
||||
-/
|
||||
issues : List MessageData := []
|
||||
deriving Inhabited
|
||||
|
||||
def Goal.admit (goal : Goal) : MetaM Unit :=
|
||||
@@ -397,13 +408,6 @@ abbrev GoalM := StateRefT Goal GrindM
|
||||
@[inline] def GoalM.run' (goal : Goal) (x : GoalM Unit) : GrindM Goal :=
|
||||
goal.mvarId.withContext do StateRefT'.run' (x *> get) goal
|
||||
|
||||
/-- Canonicalizes nested types, type formers, and instances in `e`. -/
|
||||
def canon (e : Expr) : GoalM Expr := do
|
||||
let canonS ← modifyGet fun s => (s.canon, { s with canon := {} })
|
||||
let (e, canonS) ← Canon.canon e |>.run canonS
|
||||
modify fun s => { s with canon := canonS }
|
||||
return e
|
||||
|
||||
def updateLastTag : GoalM Unit := do
|
||||
if (← isTracingEnabledFor `grind) then
|
||||
let currTag ← (← get).mvarId.getTag
|
||||
@@ -411,6 +415,20 @@ def updateLastTag : GoalM Unit := do
|
||||
trace[grind] "working on goal `{currTag}`"
|
||||
modifyThe Grind.State fun s => { s with lastTag := currTag }
|
||||
|
||||
def Goal.reportIssue (goal : Goal) (msg : MessageData) : MetaM Goal := do
|
||||
let msg ← addMessageContext msg
|
||||
let goal := { goal with issues := .trace { cls := `issue } msg #[] :: goal.issues }
|
||||
/-
|
||||
We also add a trace message because we may want to know when
|
||||
an issue happened relative to other trace messages.
|
||||
-/
|
||||
trace[grind.issues] msg
|
||||
return goal
|
||||
|
||||
def reportIssue (msg : MessageData) : GoalM Unit := do
|
||||
let goal ← (← get).reportIssue msg
|
||||
set goal
|
||||
|
||||
/--
|
||||
Macro similar to `trace[...]`, but it includes the trace message `trace[grind] "working on <current goal>"`
|
||||
if the tag has changed since the last trace message.
|
||||
@@ -860,7 +878,8 @@ def isResolvedCaseSplit (e : Expr) : GoalM Bool :=
|
||||
|
||||
/--
|
||||
Mark `e` as a case-split that does not need to be performed anymore.
|
||||
Remark: we currently use this feature to disable `match`-case-splits
|
||||
Remark: we currently use this feature to disable `match`-case-splits.
|
||||
Remark: we also use this feature to record the case-splits that have already been performed.
|
||||
-/
|
||||
def markCaseSplitAsResolved (e : Expr) : GoalM Unit := do
|
||||
unless (← isResolvedCaseSplit e) do
|
||||
|
||||
@@ -419,10 +419,10 @@ mutual
|
||||
|| (getPPAnalyzeTrustSubtypeMk (← getOptions) && (← getExpr).isAppOfArity ``Subtype.mk 4)
|
||||
|
||||
analyzeAppStagedCore { f, fType, args, mvars, bInfos, forceRegularApp } |>.run' {
|
||||
bottomUps := mkArray args.size false,
|
||||
higherOrders := mkArray args.size false,
|
||||
provideds := mkArray args.size false,
|
||||
funBinders := mkArray args.size false
|
||||
bottomUps := Array.replicate args.size false,
|
||||
higherOrders := Array.replicate args.size false,
|
||||
provideds := Array.replicate args.size false,
|
||||
funBinders := Array.replicate args.size false
|
||||
}
|
||||
|
||||
if !rest.isEmpty then
|
||||
|
||||
@@ -495,7 +495,7 @@ def getCanonicalAntiquot (stx : Syntax) : Syntax :=
|
||||
stx
|
||||
|
||||
def mkAntiquotNode (kind : Name) (term : Syntax) (nesting := 0) (name : Option String := none) (isPseudoKind := false) : Syntax :=
|
||||
let nesting := mkNullNode (mkArray nesting (mkAtom "$"))
|
||||
let nesting := mkNullNode (Array.replicate nesting (mkAtom "$"))
|
||||
let term :=
|
||||
if term.isIdent then term
|
||||
else if term.isOfKind `Lean.Parser.Term.hole then term[0]
|
||||
@@ -558,7 +558,7 @@ def getAntiquotSpliceSuffix (stx : Syntax) : Syntax :=
|
||||
stx[1]
|
||||
|
||||
def mkAntiquotSpliceNode (kind : SyntaxNodeKind) (contents : Array Syntax) (suffix : String) (nesting := 0) : Syntax :=
|
||||
let nesting := mkNullNode (mkArray nesting (mkAtom "$"))
|
||||
let nesting := mkNullNode (Array.replicate nesting (mkAtom "$"))
|
||||
mkNode (kind ++ `antiquot_splice) #[mkAtom "$", nesting, mkAtom "[", mkNullNode contents, mkAtom "]", mkAtom suffix]
|
||||
|
||||
-- `$x,*` etc.
|
||||
|
||||
@@ -31,7 +31,7 @@ structure State where
|
||||
checked : Std.HashSet Expr
|
||||
|
||||
unsafe def initCache : State := {
|
||||
visited := mkArray cacheSize.toNat (cast lcProof ())
|
||||
visited := Array.replicate cacheSize.toNat (cast lcProof ())
|
||||
checked := {}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ unsafe def replaceUnsafeM (f? : Level → Option Level) (size : USize) (e : Expr
|
||||
visit e
|
||||
|
||||
unsafe def initCache : State :=
|
||||
{ keys := mkArray cacheSize.toNat (cast lcProof ()), -- `()` is not a valid `Expr`
|
||||
results := mkArray cacheSize.toNat default }
|
||||
{ keys := Array.replicate cacheSize.toNat (cast lcProof ()), -- `()` is not a valid `Expr`
|
||||
results := Array.replicate cacheSize.toNat default }
|
||||
|
||||
unsafe def replaceUnsafe (f? : Level → Option Level) (e : Expr) : Expr :=
|
||||
(replaceUnsafeM f? cacheSize e).run' initCache
|
||||
|
||||
@@ -290,24 +290,12 @@ This function ensures that the value is used linearly.
|
||||
⟨(Raw₀.Const.insertManyIfNewUnit ⟨m.1, m.2.size_buckets_pos⟩ l).1,
|
||||
(Raw₀.Const.insertManyIfNewUnit ⟨m.1, m.2.size_buckets_pos⟩ l).2 _ Raw.WF.insertIfNew₀ m.2⟩
|
||||
|
||||
@[inline, inherit_doc Raw.ofList] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) :
|
||||
DHashMap α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
/-- Computes the union of the given hash maps, by traversing `m₂` and inserting its elements into `m₁`. -/
|
||||
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : DHashMap α β) : DHashMap α β :=
|
||||
m₂.fold (init := m₁) fun acc x => acc.insert x
|
||||
|
||||
instance [BEq α] [Hashable α] : Union (DHashMap α β) := ⟨union⟩
|
||||
|
||||
@[inline, inherit_doc Raw.Const.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : DHashMap α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.unitOfList] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
DHashMap α (fun _ => Unit) :=
|
||||
Const.insertManyIfNewUnit ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.unitOfArray] def Const.unitOfArray [BEq α] [Hashable α] (l : Array α) :
|
||||
DHashMap α (fun _ => Unit) :=
|
||||
Const.insertManyIfNewUnit ∅ l
|
||||
@@ -321,4 +309,16 @@ instance [BEq α] [Hashable α] [Repr α] [(a : α) → Repr (β a)] : Repr (DHa
|
||||
|
||||
end Unverified
|
||||
|
||||
@[inline, inherit_doc Raw.ofList] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) :
|
||||
DHashMap α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : DHashMap α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.Const.unitOfList] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
DHashMap α (fun _ => Unit) :=
|
||||
Const.insertManyIfNewUnit ∅ l
|
||||
|
||||
end Std.DHashMap
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace Raw₀
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
@[inline] def empty (capacity := 8) : Raw₀ α β :=
|
||||
⟨⟨0, mkArray (numBucketsForCapacity capacity).nextPowerOfTwo AssocList.nil⟩,
|
||||
⟨⟨0, Array.replicate (numBucketsForCapacity capacity).nextPowerOfTwo AssocList.nil⟩,
|
||||
by simpa using Nat.pos_of_isPowerOfTwo (Nat.isPowerOfTwo_nextPowerOfTwo _)⟩
|
||||
|
||||
-- Take `hash` as a function instead of `Hashable α` as per
|
||||
@@ -187,7 +187,7 @@ def expand [Hashable α] (data : { d : Array (AssocList α β) // 0 < d.size })
|
||||
{ d : Array (AssocList α β) // 0 < d.size } :=
|
||||
let ⟨data, hd⟩ := data
|
||||
let nbuckets := data.size * 2
|
||||
go 0 data ⟨mkArray nbuckets AssocList.nil, by simpa [nbuckets] using Nat.mul_pos hd Nat.two_pos⟩
|
||||
go 0 data ⟨Array.replicate nbuckets AssocList.nil, by simpa [nbuckets] using Nat.mul_pos hd Nat.two_pos⟩
|
||||
where
|
||||
/-- Inner loop of `expand`. Copies elements `source[i:]` into `target`,
|
||||
destroying `source` in the process. -/
|
||||
|
||||
@@ -7,6 +7,7 @@ prelude
|
||||
import Init.Data.BEq
|
||||
import Init.Data.Nat.Simproc
|
||||
import Init.Data.List.Perm
|
||||
import Init.Data.List.Find
|
||||
import Std.Data.DHashMap.Internal.List.Defs
|
||||
|
||||
/-!
|
||||
@@ -257,6 +258,15 @@ theorem containsKey_eq_isSome_getEntry? [BEq α] {l : List ((a : α) × β a)} {
|
||||
· simp [getEntry?_cons_of_false h, h, ih]
|
||||
· simp [getEntry?_cons_of_true h, h]
|
||||
|
||||
theorem containsKey_eq_contains_map_fst [BEq α] [PartialEquivBEq α] {l : List ((a : α) × β a)}
|
||||
{k : α} : containsKey k l = (l.map Sigma.fst).contains k := by
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons hd tl ih =>
|
||||
rw [containsKey_cons, ih]
|
||||
simp only [List.map_cons, List.contains_cons]
|
||||
rw [BEq.comm]
|
||||
|
||||
theorem isEmpty_eq_false_of_containsKey [BEq α] {l : List ((a : α) × β a)} {a : α}
|
||||
(h : containsKey a l = true) : l.isEmpty = false := by
|
||||
cases l <;> simp_all
|
||||
@@ -663,7 +673,7 @@ theorem isEmpty_replaceEntry [BEq α] {l : List ((a : α) × β a)} {k : α} {v
|
||||
(replaceEntry k v l).isEmpty = l.isEmpty := by
|
||||
induction l using assoc_induction
|
||||
· simp
|
||||
· simp [replaceEntry_cons, cond_eq_if]
|
||||
· simp only [replaceEntry_cons, cond_eq_if, List.isEmpty_cons]
|
||||
split <;> simp
|
||||
|
||||
theorem getEntry?_replaceEntry_of_containsKey_eq_false [BEq α] {l : List ((a : α) × β a)} {a k : α}
|
||||
@@ -681,7 +691,7 @@ theorem getEntry?_replaceEntry_of_false [BEq α] [PartialEquivBEq α] {l : List
|
||||
· rw [replaceEntry_cons_of_false h', getEntry?_cons, getEntry?_cons, ih]
|
||||
· rw [replaceEntry_cons_of_true h']
|
||||
have hk : (k' == a) = false := BEq.neq_of_beq_of_neq h' h
|
||||
simp [getEntry?_cons_of_false h, getEntry?_cons_of_false hk]
|
||||
simp only [getEntry?_cons_of_false h, getEntry?_cons_of_false hk]
|
||||
|
||||
theorem getEntry?_replaceEntry_of_true [BEq α] [PartialEquivBEq α] {l : List ((a : α) × β a)}
|
||||
{a k : α} {v : β k} (hl : containsKey k l = true) (h : k == a) :
|
||||
@@ -874,6 +884,11 @@ theorem containsKey_of_mem [BEq α] [ReflBEq α] {l : List ((a : α) × β a)} {
|
||||
theorem DistinctKeys.nil [BEq α] : DistinctKeys ([] : List ((a : α) × β a)) :=
|
||||
⟨by simp⟩
|
||||
|
||||
theorem DistinctKeys.def [BEq α] {l : List ((a : α) × β a)} :
|
||||
DistinctKeys l ↔ l.Pairwise (fun a b => (a.1 == b.1) = false) :=
|
||||
⟨fun h => by simpa [keys_eq_map, List.pairwise_map] using h.distinct,
|
||||
fun h => ⟨by simpa [keys_eq_map, List.pairwise_map] using h⟩⟩
|
||||
|
||||
open List
|
||||
|
||||
theorem DistinctKeys.perm_keys [BEq α] [PartialEquivBEq α] {l l' : List ((a : α) × β a)}
|
||||
@@ -909,6 +924,10 @@ theorem containsKey_eq_false_iff_forall_mem_keys [BEq α] [PartialEquivBEq α]
|
||||
(containsKey a l) = false ↔ ∀ a' ∈ keys l, (a == a') = false := by
|
||||
simp only [Bool.eq_false_iff, ne_eq, containsKey_iff_exists, not_exists, not_and]
|
||||
|
||||
theorem containsKey_eq_false_iff [BEq α] [PartialEquivBEq α] {l : List ((a : α) × β a)} {a : α} :
|
||||
containsKey a l = false ↔ ∀ (b : ((a : α) × β a)), b ∈ l → (a == b.fst) = false := by
|
||||
simp [containsKey_eq_false_iff_forall_mem_keys, keys_eq_map]
|
||||
|
||||
@[simp]
|
||||
theorem distinctKeys_cons_iff [BEq α] [PartialEquivBEq α] {l : List ((a : α) × β a)} {k : α}
|
||||
{v : β k} : DistinctKeys (⟨k, v⟩ :: l) ↔ DistinctKeys l ∧ (containsKey k l) = false := by
|
||||
@@ -963,6 +982,18 @@ theorem DistinctKeys.replaceEntry [BEq α] [PartialEquivBEq α] {l : List ((a :
|
||||
refine ⟨h.1, ?_⟩
|
||||
simpa [containsKey_congr (BEq.symm hk'k)] using h.2
|
||||
|
||||
theorem getEntry?_of_mem [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((a : α) × β a)} (hl : DistinctKeys l)
|
||||
{k k' : α} (hk : k == k') {v : β k} (hkv : ⟨k, v⟩ ∈ l) :
|
||||
getEntry? k' l = some ⟨k, v⟩ := by
|
||||
induction l using assoc_induction with
|
||||
| nil => simp at hkv
|
||||
| cons k₁ v₁ t ih =>
|
||||
obtain ⟨⟨⟩⟩|hkv := List.mem_cons.1 hkv
|
||||
· rw [getEntry?_cons_of_true hk]
|
||||
· rw [getEntry?_cons_of_false, ih hl.tail hkv]
|
||||
exact BEq.neq_of_neq_of_beq (containsKey_eq_false_iff.1 hl.containsKey_eq_false _ hkv) hk
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def insertEntry [BEq α] (k : α) (v : β k) (l : List ((a : α) × β a)) : List ((a : α) × β a) :=
|
||||
bif containsKey k l then replaceEntry k v l else ⟨k, v⟩ :: l
|
||||
@@ -1214,6 +1245,16 @@ theorem insertEntryIfNew_of_containsKey_eq_false [BEq α] {l : List ((a : α) ×
|
||||
{v : β k} (h : containsKey k l = false) : insertEntryIfNew k v l = ⟨k, v⟩ :: l := by
|
||||
simp_all [insertEntryIfNew]
|
||||
|
||||
theorem DistinctKeys.insertEntryIfNew [BEq α] [PartialEquivBEq α] {k : α} {v : β k}
|
||||
{l : List ((a : α) × β a)} (h: DistinctKeys l):
|
||||
DistinctKeys (insertEntryIfNew k v l) := by
|
||||
simp only [Std.DHashMap.Internal.List.insertEntryIfNew, cond_eq_if]
|
||||
split
|
||||
· exact h
|
||||
· rw [distinctKeys_cons_iff]
|
||||
rename_i h'
|
||||
simp [h, h']
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertEntryIfNew [BEq α] {l : List ((a : α) × β a)} {k : α} {v : β k} :
|
||||
(insertEntryIfNew k v l).isEmpty = false := by
|
||||
@@ -1845,6 +1886,836 @@ theorem eraseKey_append_of_containsKey_right_eq_false [BEq α] {l l' : List ((a
|
||||
· rw [cond_false, cond_false, ih, List.cons_append]
|
||||
· rw [cond_true, cond_true]
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def insertList [BEq α] (l toInsert : List ((a : α) × β a)) : List ((a : α) × β a) :=
|
||||
match toInsert with
|
||||
| .nil => l
|
||||
| .cons ⟨k, v⟩ toInsert => insertList (insertEntry k v l) toInsert
|
||||
|
||||
theorem DistinctKeys.insertList [BEq α] [PartialEquivBEq α] {l₁ l₂ : List ((a : α) × β a)}
|
||||
(h : DistinctKeys l₁) :
|
||||
DistinctKeys (insertList l₁ l₂) := by
|
||||
induction l₂ using assoc_induction generalizing l₁
|
||||
· simpa [insertList]
|
||||
· rename_i k v t ih
|
||||
rw [insertList.eq_def]
|
||||
exact ih h.insertEntry
|
||||
|
||||
theorem insertList_perm_of_perm_first [BEq α] [EquivBEq α] {l1 l2 toInsert : List ((a : α) × β a)}
|
||||
(h : Perm l1 l2) (distinct : DistinctKeys l1) :
|
||||
Perm (insertList l1 toInsert) (insertList l2 toInsert) := by
|
||||
induction toInsert generalizing l1 l2 with
|
||||
| nil => simp [insertList, h]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertList]
|
||||
apply ih (insertEntry_of_perm distinct h) (DistinctKeys.insertEntry distinct)
|
||||
|
||||
theorem insertList_cons_perm [BEq α] [EquivBEq α] {l₁ l₂ : List ((a : α) × β a)}
|
||||
{p : (a : α) × β a} (hl₁ : DistinctKeys l₁) (hl₂ : DistinctKeys (p :: l₂)) :
|
||||
(insertList l₁ (p :: l₂)).Perm (insertEntry p.1 p.2 (insertList l₁ l₂)) := by
|
||||
induction l₂ generalizing p l₁
|
||||
· simp [insertList]
|
||||
· rename_i h t ih
|
||||
rw [insertList]
|
||||
refine (ih hl₁.insertEntry hl₂.tail).trans
|
||||
((insertEntry_of_perm hl₁.insertList
|
||||
(ih hl₁ (distinctKeys_of_sublist (by simp) hl₂))).trans
|
||||
(List.Perm.trans ?_ (insertEntry_of_perm hl₁.insertList.insertEntry
|
||||
(ih hl₁ (distinctKeys_of_sublist (by simp) hl₂)).symm)))
|
||||
apply getEntry?_ext hl₁.insertList.insertEntry.insertEntry
|
||||
hl₁.insertList.insertEntry.insertEntry (fun k => ?_)
|
||||
simp only [getEntry?_insertEntry]
|
||||
split <;> rename_i hp <;> split <;> rename_i hh <;> try rfl
|
||||
rw [DistinctKeys.def] at hl₂
|
||||
have := List.rel_of_pairwise_cons hl₂ (List.mem_cons_self _ _)
|
||||
simp [BEq.trans hh (BEq.symm hp)] at this
|
||||
|
||||
theorem getEntry?_insertList [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false)) (k : α) :
|
||||
getEntry? k (insertList l toInsert) = (getEntry? k toInsert).or (getEntry? k l) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertList]
|
||||
| cons h t ih =>
|
||||
rw [getEntry?_of_perm distinct_l.insertList
|
||||
(insertList_cons_perm distinct_l (DistinctKeys.def.2 distinct_toInsert)),
|
||||
getEntry?_insertEntry]
|
||||
cases hk : h.1 == k
|
||||
· simp only [Bool.false_eq_true, ↓reduceIte]
|
||||
rw [ih distinct_l distinct_toInsert.tail, getEntry?_cons_of_false hk]
|
||||
· simp only [↓reduceIte]
|
||||
rw [getEntry?_cons_of_true hk, Option.some_or]
|
||||
|
||||
theorem getEntry?_insertList_of_contains_eq_false [BEq α] [PartialEquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(not_contains : containsKey k toInsert = false) :
|
||||
getEntry? k (insertList l toInsert) = getEntry? k l := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertList]
|
||||
| cons h t ih =>
|
||||
unfold insertList
|
||||
rw [containsKey_cons_eq_false] at not_contains
|
||||
rw [ih not_contains.right, getEntry?_insertEntry]
|
||||
simp [not_contains]
|
||||
|
||||
theorem getEntry?_insertList_of_contains_eq_true [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(contains : containsKey k toInsert = true) :
|
||||
getEntry? k (insertList l toInsert) = getEntry? k toInsert := by
|
||||
rw [getEntry?_insertList distinct_l distinct_toInsert]
|
||||
rw [containsKey_eq_isSome_getEntry?] at contains
|
||||
exact Option.or_of_isSome contains
|
||||
|
||||
theorem containsKey_insertList [BEq α] [PartialEquivBEq α] {l toInsert : List ((a : α) × β a)}
|
||||
{k : α} : containsKey k (List.insertList l toInsert) =
|
||||
(containsKey k l || (toInsert.map Sigma.fst).contains k) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp only [insertList, List.map_nil, List.elem_nil, Bool.or_false]
|
||||
| cons hd tl ih =>
|
||||
unfold insertList
|
||||
rw [ih]
|
||||
rw [containsKey_insertEntry]
|
||||
simp only [Bool.or_eq_true, List.map_cons, List.contains_cons]
|
||||
rw [BEq.comm]
|
||||
conv => left; left; rw [Bool.or_comm]
|
||||
rw [Bool.or_assoc]
|
||||
|
||||
theorem containsKey_of_containsKey_insertList [BEq α] [PartialEquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α} (h₁ : containsKey k (insertList l toInsert))
|
||||
(h₂ : (toInsert.map Sigma.fst).contains k = false) : containsKey k l := by
|
||||
rw [containsKey_insertList, h₂] at h₁; simp at h₁; exact h₁
|
||||
|
||||
theorem getValueCast?_insertList_of_contains_eq_false [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(not_contains : (toInsert.map Sigma.fst).contains k = false) :
|
||||
getValueCast? k (insertList l toInsert) = getValueCast? k l := by
|
||||
rw [← containsKey_eq_contains_map_fst] at not_contains
|
||||
rw [getValueCast?_eq_getEntry?, getValueCast?_eq_getEntry?]
|
||||
apply Option.dmap_congr
|
||||
rw [getEntry?_insertList_of_contains_eq_false not_contains]
|
||||
|
||||
theorem getValueCast?_insertList_of_mem [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert) :
|
||||
getValueCast? k' (insertList l toInsert) =
|
||||
some (cast (by congr; exact LawfulBEq.eq_of_beq k_beq) v) := by
|
||||
rw [getValueCast?_eq_getEntry?]
|
||||
have : getEntry? k' (insertList l toInsert) = getEntry? k' toInsert := by
|
||||
apply getEntry?_insertList_of_contains_eq_true distinct_l distinct_toInsert
|
||||
apply containsKey_of_beq _ k_beq
|
||||
exact containsKey_of_mem mem
|
||||
rw [← DistinctKeys.def] at distinct_toInsert
|
||||
rw [getEntry?_of_mem distinct_toInsert k_beq mem] at this
|
||||
rw [Option.dmap_congr this]
|
||||
simp
|
||||
|
||||
theorem getValueCast_insertList_of_contains_eq_false [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(not_contains : (toInsert.map Sigma.fst).contains k = false)
|
||||
{h} :
|
||||
getValueCast k (insertList l toInsert) h =
|
||||
getValueCast k l (containsKey_of_containsKey_insertList h not_contains) := by
|
||||
rw [← Option.some_inj, ← getValueCast?_eq_some_getValueCast, ← getValueCast?_eq_some_getValueCast,
|
||||
getValueCast?_insertList_of_contains_eq_false]
|
||||
exact not_contains
|
||||
|
||||
theorem getValueCast_insertList_of_mem [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k') (v : β k)
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert)
|
||||
{h} :
|
||||
getValueCast k' (insertList l toInsert) h =
|
||||
cast (by congr; exact LawfulBEq.eq_of_beq k_beq) v := by
|
||||
rw [← Option.some_inj, ← getValueCast?_eq_some_getValueCast,
|
||||
getValueCast?_insertList_of_mem k_beq distinct_l distinct_toInsert mem]
|
||||
|
||||
theorem getValueCast!_insertList_of_contains_eq_false [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(not_contains : (toInsert.map Sigma.fst).contains k = false) :
|
||||
getValueCast! k (insertList l toInsert) = getValueCast! k l := by
|
||||
rw [getValueCast!_eq_getValueCast?, getValueCast!_eq_getValueCast?,
|
||||
getValueCast?_insertList_of_contains_eq_false not_contains]
|
||||
|
||||
theorem getValueCast!_insertList_of_mem [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k') (v : β k) [Inhabited (β k')]
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert) :
|
||||
getValueCast! k' (insertList l toInsert) =
|
||||
cast (by congr; exact LawfulBEq.eq_of_beq k_beq) v := by
|
||||
rw [getValueCast!_eq_getValueCast?,
|
||||
getValueCast?_insertList_of_mem k_beq distinct_l distinct_toInsert mem, Option.get!_some]
|
||||
|
||||
theorem getValueCastD_insertList_of_contains_eq_false [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(not_mem : (toInsert.map Sigma.fst).contains k = false) :
|
||||
getValueCastD k (insertList l toInsert) fallback = getValueCastD k l fallback := by
|
||||
rw [getValueCastD_eq_getValueCast?, getValueCastD_eq_getValueCast?,
|
||||
getValueCast?_insertList_of_contains_eq_false not_mem]
|
||||
|
||||
theorem getValueCastD_insertList_of_mem [BEq α] [LawfulBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert) :
|
||||
getValueCastD k' (insertList l toInsert) fallback =
|
||||
cast (by congr; exact LawfulBEq.eq_of_beq k_beq) v := by
|
||||
rw [getValueCastD_eq_getValueCast?,
|
||||
getValueCast?_insertList_of_mem k_beq distinct_l distinct_toInsert mem, Option.getD_some]
|
||||
|
||||
theorem getKey?_insertList_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(not_contains : (toInsert.map Sigma.fst).contains k = false) :
|
||||
getKey? k (insertList l toInsert) = getKey? k l := by
|
||||
rw [← containsKey_eq_contains_map_fst] at not_contains
|
||||
rw [getKey?_eq_getEntry?, getKey?_eq_getEntry?,
|
||||
getEntry?_insertList_of_contains_eq_false not_contains]
|
||||
|
||||
theorem getKey?_insertList_of_mem [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Sigma.fst) :
|
||||
getKey? k' (insertList l toInsert) = some k := by
|
||||
rcases List.mem_map.1 mem with ⟨⟨k, v⟩, pair_mem, rfl⟩
|
||||
rw [getKey?_eq_getEntry?, getEntry?_insertList distinct_l distinct_toInsert,
|
||||
getEntry?_of_mem (DistinctKeys.def.2 distinct_toInsert) k_beq pair_mem, Option.some_or,
|
||||
Option.map_some']
|
||||
|
||||
theorem getKey_insertList_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(not_contains : (toInsert.map Sigma.fst).contains k = false)
|
||||
{h} :
|
||||
getKey k (insertList l toInsert) h =
|
||||
getKey k l (containsKey_of_containsKey_insertList h not_contains) := by
|
||||
rw [← Option.some_inj, ← getKey?_eq_some_getKey,
|
||||
getKey?_insertList_of_contains_eq_false not_contains, getKey?_eq_some_getKey]
|
||||
|
||||
theorem getKey_insertList_of_mem [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Sigma.fst)
|
||||
{h} :
|
||||
getKey k' (insertList l toInsert) h = k := by
|
||||
rw [← Option.some_inj, ← getKey?_eq_some_getKey,
|
||||
getKey?_insertList_of_mem k_beq distinct_l distinct_toInsert mem]
|
||||
|
||||
theorem getKey!_insertList_of_contains_eq_false [BEq α] [EquivBEq α] [Inhabited α]
|
||||
{l toInsert : List ((a : α) × β a)} {k : α}
|
||||
(contains_false : (toInsert.map Sigma.fst).contains k = false) :
|
||||
getKey! k (insertList l toInsert) = getKey! k l := by
|
||||
rw [getKey!_eq_getKey?, getKey?_insertList_of_contains_eq_false contains_false, getKey!_eq_getKey?]
|
||||
|
||||
theorem getKey!_insertList_of_mem [BEq α] [EquivBEq α] [Inhabited α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Sigma.fst) :
|
||||
getKey! k' (insertList l toInsert) = k := by
|
||||
rw [getKey!_eq_getKey?, getKey?_insertList_of_mem k_beq distinct_l distinct_toInsert mem,
|
||||
Option.get!_some]
|
||||
|
||||
theorem getKeyD_insertList_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)} {k fallback : α}
|
||||
(not_contains : (toInsert.map Sigma.fst).contains k = false) :
|
||||
getKeyD k (insertList l toInsert) fallback = getKeyD k l fallback := by
|
||||
rw [getKeyD_eq_getKey?, getKey?_insertList_of_contains_eq_false not_contains, getKeyD_eq_getKey?]
|
||||
|
||||
theorem getKeyD_insertList_of_mem [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Sigma.fst) :
|
||||
getKeyD k' (insertList l toInsert) fallback = k := by
|
||||
rw [getKeyD_eq_getKey?, getKey?_insertList_of_mem k_beq distinct_l distinct_toInsert mem,
|
||||
Option.getD_some]
|
||||
|
||||
theorem perm_insertList [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(distinct_both : ∀ (a : α), containsKey a l → (toInsert.map Sigma.fst).contains a = false) :
|
||||
Perm (insertList l toInsert) (l ++ toInsert) := by
|
||||
rw [← DistinctKeys.def] at distinct_toInsert
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp only [insertList, List.append_nil, Perm.refl]
|
||||
| cons hd tl ih =>
|
||||
simp only [List.map_cons, List.contains_cons, Bool.or_eq_false_iff] at distinct_both
|
||||
refine (insertList_cons_perm distinct_l distinct_toInsert).trans ?_
|
||||
rw [insertEntry_of_containsKey_eq_false]
|
||||
· refine (Perm.cons _ (ih distinct_l (distinct_toInsert).tail ?_)).trans List.perm_middle.symm
|
||||
exact fun a ha => (distinct_both a ha).2
|
||||
· simp only [containsKey_insertList, Bool.or_eq_false_iff, ← containsKey_eq_contains_map_fst]
|
||||
refine ⟨Bool.not_eq_true _ ▸ fun h => ?_, distinct_toInsert.containsKey_eq_false⟩
|
||||
simpa using (distinct_both _ h).1
|
||||
|
||||
theorem length_insertList [BEq α] [EquivBEq α]
|
||||
{l toInsert : List ((a : α) × β a)}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(distinct_both : ∀ (a : α), containsKey a l → (toInsert.map Sigma.fst).contains a = false) :
|
||||
(insertList l toInsert).length = l.length + toInsert.length := by
|
||||
simpa using (perm_insertList distinct_l distinct_toInsert distinct_both).length_eq
|
||||
|
||||
theorem length_le_length_insertList [BEq α]
|
||||
{l toInsert : List ((a : α) × β a)} :
|
||||
l.length ≤ (insertList l toInsert).length := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => apply Nat.le_refl
|
||||
| cons hd tl ih => exact Nat.le_trans length_le_length_insertEntry ih
|
||||
|
||||
theorem length_insertList_le [BEq α]
|
||||
{l toInsert : List ((a : α) × β a)} :
|
||||
(insertList l toInsert).length ≤ l.length + toInsert.length := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp only [insertList, List.length_nil, Nat.add_zero, Nat.le_refl]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertList, List.length_cons]
|
||||
apply Nat.le_trans ih
|
||||
rw [Nat.add_comm tl.length 1, ← Nat.add_assoc]
|
||||
apply Nat.add_le_add length_insertEntry_le (Nat.le_refl _)
|
||||
|
||||
theorem isEmpty_insertList [BEq α]
|
||||
{l toInsert : List ((a : α) × β a)} :
|
||||
(List.insertList l toInsert).isEmpty = (l.isEmpty && toInsert.isEmpty) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertList]
|
||||
| cons hd tl ih =>
|
||||
rw [insertList, List.isEmpty_cons, ih, isEmpty_insertEntry]
|
||||
simp
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def Prod.toSigma (p : α × β) : ((_ : α) × β) := ⟨p.fst, p.snd⟩
|
||||
|
||||
@[simp]
|
||||
theorem Prod.fst_comp_toSigma :
|
||||
Sigma.fst ∘ Prod.toSigma = @Prod.fst α β := by
|
||||
apply funext
|
||||
simp [Prod.toSigma]
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def insertListConst [BEq α] (l : List ((_ : α) × β)) (toInsert : List (α × β)) : List ((_ : α) × β) :=
|
||||
insertList l (toInsert.map Prod.toSigma)
|
||||
|
||||
theorem containsKey_insertListConst [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α} :
|
||||
containsKey k (insertListConst l toInsert) =
|
||||
(containsKey k l || (toInsert.map Prod.fst).contains k) := by
|
||||
unfold insertListConst
|
||||
rw [containsKey_insertList]
|
||||
simp
|
||||
|
||||
theorem containsKey_of_containsKey_insertListConst [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
(h₁ : containsKey k (insertListConst l toInsert))
|
||||
(h₂ : (toInsert.map Prod.fst).contains k = false) : containsKey k l := by
|
||||
unfold insertListConst at h₁
|
||||
apply containsKey_of_containsKey_insertList h₁
|
||||
simpa
|
||||
|
||||
theorem getKey?_insertListConst_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false) :
|
||||
getKey? k (insertListConst l toInsert) = getKey? k l := by
|
||||
unfold insertListConst
|
||||
apply getKey?_insertList_of_contains_eq_false
|
||||
simpa
|
||||
|
||||
theorem getKey?_insertListConst_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Prod.fst) :
|
||||
getKey? k' (insertListConst l toInsert) = some k := by
|
||||
unfold insertListConst
|
||||
apply getKey?_insertList_of_mem k_beq distinct_l
|
||||
· simpa [List.pairwise_map]
|
||||
· simp only [List.map_map, Prod.fst_comp_toSigma]
|
||||
exact mem
|
||||
|
||||
theorem getKey_insertListConst_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false)
|
||||
{h} :
|
||||
getKey k (insertListConst l toInsert) h =
|
||||
getKey k l (containsKey_of_containsKey_insertListConst h not_contains) := by
|
||||
rw [← Option.some_inj, ← getKey?_eq_some_getKey,
|
||||
getKey?_insertListConst_of_contains_eq_false not_contains, getKey?_eq_some_getKey]
|
||||
|
||||
theorem getKey_insertListConst_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Prod.fst)
|
||||
{h} :
|
||||
getKey k' (insertListConst l toInsert) h = k := by
|
||||
rw [← Option.some_inj, ← getKey?_eq_some_getKey,
|
||||
getKey?_insertListConst_of_mem k_beq distinct_l distinct_toInsert mem]
|
||||
|
||||
theorem getKey!_insertListConst_of_contains_eq_false [BEq α] [EquivBEq α] [Inhabited α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false) :
|
||||
getKey! k (insertListConst l toInsert) = getKey! k l := by
|
||||
rw [getKey!_eq_getKey?, getKey?_insertListConst_of_contains_eq_false not_contains,
|
||||
getKey!_eq_getKey?]
|
||||
|
||||
theorem getKey!_insertListConst_of_mem [BEq α] [EquivBEq α] [Inhabited α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Prod.fst) :
|
||||
getKey! k' (insertListConst l toInsert) = k := by
|
||||
rw [getKey!_eq_getKey?, getKey?_insertListConst_of_mem k_beq distinct_l distinct_toInsert mem,
|
||||
Option.get!_some]
|
||||
|
||||
theorem getKeyD_insertListConst_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k fallback : α}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false) :
|
||||
getKeyD k (insertListConst l toInsert) fallback = getKeyD k l fallback := by
|
||||
rw [getKeyD_eq_getKey?, getKey?_insertListConst_of_contains_eq_false not_contains,
|
||||
getKeyD_eq_getKey?]
|
||||
|
||||
theorem getKeyD_insertListConst_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ toInsert.map Prod.fst) :
|
||||
getKeyD k' (insertListConst l toInsert) fallback = k := by
|
||||
rw [getKeyD_eq_getKey?, getKey?_insertListConst_of_mem k_beq distinct_l distinct_toInsert mem,
|
||||
Option.getD_some]
|
||||
|
||||
theorem length_insertListConst [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(distinct_both : ∀ (a : α), containsKey a l → (toInsert.map Prod.fst).contains a = false) :
|
||||
(insertListConst l toInsert).length = l.length + toInsert.length := by
|
||||
unfold insertListConst
|
||||
rw [length_insertList distinct_l]
|
||||
· simp
|
||||
· simpa [List.pairwise_map]
|
||||
· simpa using distinct_both
|
||||
|
||||
theorem length_le_length_insertListConst [BEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} :
|
||||
l.length ≤ (insertListConst l toInsert).length := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => apply Nat.le_refl
|
||||
| cons hd tl ih => exact Nat.le_trans length_le_length_insertEntry ih
|
||||
|
||||
theorem length_insertListConst_le [BEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} :
|
||||
(insertListConst l toInsert).length ≤ l.length + toInsert.length := by
|
||||
unfold insertListConst
|
||||
rw [← List.length_map toInsert Prod.toSigma]
|
||||
apply length_insertList_le
|
||||
|
||||
theorem isEmpty_insertListConst [BEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} :
|
||||
(List.insertListConst l toInsert).isEmpty = (l.isEmpty && toInsert.isEmpty) := by
|
||||
unfold insertListConst
|
||||
rw [isEmpty_insertList, Bool.eq_iff_iff]
|
||||
simp
|
||||
|
||||
theorem getValue?_insertListConst_of_contains_eq_false [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false) :
|
||||
getValue? k (insertListConst l toInsert) = getValue? k l := by
|
||||
unfold insertListConst
|
||||
rw [getValue?_eq_getEntry?, getValue?_eq_getEntry?, getEntry?_insertList_of_contains_eq_false]
|
||||
rw [containsKey_eq_contains_map_fst]
|
||||
simpa
|
||||
|
||||
theorem getValue?_insertListConst_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert) :
|
||||
getValue? k' (insertListConst l toInsert) = v := by
|
||||
unfold insertListConst
|
||||
rw [getValue?_eq_getEntry?]
|
||||
have : getEntry? k' (insertList l (toInsert.map Prod.toSigma)) =
|
||||
getEntry? k' (toInsert.map Prod.toSigma) := by
|
||||
apply getEntry?_insertList_of_contains_eq_true distinct_l (by simpa [List.pairwise_map])
|
||||
apply containsKey_of_beq _ k_beq
|
||||
rw [containsKey_eq_contains_map_fst, List.map_map, Prod.fst_comp_toSigma,
|
||||
List.contains_iff_exists_mem_beq]
|
||||
exists k
|
||||
rw [List.mem_map]
|
||||
constructor
|
||||
. exists ⟨k, v⟩
|
||||
. simp
|
||||
rw [this]
|
||||
rw [getEntry?_of_mem _ k_beq _]
|
||||
. rfl
|
||||
· simpa [DistinctKeys.def, List.pairwise_map]
|
||||
. simp only [List.mem_map]
|
||||
exists (k, v)
|
||||
|
||||
theorem getValue_insertListConst_of_contains_eq_false [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
{not_contains : (toInsert.map Prod.fst).contains k = false}
|
||||
{h} :
|
||||
getValue k (insertListConst l toInsert) h =
|
||||
getValue k l (containsKey_of_containsKey_insertListConst h not_contains) := by
|
||||
rw [← Option.some_inj, ← getValue?_eq_some_getValue, ← getValue?_eq_some_getValue,
|
||||
getValue?_insertListConst_of_contains_eq_false not_contains]
|
||||
|
||||
theorem getValue_insertListConst_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert)
|
||||
{h} :
|
||||
getValue k' (insertListConst l toInsert) h = v := by
|
||||
rw [← Option.some_inj, ← getValue?_eq_some_getValue,
|
||||
getValue?_insertListConst_of_mem k_beq distinct_l distinct_toInsert mem]
|
||||
|
||||
theorem getValue!_insertListConst_of_contains_eq_false [BEq α] [PartialEquivBEq α] [Inhabited β]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false) :
|
||||
getValue! k (insertListConst l toInsert) = getValue! k l := by
|
||||
simp only [getValue!_eq_getValue?]
|
||||
rw [getValue?_insertListConst_of_contains_eq_false not_contains]
|
||||
|
||||
theorem getValue!_insertListConst_of_mem [BEq α] [EquivBEq α] [Inhabited β]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k k' : α} {v: β} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert):
|
||||
getValue! k' (insertListConst l toInsert) = v := by
|
||||
rw [getValue!_eq_getValue?,
|
||||
getValue?_insertListConst_of_mem k_beq distinct_l distinct_toInsert mem, Option.get!_some]
|
||||
|
||||
theorem getValueD_insertListConst_of_contains_eq_false [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k : α} {fallback : β}
|
||||
(not_contains : (toInsert.map Prod.fst).contains k = false) :
|
||||
getValueD k (insertListConst l toInsert) fallback = getValueD k l fallback := by
|
||||
simp only [getValueD_eq_getValue?]
|
||||
rw [getValue?_insertListConst_of_contains_eq_false not_contains]
|
||||
|
||||
theorem getValueD_insertListConst_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × β)} {toInsert : List (α × β)} {k k' : α} {v fallback: β} (k_beq : k == k')
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ toInsert):
|
||||
getValueD k' (insertListConst l toInsert) fallback= v := by
|
||||
simp only [getValueD_eq_getValue?]
|
||||
rw [getValue?_insertListConst_of_mem k_beq distinct_l distinct_toInsert mem, Option.getD_some]
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def insertListIfNewUnit [BEq α] (l: List ((_ : α) × Unit)) (toInsert: List α) :
|
||||
List ((_ : α) × Unit) :=
|
||||
match toInsert with
|
||||
| .nil => l
|
||||
| .cons hd tl => insertListIfNewUnit (insertEntryIfNew hd () l) tl
|
||||
|
||||
theorem insertListIfNewUnit_perm_of_perm_first [BEq α] [EquivBEq α] {l1 l2 : List ((_ : α) × Unit)}
|
||||
{toInsert : List α } (h : Perm l1 l2) (distinct : DistinctKeys l1) :
|
||||
Perm (insertListIfNewUnit l1 toInsert) (insertListIfNewUnit l2 toInsert) := by
|
||||
induction toInsert generalizing l1 l2 with
|
||||
| nil => simp [insertListIfNewUnit, h]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListIfNewUnit]
|
||||
apply ih
|
||||
· simp only [insertEntryIfNew, cond_eq_if]
|
||||
have contains_eq : containsKey hd l1 = containsKey hd l2 := containsKey_of_perm h
|
||||
rw [contains_eq]
|
||||
by_cases contains_hd: containsKey hd l2 = true
|
||||
· simp only [contains_hd, ↓reduceIte]
|
||||
exact h
|
||||
· simp only [contains_hd, Bool.false_eq_true, ↓reduceIte, List.perm_cons]
|
||||
exact h
|
||||
· apply DistinctKeys.insertEntryIfNew distinct
|
||||
|
||||
theorem DistinctKeys.insertListIfNewUnit [BEq α] [PartialEquivBEq α] {l : List ((_ : α) × Unit)}
|
||||
{toInsert : List α} (distinct: DistinctKeys l):
|
||||
DistinctKeys (insertListIfNewUnit l toInsert) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [List.insertListIfNewUnit, distinct]
|
||||
| cons hd tl ih =>
|
||||
simp only [List.insertListIfNewUnit]
|
||||
apply ih (insertEntryIfNew distinct)
|
||||
|
||||
theorem getEntry?_insertListIfNewUnit [BEq α] [PartialEquivBEq α] {l : List ((_ : α) × Unit)}
|
||||
{toInsert : List α} {k : α} :
|
||||
getEntry? k (insertListIfNewUnit l toInsert) =
|
||||
(getEntry? k l).or (getEntry? k (toInsert.map (⟨·, ()⟩))) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertListIfNewUnit]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListIfNewUnit, ih, getEntry?_insertEntryIfNew, List.map_cons,
|
||||
getEntry?_cons]
|
||||
cases hhd : hd == k
|
||||
· simp
|
||||
· cases hc : containsKey hd l
|
||||
· simp only [Bool.not_false, Bool.and_self, ↓reduceIte, Option.some_or, cond_true,
|
||||
Option.or_some', Option.some.injEq]
|
||||
rw [getEntry?_eq_none.2, Option.getD_none]
|
||||
rwa [← containsKey_congr hhd]
|
||||
· simp only [Bool.not_true, Bool.and_false, Bool.false_eq_true, ↓reduceIte, cond_true,
|
||||
Option.or_some', getEntry?_eq_none]
|
||||
rw [containsKey_congr hhd, containsKey_eq_isSome_getEntry?] at hc
|
||||
obtain ⟨v, hv⟩ := Option.isSome_iff_exists.1 hc
|
||||
simp [hv]
|
||||
|
||||
theorem DistinctKeys.mapUnit [BEq α]
|
||||
{l : List α} (distinct: l.Pairwise (fun a b => (a == b) = false)) :
|
||||
DistinctKeys (l.map (⟨·, ()⟩)) := by
|
||||
rw [DistinctKeys.def]
|
||||
refine List.Pairwise.map ?_ ?_ distinct
|
||||
simp
|
||||
|
||||
theorem getEntry?_insertListIfNewUnit_of_contains_eq_false [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α } {k : α}
|
||||
(not_contains : toInsert.contains k = false) :
|
||||
getEntry? k (insertListIfNewUnit l toInsert) = getEntry? k l := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertListIfNewUnit]
|
||||
| cons h t ih =>
|
||||
unfold insertListIfNewUnit
|
||||
simp only [List.contains_cons, Bool.or_eq_false_iff] at not_contains
|
||||
rw [ih not_contains.right, getEntry?_insertEntryIfNew]
|
||||
simp only [Bool.and_eq_true, Bool.not_eq_eq_eq_not, Bool.not_true, ite_eq_right_iff, and_imp]
|
||||
intro h'
|
||||
rw [BEq.comm, And.left not_contains] at h'
|
||||
simp at h'
|
||||
|
||||
theorem containsKey_insertListIfNewUnit [BEq α] [PartialEquivBEq α] {l : List ((_ : α) × Unit)}
|
||||
{toInsert : List α} {k : α} :
|
||||
containsKey k (insertListIfNewUnit l toInsert) = (containsKey k l || toInsert.contains k) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertListIfNewUnit]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListIfNewUnit, List.contains_cons]
|
||||
rw [ih, containsKey_insertEntryIfNew]
|
||||
rw [Bool.or_comm (hd == k), Bool.or_assoc, BEq.comm (a:=hd)]
|
||||
|
||||
theorem containsKey_of_containsKey_insertListIfNewUnit [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α} {k : α}
|
||||
(h₂ : toInsert.contains k = false) : containsKey k (insertListIfNewUnit l toInsert) →
|
||||
containsKey k l := by
|
||||
intro h₁
|
||||
rw [containsKey_insertListIfNewUnit, h₂] at h₁; simp at h₁; exact h₁
|
||||
|
||||
theorem getKey?_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α} {k : α}
|
||||
(h': containsKey k l = false) (h : toInsert.contains k = false) :
|
||||
getKey? k (insertListIfNewUnit l toInsert) = none := by
|
||||
rw [getKey?_eq_getEntry?,
|
||||
getEntry?_insertListIfNewUnit_of_contains_eq_false h, Option.map_eq_none', getEntry?_eq_none]
|
||||
exact h'
|
||||
|
||||
theorem getKey?_insertListIfNewUnit_of_contains_eq_false_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(mem' : containsKey k l = false)
|
||||
(distinct : toInsert.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ toInsert):
|
||||
getKey? k' (insertListIfNewUnit l toInsert) = some k := by
|
||||
simp only [getKey?_eq_getEntry?, getEntry?_insertListIfNewUnit, Option.map_eq_some',
|
||||
Option.or_eq_some, getEntry?_eq_none]
|
||||
exists ⟨k, ()⟩
|
||||
simp only [and_true]
|
||||
right
|
||||
constructor
|
||||
· rw [containsKey_congr k_beq] at mem'
|
||||
exact mem'
|
||||
· apply getEntry?_of_mem (DistinctKeys.mapUnit distinct) k_beq
|
||||
simp only [List.mem_map]
|
||||
exists k
|
||||
|
||||
theorem getKey?_insertListIfNewUnit_of_contains [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k : α}
|
||||
(h : containsKey k l = true):
|
||||
getKey? k (insertListIfNewUnit l toInsert) = getKey? k l := by
|
||||
rw [containsKey_eq_isSome_getEntry?] at h
|
||||
simp [getKey?_eq_getEntry?, getEntry?_insertListIfNewUnit, Option.or_of_isSome h]
|
||||
|
||||
theorem getKey_insertListIfNewUnit_of_contains_eq_false_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
{h} (contains_eq_false : containsKey k l = false)
|
||||
(distinct : toInsert.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ toInsert) :
|
||||
getKey k' (insertListIfNewUnit l toInsert) h = k := by
|
||||
rw [← Option.some_inj, ← getKey?_eq_some_getKey,
|
||||
getKey?_insertListIfNewUnit_of_contains_eq_false_of_mem k_beq contains_eq_false distinct mem]
|
||||
|
||||
theorem getKey_insertListIfNewUnit_of_contains [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k : α}
|
||||
(contains : containsKey k l = true) {h}:
|
||||
getKey k (insertListIfNewUnit l toInsert) h = getKey k l contains := by
|
||||
rw [← Option.some_inj, ← getKey?_eq_some_getKey, ← getKey?_eq_some_getKey,
|
||||
getKey?_insertListIfNewUnit_of_contains contains]
|
||||
|
||||
theorem getKey!_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
[Inhabited α] {l : List ((_ : α) × Unit)} {toInsert : List α} {k : α}
|
||||
(contains_eq_false : containsKey k l = false)
|
||||
(contains_eq_false' : toInsert.contains k = false) :
|
||||
getKey! k (insertListIfNewUnit l toInsert) = default := by
|
||||
rw [getKey!_eq_getKey?, getKey?_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false
|
||||
contains_eq_false contains_eq_false']
|
||||
simp
|
||||
|
||||
theorem getKey!_insertListIfNewUnit_of_contains_eq_false_of_mem [BEq α] [EquivBEq α] [Inhabited α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(h : containsKey k l = false)
|
||||
(distinct : toInsert.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ toInsert) :
|
||||
getKey! k' (insertListIfNewUnit l toInsert) = k := by
|
||||
rw [getKey!_eq_getKey?,
|
||||
getKey?_insertListIfNewUnit_of_contains_eq_false_of_mem k_beq h distinct mem, Option.get!_some]
|
||||
|
||||
theorem getKey!_insertListIfNewUnit_of_contains [BEq α] [EquivBEq α] [Inhabited α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k : α}
|
||||
(h : containsKey k l = true) :
|
||||
getKey! k (insertListIfNewUnit l toInsert) = getKey! k l := by
|
||||
rw [getKey!_eq_getKey?, getKey?_insertListIfNewUnit_of_contains h, getKey!_eq_getKey?]
|
||||
|
||||
theorem getKeyD_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α} {k fallback : α}
|
||||
(contains_eq_false : containsKey k l = false) (contains_eq_false' : toInsert.contains k = false) :
|
||||
getKeyD k (insertListIfNewUnit l toInsert) fallback = fallback := by
|
||||
rw [getKeyD_eq_getKey?, getKey?_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false
|
||||
contains_eq_false contains_eq_false']
|
||||
simp
|
||||
|
||||
theorem getKeyD_insertListIfNewUnit_of_contains_eq_false_of_mem [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(h : containsKey k l = false)
|
||||
(distinct : toInsert.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ toInsert) :
|
||||
getKeyD k' (insertListIfNewUnit l toInsert) fallback = k := by
|
||||
rw [getKeyD_eq_getKey?, getKey?_insertListIfNewUnit_of_contains_eq_false_of_mem k_beq h
|
||||
distinct mem, Option.getD_some]
|
||||
|
||||
theorem getKeyD_insertListIfNewUnit_of_contains [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
{k fallback : α}
|
||||
(contains : containsKey k l = true) :
|
||||
getKeyD k (insertListIfNewUnit l toInsert) fallback = getKeyD k l fallback := by
|
||||
rw [getKeyD_eq_getKey?,
|
||||
getKey?_insertListIfNewUnit_of_contains contains, getKeyD_eq_getKey?]
|
||||
|
||||
theorem length_insertListIfNewUnit [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}
|
||||
(distinct_l : DistinctKeys l)
|
||||
(distinct_toInsert : toInsert.Pairwise (fun a b => (a == b) = false))
|
||||
(distinct_both : ∀ (a : α), containsKey a l → toInsert.contains a = false) :
|
||||
(insertListIfNewUnit l toInsert).length = l.length + toInsert.length := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertListIfNewUnit]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListIfNewUnit, List.length_cons]
|
||||
rw [ih]
|
||||
· rw [length_insertEntryIfNew]
|
||||
specialize distinct_both hd
|
||||
simp only [List.contains_cons, BEq.refl, Bool.true_or, and_true,
|
||||
Bool.not_eq_true] at distinct_both
|
||||
cases eq : containsKey hd l with
|
||||
| true => simp [eq] at distinct_both
|
||||
| false =>
|
||||
simp only [Bool.false_eq_true, ↓reduceIte]
|
||||
rw [Nat.add_assoc, Nat.add_comm 1 _]
|
||||
· apply DistinctKeys.insertEntryIfNew distinct_l
|
||||
· simp only [pairwise_cons] at distinct_toInsert
|
||||
apply And.right distinct_toInsert
|
||||
· intro a
|
||||
simp only [List.contains_cons, Bool.or_eq_true, not_and, not_or,
|
||||
Bool.not_eq_true] at distinct_both
|
||||
rw [containsKey_insertEntryIfNew]
|
||||
simp only [Bool.or_eq_true]
|
||||
intro h
|
||||
cases h with
|
||||
| inl h =>
|
||||
simp only [pairwise_cons] at distinct_toInsert
|
||||
rw [List.contains_eq_any_beq]
|
||||
simp only [List.any_eq_false, Bool.not_eq_true]
|
||||
intro x x_mem
|
||||
rcases distinct_toInsert with ⟨left,_⟩
|
||||
specialize left x x_mem
|
||||
apply BEq.neq_of_beq_of_neq
|
||||
apply BEq.symm h
|
||||
exact left
|
||||
| inr h =>
|
||||
specialize distinct_both a h
|
||||
rw [Bool.or_eq_false_iff] at distinct_both
|
||||
apply And.right distinct_both
|
||||
|
||||
theorem length_le_length_insertListIfNewUnit [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}:
|
||||
l.length ≤ (insertListIfNewUnit l toInsert).length := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => apply Nat.le_refl
|
||||
| cons hd tl ih => exact Nat.le_trans length_le_length_insertEntryIfNew ih
|
||||
|
||||
theorem length_insertListIfNewUnit_le [BEq α] [EquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α}:
|
||||
(insertListIfNewUnit l toInsert).length ≤ l.length + toInsert.length := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp only [insertListIfNewUnit, List.length_nil, Nat.add_zero, Nat.le_refl]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListIfNewUnit, List.length_cons]
|
||||
apply Nat.le_trans ih
|
||||
rw [Nat.add_comm tl.length 1, ← Nat.add_assoc]
|
||||
apply Nat.add_le_add _ (Nat.le_refl _)
|
||||
apply length_insertEntryIfNew_le
|
||||
|
||||
theorem isEmpty_insertListIfNewUnit [BEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α} :
|
||||
(List.insertListIfNewUnit l toInsert).isEmpty = (l.isEmpty && toInsert.isEmpty) := by
|
||||
induction toInsert generalizing l with
|
||||
| nil => simp [insertListIfNewUnit]
|
||||
| cons hd tl ih =>
|
||||
rw [insertListIfNewUnit, List.isEmpty_cons, ih, isEmpty_insertEntryIfNew]
|
||||
simp
|
||||
|
||||
theorem getValue?_list_unit [BEq α] {l : List ((_ : α) × Unit)} {k : α}:
|
||||
getValue? k l = if containsKey k l = true then some () else none := by
|
||||
induction l with
|
||||
| nil => simp
|
||||
| cons hd tl ih =>
|
||||
simp only [getValue?, containsKey, Bool.or_eq_true, Bool.cond_eq_ite_iff]
|
||||
by_cases hd_k: (hd.fst == k) = true
|
||||
· simp [hd_k]
|
||||
· simp [hd_k, ih]
|
||||
|
||||
theorem getValue?_insertListIfNewUnit [BEq α] [PartialEquivBEq α]
|
||||
{l : List ((_ : α) × Unit)} {toInsert : List α} {k : α}:
|
||||
getValue? k (insertListIfNewUnit l toInsert) =
|
||||
if containsKey k l ∨ toInsert.contains k then some () else none := by
|
||||
simp [containsKey_insertListIfNewUnit, getValue?_list_unit]
|
||||
|
||||
end
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def alterKey [BEq α] [LawfulBEq α] (k : α) (f : Option (β k) → Option (β k))
|
||||
(l : List ((a : α) × β a)) : List ((a : α) × β a) :=
|
||||
|
||||
@@ -201,7 +201,7 @@ theorem toListModel_updateAllBuckets {m : Raw₀ α β} {f : AssocList α β →
|
||||
omega
|
||||
rw [updateAllBuckets, toListModel, Array.toList_map, List.flatMap_eq_foldl, List.foldl_map,
|
||||
toListModel, List.flatMap_eq_foldl]
|
||||
suffices ∀ (l : List (AssocList α β)) (l' : List ((a: α) × δ a)) (l'' : List ((a : α) × β a)),
|
||||
suffices ∀ (l : List (AssocList α β)) (l' : List ((a : α) × δ a)) (l'' : List ((a : α) × β a)),
|
||||
Perm (g l'') l' →
|
||||
Perm (l.foldl (fun acc a => acc ++ (f a).toList) l')
|
||||
(g (l.foldl (fun acc a => acc ++ a.toList) l'')) by
|
||||
@@ -219,8 +219,8 @@ theorem toListModel_updateAllBuckets {m : Raw₀ α β} {f : AssocList α β →
|
||||
namespace IsHashSelf
|
||||
|
||||
@[simp]
|
||||
theorem mkArray [BEq α] [Hashable α] {c : Nat} : IsHashSelf
|
||||
(mkArray c (AssocList.nil : AssocList α β)) :=
|
||||
theorem replicate [BEq α] [Hashable α] {c : Nat} : IsHashSelf
|
||||
(Array.replicate c (AssocList.nil : AssocList α β)) :=
|
||||
⟨by simp⟩
|
||||
|
||||
theorem uset [BEq α] [Hashable α] {m : Array (AssocList α β)} {i : USize} {h : i.toNat < m.size}
|
||||
@@ -378,6 +378,12 @@ def mapₘ (m : Raw₀ α β) (f : (a : α) → β a → δ a) : Raw₀ α δ :=
|
||||
def filterₘ (m : Raw₀ α β) (f : (a : α) → β a → Bool) : Raw₀ α β :=
|
||||
⟨withComputedSize (updateAllBuckets m.1.buckets fun l => l.filter f), by simpa using m.2⟩
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def insertListₘ [BEq α] [Hashable α] (m : Raw₀ α β) (l : List ((a : α) × β a)) : Raw₀ α β :=
|
||||
match l with
|
||||
| .nil => m
|
||||
| .cons hd tl => insertListₘ (m.insert hd.1 hd.2) tl
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
@@ -398,6 +404,20 @@ def Const.getDₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β)) (a : α)
|
||||
def Const.get!ₘ [BEq α] [Hashable α] [Inhabited β] (m : Raw₀ α (fun _ => β)) (a : α) : β :=
|
||||
(Const.get?ₘ m a).get!
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def Const.insertListₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β)) (l: List (α × β)) :
|
||||
Raw₀ α (fun _ => β) :=
|
||||
match l with
|
||||
| .nil => m
|
||||
| .cons hd tl => insertListₘ (m.insert hd.1 hd.2) tl
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
def Const.insertListIfNewUnitₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => Unit)) (l: List α) :
|
||||
Raw₀ α (fun _ => Unit) :=
|
||||
match l with
|
||||
| .nil => m
|
||||
| .cons hd tl => insertListIfNewUnitₘ (m.insertIfNew hd ()) tl
|
||||
|
||||
end
|
||||
|
||||
/-! # Equivalence between model functions and real implementations -/
|
||||
@@ -569,6 +589,19 @@ theorem map_eq_mapₘ (m : Raw₀ α β) (f : (a : α) → β a → δ a) :
|
||||
theorem filter_eq_filterₘ (m : Raw₀ α β) (f : (a : α) → β a → Bool) :
|
||||
m.filter f = m.filterₘ f := rfl
|
||||
|
||||
theorem insertMany_eq_insertListₘ [BEq α] [Hashable α](m : Raw₀ α β) (l : List ((a : α) × β a)) : insertMany m l = insertListₘ m l := by
|
||||
simp only [insertMany, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
suffices ∀ (t : { m' // ∀ (P : Raw₀ α β → Prop),
|
||||
(∀ {m'' : Raw₀ α β} {a : α} {b : β a}, P m'' → P (m''.insert a b)) → P m → P m' }),
|
||||
(List.foldl (fun m' p => ⟨m'.val.insert p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
|
||||
t.val.insertListₘ l from this _
|
||||
intro t
|
||||
induction l generalizing m with
|
||||
| nil => simp [insertListₘ]
|
||||
| cons hd tl ih =>
|
||||
simp only [List.foldl_cons, insertListₘ]
|
||||
apply ih
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
@@ -599,6 +632,36 @@ theorem Const.getThenInsertIfNew?_eq_get?ₘ [BEq α] [Hashable α] (m : Raw₀
|
||||
dsimp only [Array.ugetElem_eq_getElem, Array.uset]
|
||||
split <;> simp_all [-getValue?_eq_none]
|
||||
|
||||
theorem Const.insertMany_eq_insertListₘ [BEq α] [Hashable α] (m : Raw₀ α (fun _ => β))
|
||||
(l: List (α × β)):
|
||||
(Const.insertMany m l).1 = Const.insertListₘ m l := by
|
||||
simp only [insertMany, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
suffices ∀ (t : { m' // ∀ (P : Raw₀ α (fun _ => β) → Prop),
|
||||
(∀ {m'' : Raw₀ α (fun _ => β)} {a : α} {b : β}, P m'' → P (m''.insert a b)) → P m → P m' }),
|
||||
(List.foldl (fun m' p => ⟨m'.val.insert p.1 p.2, fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
|
||||
Const.insertListₘ t.val l from this _
|
||||
intro t
|
||||
induction l generalizing m with
|
||||
| nil => simp [insertListₘ]
|
||||
| cons hd tl ih =>
|
||||
simp only [List.foldl_cons, insertListₘ]
|
||||
apply ih
|
||||
|
||||
theorem Const.insertManyIfNewUnit_eq_insertListIfNewUnitₘ [BEq α] [Hashable α]
|
||||
(m : Raw₀ α (fun _ => Unit)) (l: List α):
|
||||
(Const.insertManyIfNewUnit m l).1 = Const.insertListIfNewUnitₘ m l := by
|
||||
simp only [insertManyIfNewUnit, Id.run, Id.pure_eq, Id.bind_eq, List.forIn_yield_eq_foldl]
|
||||
suffices ∀ (t : { m' // ∀ (P : Raw₀ α (fun _ => Unit) → Prop),
|
||||
(∀ {m'' a b}, P m'' → P (m''.insertIfNew a b)) → P m → P m'}),
|
||||
(List.foldl (fun m' p => ⟨m'.val.insertIfNew p (), fun P h₁ h₂ => h₁ (m'.2 _ h₁ h₂)⟩) t l).val =
|
||||
Const.insertListIfNewUnitₘ t.val l from this _
|
||||
intro t
|
||||
induction l generalizing m with
|
||||
| nil => simp [insertListIfNewUnitₘ]
|
||||
| cons hd tl ih =>
|
||||
simp only [List.foldl_cons, insertListIfNewUnitₘ]
|
||||
apply ih
|
||||
|
||||
end
|
||||
|
||||
end Raw₀
|
||||
|
||||
@@ -199,10 +199,52 @@ theorem filter_val [BEq α] [Hashable α] {m : Raw₀ α β} {f : (a : α) →
|
||||
m.val.filter f = m.filter f := by
|
||||
simp [Raw.filter, m.2]
|
||||
|
||||
theorem insertMany_eq [BEq α] [Hashable α] {m : Raw α β} (h : m.WF) {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] {l : ρ} :
|
||||
m.insertMany l = Raw₀.insertMany ⟨m, h.size_buckets_pos⟩ l := by
|
||||
simp [Raw.insertMany, h.size_buckets_pos]
|
||||
|
||||
theorem insertMany_val [BEq α][Hashable α] {m : Raw₀ α β} {ρ : Type w} [ForIn Id ρ ((a : α) × β a)] {l : ρ} :
|
||||
m.val.insertMany l = m.insertMany l := by
|
||||
simp [Raw.insertMany, m.2]
|
||||
|
||||
theorem ofList_eq [BEq α] [Hashable α] {l : List ((a : α) × β a)} :
|
||||
Raw.ofList l = Raw₀.insertMany Raw₀.empty l := by
|
||||
simp only [Raw.ofList, Raw.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
|
||||
congr
|
||||
|
||||
section
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
theorem Const.insertMany_eq [BEq α] [Hashable α] {m : Raw α (fun _ => β)} (h : m.WF) {ρ : Type w} [ForIn Id ρ (α × β)] {l : ρ} :
|
||||
Raw.Const.insertMany m l = Raw₀.Const.insertMany ⟨m, h.size_buckets_pos⟩ l := by
|
||||
simp [Raw.Const.insertMany, h.size_buckets_pos]
|
||||
|
||||
theorem Const.insertMany_val [BEq α][Hashable α] {m : Raw₀ α (fun _ => β)} {ρ : Type w} [ForIn Id ρ (α × β)] {l : ρ} :
|
||||
Raw.Const.insertMany m.val l = Raw₀.Const.insertMany m l := by
|
||||
simp [Raw.Const.insertMany, m.2]
|
||||
|
||||
theorem Const.ofList_eq [BEq α] [Hashable α] {l : List (α × β)} :
|
||||
Raw.Const.ofList l = Raw₀.Const.insertMany Raw₀.empty l := by
|
||||
simp only [Raw.Const.ofList, Raw.Const.insertMany, (Raw.WF.empty).size_buckets_pos ∅, ↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem Const.insertManyIfNewUnit_eq {ρ : Type w} [ForIn Id ρ α] [BEq α] [Hashable α]
|
||||
{m : Raw α (fun _ => Unit)} {l : ρ} (h : m.WF):
|
||||
Raw.Const.insertManyIfNewUnit m l = Raw₀.Const.insertManyIfNewUnit ⟨m, h.size_buckets_pos⟩ l := by
|
||||
simp [Raw.Const.insertManyIfNewUnit, h.size_buckets_pos]
|
||||
|
||||
theorem Const.insertManyIfNewUnit_val {ρ : Type w} [ForIn Id ρ α] [BEq α] [Hashable α]
|
||||
{m : Raw₀ α (fun _ => Unit)} {l : ρ} :
|
||||
Raw.Const.insertManyIfNewUnit m.val l = Raw₀.Const.insertManyIfNewUnit m l := by
|
||||
simp [Raw.Const.insertManyIfNewUnit, m.2]
|
||||
|
||||
theorem Const.unitOfList_eq [BEq α] [Hashable α] {l : List α} :
|
||||
Raw.Const.unitOfList l = Raw₀.Const.insertManyIfNewUnit Raw₀.empty l := by
|
||||
simp only [Raw.Const.unitOfList, Raw.Const.insertManyIfNewUnit, (Raw.WF.empty).size_buckets_pos ∅,
|
||||
↓reduceDIte]
|
||||
congr
|
||||
|
||||
theorem Const.get?_eq [BEq α] [Hashable α] {m : Raw α (fun _ => β)} (h : m.WF) {a : α} :
|
||||
Raw.Const.get? m a = Raw₀.Const.get? ⟨m, h.size_buckets_pos⟩ a := by
|
||||
simp [Raw.Const.get?, h.size_buckets_pos]
|
||||
|
||||
@@ -70,9 +70,10 @@ variable [BEq α] [Hashable α]
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
scoped macro "wf_trivial" : tactic => `(tactic|
|
||||
repeat (first
|
||||
| apply Raw₀.wfImp_insert | apply Raw₀.wfImp_insertIfNew | apply Raw₀.wfImp_erase
|
||||
| apply Raw.WF.out | assumption | apply Raw₀.wfImp_empty | apply Raw.WFImp.distinct
|
||||
| apply Raw.WF.empty₀))
|
||||
| apply Raw₀.wfImp_insert | apply Raw₀.wfImp_insertIfNew | apply Raw₀.wfImp_insertMany
|
||||
| apply Raw₀.Const.wfImp_insertMany| apply Raw₀.Const.wfImp_insertManyIfNewUnit
|
||||
| apply Raw₀.wfImp_erase | apply Raw.WF.out | assumption | apply Raw₀.wfImp_empty
|
||||
| apply Raw.WFImp.distinct | apply Raw.WF.empty₀))
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
scoped macro "empty" : tactic => `(tactic| { intros; simp_all [List.isEmpty_iff] } )
|
||||
@@ -90,7 +91,9 @@ private def queryNames : Array Name :=
|
||||
``Raw.pairwise_keys_iff_pairwise_keys]
|
||||
|
||||
private def modifyNames : Array Name :=
|
||||
#[``toListModel_insert, ``toListModel_erase, ``toListModel_insertIfNew]
|
||||
#[``toListModel_insert, ``toListModel_erase, ``toListModel_insertIfNew,
|
||||
``toListModel_insertMany_list, ``Const.toListModel_insertMany_list,
|
||||
``Const.toListModel_insertManyIfNewUnit_list]
|
||||
|
||||
private def congrNames : MacroM (Array (TSyntax `term)) := do
|
||||
return #[← `(_root_.List.Perm.isEmpty_eq), ← `(containsKey_of_perm),
|
||||
@@ -820,8 +823,8 @@ theorem length_keys [EquivBEq α] [LawfulHashable α] (h : m.1.WF) :
|
||||
simp_to_model using List.length_keys_eq_length
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h: m.1.WF):
|
||||
m.1.keys.isEmpty = m.1.isEmpty:= by
|
||||
theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.1.WF) :
|
||||
m.1.keys.isEmpty = m.1.isEmpty := by
|
||||
simp_to_model using List.isEmpty_keys_eq_isEmpty
|
||||
|
||||
@[simp]
|
||||
@@ -839,6 +842,884 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] (h : m.1.WF) :
|
||||
m.1.keys.Pairwise (fun a b => (a == b) = false) := by
|
||||
simp_to_model using (Raw.WF.out h).distinct.distinct
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
m.insertMany [] = m := by
|
||||
simp [insertMany, Id.run]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β k} :
|
||||
m.insertMany [⟨k, v⟩] = m.insert k v := by
|
||||
simp [insertMany, Id.run]
|
||||
|
||||
theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} :
|
||||
(m.insertMany (⟨k, v⟩ :: l)).1 = ((m.insert k v).insertMany l).1 := by
|
||||
simp only [insertMany_eq_insertListₘ]
|
||||
cases l with
|
||||
| nil => simp [insertListₘ]
|
||||
| cons hd tl => simp [insertListₘ]
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(m.insertMany l).1.contains k = (m.contains k || (l.map Sigma.fst).contains k) := by
|
||||
simp_to_model using List.containsKey_insertList
|
||||
|
||||
theorem contains_of_contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(m.insertMany l).1.contains k → (l.map Sigma.fst).contains k = false → m.contains k := by
|
||||
simp_to_model using List.containsKey_of_containsKey_insertList
|
||||
|
||||
theorem get?_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(h' : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).1.get? k = m.get? k := by
|
||||
simp_to_model using getValueCast?_insertList_of_contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_mem [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).1.get? k' = some (cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v) := by
|
||||
simp_to_model using getValueCast?_insertList_of_mem
|
||||
|
||||
theorem get_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains : (l.map Sigma.fst).contains k = false)
|
||||
{h'} :
|
||||
(m.insertMany l).1.get k h' =
|
||||
m.get k (contains_of_contains_insertMany_list _ h h' contains) := by
|
||||
simp_to_model using getValueCast_insertList_of_contains_eq_false
|
||||
|
||||
theorem get_insertMany_list_of_mem [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h'} :
|
||||
(m.insertMany l).1.get k' h' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_model using getValueCast_insertList_of_mem
|
||||
|
||||
theorem get!_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(h' : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).1.get! k = m.get! k := by
|
||||
simp_to_model using getValueCast!_insertList_of_contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_mem [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} [Inhabited (β k')]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).1.get! k' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_model using getValueCast!_insertList_of_mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).1.getD k fallback = m.getD k fallback := by
|
||||
simp_to_model using getValueCastD_insertList_of_contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [LawfulBEq α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).1.getD k' fallback = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_model using getValueCastD_insertList_of_mem
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(h' : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).1.getKey? k = m.getKey? k := by
|
||||
simp_to_model using getKey?_insertList_of_contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).1.getKey? k' = some k := by
|
||||
simp_to_model using getKey?_insertList_of_mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(h₁ : (l.map Sigma.fst).contains k = false)
|
||||
{h'} :
|
||||
(m.insertMany l).1.getKey k h' =
|
||||
m.getKey k (contains_of_contains_insertMany_list _ h h' h₁) := by
|
||||
simp_to_model using getKey_insertList_of_contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst)
|
||||
{h'} :
|
||||
(m.insertMany l).1.getKey k' h' = k := by
|
||||
simp_to_model using getKey_insertList_of_mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h : m.1.WF) {l : List ((a : α) × β a)} {k : α}
|
||||
(h' : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).1.getKey! k = m.getKey! k := by
|
||||
simp_to_model using getKey!_insertList_of_contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).1.getKey! k' = k := by
|
||||
simp_to_model using getKey!_insertList_of_mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} {k fallback : α}
|
||||
(h' : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).1.getKeyD k fallback = m.getKeyD k fallback := by
|
||||
simp_to_model using getKeyD_insertList_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).1.getKeyD k' fallback = k := by
|
||||
simp_to_model using getKeyD_insertList_of_mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), m.contains a → (l.map Sigma.fst).contains a = false) →
|
||||
(m.insertMany l).1.1.size = m.1.size + l.length := by
|
||||
simp_to_model using length_insertList
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} :
|
||||
m.1.size ≤ (m.insertMany l).1.1.size := by
|
||||
simp_to_model using length_le_length_insertList
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} :
|
||||
(m.insertMany l).1.1.size ≤ m.1.size + l.length := by
|
||||
simp_to_model using length_insertList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ((a : α) × β a)} :
|
||||
(m.insertMany l).1.1.isEmpty = (m.1.isEmpty && l.isEmpty) := by
|
||||
simp_to_model using isEmpty_insertList
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} (m : Raw₀ α (fun _ => β))
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
insertMany m [] = m := by
|
||||
simp [insertMany, Id.run]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β} :
|
||||
insertMany m [⟨k, v⟩] = m.insert k v := by
|
||||
simp [insertMany, Id.run]
|
||||
|
||||
theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} :
|
||||
(insertMany m (⟨k, v⟩ :: l)).1 = (insertMany (m.insert k v) l).1 := by
|
||||
simp only [insertMany_eq_insertListₘ]
|
||||
cases l with
|
||||
| nil => simp [insertListₘ]
|
||||
| cons hd tl => simp [insertListₘ]
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
(Const.insertMany m l).1.contains k = (m.contains k || (l.map Prod.fst).contains k) := by
|
||||
simp_to_model using containsKey_insertListConst
|
||||
|
||||
theorem contains_of_contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List ( α × β )} {k : α} :
|
||||
(insertMany m l).1.contains k → (l.map Prod.fst).contains k = false → m.contains k := by
|
||||
simp_to_model using containsKey_of_containsKey_insertListConst
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(h' : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).1.getKey? k = m.getKey? k := by
|
||||
simp_to_model using getKey?_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).1.getKey? k' = some k := by
|
||||
simp_to_model using getKey?_insertListConst_of_mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(h₁ : (l.map Prod.fst).contains k = false)
|
||||
{h'} :
|
||||
(insertMany m l).1.getKey k h' =
|
||||
m.getKey k (contains_of_contains_insertMany_list _ h h' h₁) := by
|
||||
simp_to_model using getKey_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h'} :
|
||||
(insertMany m l).1.getKey k' h' = k := by
|
||||
simp_to_model using getKey_insertListConst_of_mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h : m.1.WF) {l : List (α × β)} {k : α}
|
||||
(h' : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).1.getKey! k = m.getKey! k := by
|
||||
simp_to_model using getKey!_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.1.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).1.getKey! k' = k := by
|
||||
simp_to_model using getKey!_insertListConst_of_mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(h' : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).1.getKeyD k fallback = m.getKeyD k fallback := by
|
||||
simp_to_model using getKeyD_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).1.getKeyD k' fallback = k := by
|
||||
simp_to_model using getKeyD_insertListConst_of_mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), m.contains a → (l.map Prod.fst).contains a = false) →
|
||||
(insertMany m l).1.1.size = m.1.size + l.length := by
|
||||
simp_to_model using length_insertListConst
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} :
|
||||
m.1.size ≤ (insertMany m l).1.1.size := by
|
||||
simp_to_model using length_le_length_insertListConst
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).1.1.size ≤ m.1.size + l.length := by
|
||||
simp_to_model using length_insertListConst_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).1.1.isEmpty = (m.1.isEmpty && l.isEmpty) := by
|
||||
simp_to_model using isEmpty_insertListConst
|
||||
|
||||
theorem get?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(h' : (l.map Prod.fst).contains k = false) :
|
||||
get? (insertMany m l).1 k = get? m k := by
|
||||
simp_to_model using getValue?_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
get? (insertMany m l).1 k' = v := by
|
||||
simp_to_model using getValue?_insertListConst_of_mem
|
||||
|
||||
theorem get_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(h₁ : (l.map Prod.fst).contains k = false)
|
||||
{h'} :
|
||||
get (insertMany m l).1 k h' = get m k (contains_of_contains_insertMany_list _ h h' h₁) := by
|
||||
simp_to_model using getValue_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem get_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) {h'} :
|
||||
get (insertMany m l).1 k' h' = v := by
|
||||
simp_to_model using getValue_insertListConst_of_mem
|
||||
|
||||
theorem get!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited β] (h : m.1.WF) {l : List (α × β)} {k : α}
|
||||
(h' : (l.map Prod.fst).contains k = false) :
|
||||
get! (insertMany m l).1 k = get! m k := by
|
||||
simp_to_model using getValue!_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
get! (insertMany m l).1 k' = v := by
|
||||
simp_to_model using getValue!_insertListConst_of_mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(h' : (l.map Prod.fst).contains k = false) :
|
||||
getD (insertMany m l).1 k fallback = getD m k fallback := by
|
||||
simp_to_model using getValueD_insertListConst_of_contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (insertMany m l).1 k' fallback = v := by
|
||||
simp_to_model using getValueD_insertListConst_of_mem
|
||||
|
||||
variable (m : Raw₀ α (fun _ => Unit))
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_nil :
|
||||
insertManyIfNewUnit m [] = m := by
|
||||
simp [insertManyIfNewUnit, Id.run]
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_list_singleton {k : α} :
|
||||
insertManyIfNewUnit m [k] = m.insertIfNew k () := by
|
||||
simp [insertManyIfNewUnit, Id.run]
|
||||
|
||||
theorem insertManyIfNewUnit_cons {l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m (k :: l)).1 = (insertManyIfNewUnit (m.insertIfNew k ()) l).1 := by
|
||||
simp only [insertManyIfNewUnit_eq_insertListIfNewUnitₘ]
|
||||
cases l with
|
||||
| nil => simp [insertListIfNewUnitₘ]
|
||||
| cons hd tl => simp [insertListIfNewUnitₘ]
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l).1.contains k = (m.contains k || l.contains k) := by
|
||||
simp_to_model using containsKey_insertListIfNewUnit
|
||||
|
||||
theorem contains_of_contains_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α} {k : α} (h₂ : l.contains k = false) :
|
||||
(insertManyIfNewUnit m l).1.contains k → m.contains k := by
|
||||
simp_to_model using containsKey_of_containsKey_insertListIfNewUnit
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k : α} :
|
||||
m.contains k = false → l.contains k = false → getKey? (insertManyIfNewUnit m l).1 k = none := by
|
||||
simp_to_model using getKey?_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k k' : α} (k_beq : k == k') :
|
||||
m.contains k = false → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKey? (insertManyIfNewUnit m l).1 k' = some k := by
|
||||
simp_to_model using getKey?_insertListIfNewUnit_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_contains [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k : α} :
|
||||
m.contains k → getKey? (insertManyIfNewUnit m l).1 k = getKey? m k := by
|
||||
simp_to_model using getKey?_insertListIfNewUnit_of_contains
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_contains [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k : α} {h'} (contains : m.contains k):
|
||||
getKey (insertManyIfNewUnit m l).1 k h' = getKey m k contains := by
|
||||
simp_to_model using getKey_insertListIfNewUnit_of_contains
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_contains_eq_false_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α}
|
||||
{k k' : α} (k_beq : k == k') {h'} :
|
||||
m.contains k = false → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKey (insertManyIfNewUnit m l).1 k' h' = k := by
|
||||
simp_to_model using getKey_insertListIfNewUnit_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_mem_of_contains [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k : α} (contains : m.contains k) {h'} :
|
||||
getKey (insertManyIfNewUnit m l).1 k h' = getKey m k contains := by
|
||||
simp_to_model using getKey_insertListIfNewUnit_of_contains
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.1.WF) {l : List α} {k : α} :
|
||||
m.contains k = false → l.contains k = false →
|
||||
getKey! (insertManyIfNewUnit m l).1 k = default := by
|
||||
simp_to_model using getKey!_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.1.WF) {l : List α} {k k' : α} (k_beq : k == k') :
|
||||
contains m k = false → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKey! (insertManyIfNewUnit m l).1 k' = k := by
|
||||
simp_to_model using getKey!_insertListIfNewUnit_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_contains [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.1.WF) {l : List α} {k : α} :
|
||||
m.contains k → getKey! (insertManyIfNewUnit m l).1 k = getKey! m k := by
|
||||
simp_to_model using getKey!_insertListIfNewUnit_of_contains
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.1.WF) {l : List α} {k fallback : α} :
|
||||
m.contains k = false → l.contains k = false → getKeyD (insertManyIfNewUnit m l).1 k fallback = fallback := by
|
||||
simp_to_model using getKeyD_insertListIfNewUnit_of_contains_eq_false_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k k' fallback : α} (k_beq : k == k') :
|
||||
m.contains k = false → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKeyD (insertManyIfNewUnit m l).1 k' fallback = k := by
|
||||
simp_to_model using getKeyD_insertListIfNewUnit_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_contains [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.1.WF) {l : List α} {k fallback : α} :
|
||||
m.contains k → getKeyD (insertManyIfNewUnit m l).1 k fallback = getKeyD m k fallback := by
|
||||
simp_to_model using getKeyD_insertListIfNewUnit_of_contains
|
||||
|
||||
theorem size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), m.contains a → l.contains a = false) →
|
||||
(insertManyIfNewUnit m l).1.1.size = m.1.size + l.length := by
|
||||
simp_to_model using length_insertListIfNewUnit
|
||||
|
||||
theorem size_le_size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α} :
|
||||
m.1.size ≤ (insertManyIfNewUnit m l).1.1.size := by
|
||||
simp_to_model using length_le_length_insertListIfNewUnit
|
||||
|
||||
theorem size_insertManyIfNewUnit_list_le [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).1.1.size ≤ m.1.size + l.length := by
|
||||
simp_to_model using length_insertListIfNewUnit_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).1.1.isEmpty = (m.1.isEmpty && l.isEmpty) := by
|
||||
simp_to_model using isEmpty_insertListIfNewUnit
|
||||
|
||||
theorem get?_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.1.WF)
|
||||
{l : List α} {k : α} :
|
||||
get? (insertManyIfNewUnit m l).1 k =
|
||||
if m.contains k ∨ l.contains k then some () else none := by
|
||||
simp_to_model using getValue?_insertListIfNewUnit
|
||||
|
||||
theorem get_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {h} :
|
||||
get (insertManyIfNewUnit m l).1 k h = () := by
|
||||
simp
|
||||
|
||||
theorem get!_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} :
|
||||
get! (insertManyIfNewUnit m l).1 k = () := by
|
||||
simp
|
||||
|
||||
theorem getD_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (insertManyIfNewUnit m l).1 k fallback = () := by
|
||||
simp
|
||||
|
||||
end Const
|
||||
|
||||
end Raw₀
|
||||
|
||||
namespace Raw₀
|
||||
|
||||
variable [BEq α] [Hashable α]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_empty_list_nil :
|
||||
(insertMany empty ([] : List ((a : α) × (β a)))).1 = empty := by
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_empty_list_singleton {k : α} {v : β k} :
|
||||
(insertMany empty [⟨k, v⟩]).1 = empty.insert k v := by
|
||||
simp
|
||||
|
||||
theorem insertMany_empty_list_cons {k : α} {v : β k}
|
||||
{tl : List ((a : α) × (β a))} :
|
||||
(insertMany empty (⟨k, v⟩ :: tl)).1 = ((empty.insert k v).insertMany tl).1 := by
|
||||
rw [insertMany_cons]
|
||||
|
||||
theorem contains_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(insertMany empty l).1.contains k = (l.map Sigma.fst).contains k := by
|
||||
simp [contains_insertMany_list _ Raw.WF.empty₀]
|
||||
|
||||
theorem get?_insertMany_empty_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(h : (l.map Sigma.fst).contains k = false) :
|
||||
(insertMany empty l).1.get? k = none := by
|
||||
simp [get?_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
|
||||
theorem get?_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany empty l).1.get? k' = some (cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v) := by
|
||||
rw [get?_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem get_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
(insertMany empty l).1.get k' h = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
rw [get_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem get!_insertMany_empty_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(h : (l.map Sigma.fst).contains k = false) :
|
||||
(insertMany empty l).1.get! k = default := by
|
||||
simp only [get!_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply get!_empty
|
||||
|
||||
theorem get!_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} [Inhabited (β k')]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany empty l).1.get! k' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
rw [get!_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getD_insertMany_empty_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(insertMany empty l).1.getD k fallback = fallback := by
|
||||
rw [getD_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ contains_eq_false]
|
||||
apply getD_empty
|
||||
|
||||
theorem getD_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany empty l).1.getD k' fallback =
|
||||
cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
rw [getD_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKey?_insertMany_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(h : (l.map Sigma.fst).contains k = false) :
|
||||
(insertMany empty l).1.getKey? k = none := by
|
||||
rw [getKey?_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply getKey?_empty
|
||||
|
||||
theorem getKey?_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(insertMany empty l).1.getKey? k' = some k := by
|
||||
rw [getKey?_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKey_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst)
|
||||
{h'} :
|
||||
(insertMany empty l).1.getKey k' h' = k := by
|
||||
rw [getKey_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKey!_insertMany_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List ((a : α) × β a)} {k : α}
|
||||
(h : (l.map Sigma.fst).contains k = false) :
|
||||
(insertMany empty l).1.getKey! k = default := by
|
||||
rw [getKey!_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply getKey!_empty
|
||||
|
||||
theorem getKey!_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(insertMany empty l).1.getKey! k' = k := by
|
||||
rw [getKey!_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKeyD_insertMany_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k fallback : α}
|
||||
(h : (l.map Sigma.fst).contains k = false) :
|
||||
(insertMany empty l).1.getKeyD k fallback = fallback := by
|
||||
rw [getKeyD_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply getKeyD_empty
|
||||
|
||||
theorem getKeyD_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(insertMany empty l).1.getKeyD k' fallback = k := by
|
||||
rw [getKeyD_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem size_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(insertMany empty l).1.1.size = l.length := by
|
||||
rw [size_insertMany_list _ Raw.WF.empty₀ distinct]
|
||||
· simp only [size_empty, Nat.zero_add]
|
||||
· simp only [contains_empty, Bool.false_eq_true, false_implies, implies_true]
|
||||
|
||||
theorem size_insertMany_empty_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(insertMany empty l).1.1.size ≤ l.length := by
|
||||
rw [← Nat.zero_add l.length]
|
||||
apply (size_insertMany_list_le _ Raw.WF.empty₀)
|
||||
|
||||
theorem isEmpty_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(insertMany empty l).1.1.isEmpty = l.isEmpty := by
|
||||
simp [isEmpty_insertMany_list _ Raw.WF.empty₀]
|
||||
|
||||
namespace Const
|
||||
variable {β : Type v}
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_empty_list_nil :
|
||||
(insertMany empty ([] : List (α × β))).1 = empty := by
|
||||
simp only [insertMany_nil]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_empty_list_singleton {k : α} {v : β} :
|
||||
(insertMany empty [⟨k, v⟩]).1 = empty.insert k v := by
|
||||
simp only [insertMany_list_singleton]
|
||||
|
||||
theorem insertMany_empty_list_cons {k : α} {v : β}
|
||||
{tl : List (α × β)} :
|
||||
(insertMany empty (⟨k, v⟩ :: tl)) = (insertMany (empty.insert k v) tl).1 := by
|
||||
rw [insertMany_cons]
|
||||
|
||||
theorem contains_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.contains k = (l.map Prod.fst).contains k := by
|
||||
simp [contains_insertMany_list _ Raw.WF.empty₀]
|
||||
|
||||
theorem get?_insertMany_empty_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(h : (l.map Prod.fst).contains k = false) :
|
||||
get? (insertMany (empty : Raw₀ α (fun _ => β)) l).1 k = none := by
|
||||
rw [get?_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply get?_empty
|
||||
|
||||
theorem get?_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
get? (insertMany (empty : Raw₀ α (fun _ => β)) l) k' = some v := by
|
||||
rw [get?_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem get_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
get (insertMany (empty : Raw₀ α (fun _ => β)) l) k' h = v := by
|
||||
rw [get_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem get!_insertMany_empty_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} [Inhabited β]
|
||||
(h : (l.map Prod.fst).contains k = false) :
|
||||
get! (insertMany (empty : Raw₀ α (fun _ => β)) l) k = (default : β) := by
|
||||
rw [get!_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply get!_empty
|
||||
|
||||
theorem get!_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} [Inhabited β]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
get! (insertMany (empty : Raw₀ α (fun _ => β)) l) k' = v := by
|
||||
rw [get!_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getD_insertMany_empty_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (insertMany (empty : Raw₀ α (fun _ => β)) l) k fallback = fallback := by
|
||||
rw [getD_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ contains_eq_false]
|
||||
apply getD_empty
|
||||
|
||||
theorem getD_insertMany_empty_list_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} {fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (insertMany (empty : Raw₀ α (fun _ => β)) l) k' fallback = v := by
|
||||
rw [getD_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKey?_insertMany_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(h : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKey? k = none := by
|
||||
rw [getKey?_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply getKey?_empty
|
||||
|
||||
theorem getKey?_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKey? k' = some k := by
|
||||
rw [getKey?_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKey_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h'} :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKey k' h' = k := by
|
||||
rw [getKey_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKey!_insertMany_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List (α × β)} {k : α}
|
||||
(h : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKey! k = default := by
|
||||
rw [getKey!_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply getKey!_empty
|
||||
|
||||
theorem getKey!_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKey! k' = k := by
|
||||
rw [getKey!_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem getKeyD_insertMany_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(h : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKeyD k fallback = fallback := by
|
||||
rw [getKeyD_insertMany_list_of_contains_eq_false _ Raw.WF.empty₀ h]
|
||||
apply getKeyD_empty
|
||||
|
||||
theorem getKeyD_insertMany_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.getKeyD k' fallback = k := by
|
||||
rw [getKeyD_insertMany_list_of_mem _ Raw.WF.empty₀ k_beq distinct mem]
|
||||
|
||||
theorem size_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.1.size = l.length := by
|
||||
rw [size_insertMany_list _ Raw.WF.empty₀ distinct]
|
||||
· simp only [size_empty, Nat.zero_add]
|
||||
· simp only [contains_empty, Bool.false_eq_true, false_implies, implies_true]
|
||||
|
||||
theorem size_insertMany_empty_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.1.size ≤ l.length := by
|
||||
rw [← Nat.zero_add l.length]
|
||||
apply (size_insertMany_list_le _ Raw.WF.empty₀)
|
||||
|
||||
theorem isEmpty_insertMany_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(insertMany (empty : Raw₀ α (fun _ => β)) l).1.1.isEmpty = l.isEmpty := by
|
||||
simp [isEmpty_insertMany_list _ Raw.WF.empty₀]
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_empty_list_nil :
|
||||
insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) ([] : List α) =
|
||||
(empty : Raw₀ α (fun _ => Unit)) := by
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_empty_list_singleton {k : α} :
|
||||
(insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) [k]).1 = empty.insertIfNew k () := by
|
||||
simp
|
||||
|
||||
theorem insertManyIfNewUnit_empty_list_cons {hd : α} {tl : List α} :
|
||||
insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) (hd :: tl) =
|
||||
(insertManyIfNewUnit (empty.insertIfNew hd ()) tl).1 := by
|
||||
rw [insertManyIfNewUnit_cons]
|
||||
|
||||
theorem contains_insertManyIfNewUnit_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1.contains k = l.contains k := by
|
||||
simp [contains_insertManyIfNewUnit_list _ Raw.WF.empty₀]
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (h' : l.contains k = false) :
|
||||
getKey? (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k = none := by
|
||||
exact getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false _ Raw.WF.empty₀
|
||||
contains_empty h'
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k' = some k := by
|
||||
exact getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_mem _ Raw.WF.empty₀ k_beq
|
||||
contains_empty distinct mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h'} :
|
||||
getKey (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k' h' = k := by
|
||||
exact getKey_insertManyIfNewUnit_list_of_contains_eq_false_of_mem _ Raw.WF.empty₀ k_beq
|
||||
contains_empty distinct mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(h' : l.contains k = false) :
|
||||
getKey! (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k = default := by
|
||||
exact getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false _ Raw.WF.empty₀
|
||||
contains_empty h'
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKey! (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k' = k := by
|
||||
exact getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_mem _ Raw.WF.empty₀ k_beq
|
||||
contains_empty distinct mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_empty_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(h' : l.contains k = false) :
|
||||
getKeyD (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k fallback = fallback := by
|
||||
exact getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
_ Raw.WF.empty₀ contains_empty h'
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_empty_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKeyD (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1 k' fallback = k := by
|
||||
exact getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_mem _ Raw.WF.empty₀ k_beq
|
||||
contains_empty distinct mem
|
||||
|
||||
theorem size_insertManyIfNewUnit_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1.1.size = l.length := by
|
||||
simp [size_insertManyIfNewUnit_list _ Raw.WF.empty₀ distinct]
|
||||
|
||||
theorem size_insertManyIfNewUnit_empty_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1.1.size ≤ l.length := by
|
||||
apply Nat.le_trans (size_insertManyIfNewUnit_list_le _ Raw.WF.empty₀)
|
||||
simp
|
||||
|
||||
theorem isEmpty_insertManyIfNewUnit_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l).1.1.isEmpty = l.isEmpty := by
|
||||
rw [isEmpty_insertManyIfNewUnit_list _ Raw.WF.empty₀]
|
||||
simp
|
||||
|
||||
theorem get?_insertManyIfNewUnit_empty_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
get? (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l) k =
|
||||
if l.contains k then some () else none := by
|
||||
rw [get?_insertManyIfNewUnit_list _ Raw.WF.empty₀]
|
||||
simp
|
||||
|
||||
theorem get_insertManyIfNewUnit_empty_list
|
||||
{l : List α} {k : α} {h} :
|
||||
get (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l) k h = () := by
|
||||
simp
|
||||
|
||||
theorem get!_insertManyIfNewUnit_empty_list
|
||||
{l : List α} {k : α} :
|
||||
get! (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l) k = () := by
|
||||
simp
|
||||
|
||||
theorem getD_insertManyIfNewUnit_empty_list
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (insertManyIfNewUnit (empty : Raw₀ α (fun _ => Unit)) l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Const
|
||||
|
||||
end Raw₀
|
||||
|
||||
end Std.DHashMap.Internal
|
||||
|
||||
@@ -29,8 +29,8 @@ open List
|
||||
namespace Std.DHashMap.Internal
|
||||
|
||||
@[simp]
|
||||
theorem toListModel_mkArray_nil {c} :
|
||||
toListModel (mkArray c (AssocList.nil : AssocList α β)) = [] := by
|
||||
theorem toListModel_replicate_nil {c} :
|
||||
toListModel (Array.replicate c (AssocList.nil : AssocList α β)) = [] := by
|
||||
suffices ∀ d, (List.replicate d AssocList.nil).flatMap AssocList.toList = [] from this _
|
||||
intro d
|
||||
induction d <;> simp_all [List.replicate]
|
||||
@@ -143,7 +143,7 @@ namespace Raw₀
|
||||
|
||||
@[simp]
|
||||
theorem toListModel_buckets_empty {c} : toListModel (empty c : Raw₀ α β).1.buckets = [] :=
|
||||
toListModel_mkArray_nil
|
||||
toListModel_replicate_nil
|
||||
|
||||
theorem wfImp_empty [BEq α] [Hashable α] {c} : Raw.WFImp (empty c : Raw₀ α β).1 where
|
||||
buckets_hash_self := by simp [Raw.empty, Raw₀.empty]
|
||||
@@ -229,7 +229,7 @@ theorem toListModel_expand [BEq α] [Hashable α] [PartialEquivBEq α]
|
||||
{buckets : {d : Array (AssocList α β) // 0 < d.size}} :
|
||||
Perm (toListModel (expand buckets).1) (toListModel buckets.1) := by
|
||||
simpa [expand, expand.go_eq] using toListModel_foldl_reinsertAux (toListModel buckets.1)
|
||||
⟨mkArray (buckets.1.size * 2) .nil, by simpa using Nat.mul_pos buckets.2 Nat.two_pos⟩
|
||||
⟨Array.replicate (buckets.1.size * 2) .nil, by simpa using Nat.mul_pos buckets.2 Nat.two_pos⟩
|
||||
|
||||
theorem toListModel_expandIfNecessary [BEq α] [Hashable α] [PartialEquivBEq α] (m : Raw₀ α β) :
|
||||
Perm (toListModel (expandIfNecessary m).1.2) (toListModel m.1.2) := by
|
||||
@@ -789,7 +789,7 @@ theorem Const.toListModel_getThenInsertIfNew? {β : Type v} [BEq α] [Hashable
|
||||
exact toListModel_insertIfNewₘ h
|
||||
|
||||
theorem Const.wfImp_getThenInsertIfNew? {β : Type v} [BEq α] [Hashable α] [EquivBEq α]
|
||||
[LawfulHashable α] {m : Raw₀ α (fun _ => β)} {a : α} {b : β} (h : Raw.WFImp m.1):
|
||||
[LawfulHashable α] {m : Raw₀ α (fun _ => β)} {a : α} {b : β} (h : Raw.WFImp m.1) :
|
||||
Raw.WFImp (Const.getThenInsertIfNew? m a b).2.1 := by
|
||||
rw [getThenInsertIfNew?_eq_insertIfNewₘ]
|
||||
exact wfImp_insertIfNewₘ h
|
||||
@@ -955,6 +955,20 @@ theorem wfImp_filter [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α] {m
|
||||
rw [filter_eq_filterₘ]
|
||||
exact wfImp_filterₘ h
|
||||
|
||||
/-! # `insertListₘ` -/
|
||||
|
||||
theorem toListModel_insertListₘ [BEq α] [Hashable α] [EquivBEq α][LawfulHashable α]
|
||||
{m : Raw₀ α β} {l : List ((a : α) × β a)} (h : Raw.WFImp m.1) :
|
||||
Perm (toListModel (insertListₘ m l).1.buckets)
|
||||
(List.insertList (toListModel m.1.buckets) l) := by
|
||||
induction l generalizing m with
|
||||
| nil =>
|
||||
simp [insertListₘ, List.insertList]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListₘ, List.insertList]
|
||||
apply Perm.trans (ih (wfImp_insert h))
|
||||
apply List.insertList_perm_of_perm_first (toListModel_insert h) (wfImp_insert h).distinct
|
||||
|
||||
end Raw₀
|
||||
|
||||
namespace Raw
|
||||
@@ -981,16 +995,72 @@ end Raw
|
||||
|
||||
namespace Raw₀
|
||||
|
||||
/-! # `insertMany` -/
|
||||
|
||||
theorem wfImp_insertMany [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α] {ρ : Type w}
|
||||
[ForIn Id ρ ((a : α) × β a)] {m : Raw₀ α β} {l : ρ} (h : Raw.WFImp m.1) :
|
||||
Raw.WFImp (m.insertMany l).1.1 :=
|
||||
Raw.WF.out ((m.insertMany l).2 _ Raw.WF.insert₀ (.wf m.2 h))
|
||||
|
||||
theorem toListModel_insertMany_list [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
|
||||
{m : Raw₀ α β} {l : List ((a : α) × (β a))} (h : Raw.WFImp m.1) :
|
||||
Perm (toListModel (insertMany m l).1.1.buckets)
|
||||
(List.insertList (toListModel m.1.buckets) l) := by
|
||||
rw [insertMany_eq_insertListₘ]
|
||||
apply toListModel_insertListₘ
|
||||
exact h
|
||||
|
||||
/-! # `Const.insertListₘ` -/
|
||||
|
||||
theorem Const.toListModel_insertListₘ {β : Type v} [BEq α] [Hashable α] [EquivBEq α]
|
||||
[LawfulHashable α] {m : Raw₀ α (fun _ => β)} {l : List (α × β)} (h : Raw.WFImp m.1) :
|
||||
Perm (toListModel (Const.insertListₘ m l).1.buckets)
|
||||
(insertListConst (toListModel m.1.buckets) l) := by
|
||||
induction l generalizing m with
|
||||
| nil => simp [Const.insertListₘ, insertListConst, insertList]
|
||||
| cons hd tl ih =>
|
||||
simp only [Const.insertListₘ, insertListConst]
|
||||
apply Perm.trans (ih (wfImp_insert h))
|
||||
unfold insertListConst
|
||||
apply List.insertList_perm_of_perm_first (toListModel_insert h) (wfImp_insert h).distinct
|
||||
|
||||
/-! # `Const.insertMany` -/
|
||||
|
||||
theorem Const.toListModel_insertMany_list {β : Type v} [BEq α] [Hashable α] [EquivBEq α]
|
||||
[LawfulHashable α] {m : Raw₀ α (fun _ => β)} {l : List (α × β)} (h : Raw.WFImp m.1) :
|
||||
Perm (toListModel (Const.insertMany m l).1.1.buckets)
|
||||
(insertListConst (toListModel m.1.buckets) l) := by
|
||||
rw [Const.insertMany_eq_insertListₘ]
|
||||
apply toListModel_insertListₘ h
|
||||
|
||||
theorem Const.wfImp_insertMany {β : Type v} [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
|
||||
{ρ : Type w} [ForIn Id ρ (α × β)] {m : Raw₀ α (fun _ => β)}
|
||||
{l : ρ} (h : Raw.WFImp m.1) : Raw.WFImp (Const.insertMany m l).1.1 :=
|
||||
Raw.WF.out ((Const.insertMany m l).2 _ Raw.WF.insert₀ (.wf m.2 h))
|
||||
|
||||
/-! # `Const.insertListIfNewUnitₘ` -/
|
||||
|
||||
theorem Const.toListModel_insertListIfNewUnitₘ [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
|
||||
{m : Raw₀ α (fun _ => Unit)} {l : List α} (h : Raw.WFImp m.1) :
|
||||
Perm (toListModel (Const.insertListIfNewUnitₘ m l).1.buckets)
|
||||
(List.insertListIfNewUnit (toListModel m.1.buckets) l) := by
|
||||
induction l generalizing m with
|
||||
| nil => simp [insertListIfNewUnitₘ, List.insertListIfNewUnit]
|
||||
| cons hd tl ih =>
|
||||
simp only [insertListIfNewUnitₘ, insertListIfNewUnit]
|
||||
apply Perm.trans (ih (wfImp_insertIfNew h))
|
||||
apply List.insertListIfNewUnit_perm_of_perm_first (toListModel_insertIfNew h)
|
||||
apply (wfImp_insertIfNew h).distinct
|
||||
|
||||
/-! # `Const.insertManyIfNewUnit` -/
|
||||
|
||||
theorem Const.toListModel_insertManyIfNewUnit_list [BEq α] [Hashable α] [EquivBEq α]
|
||||
[LawfulHashable α] {m : Raw₀ α (fun _ => Unit)} {l : List α} (h : Raw.WFImp m.1) :
|
||||
Perm (toListModel (Const.insertManyIfNewUnit m l).1.1.buckets)
|
||||
(List.insertListIfNewUnit (toListModel m.1.buckets) l) := by
|
||||
rw [Const.insertManyIfNewUnit_eq_insertListIfNewUnitₘ]
|
||||
apply toListModel_insertListIfNewUnitₘ h
|
||||
|
||||
theorem Const.wfImp_insertManyIfNewUnit [BEq α] [Hashable α] [EquivBEq α] [LawfulHashable α]
|
||||
{ρ : Type w} [ForIn Id ρ α] {m : Raw₀ α (fun _ => Unit)} {l : ρ} (h : Raw.WFImp m.1) :
|
||||
Raw.WFImp (Const.insertManyIfNewUnit m l).1.1 :=
|
||||
|
||||
@@ -913,7 +913,6 @@ theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] {k a fallback : α
|
||||
simp [mem_iff_contains, contains_insertIfNew]
|
||||
exact Raw₀.getKeyD_insertIfNew ⟨m.1, _⟩ m.2
|
||||
|
||||
|
||||
@[simp]
|
||||
theorem getThenInsertIfNew?_fst [LawfulBEq α] {k : α} {v : β k} :
|
||||
(m.getThenInsertIfNew? k v).1 = m.get? k :=
|
||||
@@ -964,4 +963,907 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] :
|
||||
m.keys.Pairwise (fun a b => (a == b) = false) :=
|
||||
Raw₀.distinct_keys ⟨m.1, m.2.size_buckets_pos⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
m.insertMany [] = m :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_nil ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β k} :
|
||||
m.insertMany [⟨k, v⟩] = m.insert k v :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_list_singleton ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} :
|
||||
m.insertMany (⟨k, v⟩ :: l) = (m.insert k v).insertMany l :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_cons ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(m.insertMany l).contains k = (m.contains k || (l.map Sigma.fst).contains k) :=
|
||||
Raw₀.contains_insertMany_list ⟨m.1, _⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
k ∈ m.insertMany l ↔ k ∈ m ∨ (l.map Sigma.fst).contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} (mem : k ∈ m.insertMany l)
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
k ∈ m :=
|
||||
Raw₀.contains_of_contains_insertMany_list ⟨m.1, _⟩ m.2 mem contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).get? k = m.get? k :=
|
||||
Raw₀.get?_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).get? k' = some (cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v) :=
|
||||
Raw₀.get?_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem get_insertMany_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false)
|
||||
{h} :
|
||||
(m.insertMany l).get k h =
|
||||
m.get k (mem_of_mem_insertMany_list h contains_eq_false) :=
|
||||
Raw₀.get_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem get_insertMany_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
(m.insertMany l).get k' h = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v :=
|
||||
Raw₀.get_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem get!_insertMany_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).get! k = m.get! k :=
|
||||
Raw₀.get!_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} [Inhabited (β k')]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).get! k' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v :=
|
||||
Raw₀.get!_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getD k fallback = m.getD k fallback :=
|
||||
Raw₀.getD_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).getD k' fallback = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v :=
|
||||
Raw₀.getD_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getKey? k = m.getKey? k :=
|
||||
Raw₀.getKey?_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).getKey? k' = some k :=
|
||||
Raw₀.getKey?_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false)
|
||||
{h} :
|
||||
(m.insertMany l).getKey k h =
|
||||
m.getKey k (mem_of_mem_insertMany_list h contains_eq_false) :=
|
||||
Raw₀.getKey_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst)
|
||||
{h} :
|
||||
(m.insertMany l).getKey k' h = k :=
|
||||
Raw₀.getKey_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getKey! k = m.getKey! k :=
|
||||
Raw₀.getKey!_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).getKey! k' = k :=
|
||||
Raw₀.getKey!_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getKeyD k fallback = m.getKeyD k fallback :=
|
||||
Raw₀.getKeyD_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).getKeyD k' fallback = k :=
|
||||
Raw₀.getKeyD_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), a ∈ m → (l.map Sigma.fst).contains a = false) →
|
||||
(m.insertMany l).size = m.size + l.length :=
|
||||
Raw₀.size_insertMany_list ⟨m.1, _⟩ m.2 distinct
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
m.size ≤ (m.insertMany l).size :=
|
||||
Raw₀.size_le_size_insertMany_list ⟨m.1, _⟩ m.2
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(m.insertMany l).size ≤ m.size + l.length :=
|
||||
Raw₀.size_insertMany_list_le ⟨m.1, _⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(m.insertMany l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
Raw₀.isEmpty_insertMany_list ⟨m.1, _⟩ m.2
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m : DHashMap α (fun _ => β)}
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
insertMany m [] = m :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_nil ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β} :
|
||||
insertMany m [⟨k, v⟩] = m.insert k v :=
|
||||
Subtype.eq (congrArg Subtype.val
|
||||
(Raw₀.Const.insertMany_list_singleton ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} :
|
||||
insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_cons ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(Const.insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) :=
|
||||
Raw₀.Const.contains_insertMany_list ⟨m.1, _⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} (mem : k ∈ insertMany m l)
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
k ∈ m :=
|
||||
Raw₀.Const.contains_of_contains_insertMany_list ⟨m.1, _⟩ m.2 mem contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey? k = m.getKey? k :=
|
||||
Raw₀.Const.getKey?_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey? k' = some k :=
|
||||
Raw₀.Const.getKey?_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h} :
|
||||
(insertMany m l).getKey k h =
|
||||
m.getKey k (mem_of_mem_insertMany_list h contains_eq_false) :=
|
||||
Raw₀.Const.getKey_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h} :
|
||||
(insertMany m l).getKey k' h = k :=
|
||||
Raw₀.Const.getKey_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey! k = m.getKey! k :=
|
||||
Raw₀.Const.getKey!_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey! k' = k :=
|
||||
Raw₀.Const.getKey!_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKeyD k fallback = m.getKeyD k fallback :=
|
||||
Raw₀.Const.getKeyD_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKeyD k' fallback = k :=
|
||||
Raw₀.Const.getKeyD_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), a ∈ m → (l.map Prod.fst).contains a = false) →
|
||||
(insertMany m l).size = m.size + l.length :=
|
||||
Raw₀.Const.size_insertMany_list ⟨m.1, _⟩ m.2 distinct
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
m.size ≤ (insertMany m l).size :=
|
||||
Raw₀.Const.size_le_size_insertMany_list ⟨m.1, _⟩ m.2
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).size ≤ m.size + l.length :=
|
||||
Raw₀.Const.size_insertMany_list_le ⟨m.1, _⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
Raw₀.Const.isEmpty_insertMany_list ⟨m.1, _⟩ m.2
|
||||
|
||||
theorem get?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get? (insertMany m l) k = get? m k :=
|
||||
Raw₀.Const.get?_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
get? (insertMany m l) k' = v :=
|
||||
Raw₀.Const.get?_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem get_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h} :
|
||||
get (insertMany m l) k h = get m k (mem_of_mem_insertMany_list h contains_eq_false) :=
|
||||
Raw₀.Const.get_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem get_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) {h} :
|
||||
get (insertMany m l) k' h = v :=
|
||||
Raw₀.Const.get_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem get!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited β] {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get! (insertMany m l) k = get! m k :=
|
||||
Raw₀.Const.get!_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited β]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
get! (insertMany m l) k' = v :=
|
||||
Raw₀.Const.get!_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (insertMany m l) k fallback = getD m k fallback :=
|
||||
Raw₀.Const.getD_insertMany_list_of_contains_eq_false ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (insertMany m l) k' fallback = v :=
|
||||
Raw₀.Const.getD_insertMany_list_of_mem ⟨m.1, _⟩ m.2 k_beq distinct mem
|
||||
|
||||
variable {m : DHashMap α (fun _ => Unit)}
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_nil :
|
||||
insertManyIfNewUnit m [] = m :=
|
||||
Subtype.eq (congrArg Subtype.val
|
||||
(Raw₀.Const.insertManyIfNewUnit_nil ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_list_singleton {k : α} :
|
||||
insertManyIfNewUnit m [k] = m.insertIfNew k () :=
|
||||
Subtype.eq (congrArg Subtype.val
|
||||
(Raw₀.Const.insertManyIfNewUnit_list_singleton ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
theorem insertManyIfNewUnit_cons {l : List α} {k : α} :
|
||||
insertManyIfNewUnit m (k :: l) = insertManyIfNewUnit (m.insertIfNew k ()) l :=
|
||||
Subtype.eq (congrArg Subtype.val
|
||||
(Raw₀.Const.insertManyIfNewUnit_cons ⟨m.1, m.2.size_buckets_pos⟩) :)
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l).contains k = (m.contains k || l.contains k) :=
|
||||
Raw₀.Const.contains_insertManyIfNewUnit_list ⟨m.1, _⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ insertManyIfNewUnit m l ↔ k ∈ m ∨ l.contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem mem_of_mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
k ∈ insertManyIfNewUnit m l → k ∈ m :=
|
||||
Raw₀.Const.contains_of_contains_insertManyIfNewUnit_list ⟨m.1, _⟩ m.2 contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKey? (insertManyIfNewUnit m l) k = none := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
⟨m.1, _⟩ m.2 not_mem contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (insertManyIfNewUnit m l) k' = some k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_mem ⟨m.1, _⟩
|
||||
m.2 k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (h' : k ∈ m) :
|
||||
getKey? (insertManyIfNewUnit m l) k = getKey? m k :=
|
||||
Raw₀.Const.getKey?_insertManyIfNewUnit_list_of_contains ⟨m.1, _⟩ m.2 h'
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m) (distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h} :
|
||||
getKey (insertManyIfNewUnit m l) k' h = k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKey_insertManyIfNewUnit_list_of_contains_eq_false_of_mem ⟨m.1, _⟩ m.2 k_beq
|
||||
not_mem distinct mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (mem : k ∈ m) {h} :
|
||||
getKey (insertManyIfNewUnit m l) k h = getKey m k mem :=
|
||||
Raw₀.Const.getKey_insertManyIfNewUnit_list_of_contains ⟨m.1, _⟩ m.2 _
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKey! (insertManyIfNewUnit m l) k = default := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
⟨m.1, _⟩ m.2 not_mem contains_eq_false
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m) (distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKey! (insertManyIfNewUnit m l) k' = k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_mem ⟨m.1, _⟩ m.2 k_beq
|
||||
not_mem distinct mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α} (mem : k ∈ m) :
|
||||
getKey! (insertManyIfNewUnit m l) k = getKey! m k :=
|
||||
Raw₀.Const.getKey!_insertManyIfNewUnit_list_of_contains ⟨m.1, _⟩ m.2 mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] {l : List α} {k fallback : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = fallback := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
⟨m.1, _⟩ m.2 not_mem contains_eq_false
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKeyD (insertManyIfNewUnit m l) k' fallback = k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true] at not_mem
|
||||
exact Raw₀.Const.getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_mem ⟨m.1, _⟩ m.2 k_beq
|
||||
not_mem distinct mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α} (mem : k ∈ m) :
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = getKeyD m k fallback :=
|
||||
Raw₀.Const.getKeyD_insertManyIfNewUnit_list_of_contains ⟨m.1, _⟩ m.2 mem
|
||||
|
||||
theorem size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), a ∈ m → l.contains a = false) →
|
||||
(insertManyIfNewUnit m l).size = m.size + l.length :=
|
||||
Raw₀.Const.size_insertManyIfNewUnit_list ⟨m.1, _⟩ m.2 distinct
|
||||
|
||||
theorem size_le_size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
m.size ≤ (insertManyIfNewUnit m l).size :=
|
||||
Raw₀.Const.size_le_size_insertManyIfNewUnit_list ⟨m.1, _⟩ m.2
|
||||
|
||||
theorem size_insertManyIfNewUnit_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).size ≤ m.size + l.length :=
|
||||
Raw₀.Const.size_insertManyIfNewUnit_list_le ⟨m.1, _⟩ m.2
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
Raw₀.Const.isEmpty_insertManyIfNewUnit_list ⟨m.1, _⟩ m.2
|
||||
|
||||
theorem get?_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
get? (insertManyIfNewUnit m l) k =
|
||||
if k ∈ m ∨ l.contains k then some () else none :=
|
||||
Raw₀.Const.get?_insertManyIfNewUnit_list ⟨m.1, _⟩ m.2
|
||||
|
||||
theorem get_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {h} :
|
||||
get (insertManyIfNewUnit m l) k h = () :=
|
||||
Raw₀.Const.get_insertManyIfNewUnit_list ⟨m.1, _⟩
|
||||
|
||||
theorem get!_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} :
|
||||
get! (insertManyIfNewUnit m l) k = () :=
|
||||
Raw₀.Const.get!_insertManyIfNewUnit_list ⟨m.1, _⟩
|
||||
|
||||
theorem getD_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (insertManyIfNewUnit m l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Const
|
||||
|
||||
end DHashMap
|
||||
|
||||
namespace DHashMap
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List ((a : α) × (β a))) = ∅ :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_empty_list_nil (α := α)) :)
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} {v : β k} :
|
||||
ofList [⟨k, v⟩] = (∅: DHashMap α β).insert k v :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_empty_list_singleton (α := α)) :)
|
||||
|
||||
theorem ofList_cons {k : α} {v : β k} {tl : List ((a : α) × (β a))} :
|
||||
ofList (⟨k, v⟩ :: tl) = ((∅ : DHashMap α β).insert k v).insertMany tl :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.insertMany_empty_list_cons (α := α)) :)
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(ofList l).contains k = (l.map Sigma.fst).contains k :=
|
||||
Raw₀.contains_insertMany_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
k ∈ ofList l ↔ (l.map Sigma.fst).contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem get?_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).get? k = none :=
|
||||
Raw₀.get?_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get?_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l).get? k' = some (cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v) :=
|
||||
Raw₀.get?_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem get_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
(ofList l).get k' h = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v :=
|
||||
Raw₀.get_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem get!_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).get! k = default :=
|
||||
Raw₀.get!_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get!_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} [Inhabited (β k')]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l).get! k' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v :=
|
||||
Raw₀.get!_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getD k fallback = fallback :=
|
||||
Raw₀.getD_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l).getD k' fallback = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v :=
|
||||
Raw₀.getD_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getKey? k = none :=
|
||||
Raw₀.getKey?_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(ofList l).getKey? k' = some k :=
|
||||
Raw₀.getKey?_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst)
|
||||
{h} :
|
||||
(ofList l).getKey k' h = k :=
|
||||
Raw₀.getKey_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getKey! k = default :=
|
||||
Raw₀.getKey!_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_ofList_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(ofList l).getKey! k' = k :=
|
||||
Raw₀.getKey!_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getKeyD k fallback = fallback :=
|
||||
Raw₀.getKeyD_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(ofList l).getKeyD k' fallback = k :=
|
||||
Raw₀.getKeyD_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(ofList l).size = l.length :=
|
||||
Raw₀.size_insertMany_empty_list distinct
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(ofList l).size ≤ l.length :=
|
||||
Raw₀.size_insertMany_empty_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(ofList l).isEmpty = l.isEmpty :=
|
||||
Raw₀.isEmpty_insertMany_empty_list
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List (α × β)) = ∅ :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_empty_list_nil (α:= α)) :)
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} {v : β} :
|
||||
ofList [⟨k, v⟩] = (∅ : DHashMap α (fun _ => β)).insert k v :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_empty_list_singleton (α:= α)) :)
|
||||
|
||||
theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} :
|
||||
ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : DHashMap α (fun _ => β)).insert k v) tl :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertMany_empty_list_cons (α:= α)) :)
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(ofList l).contains k = (l.map Prod.fst).contains k :=
|
||||
Raw₀.Const.contains_insertMany_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ ofList l ↔ (l.map Prod.fst).contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem get?_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get? (ofList l) k = none :=
|
||||
Raw₀.Const.get?_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get?_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
get? (ofList l) k' = some v :=
|
||||
Raw₀.Const.get?_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem get_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
get (ofList l) k' h = v :=
|
||||
Raw₀.Const.get_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem get!_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} [Inhabited β]
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get! (ofList l) k = (default : β) :=
|
||||
Raw₀.Const.get!_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get!_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} [Inhabited β]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
get! (ofList l) k' = v :=
|
||||
Raw₀.Const.get!_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (ofList l) k fallback = fallback :=
|
||||
Raw₀.Const.getD_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} {fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (ofList l) k' fallback = v :=
|
||||
Raw₀.Const.getD_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey? k = none :=
|
||||
Raw₀.Const.getKey?_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey? k' = some k :=
|
||||
Raw₀.Const.getKey?_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h} :
|
||||
(ofList l).getKey k' h = k :=
|
||||
Raw₀.Const.getKey_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey! k = default :=
|
||||
Raw₀.Const.getKey!_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_ofList_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey! k' = k :=
|
||||
Raw₀.Const.getKey!_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKeyD k fallback = fallback :=
|
||||
Raw₀.Const.getKeyD_insertMany_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKeyD k' fallback = k :=
|
||||
Raw₀.Const.getKeyD_insertMany_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(ofList l).size = l.length :=
|
||||
Raw₀.Const.size_insertMany_empty_list distinct
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).size ≤ l.length :=
|
||||
Raw₀.Const.size_insertMany_empty_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).isEmpty = l.isEmpty :=
|
||||
Raw₀.Const.isEmpty_insertMany_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_nil :
|
||||
unitOfList ([] : List α) = ∅ :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertManyIfNewUnit_empty_list_nil (α := α)) :)
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_singleton {k : α} :
|
||||
unitOfList [k] = (∅ : DHashMap α (fun _ => Unit)).insertIfNew k () :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertManyIfNewUnit_empty_list_singleton (α := α)) :)
|
||||
|
||||
theorem unitOfList_cons {hd : α} {tl : List α} :
|
||||
unitOfList (hd :: tl) =
|
||||
insertManyIfNewUnit ((∅ : DHashMap α (fun _ => Unit)).insertIfNew hd ()) tl :=
|
||||
Subtype.eq (congrArg Subtype.val (Raw₀.Const.insertManyIfNewUnit_empty_list_cons (α := α)) :)
|
||||
|
||||
@[simp]
|
||||
theorem contains_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l).contains k = l.contains k :=
|
||||
Raw₀.Const.contains_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ unitOfList l ↔ l.contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem getKey?_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
getKey? (unitOfList l) k = none :=
|
||||
Raw₀.Const.getKey?_insertManyIfNewUnit_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (unitOfList l) k' = some k :=
|
||||
Raw₀.Const.getKey?_insertManyIfNewUnit_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h} :
|
||||
getKey (unitOfList l) k' h = k :=
|
||||
Raw₀.Const.getKey_insertManyIfNewUnit_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKey! (unitOfList l) k = default :=
|
||||
Raw₀.Const.getKey!_insertManyIfNewUnit_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKey! (unitOfList l) k' = k :=
|
||||
Raw₀.Const.getKey!_insertManyIfNewUnit_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKeyD (unitOfList l) k fallback = fallback :=
|
||||
Raw₀.Const.getKeyD_insertManyIfNewUnit_empty_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKeyD (unitOfList l) k' fallback = k :=
|
||||
Raw₀.Const.getKeyD_insertManyIfNewUnit_empty_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(unitOfList l).size = l.length :=
|
||||
Raw₀.Const.size_insertManyIfNewUnit_empty_list distinct
|
||||
|
||||
theorem size_unitOfList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).size ≤ l.length :=
|
||||
Raw₀.Const.size_insertManyIfNewUnit_empty_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).isEmpty = l.isEmpty :=
|
||||
Raw₀.Const.isEmpty_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem get?_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
get? (unitOfList l) k =
|
||||
if l.contains k then some () else none :=
|
||||
Raw₀.Const.get?_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem get_unitOfList
|
||||
{l : List α} {k : α} {h} :
|
||||
get (unitOfList l) k h = () :=
|
||||
Raw₀.Const.get_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem get!_unitOfList
|
||||
{l : List α} {k : α} :
|
||||
get! (unitOfList l) k = () :=
|
||||
Raw₀.Const.get!_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem getD_unitOfList
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (unitOfList l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Const
|
||||
|
||||
end Std.DHashMap
|
||||
|
||||
@@ -94,7 +94,7 @@ Checks whether a key is present in a map, and unconditionally inserts a value fo
|
||||
Equivalent to (but potentially faster than) calling `contains` followed by `insert`.
|
||||
-/
|
||||
@[inline] def containsThenInsert [BEq α] [Hashable α] (m : Raw α β) (a : α) (b : β a) :
|
||||
Bool × Raw α β:=
|
||||
Bool × Raw α β :=
|
||||
if h : 0 < m.buckets.size then
|
||||
let ⟨replaced, ⟨r, _⟩⟩ := Raw₀.containsThenInsert ⟨m, h⟩ a b
|
||||
⟨replaced, r⟩
|
||||
@@ -422,29 +422,12 @@ This is mainly useful to implement `HashSet.insertMany`, so if you are consideri
|
||||
(Raw₀.Const.insertManyIfNewUnit ⟨m, h⟩ l).1
|
||||
else m -- will never happen for well-formed inputs
|
||||
|
||||
/-- Creates a hash map from a list of mappings. If the same key appears multiple times, the last
|
||||
occurrence takes precedence. -/
|
||||
@[inline] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) : Raw α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
/-- Computes the union of the given hash maps, by traversing `m₂` and inserting its elements into `m₁`. -/
|
||||
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : Raw α β) : Raw α β :=
|
||||
m₂.fold (init := m₁) fun acc x => acc.insert x
|
||||
|
||||
instance [BEq α] [Hashable α] : Union (Raw α β) := ⟨union⟩
|
||||
|
||||
@[inline, inherit_doc Raw.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : Raw α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
/-- Creates a hash map from a list of keys, associating the value `()` with each key.
|
||||
|
||||
This is mainly useful to implement `HashSet.ofList`, so if you are considering using this,
|
||||
`HashSet` or `HashSet.Raw` might be a better fit for you. -/
|
||||
@[inline] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
Raw α (fun _ => Unit) :=
|
||||
Const.insertManyIfNewUnit ∅ l
|
||||
|
||||
/-- Creates a hash map from an array of keys, associating the value `()` with each key.
|
||||
|
||||
This is mainly useful to implement `HashSet.ofArray`, so if you are considering using this,
|
||||
@@ -470,6 +453,23 @@ end Unverified
|
||||
@[inline] def keys (m : Raw α β) : List α :=
|
||||
m.foldRev (fun acc k _ => k :: acc) []
|
||||
|
||||
/-- Creates a hash map from a list of mappings. If the same key appears multiple times, the last
|
||||
occurrence takes precedence. -/
|
||||
@[inline] def ofList [BEq α] [Hashable α] (l : List ((a : α) × β a)) : Raw α β :=
|
||||
insertMany ∅ l
|
||||
|
||||
@[inline, inherit_doc Raw.ofList] def Const.ofList {β : Type v} [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : Raw α (fun _ => β) :=
|
||||
Const.insertMany ∅ l
|
||||
|
||||
/-- Creates a hash map from a list of keys, associating the value `()` with each key.
|
||||
|
||||
This is mainly useful to implement `HashSet.ofList`, so if you are considering using this,
|
||||
`HashSet` or `HashSet.Raw` might be a better fit for you. -/
|
||||
@[inline] def Const.unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
Raw α (fun _ => Unit) :=
|
||||
Const.insertManyIfNewUnit ∅ l
|
||||
|
||||
section WF
|
||||
|
||||
/--
|
||||
|
||||
@@ -58,7 +58,11 @@ private def baseNames : Array Name :=
|
||||
``getKey?_eq, ``getKey?_val,
|
||||
``getKey_eq, ``getKey_val,
|
||||
``getKey!_eq, ``getKey!_val,
|
||||
``getKeyD_eq, ``getKeyD_val]
|
||||
``getKeyD_eq, ``getKeyD_val,
|
||||
``insertMany_eq, ``insertMany_val,
|
||||
``Const.insertMany_eq, ``Const.insertMany_val,
|
||||
``Const.insertManyIfNewUnit_eq, ``Const.insertManyIfNewUnit_val,
|
||||
``ofList_eq, ``Const.ofList_eq, ``Const.unitOfList_eq]
|
||||
|
||||
/-- Internal implementation detail of the hash map -/
|
||||
scoped syntax "simp_to_raw" ("using" term)? : tactic
|
||||
@@ -765,7 +769,7 @@ theorem getKey!_eq_default_of_contains_eq_false [EquivBEq α] [LawfulHashable α
|
||||
m.contains a = false → m.getKey! a = default := by
|
||||
simp_to_raw using Raw₀.getKey!_eq_default
|
||||
|
||||
theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {a : α}:
|
||||
theorem getKey!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {a : α} :
|
||||
¬a ∈ m → m.getKey! a = default := by
|
||||
simpa [mem_iff_contains] using getKey!_eq_default_of_contains_eq_false h
|
||||
|
||||
@@ -1028,7 +1032,7 @@ theorem length_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
simp_to_raw using Raw₀.length_keys ⟨m, h.size_buckets_pos⟩ h
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.WF):
|
||||
theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.keys.isEmpty = m.isEmpty := by
|
||||
simp_to_raw using Raw₀.isEmpty_keys ⟨m, h.size_buckets_pos⟩
|
||||
|
||||
@@ -1039,7 +1043,7 @@ theorem contains_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
|
||||
|
||||
@[simp]
|
||||
theorem mem_keys [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
|
||||
k ∈ m.keys ↔ k ∈ m := by
|
||||
k ∈ m.keys ↔ k ∈ m := by
|
||||
rw [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.mem_keys ⟨m, _⟩ h
|
||||
|
||||
@@ -1047,6 +1051,931 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.keys.Pairwise (fun a b => (a == b) = false) := by
|
||||
simp_to_raw using Raw₀.distinct_keys ⟨m, h.size_buckets_pos⟩ h
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.insertMany [] = m := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_nil]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β k} [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.insertMany [⟨k, v⟩] = m.insert k v := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_list_singleton]
|
||||
|
||||
theorem insertMany_cons {l : List ((a : α) × β a)} {k : α} {v : β k} [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) :
|
||||
m.insertMany (⟨k, v⟩ :: l) = (m.insert k v).insertMany l := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_cons]
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(m.insertMany l).contains k = (m.contains k || (l.map Sigma.fst).contains k) := by
|
||||
simp_to_raw using Raw₀.contains_insertMany_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
k ∈ (m.insertMany l) ↔ k ∈ m ∨ (l.map Sigma.fst).contains k := by
|
||||
simp [mem_iff_contains, contains_insertMany_list h]
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
k ∈ (m.insertMany l) → (l.map Sigma.fst).contains k = false → k ∈ m := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.contains_of_contains_insertMany_list
|
||||
|
||||
theorem get?_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).get? k = m.get? k := by
|
||||
simp_to_raw using Raw₀.get?_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_mem [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).get? k' = some (cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v) := by
|
||||
simp_to_raw using Raw₀.get?_insertMany_list_of_mem
|
||||
|
||||
theorem get_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false)
|
||||
{h'} :
|
||||
(m.insertMany l).get k h' =
|
||||
m.get k (mem_of_mem_insertMany_list h h' contains_eq_false) := by
|
||||
simp_to_raw using Raw₀.get_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem get_insertMany_list_of_mem [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h'} :
|
||||
(m.insertMany l).get k' h' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_raw using Raw₀.get_insertMany_list_of_mem
|
||||
|
||||
theorem get!_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).get! k = m.get! k := by
|
||||
simp_to_raw using Raw₀.get!_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_mem [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} [Inhabited (β k')]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).get! k' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_raw using Raw₀.get!_insertMany_list_of_mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getD k fallback = m.getD k fallback := by
|
||||
simp_to_raw using Raw₀.getD_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [LawfulBEq α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(m.insertMany l).getD k' fallback = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_raw using Raw₀.getD_insertMany_list_of_mem
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getKey? k = m.getKey? k := by
|
||||
simp_to_raw using Raw₀.getKey?_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).getKey? k' = some k := by
|
||||
simp_to_raw using Raw₀.getKey?_insertMany_list_of_mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false)
|
||||
{h'} :
|
||||
(m.insertMany l).getKey k h' =
|
||||
m.getKey k (mem_of_mem_insertMany_list h h' contains_eq_false) := by
|
||||
simp_to_raw using Raw₀.getKey_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst)
|
||||
{h'} :
|
||||
(m.insertMany l).getKey k' h' = k := by
|
||||
simp_to_raw using Raw₀.getKey_insertMany_list_of_mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h : m.WF) {l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getKey! k = m.getKey! k := by
|
||||
simp_to_raw using Raw₀.getKey!_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).getKey! k' = k := by
|
||||
simp_to_raw using Raw₀.getKey!_insertMany_list_of_mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(m.insertMany l).getKeyD k fallback = m.getKeyD k fallback := by
|
||||
simp_to_raw using Raw₀.getKeyD_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(m.insertMany l).getKeyD k' fallback = k := by
|
||||
simp_to_raw using Raw₀.getKeyD_insertMany_list_of_mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), a ∈ m → (l.map Sigma.fst).contains a = false) →
|
||||
(m.insertMany l).size = m.size + l.length := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.size_insertMany_list
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} :
|
||||
m.size ≤ (m.insertMany l).size := by
|
||||
simp_to_raw using Raw₀.size_le_size_insertMany_list ⟨m, _⟩
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} :
|
||||
(m.insertMany l).size ≤ m.size + l.length := by
|
||||
simp_to_raw using Raw₀.size_insertMany_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List ((a : α) × β a)} :
|
||||
(m.insertMany l).isEmpty = (m.isEmpty && l.isEmpty) := by
|
||||
simp_to_raw using Raw₀.isEmpty_insertMany_list
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v} {m : Raw α (fun _ => β)}
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil (h : m.WF) :
|
||||
insertMany m [] = m := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertMany_nil]
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton (h : m.WF)
|
||||
{k : α} {v : β} :
|
||||
insertMany m [⟨k, v⟩] = m.insert k v := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertMany_list_singleton]
|
||||
|
||||
theorem insertMany_cons (h : m.WF) {l : List (α × β)}
|
||||
{k : α} {v : β} :
|
||||
insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertMany_cons]
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
(insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) := by
|
||||
simp_to_raw using Raw₀.Const.contains_insertMany_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k := by
|
||||
simp [mem_iff_contains, contains_insertMany_list h]
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ insertMany m l → (l.map Prod.fst).contains k = false → k ∈ m := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.contains_of_contains_insertMany_list
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey? k = m.getKey? k := by
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey? k' = some k := by
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertMany_list_of_mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h'} :
|
||||
(insertMany m l).getKey k h' =
|
||||
m.getKey k (mem_of_mem_insertMany_list h h' contains_eq_false) := by
|
||||
simp_to_raw using Raw₀.Const.getKey_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h'} :
|
||||
(insertMany m l).getKey k' h' = k := by
|
||||
simp_to_raw using Raw₀.Const.getKey_insertMany_list_of_mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey! k = m.getKey! k := by
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey! k' = k := by
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertMany_list_of_mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKeyD k fallback = m.getKeyD k fallback := by
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKeyD k' fallback = k := by
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertMany_list_of_mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), a ∈ m → (l.map Prod.fst).contains a = false) →
|
||||
(insertMany m l).size = m.size + l.length := by
|
||||
simp [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.size_insertMany_list
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} :
|
||||
m.size ≤ (insertMany m l).size := by
|
||||
simp_to_raw using Raw₀.Const.size_le_size_insertMany_list ⟨m, _⟩
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).size ≤ m.size + l.length := by
|
||||
simp_to_raw using Raw₀.Const.size_insertMany_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) := by
|
||||
simp_to_raw using Raw₀.Const.isEmpty_insertMany_list
|
||||
|
||||
theorem get?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get? (insertMany m l) k = get? m k := by
|
||||
simp_to_raw using Raw₀.Const.get?_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
get? (insertMany m l) k' = v := by
|
||||
simp_to_raw using Raw₀.Const.get?_insertMany_list_of_mem
|
||||
|
||||
theorem get_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h'} :
|
||||
get (insertMany m l) k h' =
|
||||
get m k (mem_of_mem_insertMany_list h h' contains_eq_false) := by
|
||||
simp_to_raw using Raw₀.Const.get_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem get_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l){h'} :
|
||||
get (insertMany m l) k' h' = v := by
|
||||
simp_to_raw using Raw₀.Const.get_insertMany_list_of_mem
|
||||
|
||||
theorem get!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited β] (h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get! (insertMany m l) k = get! m k := by
|
||||
simp_to_raw using Raw₀.Const.get!_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
get! (insertMany m l) k' = v := by
|
||||
simp_to_raw using Raw₀.Const.get!_insertMany_list_of_mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (insertMany m l) k fallback = getD m k fallback := by
|
||||
simp_to_raw using Raw₀.Const.getD_insertMany_list_of_contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (insertMany m l) k' fallback = v := by
|
||||
simp_to_raw using Raw₀.Const.getD_insertMany_list_of_mem
|
||||
|
||||
variable {m : Raw α (fun _ => Unit)}
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_nil (h : m.WF) :
|
||||
insertManyIfNewUnit m [] = m := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertManyIfNewUnit_nil]
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_list_singleton {k : α} (h : m.WF) :
|
||||
insertManyIfNewUnit m [k] = m.insertIfNew k () := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertManyIfNewUnit_list_singleton]
|
||||
|
||||
theorem insertManyIfNewUnit_cons (h : m.WF) {l : List α} {k : α} :
|
||||
insertManyIfNewUnit m (k :: l) = insertManyIfNewUnit (m.insertIfNew k ()) l := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertManyIfNewUnit_cons]
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l).contains k = (m.contains k || l.contains k) := by
|
||||
simp_to_raw using Raw₀.Const.contains_insertManyIfNewUnit_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
k ∈ insertManyIfNewUnit m l ↔ k ∈ m ∨ l.contains k := by
|
||||
simp [mem_iff_contains, contains_insertManyIfNewUnit_list h]
|
||||
|
||||
theorem mem_of_mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
k ∈ insertManyIfNewUnit m l → k ∈ m := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.contains_of_contains_insertManyIfNewUnit_list
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k : α} :
|
||||
¬ k ∈ m → l.contains k = false →
|
||||
getKey? (insertManyIfNewUnit m l) k = none := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k k' : α} (k_beq : k == k') :
|
||||
¬ k ∈ m → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKey? (insertManyIfNewUnit m l) k' = some k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertManyIfNewUnit_list_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k : α} :
|
||||
k ∈ m → getKey? (insertManyIfNewUnit m l) k = getKey? m k := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertManyIfNewUnit_list_of_contains
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_mem
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k : α} {h'} (mem : k ∈ m) :
|
||||
getKey (insertManyIfNewUnit m l) k h' = getKey m k mem := by
|
||||
simp_to_raw using Raw₀.Const.getKey_insertManyIfNewUnit_list_of_contains
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α}
|
||||
{k k' : α} (k_beq : k == k') {h'} :
|
||||
¬ k ∈ m → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKey (insertManyIfNewUnit m l) k' h' = k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using Raw₀.Const.getKey_insertManyIfNewUnit_list_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {l : List α} {k : α} :
|
||||
¬ k ∈ m → l.contains k = false → getKey! (insertManyIfNewUnit m l) k = default := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using
|
||||
Raw₀.Const.getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.WF) {l : List α} {k k' : α} (k_beq : k == k') :
|
||||
¬ k ∈ m → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKey! (insertManyIfNewUnit m l) k' = k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertManyIfNewUnit_list_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.WF) {l : List α} {k : α} :
|
||||
k ∈ m → getKey! (insertManyIfNewUnit m l) k = getKey! m k := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertManyIfNewUnit_list_of_contains
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k fallback : α} :
|
||||
¬ k ∈ m → l.contains k = false →
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = fallback := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using
|
||||
Raw₀.Const.getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k k' fallback : α} (k_beq : k == k') :
|
||||
¬ k ∈ m → l.Pairwise (fun a b => (a == b) = false) → k ∈ l →
|
||||
getKeyD (insertManyIfNewUnit m l) k' fallback = k := by
|
||||
simp only [mem_iff_contains, Bool.not_eq_true]
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertManyIfNewUnit_list_of_contains_eq_false_of_mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k fallback : α} :
|
||||
k ∈ m → getKeyD (insertManyIfNewUnit m l) k fallback = getKeyD m k fallback := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertManyIfNewUnit_list_of_contains
|
||||
|
||||
theorem size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), a ∈ m → l.contains a = false) →
|
||||
(insertManyIfNewUnit m l).size = m.size + l.length := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.size_insertManyIfNewUnit_list
|
||||
|
||||
theorem size_le_size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
m.size ≤ (insertManyIfNewUnit m l).size := by
|
||||
simp_to_raw using Raw₀.Const.size_le_size_insertManyIfNewUnit_list ⟨m, _⟩
|
||||
|
||||
theorem size_insertManyIfNewUnit_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).size ≤ m.size + l.length := by
|
||||
simp_to_raw using Raw₀.Const.size_insertManyIfNewUnit_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).isEmpty = (m.isEmpty && l.isEmpty) := by
|
||||
simp_to_raw using Raw₀.Const.isEmpty_insertManyIfNewUnit_list
|
||||
|
||||
@[simp]
|
||||
theorem get?_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
get? (insertManyIfNewUnit m l) k =
|
||||
if k ∈ m ∨ l.contains k then some () else none := by
|
||||
simp only [mem_iff_contains]
|
||||
simp_to_raw using Raw₀.Const.get?_insertManyIfNewUnit_list
|
||||
|
||||
@[simp]
|
||||
theorem get_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {h} :
|
||||
get (insertManyIfNewUnit m l) k h = () := by
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem get!_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} :
|
||||
get! (insertManyIfNewUnit m l) k = () := by
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem getD_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (insertManyIfNewUnit m l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Const
|
||||
|
||||
end Raw
|
||||
|
||||
namespace Raw
|
||||
|
||||
variable [BEq α] [Hashable α]
|
||||
|
||||
open Internal.Raw Internal.Raw₀
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List ((a : α) × (β a))) = ∅ := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_empty_list_nil]
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} {v : β k} :
|
||||
ofList [⟨k, v⟩] = (∅ : Raw α β).insert k v := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_empty_list_singleton]
|
||||
|
||||
theorem ofList_cons [EquivBEq α] [LawfulHashable α] {k : α} {v : β k} {tl : List ((a : α) × (β a))} :
|
||||
ofList (⟨k, v⟩ :: tl) = ((∅ : Raw α β).insert k v).insertMany tl := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.insertMany_empty_list_cons]
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
(ofList l).contains k = (l.map Sigma.fst).contains k := by
|
||||
simp_to_raw using Raw₀.contains_insertMany_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α} :
|
||||
k ∈ ofList l ↔ (l.map Sigma.fst).contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem get?_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).get? k = none := by
|
||||
simp_to_raw using Raw₀.get?_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem get?_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l).get? k' = some (cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v) := by
|
||||
simp_to_raw using Raw₀.get?_insertMany_empty_list_of_mem
|
||||
|
||||
theorem get_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
(ofList l).get k' h = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_raw using Raw₀.get_insertMany_empty_list_of_mem
|
||||
|
||||
theorem get!_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} [Inhabited (β k)]
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).get! k = default := by
|
||||
simp_to_raw using get!_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem get!_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} [Inhabited (β k')]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l).get! k' = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_raw using Raw₀.get!_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k : α} {fallback : β k}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getD k fallback = fallback := by
|
||||
simp_to_raw using Raw₀.getD_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [LawfulBEq α]
|
||||
{l : List ((a : α) × β a)} {k k' : α} (k_beq : k == k') {v : β k} {fallback : β k'}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l).getD k' fallback = cast (by congr; apply LawfulBEq.eq_of_beq k_beq) v := by
|
||||
simp_to_raw using Raw₀.getD_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKey?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getKey? k = none := by
|
||||
simp_to_raw using Raw₀.getKey?_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKey?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(ofList l).getKey? k' = some k := by
|
||||
simp_to_raw using Raw₀.getKey?_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKey_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst)
|
||||
{h'} :
|
||||
(ofList l).getKey k' h' = k := by
|
||||
simp_to_raw using Raw₀.getKey_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKey!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)} {k : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getKey! k = default := by
|
||||
simp_to_raw using Raw₀.getKey!_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKey!_ofList_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(ofList l).getKey! k' = k := by
|
||||
simp_to_raw using Raw₀.getKey!_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKeyD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Sigma.fst).contains k = false) :
|
||||
(ofList l).getKeyD k fallback = fallback := by
|
||||
simp_to_raw using Raw₀.getKeyD_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Sigma.fst) :
|
||||
(ofList l).getKeyD k' fallback = k := by
|
||||
simp_to_raw using Raw₀.getKeyD_insertMany_empty_list_of_mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(ofList l).size = l.length := by
|
||||
simp_to_raw using Raw₀.size_insertMany_empty_list
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(ofList l).size ≤ l.length := by
|
||||
simp_to_raw using Raw₀.size_insertMany_empty_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List ((a : α) × β a)} :
|
||||
(ofList l).isEmpty = l.isEmpty := by
|
||||
simp_to_raw using Raw₀.isEmpty_insertMany_empty_list
|
||||
|
||||
namespace Const
|
||||
|
||||
variable {β : Type v}
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List (α × β)) = ∅ := by
|
||||
simp_to_raw
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} {v : β} :
|
||||
ofList [⟨k, v⟩] = (∅ : Raw α (fun _ => β)).insert k v := by
|
||||
simp_to_raw
|
||||
simp
|
||||
|
||||
theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} :
|
||||
ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : Raw α (fun _ => β)).insert k v) tl := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertMany_empty_list_cons]
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(ofList l).contains k = (l.map Prod.fst).contains k := by
|
||||
simp_to_raw using Raw₀.Const.contains_insertMany_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ (ofList l) ↔ (l.map Prod.fst).contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem get?_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get? (ofList l) k = none := by
|
||||
simp_to_raw using Raw₀.Const.get?_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem get?_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
get? (ofList l) k' = some v := by
|
||||
simp_to_raw using Raw₀.Const.get?_insertMany_empty_list_of_mem
|
||||
|
||||
theorem get_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
get (ofList l) k' h = v := by
|
||||
simp_to_raw using Raw₀.Const.get_insertMany_empty_list_of_mem
|
||||
|
||||
theorem get!_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} [Inhabited β]
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
get! (ofList l) k = default := by
|
||||
simp_to_raw using Raw₀.Const.get!_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem get!_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} [Inhabited β]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
get! (ofList l) k' = v := by
|
||||
simp_to_raw using Raw₀.Const.get!_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (ofList l) k fallback = fallback := by
|
||||
simp_to_raw using Raw₀.Const.getD_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} {fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (ofList l) k' fallback = v := by
|
||||
simp_to_raw using Raw₀.Const.getD_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKey?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey? k = none := by
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKey?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey? k' = some k := by
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKey_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h'} :
|
||||
(ofList l).getKey k' h' = k := by
|
||||
simp_to_raw using Raw₀.Const.getKey_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKey!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey! k = default := by
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKey!_ofList_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey! k' = k := by
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertMany_empty_list_of_mem
|
||||
|
||||
theorem getKeyD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKeyD k fallback = fallback := by
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertMany_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKeyD k' fallback = k := by
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertMany_empty_list_of_mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(ofList l).size = l.length := by
|
||||
simp_to_raw using Raw₀.Const.size_insertMany_empty_list
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).size ≤ l.length := by
|
||||
simp_to_raw using Raw₀.Const.size_insertMany_empty_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).isEmpty = l.isEmpty := by
|
||||
simp_to_raw using Raw₀.Const.isEmpty_insertMany_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_nil :
|
||||
unitOfList ([] : List α) = ∅ := by
|
||||
simp_to_raw
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_singleton {k : α} :
|
||||
unitOfList [k] = (∅ : Raw α (fun _ => Unit)).insertIfNew k () := by
|
||||
simp_to_raw
|
||||
simp
|
||||
|
||||
theorem unitOfList_cons {hd : α} {tl : List α} :
|
||||
unitOfList (hd :: tl) = insertManyIfNewUnit ((∅ : Raw α (fun _ => Unit)).insertIfNew hd ()) tl := by
|
||||
simp_to_raw
|
||||
rw [Raw₀.Const.insertManyIfNewUnit_empty_list_cons]
|
||||
|
||||
@[simp]
|
||||
theorem contains_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l).contains k = l.contains k := by
|
||||
simp_to_raw using Raw₀.Const.contains_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ unitOfList l ↔ l.contains k := by
|
||||
simp [mem_iff_contains]
|
||||
|
||||
theorem getKey?_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
getKey? (unitOfList l) k = none := by
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertManyIfNewUnit_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKey?_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (unitOfList l) k' = some k := by
|
||||
simp_to_raw using Raw₀.Const.getKey?_insertManyIfNewUnit_empty_list_of_mem
|
||||
|
||||
theorem getKey_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h'} :
|
||||
getKey (unitOfList l) k' h' = k := by
|
||||
simp_to_raw using Raw₀.Const.getKey_insertManyIfNewUnit_empty_list_of_mem
|
||||
|
||||
theorem getKey!_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKey! (unitOfList l) k = default := by
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertManyIfNewUnit_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKey!_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKey! (unitOfList l) k' = k := by
|
||||
simp_to_raw using Raw₀.Const.getKey!_insertManyIfNewUnit_empty_list_of_mem
|
||||
|
||||
theorem getKeyD_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKeyD (unitOfList l) k fallback = fallback := by
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertManyIfNewUnit_empty_list_of_contains_eq_false
|
||||
|
||||
theorem getKeyD_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l ) :
|
||||
getKeyD (unitOfList l) k' fallback = k := by
|
||||
simp_to_raw using Raw₀.Const.getKeyD_insertManyIfNewUnit_empty_list_of_mem
|
||||
|
||||
theorem size_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(unitOfList l).size = l.length := by
|
||||
simp_to_raw using Raw₀.Const.size_insertManyIfNewUnit_empty_list
|
||||
|
||||
theorem size_unitOfList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).size ≤ l.length := by
|
||||
simp_to_raw using Raw₀.Const.size_insertManyIfNewUnit_empty_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).isEmpty = l.isEmpty := by
|
||||
simp_to_raw using Raw₀.Const.isEmpty_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem get?_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
get? (unitOfList l) k =
|
||||
if l.contains k then some () else none := by
|
||||
simp_to_raw using Raw₀.Const.get?_insertManyIfNewUnit_empty_list
|
||||
|
||||
@[simp]
|
||||
theorem get_unitOfList
|
||||
{l : List α} {k : α} {h} :
|
||||
get (unitOfList l) k h = () := by
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem get!_unitOfList
|
||||
{l : List α} {k : α} :
|
||||
get! (unitOfList l) k = () := by
|
||||
simp
|
||||
|
||||
@[simp]
|
||||
theorem getD_unitOfList
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (unitOfList l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Const
|
||||
end Raw
|
||||
|
||||
end Std.DHashMap
|
||||
|
||||
@@ -191,6 +191,14 @@ instance [BEq α] [Hashable α] : GetElem? (HashMap α β) α β (fun m a => a
|
||||
@[inline, inherit_doc DHashMap.keys] def keys (m : HashMap α β) : List α :=
|
||||
m.inner.keys
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.ofList] def ofList [BEq α] [Hashable α] (l : List (α × β)) :
|
||||
HashMap α β :=
|
||||
⟨DHashMap.Const.ofList l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.unitOfList] def unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
HashMap α Unit :=
|
||||
⟨DHashMap.Const.unitOfList l⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
@@ -261,20 +269,12 @@ instance [BEq α] [Hashable α] {m : Type w → Type w} : ForIn m (HashMap α β
|
||||
{ρ : Type w} [ForIn Id ρ α] (m : HashMap α Unit) (l : ρ) : HashMap α Unit :=
|
||||
⟨DHashMap.Const.insertManyIfNewUnit m.inner l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.ofList] def ofList [BEq α] [Hashable α] (l : List (α × β)) :
|
||||
HashMap α β :=
|
||||
⟨DHashMap.Const.ofList l⟩
|
||||
|
||||
/-- Computes the union of the given hash maps, by traversing `m₂` and inserting its elements into `m₁`. -/
|
||||
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : HashMap α β) : HashMap α β :=
|
||||
m₂.fold (init := m₁) fun acc x => acc.insert x
|
||||
|
||||
instance [BEq α] [Hashable α] : Union (HashMap α β) := ⟨union⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.unitOfList] def unitOfList [BEq α] [Hashable α] (l : List α) :
|
||||
HashMap α Unit :=
|
||||
⟨DHashMap.Const.unitOfList l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Const.unitOfArray] def unitOfArray [BEq α] [Hashable α] (l : Array α) :
|
||||
HashMap α Unit :=
|
||||
⟨DHashMap.Const.unitOfArray l⟩
|
||||
|
||||
@@ -698,6 +698,575 @@ theorem distinct_keys [EquivBEq α] [LawfulHashable α] :
|
||||
m.keys.Pairwise (fun a b => (a == b) = false) :=
|
||||
DHashMap.distinct_keys
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
insertMany m [] = m :=
|
||||
ext DHashMap.Const.insertMany_nil
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} {v : β} :
|
||||
insertMany m [⟨k, v⟩] = m.insert k v :=
|
||||
ext DHashMap.Const.insertMany_list_singleton
|
||||
|
||||
theorem insertMany_cons {l : List (α × β)} {k : α} {v : β} :
|
||||
insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l :=
|
||||
ext DHashMap.Const.insertMany_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) :=
|
||||
DHashMap.Const.contains_insertMany_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k :=
|
||||
DHashMap.Const.mem_insertMany_list
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} (mem : k ∈ insertMany m l)
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
k ∈ m :=
|
||||
DHashMap.Const.mem_of_mem_insertMany_list mem contains_eq_false
|
||||
|
||||
theorem getElem?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l)[k]? = m[k]? :=
|
||||
DHashMap.Const.get?_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany m l)[k']? = some v :=
|
||||
DHashMap.Const.get?_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getElem_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h} :
|
||||
(insertMany m l)[k] = m[k]'(mem_of_mem_insertMany_list h contains_eq_false) :=
|
||||
DHashMap.Const.get_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) {h} :
|
||||
(insertMany m l)[k'] = v :=
|
||||
DHashMap.Const.get_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getElem!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited β] {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l)[k]! = m[k]! :=
|
||||
DHashMap.Const.get!_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited β]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany m l)[k']! = v :=
|
||||
DHashMap.Const.get!_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (insertMany m l) k fallback = getD m k fallback :=
|
||||
DHashMap.Const.getD_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (insertMany m l) k' fallback = v :=
|
||||
DHashMap.Const.getD_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey? k = m.getKey? k :=
|
||||
DHashMap.Const.getKey?_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey? k' = some k :=
|
||||
DHashMap.Const.getKey?_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h} :
|
||||
(insertMany m l).getKey k h =
|
||||
m.getKey k (mem_of_mem_insertMany_list h contains_eq_false) :=
|
||||
DHashMap.Const.getKey_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h} :
|
||||
(insertMany m l).getKey k' h = k :=
|
||||
DHashMap.Const.getKey_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey! k = m.getKey! k :=
|
||||
DHashMap.Const.getKey!_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey! k' = k :=
|
||||
DHashMap.Const.getKey!_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKeyD k fallback = m.getKeyD k fallback :=
|
||||
DHashMap.Const.getKeyD_insertMany_list_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKeyD k' fallback = k :=
|
||||
DHashMap.Const.getKeyD_insertMany_list_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), a ∈ m → (l.map Prod.fst).contains a = false) →
|
||||
(insertMany m l).size = m.size + l.length :=
|
||||
DHashMap.Const.size_insertMany_list distinct
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
m.size ≤ (insertMany m l).size :=
|
||||
DHashMap.Const.size_le_size_insertMany_list
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).size ≤ m.size + l.length :=
|
||||
DHashMap.Const.size_insertMany_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
DHashMap.Const.isEmpty_insertMany_list
|
||||
|
||||
variable {m : HashMap α Unit}
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_nil :
|
||||
insertManyIfNewUnit m [] = m :=
|
||||
ext DHashMap.Const.insertManyIfNewUnit_nil
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_list_singleton {k : α} :
|
||||
insertManyIfNewUnit m [k] = m.insertIfNew k () :=
|
||||
ext DHashMap.Const.insertManyIfNewUnit_list_singleton
|
||||
|
||||
theorem insertManyIfNewUnit_cons {l : List α} {k : α} :
|
||||
insertManyIfNewUnit m (k :: l) = insertManyIfNewUnit (m.insertIfNew k ()) l :=
|
||||
ext DHashMap.Const.insertManyIfNewUnit_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l).contains k = (m.contains k || l.contains k) :=
|
||||
DHashMap.Const.contains_insertManyIfNewUnit_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ insertManyIfNewUnit m l ↔ k ∈ m ∨ l.contains k :=
|
||||
DHashMap.Const.mem_insertManyIfNewUnit_list
|
||||
|
||||
theorem mem_of_mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
k ∈ insertManyIfNewUnit m l → k ∈ m :=
|
||||
DHashMap.Const.mem_of_mem_insertManyIfNewUnit_list contains_eq_false
|
||||
|
||||
theorem getElem?_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l)[k]? =
|
||||
if k ∈ m ∨ l.contains k then some () else none :=
|
||||
DHashMap.Const.get?_insertManyIfNewUnit_list
|
||||
|
||||
theorem getElem_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {h} :
|
||||
(insertManyIfNewUnit m l)[k] = () :=
|
||||
DHashMap.Const.get_insertManyIfNewUnit_list
|
||||
|
||||
theorem getElem!_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l)[k]! = () :=
|
||||
DHashMap.Const.get!_insertManyIfNewUnit_list
|
||||
|
||||
theorem getD_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (insertManyIfNewUnit m l) k fallback = () := by
|
||||
simp
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKey? (insertManyIfNewUnit m l) k = none :=
|
||||
DHashMap.Const.getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
not_mem contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k') (not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (insertManyIfNewUnit m l) k' = some k :=
|
||||
DHashMap.Const.getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (mem : k ∈ m) :
|
||||
getKey? (insertManyIfNewUnit m l) k = getKey? m k :=
|
||||
DHashMap.Const.getKey?_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k') (not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) {h} :
|
||||
getKey (insertManyIfNewUnit m l) k' h = k :=
|
||||
DHashMap.Const.getKey_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (mem : k ∈ m) {h} :
|
||||
getKey (insertManyIfNewUnit m l) k h = getKey m k mem :=
|
||||
DHashMap.Const.getKey_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKey! (insertManyIfNewUnit m l) k = default :=
|
||||
DHashMap.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
not_mem contains_eq_false
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey! (insertManyIfNewUnit m l) k' = k :=
|
||||
DHashMap.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α} (mem : k ∈ m) :
|
||||
getKey! (insertManyIfNewUnit m l) k = getKey! m k :=
|
||||
DHashMap.Const.getKey!_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] {l : List α} {k fallback : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = fallback :=
|
||||
DHashMap.Const.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
not_mem contains_eq_false
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l ) :
|
||||
getKeyD (insertManyIfNewUnit m l) k' fallback = k :=
|
||||
DHashMap.Const.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α} (mem : k ∈ m) :
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = getKeyD m k fallback :=
|
||||
DHashMap.Const.getKeyD_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), a ∈ m → l.contains a = false) →
|
||||
(insertManyIfNewUnit m l).size = m.size + l.length :=
|
||||
DHashMap.Const.size_insertManyIfNewUnit_list distinct
|
||||
|
||||
theorem size_le_size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
m.size ≤ (insertManyIfNewUnit m l).size :=
|
||||
DHashMap.Const.size_le_size_insertManyIfNewUnit_list
|
||||
|
||||
theorem size_insertManyIfNewUnit_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).size ≤ m.size + l.length :=
|
||||
DHashMap.Const.size_insertManyIfNewUnit_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
DHashMap.Const.isEmpty_insertManyIfNewUnit_list
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List (α × β)) = ∅ :=
|
||||
ext DHashMap.Const.ofList_nil
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} {v : β} :
|
||||
ofList [⟨k, v⟩] = (∅ : HashMap α β).insert k v :=
|
||||
ext DHashMap.Const.ofList_singleton
|
||||
|
||||
theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} :
|
||||
ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : HashMap α β).insert k v) tl :=
|
||||
ext DHashMap.Const.ofList_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(ofList l).contains k = (l.map Prod.fst).contains k :=
|
||||
DHashMap.Const.contains_ofList
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ ofList l ↔ (l.map Prod.fst).contains k :=
|
||||
DHashMap.Const.mem_ofList
|
||||
|
||||
theorem getElem?_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l)[k]? = none :=
|
||||
DHashMap.Const.get?_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem?_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l)[k']? = some v :=
|
||||
DHashMap.Const.get?_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getElem_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
(ofList l)[k'] = v :=
|
||||
DHashMap.Const.get_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getElem!_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} [Inhabited β]
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l)[k]! = (default : β) :=
|
||||
DHashMap.Const.get!_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem!_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} [Inhabited β]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l)[k']! = v :=
|
||||
DHashMap.Const.get!_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (ofList l) k fallback = fallback :=
|
||||
DHashMap.Const.getD_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} {fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (ofList l) k' fallback = v :=
|
||||
DHashMap.Const.getD_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey? k = none :=
|
||||
DHashMap.Const.getKey?_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey? k' = some k :=
|
||||
DHashMap.Const.getKey?_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h} :
|
||||
(ofList l).getKey k' h = k :=
|
||||
DHashMap.Const.getKey_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey! k = default :=
|
||||
DHashMap.Const.getKey!_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_ofList_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey! k' = k :=
|
||||
DHashMap.Const.getKey!_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKeyD k fallback = fallback :=
|
||||
DHashMap.Const.getKeyD_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKeyD k' fallback = k :=
|
||||
DHashMap.Const.getKeyD_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(ofList l).size = l.length :=
|
||||
DHashMap.Const.size_ofList distinct
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).size ≤ l.length :=
|
||||
DHashMap.Const.size_ofList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).isEmpty = l.isEmpty :=
|
||||
DHashMap.Const.isEmpty_ofList
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_nil :
|
||||
unitOfList ([] : List α) = ∅ :=
|
||||
ext DHashMap.Const.unitOfList_nil
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_singleton {k : α} :
|
||||
unitOfList [k] = (∅ : HashMap α Unit).insertIfNew k () :=
|
||||
ext DHashMap.Const.unitOfList_singleton
|
||||
|
||||
theorem unitOfList_cons {hd : α} {tl : List α} :
|
||||
unitOfList (hd :: tl) =
|
||||
insertManyIfNewUnit ((∅ : HashMap α Unit).insertIfNew hd ()) tl :=
|
||||
ext DHashMap.Const.unitOfList_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l).contains k = l.contains k :=
|
||||
DHashMap.Const.contains_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem mem_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ unitOfList l ↔ l.contains k :=
|
||||
DHashMap.Const.mem_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getElem?_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l)[k]? =
|
||||
if l.contains k then some () else none :=
|
||||
DHashMap.Const.get?_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getElem_unitOfList
|
||||
{l : List α} {k : α} {h} :
|
||||
(unitOfList l)[k] = () :=
|
||||
DHashMap.Const.get_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getElem!_unitOfList
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l)[k]! = () :=
|
||||
DHashMap.Const.get!_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getD_unitOfList
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (unitOfList l) k fallback = () := by
|
||||
simp
|
||||
|
||||
theorem getKey?_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
getKey? (unitOfList l) k = none :=
|
||||
DHashMap.Const.getKey?_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (unitOfList l) k' = some k :=
|
||||
DHashMap.Const.getKey?_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h} :
|
||||
getKey (unitOfList l) k' h = k :=
|
||||
DHashMap.Const.getKey_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKey! (unitOfList l) k = default :=
|
||||
DHashMap.Const.getKey!_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKey! (unitOfList l) k' = k :=
|
||||
DHashMap.Const.getKey!_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKeyD (unitOfList l) k fallback = fallback :=
|
||||
DHashMap.Const.getKeyD_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKeyD (unitOfList l) k' fallback = k :=
|
||||
DHashMap.Const.getKeyD_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(unitOfList l).size = l.length :=
|
||||
DHashMap.Const.size_unitOfList distinct
|
||||
|
||||
theorem size_unitOfList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).size ≤ l.length :=
|
||||
DHashMap.Const.size_unitOfList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).isEmpty = l.isEmpty :=
|
||||
DHashMap.Const.isEmpty_unitOfList
|
||||
|
||||
end
|
||||
|
||||
end Std.HashMap
|
||||
|
||||
@@ -173,6 +173,14 @@ instance [BEq α] [Hashable α] : GetElem? (Raw α β) α β (fun m a => a ∈ m
|
||||
@[inline, inherit_doc DHashMap.Raw.keys] def keys (m : Raw α β) : List α :=
|
||||
m.inner.keys
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.ofList] def ofList [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : Raw α β :=
|
||||
⟨DHashMap.Raw.Const.ofList l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.unitOfList] def unitOfList [BEq α] [Hashable α]
|
||||
(l : List α) : Raw α Unit :=
|
||||
⟨DHashMap.Raw.Const.unitOfList l⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
@@ -233,20 +241,12 @@ m.inner.values
|
||||
[Hashable α] {ρ : Type w} [ForIn Id ρ α] (m : Raw α Unit) (l : ρ) : Raw α Unit :=
|
||||
⟨DHashMap.Raw.Const.insertManyIfNewUnit m.inner l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.ofList] def ofList [BEq α] [Hashable α]
|
||||
(l : List (α × β)) : Raw α β :=
|
||||
⟨DHashMap.Raw.Const.ofList l⟩
|
||||
|
||||
/-- Computes the union of the given hash maps, by traversing `m₂` and inserting its elements into `m₁`. -/
|
||||
@[inline] def union [BEq α] [Hashable α] (m₁ m₂ : Raw α β) : Raw α β :=
|
||||
m₂.fold (init := m₁) fun acc x => acc.insert x
|
||||
|
||||
instance [BEq α] [Hashable α] : Union (Raw α β) := ⟨union⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.unitOfList] def unitOfList [BEq α] [Hashable α]
|
||||
(l : List α) : Raw α Unit :=
|
||||
⟨DHashMap.Raw.Const.unitOfList l⟩
|
||||
|
||||
@[inline, inherit_doc DHashMap.Raw.Const.unitOfArray] def unitOfArray [BEq α] [Hashable α]
|
||||
(l : Array α) : Raw α Unit :=
|
||||
⟨DHashMap.Raw.Const.unitOfArray l⟩
|
||||
|
||||
@@ -671,7 +671,6 @@ theorem getKeyD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.WF) {k a fa
|
||||
(m.insertIfNew k v).getKeyD a fallback = if k == a ∧ ¬k ∈ m then k else m.getKeyD a fallback :=
|
||||
DHashMap.Raw.getKeyD_insertIfNew h.out
|
||||
|
||||
|
||||
@[simp]
|
||||
theorem getThenInsertIfNew?_fst (h : m.WF) {k : α} {v : β} :
|
||||
(getThenInsertIfNew? m k v).1 = get? m k :=
|
||||
@@ -688,7 +687,7 @@ theorem length_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
DHashMap.Raw.length_keys h.out
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.WF):
|
||||
theorem isEmpty_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.keys.isEmpty = m.isEmpty :=
|
||||
DHashMap.Raw.isEmpty_keys h.out
|
||||
|
||||
@@ -699,13 +698,592 @@ theorem contains_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
|
||||
|
||||
@[simp]
|
||||
theorem mem_keys [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
|
||||
k ∈ m.keys ↔ k ∈ m :=
|
||||
k ∈ m.keys ↔ k ∈ m :=
|
||||
DHashMap.Raw.mem_keys h.out
|
||||
|
||||
theorem distinct_keys [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.keys.Pairwise (fun a b => (a == b) = false) :=
|
||||
m.keys.Pairwise (fun a b => (a == b) = false) :=
|
||||
DHashMap.Raw.distinct_keys h.out
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil (h : m.WF) :
|
||||
insertMany m [] = m :=
|
||||
ext (DHashMap.Raw.Const.insertMany_nil h.out)
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton (h : m.WF)
|
||||
{k : α} {v : β} :
|
||||
insertMany m [⟨k, v⟩] = m.insert k v :=
|
||||
ext (DHashMap.Raw.Const.insertMany_list_singleton h.out)
|
||||
|
||||
theorem insertMany_cons (h : m.WF) {l : List (α × β)}
|
||||
{k : α} {v : β} :
|
||||
insertMany m (⟨k, v⟩ :: l) = insertMany (m.insert k v) l :=
|
||||
ext (DHashMap.Raw.Const.insertMany_cons h.out)
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
(insertMany m l).contains k = (m.contains k || (l.map Prod.fst).contains k) :=
|
||||
DHashMap.Raw.Const.contains_insertMany_list h.out
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ insertMany m l ↔ k ∈ m ∨ (l.map Prod.fst).contains k :=
|
||||
DHashMap.Raw.Const.mem_insertMany_list h.out
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ insertMany m l → (l.map Prod.fst).contains k = false → k ∈ m :=
|
||||
DHashMap.Raw.Const.mem_of_mem_insertMany_list h.out
|
||||
|
||||
theorem getKey?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey? k = m.getKey? k :=
|
||||
DHashMap.Raw.Const.getKey?_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getKey?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey? k' = some k :=
|
||||
DHashMap.Raw.Const.getKey?_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
theorem getKey_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h'} :
|
||||
(insertMany m l).getKey k h' =
|
||||
m.getKey k (mem_of_mem_insertMany_list h h' contains_eq_false) :=
|
||||
DHashMap.Raw.Const.getKey_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getKey_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h'} :
|
||||
(insertMany m l).getKey k' h' = k :=
|
||||
DHashMap.Raw.Const.getKey_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
theorem getKey!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKey! k = m.getKey! k :=
|
||||
DHashMap.Raw.Const.getKey!_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getKey!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
(h : m.WF) {l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKey! k' = k :=
|
||||
DHashMap.Raw.Const.getKey!_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
theorem getKeyD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l).getKeyD k fallback = m.getKeyD k fallback :=
|
||||
DHashMap.Raw.Const.getKeyD_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getKeyD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(insertMany m l).getKeyD k' fallback = k :=
|
||||
DHashMap.Raw.Const.getKeyD_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(∀ (a : α), a ∈ m → (l.map Prod.fst).contains a = false) →
|
||||
(insertMany m l).size = m.size + l.length :=
|
||||
DHashMap.Raw.Const.size_insertMany_list h.out distinct
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} :
|
||||
m.size ≤ (insertMany m l).size :=
|
||||
DHashMap.Raw.Const.size_le_size_insertMany_list h.out
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} :
|
||||
(insertMany m l).size ≤ m.size + l.length :=
|
||||
DHashMap.Raw.Const.size_insertMany_list_le h.out
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} :
|
||||
(insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
DHashMap.Raw.Const.isEmpty_insertMany_list h.out
|
||||
|
||||
theorem getElem?_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l)[k]? = m[k]? :=
|
||||
DHashMap.Raw.Const.get?_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getElem?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany m l)[k']? = v :=
|
||||
DHashMap.Raw.Const.get?_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
theorem getElem_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false)
|
||||
{h'} :
|
||||
(insertMany m l)[k] =
|
||||
m[k]'(mem_of_mem_insertMany_list h h' contains_eq_false) :=
|
||||
DHashMap.Raw.Const.get_insertMany_list_of_contains_eq_false h.out contains_eq_false (h':= h')
|
||||
|
||||
theorem getElem_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) {h'} :
|
||||
(insertMany m l)[k'] = v :=
|
||||
DHashMap.Raw.Const.get_insertMany_list_of_mem h.out k_beq distinct mem (h' := h')
|
||||
|
||||
theorem getElem!_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited β] (h : m.WF) {l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(insertMany m l)[k]! = m[k]! :=
|
||||
DHashMap.Raw.Const.get!_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getElem!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited β]
|
||||
(h : m.WF) {l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
(insertMany m l)[k']! = v :=
|
||||
DHashMap.Raw.Const.get!_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
theorem getD_insertMany_list_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (insertMany m l) k fallback = getD m k fallback :=
|
||||
DHashMap.Raw.Const.getD_insertMany_list_of_contains_eq_false h.out contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List (α × β)} {k k' : α} (k_beq : k == k') {v fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) (mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (insertMany m l) k' fallback = v :=
|
||||
DHashMap.Raw.Const.getD_insertMany_list_of_mem h.out k_beq distinct mem
|
||||
|
||||
variable {m : Raw α Unit}
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_nil (h : m.WF) :
|
||||
insertManyIfNewUnit m [] = m :=
|
||||
ext (DHashMap.Raw.Const.insertManyIfNewUnit_nil h.out)
|
||||
|
||||
@[simp]
|
||||
theorem insertManyIfNewUnit_list_singleton (h : m.WF) {k : α} :
|
||||
insertManyIfNewUnit m [k] = m.insertIfNew k () :=
|
||||
ext (DHashMap.Raw.Const.insertManyIfNewUnit_list_singleton h.out)
|
||||
|
||||
theorem insertManyIfNewUnit_cons (h : m.WF) {l : List α} {k : α} :
|
||||
insertManyIfNewUnit m (k :: l) = insertManyIfNewUnit (m.insertIfNew k ()) l :=
|
||||
ext (DHashMap.Raw.Const.insertManyIfNewUnit_cons h.out)
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l).contains k = (m.contains k || l.contains k) :=
|
||||
DHashMap.Raw.Const.contains_insertManyIfNewUnit_list h.out
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
k ∈ insertManyIfNewUnit m l ↔ k ∈ m ∨ l.contains k :=
|
||||
DHashMap.Raw.Const.mem_insertManyIfNewUnit_list h.out
|
||||
|
||||
theorem mem_of_mem_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
k ∈ insertManyIfNewUnit m l → k ∈ m :=
|
||||
DHashMap.Raw.Const.mem_of_mem_insertManyIfNewUnit_list h.out contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false: l.contains k = false) :
|
||||
getKey? (insertManyIfNewUnit m l) k = none :=
|
||||
DHashMap.Raw.Const.getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
h.out not_mem contains_eq_false
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (insertManyIfNewUnit m l) k' = some k :=
|
||||
DHashMap.Raw.Const.getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.out k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey?_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k : α} (mem : k ∈ m) :
|
||||
getKey? (insertManyIfNewUnit m l) k = getKey? m k :=
|
||||
DHashMap.Raw.Const.getKey?_insertManyIfNewUnit_list_of_mem h.out mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) {h'} :
|
||||
getKey (insertManyIfNewUnit m l) k' h' = k :=
|
||||
DHashMap.Raw.Const.getKey_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.out k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k : α} (mem: k ∈ m) {h₃} :
|
||||
getKey (insertManyIfNewUnit m l) k h₃ = getKey m k mem :=
|
||||
DHashMap.Raw.Const.getKey_insertManyIfNewUnit_list_of_mem h.out mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKey! (insertManyIfNewUnit m l) k = default :=
|
||||
DHashMap.Raw.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
h.out not_mem contains_eq_false
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.WF) {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey! (insertManyIfNewUnit m l) k' = k :=
|
||||
DHashMap.Raw.Const.getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.out k_beq not_mem distinct mem
|
||||
|
||||
theorem getKey!_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.WF) {l : List α} {k : α} (mem : k ∈ m) :
|
||||
getKey! (insertManyIfNewUnit m l) k = getKey! m k :=
|
||||
DHashMap.Raw.Const.getKey!_insertManyIfNewUnit_list_of_mem h.out mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k fallback : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = fallback :=
|
||||
DHashMap.Raw.Const.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
h.out not_mem contains_eq_false
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKeyD (insertManyIfNewUnit m l) k' fallback = k :=
|
||||
DHashMap.Raw.Const.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.out k_beq not_mem distinct mem
|
||||
|
||||
theorem getKeyD_insertManyIfNewUnit_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k fallback : α} (mem : k ∈ m) :
|
||||
getKeyD (insertManyIfNewUnit m l) k fallback = getKeyD m k fallback :=
|
||||
DHashMap.Raw.Const.getKeyD_insertManyIfNewUnit_list_of_mem h.out mem
|
||||
|
||||
theorem size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), a ∈ m → l.contains a = false) →
|
||||
(insertManyIfNewUnit m l).size = m.size + l.length :=
|
||||
DHashMap.Raw.Const.size_insertManyIfNewUnit_list h.out distinct
|
||||
|
||||
theorem size_le_size_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
m.size ≤ (insertManyIfNewUnit m l).size :=
|
||||
DHashMap.Raw.Const.size_le_size_insertManyIfNewUnit_list h.out
|
||||
|
||||
theorem size_insertManyIfNewUnit_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).size ≤ m.size + l.length :=
|
||||
DHashMap.Raw.Const.size_insertManyIfNewUnit_list_le h.out
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
(insertManyIfNewUnit m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
DHashMap.Raw.Const.isEmpty_insertManyIfNewUnit_list h.out
|
||||
|
||||
@[simp]
|
||||
theorem getElem?_insertManyIfNewUnit_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l)[k]? =
|
||||
if k ∈ m ∨ l.contains k then some () else none :=
|
||||
DHashMap.Raw.Const.get?_insertManyIfNewUnit_list h.out
|
||||
|
||||
@[simp]
|
||||
theorem getElem_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {h} :
|
||||
(insertManyIfNewUnit m l)[k] = () :=
|
||||
DHashMap.Raw.Const.get_insertManyIfNewUnit_list (h:=h)
|
||||
|
||||
@[simp]
|
||||
theorem getElem!_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} :
|
||||
(insertManyIfNewUnit m l)[k]! = () :=
|
||||
DHashMap.Raw.Const.get!_insertManyIfNewUnit_list
|
||||
|
||||
@[simp]
|
||||
theorem getD_insertManyIfNewUnit_list
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (insertManyIfNewUnit m l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Raw
|
||||
|
||||
namespace Raw
|
||||
|
||||
variable [BEq α] [Hashable α]
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List (α × β)) = ∅ :=
|
||||
ext DHashMap.Raw.Const.ofList_nil
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} {v : β} :
|
||||
ofList [⟨k, v⟩] = (∅ : Raw α β).insert k v :=
|
||||
ext DHashMap.Raw.Const.ofList_singleton
|
||||
|
||||
theorem ofList_cons {k : α} {v : β} {tl : List (α × β)} :
|
||||
ofList (⟨k, v⟩ :: tl) = insertMany ((∅ : Raw α β).insert k v) tl :=
|
||||
ext DHashMap.Raw.Const.ofList_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
(ofList l).contains k = (l.map Prod.fst).contains k :=
|
||||
DHashMap.Raw.Const.contains_ofList
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α} :
|
||||
k ∈ (ofList l) ↔ (l.map Prod.fst).contains k :=
|
||||
DHashMap.Raw.Const.mem_ofList
|
||||
|
||||
theorem getElem?_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l)[k]? = none :=
|
||||
DHashMap.Raw.Const.get?_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem?_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l)[k']? = some v :=
|
||||
DHashMap.Raw.Const.get?_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getElem_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l)
|
||||
{h} :
|
||||
(ofList l)[k'] = v :=
|
||||
DHashMap.Raw.Const.get_ofList_of_mem k_beq distinct mem (h:=h)
|
||||
|
||||
theorem getElem!_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} [Inhabited β]
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l)[k]! = default :=
|
||||
DHashMap.Raw.Const.get!_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getElem!_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} [Inhabited β]
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
(ofList l)[k']! = v :=
|
||||
DHashMap.Raw.Const.get!_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [LawfulBEq α]
|
||||
{l : List (α × β)} {k : α} {fallback : β}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
getD (ofList l) k fallback = fallback :=
|
||||
DHashMap.Raw.Const.getD_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [LawfulBEq α]
|
||||
{l : List (α × β)} {k k' : α} (k_beq : k == k') {v : β} {fallback : β}
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : ⟨k, v⟩ ∈ l) :
|
||||
getD (ofList l) k' fallback = v :=
|
||||
DHashMap.Raw.Const.getD_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey? k = none :=
|
||||
DHashMap.Raw.Const.getKey?_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey? k' = some k :=
|
||||
DHashMap.Raw.Const.getKey?_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst)
|
||||
{h'} :
|
||||
(ofList l).getKey k' h' = k :=
|
||||
DHashMap.Raw.Const.getKey_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)} {k : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKey! k = default :=
|
||||
DHashMap.Raw.Const.getKey!_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_ofList_of_mem [EquivBEq α] [LawfulHashable α] [Inhabited α]
|
||||
{l : List (α × β)}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKey! k' = k :=
|
||||
DHashMap.Raw.Const.getKey!_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} {k fallback : α}
|
||||
(contains_eq_false : (l.map Prod.fst).contains k = false) :
|
||||
(ofList l).getKeyD k fallback = fallback :=
|
||||
DHashMap.Raw.Const.getKeyD_ofList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)}
|
||||
{k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a.1 == b.1) = false))
|
||||
(mem : k ∈ l.map Prod.fst) :
|
||||
(ofList l).getKeyD k' fallback = k :=
|
||||
DHashMap.Raw.Const.getKeyD_ofList_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} (distinct : l.Pairwise (fun a b => (a.1 == b.1) = false)) :
|
||||
(ofList l).size = l.length :=
|
||||
DHashMap.Raw.Const.size_ofList distinct
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).size ≤ l.length :=
|
||||
DHashMap.Raw.Const.size_ofList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List (α × β)} :
|
||||
(ofList l).isEmpty = l.isEmpty :=
|
||||
DHashMap.Raw.Const.isEmpty_ofList
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_nil :
|
||||
unitOfList ([] : List α) = ∅ :=
|
||||
ext DHashMap.Raw.Const.unitOfList_nil
|
||||
|
||||
@[simp]
|
||||
theorem unitOfList_singleton {k : α} :
|
||||
unitOfList [k] = (∅ : Raw α Unit).insertIfNew k () :=
|
||||
ext DHashMap.Raw.Const.unitOfList_singleton
|
||||
|
||||
theorem unitOfList_cons {hd : α} {tl : List α} :
|
||||
unitOfList (hd :: tl) = insertManyIfNewUnit ((∅ : Raw α Unit).insertIfNew hd ()) tl :=
|
||||
ext DHashMap.Raw.Const.unitOfList_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l).contains k = l.contains k :=
|
||||
DHashMap.Raw.Const.contains_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem mem_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ unitOfList l ↔ l.contains k :=
|
||||
DHashMap.Raw.Const.mem_unitOfList
|
||||
|
||||
theorem getKey?_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
getKey? (unitOfList l) k = none :=
|
||||
DHashMap.Raw.Const.getKey?_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey?_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getKey? (unitOfList l) k' = some k :=
|
||||
DHashMap.Raw.Const.getKey?_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h'} :
|
||||
getKey (unitOfList l) k' h' = k :=
|
||||
DHashMap.Raw.Const.getKey_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKey!_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKey! (unitOfList l) k = default :=
|
||||
DHashMap.Raw.Const.getKey!_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKey!_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKey! (unitOfList l) k' = k :=
|
||||
DHashMap.Raw.Const.getKey!_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getKeyD_unitOfList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getKeyD (unitOfList l) k fallback = fallback :=
|
||||
DHashMap.Raw.Const.getKeyD_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getKeyD_unitOfList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getKeyD (unitOfList l) k' fallback = k :=
|
||||
DHashMap.Raw.Const.getKeyD_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(unitOfList l).size = l.length :=
|
||||
DHashMap.Raw.Const.size_unitOfList distinct
|
||||
|
||||
theorem size_unitOfList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).size ≤ l.length :=
|
||||
DHashMap.Raw.Const.size_unitOfList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(unitOfList l).isEmpty = l.isEmpty :=
|
||||
DHashMap.Raw.Const.isEmpty_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getElem?_unitOfList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l)[k]? =
|
||||
if l.contains k then some () else none :=
|
||||
DHashMap.Raw.Const.get?_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getElem_unitOfList
|
||||
{l : List α} {k : α} {h} :
|
||||
(unitOfList l)[k] = () :=
|
||||
DHashMap.Raw.Const.get_unitOfList (h:=h)
|
||||
|
||||
@[simp]
|
||||
theorem getElem!_unitOfList
|
||||
{l : List α} {k : α} :
|
||||
(unitOfList l)[k]! = () :=
|
||||
DHashMap.Raw.Const.get!_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem getD_unitOfList
|
||||
{l : List α} {k : α} {fallback : Unit} :
|
||||
getD (unitOfList l) k fallback = () := by
|
||||
simp
|
||||
|
||||
end Raw
|
||||
|
||||
end Std.HashMap
|
||||
|
||||
@@ -162,6 +162,14 @@ for all `a`.
|
||||
@[inline] def toList (m : HashSet α) : List α :=
|
||||
m.inner.keys
|
||||
|
||||
/--
|
||||
Creates a hash set from a list of elements. Note that unlike repeatedly calling `insert`, if the
|
||||
collection contains multiple elements that are equal (with regard to `==`), then the last element
|
||||
in the collection will be present in the returned hash set.
|
||||
-/
|
||||
@[inline] def ofList [BEq α] [Hashable α] (l : List α) : HashSet α :=
|
||||
⟨HashMap.unitOfList l⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
@@ -233,14 +241,6 @@ appearance.
|
||||
HashSet α :=
|
||||
⟨m.inner.insertManyIfNewUnit l⟩
|
||||
|
||||
/--
|
||||
Creates a hash set from a list of elements. Note that unlike repeatedly calling `insert`, if the
|
||||
collection contains multiple elements that are equal (with regard to `==`), then the last element
|
||||
in the collection will be present in the returned hash set.
|
||||
-/
|
||||
@[inline] def ofList [BEq α] [Hashable α] (l : List α) : HashSet α :=
|
||||
⟨HashMap.unitOfList l⟩
|
||||
|
||||
/--
|
||||
Creates a hash set from an array of elements. Note that unlike repeatedly calling `insert`, if the
|
||||
collection contains multiple elements that are equal (with regard to `==`), then the last element
|
||||
|
||||
@@ -361,7 +361,7 @@ theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] :
|
||||
HashMap.isEmpty_keys
|
||||
|
||||
@[simp]
|
||||
theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α}:
|
||||
theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} :
|
||||
m.toList.contains k = m.contains k :=
|
||||
HashMap.contains_keys
|
||||
|
||||
@@ -373,6 +373,222 @@ theorem mem_toList [LawfulBEq α] [LawfulHashable α] {k : α} :
|
||||
theorem distinct_toList [EquivBEq α] [LawfulHashable α]:
|
||||
m.toList.Pairwise (fun a b => (a == b) = false) :=
|
||||
HashMap.distinct_keys
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil :
|
||||
insertMany m [] = m :=
|
||||
ext HashMap.insertManyIfNewUnit_nil
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton {k : α} :
|
||||
insertMany m [k] = m.insert k :=
|
||||
ext HashMap.insertManyIfNewUnit_list_singleton
|
||||
|
||||
theorem insertMany_cons {l : List α} {k : α} :
|
||||
insertMany m (k :: l) = insertMany (m.insert k) l :=
|
||||
ext HashMap.insertManyIfNewUnit_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(insertMany m l).contains k = (m.contains k || l.contains k) :=
|
||||
HashMap.contains_insertManyIfNewUnit_list
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ insertMany m l ↔ k ∈ m ∨ l.contains k :=
|
||||
HashMap.mem_insertManyIfNewUnit_list
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
k ∈ insertMany m l → k ∈ m :=
|
||||
HashMap.mem_of_mem_insertManyIfNewUnit_list contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
get? (insertMany m l) k = none :=
|
||||
HashMap.getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
not_mem contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
get? (insertMany m l) k' = some k :=
|
||||
HashMap.getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (mem : k ∈ m) :
|
||||
get? (insertMany m l) k = get? m k :=
|
||||
HashMap.getKey?_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem get_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) {h} :
|
||||
get (insertMany m l) k' h = k :=
|
||||
HashMap.getKey_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem get_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (mem : k ∈ m) {h} :
|
||||
get (insertMany m l) k h = get m k mem :=
|
||||
HashMap.getKey_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem get!_insertMany_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
get! (insertMany m l) k = default :=
|
||||
HashMap.getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
not_mem contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
get! (insertMany m l) k' = k :=
|
||||
HashMap.getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem get!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α} (mem : k ∈ m) :
|
||||
get! (insertMany m l) k = get! m k :=
|
||||
HashMap.getKey!_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem getD_insertMany_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] {l : List α} {k fallback : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getD (insertMany m l) k fallback = fallback :=
|
||||
HashMap.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
not_mem contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getD (insertMany m l) k' fallback = k :=
|
||||
HashMap.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
k_beq not_mem distinct mem
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α} (mem : k ∈ m) :
|
||||
getD (insertMany m l) k fallback = getD m k fallback :=
|
||||
HashMap.getKeyD_insertManyIfNewUnit_list_of_mem mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), a ∈ m → l.contains a = false) →
|
||||
(insertMany m l).size = m.size + l.length :=
|
||||
HashMap.size_insertManyIfNewUnit_list distinct
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
m.size ≤ (insertMany m l).size :=
|
||||
HashMap.size_le_size_insertManyIfNewUnit_list
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertMany m l).size ≤ m.size + l.length :=
|
||||
HashMap.size_insertManyIfNewUnit_list_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
HashMap.isEmpty_insertManyIfNewUnit_list
|
||||
|
||||
end
|
||||
|
||||
section
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List α) = ∅ :=
|
||||
ext HashMap.unitOfList_nil
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} :
|
||||
ofList [k] = (∅ : HashSet α).insert k :=
|
||||
ext HashMap.unitOfList_singleton
|
||||
|
||||
theorem ofList_cons {hd : α} {tl : List α} :
|
||||
ofList (hd :: tl) =
|
||||
insertMany ((∅ : HashSet α).insert hd) tl :=
|
||||
ext HashMap.unitOfList_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(ofList l).contains k = l.contains k :=
|
||||
HashMap.contains_unitOfList
|
||||
|
||||
theorem get?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
get? (ofList l) k = none :=
|
||||
HashMap.getKey?_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
get? (ofList l) k' = some k :=
|
||||
HashMap.getKey?_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem get_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h} :
|
||||
get (ofList l) k' h = k :=
|
||||
HashMap.getKey_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem get!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
get! (ofList l) k = default :=
|
||||
HashMap.getKey!_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get!_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
get! (ofList l) k' = k :=
|
||||
HashMap.getKey!_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getD (ofList l) k fallback = fallback :=
|
||||
HashMap.getKeyD_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getD (ofList l) k' fallback = k :=
|
||||
HashMap.getKeyD_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(ofList l).size = l.length :=
|
||||
HashMap.size_unitOfList distinct
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(ofList l).size ≤ l.length :=
|
||||
HashMap.size_unitOfList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(ofList l).isEmpty = l.isEmpty :=
|
||||
HashMap.isEmpty_unitOfList
|
||||
|
||||
end
|
||||
|
||||
end Std.HashSet
|
||||
|
||||
@@ -165,6 +165,14 @@ for all `a`.
|
||||
@[inline] def toList (m : Raw α) : List α :=
|
||||
m.inner.keys
|
||||
|
||||
/--
|
||||
Creates a hash set from a list of elements. Note that unlike repeatedly calling `insert`, if the
|
||||
collection contains multiple elements that are equal (with regard to `==`), then the last element
|
||||
in the collection will be present in the returned hash set.
|
||||
-/
|
||||
@[inline] def ofList [BEq α] [Hashable α] (l : List α) : Raw α :=
|
||||
⟨HashMap.Raw.unitOfList l⟩
|
||||
|
||||
section Unverified
|
||||
|
||||
/-! We currently do not provide lemmas for the functions below. -/
|
||||
@@ -231,14 +239,6 @@ appearance.
|
||||
Raw α :=
|
||||
⟨m.inner.insertManyIfNewUnit l⟩
|
||||
|
||||
/--
|
||||
Creates a hash set from a list of elements. Note that unlike repeatedly calling `insert`, if the
|
||||
collection contains multiple elements that are equal (with regard to `==`), then the last element
|
||||
in the collection will be present in the returned hash set.
|
||||
-/
|
||||
@[inline] def ofList [BEq α] [Hashable α] (l : List α) : Raw α :=
|
||||
⟨HashMap.Raw.unitOfList l⟩
|
||||
|
||||
/--
|
||||
Creates a hash set from an array of elements. Note that unlike repeatedly calling `insert`, if the
|
||||
collection contains multiple elements that are equal (with regard to `==`), then the last element
|
||||
|
||||
@@ -367,22 +367,22 @@ theorem containsThenInsert_snd (h : m.WF) {k : α} : (m.containsThenInsert k).2
|
||||
ext (HashMap.Raw.containsThenInsertIfNew_snd h.out)
|
||||
|
||||
@[simp]
|
||||
theorem length_toList [EquivBEq α] [LawfulHashable α] (h : m.WF):
|
||||
theorem length_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.toList.length = m.size :=
|
||||
HashMap.Raw.length_keys h.1
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] (h : m.WF):
|
||||
theorem isEmpty_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.toList.isEmpty = m.isEmpty :=
|
||||
HashMap.Raw.isEmpty_keys h.1
|
||||
|
||||
@[simp]
|
||||
theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} (h : m.WF):
|
||||
theorem contains_toList [EquivBEq α] [LawfulHashable α] {k : α} (h : m.WF) :
|
||||
m.toList.contains k = m.contains k :=
|
||||
HashMap.Raw.contains_keys h.1
|
||||
|
||||
@[simp]
|
||||
theorem mem_toList [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α}:
|
||||
theorem mem_toList [LawfulBEq α] [LawfulHashable α] (h : m.WF) {k : α} :
|
||||
k ∈ m.toList ↔ k ∈ m :=
|
||||
HashMap.Raw.mem_keys h.1
|
||||
|
||||
@@ -390,6 +390,222 @@ theorem distinct_toList [EquivBEq α] [LawfulHashable α] (h : m.WF) :
|
||||
m.toList.Pairwise (fun a b => (a == b) = false) :=
|
||||
HashMap.Raw.distinct_keys h.1
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_nil (h : m.WF) :
|
||||
insertMany m [] = m :=
|
||||
ext (HashMap.Raw.insertManyIfNewUnit_nil h.1)
|
||||
|
||||
@[simp]
|
||||
theorem insertMany_list_singleton (h : m.WF) {k : α} :
|
||||
insertMany m [k] = m.insert k :=
|
||||
ext (HashMap.Raw.insertManyIfNewUnit_list_singleton h.1)
|
||||
|
||||
theorem insertMany_cons (h : m.WF) {l : List α} {k : α} :
|
||||
insertMany m (k :: l) = insertMany (m.insert k) l :=
|
||||
ext (HashMap.Raw.insertManyIfNewUnit_cons h.1)
|
||||
|
||||
@[simp]
|
||||
theorem contains_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
(insertMany m l).contains k = (m.contains k || l.contains k) :=
|
||||
HashMap.Raw.contains_insertManyIfNewUnit_list h.1
|
||||
|
||||
@[simp]
|
||||
theorem mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} :
|
||||
k ∈ insertMany m l ↔ k ∈ m ∨ l.contains k :=
|
||||
HashMap.Raw.mem_insertManyIfNewUnit_list h.1
|
||||
|
||||
theorem mem_of_mem_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
k ∈ insertMany m l → k ∈ m :=
|
||||
HashMap.Raw.mem_of_mem_insertManyIfNewUnit_list h.1 contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
get? (insertMany m l) k = none :=
|
||||
HashMap.Raw.getKey?_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
h.1 not_mem contains_eq_false
|
||||
|
||||
theorem get?_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
get? (insertMany m l) k' = some k :=
|
||||
HashMap.Raw.getKey?_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.1 k_beq not_mem distinct mem
|
||||
|
||||
theorem get?_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k : α} (mem : k ∈ m) :
|
||||
get? (insertMany m l) k = get? m k :=
|
||||
HashMap.Raw.getKey?_insertManyIfNewUnit_list_of_mem h.1 mem
|
||||
|
||||
theorem get_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) {h'} :
|
||||
get (insertMany m l) k' h' = k :=
|
||||
HashMap.Raw.getKey_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.1 k_beq not_mem distinct mem
|
||||
|
||||
theorem get_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k : α} (mem : k ∈ m) {h₃} :
|
||||
get (insertMany m l) k h₃ = get m k mem :=
|
||||
HashMap.Raw.getKey_insertManyIfNewUnit_list_of_mem h.1 mem
|
||||
|
||||
theorem get!_insertMany_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] [Inhabited α] (h : m.WF) {l : List α} {k : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
get! (insertMany m l) k = default :=
|
||||
HashMap.Raw.getKey!_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
h.1 not_mem contains_eq_false
|
||||
|
||||
theorem get!_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.WF) {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
get! (insertMany m l) k' = k :=
|
||||
HashMap.Raw.getKey!_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.1 k_beq not_mem distinct mem
|
||||
|
||||
theorem get!_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] (h : m.WF) {l : List α} {k : α} (mem : k ∈ m) :
|
||||
get! (insertMany m l) k = get! m k :=
|
||||
HashMap.Raw.getKey!_insertManyIfNewUnit_list_of_mem h.1 mem
|
||||
|
||||
theorem getD_insertMany_list_of_not_mem_of_contains_eq_false
|
||||
[EquivBEq α] [LawfulHashable α] (h : m.WF) {l : List α} {k fallback : α}
|
||||
(not_mem : ¬ k ∈ m) (contains_eq_false : l.contains k = false) :
|
||||
getD (insertMany m l) k fallback = fallback :=
|
||||
HashMap.Raw.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_contains_eq_false
|
||||
h.1 not_mem contains_eq_false
|
||||
|
||||
theorem getD_insertMany_list_of_not_mem_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(not_mem : ¬ k ∈ m)
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
getD (insertMany m l) k' fallback = k :=
|
||||
HashMap.Raw.getKeyD_insertManyIfNewUnit_list_of_not_mem_of_mem
|
||||
h.1 k_beq not_mem distinct mem
|
||||
|
||||
theorem getD_insertMany_list_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
(h : m.WF) {l : List α} {k fallback : α} (mem : k ∈ m) :
|
||||
getD (insertMany m l) k fallback = getD m k fallback :=
|
||||
HashMap.Raw.getKeyD_insertManyIfNewUnit_list_of_mem h.1 mem
|
||||
|
||||
theorem size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(∀ (a : α), a ∈ m → l.contains a = false) →
|
||||
(insertMany m l).size = m.size + l.length :=
|
||||
HashMap.Raw.size_insertManyIfNewUnit_list h.1 distinct
|
||||
|
||||
theorem size_le_size_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
m.size ≤ (insertMany m l).size :=
|
||||
HashMap.Raw.size_le_size_insertManyIfNewUnit_list h.1
|
||||
|
||||
theorem size_insertMany_list_le [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
(insertMany m l).size ≤ m.size + l.length :=
|
||||
HashMap.Raw.size_insertManyIfNewUnit_list_le h.1
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_insertMany_list [EquivBEq α] [LawfulHashable α] (h : m.WF)
|
||||
{l : List α} :
|
||||
(insertMany m l).isEmpty = (m.isEmpty && l.isEmpty) :=
|
||||
HashMap.Raw.isEmpty_insertManyIfNewUnit_list h.1
|
||||
|
||||
@[simp]
|
||||
theorem ofList_nil :
|
||||
ofList ([] : List α) = ∅ :=
|
||||
ext HashMap.Raw.unitOfList_nil
|
||||
|
||||
@[simp]
|
||||
theorem ofList_singleton {k : α} :
|
||||
ofList [k] = (∅ : Raw α).insert k :=
|
||||
ext HashMap.Raw.unitOfList_singleton
|
||||
|
||||
theorem ofList_cons {hd : α} {tl : List α} :
|
||||
ofList (hd :: tl) = insertMany ((∅ : Raw α).insert hd) tl :=
|
||||
ext HashMap.Raw.unitOfList_cons
|
||||
|
||||
@[simp]
|
||||
theorem contains_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
(ofList l).contains k = l.contains k :=
|
||||
HashMap.Raw.contains_unitOfList
|
||||
|
||||
@[simp]
|
||||
theorem mem_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} :
|
||||
k ∈ ofList l ↔ l.contains k :=
|
||||
HashMap.Raw.mem_unitOfList
|
||||
|
||||
theorem get?_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k : α} (contains_eq_false : l.contains k = false) :
|
||||
get? (ofList l) k = none :=
|
||||
HashMap.Raw.getKey?_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get?_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) (mem : k ∈ l) :
|
||||
get? (ofList l) k' = some k :=
|
||||
HashMap.Raw.getKey?_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem get_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
{k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) {h'} :
|
||||
get (ofList l) k' h' = k :=
|
||||
HashMap.Raw.getKey_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem get!_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
get! (ofList l) k = default :=
|
||||
HashMap.Raw.getKey!_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem get!_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
[Inhabited α] {l : List α} {k k' : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
get! (ofList l) k' = k :=
|
||||
HashMap.Raw.getKey!_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem getD_ofList_of_contains_eq_false [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k fallback : α}
|
||||
(contains_eq_false : l.contains k = false) :
|
||||
getD (ofList l) k fallback = fallback :=
|
||||
HashMap.Raw.getKeyD_unitOfList_of_contains_eq_false contains_eq_false
|
||||
|
||||
theorem getD_ofList_of_mem [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} {k k' fallback : α} (k_beq : k == k')
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false))
|
||||
(mem : k ∈ l) :
|
||||
getD (ofList l) k' fallback = k :=
|
||||
HashMap.Raw.getKeyD_unitOfList_of_mem k_beq distinct mem
|
||||
|
||||
theorem size_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α}
|
||||
(distinct : l.Pairwise (fun a b => (a == b) = false)) :
|
||||
(ofList l).size = l.length :=
|
||||
HashMap.Raw.size_unitOfList distinct
|
||||
|
||||
theorem size_ofList_le [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(ofList l).size ≤ l.length :=
|
||||
HashMap.Raw.size_unitOfList_le
|
||||
|
||||
@[simp]
|
||||
theorem isEmpty_ofList [EquivBEq α] [LawfulHashable α]
|
||||
{l : List α} :
|
||||
(ofList l).isEmpty = l.isEmpty :=
|
||||
HashMap.Raw.isEmpty_unitOfList
|
||||
|
||||
end Raw
|
||||
|
||||
end Std.HashSet
|
||||
|
||||
@@ -162,7 +162,7 @@ structure Cache.Inv (cnf : CNF (CNFVar aig)) (marks : Array Bool) (hmarks : mark
|
||||
/--
|
||||
The `Cache` invariant always holds for an empty CNF when all nodes are unmarked.
|
||||
-/
|
||||
theorem Cache.Inv_init : Inv ([] : CNF (CNFVar aig)) (mkArray aig.decls.size false) (by simp) where
|
||||
theorem Cache.Inv_init : Inv ([] : CNF (CNFVar aig)) (Array.replicate aig.decls.size false) (by simp) where
|
||||
hmark := by
|
||||
intro lhs rhs linv rinv idx hbound hmarked heq
|
||||
simp at hmarked
|
||||
@@ -254,7 +254,7 @@ theorem Cache.IsExtensionBy_set (cache1 : Cache aig cnf1) (cache2 : Cache aig cn
|
||||
A cache with no entries is valid for an empty CNF.
|
||||
-/
|
||||
def Cache.init (aig : AIG Nat) : Cache aig [] where
|
||||
marks := mkArray aig.decls.size false
|
||||
marks := Array.replicate aig.decls.size false
|
||||
hmarks := by simp
|
||||
inv := Inv_init
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ can appear in the formula (hence why the parameter `n` is called `numVarsSucc` b
|
||||
namespace DefaultFormula
|
||||
|
||||
instance {n : Nat} : Inhabited (DefaultFormula n) where
|
||||
default := ⟨#[], #[], #[], Array.mkArray n unassigned⟩
|
||||
default := ⟨#[], #[], #[], Array.replicate n unassigned⟩
|
||||
|
||||
/-- Note: This function is only for reasoning about semantics. Its efficiency doesn't actually matter -/
|
||||
def toList {n : Nat} (f : DefaultFormula n) : List (DefaultClause n) :=
|
||||
@@ -88,7 +88,7 @@ Note: This function assumes that the provided `clauses` Array is indexed accordi
|
||||
field invariant described in the DefaultFormula doc comment.
|
||||
-/
|
||||
def ofArray {n : Nat} (clauses : Array (Option (DefaultClause n))) : DefaultFormula n :=
|
||||
let assignments := clauses.foldl ofArray_fold_fn (Array.mkArray n unassigned)
|
||||
let assignments := clauses.foldl ofArray_fold_fn (Array.replicate n unassigned)
|
||||
⟨clauses, #[], #[], assignments⟩
|
||||
|
||||
def insert {n : Nat} (f : DefaultFormula n) (c : DefaultClause n) : DefaultFormula n :=
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace DefaultFormula
|
||||
|
||||
open Std.Sat
|
||||
open DefaultClause DefaultFormula Assignment
|
||||
open Array (replicate)
|
||||
|
||||
/--
|
||||
This invariant states that if the `assignments` field of a default formula `f` indicates that `f`
|
||||
@@ -107,17 +108,17 @@ theorem readyForRupAdd_ofArray {n : Nat} (arr : Array (Option (DefaultClause n))
|
||||
· simp only [ofArray]
|
||||
· have hsize : (ofArray arr).assignments.size = n := by
|
||||
simp only [ofArray, ← Array.foldl_toList]
|
||||
have hb : (mkArray n unassigned).size = n := by simp only [Array.size_mkArray]
|
||||
have hb : (replicate n unassigned).size = n := by simp only [Array.size_replicate]
|
||||
have hl (acc : Array Assignment) (ih : acc.size = n) (cOpt : Option (DefaultClause n)) (_cOpt_in_arr : cOpt ∈ arr.toList) :
|
||||
(ofArray_fold_fn acc cOpt).size = n := by rw [size_ofArray_fold_fn acc cOpt, ih]
|
||||
exact List.foldlRecOn arr.toList ofArray_fold_fn (mkArray n unassigned) hb hl
|
||||
exact List.foldlRecOn arr.toList ofArray_fold_fn (replicate n unassigned) hb hl
|
||||
apply Exists.intro hsize
|
||||
let ModifiedAssignmentsInvariant (assignments : Array Assignment) : Prop :=
|
||||
∃ hsize : assignments.size = n,
|
||||
∀ i : PosFin n, ∀ b : Bool, hasAssignment b (assignments[i.1]'(by rw [hsize]; exact i.2.2)) →
|
||||
(unit (i, b)) ∈ toList (ofArray arr)
|
||||
have hb : ModifiedAssignmentsInvariant (mkArray n unassigned) := by
|
||||
have hsize : (mkArray n unassigned).size = n := by simp only [Array.size_mkArray]
|
||||
have hb : ModifiedAssignmentsInvariant (replicate n unassigned) := by
|
||||
have hsize : (replicate n unassigned).size = n := by simp only [Array.size_replicate]
|
||||
apply Exists.intro hsize
|
||||
intro i b h
|
||||
by_cases hb : b <;> simp [hasAssignment, hb, hasPosAssignment, hasNegAssignment] at h
|
||||
@@ -185,7 +186,7 @@ theorem readyForRupAdd_ofArray {n : Nat} (arr : Array (Option (DefaultClause n))
|
||||
· next i_ne_l =>
|
||||
simp only [Array.getElem_modify_of_ne (Ne.symm i_ne_l)] at h
|
||||
exact ih i b h
|
||||
rcases List.foldlRecOn arr.toList ofArray_fold_fn (mkArray n unassigned) hb hl with ⟨_h_size, h'⟩
|
||||
rcases List.foldlRecOn arr.toList ofArray_fold_fn (replicate n unassigned) hb hl with ⟨_h_size, h'⟩
|
||||
intro i b h
|
||||
simp only [ofArray, ← Array.foldl_toList] at h
|
||||
exact h' i b h
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Lake
|
||||
|
||||
/-- A recursive build of a Lake build store that may encounter a cycle. -/
|
||||
abbrev RecBuildM :=
|
||||
CallStackT BuildKey <| BuildT <| ELogT <| StateT BuildStore <| BaseIO
|
||||
CallStackT BuildKey <| BuildT <| ELogT <| StateRefT BuildStore BaseIO
|
||||
|
||||
instance : MonadLift LogIO RecBuildM := ⟨ELogT.takeAndRun⟩
|
||||
|
||||
@@ -32,10 +32,10 @@ Run a `JobM` action in `RecBuildM` (and thus `FetchM`).
|
||||
Generally, this should not be done, and instead a job action
|
||||
should be run asynchronously in a Job (e.g., via `Job.async`).
|
||||
-/
|
||||
@[inline] def RecBuildM.runJobM (x : JobM α) : RecBuildM α := fun _ ctx log store => do
|
||||
@[inline] def RecBuildM.runJobM (x : JobM α) : RecBuildM α := fun _ ctx log => do
|
||||
match (← x ctx {log}) with
|
||||
| .ok a s => return (.ok a s.log, store)
|
||||
| .error e s => return (.error e s.log, store)
|
||||
| .ok a s => return .ok a s.log
|
||||
| .error e s => return .error e s.log
|
||||
|
||||
instance : MonadLift JobM RecBuildM := ⟨RecBuildM.runJobM⟩
|
||||
|
||||
@@ -43,7 +43,7 @@ instance : MonadLift JobM RecBuildM := ⟨RecBuildM.runJobM⟩
|
||||
@[inline] def RecBuildM.run
|
||||
(stack : CallStack BuildKey) (store : BuildStore) (build : RecBuildM α)
|
||||
: CoreBuildM (α × BuildStore) := fun ctx log => do
|
||||
match (← build stack ctx log store) with
|
||||
match (← (build stack ctx log).run store) with
|
||||
| (.ok a log, store) => return .ok (a, store) log
|
||||
| (.error e log, _) => return .error e log
|
||||
|
||||
@@ -92,16 +92,16 @@ def ensureJob (x : FetchM (Job α))
|
||||
: FetchM (Job α) := fun fetch stack ctx log store => do
|
||||
let iniPos := log.endPos
|
||||
match (← (withLoggedIO x) fetch stack ctx log store) with
|
||||
| (.ok job log, store) =>
|
||||
| .ok job log =>
|
||||
if iniPos < log.endPos then
|
||||
let (log, jobLog) := log.split iniPos
|
||||
let job := job.mapResult (sync := true) (·.prependLog jobLog)
|
||||
return (.ok job log, store)
|
||||
return .ok job log
|
||||
else
|
||||
return (.ok job log, store)
|
||||
| (.error _ log, store) =>
|
||||
return .ok job log
|
||||
| .error _ log =>
|
||||
let (log, jobLog) := log.split iniPos
|
||||
return (.ok (.error jobLog) log, store)
|
||||
return .ok (.error jobLog) log
|
||||
|
||||
/--
|
||||
Registers the job for the top-level build monitor,
|
||||
|
||||
@@ -16,19 +16,35 @@ instance [Monad m] [EqOfCmpWrt κ β cmp] : MonadDStore κ β (StateT (DRBMap κ
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
instance [MonadLiftT (ST ω) m] [Monad m] [EqOfCmpWrt κ β cmp] : MonadDStore κ β (StateRefT' ω (DRBMap κ β cmp) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
instance [Monad m] : MonadStore κ α (StateT (RBMap κ α cmp) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
instance [MonadLiftT (ST ω) m] [Monad m] : MonadStore κ α (StateRefT' ω (RBMap κ α cmp) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
instance [Monad m] : MonadStore κ α (StateT (RBArray κ α cmp) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
instance [MonadLiftT (ST ω) m] [Monad m] : MonadStore κ α (StateRefT' ω (RBArray κ α cmp) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
-- uses the eagerly specialized `RBMap` functions in `NameMap`
|
||||
instance [Monad m] : MonadStore Name α (StateT (NameMap α) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
instance [MonadLiftT (ST ω) m] [Monad m] : MonadStore Name α (StateRefT' ω (NameMap α) m) where
|
||||
fetch? k := return (← get).find? k
|
||||
store k a := modify (·.insert k a)
|
||||
|
||||
@[inline] instance [MonadDStore κ β m] [t : FamilyOut β k α] : MonadStore1Of k α m where
|
||||
fetch? := cast (by rw [t.family_key_eq_type]) <| fetch? (m := m) k
|
||||
store a := store k <| cast t.family_key_eq_type.symm a
|
||||
|
||||
BIN
stage0/src/runtime/CMakeLists.txt
generated
BIN
stage0/src/runtime/CMakeLists.txt
generated
Binary file not shown.
BIN
stage0/src/runtime/init_module.cpp
generated
BIN
stage0/src/runtime/init_module.cpp
generated
Binary file not shown.
BIN
stage0/src/runtime/libuv.cpp
generated
BIN
stage0/src/runtime/libuv.cpp
generated
Binary file not shown.
BIN
stage0/src/runtime/libuv.h
generated
BIN
stage0/src/runtime/libuv.h
generated
Binary file not shown.
BIN
stage0/src/runtime/object.h
generated
BIN
stage0/src/runtime/object.h
generated
Binary file not shown.
BIN
stage0/src/runtime/uv/event_loop.cpp
generated
Normal file
BIN
stage0/src/runtime/uv/event_loop.cpp
generated
Normal file
Binary file not shown.
BIN
stage0/src/runtime/uv/event_loop.h
generated
Normal file
BIN
stage0/src/runtime/uv/event_loop.h
generated
Normal file
Binary file not shown.
BIN
stage0/src/runtime/uv/timer.cpp
generated
Normal file
BIN
stage0/src/runtime/uv/timer.cpp
generated
Normal file
Binary file not shown.
BIN
stage0/src/runtime/uv/timer.h
generated
Normal file
BIN
stage0/src/runtime/uv/timer.h
generated
Normal file
Binary file not shown.
BIN
stage0/src/util/shell.cpp
generated
BIN
stage0/src/util/shell.cpp
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Array/Basic.c
generated
BIN
stage0/stdlib/Init/Data/Array/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/BitVec/Lemmas.c
generated
BIN
stage0/stdlib/Init/Data/BitVec/Lemmas.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/UInt/Bitwise.c
generated
BIN
stage0/stdlib/Init/Data/UInt/Bitwise.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Vector/Basic.c
generated
BIN
stage0/stdlib/Init/Data/Vector/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Data/Vector/Lemmas.c
generated
BIN
stage0/stdlib/Init/Data/Vector/Lemmas.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Grind.c
generated
BIN
stage0/stdlib/Init/Grind.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Grind/Offset.c
generated
BIN
stage0/stdlib/Init/Grind/Offset.c
generated
Binary file not shown.
BIN
stage0/stdlib/Init/Grind/PP.c
generated
Normal file
BIN
stage0/stdlib/Init/Grind/PP.c
generated
Normal file
Binary file not shown.
BIN
stage0/stdlib/Lake/Build/Actions.c
generated
BIN
stage0/stdlib/Lake/Build/Actions.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/Build/Common.c
generated
BIN
stage0/stdlib/Lake/Build/Common.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/Build/Job.c
generated
BIN
stage0/stdlib/Lake/Build/Job.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/Build/Module.c
generated
BIN
stage0/stdlib/Lake/Build/Module.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/CLI/Build.c
generated
BIN
stage0/stdlib/Lake/CLI/Build.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/Load/Lean/Elab.c
generated
BIN
stage0/stdlib/Lake/Load/Lean/Elab.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/Load/Toml.c
generated
BIN
stage0/stdlib/Lake/Load/Toml.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lake/Toml/Decode.c
generated
BIN
stage0/stdlib/Lake/Toml/Decode.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/AddDecl.c
generated
BIN
stage0/stdlib/Lean/AddDecl.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/BuiltinDocAttr.c
generated
BIN
stage0/stdlib/Lean/BuiltinDocAttr.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/Compiler/IR/Basic.c
generated
BIN
stage0/stdlib/Lean/Compiler/IR/Basic.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/Compiler/InitAttr.c
generated
BIN
stage0/stdlib/Lean/Compiler/InitAttr.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/Compiler/LCNF/MonoTypes.c
generated
BIN
stage0/stdlib/Lean/Compiler/LCNF/MonoTypes.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/Compiler/Old.c
generated
BIN
stage0/stdlib/Lean/Compiler/Old.c
generated
Binary file not shown.
BIN
stage0/stdlib/Lean/CoreM.c
generated
BIN
stage0/stdlib/Lean/CoreM.c
generated
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user