1#!nobacktrace
2(library (srfi srfi-1)
3  (export
4   ;; constructors
5   xcons
6   list
7   cons*
8   make-list
9   list-tabulate
10   list-copy
11   circular-list
12   iota
13   ;; predicates
14   pair?
15   null?
16   (rename (list? proper-list?))
17   circular-list?
18   dotted-list?
19   not-pair?
20   (rename (null? null-list?))
21   list=
22   ;; selectors
23   car cdr
24   caar cadr cdar cddr
25   caaar caadr cadar caddr
26   cdaar cdadr cddar cdddr
27   caaaar caaadr caadar caaddr
28   cadaar cadadr caddar cadddr
29   cdaaar cdaadr cdadar cdaddr
30   cddaar cddadr cdddar cddddr
31   list-ref
32   first
33   second
34   third
35   fourth
36   fifth
37   sixth
38   seventh
39   eighth
40   ninth
41   tenth
42   car+cdr
43   take
44   (rename (take take!))
45   drop
46   take-right
47   drop-right
48   (rename (drop-right drop-right!))
49   split-at
50   (rename (split-at split-at!))
51   last
52   last-pair
53   ;; miscellaneous: length, append, concatenate, reverse, zip & count
54   length
55   length+
56   append
57   (rename (append append!))
58   concatenate
59   (rename (concatenate concatenate!))
60   reverse
61   (rename (reverse reverse!))
62   append-reverse
63   (rename (append-reverse append-reverse!))
64   zip
65   unzip1 unzip2 unzip3 unzip4 unzip5
66   count
67   ;; fold, unfold & map
68   map
69   (rename (map map!))
70   map/srfi-1
71   (rename (map/srfi-1 map!/srfi-1))
72   for-each
73   for-each/srfi-1
74   fold
75   fold-right
76   fold-right/srfi-1
77   unfold
78   pair-fold
79   (rename (fold reduce))
80   unfold-right
81   pair-fold-right
82   (rename (fold-right/srfi-1 reduce-right))
83   append-map
84   (rename (append-map append-map!))
85   pair-for-each
86   filter-map
87   map-in-order
88   ;; filtering & partitioning
89   filter
90   (rename (filter filter!))
91   partition
92   (rename (partition partition!))
93   (rename (remp remove/srfi-1))
94   (rename (remp remove!/srfi-1))
95   ;; seaching
96   member
97   member/srfi-1
98   memq
99   memv
100   find
101   find-tail
102   any
103   every
104   list-index
105   take-while
106   (rename (take-while take-while!))
107   drop-while
108   span
109   (rename (span span!))
110   break
111   (rename (break break!))
112   ;; deleting
113   delete
114   (rename (delete delete!))
115   delete-duplicates
116   (rename (delete-duplicates delete-duplicates!))
117   ;; association lists
118   assoc
119   assoc/srfi-1
120   assq
121   assv
122   alist-cons
123   alist-copy
124   alist-delete
125   (rename (alist-delete alist-delete!))
126   ;; set operations on lists
127   lset<=
128   lset=
129   lset-adjoin
130   (rename (lset-adjoin lset-adjoin!))
131   lset-union
132   (rename (lset-union lset-union!))
133   lset-intersection
134   (rename (lset-intersection lset-intersection!))
135   lset-difference
136   (rename (lset-difference lset-difference!))
137   lset-xor
138   (rename (lset-xor lset-xor!))
139   lset-diff+intersection
140   (rename (lset-diff+intersection lset-diff+intersection!)))
141   ;; procedures conflict with r6rs
142   #;(rename (map/srfi-1 map)
143             (map!/srfi-1 map!)
144             (for-each/srfi-1 for-each)
145             (fold-right/srfi-1 fold-right)
146             (member/srfi-1 member)
147             (assoc/srfi-1 assoc)
148             (remove/srfi-1 remove)
149             (remove!/srfi-1 remove!))
150  (import (except (core) remp))
151
152  (define xcons (lambda (d a) (cons a d)))
153
154  (define list-tabulate
155    (lambda (n proc)
156      (let loop ((lst '()) (n (- n 1)))
157        (cond ((< n 0) lst)
158              (else (loop (cons (proc n) lst) (- n 1)))))))
159
160  (define circular-list
161    (lambda lst
162      (let ((lst (list-copy lst)))
163        (begin (set-cdr! (last-pair lst) lst) lst))))
164
165  (define dotted-list?
166    (lambda (lst)
167      (not (let loop ((head lst) (tail lst))
168             (or (and (pair? head)
169                      (or (and (pair? (cdr head))
170                               (or (eq? (cdr head) tail)
171                                   (loop (cddr head) (cdr tail))))
172                          (null? (cdr head))))
173                 (null? head))))))
174
175  (define not-pair?
176    (lambda (x)
177      (not (pair? x))))
178
179  (define list=
180    (lambda (proc . lists)
181      (define list-equal-1
182        (lambda (lst)
183          (let loop ((lst1 (car lists)) (lst2 lst))
184            (if (null? lst1)
185                (null? lst2)
186                (and (proc (car lst1) (car lst2))
187                     (loop (cdr lst1) (cdr lst2)))))))
188      (or (null? lists)
189          (null? (cdr lists))
190          (let loop ((head (cadr lists)) (rest (cddr lists)))
191            (if (null? rest)
192                (list-equal-1 head)
193                (and (list-equal-1 head)
194                     (loop (car rest) (cdr rest))))))))
195
196  (define first   car)
197  (define second  cadr)
198  (define third   caddr)
199  (define fourth  cadddr)
200  (define fifth   (lambda (lst) (list-ref lst 4)))
201  (define sixth   (lambda (lst) (list-ref lst 5)))
202  (define seventh (lambda (lst) (list-ref lst 6)))
203  (define eighth  (lambda (lst) (list-ref lst 7)))
204  (define ninth   (lambda (lst) (list-ref lst 8)))
205  (define tenth   (lambda (lst) (list-ref lst 9)))
206  (define car+cdr (lambda (lst) (values (car lst) (cdr lst))))
207
208  (define count-pair
209    (lambda (lst)
210      (let loop ((lst lst) (n 0))
211        (cond ((pair? lst)
212               (loop (cdr lst) (+ n 1)))
213              (else n)))))
214
215  (define take-right
216    (lambda (lst n)
217      (let loop ((head (list-tail lst n)) (tail lst))
218        (cond ((pair? head)
219               (loop (cdr head) (cdr tail)))
220              (else tail)))))
221
222  (define drop-right
223    (lambda (lst n)
224      (list-head lst (- (count-pair lst) n))))
225
226  (define split-at
227    (lambda (lst n)
228      (values (take lst n) (drop lst n))))
229
230  (define last (lambda (lst) (car (last-pair lst))))
231
232  (define last-pair
233    (lambda (lst)
234      (let loop ((lst lst))
235        (cond ((pair? (cdr lst)) (loop (cdr lst)))
236              (else lst)))))
237
238  (define length+
239    (lambda (lst)
240      (and (list? lst) (length lst))))
241
242  (define concatenate
243    (lambda (lst)
244      (apply append lst)))
245
246  (define append-reverse
247    (lambda (head tail)
248      (cond ((pair? head)
249             (append-reverse (cdr head)
250                             (cons (car head) tail)))
251            (else tail))))
252
253  (define zip
254    (lambda lists
255      (apply list-transpose* lists)))
256
257  (define unzip1
258    (lambda (lst)
259      (map-1/srfi-1 first lst)))
260
261  (define unzip2
262    (lambda (lst)
263      (values (map-1/srfi-1 first lst) (map-1/srfi-1 second lst))))
264
265  (define unzip3
266    (lambda (lst)
267      (values (map-1/srfi-1 first lst) (map-1/srfi-1 second lst) (map-1/srfi-1 third lst))))
268
269  (define unzip4
270    (lambda (lst)
271      (values (map-1/srfi-1 first lst) (map-1/srfi-1 second lst) (map-1/srfi-1 third lst) (map-1/srfi-1 fourth lst))))
272
273  (define unzip5
274    (lambda (lst)
275      (values (map-1/srfi-1 first lst) (map-1/srfi-1 second lst) (map-1/srfi-1 third lst) (map-1/srfi-1 fourth lst) (map-1/srfi-1 fifth lst))))
276
277  (define count
278    (lambda (proc lst1 . lst2)
279      (cond ((null? lst2)
280             (fold-1 (lambda (args acc)
281                       (if (apply proc args) (+ acc 1) acc))
282                     0
283                     lst1))
284            (else
285             (fold-n (lambda (arg acc)
286                       (if (proc arg) (+ acc 1) acc))
287                     0
288                     (apply list-transpose* lst1 lst2))))))
289
290  (define fold-1
291    (lambda (proc seed lst)
292      (cond ((null? lst) seed)
293            (else (fold-1 proc (proc (car lst) seed) (cdr lst))))))
294
295  (define fold-n
296    (lambda (proc seed lst)
297      (cond ((null? lst) seed)
298            (else (fold-n proc (apply proc (append (car lst) (list seed))) (cdr lst))))))
299
300  (define fold
301    (lambda (proc seed lst1 . lst2)
302      (if (null? lst2)
303          (fold-1 proc seed lst1)
304          (fold-n proc seed (apply list-transpose* lst1 lst2)))))
305
306  (define fold-right/srfi-1
307    (lambda (proc seed lst1 . lst2)
308      (define fold-right-1 (lambda (proc seed lst)
309                             (cond ((null? lst) seed)
310                                   (else (proc (car lst) (fold-right-1 proc seed (cdr lst)))))))
311      (define fold-right-n (lambda (proc seed lst)
312                             (cond ((null? lst) seed)
313                                   (else (apply proc (append (car lst) (list (fold-right-n proc seed (cdr lst)))))))))
314      (if (null? lst2)
315          (fold-right-1 proc seed lst1)
316          (fold-right-n proc seed (apply list-transpose* lst1 lst2)))))
317
318  (define unfold
319    (lambda (pred func gen seed . opt)
320      (let-optionals opt ((tail-gen (lambda (x) '())))
321        (let loop ((seed seed))
322          (if (pred seed)
323              (tail-gen seed)
324              (cons (func seed) (loop (gen seed))))))))
325
326  (define unfold-right
327    (lambda (pred func gen seed . opt)
328      (let-optionals opt ((tail '()))
329        (let loop ((seed seed) (lst tail))
330          (if (pred seed)
331              lst
332              (loop (gen seed) (cons (func seed) lst)))))))
333
334  (define reduce fold)
335
336  (define every
337    (lambda (proc lst1 . lst2)
338      (define every-1 (lambda (proc lst)
339                        (or (null? lst)
340                            (let loop ((head (car lst)) (rest (cdr lst)))
341                              (if (null? rest)
342                                  (proc head)
343                                  (and (proc head)
344                                       (loop (car rest) (cdr rest))))))))
345      (define every-n (lambda (proc lst)
346                        (or (null? lst)
347                            (let loop ((head (car lst)) (rest (cdr lst)))
348                              (if (null? rest)
349                                  (apply proc head)
350                                  (and (apply proc head)
351                                       (loop (car rest) (cdr rest))))))))
352      (if (null? lst2)
353          (every-1 proc lst1)
354          (every-n proc (apply list-transpose* lst1 lst2)))))
355
356  (define any
357    (lambda (proc lst1 . lst2)
358      (define any-1 (lambda (proc lst)
359                      (cond ((null? lst) #f)
360                            (else (let loop ((head (car lst)) (rest (cdr lst)))
361                                    (if (null? rest)
362                                        (proc head)
363                                        (or (proc head)
364                                            (loop (car rest) (cdr rest)))))))))
365      (define any-n (lambda (proc lst)
366                      (cond ((null? lst) #f)
367                            (else (let loop ((head (car lst)) (rest (cdr lst)))
368                                    (if (null? rest)
369                                        (apply proc head)
370                                        (or (apply proc head)
371                                            (loop (car rest) (cdr rest)))))))))
372      (if (null? lst2)
373          (any-1 proc lst1)
374          (any-n proc (apply list-transpose* lst1 lst2)))))
375
376  (define map-1/srfi-1
377    (lambda (proc lst)
378      (cond ((null? lst) '())
379            (else
380             (cons (proc (car lst))
381                   (map-1/srfi-1 proc (cdr lst)))))))
382
383  (define map-n/srfi-1
384    (lambda (proc lst)
385      (cond ((null? lst) '())
386            (else
387             (cons (apply proc (car lst))
388                   (map-n/srfi-1 proc (cdr lst)))))))
389
390  (define map/srfi-1
391    (lambda (proc lst1 . lst2)
392      (if (null? lst2)
393          (map-1/srfi-1 proc lst1)
394          (map-n/srfi-1 proc (apply list-transpose* lst1 lst2)))))
395
396  (define for-each-1/srfi-1
397    (lambda (proc lst)
398      (if (null? lst)
399          (unspecified)
400          (begin
401            (proc (car lst))
402            (for-each-1/srfi-1 proc (cdr lst))))))
403
404  (define for-each-n/srfi-1
405    (lambda (proc lst)
406      (cond ((null? lst) (unspecified))
407            (else
408             (apply proc (car lst))
409             (for-each-n/srfi-1 proc (cdr lst))))))
410
411  (define for-each/srfi-1
412    (lambda (proc lst1 . lst2)
413      (if (null? lst2)
414          (for-each-1/srfi-1 proc lst1)
415          (for-each-n/srfi-1 proc (apply list-transpose* lst1 lst2)))))
416
417  (define list-of-subset
418    (lambda (lst)
419      (let loop ((lst lst) (acc '()))
420        (cond ((null? lst) acc)
421              (else
422               (cons lst (loop (cdr lst) acc)))))))
423
424  (define pair-fold
425    (lambda (proc seed lst1 . lst2)
426      (define pair-fold-1 (lambda (proc seed lst)
427                            (cond ((null? lst) seed)
428                                  (else (pair-fold-1 proc (proc lst seed) (cdr lst))))))
429      (define pair-fold-n (lambda (proc seed lst)
430                            (cond ((null? lst) seed)
431                                  (else (pair-fold-n proc (apply proc (append (car lst) (list seed))) (cdr lst))))))
432      (if (null? lst2)
433          (pair-fold-1 proc seed lst1)
434          (pair-fold-n proc seed (apply list-transpose* (list-of-subset lst1) (map-1/srfi-1 list-of-subset lst2))))))
435
436  (define pair-fold-right
437    (lambda (proc seed lst1 . lst2)
438      (define pair-fold-right-1 (lambda (proc seed lst)
439                                  (cond ((null? lst) seed)
440                                        (else (proc lst (pair-fold-right-1 proc seed (cdr lst)))))))
441      (define pair-fold-right-n (lambda (proc seed lst)
442                                  (cond ((null? lst) seed)
443                                        (else (apply proc (append (car lst) (list (pair-fold-right-n proc seed (cdr lst)))))))))
444      (if (null? lst2)
445          (pair-fold-right-1 proc seed lst1)
446          (pair-fold-right-n proc seed (apply list-transpose* (list-of-subset lst1) (map-1/srfi-1 list-of-subset lst2))))))
447
448  (define append-map
449    (lambda (proc lst1 . lst2)
450      (if (null? lst2)
451          (apply append (map-1/srfi-1 proc lst1))
452          (apply append (map-n/srfi-1 proc (apply list-transpose* lst1 lst2))))))
453
454  (define pair-for-each
455    (lambda (proc lst1 . lst2)
456      (if (null? lst2)
457          (for-each-1/srfi-1 proc (list-of-subset lst1))
458          (for-each-n/srfi-1 proc (apply list-transpose* (list-of-subset lst1) (map list-of-subset lst2))))))
459
460  (define filter-map
461    (lambda (proc lst1 . lst2)
462      (if (null? lst2)
463          (filter values (map-1/srfi-1 proc lst1))
464          (filter values (map-n/srfi-1 proc (apply list-transpose* lst1 lst2))))))
465
466  (define map-in-order map/srfi-1)
467
468  (define find-tail
469    (lambda (proc lst)
470      (let loop ((lst lst))
471        (cond ((null? lst) #f)
472              ((proc (car lst)) lst)
473              (else (loop (cdr lst)))))))
474
475  (define list-index
476    (lambda (proc lst1 . lst2)
477      (define list-index-1
478        (lambda (proc lst)
479          (and (not (null? lst))
480               (let loop ((head (car lst)) (rest (cdr lst)) (n 0))
481                 (cond ((proc head) n)
482                       ((null? rest) #f)
483                       (else
484                        (loop (car rest) (cdr rest) (+ n 1))))))))
485      (define list-index-n
486        (lambda (proc lst)
487          (and (not (null? lst))
488               (let loop ((head (car lst)) (rest (cdr lst)) (n 0))
489                 (cond ((apply proc head) n)
490                       ((null? rest) #f)
491                       (else
492                        (loop (car rest) (cdr rest) (+ n 1))))))))
493      (if (null? lst2)
494          (list-index-1 proc lst1)
495          (list-index-n proc (apply map/srfi-1 list lst1 lst2)))))
496
497  (define take-while
498    (lambda (proc lst)
499      (let loop ((lst lst))
500        (cond ((null? lst) '())
501              ((proc (car lst))
502               (cons (car lst)
503                     (loop (cdr lst))))
504              (else '())))))
505
506  (define drop-while
507    (lambda (proc lst)
508      (let loop ((lst lst))
509        (cond ((null? lst) '())
510              ((proc (car lst))
511               (loop (cdr lst)))
512              (else lst)))))
513
514  (define span
515    (lambda (proc lst)
516      (values (take-while proc lst)
517              (drop-while proc lst))))
518
519  (define remp
520    (lambda (proc lst)
521      (let loop ((lst lst))
522        (cond ((null? lst) '())
523              ((proc (car lst)) (loop (cdr lst)))
524              (else (cons (car lst) (loop (cdr lst))))))))
525
526  (define delete
527    (lambda (x lst . opt)
528      (let-optionals opt ((proc equal?))
529        (remp (lambda (e) (proc x e)) lst))))
530
531  (define delete-duplicates
532    (lambda (lst . opt)
533      (let-optionals opt ((proc equal?))
534        (cond ((null? lst) '())
535              (else (let loop ((head (car lst)) (rest (cdr lst)))
536                      (cond ((null? rest) (list head))
537                            ((memp (lambda (e) (proc head e)) rest)
538                             (let ((rest (delete head rest proc)))
539                               (cond ((null? rest) (list head))
540                                     (else
541                                      (cons head (loop (car rest) (cdr rest)))))))
542                            (else
543                             (cons head (loop (car rest) (cdr rest)))))))))))
544
545  (define alist-cons
546    (lambda (key val lst)
547      (cons (cons key val) lst)))
548
549  (define alist-copy
550    (lambda (lst)
551      (map (lambda (e) (cons (car e) (cdr e))) lst)))
552
553  (define alist-delete
554    (lambda (key lst . opt)
555      (let-optionals opt ((proc equal?))
556        (remp (lambda (e) (proc key (car e))) lst))))
557
558  (define assoc/srfi-1
559    (lambda (key lst . opt)
560      (let-optionals opt ((proc equal?))
561        (find (lambda (e) (proc key (car e))) lst))))
562
563  (define member/srfi-1
564    (lambda (x lst . opt)
565      (let-optionals opt ((proc equal?))
566        (find-tail (lambda (e) (proc x e)) lst))))
567
568  (define lset-member?
569    (lambda (proc x lst)
570      (exists (lambda (e) (proc x e)) lst)))
571
572  (define lset<=
573    (lambda (proc . lst)
574      (or (null? lst)
575          (let loop ((head (car lst)) (rest (cdr lst)))
576            (or (null? rest)
577                (and (for-all (lambda (e) (lset-member? proc e (car rest))) head)
578                     (loop (car rest) (cdr rest))))))))
579
580  (define lset=
581    (lambda (proc . lst)
582      (or (null? lst)
583          (let loop ((head (car lst)) (rest (cdr lst)))
584            (or (null? rest)
585                (and (for-all (lambda (e1) (exists (lambda (e2) (proc e1 e2)) (car rest))) head)
586                     (for-all (lambda (e2) (exists (lambda (e1) (proc e1 e2)) head)) (car rest))
587                     (loop (car rest) (cdr rest))))))))
588
589  (define lset-union-1
590    (lambda (proc lst1 lst2)
591      (cond ((null? lst2) lst1)
592            ((null? lst1) lst2)
593            (else (let loop ((lst2 lst2) (acc lst1))
594                    (if (null? lst2)
595                        acc
596                        (let ((e (car lst2)))
597                          (loop (cdr lst2)
598                                (if (lset-member? proc e acc)
599                                    acc
600                                    (cons e acc))))))))))
601
602  (define lset-adjoin
603    (lambda (proc lst . elts)
604      (lset-union-1 proc lst elts)))
605
606  (define lset-union
607    (lambda (proc . lst)
608      (cond ((null? lst) '())
609            ((null? (cdr lst)) (car lst))
610            (else (let loop ((head (cadr lst)) (rest (cddr lst)) (acc (car lst)))
611                    (if (null? rest)
612                        (lset-union-1 proc acc head)
613                        (loop (car rest) (cdr rest) (lset-union-1 proc acc head))))))))
614
615  (define lset-intersection-1
616    (lambda (proc lst1 lst2)
617      (cond ((null? lst2) '())
618            (else (let loop ((acc '()) (lst1 lst1))
619                    (if (null? lst1)
620                        (reverse acc)
621                        (let ((e (car lst1)))
622                          (loop (cond ((lset-member? proc e lst2) (cons e acc))
623                                      (else acc))
624                                (cdr lst1)))))))))
625
626  (define lset-intersection
627    (lambda (proc . lst)
628      (cond ((null? lst) '())
629            ((null? (cdr lst)) (car lst))
630            (else (let loop ((head (cadr lst)) (rest (cddr lst)) (acc (car lst)))
631                    (if (null? rest)
632                        (lset-intersection-1 proc acc head)
633                        (loop (car rest) (cdr rest) (lset-intersection-1 proc acc head))))))))
634
635  (define lset-difference-1
636    (lambda (proc lst1 lst2)
637      (cond ((null? lst2) '())
638            (else (let loop ((lst1 lst1) (acc '()))
639                    (if (null? lst1)
640                        (reverse acc)
641                        (let ((e (car lst1)))
642                          (loop (cdr lst1)
643                                (if (lset-member? proc e lst2) acc (cons e acc))))))))))
644
645  (define lset-difference
646    (lambda (proc . lst)
647      (cond ((null? lst) '())
648            ((null? (cdr lst)) (car lst))
649            (else (let loop ((head (cadr lst)) (rest (cddr lst)) (acc (car lst)))
650                    (if (null? rest)
651                        (lset-difference-1 proc acc head)
652                        (loop (car rest) (cdr rest) (lset-difference-1 proc acc head))))))))
653
654  (define lset-xor-1
655    (lambda (proc lst1 lst2)
656      (cond ((null? lst2) lst1)
657            ((null? lst1) lst2)
658            (else
659             (append (lset-difference-1 proc lst1 lst2)
660                     (lset-difference-1 proc lst2 lst1))))))
661
662  (define lset-xor
663    (lambda (proc . lst)
664      (cond ((null? lst) '())
665            ((null? (cdr lst)) (car lst))
666            (else (let loop ((head (cadr lst)) (rest (cddr lst)) (acc (car lst)))
667                    (if (null? rest)
668                        (lset-xor-1 proc acc head)
669                        (loop (car rest) (cdr rest) (lset-xor-1 proc acc head))))))))
670
671  (define lset-diff+intersection
672    (lambda (proc . lst)
673      (values (apply lset-difference proc lst)
674              (apply lset-intersection proc lst))))
675
676  ) ;[end]
677