Skip to content

Commit 054cfa7

Browse files
chore: extends Membership (#47)
1 parent 9741d3d commit 054cfa7

File tree

7 files changed

+95
-81
lines changed

7 files changed

+95
-81
lines changed

Algorithm/Data/Classes/Bag.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ variable {C α : Type*} [Bag.ReadOnly C α] (c : C)
2121
attribute [local instance] Bag.ReadOnly.decidableMem in
2222
instance : MultiBag.ReadOnly C α where
2323
count a c := if a ∈ c then 1 else 0
24-
count_eq_count_toMultiset a c := by symm; convert Multiset.count_eq_of_nodup (nodup_toMultiset c)
24+
count_eq_count_toMultiset a c := by
25+
simp [Multiset.count_eq_of_nodup (nodup_toMultiset c)]
2526

2627
end Bag.ReadOnly

Algorithm/Data/Classes/IndexedMinHeap.lean

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,9 @@ def mk [DecidableEq α] (assocArray : C) (minHeap : C')
192192
simpa [h, size_eq_card_toMultiset, Multiset.card_erase_lt_of_mem, - MinHeap.head_def] using
193193
Multiset.card_erase_lt_of_mem (MinHeap.head_mem_toMultiset _ _)
194194
mk assocArray (MinHeap.tail minHeap) fun i hi ↦ by
195-
simp? [ToMultiset.mem_iff, h] says
196-
simp only [ToMultiset.mem_iff, MinHeap.toMultiset_tail, h, Bool.false_eq_true, ↓reduceDIte,
197-
MinHeap.head_def]
198-
rw [Multiset.mem_erase_of_ne]
195+
simp only [← mem_toMultiset, MinHeap.toMultiset_tail, h, Bool.false_eq_true, ↓reduceDIte,
196+
MinHeap.head_def]
197+
rw [Multiset.mem_erase_of_ne, mem_toMultiset]
199198
· exact mem_minHeap _ _
200199
· intro h''
201200
apply h'
@@ -238,7 +237,8 @@ instance [DecidableEq α] :
238237
rw [ite_eq_left_iff, Classical.not_imp] at hj
239238
simp only [hj.1, ↓reduceIte]
240239
exact c.mem_minHeap j hj.2
241-
· rw [ToMultiset.mem_iff, toMultiset_insert, Multiset.mem_cons]
240+
· -- TODO: `mem_insert`
241+
rw [← mem_toMultiset, toMultiset_insert, Multiset.mem_cons, mem_toMultiset]
242242
split_ifs at hj ⊢ with hji
243243
· simp [hji]
244244
· exact .inr <| c.mem_minHeap j hj

Algorithm/Data/Classes/ToFinset.lean

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ Authors: Yuyang Zhao
66
import Algorithm.Data.Classes.ToMultiset
77
import Mathlib.Data.Finset.Card
88

9-
class ToFinset (C : Type*) (α : outParam Type*) extends Size C where
9+
variable {C α : Type*}
10+
11+
class ToFinset (C : Type*) (α : outParam Type*) extends Membership α C, Size C where
1012
toFinset : C → Finset α
13+
mem c a := a ∈ toFinset c
14+
mem_toFinset {x c} : x ∈ toFinset c ↔ x ∈ c := by rfl
1115
size_eq_card_toFinset c : size c = (toFinset c).card
12-
export ToFinset (toFinset size_eq_card_toFinset)
16+
export ToFinset (toFinset mem_toFinset size_eq_card_toFinset)
17+
18+
attribute [simp] mem_toFinset
1319

1420
class ToFinset.LawfulInsert (C : Type*) (α : outParam Type*)
1521
[ToFinset C α] [Insert α C] : Prop where
@@ -18,38 +24,31 @@ export ToFinset.LawfulInsert (toFinset_insert)
1824

1925
attribute [simp] toFinset_insert
2026

21-
section
22-
variable {α : Type*}
23-
2427
section ToFinset
25-
variable {C α : Type*} [ToFinset C α] (c : C)
2628

27-
instance (priority := 100) ToFinset.toMultiset : ToMultiset C α where
29+
variable [ToFinset C α] (c : C)
30+
31+
instance (priority := 100) ToFinset.toToMultiset : ToMultiset C α where
2832
toMultiset c := (toFinset c).val
33+
mem_toMultiset := mem_toFinset
2934
size_eq_card_toMultiset c := size_eq_card_toFinset c
3035

3136
section LawfulEmptyCollection
3237
variable [EmptyCollection C]
3338

34-
lemma ToFinset.lawfulEmptyCollection_iff :
39+
lemma lawfulEmptyCollection_iff_toFinset :
3540
LawfulEmptyCollection C α ↔ toFinset (∅ : C) = ∅ := by
36-
rw [ToMultiset.lawfulEmptyCollection_iff]
37-
change (toFinset (∅ : C)).val = ∅ ↔ _
38-
simp
41+
simp_rw [lawfulEmptyCollection_iff, Finset.eq_empty_iff_forall_not_mem, mem_toFinset]
3942

40-
alias ⟨_, LawfulEmptyCollection.ofToFinset⟩ := ToFinset.lawfulEmptyCollection_iff
43+
alias ⟨_, LawfulEmptyCollection.of_toFinset⟩ := lawfulEmptyCollection_iff_toFinset
4144

4245
@[simp]
43-
lemma toFinset_empty [inst : LawfulEmptyCollection C α] :
46+
lemma toFinset_empty [LawfulEmptyCollection C α] :
4447
toFinset (∅ : C) = ∅ := by
45-
rwa [ToFinset.lawfulEmptyCollection_iff] at inst
48+
rwa [← lawfulEmptyCollection_iff_toFinset]
4649

4750
end LawfulEmptyCollection
4851

49-
lemma ToFinset.mem_iff {c : C} {v : α} : v ∈ c ↔ v ∈ toFinset c := .rfl
50-
51-
lemma mem_toFinset {c : C} {v : α} : v ∈ toFinset c ↔ v ∈ c := .rfl
52-
5352
@[simp]
5453
lemma toFinset_val : (toFinset c).val = toMultiset c := rfl
5554

Algorithm/Data/Classes/ToList.lean

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -77,36 +77,52 @@ lemma dropLast_toList : a.toList.dropLast = a.pop.toList := by
7777

7878
end Array
7979

80-
class ToList (C : Type*) (α : outParam Type*) extends Size C where
80+
class ToList (C : Type*) (α : outParam Type*) extends Membership α C, Size C where
8181
toList : C → List α
8282
toArray : C → Array α
8383
toArray_eq_mk_toList a : toArray a = Array.mk (toList a)
84+
mem c a := a ∈ toList c
85+
mem_toList {x c} : x ∈ toList c ↔ x ∈ c := by rfl
8486
size_eq_length_toList c : size c = (toList c).length
85-
export ToList (toList toArray toArray_eq_mk_toList size_eq_length_toList)
87+
export ToList (toList toArray toArray_eq_mk_toList mem_toList size_eq_length_toList)
8688

87-
attribute [simp] toArray_eq_mk_toList
89+
attribute [simp] toArray_eq_mk_toList mem_toList
8890

8991
section ToList
92+
93+
instance : ToList (List α) α where
94+
toList := id
95+
toArray := Array.mk
96+
toArray_eq_mk_toList _ := rfl
97+
size_eq_length_toList _ := rfl
98+
99+
instance : ToList (Array α) α where
100+
toList := Array.toList
101+
toArray := id
102+
toArray_eq_mk_toList _ := rfl
103+
mem_toList := Array.mem_def.symm
104+
size_eq_length_toList _ := rfl
105+
90106
variable [ToList C α]
91107

92-
instance (priority := 100) ToList.toMultiset : ToMultiset C α where
108+
instance (priority := 100) ToList.toToMultiset : ToMultiset C α where
93109
toMultiset c := ↑(toList c)
110+
mem_toMultiset := mem_toList
94111
size_eq_card_toMultiset c := size_eq_length_toList c
95112

96113
section LawfulEmptyCollection
97114
variable [EmptyCollection C]
98115

99-
lemma ToList.lawfulEmptyCollection_iff :
116+
lemma lawfulEmptyCollection_iff_toList :
100117
LawfulEmptyCollection C α ↔ toList (∅ : C) = [] := by
101-
rw [ToMultiset.lawfulEmptyCollection_iff]
102-
simp [toMultiset]
118+
simp_rw [lawfulEmptyCollection_iff, List.eq_nil_iff_forall_not_mem, mem_toList]
103119

104-
alias ⟨_, LawfulEmptyCollection.ofToList⟩ := ToList.lawfulEmptyCollection_iff
120+
alias ⟨_, LawfulEmptyCollection.of_toList⟩ := lawfulEmptyCollection_iff_toList
105121

106122
@[simp]
107-
lemma toList_empty [inst : LawfulEmptyCollection C α] :
123+
lemma toList_empty [LawfulEmptyCollection C α] :
108124
toList (∅ : C) = [] := by
109-
rwa [ToList.lawfulEmptyCollection_iff] at inst
125+
rwa [← lawfulEmptyCollection_iff_toList]
110126

111127
end LawfulEmptyCollection
112128

@@ -127,11 +143,6 @@ lemma coe_toList : ↑(toList c) = toMultiset c := rfl
127143
lemma isEmpty_toList : (toList c).isEmpty = isEmpty c := by
128144
rw [isEmpty_eq_decide_size, List.isEmpty_eq_decide_length, size_eq_length_toList]
129145

130-
lemma ToList.mem_iff {c : C} {v : α} : v ∈ c ↔ v ∈ toList c := .rfl
131-
132-
@[simp]
133-
lemma mem_toList {c : C} {v : α} : v ∈ toList c ↔ v ∈ c := .rfl
134-
135146
end ToList
136147

137148
class Front (C : Type*) (α : outParam Type*) [ToList C α] where
@@ -235,12 +246,6 @@ end ToList
235246

236247
section List
237248

238-
instance : ToList (List α) α where
239-
toList := id
240-
toArray := Array.mk
241-
toArray_eq_mk_toList _ := rfl
242-
size_eq_length_toList _ := rfl
243-
244249
instance : Front (List α) α where
245250
front? := List.head?
246251
front?_def _ := rfl
@@ -264,12 +269,6 @@ end List
264269

265270
section Array
266271

267-
instance : ToList (Array α) α where
268-
toList := Array.toList
269-
toArray := id
270-
toArray_eq_mk_toList _ := rfl
271-
size_eq_length_toList _ := rfl
272-
273272
instance : Front (Array α) α where
274273
front? c := c.get? 0
275274
front?_def c := by

Algorithm/Data/Classes/ToMultiset.lean

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ Authors: Yuyang Zhao
66
import Algorithm.Data.Classes.Size
77
import Mathlib.Data.Multiset.Basic
88

9-
class ToMultiset (C : Type*) (α : outParam Type*) extends Size C where
10-
toMultiset : C → Multiset α
11-
size_eq_card_toMultiset c : size c = Multiset.card (toMultiset c)
12-
export ToMultiset (toMultiset size_eq_card_toMultiset)
9+
variable {C α : Type*}
1310

14-
@[mk_iff ToMultiset.lawfulEmptyCollection_iff]
11+
@[mk_iff]
1512
class LawfulEmptyCollection (C : Type*) (α : outParam Type*)
16-
[ToMultiset C α] [EmptyCollection C] : Prop where
17-
toMultiset_empty : toMultiset (∅ : C) = 0
18-
export LawfulEmptyCollection (toMultiset_empty)
13+
[Membership α C] [EmptyCollection C] : Prop where
14+
not_mem_empty (x : α) : x ∉ (∅ : C)
15+
export LawfulEmptyCollection (not_mem_empty)
16+
17+
class ToMultiset (C : Type*) (α : outParam Type*) extends Membership α C, Size C where
18+
toMultiset : C → Multiset α
19+
mem c a := a ∈ toMultiset c
20+
mem_toMultiset {x c} : x ∈ toMultiset c ↔ x ∈ c := by rfl
21+
size_eq_card_toMultiset c : size c = Multiset.card (toMultiset c)
22+
export ToMultiset (toMultiset mem_toMultiset size_eq_card_toMultiset)
1923

20-
attribute [simp] toMultiset_empty
24+
attribute [simp] mem_toMultiset
2125

2226
class ToMultiset.LawfulInsert (C : Type*) (α : outParam Type*)
2327
[ToMultiset C α] [Insert α C] : Prop where
@@ -26,42 +30,51 @@ export ToMultiset.LawfulInsert (toMultiset_insert)
2630

2731
attribute [simp] toMultiset_insert
2832

29-
section
30-
variable {α : Type*}
33+
section ToMultiset
3134

3235
instance : ToMultiset (List α) α where
3336
toMultiset := (↑)
37+
mem_toMultiset := .rfl
3438
size_eq_card_toMultiset _ := rfl
3539

3640
instance : ToMultiset (Array α) α where
3741
toMultiset c := ↑c.toList
42+
mem_toMultiset := Array.mem_def.symm
3843
size_eq_card_toMultiset _ := by simp [size]
3944

40-
section ToMultiset
41-
variable {C α : Type*} [ToMultiset C α] (c : C)
45+
variable [ToMultiset C α]
4246

43-
instance (priority := 100) : Membership α C where
44-
mem c a := a ∈ toMultiset c
47+
section LawfulEmptyCollection
48+
variable [EmptyCollection C]
4549

46-
lemma ToMultiset.mem_iff {c : C} {v : α} : v ∈ c ↔ v ∈ toMultiset c := .rfl
50+
lemma lawfulEmptyCollection_iff_toMultiset :
51+
LawfulEmptyCollection C α ↔ toMultiset (∅ : C) = 0 := by
52+
simp_rw [lawfulEmptyCollection_iff, Multiset.eq_zero_iff_forall_not_mem, mem_toMultiset]
53+
54+
alias ⟨_, LawfulEmptyCollection.of_toMultiset⟩ := lawfulEmptyCollection_iff_toMultiset
55+
56+
@[simp]
57+
lemma toMultiset_empty [LawfulEmptyCollection C α] :
58+
toMultiset (∅ : C) = 0 := by
59+
rwa [← lawfulEmptyCollection_iff_toMultiset]
4760

48-
lemma mem_toMultiset {c : C} {v : α} : v ∈ toMultiset c ↔ v ∈ c := .rfl
61+
end LawfulEmptyCollection
4962

5063
@[simp]
51-
lemma toMultiset_of_isEmpty (h : isEmpty c) : toMultiset c = 0 := by
64+
lemma toMultiset_of_isEmpty {c : C} (h : isEmpty c) : toMultiset c = 0 := by
5265
simpa [size_eq_card_toMultiset] using h
5366

5467
@[simp]
5568
lemma toMultiset_list (l : List α) : toMultiset l = ↑l := rfl
5669

5770
@[simp]
58-
lemma ToMultiset.not_isEmpty_of_mem {c : C} {v} (hv : v ∈ c) : ¬isEmpty c := by
59-
simpa [size_eq_card_toMultiset, Multiset.eq_zero_iff_forall_not_mem] using ⟨v, hv
71+
lemma ToMultiset.not_isEmpty_of_mem {c : C} {x} (hx : x ∈ c) : ¬isEmpty c := by
72+
simpa [size_eq_card_toMultiset, Multiset.eq_zero_iff_forall_not_mem] using ⟨x, hx
6073

6174
variable [DecidableEq α]
6275

63-
theorem count_toMultiset_eq_zero {a : α} {c : C} : (toMultiset c).count a = 0 ↔ a ∉ c :=
64-
Multiset.count_eq_zero
76+
theorem count_toMultiset_eq_zero {a : α} {c : C} : (toMultiset c).count a = 0 ↔ a ∉ c := by
77+
simp
6578

6679
theorem count_toMultiset_ne_zero {a : α} {c : C} : (toMultiset c).count a ≠ 0 ↔ a ∈ c := by
6780
simp [count_toMultiset_eq_zero, mem_toMultiset]

Algorithm/Data/PairingHeap.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ instance : ToMultiset (PairingHeap α le) α where
180180
instance : EmptyCollection (PairingHeap α le) where
181181
emptyCollection := empty
182182

183-
instance : LawfulEmptyCollection (PairingHeap α le) α where
184-
toMultiset_empty := rfl
183+
instance : LawfulEmptyCollection (PairingHeap α le) α :=
184+
.of_toMultiset rfl
185185

186186
@[simp]
187187
lemma size_eq_zero_iff (x : PairingHeap α le) : x.size = 0 ↔ x = ∅ := by
@@ -213,12 +213,12 @@ instance [Preorder α] [IsTotal α (· ≤ ·)] [DecidableRel (α := α) (· ≤
213213
simp only [isEmpty_iff_size_eq_zero] at hx
214214
match x, hx with
215215
| ⟨.node a c .nil, _⟩, _ =>
216-
simpa using ⟨a, by
216+
simpa [- mem_toMultiset] using ⟨a, by
217217
simp [toMultiset, toListUnordered, PairingHeapImp.Heap.toListUnordered_node], rfl⟩
218218
head?_le x b hb := by
219219
match x with
220220
| ⟨.node a c .nil, hwf⟩ =>
221-
simp_rw [ToMultiset.mem_iff, toMultiset, toListUnordered,
221+
simp_rw [← mem_toMultiset, toMultiset, toListUnordered,
222222
PairingHeapImp.Heap.toListUnordered_node, PairingHeapImp.Heap.toListUnordered_nil,
223223
List.append_nil, ← Multiset.cons_coe, Multiset.mem_cons] at hb
224224
obtain (rfl | hb) := hb; · rfl

Algorithm/Graph/Dijkstra.lean

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,9 @@ lemma dijkstraStep_fst_getElem' (g : G) (c : Info → CostType)
445445
split_ifs with h
446446
· simp? [Function.update_apply] says
447447
simp only [Function.update_apply, min_eq_top, ite_eq_left_iff, Multiset.inf_eq_top,
448-
Multiset.mem_filterMap, Option.ite_none_right_eq_some, Option.some.injEq, Prod.exists,
449-
Prod.mk.injEq, exists_eq_right_right, exists_eq_right, forall_exists_index, and_imp]
448+
Multiset.mem_filterMap, mem_toMultiset, Option.ite_none_right_eq_some, Option.some.injEq,
449+
Prod.exists, Prod.mk.injEq, exists_eq_right_right, exists_eq_right, forall_exists_index,
450+
and_imp]
450451
use fun hv ↦ (spec₁ v).resolve_right (h.resolve_left hv)
451452
rintro - e - h' ⟨rfl⟩ ⟨rfl⟩
452453
split_ifs at h' with snde
@@ -482,8 +483,9 @@ lemma dijkstraStep_fst_getElem (g : G) (c : Info → CostType)
482483
apply Multiset.inf_congr
483484
intro d
484485
simp? says
485-
simp only [Multiset.mem_dedup, Multiset.mem_filterMap, Option.ite_none_right_eq_some,
486-
Option.some.injEq, Multiset.mem_map, Finset.mem_val, Finset.mem_univ, true_and]
486+
simp only [Multiset.mem_dedup, Multiset.mem_filterMap, mem_toMultiset,
487+
Option.ite_none_right_eq_some, Option.some.injEq, Multiset.mem_map, Finset.mem_val,
488+
Finset.mem_univ, true_and]
487489
constructor
488490
· rintro ⟨x, hx, rfl, rfl, rfl⟩
489491
exact ⟨homOfStar x hx, rfl⟩

0 commit comments

Comments
 (0)