lean4-htt/src/Std/Data/DHashMap/Internal/RawLemmas.lean
2024-08-17 04:11:35 +00:00

650 lines
27 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Markus Himmel
-/
prelude
import Std.Data.DHashMap.Internal.WF
/-!
This is an internal implementation file of the hash map. Users of the hash map should not rely on
the contents of this file.
File contents: verification of operations on `Raw₀`
-/
set_option linter.missingDocs true
set_option autoImplicit false
open Std.DHashMap.Internal.List
universe u v
variable {α : Type u} {β : α → Type v}
namespace Std.DHashMap.Internal
section empty
@[simp]
theorem Raw₀.buckets_empty {c} {i : Nat} {h} :
(empty c : Raw₀ α β).1.buckets[i]'h = AssocList.nil := by
simp [empty]
@[simp]
theorem Raw.buckets_empty {c} {i : Nat} {h} :
(Raw.empty c : Raw α β).buckets[i]'h = AssocList.nil := by
simp [Raw.empty]
@[simp]
theorem Raw.buckets_emptyc {i : Nat} {h} :
(∅ : Raw α β).buckets[i]'h = AssocList.nil :=
buckets_empty
variable [BEq α] [Hashable α]
@[simp]
theorem buckets_empty {c} {i : Nat} {h} :
(empty c : DHashMap α β).1.buckets[i]'h = AssocList.nil := by
simp [empty]
@[simp]
theorem buckets_emptyc {i : Nat} {h} :
(∅ : DHashMap α β).1.buckets[i]'h = AssocList.nil :=
buckets_empty
end empty
namespace Raw₀
variable (m : Raw₀ α β)
@[simp]
theorem size_empty {c} : (empty c : Raw₀ α β).1.size = 0 := rfl
theorem isEmpty_eq_size_eq_zero : m.1.isEmpty = (m.1.size == 0) := by
simp [Raw.isEmpty]
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₀))
/-- Internal implementation detail of the hash map -/
scoped macro "empty" : tactic => `(tactic| { intros; simp_all [List.isEmpty_iff] } )
open Lean
private def queryNames : Array Name :=
#[``contains_eq_containsKey, ``Raw.isEmpty_eq_isEmpty, ``Raw.size_eq_length,
``get?_eq_getValueCast?, ``Const.get?_eq_getValue?, ``get_eq_getValueCast,
``Const.get_eq_getValue, ``get!_eq_getValueCast!, ``getD_eq_getValueCastD,
``Const.get!_eq_getValue!, ``Const.getD_eq_getValueD]
private def modifyNames : Array Name :=
#[``toListModel_insert, ``toListModel_erase, ``toListModel_insertIfNew]
private def congrNames : MacroM (Array (TSyntax `term)) := do
return #[← `(_root_.List.Perm.isEmpty_eq), ← `(containsKey_of_perm),
← `(_root_.List.Perm.length_eq), ← `(getValueCast?_of_perm _),
← `(getValue?_of_perm _), ← `(getValue_of_perm _), ← `(getValueCast_of_perm _),
← `(getValueCast!_of_perm _), ← `(getValueCastD_of_perm _), ← `(getValue!_of_perm _),
← `(getValueD_of_perm _) ]
/-- Internal implementation detail of the hash map -/
scoped syntax "simp_to_model" ("using" term)? : tactic
macro_rules
| `(tactic| simp_to_model $[using $using?]?) => do
let mut congrModify : Array (TSyntax `term) := #[]
for congr in (← congrNames) do
for modify in modifyNames do
congrModify := congrModify.push (← `($congr:term ($(mkIdent modify) ..)))
`(tactic|
(simp (discharger := wf_trivial) only
[$[$(Array.map Lean.mkIdent queryNames):term],*, $[$congrModify:term],*]
$[apply $(using?.toArray):term];*)
<;> wf_trivial)
@[simp]
theorem isEmpty_empty {c} : (empty c : Raw₀ α β).1.isEmpty := by
rw [Raw.isEmpty_eq_isEmpty wfImp_empty, toListModel_buckets_empty, List.isEmpty_nil]
@[simp]
theorem isEmpty_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insert k v).1.isEmpty = false := by
simp_to_model using List.isEmpty_insertEntry
theorem contains_congr [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a b : α} (hab : a == b) :
m.contains a = m.contains b := by
simp_to_model using List.containsKey_congr hab
@[simp]
theorem contains_empty {a : α} {c : Nat} : (empty c : Raw₀ α β).contains a = false := by
simp [contains]
theorem contains_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} :
m.1.isEmpty = true → m.contains a = false := by
simp_to_model; empty
theorem isEmpty_eq_false_iff_exists_contains_eq_true [EquivBEq α] [LawfulHashable α] (h : m.1.WF) :
m.1.isEmpty = false ↔ ∃ a, m.contains a = true := by
simp_to_model using List.isEmpty_eq_false_iff_exists_containsKey
theorem isEmpty_iff_forall_contains [EquivBEq α] [LawfulHashable α] (h : m.1.WF) :
m.1.isEmpty ↔ ∀ a, m.contains a = false := by
simp_to_model using List.isEmpty_iff_forall_containsKey
theorem contains_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {v : β k} :
(m.insert k v).contains a = ((k == a) || m.contains a) := by
simp_to_model using List.containsKey_insertEntry
theorem contains_of_contains_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α}
{v : β k} : (m.insert k v).contains a → (k == a) = false → m.contains a := by
simp_to_model using List.containsKey_of_containsKey_insertEntry
theorem contains_insert_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insert k v).contains k := by
simp_to_model using List.containsKey_insertEntry_self
theorem size_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insert k v).1.size = if m.contains k then m.1.size else m.1.size + 1 := by
simp_to_model using List.length_insertEntry
theorem size_le_size_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
m.1.size ≤ (m.insert k v).1.size := by
simp_to_model using List.length_le_length_insertEntry
theorem size_insert_le [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insert k v).1.size ≤ m.1.size + 1 := by
simp_to_model using List.length_insertEntry_le
@[simp]
theorem erase_empty {k : α} {c : Nat} : (empty c : Raw₀ α β).erase k = empty c := by
simp [erase, empty]
theorem isEmpty_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} :
(m.erase k).1.isEmpty = (m.1.isEmpty || (m.1.size == 1 && m.contains k)) := by
simp_to_model using List.isEmpty_eraseKey
theorem contains_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} :
(m.erase k).contains a = (!(k == a) && m.contains a) := by
simp_to_model using List.containsKey_eraseKey
theorem contains_of_contains_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} :
(m.erase k).contains a → m.contains a := by
simp_to_model using List.containsKey_of_containsKey_eraseKey
theorem size_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} :
(m.erase k).1.size = if m.contains k then m.1.size - 1 else m.1.size := by
simp_to_model using List.length_eraseKey
theorem size_erase_le [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} :
(m.erase k).1.size ≤ m.1.size := by
simp_to_model using List.length_eraseKey_le
theorem size_le_size_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} :
m.1.size ≤ (m.erase k).1.size + 1 := by
simp_to_model using List.length_le_length_eraseKey
@[simp]
theorem containsThenInsert_fst {k : α} {v : β k} : (m.containsThenInsert k v).1 = m.contains k := by
rw [containsThenInsert_eq_containsₘ, contains_eq_containsₘ]
@[simp]
theorem containsThenInsert_snd {k : α} {v : β k} : (m.containsThenInsert k v).2 = m.insert k v := by
rw [containsThenInsert_eq_insertₘ, insert_eq_insertₘ]
@[simp]
theorem containsThenInsertIfNew_fst {k : α} {v : β k} :
(m.containsThenInsertIfNew k v).1 = m.contains k := by
rw [containsThenInsertIfNew_eq_containsₘ, contains_eq_containsₘ]
@[simp]
theorem containsThenInsertIfNew_snd {k : α} {v : β k} :
(m.containsThenInsertIfNew k v).2 = m.insertIfNew k v := by
rw [containsThenInsertIfNew_eq_insertIfNewₘ, insertIfNew_eq_insertIfNewₘ]
@[simp]
theorem get?_empty [LawfulBEq α] {a : α} {c} : (empty c : Raw₀ α β).get? a = none := by
simp [get?]
theorem get?_of_isEmpty [LawfulBEq α] (h : m.1.WF) {a : α} :
m.1.isEmpty = true → m.get? a = none := by
simp_to_model; empty
theorem get?_insert [LawfulBEq α] (h : m.1.WF) {a k : α} {v : β k} : (m.insert k v).get? a =
if h : k == a then some (cast (congrArg β (eq_of_beq h)) v) else m.get? a := by
simp_to_model using List.getValueCast?_insertEntry
theorem get?_insert_self [LawfulBEq α] (h : m.1.WF) {k : α} {v : β k} :
(m.insert k v).get? k = some v := by
simp_to_model using List.getValueCast?_insertEntry_self
theorem contains_eq_isSome_get? [LawfulBEq α] (h : m.1.WF) {a : α} :
m.contains a = (m.get? a).isSome := by
simp_to_model using List.containsKey_eq_isSome_getValueCast?
theorem get?_eq_none [LawfulBEq α] (h : m.1.WF) {a : α} :
m.contains a = false → m.get? a = none := by
simp_to_model using List.getValueCast?_eq_none
theorem get?_erase [LawfulBEq α] (h : m.1.WF) {k a : α} :
(m.erase k).get? a = if k == a then none else m.get? a := by
simp_to_model using List.getValueCast?_eraseKey
theorem get?_erase_self [LawfulBEq α] (h : m.1.WF) {k : α} : (m.erase k).get? k = none := by
simp_to_model using List.getValueCast?_eraseKey_self
namespace Const
variable {β : Type v} (m : Raw₀ α (fun _ => β)) (h : m.1.WF)
@[simp]
theorem get?_empty {a : α} {c} : get? (empty c : Raw₀ α (fun _ => β)) a = none := by
simp [get?]
theorem get?_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} :
m.1.isEmpty = true → get? m a = none := by
simp_to_model; empty
theorem get?_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {v : β} :
get? (m.insert k v) a = if k == a then some v else get? m a := by
simp_to_model using List.getValue?_insertEntry
theorem get?_insert_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β} :
get? (m.insert k v) k = some v := by
simp_to_model using List.getValue?_insertEntry_self
theorem contains_eq_isSome_get? [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} :
m.contains a = (get? m a).isSome := by
simp_to_model using List.containsKey_eq_isSome_getValue?
theorem get?_eq_none [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} :
m.contains a = false → get? m a = none := by
simp_to_model using List.getValue?_eq_none.2
theorem get?_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} :
Const.get? (m.erase k) a = if k == a then none else get? m a := by
simp_to_model using List.getValue?_eraseKey
theorem get?_erase_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} :
get? (m.erase k) k = none := by
simp_to_model using List.getValue?_eraseKey_self
theorem get?_eq_get? [LawfulBEq α] (h : m.1.WF) {a : α} : get? m a = m.get? a := by
simp_to_model using List.getValue?_eq_getValueCast?
theorem get?_congr [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a b : α} (hab : a == b) :
get? m a = get? m b := by
simp_to_model using List.getValue?_congr
end Const
theorem get_insert [LawfulBEq α] (h : m.1.WF) {k a : α} {v : β k} {h₁} :
(m.insert k v).get a h₁ =
if h₂ : k == a then
cast (congrArg β (eq_of_beq h₂)) v
else
m.get a (contains_of_contains_insert _ h h₁ (Bool.eq_false_iff.2 h₂)) := by
simp_to_model using List.getValueCast_insertEntry
theorem get_insert_self [LawfulBEq α] (h : m.1.WF) {k : α} {v : β k} :
(m.insert k v).get k (contains_insert_self _ h) = v := by
simp_to_model using List.getValueCast_insertEntry_self
@[simp]
theorem get_erase [LawfulBEq α] (h : m.1.WF) {k a : α} {h'} :
(m.erase k).get a h' = m.get a (contains_of_contains_erase _ h h') := by
simp_to_model using List.getValueCast_eraseKey
theorem get?_eq_some_get [LawfulBEq α] (h : m.1.WF) {a : α} {h} : m.get? a = some (m.get a h) := by
simp_to_model using List.getValueCast?_eq_some_getValueCast
namespace Const
variable {β : Type v} (m : Raw₀ α (fun _ => β)) (h : m.1.WF)
theorem get_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {v : β} {h₁} :
get (m.insert k v) a h₁ =
if h₂ : k == a then v
else get m a (contains_of_contains_insert _ h h₁ (Bool.eq_false_iff.2 h₂)) := by
simp_to_model using List.getValue_insertEntry
theorem get_insert_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β} :
get (m.insert k v) k (contains_insert_self _ h) = v := by
simp_to_model using List.getValue_insertEntry_self
@[simp]
theorem get_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {h'} :
get (m.erase k) a h' = get m a (contains_of_contains_erase _ h h') := by
simp_to_model using List.getValue_eraseKey
theorem get?_eq_some_get [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} {h} :
get? m a = some (get m a h) := by
simp_to_model using List.getValue?_eq_some_getValue
theorem get_eq_get [LawfulBEq α] (h : m.1.WF) {a : α} {h} : get m a h = m.get a h := by
simp_to_model using List.getValue_eq_getValueCast
theorem get_congr [LawfulBEq α] (h : m.1.WF) {a b : α} (hab : a == b) {h'} :
get m a h' = get m b ((contains_congr _ h hab).symm.trans h') := by
simp_to_model using List.getValue_congr
end Const
theorem get!_empty [LawfulBEq α] {a : α} [Inhabited (β a)] {c} :
(empty c : Raw₀ α β).get! a = default := by
simp [get!, empty]
theorem get!_of_isEmpty [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] :
m.1.isEmpty = true → m.get! a = default := by
simp_to_model; empty
theorem get!_insert [LawfulBEq α] (h : m.1.WF) {k a : α} [Inhabited (β a)] {v : β k} :
(m.insert k v).get! a =
if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.get! a := by
simp_to_model using List.getValueCast!_insertEntry
theorem get!_insert_self [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] {b : β a} :
(m.insert a b).get! a = b := by
simp_to_model using List.getValueCast!_insertEntry_self
theorem get!_eq_default [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] :
m.contains a = false → m.get! a = default := by
simp_to_model using List.getValueCast!_eq_default
theorem get!_erase [LawfulBEq α] (h : m.1.WF) {k a : α} [Inhabited (β a)] :
(m.erase k).get! a = if k == a then default else m.get! a := by
simp_to_model using List.getValueCast!_eraseKey
theorem get!_erase_self [LawfulBEq α] (h : m.1.WF) {k : α} [Inhabited (β k)] :
(m.erase k).get! k = default := by
simp_to_model using List.getValueCast!_eraseKey_self
theorem get?_eq_some_get! [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] :
m.contains a = true → m.get? a = some (m.get! a) := by
simp_to_model using List.getValueCast?_eq_some_getValueCast!
theorem get!_eq_get!_get? [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] :
m.get! a = (m.get? a).get! := by
simp_to_model using List.getValueCast!_eq_getValueCast?
theorem get_eq_get! [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] {h} :
m.get a h = m.get! a := by
simp_to_model using List.getValueCast_eq_getValueCast!
namespace Const
variable {β : Type v} (m : Raw₀ α (fun _ => β)) (h : m.1.WF)
theorem get!_empty [Inhabited β] {a : α} {c} :
get! (empty c : Raw₀ α (fun _ => β)) a = default := by
simp [get!, empty]
theorem get!_of_isEmpty [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a : α} :
m.1.isEmpty = true → get! m a = default := by
simp_to_model; empty
theorem get!_insert [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {k a : α} {v : β} :
get! (m.insert k v) a = if k == a then v else get! m a := by
simp_to_model using List.getValue!_insertEntry
theorem get!_insert_self [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {k : α}
{v : β} : get! (m.insert k v) k = v := by
simp_to_model using List.getValue!_insertEntry_self
theorem get!_eq_default [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a : α} :
m.contains a = false → get! m a = default := by
simp_to_model using List.getValue!_eq_default
theorem get!_erase [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {k a : α} :
get! (m.erase k) a = if k == a then default else get! m a := by
simp_to_model using List.getValue!_eraseKey
theorem get!_erase_self [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {k : α} :
get! (m.erase k) k = default := by
simp_to_model using List.getValue!_eraseKey_self
theorem get?_eq_some_get! [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a : α} :
m.contains a = true → get? m a = some (get! m a) := by
simp_to_model using List.getValue?_eq_some_getValue!
theorem get!_eq_get!_get? [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a : α} :
get! m a = (get? m a).get! := by
simp_to_model using List.getValue!_eq_getValue?
theorem get_eq_get! [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a : α} {h} :
get m a h = get! m a := by
simp_to_model using List.getValue_eq_getValue!
theorem get!_eq_get! [LawfulBEq α] [Inhabited β] (h : m.1.WF) {a : α} :
get! m a = m.get! a := by
simp_to_model using List.getValue!_eq_getValueCast!
theorem get!_congr [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a b : α}
(hab : a == b) : get! m a = get! m b := by
simp_to_model using List.getValue!_congr
end Const
theorem getD_empty [LawfulBEq α] {a : α} {fallback : β a} {c} :
(empty c : Raw₀ α β).getD a fallback = fallback := by
simp [getD, empty]
theorem getD_of_isEmpty [LawfulBEq α] (h : m.1.WF) {a : α} {fallback : β a} :
m.1.isEmpty = true → m.getD a fallback = fallback := by
simp_to_model; empty
theorem getD_insert [LawfulBEq α] (h : m.1.WF) {k a : α} {fallback : β a} {v : β k} :
(m.insert k v).getD a fallback =
if h : k == a then cast (congrArg β (eq_of_beq h)) v else m.getD a fallback := by
simp_to_model using List.getValueCastD_insertEntry
theorem getD_insert_self [LawfulBEq α] (h : m.1.WF) {a : α} {fallback b : β a} :
(m.insert a b).getD a fallback = b := by
simp_to_model using List.getValueCastD_insertEntry_self
theorem getD_eq_fallback [LawfulBEq α] (h : m.1.WF) {a : α} {fallback : β a} :
m.contains a = false → m.getD a fallback = fallback := by
simp_to_model using List.getValueCastD_eq_fallback
theorem getD_erase [LawfulBEq α] (h : m.1.WF) {k a : α} {fallback : β a} :
(m.erase k).getD a fallback = if k == a then fallback else m.getD a fallback := by
simp_to_model using List.getValueCastD_eraseKey
theorem getD_erase_self [LawfulBEq α] (h : m.1.WF) {k : α} {fallback : β k} :
(m.erase k).getD k fallback = fallback := by
simp_to_model using List.getValueCastD_eraseKey_self
theorem get?_eq_some_getD [LawfulBEq α] (h : m.1.WF) {a : α} {fallback : β a} :
m.contains a = true → m.get? a = some (m.getD a fallback) := by
simp_to_model using List.getValueCast?_eq_some_getValueCastD
theorem getD_eq_getD_get? [LawfulBEq α] (h : m.1.WF) {a : α} {fallback : β a} :
m.getD a fallback = (m.get? a).getD fallback := by
simp_to_model using List.getValueCastD_eq_getValueCast?
theorem get_eq_getD [LawfulBEq α] (h : m.1.WF) {a : α} {fallback : β a} {h} :
m.get a h = m.getD a fallback := by
simp_to_model using List.getValueCast_eq_getValueCastD
theorem get!_eq_getD_default [LawfulBEq α] (h : m.1.WF) {a : α} [Inhabited (β a)] :
m.get! a = m.getD a default := by
simp_to_model using List.getValueCast!_eq_getValueCastD_default
namespace Const
variable {β : Type v} (m : Raw₀ α (fun _ => β)) (h : m.1.WF)
theorem getD_empty {a : α} {fallback : β} {c} :
getD (empty c : Raw₀ α (fun _ => β)) a fallback = fallback := by
simp [getD, empty]
theorem getD_of_isEmpty [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} {fallback : β} :
m.1.isEmpty = true → getD m a fallback = fallback := by
simp_to_model; empty
theorem getD_insert [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {fallback v : β} :
getD (m.insert k v) a fallback = if k == a then v else getD m a fallback := by
simp_to_model using List.getValueD_insertEntry
theorem getD_insert_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {fallback v : β} :
getD (m.insert k v) k fallback = v := by
simp_to_model using List.getValueD_insertEntry_self
theorem getD_eq_fallback [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} {fallback : β} :
m.contains a = false → getD m a fallback = fallback := by
simp_to_model using List.getValueD_eq_fallback
theorem getD_erase [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {fallback : β} :
getD (m.erase k) a fallback = if k == a then fallback else getD m a fallback := by
simp_to_model using List.getValueD_eraseKey
theorem getD_erase_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {fallback : β} :
getD (m.erase k) k fallback = fallback := by
simp_to_model using List.getValueD_eraseKey_self
theorem get?_eq_some_getD [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} {fallback : β} :
m.contains a = true → get? m a = some (getD m a fallback) := by
simp_to_model using List.getValue?_eq_some_getValueD
theorem getD_eq_getD_get? [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} {fallback : β} :
getD m a fallback = (get? m a).getD fallback := by
simp_to_model using List.getValueD_eq_getValue?
theorem get_eq_getD [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a : α} {fallback : β} {h} :
get m a h = getD m a fallback := by
simp_to_model using List.getValue_eq_getValueD
theorem get!_eq_getD_default [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {a : α} :
get! m a = getD m a default := by
simp_to_model using List.getValue!_eq_getValueD_default
theorem getD_eq_getD [LawfulBEq α] (h : m.1.WF) {a : α} {fallback : β} :
getD m a fallback = m.getD a fallback := by
simp_to_model using List.getValueD_eq_getValueCastD
theorem getD_congr [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {a b : α} {fallback : β}
(hab : a == b) : getD m a fallback = getD m b fallback := by
simp_to_model using List.getValueD_congr
end Const
theorem isEmpty_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insertIfNew k v).1.isEmpty = false := by
simp_to_model using List.isEmpty_insertEntryIfNew
theorem contains_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {v : β k} :
(m.insertIfNew k v).contains a = (k == a || m.contains a) := by
simp_to_model using List.containsKey_insertEntryIfNew
theorem contains_insertIfNew_self [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insertIfNew k v).contains k := by
simp_to_model using List.containsKey_insertEntryIfNew_self
theorem contains_of_contains_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α}
{v : β k} : (m.insertIfNew k v).contains a → (k == a) = false → m.contains a := by
simp_to_model using List.containsKey_of_containsKey_insertEntryIfNew
/-- This is a restatement of `contains_insertIfNew` that is written to exactly match the proof
obligation in the statement of `get_insertIfNew`. -/
theorem contains_of_contains_insertIfNew' [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α}
{v : β k} :
(m.insertIfNew k v).contains a → ¬((k == a) ∧ m.contains k = false) → m.contains a := by
simp_to_model using List.containsKey_of_containsKey_insertEntryIfNew'
theorem size_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insertIfNew k v).1.size = if m.contains k then m.1.size else m.1.size + 1 := by
simp_to_model using List.length_insertEntryIfNew
theorem size_le_size_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
m.1.size ≤ (m.insertIfNew k v).1.size := by
simp_to_model using List.length_le_length_insertEntryIfNew
theorem size_insertIfNew_le [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k : α} {v : β k} :
(m.insertIfNew k v).1.size ≤ m.1.size + 1 := by
simp_to_model using List.length_insertEntryIfNew_le
theorem get?_insertIfNew [LawfulBEq α] (h : m.1.WF) {k a : α} {v : β k} :
(m.insertIfNew k v).get? a =
if h : k == a ∧ m.contains k = false then some (cast (congrArg β (eq_of_beq h.1)) v)
else m.get? a := by
simp_to_model using List.getValueCast?_insertEntryIfNew
theorem get_insertIfNew [LawfulBEq α] (h : m.1.WF) {k a : α} {v : β k} {h₁} :
(m.insertIfNew k v).get a h₁ =
if h₂ : k == a ∧ m.contains k = false then cast (congrArg β (eq_of_beq h₂.1)) v
else m.get a (contains_of_contains_insertIfNew' _ h h₁ h₂) := by
simp_to_model using List.getValueCast_insertEntryIfNew
theorem get!_insertIfNew [LawfulBEq α] (h : m.1.WF) {k a : α} [Inhabited (β a)] {v : β k} :
(m.insertIfNew k v).get! a =
if h : k == a ∧ m.contains k = false then cast (congrArg β (eq_of_beq h.1)) v
else m.get! a := by
simp_to_model using List.getValueCast!_insertEntryIfNew
theorem getD_insertIfNew [LawfulBEq α] (h : m.1.WF) {k a : α} {fallback : β a} {v : β k} :
(m.insertIfNew k v).getD a fallback =
if h : k == a ∧ m.contains k = false then cast (congrArg β (eq_of_beq h.1)) v
else m.getD a fallback := by
simp_to_model using List.getValueCastD_insertEntryIfNew
namespace Const
variable {β : Type v} (m : Raw₀ α (fun _ => β)) (h : m.1.WF)
theorem get?_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {v : β} :
get? (m.insertIfNew k v) a = if k == a ∧ m.contains k = false then some v else get? m a := by
simp_to_model using List.getValue?_insertEntryIfNew
theorem get_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {v : β} {h₁} :
get (m.insertIfNew k v) a h₁ =
if h₂ : k == a ∧ m.contains k = false then v
else get m a (contains_of_contains_insertIfNew' _ h h₁ h₂) := by
simp_to_model using List.getValue_insertEntryIfNew
theorem get!_insertIfNew [EquivBEq α] [LawfulHashable α] [Inhabited β] (h : m.1.WF) {k a : α}
{v : β} :
get! (m.insertIfNew k v) a = if k == a ∧ m.contains k = false then v else get! m a := by
simp_to_model using List.getValue!_insertEntryIfNew
theorem getD_insertIfNew [EquivBEq α] [LawfulHashable α] (h : m.1.WF) {k a : α} {fallback v : β} :
getD (m.insertIfNew k v) a fallback =
if k == a ∧ m.contains k = false then v else getD m a fallback := by
simp_to_model using List.getValueD_insertEntryIfNew
end Const
@[simp]
theorem getThenInsertIfNew?_fst [LawfulBEq α] {k : α} {v : β k} :
(m.getThenInsertIfNew? k v).1 = m.get? k := by
rw [getThenInsertIfNew?_eq_get?ₘ, get?_eq_get?ₘ]
@[simp]
theorem getThenInsertIfNew?_snd [LawfulBEq α] {k : α} {v : β k} :
(m.getThenInsertIfNew? k v).2 = m.insertIfNew k v := by
rw [getThenInsertIfNew?_eq_insertIfNewₘ, insertIfNew_eq_insertIfNewₘ]
namespace Const
variable {β : Type v} (m : Raw₀ α (fun _ => β)) (h : m.1.WF)
@[simp]
theorem getThenInsertIfNew?_fst {k : α} {v : β} : (getThenInsertIfNew? m k v).1 = get? m k := by
rw [getThenInsertIfNew?_eq_get?ₘ, get?_eq_get?ₘ]
@[simp]
theorem getThenInsertIfNew?_snd {k : α} {v : β} :
(getThenInsertIfNew? m k v).2 = m.insertIfNew k v := by
rw [getThenInsertIfNew?_eq_insertIfNewₘ, insertIfNew_eq_insertIfNewₘ]
end Const
end Raw₀
end Std.DHashMap.Internal