43.body.scm 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. ;;;;;; SRFI 43: Vector library -*- Scheme -*-
  2. ;;;
  3. ;;; $Id: vector-lib.scm,v 1.7 2009/03/29 09:46:03 sperber Exp $
  4. ;;;
  5. ;;; Taylor Campbell wrote this code; he places it in the public domain.
  6. ;;; Will Clinger [wdc] made some corrections, also in the public domain.
  7. ;;; Copyright (C) Taylor Campbell (2003). All rights reserved.
  8. ;;; Made an R7RS library by Taylan Ulrich Bayırlı/Kammer, Copyright (C) 2014.
  9. ;;; Permission is hereby granted, free of charge, to any person obtaining a copy
  10. ;;; of this software and associated documentation files (the "Software"), to
  11. ;;; deal in the Software without restriction, including without limitation the
  12. ;;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  13. ;;; sell copies of the Software, and to permit persons to whom the Software is
  14. ;;; furnished to do so, subject to the following conditions:
  15. ;;; The above copyright notice and this permission notice shall be included in
  16. ;;; all copies or substantial portions of the Software.
  17. ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. ;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. ;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. ;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. ;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. ;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  23. ;;; IN THE SOFTWARE.
  24. ;;; --------------------
  25. ;;; Exported procedure index
  26. ;;;
  27. ;;; * Constructors
  28. ;;; make-vector vector
  29. ;;; vector-unfold vector-unfold-right
  30. ;;; vector-copy vector-reverse-copy
  31. ;;; vector-append vector-concatenate
  32. ;;;
  33. ;;; * Predicates
  34. ;;; vector?
  35. ;;; vector-empty?
  36. ;;; vector=
  37. ;;;
  38. ;;; * Selectors
  39. ;;; vector-ref
  40. ;;; vector-length
  41. ;;;
  42. ;;; * Iteration
  43. ;;; vector-fold vector-fold-right
  44. ;;; vector-map vector-map!
  45. ;;; vector-for-each
  46. ;;; vector-count
  47. ;;;
  48. ;;; * Searching
  49. ;;; vector-index vector-skip
  50. ;;; vector-index-right vector-skip-right
  51. ;;; vector-binary-search
  52. ;;; vector-any vector-every
  53. ;;;
  54. ;;; * Mutators
  55. ;;; vector-set!
  56. ;;; vector-swap!
  57. ;;; vector-fill!
  58. ;;; vector-reverse!
  59. ;;; vector-copy! vector-reverse-copy!
  60. ;;; vector-reverse!
  61. ;;;
  62. ;;; * Conversion
  63. ;;; vector->list reverse-vector->list
  64. ;;; list->vector reverse-list->vector
  65. ;;; --------------------
  66. ;;; Commentary on efficiency of the code
  67. ;;; This code is somewhat tuned for efficiency. There are several
  68. ;;; internal routines that can be optimized greatly to greatly improve
  69. ;;; the performance of much of the library. These internal procedures
  70. ;;; are already carefully tuned for performance, and lambda-lifted by
  71. ;;; hand. Some other routines are lambda-lifted by hand, but only the
  72. ;;; loops are lambda-lifted, and only if some routine has two possible
  73. ;;; loops -- a fast path and an n-ary case --, whereas _all_ of the
  74. ;;; internal routines' loops are lambda-lifted so as to never cons a
  75. ;;; closure in their body (VECTOR-PARSE-START+END doesn't have a loop),
  76. ;;; even in Scheme systems that perform no loop optimization (which is
  77. ;;; most of them, unfortunately).
  78. ;;;
  79. ;;; Fast paths are provided for common cases in most of the loops in
  80. ;;; this library.
  81. ;;;
  82. ;;; All calls to primitive vector operations are protected by a prior
  83. ;;; type check; they can be safely converted to use unsafe equivalents
  84. ;;; of the operations, if available. Ideally, the compiler should be
  85. ;;; able to determine this, but the state of Scheme compilers today is
  86. ;;; not a happy one.
  87. ;;;
  88. ;;; Efficiency of the actual algorithms is a rather mundane point to
  89. ;;; mention; vector operations are rarely beyond being straightforward.
  90. ;;; --------------------
  91. ;;; Utilities
  92. (define (nonneg-int? x)
  93. (and (integer? x)
  94. (not (negative? x))))
  95. (define (between? x y z)
  96. (and (< x y)
  97. (<= y z)))
  98. (define (unspecified-value) (if #f #f))
  99. ;++ This should be implemented more efficiently. It shouldn't cons a
  100. ;++ closure, and the cons cells used in the loops when using this could
  101. ;++ be reused.
  102. (define (vectors-ref vectors i)
  103. (map (lambda (v) (vector-ref v i)) vectors))
  104. ;;; --------------------
  105. ;;; Internal routines
  106. ;;; These should all be integrated, native, or otherwise optimized --
  107. ;;; they're used a _lot_ --. All of the loops and LETs inside loops
  108. ;;; are lambda-lifted by hand, just so as not to cons closures in the
  109. ;;; loops. (If your compiler can do better than that if they're not
  110. ;;; lambda-lifted, then lambda-drop (?) them.)
  111. ;;; (VECTOR-PARSE-START+END <vector> <arguments>
  112. ;;; <start-name> <end-name>
  113. ;;; <callee>)
  114. ;;; -> [start end]
  115. ;;; Return two values, composing a valid range within VECTOR, as
  116. ;;; extracted from ARGUMENTS or defaulted from VECTOR -- 0 for START
  117. ;;; and the length of VECTOR for END --; START-NAME and END-NAME are
  118. ;;; purely for error checking.
  119. (define (vector-parse-start+end vec args start-name end-name callee)
  120. (let ((len (vector-length vec)))
  121. (cond ((null? args)
  122. (values 0 len))
  123. ((null? (cdr args))
  124. (check-indices vec
  125. (car args) start-name
  126. len end-name
  127. callee))
  128. ((null? (cddr args))
  129. (check-indices vec
  130. (car args) start-name
  131. (cadr args) end-name
  132. callee))
  133. (else
  134. (error "too many arguments"
  135. `(extra args were ,(cddr args))
  136. `(while calling ,callee))))))
  137. (define-syntax let-vector-start+end
  138. (syntax-rules ()
  139. ((let-vector-start+end ?callee ?vec ?args (?start ?end)
  140. ?body1 ?body2 ...)
  141. (let ((?vec (check-type vector? ?vec ?callee)))
  142. (receive (?start ?end)
  143. (vector-parse-start+end ?vec ?args '?start '?end
  144. ?callee)
  145. ?body1 ?body2 ...)))))
  146. ;;; (%SMALLEST-LENGTH <vector-list> <default-length> <callee>)
  147. ;;; -> exact, nonnegative integer
  148. ;;; Compute the smallest length of VECTOR-LIST. DEFAULT-LENGTH is
  149. ;;; the length that is returned if VECTOR-LIST is empty. Common use
  150. ;;; of this is in n-ary vector routines:
  151. ;;; (define (f vec . vectors)
  152. ;;; (let ((vec (check-type vector? vec f)))
  153. ;;; ...(%smallest-length vectors (vector-length vec) f)...))
  154. ;;; %SMALLEST-LENGTH takes care of the type checking -- which is what
  155. ;;; the CALLEE argument is for --; thus, the design is tuned for
  156. ;;; avoiding redundant type checks.
  157. (define %smallest-length
  158. (letrec ((loop (lambda (vector-list length callee)
  159. (if (null? vector-list)
  160. length
  161. (loop (cdr vector-list)
  162. (min (vector-length
  163. (check-type vector?
  164. (car vector-list)
  165. callee))
  166. length)
  167. callee)))))
  168. loop))
  169. ;;; (%VECTOR-REVERSE-COPY! <target> <tstart> <source> <sstart> <send>)
  170. ;;; Copy elements from SSTART to SEND from SOURCE to TARGET, in the
  171. ;;; reverse order.
  172. (define %vector-reverse-copy!
  173. (letrec ((loop (lambda (target source sstart i j)
  174. (cond ((>= i sstart)
  175. (vector-set! target j (vector-ref source i))
  176. (loop target source sstart
  177. (- i 1)
  178. (+ j 1)))))))
  179. (lambda (target tstart source sstart send)
  180. (loop target source sstart
  181. (- send 1)
  182. tstart))))
  183. ;;; (%VECTOR-REVERSE! <vector>)
  184. (define %vector-reverse!
  185. (letrec ((loop (lambda (vec i j)
  186. (cond ((<= i j)
  187. (let ((v (vector-ref vec i)))
  188. (vector-set! vec i (vector-ref vec j))
  189. (vector-set! vec j v)
  190. (loop vec (+ i 1) (- j 1))))))))
  191. (lambda (vec start end)
  192. (loop vec start (- end 1)))))
  193. ;;; (%VECTOR-FOLD1 <kons> <knil> <vector>) -> knil'
  194. ;;; (KONS <index> <knil> <elt>) -> knil'
  195. (define %vector-fold1
  196. (letrec ((loop (lambda (kons knil len vec i)
  197. (if (= i len)
  198. knil
  199. (loop kons
  200. (kons i knil (vector-ref vec i))
  201. len vec (+ i 1))))))
  202. (lambda (kons knil len vec)
  203. (loop kons knil len vec 0))))
  204. ;;; (%VECTOR-FOLD2+ <kons> <knil> <vector> ...) -> knil'
  205. ;;; (KONS <index> <knil> <elt> ...) -> knil'
  206. (define %vector-fold2+
  207. (letrec ((loop (lambda (kons knil len vectors i)
  208. (if (= i len)
  209. knil
  210. (loop kons
  211. (apply kons i knil
  212. (vectors-ref vectors i))
  213. len vectors (+ i 1))))))
  214. (lambda (kons knil len vectors)
  215. (loop kons knil len vectors 0))))
  216. ;;; (%VECTOR-MAP! <f> <target> <length> <vector>) -> target
  217. ;;; (F <index> <elt>) -> elt'
  218. (define %vector-map1!
  219. (letrec ((loop (lambda (f target vec i)
  220. (if (zero? i)
  221. target
  222. (let ((j (- i 1)))
  223. (vector-set! target j
  224. (f j (vector-ref vec j)))
  225. (loop f target vec j))))))
  226. (lambda (f target vec len)
  227. (loop f target vec len))))
  228. ;;; (%VECTOR-MAP2+! <f> <target> <vectors> <len>) -> target
  229. ;;; (F <index> <elt> ...) -> elt'
  230. (define %vector-map2+!
  231. (letrec ((loop (lambda (f target vectors i)
  232. (if (zero? i)
  233. target
  234. (let ((j (- i 1)))
  235. (vector-set! target j
  236. (apply f j (vectors-ref vectors j)))
  237. (loop f target vectors j))))))
  238. (lambda (f target vectors len)
  239. (loop f target vectors len))))
  240. ;;;;;;;;;;;;;;;;;;;;;;;; ***** vector-lib ***** ;;;;;;;;;;;;;;;;;;;;;;;
  241. ;;; --------------------
  242. ;;; Constructors
  243. ;;; (VECTOR-UNFOLD <f> <length> <initial-seed> ...) -> vector
  244. ;;; (F <index> <seed> ...) -> [elt seed' ...]
  245. ;;; The fundamental vector constructor. Creates a vector whose
  246. ;;; length is LENGTH and iterates across each index K between 0 and
  247. ;;; LENGTH, applying F at each iteration to the current index and the
  248. ;;; current seeds to receive N+1 values: first, the element to put in
  249. ;;; the Kth slot and then N new seeds for the next iteration.
  250. (define vector-unfold
  251. (letrec ((tabulate! ; Special zero-seed case.
  252. (lambda (f vec i len)
  253. (cond ((< i len)
  254. (vector-set! vec i (f i))
  255. (tabulate! f vec (+ i 1) len)))))
  256. (unfold1! ; Fast path for one seed.
  257. (lambda (f vec i len seed)
  258. (if (< i len)
  259. (receive (elt new-seed)
  260. (f i seed)
  261. (vector-set! vec i elt)
  262. (unfold1! f vec (+ i 1) len new-seed)))))
  263. (unfold2+! ; Slower variant for N seeds.
  264. (lambda (f vec i len seeds)
  265. (if (< i len)
  266. (receive (elt . new-seeds)
  267. (apply f i seeds)
  268. (vector-set! vec i elt)
  269. (unfold2+! f vec (+ i 1) len new-seeds))))))
  270. (lambda (f len . initial-seeds)
  271. (let ((f (check-type procedure? f vector-unfold))
  272. (len (check-type nonneg-int? len vector-unfold)))
  273. (let ((vec (make-vector len)))
  274. (cond ((null? initial-seeds)
  275. (tabulate! f vec 0 len))
  276. ((null? (cdr initial-seeds))
  277. (unfold1! f vec 0 len (car initial-seeds)))
  278. (else
  279. (unfold2+! f vec 0 len initial-seeds)))
  280. vec)))))
  281. ;;; (VECTOR-UNFOLD-RIGHT <f> <length> <initial-seed> ...) -> vector
  282. ;;; (F <seed> ...) -> [seed' ...]
  283. ;;; Like VECTOR-UNFOLD, but it generates elements from LENGTH to 0
  284. ;;; (still exclusive with LENGTH and inclusive with 0), not 0 to
  285. ;;; LENGTH as with VECTOR-UNFOLD.
  286. (define vector-unfold-right
  287. (letrec ((tabulate!
  288. (lambda (f vec i)
  289. (cond ((>= i 0)
  290. (vector-set! vec i (f i))
  291. (tabulate! f vec (- i 1))))))
  292. (unfold1!
  293. (lambda (f vec i seed)
  294. (if (>= i 0)
  295. (receive (elt new-seed)
  296. (f i seed)
  297. (vector-set! vec i elt)
  298. (unfold1! f vec (- i 1) new-seed)))))
  299. (unfold2+!
  300. (lambda (f vec i seeds)
  301. (if (>= i 0)
  302. (receive (elt . new-seeds)
  303. (apply f i seeds)
  304. (vector-set! vec i elt)
  305. (unfold2+! f vec (- i 1) new-seeds))))))
  306. (lambda (f len . initial-seeds)
  307. (let ((f (check-type procedure? f vector-unfold-right))
  308. (len (check-type nonneg-int? len vector-unfold-right)))
  309. (let ((vec (make-vector len))
  310. (i (- len 1)))
  311. (cond ((null? initial-seeds)
  312. (tabulate! f vec i))
  313. ((null? (cdr initial-seeds))
  314. (unfold1! f vec i (car initial-seeds)))
  315. (else
  316. (unfold2+! f vec i initial-seeds)))
  317. vec)))))
  318. ;;; (VECTOR-REVERSE-COPY <vector> [<start> <end>]) -> vector
  319. ;;; Create a newly allocated vector whose elements are the reversed
  320. ;;; sequence of elements between START and END in VECTOR. START's
  321. ;;; default is 0; END's default is the length of VECTOR.
  322. (define (vector-reverse-copy vec . maybe-start+end)
  323. (let-vector-start+end vector-reverse-copy vec maybe-start+end
  324. (start end)
  325. (let ((new (make-vector (- end start))))
  326. (%vector-reverse-copy! new 0 vec start end)
  327. new)))
  328. ;;; (VECTOR-CONCATENATE <vector-list>) -> vector
  329. ;;; Concatenate the vectors in VECTOR-LIST. This is equivalent to
  330. ;;; (apply vector-append VECTOR-LIST)
  331. ;;; but VECTOR-APPEND tends to be implemented in terms of
  332. ;;; VECTOR-CONCATENATE, and some Schemes bork when the list to apply
  333. ;;; a function to is too long.
  334. ;;;
  335. ;;; Actually, they're both implemented in terms of an internal routine.
  336. (define (vector-concatenate vector-list)
  337. (vector-concatenate:aux vector-list vector-concatenate))
  338. ;;; Auxiliary for VECTOR-APPEND and VECTOR-CONCATENATE
  339. (define vector-concatenate:aux
  340. (letrec ((compute-length
  341. (lambda (vectors len callee)
  342. (if (null? vectors)
  343. len
  344. (let ((vec (check-type vector? (car vectors)
  345. callee)))
  346. (compute-length (cdr vectors)
  347. (+ (vector-length vec) len)
  348. callee)))))
  349. (concatenate!
  350. (lambda (vectors target to)
  351. (if (null? vectors)
  352. target
  353. (let* ((vec1 (car vectors))
  354. (len (vector-length vec1)))
  355. (vector-copy! target to vec1 0 len)
  356. (concatenate! (cdr vectors) target
  357. (+ to len)))))))
  358. (lambda (vectors callee)
  359. (cond ((null? vectors) ;+++
  360. (make-vector 0))
  361. ((null? (cdr vectors)) ;+++
  362. ;; Blech, we still have to allocate a new one.
  363. (let* ((vec (check-type vector? (car vectors) callee))
  364. (len (vector-length vec))
  365. (new (make-vector len)))
  366. (vector-copy! new 0 vec 0 len)
  367. new))
  368. (else
  369. (let ((new-vector
  370. (make-vector (compute-length vectors 0 callee))))
  371. (concatenate! vectors new-vector 0)
  372. new-vector))))))
  373. ;;; --------------------
  374. ;;; Predicates
  375. ;;; (VECTOR-EMPTY? <vector>) -> boolean
  376. ;;; Return #T if VECTOR has zero elements in it, i.e. VECTOR's length
  377. ;;; is 0, and #F if not.
  378. (define (vector-empty? vec)
  379. (let ((vec (check-type vector? vec vector-empty?)))
  380. (zero? (vector-length vec))))
  381. ;;; (VECTOR= <elt=?> <vector> ...) -> boolean
  382. ;;; (ELT=? <value> <value>) -> boolean
  383. ;;; Determine vector equality generalized across element comparators.
  384. ;;; Vectors A and B are equal iff their lengths are the same and for
  385. ;;; each respective elements E_a and E_b (element=? E_a E_b) returns
  386. ;;; a true value. ELT=? is always applied to two arguments. Element
  387. ;;; comparison must be consistent wtih EQ?; that is, if (eq? E_a E_b)
  388. ;;; results in a true value, then (ELEMENT=? E_a E_b) must result in a
  389. ;;; true value. This may be exploited to avoid multiple unnecessary
  390. ;;; element comparisons. (This implementation does, but does not deal
  391. ;;; with the situation that ELEMENT=? is EQ? to avoid more unnecessary
  392. ;;; comparisons, but I believe this optimization is probably fairly
  393. ;;; insignificant.)
  394. ;;;
  395. ;;; If the number of vector arguments is zero or one, then #T is
  396. ;;; automatically returned. If there are N vector arguments,
  397. ;;; VECTOR_1 VECTOR_2 ... VECTOR_N, then VECTOR_1 & VECTOR_2 are
  398. ;;; compared; if they are equal, the vectors VECTOR_2 ... VECTOR_N
  399. ;;; are compared. The precise order in which ELT=? is applied is not
  400. ;;; specified.
  401. (define (vector= elt=? . vectors)
  402. (let ((elt=? (check-type procedure? elt=? vector=)))
  403. (cond ((null? vectors)
  404. #t)
  405. ((null? (cdr vectors))
  406. (check-type vector? (car vectors) vector=)
  407. #t)
  408. (else
  409. (let loop ((vecs vectors))
  410. (let ((vec1 (check-type vector? (car vecs) vector=))
  411. (vec2+ (cdr vecs)))
  412. (or (null? vec2+)
  413. (and (binary-vector= elt=? vec1 (car vec2+))
  414. (loop vec2+)))))))))
  415. (define (binary-vector= elt=? vector-a vector-b)
  416. (or (eq? vector-a vector-b) ;+++
  417. (let ((length-a (vector-length vector-a))
  418. (length-b (vector-length vector-b)))
  419. (letrec ((loop (lambda (i)
  420. (or (= i length-a)
  421. (and (< i length-b)
  422. (test (vector-ref vector-a i)
  423. (vector-ref vector-b i)
  424. i)))))
  425. (test (lambda (elt-a elt-b i)
  426. (and (or (eq? elt-a elt-b) ;+++
  427. (elt=? elt-a elt-b))
  428. (loop (+ i 1))))))
  429. (and (= length-a length-b)
  430. (loop 0))))))
  431. ;;; --------------------
  432. ;;; Iteration
  433. ;;; (VECTOR-FOLD <kons> <initial-knil> <vector> ...) -> knil
  434. ;;; (KONS <knil> <elt> ...) -> knil' ; N vectors -> N+1 args
  435. ;;; The fundamental vector iterator. KONS is iterated over each
  436. ;;; index in all of the vectors in parallel, stopping at the end of
  437. ;;; the shortest; KONS is applied to an argument list of (list I
  438. ;;; STATE (vector-ref VEC I) ...), where STATE is the current state
  439. ;;; value -- the state value begins with KNIL and becomes whatever
  440. ;;; KONS returned at the respective iteration --, and I is the
  441. ;;; current index in the iteration. The iteration is strictly left-
  442. ;;; to-right.
  443. ;;; (vector-fold KONS KNIL (vector E_1 E_2 ... E_N))
  444. ;;; <=>
  445. ;;; (KONS (... (KONS (KONS KNIL E_1) E_2) ... E_N-1) E_N)
  446. (define (vector-fold kons knil vec . vectors)
  447. (let ((kons (check-type procedure? kons vector-fold))
  448. (vec (check-type vector? vec vector-fold)))
  449. (if (null? vectors)
  450. (%vector-fold1 kons knil (vector-length vec) vec)
  451. (%vector-fold2+ kons knil
  452. (%smallest-length vectors
  453. (vector-length vec)
  454. vector-fold)
  455. (cons vec vectors)))))
  456. ;;; (VECTOR-FOLD-RIGHT <kons> <initial-knil> <vector> ...) -> knil
  457. ;;; (KONS <knil> <elt> ...) -> knil' ; N vectors => N+1 args
  458. ;;; The fundamental vector recursor. Iterates in parallel across
  459. ;;; VECTOR ... right to left, applying KONS to the elements and the
  460. ;;; current state value; the state value becomes what KONS returns
  461. ;;; at each next iteration. KNIL is the initial state value.
  462. ;;; (vector-fold-right KONS KNIL (vector E_1 E_2 ... E_N))
  463. ;;; <=>
  464. ;;; (KONS (... (KONS (KONS KNIL E_N) E_N-1) ... E_2) E_1)
  465. ;;;
  466. ;;; Not implemented in terms of a more primitive operations that might
  467. ;;; called %VECTOR-FOLD-RIGHT due to the fact that it wouldn't be very
  468. ;;; useful elsewhere.
  469. (define vector-fold-right
  470. (letrec ((loop1 (lambda (kons knil vec i)
  471. (if (negative? i)
  472. knil
  473. (loop1 kons (kons i knil (vector-ref vec i))
  474. vec
  475. (- i 1)))))
  476. (loop2+ (lambda (kons knil vectors i)
  477. (if (negative? i)
  478. knil
  479. (loop2+ kons
  480. (apply kons i knil
  481. (vectors-ref vectors i))
  482. vectors
  483. (- i 1))))))
  484. (lambda (kons knil vec . vectors)
  485. (let ((kons (check-type procedure? kons vector-fold-right))
  486. (vec (check-type vector? vec vector-fold-right)))
  487. (if (null? vectors)
  488. (loop1 kons knil vec (- (vector-length vec) 1))
  489. (loop2+ kons knil (cons vec vectors)
  490. (- (%smallest-length vectors
  491. (vector-length vec)
  492. vector-fold-right)
  493. 1)))))))
  494. ;;; (VECTOR-MAP <f> <vector> ...) -> vector
  495. ;;; (F <elt> ...) -> value ; N vectors -> N args
  496. ;;; Constructs a new vector of the shortest length of the vector
  497. ;;; arguments. Each element at index I of the new vector is mapped
  498. ;;; from the old vectors by (F I (vector-ref VECTOR I) ...). The
  499. ;;; dynamic order of application of F is unspecified.
  500. (define (vector-map f vec . vectors)
  501. (let ((f (check-type procedure? f vector-map))
  502. (vec (check-type vector? vec vector-map)))
  503. (if (null? vectors)
  504. (let ((len (vector-length vec)))
  505. (%vector-map1! f (make-vector len) vec len))
  506. (let ((len (%smallest-length vectors
  507. (vector-length vec)
  508. vector-map)))
  509. (%vector-map2+! f (make-vector len) (cons vec vectors)
  510. len)))))
  511. ;;; (VECTOR-MAP! <f> <vector> ...) -> unspecified
  512. ;;; (F <elt> ...) -> element' ; N vectors -> N args
  513. ;;; Similar to VECTOR-MAP, but rather than mapping the new elements
  514. ;;; into a new vector, the new mapped elements are destructively
  515. ;;; inserted into the first vector. Again, the dynamic order of
  516. ;;; application of F is unspecified, so it is dangerous for F to
  517. ;;; manipulate the first VECTOR.
  518. (define (vector-map! f vec . vectors)
  519. (let ((f (check-type procedure? f vector-map!))
  520. (vec (check-type vector? vec vector-map!)))
  521. (if (null? vectors)
  522. (%vector-map1! f vec vec (vector-length vec))
  523. (%vector-map2+! f vec (cons vec vectors)
  524. (%smallest-length vectors
  525. (vector-length vec)
  526. vector-map!)))
  527. (unspecified-value)))
  528. ;;; (VECTOR-FOR-EACH <f> <vector> ...) -> unspecified
  529. ;;; (F <elt> ...) ; N vectors -> N args
  530. ;;; Simple vector iterator: applies F to each index in the range [0,
  531. ;;; LENGTH), where LENGTH is the length of the smallest vector
  532. ;;; argument passed, and the respective element at that index. In
  533. ;;; contrast with VECTOR-MAP, F is reliably applied to each
  534. ;;; subsequent elements, starting at index 0 from left to right, in
  535. ;;; the vectors.
  536. (define vector-for-each
  537. (letrec ((for-each1
  538. (lambda (f vec i len)
  539. (cond ((< i len)
  540. (f i (vector-ref vec i))
  541. (for-each1 f vec (+ i 1) len)))))
  542. (for-each2+
  543. (lambda (f vecs i len)
  544. (cond ((< i len)
  545. (apply f i (vectors-ref vecs i))
  546. (for-each2+ f vecs (+ i 1) len))))))
  547. (lambda (f vec . vectors)
  548. (let ((f (check-type procedure? f vector-for-each))
  549. (vec (check-type vector? vec vector-for-each)))
  550. (if (null? vectors)
  551. (for-each1 f vec 0 (vector-length vec))
  552. (for-each2+ f (cons vec vectors) 0
  553. (%smallest-length vectors
  554. (vector-length vec)
  555. vector-for-each)))))))
  556. ;;; (VECTOR-COUNT <predicate?> <vector> ...)
  557. ;;; -> exact, nonnegative integer
  558. ;;; (PREDICATE? <index> <value> ...) ; N vectors -> N+1 args
  559. ;;; PREDICATE? is applied element-wise to the elements of VECTOR ...,
  560. ;;; and a count is tallied of the number of elements for which a
  561. ;;; true value is produced by PREDICATE?. This count is returned.
  562. (define (vector-count pred? vec . vectors)
  563. (let ((pred? (check-type procedure? pred? vector-count))
  564. (vec (check-type vector? vec vector-count)))
  565. (if (null? vectors)
  566. (%vector-fold1 (lambda (index count elt)
  567. (if (pred? index elt)
  568. (+ count 1)
  569. count))
  570. 0
  571. (vector-length vec)
  572. vec)
  573. (%vector-fold2+ (lambda (index count . elts)
  574. (if (apply pred? index elts)
  575. (+ count 1)
  576. count))
  577. 0
  578. (%smallest-length vectors
  579. (vector-length vec)
  580. vector-count)
  581. (cons vec vectors)))))
  582. ;;; --------------------
  583. ;;; Searching
  584. ;;; (VECTOR-INDEX <predicate?> <vector> ...)
  585. ;;; -> exact, nonnegative integer or #F
  586. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  587. ;;; Search left-to-right across VECTOR ... in parallel, returning the
  588. ;;; index of the first set of values VALUE ... such that (PREDICATE?
  589. ;;; VALUE ...) returns a true value; if no such set of elements is
  590. ;;; reached, return #F.
  591. (define (vector-index pred? vec . vectors)
  592. (vector-index/skip pred? vec vectors vector-index))
  593. ;;; (VECTOR-SKIP <predicate?> <vector> ...)
  594. ;;; -> exact, nonnegative integer or #F
  595. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  596. ;;; (vector-index (lambda elts (not (apply PREDICATE? elts)))
  597. ;;; VECTOR ...)
  598. ;;; Like VECTOR-INDEX, but find the index of the first set of values
  599. ;;; that do _not_ satisfy PREDICATE?.
  600. (define (vector-skip pred? vec . vectors)
  601. (vector-index/skip (lambda elts (not (apply pred? elts)))
  602. vec vectors
  603. vector-skip))
  604. ;;; Auxiliary for VECTOR-INDEX & VECTOR-SKIP
  605. (define vector-index/skip
  606. (letrec ((loop1 (lambda (pred? vec len i)
  607. (cond ((= i len) #f)
  608. ((pred? (vector-ref vec i)) i)
  609. (else (loop1 pred? vec len (+ i 1))))))
  610. (loop2+ (lambda (pred? vectors len i)
  611. (cond ((= i len) #f)
  612. ((apply pred? (vectors-ref vectors i)) i)
  613. (else (loop2+ pred? vectors len
  614. (+ i 1)))))))
  615. (lambda (pred? vec vectors callee)
  616. (let ((pred? (check-type procedure? pred? callee))
  617. (vec (check-type vector? vec callee)))
  618. (if (null? vectors)
  619. (loop1 pred? vec (vector-length vec) 0)
  620. (loop2+ pred? (cons vec vectors)
  621. (%smallest-length vectors
  622. (vector-length vec)
  623. callee)
  624. 0))))))
  625. ;;; (VECTOR-INDEX-RIGHT <predicate?> <vector> ...)
  626. ;;; -> exact, nonnegative integer or #F
  627. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  628. ;;; Right-to-left variant of VECTOR-INDEX.
  629. (define (vector-index-right pred? vec . vectors)
  630. (vector-index/skip-right pred? vec vectors vector-index-right))
  631. ;;; (VECTOR-SKIP-RIGHT <predicate?> <vector> ...)
  632. ;;; -> exact, nonnegative integer or #F
  633. ;;; (PREDICATE? <elt> ...) -> boolean ; N vectors -> N args
  634. ;;; Right-to-left variant of VECTOR-SKIP.
  635. (define (vector-skip-right pred? vec . vectors)
  636. (vector-index/skip-right (lambda elts (not (apply pred? elts)))
  637. vec vectors
  638. vector-index-right))
  639. (define vector-index/skip-right
  640. (letrec ((loop1 (lambda (pred? vec i)
  641. (cond ((negative? i) #f)
  642. ((pred? (vector-ref vec i)) i)
  643. (else (loop1 pred? vec (- i 1))))))
  644. (loop2+ (lambda (pred? vectors i)
  645. (cond ((negative? i) #f)
  646. ((apply pred? (vectors-ref vectors i)) i)
  647. (else (loop2+ pred? vectors (- i 1)))))))
  648. (lambda (pred? vec vectors callee)
  649. (let ((pred? (check-type procedure? pred? callee))
  650. (vec (check-type vector? vec callee)))
  651. (if (null? vectors)
  652. (loop1 pred? vec (- (vector-length vec) 1))
  653. (loop2+ pred? (cons vec vectors)
  654. (- (%smallest-length vectors
  655. (vector-length vec)
  656. callee)
  657. 1)))))))
  658. ;;; (VECTOR-BINARY-SEARCH <vector> <value> <cmp> [<start> <end>])
  659. ;;; -> exact, nonnegative integer or #F
  660. ;;; (CMP <value1> <value2>) -> integer
  661. ;;; positive -> VALUE1 > VALUE2
  662. ;;; zero -> VALUE1 = VALUE2
  663. ;;; negative -> VALUE1 < VALUE2
  664. ;;; Perform a binary search through VECTOR for VALUE, comparing each
  665. ;;; element to VALUE with CMP.
  666. (define (vector-binary-search vec value cmp . maybe-start+end)
  667. (let ((cmp (check-type procedure? cmp vector-binary-search)))
  668. (let-vector-start+end vector-binary-search vec maybe-start+end
  669. (start end)
  670. (let loop ((start start) (end end) (j #f))
  671. (let ((i (quotient (+ start end) 2)))
  672. (if (or (= start end) (and j (= i j)))
  673. #f
  674. (let ((comparison
  675. (check-type integer?
  676. (cmp (vector-ref vec i) value)
  677. `(,cmp for ,vector-binary-search))))
  678. (cond ((zero? comparison) i)
  679. ((positive? comparison) (loop start i i))
  680. (else (loop i end i))))))))))
  681. ;;; (VECTOR-ANY <pred?> <vector> ...) -> value
  682. ;;; Apply PRED? to each parallel element in each VECTOR ...; if PRED?
  683. ;;; should ever return a true value, immediately stop and return that
  684. ;;; value; otherwise, when the shortest vector runs out, return #F.
  685. ;;; The iteration and order of application of PRED? across elements
  686. ;;; is of the vectors is strictly left-to-right.
  687. (define vector-any
  688. (letrec ((loop1 (lambda (pred? vec i len len-1)
  689. (and (not (= i len))
  690. (if (= i len-1)
  691. (pred? (vector-ref vec i))
  692. (or (pred? (vector-ref vec i))
  693. (loop1 pred? vec (+ i 1)
  694. len len-1))))))
  695. (loop2+ (lambda (pred? vectors i len len-1)
  696. (and (not (= i len))
  697. (if (= i len-1)
  698. (apply pred? (vectors-ref vectors i))
  699. (or (apply pred? (vectors-ref vectors i))
  700. (loop2+ pred? vectors (+ i 1)
  701. len len-1)))))))
  702. (lambda (pred? vec . vectors)
  703. (let ((pred? (check-type procedure? pred? vector-any))
  704. (vec (check-type vector? vec vector-any)))
  705. (if (null? vectors)
  706. (let ((len (vector-length vec)))
  707. (loop1 pred? vec 0 len (- len 1)))
  708. (let ((len (%smallest-length vectors
  709. (vector-length vec)
  710. vector-any)))
  711. (loop2+ pred? (cons vec vectors) 0 len (- len 1))))))))
  712. ;;; (VECTOR-EVERY <pred?> <vector> ...) -> value
  713. ;;; Apply PRED? to each parallel value in each VECTOR ...; if PRED?
  714. ;;; should ever return #F, immediately stop and return #F; otherwise,
  715. ;;; if PRED? should return a true value for each element, stopping at
  716. ;;; the end of the shortest vector, return the last value that PRED?
  717. ;;; returned. In the case that there is an empty vector, return #T.
  718. ;;; The iteration and order of application of PRED? across elements
  719. ;;; is of the vectors is strictly left-to-right.
  720. (define vector-every
  721. (letrec ((loop1 (lambda (pred? vec i len len-1)
  722. (or (= i len)
  723. (if (= i len-1)
  724. (pred? (vector-ref vec i))
  725. (and (pred? (vector-ref vec i))
  726. (loop1 pred? vec (+ i 1)
  727. len len-1))))))
  728. (loop2+ (lambda (pred? vectors i len len-1)
  729. (or (= i len)
  730. (if (= i len-1)
  731. (apply pred? (vectors-ref vectors i))
  732. (and (apply pred? (vectors-ref vectors i))
  733. (loop2+ pred? vectors (+ i 1)
  734. len len-1)))))))
  735. (lambda (pred? vec . vectors)
  736. (let ((pred? (check-type procedure? pred? vector-every))
  737. (vec (check-type vector? vec vector-every)))
  738. (if (null? vectors)
  739. (let ((len (vector-length vec)))
  740. (loop1 pred? vec 0 len (- len 1)))
  741. (let ((len (%smallest-length vectors
  742. (vector-length vec)
  743. vector-every)))
  744. (loop2+ pred? (cons vec vectors) 0 len (- len 1))))))))
  745. ;;; --------------------
  746. ;;; Mutators
  747. ;;; (VECTOR-SWAP! <vector> <index1> <index2>) -> unspecified
  748. ;;; Swap the values in the locations at INDEX1 and INDEX2.
  749. (define (vector-swap! vec i j)
  750. (let ((vec (check-type vector? vec vector-swap!)))
  751. (let ((i (check-index vec i vector-swap!))
  752. (j (check-index vec j vector-swap!)))
  753. (let ((x (vector-ref vec i)))
  754. (vector-set! vec i (vector-ref vec j))
  755. (vector-set! vec j x)))))
  756. ;;; (VECTOR-REVERSE-COPY! <target> <tstart> <source> [<sstart> <send>])
  757. ;;; [wdc] Corrected to allow 0 <= sstart <= send <= (vector-length source).
  758. (define (vector-reverse-copy! target tstart source . maybe-sstart+send)
  759. (define (doit! sstart send source-length)
  760. (let ((tstart (check-type nonneg-int? tstart vector-reverse-copy!))
  761. (sstart (check-type nonneg-int? sstart vector-reverse-copy!))
  762. (send (check-type nonneg-int? send vector-reverse-copy!)))
  763. (cond ((and (eq? target source)
  764. (or (between? sstart tstart send)
  765. (between? tstart sstart
  766. (+ tstart (- send sstart)))))
  767. (error "vector range for self-copying overlaps"
  768. vector-reverse-copy!
  769. `(vector was ,target)
  770. `(tstart was ,tstart)
  771. `(sstart was ,sstart)
  772. `(send was ,send)))
  773. ((and (<= 0 sstart send source-length)
  774. (<= (+ tstart (- send sstart)) (vector-length target)))
  775. (%vector-reverse-copy! target tstart source sstart send))
  776. (else
  777. (error "illegal arguments"
  778. `(while calling ,vector-reverse-copy!)
  779. `(target was ,target)
  780. `(target-length was ,(vector-length target))
  781. `(tstart was ,tstart)
  782. `(source was ,source)
  783. `(source-length was ,source-length)
  784. `(sstart was ,sstart)
  785. `(send was ,send))))))
  786. (let ((n (vector-length source)))
  787. (cond ((null? maybe-sstart+send)
  788. (doit! 0 n n))
  789. ((null? (cdr maybe-sstart+send))
  790. (doit! (car maybe-sstart+send) n n))
  791. ((null? (cddr maybe-sstart+send))
  792. (doit! (car maybe-sstart+send) (cadr maybe-sstart+send) n))
  793. (else
  794. (error "too many arguments"
  795. vector-reverse-copy!
  796. (cddr maybe-sstart+send))))))
  797. ;;; (VECTOR-REVERSE! <vector> [<start> <end>]) -> unspecified
  798. ;;; Destructively reverse the contents of the sequence of locations
  799. ;;; in VECTOR between START, whose default is 0, and END, whose
  800. ;;; default is the length of VECTOR.
  801. (define (vector-reverse! vec . start+end)
  802. (let-vector-start+end vector-reverse! vec start+end
  803. (start end)
  804. (%vector-reverse! vec start end)))
  805. ;;; --------------------
  806. ;;; Conversion
  807. ;;; (REVERSE-VECTOR->LIST <vector> [<start> <end>]) -> list
  808. ;;; Produce a list containing the elements in the locations between
  809. ;;; START, whose default is 0, and END, whose default is the length
  810. ;;; of VECTOR, from VECTOR, in reverse order.
  811. (define (reverse-vector->list vec . maybe-start+end)
  812. (let-vector-start+end reverse-vector->list vec maybe-start+end
  813. (start end)
  814. ;(unfold (lambda (i) (= i end)) ; No SRFI 1.
  815. ; (lambda (i) (vector-ref vec i))
  816. ; (lambda (i) (+ i 1))
  817. ; start)
  818. (do ((i start (+ i 1))
  819. (result '() (cons (vector-ref vec i) result)))
  820. ((= i end) result))))
  821. ;;; (LIST->VECTOR <list> [<start> <end>]) -> vector
  822. ;;; [R5RS+] Produce a vector containing the elements in LIST, which
  823. ;;; must be a proper list, between START, whose default is 0, & END,
  824. ;;; whose default is the length of LIST. It is suggested that if the
  825. ;;; length of LIST is known in advance, the START and END arguments
  826. ;;; be passed, so that LIST->VECTOR need not call LENGTH to determine
  827. ;;; the the length.
  828. ;;;
  829. ;;; This implementation diverges on circular lists, unless LENGTH fails
  830. ;;; and causes - to fail as well. Given a LENGTH* that computes the
  831. ;;; length of a list's cycle, this wouldn't diverge, and would work
  832. ;;; great for circular lists.
  833. (define list->vector
  834. (case-lambda
  835. ((lst) (%list->vector lst))
  836. ((lst start) (list->vector lst start (length lst)))
  837. ((lst start end)
  838. (let ((start (check-type nonneg-int? start list->vector))
  839. (end (check-type nonneg-int? end list->vector)))
  840. ((lambda (f)
  841. (vector-unfold f (- end start) (list-tail lst start)))
  842. (lambda (index l)
  843. (cond ((null? l)
  844. (error "list was too short"
  845. `(list was ,lst)
  846. `(attempted end was ,end)
  847. `(while calling ,list->vector)))
  848. ((pair? l)
  849. (values (car l) (cdr l)))
  850. (else
  851. ;; Make this look as much like what CHECK-TYPE
  852. ;; would report as possible.
  853. (error "erroneous value"
  854. ;; We want SRFI 1's PROPER-LIST?, but it
  855. ;; would be a waste to link all of SRFI
  856. ;; 1 to this module for only the single
  857. ;; function PROPER-LIST?.
  858. (list list? lst)
  859. `(while calling
  860. ,list->vector))))))))))
  861. ;;; (REVERSE-LIST->VECTOR <list> [<start> <end>]) -> vector
  862. ;;; Produce a vector containing the elements in LIST, which must be a
  863. ;;; proper list, between START, whose default is 0, and END, whose
  864. ;;; default is the length of LIST, in reverse order. It is suggested
  865. ;;; that if the length of LIST is known in advance, the START and END
  866. ;;; arguments be passed, so that REVERSE-LIST->VECTOR need not call
  867. ;;; LENGTH to determine the the length.
  868. ;;;
  869. ;;; This also diverges on circular lists unless, again, LENGTH returns
  870. ;;; something that makes - bork.
  871. (define reverse-list->vector
  872. (case-lambda
  873. ((lst) (reverse-list->vector lst 0 (length lst)))
  874. ((lst start) (reverse-list->vector start (length lst)))
  875. ((lst start end)
  876. (let ((start (check-type nonneg-int? start reverse-list->vector))
  877. (end (check-type nonneg-int? end reverse-list->vector)))
  878. ((lambda (f)
  879. (vector-unfold-right f (- end start) (list-tail lst start)))
  880. (lambda (index l)
  881. (cond ((null? l)
  882. (error "list too short"
  883. `(list was ,lst)
  884. `(attempted end was ,end)
  885. `(while calling ,reverse-list->vector)))
  886. ((pair? l)
  887. (values (car l) (cdr l)))
  888. (else
  889. (error "erroneous value"
  890. (list list? lst)
  891. `(while calling ,reverse-list->vector))))))))))