Compare commits

..

16 Commits

Author SHA1 Message Date
Kim Morrison
c8c2b7832c feat: rename Array.mkArray to replicate 2025-01-16 18:52:37 +11:00
Kim Morrison
80ddbf45eb feat: align List/Array/Vector.flatMap (#6660)
This PR defines `Vector.flatMap`, changes the order of arguments in
`List.flatMap` for consistency, and aligns the lemmas for
`List`/`Array`/`Vector` `flatMap`.
2025-01-16 05:19:28 +00:00
Leonardo de Moura
3a6c5cf4f1 feat: canonicalizer diagnostics (#6662)
This PR improves the canonicalizer used in the `grind` tactic and the
diagnostics it produces. It also adds a new configuration option,
`canonHeartbeats`, to address (some of) the issues. Here is an example
illustrating the new diagnostics, where we intentionally create a
problem by using a very small number of heartbeats.

<img width="1173" alt="image"
src="https://github.com/user-attachments/assets/484005c8-dcaa-4164-8fbf-617864ed7350"
/>
2025-01-16 04:59:18 +00:00
Leonardo de Moura
af4a7d7e98 fix: grind term preprocessor (#6659)
This PR fixes a bug in the `grind` term preprocessor. It was abstracting
nested proofs **before** reducible constants were unfolded.

---------

Co-authored-by: Kim Morrison <kim@tqft.net>
2025-01-16 01:22:06 +00:00
Leonardo de Moura
6259b4742c feat: improve case-split heuristic used in grind (#6658)
This PR ensures that `grind` avoids case-splitting on terms congruent to
those that have already been case-split.
2025-01-16 00:17:27 +00:00
Mac Malone
0050e9369c refactor: lake: use StateRefT for BuildStore (#6290)
This PR uses `StateRefT` instead of `StateT` to equip the Lake build
monad with a build store.

As a IO reference, different threads may now contend with the build
store. However, benchmark results indicate that this does not have a
significant performance impact. On a synchronization front, the lack of
a mutex should not be a concern because the build store is a
memorization data structure and thus order is theoretically irrelevant.
2025-01-15 23:42:32 +00:00
Leonardo de Moura
64cf5e5e6a feat: improve grind search procedure (#6657)
This PR improves the `grind` search procedure, and adds the new
configuration option: `failures`.
2025-01-15 23:08:41 +00:00
Kim Morrison
127b3f9191 feat: more grind tests (#6650)
This PR adds some tests for `grind`, working on `List` lemmas.
2025-01-15 23:00:23 +00:00
Leonardo de Moura
65175dc7d4 feat: improvegrind diagnostic information (#6656)
This PR improves the diagnostic information provided in `grind` failure
states. We now include the list of issues found during the search, and
all search thresholds that have been reached. This PR also improves its
formatting.
2025-01-15 20:57:28 +00:00
Leonardo de Moura
54f06ccd64 feat: better support for partial applications in the E-matching procedure (#6654)
This PR improves the support for partial applications in the E-matching
procedure used in `grind`.
2025-01-15 18:31:34 +00:00
Leonardo de Moura
b3f8feffd3 fix: improve E-matching pattern selection heuristics (#6653)
This PR improves the E-matching pattern selection heuristics in the
`grind` tactic. They now take into account type predicates and
transformers.
2025-01-15 16:43:59 +00:00
Lukas Gerlach
6665837232 feat: verify insertMany method for adding lists to HashMaps (#6211)
This PR verifies the `insertMany` method on `HashMap`s for the special
case of inserting lists.

---------

Co-authored-by: jt0202 <johannes.tantow@gmail.com>
Co-authored-by: monsterkrampe <monsterkrampe@users.noreply.github.com>
Co-authored-by: Johannes Tantow <44068763+jt0202@users.noreply.github.com>
2025-01-15 14:57:26 +00:00
Henrik Böving
c7fd873333 feat: tag lemmas 2025-01-15 15:17:36 +01:00
Henrik Böving
a10ce9492f chore: update stage0 2025-01-15 15:17:36 +01:00
Henrik Böving
838ad281f2 feat: add the int_toBitVec simpset 2025-01-15 15:17:36 +01:00
Henrik Böving
a1ef26bd8b perf: improve bv_decide preprocessing based on Bitwuzla optimisations (#6641)
This PR implements several optimisation tricks from Bitwuzla's
preprocessing passes into the Lean equivalent in `bv_decide`. Note that
these changes are mostly geared towards large proof states as for
example seen in SMT-Lib.
2025-01-15 12:09:43 +00:00
199 changed files with 6585 additions and 556 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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]

View File

@@ -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) : α :=

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 α :=

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 ())

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 ()
/--

View File

@@ -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

View File

@@ -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

View File

@@ -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 ()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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'

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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 := {}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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. -/

View File

@@ -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) :=

View File

@@ -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₀

View File

@@ -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]

View File

@@ -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

View File

@@ -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 :=

View File

@@ -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

View File

@@ -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
/--

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 :=

View File

@@ -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

View File

@@ -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,

View File

@@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

BIN
stage0/src/runtime/uv/timer.cpp generated Normal file

Binary file not shown.

BIN
stage0/src/runtime/uv/timer.h generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
stage0/stdlib/Init/Grind/PP.c generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More