-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathFinSetExtras.v
296 lines (258 loc) · 6.49 KB
/
FinSetExtras.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
From VLSM.Lib Require Import Itauto.
From stdpp Require Import prelude fin_maps.
From VLSM.Lib Require Import Preamble.
(** * Utility: Finite Set Utility Definitions and Results *)
(** For some reason, this instance is not exported by stdpp. *)
#[export] Existing Instance elem_of_dec_slow.
Section sec_fin_set.
Context
`{FinSet A C}.
Section sec_general.
(**
If <<X>> is a subset of <<Y>>, then the elements of <<X>> are a sublist
of the elements of <<Y>>.
*)
Lemma elements_subseteq (X Y : C) :
X ⊆ Y -> elements X ⊆ elements Y.
Proof. by set_solver. Qed.
Lemma union_size_ge_size1
(X Y : C) :
size (X ∪ Y) >= size X.
Proof.
apply subseteq_size.
apply subseteq_union.
by set_solver.
Qed.
Lemma union_size_ge_size2
(X Y : C) :
size (X ∪ Y) >= size Y.
Proof.
apply subseteq_size.
apply subseteq_union.
by set_solver.
Qed.
Lemma union_size_ge_average
(X Y : C) :
2 * size (X ∪ Y) >= size X + size Y.
Proof.
specialize (union_size_ge_size1 X Y) as Hx.
specialize (union_size_ge_size2 X Y) as Hy.
by lia.
Qed.
Lemma difference_size_le_self
(X Y : C) :
size (X ∖ Y) <= size X.
Proof.
apply subseteq_size.
apply elem_of_subseteq.
intros x Hx.
apply elem_of_difference in Hx.
by itauto.
Qed.
Lemma union_size_le_sum
(X Y : C) :
size (X ∪ Y) <= size X + size Y.
Proof.
specialize (size_union_alt X Y) as Halt.
rewrite Halt.
specialize (difference_size_le_self Y X).
by lia.
Qed.
Lemma intersection_size1
(X Y : C) :
size (X ∩ Y) <= size X.
Proof.
apply (subseteq_size (X ∩ Y) X).
by set_solver.
Qed.
Lemma intersection_size2
(X Y : C) :
size (X ∩ Y) <= size Y.
Proof.
apply (subseteq_size (X ∩ Y) Y).
by set_solver.
Qed.
Lemma difference_size_subset
(X Y : C)
(Hsub : Y ⊆ X) :
(Z.of_nat (size (X ∖ Y)) = Z.of_nat (size X) - Z.of_nat (size Y))%Z.
Proof.
assert (Htemp : Y ∪ (X ∖ Y) ≡ X).
{
apply set_equiv_equivalence.
intros a.
split; intros Ha.
- by set_solver.
- destruct (decide (a ∈ Y)).
+ by apply elem_of_union; left; itauto.
+ by apply elem_of_union; right; set_solver.
}
assert (Htemp2 : size Y + size (X ∖ Y) = size X).
{
specialize (size_union Y (X ∖ Y)) as Hun.
spec Hun.
{
apply elem_of_disjoint.
intros a Ha Ha2.
apply elem_of_difference in Ha2.
by itauto.
}
rewrite Htemp in Hun.
by itauto.
}
by lia.
Qed.
Lemma difference_with_intersection
(X Y : C) :
X ∖ Y ≡ X ∖ (X ∩ Y).
Proof.
by set_solver.
Qed.
Lemma difference_size
(X Y : C) :
(Z.of_nat (size (X ∖ Y)) = Z.of_nat (size X) - Z.of_nat (size (X ∩ Y)))%Z.
Proof.
rewrite difference_with_intersection.
specialize (difference_size_subset X (X ∩ Y)) as Hdif.
by set_solver.
Qed.
Lemma difference_size_ge_disjoint_case
(X Y : C) :
size (X ∖ Y) >= size X - size Y.
Proof.
specialize (difference_size X Y).
specialize (intersection_size2 X Y).
by lia.
Qed.
Lemma list_to_set_size
(l : list A) :
size (list_to_set l (C := C)) <= length l.
Proof.
induction l; cbn.
- by rewrite size_empty; lia.
- specialize (union_size_le_sum ({[ a ]}) (list_to_set l)) as Hun_size.
by rewrite size_singleton in Hun_size; lia.
Qed.
#[export] Instance fin_set_subseteq_dec : RelDecision (⊆@{C}).
Proof.
intros X Y.
eapply @Decision_iff with (P := set_Forall (fun a => a ∈ Y) X).
- by set_solver.
- by typeclasses eauto.
Qed.
#[export] Instance fin_set_empty_eq_dec :
forall (X : C), Decision (X ≡ ∅).
Proof.
intros.
destruct (decide (elements X = [])).
- by left; rewrite <- elements_empty_iff.
- by right; rewrite <- elements_empty_iff.
Qed.
#[export] Instance fin_set_singleton_eq_dec :
forall (X : C) (x : A), Decision (X ≡ {[x]}).
Proof.
intros X x.
destruct (decide (elements X = [x])) as [Heq|Heq].
- left; intro i.
rewrite elem_of_singleton, <- elem_of_elements.
by rewrite Heq, elem_of_list_singleton.
- right; contradict Heq.
apply Permutation_singleton_r.
by rewrite Heq, elements_singleton.
Qed.
#[export] Instance finset_equiv_dec `{FinSet A C} : RelDecision (≡@{C}).
Proof.
intros X Y.
destruct (decide (elements X ≡ₚ elements Y));
[| by right; contradict n; rewrite n].
left; intros a.
rewrite <- !elem_of_elements, !elem_of_list_lookup.
split; intros (i & Hi); [| symmetry in p];
apply Permutation_inj in p as (Hlen & f & Hinjf & Hp).
- by rewrite Hp in Hi; eexists.
- by rewrite Hp in Hi; eexists.
Qed.
End sec_general.
Section sec_filter.
Context
(P P2 : A -> Prop)
`{!forall x, Decision (P x)}
`{!forall x, Decision (P2 x)}
(X Y : C).
Lemma filter_subset
(Hsub : X ⊆ Y) :
filter P X ⊆ filter P Y.
Proof.
intros a HaX.
apply elem_of_filter in HaX.
apply elem_of_filter.
by set_solver.
Qed.
Lemma filter_subprop
(Hsub : forall a, (P a -> P2 a)) :
filter P X ⊆ filter P2 X.
Proof.
intros a HaP.
apply elem_of_filter in HaP.
apply elem_of_filter.
by itauto.
Qed.
End sec_filter.
End sec_fin_set.
Section sec_map.
Context
`{FinSet A C}
`{FinSet B D}.
Lemma set_map_subset
(f : A -> B)
(X Y : C)
(Hsub : X ⊆ Y) :
set_map (D := D) f X ⊆ set_map (D := D) f Y.
Proof.
intros a Ha.
apply elem_of_map in Ha.
apply elem_of_map.
by firstorder.
Qed.
Lemma set_map_size_upper_bound
(f : A -> B)
(X : C) :
size (set_map (D := D) f X) <= size X.
Proof.
unfold set_map.
remember (f <$> elements X) as fX.
set (x := size (list_to_set _)).
cut (x <= length fX); [| by apply list_to_set_size].
enough (length fX = size X) by lia.
unfold size, set_size.
simpl; subst fX.
by apply fmap_length.
Qed.
Lemma elem_of_set_map_inj (f : A -> B) `{!Inj (=) (=) f} (a : A) (X : C) :
f a ∈@{D} fin_sets.set_map f X <-> a ∈ X.
Proof.
intros; rewrite elem_of_map.
split; [| by eexists].
intros (_v & HeqAv & H_v).
eapply inj in HeqAv; [| done].
by subst.
Qed.
Lemma set_map_id (X : C) : X ≡ set_map id X.
Proof. by set_solver. Qed.
End sec_map.
Definition mmap_insert
{I A SA : Type} {MI : Type -> Type}
`{FinMap I MI} `{FinSet A SA} (i : I) (a : A) (m : MI SA) :=
<[ i := {[ a ]} ∪ m !!! i ]> m.
Lemma elem_of_mmap_insert
{I A SA : Type} {MI : Type -> Type}
`{FinMap I MI} `{FinSet A SA} (m : MI SA) (i j : I) (a b : A) :
b ∈ mmap_insert i a m !!! j <-> (a = b /\ i = j) \/ (b ∈ m !!! j).
Proof.
unfold mmap_insert.
destruct (decide (i = j)) as [<- | Hij].
- rewrite lookup_total_insert.
by destruct (decide (a = b)); set_solver.
- rewrite lookup_total_insert_ne by done.
by set_solver.
Qed.