-
Notifications
You must be signed in to change notification settings - Fork 165
/
Sorting.alfa
537 lines (501 loc) · 25.8 KB
/
Sorting.alfa
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
{- \section{Introduction}
In this document, we prove the correctness of insertion sort.
\subsection{Preliminaries}
In the sections below, we rely on various definitions stated in the
following separate documents:
-}
--#include "Sorting/predikatlogik.alfa"
--#include "Sorting/satslogik.alfa"
--#include "Sorting/decide.alfa"
--#include "Sorting/nat.alfa"
{- \section{Miscellaneuos definitions and lemmas}
Here we define what a list is, what it means for a list to be sorted (ordered)
and how to insert a new element at the right position in a sorted list.
-}
List (A::Set) :: Set
= data Nil | Cons (x::A) (xs::List A)
singleton (A::Set)(x::A) :: List A
= Cons@_ x Nil@_
IsLeAll (x::Nat)(xs::List Nat) :: Prop
= case xs of -- use layout!
(Nil) -> Triviality
(Cons x' xs') -> And (LeNat x x') (IsLeAll x xs')
IsSorted (xs::List Nat) :: Prop
= case xs of {
(Nil) -> Triviality;
(Cons x xs') -> And (IsLeAll x xs') (IsSorted xs');}
{-
Regarding the above definition of what it means for a list to be sorted, it is
worth noting that, for empty lists, there is nothing to prove, and for
non-empty lists, there are two things to prove.
-}
insert (x::Nat)(xs::List Nat) :: List Nat
= case xs of {
(Nil) -> singleton Nat x;
(Cons x' xs') -> ifLt (List Nat) x x' (Cons@_ x xs) (Cons@_ x' (insert x xs'));}
IsLeFirst (a::Nat)
(x::Nat)
(xs::List Nat)
(ax::LeNat a x)
(p::IsSorted (Cons@_ x xs))
:: IsLeAll a (Cons@_ x xs)
= case xs of {
(Nil) ->
let ndgoal :: IsLeAll a (Cons@_ x Nil@_)
= AndIntro (LeNat a x) (IsLeAll a Nil@_)
(let ndgoal :: LeNat a x
= ax
in ndgoal)
(let ndgoal :: IsLeAll a Nil@_
= trivial
in ndgoal)
in ndgoal;
(Cons x' xs') ->
let ndgoal :: IsLeAll a (Cons@_ x (Cons@_ x' xs'))
= AndIntro (LeNat a x) (IsLeAll a (Cons@_ x' xs'))
(let ndgoal :: LeNat a x
= ax
in ndgoal)
(let ndgoal :: IsLeAll a (Cons@_ x' xs')
= AndElim (IsLeAll x (Cons@_ x' xs')) (IsSorted (Cons@_ x' xs'))
(IsLeAll a (Cons@_ x' xs'))
(let ndgoal :: IsSorted (Cons@_ x xs)
= p
in ndgoal)
(\(h::IsLeAll x (Cons@_ x' xs')) ->
\(h'::IsSorted (Cons@_ x' xs')) ->
let ndgoal :: IsLeAll a (Cons@_ x' xs')
= AndElim (LeNat x x') (IsLeAll x xs')
(IsLeAll a (Cons@_ x' xs'))
(let ndgoal :: And (LeNat x x') (IsLeAll x xs')
= h
in ndgoal)
(\(h0::LeNat x x') ->
\(h1::IsLeAll x xs') ->
let ndgoal :: IsLeAll a (Cons@_ x' xs')
= IsLeFirst a x' xs'
(let ndgoal :: LeNat a x'
= letrans a x x'
(let ndgoal :: LeNat a x
= ax
in ndgoal)
(let ndgoal :: LeNat x x'
= h0
in ndgoal)
in ndgoal)
(let ndgoal :: IsSorted (Cons@_ x' xs')
= h'
in ndgoal)
in ndgoal)
in ndgoal)
in ndgoal)
in ndgoal;}
ThInsertInSorted (x::Nat)(xs::List Nat)(p::IsSorted xs)
:: IsSorted (insert x xs)
= case xs of {
(Nil) ->
let ndgoal :: IsSorted (insert x Nil@_)
= AndIntro (IsLeAll x Nil@_) (IsSorted Nil@_)
(let ndgoal :: IsLeAll x Nil@_
= trivial
in ndgoal)
(let ndgoal :: IsSorted Nil@_
= trivial
in ndgoal)
in ndgoal;
(Cons x' xs') ->
ifLtCase (List Nat) (\(h::List Nat) -> IsSorted h) x x'
(Cons@_ x (Cons@_ x' xs'))
(Cons@_ x' (insert x xs'))
(\(h::LeNat x x') ->
let ndgoal :: IsSorted (Cons@_ x (Cons@_ x' xs'))
= AndIntro (IsLeAll x (Cons@_ x' xs')) (IsSorted (Cons@_ x' xs'))
(let ndgoal :: IsLeAll x (Cons@_ x' xs')
= IsLeFirst x x' xs'
(let ndgoal :: LeNat x x'
= h
in ndgoal)
(let ndgoal :: IsSorted (Cons@_ x' xs')
= p
in ndgoal)
in ndgoal)
(let ndgoal :: IsSorted (Cons@_ x' xs')
= p
in ndgoal)
in ndgoal)
(\(h::Not (LeNat x x')) ->
let indhyp :: IsSorted (insert x xs')
= let ndgoal :: IsSorted (insert x xs')
= ThInsertInSorted x xs'
(let ndgoal :: IsSorted xs'
= And2Elim (IsLeAll x' xs') (IsSorted xs')
(let ndgoal :: And (IsLeAll x' xs') (IsSorted xs')
= p
in ndgoal)
in ndgoal)
in ndgoal
lemma1 :: LeNat x' x
= leSym x x' h
lemma2 (x'::Nat)(x::Nat)(xs'::List Nat)(px::LeNat x' x)(pxs::IsLeAll x' xs')
:: IsLeAll x' (insert x xs')
= case xs' of {
(Nil) ->
let ndgoal :: IsLeAll x' (insert x Nil@_)
= AndIntro (LeNat x' x) (IsLeAll x' Nil@_) px trivial
in ndgoal;
(Cons x0 xs0) ->
ifLtCase (List Nat) (\(h'::List Nat) -> IsLeAll x' h') x x0
(Cons@_ x (Cons@_ x0 xs0))
(Cons@_ x0 (insert x xs0))
(\(h'::LeNat x x0) ->
let ndgoal :: IsLeAll x' (Cons@_ x (Cons@_ x0 xs0))
= AndIntro (LeNat x' x) (IsLeAll x' (Cons@_ x0 xs0))
(let ndgoal :: LeNat x' x
= px
in ndgoal)
(let ndgoal :: IsLeAll x' (Cons@_ x0 xs0)
= pxs
in ndgoal)
in ndgoal)
(\(h'::Not (LeNat x x0)) ->
let ndgoal :: IsLeAll x' (Cons@_ x0 (insert x xs0))
= AndElim (LeNat x' x0) (IsLeAll x' xs0)
(IsLeAll x' (Cons@_ x0 (insert x xs0)))
(let ndgoal :: And (LeNat x' x0) (IsLeAll x' xs0)
= pxs
in ndgoal)
(\(h0::LeNat x' x0) ->
\(h1::IsLeAll x' xs0) ->
let ndgoal :: IsLeAll x' (Cons@_ x0 (insert x xs0))
= AndIntro (LeNat x' x0) (IsLeAll x' (insert x xs0))
(let ndgoal :: LeNat x' x0
= h0
in ndgoal)
(let ndgoal :: IsLeAll x' (insert x xs0)
= lemma2 x' x xs0
(let ndgoal :: LeNat x' x
= px
in ndgoal)
(let ndgoal :: IsLeAll x' xs0
= h1
in ndgoal)
in ndgoal)
in ndgoal)
in ndgoal);}
in let ndgoal :: IsSorted (Cons@_ x' (insert x xs'))
= AndIntro (IsLeAll x' (insert x xs')) (IsSorted (insert x xs'))
(let ndgoal :: IsLeAll x' (insert x xs')
= lemma2 x' x xs'
(let ndgoal :: LeNat x' x
= lemma1
in ndgoal)
(let ndgoal :: IsLeAll x' xs'
= And1Elim (IsLeAll x' xs') (IsSorted xs')
(let ndgoal :: And (IsLeAll x' xs') (IsSorted xs')
= p
in ndgoal)
in ndgoal)
in ndgoal)
(let ndgoal :: IsSorted (insert x xs')
= indhyp
in ndgoal)
in ndgoal);}
{- \section{Definitions and lemmas relating to permutations}
-}
count (x::Nat)(xs::List Nat) :: Nat
= case xs of {
(Nil) -> Zero@_;
(Cons x' xs') -> ifEq Nat x x' (Succ@_ (count x xs')) (count x xs');}
Permutation (xs::List Nat)(ys::List Nat) :: Prop
= ForAll Nat (\(n::Nat) -> EqNat (count n xs) (count n ys))
ThPermNil :: Permutation Nil@_ Nil@_
= let ndgoal :: Permutation Nil@_ Nil@_
= ForAllIntro Nat (\(n::Nat) -> EqNat (count n Nil@_) (count n Nil@_))
(\(any::Nat) ->
let ndgoal :: EqNat (count any Nil@_) (count any Nil@_)
= trivial
in ndgoal)
in ndgoal
ThPermCons (x::Nat)(ys::List Nat)(zs::List Nat)(p::Permutation ys zs)
:: Permutation (Cons@_ x ys) (Cons@_ x zs)
= {-#H#-}ForAllIntro Nat
(\(n::Nat) -> EqNat (count n (Cons@_ x ys)) (count n (Cons@_ x zs)))
(\(n::Nat) ->
ifEqCase Nat (\(h::Nat) -> EqNat h (count n (Cons@_ x zs))) n x
(Succ@_ (count n ys))
(count n ys)
(\(h::EqNat n x) ->
ifEqCase Nat (\(h'::Nat) -> EqNat (Succ@_ (count n ys)) h') n x
(Succ@_ (count n zs))
(count n zs)
(\(h'::EqNat n x) ->
ForAllElim Nat (\(h0::Nat) -> EqNat (count h0 ys) (count h0 zs)) n p)
(\(h'::Not (EqNat n x)) ->
AbsurdityElim (EqNat (Succ@_ (count n ys)) (count n zs))
(ImpliesElim (EqNat n x) Absurdity h' h)))
(\(h::Not (EqNat n x)) ->
ifEqCase Nat (\(h'::Nat) -> EqNat (count n ys) h') n x (Succ@_ (count n zs))
(count n zs)
(\(h'::EqNat n x) ->
AbsurdityElim (EqNat (count n ys) (Succ@_ (count n zs)))
(ImpliesElim (EqNat n x) Absurdity h h'))
(\(h'::Not (EqNat n x)) ->
ForAllElim Nat (\(h0::Nat) -> EqNat (count h0 ys) (count h0 zs)) n p)))
ThPermTrans (xs::List Nat)
(ys::List Nat)
(zs::List Nat)
(xy::Permutation xs ys)
(yz::Permutation ys zs)
:: Permutation xs zs
= ForAllIntro Nat (\(n::Nat) -> EqNat (count n xs) (count n zs))
(\(any::Nat) ->
trans (count any xs) (count any ys) (count any zs)
(ForAllElim Nat (\(h::Nat) -> EqNat (count h xs) (count h ys)) any xy)
(ForAllElim Nat (\(h::Nat) -> EqNat (count h ys) (count h zs)) any yz))
ThPermSwap (x1::Nat)(x2::Nat)(xs::List Nat)
:: Permutation (Cons@_ x1 (Cons@_ x2 xs)) (Cons@_ x2 (Cons@_ x1 xs))
= {-#H#-}ForAllIntro Nat
(\(n::Nat) ->
EqNat (count n (Cons@_ x1 (Cons@_ x2 xs))) (count n (Cons@_ x2 (Cons@_ x1 xs))))
(\(any::Nat) ->
ifEqCase Nat (\(h'::Nat) -> EqNat h' (count any (Cons@_ x2 (Cons@_ x1 xs)))) any
x1
(Succ@_ (count any (Cons@_ x2 xs)))
(count any (Cons@_ x2 xs))
(\(h'::EqNat any x1) ->
ifEqCase Nat (\(h::Nat) -> EqNat (Succ@_ (count any (Cons@_ x2 xs))) h) any x2
(Succ@_ (count any (Cons@_ x1 xs)))
(count any (Cons@_ x1 xs))
(\(h::EqNat any x2) ->
ifEqCase Nat (\(h0::Nat) -> EqNat h0 (count any (Cons@_ x1 xs))) any x2
(Succ@_ (count any xs))
(count any xs)
(\(h0::EqNat any x2) ->
ifEqCase Nat (\(h1::Nat) -> EqNat (Succ@_ (count any xs)) h1) any x1
(Succ@_ (count any xs))
(count any xs)
(\(h1::EqNat any x1) -> refl (count any xs))
(\(h1::Not (EqNat any x1)) ->
AbsurdityElim (EqNat (Succ@_ (count any xs)) (count any xs))
(ImpliesElim (EqNat any x1) Absurdity h1 h')))
(\(h0::Not (EqNat any x2)) ->
AbsurdityElim (EqNat (count any xs) (count any (Cons@_ x1 xs)))
(ImpliesElim (EqNat any x2) Absurdity h0 h)))
(\(h::Not (EqNat any x2)) ->
ifEqCase Nat (\(h0::Nat) -> EqNat (Succ@_ (count any (Cons@_ x2 xs))) h0) any x1
(Succ@_ (count any xs))
(count any xs)
(\(h0::EqNat any x1) ->
ifEqCase Nat (\(h1::Nat) -> EqNat h1 (count any xs)) any x2
(Succ@_ (count any xs))
(count any xs)
(\(h1::EqNat any x2) ->
AbsurdityElim (EqNat (Succ@_ (count any xs)) (count any xs))
(ImpliesElim (EqNat any x2) Absurdity h h1))
(\(h1::Not (EqNat any x2)) -> refl (count any xs)))
(\(h0::Not (EqNat any x1)) ->
AbsurdityElim (EqNat (Succ@_ (count any (Cons@_ x2 xs))) (count any xs))
(ImpliesElim (EqNat any x1) Absurdity h0 h'))))
(\(h'::Not (EqNat any x1)) ->
ifEqCase Nat (\(h0::Nat) -> EqNat (count any (Cons@_ x2 xs)) h0) any x2
(Succ@_ (count any (Cons@_ x1 xs)))
(count any (Cons@_ x1 xs))
(\(h0::EqNat any x2) ->
ifEqCase Nat (\(h::Nat) -> EqNat h (Succ@_ (count any (Cons@_ x1 xs)))) any x2
(Succ@_ (count any xs))
(count any xs)
(\(h::EqNat any x2) ->
ifEqCase Nat (\(h1::Nat) -> EqNat (count any xs) h1) any x1
(Succ@_ (count any xs))
(count any xs)
(\(h1::EqNat any x1) ->
AbsurdityElim (EqNat (count any xs) (Succ@_ (count any xs)))
(ImpliesElim (EqNat any x1) Absurdity h' h1))
(\(h1::Not (EqNat any x1)) -> refl (count any xs)))
(\(h::Not (EqNat any x2)) ->
AbsurdityElim (EqNat (count any xs) (Succ@_ (count any (Cons@_ x1 xs))))
(ImpliesElim (EqNat any x2) Absurdity h h0)))
(\(h::Not (EqNat any x2)) ->
ifEqCase Nat (\(h0::Nat) -> EqNat h0 (count any (Cons@_ x1 xs))) any x2
(Succ@_ (count any xs))
(count any xs)
(\(h0::EqNat any x2) ->
AbsurdityElim (EqNat (Succ@_ (count any xs)) (count any (Cons@_ x1 xs)))
(ImpliesElim (EqNat any x2) Absurdity h h0))
(\(h0::Not (EqNat any x2)) ->
ifEqCase Nat (\(h1::Nat) -> EqNat (count any xs) h1) any x1
(Succ@_ (count any xs))
(count any xs)
(\(h1::EqNat any x1) ->
AbsurdityElim (EqNat (count any xs) (Succ@_ (count any xs)))
(ImpliesElim (EqNat any x1) Absurdity h' h1))
(\(h1::Not (EqNat any x1)) -> refl (count any xs))))))
ThPermInsert (x::Nat)(xs::List Nat) :: Permutation (Cons@_ x xs) (insert x xs)
= case xs of {
(Nil) ->
ForAllIntro Nat
(\(n::Nat) -> EqNat (count n (Cons@_ x Nil@_)) (count n (insert x Nil@_)))
(\(any::Nat) -> refl (count any (Cons@_ x Nil@_)));
(Cons x' xs') ->
ifLtCase (List Nat) (\(h::List Nat) -> Permutation (Cons@_ x (Cons@_ x' xs')) h)
x
x'
(Cons@_ x (Cons@_ x' xs'))
(Cons@_ x' (insert x xs'))
(\(h::LeNat x x') ->
ForAllIntro Nat
(\(n::Nat) ->
EqNat (count n (Cons@_ x (Cons@_ x' xs'))) (count n (Cons@_ x (Cons@_ x' xs'))))
(\(any::Nat) -> refl (count any (Cons@_ x (Cons@_ x' xs')))))
(\(h::Not (LeNat x x')) ->
let indhyp :: Permutation (Cons@_ x xs') (insert x xs')
= ThPermInsert x xs'
in let it :: Permutation (Cons@_ x (Cons@_ x' xs')) (Cons@_ x' (insert x xs'))
= ThPermTrans (Cons@_ x (Cons@_ x' xs')) (Cons@_ x' (Cons@_ x xs'))
(Cons@_ x' (insert x xs'))
(ThPermSwap x x' xs')
(ThPermCons x' (Cons@_ x xs') (insert x xs') indhyp)
in it);}
{-
\section{The sorting algorithm, the correctness criterion and
the correctness proof}
-}
sort (xs::List Nat) :: List Nat
= case xs of {
(Nil) -> Nil@_;
(Cons x xs') -> insert x (sort xs');}
SortSpec (xs::List Nat)(ys::List Nat) :: Prop
= And (Permutation xs ys) (IsSorted ys)
-- %% Although SortLemma is only used in ThSortIsCorrect, I made it global to be able to specify linearization properties for it.
SortLemma (x::Nat)(xs'::List Nat)(h::Permutation xs' (sort xs'))
:: Permutation (Cons@_ x xs') (sort (Cons@_ x xs'))
= let ndgoal :: Permutation (Cons@_ x xs') (sort (Cons@_ x xs'))
= ThPermTrans (Cons@_ x xs') (Cons@_ x (sort xs')) (sort (Cons@_ x xs'))
(let ndgoal :: Permutation (Cons@_ x xs') (Cons@_ x (sort xs'))
= ThPermCons x xs' (sort xs')
(let ndgoal :: Permutation xs' (sort xs')
= h
in ndgoal)
in ndgoal)
(let ndgoal :: Permutation (Cons@_ x (sort xs')) (sort (Cons@_ x xs'))
= ThPermInsert x (sort xs')
in ndgoal)
in ndgoal
ThSortIsCorrect (xs::List Nat) :: SortSpec xs (sort xs)
= case xs of {
(Nil) ->
let ndgoal :: SortSpec Nil@_ (sort Nil@_)
= AndIntro (Permutation Nil@_ (sort Nil@_)) (IsSorted (sort Nil@_))
(let ndgoal :: Permutation Nil@_ (sort Nil@_)
= ThPermNil
in ndgoal)
(let ndgoal :: IsSorted (sort Nil@_)
= trivial
in ndgoal)
in ndgoal;
(Cons x xs') ->
let indhyp :: SortSpec xs' (sort xs')
= ThSortIsCorrect xs'
in let ndgoal :: SortSpec (Cons@_ x xs') (sort (Cons@_ x xs'))
= AndElim (Permutation xs' (sort xs')) (IsSorted (sort xs'))
(SortSpec (Cons@_ x xs') (sort (Cons@_ x xs')))
(let ndgoal :: SortSpec xs' (sort xs')
= indhyp
in ndgoal)
(\(h::Permutation xs' (sort xs')) ->
\(h'::IsSorted (sort xs')) ->
let ndgoal :: SortSpec (Cons@_ x xs') (sort (Cons@_ x xs'))
= AndIntro (Permutation (Cons@_ x xs') (sort (Cons@_ x xs')))
(IsSorted (sort (Cons@_ x xs')))
(let ndgoal :: Permutation (Cons@_ x xs') (sort (Cons@_ x xs'))
= SortLemma x xs'
(let ndgoal :: Permutation xs' (sort xs')
= h
in ndgoal)
in ndgoal)
(let ndgoal :: IsSorted (sort (Cons@_ x xs'))
= ThInsertInSorted x (sort xs')
(let ndgoal :: IsSorted (sort xs')
= h'
in ndgoal)
in ndgoal)
in ndgoal)
in ndgoal;}
-- \section{A simple corollary}
ThSorting
:: ForAll (List Nat)
(\(xs::List Nat) -> Exists (List Nat) (\(ys::List Nat) -> SortSpec xs ys))
= let ndgoal
:: ForAll (List Nat)
(\(xs::List Nat) -> Exists (List Nat) (\(ys::List Nat) -> SortSpec xs ys))
= ForAllIntro (List Nat)
(\(xs::List Nat) -> Exists (List Nat) (\(ys::List Nat) -> SortSpec xs ys))
(\(xs::List Nat) ->
let ndgoal :: Exists (List Nat) (\(ys::List Nat) -> SortSpec xs ys)
= ExistsIntro (List Nat) (\(ys::List Nat) -> SortSpec xs ys) (sort xs)
(let ndgoal :: SortSpec xs (sort xs)
= ThSortIsCorrect xs
in ndgoal)
in ndgoal)
in ndgoal
sortfun :: List Nat -> List Nat
= \(xs::List Nat) -> sort xs
ThSorting2 =
ExistsIntro (List Nat -> List Nat)
(\(f::List Nat -> List Nat) ->
ForAll (List Nat) (\(xs::List Nat) -> SortSpec xs (f xs)))
sortfun
(ForAllIntro (List Nat) (\(xs::List Nat) -> SortSpec xs (sort xs))
(\(any::List Nat) -> ThSortIsCorrect any))
{-# Alfa hiding on
var "if" hide 2
con "Nil" as "[]"
con "Cons" infix rightassoc 5 as ":"
var "ThPermTrans" hide 3
var "ThPermCons" hide 3
var "ThPermInsert" hide 2
var "ThInsertInSorted" hide 2
var "Permutation" infix 4 as "~" with symbolfont
var "List" mixfix 0 as "[_]"
var "IsLeFirst" hide 3
var "singleton" hide 1 mixfix 0 as "[_]"
var "listInd" hide 2
var "SortLemma" hide 2
#-}
{-# GF Eng insert x xs = mkPN (["the list with"]++x.s!pnv++["inserted into"]++xs.s!pnv) #-}
{-# GF Eng IsLeAll x xs = mkSent (x.s!pnv++["is less than or equal to all the elements of"]++xs.s!pnv) #-}
{-# GF Eng IsLeFirst a x xs ax p =
mkText (ax.s!text++"."++p.s!text++
[". This means that "]++
a.s!pnv++["is less than or equal to all the elements of the list with"]++
x.s!pnv++["prepended to"]++xs.s!pnv) #-}
{-# GF Eng SortLemma x xs' h =
mkText (h.s!text++[". Use SortLemma"]) #-}
{-# GF Eng ThInsertInSorted x xs p =
mkText (p.s!text++[". Use the correctness of insertion"]) #-}
{-# GF Eng ThPermNil = mkThm ["the permutation of empty list theorem"] #-}
{-# GF Eng ThPermCons x ys zs p =
mkText (p.s!text++
[". We can now use the theorem about prepending an element to permutations"]) #-}
{-# GF Eng ThPermTrans xs ys zs xy yz =
mkText (indent("·"++xy.s!text++"."++newParagraph++"·"++yz.s!text)++
[". By the transitivity of the permutation relation,"]++
zs.s!pnv++"is a permutation of"++xs.s!pnv) #-}
{-# GF Eng ThPermInsert x xs = mkThm ["the theorem that inserting yields a permutation of prepending"] #-}
{-# GF Sve IsLeAll x xs = mkSent (x.s!pn++["är mindre än alla element i"]++xs.s!pn) #-}
{-# GF Sve CCCons x xs = mkPN (["listan med"]++x.s!pn++["insatt först i"]++xs.s!pn) en #-}
{-# GF Sve singleton A x = mkPN (["enelementslistan med"]++x.s!pn) en #-}
{-# GF Sve CCNil = mkPN ["den tomma listan"] en #-}
{-# GF Sve List A = {s = tbl {n => ("list"+nomReg1!n)++"av" ++ A.s ! (cn pl)} ; form = CN en} #-}
{-# GF Eng ThSortIsCorrect xs = mkThm(["the correctness of insertion sort applied to"]++xs.s!pnv) #-}
{-# GF Eng ThSorting = mkThm ["a sorting theorem"] #-}
{-# GF Eng SortSpec xs ys = mkSent(ys.s!pnv++["is a sorted version of"]++xs.s!pnv) #-}
{-# GF Eng sort xs = mkPN(["insertion sort applied to"]++xs.s!pnv) #-}
{-# GF Eng sortfun xs = mkPN(["insertion sort"]) #-}
{-# GF Eng List A = mkCN(tbl {n=>("list"+nomReg!n)++"of"++A.s!(cn pl)}) #-}
{-# GF Eng Permutation xs ys = mkSent(ys.s!pnv++["is a permutation of"]++xs.s!pnv) #-}
{-# GF Eng count x xs = mkPN(["the number of occurences of"]++x.s!pnv++"in"++xs.s!pnv) #-}
{-# GF Eng singleton A x = mkPN(["the singleton list containing"]++x.s!pnv) #-}
{-# GF Eng IsSorted xs = mkSent (xs.s!pnv ++ ["is sorted"]) #-}
{-# GF Eng CCCons x xs = mkPN (["the list with"]++x.s!pnv++["prepended to"]++xs.s!pnv) #-}
{-# GF Eng CCNil = mkPN ["the empty list"] #-}