PageRenderTime 396ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/scheme/ikarus.lists.sls

http://github.com/marcomaggi/vicare
Unknown | 1298 lines | 1182 code | 116 blank | 0 comment | 0 complexity | d901aa21df31e6019aff9f9007479ac0 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-3.0
  1. ;;;Ikarus Scheme -- A compiler for R6RS Scheme.
  2. ;;;Copyright (C) 2006,2007,2008 Abdulaziz Ghuloum
  3. ;;;Modified by Marco Maggi <marco.maggi-ipsu@poste.it>
  4. ;;;
  5. ;;;This program is free software: you can redistribute it and/or modify
  6. ;;;it under the terms of the GNU General Public License version 3 as
  7. ;;;published by the Free Software Foundation.
  8. ;;;
  9. ;;;This program is distributed in the hope that it will be useful, but
  10. ;;;WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;;;General Public License for more details.
  13. ;;;
  14. ;;;You should have received a copy of the GNU General Public License
  15. ;;;along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #!vicare
  17. (library (ikarus lists)
  18. (export
  19. make-list-of-predicate
  20. list? circular-list? list-of-single-item?
  21. list cons* make-list append length list-ref reverse
  22. last-pair memq memp memv member find assq assp assv assoc
  23. remq remv remove remp filter map for-each
  24. (rename (for-each for-each-in-order)) andmap ormap list-tail
  25. partition for-all exists fold-left fold-right
  26. make-queue-procs
  27. ;; unsafe bindings
  28. $length)
  29. (import (except (vicare)
  30. make-list-of-predicate
  31. list? circular-list? list-of-single-item?
  32. list cons* make-list append reverse
  33. last-pair length list-ref memq memp memv member find
  34. assq assp assv assoc remq remv remove remp filter
  35. map for-each for-each-in-order andmap ormap list-tail partition
  36. for-all exists fold-left fold-right
  37. make-queue-procs)
  38. (vicare system $fx)
  39. (vicare system $pairs))
  40. ;;;; arguments validation
  41. (define (list-length? obj)
  42. (and (fixnum? obj) ($fxnonnegative? obj)))
  43. (define (list-index? obj)
  44. (and (fixnum? obj) ($fxnonnegative? obj)))
  45. (define-syntax-rule (%error-list-was-altered-while-processing)
  46. (assertion-violation __who__ "list was altered while processing"))
  47. (define-syntax-rule (%error-circular-list-is-invalid-as-argument ?obj)
  48. (assertion-violation __who__ "circular list is invalid as argument" ?obj))
  49. (define-syntax-rule (%error-length-mismatch-among-list-arguments)
  50. (procedure-arguments-consistency-violation __who__ "length mismatch among list arguments"))
  51. (define-syntax-rule (%error-expected-proper-list-as-argument ?obj)
  52. (assertion-violation __who__ "expected proper list as argument" ?obj))
  53. (define-syntax-rule (%error-improper-list-is-invalid-as-argument ?obj)
  54. (assertion-violation __who__ "improper list is invalid as argument" ?obj))
  55. (define-syntax-rule (%error-malformed-alist-as-argument ?arg-index ?arg)
  56. (procedure-argument-violation __who__ "malformed alist as argument" ?arg))
  57. ;;;; helpers
  58. (define-syntax-rule (with-who ?name . ?body)
  59. (fluid-let-syntax
  60. ((__who__ (identifier-syntax (quote ?name))))
  61. . ?body))
  62. ;;Commented out because it appears to be useless: $MEMQ is a primitive
  63. ;;operation (Marco Maggi; Oct 28, 2011).
  64. ;;
  65. ;; (define ($memq x ls)
  66. ;; (and (pair? ls)
  67. ;; (if (eq? x ($car ls))
  68. ;; ls
  69. ;; ($memq x ($cdr ls)))))
  70. (define list (lambda x x))
  71. (define (cons* fst . rest)
  72. (let loop ((fst fst) (rest rest))
  73. (if (null? rest)
  74. fst
  75. (cons fst (loop ($car rest) ($cdr rest))))))
  76. (module (list?)
  77. (define (list? x)
  78. (%race x x))
  79. (define (%race h t)
  80. ;;Tortoise and hare algorithm to detect circular lists.
  81. (if (pair? h)
  82. (let ((h ($cdr h)))
  83. (if (pair? h)
  84. (and (not (eq? h t))
  85. (%race ($cdr h) ($cdr t)))
  86. (null? h)))
  87. (null? h)))
  88. #| end of module |# )
  89. (define (list-of-single-item? ell)
  90. (and (pair? ell)
  91. (null? (cdr ell))))
  92. (define (circular-list? obj)
  93. ;;At every iteration ELL is CDR-ed twice, LAG is CDR-ed once.
  94. (let loop ((ell obj)
  95. (lag obj))
  96. (and (pair? ell)
  97. (let ((ell (cdr ell)))
  98. (and (pair? ell)
  99. (let ((ell (cdr ell))
  100. (lag (cdr lag)))
  101. (or (eq? ell lag)
  102. (loop ell lag))))))))
  103. (define (make-list-of-predicate item-pred)
  104. (define (%race h t)
  105. ;;Tortoise and hare algorithm to detect circular lists.
  106. (if (pair? h)
  107. (begin
  108. (debug-print 'list-of (car h))
  109. (and (item-pred ($car h))
  110. (let ((h ($cdr h)))
  111. (if (pair? h)
  112. (begin
  113. (debug-print 'list-of (car h))
  114. (and (item-pred ($car h))
  115. (not (eq? h t))
  116. (%race ($cdr h) ($cdr t))))
  117. (null? h)))))
  118. (null? h)))
  119. (lambda (obj)
  120. (%race obj obj)))
  121. (case-define* make-list
  122. (({n list-length?})
  123. (%$make-list n (void) '()))
  124. (({n list-length?} fill)
  125. (%$make-list n fill '())))
  126. (define (%$make-list n fill ls)
  127. (if ($fxzero? n)
  128. ls
  129. (%$make-list ($fxsub1 n) fill (cons fill ls))))
  130. (define* (length ls)
  131. (define (%race h t ls n)
  132. (with-who length
  133. (cond ((pair? h)
  134. (let ((h ($cdr h)))
  135. (if (pair? h)
  136. (if (not (eq? h t))
  137. (%race ($cdr h) ($cdr t) ls ($fx+ n 2))
  138. (%error-circular-list-is-invalid-as-argument ls))
  139. (if (null? h)
  140. ($fxadd1 n)
  141. (%error-improper-list-is-invalid-as-argument ls)))))
  142. ((null? h)
  143. n)
  144. (else
  145. (%error-expected-proper-list-as-argument ls)))))
  146. (%race ls ls ls 0))
  147. (define ($length ell)
  148. ;;Assume ELL is a proper list and compute its length as fast as possible.
  149. ;;
  150. (let recur ((len 0)
  151. (ell ell))
  152. (if (pair? ell)
  153. (recur ($fxadd1 len) ($cdr ell))
  154. len)))
  155. (define* (list-ref the-list {the-index list-index?})
  156. (define (%error-index-out-of-range)
  157. (procedure-arguments-consistency-violation __who__ "index is out of range" the-index the-list))
  158. (define (%$list-ref ls i)
  159. (with-who list-ref
  160. (cond (($fxzero? i)
  161. (if (pair? ls)
  162. ($car ls)
  163. (%error-index-out-of-range)))
  164. ((pair? ls)
  165. (%$list-ref ($cdr ls) ($fxsub1 i)))
  166. ((null? ls)
  167. (%error-index-out-of-range))
  168. (else
  169. (%error-expected-proper-list-as-argument the-list)))))
  170. (%$list-ref the-list the-index))
  171. (define* (list-tail list {index list-index?})
  172. (define (%$list-tail ls i)
  173. (with-who list-tail
  174. (cond (($fxzero? i)
  175. ls)
  176. ((pair? ls)
  177. (%$list-tail ($cdr ls) ($fxsub1 i)))
  178. ((null? ls)
  179. (procedure-arguments-consistency-violation __who__ "index is out of range" index list))
  180. (else
  181. (%error-expected-proper-list-as-argument list)))))
  182. (%$list-tail list index))
  183. (case-define* append
  184. (() '())
  185. ((ls) ls)
  186. ((ls . ls*)
  187. (define (reverse h t ls ac)
  188. (with-who append
  189. (cond ((pair? h)
  190. (let ((h ($cdr h)) (a1 ($car h)))
  191. (cond ((pair? h)
  192. (if (not (eq? h t))
  193. (let ((a2 ($car h)))
  194. (reverse ($cdr h) ($cdr t) ls (cons a2 (cons a1 ac))))
  195. (%error-circular-list-is-invalid-as-argument ls)))
  196. ((null? h)
  197. (cons a1 ac))
  198. (else
  199. (%error-expected-proper-list-as-argument ls)))))
  200. ((null? h)
  201. ac)
  202. (else
  203. (%error-expected-proper-list-as-argument ls)))))
  204. (define (rev! ls ac)
  205. (if (null? ls)
  206. ac
  207. (let ((ls^ ($cdr ls)))
  208. ($set-cdr! ls ac)
  209. (rev! ls^ ls))))
  210. (define (append1 ls ls*)
  211. (if (null? ls*)
  212. ls
  213. (rev! (reverse ls ls ls '())
  214. (append1 ($car ls*) ($cdr ls*)))))
  215. (append1 ls ls*))
  216. #| end of CASE-DEFINE* |# )
  217. (define* (reverse x)
  218. (define (%race h t ls ac)
  219. (with-who reverse
  220. (cond ((pair? h)
  221. (let ((h ($cdr h))
  222. (ac (cons ($car h) ac)))
  223. (cond ((pair? h)
  224. (if (not (eq? h t))
  225. (%race ($cdr h) ($cdr t) ls (cons ($car h) ac))
  226. (%error-circular-list-is-invalid-as-argument ls)))
  227. ((null? h)
  228. ac)
  229. (else
  230. (%error-expected-proper-list-as-argument ls)))))
  231. ((null? h)
  232. ac)
  233. (else
  234. (%error-expected-proper-list-as-argument ls)))))
  235. (%race x x x '()))
  236. (define* (last-pair {x pair?})
  237. (define (%race h t ls last)
  238. (if (pair? h)
  239. (let ((h ($cdr h)) (last h))
  240. (if (pair? h)
  241. (if (not (eq? h t))
  242. (%race ($cdr h) ($cdr t) ls h)
  243. (%error-circular-list-is-invalid-as-argument ls))
  244. last))
  245. last))
  246. (let ((d ($cdr x)))
  247. (%race d d x x)))
  248. (define* (memq x ls)
  249. (define (%race h t ls x)
  250. (with-who memq
  251. (cond ((pair? h)
  252. (if (eq? ($car h) x)
  253. h
  254. (let ((h ($cdr h)))
  255. (cond ((pair? h)
  256. (cond ((eq? ($car h) x)
  257. h)
  258. ((not (eq? h t))
  259. (%race ($cdr h) ($cdr t) ls x))
  260. (else
  261. (%error-circular-list-is-invalid-as-argument ls))))
  262. ((null? h)
  263. #f)
  264. (else
  265. (%error-expected-proper-list-as-argument ls))))))
  266. ((null? h)
  267. #f)
  268. (else
  269. (%error-expected-proper-list-as-argument ls)))))
  270. (%race ls ls ls x))
  271. (define* (memv x ls)
  272. (define (%race h t ls x)
  273. (with-who memv
  274. (cond ((pair? h)
  275. (if (eqv? ($car h) x)
  276. h
  277. (let ((h ($cdr h)))
  278. (cond ((pair? h)
  279. (cond ((eqv? ($car h) x)
  280. h)
  281. ((not (eq? h t))
  282. (%race ($cdr h) ($cdr t) ls x))
  283. (else
  284. (%error-circular-list-is-invalid-as-argument ls))))
  285. ((null? h)
  286. #f)
  287. (else
  288. (%error-expected-proper-list-as-argument ls))))))
  289. ((null? h)
  290. #f)
  291. (else
  292. (%error-expected-proper-list-as-argument ls)))))
  293. (%race ls ls ls x))
  294. (define* (member x ls)
  295. (define (%race h t ls x)
  296. (with-who member
  297. (cond ((pair? h)
  298. (if (equal? ($car h) x)
  299. h
  300. (let ((h ($cdr h)))
  301. (cond ((pair? h)
  302. (cond ((equal? ($car h) x)
  303. h)
  304. ((not (eq? h t))
  305. (%race ($cdr h) ($cdr t) ls x))
  306. (else
  307. (%error-circular-list-is-invalid-as-argument ls))))
  308. ((null? h)
  309. #f)
  310. (else
  311. (%error-expected-proper-list-as-argument ls))))))
  312. ((null? h)
  313. #f)
  314. (else
  315. (%error-expected-proper-list-as-argument ls)))))
  316. (%race ls ls ls x))
  317. (define* (memp {p procedure?} ls)
  318. (define (%race h t ls p)
  319. (with-who memp
  320. (cond ((pair? h)
  321. (if (p ($car h))
  322. h
  323. (let ((h ($cdr h)))
  324. (cond ((pair? h)
  325. (cond ((p ($car h))
  326. h)
  327. ((not (eq? h t))
  328. (%race ($cdr h) ($cdr t) ls p))
  329. (else
  330. (%error-circular-list-is-invalid-as-argument ls))))
  331. ((null? h)
  332. #f)
  333. (else
  334. (%error-expected-proper-list-as-argument ls))))))
  335. ((null? h)
  336. #f)
  337. (else
  338. (%error-expected-proper-list-as-argument ls)))))
  339. (%race ls ls ls p))
  340. (define* (find {p procedure?} ls)
  341. (define (%race h t ls p)
  342. (with-who find
  343. (cond ((pair? h)
  344. (let ((a ($car h)))
  345. (if (p a)
  346. a
  347. (let ((h ($cdr h)))
  348. (cond ((pair? h)
  349. (let ((a ($car h)))
  350. (cond ((p a)
  351. a)
  352. ((not (eq? h t))
  353. (%race ($cdr h) ($cdr t) ls p))
  354. (else
  355. (%error-circular-list-is-invalid-as-argument ls)))))
  356. ((null? h)
  357. #f)
  358. (else
  359. (%error-expected-proper-list-as-argument ls)))))))
  360. ((null? h)
  361. #f)
  362. (else
  363. (%error-expected-proper-list-as-argument ls)))))
  364. (%race ls ls ls p))
  365. (define* (assq x ls)
  366. (define (%race x h t ls)
  367. (with-who assq
  368. (cond ((pair? h)
  369. (let ((a ($car h)) (h ($cdr h)))
  370. (if (pair? a)
  371. (cond ((eq? ($car a) x)
  372. a)
  373. ((pair? h)
  374. (if (not (eq? h t))
  375. (let ((a ($car h)))
  376. (if (pair? a)
  377. (if (eq? ($car a) x)
  378. a
  379. (%race x ($cdr h) ($cdr t) ls))
  380. (%error-malformed-alist-as-argument 2 ls)))
  381. (%error-circular-list-is-invalid-as-argument ls)))
  382. ((null? h)
  383. #f)
  384. (else
  385. (%error-expected-proper-list-as-argument ls)))
  386. (%error-malformed-alist-as-argument 2 ls))))
  387. ((null? h)
  388. #f)
  389. (else
  390. (%error-expected-proper-list-as-argument ls)))))
  391. (%race x ls ls ls))
  392. (define* (assp {p procedure?} ls)
  393. (define (%race p h t ls)
  394. (with-who assp
  395. (cond ((pair? h)
  396. (let ((a ($car h)) (h ($cdr h)))
  397. (if (pair? a)
  398. (cond ((p ($car a))
  399. a)
  400. ((pair? h)
  401. (if (not (eq? h t))
  402. (let ((a ($car h)))
  403. (if (pair? a)
  404. (if (p ($car a))
  405. a
  406. (%race p ($cdr h) ($cdr t) ls))
  407. (%error-malformed-alist-as-argument 2 ls)))
  408. (%error-circular-list-is-invalid-as-argument ls)))
  409. ((null? h)
  410. #f)
  411. (else
  412. (%error-expected-proper-list-as-argument ls)))
  413. (%error-malformed-alist-as-argument 2 ls))))
  414. ((null? h)
  415. #f)
  416. (else
  417. (%error-expected-proper-list-as-argument ls)))))
  418. (%race p ls ls ls))
  419. (define* (assv x ls)
  420. (define (%race x h t ls)
  421. (with-who assv
  422. (cond ((pair? h)
  423. (let ((a ($car h)) (h ($cdr h)))
  424. (if (pair? a)
  425. (cond ((eqv? ($car a) x)
  426. a)
  427. ((pair? h)
  428. (if (not (eq? h t))
  429. (let ((a ($car h)))
  430. (if (pair? a)
  431. (if (eqv? ($car a) x)
  432. a
  433. (%race x ($cdr h) ($cdr t) ls))
  434. (%error-malformed-alist-as-argument 2 ls)))
  435. (%error-circular-list-is-invalid-as-argument ls)))
  436. ((null? h)
  437. #f)
  438. (else
  439. (%error-expected-proper-list-as-argument ls)))
  440. (%error-malformed-alist-as-argument 2 ls))))
  441. ((null? h)
  442. #f)
  443. (else
  444. (%error-expected-proper-list-as-argument ls)))))
  445. (%race x ls ls ls))
  446. (define* (assoc x ls)
  447. (define (%race x h t ls)
  448. (with-who assoc
  449. (cond ((pair? h)
  450. (let ((a ($car h)) (h ($cdr h)))
  451. (if (pair? a)
  452. (cond ((equal? ($car a) x)
  453. a)
  454. ((pair? h)
  455. (if (not (eq? h t))
  456. (let ((a ($car h)))
  457. (if (pair? a)
  458. (if (equal? ($car a) x)
  459. a
  460. (%race x ($cdr h) ($cdr t) ls))
  461. (%error-malformed-alist-as-argument 2 ls)))
  462. (%error-circular-list-is-invalid-as-argument ls)))
  463. ((null? h)
  464. #f)
  465. (else
  466. (%error-expected-proper-list-as-argument ls)))
  467. (%error-malformed-alist-as-argument 2 ls))))
  468. ((null? h)
  469. #f)
  470. (else
  471. (%error-expected-proper-list-as-argument ls)))))
  472. (%race x ls ls ls))
  473. (define-syntax define-remover
  474. (syntax-rules ()
  475. ((_ ?name ?cmp ?check)
  476. (define* (?name {x ?check} ls)
  477. (define (%race h t ls x)
  478. (with-who ?name
  479. (cond ((pair? h)
  480. (if (?cmp ($car h) x)
  481. (let ((h ($cdr h)))
  482. (cond ((pair? h)
  483. (if (not (eq? h t))
  484. (if (?cmp ($car h) x)
  485. (%race ($cdr h) ($cdr t) ls x)
  486. (cons ($car h) (%race ($cdr h) ($cdr t) ls x)))
  487. (%error-circular-list-is-invalid-as-argument ls)))
  488. ((null? h)
  489. '())
  490. (else
  491. (%error-expected-proper-list-as-argument ls))))
  492. (let ((a0 ($car h)) (h ($cdr h)))
  493. (cond ((pair? h)
  494. (if (not (eq? h t))
  495. (if (?cmp ($car h) x)
  496. (cons a0 (%race ($cdr h) ($cdr t) ls x))
  497. (cons* a0 ($car h) (%race ($cdr h) ($cdr t) ls x)))
  498. (%error-circular-list-is-invalid-as-argument ls)))
  499. ((null? h)
  500. (list a0))
  501. (else
  502. (%error-expected-proper-list-as-argument ls))))))
  503. ((null? h)
  504. '())
  505. (else
  506. (%error-expected-proper-list-as-argument ls)))))
  507. (%race ls ls ls x)))
  508. ))
  509. (define (%always-true? obj)
  510. #t)
  511. (define-remover remq eq? %always-true?)
  512. (define-remover remv eqv? %always-true?)
  513. (define-remover remove equal? %always-true?)
  514. (define-remover remp (lambda (elt p) (p elt)) procedure?)
  515. (define-remover filter (lambda (elt p) (not (p elt))) procedure?)
  516. (module (map)
  517. (case-define* map
  518. (({f procedure?} ls)
  519. (cond ((pair? ls)
  520. (let ((d ($cdr ls)))
  521. (map1 f ($car ls) d (len d d 0))))
  522. ((null? ls)
  523. '())
  524. (else
  525. (err-invalid (list ls)))))
  526. (({f procedure?} ls ls2)
  527. (cond ((pair? ls)
  528. (if (pair? ls2)
  529. (let ((d ($cdr ls)))
  530. (map2 f ($car ls) ($car ls2) d ($cdr ls2) (len d d 0)))
  531. (err-invalid (list ls ls2))))
  532. ((and (null? ls) (null? ls2))
  533. '())
  534. (else
  535. (err-invalid (list ls ls2)))))
  536. (({f procedure?} ls . ls*)
  537. (cond ((pair? ls)
  538. (let ((n (len ls ls 0)))
  539. (mapm f ls ls* n (cons ls ls*))))
  540. ((and (null? ls) (andmap null? ls*))
  541. '())
  542. (else
  543. (err-invalid (cons ls ls*)))))
  544. #| end of CASE-DEFINE* |# )
  545. (define (len h t n)
  546. (with-who map
  547. (cond ((pair? h)
  548. (let ((h ($cdr h)))
  549. (cond ((pair? h)
  550. (if (eq? h t)
  551. (%error-circular-list-is-invalid-as-argument h)
  552. (len ($cdr h) ($cdr t) ($fx+ n 2))))
  553. ((null? h)
  554. ($fxadd1 n))
  555. (else
  556. (%error-expected-proper-list-as-argument h)))))
  557. ((null? h)
  558. n)
  559. (else
  560. (%error-expected-proper-list-as-argument h)))))
  561. (define (map1 f a d n)
  562. (with-who map
  563. (cond ((pair? d)
  564. (if ($fxzero? n)
  565. (%error-list-was-altered-while-processing)
  566. (cons (f a) (map1 f ($car d) ($cdr d) ($fxsub1 n)))))
  567. ((null? d)
  568. (if ($fxzero? n)
  569. (cons (f a) '())
  570. (%error-list-was-altered-while-processing)))
  571. (else
  572. (%error-list-was-altered-while-processing)))))
  573. (define (map2 f a1 a2 d1 d2 n)
  574. (with-who map
  575. (cond ((pair? d1)
  576. (cond ((pair? d2)
  577. (if ($fxzero? n)
  578. (%error-list-was-altered-while-processing)
  579. (cons (f a1 a2)
  580. (map2 f
  581. ($car d1) ($car d2)
  582. ($cdr d1) ($cdr d2)
  583. ($fxsub1 n)))))
  584. ((null? d2)
  585. (%error-length-mismatch-among-list-arguments))
  586. (else
  587. (%error-expected-proper-list-as-argument d2))))
  588. ((null? d1)
  589. (cond ((null? d2)
  590. (if ($fxzero? n)
  591. (cons (f a1 a2) '())
  592. (%error-list-was-altered-while-processing)))
  593. (else
  594. (if (list? d2)
  595. (%error-length-mismatch-among-list-arguments)
  596. (%error-expected-proper-list-as-argument d2)))))
  597. (else
  598. (%error-list-was-altered-while-processing)))))
  599. (define (cars ls*)
  600. (with-who map
  601. (if (null? ls*)
  602. '()
  603. (let ((a (car ls*)))
  604. (if (pair? a)
  605. (cons (car a) (cars (cdr ls*)))
  606. (%error-length-mismatch-among-list-arguments))))))
  607. (define (cdrs ls*)
  608. (with-who map
  609. (if (null? ls*)
  610. '()
  611. (let ((a (car ls*)))
  612. (if (pair? a)
  613. (cons (cdr a) (cdrs (cdr ls*)))
  614. (%error-length-mismatch-among-list-arguments))))))
  615. (define (err-mutated all-lists)
  616. (with-who map
  617. (%error-list-was-altered-while-processing)))
  618. (define (err-mismatch all-lists)
  619. (with-who map
  620. (%error-length-mismatch-among-list-arguments)))
  621. (define (err-invalid all-lists)
  622. (with-who map
  623. (apply assertion-violation __who__ "invalid arguments" all-lists)))
  624. (define (mapm f ls ls* n all-lists)
  625. (cond ((null? ls)
  626. (if (andmap null? ls*)
  627. (if (fxzero? n)
  628. '()
  629. (err-mutated all-lists))
  630. (err-mismatch all-lists)))
  631. ((fxzero? n)
  632. (err-mutated all-lists))
  633. (else
  634. (cons (apply f (car ls) (cars ls*))
  635. (mapm f (cdr ls) (cdrs ls*) (fxsub1 n) all-lists)))))
  636. #| end of module |# )
  637. (module (for-each)
  638. (case-define* for-each
  639. (({f procedure?} ls)
  640. (cond ((pair? ls)
  641. (let ((d ($cdr ls)))
  642. (for-each1 f ($car ls) d (len d d 0))))
  643. ((null? ls)
  644. (void))
  645. (else
  646. (%error-expected-proper-list-as-argument ls))))
  647. (({f procedure?} ls ls2)
  648. (cond ((pair? ls)
  649. (if (pair? ls2)
  650. (let ((d ($cdr ls)))
  651. (for-each2 f ($car ls) ($car ls2) d ($cdr ls2) (len d d 0)))
  652. (%error-length-mismatch-among-list-arguments)))
  653. ((null? ls)
  654. (if (null? ls2)
  655. (void)
  656. (%error-length-mismatch-among-list-arguments)))
  657. (else
  658. (%error-expected-proper-list-as-argument ls))))
  659. (({f procedure?} {ls list?} . ls*)
  660. (let ((n (length ls)))
  661. (for-each (lambda (x)
  662. (unless (and (list? x) (= (length x) n))
  663. (%error-expected-proper-list-as-argument x)))
  664. ls*)
  665. (let loop ((n (length ls)) (ls ls) (ls* ls*))
  666. (if ($fxzero? n)
  667. (unless (and (null? ls) (andmap null? ls*))
  668. (%error-list-was-altered-while-processing))
  669. (begin
  670. (unless (and (pair? ls) (andmap pair? ls*))
  671. (%error-list-was-altered-while-processing))
  672. (apply f (car ls) (map car ls*))
  673. (loop (fx- n 1) (cdr ls) (map cdr ls*)))))))
  674. #| end of CASE-DEFINE* |# )
  675. (define (len h t n)
  676. (with-who for-each
  677. (cond ((pair? h)
  678. (let ((h ($cdr h)))
  679. (cond ((pair? h)
  680. (if (eq? h t)
  681. (%error-circular-list-is-invalid-as-argument h)
  682. (len ($cdr h) ($cdr t) ($fx+ n 2))))
  683. ((null? h)
  684. ($fxadd1 n))
  685. (else
  686. (%error-expected-proper-list-as-argument h)))))
  687. ((null? h)
  688. n)
  689. (else
  690. (%error-expected-proper-list-as-argument h)))))
  691. (define (for-each1 f a d n)
  692. (with-who for-each
  693. (cond ((pair? d)
  694. (if ($fxzero? n)
  695. (%error-list-was-altered-while-processing)
  696. (begin
  697. (f a)
  698. (for-each1 f ($car d) ($cdr d) ($fxsub1 n)))))
  699. ((null? d)
  700. (if ($fxzero? n)
  701. (f a)
  702. (%error-list-was-altered-while-processing)))
  703. (else
  704. (%error-list-was-altered-while-processing)))))
  705. (define (for-each2 f a1 a2 d1 d2 n)
  706. (with-who for-each
  707. (cond ((pair? d1)
  708. (if (pair? d2)
  709. (if ($fxzero? n)
  710. (%error-list-was-altered-while-processing)
  711. (begin
  712. (f a1 a2)
  713. (for-each2 f
  714. ($car d1) ($car d2)
  715. ($cdr d1) ($cdr d2)
  716. ($fxsub1 n))))
  717. (%error-length-mismatch-among-list-arguments)))
  718. ((null? d1)
  719. (if (null? d2)
  720. (if ($fxzero? n)
  721. (f a1 a2)
  722. (%error-list-was-altered-while-processing))
  723. (%error-length-mismatch-among-list-arguments)))
  724. (else
  725. (%error-list-was-altered-while-processing)))))
  726. #| end of module |#)
  727. (module (andmap)
  728. ;;ANDMAP should be the same as R6RS's FOR-ALL (Marco Maggi; Oct 28, 2011).
  729. ;;
  730. (case-define* andmap
  731. (({f procedure?} ls)
  732. (cond ((pair? ls)
  733. (let ((d ($cdr ls)))
  734. (andmap1 f ($car ls) d (len d d 0))))
  735. ((null? ls)
  736. #t)
  737. (else
  738. (%error-expected-proper-list-as-argument ls))))
  739. (({f procedure?} ls ls2)
  740. (cond ((pair? ls)
  741. (if (pair? ls2)
  742. (let ((d ($cdr ls)))
  743. (andmap2 f
  744. ($car ls) ($car ls2) d ($cdr ls2) (len d d 0)))
  745. (%error-length-mismatch-among-list-arguments)))
  746. ((null? ls)
  747. (if (null? ls2)
  748. #t
  749. (%error-length-mismatch-among-list-arguments)))
  750. (else
  751. (%error-expected-proper-list-as-argument ls))))
  752. #| end of CASE-DEFINE* |# )
  753. (define (len h t n)
  754. (with-who andmap
  755. (cond ((pair? h)
  756. (let ((h ($cdr h)))
  757. (cond ((pair? h)
  758. (if (eq? h t)
  759. (%error-circular-list-is-invalid-as-argument h)
  760. (len ($cdr h) ($cdr t) ($fx+ n 2))))
  761. ((null? h)
  762. ($fxadd1 n))
  763. (else
  764. (%error-expected-proper-list-as-argument h)))))
  765. ((null? h)
  766. n)
  767. (else
  768. (%error-expected-proper-list-as-argument h)))))
  769. (define (andmap1 f a d n)
  770. (with-who for-each
  771. (cond ((pair? d)
  772. (if ($fxzero? n)
  773. (%error-list-was-altered-while-processing)
  774. (and (f a)
  775. (andmap1 f ($car d) ($cdr d) ($fxsub1 n)))))
  776. ((null? d)
  777. (if ($fxzero? n)
  778. (f a)
  779. (%error-list-was-altered-while-processing)))
  780. (else
  781. (%error-list-was-altered-while-processing)))))
  782. (define (andmap2 f a1 a2 d1 d2 n)
  783. (with-who for-each
  784. (cond ((pair? d1)
  785. (if (pair? d2)
  786. (if ($fxzero? n)
  787. (%error-list-was-altered-while-processing)
  788. (and (f a1 a2)
  789. (andmap2 f
  790. ($car d1) ($car d2)
  791. ($cdr d1) ($cdr d2)
  792. ($fxsub1 n))))
  793. (%error-length-mismatch-among-list-arguments)))
  794. ((null? d1)
  795. (if (null? d2)
  796. (if ($fxzero? n)
  797. (f a1 a2)
  798. (%error-list-was-altered-while-processing))
  799. (%error-length-mismatch-among-list-arguments)))
  800. (else
  801. (%error-list-was-altered-while-processing)))))
  802. #| end of module |# )
  803. (module (ormap)
  804. ;;ANDMAP should be the same as R6RS's EXISTS (Marco Maggi; Oct 28, 2011).
  805. ;;
  806. (define* (ormap {f procedure?} ls)
  807. (cond ((pair? ls)
  808. (let ((d ($cdr ls)))
  809. (ormap1 f ($car ls) d (len d d 0))))
  810. ((null? ls)
  811. #f)
  812. (else
  813. (%error-expected-proper-list-as-argument ls))))
  814. (define (len h t n)
  815. (with-who for-each
  816. (cond ((pair? h)
  817. (let ((h ($cdr h)))
  818. (cond ((pair? h)
  819. (if (eq? h t)
  820. (%error-circular-list-is-invalid-as-argument h)
  821. (len ($cdr h) ($cdr t) ($fx+ n 2))))
  822. ((null? h)
  823. ($fxadd1 n))
  824. (else
  825. (%error-expected-proper-list-as-argument h)))))
  826. ((null? h)
  827. n)
  828. (else
  829. (%error-expected-proper-list-as-argument h)))))
  830. (define (ormap1 f a d n)
  831. (with-who for-each
  832. (cond ((pair? d)
  833. (if ($fxzero? n)
  834. (%error-list-was-altered-while-processing)
  835. (or (f a)
  836. (ormap1 f ($car d) ($cdr d) ($fxsub1 n)))))
  837. ((null? d)
  838. (if ($fxzero? n)
  839. (f a)
  840. (%error-list-was-altered-while-processing)))
  841. (else
  842. (%error-list-was-altered-while-processing)))))
  843. #| end of module |# )
  844. (define* (partition {p procedure?} ls)
  845. (define (%race h t ls p)
  846. (with-who partition
  847. (cond ((pair? h)
  848. (let ((a0 ($car h))
  849. (h ($cdr h)))
  850. (cond ((pair? h)
  851. (if (eq? h t)
  852. (%error-circular-list-is-invalid-as-argument ls)
  853. (let ((a1 ($car h)))
  854. (let-values (((a* b*) (%race ($cdr h) ($cdr t) ls p)))
  855. (cond ((p a0)
  856. (if (p a1)
  857. (values (cons* a0 a1 a*) b*)
  858. (values (cons a0 a*) (cons a1 b*))))
  859. ((p a1)
  860. (values (cons a1 a*) (cons a0 b*)))
  861. (else
  862. (values a* (cons* a0 a1 b*))))))))
  863. ((null? h)
  864. (if (p a0)
  865. (values (list a0) '())
  866. (values '() (list a0))))
  867. (else
  868. (%error-expected-proper-list-as-argument ls)))))
  869. ((null? h)
  870. (values '() '()))
  871. (else
  872. (%error-expected-proper-list-as-argument ls)))))
  873. (%race ls ls ls p))
  874. (define-syntax define-iterator
  875. (syntax-rules ()
  876. ((_ ?name ?combine)
  877. (module (?name)
  878. (case-define* ?name
  879. (({f procedure?} ls)
  880. (cond ((pair? ls)
  881. (loop1 f (car ls) (cdr ls) (cdr ls) ls))
  882. ((null? ls)
  883. (?combine))
  884. (else
  885. (%error-expected-proper-list-as-argument ls))))
  886. (({f procedure?} ls . ls*)
  887. (cond ((pair? ls)
  888. (let-values (((cars cdrs) (cars+cdrs ls* ls*)))
  889. (loopn f (car ls) cars (cdr ls) cdrs (cdr ls) ls ls*)))
  890. ((and (null? ls) (null*? ls*))
  891. (?combine))
  892. (else
  893. (err* ls*))))
  894. #| end of CASE-DEFINE* |# )
  895. (define (null*? ls)
  896. (or (null? ls) (and (null? (car ls)) (null*? (cdr ls)))))
  897. (define (err* ls*)
  898. (with-who ?name
  899. (for-each (lambda (ls)
  900. (unless (list? ls)
  901. (%error-expected-proper-list-as-argument ls)))
  902. ls*)
  903. (%error-length-mismatch-among-list-arguments)))
  904. (define (cars+cdrs ls ls*)
  905. (with-who ?name
  906. (if (null? ls)
  907. (values '() '())
  908. (let ((a (car ls)))
  909. (cond ((pair? a)
  910. (let-values (((cars cdrs) (cars+cdrs (cdr ls) (cdr ls*))))
  911. (values (cons (car a) cars) (cons (cdr a) cdrs))))
  912. ((list? (car ls*))
  913. (%error-length-mismatch-among-list-arguments))
  914. (else
  915. (%error-expected-proper-list-as-argument (car ls*))))))))
  916. (define (loop1 f a h t ls)
  917. (with-who ?name
  918. (cond ((pair? h)
  919. (let ((b (car h)) (h (cdr h)))
  920. (?combine (f a)
  921. (cond ((pair? h)
  922. (if (eq? h t)
  923. (%error-circular-list-is-invalid-as-argument h)
  924. (let ((c (car h)) (h (cdr h)))
  925. (?combine (f b) (loop1 f c h (cdr t) ls)))))
  926. ((null? h)
  927. (f b))
  928. (else
  929. (?combine (f b)
  930. (%error-expected-proper-list-as-argument ls)))))))
  931. ((null? h)
  932. (f a))
  933. (else
  934. (?combine (f a) (%error-expected-proper-list-as-argument ls))))))
  935. (define (loopn f a a* h h* t ls ls*)
  936. (with-who ?name
  937. (cond ((pair? h)
  938. (let-values (((b* h*) (cars+cdrs h* ls*)))
  939. (let ((b (car h)) (h (cdr h)))
  940. (?combine (apply f a a*)
  941. (if (pair? h)
  942. (if (eq? h t)
  943. (%error-circular-list-is-invalid-as-argument h)
  944. (let-values (((c* h*) (cars+cdrs h* ls*)))
  945. (let ((c (car h)) (h (cdr h)))
  946. (?combine (apply f b b*)
  947. (loopn f c c* h h* (cdr t) ls ls*)))))
  948. (if (and (null? h) (null*? h*))
  949. (apply f b b*)
  950. (?combine (apply f b b*) (err* (cons ls ls*)))))))))
  951. ((and (null? h) (null*? h*))
  952. (apply f a a*))
  953. (else
  954. (?combine (apply f a a*) (err* (cons ls ls*)))))))
  955. #| end of module |# )
  956. )))
  957. (define-iterator for-all and)
  958. (define-iterator exists or)
  959. (module (fold-left)
  960. (case-define* fold-left
  961. (({f procedure?} nil ls)
  962. (loop1 f nil ls ls ls))
  963. (({f procedure?} nil ls . ls*)
  964. (loopn f nil ls ls* ls ls ls*))
  965. #| end of CASE-DEFINE* |# )
  966. (define (null*? ls)
  967. (or (null? ls) (and (null? (car ls)) (null*? (cdr ls)))))
  968. (define (err* ls*)
  969. (with-who fold-left
  970. (cond ((null? ls*)
  971. (%error-length-mismatch-among-list-arguments))
  972. ((list? (car ls*))
  973. (err* (cdr ls*)))
  974. (else
  975. (%error-expected-proper-list-as-argument (car ls*))))))
  976. (define (cars+cdrs ls ls*)
  977. (with-who fold-left
  978. (if (null? ls)
  979. (values '() '())
  980. (let ((a (car ls)))
  981. (cond ((pair? a)
  982. (let-values (((cars cdrs) (cars+cdrs (cdr ls) (cdr ls*))))
  983. (values (cons (car a) cars) (cons (cdr a) cdrs))))
  984. ((list? (car ls*))
  985. (%error-length-mismatch-among-list-arguments))
  986. (else
  987. (%error-expected-proper-list-as-argument (car ls*))))))))
  988. (define (loop1 f nil h t ls)
  989. (with-who fold-left
  990. (cond ((pair? h)
  991. (let ((a (car h)) (h (cdr h)))
  992. (cond ((pair? h)
  993. (if (eq? h t)
  994. (%error-circular-list-is-invalid-as-argument ls)
  995. (let ((b (car h)) (h (cdr h)) (t (cdr t)))
  996. (loop1 f (f (f nil a) b) h t ls))))
  997. ((null? h)
  998. (f nil a))
  999. (else
  1000. (%error-expected-proper-list-as-argument ls)))))
  1001. ((null? h)
  1002. nil)
  1003. (else
  1004. (%error-expected-proper-list-as-argument ls)))))
  1005. (define (loopn f nil h h* t ls ls*)
  1006. (with-who fold-left
  1007. (cond ((pair? h)
  1008. (let-values (((a* h*) (cars+cdrs h* ls*)))
  1009. (let ((a (car h)) (h (cdr h)))
  1010. (cond ((pair? h)
  1011. (if (eq? h t)
  1012. (%error-circular-list-is-invalid-as-argument ls)
  1013. (let-values (((b* h*) (cars+cdrs h* ls*)))
  1014. (let ((b (car h)) (h (cdr h)) (t (cdr t)))
  1015. (loopn f
  1016. (apply f (apply f nil a a*) b b*)
  1017. h h* t ls ls*)))))
  1018. ((and (null? h)
  1019. (null*? h*))
  1020. (apply f nil a a*))
  1021. (else
  1022. (err* (cons ls ls*)))))))
  1023. ((and (null? h) (null*? h*))
  1024. nil)
  1025. (else
  1026. (err* (cons ls ls*))))))
  1027. #| end of module |# )
  1028. (module (fold-right)
  1029. (case-define* fold-right
  1030. (({f procedure?} nil ls)
  1031. (loop1 f nil ls ls ls))
  1032. (({f procedure?} nil ls . ls*)
  1033. (loopn f nil ls ls* ls ls ls*))
  1034. #| end of CASE-DEFINE* |# )
  1035. (define (null*? ls)
  1036. (or (null? ls) (and (null? (car ls)) (null*? (cdr ls)))))
  1037. (define (err* ls*)
  1038. (with-who fold-right
  1039. (cond ((null? ls*)
  1040. (%error-length-mismatch-among-list-arguments))
  1041. ((list? (car ls*))
  1042. (err* (cdr ls*)))
  1043. (else
  1044. (%error-expected-proper-list-as-argument (car ls*))))))
  1045. (define (cars+cdrs ls ls*)
  1046. (with-who fold-right
  1047. (if (null? ls)
  1048. (values '() '())
  1049. (let ((a (car ls)))
  1050. (cond ((pair? a)
  1051. (let-values (((cars cdrs) (cars+cdrs (cdr ls) (cdr ls*))))
  1052. (values (cons (car a) cars) (cons (cdr a) cdrs))))
  1053. ((list? (car ls*))
  1054. (%error-length-mismatch-among-list-arguments))
  1055. (else
  1056. (%error-expected-proper-list-as-argument (car ls*))))))))
  1057. (define (loop1 f nil h t ls)
  1058. (with-who fold-right
  1059. (cond ((pair? h)
  1060. (let ((a (car h)) (h (cdr h)))
  1061. (cond ((pair? h)
  1062. (if (eq? h t)
  1063. (%error-circular-list-is-invalid-as-argument ls)
  1064. (let ((b (car h)) (h (cdr h)) (t (cdr t)))
  1065. (f a (f b (loop1 f nil h t ls))))))
  1066. ((null? h)
  1067. (f a nil))
  1068. (else
  1069. (%error-expected-proper-list-as-argument ls)))))
  1070. ((null? h)
  1071. nil)
  1072. (else
  1073. (%error-expected-proper-list-as-argument ls)))))
  1074. (define (loopn f nil h h* t ls ls*)
  1075. (with-who fold-right
  1076. (cond ((pair? h)
  1077. (let-values (((a* h*) (cars+cdrs h* ls*)))
  1078. (let ((a (car h)) (h (cdr h)))
  1079. (cond ((pair? h)
  1080. (if (eq? h t)
  1081. (%error-circular-list-is-invalid-as-argument ls)
  1082. (let-values (((b* h*) (cars+cdrs h* ls*)))
  1083. (let ((b (car h))
  1084. (h (cdr h))
  1085. (t (cdr t)))
  1086. (apply f a
  1087. (append
  1088. a* (list
  1089. (apply f
  1090. b (append
  1091. b* (list (loopn f nil h h* t ls ls*)))))))))))
  1092. ((and (null? h)
  1093. (null*? h*))
  1094. (apply f a (append a* (list nil))))
  1095. (else
  1096. (err* (cons ls ls*)))))))
  1097. ((and (null? h) (null*? h*))
  1098. nil)
  1099. (else
  1100. (err* (cons ls ls*))))))
  1101. #| end of module |#)
  1102. ;;;; queue of items
  1103. (define make-queue-procs
  1104. (case-lambda
  1105. (()
  1106. (make-queue-procs '()))
  1107. ((init-values)
  1108. ;;The value of this variable is #f or a pair representing a queue of
  1109. ;;items.
  1110. ;;
  1111. ;;The car of the queue-pair is the first pair of the list of items.
  1112. ;;The cdr of the queue-pair is the last pair of the list of items.
  1113. ;;
  1114. (define queue-pair
  1115. (if (null? init-values)
  1116. #f
  1117. (cons init-values
  1118. (let find-last-pair ((L init-values))
  1119. (if (null? ($cdr L))
  1120. L
  1121. (find-last-pair ($cdr L)))))))
  1122. (define-syntax queue
  1123. (syntax-rules ()
  1124. ((_)
  1125. queue-pair)
  1126. ((_ ?item)
  1127. (set! queue-pair ?item))))
  1128. (define (empty-queue?)
  1129. (not (queue)))
  1130. (define (enqueue! item)
  1131. (if (queue)
  1132. (let ((old-last-pair ($cdr (queue)))
  1133. (new-last-pair (list item)))
  1134. ($set-cdr! old-last-pair new-last-pair)
  1135. ($set-cdr! (queue) new-last-pair))
  1136. (let ((Q (list item)))
  1137. (queue (cons Q Q)))))
  1138. (define (dequeue!)
  1139. (if (queue)
  1140. (let ((head ($car (queue))))
  1141. (begin0
  1142. ($car head)
  1143. (let ((head ($cdr head)))
  1144. (if (null? head)
  1145. (queue #f)
  1146. ($set-car! (queue) head)))))
  1147. (error 'dequeue! "no more items in queue")))
  1148. (values empty-queue? enqueue! dequeue!))))
  1149. ;;;; done
  1150. #| end of library |# )
  1151. ;;; end of file
  1152. ;; Local Variables:
  1153. ;; eval: (put 'with-who 'scheme-indent-function 1)
  1154. ;; End: