-
Notifications
You must be signed in to change notification settings - Fork 307
/
Finite.lean
1755 lines (1384 loc) · 75.5 KB
/
Finite.lean
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/-
Copyright (c) 2017 Johannes Hölzl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl, Mario Carneiro, Kyle Miller
-/
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Set.Functor
import Mathlib.Data.Finite.Basic
#align_import data.set.finite from "leanprover-community/mathlib"@"65a1391a0106c9204fe45bc73a039f056558cb83"
/-!
# Finite sets
This file defines predicates for finite and infinite sets and provides
`Fintype` instances for many set constructions. It also proves basic facts
about finite sets and gives ways to manipulate `Set.Finite` expressions.
## Main definitions
* `Set.Finite : Set α → Prop`
* `Set.Infinite : Set α → Prop`
* `Set.toFinite` to prove `Set.Finite` for a `Set` from a `Finite` instance.
* `Set.Finite.toFinset` to noncomputably produce a `Finset` from a `Set.Finite` proof.
(See `Set.toFinset` for a computable version.)
## Implementation
A finite set is defined to be a set whose coercion to a type has a `Finite` instance.
There are two components to finiteness constructions. The first is `Fintype` instances for each
construction. This gives a way to actually compute a `Finset` that represents the set, and these
may be accessed using `set.toFinset`. This gets the `Finset` in the correct form, since otherwise
`Finset.univ : Finset s` is a `Finset` for the subtype for `s`. The second component is
"constructors" for `Set.Finite` that give proofs that `Fintype` instances exist classically given
other `Set.Finite` proofs. Unlike the `Fintype` instances, these *do not* use any decidability
instances since they do not compute anything.
## Tags
finite sets
-/
open Set Function
universe u v w x
variable {α : Type u} {β : Type v} {ι : Sort w} {γ : Type x}
namespace Set
/-- A set is finite if the corresponding `Subtype` is finite,
i.e., if there exists a natural `n : ℕ` and an equivalence `s ≃ Fin n`. -/
protected def Finite (s : Set α) : Prop := Finite s
#align set.finite Set.Finite
-- The `protected` attribute does not take effect within the same namespace block.
end Set
namespace Set
theorem finite_def {s : Set α} : s.Finite ↔ Nonempty (Fintype s) :=
finite_iff_nonempty_fintype s
#align set.finite_def Set.finite_def
protected alias ⟨Finite.nonempty_fintype, _⟩ := finite_def
#align set.finite.nonempty_fintype Set.Finite.nonempty_fintype
theorem finite_coe_iff {s : Set α} : Finite s ↔ s.Finite := .rfl
#align set.finite_coe_iff Set.finite_coe_iff
/-- Constructor for `Set.Finite` using a `Finite` instance. -/
theorem toFinite (s : Set α) [Finite s] : s.Finite := ‹_›
#align set.to_finite Set.toFinite
/-- Construct a `Finite` instance for a `Set` from a `Finset` with the same elements. -/
protected theorem Finite.ofFinset {p : Set α} (s : Finset α) (H : ∀ x, x ∈ s ↔ x ∈ p) : p.Finite :=
have := Fintype.ofFinset s H; p.toFinite
#align set.finite.of_finset Set.Finite.ofFinset
/-- Projection of `Set.Finite` to its `Finite` instance.
This is intended to be used with dot notation.
See also `Set.Finite.Fintype` and `Set.Finite.nonempty_fintype`. -/
protected theorem Finite.to_subtype {s : Set α} (h : s.Finite) : Finite s := h
#align set.finite.to_subtype Set.Finite.to_subtype
/-- A finite set coerced to a type is a `Fintype`.
This is the `Fintype` projection for a `Set.Finite`.
Note that because `Finite` isn't a typeclass, this definition will not fire if it
is made into an instance -/
protected noncomputable def Finite.fintype {s : Set α} (h : s.Finite) : Fintype s :=
h.nonempty_fintype.some
#align set.finite.fintype Set.Finite.fintype
/-- Using choice, get the `Finset` that represents this `Set`. -/
protected noncomputable def Finite.toFinset {s : Set α} (h : s.Finite) : Finset α :=
@Set.toFinset _ _ h.fintype
#align set.finite.to_finset Set.Finite.toFinset
theorem Finite.toFinset_eq_toFinset {s : Set α} [Fintype s] (h : s.Finite) :
h.toFinset = s.toFinset := by
-- Porting note: was `rw [Finite.toFinset]; congr`
-- in Lean 4, a goal is left after `congr`
have : h.fintype = ‹_› := Subsingleton.elim _ _
rw [Finite.toFinset, this]
#align set.finite.to_finset_eq_to_finset Set.Finite.toFinset_eq_toFinset
@[simp]
theorem toFinite_toFinset (s : Set α) [Fintype s] : s.toFinite.toFinset = s.toFinset :=
s.toFinite.toFinset_eq_toFinset
#align set.to_finite_to_finset Set.toFinite_toFinset
theorem Finite.exists_finset {s : Set α} (h : s.Finite) :
∃ s' : Finset α, ∀ a : α, a ∈ s' ↔ a ∈ s := by
cases h.nonempty_fintype
exact ⟨s.toFinset, fun _ => mem_toFinset⟩
#align set.finite.exists_finset Set.Finite.exists_finset
theorem Finite.exists_finset_coe {s : Set α} (h : s.Finite) : ∃ s' : Finset α, ↑s' = s := by
cases h.nonempty_fintype
exact ⟨s.toFinset, s.coe_toFinset⟩
#align set.finite.exists_finset_coe Set.Finite.exists_finset_coe
/-- Finite sets can be lifted to finsets. -/
instance : CanLift (Set α) (Finset α) (↑) Set.Finite where prf _ hs := hs.exists_finset_coe
/-- A set is infinite if it is not finite.
This is protected so that it does not conflict with global `Infinite`. -/
protected def Infinite (s : Set α) : Prop :=
¬s.Finite
#align set.infinite Set.Infinite
@[simp]
theorem not_infinite {s : Set α} : ¬s.Infinite ↔ s.Finite :=
not_not
#align set.not_infinite Set.not_infinite
alias ⟨_, Finite.not_infinite⟩ := not_infinite
#align set.finite.not_infinite Set.Finite.not_infinite
attribute [simp] Finite.not_infinite
/-- See also `finite_or_infinite`, `fintypeOrInfinite`. -/
protected theorem finite_or_infinite (s : Set α) : s.Finite ∨ s.Infinite :=
em _
#align set.finite_or_infinite Set.finite_or_infinite
protected theorem infinite_or_finite (s : Set α) : s.Infinite ∨ s.Finite :=
em' _
#align set.infinite_or_finite Set.infinite_or_finite
/-! ### Basic properties of `Set.Finite.toFinset` -/
namespace Finite
variable {s t : Set α} {a : α} (hs : s.Finite) {ht : t.Finite}
@[simp]
protected theorem mem_toFinset : a ∈ hs.toFinset ↔ a ∈ s :=
@mem_toFinset _ _ hs.fintype _
#align set.finite.mem_to_finset Set.Finite.mem_toFinset
@[simp]
protected theorem coe_toFinset : (hs.toFinset : Set α) = s :=
@coe_toFinset _ _ hs.fintype
#align set.finite.coe_to_finset Set.Finite.coe_toFinset
@[simp]
protected theorem toFinset_nonempty : hs.toFinset.Nonempty ↔ s.Nonempty := by
rw [← Finset.coe_nonempty, Finite.coe_toFinset]
#align set.finite.to_finset_nonempty Set.Finite.toFinset_nonempty
/-- Note that this is an equality of types not holding definitionally. Use wisely. -/
theorem coeSort_toFinset : ↥hs.toFinset = ↥s := by
rw [← Finset.coe_sort_coe _, hs.coe_toFinset]
#align set.finite.coe_sort_to_finset Set.Finite.coeSort_toFinset
/-- The identity map, bundled as an equivalence between the subtypes of `s : Set α` and of
`h.toFinset : Finset α`, where `h` is a proof of finiteness of `s`. -/
@[simps!] def subtypeEquivToFinset : {x // x ∈ s} ≃ {x // x ∈ hs.toFinset} :=
(Equiv.refl α).subtypeEquiv fun _ ↦ hs.mem_toFinset.symm
variable {hs}
@[simp]
protected theorem toFinset_inj : hs.toFinset = ht.toFinset ↔ s = t :=
@toFinset_inj _ _ _ hs.fintype ht.fintype
#align set.finite.to_finset_inj Set.Finite.toFinset_inj
@[simp]
theorem toFinset_subset {t : Finset α} : hs.toFinset ⊆ t ↔ s ⊆ t := by
rw [← Finset.coe_subset, Finite.coe_toFinset]
#align set.finite.to_finset_subset Set.Finite.toFinset_subset
@[simp]
theorem toFinset_ssubset {t : Finset α} : hs.toFinset ⊂ t ↔ s ⊂ t := by
rw [← Finset.coe_ssubset, Finite.coe_toFinset]
#align set.finite.to_finset_ssubset Set.Finite.toFinset_ssubset
@[simp]
theorem subset_toFinset {s : Finset α} : s ⊆ ht.toFinset ↔ ↑s ⊆ t := by
rw [← Finset.coe_subset, Finite.coe_toFinset]
#align set.finite.subset_to_finset Set.Finite.subset_toFinset
@[simp]
theorem ssubset_toFinset {s : Finset α} : s ⊂ ht.toFinset ↔ ↑s ⊂ t := by
rw [← Finset.coe_ssubset, Finite.coe_toFinset]
#align set.finite.ssubset_to_finset Set.Finite.ssubset_toFinset
@[mono]
protected theorem toFinset_subset_toFinset : hs.toFinset ⊆ ht.toFinset ↔ s ⊆ t := by
simp only [← Finset.coe_subset, Finite.coe_toFinset]
#align set.finite.to_finset_subset_to_finset Set.Finite.toFinset_subset_toFinset
@[mono]
protected theorem toFinset_ssubset_toFinset : hs.toFinset ⊂ ht.toFinset ↔ s ⊂ t := by
simp only [← Finset.coe_ssubset, Finite.coe_toFinset]
#align set.finite.to_finset_ssubset_to_finset Set.Finite.toFinset_ssubset_toFinset
alias ⟨_, toFinset_mono⟩ := Finite.toFinset_subset_toFinset
#align set.finite.to_finset_mono Set.Finite.toFinset_mono
alias ⟨_, toFinset_strictMono⟩ := Finite.toFinset_ssubset_toFinset
#align set.finite.to_finset_strict_mono Set.Finite.toFinset_strictMono
-- Porting note: attribute [protected] doesn't work
-- attribute [protected] toFinset_mono toFinset_strictMono
-- Porting note: `simp` can simplify LHS but then it simplifies something
-- in the generated `Fintype {x | p x}` instance and fails to apply `Set.toFinset_setOf`
@[simp high]
protected theorem toFinset_setOf [Fintype α] (p : α → Prop) [DecidablePred p]
(h : { x | p x }.Finite) : h.toFinset = Finset.univ.filter p := by
ext
-- Porting note: `simp` doesn't use the `simp` lemma `Set.toFinset_setOf` without the `_`
simp [Set.toFinset_setOf _]
#align set.finite.to_finset_set_of Set.Finite.toFinset_setOf
@[simp]
nonrec theorem disjoint_toFinset {hs : s.Finite} {ht : t.Finite} :
Disjoint hs.toFinset ht.toFinset ↔ Disjoint s t :=
@disjoint_toFinset _ _ _ hs.fintype ht.fintype
#align set.finite.disjoint_to_finset Set.Finite.disjoint_toFinset
protected theorem toFinset_inter [DecidableEq α] (hs : s.Finite) (ht : t.Finite)
(h : (s ∩ t).Finite) : h.toFinset = hs.toFinset ∩ ht.toFinset := by
ext
simp
#align set.finite.to_finset_inter Set.Finite.toFinset_inter
protected theorem toFinset_union [DecidableEq α] (hs : s.Finite) (ht : t.Finite)
(h : (s ∪ t).Finite) : h.toFinset = hs.toFinset ∪ ht.toFinset := by
ext
simp
#align set.finite.to_finset_union Set.Finite.toFinset_union
protected theorem toFinset_diff [DecidableEq α] (hs : s.Finite) (ht : t.Finite)
(h : (s \ t).Finite) : h.toFinset = hs.toFinset \ ht.toFinset := by
ext
simp
#align set.finite.to_finset_diff Set.Finite.toFinset_diff
open scoped symmDiff in
protected theorem toFinset_symmDiff [DecidableEq α] (hs : s.Finite) (ht : t.Finite)
(h : (s ∆ t).Finite) : h.toFinset = hs.toFinset ∆ ht.toFinset := by
ext
simp [mem_symmDiff, Finset.mem_symmDiff]
#align set.finite.to_finset_symm_diff Set.Finite.toFinset_symmDiff
protected theorem toFinset_compl [DecidableEq α] [Fintype α] (hs : s.Finite) (h : sᶜ.Finite) :
h.toFinset = hs.toFinsetᶜ := by
ext
simp
#align set.finite.to_finset_compl Set.Finite.toFinset_compl
protected theorem toFinset_univ [Fintype α] (h : (Set.univ : Set α).Finite) :
h.toFinset = Finset.univ := by
simp
#align set.finite.to_finset_univ Set.Finite.toFinset_univ
@[simp]
protected theorem toFinset_eq_empty {h : s.Finite} : h.toFinset = ∅ ↔ s = ∅ :=
@toFinset_eq_empty _ _ h.fintype
#align set.finite.to_finset_eq_empty Set.Finite.toFinset_eq_empty
protected theorem toFinset_empty (h : (∅ : Set α).Finite) : h.toFinset = ∅ := by
simp
#align set.finite.to_finset_empty Set.Finite.toFinset_empty
@[simp]
protected theorem toFinset_eq_univ [Fintype α] {h : s.Finite} :
h.toFinset = Finset.univ ↔ s = univ :=
@toFinset_eq_univ _ _ _ h.fintype
#align set.finite.to_finset_eq_univ Set.Finite.toFinset_eq_univ
protected theorem toFinset_image [DecidableEq β] (f : α → β) (hs : s.Finite) (h : (f '' s).Finite) :
h.toFinset = hs.toFinset.image f := by
ext
simp
#align set.finite.to_finset_image Set.Finite.toFinset_image
-- Porting note (#10618): now `simp` can prove it but it needs the `fintypeRange` instance
-- from the next section
protected theorem toFinset_range [DecidableEq α] [Fintype β] (f : β → α) (h : (range f).Finite) :
h.toFinset = Finset.univ.image f := by
ext
simp
#align set.finite.to_finset_range Set.Finite.toFinset_range
end Finite
/-! ### Fintype instances
Every instance here should have a corresponding `Set.Finite` constructor in the next section.
-/
section FintypeInstances
instance fintypeUniv [Fintype α] : Fintype (@univ α) :=
Fintype.ofEquiv α (Equiv.Set.univ α).symm
#align set.fintype_univ Set.fintypeUniv
/-- If `(Set.univ : Set α)` is finite then `α` is a finite type. -/
noncomputable def fintypeOfFiniteUniv (H : (univ (α := α)).Finite) : Fintype α :=
@Fintype.ofEquiv _ (univ : Set α) H.fintype (Equiv.Set.univ _)
#align set.fintype_of_finite_univ Set.fintypeOfFiniteUniv
instance fintypeUnion [DecidableEq α] (s t : Set α) [Fintype s] [Fintype t] :
Fintype (s ∪ t : Set α) :=
Fintype.ofFinset (s.toFinset ∪ t.toFinset) <| by simp
#align set.fintype_union Set.fintypeUnion
instance fintypeSep (s : Set α) (p : α → Prop) [Fintype s] [DecidablePred p] :
Fintype ({ a ∈ s | p a } : Set α) :=
Fintype.ofFinset (s.toFinset.filter p) <| by simp
#align set.fintype_sep Set.fintypeSep
instance fintypeInter (s t : Set α) [DecidableEq α] [Fintype s] [Fintype t] :
Fintype (s ∩ t : Set α) :=
Fintype.ofFinset (s.toFinset ∩ t.toFinset) <| by simp
#align set.fintype_inter Set.fintypeInter
/-- A `Fintype` instance for set intersection where the left set has a `Fintype` instance. -/
instance fintypeInterOfLeft (s t : Set α) [Fintype s] [DecidablePred (· ∈ t)] :
Fintype (s ∩ t : Set α) :=
Fintype.ofFinset (s.toFinset.filter (· ∈ t)) <| by simp
#align set.fintype_inter_of_left Set.fintypeInterOfLeft
/-- A `Fintype` instance for set intersection where the right set has a `Fintype` instance. -/
instance fintypeInterOfRight (s t : Set α) [Fintype t] [DecidablePred (· ∈ s)] :
Fintype (s ∩ t : Set α) :=
Fintype.ofFinset (t.toFinset.filter (· ∈ s)) <| by simp [and_comm]
#align set.fintype_inter_of_right Set.fintypeInterOfRight
/-- A `Fintype` structure on a set defines a `Fintype` structure on its subset. -/
def fintypeSubset (s : Set α) {t : Set α} [Fintype s] [DecidablePred (· ∈ t)] (h : t ⊆ s) :
Fintype t := by
rw [← inter_eq_self_of_subset_right h]
apply Set.fintypeInterOfLeft
#align set.fintype_subset Set.fintypeSubset
instance fintypeDiff [DecidableEq α] (s t : Set α) [Fintype s] [Fintype t] :
Fintype (s \ t : Set α) :=
Fintype.ofFinset (s.toFinset \ t.toFinset) <| by simp
#align set.fintype_diff Set.fintypeDiff
instance fintypeDiffLeft (s t : Set α) [Fintype s] [DecidablePred (· ∈ t)] :
Fintype (s \ t : Set α) :=
Set.fintypeSep s (· ∈ tᶜ)
#align set.fintype_diff_left Set.fintypeDiffLeft
instance fintypeiUnion [DecidableEq α] [Fintype (PLift ι)] (f : ι → Set α) [∀ i, Fintype (f i)] :
Fintype (⋃ i, f i) :=
Fintype.ofFinset (Finset.univ.biUnion fun i : PLift ι => (f i.down).toFinset) <| by simp
#align set.fintype_Union Set.fintypeiUnion
instance fintypesUnion [DecidableEq α] {s : Set (Set α)} [Fintype s]
[H : ∀ t : s, Fintype (t : Set α)] : Fintype (⋃₀ s) := by
rw [sUnion_eq_iUnion]
exact @Set.fintypeiUnion _ _ _ _ _ H
#align set.fintype_sUnion Set.fintypesUnion
/-- A union of sets with `Fintype` structure over a set with `Fintype` structure has a `Fintype`
structure. -/
def fintypeBiUnion [DecidableEq α] {ι : Type*} (s : Set ι) [Fintype s] (t : ι → Set α)
(H : ∀ i ∈ s, Fintype (t i)) : Fintype (⋃ x ∈ s, t x) :=
haveI : ∀ i : toFinset s, Fintype (t i) := fun i => H i (mem_toFinset.1 i.2)
Fintype.ofFinset (s.toFinset.attach.biUnion fun x => (t x).toFinset) fun x => by simp
#align set.fintype_bUnion Set.fintypeBiUnion
instance fintypeBiUnion' [DecidableEq α] {ι : Type*} (s : Set ι) [Fintype s] (t : ι → Set α)
[∀ i, Fintype (t i)] : Fintype (⋃ x ∈ s, t x) :=
Fintype.ofFinset (s.toFinset.biUnion fun x => (t x).toFinset) <| by simp
#align set.fintype_bUnion' Set.fintypeBiUnion'
section monad
attribute [local instance] Set.monad
/-- If `s : Set α` is a set with `Fintype` instance and `f : α → Set β` is a function such that
each `f a`, `a ∈ s`, has a `Fintype` structure, then `s >>= f` has a `Fintype` structure. -/
def fintypeBind {α β} [DecidableEq β] (s : Set α) [Fintype s] (f : α → Set β)
(H : ∀ a ∈ s, Fintype (f a)) : Fintype (s >>= f) :=
Set.fintypeBiUnion s f H
#align set.fintype_bind Set.fintypeBind
instance fintypeBind' {α β} [DecidableEq β] (s : Set α) [Fintype s] (f : α → Set β)
[∀ a, Fintype (f a)] : Fintype (s >>= f) :=
Set.fintypeBiUnion' s f
#align set.fintype_bind' Set.fintypeBind'
end monad
instance fintypeEmpty : Fintype (∅ : Set α) :=
Fintype.ofFinset ∅ <| by simp
#align set.fintype_empty Set.fintypeEmpty
instance fintypeSingleton (a : α) : Fintype ({a} : Set α) :=
Fintype.ofFinset {a} <| by simp
#align set.fintype_singleton Set.fintypeSingleton
instance fintypePure : ∀ a : α, Fintype (pure a : Set α) :=
Set.fintypeSingleton
#align set.fintype_pure Set.fintypePure
/-- A `Fintype` instance for inserting an element into a `Set` using the
corresponding `insert` function on `Finset`. This requires `DecidableEq α`.
There is also `Set.fintypeInsert'` when `a ∈ s` is decidable. -/
instance fintypeInsert (a : α) (s : Set α) [DecidableEq α] [Fintype s] :
Fintype (insert a s : Set α) :=
Fintype.ofFinset (insert a s.toFinset) <| by simp
#align set.fintype_insert Set.fintypeInsert
/-- A `Fintype` structure on `insert a s` when inserting a new element. -/
def fintypeInsertOfNotMem {a : α} (s : Set α) [Fintype s] (h : a ∉ s) :
Fintype (insert a s : Set α) :=
Fintype.ofFinset ⟨a ::ₘ s.toFinset.1, s.toFinset.nodup.cons (by simp [h])⟩ <| by simp
#align set.fintype_insert_of_not_mem Set.fintypeInsertOfNotMem
/-- A `Fintype` structure on `insert a s` when inserting a pre-existing element. -/
def fintypeInsertOfMem {a : α} (s : Set α) [Fintype s] (h : a ∈ s) : Fintype (insert a s : Set α) :=
Fintype.ofFinset s.toFinset <| by simp [h]
#align set.fintype_insert_of_mem Set.fintypeInsertOfMem
/-- The `Set.fintypeInsert` instance requires decidable equality, but when `a ∈ s`
is decidable for this particular `a` we can still get a `Fintype` instance by using
`Set.fintypeInsertOfNotMem` or `Set.fintypeInsertOfMem`.
This instance pre-dates `Set.fintypeInsert`, and it is less efficient.
When `Set.decidableMemOfFintype` is made a local instance, then this instance would
override `Set.fintypeInsert` if not for the fact that its priority has been
adjusted. See Note [lower instance priority]. -/
instance (priority := 100) fintypeInsert' (a : α) (s : Set α) [Decidable <| a ∈ s] [Fintype s] :
Fintype (insert a s : Set α) :=
if h : a ∈ s then fintypeInsertOfMem s h else fintypeInsertOfNotMem s h
#align set.fintype_insert' Set.fintypeInsert'
instance fintypeImage [DecidableEq β] (s : Set α) (f : α → β) [Fintype s] : Fintype (f '' s) :=
Fintype.ofFinset (s.toFinset.image f) <| by simp
#align set.fintype_image Set.fintypeImage
/-- If a function `f` has a partial inverse and sends a set `s` to a set with `[Fintype]` instance,
then `s` has a `Fintype` structure as well. -/
def fintypeOfFintypeImage (s : Set α) {f : α → β} {g} (I : IsPartialInv f g) [Fintype (f '' s)] :
Fintype s :=
Fintype.ofFinset ⟨_, (f '' s).toFinset.2.filterMap g <| injective_of_isPartialInv_right I⟩
fun a => by
suffices (∃ b x, f x = b ∧ g b = some a ∧ x ∈ s) ↔ a ∈ s by
simpa [exists_and_left.symm, and_comm, and_left_comm, and_assoc]
rw [exists_swap]
suffices (∃ x, x ∈ s ∧ g (f x) = some a) ↔ a ∈ s by simpa [and_comm, and_left_comm, and_assoc]
simp [I _, (injective_of_isPartialInv I).eq_iff]
#align set.fintype_of_fintype_image Set.fintypeOfFintypeImage
instance fintypeRange [DecidableEq α] (f : ι → α) [Fintype (PLift ι)] : Fintype (range f) :=
Fintype.ofFinset (Finset.univ.image <| f ∘ PLift.down) <| by simp
#align set.fintype_range Set.fintypeRange
instance fintypeMap {α β} [DecidableEq β] :
∀ (s : Set α) (f : α → β) [Fintype s], Fintype (f <$> s) :=
Set.fintypeImage
#align set.fintype_map Set.fintypeMap
instance fintypeLTNat (n : ℕ) : Fintype { i | i < n } :=
Fintype.ofFinset (Finset.range n) <| by simp
#align set.fintype_lt_nat Set.fintypeLTNat
instance fintypeLENat (n : ℕ) : Fintype { i | i ≤ n } := by
simpa [Nat.lt_succ_iff] using Set.fintypeLTNat (n + 1)
#align set.fintype_le_nat Set.fintypeLENat
/-- This is not an instance so that it does not conflict with the one
in `Mathlib/Order/LocallyFinite.lean`. -/
def Nat.fintypeIio (n : ℕ) : Fintype (Iio n) :=
Set.fintypeLTNat n
#align set.nat.fintype_Iio Set.Nat.fintypeIio
instance fintypeProd (s : Set α) (t : Set β) [Fintype s] [Fintype t] :
Fintype (s ×ˢ t : Set (α × β)) :=
Fintype.ofFinset (s.toFinset ×ˢ t.toFinset) <| by simp
#align set.fintype_prod Set.fintypeProd
instance fintypeOffDiag [DecidableEq α] (s : Set α) [Fintype s] : Fintype s.offDiag :=
Fintype.ofFinset s.toFinset.offDiag <| by simp
#align set.fintype_off_diag Set.fintypeOffDiag
/-- `image2 f s t` is `Fintype` if `s` and `t` are. -/
instance fintypeImage2 [DecidableEq γ] (f : α → β → γ) (s : Set α) (t : Set β) [hs : Fintype s]
[ht : Fintype t] : Fintype (image2 f s t : Set γ) := by
rw [← image_prod]
apply Set.fintypeImage
#align set.fintype_image2 Set.fintypeImage2
instance fintypeSeq [DecidableEq β] (f : Set (α → β)) (s : Set α) [Fintype f] [Fintype s] :
Fintype (f.seq s) := by
rw [seq_def]
apply Set.fintypeBiUnion'
#align set.fintype_seq Set.fintypeSeq
instance fintypeSeq' {α β : Type u} [DecidableEq β] (f : Set (α → β)) (s : Set α) [Fintype f]
[Fintype s] : Fintype (f <*> s) :=
Set.fintypeSeq f s
#align set.fintype_seq' Set.fintypeSeq'
instance fintypeMemFinset (s : Finset α) : Fintype { a | a ∈ s } :=
Finset.fintypeCoeSort s
#align set.fintype_mem_finset Set.fintypeMemFinset
end FintypeInstances
end Set
theorem Equiv.set_finite_iff {s : Set α} {t : Set β} (hst : s ≃ t) : s.Finite ↔ t.Finite := by
simp_rw [← Set.finite_coe_iff, hst.finite_iff]
#align equiv.set_finite_iff Equiv.set_finite_iff
/-! ### Finset -/
namespace Finset
/-- Gives a `Set.Finite` for the `Finset` coerced to a `Set`.
This is a wrapper around `Set.toFinite`. -/
@[simp]
theorem finite_toSet (s : Finset α) : (s : Set α).Finite :=
Set.toFinite _
#align finset.finite_to_set Finset.finite_toSet
-- Porting note (#10618): was @[simp], now `simp` can prove it
theorem finite_toSet_toFinset (s : Finset α) : s.finite_toSet.toFinset = s := by
rw [toFinite_toFinset, toFinset_coe]
#align finset.finite_to_set_to_finset Finset.finite_toSet_toFinset
end Finset
namespace Multiset
@[simp]
theorem finite_toSet (s : Multiset α) : { x | x ∈ s }.Finite := by
classical simpa only [← Multiset.mem_toFinset] using s.toFinset.finite_toSet
#align multiset.finite_to_set Multiset.finite_toSet
@[simp]
theorem finite_toSet_toFinset [DecidableEq α] (s : Multiset α) :
s.finite_toSet.toFinset = s.toFinset := by
ext x
simp
#align multiset.finite_to_set_to_finset Multiset.finite_toSet_toFinset
end Multiset
@[simp]
theorem List.finite_toSet (l : List α) : { x | x ∈ l }.Finite :=
(show Multiset α from ⟦l⟧).finite_toSet
#align list.finite_to_set List.finite_toSet
/-! ### Finite instances
There is seemingly some overlap between the following instances and the `Fintype` instances
in `Data.Set.Finite`. While every `Fintype` instance gives a `Finite` instance, those
instances that depend on `Fintype` or `Decidable` instances need an additional `Finite` instance
to be able to generally apply.
Some set instances do not appear here since they are consequences of others, for example
`Subtype.Finite` for subsets of a finite type.
-/
namespace Finite.Set
open scoped Classical
example {s : Set α} [Finite α] : Finite s :=
inferInstance
example : Finite (∅ : Set α) :=
inferInstance
example (a : α) : Finite ({a} : Set α) :=
inferInstance
instance finite_union (s t : Set α) [Finite s] [Finite t] : Finite (s ∪ t : Set α) := by
cases nonempty_fintype s
cases nonempty_fintype t
infer_instance
#align finite.set.finite_union Finite.Set.finite_union
instance finite_sep (s : Set α) (p : α → Prop) [Finite s] : Finite ({ a ∈ s | p a } : Set α) := by
cases nonempty_fintype s
infer_instance
#align finite.set.finite_sep Finite.Set.finite_sep
protected theorem subset (s : Set α) {t : Set α} [Finite s] (h : t ⊆ s) : Finite t := by
rw [← sep_eq_of_subset h]
infer_instance
#align finite.set.subset Finite.Set.subset
instance finite_inter_of_right (s t : Set α) [Finite t] : Finite (s ∩ t : Set α) :=
Finite.Set.subset t (inter_subset_right s t)
#align finite.set.finite_inter_of_right Finite.Set.finite_inter_of_right
instance finite_inter_of_left (s t : Set α) [Finite s] : Finite (s ∩ t : Set α) :=
Finite.Set.subset s (inter_subset_left s t)
#align finite.set.finite_inter_of_left Finite.Set.finite_inter_of_left
instance finite_diff (s t : Set α) [Finite s] : Finite (s \ t : Set α) :=
Finite.Set.subset s (diff_subset s t)
#align finite.set.finite_diff Finite.Set.finite_diff
instance finite_range (f : ι → α) [Finite ι] : Finite (range f) := by
haveI := Fintype.ofFinite (PLift ι)
infer_instance
#align finite.set.finite_range Finite.Set.finite_range
instance finite_iUnion [Finite ι] (f : ι → Set α) [∀ i, Finite (f i)] : Finite (⋃ i, f i) := by
rw [iUnion_eq_range_psigma]
apply Set.finite_range
#align finite.set.finite_Union Finite.Set.finite_iUnion
instance finite_sUnion {s : Set (Set α)} [Finite s] [H : ∀ t : s, Finite (t : Set α)] :
Finite (⋃₀ s) := by
rw [sUnion_eq_iUnion]
exact @Finite.Set.finite_iUnion _ _ _ _ H
#align finite.set.finite_sUnion Finite.Set.finite_sUnion
theorem finite_biUnion {ι : Type*} (s : Set ι) [Finite s] (t : ι → Set α)
(H : ∀ i ∈ s, Finite (t i)) : Finite (⋃ x ∈ s, t x) := by
rw [biUnion_eq_iUnion]
haveI : ∀ i : s, Finite (t i) := fun i => H i i.property
infer_instance
#align finite.set.finite_bUnion Finite.Set.finite_biUnion
instance finite_biUnion' {ι : Type*} (s : Set ι) [Finite s] (t : ι → Set α) [∀ i, Finite (t i)] :
Finite (⋃ x ∈ s, t x) :=
finite_biUnion s t fun _ _ => inferInstance
#align finite.set.finite_bUnion' Finite.Set.finite_biUnion'
/-- Example: `Finite (⋃ (i < n), f i)` where `f : ℕ → Set α` and `[∀ i, Finite (f i)]`
(when given instances from `Data.Nat.Interval`).
-/
instance finite_biUnion'' {ι : Type*} (p : ι → Prop) [h : Finite { x | p x }] (t : ι → Set α)
[∀ i, Finite (t i)] : Finite (⋃ (x) (_ : p x), t x) :=
@Finite.Set.finite_biUnion' _ _ (setOf p) h t _
#align finite.set.finite_bUnion'' Finite.Set.finite_biUnion''
instance finite_iInter {ι : Sort*} [Nonempty ι] (t : ι → Set α) [∀ i, Finite (t i)] :
Finite (⋂ i, t i) :=
Finite.Set.subset (t <| Classical.arbitrary ι) (iInter_subset _ _)
#align finite.set.finite_Inter Finite.Set.finite_iInter
instance finite_insert (a : α) (s : Set α) [Finite s] : Finite (insert a s : Set α) :=
Finite.Set.finite_union {a} s
#align finite.set.finite_insert Finite.Set.finite_insert
instance finite_image (s : Set α) (f : α → β) [Finite s] : Finite (f '' s) := by
cases nonempty_fintype s
infer_instance
#align finite.set.finite_image Finite.Set.finite_image
instance finite_replacement [Finite α] (f : α → β) :
Finite {f x | x : α} :=
Finite.Set.finite_range f
#align finite.set.finite_replacement Finite.Set.finite_replacement
instance finite_prod (s : Set α) (t : Set β) [Finite s] [Finite t] :
Finite (s ×ˢ t : Set (α × β)) :=
Finite.of_equiv _ (Equiv.Set.prod s t).symm
#align finite.set.finite_prod Finite.Set.finite_prod
instance finite_image2 (f : α → β → γ) (s : Set α) (t : Set β) [Finite s] [Finite t] :
Finite (image2 f s t : Set γ) := by
rw [← image_prod]
infer_instance
#align finite.set.finite_image2 Finite.Set.finite_image2
instance finite_seq (f : Set (α → β)) (s : Set α) [Finite f] [Finite s] : Finite (f.seq s) := by
rw [seq_def]
infer_instance
#align finite.set.finite_seq Finite.Set.finite_seq
end Finite.Set
namespace Set
/-! ### Constructors for `Set.Finite`
Every constructor here should have a corresponding `Fintype` instance in the previous section
(or in the `Fintype` module).
The implementation of these constructors ideally should be no more than `Set.toFinite`,
after possibly setting up some `Fintype` and classical `Decidable` instances.
-/
section SetFiniteConstructors
@[nontriviality]
theorem Finite.of_subsingleton [Subsingleton α] (s : Set α) : s.Finite :=
s.toFinite
#align set.finite.of_subsingleton Set.Finite.of_subsingleton
theorem finite_univ [Finite α] : (@univ α).Finite :=
Set.toFinite _
#align set.finite_univ Set.finite_univ
theorem finite_univ_iff : (@univ α).Finite ↔ Finite α := (Equiv.Set.univ α).finite_iff
#align set.finite_univ_iff Set.finite_univ_iff
alias ⟨_root_.Finite.of_finite_univ, _⟩ := finite_univ_iff
#align finite.of_finite_univ Finite.of_finite_univ
theorem Finite.subset {s : Set α} (hs : s.Finite) {t : Set α} (ht : t ⊆ s) : t.Finite := by
have := hs.to_subtype
exact Finite.Set.subset _ ht
#align set.finite.subset Set.Finite.subset
theorem Finite.union {s t : Set α} (hs : s.Finite) (ht : t.Finite) : (s ∪ t).Finite := by
rw [Set.Finite] at hs ht
apply toFinite
#align set.finite.union Set.Finite.union
theorem Finite.finite_of_compl {s : Set α} (hs : s.Finite) (hsc : sᶜ.Finite) : Finite α := by
rw [← finite_univ_iff, ← union_compl_self s]
exact hs.union hsc
#align set.finite.finite_of_compl Set.Finite.finite_of_compl
theorem Finite.sup {s t : Set α} : s.Finite → t.Finite → (s ⊔ t).Finite :=
Finite.union
#align set.finite.sup Set.Finite.sup
theorem Finite.sep {s : Set α} (hs : s.Finite) (p : α → Prop) : { a ∈ s | p a }.Finite :=
hs.subset <| sep_subset _ _
#align set.finite.sep Set.Finite.sep
theorem Finite.inter_of_left {s : Set α} (hs : s.Finite) (t : Set α) : (s ∩ t).Finite :=
hs.subset <| inter_subset_left _ _
#align set.finite.inter_of_left Set.Finite.inter_of_left
theorem Finite.inter_of_right {s : Set α} (hs : s.Finite) (t : Set α) : (t ∩ s).Finite :=
hs.subset <| inter_subset_right _ _
#align set.finite.inter_of_right Set.Finite.inter_of_right
theorem Finite.inf_of_left {s : Set α} (h : s.Finite) (t : Set α) : (s ⊓ t).Finite :=
h.inter_of_left t
#align set.finite.inf_of_left Set.Finite.inf_of_left
theorem Finite.inf_of_right {s : Set α} (h : s.Finite) (t : Set α) : (t ⊓ s).Finite :=
h.inter_of_right t
#align set.finite.inf_of_right Set.Finite.inf_of_right
protected lemma Infinite.mono {s t : Set α} (h : s ⊆ t) : s.Infinite → t.Infinite :=
mt fun ht ↦ ht.subset h
#align set.infinite.mono Set.Infinite.mono
theorem Finite.diff {s : Set α} (hs : s.Finite) (t : Set α) : (s \ t).Finite :=
hs.subset <| diff_subset _ _
#align set.finite.diff Set.Finite.diff
theorem Finite.of_diff {s t : Set α} (hd : (s \ t).Finite) (ht : t.Finite) : s.Finite :=
(hd.union ht).subset <| subset_diff_union _ _
#align set.finite.of_diff Set.Finite.of_diff
theorem finite_iUnion [Finite ι] {f : ι → Set α} (H : ∀ i, (f i).Finite) : (⋃ i, f i).Finite :=
haveI := fun i => (H i).to_subtype
toFinite _
#align set.finite_Union Set.finite_iUnion
/-- Dependent version of `Finite.biUnion`. -/
theorem Finite.biUnion' {ι} {s : Set ι} (hs : s.Finite) {t : ∀ i ∈ s, Set α}
(ht : ∀ i (hi : i ∈ s), (t i hi).Finite) : (⋃ i ∈ s, t i ‹_›).Finite := by
have := hs.to_subtype
rw [biUnion_eq_iUnion]
apply finite_iUnion fun i : s => ht i.1 i.2
#align set.finite.bUnion' Set.Finite.biUnion'
theorem Finite.biUnion {ι} {s : Set ι} (hs : s.Finite) {t : ι → Set α}
(ht : ∀ i ∈ s, (t i).Finite) : (⋃ i ∈ s, t i).Finite :=
hs.biUnion' ht
#align set.finite.bUnion Set.Finite.biUnion
theorem Finite.sUnion {s : Set (Set α)} (hs : s.Finite) (H : ∀ t ∈ s, Set.Finite t) :
(⋃₀ s).Finite := by
simpa only [sUnion_eq_biUnion] using hs.biUnion H
#align set.finite.sUnion Set.Finite.sUnion
theorem Finite.sInter {α : Type*} {s : Set (Set α)} {t : Set α} (ht : t ∈ s) (hf : t.Finite) :
(⋂₀ s).Finite :=
hf.subset (sInter_subset_of_mem ht)
#align set.finite.sInter Set.Finite.sInter
/-- If sets `s i` are finite for all `i` from a finite set `t` and are empty for `i ∉ t`, then the
union `⋃ i, s i` is a finite set. -/
theorem Finite.iUnion {ι : Type*} {s : ι → Set α} {t : Set ι} (ht : t.Finite)
(hs : ∀ i ∈ t, (s i).Finite) (he : ∀ i, i ∉ t → s i = ∅) : (⋃ i, s i).Finite := by
suffices ⋃ i, s i ⊆ ⋃ i ∈ t, s i by exact (ht.biUnion hs).subset this
refine' iUnion_subset fun i x hx => _
by_cases hi : i ∈ t
· exact mem_biUnion hi hx
· rw [he i hi, mem_empty_iff_false] at hx
contradiction
#align set.finite.Union Set.Finite.iUnion
section monad
attribute [local instance] Set.monad
theorem Finite.bind {α β} {s : Set α} {f : α → Set β} (h : s.Finite) (hf : ∀ a ∈ s, (f a).Finite) :
(s >>= f).Finite :=
h.biUnion hf
#align set.finite.bind Set.Finite.bind
end monad
@[simp]
theorem finite_empty : (∅ : Set α).Finite :=
toFinite _
#align set.finite_empty Set.finite_empty
protected theorem Infinite.nonempty {s : Set α} (h : s.Infinite) : s.Nonempty :=
nonempty_iff_ne_empty.2 <| by
rintro rfl
exact h finite_empty
#align set.infinite.nonempty Set.Infinite.nonempty
@[simp]
theorem finite_singleton (a : α) : ({a} : Set α).Finite :=
toFinite _
#align set.finite_singleton Set.finite_singleton
theorem finite_pure (a : α) : (pure a : Set α).Finite :=
toFinite _
#align set.finite_pure Set.finite_pure
@[simp]
protected theorem Finite.insert (a : α) {s : Set α} (hs : s.Finite) : (insert a s).Finite :=
(finite_singleton a).union hs
#align set.finite.insert Set.Finite.insert
theorem Finite.image {s : Set α} (f : α → β) (hs : s.Finite) : (f '' s).Finite := by
have := hs.to_subtype
apply toFinite
#align set.finite.image Set.Finite.image
theorem finite_range (f : ι → α) [Finite ι] : (range f).Finite :=
toFinite _
#align set.finite_range Set.finite_range
lemma Finite.of_surjOn {s : Set α} {t : Set β} (f : α → β) (hf : SurjOn f s t) (hs : s.Finite) :
t.Finite := (hs.image _).subset hf
theorem Finite.dependent_image {s : Set α} (hs : s.Finite) (F : ∀ i ∈ s, β) :
{y : β | ∃ x hx, F x hx = y}.Finite := by
have := hs.to_subtype
simpa [range] using finite_range fun x : s => F x x.2
#align set.finite.dependent_image Set.Finite.dependent_image
theorem Finite.map {α β} {s : Set α} : ∀ f : α → β, s.Finite → (f <$> s).Finite :=
Finite.image
#align set.finite.map Set.Finite.map
theorem Finite.of_finite_image {s : Set α} {f : α → β} (h : (f '' s).Finite) (hi : Set.InjOn f s) :
s.Finite :=
have := h.to_subtype
.of_injective _ hi.bijOn_image.bijective.injective
#align set.finite.of_finite_image Set.Finite.of_finite_image
section preimage
variable {f : α → β} {s : Set β}
theorem finite_of_finite_preimage (h : (f ⁻¹' s).Finite) (hs : s ⊆ range f) : s.Finite := by
rw [← image_preimage_eq_of_subset hs]
exact Finite.image f h
#align set.finite_of_finite_preimage Set.finite_of_finite_preimage
theorem Finite.of_preimage (h : (f ⁻¹' s).Finite) (hf : Surjective f) : s.Finite :=
hf.image_preimage s ▸ h.image _
#align set.finite.of_preimage Set.Finite.of_preimage
theorem Finite.preimage (I : Set.InjOn f (f ⁻¹' s)) (h : s.Finite) : (f ⁻¹' s).Finite :=
(h.subset (image_preimage_subset f s)).of_finite_image I
#align set.finite.preimage Set.Finite.preimage
protected lemma Infinite.preimage (hs : s.Infinite) (hf : s ⊆ range f) : (f ⁻¹' s).Infinite :=
fun h ↦ hs <| finite_of_finite_preimage h hf
lemma Infinite.preimage' (hs : (s ∩ range f).Infinite) : (f ⁻¹' s).Infinite :=
(hs.preimage <| inter_subset_right _ _).mono <| preimage_mono <| inter_subset_left _ _
theorem Finite.preimage_embedding {s : Set β} (f : α ↪ β) (h : s.Finite) : (f ⁻¹' s).Finite :=
h.preimage fun _ _ _ _ h' => f.injective h'
#align set.finite.preimage_embedding Set.Finite.preimage_embedding
end preimage
theorem finite_lt_nat (n : ℕ) : Set.Finite { i | i < n } :=
toFinite _
#align set.finite_lt_nat Set.finite_lt_nat
theorem finite_le_nat (n : ℕ) : Set.Finite { i | i ≤ n } :=
toFinite _
#align set.finite_le_nat Set.finite_le_nat
section MapsTo
variable {s : Set α} {f : α → α} (hs : s.Finite) (hm : MapsTo f s s)
theorem Finite.surjOn_iff_bijOn_of_mapsTo : SurjOn f s s ↔ BijOn f s s := by
refine ⟨fun h ↦ ⟨hm, ?_, h⟩, BijOn.surjOn⟩
have : Finite s := finite_coe_iff.mpr hs
exact hm.restrict_inj.mp (Finite.injective_iff_surjective.mpr <| hm.restrict_surjective_iff.mpr h)
theorem Finite.injOn_iff_bijOn_of_mapsTo : InjOn f s ↔ BijOn f s s := by
refine ⟨fun h ↦ ⟨hm, h, ?_⟩, BijOn.injOn⟩
have : Finite s := finite_coe_iff.mpr hs
exact hm.restrict_surjective_iff.mp (Finite.injective_iff_surjective.mp <| hm.restrict_inj.mpr h)
end MapsTo
section Prod
variable {s : Set α} {t : Set β}
protected theorem Finite.prod (hs : s.Finite) (ht : t.Finite) : (s ×ˢ t : Set (α × β)).Finite := by
have := hs.to_subtype
have := ht.to_subtype
apply toFinite
#align set.finite.prod Set.Finite.prod
theorem Finite.of_prod_left (h : (s ×ˢ t : Set (α × β)).Finite) : t.Nonempty → s.Finite :=
fun ⟨b, hb⟩ => (h.image Prod.fst).subset fun a ha => ⟨(a, b), ⟨ha, hb⟩, rfl⟩
#align set.finite.of_prod_left Set.Finite.of_prod_left
theorem Finite.of_prod_right (h : (s ×ˢ t : Set (α × β)).Finite) : s.Nonempty → t.Finite :=
fun ⟨a, ha⟩ => (h.image Prod.snd).subset fun b hb => ⟨(a, b), ⟨ha, hb⟩, rfl⟩
#align set.finite.of_prod_right Set.Finite.of_prod_right
protected theorem Infinite.prod_left (hs : s.Infinite) (ht : t.Nonempty) : (s ×ˢ t).Infinite :=
fun h => hs <| h.of_prod_left ht
#align set.infinite.prod_left Set.Infinite.prod_left
protected theorem Infinite.prod_right (ht : t.Infinite) (hs : s.Nonempty) : (s ×ˢ t).Infinite :=
fun h => ht <| h.of_prod_right hs
#align set.infinite.prod_right Set.Infinite.prod_right
protected theorem infinite_prod :
(s ×ˢ t).Infinite ↔ s.Infinite ∧ t.Nonempty ∨ t.Infinite ∧ s.Nonempty := by
refine' ⟨fun h => _, _⟩
· simp_rw [Set.Infinite, @and_comm ¬_, ← not_imp]
by_contra!
exact h ((this.1 h.nonempty.snd).prod <| this.2 h.nonempty.fst)
· rintro (h | h)
· exact h.1.prod_left h.2
· exact h.1.prod_right h.2
#align set.infinite_prod Set.infinite_prod
theorem finite_prod : (s ×ˢ t).Finite ↔ (s.Finite ∨ t = ∅) ∧ (t.Finite ∨ s = ∅) := by
simp only [← not_infinite, Set.infinite_prod, not_or, not_and_or, not_nonempty_iff_eq_empty]
#align set.finite_prod Set.finite_prod
protected theorem Finite.offDiag {s : Set α} (hs : s.Finite) : s.offDiag.Finite :=
(hs.prod hs).subset s.offDiag_subset_prod
#align set.finite.off_diag Set.Finite.offDiag
protected theorem Finite.image2 (f : α → β → γ) (hs : s.Finite) (ht : t.Finite) :
(image2 f s t).Finite := by
have := hs.to_subtype
have := ht.to_subtype
apply toFinite
#align set.finite.image2 Set.Finite.image2
end Prod
theorem Finite.seq {f : Set (α → β)} {s : Set α} (hf : f.Finite) (hs : s.Finite) :
(f.seq s).Finite :=
hf.image2 _ hs
#align set.finite.seq Set.Finite.seq
theorem Finite.seq' {α β : Type u} {f : Set (α → β)} {s : Set α} (hf : f.Finite) (hs : s.Finite) :
(f <*> s).Finite :=
hf.seq hs