Skip to content

Commit ec6b06a

Browse files
Rob23obaalgebraic-dev
authored andcommitted
feat: equivalence of tree maps (leanprover#8210)
This PR adds an equivalence relation to tree maps akin to the existing one for hash maps. In order to get many congruence lemmas to eventually use for defining functions on extensional tree maps, almost all of the remaining tree map functions have also been given lemmas to relate them to list functions, although these aren't currently used to prove lemmas other than congruence lemmas.
1 parent f686b06 commit ec6b06a

File tree

23 files changed

+4264
-181
lines changed

23 files changed

+4264
-181
lines changed

src/Init/Data/Array/Lemmas.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3621,8 +3621,8 @@ We can prove that two folds over the same array are related (by some arbitrary r
36213621
if we know that the initial elements are related and the folding function, for each element of the array,
36223622
preserves the relation.
36233623
-/
3624-
theorem foldl_rel {xs : Array α} {f g : β → α → β} {a b : β} {r : β → βProp}
3625-
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f c a) (g c' a)) :
3624+
theorem foldl_rel {xs : Array α} {f : β → α → β} {g : γ → α → γ} {a : β} {b : γ} {r : β → γProp}
3625+
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f c a) (g c' a)) :
36263626
r (xs.foldl (fun acc a => f acc a) a) (xs.foldl (fun acc a => g acc a) b) := by
36273627
rcases xs with ⟨xs⟩
36283628
simpa using List.foldl_rel h (by simpa using h')
@@ -3632,8 +3632,8 @@ We can prove that two folds over the same array are related (by some arbitrary r
36323632
if we know that the initial elements are related and the folding function, for each element of the array,
36333633
preserves the relation.
36343634
-/
3635-
theorem foldr_rel {xs : Array α} {f g : α → β → β} {a b : β} {r : β → βProp}
3636-
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f a c) (g a c')) :
3635+
theorem foldr_rel {xs : Array α} {f : α → β → β} {g : α → γ → γ} {a : β} {b : γ} {r : β → γProp}
3636+
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f a c) (g a c')) :
36373637
r (xs.foldr (fun a acc => f a acc) a) (xs.foldr (fun a acc => g a acc) b) := by
36383638
rcases xs with ⟨xs⟩
36393639
simpa using List.foldr_rel h (by simpa using h')

src/Init/Data/List/Lemmas.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,8 +2778,8 @@ We can prove that two folds over the same list are related (by some arbitrary re
27782778
if we know that the initial elements are related and the folding function, for each element of the list,
27792779
preserves the relation.
27802780
-/
2781-
theorem foldl_rel {l : List α} {f g : β → α → β} {a b : β} {r : β → βProp}
2782-
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c c' : β), r c c' → r (f c a) (g c' a)) :
2781+
theorem foldl_rel {l : List α} {f : β → α → β} {g : γ → α → γ} {a : β} {b : γ} {r : β → γProp}
2782+
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c : β) (c' : γ), r c c' → r (f c a) (g c' a)) :
27832783
r (l.foldl (fun acc a => f acc a) a) (l.foldl (fun acc a => g acc a) b) := by
27842784
induction l generalizing a b with
27852785
| nil => simp_all
@@ -2794,8 +2794,8 @@ We can prove that two folds over the same list are related (by some arbitrary re
27942794
if we know that the initial elements are related and the folding function, for each element of the list,
27952795
preserves the relation.
27962796
-/
2797-
theorem foldr_rel {l : List α} {f g : α → β → β} {a b : β} {r : β → βProp}
2798-
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c c' : β), r c c' → r (f a c) (g a c')) :
2797+
theorem foldr_rel {l : List α} {f : α → β → β} {g : α → γ → γ} {a : β} {b : γ} {r : β → γProp}
2798+
(h : r a b) (h' : ∀ (a : α), a ∈ l → ∀ (c : β) (c' : γ), r c c' → r (f a c) (g a c')) :
27992799
r (l.foldr (fun a acc => f a acc) a) (l.foldr (fun a acc => g a acc) b) := by
28002800
induction l generalizing a b with
28012801
| nil => simp_all

src/Init/Data/Vector/Lemmas.lean

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,23 +2538,23 @@ theorem foldr_hom (f : β₁ → β₂) {g₁ : α → β₁ → β₁} {g₂ :
25382538
rw [Array.foldr_hom _ H]
25392539

25402540
/--
2541-
We can prove that two folds over the same array are related (by some arbitrary relation)
2542-
if we know that the initial elements are related and the folding function, for each element of the array,
2543-
preserves the relation.
2541+
We can prove that two folds over the same vector are related (by some arbitrary relation)
2542+
if we know that the initial elements are related and the folding function, for each element of the
2543+
vector, preserves the relation.
25442544
-/
2545-
theorem foldl_rel {xs : Vector α n} {f g : β → α → β} {a b : β} {r : β → βProp}
2546-
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f c a) (g c' a)) :
2545+
theorem foldl_rel {xs : Vector α n} {f : β → α → β} {g : γ → α → γ} {a : β} {b : γ} {r : β → γProp}
2546+
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f c a) (g c' a)) :
25472547
r (xs.foldl (fun acc a => f acc a) a) (xs.foldl (fun acc a => g acc a) b) := by
25482548
rcases xs with ⟨xs, rfl⟩
25492549
simpa using Array.foldl_rel h (by simpa using h')
25502550

25512551
/--
2552-
We can prove that two folds over the same array are related (by some arbitrary relation)
2553-
if we know that the initial elements are related and the folding function, for each element of the array,
2554-
preserves the relation.
2552+
We can prove that two folds over the same vector are related (by some arbitrary relation)
2553+
if we know that the initial elements are related and the folding function, for each element of the
2554+
vector, preserves the relation.
25552555
-/
2556-
theorem foldr_rel {xs : Vector α n} {f g : α → β → β} {a b : β} {r : β → βProp}
2557-
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c c' : β), r c c' → r (f a c) (g a c')) :
2556+
theorem foldr_rel {xs : Vector α n} {f : α → β → β} {g : α → γ → γ} {a : β} {b : γ} {r : β → γProp}
2557+
(h : r a b) (h' : ∀ (a : α), a ∈ xs → ∀ (c : β) (c' : γ), r c c' → r (f a c) (g a c')) :
25582558
r (xs.foldr (fun a acc => f a acc) a) (xs.foldr (fun a acc => g a acc) b) := by
25592559
rcases xs with ⟨xs, rfl⟩
25602560
simpa using Array.foldr_rel h (by simpa using h')

src/Std/Data/DTreeMap/AdditionalOperations.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def getEntryLE [TransCmp cmp] (t : DTreeMap α β cmp) (k : α) (h : ∃ a ∈ t
6666
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE k t.inner t.wf.ordered h
6767

6868
/--
69-
Given a proof that such a mapping exists, retrieves the key-value pair with the smallest key that is
69+
Given a proof that such a mapping exists, retrieves the key-value pair with the largest key that is
7070
less than the given key.
7171
-/
7272
@[inline]
@@ -99,7 +99,7 @@ def getKeyLE [TransCmp cmp] (t : DTreeMap α β cmp) (k : α) (h : ∃ a ∈ t,
9999
letI : Ord α := ⟨cmp⟩; Impl.getKeyLE k t.inner t.wf.ordered h
100100

101101
/--
102-
Given a proof that such a mapping exists, retrieves the smallest key that is
102+
Given a proof that such a mapping exists, retrieves the largest key that is
103103
less than the given key.
104104
-/
105105
@[inline]
@@ -138,7 +138,7 @@ def getEntryLE [TransCmp cmp] (t : DTreeMap α β cmp) (k : α) (h : ∃ a ∈ t
138138
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLE k t.inner t.wf.ordered h
139139

140140
/--
141-
Given a proof that such a mapping exists, retrieves the key-value pair with the smallest key that is
141+
Given a proof that such a mapping exists, retrieves the key-value pair with the largest key that is
142142
less than the given key.
143143
-/
144144
@[inline]

src/Std/Data/DTreeMap/Basic.lean

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ instance : EmptyCollection (DTreeMap α β cmp) where
8383
instance : Inhabited (DTreeMap α β cmp) where
8484
default := ∅
8585

86+
@[inherit_doc Impl.Equiv]
87+
structure Equiv (m₁ m₂ : DTreeMap α β cmp) where
88+
/-- Internal implementation detail of the tree map -/
89+
inner : m₁.1.Equiv m₂.1
90+
91+
@[inherit_doc] scoped infix:50 " ~m " => Equiv
92+
8693
@[simp]
8794
theorem empty_eq_emptyc : (empty : DTreeMap α β cmp) = ∅ :=
8895
rfl
@@ -500,7 +507,7 @@ def getEntryLE? (t : DTreeMap α β cmp) (k : α) : Option ((a : α) × β a) :=
500507
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE? k t.inner
501508

502509
/--
503-
Tries to retrieve the key-value pair with the smallest key that is less than the given key,
510+
Tries to retrieve the key-value pair with the largest key that is less than the given key,
504511
returning `none` if no such pair exists.
505512
-/
506513
@[inline]
@@ -537,7 +544,7 @@ def getEntryLE! [Inhabited (Sigma β)] (t : DTreeMap α β cmp) (k : α) : (a :
537544
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE! k t.inner
538545

539546
/--
540-
Tries to retrieve the key-value pair with the smallest key that is less than the given key,
547+
Tries to retrieve the key-value pair with the largest key that is less than the given key,
541548
panicking if no such pair exists.
542549
-/
543550
@[inline]
@@ -569,7 +576,7 @@ def getEntryLED (t : DTreeMap α β cmp) (k : α) (fallback : Sigma β) : (a :
569576
letI : Ord α := ⟨cmp⟩; Impl.getEntryLED k t.inner fallback
570577

571578
/--
572-
Tries to retrieve the key-value pair with the smallest key that is less than the given key,
579+
Tries to retrieve the key-value pair with the largest key that is less than the given key,
573580
returning `fallback` if no such pair exists.
574581
-/
575582
@[inline]
@@ -601,7 +608,7 @@ def getKeyLE? (t : DTreeMap α β cmp) (k : α) : Option α :=
601608
letI : Ord α := ⟨cmp⟩; t.inner.getKeyLE? k
602609

603610
/--
604-
Tries to retrieve the smallest key that is less than the given key,
611+
Tries to retrieve the largest key that is less than the given key,
605612
returning `none` if no such key exists.
606613
-/
607614
@[inline]
@@ -638,7 +645,7 @@ def getKeyLE! [Inhabited α] (t : DTreeMap α β cmp) (k : α) : α :=
638645
letI : Ord α := ⟨cmp⟩; Impl.getKeyLE! k t.inner
639646

640647
/--
641-
Tries to retrieve the smallest key that is less than the given key,
648+
Tries to retrieve the largest key that is less than the given key,
642649
panicking if no such key exists.
643650
-/
644651
@[inline]
@@ -670,7 +677,7 @@ def getKeyLED (t : DTreeMap α β cmp) (k : α) (fallback : α) : α :=
670677
letI : Ord α := ⟨cmp⟩; Impl.getKeyLED k t.inner fallback
671678

672679
/--
673-
Tries to retrieve the smallest key that is less than the given key,
680+
Tries to retrieve the largest key that is less than the given key,
674681
returning `fallback` if no such key exists.
675682
-/
676683
@[inline]

0 commit comments

Comments
 (0)