-
Notifications
You must be signed in to change notification settings - Fork 5
/
Chap8.qmd
2620 lines (2266 loc) · 104 KB
/
Chap8.qmd
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
# Infinite Sets
## 8.1. Equinumerous Sets
Chapter 8 of *HTPI* begins by defining a set $A$ to be *equinumerous* with a set $B$ if there is a function $f : A \to B$ that is one-to-one and onto. As we will see, in Lean we will need to phrase this definition somewhat differently. However, we begin by considering some examples of functions that are one-to-one and onto.
The first example in *HTPI* is a one-to-one, onto function from $\mathbb{Z}^+$ to $\mathbb{Z}$. We will modify this example slightly to make it a function `fnz` from `Nat` to `Int`:
```lean
def fnz (n : Nat) : Int := if 2 ∣ n then ↑(n / 2) else -↑((n + 1) / 2)
```
Note that, to get a result of type `Int`, coercion is necessary. We have specified that the coercion should be done after the computation of either `n / 2` or `(n + 1) / 2`, with that computation being done using natural-number arithmetic. Checking a few values of this functions suggests a simple pattern:
```lean
#eval [fnz 0, fnz 1, fnz 2, fnz 3, fnz 4, fnz 5, fnz 6]
--Answer: [0, -1, 1, -2, 2, -3, 3]
```
Perhaps the easiest way to prove that `fnz` is one-to-one and onto is to define a function that turns out to be its inverse. This time, in order to get the right type for the value of the function, we use the function `Int.toNat` to convert a nonnegative integer to a natural number.
```lean
def fzn (a : Int) : Nat :=
if a ≥ 0 then 2 * Int.toNat a else 2 * Int.toNat (-a) - 1
#eval [fzn 0, fzn (-1), fzn 1, fzn (-2), fzn 2, fzn (-3), fzn 3]
--Answer: [0, 1, 2, 3, 4, 5, 6]
```
To prove that `fzn` is the inverse of `fnz`, we begin by proving lemmas making it easier to compute the values of these functions
```lean
lemma fnz_even (k : Nat) : fnz (2 * k) = ↑k := by
have h1 : 2 ∣ 2 * k := by
apply Exists.intro k
rfl
done
have h2 : fnz (2 * k) = if 2 ∣ 2 * k then ↑(2 * k / 2)
else -↑((2 * k + 1) / 2) := by rfl
rewrite [if_pos h1] at h2 --h2 : fnz (2 * k) = ↑(2 * k / 2)
have h3 : 0 < 2 := by linarith
rewrite [Nat.mul_div_cancel_left k h3] at h2
show fnz (2 * k) = ↑k from h2
done
lemma fnz_odd (k : Nat) : fnz (2 * k + 1) = -↑(k + 1) := sorry
lemma fzn_nat (k : Nat) : fzn ↑k = 2 * k := by rfl
lemma fzn_neg_succ_nat (k : Nat) : fzn (-↑(k + 1)) = 2 * k + 1 := by rfl
```
Using these lemmas and reasoning by cases, it is straightforward to prove lemmas confirming that the composition of these functions, in either order, yields the identity function. The cases for the first lemma are based on an exercise from Section 6.1.
```lean
lemma fzn_fnz : fzn ∘ fnz = id := by
apply funext --Goal : ∀ (x : Nat), (fzn ∘ fnz) x = id x
fix n : Nat
rewrite [comp_def] --Goal : fzn (fnz n) = id n
have h1 : nat_even n ∨ nat_odd n := Exercise_6_1_16a1 n
by_cases on h1
· -- Case 1. h1 : nat_even n
obtain (k : Nat) (h2 : n = 2 * k) from h1
rewrite [h2, fnz_even, fzn_nat]
rfl
done
· -- Case 2. h1 : nat_odd n
obtain (k : Nat) (h2 : n = 2 * k + 1) from h1
rewrite [h2, fnz_odd, fzn_neg_succ_nat]
rfl
done
done
lemma fnz_fzn : fnz ∘ fzn = id := sorry
```
By theorems from Chapter 5, it follows that both `fnz` and `fzn` are one-to-one and onto.
```lean
lemma fzn_one_one : one_to_one fzn := Theorem_5_3_3_1 fzn fnz fnz_fzn
lemma fzn_onto : onto fzn := Theorem_5_3_3_2 fzn fnz fzn_fnz
lemma fnz_one_one : one_to_one fnz := Theorem_5_3_3_1 fnz fzn fzn_fnz
lemma fnz_onto : onto fnz := Theorem_5_3_3_2 fnz fzn fnz_fzn
```
We'll give one more example: a one-to-one, onto function `fnnn` from `Nat × Nat` to `Nat`, whose definition is modeled on a function from $\mathbb{Z}^+ \times \mathbb{Z}^+$ to $\mathbb{Z}^+$ in *HTPI*. The definition of `fnnn` will use numbers of the form `k * (k + 1) / 2`. These numbers are sometimes called *triangular numbers*, because they count the number of objects in a triangular grid with `k` rows.
```lean
def tri (k : Nat) : Nat := k * (k + 1) / 2
def fnnn (p : Nat × Nat) : Nat := tri (p.1 + p.2) + p.1
lemma fnnn_def (a b : Nat) : fnnn (a, b) = tri (a + b) + a := by rfl
#eval [fnnn (0, 0), fnnn (0, 1), fnnn (1, 0), fnnn (0, 2), fnnn (1, 1)]
--Answer: [0, 1, 2, 3, 4]
```
Two simple lemmas about `tri` will help us prove the important properties of `fnnn`:
```lean
lemma tri_step (k : Nat) : tri (k + 1) = tri k + k + 1 := sorry
lemma tri_incr {j k : Nat} (h1 : j ≤ k) : tri j ≤ tri k := sorry
lemma le_of_fnnn_eq {a1 b1 a2 b2 : Nat}
(h1 : fnnn (a1, b1) = fnnn (a2, b2)) : a1 + b1 ≤ a2 + b2 := by
by_contra h2
have h3 : a2 + b2 + 1 ≤ a1 + b1 := by linarith
have h4 : fnnn (a2, b2) < fnnn (a1, b1) :=
calc fnnn (a2, b2)
_ = tri (a2 + b2) + a2 := by rfl
_ < tri (a2 + b2) + (a2 + b2) + 1 := by linarith
_ = tri (a2 + b2 + 1) := (tri_step _).symm
_ ≤ tri (a1 + b1) := tri_incr h3
_ ≤ tri (a1 + b1) + a1 := by linarith
_ = fnnn (a1, b1) := by rfl
linarith
done
lemma fnnn_one_one : one_to_one fnnn := by
fix (a1, b1) : Nat × Nat
fix (a2, b2) : Nat × Nat
assume h1 : fnnn (a1, b1) = fnnn (a2, b2) --Goal : (a1, b1) = (a2, b2)
have h2 : a1 + b1 ≤ a2 + b2 := le_of_fnnn_eq h1
have h3 : a2 + b2 ≤ a1 + b1 := le_of_fnnn_eq h1.symm
have h4 : a1 + b1 = a2 + b2 := by linarith
rewrite [fnnn_def, fnnn_def, h4] at h1
--h1 : tri (a2 + b2) + a1 = tri (a2 + b2) + a2
have h6 : a1 = a2 := Nat.add_left_cancel h1
rewrite [h6] at h4 --h4 : a2 + b1 = a2 + b2
have h7 : b1 = b2 := Nat.add_left_cancel h4
rewrite [h6, h7]
rfl
done
lemma fnnn_onto : onto fnnn := by
define --Goal : ∀ (y : Nat), ∃ (x : Nat × Nat), fnnn x = y
by_induc
· -- Base Case
apply Exists.intro (0, 0)
rfl
done
· -- Induction Step
fix n : Nat
assume ih : ∃ (x : Nat × Nat), fnnn x = n
obtain ((a, b) : Nat × Nat) (h1 : fnnn (a, b) = n) from ih
by_cases h2 : b = 0
· -- Case 1. h2 : b = 0
apply Exists.intro (0, a + 1)
show fnnn (0, a + 1) = n + 1 from
calc fnnn (0, a + 1)
_ = tri (0 + (a + 1)) + 0 := by rfl
_ = tri (a + 1) := by ring
_ = tri a + a + 1 := tri_step a
_ = tri (a + 0) + a + 1 := by ring
_ = fnnn (a, b) + 1 := by rw [h2, fnnn_def]
_ = n + 1 := by rw [h1]
done
· -- Case 2. h2 : b ≠ 0
obtain (k : Nat) (h3 : b = k + 1) from
exists_eq_add_one_of_ne_zero h2
apply Exists.intro (a + 1, k)
show fnnn (a + 1, k) = n + 1 from
calc fnnn (a + 1, k)
_ = tri (a + 1 + k) + (a + 1) := by rfl
_ = tri (a + (k + 1)) + a + 1 := by ring
_ = tri (a + b) + a + 1 := by rw [h3]
_ = fnnn (a, b) + 1 := by rfl
_ = n + 1 := by rw [h1]
done
done
done
```
Despite these successes with one-to-one, onto functions, we will use a definition of "equinumerous" in Lean that is different from the definition in *HTPI*. There are two reasons for this change. First of all, the domain of a function in Lean must be a *type*, but we want to be able to talk about *sets* being equinumerous. Secondly, Lean expects functions to be *computable*; it regards the definition of a function as an algorithm for computing the value of the function on any input. This restriction would cause problems with some of our proofs. While there are ways to overcome these difficulties, they would introduce complications that we can avoid by using a different approach.
Suppose `U` and `V` are types, and we have sets `A : Set U` and `B : Set V`. We will define `A` to be equinumerous with `B` if there is a relation `R` from `U` to `V` that defines a one-to-one correspondence between the elements of `A` and `B`. To formulate this precisely, suppose that `R` has type `Rel U V`. We will place three requirements on `R`. First, we require that the relation `R` should hold only between elements of `A` and `B`. We say in this case that `R` is a *relation within `A` and `B`*:
```lean
def rel_within {U V : Type} (R : Rel U V) (A : Set U) (B : Set V) : Prop :=
∀ ⦃x : U⦄ ⦃y : V⦄, R x y → x ∈ A ∧ y ∈ B
```
Notice that in this definition, we have used the same double braces for the quantified variables `x` and `y` that were used in the definition of "subset." This means that `x` and `y` are implicit arguments, and therefore if we have `h1 : rel_within R A B` and `h2 : R a b`, then `h1 h2` is a proof of `a ∈ A ∧ b ∈ B`. There is no need to specify that `a` and `b` are the values to be assigned to `x` and `y`; Lean will figure that out for itself. (To type the double braces `⦃` and `⦄`, type `\{{` and `\}}`. There were cases in previous chapters where it would have been appropriate to use such implicit arguments, but we chose not to do so to avoid confusion. But by now you should be comfortable enough with Lean that you won't be confused by this new complication.)
Next, we require that every element of `A` is related by `R` to exactly one thing. We say in this case that `R` is *functional on `A`*:
```lean
def fcnl_on {U V : Type} (R : Rel U V) (A : Set U) : Prop :=
∀ ⦃x : U⦄, x ∈ A → ∃! (y : V), R x y
```
Finally, we impose the same requirement in the other direction: for every element of `B`, exactly one thing should be related to it by `R`. We can express this by saying that the inverse of `R` is functional on `B`. In Chapter 4, we defined the inverse of a set of ordered pairs, but we can easily convert this to an operation on relations:
```lean
def invRel {U V : Type} (R : Rel U V) : Rel V U :=
RelFromExt (inv (extension R))
lemma invRel_def {U V : Type} (R : Rel U V) (u : U) (v : V) :
invRel R v u ↔ R u v := by rfl
```
We will call `R` a *matching from `A` to `B`* if it meets the three requirements above:
```lean
def matching {U V : Type} (R : Rel U V) (A : Set U) (B : Set V) : Prop :=
rel_within R A B ∧ fcnl_on R A ∧ fcnl_on (invRel R) B
```
Finally, we say that *`A` is equinumerous with `B`* if there is a matching from `A` to `B`, and, as in *HTPI* we introduce the notation `A ∼ B` to indicate that `A` is equinumerous with `B` (to enter the symbol `∼`, type `\sim` or `\~`).
```lean
def equinum {U V : Type} (A : Set U) (B : Set V) : Prop :=
∃ (R : Rel U V), matching R A B
notation:50 A:50 " ∼ " B:50 => equinum A B
```
Can the examples at the beginning of this section be used to establish that `Int ∼ Nat` and `Nat × Nat ∼ Nat`? Not quite, because `Int`, `Nat`, and `Nat × Nat` are types, not sets. We must talk about the sets of all objects of those types, not the types themselves, so we introduce another definition.
```lean
def Univ (U : Type) : Set U := {x : U | True}
lemma elt_Univ {U : Type} (u : U) :
u ∈ Univ U := by trivial
```
For any type `U`, `Univ U` is the set of all objects of type `U`; we might call it the *universal set* for the type `U`. Now we can use the functions defined earlier to prove that `Univ Int ∼ Univ Nat` and `Univ (Nat × Nat) ∼ Univ Nat`. The do this, we must convert the functions into relations and prove that those relations are matchings. The conversion can be done with the following function.
```lean
def RelWithinFromFunc {U V : Type} (f : U → V) (A : Set U)
(x : U) (y : V) : Prop := x ∈ A ∧ f x = y
```
This definition says that if we have `f : U → V` and `A : Set U`, then `RelWithinFromFunc f A` is a relation from `U` to `V` that relates any `x` that is an element of `A` to `f x`.
We will say that a function is one-to-one on a set `A` if it satisfies the definition of one-to-one when applied to elements of `A`:
```lean
def one_one_on {U V : Type} (f : U → V) (A : Set U) : Prop :=
∀ ⦃x1 x2 : U⦄, x1 ∈ A → x2 ∈ A → f x1 = f x2 → x1 = x2
```
With all of this preparation, we can now prove that if `f` is one-to-one on `A`, then `A` is equinumerous with its image under `f`.
```lean
theorem equinum_image {U V : Type} {A : Set U} {B : Set V} {f : U → V}
(h1 : one_one_on f A) (h2 : image f A = B) : A ∼ B := by
rewrite [←h2]
define --Goal : ∃ (R : Rel U V), matching R A (image f A)
set R : Rel U V := RelWithinFromFunc f A
apply Exists.intro R
define --Goal : rel_within R A (image f A) ∧
--fcnl_on R A ∧ fcnl_on (invRel R) (image f A)
apply And.intro
· -- Proof of rel_within
define --Goal : ∀ ⦃x : U⦄ ⦃y : V⦄, R x y → x ∈ A ∧ y ∈ image f A
fix x : U; fix y : V
assume h3 : R x y --Goal : x ∈ A ∧ y ∈ image f A
define at h3 --h3 : x ∈ A ∧ f x = y
apply And.intro h3.left
define
show ∃ x ∈ A, f x = y from Exists.intro x h3
done
· -- Proofs of fcnl_ons
apply And.intro
· -- Proof of fcnl_on R A
define --Goal : ∀ ⦃x : U⦄, x ∈ A → ∃! (y : V), R x y
fix x : U
assume h3 : x ∈ A
exists_unique
· -- Existence
apply Exists.intro (f x)
define --Goal : x ∈ A ∧ f x = f x
apply And.intro h3
rfl
done
· -- Uniqueness
fix y1 : V; fix y2 : V
assume h4 : R x y1
assume h5 : R x y2 --Goal : y1 = y2
define at h4; define at h5
--h4 : x ∈ A ∧ f x = y1; h5 : x ∈ A ∧ f x = y2
rewrite [h4.right] at h5
show y1 = y2 from h5.right
done
done
· -- Proof of fcnl_on (invRel R) (image f A)
define --Goal : ∀ ⦃x : V⦄, x ∈ image f A → ∃! (y : U), invRel R x y
fix y : V
assume h3 : y ∈ image f A
obtain (x : U) (h4 : x ∈ A ∧ f x = y) from h3
exists_unique
· -- Existence
apply Exists.intro x
define
show x ∈ A ∧ f x = y from h4
done
· -- Uniqueness
fix x1 : U; fix x2 : U
assume h5 : invRel R y x1
assume h6 : invRel R y x2
define at h5; define at h6
--h5 : x1 ∈ A ∧ f x1 = y; h6 : x2 ∈ A ∧ f x2 = y
rewrite [←h6.right] at h5
show x1 = x2 from h1 h5.left h6.left h5.right
done
done
done
done
```
To apply this result to the functions introduced at the beginning of this section, we will want to use `Univ U` for the set `A` in the theorem `equinum_image`:
```lean
lemma one_one_on_of_one_one {U V : Type} {f : U → V}
(h : one_to_one f) (A : Set U) : one_one_on f A := sorry
theorem equinum_Univ {U V : Type} {f : U → V}
(h1 : one_to_one f) (h2 : onto f) : Univ U ∼ Univ V := by
have h3 : image f (Univ U) = Univ V := by
apply Set.ext
fix v : V
apply Iff.intro
· -- (→)
assume h3 : v ∈ image f (Univ U)
show v ∈ Univ V from elt_Univ v
done
· -- (←)
assume h3 : v ∈ Univ V
obtain (u : U) (h4 : f u = v) from h2 v
apply Exists.intro u
apply And.intro _ h4
show u ∈ Univ U from elt_Univ u
done
done
show Univ U ∼ Univ V from
equinum_image (one_one_on_of_one_one h1 (Univ U)) h3
done
theorem Z_equinum_N : Univ Int ∼ Univ Nat :=
equinum_Univ fzn_one_one fzn_onto
theorem NxN_equinum_N : Univ (Nat × Nat) ∼ Univ Nat :=
equinum_Univ fnnn_one_one fnnn_onto
```
Theorem 8.1.3 in *HTPI* shows that `∼` is reflexive, symmetric, and transitive. We'll prove the three parts of this theorem separately. To prove that `∼` is reflexive, we use the identity function.
```lean
lemma id_one_one_on {U : Type} (A : Set U) : one_one_on id A := sorry
lemma image_id {U : Type} (A : Set U) : image id A = A := sorry
theorem Theorem_8_1_3_1 {U : Type} (A : Set U) : A ∼ A :=
equinum_image (id_one_one_on A) (image_id A)
```
For symmetry, we show that the inverse of a matching is also a matching.
```lean
lemma inv_inv {U V : Type} (R : Rel U V) : invRel (invRel R) = R := by rfl
lemma inv_match {U V : Type} {R : Rel U V} {A : Set U} {B : Set V}
(h : matching R A B) : matching (invRel R) B A := by
define --Goal : rel_within (invRel R) B A ∧
--fcnl_on (invRel R) B ∧ fcnl_on (invRel (invRel R)) A
define at h --h : rel_within R A B ∧ fcnl_on R A ∧ fcnl_on (invRel R) B
apply And.intro
· -- Proof that rel_within (invRel R) B A
define --Goal : ∀ ⦃x : V⦄ ⦃y : U⦄, invRel R x y → x ∈ B ∧ y ∈ A
fix y : V; fix x : U
assume h1 : invRel R y x
define at h1 --h1 : R x y
have h2 : x ∈ A ∧ y ∈ B := h.left h1
show y ∈ B ∧ x ∈ A from And.intro h2.right h2.left
done
· -- proof that fcnl_on (inv R) B ∧ fcnl_on (inv (inv R)) A
rewrite [inv_inv]
show fcnl_on (invRel R) B ∧ fcnl_on R A from
And.intro h.right.right h.right.left
done
done
theorem Theorem_8_1_3_2 {U V : Type} {A : Set U} {B : Set V}
(h : A ∼ B) : B ∼ A := by
obtain (R : Rel U V) (h1 : matching R A B) from h
apply Exists.intro (invRel R)
show matching (invRel R) B A from inv_match h1
done
```
The proof of transitivity is a bit more involved. In this proof, as well as some later proofs, we find it useful to separate out the existence and uniqueness parts of the definition of `fcnl_on`:
```lean
lemma fcnl_exists {U V : Type} {R : Rel U V} {A : Set U} {x : U}
(h1 : fcnl_on R A) (h2 : x ∈ A) : ∃ (y : V), R x y := by
define at h1
obtain (y : V) (h3 : R x y)
(h4 : ∀ (y_1 y_2 : V), R x y_1 → R x y_2 → y_1 = y_2) from h1 h2
show ∃ (y : V), R x y from Exists.intro y h3
done
lemma fcnl_unique {U V : Type}
{R : Rel U V} {A : Set U} {x : U} {y1 y2 : V} (h1 : fcnl_on R A)
(h2 : x ∈ A) (h3 : R x y1) (h4 : R x y2) : y1 = y2 := by
define at h1
obtain (z : V) (h5 : R x z)
(h6 : ∀ (y_1 y_2 : V), R x y_1 → R x y_2 → y_1 = y_2) from h1 h2
show y1 = y2 from h6 y1 y2 h3 h4
done
```
To prove transitivity, we will show that a composition of matchings is a matching. Once again we must convert our definition of composition of sets of ordered pairs into an operation on relations. A few preliminary lemmas help with the proof.
```lean
def compRel {U V W : Type} (S : Rel V W) (R : Rel U V) : Rel U W :=
RelFromExt (comp (extension S) (extension R))
lemma compRel_def {U V W : Type}
(S : Rel V W) (R : Rel U V) (u : U) (w : W) :
compRel S R u w ↔ ∃ (x : V), R u x ∧ S x w := by rfl
lemma inv_comp {U V W : Type} (R : Rel U V) (S : Rel V W) :
invRel (compRel S R) = compRel (invRel R) (invRel S) :=
calc invRel (compRel S R)
_ = RelFromExt (inv (comp (extension S) (extension R))) := by rfl
_ = RelFromExt (comp (inv (extension R)) (inv (extension S))) := by
rw [Theorem_4_2_5_5]
_ = compRel (invRel R) (invRel S) := by rfl
lemma comp_fcnl {U V W : Type} {R : Rel U V} {S : Rel V W}
{A : Set U} {B : Set V} {C : Set W} (h1 : matching R A B)
(h2 : matching S B C) : fcnl_on (compRel S R) A := by
define; define at h1; define at h2
fix a : U
assume h3 : a ∈ A
obtain (b : V) (h4 : R a b) from fcnl_exists h1.right.left h3
have h5 : a ∈ A ∧ b ∈ B := h1.left h4
obtain (c : W) (h6 : S b c) from fcnl_exists h2.right.left h5.right
exists_unique
· -- Existence
apply Exists.intro c
rewrite [compRel_def]
show ∃ (x : V), R a x ∧ S x c from Exists.intro b (And.intro h4 h6)
done
· -- Uniqueness
fix c1 : W; fix c2 : W
assume h7 : compRel S R a c1
assume h8 : compRel S R a c2 --Goal : c1 = c2
rewrite [compRel_def] at h7
rewrite [compRel_def] at h8
obtain (b1 : V) (h9 : R a b1 ∧ S b1 c1) from h7
obtain (b2 : V) (h10 : R a b2 ∧ S b2 c2) from h8
have h11 : b1 = b := fcnl_unique h1.right.left h3 h9.left h4
have h12 : b2 = b := fcnl_unique h1.right.left h3 h10.left h4
rewrite [h11] at h9
rewrite [h12] at h10
show c1 = c2 from
fcnl_unique h2.right.left h5.right h9.right h10.right
done
done
lemma comp_match {U V W : Type} {R : Rel U V} {S : Rel V W}
{A : Set U} {B : Set V} {C : Set W} (h1 : matching R A B)
(h2 : matching S B C) : matching (compRel S R) A C := by
define
apply And.intro
· -- Proof of rel_within (compRel S R) A C
define
fix a : U; fix c : W
assume h3 : compRel S R a c
rewrite [compRel_def] at h3
obtain (b : V) (h4 : R a b ∧ S b c) from h3
have h5 : a ∈ A ∧ b ∈ B := h1.left h4.left
have h6 : b ∈ B ∧ c ∈ C := h2.left h4.right
show a ∈ A ∧ c ∈ C from And.intro h5.left h6.right
done
· -- Proof of fcnl_on statements
apply And.intro
· -- Proof of fcnl_on (compRel S R) A
show fcnl_on (compRel S R) A from comp_fcnl h1 h2
done
· -- Proof of fcnl_on (invRel (compRel S R)) Z
rewrite [inv_comp]
have h3 : matching (invRel R) B A := inv_match h1
have h4 : matching (invRel S) C B := inv_match h2
show fcnl_on (compRel (invRel R) (invRel S)) C from comp_fcnl h4 h3
done
done
done
theorem Theorem_8_1_3_3 {U V W : Type} {A : Set U} {B : Set V} {C : Set W}
(h1 : A ∼ B) (h2 : B ∼ C) : A ∼ C := by
obtain (R : Rel U V) (h3 : matching R A B) from h1
obtain (S : Rel V W) (h4 : matching S B C) from h2
apply Exists.intro (compRel S R)
show matching (compRel S R) A C from comp_match h3 h4
done
```
Now that we have a basic understanding of the concept of equinumerous sets, we can use this concept to make a number of definitions. For any natural number $n$, *HTPI* defines $I_n$ to be the set $\{1, 2, \ldots, n\}$, and then it defines a set to be *finite* if it is equinumerous with $I_n$, for some $n$. In Lean, it is a bit more convenient to use sets of the form $\{0, 1, \ldots, n - 1\}$. With that small change, we can repeat the definitions of finite, denumerable, and countable in *HTPI*.
```lean
def I (n : Nat) : Set Nat := {k : Nat | k < n}
lemma I_def (k n : Nat) : k ∈ I n ↔ k < n := by rfl
def finite {U : Type} (A : Set U) : Prop :=
∃ (n : Nat), I n ∼ A
def denum {U : Type} (A : Set U) : Prop :=
Univ Nat ∼ A
lemma denum_def {U : Type} (A : Set U) : denum A ↔ Univ Nat ∼ A := by rfl
def ctble {U : Type} (A : Set U) : Prop :=
finite A ∨ denum A
```
Theorem 8.1.5 in *HTPI* gives two useful ways to characterize countable sets. The proof of the theorem in *HTPI* uses the fact that every set of natural numbers is countable. *HTPI* gives an intuitive explanation of why this is true, but of course in Lean an intuitive explanation won't do. So before proving a version of Theorem 8.1.5, we sketch a proof that every set of natural numbers is countable.
Suppose `A` has type `Set Nat`. To prove that `A` is countable, we will define a relation `enum A` that "enumerates" the elements of `A` by relating `0` to the smallest element of `A`, `1` to the next element of `A`, `2` to the next, and so on. How do we tell which natural number should be related to any element `n` of `A`? Notice that if `n` is the smallest element of `A`, then there are `0` elements of `A` that are smaller than `n`; if it is second smallest element of `A`, then there is `1` element of `A` that is smaller than `n`; and so on. Thus, `enum A` should relate a natural number `s` to `n` if and only if the number of elements of `A` that are smaller than `n` is `s`. This suggests a plan: First we define a proposition `num_elts_below A n s` saying that the number of elements of `A` that are smaller than `n` is `s`. Then we use this proposition to define the relation `enum A`, and finally we show that `enum A` is a matching that can be used to prove that `A` is countable.
The definition of `num_elts_below` is recursive. The recursive step relates the number of elements of `A` below `n + 1` to the number of elements below `n`. There are two possibilities: either `n ∈ A` and the number of elements below `n + 1` is one larger than the number below `n`, or `n ∉ A` and the two numbers are the same. (This may remind you of the recursion we used to define `num_rp_below` in Chapter 7.)
```lean
def num_elts_below (A : Set Nat) (m s : Nat) : Prop :=
match m with
| 0 => s = 0
| n + 1 => (n ∈ A ∧ 1 ≤ s ∧ num_elts_below A n (s - 1)) ∨
(n ∉ A ∧ num_elts_below A n s)
def enum (A : Set Nat) (s n : Nat) : Prop := n ∈ A ∧ num_elts_below A n s
```
The details of the proof that `enum A` is the required matching are long. We'll skip them here, but you can find them in the HTPI Lean package.
```lean
lemma neb_exists (A : Set Nat) :
∀ (n : Nat), ∃ (s : Nat), num_elts_below A n s := sorry
lemma bdd_subset_nat_match {A : Set Nat} {m s : Nat}
(h1 : ∀ n ∈ A, n < m) (h2 : num_elts_below A m s) :
matching (enum A) (I s) A := sorry
lemma bdd_subset_nat {A : Set Nat} {m s : Nat}
(h1 : ∀ n ∈ A, n < m) (h2 : num_elts_below A m s) :
I s ∼ A := Exists.intro (enum A) (bdd_subset_nat_match h1 h2)
lemma unbdd_subset_nat_match {A : Set Nat}
(h1 : ∀ (m : Nat), ∃ n ∈ A, n ≥ m) :
matching (enum A) (Univ Nat) A := sorry
lemma unbdd_subset_nat {A : Set Nat}
(h1 : ∀ (m : Nat), ∃ n ∈ A, n ≥ m) :
denum A := Exists.intro (enum A) (unbdd_subset_nat_match h1)
lemma subset_nat_ctble (A : Set Nat) : ctble A := by
define --Goal : finite A ∨ denum A
by_cases h1 : ∃ (m : Nat), ∀ n ∈ A, n < m
· -- Case 1. h1 : ∃ (m : Nat), ∀ n ∈ A, n < m
apply Or.inl --Goal : finite A
obtain (m : Nat) (h2 : ∀ n ∈ A, n < m) from h1
obtain (s : Nat) (h3 : num_elts_below A m s) from neb_exists A m
apply Exists.intro s
show I s ∼ A from bdd_subset_nat h2 h3
done
· -- Case 2. h1 : ¬∃ (m : Nat), ∀ n ∈ A, n < m
apply Or.inr --Goal : denum A
push_neg at h1
--This tactic converts h1 to ∀ (m : Nat), ∃ n ∈ A, m ≤ n
show denum A from unbdd_subset_nat h1
done
done
```
As a consequence of our last lemma, we get another characterization of countable sets: a set is countable if and only if it is equinumerous with some subset of the natural numbers:
```lean
lemma ctble_of_equinum_ctble {U V : Type} {A : Set U} {B : Set V}
(h1 : A ∼ B) (h2 : ctble A) : ctble B := sorry
lemma ctble_iff_equinum_set_nat {U : Type} (A : Set U) :
ctble A ↔ ∃ (I : Set Nat), I ∼ A := by
apply Iff.intro
· -- (→)
assume h1 : ctble A
define at h1 --h1 : finite A ∨ denum A
by_cases on h1
· -- Case 1. h1 : finite A
define at h1 --h1 : ∃ (n : Nat), I n ∼ A
obtain (n : Nat) (h2 : I n ∼ A) from h1
show ∃ (I : Set Nat), I ∼ A from Exists.intro (I n) h2
done
· -- Case 2. h1 : denum A
rewrite [denum_def] at h1 --h1 : Univ Nat ∼ A
show ∃ (I : Set Nat), I ∼ A from Exists.intro (Univ Nat) h1
done
done
· -- (←)
assume h1 : ∃ (I : Set Nat), I ∼ A
obtain (I : Set Nat) (h2 : I ∼ A) from h1
have h3 : ctble I := subset_nat_ctble I
show ctble A from ctble_of_equinum_ctble h2 h3
done
done
```
We are now ready to turn to Theorem 8.1.5 in *HTPI*. The theorem gives two statements that are equivalent to the countability of a set $A$. The first involves a function from the natural numbers to $A$ that is onto. In keeping with our approach in this section, we state a similar characterization involving a relation rather than a function.
```lean
def unique_val_on_N {U : Type} (R : Rel Nat U) : Prop :=
∀ ⦃n : Nat⦄ ⦃x1 x2 : U⦄, R n x1 → R n x2 → x1 = x2
def nat_rel_onto {U : Type} (R : Rel Nat U) (A : Set U) : Prop :=
∀ ⦃x : U⦄, x ∈ A → ∃ (n : Nat), R n x
def fcnl_onto_from_nat {U : Type} (R : Rel Nat U) (A : Set U) : Prop :=
unique_val_on_N R ∧ nat_rel_onto R A
```
Intuitively, you might think of `fcnl_onto_from_nat R A` as meaning that the relation `R` defines a function whose domain is a subset of the natural numbers and whose range contains `A`.
The second characterization of the countability of $A$ in Theorem 8.1.5 involves a function from $A$ to the natural numbers that is one-to-one. Once again, we rephrase this in terms of relations. We define `fcnl_one_one_to_nat R A` to mean that `R` defines a function from `A` to the natural numbers that is one-to-one:
```lean
def fcnl_one_one_to_nat {U : Type} (R : Rel U Nat) (A : Set U) : Prop :=
fcnl_on R A ∧ ∀ ⦃x1 x2 : U⦄ ⦃n : Nat⦄,
(x1 ∈ A ∧ R x1 n) → (x2 ∈ A ∧ R x2 n) → x1 = x2
```
Our plan is to prove that if `A` has type `Set U` then the following statements are equivalent:
1. `ctble A`
2. `∃ (R : Rel Nat U), fcnl_onto_from_nat R A`
3. `∃ (R : Rel U Nat), fcnl_one_one_to_nat R A`
As in *HTPI*, we will do this by proving 1 → 2 → 3 → 1. Here is the proof of 1 → 2.
```lean
theorem Theorem_8_1_5_1_to_2 {U : Type} {A : Set U} (h1 : ctble A) :
∃ (R : Rel Nat U), fcnl_onto_from_nat R A := by
rewrite [ctble_iff_equinum_set_nat] at h1
obtain (I : Set Nat) (h2 : I ∼ A) from h1
obtain (R : Rel Nat U) (h3 : matching R I A) from h2
define at h3
--h3 : rel_within R I A ∧ fcnl_on R I ∧ fcnl_on (invRel R) A
apply Exists.intro R
define --Goal : unique_val_on_N R ∧ nat_rel_onto R A
apply And.intro
· -- Proof of unique_val_on_N R
define
fix n : Nat; fix x1 : U; fix x2 : U
assume h4 : R n x1
assume h5 : R n x2 --Goal : x1 = x2
have h6 : n ∈ I ∧ x1 ∈ A := h3.left h4
show x1 = x2 from fcnl_unique h3.right.left h6.left h4 h5
done
· -- Proof of nat_rel_onto R A
define
fix x : U
assume h4 : x ∈ A --Goal : ∃ (n : Nat), R n x
show ∃ (n : Nat), R n x from fcnl_exists h3.right.right h4
done
done
```
For the proof of 2 → 3, suppose we have `A : Set U` and `S : Rel Nat U`, and the statement `fcnl_onto_from_nat S A` is true. We need to come up with a relation `R : Rel U Nat` for which we can prove `fcnl_one_one_to_nat R A`. You might be tempted to try `R = invRel S`, but there is a problem with this choice: if `x ∈ A`, there might be multiple natural numbers `n` such that `S n x` holds, but we must make sure that there is only one `n` for which `R x n` holds. Our solution to this problem will be to define `R x n` to mean that `n` is the smallest natural number for which `S n x` holds. (The proof in *HTPI* uses a similar idea.) The well-ordering principle guarantees that there always is such a smallest element.
```lean
def least_rel_to {U : Type} (S : Rel Nat U) (x : U) (n : Nat) : Prop :=
S n x ∧ ∀ (m : Nat), S m x → n ≤ m
lemma exists_least_rel_to {U : Type} {S : Rel Nat U} {x : U}
(h1 : ∃ (n : Nat), S n x) : ∃ (n : Nat), least_rel_to S x n := by
set W : Set Nat := {n : Nat | S n x}
have h2 : ∃ (n : Nat), n ∈ W := h1
show ∃ (n : Nat), least_rel_to S x n from well_ord_princ W h2
done
theorem Theorem_8_1_5_2_to_3 {U : Type} {A : Set U}
(h1 : ∃ (R : Rel Nat U), fcnl_onto_from_nat R A) :
∃ (R : Rel U Nat), fcnl_one_one_to_nat R A := by
obtain (S : Rel Nat U) (h2 : fcnl_onto_from_nat S A) from h1
define at h2 --h2 : unique_val_on_N S ∧ nat_rel_onto S A
set R : Rel U Nat := least_rel_to S
apply Exists.intro R
define
apply And.intro
· -- Proof of fcnl_on R A
define
fix x : U
assume h4 : x ∈ A --Goal : ∃! (y : Nat), R x y
exists_unique
· -- Existence
have h5 : ∃ (n : Nat), S n x := h2.right h4
show ∃ (n : Nat), R x n from exists_least_rel_to h5
done
· -- Uniqueness
fix n1 : Nat; fix n2 : Nat
assume h5 : R x n1
assume h6 : R x n2 --Goal : n1 = n2
define at h5 --h5 : S n1 x ∧ ∀ (m : Nat), S m x → n1 ≤ m
define at h6 --h6 : S n2 x ∧ ∀ (m : Nat), S m x → n2 ≤ m
have h7 : n1 ≤ n2 := h5.right n2 h6.left
have h8 : n2 ≤ n1 := h6.right n1 h5.left
linarith
done
done
· -- Proof of one-to-one
fix x1 : U; fix x2 : U; fix n : Nat
assume h4 : x1 ∈ A ∧ R x1 n
assume h5 : x2 ∈ A ∧ R x2 n
have h6 : R x1 n := h4.right
have h7 : R x2 n := h5.right
define at h6 --h6 : S n x1 ∧ ∀ (m : Nat), S m x1 → n ≤ m
define at h7 --h7 : S n x2 ∧ ∀ (m : Nat), S m x2 → n ≤ m
show x1 = x2 from h2.left h6.left h7.left
done
done
```
Finally, for the proof of 3 → 1, suppose we have `A : Set U`, `S : Rel U Nat`, and `fcnl_one_one_to_nat S A` holds. Our plan is to restrict `S` to elements of `A` and then show that the inverse of the resulting relation is a matching from some set of natural numbers to `A`. By `ctble_iff_equinum_set_nat`, this implies that `A` is countable.
```lean
def restrict_to {U V : Type} (S : Rel U V) (A : Set U)
(x : U) (y : V) : Prop := x ∈ A ∧ S x y
theorem Theorem_8_1_5_3_to_1 {U : Type} {A : Set U}
(h1 : ∃ (R : Rel U Nat), fcnl_one_one_to_nat R A) :
ctble A := by
obtain (S : Rel U Nat) (h2 : fcnl_one_one_to_nat S A) from h1
define at h2 --h2 : fcnl_on S A ∧ ∀ ⦃x1 x2 : U⦄ ⦃n : Nat⦄,
--x1 ∈ A ∧ S x1 n → x2 ∈ A ∧ S x2 n → x1 = x2
rewrite [ctble_iff_equinum_set_nat] --Goal : ∃ (I : Set Nat), I ∼ A
set R : Rel Nat U := invRel (restrict_to S A)
set I : Set Nat := {n : Nat | ∃ (x : U), R n x}
apply Exists.intro I
define --Goal : ∃ (R : Rel Nat U), matching R I A
apply Exists.intro R
define
apply And.intro
· -- Proof of rel_within R I A
define
fix n : Nat; fix x : U
assume h3 : R n x --Goal : n ∈ I ∧ x ∈ A
apply And.intro
· -- Proof that n ∈ I
define --Goal : ∃ (x : U), R n x
show ∃ (x : U), R n x from Exists.intro x h3
done
· -- Proof that x ∈ A
define at h3 --h3 : x ∈ A ∧ S x n
show x ∈ A from h3.left
done
done
· -- Proofs of fcnl_ons
apply And.intro
· -- Proof of fcnl_on R I
define
fix n : Nat
assume h3 : n ∈ I --Goal : ∃! (y : U), R n y
exists_unique
· -- Existence
define at h3 --h3 : ∃ (x : U), R n x
show ∃ (y : U), R n y from h3
done
· -- Uniqueness
fix x1 : U; fix x2 : U
assume h4 : R n x1
assume h5 : R n x2
define at h4 --h4 : x1 ∈ A ∧ S x1 n;
define at h5 --h5 : x2 ∈ A ∧ S x2 n
show x1 = x2 from h2.right h4 h5
done
done
· -- Proof of fcnl_on (invRel R) A
define
fix x : U
assume h3 : x ∈ A --Goal : ∃! (y : Nat), invRel R x y
exists_unique
· -- Existence
obtain (y : Nat) (h4 : S x y) from fcnl_exists h2.left h3
apply Exists.intro y
define
show x ∈ A ∧ S x y from And.intro h3 h4
done
· -- Uniqueness
fix n1 : Nat; fix n2 : Nat
assume h4 : invRel R x n1
assume h5 : invRel R x n2 --Goal : n1 = n2
define at h4 --h4 : x ∈ A ∧ S x n1
define at h5 --h5 : x ∈ A ∧ S x n2
show n1 = n2 from fcnl_unique h2.left h3 h4.right h5.right
done
done
done
done
```
We now know that statements 1--3 are equivalent, which means that statements 2 and 3 can be thought of as alternative ways to think about countability:
```lean
theorem Theorem_8_1_5_2 {U : Type} (A : Set U) :
ctble A ↔ ∃ (R : Rel Nat U), fcnl_onto_from_nat R A := by
apply Iff.intro
· -- (→)
assume h1 : ctble A
show ∃ (R : Rel Nat U), fcnl_onto_from_nat R A from
Theorem_8_1_5_1_to_2 h1
done
· -- (←)
assume h1 : ∃ (R : Rel Nat U), fcnl_onto_from_nat R A
have h2 : ∃ (R : Rel U Nat), fcnl_one_one_to_nat R A :=
Theorem_8_1_5_2_to_3 h1
show ctble A from Theorem_8_1_5_3_to_1 h2
done
done
theorem Theorem_8_1_5_3 {U : Type} (A : Set U) :
ctble A ↔ ∃ (R : Rel U Nat), fcnl_one_one_to_nat R A := sorry
```
In the exercises, we ask you to show that countability of a set can be proven using functions of the kind considered in Theorem 8.1.5 of *HTPI*.
We end this section with a proof of Theorem 8.1.6 in *HTPI*, which says that the set of rational numbers is denumerable. Our strategy is to define a one-to-one function from `Rat` (the type of rational numbers) to `Nat`. We will need to know a little bit about the way rational numbers are represented in Lean. If `q` has type `Rat`, then `q.num` is the numerator of `q`, which is an integer, and `q.den` is the denominator, which is a nonzero natural number. The theorem `Rat.ext` says that if two rational numbers have the same numerator and denominator, then they are equal. And we will also use the theorem `Prod.mk.inj`, which says that if two ordered pairs are equal, then their first coordinates are equal, as are their second coordinates.
```lean
def fqn (q : Rat) : Nat := fnnn (fzn q.num, q.den)
lemma fqn_def (q : Rat) : fqn q = fnnn (fzn q.num, q.den) := by rfl
lemma fqn_one_one : one_to_one fqn := by
define
fix q1 : Rat; fix q2 : Rat
assume h1 : fqn q1 = fqn q2
rewrite [fqn_def, fqn_def] at h1
--h1 : fnnn (fzn q1.num, q1.den) = fnnn (fzn q2.num, q2.den)
have h2 : (fzn q1.num, q1.den) = (fzn q2.num, q2.den) :=
fnnn_one_one _ _ h1
have h3 : fzn q1.num = fzn q2.num ∧ q1.den = q2.den :=
Prod.mk.inj h2
have h4 : q1.num = q2.num := fzn_one_one _ _ h3.left
show q1 = q2 from Rat.ext h4 h3.right
done
lemma image_fqn_unbdd :
∀ (m : Nat), ∃ n ∈ image fqn (Univ Rat), n ≥ m := by
fix m : Nat
set n : Nat := fqn ↑m
apply Exists.intro n
apply And.intro
· -- Proof that n ∈ image fqn (Univ Rat)
define
apply Exists.intro ↑m
apply And.intro (elt_Univ (↑m : Rat))
rfl
done
· -- Proof that n ≥ m
show n ≥ m from
calc n
_ = tri (2 * m + 1) + 2 * m := by rfl
_ ≥ m := by linarith
done
done
theorem Theorem_8_1_6 : denum (Univ Rat) := by
set I : Set Nat := image fqn (Univ Rat)
have h1 : Univ Nat ∼ I := unbdd_subset_nat image_fqn_unbdd
have h2 : image fqn (Univ Rat) = I := by rfl
have h3 : Univ Rat ∼ I :=
equinum_image (one_one_on_of_one_one fqn_one_one (Univ Rat)) h2
have h4 : I ∼ Univ Rat := Theorem_8_1_3_2 h3
show denum (Univ Rat) from Theorem_8_1_3_3 h1 h4
done
```
### Exercises
::: {.numex arguments="1"}
```lean
--Hint: Use Exercise_6_1_16a2 from the exercises of Section 6.1
lemma fnz_odd (k : Nat) : fnz (2 * k + 1) = -↑(k + 1) := sorry
```
:::
::: {.numex arguments="2"}
```lean
lemma fnz_fzn : fnz ∘ fzn = id := sorry
```
:::
::: {.numex arguments="3"}
```lean
lemma tri_step (k : Nat) : tri (k + 1) = tri k + k + 1 := sorry
```
:::
::: {.numex arguments="4"}
```lean
lemma tri_incr {j k : Nat} (h1 : j ≤ k) : tri j ≤ tri k := sorry
```
:::
::: {.numex arguments="5"}
```lean
lemma ctble_of_equinum_ctble {U V : Type} {A : Set U} {B : Set V}
(h1 : A ∼ B) (h2 : ctble A) : ctble B := sorry
```
:::
::: {.numex arguments="6"}
```lean
theorem Exercise_8_1_1_b : denum {n : Int | even n} := sorry
```
:::
::: {.mdsk}
:::
The next four exercises use the following definition:
```lean
def Rel_image {U V : Type} (R : Rel U V) (A : Set U) : Set V :=
{y : V | ∃ x ∈ A, R x y}
```
Note that if `R` has type `Rel U V`, then `Rel_image R` has type `Set U → Set V`.
::: {.numex arguments="7"}
```lean
lemma Rel_image_on_power_set {U V : Type} {R : Rel U V}
{A C : Set U} {B : Set V} (h1 : matching R A B) (h2 : C ∈ 𝒫 A) :
Rel_image R C ∈ 𝒫 B := sorry
```
:::
::: {.numex arguments="8"}
```lean
lemma Rel_image_inv {U V : Type} {R : Rel U V}
{A C : Set U} {B : Set V} (h1 : matching R A B) (h2 : C ∈ 𝒫 A) :
Rel_image (invRel R) (Rel_image R C) = C := sorry
```
:::
::: {.numex arguments="9"}
```lean
lemma Rel_image_one_one_on {U V : Type} {R : Rel U V}
{A : Set U} {B : Set V} (h1 : matching R A B) :
one_one_on (Rel_image R) (𝒫 A) := sorry
```
:::
::: {.numex arguments="10"}
```lean
lemma Rel_image_image {U V : Type} {R : Rel U V}
{A : Set U} {B : Set V} (h1 : matching R A B) :
image (Rel_image R) (𝒫 A) = 𝒫 B := sorry
```
:::
::: {.numex arguments="11"}
```lean
--Hint: Use the previous two exercises.
theorem Exercise_8_1_5 {U V : Type} {A : Set U} {B : Set V}
(h1 : A ∼ B) : 𝒫 A ∼ 𝒫 B := sorry
```
:::
::: {.numex arguments="12"}
```lean
theorem Exercise_8_1_17 {U : Type} {A B : Set U}
(h1 : B ⊆ A) (h2 : ctble A) : ctble B := sorry
```
:::
::: {.numex arguments="13"}
```lean
theorem ctble_of_onto_func_from_N {U : Type} {A : Set U} {f : Nat → U}
(h1 : ∀ x ∈ A, ∃ (n : Nat), f n = x) : ctble A := sorry
```
:::
::: {.numex arguments="14"}
```lean
theorem ctble_of_one_one_func_to_N {U : Type} {A : Set U} {f : U → Nat}
(h1 : one_one_on f A) : ctble A := sorry
```
:::
## 8.1½. Debts Paid
It is time to fulfill promises we made in two earlier chapters.