-
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
-
1001
-
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
-
1009
-
1010
-
1011
-
1012
-
1013
-
1014
-
1015
-
1016
-
1017
-
1018
-
1019
-
1020
-
1021
-
1022
-
1023
-
1024
-
1025
-
1026
-
1027
-
1028
-
1029
-
1030
-
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-
1037
-
1038
-
1039
-
1040
-
1041
-
1042
-
1043
-
1044
-
1045
-
1046
-
1047
-
1048
-
1049
-
1050
-
1051
-
1052
-
1053
-
1054
-
1055
-
1056
-
1057
-
1058
-
1059
-
1060
-
1061
-
1062
-
1063
-
1064
-
1065
-
1066
-
1067
-
1068
-
1069
-
1070
-
1071
-
1072
-
1073
-
1074
-
1075
-
1076
-
1077
-
1078
-
1079
-
1080
-
1081
-
1082
-
1083
-
1084
-
1085
-
1086
-
1087
-
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1097
-
1098
-
1099
-
1100
-
1101
-
1102
-
1103
-
1104
-
1105
-
1106
-
1107
-
1108
-
1109
-
1110
-
1111
-
1112
-
1113
-
1114
-
1115
-
1116
-
1117
-
1118
-
1119
-
1120
-
1121
-
1122
-
1123
-
1124
-
1125
-
1126
-
1127
-
1128
-
1129
-
1130
-
1131
-
1132
-
1133
-
1134
-
1135
-
1136
-
1137
-
1138
-
1139
-
1140
-
1141
-
1142
-
1143
-
1144
-
1145
-
1146
-
1147
-
1148
-
1149
-
1150
-
1151
-
1152
-
1153
-
1154
-
1155
-
1156
-
1157
-
1158
-
1159
-
1160
-
1161
-
1162
-
1163
-
1164
-
1165
-
1166
-
1167
-
1168
-
1169
-
1170
-
1171
-
1172
-
1173
-
1174
-
1175
-
1176
-
1177
-
1178
-
1179
-
1180
-
1181
-
1182
-
1183
-
1184
-
1185
-
1186
-
1187
-
1188
-
1189
-
1190
-
1191
-
1192
-
1193
-
1194
-
1195
-
1196
-
1197
-
1198
-
1199
-
1200
-
1201
-
1202
-
1203
-
1204
-
1205
-
1206
-
1207
-
1208
-
1209
-
1210
-
1211
-
1212
-
1213
-
1214
-
1215
-
1216
-
1217
-
1218
-
1219
-
1220
-
1221
-
1222
-
1223
-
1224
-
1225
-
1226
-
1227
-
1228
-
1229
-
1230
-
1231
-
1232
-
1233
-
1234
-
1235
-
1236
-
1237
-
1238
-
1239
-
1240
-
1241
-
1242
-
1243
-
1244
-
1245
-
1246
-
1247
-
1248
-
1249
-
1250
-
1251
-
1252
-
1253
-
1254
-
1255
-
1256
-
1257
-
1258
-
1259
-
1260
-
1261
-
1262
-
1263
-
1264
-
1265
-
1266
-
1267
-
1268
-
1269
-
1270
-
1271
-
1272
-
1273
-
1274
-
1275
-
1276
-
1277
-
1278
-
1279
-
1280
-
1281
-
1282
-
1283
-
1284
-
1285
-
1286
-
1287
-
1288
-
1289
-
1290
-
1291
-
1292
-
1293
-
1294
-
1295
-
1296
-
1297
-
1298
-
1299
-
1300
-
1301
-
1302
-
1303
-
1304
-
1305
-
1306
-
1307
-
1308
-
1309
-
1310
-
1311
-
1312
-
1313
-
1314
-
1315
-
1316
-
1317
-
1318
-
1319
-
1320
-
1321
-
1322
-
1323
-
1324
-
1325
-
1326
-
1327
-
1328
-
1329
-
1330
-
1331
-
1332
-
1333
-
1334
-
1335
-
1336
-
1337
-
1338
-
1339
-
1340
-
1341
-
1342
-
1343
-
1344
-
1345
-
1346
-
1347
-
1348
-
1349
-
1350
-
1351
-
1352
-
1353
-
1354
-
1355
-
1356
-
1357
-
1358
-
1359
-
1360
-
1361
-
1362
-
1363
-
1364
-
1365
-
1366
-
1367
-
1368
-
1369
-
1370
-
1371
-
1372
-
1373
-
1374
-
1375
-
1376
-
1377
-
1378
-
1379
-
1380
-
1381
-
1382
-
1383
-
1384
-
1385
-
1386
-
1387
-
1388
-
1389
-
1390
-
1391
-
1392
-
1393
-
1394
-
1395
-
1396
-
1397
-
1398
-
1399
-
1400
-
1401
-
1402
-
1403
-
1404
-
1405
-
1406
-
1407
-
1408
-
1409
-
1410
-
1411
-
1412
-
1413
-
1414
-
1415
-
1416
-
1417
-
1418
-
1419
-
1420
-
1421
-
1422
-
1423
-
1424
-
1425
-
1426
-
1427
-
1428
-
1429
-
1430
-
1431
-
1432
-
1433
-
1434
-
1435
-
1436
-
1437
-
1438
-
1439
-
1440
-
1441
-
1442
-
1443
-
1444
-
1445
-
1446
-
1447
-
1448
-
1449
-
1450
-
1451
-
1452
-
1453
-
1454
-
1455
-
1456
-
1457
-
1458
-
1459
-
1460
-
1461
-
1462
-
1463
-
1464
-
1465
-
1466
-
1467
-
1468
-
1469
-
1470
-
1471
-
1472
-
1473
-
1474
-
1475
-
1476
-
1477
-
1478
-
1479
-
1480
-
1481
-
1482
-
1483
-
1484
-
1485
-
1486
-
1487
-
1488
-
1489
-
1490
-
1491
-
1492
-
1493
-
1494
-
1495
-
1496
-
1497
-
1498
-
1499
-
1500
-
1501
-
1502
-
1503
-
1504
-
1505
-
1506
-
1507
-
1508
-
1509
-
1510
-
1511
-
1512
-
1513
-
1514
-
1515
-
1516
-
1517
-
1518
-
1519
-
1520
-
1521
-
1522
-
1523
-
1524
-
1525
-
1526
-
1527
-
1528
-
1529
-
1530
-
1531
-
1532
-
1533
-
1534
-
1535
-
1536
-
1537
-
1538
-
1539
-
1540
-
1541
-
1542
-
1543
-
1544
-
1545
-
1546
-
1547
-
1548
-
1549
-
1550
-
1551
-
1552
-
1553
-
1554
-
1555
-
1556
-
1557
-
1558
-
1559
-
1560
-
1561
-
1562
-
1563
-
1564
-
1565
-
1566
-
1567
-
1568
-
1569
-
1570
-
1571
-
1572
-
1573
-
1574
-
1575
-
1576
-
1577
-
1578
-
1579
-
1580
-
1581
-
1582
-
1583
-
1584
-
1585
-
1586
-
1587
-
1588
-
1589
-
1590
-
1591
-
1592
-
1593
-
1594
-
1595
-
1596
-
1597
-
1598
-
1599
-
1600
-
1601
-
1602
-
1603
-
1604
-
1605
-
1606
-
1607
-
1608
-
1609
-
1610
-
1611
-
1612
-
1613
-
1614
-
1615
-
1616
-
1617
-
1618
-
1619
-
1620
-
1621
-
1622
-
1623
-
1624
-
1625
-
1626
-
1627
-
1628
-
1629
-
1630
-
1631
-
1632
-
1633
-
1634
-
1635
-
1636
-
1637
-
1638
-
1639
-
1640
-
1641
-
1642
-
1643
-
1644
-
1645
-
1646
-
1647
-
1648
-
1649
-
1650
-
1651
-
1652
-
1653
-
1654
-
1655
-
1656
-
1657
-
1658
-
1659
-
1660
-
1661
-
1662
-
1663
-
1664
-
1665
-
1666
-
1667
-
1668
-
1669
-
1670
-
1671
-
1672
-
1673
-
1674
-
1675
-
1676
-
1677
-
1678
-
1679
-
1680
-
1681
-
1682
-
1683
-
1684
-
1685
-
1686
-
1687
-
1688
-
1689
-
1690
-
1691
-
1692
-
1693
-
1694
-
1695
-
1696
-
1697
-
1698
-
1699
-
1700
-
1701
-
1702
-
1703
-
1704
-
1705
-
1706
-
1707
-
1708
-
1709
-
1710
-
1711
-
1712
-
1713
-
1714
-
1715
-
1716
-
1717
-
1718
-
1719
-
1720
-
1721
-
1722
-
1723
-
1724
-
1725
-
1726
-
1727
-
1728
-
1729
-
1730
-
1731
-
1732
-
1733
-
1734
-
1735
-
1736
-
1737
-
1738
-
1739
-
1740
-
1741
-
1742
-
1743
-
1744
-
1745
-
1746
-
1747
-
1748
-
1749
-
1750
-
1751
-
1752
-
1753
-
1754
-
1755
-
1756
-
1757
-
1758
-
1759
-
1760
-
1761
-
1762
-
1763
-
1764
-
1765
-
1766
-
1767
-
1768
-
1769
-
1770
-
1771
-
1772
-
1773
-
1774
-
1775
-
1776
-
1777
-
1778
-
1779
-
1780
-
1781
-
1782
-
1783
-
1784
-
1785
-
1786
-
1787
-
1788
-
1789
-
1790
-
1791
-
1792
-
1793
-
1794
-
1795
-
1796
-
1797
-
1798
-
1799
-
1800
-
1801
-
1802
-
1803
-
1804
-
1805
-
1806
-
1807
-
1808
-
1809
-
1810
-
1811
-
1812
-
1813
-
1814
-
1815
-
1816
-
1817
-
1818
-
1819
-
1820
-
1821
-
1822
-
1823
-
1824
-
1825
-
1826
-
1827
-
1828
-
1829
-
1830
-
1831
-
1832
-
1833
-
1834
-
1835
-
1836
-
1837
-
1838
-
1839
-
1840
-
1841
-
1842
-
1843
-
1844
-
1845
-
1846
-
1847
-
1848
-
1849
-
1850
-
1851
-
1852
-
1853
-
1854
-
1855
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="./">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3. Logic — Mathematics in Lean v4.19.0 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b86133f3" />
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" />
<link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" />
<link rel="shortcut icon" href="_static/favicon.ico"/>
<script src="_static/jquery.js?v=5d32c60e"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=7048e04d"></script>
<script src="_static/doctools.js?v=9bcbadda"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="4. Sets and Functions" href="C04_Sets_and_Functions.html" />
<link rel="prev" title="2. Basics" href="C02_Basics.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home">
Mathematics in Lean
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="C01_Introduction.html">1. Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="C02_Basics.html">2. Basics</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">3. Logic</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#implication-and-the-universal-quantifier">3.1. Implication and the Universal Quantifier</a></li>
<li class="toctree-l2"><a class="reference internal" href="#the-existential-quantifier">3.2. The Existential Quantifier</a></li>
<li class="toctree-l2"><a class="reference internal" href="#negation">3.3. Negation</a></li>
<li class="toctree-l2"><a class="reference internal" href="#conjunction-and-iff">3.4. Conjunction and Iff</a></li>
<li class="toctree-l2"><a class="reference internal" href="#disjunction">3.5. Disjunction</a></li>
<li class="toctree-l2"><a class="reference internal" href="#sequences-and-convergence">3.6. Sequences and Convergence</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="C04_Sets_and_Functions.html">4. Sets and Functions</a></li>
<li class="toctree-l1"><a class="reference internal" href="C05_Elementary_Number_Theory.html">5. Elementary Number Theory</a></li>
<li class="toctree-l1"><a class="reference internal" href="C06_Discrete_Mathematics.html">6. Discrete Mathematics</a></li>
<li class="toctree-l1"><a class="reference internal" href="C07_Structures.html">7. Structures</a></li>
<li class="toctree-l1"><a class="reference internal" href="C08_Hierarchies.html">8. Hierarchies</a></li>
<li class="toctree-l1"><a class="reference internal" href="C09_Groups_and_Rings.html">9. Groups and Rings</a></li>
<li class="toctree-l1"><a class="reference internal" href="C10_Linear_Algebra.html">10. Linear algebra</a></li>
<li class="toctree-l1"><a class="reference internal" href="C11_Topology.html">11. Topology</a></li>
<li class="toctree-l1"><a class="reference internal" href="C12_Differential_Calculus.html">12. Differential Calculus</a></li>
<li class="toctree-l1"><a class="reference internal" href="C13_Integration_and_Measure_Theory.html">13. Integration and Measure Theory</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="genindex.html">Index</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Mathematics in Lean</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active"><span class="section-number">3. </span>Logic</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/C03_Logic.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="logic">
<span id="id1"></span><h1><span class="section-number">3. </span>Logic<a class="headerlink" href="#logic" title="Link to this heading"></a></h1>
<p>In the last chapter, we dealt with equations, inequalities,
and basic mathematical statements like
“<span class="math notranslate nohighlight">\(x\)</span> divides <span class="math notranslate nohighlight">\(y\)</span>.”
Complex mathematical statements are built up from
simple ones like these
using logical terms like “and,” “or,” “not,” and
“if … then,” “every,” and “some.”
In this chapter, we show you how to work with statements
that are built up in this way.</p>
<section id="implication-and-the-universal-quantifier">
<span id="id2"></span><h2><span class="section-number">3.1. </span>Implication and the Universal Quantifier<a class="headerlink" href="#implication-and-the-universal-quantifier" title="Link to this heading"></a></h2>
<p>Consider the statement after the <code class="docutils literal notranslate"><span class="pre">#check</span></code>:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span>
</pre></div>
</div>
<p>In words, we would say “for every real number <code class="docutils literal notranslate"><span class="pre">x</span></code>, if <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre">≤</span> <span class="pre">x</span></code> then
the absolute value of <code class="docutils literal notranslate"><span class="pre">x</span></code> equals <code class="docutils literal notranslate"><span class="pre">x</span></code>”.
We can also have more complicated statements like:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span>
</pre></div>
</div>
<p>In words, we would say “for every <code class="docutils literal notranslate"><span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">y</span></code>, and <code class="docutils literal notranslate"><span class="pre">ε</span></code>,
if <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><</span> <span class="pre">ε</span> <span class="pre">≤</span> <span class="pre">1</span></code>, the absolute value of <code class="docutils literal notranslate"><span class="pre">x</span></code> is less than <code class="docutils literal notranslate"><span class="pre">ε</span></code>,
and the absolute value of <code class="docutils literal notranslate"><span class="pre">y</span></code> is less than <code class="docutils literal notranslate"><span class="pre">ε</span></code>,
then the absolute value of <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span></code> is less than <code class="docutils literal notranslate"><span class="pre">ε</span></code>.”
In Lean, in a sequence of implications there are
implicit parentheses grouped to the right.
So the expression above means
“if <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><</span> <span class="pre">ε</span></code> then if <code class="docutils literal notranslate"><span class="pre">ε</span> <span class="pre">≤</span> <span class="pre">1</span></code> then if <code class="docutils literal notranslate"><span class="pre">|x|</span> <span class="pre"><</span> <span class="pre">ε</span></code> …”
As a result, the expression says that all the
assumptions together imply the conclusion.</p>
<p>You have already seen that even though the universal quantifier
in this statement
ranges over objects and the implication arrows introduce hypotheses,
Lean treats the two in very similar ways.
In particular, if you have proved a theorem of that form,
you can apply it to objects and hypotheses in the same way.
We will use as an example the following statement that we will help you to prove a
bit later:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kn">section</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">ha</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span>
<span class="k">#check</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span>
<span class="k">#check</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span>
<span class="k">#check</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="n">ha</span><span class="w"> </span><span class="n">hb</span>
<span class="kd">end</span>
</pre></div>
</div>
<p>You have also already seen that it is common in Lean
to use curly brackets to make quantified variables implicit
when they can be inferred from subsequent hypotheses.
When we do that, we can just apply a lemma to the hypotheses without
mentioning the objects.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kn">section</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">ha</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span>
<span class="k">#check</span><span class="w"> </span><span class="n">my_lemma2</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="n">ha</span><span class="w"> </span><span class="n">hb</span>
<span class="kd">end</span>
</pre></div>
</div>
<p>At this stage, you also know that if you use
the <code class="docutils literal notranslate"><span class="pre">apply</span></code> tactic to apply <code class="docutils literal notranslate"><span class="pre">my_lemma</span></code>
to a goal of the form <code class="docutils literal notranslate"><span class="pre">|a</span> <span class="pre">*</span> <span class="pre">b|</span> <span class="pre"><</span> <span class="pre">δ</span></code>,
you are left with new goals that require you to prove
each of the hypotheses.</p>
<p id="index-0">To prove a statement like this, use the <code class="docutils literal notranslate"><span class="pre">intro</span></code> tactic.
Take a look at what it does in this example:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma3</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">epos</span><span class="w"> </span><span class="n">ele1</span><span class="w"> </span><span class="n">xlt</span><span class="w"> </span><span class="n">ylt</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>We can use any names we want for the universally quantified variables;
they do not have to be <code class="docutils literal notranslate"><span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">y</span></code>, and <code class="docutils literal notranslate"><span class="pre">ε</span></code>.
Notice that we have to introduce the variables
even though they are marked implicit:
making them implicit means that we leave them out when
we write an expression <em>using</em> <code class="docutils literal notranslate"><span class="pre">my_lemma</span></code>,
but they are still an essential part of the statement
that we are proving.
After the <code class="docutils literal notranslate"><span class="pre">intro</span></code> command,
the goal is what it would have been at the start if we
listed all the variables and hypotheses <em>before</em> the colon,
as we did in the last section.
In a moment, we will see why it is sometimes necessary to
introduce variables and hypotheses after the proof begins.</p>
<p>To help you prove the lemma, we will start you off:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma4</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">epos</span><span class="w"> </span><span class="n">ele1</span><span class="w"> </span><span class="n">xlt</span><span class="w"> </span><span class="n">ylt</span>
<span class="w"> </span><span class="k">calc</span>
<span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Finish the proof using the theorems
<code class="docutils literal notranslate"><span class="pre">abs_mul</span></code>, <code class="docutils literal notranslate"><span class="pre">mul_le_mul</span></code>, <code class="docutils literal notranslate"><span class="pre">abs_nonneg</span></code>,
<code class="docutils literal notranslate"><span class="pre">mul_lt_mul_right</span></code>, and <code class="docutils literal notranslate"><span class="pre">one_mul</span></code>.
Remember that you can find theorems like these using
Ctrl-space completion (or Cmd-space completion on a Mac).
Remember also that you can use <code class="docutils literal notranslate"><span class="pre">.mp</span></code> and <code class="docutils literal notranslate"><span class="pre">.mpr</span></code>
or <code class="docutils literal notranslate"><span class="pre">.1</span></code> and <code class="docutils literal notranslate"><span class="pre">.2</span></code> to extract the two directions
of an if-and-only-if statement.</p>
<p>Universal quantifiers are often hidden in definitions,
and Lean will unfold definitions to expose them when necessary.
For example, let’s define two predicates,
<code class="docutils literal notranslate"><span class="pre">FnUb</span> <span class="pre">f</span> <span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">FnLb</span> <span class="pre">f</span> <span class="pre">a</span></code>,
where <code class="docutils literal notranslate"><span class="pre">f</span></code> is a function from the real numbers to the real
numbers and <code class="docutils literal notranslate"><span class="pre">a</span></code> is a real number.
The first says that <code class="docutils literal notranslate"><span class="pre">a</span></code> is an upper bound on the
values of <code class="docutils literal notranslate"><span class="pre">f</span></code>,
and the second says that <code class="docutils literal notranslate"><span class="pre">a</span></code> is a lower bound
on the values of <code class="docutils literal notranslate"><span class="pre">f</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span>
<span class="kd">def</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span>
</pre></div>
</div>
<p id="index-1">In the next example, <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code> is the
function that maps <code class="docutils literal notranslate"><span class="pre">x</span></code> to <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code>. Going from the expression <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code>
to this function is called a lambda abstraction in type theory.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="n">dsimp</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_le_add</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">hfa</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">hgb</span>
</pre></div>
</div>
<p id="index-2">Applying <code class="docutils literal notranslate"><span class="pre">intro</span></code> to the goal <code class="docutils literal notranslate"><span class="pre">FnUb</span> <span class="pre">(fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x)</span> <span class="pre">(a</span> <span class="pre">+</span> <span class="pre">b)</span></code>
forces Lean to unfold the definition of <code class="docutils literal notranslate"><span class="pre">FnUb</span></code>
and introduce <code class="docutils literal notranslate"><span class="pre">x</span></code> for the universal quantifier.
The goal is then <code class="docutils literal notranslate"><span class="pre">(fun</span> <span class="pre">(x</span> <span class="pre">:</span> <span class="pre">ℝ)</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x)</span> <span class="pre">x</span> <span class="pre">≤</span> <span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>.
But applying <code class="docutils literal notranslate"><span class="pre">(fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x)</span></code> to <code class="docutils literal notranslate"><span class="pre">x</span></code> should result in <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code>,
and the <code class="docutils literal notranslate"><span class="pre">dsimp</span></code> command performs that simplification.
(The “d” stands for “definitional.”)
You can delete that command and the proof still works;
Lean would have to perform that contraction anyhow to make
sense of the next <code class="docutils literal notranslate"><span class="pre">apply</span></code>.
The <code class="docutils literal notranslate"><span class="pre">dsimp</span></code> command simply makes the goal more readable
and helps us figure out what to do next.
Another option is to use the <code class="docutils literal notranslate"><span class="pre">change</span></code> tactic
by writing <code class="docutils literal notranslate"><span class="pre">change</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span> <span class="pre">≤</span> <span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>.
This helps make the proof more readable,
and gives you more control over how the goal is transformed.</p>
<p>The rest of the proof is routine.
The last two <code class="docutils literal notranslate"><span class="pre">apply</span></code> commands force Lean to unfold the definitions
of <code class="docutils literal notranslate"><span class="pre">FnUb</span></code> in the hypotheses.
Try carrying out similar proofs of these:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">nnf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nng</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nng</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nna</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Even though we have defined <code class="docutils literal notranslate"><span class="pre">FnUb</span></code> and <code class="docutils literal notranslate"><span class="pre">FnLb</span></code> for functions
from the reals to the reals,
you should recognize that the definitions and proofs are much
more general.
The definitions make sense for functions between any two types
for which there is a notion of order on the codomain.
Checking the type of the theorem <code class="docutils literal notranslate"><span class="pre">add_le_add</span></code> shows that it holds
of any structure that is an “ordered additive commutative monoid”;
the details of what that means don’t matter now,
but it is worth knowing that the natural numbers, integers, rationals,
and real numbers are all instances.
So if we prove the theorem <code class="docutils literal notranslate"><span class="pre">fnUb_add</span></code> at that level of generality,
it will apply in all these instances.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommMonoid</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">PartialOrder</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">IsOrderedCancelAddMonoid</span><span class="w"> </span><span class="n">R</span><span class="o">]</span>
<span class="k">#check</span><span class="w"> </span><span class="n">add_le_add</span>
<span class="kd">def</span><span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">add_le_add</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="n">x</span><span class="o">)</span>
</pre></div>
</div>
<p>You have already seen square brackets like these in
Section <a class="reference internal" href="C02_Basics.html#proving-identities-in-algebraic-structures"><span class="std std-numref">Section 2.2</span></a>,
though we still haven’t explained what they mean.
For concreteness, we will stick to the real numbers
for most of our examples,
but it is worth knowing that Mathlib contains definitions and theorems
that work at a high level of generality.</p>
<p id="index-3">For another example of a hidden universal quantifier,
Mathlib defines a predicate <code class="docutils literal notranslate"><span class="pre">Monotone</span></code>,
which says that a function is nondecreasing in its arguments:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">},</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">@</span><span class="n">h</span>
</pre></div>
</div>
<p>The property <code class="docutils literal notranslate"><span class="pre">Monotone</span> <span class="pre">f</span></code> is defined to be exactly the expression
after the colon. We need to put the <code class="docutils literal notranslate"><span class="pre">@</span></code> symbol before <code class="docutils literal notranslate"><span class="pre">h</span></code> because
if we don’t,
Lean expands the implicit arguments to <code class="docutils literal notranslate"><span class="pre">h</span></code> and inserts placeholders.</p>
<p>Proving statements about monotonicity
involves using <code class="docutils literal notranslate"><span class="pre">intro</span></code> to introduce two variables,
say, <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code>, and the hypothesis <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span></code>.
To <em>use</em> a monotonicity hypothesis,
you can apply it to suitable arguments and hypotheses,
and then apply the resulting expression to the goal.
Or you can apply it to the goal and let Lean help you
work backwards by displaying the remaining hypotheses
as new subgoals.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">aleb</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_le_add</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">mf</span><span class="w"> </span><span class="n">aleb</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">mg</span><span class="w"> </span><span class="n">aleb</span>
</pre></div>
</div>
<p>When a proof is this short, it is often convenient
to give a proof term instead.
To describe a proof that temporarily introduces objects
<code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code> and a hypothesis <code class="docutils literal notranslate"><span class="pre">aleb</span></code>,
Lean uses the notation <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">a</span> <span class="pre">b</span> <span class="pre">aleb</span> <span class="pre">↦</span> <span class="pre">...</span></code>.
This is analogous to the way that an expression
like <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">x^2</span></code> describes a function
by temporarily naming an object, <code class="docutils literal notranslate"><span class="pre">x</span></code>,
and then using it to describe a value.
So the <code class="docutils literal notranslate"><span class="pre">intro</span></code> command in the previous proof
corresponds to the lambda abstraction in the next proof term.
The <code class="docutils literal notranslate"><span class="pre">apply</span></code> commands then correspond to building
the application of the theorem to its arguments.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">aleb</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">add_le_add</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="n">aleb</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="n">aleb</span><span class="o">)</span>
</pre></div>
</div>
<p>Here is a useful trick: if you start writing
the proof term <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">a</span> <span class="pre">b</span> <span class="pre">aleb</span> <span class="pre">↦</span> <span class="pre">_</span></code> using
an underscore where the rest of the
expression should go,
Lean will flag an error,
indicating that it can’t guess the value of that expression.
If you check the Lean Goal window in VS Code or
hover over the squiggly error marker,
Lean will show you the goal that the remaining
expression has to solve.</p>
<p>Try proving these, with either tactics or proof terms:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nnc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Here are some more examples.
A function <span class="math notranslate nohighlight">\(f\)</span> from <span class="math notranslate nohighlight">\(\Bbb R\)</span> to
<span class="math notranslate nohighlight">\(\Bbb R\)</span> is said to be <em>even</em> if
<span class="math notranslate nohighlight">\(f(-x) = f(x)\)</span> for every <span class="math notranslate nohighlight">\(x\)</span>,
and <em>odd</em> if <span class="math notranslate nohighlight">\(f(-x) = -f(x)\)</span> for every <span class="math notranslate nohighlight">\(x\)</span>.
The following example defines these two notions formally
and establishes one fact about them.
You can complete the proofs of the others.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span>
<span class="kd">def</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ef</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">eg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="k">calc</span>
<span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span>
<span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">ef</span><span class="o">,</span><span class="w"> </span><span class="n">eg</span><span class="o">]</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">of</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">og</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ef</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">og</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ef</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">og</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-4">The first proof can be shortened using <code class="docutils literal notranslate"><span class="pre">dsimp</span></code> or <code class="docutils literal notranslate"><span class="pre">change</span></code>
to get rid of the lambda abstraction.
But you can check that the subsequent <code class="docutils literal notranslate"><span class="pre">rw</span></code> won’t work
unless we get rid of the lambda abstraction explicitly,
because otherwise it cannot find the patterns <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span> <span class="pre">x</span></code>
in the expression.
Contrary to some other tactics, <code class="docutils literal notranslate"><span class="pre">rw</span></code> operates on the syntactic level,
it won’t unfold definitions or apply reductions for you
(it has a variant called <code class="docutils literal notranslate"><span class="pre">erw</span></code> that tries a little harder in this
direction, but not much harder).</p>
<p>You can find implicit universal quantifiers all over the place,
once you know how to spot them.</p>
<p>Mathlib includes a good library for manipulating sets. Recall that Lean does not
use foundations based on set theory, so here the word set has its mundane meaning
of a collection of mathematical objects of some given type <code class="docutils literal notranslate"><span class="pre">α</span></code>.
If <code class="docutils literal notranslate"><span class="pre">x</span></code> has type <code class="docutils literal notranslate"><span class="pre">α</span></code> and <code class="docutils literal notranslate"><span class="pre">s</span></code> has type <code class="docutils literal notranslate"><span class="pre">Set</span> <span class="pre">α</span></code>, then <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span></code> is a proposition
that asserts that <code class="docutils literal notranslate"><span class="pre">x</span></code> is an element of <code class="docutils literal notranslate"><span class="pre">s</span></code>. If <code class="docutils literal notranslate"><span class="pre">y</span></code> has some different type <code class="docutils literal notranslate"><span class="pre">β</span></code> then the
expression <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">∈</span> <span class="pre">s</span></code> makes no sense. Here “makes no sense” means “has no type hence Lean does not
accept it as a well-formed statement”. This contrasts with Zermelo-Fraenkel set theory for instance
where <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">∈</span> <span class="pre">b</span></code> is a well-formed statement for every mathematical objects <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">b</span></code>.
For instance <code class="docutils literal notranslate"><span class="pre">sin</span> <span class="pre">∈</span> <span class="pre">cos</span></code> is a well-formed statement in ZF. This defect of set theoretic
foundations is an important motivation for not using it in a proof assistant which is meant to assist
us by detecting meaningless expressions. In Lean <code class="docutils literal notranslate"><span class="pre">sin</span></code> has type <code class="docutils literal notranslate"><span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> and <code class="docutils literal notranslate"><span class="pre">cos</span></code> has type
<code class="docutils literal notranslate"><span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> which is not equal to <code class="docutils literal notranslate"><span class="pre">Set</span> <span class="pre">(ℝ</span> <span class="pre">→</span> <span class="pre">ℝ)</span></code>, even after unfolding definitions, so the statement
<code class="docutils literal notranslate"><span class="pre">sin</span> <span class="pre">∈</span> <span class="pre">cos</span></code> makes no sense.
One can also use Lean to work on set theory itself. For instance the independence of the continuum
hypothesis from the axioms of Zermelo-Fraenkel has been formalized in Lean. But such a meta-theory
of set theory is completely beyond the scope of this book.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">s</span></code> and <code class="docutils literal notranslate"><span class="pre">t</span></code> are of type <code class="docutils literal notranslate"><span class="pre">Set</span> <span class="pre">α</span></code>,
then the subset relation <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">⊆</span> <span class="pre">t</span></code> is defined to mean
<code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">{x</span> <span class="pre">:</span> <span class="pre">α},</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span> <span class="pre">→</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">t</span></code>.
The variable in the quantifier is marked implicit so that
given <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">s</span> <span class="pre">⊆</span> <span class="pre">t</span></code> and <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span></code>,
we can write <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">h'</span></code> as justification for <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">t</span></code>.
The following example provides a tactic proof and a proof term
justifying the reflexivity of the subset relation,
and asks you to do the same for transitivity.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xs</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">Subset.refl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">xs</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">Subset.trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Just as we defined <code class="docutils literal notranslate"><span class="pre">FnUb</span></code> for functions,
we can define <code class="docutils literal notranslate"><span class="pre">SetUb</span> <span class="pre">s</span> <span class="pre">a</span></code> to mean that <code class="docutils literal notranslate"><span class="pre">a</span></code>
is an upper bound on the set <code class="docutils literal notranslate"><span class="pre">s</span></code>,
assuming <code class="docutils literal notranslate"><span class="pre">s</span></code> is a set of elements of some type that
has an order associated with it.
In the next example, we ask you to prove that
if <code class="docutils literal notranslate"><span class="pre">a</span></code> is a bound on <code class="docutils literal notranslate"><span class="pre">s</span></code> and <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span></code>,
then <code class="docutils literal notranslate"><span class="pre">b</span></code> is a bound on <code class="docutils literal notranslate"><span class="pre">s</span></code> as well.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">PartialOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span>
<span class="kd">def</span><span class="w"> </span><span class="n">SetUb</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SetUb</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SetUb</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-5">We close this section with one last important example.
A function <span class="math notranslate nohighlight">\(f\)</span> is said to be <em>injective</em> if for
every <span class="math notranslate nohighlight">\(x_1\)</span> and <span class="math notranslate nohighlight">\(x_2\)</span>,
if <span class="math notranslate nohighlight">\(f(x_1) = f(x_2)\)</span> then <span class="math notranslate nohighlight">\(x_1 = x_2\)</span>.
Mathlib defines <code class="docutils literal notranslate"><span class="pre">Function.Injective</span> <span class="pre">f</span></code> with
<code class="docutils literal notranslate"><span class="pre">x₁</span></code> and <code class="docutils literal notranslate"><span class="pre">x₂</span></code> implicit.
The next example shows that, on the real numbers,
any function that adds a constant is injective.
We then ask you to show that multiplication by a nonzero
constant is also injective, using the lemma name in the example as a source
of inspiration. Recall you should use Ctrl-space completion after guessing the beginning of
a lemma name.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Function</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="n">h'</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">(</span><span class="n">add_left_inj</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="bp">.</span><span class="n">mp</span><span class="w"> </span><span class="n">h'</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Finally, show that the composition of two injective functions is injective:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">γ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">γ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">injg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">injf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
</section>
<section id="the-existential-quantifier">
<span id="id3"></span><h2><span class="section-number">3.2. </span>The Existential Quantifier<a class="headerlink" href="#the-existential-quantifier" title="Link to this heading"></a></h2>
<p>The existential quantifier, which can be entered as <code class="docutils literal notranslate"><span class="pre">\ex</span></code> in VS Code,
is used to represent the phrase “there exists.”
The formal expression <code class="docutils literal notranslate"><span class="pre">∃</span> <span class="pre">x</span> <span class="pre">:</span> <span class="pre">ℝ,</span> <span class="pre">2</span> <span class="pre"><</span> <span class="pre">x</span> <span class="pre">∧</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">3</span></code> in Lean says
that there is a real number between 2 and 3.
(We will discuss the conjunction symbol, <code class="docutils literal notranslate"><span class="pre">∧</span></code>, in <a class="reference internal" href="#conjunction-and-biimplication"><span class="std std-numref">Section 3.4</span></a>.)
The canonical way to prove such a statement is to exhibit a real number
and show that it has the stated property.
The number 2.5, which we can enter as <code class="docutils literal notranslate"><span class="pre">5</span> <span class="pre">/</span> <span class="pre">2</span></code>
or <code class="docutils literal notranslate"><span class="pre">(5</span> <span class="pre">:</span> <span class="pre">ℝ)</span> <span class="pre">/</span> <span class="pre">2</span></code> when Lean cannot infer from context that we have
the real numbers in mind, has the required property,
and the <code class="docutils literal notranslate"><span class="pre">norm_num</span></code> tactic can prove that it meets the description.</p>
<p id="index-6">There are a few ways we can put the information together.
Given a goal that begins with an existential quantifier,
the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic is used to provide the object,
leaving the goal of proving the property.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span>
<span class="w"> </span><span class="n">norm_num</span>
</pre></div>
</div>
<p>You can give the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic proofs as well as data:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="n">h1</span><span class="o">,</span><span class="w"> </span><span class="n">h2</span>
</pre></div>
</div>
<p>In fact, the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic automatically tries to use available assumptions as well.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span>
</pre></div>
</div>
<p id="index-7">Alternatively, we can use Lean’s <em>anonymous constructor</em> notation
to construct a proof of an existential quantifier.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span>
<span class="w"> </span><span class="o">⟨</span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span>
</pre></div>
</div>
<p>Notice that there is no <code class="docutils literal notranslate"><span class="pre">by</span></code>; here we are giving an explicit proof term.
The left and right angle brackets,
which can be entered as <code class="docutils literal notranslate"><span class="pre">\<</span></code> and <code class="docutils literal notranslate"><span class="pre">\></span></code> respectively,
tell Lean to put together the given data using
whatever construction is appropriate
for the current goal.
We can use the notation without going first into tactic mode:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="o">⟨</span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">⟩</span>
</pre></div>
</div>
<p>So now we know how to <em>prove</em> an exists statement.
But how do we <em>use</em> one?
If we know that there exists an object with a certain property,
we should be able to give a name to an arbitrary one
and reason about it.
For example, remember the predicates <code class="docutils literal notranslate"><span class="pre">FnUb</span> <span class="pre">f</span> <span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">FnLb</span> <span class="pre">f</span> <span class="pre">a</span></code>
from the last section,
which say that <code class="docutils literal notranslate"><span class="pre">a</span></code> is an upper bound or lower bound on <code class="docutils literal notranslate"><span class="pre">f</span></code>,
respectively.
We can use the existential quantifier to say that “<code class="docutils literal notranslate"><span class="pre">f</span></code> is bounded”
without specifying the bound:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span>
<span class="kd">def</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span>
<span class="kd">def</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span>
<span class="kd">def</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span>
</pre></div>
</div>
<p>We can use the theorem <code class="docutils literal notranslate"><span class="pre">FnUb_add</span></code> from the last section
to prove that if <code class="docutils literal notranslate"><span class="pre">f</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span></code> have upper bounds,
then so does <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ubf</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ubg</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span>
</pre></div>
</div>
<p id="index-8">The <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic unpacks the information
in the existential quantifier.
The annotations like <code class="docutils literal notranslate"><span class="pre">⟨a,</span> <span class="pre">ubfa⟩</span></code>, written with the
same angle brackets as the anonymous constructors,
are known as <em>patterns</em>, and they describe the information
that we expect to find when we unpack the main argument.
Given the hypothesis <code class="docutils literal notranslate"><span class="pre">ubf</span></code> that there is an upper bound
for <code class="docutils literal notranslate"><span class="pre">f</span></code>,
<code class="docutils literal notranslate"><span class="pre">rcases</span> <span class="pre">ubf</span> <span class="pre">with</span> <span class="pre">⟨a,</span> <span class="pre">ubfa⟩</span></code> adds a new variable <code class="docutils literal notranslate"><span class="pre">a</span></code>
for an upper bound to the context,
together with the hypothesis <code class="docutils literal notranslate"><span class="pre">ubfa</span></code> that it has the given property.
The goal is left unchanged;
what <em>has</em> changed is that we can now use
the new object and the new hypothesis
to prove the goal.
This is a common method of reasoning in mathematics:
we unpack objects whose existence is asserted or implied
by some hypothesis, and then use it to establish the existence
of something else.</p>
<p>Try using this method to establish the following.
You might find it useful to turn some of the examples
from the last section into named theorems,
as we did with <code class="docutils literal notranslate"><span class="pre">fn_ub_add</span></code>,
or you can insert the arguments directly
into the proofs.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">lbf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">lbg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-9">The “r” in <code class="docutils literal notranslate"><span class="pre">rcases</span></code> stands for “recursive,” because it allows
us to use arbitrarily complex patterns to unpack nested data.
The <code class="docutils literal notranslate"><span class="pre">rintro</span></code> tactic
is a combination of <code class="docutils literal notranslate"><span class="pre">intro</span></code> and <code class="docutils literal notranslate"><span class="pre">rcases</span></code>:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
</pre></div>
</div>
<p>In fact, Lean also supports a pattern-matching fun
in expressions and proof terms:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
</pre></div>
</div>
<p>The task of unpacking information in a hypothesis is
so important that Lean and Mathlib provide a number of
ways to do it. For example, the <code class="docutils literal notranslate"><span class="pre">obtain</span></code> tactic provides suggestive syntax:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">ubf</span>
<span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">ubg</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
</pre></div>
</div>
<p>Think of the first <code class="docutils literal notranslate"><span class="pre">obtain</span></code> instruction as matching the “contents” of <code class="docutils literal notranslate"><span class="pre">ubf</span></code>
with the given pattern and assigning the components to the named variables.
<code class="docutils literal notranslate"><span class="pre">rcases</span></code> and <code class="docutils literal notranslate"><span class="pre">obtain</span></code> are said to <code class="docutils literal notranslate"><span class="pre">destruct</span></code> their arguments.</p>
<p>Lean also supports syntax that is similar to that used in other functional programming
languages:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubf</span>
<span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubg</span>
<span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">ubgb</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubf</span>
<span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubg</span>
<span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">ubgb</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">ubf</span><span class="o">,</span><span class="w"> </span><span class="n">ubg</span><span class="w"> </span><span class="k">with</span>
<span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩,</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">ubf</span><span class="o">,</span><span class="w"> </span><span class="n">ubg</span><span class="w"> </span><span class="k">with</span>
<span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩,</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span>
</pre></div>
</div>
<p>In the first example, if you put your cursor after <code class="docutils literal notranslate"><span class="pre">cases</span> <span class="pre">ubf</span></code>,
you will see that the tactic produces a single goal, which Lean has tagged
<code class="docutils literal notranslate"><span class="pre">intro</span></code>. (The particular name chosen comes from the internal name for
the axiomatic primitive that builds a proof of an existential statement.)
The <code class="docutils literal notranslate"><span class="pre">case</span></code> tactic then names the components. The second example is similar,
except using <code class="docutils literal notranslate"><span class="pre">next</span></code> instead of <code class="docutils literal notranslate"><span class="pre">case</span></code> means that you can avoid mentioning
<code class="docutils literal notranslate"><span class="pre">intro</span></code>. The word <code class="docutils literal notranslate"><span class="pre">match</span></code> in the last two examples highlights that
what we are doing here is what computer scientists call “pattern matching.”
Notice that the third proof begins by <code class="docutils literal notranslate"><span class="pre">by</span></code>, after which the tactic version
of <code class="docutils literal notranslate"><span class="pre">match</span></code> expects a tactic proof on the right side of the arrow.
The last example is a proof term: there are no tactics in sight.</p>
<p>For the rest of this book, we will stick to <code class="docutils literal notranslate"><span class="pre">rcases</span></code>, <code class="docutils literal notranslate"><span class="pre">rintro</span></code>, and <code class="docutils literal notranslate"><span class="pre">obtain</span></code>,
as the preferred ways of using an existential quantifier.
But it can’t hurt to see the alternative syntax, especially if there is
a chance you will find yourself in the company of computer scientists.</p>
<p>To illustrate one way that <code class="docutils literal notranslate"><span class="pre">rcases</span></code> can be used,
we prove an old mathematical chestnut:
if two integers <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code> can each be written as
a sum of two squares,
then so can their product, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span></code>.
In fact, the statement is true for any commutative
ring, not just the integers.
In the next example, <code class="docutils literal notranslate"><span class="pre">rcases</span></code> unpacks two existential
quantifiers at once.
We then provide the magic values needed to express <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span></code>
as a sum of squares as a list to the <code class="docutils literal notranslate"><span class="pre">use</span></code> statement,
and we use <code class="docutils literal notranslate"><span class="pre">ring</span></code> to verify that they work.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">α</span><span class="o">]</span>
<span class="kd">def</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">sumOfSquares_mul</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">sosx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">sosy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosx</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">xeq</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosy</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">yeq</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">xeq</span><span class="o">,</span><span class="w"> </span><span class="n">yeq</span><span class="o">]</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span>
<span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>This proof doesn’t provide much insight,
but here is one way to motivate it.
A <em>Gaussian integer</em> is a number of the form <span class="math notranslate nohighlight">\(a + bi\)</span>
where <span class="math notranslate nohighlight">\(a\)</span> and <span class="math notranslate nohighlight">\(b\)</span> are integers and <span class="math notranslate nohighlight">\(i = \sqrt{-1}\)</span>.
The <em>norm</em> of the Gaussian integer <span class="math notranslate nohighlight">\(a + bi\)</span> is, by definition,
<span class="math notranslate nohighlight">\(a^2 + b^2\)</span>.
So the norm of a Gaussian integer is a sum of squares,
and any sum of squares can be expressed in this way.
The theorem above reflects the fact that norm of a product of
Gaussian integers is the product of their norms:
if <span class="math notranslate nohighlight">\(x\)</span> is the norm of <span class="math notranslate nohighlight">\(a + bi\)</span> and
<span class="math notranslate nohighlight">\(y\)</span> in the norm of <span class="math notranslate nohighlight">\(c + di\)</span>,
then <span class="math notranslate nohighlight">\(xy\)</span> is the norm of <span class="math notranslate nohighlight">\((a + bi) (c + di)\)</span>.
Our cryptic proof illustrates the fact that
the proof that is easiest to formalize isn’t always
the most perspicuous one.
In <a class="reference internal" href="C07_Structures.html#section-building-the-gaussian-integers"><span class="std std-numref">Section 7.3</span></a>,
we will provide you with the means to define the Gaussian
integers and use them to provide an alternative proof.</p>
<p>The pattern of unpacking an equation inside an existential quantifier
and then using it to rewrite an expression in the goal
comes up often,
so much so that the <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic provides
an abbreviation:
if you use the keyword <code class="docutils literal notranslate"><span class="pre">rfl</span></code> in place of a new identifier,
<code class="docutils literal notranslate"><span class="pre">rcases</span></code> does the rewriting automatically (this trick doesn’t work
with pattern-matching lambdas).</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sumOfSquares_mul'</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">sosx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">sosy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosx</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosy</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span>
<span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>As with the universal quantifier,
you can find existential quantifiers hidden all over
if you know how to spot them.
For example, divisibility is implicitly an “exists” statement.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">divab</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">divbc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">divab</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">beq</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">divbc</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">e</span><span class="o">,</span><span class="w"> </span><span class="n">ceq</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">ceq</span><span class="o">,</span><span class="w"> </span><span class="n">beq</span><span class="o">]</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>And once again, this provides a nice setting for using
<code class="docutils literal notranslate"><span class="pre">rcases</span></code> with <code class="docutils literal notranslate"><span class="pre">rfl</span></code>.
Try it out in the proof above.
It feels pretty good!</p>
<p>Then try proving the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">divab</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">divac</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-10">For another important example, a function <span class="math notranslate nohighlight">\(f : \alpha \to \beta\)</span>
is said to be <em>surjective</em> if for every <span class="math notranslate nohighlight">\(y\)</span> in the
codomain, <span class="math notranslate nohighlight">\(\beta\)</span>,
there is an <span class="math notranslate nohighlight">\(x\)</span> in the domain, <span class="math notranslate nohighlight">\(\alpha\)</span>,
such that <span class="math notranslate nohighlight">\(f(x) = y\)</span>.
Notice that this statement includes both a universal
and an existential quantifier, which explains
why the next example makes use of both <code class="docutils literal notranslate"><span class="pre">intro</span></code> and <code class="docutils literal notranslate"><span class="pre">use</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">c</span>
<span class="w"> </span><span class="n">dsimp</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>Try this example yourself using the theorem <code class="docutils literal notranslate"><span class="pre">mul_div_cancel₀</span></code>.:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-11">At this point, it is worth mentioning that there is a tactic, <code class="docutils literal notranslate"><span class="pre">field_simp</span></code>,
that will often clear denominators in a useful way.
It can be used in conjunction with the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">field_simp</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>The next example uses a surjectivity hypothesis
by applying it to a suitable value.
Note that you can use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> with any expression,
not just a hypothesis.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hx</span><span class="o">]</span>
<span class="w"> </span><span class="n">norm_num</span>
</pre></div>
</div>
<p>See if you can use these methods to show that
the composition of surjective functions is surjective.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">γ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">γ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">surjg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">surjf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
</section>
<section id="negation">
<span id="id4"></span><h2><span class="section-number">3.3. </span>Negation<a class="headerlink" href="#negation" title="Link to this heading"></a></h2>
<p>The symbol <code class="docutils literal notranslate"><span class="pre">¬</span></code> is meant to express negation,
so <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">y</span></code> says that <code class="docutils literal notranslate"><span class="pre">x</span></code> is not less than <code class="docutils literal notranslate"><span class="pre">y</span></code>,
<code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">x</span> <span class="pre">=</span> <span class="pre">y</span></code> (or, equivalently, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">≠</span> <span class="pre">y</span></code>) says that
<code class="docutils literal notranslate"><span class="pre">x</span></code> is not equal to <code class="docutils literal notranslate"><span class="pre">y</span></code>,
and <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">∃</span> <span class="pre">z,</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">z</span> <span class="pre">∧</span> <span class="pre">z</span> <span class="pre"><</span> <span class="pre">y</span></code> says that there does not exist a <code class="docutils literal notranslate"><span class="pre">z</span></code>
strictly between <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>.
In Lean, the notation <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">A</span></code> abbreviates <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">→</span> <span class="pre">False</span></code>,
which you can think of as saying that <code class="docutils literal notranslate"><span class="pre">A</span></code> implies a contradiction.
Practically speaking, this means that you already know something
about how to work with negations:
you can prove <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">A</span></code> by introducing a hypothesis <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">A</span></code>
and proving <code class="docutils literal notranslate"><span class="pre">False</span></code>,
and if you have <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">¬</span> <span class="pre">A</span></code> and <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">A</span></code>,
then applying <code class="docutils literal notranslate"><span class="pre">h</span></code> to <code class="docutils literal notranslate"><span class="pre">h'</span></code> yields <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p>
<p>To illustrate, consider the irreflexivity principle <code class="docutils literal notranslate"><span class="pre">lt_irrefl</span></code>
for a strict order,
which says that we have <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">a</span> <span class="pre"><</span> <span class="pre">a</span></code> for every <code class="docutils literal notranslate"><span class="pre">a</span></code>.
The asymmetry principle <code class="docutils literal notranslate"><span class="pre">lt_asymm</span></code> says that we have
<code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span> <span class="pre">→</span> <span class="pre">¬</span> <span class="pre">b</span> <span class="pre"><</span> <span class="pre">a</span></code>. Let’s show that <code class="docutils literal notranslate"><span class="pre">lt_asymm</span></code> follows
from <code class="docutils literal notranslate"><span class="pre">lt_irrefl</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h'</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h'</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">this</span>
</pre></div>
</div>
<p id="index-12">This example introduces a couple of new tricks.
First, when you use <code class="docutils literal notranslate"><span class="pre">have</span></code> without providing
a label,
Lean uses the name <code class="docutils literal notranslate"><span class="pre">this</span></code>,
providing a convenient way to refer back to it.
Because the proof is so short, we provide an explicit proof term.
But what you should really be paying attention to in this
proof is the result of the <code class="docutils literal notranslate"><span class="pre">intro</span></code> tactic,
which leaves a goal of <code class="docutils literal notranslate"><span class="pre">False</span></code>,
and the fact that we eventually prove <code class="docutils literal notranslate"><span class="pre">False</span></code>
by applying <code class="docutils literal notranslate"><span class="pre">lt_irrefl</span></code> to a proof of <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">a</span></code>.</p>
<p>Here is another example, which uses the
predicate <code class="docutils literal notranslate"><span class="pre">FnHasUb</span></code> defined in the last section,
which says that a function has an upper bound.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">fnub</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">fnub</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">fnuba</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">fnuba</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="n">linarith</span>
</pre></div>
</div>
<p>Remember that it is often convenient to use <code class="docutils literal notranslate"><span class="pre">linarith</span></code>
when a goal follows from linear equations and
inequalities that are in the context.</p>
<p>See if you can prove these in a similar way:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Mathlib offers a number of useful theorems for relating orders
and negations:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">not_le_of_gt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span>
<span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">not_lt_of_ge</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span>
<span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_of_not_ge</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span>
<span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_of_not_gt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span>
</pre></div>
</div>
<p>Recall the predicate <code class="docutils literal notranslate"><span class="pre">Monotone</span> <span class="pre">f</span></code>,
which says that <code class="docutils literal notranslate"><span class="pre">f</span></code> is nondecreasing.
Use some of the theorems just enumerated to prove the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>We can show that the first example in the last snippet
cannot be proved if we replace <code class="docutils literal notranslate"><span class="pre"><</span></code> by <code class="docutils literal notranslate"><span class="pre">≤</span></code>.
Notice that we can prove the negation of a universally
quantified statement by giving a counterexample.
Complete the proof.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">},</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">monof</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">le_refl</span><span class="w"> </span><span class="n">_</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-13">This example introduces the <code class="docutils literal notranslate"><span class="pre">let</span></code> tactic,
which adds a <em>local definition</em> to the context.
If you put the cursor after the <code class="docutils literal notranslate"><span class="pre">let</span></code> command,
in the goal window you will see that the definition
<code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span> <span class="pre">:=</span> <span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">0</span></code> has been added to the context.
Lean will unfold the definition of <code class="docutils literal notranslate"><span class="pre">f</span></code> when it has to.
In particular, when we prove <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">1</span> <span class="pre">≤</span> <span class="pre">f</span> <span class="pre">0</span></code> with <code class="docutils literal notranslate"><span class="pre">le_refl</span></code>,
Lean reduces <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">1</span></code> and <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">0</span></code> to <code class="docutils literal notranslate"><span class="pre">0</span></code>.</p>
<p>Use <code class="docutils literal notranslate"><span class="pre">le_of_not_gt</span></code> to prove the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Implicit in many of the proofs we have just done
is the fact that if <code class="docutils literal notranslate"><span class="pre">P</span></code> is any property,
saying that there is nothing with property <code class="docutils literal notranslate"><span class="pre">P</span></code>
is the same as saying that everything fails to have
property <code class="docutils literal notranslate"><span class="pre">P</span></code>,
and saying that not everything has property <code class="docutils literal notranslate"><span class="pre">P</span></code>
is equivalent to saying that something fails to have property <code class="docutils literal notranslate"><span class="pre">P</span></code>.
In other words, all four of the following implications
are valid (but one of them cannot be proved with what we explained so
far):</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>The first, second, and fourth are straightforward to
prove using the methods you have already seen.
We encourage you to try it.
The third is more difficult, however,
because it concludes that an object exists
from the fact that its nonexistence is contradictory.
This is an instance of <em>classical</em> mathematical reasoning.
We can use proof by contradiction
to prove the third implication as follows.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h'</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span>
<span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h''</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">h''</span><span class="o">⟩</span>
</pre></div>
</div>
<p id="index-14">Make sure you understand how this works.
The <code class="docutils literal notranslate"><span class="pre">by_contra</span></code> tactic
allows us to prove a goal <code class="docutils literal notranslate"><span class="pre">Q</span></code> by assuming <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">Q</span></code>
and deriving a contradiction.
In fact, it is equivalent to using the
equivalence <code class="docutils literal notranslate"><span class="pre">not_not</span> <span class="pre">:</span> <span class="pre">¬</span> <span class="pre">¬</span> <span class="pre">Q</span> <span class="pre">↔</span> <span class="pre">Q</span></code>.
Confirm that you can prove the forward direction
of this equivalence using <code class="docutils literal notranslate"><span class="pre">by_contra</span></code>,
while the reverse direction follows from the
ordinary rules for negation.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">Q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Use proof by contradiction to establish the following,
which is the converse of one of the implications we proved above.
(Hint: use <code class="docutils literal notranslate"><span class="pre">intro</span></code> first.)</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-15">It is often tedious to work with compound statements with
a negation in front,
and it is a common mathematical pattern to replace such
statements with equivalent forms in which the negation
has been pushed inward.
To facilitate this, Mathlib offers a <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> tactic,
which restates the goal in this way.
The command <code class="docutils literal notranslate"><span class="pre">push_neg</span> <span class="pre">at</span> <span class="pre">h</span></code> restates the hypothesis <code class="docutils literal notranslate"><span class="pre">h</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">dsimp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">FnHasUb</span><span class="o">,</span><span class="w"> </span><span class="n">FnUb</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
</pre></div>
</div>
<p>In the second example, we use dsimp to
expand the definitions of <code class="docutils literal notranslate"><span class="pre">FnHasUb</span></code> and <code class="docutils literal notranslate"><span class="pre">FnUb</span></code>.
(We need to use <code class="docutils literal notranslate"><span class="pre">dsimp</span></code> rather than <code class="docutils literal notranslate"><span class="pre">rw</span></code>
to expand <code class="docutils literal notranslate"><span class="pre">FnUb</span></code>,
because it appears in the scope of a quantifier.)
You can verify that in the examples above
with <code class="docutils literal notranslate"><span class="pre">¬∃</span> <span class="pre">x,</span> <span class="pre">P</span> <span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">¬∀</span> <span class="pre">x,</span> <span class="pre">P</span> <span class="pre">x</span></code>,
the <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> tactic does the expected thing.
Without even knowing how to use the conjunction
symbol,
you should be able to use <code class="docutils literal notranslate"><span class="pre">push_neg</span></code>
to prove the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-16">Mathlib also has a tactic, <code class="docutils literal notranslate"><span class="pre">contrapose</span></code>,
which transforms a goal <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">→</span> <span class="pre">B</span></code> to <code class="docutils literal notranslate"><span class="pre">¬B</span> <span class="pre">→</span> <span class="pre">¬A</span></code>.
Similarly, given a goal of proving <code class="docutils literal notranslate"><span class="pre">B</span></code> from
hypothesis <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">A</span></code>,
<code class="docutils literal notranslate"><span class="pre">contrapose</span> <span class="pre">h</span></code> leaves you with a goal of proving
<code class="docutils literal notranslate"><span class="pre">¬A</span></code> from hypothesis <code class="docutils literal notranslate"><span class="pre">¬B</span></code>.
Using <code class="docutils literal notranslate"><span class="pre">contrapose!</span></code> instead of <code class="docutils literal notranslate"><span class="pre">contrapose</span></code>
applies <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> to the goal and the relevant
hypothesis as well.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span>
<span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">linarith</span>
</pre></div>
</div>
<p>We have not yet explained the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> command
or the use of the semicolon after it,
but we will do that in the next section.</p>
<p>We close this section with
the principle of <em>ex falso</em>,
which says that anything follows from a contradiction.
In Lean, this is represented by <code class="docutils literal notranslate"><span class="pre">False.elim</span></code>,
which establishes <code class="docutils literal notranslate"><span class="pre">False</span> <span class="pre">→</span> <span class="pre">P</span></code> for any proposition <code class="docutils literal notranslate"><span class="pre">P</span></code>.
This may seem like a strange principle,
but it comes up fairly often.
We often prove a theorem by splitting on cases,
and sometimes we can show that one of
the cases is contradictory.
In that case, we need to assert that the contradiction
establishes the goal so we can move on to the next one.
(We will see instances of reasoning by cases in
<a class="reference internal" href="#disjunction"><span class="std std-numref">Section 3.5</span></a>.)</p>
<p id="index-17">Lean provides a number of ways of closing
a goal once a contradiction has been reached.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">exfalso</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">h</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="n">absurd</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">(</span><span class="n">lt_irrefl</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="n">contradiction</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">exfalso</span></code> tactic replaces the current goal with
the goal of proving <code class="docutils literal notranslate"><span class="pre">False</span></code>.
Given <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">P</span></code> and <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">¬</span> <span class="pre">P</span></code>,
the term <code class="docutils literal notranslate"><span class="pre">absurd</span> <span class="pre">h</span> <span class="pre">h'</span></code> establishes any proposition.
Finally, the <code class="docutils literal notranslate"><span class="pre">contradiction</span></code> tactic tries to close a goal
by finding a contradiction in the hypotheses,
such as a pair of the form <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">P</span></code> and <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">¬</span> <span class="pre">P</span></code>.
Of course, in this example, <code class="docutils literal notranslate"><span class="pre">linarith</span></code> also works.</p>
</section>
<section id="conjunction-and-iff">
<span id="conjunction-and-biimplication"></span><h2><span class="section-number">3.4. </span>Conjunction and Iff<a class="headerlink" href="#conjunction-and-iff" title="Link to this heading"></a></h2>
<p id="index-18">You have already seen that the conjunction symbol, <code class="docutils literal notranslate"><span class="pre">∧</span></code>,
is used to express “and.”
The <code class="docutils literal notranslate"><span class="pre">constructor</span></code> tactic allows you to prove a statement of
the form <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">∧</span> <span class="pre">B</span></code>
by proving <code class="docutils literal notranslate"><span class="pre">A</span></code> and then proving <code class="docutils literal notranslate"><span class="pre">B</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">constructor</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">assumption</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span>
</pre></div>
</div>
<p id="index-19">In this example, the <code class="docutils literal notranslate"><span class="pre">assumption</span></code> tactic
tells Lean to find an assumption that will solve the goal.
Notice that the final <code class="docutils literal notranslate"><span class="pre">rw</span></code> finishes the goal by
applying the reflexivity of <code class="docutils literal notranslate"><span class="pre">≤</span></code>.
The following are alternative ways of carrying out
the previous examples using the anonymous constructor
angle brackets.
The first is a slick proof-term version of the
previous proof,
which drops into tactic mode at the keyword <code class="docutils literal notranslate"><span class="pre">by</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">])⟩</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h₁</span><span class="o">]</span>
<span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span>
</pre></div>
</div>
<p><em>Using</em> a conjunction instead of proving one involves unpacking the proofs of the
two parts.
You can use the <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic for that,
as well as <code class="docutils literal notranslate"><span class="pre">rintro</span></code> or a pattern-matching <code class="docutils literal notranslate"><span class="pre">fun</span></code>,
all in a manner similar to the way they are used with
the existential quantifier.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="n">h'</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span>
</pre></div>
</div>
<p>In analogy to the <code class="docutils literal notranslate"><span class="pre">obtain</span></code> tactic, there is also a pattern-matching <code class="docutils literal notranslate"><span class="pre">have</span></code>:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span>
</pre></div>
</div>
<p>In contrast to <code class="docutils literal notranslate"><span class="pre">rcases</span></code>, here the <code class="docutils literal notranslate"><span class="pre">have</span></code> tactic leaves <code class="docutils literal notranslate"><span class="pre">h</span></code> in the context.
And even though we won’t use them, once again we have the computer scientists’
pattern-matching syntax:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span>
<span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span>
</pre></div>
</div>
<p>In contrast to using an existential quantifier,
you can also extract proofs of the two components
of a hypothesis <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">A</span> <span class="pre">∧</span> <span class="pre">B</span></code>
by writing <code class="docutils literal notranslate"><span class="pre">h.left</span></code> and <code class="docutils literal notranslate"><span class="pre">h.right</span></code>,
or, equivalently, <code class="docutils literal notranslate"><span class="pre">h.1</span></code> and <code class="docutils literal notranslate"><span class="pre">h.2</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h'</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h.right</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h.left</span><span class="w"> </span><span class="n">h'</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h.right</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h.left</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span>
</pre></div>
</div>
<p>Try using these techniques to come up with various ways of proving of the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">¬</span><span class="n">n</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>You can nest uses of <code class="docutils literal notranslate"><span class="pre">∃</span></code> and <code class="docutils literal notranslate"><span class="pre">∧</span></code>
with anonymous constructors, <code class="docutils literal notranslate"><span class="pre">rintro</span></code>, and <code class="docutils literal notranslate"><span class="pre">rcases</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="o">⟨</span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">⟩</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">xltz</span><span class="o">,</span><span class="w"> </span><span class="n">zlty</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">xltz</span><span class="w"> </span><span class="n">zlty</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">xltz</span><span class="o">,</span><span class="w"> </span><span class="n">zlty</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">xltz</span><span class="w"> </span><span class="n">zlty</span>
</pre></div>
</div>
<p>You can also use the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span>
<span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">norm_num</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">7</span>
<span class="w"> </span><span class="n">norm_num</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">h₀</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span>
</pre></div>
</div>
<p>In the first example, the semicolon after the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> command tells Lean to use the
<code class="docutils literal notranslate"><span class="pre">norm_num</span></code> tactic on both of the goals that result.</p>
<p>In Lean, <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">↔</span> <span class="pre">B</span></code> is <em>not</em> defined to be <code class="docutils literal notranslate"><span class="pre">(A</span> <span class="pre">→</span> <span class="pre">B)</span> <span class="pre">∧</span> <span class="pre">(B</span> <span class="pre">→</span> <span class="pre">A)</span></code>,
but it could have been,
and it behaves roughly the same way.
You have already seen that you can write <code class="docutils literal notranslate"><span class="pre">h.mp</span></code> and <code class="docutils literal notranslate"><span class="pre">h.mpr</span></code>
or <code class="docutils literal notranslate"><span class="pre">h.1</span></code> and <code class="docutils literal notranslate"><span class="pre">h.2</span></code> for the two directions of <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">A</span> <span class="pre">↔</span> <span class="pre">B</span></code>.
You can also use <code class="docutils literal notranslate"><span class="pre">cases</span></code> and friends.
To prove an if-and-only-if statement,
you can use <code class="docutils literal notranslate"><span class="pre">constructor</span></code> or angle brackets,
just as you would if you were proving a conjunction.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">constructor</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span>
<span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">rfl</span>
<span class="w"> </span><span class="n">rfl</span>
<span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h₁</span><span class="o">]),</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h₁</span><span class="o">)⟩</span>
</pre></div>
</div>
<p>The last proof term is inscrutable. Remember that you can
use underscores while writing an expression like that to
see what Lean expects.</p>
<p>Try out the various techniques and gadgets you have just seen
in order to prove the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>For a more interesting exercise, show that for any
two real numbers <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>,
<code class="docutils literal notranslate"><span class="pre">x^2</span> <span class="pre">+</span> <span class="pre">y^2</span> <span class="pre">=</span> <span class="pre">0</span></code> if and only if <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">=</span> <span class="pre">0</span></code>.
We suggest proving an auxiliary lemma using
<code class="docutils literal notranslate"><span class="pre">linarith</span></code>, <code class="docutils literal notranslate"><span class="pre">pow_two_nonneg</span></code>, and <code class="docutils literal notranslate"><span class="pre">pow_eq_zero</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="n">pow_eq_zero</span><span class="w"> </span><span class="n">h'</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>In Lean, bi-implication leads a double-life.
You can treat it like a conjunction and use its two
parts separately.
But Lean also knows that it is a reflexive, symmetric,
and transitive relation between propositions,
and you can also use it with <code class="docutils literal notranslate"><span class="pre">calc</span></code> and <code class="docutils literal notranslate"><span class="pre">rw</span></code>.
It is often convenient to rewrite a statement to
an equivalent one.
In the next example, we use <code class="docutils literal notranslate"><span class="pre">abs_lt</span></code> to
replace an expression of the form <code class="docutils literal notranslate"><span class="pre">|x|</span> <span class="pre"><</span> <span class="pre">y</span></code>
by the equivalent expression <code class="docutils literal notranslate"><span class="pre">-</span> <span class="pre">y</span> <span class="pre"><</span> <span class="pre">x</span> <span class="pre">∧</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">y</span></code>,
and in the one after that we use <code class="docutils literal notranslate"><span class="pre">Nat.dvd_gcd_iff</span></code>
to replace an expression of the form <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">∣</span> <span class="pre">Nat.gcd</span> <span class="pre">n</span> <span class="pre">k</span></code> by the equivalent expression <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">∣</span> <span class="pre">n</span> <span class="pre">∧</span> <span class="pre">m</span> <span class="pre">∣</span> <span class="pre">k</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">3</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">-</span><span class="mi">8</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_lt</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">linarith</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.dvd_gcd_iff</span><span class="o">]</span>
<span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">norm_num</span>
</pre></div>
</div>
<p>See if you can use <code class="docutils literal notranslate"><span class="pre">rw</span></code> with the theorem below
to provide a short proof that negation is not a
nondecreasing function. (Note that <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> won’t
unfold definitions for you, so the <code class="docutils literal notranslate"><span class="pre">rw</span> <span class="pre">[Monotone]</span></code> in
the proof of the theorem is needed.)</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">not_monotone_iff</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Monotone</span><span class="o">]</span>
<span class="w"> </span><span class="n">push_neg</span>
<span class="w"> </span><span class="n">rfl</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">-</span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>The remaining exercises in this section are designed
to give you some more practice with conjunction and
bi-implication. Remember that a <em>partial order</em> is a
binary relation that is transitive, reflexive, and
antisymmetric.
An even weaker notion sometimes arises:
a <em>preorder</em> is just a reflexive, transitive relation.
For any pre-order <code class="docutils literal notranslate"><span class="pre">≤</span></code>,
Lean axiomatizes the associated strict pre-order by
<code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span> <span class="pre">↔</span> <span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span> <span class="pre">∧</span> <span class="pre">¬</span> <span class="pre">b</span> <span class="pre">≤</span> <span class="pre">a</span></code>.
Show that if <code class="docutils literal notranslate"><span class="pre">≤</span></code> is a partial order,
then <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span></code> is equivalent to <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span> <span class="pre">∧</span> <span class="pre">a</span> <span class="pre">≠</span> <span class="pre">b</span></code>:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">PartialOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">lt_iff_le_not_ge</span><span class="o">]</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p id="index-20">Beyond logical operations, you do not need
anything more than <code class="docutils literal notranslate"><span class="pre">le_refl</span></code> and <code class="docutils literal notranslate"><span class="pre">le_trans</span></code>.
Show that even in the case where <code class="docutils literal notranslate"><span class="pre">≤</span></code>
is only assumed to be a preorder,
we can prove that the strict order is irreflexive
and transitive.
In the second example,
for convenience, we use the simplifier rather than <code class="docutils literal notranslate"><span class="pre">rw</span></code>
to express <code class="docutils literal notranslate"><span class="pre"><</span></code> in terms of <code class="docutils literal notranslate"><span class="pre">≤</span></code> and <code class="docutils literal notranslate"><span class="pre">¬</span></code>.
We will come back to the simplifier later,
but here we are only relying on the fact that it will
use the indicated lemma repeatedly, even if it needs
to be instantiated to different values.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Preorder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">lt_iff_le_not_ge</span><span class="o">]</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">lt_iff_le_not_ge</span><span class="o">]</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
</section>
<section id="disjunction">
<span id="id5"></span><h2><span class="section-number">3.5. </span>Disjunction<a class="headerlink" href="#disjunction" title="Link to this heading"></a></h2>
<p id="index-21">The canonical way to prove a disjunction <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">∨</span> <span class="pre">B</span></code> is to prove
<code class="docutils literal notranslate"><span class="pre">A</span></code> or to prove <code class="docutils literal notranslate"><span class="pre">B</span></code>.
The <code class="docutils literal notranslate"><span class="pre">left</span></code> tactic chooses <code class="docutils literal notranslate"><span class="pre">A</span></code>,
and the <code class="docutils literal notranslate"><span class="pre">right</span></code> tactic chooses <code class="docutils literal notranslate"><span class="pre">B</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">left</span>
<span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">pow_two_nonneg</span><span class="w"> </span><span class="n">x</span><span class="o">]</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">right</span>
<span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">pow_two_nonneg</span><span class="w"> </span><span class="n">x</span><span class="o">]</span>
</pre></div>
</div>
<p>We cannot use an anonymous constructor to construct a proof
of an “or” because Lean would have to guess
which disjunct we are trying to prove.
When we write proof terms we can use
<code class="docutils literal notranslate"><span class="pre">Or.inl</span></code> and <code class="docutils literal notranslate"><span class="pre">Or.inr</span></code> instead
to make the choice explicitly.
Here, <code class="docutils literal notranslate"><span class="pre">inl</span></code> is short for “introduction left” and
<code class="docutils literal notranslate"><span class="pre">inr</span></code> is short for “introduction right.”</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="n">Or.inl</span><span class="w"> </span><span class="n">h</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="n">Or.inr</span><span class="w"> </span><span class="n">h</span>
</pre></div>
</div>
<p>It may seem strange to prove a disjunction by proving one side
or the other.
In practice, which case holds usually depends on a case distinction
that is implicit or explicit in the assumptions and the data.
The <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic allows us to make use of a hypothesis
of the form <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">∨</span> <span class="pre">B</span></code>.
In contrast to the use of <code class="docutils literal notranslate"><span class="pre">rcases</span></code> with conjunction or an
existential quantifier,
here the <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic produces <em>two</em> goals.
Both have the same conclusion, but in the first case,
<code class="docutils literal notranslate"><span class="pre">A</span></code> is assumed to be true,
and in the second case,
<code class="docutils literal notranslate"><span class="pre">B</span></code> is assumed to be true.
In other words, as the name suggests,
the <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic carries out a proof by cases.
As usual, we can tell Lean what names to use for the hypotheses.
In the next example, we tell Lean
to use the name <code class="docutils literal notranslate"><span class="pre">h</span></code> on each branch.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
</pre></div>
</div>
<p>Notice that the pattern changes from <code class="docutils literal notranslate"><span class="pre">⟨h₀,</span> <span class="pre">h₁⟩</span></code> in the case of
a conjunction to <code class="docutils literal notranslate"><span class="pre">h₀</span> <span class="pre">|</span> <span class="pre">h₁</span></code> in the case of a disjunction.
Think of the first pattern as matching against data the contains
<em>both</em> an <code class="docutils literal notranslate"><span class="pre">h₀</span></code> and a <code class="docutils literal notranslate"><span class="pre">h₁</span></code>, whereas second pattern, with the bar,
matches against data that contains <em>either</em> an <code class="docutils literal notranslate"><span class="pre">h₀</span></code> or <code class="docutils literal notranslate"><span class="pre">h₁</span></code>.
In this case, because the two goals are separate, we have chosen
to use the same name, <code class="docutils literal notranslate"><span class="pre">h</span></code>, in each case.</p>
<p>The absolute value function is defined in such a way
that we can immediately prove that
<code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">≥</span> <span class="pre">0</span></code> implies <code class="docutils literal notranslate"><span class="pre">|x|</span> <span class="pre">=</span> <span class="pre">x</span></code>
(this is the theorem <code class="docutils literal notranslate"><span class="pre">abs_of_nonneg</span></code>)
and <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre"><</span> <span class="pre">0</span></code> implies <code class="docutils literal notranslate"><span class="pre">|x|</span> <span class="pre">=</span> <span class="pre">-x</span></code> (this is <code class="docutils literal notranslate"><span class="pre">abs_of_neg</span></code>).
The expression <code class="docutils literal notranslate"><span class="pre">le_or_gt</span> <span class="pre">0</span> <span class="pre">x</span></code> establishes <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre">≤</span> <span class="pre">x</span> <span class="pre">∨</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">0</span></code>,
allowing us to split on those two cases.</p>
<p>Lean also supports the computer scientists’ pattern-matching
syntax for disjunction. Now the <code class="docutils literal notranslate"><span class="pre">cases</span></code> tactic is more attractive,
because it allows us to name each <code class="docutils literal notranslate"><span class="pre">case</span></code>, and name the hypothesis
that is introduced closer to where it is used.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span>
<span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">inl</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">inr</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
</pre></div>
</div>
<p>The names <code class="docutils literal notranslate"><span class="pre">inl</span></code> and <code class="docutils literal notranslate"><span class="pre">inr</span></code> are short for “intro left” and “intro right,”
respectively. Using <code class="docutils literal notranslate"><span class="pre">case</span></code> has the advantage that you can prove the
cases in either order; Lean uses the tag to find the relevant goal.
If you don’t care about that, you can use <code class="docutils literal notranslate"><span class="pre">next</span></code>, or <code class="docutils literal notranslate"><span class="pre">match</span></code>,
or even a pattern-matching <code class="docutils literal notranslate"><span class="pre">have</span></code>.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span>
<span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">with</span>
<span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Or.inl</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Or.inr</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span>
</pre></div>
</div>
<p>In the case of <code class="docutils literal notranslate"><span class="pre">match</span></code>, we need to use the full names
<code class="docutils literal notranslate"><span class="pre">Or.inl</span></code> and <code class="docutils literal notranslate"><span class="pre">Or.inr</span></code> of the canonical ways to prove a disjunction.
In this textbook, we will generally use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> to split on the
cases of a disjunction.</p>
<p>Try proving the triangle inequality using the
first two theorems in the next snippet.
They are given the same names they have in Mathlib.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span><span class="w"> </span><span class="n">MyAbs</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">le_abs_self</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">neg_le_abs_self</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">abs_add</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>In case you enjoyed these (pun intended) and
you want more practice with disjunction,
try these.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">lt_abs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">theorem</span><span class="w"> </span><span class="n">abs_lt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>You can also use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> and <code class="docutils literal notranslate"><span class="pre">rintro</span></code> with nested disjunctions.
When these result in a genuine case split with multiple goals,
the patterns for each new goal are separated by a vertical bar.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">lt_trichotomy</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">xlt</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xeq</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xgt</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">left</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xlt</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">contradiction</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xgt</span>
</pre></div>
</div>
<p>You can still nest patterns and use the <code class="docutils literal notranslate"><span class="pre">rfl</span></code> keyword
to substitute equations:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_right</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="o">,</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">]</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_right</span>
</pre></div>
</div>
<p>See if you can prove the following with a single (long) line.
Use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> to unpack the hypotheses and split on cases,
and use a semicolon and <code class="docutils literal notranslate"><span class="pre">linarith</span></code> to solve each branch.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>On the real numbers, an equation <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">0</span></code>
tells us that <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">0</span></code> or <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">=</span> <span class="pre">0</span></code>.
In Mathlib, this fact is known as <code class="docutils literal notranslate"><span class="pre">eq_zero_or_eq_zero_of_mul_eq_zero</span></code>,
and it is another nice example of how a disjunction can arise.
See if you can use it to prove the following:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>Remember that you can use the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic to help
with calculations.</p>
<p>In an arbitrary ring <span class="math notranslate nohighlight">\(R\)</span>, an element <span class="math notranslate nohighlight">\(x\)</span> such
that <span class="math notranslate nohighlight">\(x y = 0\)</span> for some nonzero <span class="math notranslate nohighlight">\(y\)</span> is called
a <em>left zero divisor</em>,
an element <span class="math notranslate nohighlight">\(x\)</span> such
that <span class="math notranslate nohighlight">\(y x = 0\)</span> for some nonzero <span class="math notranslate nohighlight">\(y\)</span> is called
a <em>right zero divisor</em>,
and an element that is either a left or right zero divisor
is called simply a <em>zero divisor</em>.
The theorem <code class="docutils literal notranslate"><span class="pre">eq_zero_or_eq_zero_of_mul_eq_zero</span></code>
says that the real numbers have no nontrivial zero divisors.
A commutative ring with this property is called an <em>integral domain</em>.
Your proofs of the two theorems above should work equally well
in any integral domain:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">IsDomain</span><span class="w"> </span><span class="n">R</span><span class="o">]</span>
<span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
<span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>In fact, if you are careful, you can prove the first
theorem without using commutativity of multiplication.
In that case, it suffices to assume that <code class="docutils literal notranslate"><span class="pre">R</span></code> is
a <code class="docutils literal notranslate"><span class="pre">Ring</span></code> instead of an <code class="docutils literal notranslate"><span class="pre">CommRing</span></code>.</p>
<p id="index-22">Sometimes in a proof we want to split on cases
depending on whether some statement is true or not.
For any proposition <code class="docutils literal notranslate"><span class="pre">P</span></code>, we can use
<code class="docutils literal notranslate"><span class="pre">em</span> <span class="pre">P</span> <span class="pre">:</span> <span class="pre">P</span> <span class="pre">∨</span> <span class="pre">¬</span> <span class="pre">P</span></code>.
The name <code class="docutils literal notranslate"><span class="pre">em</span></code> is short for “excluded middle.”</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">P</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">em</span><span class="w"> </span><span class="n">P</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">assumption</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">contradiction</span>
</pre></div>
</div>
<p id="index-23">Alternatively, you can use the <code class="docutils literal notranslate"><span class="pre">by_cases</span></code> tactic.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">P</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">P</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">assumption</span>
<span class="w"> </span><span class="n">contradiction</span>
</pre></div>
</div>
<p>Notice that the <code class="docutils literal notranslate"><span class="pre">by_cases</span></code> tactic lets you
specify a label for the hypothesis that is
introduced in each branch,
in this case, <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">P</span></code> in one and <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">¬</span> <span class="pre">P</span></code>
in the other.
If you leave out the label,
Lean uses <code class="docutils literal notranslate"><span class="pre">h</span></code> by default.
Try proving the following equivalence,
using <code class="docutils literal notranslate"><span class="pre">by_cases</span></code> to establish one direction.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
</section>
<section id="sequences-and-convergence">
<span id="id6"></span><h2><span class="section-number">3.6. </span>Sequences and Convergence<a class="headerlink" href="#sequences-and-convergence" title="Link to this heading"></a></h2>
<p>We now have enough skills at our disposal to do some real mathematics.
In Lean, we can represent a sequence <span class="math notranslate nohighlight">\(s_0, s_1, s_2, \ldots\)</span> of
real numbers as a function <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">:</span> <span class="pre">ℕ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code>.
Such a sequence is said to <em>converge</em> to a number <span class="math notranslate nohighlight">\(a\)</span> if for every
<span class="math notranslate nohighlight">\(\varepsilon > 0\)</span> there is a point beyond which the sequence
remains within <span class="math notranslate nohighlight">\(\varepsilon\)</span> of <span class="math notranslate nohighlight">\(a\)</span>,
that is, there is a number <span class="math notranslate nohighlight">\(N\)</span> such that for every
<span class="math notranslate nohighlight">\(n \ge N\)</span>, <span class="math notranslate nohighlight">\(| s_n - a | < \varepsilon\)</span>.
In Lean, we can render this as follows:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span>
</pre></div>
</div>
<p>The notation <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">ε</span> <span class="pre">></span> <span class="pre">0,</span> <span class="pre">...</span></code> is a convenient abbreviation
for <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">ε,</span> <span class="pre">ε</span> <span class="pre">></span> <span class="pre">0</span> <span class="pre">→</span> <span class="pre">...</span></code>, and, similarly,
<code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">n</span> <span class="pre">≥</span> <span class="pre">N,</span> <span class="pre">...</span></code> abbreviates <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">n,</span> <span class="pre">n</span> <span class="pre">≥</span> <span class="pre">N</span> <span class="pre">→</span>  <span class="pre">...</span></code>.
And remember that <code class="docutils literal notranslate"><span class="pre">ε</span> <span class="pre">></span> <span class="pre">0</span></code>, in turn, is defined as <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><</span> <span class="pre">ε</span></code>,
and <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">≥</span> <span class="pre">N</span></code> is defined as <code class="docutils literal notranslate"><span class="pre">N</span> <span class="pre">≤</span> <span class="pre">n</span></code>.</p>
<p id="index-24">In this section, we’ll establish some properties of convergence.
But first, we will discuss three tactics for working with equality
that will prove useful.
The first, the <code class="docutils literal notranslate"><span class="pre">ext</span></code> tactic,
gives us a way of proving that two functions are equal.
Let <span class="math notranslate nohighlight">\(f(x) = x + 1\)</span> and <span class="math notranslate nohighlight">\(g(x) = 1 + x\)</span>
be functions from reals to reals.
Then, of course, <span class="math notranslate nohighlight">\(f = g\)</span>, because they return the same
value for every <span class="math notranslate nohighlight">\(x\)</span>.
The <code class="docutils literal notranslate"><span class="pre">ext</span></code> tactic enables us to prove an equation between functions
by proving that their values are the same
at all the values of their arguments.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">ext</span>
<span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p id="index-25">We’ll see later that <code class="docutils literal notranslate"><span class="pre">ext</span></code> is actually more general, and also one can
specify the name of the variables that appear.
For instance you can try to replace <code class="docutils literal notranslate"><span class="pre">ext</span></code> with <code class="docutils literal notranslate"><span class="pre">ext</span> <span class="pre">u</span> <span class="pre">v</span></code> in the
above proof.
The second tactic, the <code class="docutils literal notranslate"><span class="pre">congr</span></code> tactic,
allows us to prove an equation between two expressions
by reconciling the parts that are different:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">congr</span>
<span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>Here the <code class="docutils literal notranslate"><span class="pre">congr</span></code> tactic peels off the <code class="docutils literal notranslate"><span class="pre">abs</span></code> on each side,
leaving us to prove <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">=</span> <span class="pre">a</span> <span class="pre">-</span> <span class="pre">b</span> <span class="pre">+</span> <span class="pre">b</span></code>.</p>
<p id="index-26">Finally, the <code class="docutils literal notranslate"><span class="pre">convert</span></code> tactic is used to apply a theorem
to a goal when the conclusion of the theorem doesn’t quite match.
For example, suppose we want to prove <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">a</span></code> from <code class="docutils literal notranslate"><span class="pre">1</span> <span class="pre"><</span> <span class="pre">a</span></code>.
A theorem in the library, <code class="docutils literal notranslate"><span class="pre">mul_lt_mul_right</span></code>,
will let us prove <code class="docutils literal notranslate"><span class="pre">1</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre"><</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">a</span></code>.
One possibility is to work backwards and rewrite the goal
so that it has that form.
Instead, the <code class="docutils literal notranslate"><span class="pre">convert</span></code> tactic lets us apply the theorem
as it is,
and leaves us with the task of proving the equations that
are needed to make the goal match.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="o">(</span><span class="n">mul_lt_mul_right</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">one_mul</span><span class="o">]</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">zero_lt_one</span><span class="w"> </span><span class="n">h</span>
</pre></div>
</div>
<p>This example illustrates another useful trick: when we apply an
expression with an underscore
and Lean can’t fill it in for us automatically,
it simply leaves it for us as another goal.</p>
<p>The following shows that any constant sequence <span class="math notranslate nohighlight">\(a, a, a, \ldots\)</span>
converges.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_const</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">nge</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">sub_self</span><span class="o">,</span><span class="w"> </span><span class="n">abs_zero</span><span class="o">]</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">εpos</span>
</pre></div>
</div>
<p>Lean has a tactic, <code class="docutils literal notranslate"><span class="pre">simp</span></code>, which can often save you the
trouble of carrying out steps like <code class="docutils literal notranslate"><span class="pre">rw</span> <span class="pre">[sub_self,</span> <span class="pre">abs_zero]</span></code>
by hand.
We will tell you more about it soon.</p>
<p>For a more interesting theorem, let’s show that if <code class="docutils literal notranslate"><span class="pre">s</span></code>
converges to <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">t</span></code> converges to <code class="docutils literal notranslate"><span class="pre">b</span></code>, then
<code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">n</span> <span class="pre">↦</span> <span class="pre">s</span> <span class="pre">n</span> <span class="pre">+</span> <span class="pre">t</span> <span class="pre">n</span></code> converges to <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>.
It is helpful to have a clear pen-and-paper
proof in mind before you start writing a formal one.
Given <code class="docutils literal notranslate"><span class="pre">ε</span></code> greater than <code class="docutils literal notranslate"><span class="pre">0</span></code>,
the idea is to use the hypotheses to obtain an <code class="docutils literal notranslate"><span class="pre">Ns</span></code>
such that beyond that point, <code class="docutils literal notranslate"><span class="pre">s</span></code> is within <code class="docutils literal notranslate"><span class="pre">ε</span> <span class="pre">/</span> <span class="pre">2</span></code>
of <code class="docutils literal notranslate"><span class="pre">a</span></code>,
and an <code class="docutils literal notranslate"><span class="pre">Nt</span></code> such that beyond that point, <code class="docutils literal notranslate"><span class="pre">t</span></code> is within
<code class="docutils literal notranslate"><span class="pre">ε</span> <span class="pre">/</span> <span class="pre">2</span></code> of <code class="docutils literal notranslate"><span class="pre">b</span></code>.
Then, whenever <code class="docutils literal notranslate"><span class="pre">n</span></code> is greater than or equal to the
maximum of <code class="docutils literal notranslate"><span class="pre">Ns</span></code> and <code class="docutils literal notranslate"><span class="pre">Nt</span></code>,
the sequence <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">n</span> <span class="pre">↦</span> <span class="pre">s</span> <span class="pre">n</span> <span class="pre">+</span> <span class="pre">t</span> <span class="pre">n</span></code> should be within <code class="docutils literal notranslate"><span class="pre">ε</span></code>
of <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>.
The following example begins to implement this strategy.
See if you can finish it off.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span>
<span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ct</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span>
<span class="w"> </span><span class="n">dsimp</span><span class="w"> </span><span class="c1">-- this line is not needed but cleans up the goal a bit.</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">ε2pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">linarith</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">cs</span><span class="w"> </span><span class="o">(</span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">ε2pos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Ns</span><span class="o">,</span><span class="w"> </span><span class="n">hs</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ct</span><span class="w"> </span><span class="o">(</span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">ε2pos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Nt</span><span class="o">,</span><span class="w"> </span><span class="n">ht</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">max</span><span class="w"> </span><span class="n">Ns</span><span class="w"> </span><span class="n">Nt</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>As hints, you can use <code class="docutils literal notranslate"><span class="pre">le_of_max_le_left</span></code> and <code class="docutils literal notranslate"><span class="pre">le_of_max_le_right</span></code>,
and <code class="docutils literal notranslate"><span class="pre">norm_num</span></code> can prove <code class="docutils literal notranslate"><span class="pre">ε</span> <span class="pre">/</span> <span class="pre">2</span> <span class="pre">+</span> <span class="pre">ε</span> <span class="pre">/</span> <span class="pre">2</span> <span class="pre">=</span> <span class="pre">ε</span></code>.
Also, it is helpful to use the <code class="docutils literal notranslate"><span class="pre">congr</span></code> tactic to
show that <code class="docutils literal notranslate"><span class="pre">|s</span> <span class="pre">n</span> <span class="pre">+</span> <span class="pre">t</span> <span class="pre">n</span> <span class="pre">-</span> <span class="pre">(a</span> <span class="pre">+</span> <span class="pre">b)|</span></code> is equal to
<code class="docutils literal notranslate"><span class="pre">|(s</span> <span class="pre">n</span> <span class="pre">-</span> <span class="pre">a)</span> <span class="pre">+</span> <span class="pre">(t</span> <span class="pre">n</span> <span class="pre">-</span> <span class="pre">b)|,</span></code>
since then you can use the triangle inequality.
Notice that we marked all the variables <code class="docutils literal notranslate"><span class="pre">s</span></code>, <code class="docutils literal notranslate"><span class="pre">t</span></code>, <code class="docutils literal notranslate"><span class="pre">a</span></code>, and <code class="docutils literal notranslate"><span class="pre">b</span></code>
implicit because they can be inferred from the hypotheses.</p>
<p>Proving the same theorem with multiplication in place
of addition is tricky.
We will get there by proving some auxiliary statements first.
See if you can also finish off the next proof,
which shows that if <code class="docutils literal notranslate"><span class="pre">s</span></code> converges to <code class="docutils literal notranslate"><span class="pre">a</span></code>,
then <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">n</span> <span class="pre">↦</span> <span class="pre">c</span> <span class="pre">*</span> <span class="pre">s</span> <span class="pre">n</span></code> converges to <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">*</span> <span class="pre">a</span></code>.
It is helpful to split into cases depending on whether <code class="docutils literal notranslate"><span class="pre">c</span></code>
is equal to zero or not.
We have taken care of the zero case,
and we have left you to prove the result with
the extra assumption that <code class="docutils literal notranslate"><span class="pre">c</span></code> is nonzero.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_mul_const</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">convergesTo_const</span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">ring</span>
<span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span>
<span class="w"> </span><span class="n">ring</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">acpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">c</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">abs_pos.mpr</span><span class="w"> </span><span class="n">h</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>The next theorem is also independently interesting:
it shows that a convergent sequence is eventually bounded
in absolute value.
We have started you off; see if you can finish it.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">exists_abs_le_of_convergesTo</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">cs</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">zero_lt_one</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>In fact, the theorem could be strengthened to assert
that there is a bound <code class="docutils literal notranslate"><span class="pre">b</span></code> that holds for all values of <code class="docutils literal notranslate"><span class="pre">n</span></code>.
But this version is strong enough for our purposes,
and we will see at the end of this section that it
holds more generally.</p>
<p>The next lemma is auxiliary: we prove that if
<code class="docutils literal notranslate"><span class="pre">s</span></code> converges to <code class="docutils literal notranslate"><span class="pre">a</span></code> and <code class="docutils literal notranslate"><span class="pre">t</span></code> converges to <code class="docutils literal notranslate"><span class="pre">0</span></code>,
then <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">n</span> <span class="pre">↦</span> <span class="pre">s</span> <span class="pre">n</span> <span class="pre">*</span> <span class="pre">t</span> <span class="pre">n</span></code> converges to <code class="docutils literal notranslate"><span class="pre">0</span></code>.
To do so, we use the previous theorem to find a <code class="docutils literal notranslate"><span class="pre">B</span></code>
that bounds <code class="docutils literal notranslate"><span class="pre">s</span></code> beyond some point <code class="docutils literal notranslate"><span class="pre">N₀</span></code>.
See if you can understand the strategy we have outlined
and finish the proof.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ct</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span>
<span class="w"> </span><span class="n">dsimp</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">exists_abs_le_of_convergesTo</span><span class="w"> </span><span class="n">cs</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">N₀</span><span class="o">,</span><span class="w"> </span><span class="n">B</span><span class="o">,</span><span class="w"> </span><span class="n">h₀</span><span class="o">⟩</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">Bpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">lt_of_le_of_lt</span><span class="w"> </span><span class="o">(</span><span class="n">abs_nonneg</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="n">N₀</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="n">_</span><span class="o">))</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">pos₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">div_pos</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="n">Bpos</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ct</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">pos₀</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">N₁</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span>
<span class="w"> </span><span class="gr">sorry</span>
</pre></div>
</div>
<p>If you have made it this far, congratulations!
We are now within striking distance of our theorem.
The following proof finishes it off.</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_mul</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span>
<span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ct</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="n">cs</span>
<span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="n">ct</span><span class="w"> </span><span class="o">(</span><span class="n">convergesTo_const</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">b</span><span class="o">))</span>
<span class="w"> </span><span class="n">ring</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">convergesTo_mul_const</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">cs</span><span class="o">)</span>
<span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">convergesTo_mul_const</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">cs</span><span class="o">)</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="mi">1</span>
<span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">ext</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span>
<span class="w"> </span><span class="n">ring</span>
</pre></div>
</div>
<p>For another challenging exercise,
try filling out the following sketch of a proof that limits
are unique.
(If you are feeling bold,
you can delete the proof sketch and try proving it from scratch.)</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_unique</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span>
<span class="w"> </span><span class="o">(</span><span class="n">sa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">sb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span>
<span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">abne</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span>
<span class="w"> </span><span class="n">change</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span>
<span class="w"> </span><span class="n">linarith</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sa</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Na</span><span class="o">,</span><span class="w"> </span><span class="n">hNa</span><span class="o">⟩</span>
<span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sb</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Nb</span><span class="o">,</span><span class="w"> </span><span class="n">hNb</span><span class="o">⟩</span>
<span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">max</span><span class="w"> </span><span class="n">Na</span><span class="w"> </span><span class="n">Nb</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">absa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">absb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span>
<span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">this</span>
</pre></div>
</div>
<p>We close the section with the observation that our proofs can be generalized.
For example, the only properties that we have used of the
natural numbers is that their structure carries a partial order
with <code class="docutils literal notranslate"><span class="pre">min</span></code> and <code class="docutils literal notranslate"><span class="pre">max</span></code>.
You can check that everything still works if you replace <code class="docutils literal notranslate"><span class="pre">ℕ</span></code>
everywhere by any linear order <code class="docutils literal notranslate"><span class="pre">α</span></code>:</p>
<div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">LinearOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span>
<span class="kd">def</span><span class="w"> </span><span class="n">ConvergesTo'</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span>
<span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span>
</pre></div>
</div>
<p>In <a class="reference internal" href="C11_Topology.html#filters"><span class="std std-numref">Section 11.1</span></a>, we will see that Mathlib has mechanisms
for dealing with convergence in vastly more general terms,
not only abstracting away particular features of the domain
and codomain,
but also abstracting over different types of convergence.</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="C02_Basics.html" class="btn btn-neutral float-left" title="2. Basics" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="C04_Sets_and_Functions.html" class="btn btn-neutral float-right" title="4. Sets and Functions" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2020-2025, Jeremy Avigad, Patrick Massot. Text licensed under CC BY 4.0.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>