forked from jsiek/deduce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Nat.pf
2299 lines (2149 loc) · 61.4 KB
/
Nat.pf
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
import Option
union Nat {
zero
suc(Nat)
}
function operator +(Nat,Nat) -> Nat {
operator +(0, m) = m
operator +(suc(n), m) = suc(n + m)
}
function operator *(Nat,Nat) -> Nat {
operator *(0, m) = 0
operator *(suc(n), m) = m + (n * m)
}
function max(Nat,Nat) -> Nat {
max(zero, n) = n
max(suc(m'), n) =
switch n {
case zero { suc(m') }
case suc(n') { suc(max(m',n')) }
}
}
function pred(Nat) -> Nat {
pred(0) = 0
pred(suc(n)) = n
}
function operator -(Nat,Nat) -> Nat {
operator -(0, m) = 0
operator -(suc(n), m) =
switch m {
case 0 { suc(n) }
case suc(m') { n - m' }
}
}
union Pos {
one
succ(Pos)
}
function nat2pos(Nat) -> Option<Pos> {
nat2pos(0) = none
nat2pos(suc(n')) =
switch nat2pos(n') {
case none {
just(one)
}
case just(p) {
just(succ(p))
}
}
}
function pos2nat(Pos) -> Nat {
pos2nat(one) = 1
pos2nat(succ(p)) = suc(pos2nat(p))
}
function find_quotient(Nat,Nat,Pos,Nat) -> Nat {
find_quotient(0, n, m, q) = q
find_quotient(suc(u), n, m, q) =
if suc(q) * pos2nat(m) ≤ n then
(if n < u * pos2nat(m) then
find_quotient(u, n, m, suc(q))
else
u)
else
q
}
function operator /(Nat,Pos) -> Nat {
operator /(0, m) = 0
operator /(suc(n'), m) =
find_quotient(suc(suc(n')) * pos2nat(m), suc(n'), m, 0)
}
function operator%(Nat,Pos) -> Nat {
operator %(0, m) = 0
operator %(suc(n'), m) = suc(n') - (suc(n') / m) * pos2nat(m)
}
function operator ≤(Nat,Nat) -> bool {
operator ≤(0, m) = true
operator ≤(suc(n'), m) =
switch m {
case 0 { false }
case suc(m') { n' ≤ m' }
}
}
define operator < : fn Nat,Nat -> bool = λ x, y { suc(x) ≤ y }
define operator > : fn Nat,Nat -> bool = λ x, y { y < x }
define operator ≥ : fn Nat,Nat -> bool = λ x, y { y ≤ x }
function summation(Nat, Nat, fn Nat->Nat) -> Nat {
summation(0, begin, f) = 0
summation(suc(k), begin, f) = f(begin) + summation(k, suc(begin), f)
}
function iterate<T>(Nat, T, fn T -> T) -> T {
iterate(0, init, f) = init
iterate(suc(n), init, f) = f(iterate(n, init, f))
}
function pow2(Nat) -> Nat {
pow2(0) = 1
pow2(suc(n')) = 2 * pow2(n')
}
function div2(Nat) -> Nat {
div2(0) = 0
div2(suc(n')) = div2_aux(n')
}
function div2_aux(Nat) -> Nat {
div2_aux(0) = 0
div2_aux(suc(n')) = suc(div2(n'))
}
function equal(Nat, Nat) -> bool {
equal(0, n) =
switch n {
case 0 { true }
case suc(n') { false }
}
equal(suc(m'), n) =
switch n {
case 0 { false }
case suc(n') { equal(m', n') }
}
}
function dist(Nat, Nat) -> Nat {
dist(0, n) = n
dist(suc(m), n) =
switch n {
case 0 {
suc(m)
}
case suc(n) {
dist(m, n)
}
}
}
/*
Properties of Addition
*/
theorem zero_add: all n:Nat.
0 + n = n
proof
arbitrary n:Nat
conclude 0 + n = n by definition operator+
end
theorem add_zero: all n:Nat.
n + 0 = n
proof
induction Nat
case 0 {
conclude 0 + 0 = 0 by definition operator+
}
case suc(n') suppose IH: n' + 0 = n' {
equations
suc(n') + 0 = suc(n' + 0) by definition operator+
... = suc(n') by rewrite IH
}
end
lemma suc_add: all m:Nat, n:Nat.
suc(m) + n = suc(m + n)
proof
arbitrary m:Nat, n:Nat
definition operator+
end
theorem suc_one_add: all n:Nat.
suc(n) = 1 + n
proof
arbitrary n:Nat
equations
suc(n) ={ suc(0 + n) } by definition operator+
... = suc(0) + n by symmetric suc_add[0, n]
end
theorem one_add_suc: all n:Nat.
1 + n = suc(n)
proof
arbitrary n:Nat
symmetric suc_one_add[n]
end
lemma not_one_add_zero: all n:Nat.
not (1 + n = 0)
proof
arbitrary n:Nat
definition operator+
end
lemma add_suc: all m:Nat. all n:Nat.
m + suc(n) = suc(m + n)
proof
enable operator +
induction Nat
case 0 {
arbitrary n : Nat
conclude 0 + suc(n) = suc(0 + n) by .
}
case suc(n') suppose IH {
arbitrary n : Nat
equations
suc(n') + suc(n) = suc(n' + suc(n)) by .
... = suc(suc(n' + n)) by rewrite IH[n]
... = suc(suc(n') + n) by .
}
end
theorem add_commute: all n:Nat. all m:Nat. n + m = m + n
proof
enable operator +
induction Nat
case 0 {
arbitrary m : Nat
equations 0 + m = m by .
... = m + 0 by symmetric add_zero[m]
}
case suc(n') suppose IH {
arbitrary m : Nat
equations suc(n') + m = suc(n' + m) by .
... = suc(m + n') by rewrite IH[m]
... = m + suc(n') by symmetric add_suc[m][n']
}
end
theorem one_add: all m:Nat. 1 + m = suc(m)
proof
arbitrary m:Nat
definition {operator+, operator+}
end
theorem add_one: all m:Nat. m + 1 = suc(m)
proof
arbitrary m:Nat
equations
m + 1 = 1 + m by add_commute[m][1]
... = suc(m) by one_add[m]
end
theorem add_assoc: all m:Nat. all n:Nat, o:Nat.
(m + n) + o = m + (n + o)
proof
enable operator +
induction Nat
case 0 {
arbitrary n:Nat, o:Nat
conclude (0 + n) + o = 0 + (n + o) by .
}
case suc(m') suppose IH {
arbitrary n:Nat, o:Nat
equations
(suc(m') + n) + o = suc((m' + n) + o) by .
... = suc(m' + (n + o)) by rewrite IH[n,o]
... = suc(m') + (n + o) by .
}
end
theorem left_cancel: all x:Nat. all y:Nat, z:Nat.
if x + y = x + z then y = z
proof
enable operator +
induction Nat
case 0 {
arbitrary y:Nat, z:Nat
suppose prem: 0 + y = 0 + z
equations y = 0 + y by .
... = 0 + z by prem
... = z by .
}
case suc(x') suppose IH {
arbitrary y:Nat, z:Nat
suppose prem: suc(x') + y = suc(x') + z
suffices y = z by .
apply IH[y,z] to
suffices x' + y = x' + z by .
injective suc
conclude suc(x' + y) = suc(x' + z) by prem
}
end
theorem add_to_zero: all n:Nat. all m:Nat.
if n + m = 0
then n = 0 and m = 0
proof
induction Nat
case 0 {
arbitrary m:Nat
suppose zmz
have mz: m = 0
by definition operator + in zmz
rewrite mz
}
case suc(n') suppose IH {
arbitrary m:Nat
suppose snmz: suc(n') + m = 0
conclude false
by definition operator + in snmz
}
end
/*
Properties of pred
*/
theorem pred_one: pred(suc(0)) = 0
proof
definition pred
end
/*
Properties of Subtraction
*/
theorem sub_cancel: all n:Nat. n - n = 0
proof
induction Nat
case 0 {
conclude 0 - 0 = 0 by definition operator-
}
case suc(n') suppose IH: n' - n' = 0 {
equations
suc(n') - suc(n') = n' - n' by definition operator-
... = 0 by IH
}
end
theorem sub_zero: all n:Nat.
n - 0 = n
proof
induction Nat
case 0 {
conclude 0 - 0 = 0 by definition operator-
}
case suc(n') suppose IH {
conclude suc(n') - 0 = suc(n') by definition operator-
}
end
/*
Properties of Addition and Subtraction
*/
theorem add_sub_identity: all m:Nat. all n:Nat.
(m + n) - m = n
proof
induction Nat
case 0 {
arbitrary n:Nat
equations (0 + n) - 0 = n - 0 by rewrite zero_add[n]
... = n by sub_zero[n]
}
case suc(m') suppose IH {
arbitrary n:Nat
equations (suc(m') + n) - suc(m')
= suc(m' + n) - suc(m') by rewrite suc_add[m',n]
... = (m' + n) - m' by definition operator-
... = n by IH[n]
}
end
/*
Properties of Multiplication
*/
theorem zero_mult: all n:Nat.
0 * n = 0
proof
arbitrary n:Nat
definition operator*
end
theorem mult_zero: all n:Nat.
n * 0 = 0
proof
induction Nat
case 0 {
conclude 0 * 0 = 0 by definition operator*
}
case suc(n') suppose IH {
equations suc(n') * 0
= 0 + n' * 0 by definition operator*
... = n' * 0 by zero_add[n'*0]
... = 0 by IH
}
end
lemma suc_mult: all m:Nat, n:Nat.
suc(m) * n = n + m * n
proof
arbitrary m:Nat, n:Nat
definition operator*
end
lemma mult_suc: all m:Nat. all n:Nat.
m * suc(n) = m + m * n
proof
induction Nat
case 0 {
arbitrary n:Nat
equations 0 * suc(n) = 0 by zero_mult[suc(n)]
... = 0 * n by symmetric zero_mult[n]
... = 0 + 0 * n by symmetric zero_add[0*n]
}
case suc(m') suppose IH {
arbitrary n:Nat
suffices suc(n + m' * suc(n)) = suc(m' + (n + m' * n))
with definition {operator*, operator+}
equations suc(n + m' * suc(n))
= suc(n + (m' + m' * n)) by rewrite IH[n]
... ={ suc((n + m') + m' * n) } by rewrite add_assoc[n][m', m' * n]
... = suc((m' + n) + m' * n) by rewrite add_commute[n][m']
... = suc(m' + (n + m' * n)) by rewrite add_assoc[m'][n, m' * n]
}
end
theorem mult_commute: all m:Nat. all n:Nat.
m * n = n * m
proof
induction Nat
case 0 {
arbitrary n:Nat
equations 0 * n = 0 by zero_mult[n]
... = n * 0 by symmetric mult_zero[n]
}
case suc(m') suppose IH: all n:Nat. m' * n = n * m' {
arbitrary n:Nat
equations suc(m') * n
= n + m' * n by definition operator*
... = n + (n * m') by rewrite IH[n]
... = n * suc(m') by symmetric mult_suc[n][m']
}
end
theorem one_mult: all n:Nat.
1 * n = n
proof
arbitrary n:Nat
equations 1 * n = n + 0 * n by suc_mult[0,n]
... = n + 0 by rewrite zero_mult[n]
... = n by add_zero[n]
end
theorem mult_one: all n:Nat.
n * 1 = n
proof
arbitrary n:Nat
equations n * 1 = 1 * n by mult_commute[n][1]
... = n by one_mult[n]
end
theorem two_mult: all n:Nat.
2 * n = n + n
proof
arbitrary n:Nat
equations 2 * n = n + 1 * n by suc_mult[1,n]
... = n + n by rewrite one_mult[n]
end
theorem dist_mult_add:
all a:Nat. all x:Nat, y:Nat.
a * (x + y) = a * x + a * y
proof
induction Nat
case zero {
arbitrary x:Nat, y:Nat
equations 0 * (x + y)
= 0 by zero_mult[x+y]
... = 0 + 0 by symmetric add_zero[0]
... ={ 0 * x + 0 * y } by rewrite zero_mult[x] | zero_mult[y]
}
case suc(a') suppose IH {
arbitrary x:Nat, y:Nat
suffices (x + y) + a' * (x + y) = (x + a' * x) + (y + a' * y)
with definition operator *
equations
(x + y) + a' * (x + y)
= (x + y) + (a' * x + a' * y) by rewrite IH[x,y]
... = ((x + y) + a' * x) + a' * y by symmetric add_assoc[x+y][a'*x,a'*y]
... = (x + (y + a' * x)) + a' * y by rewrite add_assoc[x][y,a'*x]
... = (x + (a' * x + y)) + a' * y by rewrite add_commute[y][a'*x]
... = ((x + a' * x) + y) + a' * y by rewrite symmetric add_assoc[x][a'*x,y]
... = (x + a' * x) + (y + a' * y) by add_assoc[x+a'*x][y,a'*y]
}
end
theorem dist_mult_add_right:
all x:Nat, y:Nat, a:Nat.
(x + y) * a = x * a + y * a
proof
arbitrary x:Nat, y:Nat, a:Nat
equations
(x + y) * a = a * (x + y) by mult_commute[x+y][a]
... = a * x + a * y by dist_mult_add[a][x,y]
... = x * a + a * y by rewrite mult_commute[a][x]
... = x * a + y * a by rewrite mult_commute[a][y]
end
theorem mult_assoc: all m:Nat. all n:Nat, o:Nat.
(m * n) * o = m * (n * o)
proof
induction Nat
case 0 {
arbitrary n:Nat, o:Nat
equations (0 * n) * o = 0 * o by rewrite zero_mult[n]
... = 0 by zero_mult[o]
... = 0 * (n * o) by symmetric zero_mult[n*o]
}
case suc(m') suppose IH: all n:Nat, o:Nat. (m' * n) * o = m' * (n * o) {
arbitrary n:Nat, o:Nat
equations
(suc(m') * n) * o
= (n + m' * n) * o by definition operator*
... = n * o + (m' * n) * o by dist_mult_add_right[n, m'*n, o]
... = n * o + m' * (n * o) by rewrite IH[n,o]
... = {suc(m') * (n * o)} by definition operator*
}
end
/*
Properties of Less-Than, Greater-Than, etc.
*/
theorem suc_less_equal: all x:Nat, y:Nat.
if suc(x) ≤ suc(y)
then x ≤ y
proof
arbitrary x:Nat, y:Nat
suppose prem
definition operator≤ in prem
end
theorem suc_less_equal_suc: all x:Nat, y:Nat.
if x ≤ y
then suc(x) ≤ suc(y)
proof
arbitrary x:Nat, y:Nat
suppose prem
suffices x ≤ y with definition operator ≤
prem
end
theorem less_suc: all x:Nat, y:Nat.
if x < y
then suc(x) < suc(y)
proof
arbitrary x:Nat, y:Nat
suppose x_l_y: x < y
suffices suc(suc(x)) ≤ suc(y) with definition operator<
suffices suc(x) ≤ y with definition operator≤
definition operator< in x_l_y
end
theorem suc_less: all x:Nat, y:Nat.
if suc(x) < suc(y)
then x < y
proof
arbitrary x:Nat, y:Nat
suppose prem
suffices suc(x) ≤ y with definition operator<
apply suc_less_equal[suc(x), y] to definition operator< in prem
end
theorem less_equal_implies_less_or_equal:
all x:Nat. all y:Nat.
if x ≤ y then x < y or x = y
proof
induction Nat
case 0 {
arbitrary y:Nat
switch y {
case 0 {
.
}
case suc(y') {
suppose _
suffices suc(0) ≤ suc(y') with definition operator<
suffices 0 ≤ y' with definition operator≤
definition operator≤
}
}
}
case suc(x') suppose IH {
arbitrary y:Nat
suppose sx_le_y
switch y {
case 0 suppose yz {
conclude false by definition operator≤ in rewrite yz in sx_le_y
}
case suc(y') suppose y_sy {
have x_le_y: x' ≤ y'
by definition operator≤ in rewrite y_sy in sx_le_y
have xy_or_xy: x' < y' or x' = y'
by apply IH[y'] to x_le_y
cases xy_or_xy
case x_l_y {
have sx_l_sy: suc(x') < suc(y')
by apply less_suc to x_l_y
conclude (suc(x') < suc(y') or suc(x') = suc(y'))
by sx_l_sy
}
case x_y {
have sx_sy: suc(x') = suc(y')
by rewrite x_y
conclude (suc(x') < suc(y') or suc(x') = suc(y'))
by sx_sy
}
}
}
}
end
theorem less_implies_less_equal:
all x:Nat. all y:Nat.
if x < y then x ≤ y
proof
induction Nat
case zero {
arbitrary y:Nat
suppose _
conclude 0 ≤ y by definition operator ≤
}
case suc(x') suppose IH {
arbitrary y:Nat
suppose sx_y: suc(x') < y
have ssx_y: suc(suc(x')) ≤ y by definition operator < in sx_y
switch y {
case zero suppose yz {
conclude false by definition operator ≤ in (rewrite yz in ssx_y)
}
case suc(y') suppose EQ : y = suc(y') {
have ssx_sy: suc(suc(x')) ≤ suc(y') by rewrite EQ in ssx_y
have x_y: x' < y'
by suffices suc(x') ≤ y' with definition operator <
definition operator ≤ in ssx_sy
suffices suc(x') ≤ suc(y') by .
suffices x' ≤ y' with definition operator ≤
apply IH[y'] to x_y
}
}
}
end
theorem less_equal_refl: all n:Nat. n ≤ n
proof
enable operator ≤
induction Nat
case 0 { conclude 0 ≤ 0 by . }
case suc(n') suppose IH { conclude suc(n') ≤ suc(n') by IH }
end
theorem equal_implies_less_equal: all x:Nat, y:Nat.
if x = y then x ≤ y
proof
arbitrary x:Nat, y:Nat
suppose x_y
suffices y ≤ y with rewrite x_y
less_equal_refl[y]
end
theorem less_equal_antisymmetric:
all x:Nat. all y:Nat.
if x ≤ y and y ≤ x
then x = y
proof
induction Nat
case zero {
arbitrary y:Nat
suppose zy_yz: 0 ≤ y and y ≤ 0
switch y {
case zero { . }
case suc(y') suppose y_suc {
have sy_z: suc(y') ≤ 0 by rewrite y_suc in zy_yz
conclude false by definition operator ≤ in sy_z
}
}
}
case suc(x') suppose IH {
arbitrary y:Nat
suppose sxy_ysx: suc(x') ≤ y and y ≤ suc(x')
switch y {
case zero suppose y_z {
have sx_z: suc(x') ≤ 0 by rewrite y_z in sxy_ysx
conclude false by definition operator ≤ in sx_z
}
case suc(y') suppose y_suc {
enable operator ≤
have x_le_y: x' ≤ y' by rewrite y_suc in sxy_ysx
have y_le_x: y' ≤ x' by rewrite y_suc in sxy_ysx
have x_y: x' = y' by (apply IH[y'] to x_le_y, y_le_x)
conclude suc(x') = suc(y') by rewrite x_y
}
}
}
end
theorem less_equal_trans: all m:Nat. all n:Nat, o:Nat.
if m ≤ n and n ≤ o then m ≤ o
proof
enable operator ≤
induction Nat
case 0 {
arbitrary n:Nat, o:Nat
suppose _
conclude 0 ≤ o by .
}
case suc(m') suppose IH {
arbitrary n:Nat, o:Nat
suppose Prem: suc(m') ≤ n and n ≤ o
have sm_n: suc(m') ≤ n by Prem // bug
have n_o: n ≤ o by Prem
switch n {
case 0 suppose nz {
have sm_z: suc(m') ≤ 0 by rewrite nz in sm_n
conclude false by sm_z
}
case suc(n') suppose ns {
have sm_sn: suc(m') ≤ suc(n') by rewrite ns in sm_n
have m_n: m' ≤ n' by sm_sn
have sn_o: suc(n') ≤ o by rewrite ns in n_o
switch o {
case 0 suppose oz {
have sn_z: suc(n') ≤ 0 by rewrite oz in sn_o
conclude false by sn_z
}
case suc(o') suppose os {
have sn_so: suc(n') ≤ suc(o') by rewrite os in sn_o
have n_o: n' ≤ o' by sn_so
conclude m' ≤ o' by apply IH[n',o'] to m_n, n_o
}
}
}
}
}
end
theorem not_less_less_equal:
all x: Nat. all y: Nat.
if not (x < y) then y ≤ x
proof
induction Nat
case zero {
arbitrary y: Nat
suppose not_0_y: not (0 < y)
switch y {
case zero { definition operator ≤ }
case suc(y') suppose ys {
conclude false by apply (rewrite ys in not_0_y)
to (suffices 1 ≤ suc(y') with definition operator <
definition {operator ≤,operator ≤})
}
}
}
case suc(x') suppose IH {
arbitrary y: Nat
suppose not_sx_y: not (suc(x') < y)
switch y {
case zero { definition operator ≤ }
case suc(y') suppose ys {
have not_x_y: not (x' < y')
by (suppose x_y: x' < y'
have sx_sy: suc(x') < suc(y')
by suffices suc(suc(x')) ≤ suc(y') with definition operator <
suffices suc(x') ≤ y' with definition operator ≤
(definition operator < in x_y)
have sx_y: suc(x') < y by (suffices suc(x') < suc(y') with rewrite ys
sx_sy)
apply not_sx_y to sx_y)
suffices y' ≤ x' with definition operator ≤
apply IH[y'] to not_x_y
}
}
}
end
theorem less_irreflexive: all x:Nat. not (x < x)
proof
induction Nat
case zero {
suppose z_l_z: 0 < 0
enable {operator <, operator ≤}
conclude false by z_l_z
}
case suc(x') suppose IH: not (x' < x') {
suppose sx_l_sx: suc(x') < suc(x')
have x_l_x: x' < x' by apply suc_less to sx_l_sx
conclude false by apply IH to x_l_x
}
end
theorem less_not_greater_equal:
all x:Nat. all y:Nat.
if x < y then not (y ≤ x)
proof
induction Nat
case zero {
arbitrary y : Nat
suppose z_l_y: 0 < y
suppose y_le_z: y ≤ 0
switch y {
case zero suppose y_z: y = 0 {
definition {operator <, operator ≤}
in (rewrite y_z in z_l_y)
}
case suc(y') suppose y_s: y = suc(y') {
definition {operator ≤}
in (rewrite y_s in y_le_z)
}
}
}
case suc(x') suppose IH {
arbitrary y : Nat
suppose sx_less_y
suppose y_le_sx
switch y {
case zero suppose y_eq_zero {
enable {operator <, operator ≤}
conclude false by rewrite y_eq_zero in sx_less_y
}
case suc(y') suppose ys {
enable {operator <, operator ≤}
have x_less_y: x' < y' by rewrite ys in sx_less_y
have y_le_x: y' ≤ x' by rewrite ys in y_le_sx
conclude false by apply (apply IH[y'] to x_less_y) to y_le_x
}
}
}
end
theorem less_not_equal: all x:Nat, y:Nat.
if x < y then not (x = y)
proof
arbitrary x:Nat, y:Nat
suppose x_l_y: x < y
suppose x_y: x = y
have y_l_y: y < y by rewrite x_y in x_l_y
conclude false by apply less_irreflexive[y] to y_l_y
end
theorem greater_not_equal: all x:Nat, y:Nat.
if x > y then not (x = y)
proof
arbitrary x:Nat, y:Nat
suppose x_g_y: x > y
suppose x_y: x = y
have y_g_y: y > y by rewrite x_y in x_g_y
have y_l_y: y < y by definition operator> in y_g_y
conclude false by apply less_irreflexive[y] to y_l_y
end
theorem less_implies_not_less_equal:
all x:Nat. all y:Nat.
if x < y then not (y ≤ x)
proof
induction Nat
case zero {
arbitrary y:Nat
suppose y_pos
suppose y_le_z
switch y {
case 0 suppose y_z {
conclude false by definition {operator <, operator≤} in
rewrite y_z in y_pos
}
case suc(y') suppose y_sy {
conclude false by definition operator≤ in rewrite y_sy in y_le_z
}
}
}
case suc(x') suppose IH {
arbitrary y:Nat
suppose sx_l_y
suppose y_le_sx
switch y {
case 0 suppose y_z {
conclude false by definition{operator<, operator≤} in
rewrite y_z in sx_l_y
}
case suc(y') suppose y_sy {
have x_l_y: x' < y'
by suffices suc(x') ≤ y' with definition operator<
definition {operator ≤} in
definition {operator<} in rewrite y_sy in sx_l_y
have y_le_x: y' ≤ x'
by definition operator≤ in rewrite y_sy in y_le_sx
conclude false by apply (apply IH[y'] to x_l_y) to y_le_x
}
}
}
end
theorem less_implies_not_greater:
all x:Nat. all y:Nat.
if x < y then not (y < x)
proof
induction Nat
case zero {
arbitrary y:Nat
suppose zero_less_y
suppose y_less_zero
conclude false by (definition {operator <, operator ≤} in y_less_zero)
}
case suc(x') suppose IH {
arbitrary y:Nat
suppose sx_less_y
suppose y_less_sx
switch y {
case zero suppose y_eq_zero {
conclude false by (definition {operator <, operator ≤} in
(rewrite y_eq_zero in sx_less_y))
}
case suc(y') suppose ys {
enable {operator<,operator≤}
have x_less_y: x' < y' by rewrite ys in sx_less_y
have y_less_x: y' < x' by rewrite ys in y_less_sx
conclude false by apply (apply IH[y'] to x_less_y) to y_less_x
}
}
}
end
theorem trichotomy:
all x:Nat. all y:Nat.
x < y or x = y or y < x
proof
induction Nat
case zero {
arbitrary y:Nat
switch y {
case zero { conclude 0 = 0 by . }
case suc(y') {
enable {operator <, operator ≤, operator ≤}
conclude 0 < suc(y') by .
}
}
}
case suc(x') suppose IH {
arbitrary y:Nat
switch y {
case zero {
conclude 0 < suc(x')
by definition {operator<, operator≤, operator≤}
}
case suc(y') {
have IH': (x' < y' or x' = y' or y' < x') by IH[y']
cases IH'
case less { conclude suc(x') < suc(y')
by suffices suc(suc(x')) ≤ suc(y') with definition operator <
suffices suc(x') ≤ y' with definition operator ≤
definition operator < in less
}
case equal { conclude suc(x') = suc(y') by rewrite equal }
case greater {
conclude suc(y') < suc(x')
by suffices suc(suc(y')) ≤ suc(x') with definition operator <
suffices suc(y') ≤ x' with definition operator ≤
definition operator < in greater
}
}
}
}
end
theorem trichotomy2:
all y:Nat, x:Nat.
if not (x = y) and not (x < y)
then y < x
proof
arbitrary y:Nat, x:Nat
suppose prem: not (x = y) and not (x < y)
cases trichotomy[x][y]
case less: x < y {
have not_less: not (x < y) by prem
conclude false by apply not_less to less
}
case equal: x = y {
have not_equal: not (x = y) by prem
conclude false by apply not_equal to equal
}
case greater: y < x {
conclude y < x by greater
}
end
theorem positive_1_and_2: 0 ≤ 1 and 0 ≤ 2