From 648f615b778697149f91af774d7e55c9a58dba8c Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Tue, 28 Jul 2020 15:29:49 +0900 Subject: [PATCH] tabs in srfi 146 --- lib/srfi/146/hamt-map-test.scm | 312 ++++----- lib/srfi/146/hamt-map.scm | 12 +- lib/srfi/146/hamt-misc-test.scm | 8 +- lib/srfi/146/hamt-misc.scm | 14 +- lib/srfi/146/hamt.scm | 1050 ++++++++++++++--------------- lib/srfi/146/hash.scm | 384 +++++------ lib/srfi/146/mapping.scm | 448 ++++++------ lib/srfi/146/rbtree.scm | 248 +++---- lib/srfi/146/test.sld | 2 +- lib/srfi/146/vector-edit-test.scm | 24 +- lib/srfi/146/vector-edit.scm | 16 +- 11 files changed, 1259 insertions(+), 1259 deletions(-) diff --git a/lib/srfi/146/hamt-map-test.scm b/lib/srfi/146/hamt-map-test.scm index b9ea0718..6255aa12 100644 --- a/lib/srfi/146/hamt-map-test.scm +++ b/lib/srfi/146/hamt-map-test.scm @@ -38,61 +38,61 @@ (define (sort-alist alist) (list-sort (lambda (a1 a2) (stringchar (+ 97 (random-integer 26))))))))) + (let ((size (+ (random-integer max-key-length) 1))) + (with-output-to-string + (lambda () + (do ((i 0 (+ i 1))) + ((= i size)) + (write-char (integer->char (+ 97 (random-integer 26))))))))) (define (fill-phm i phm) - (let ((size (hash-table-size contents))) - (cond ((zero? i) phm) - ((and (not (zero? size)) - (zero? (random-integer deletion-odds))) - (let ((key (list-ref (hash-table-keys contents) - (random-integer size)))) - (set-adjoin! deleted-keys key) - (hash-table-delete! contents key) - (fill-phm (- i 1) - (remove phm key)))) - (else (let* ((key (random-key)) - (datum (random-integer 1000))) - (set-delete! deleted-keys key) - (hash-table-set! contents key datum) - (fill-phm (- i 1) - (put phm key datum))))))) + (let ((size (hash-table-size contents))) + (cond ((zero? i) phm) + ((and (not (zero? size)) + (zero? (random-integer deletion-odds))) + (let ((key (list-ref (hash-table-keys contents) + (random-integer size)))) + (set-adjoin! deleted-keys key) + (hash-table-delete! contents key) + (fill-phm (- i 1) + (remove phm key)))) + (else (let* ((key (random-key)) + (datum (random-integer 1000))) + (set-delete! deleted-keys key) + (hash-table-set! contents key datum) + (fill-phm (- i 1) + (put phm key datum))))))) (let ((phm (fill-phm operations - (transform (make-phm string-hash string=?))))) - (test-assert (= (phm/count phm) (hash-table-size contents))) - (hash-table-for-each (lambda (key datum) - (test-assert (= datum (phm/get phm key -1))) - (test-assert (phm/contains? phm key))) - contents) - (set-for-each (lambda (key) - (test-assert (= -1 (phm/get phm key -1))) - (test-assert (not (phm/contains? phm key)))) - deleted-keys) - (let ((ht-alist (hash-table->alist contents)) - (phm-alist (phm->alist phm))) - (test-assert (equal? (sort-alist ht-alist) - (sort-alist phm-alist))))))) + (transform (make-phm string-hash string=?))))) + (test-assert (= (phm/count phm) (hash-table-size contents))) + (hash-table-for-each (lambda (key datum) + (test-assert (= datum (phm/get phm key -1))) + (test-assert (phm/contains? phm key))) + contents) + (set-for-each (lambda (key) + (test-assert (= -1 (phm/get phm key -1))) + (test-assert (not (phm/contains? phm key)))) + deleted-keys) + (let ((ht-alist (hash-table->alist contents)) + (phm-alist (phm->alist phm))) + (test-assert (equal? (sort-alist ht-alist) + (sort-alist phm-alist))))))) (define (phm-remove-non-existent-test remove transform) (define (terrible-hash string) 0) (let ((phm (remove (transform (make-phm string-hash string=?)) - "not-present"))) + "not-present"))) (test-assert (zero? (phm/count phm))) (test-assert (not (phm/contains? phm "not-present"))) (test-assert (not (phm/get phm "not-present" #f)))) (let ((phm (remove (transform (phm/put (make-phm terrible-hash string=?) - "foo" - 1)) - "not-present"))) + "foo" + 1)) + "not-present"))) (test-assert (= 1 (phm/count phm))) (test-assert (phm/contains? phm "foo")) (test-assert (not (phm/contains? phm "not-present"))))) @@ -102,72 +102,72 @@ (list-sort (lambda (a1 a2) (stringalist phm))) - (test-assert (equal? (sort-alist alist) - (sort-alist phm-alist)))) + (test-assert (equal? (sort-alist alist) + (sort-alist phm-alist)))) (let ((alist-minus-baz (alist-delete "baz" alist string=?)) - (phm-minus-baz (remove (transform phm) "baz"))) - (assert-phm= phm-minus-baz alist-minus-baz) - (let ((phm-minus-nonexistent (remove phm-minus-baz "not-present"))) - (test-equal = (phm/count phm-minus-nonexistent) (- (length alist) 1)) - (let ((alist-minus-bat (alist-delete "bat" alist-minus-baz string=?)) - (phm-minus-bat (remove phm-minus-nonexistent "bat"))) - (assert-phm= phm-minus-bat alist-minus-bat)))))) + (phm-minus-baz (remove (transform phm) "baz"))) + (assert-phm= phm-minus-baz alist-minus-baz) + (let ((phm-minus-nonexistent (remove phm-minus-baz "not-present"))) + (test-equal = (phm/count phm-minus-nonexistent) (- (length alist) 1)) + (let ((alist-minus-bat (alist-delete "bat" alist-minus-baz string=?)) + (phm-minus-bat (remove phm-minus-nonexistent "bat"))) + (assert-phm= phm-minus-bat alist-minus-bat)))))) (define (persistent-hash-map replace transform) (define (sort-alist alist) (list-sort (lambda (a1 a2) (stringalist phm)))) (test-assert (equal? alist-3 - (sort-alist - (phm->alist - (replace phm "c" (lambda (x) hamt-null)))))))) + (sort-alist + (phm->alist + (replace phm "c" (lambda (x) hamt-null)))))))) (define (hamt-max-depth hamt) "Return maximum depth of `hamt'. For testing." (let descend ((n (hamt/root hamt))) (cond ((collision? n) 1) - ((narrow? n) - (let* ((array (narrow/array n)) - (stride (leaf-stride (hamt/payload? hamt))) - (start (* stride (bit-count (narrow/leaves n)))) - (end (vector-length array))) - (do ((i start (+ i 1)) - (high 0 (max high (descend (vector-ref array i))))) - ((= i end) (+ high 1))))) - ((wide? n) - (let ((array (wide/array n)) - (c (wide/children n))) - (let next-child ((high 0) - (i 0)) - (cond ((next-set-bit c i hamt-bucket-size) - => (lambda (j) - (next-child (max high - (descend (vector-ref array j))) - (+ j 1)))) - (else (+ high 1)))))) - (else (error "Invalid type of node." n))))) + ((narrow? n) + (let* ((array (narrow/array n)) + (stride (leaf-stride (hamt/payload? hamt))) + (start (* stride (bit-count (narrow/leaves n)))) + (end (vector-length array))) + (do ((i start (+ i 1)) + (high 0 (max high (descend (vector-ref array i))))) + ((= i end) (+ high 1))))) + ((wide? n) + (let ((array (wide/array n)) + (c (wide/children n))) + (let next-child ((high 0) + (i 0)) + (cond ((next-set-bit c i hamt-bucket-size) + => (lambda (j) + (next-child (max high + (descend (vector-ref array j))) + (+ j 1)))) + (else (+ high 1)))))) + (else (error "Invalid type of node." n))))) (test-begin "hamt-map") (test-group "(persistent-hash-map make-phm alist)" (let* ((alist '(("a" . 1) ("b" . 2))) - (phm (make-phm string-hash string=? alist))) + (phm (make-phm string-hash string=? alist))) (test-assert (not (hamt/mutable? phm))) (assert-phm= phm alist))) @@ -189,20 +189,20 @@ (define (flip mutate? phm) ((if mutate? phm/mutable phm/immutable) phm)) (phm-random-test (let ((mutate? #t)) - (lambda (phm key datum) - (set! mutate? (not mutate?)) - ((if mutate? phm/put! phm/put) - (flip mutate? phm) - key - datum))) - (let ((count 0)) - (lambda (phm key) - (set! count (remainder (+ count 1) 3)) - (let ((mutate? (zero? count))) - ((if mutate? phm/remove! phm/remove) - (flip mutate? phm) - key)))) - (lambda (m) m))) + (lambda (phm key datum) + (set! mutate? (not mutate?)) + ((if mutate? phm/put! phm/put) + (flip mutate? phm) + key + datum))) + (let ((count 0)) + (lambda (phm key) + (set! count (remainder (+ count 1) 3)) + (let ((mutate? (zero? count))) + ((if mutate? phm/remove! phm/remove) + (flip mutate? phm) + key)))) + (lambda (m) m))) (test-group "(persistent-hash-map remove-non-existent pure)" (phm-remove-non-existent-test phm/remove (lambda (m) m))) @@ -212,12 +212,12 @@ (test-group "(persistent-hash-map phm/add-alist)" (let* ((alist '(("foo" . 1) ("bar" . 2) ("baz" . 3))) - (phm (phm/add-alist (make-phm string-hash string=?) alist))) + (phm (phm/add-alist (make-phm string-hash string=?) alist))) (assert-phm= phm alist))) (test-group "(persistent-hash-map phm/add-alist!)" (let* ((alist '(("foo" . 1) ("bar" . 2) ("baz" . 3))) - (phm (phm/mutable (make-phm string-hash string=?)))) + (phm (phm/mutable (make-phm string-hash string=?)))) (phm/add-alist! phm alist) (assert-phm= phm alist))) @@ -231,26 +231,26 @@ "Test that hashes that differ only above `hamt-hash-size' still work." (define big-hash (let* ((big-1 (expt 2 hamt-hash-size)) - (big-2 (* 2 big-1))) - (lambda (string) - (cond ((string=? string "foo") big-1) - (else big-2))))) + (big-2 (* 2 big-1))) + (lambda (string) + (cond ((string=? string "foo") big-1) + (else big-2))))) (let* ((alist '(("foo" . 1) ("bar" . 2) ("baz" . 3) ("bat" . 4) - ("quux" . 5))) - (phm (phm/add-alist (make-phm big-hash string=?) alist))) + ("quux" . 5))) + (phm (phm/add-alist (make-phm big-hash string=?) alist))) (assert-phm= phm alist))) (test-group "(persistent-hash-map same-first-fragment)" (define (same-first-fragment string) (* hamt-bucket-size (string-hash string))) (let* ((alist '(("foo" . 1) ("bar" . 2) ("baz" . 3) ("bat" . 4) - ("quux" . 5))) - (phm (phm/add-alist (make-phm same-first-fragment string=?) alist))) + ("quux" . 5))) + (phm (phm/add-alist (make-phm same-first-fragment string=?) alist))) (assert-phm= phm alist) (let ((phm-minus-baz (phm/remove phm "baz"))) - (assert-phm= phm-minus-baz (alist-delete "baz" alist string=?))) + (assert-phm= phm-minus-baz (alist-delete "baz" alist string=?))) (let ((phm-minus-nonexistent (phm/remove phm "not-present"))) - (test-assert (= (phm/count phm-minus-nonexistent) (length alist)))))) + (test-assert (= (phm/count phm-minus-nonexistent) (length alist)))))) (test-group "(persistent-hash-map pure-mutate-interference)" "Test that mutating and pure operations interact with each other @@ -258,20 +258,20 @@ correctly." (define (alist-replace alist key datum) (cons (cons key datum) (alist-delete key alist string=?))) (let* ((m0 (make-phm string-hash string=?)) - (a1 '(("foo" . 1) ("bar" . 2) ("baz" . 3))) - (m1 (phm/add-alist m0 a1)) - (a4 (alist-replace a1 "foo" 4)) - (m2 (phm/put m1 "foo" 4)) - (a5 (alist-replace a1 "foo" 5)) - (m3 (phm/mutable m2)) - (m4 (phm/put! m3 "foo" 5)) - (a6 (alist-replace a1 "foo" 6)) - (m5 (phm/immutable m4)) - (m6 (phm/mutable m5)) - (m7 (phm/put! m6 "foo" 6)) - (a7 (alist-replace a1 "foo" 7)) - (a8 (alist-replace a1 "foo" 8)) - (m8 (phm/put! m6 "foo" 7))) + (a1 '(("foo" . 1) ("bar" . 2) ("baz" . 3))) + (m1 (phm/add-alist m0 a1)) + (a4 (alist-replace a1 "foo" 4)) + (m2 (phm/put m1 "foo" 4)) + (a5 (alist-replace a1 "foo" 5)) + (m3 (phm/mutable m2)) + (m4 (phm/put! m3 "foo" 5)) + (a6 (alist-replace a1 "foo" 6)) + (m5 (phm/immutable m4)) + (m6 (phm/mutable m5)) + (m7 (phm/put! m6 "foo" 6)) + (a7 (alist-replace a1 "foo" 7)) + (a8 (alist-replace a1 "foo" 8)) + (m8 (phm/put! m6 "foo" 7))) (phm/put! m4 "foo" 8) (assert-phm= m0 '()) (assert-phm= m1 a1) @@ -283,31 +283,31 @@ correctly." (assert-phm= m7 a7) (assert-phm= m8 a7) (let ((a (alist-delete "foo" a1 string=?)) - (m9 (phm/remove! m4 "foo"))) - (assert-phm= m4 a) - (assert-phm= m9 a)))) + (m9 (phm/remove! m4 "foo"))) + (assert-phm= m4 a) + (assert-phm= m9 a)))) (test-group "(persistent-hash-map phm/data)" (let* ((alist '(("a" . 1) ("b" . 2) ("c" . 3))) - (data (phm/data (make-phm string-hash string=? alist)))) + (data (phm/data (make-phm string-hash string=? alist)))) (test-assert (equal? (map cdr alist) - (list-sort < data))))) + (list-sort < data))))) (test-group "(persistent-hash-map phm/keys)" (let* ((alist '(("a" . 1) ("b" . 2) ("c" . 3))) - (keys (phm/keys (make-phm string-hash string=? alist)))) + (keys (phm/keys (make-phm string-hash string=? alist)))) (test-assert (equal? (map car alist) - (list-sort stringalist phm-2))))))) + (lambda (k d) (if (string=? k "b") (+ d 1) d))))) + (test-assert (equal? alist-2 (sort-alist (phm->alist phm-2))))))) (test-group "(persistent-hash-map phm/mutable?)" (let ((phm (make-phm string-hash string=?))) @@ -336,26 +336,26 @@ correctly." (test-group "(persistent-hash-map modify-collision add-different-hash)" (define (terrible-hash string) (cond ((string=? string "foo") 0) - ((string=? string "bar") 0) - (else hamt-bucket-size))) ; same as 0 in bottom 5 bits + ((string=? string "bar") 0) + (else hamt-bucket-size))) ; same as 0 in bottom 5 bits (let* ((alist '(("foo" . 1) ("bar" . 2))) - (phm-1 (make-phm terrible-hash string=? alist)) - (phm-2 (phm/put phm-1 "baz" 3))) + (phm-1 (make-phm terrible-hash string=? alist)) + (phm-2 (phm/put phm-1 "baz" 3))) (assert-phm= phm-2 '(("foo" . 1) ("bar" . 2) ("baz" . 3))))) (test-group "(persistent-hash-map lower-collision)" (define same-bottom-three-fragments (expt hamt-bucket-size 3)) (define (terrible-hash string) (if (or (string=? string "foo") - (string=? string "bar")) - same-bottom-three-fragments - (* 2 same-bottom-three-fragments))) + (string=? string "bar")) + same-bottom-three-fragments + (* 2 same-bottom-three-fragments))) (let* ((alist '(("foo" . 1) ("bar" . 2))) - (phm-1 (make-phm terrible-hash string=? alist)) - (phm-2 (phm/put phm-1 "baz" 3)) - (phm-3 (phm/remove phm-2 "foo")) - (phm-4 (phm/remove phm-3 "bar")) - (phm-5 (phm/remove phm-4 "baz"))) + (phm-1 (make-phm terrible-hash string=? alist)) + (phm-2 (phm/put phm-1 "baz" 3)) + (phm-3 (phm/remove phm-2 "foo")) + (phm-4 (phm/remove phm-3 "bar")) + (phm-5 (phm/remove phm-4 "baz"))) (assert-phm= phm-2 '(("foo" . 1) ("bar" . 2) ("baz" . 3))) (assert-phm= phm-3 '(("bar" . 2) ("baz" . 3))) (assert-phm= phm-4 '(("baz" . 3))) diff --git a/lib/srfi/146/hamt-map.scm b/lib/srfi/146/hamt-map.scm index 55381552..fb4f0f27 100644 --- a/lib/srfi/146/hamt-map.scm +++ b/lib/srfi/146/hamt-map.scm @@ -142,10 +142,10 @@ (define (make-phm-inner hash = alist) (let ((phm (make-hamt = hash #t))) (if (null? alist) - phm - (let ((phm-1 (phm/mutable phm))) - (phm/add-alist! phm-1 alist) - (phm/immutable phm-1))))) + phm + (let ((phm-1 (phm/mutable phm))) + (phm/add-alist! phm-1 alist) + (phm/immutable phm-1))))) (define make-phm (case-lambda @@ -197,8 +197,8 @@ (assert (phm? phm)) (let ((result (hamt-fetch phm key))) (if (hamt-null? result) - default - result))) + default + result))) (define phm/get (case-lambda diff --git a/lib/srfi/146/hamt-misc-test.scm b/lib/srfi/146/hamt-misc-test.scm index 3c8790cf..c93063e8 100644 --- a/lib/srfi/146/hamt-misc-test.scm +++ b/lib/srfi/146/hamt-misc-test.scm @@ -27,13 +27,13 @@ (test-group "(do-list)" (let ((index-accumulator '()) - (value-accumulator '()) - (all-values '(1 2 3 4 5))) + (value-accumulator '()) + (all-values '(1 2 3 4 5))) (do-list (value all-values) - (set! value-accumulator (cons value value-accumulator))) + (set! value-accumulator (cons value value-accumulator))) (test all-values (reverse value-accumulator)) (do-list (value index all-values) - (set! index-accumulator (cons index index-accumulator))) + (set! index-accumulator (cons index index-accumulator))) (test '(4 3 2 1 0) index-accumulator))) (test-end)) \ No newline at end of file diff --git a/lib/srfi/146/hamt-misc.scm b/lib/srfi/146/hamt-misc.scm index 3445a372..8f84aef1 100644 --- a/lib/srfi/146/hamt-misc.scm +++ b/lib/srfi/146/hamt-misc.scm @@ -27,8 +27,8 @@ ((_ (operator argument ...)) (unless (operator argument ...) (error "Assertion failed:" - '(operator argument ...) - (list 'operator argument ...)))) + '(operator argument ...) + (list 'operator argument ...)))) ((_ expression) (unless expression (error "Assertion failed:" 'expression))))) @@ -37,15 +37,15 @@ (syntax-rules () ((_ (variable list) body ...) (do ((remaining list (cdr remaining))) - ((null? remaining)) + ((null? remaining)) (let ((variable (car remaining))) - body ...))) + body ...))) ((_ (element-variable index-variable list) body ...) (do ((remaining list (cdr remaining)) - (index-variable 0 (+ index-variable 1))) - ((null? remaining)) + (index-variable 0 (+ index-variable 1))) + ((null? remaining)) (let ((element-variable (car remaining))) - body ...))))) + body ...))))) (define string-comparator (make-comparator string? string=? #f string-hash)) diff --git a/lib/srfi/146/hamt.scm b/lib/srfi/146/hamt.scm index cb2dbf5e..960dd5e6 100644 --- a/lib/srfi/146/hamt.scm +++ b/lib/srfi/146/hamt.scm @@ -122,12 +122,12 @@ data in wide nodes will have been modified since the change to mutable happened.)" (if (hamt/mutable? hamt) (let ((payload? (hamt/payload? hamt))) - (%make-hamt (hamt/= hamt) - (hamt/count hamt) - (hamt/hash hamt) - #f - payload? - (->immutable (hamt/root hamt) payload? replace))) + (%make-hamt (hamt/= hamt) + (hamt/count hamt) + (hamt/hash hamt) + #f + payload? + (->immutable (hamt/root hamt) payload? replace))) hamt)) (define hamt/immutable @@ -139,24 +139,24 @@ happened.)" (if (hamt/mutable? hamt) hamt (%make-hamt (hamt/= hamt) - (hamt/count hamt) - (hamt/hash hamt) - #t - (hamt/payload? hamt) - (hamt/root hamt)))) + (hamt/count hamt) + (hamt/hash hamt) + #t + (hamt/payload? hamt) + (hamt/root hamt)))) (define (hamt/replace hamt key dp) (assert (not (hamt/mutable? hamt))) (let*-values (((payload?) (hamt/payload? hamt)) - ((root) (hamt/root hamt)) - ((==) (hamt/= hamt)) - ((hp) (hamt/hash hamt)) - ((hash) (hash-bits hp key)) - ((change node) (modify-pure hamt root 0 dp hash key))) + ((root) (hamt/root hamt)) + ((==) (hamt/= hamt)) + ((hp) (hamt/hash hamt)) + ((hash) (hash-bits hp key)) + ((change node) (modify-pure hamt root 0 dp hash key))) (if (eq? node root) - hamt - (let ((count (+ (hamt/count hamt) change))) - (%make-hamt == count hp #f payload? node))))) + hamt + (let ((count (+ (hamt/count hamt) change))) + (%make-hamt == count hp #f payload? node))))) (define (hamt/put hamt key datum) (hamt/replace hamt key (lambda (x) datum))) @@ -164,9 +164,9 @@ happened.)" (define (hamt/replace! hamt key dp) (assert (hamt/mutable? hamt)) (let*-values (((root) (hamt/root hamt)) - ((hp) (hamt/hash hamt)) - ((hash) (hash-bits hp key)) - ((change node) (mutate hamt root 0 dp hash key))) + ((hp) (hamt/hash hamt)) + ((hash) (hash-bits hp key)) + ((change node) (mutate hamt root 0 dp hash key))) (unless (zero? change) (set-hamt/count! hamt (+ (hamt/count hamt) change))) (unless (eq? node root) @@ -185,7 +185,7 @@ happened.)" (define (collision-single-leaf? n) (let ((elements (collision/entries n))) (and (not (null? elements)) - (null? (cdr elements))))) + (null? (cdr elements))))) (define (narrow-single-leaf? n) (and (zero? (narrow/children n)) @@ -201,27 +201,27 @@ happened.)" (define (next-set-bit i start end) (let ((index (first-set-bit (bit-field i start end)))) (and (not (= index -1)) - (+ index start)))) + (+ index start)))) (define (narrow->wide n payload?) (let* ((c (narrow/children n)) - (l (narrow/leaves n)) - (stride (leaf-stride payload?)) - (a-in (narrow/array n)) - (a-out (make-vector (* stride hamt-bucket-size)))) + (l (narrow/leaves n)) + (stride (leaf-stride payload?)) + (a-in (narrow/array n)) + (a-out (make-vector (* stride hamt-bucket-size)))) (let next-leaf ((start 0) (count 0)) (let ((i (next-set-bit l start hamt-bucket-size))) - (when i - (let ((j (* stride i))) - (vector-set! a-out j (vector-ref a-in count)) - (when payload? - (vector-set! a-out (+ j 1) (vector-ref a-in (+ count 1))))) - (next-leaf (+ i 1) (+ stride count))))) + (when i + (let ((j (* stride i))) + (vector-set! a-out j (vector-ref a-in count)) + (when payload? + (vector-set! a-out (+ j 1) (vector-ref a-in (+ count 1))))) + (next-leaf (+ i 1) (+ stride count))))) (let next-child ((start 0) (offset (* stride (bit-count l)))) (let ((i (next-set-bit c start hamt-bucket-size))) - (when i - (vector-set! a-out (* stride i) (vector-ref a-in offset)) - (next-child (+ i 1) (+ offset 1))))) + (when i + (vector-set! a-out (* stride i) (vector-ref a-in offset)) + (next-child (+ i 1) (+ offset 1))))) (make-wide a-out c l))) (define (->immutable n payload? replace) @@ -231,43 +231,43 @@ Stop at the first `collision' node or `narrow' node on each path. If datum in a wide node with what `replace' returns when passed the key and corresponding datum." (cond ((collision? n) n) - ((narrow? n) n) - ((wide? n) - (let* ((c (wide/children n)) - (l (wide/leaves n)) - (stride (leaf-stride payload?)) - (l-count (bit-count l)) - (a-in (wide/array n)) - (a-out (make-vector - (+ (* stride l-count) (bit-count c))))) - (let next-leaf ((start 0) (count 0)) - (let ((i (next-set-bit l - start - hamt-bucket-size))) - (when i - (let* ((j (* stride i)) - (key (vector-ref a-in j))) - (vector-set! a-out count key) - (when payload? - (vector-set! a-out - (+ count 1) - (replace - key - (vector-ref a-in (+ j 1)))))) - (next-leaf (+ i 1) (+ stride count))))) - (let next-child ((start 0) (offset (* stride l-count))) - (let ((i (next-set-bit c - start - hamt-bucket-size))) - (when i - (vector-set! a-out - offset - (->immutable (vector-ref a-in (* stride i)) - payload? - replace)) - (next-child (+ i 1) (+ offset 1))))) - (make-narrow a-out c l))) - (else (error "Unexpected type of node.")))) + ((narrow? n) n) + ((wide? n) + (let* ((c (wide/children n)) + (l (wide/leaves n)) + (stride (leaf-stride payload?)) + (l-count (bit-count l)) + (a-in (wide/array n)) + (a-out (make-vector + (+ (* stride l-count) (bit-count c))))) + (let next-leaf ((start 0) (count 0)) + (let ((i (next-set-bit l + start + hamt-bucket-size))) + (when i + (let* ((j (* stride i)) + (key (vector-ref a-in j))) + (vector-set! a-out count key) + (when payload? + (vector-set! a-out + (+ count 1) + (replace + key + (vector-ref a-in (+ j 1)))))) + (next-leaf (+ i 1) (+ stride count))))) + (let next-child ((start 0) (offset (* stride l-count))) + (let ((i (next-set-bit c + start + hamt-bucket-size))) + (when i + (vector-set! a-out + offset + (->immutable (vector-ref a-in (* stride i)) + payload? + replace)) + (next-child (+ i 1) (+ offset 1))))) + (make-narrow a-out c l))) + (else (error "Unexpected type of node.")))) (define (hash-fragment shift hash) (bit-field hash shift (+ shift hamt-hash-slice-size))) @@ -277,46 +277,46 @@ and corresponding datum." (define (mutate hamt n shift dp h k) (cond ((collision? n) (modify-collision hamt n shift dp h k)) - ((narrow? n) - (modify-wide hamt - (narrow->wide n (hamt/payload? hamt)) - shift - dp - h - k)) - ((wide? n) (modify-wide hamt n shift dp h k)) - (else (error "Unknown HAMT node type." n)))) + ((narrow? n) + (modify-wide hamt + (narrow->wide n (hamt/payload? hamt)) + shift + dp + h + k)) + ((wide? n) (modify-wide hamt n shift dp h k)) + (else (error "Unknown HAMT node type." n)))) (define (modify-wide hamt n shift dp h k) (let ((fragment (hash-fragment shift h))) (cond ((bit-set? fragment (wide/children n)) - (modify-wide-child hamt n shift dp h k)) - ((bit-set? fragment (wide/leaves n)) - (modify-wide-leaf hamt n shift dp h k)) - (else - (let ((d (dp hamt-null))) - (if (hamt-null? d) - (values 0 n) - (modify-wide-new hamt n shift d h k))))))) + (modify-wide-child hamt n shift dp h k)) + ((bit-set? fragment (wide/leaves n)) + (modify-wide-leaf hamt n shift dp h k)) + (else + (let ((d (dp hamt-null))) + (if (hamt-null? d) + (values 0 n) + (modify-wide-new hamt n shift d h k))))))) (define (modify-wide-child hamt n shift dp h k) (let*-values (((fragment) (hash-fragment shift h)) - ((array) (wide/array n)) - ((payload?) (hamt/payload? hamt)) - ((stride) (leaf-stride payload?)) - ((i) (* stride fragment)) - ((child) (vector-ref array i)) - ((change new-child) - (mutate hamt - child - (+ shift hamt-hash-slice-size) - dp - h - k))) + ((array) (wide/array n)) + ((payload?) (hamt/payload? hamt)) + ((stride) (leaf-stride payload?)) + ((i) (* stride fragment)) + ((child) (vector-ref array i)) + ((change new-child) + (mutate hamt + child + (+ shift hamt-hash-slice-size) + dp + h + k))) (define (coalesce key datum) (vector-set! array i key) (when payload? - (vector-set! array (+ i 1) datum)) + (vector-set! array (+ i 1) datum)) (set-wide/children! n (copy-bit fragment (wide/children n) #f)) (set-wide/leaves! n (copy-bit fragment (wide/leaves n) #t)) (values change n)) @@ -324,77 +324,77 @@ and corresponding datum." (vector-set! array i new-child) (values change n)) (cond ((eq? new-child child) (values change n)) - ((hamt-null? new-child) - (error "Child cannot become null." n)) - ((collision? new-child) - (if (collision-single-leaf? new-child) - (let ((a (car (collision/entries new-child)))) - (if payload? - (coalesce (car a) (cdr a)) - (coalesce a #f))) - (replace))) - ((wide? new-child) - (if (wide-single-leaf? new-child) - (let ((a (wide/array new-child)) - (j (* stride (next-set-bit (wide/leaves new-child) - 0 - hamt-bucket-size)))) - (coalesce (vector-ref a j) - (and payload? (vector-ref a (+ j 1))))) - (replace))) - ((narrow? new-child) - (replace)) - (else (error "Unexpected type of child node."))))) + ((hamt-null? new-child) + (error "Child cannot become null." n)) + ((collision? new-child) + (if (collision-single-leaf? new-child) + (let ((a (car (collision/entries new-child)))) + (if payload? + (coalesce (car a) (cdr a)) + (coalesce a #f))) + (replace))) + ((wide? new-child) + (if (wide-single-leaf? new-child) + (let ((a (wide/array new-child)) + (j (* stride (next-set-bit (wide/leaves new-child) + 0 + hamt-bucket-size)))) + (coalesce (vector-ref a j) + (and payload? (vector-ref a (+ j 1))))) + (replace))) + ((narrow? new-child) + (replace)) + (else (error "Unexpected type of child node."))))) (define (modify-wide-leaf hamt n shift dp h k) (let* ((fragment (hash-fragment shift h)) - (array (wide/array n)) - (payload? (hamt/payload? hamt)) - (stride (leaf-stride payload?)) - (i (* stride fragment)) - (key (vector-ref array i))) + (array (wide/array n)) + (payload? (hamt/payload? hamt)) + (stride (leaf-stride payload?)) + (i (* stride fragment)) + (key (vector-ref array i))) (if ((hamt/= hamt) k key) - (let* ((existing (if payload? (vector-ref array (+ i 1)) hamt-null)) - (d (dp existing))) - (cond ((hamt-null? d) - (vector-set! array i #f) - (when payload? (vector-set! array (+ i 1) #f)) - (set-wide/leaves! n (copy-bit fragment (wide/leaves n) #f)) - (values -1 n)) - (else - (when payload? (vector-set! array (+ i 1) d)) - (values 0 n)))) - (let ((d (dp hamt-null))) - (if (hamt-null? d) - (values 0 n) - (add-wide-leaf-key hamt n shift d h k)))))) + (let* ((existing (if payload? (vector-ref array (+ i 1)) hamt-null)) + (d (dp existing))) + (cond ((hamt-null? d) + (vector-set! array i #f) + (when payload? (vector-set! array (+ i 1) #f)) + (set-wide/leaves! n (copy-bit fragment (wide/leaves n) #f)) + (values -1 n)) + (else + (when payload? (vector-set! array (+ i 1) d)) + (values 0 n)))) + (let ((d (dp hamt-null))) + (if (hamt-null? d) + (values 0 n) + (add-wide-leaf-key hamt n shift d h k)))))) (define (add-wide-leaf-key hamt n shift d h k) (define payload? (hamt/payload? hamt)) (define make-entry (if payload? cons (lambda (k d) k))) (let* ((fragment (hash-fragment shift h)) - (array (wide/array n)) - (stride (leaf-stride payload?)) - (i (* stride fragment)) - (key (vector-ref array i)) - (hash (hash-bits (hamt/hash hamt) key)) - (datum (and payload? (vector-ref array (+ i 1))))) + (array (wide/array n)) + (stride (leaf-stride payload?)) + (i (* stride fragment)) + (key (vector-ref array i)) + (hash (hash-bits (hamt/hash hamt) key)) + (datum (and payload? (vector-ref array (+ i 1))))) (vector-set! array - i - (if (= h hash) - (make-collision (list (make-entry k d) - (make-entry key datum)) - h) - (make-narrow-with-two-keys - payload? - (+ shift hamt-hash-slice-size) - h - k - d - hash - key - datum))) + i + (if (= h hash) + (make-collision (list (make-entry k d) + (make-entry key datum)) + h) + (make-narrow-with-two-keys + payload? + (+ shift hamt-hash-slice-size) + h + k + d + hash + key + datum))) (when payload? (vector-set! array (+ i 1) #f)) (set-wide/children! n (copy-bit fragment (wide/children n) #t)) @@ -403,10 +403,10 @@ and corresponding datum." (define (modify-wide-new hamt n shift d h k) (let* ((fragment (hash-fragment shift h)) - (array (wide/array n)) - (payload? (hamt/payload? hamt)) - (stride (leaf-stride payload?)) - (i (* stride fragment))) + (array (wide/array n)) + (payload? (hamt/payload? hamt)) + (stride (leaf-stride payload?)) + (i (* stride fragment))) (vector-set! array i k) (when payload? (vector-set! array (+ i 1) d)) @@ -417,35 +417,35 @@ and corresponding datum." (define (two-leaves f1 k1 d1 f2 k2 d2) (make-narrow (if payload? - (vector k1 d1 k2 d2) - (vector k1 k2)) + (vector k1 d1 k2 d2) + (vector k1 k2)) 0 (copy-bit f2 (copy-bit f1 0 #t) #t))) (assert (not (= h1 h2))) (let ((f1 (hash-fragment shift h1)) - (f2 (hash-fragment shift h2))) + (f2 (hash-fragment shift h2))) (cond ((= f1 f2) - (make-narrow - (vector (make-narrow-with-two-keys payload? - (+ shift hamt-hash-slice-size) - h1 - k1 - d1 - h2 - k2 - d2)) - (copy-bit f1 0 #t) - 0)) - ((< f1 f2) - (two-leaves f1 k1 d1 f2 k2 d2)) - (else - (two-leaves f2 k2 d2 f1 k1 d1))))) + (make-narrow + (vector (make-narrow-with-two-keys payload? + (+ shift hamt-hash-slice-size) + h1 + k1 + d1 + h2 + k2 + d2)) + (copy-bit f1 0 #t) + 0)) + ((< f1 f2) + (two-leaves f1 k1 d1 f2 k2 d2)) + (else + (two-leaves f2 k2 d2 f1 k1 d1))))) (define (modify-pure hamt n shift dp h k) (cond ((collision? n) (modify-collision hamt n shift dp h k)) - ((narrow? n) (modify-narrow hamt n shift dp h k)) - ((wide? n) (error "Should have been converted to narrow before here.")) - (else (error "Unknown HAMT node type." n)))) + ((narrow? n) (modify-narrow hamt n shift dp h k)) + ((wide? n) (error "Should have been converted to narrow before here.")) + (else (error "Unknown HAMT node type." n)))) (define (lower-collision hamt n shift dp h k) "If we try to add a key to a collision but it has a different hash @@ -455,56 +455,56 @@ the point where the hash fragments differ. This is guaranteed to happen at some level because we're only called when the full hashes differ." (let ((collision-hash (collision/hash n)) - (d (dp hamt-null))) + (d (dp hamt-null))) (if (hamt-null? d) - (values 0 n) - (values - 1 - (let descend ((shift shift)) - (let ((collision-fragment (hash-fragment shift collision-hash)) - (leaf-fragment (hash-fragment shift h))) - (if (= collision-fragment leaf-fragment) - (let ((child (descend (+ shift hamt-hash-slice-size)))) - (make-narrow - (vector child) - (copy-bit collision-fragment 0 #t) - 0)) - (make-narrow - (if (hamt/payload? hamt) - (vector k d n) - (vector k n)) - (copy-bit collision-fragment 0 #t) - (copy-bit leaf-fragment 0 #t))))))))) + (values 0 n) + (values + 1 + (let descend ((shift shift)) + (let ((collision-fragment (hash-fragment shift collision-hash)) + (leaf-fragment (hash-fragment shift h))) + (if (= collision-fragment leaf-fragment) + (let ((child (descend (+ shift hamt-hash-slice-size)))) + (make-narrow + (vector child) + (copy-bit collision-fragment 0 #t) + 0)) + (make-narrow + (if (hamt/payload? hamt) + (vector k d n) + (vector k n)) + (copy-bit collision-fragment 0 #t) + (copy-bit leaf-fragment 0 #t))))))))) (define (modify-collision hamt n shift dp h k) (if (= h (collision/hash n)) (let ((payload? (hamt/payload? hamt))) - (let next ((entries (collision/entries n)) - (checked '())) - (if (null? entries) - (let ((d (dp hamt-null))) - (if (hamt-null? d) - (values 0 n) - (values 1 - (make-collision (if payload? - (cons (cons k d) checked) - (cons k checked)) - h)))) - (let* ((entry (car entries)) - (key (if payload? (car entry) entry))) - (if ((hamt/= hamt) k key) - (let* ((existing (if payload? (cdr entry) hamt-null)) - (d (dp existing)) - (delete? (hamt-null? d)) - (others (append checked (cdr entries)))) - (values - (if delete? -1 0) - (make-collision (cond (delete? others) - (payload? (cons (cons k d) others)) - (else (cons k others))) - h))) - (next (cdr entries) - (cons (car entries) checked))))))) + (let next ((entries (collision/entries n)) + (checked '())) + (if (null? entries) + (let ((d (dp hamt-null))) + (if (hamt-null? d) + (values 0 n) + (values 1 + (make-collision (if payload? + (cons (cons k d) checked) + (cons k checked)) + h)))) + (let* ((entry (car entries)) + (key (if payload? (car entry) entry))) + (if ((hamt/= hamt) k key) + (let* ((existing (if payload? (cdr entry) hamt-null)) + (d (dp existing)) + (delete? (hamt-null? d)) + (others (append checked (cdr entries)))) + (values + (if delete? -1 0) + (make-collision (cond (delete? others) + (payload? (cons (cons k d) others)) + (else (cons k others))) + h))) + (next (cdr entries) + (cons (car entries) checked))))))) (lower-collision hamt n shift dp h k))) ;; If we're storing "payloads," i.e. a datum to go with each key, we @@ -523,289 +523,289 @@ differ." (define (modify-narrow hamt n shift dp h k) (let ((fragment (hash-fragment shift h))) (cond ((bit-set? fragment (narrow/children n)) - (modify-narrow-child hamt n shift dp h k)) - ((bit-set? fragment (narrow/leaves n)) - (modify-narrow-leaf hamt n shift dp h k)) - (else - (let ((d (dp hamt-null))) - (if (hamt-null? d) - (values 0 n) - (modify-narrow-new hamt n shift d h k))))))) + (modify-narrow-child hamt n shift dp h k)) + ((bit-set? fragment (narrow/leaves n)) + (modify-narrow-leaf hamt n shift dp h k)) + (else + (let ((d (dp hamt-null))) + (if (hamt-null? d) + (values 0 n) + (modify-narrow-new hamt n shift d h k))))))) (define (modify-narrow-child hamt n shift dp h k) (let*-values (((fragment) (hash-fragment shift h)) - ((mask) (fragment->mask fragment)) - ((c) (narrow/children n)) - ((l) (narrow/leaves n)) - ((array) (narrow/array n)) - ((payload?) (hamt/payload? hamt)) - ((child-index) - (narrow-child-index l c mask payload?)) - ((child) (vector-ref array child-index)) - ((change new-child) - (modify-pure hamt - child - (+ shift hamt-hash-slice-size) - dp - h - k))) + ((mask) (fragment->mask fragment)) + ((c) (narrow/children n)) + ((l) (narrow/leaves n)) + ((array) (narrow/array n)) + ((payload?) (hamt/payload? hamt)) + ((child-index) + (narrow-child-index l c mask payload?)) + ((child) (vector-ref array child-index)) + ((change new-child) + (modify-pure hamt + child + (+ shift hamt-hash-slice-size) + dp + h + k))) (define (coalesce key datum) (let ((leaf-index (narrow-leaf-index l mask payload?))) - (values change - (make-narrow (if payload? - (vector-edit array - (add leaf-index key) - (add leaf-index datum) - (drop child-index 1)) - (vector-edit array - (add leaf-index key) - (drop child-index 1))) - (copy-bit fragment c #f) - (copy-bit fragment l #t))))) + (values change + (make-narrow (if payload? + (vector-edit array + (add leaf-index key) + (add leaf-index datum) + (drop child-index 1)) + (vector-edit array + (add leaf-index key) + (drop child-index 1))) + (copy-bit fragment c #f) + (copy-bit fragment l #t))))) (define (replace) (values change - (make-narrow (vector-replace-one array child-index new-child) - c - l))) + (make-narrow (vector-replace-one array child-index new-child) + c + l))) (cond ((eq? new-child child) (values 0 n)) - ((hamt-null? new-child) - (error "Child cannot become null." n)) - ((collision? new-child) - (if (collision-single-leaf? new-child) - (let ((a (car (collision/entries new-child)))) - (if payload? - (coalesce (car a) (cdr a)) - (coalesce a #f))) - (replace))) - ((narrow? new-child) - (if (narrow-single-leaf? new-child) - (let ((a (narrow/array new-child))) - (coalesce (vector-ref a 0) - (and payload? (vector-ref a 1)))) - (replace))) - ((wide? new-child) - (error "New child should be collision or narrow.")) - (else (error "Unexpected type of child node."))))) + ((hamt-null? new-child) + (error "Child cannot become null." n)) + ((collision? new-child) + (if (collision-single-leaf? new-child) + (let ((a (car (collision/entries new-child)))) + (if payload? + (coalesce (car a) (cdr a)) + (coalesce a #f))) + (replace))) + ((narrow? new-child) + (if (narrow-single-leaf? new-child) + (let ((a (narrow/array new-child))) + (coalesce (vector-ref a 0) + (and payload? (vector-ref a 1)))) + (replace))) + ((wide? new-child) + (error "New child should be collision or narrow.")) + (else (error "Unexpected type of child node."))))) (define (modify-narrow-leaf hamt n shift dp h k) (let* ((fragment (hash-fragment shift h)) - (mask (fragment->mask fragment)) - (c (narrow/children n)) - (l (narrow/leaves n)) - (array (narrow/array n)) - (payload? (hamt/payload? hamt)) - (stride (leaf-stride payload?)) - (leaf-index (narrow-leaf-index l mask payload?)) - (key (vector-ref array leaf-index))) + (mask (fragment->mask fragment)) + (c (narrow/children n)) + (l (narrow/leaves n)) + (array (narrow/array n)) + (payload? (hamt/payload? hamt)) + (stride (leaf-stride payload?)) + (leaf-index (narrow-leaf-index l mask payload?)) + (key (vector-ref array leaf-index))) (if ((hamt/= hamt) k key) - (let* ((existing (if payload? - (vector-ref array (+ leaf-index 1)) - hamt-null)) - (d (dp existing))) - (cond ((hamt-null? d) - (values -1 - (make-narrow (vector-without array - leaf-index - (+ leaf-index stride)) - c - (copy-bit fragment l #f)))) - (payload? - (values - 0 - (make-narrow (vector-replace-one array (+ leaf-index 1) d) - c - l))) - (else (values 0 n)))) - (let ((d (dp hamt-null))) - (if (hamt-null? d) - (values 0 n) - (add-narrow-leaf-key hamt n shift d h k)))))) + (let* ((existing (if payload? + (vector-ref array (+ leaf-index 1)) + hamt-null)) + (d (dp existing))) + (cond ((hamt-null? d) + (values -1 + (make-narrow (vector-without array + leaf-index + (+ leaf-index stride)) + c + (copy-bit fragment l #f)))) + (payload? + (values + 0 + (make-narrow (vector-replace-one array (+ leaf-index 1) d) + c + l))) + (else (values 0 n)))) + (let ((d (dp hamt-null))) + (if (hamt-null? d) + (values 0 n) + (add-narrow-leaf-key hamt n shift d h k)))))) (define (add-narrow-leaf-key hamt n shift d h k) (define payload? (hamt/payload? hamt)) (define make-entry (if payload? cons (lambda (k d) k))) (let* ((fragment (hash-fragment shift h)) - (mask (fragment->mask fragment)) - (c (narrow/children n)) - (l (narrow/leaves n)) - (array (narrow/array n)) - (payload? (hamt/payload? hamt)) - (stride (leaf-stride payload?)) - (leaf-index (narrow-leaf-index l mask payload?)) - (key (vector-ref array leaf-index)) - (child-index (narrow-child-index l c mask payload?)) - (hash (hash-bits (hamt/hash hamt) key)) - (datum (and payload? (vector-ref array (+ leaf-index 1))))) + (mask (fragment->mask fragment)) + (c (narrow/children n)) + (l (narrow/leaves n)) + (array (narrow/array n)) + (payload? (hamt/payload? hamt)) + (stride (leaf-stride payload?)) + (leaf-index (narrow-leaf-index l mask payload?)) + (key (vector-ref array leaf-index)) + (child-index (narrow-child-index l c mask payload?)) + (hash (hash-bits (hamt/hash hamt) key)) + (datum (and payload? (vector-ref array (+ leaf-index 1))))) (values 1 - (make-narrow (if (= h hash) - (vector-edit - array - (drop leaf-index stride) - (add child-index - (make-collision (list (make-entry k d) - (make-entry key datum)) - h))) - (vector-edit - array - (drop leaf-index stride) - (add child-index - (make-narrow-with-two-keys - payload? - (+ shift hamt-hash-slice-size) - h - k - d - hash - key - datum)))) - (copy-bit fragment c #t) - (copy-bit fragment l #f))))) + (make-narrow (if (= h hash) + (vector-edit + array + (drop leaf-index stride) + (add child-index + (make-collision (list (make-entry k d) + (make-entry key datum)) + h))) + (vector-edit + array + (drop leaf-index stride) + (add child-index + (make-narrow-with-two-keys + payload? + (+ shift hamt-hash-slice-size) + h + k + d + hash + key + datum)))) + (copy-bit fragment c #t) + (copy-bit fragment l #f))))) (define (modify-narrow-new hamt n shift d h k) (let* ((fragment (hash-fragment shift h)) - (mask (fragment->mask fragment)) - (c (narrow/children n)) - (l (narrow/leaves n)) - (array (narrow/array n)) - (payload? (hamt/payload? hamt)) - (leaf-index (narrow-leaf-index l mask payload?)) - (delete? (hamt-null? d))) + (mask (fragment->mask fragment)) + (c (narrow/children n)) + (l (narrow/leaves n)) + (array (narrow/array n)) + (payload? (hamt/payload? hamt)) + (leaf-index (narrow-leaf-index l mask payload?)) + (delete? (hamt-null? d))) (values 1 - (make-narrow (if payload? - (vector-edit array - (add leaf-index k) - (add leaf-index d)) - (vector-edit array - (add leaf-index k))) - c - (copy-bit fragment l #t))))) + (make-narrow (if payload? + (vector-edit array + (add leaf-index k) + (add leaf-index d)) + (vector-edit array + (add leaf-index k))) + c + (copy-bit fragment l #t))))) (define (hamt-fetch hamt key) "Fetch datum from `hamt' at `key'. Return `hamt-null' if the key is not present. If `hamt' stores no payloads, return the symbol `present' if the key is present." (let ((h (hash-bits (hamt/hash hamt) key)) - (payload? (hamt/payload? hamt))) + (payload? (hamt/payload? hamt))) (let descend ((n (hamt/root hamt)) - (shift 0)) + (shift 0)) (cond ((collision? n) - (let ((entries (collision/entries n)) - (key= (hamt/= hamt))) - (if payload? - (cond ((assoc key entries key=) => cdr) - (else hamt-null)) - (if (find-tail (lambda (e) (key= key e)) entries) - 'present - hamt-null)))) - ((narrow? n) - (let ((array (narrow/array n)) - (c (narrow/children n)) - (l (narrow/leaves n)) - (fragment (hash-fragment shift h))) - (cond ((bit-set? fragment c) - (let* ((mask (fragment->mask fragment)) - (child-index (narrow-child-index - l - c - mask - (hamt/payload? hamt)))) - (descend (vector-ref array child-index) - (+ shift hamt-hash-slice-size)))) - ((bit-set? fragment l) - (let* ((mask (fragment->mask fragment)) - (leaf-index - (narrow-leaf-index l mask (hamt/payload? hamt))) - (k (vector-ref array leaf-index))) - (if ((hamt/= hamt) k key) - (if payload? - (vector-ref array (+ leaf-index 1)) - 'present) - hamt-null))) - (else hamt-null)))) - ((wide? n) - (let ((array (wide/array n)) - (stride (leaf-stride (hamt/payload? hamt))) - (c (wide/children n)) - (l (wide/leaves n)) - (i (hash-fragment shift h))) - (cond ((bit-set? i c) - (descend (vector-ref array (* stride i)) - (+ shift hamt-hash-slice-size))) - ((bit-set? i l) - (let* ((j (* stride i)) - (k (vector-ref array j))) - (if ((hamt/= hamt) k key) - (if payload? - (vector-ref array (+ j 1)) - 'present) - hamt-null))) - (else hamt-null)))) - (else (error "Unexpected type of child node.")))))) + (let ((entries (collision/entries n)) + (key= (hamt/= hamt))) + (if payload? + (cond ((assoc key entries key=) => cdr) + (else hamt-null)) + (if (find-tail (lambda (e) (key= key e)) entries) + 'present + hamt-null)))) + ((narrow? n) + (let ((array (narrow/array n)) + (c (narrow/children n)) + (l (narrow/leaves n)) + (fragment (hash-fragment shift h))) + (cond ((bit-set? fragment c) + (let* ((mask (fragment->mask fragment)) + (child-index (narrow-child-index + l + c + mask + (hamt/payload? hamt)))) + (descend (vector-ref array child-index) + (+ shift hamt-hash-slice-size)))) + ((bit-set? fragment l) + (let* ((mask (fragment->mask fragment)) + (leaf-index + (narrow-leaf-index l mask (hamt/payload? hamt))) + (k (vector-ref array leaf-index))) + (if ((hamt/= hamt) k key) + (if payload? + (vector-ref array (+ leaf-index 1)) + 'present) + hamt-null))) + (else hamt-null)))) + ((wide? n) + (let ((array (wide/array n)) + (stride (leaf-stride (hamt/payload? hamt))) + (c (wide/children n)) + (l (wide/leaves n)) + (i (hash-fragment shift h))) + (cond ((bit-set? i c) + (descend (vector-ref array (* stride i)) + (+ shift hamt-hash-slice-size))) + ((bit-set? i l) + (let* ((j (* stride i)) + (k (vector-ref array j))) + (if ((hamt/= hamt) k key) + (if payload? + (vector-ref array (+ j 1)) + 'present) + hamt-null))) + (else hamt-null)))) + (else (error "Unexpected type of child node.")))))) (define (collision/for-each procedure node payload?) (if payload? (do-list (e (collision/entries node)) - (procedure (car e) (cdr e))) + (procedure (car e) (cdr e))) (do-list (e (collision/entries node)) - (procedure e #f)))) + (procedure e #f)))) (define (narrow/for-each procedure node payload?) (let ((array (narrow/array node)) - (stride (leaf-stride payload?)) - (c (narrow/children node)) - (l (narrow/leaves node))) + (stride (leaf-stride payload?)) + (c (narrow/children node)) + (l (narrow/leaves node))) (let next-leaf ((count 0) - (start 0)) + (start 0)) (let ((i (next-set-bit l start hamt-bucket-size))) - (if i - (let* ((j (* stride count)) - (k (vector-ref array j)) - (d (and payload? (vector-ref array (+ j 1))))) - (procedure k d) - (next-leaf (+ count 1) (+ i 1))) - (let next-child ((start 0) - (offset (* stride count))) - (let ((i (next-set-bit c start hamt-bucket-size))) - (when i - (let ((child (vector-ref array offset))) - (hamt-node/for-each child payload? procedure) - (next-child (+ i 1) (+ offset 1))))))))))) + (if i + (let* ((j (* stride count)) + (k (vector-ref array j)) + (d (and payload? (vector-ref array (+ j 1))))) + (procedure k d) + (next-leaf (+ count 1) (+ i 1))) + (let next-child ((start 0) + (offset (* stride count))) + (let ((i (next-set-bit c start hamt-bucket-size))) + (when i + (let ((child (vector-ref array offset))) + (hamt-node/for-each child payload? procedure) + (next-child (+ i 1) (+ offset 1))))))))))) (define (wide/for-each procedure node payload?) (let ((array (wide/array node)) - (stride (leaf-stride payload?)) - (c (wide/children node)) - (l (wide/leaves node))) + (stride (leaf-stride payload?)) + (c (wide/children node)) + (l (wide/leaves node))) (do ((i 0 (+ i 1))) - ((= i hamt-bucket-size)) + ((= i hamt-bucket-size)) (let ((j (* stride i))) - (cond ((bit-set? i l) - (let ((k (vector-ref array j)) - (d (and payload? (vector-ref array (+ j 1))))) - (procedure k d))) - ((bit-set? i c) - (let ((child (vector-ref array j))) - (hamt-node/for-each child payload? procedure)))))))) + (cond ((bit-set? i l) + (let ((k (vector-ref array j)) + (d (and payload? (vector-ref array (+ j 1))))) + (procedure k d))) + ((bit-set? i c) + (let ((child (vector-ref array j))) + (hamt-node/for-each child payload? procedure)))))))) (define (hamt-node/for-each node payload? procedure) (cond ((collision? node) (collision/for-each procedure node payload?)) - ((narrow? node) (narrow/for-each procedure node payload?)) - ((wide? node) (wide/for-each procedure node payload?)) - (else (error "Invalid type of node." node)))) + ((narrow? node) (narrow/for-each procedure node payload?)) + ((wide? node) (wide/for-each procedure node payload?)) + (else (error "Invalid type of node." node)))) (define (hamt/for-each procedure hamt) (hamt-node/for-each (hamt/root hamt) - (hamt/payload? hamt) - procedure)) + (hamt/payload? hamt) + procedure)) (define (hamt->list hamt procedure) (let ((accumulator '())) (hamt/for-each (lambda (k v) - (set! accumulator - (cons (procedure k v) - accumulator))) - hamt) + (set! accumulator + (cons (procedure k v) + accumulator))) + hamt) accumulator)) ;;; Debugging @@ -814,93 +814,93 @@ not present. If `hamt' stores no payloads, return the symbol "Do sanity checks on a collision. Return the list of all keys present." (let ((entries (collision/entries node)) - (hash (collision/hash node)) - (extract (if payload? car (lambda (x) x)))) + (hash (collision/hash node)) + (extract (if payload? car (lambda (x) x)))) (do-list (a entries) (assert (= hash (hash-bits hp (extract a))))) (if payload? - (map car entries) - entries))) + (map car entries) + entries))) (define (assert-narrow-valid node hp payload? shift) "Do sanity checks on a narrow and all its children. Return the list of all keys present." (let ((array (narrow/array node)) - (stride (leaf-stride payload?)) - (c (narrow/children node)) - (l (narrow/leaves node))) + (stride (leaf-stride payload?)) + (c (narrow/children node)) + (l (narrow/leaves node))) (assert (zero? (bitwise-and c l))) (let next-leaf ((count 0) - (i 0) - (keys '())) + (i 0) + (keys '())) (if (< i hamt-bucket-size) - (cond ((bit-set? i l) - (let ((k (vector-ref array (* stride count)))) - (assert (= i (hash-fragment shift (hash-bits hp k)))) - (next-leaf (+ count 1) (+ i 1) (cons k keys)))) - (else (next-leaf count (+ i 1) keys))) - (let next-child ((i 0) - (key-groups (list keys)) - (offset (* stride count))) - (if (= i hamt-bucket-size) - (apply append key-groups) - (cond ((bit-set? i c) - (let* ((child (vector-ref array offset)) - (child-keys (assert-hamt-node-valid - child - hp - payload? - (+ shift hamt-hash-slice-size)))) - (do-list (k child-keys) - (assert (= i - (hash-fragment shift (hash-bits hp k))))) - (next-child (+ i 1) - (cons child-keys key-groups) - (+ offset 1)))) - (else (next-child (+ i 1) key-groups offset))))))))) + (cond ((bit-set? i l) + (let ((k (vector-ref array (* stride count)))) + (assert (= i (hash-fragment shift (hash-bits hp k)))) + (next-leaf (+ count 1) (+ i 1) (cons k keys)))) + (else (next-leaf count (+ i 1) keys))) + (let next-child ((i 0) + (key-groups (list keys)) + (offset (* stride count))) + (if (= i hamt-bucket-size) + (apply append key-groups) + (cond ((bit-set? i c) + (let* ((child (vector-ref array offset)) + (child-keys (assert-hamt-node-valid + child + hp + payload? + (+ shift hamt-hash-slice-size)))) + (do-list (k child-keys) + (assert (= i + (hash-fragment shift (hash-bits hp k))))) + (next-child (+ i 1) + (cons child-keys key-groups) + (+ offset 1)))) + (else (next-child (+ i 1) key-groups offset))))))))) (define (assert-wide-valid node hp payload? shift) "Do sanity checks on a wide and all its children. Return the list of all keys present." (let ((array (wide/array node)) - (stride (leaf-stride payload?)) - (c (wide/children node)) - (l (wide/leaves node))) + (stride (leaf-stride payload?)) + (c (wide/children node)) + (l (wide/leaves node))) (assert (zero? (bitwise-and c l))) (let next-fragment ((i 0) - (key-groups '())) + (key-groups '())) (if (= i hamt-bucket-size) - (apply append key-groups) - (let ((j (* stride i))) - (cond ((bit-set? i l) - (let ((k (vector-ref array j))) - (assert (= i (hash-fragment shift (hash-bits hp k)))) - (next-fragment (+ i 1) (cons (list k) key-groups)))) - ((bit-set? i c) - (let* ((child (vector-ref array j)) - (child-keys (assert-hamt-node-valid - child - hp - payload? - (+ shift hamt-hash-slice-size)))) - (do-list (k child-keys) - (assert (= i - (hash-fragment shift (hash-bits hp k))))) - (next-fragment (+ i 1) - (cons child-keys key-groups)))) - (else - (assert (not (vector-ref array j))) - (when payload? - (assert (not (vector-ref array (+ j 1))))) - (next-fragment (+ i 1) key-groups)))))))) + (apply append key-groups) + (let ((j (* stride i))) + (cond ((bit-set? i l) + (let ((k (vector-ref array j))) + (assert (= i (hash-fragment shift (hash-bits hp k)))) + (next-fragment (+ i 1) (cons (list k) key-groups)))) + ((bit-set? i c) + (let* ((child (vector-ref array j)) + (child-keys (assert-hamt-node-valid + child + hp + payload? + (+ shift hamt-hash-slice-size)))) + (do-list (k child-keys) + (assert (= i + (hash-fragment shift (hash-bits hp k))))) + (next-fragment (+ i 1) + (cons child-keys key-groups)))) + (else + (assert (not (vector-ref array j))) + (when payload? + (assert (not (vector-ref array (+ j 1))))) + (next-fragment (+ i 1) key-groups)))))))) (define (assert-hamt-node-valid node hp payload? shift) "Do sanity checks on a HAMT node and all its children. Return the list of all keys present." (cond ((collision? node) (assert-collision-valid node hp payload?)) - ((narrow? node) (assert-narrow-valid node hp payload? shift)) - ((wide? node) (assert-wide-valid node hp payload? shift)) - (else (error "Invalid type of node." node)))) + ((narrow? node) (assert-narrow-valid node hp payload? shift)) + ((wide? node) (assert-wide-valid node hp payload? shift)) + (else (error "Invalid type of node." node)))) (define (assert-hamt-valid hamt) "Do sanity checks on `hamt'." @@ -909,5 +909,5 @@ list of all keys present." (assert (procedure? hp)) (assert (memq (hamt/mutable? hamt) '(#t #f))) (let* ((payload? (hamt/payload? hamt)) - (keys (assert-hamt-node-valid (hamt/root hamt) hp payload? 0))) + (keys (assert-hamt-node-valid (hamt/root hamt) hp payload? 0))) (assert (= (hamt/count hamt) (length keys)))))) diff --git a/lib/srfi/146/hash.scm b/lib/srfi/146/hash.scm index b6aec04f..e8746c33 100644 --- a/lib/srfi/146/hash.scm +++ b/lib/srfi/146/hash.scm @@ -26,35 +26,35 @@ (define (tree-search comparator tree obj failure success) (let ((entry (phm/get tree obj))) (if entry - (success (car entry) (cdr entry) - (lambda (new-key new-datum ret) - (let ((tree (phm/remove tree obj))) - (values (phm/put tree new-key (cons new-key new-datum)) - ret))) - (lambda (ret) - (values (phm/remove tree obj) ret))) - (failure (lambda (new-key new-datum ret) - (values (phm/put tree new-key (cons new-key new-datum)) - ret)) - (lambda (ret) - (values tree ret)))))) + (success (car entry) (cdr entry) + (lambda (new-key new-datum ret) + (let ((tree (phm/remove tree obj))) + (values (phm/put tree new-key (cons new-key new-datum)) + ret))) + (lambda (ret) + (values (phm/remove tree obj) ret))) + (failure (lambda (new-key new-datum ret) + (values (phm/put tree new-key (cons new-key new-datum)) + ret)) + (lambda (ret) + (values tree ret)))))) (define (tree-fold proc seed tree) (phm/for-each (lambda (key entry) - (set! seed (proc (car entry) (cdr entry) seed))) - tree) + (set! seed (proc (car entry) (cdr entry) seed))) + tree) seed) (define (tree-for-each proc tree) (phm/for-each (lambda (key entry) - (proc (car entry) (cdr entry))) - tree)) + (proc (car entry) (cdr entry))) + tree)) (define (tree-generator tree) (make-coroutine-generator (lambda (yield) (tree-for-each (lambda item (yield item)) - tree)))) + tree)))) ;;; New types @@ -67,8 +67,8 @@ (define (make-empty-hashmap comparator) (assume (comparator? comparator)) (%make-hashmap comparator - (make-phm (comparator-hash-function comparator) - (comparator-equality-predicate comparator)))) + (make-phm (comparator-hash-function comparator) + (comparator-equality-predicate comparator)))) ;;; Exported procedures @@ -77,12 +77,12 @@ (define (hashmap comparator . args) (assume (comparator? comparator)) (hashmap-unfold null? - (lambda (args) - (values (car args) - (cadr args))) - cddr - args - comparator)) + (lambda (args) + (values (car args) + (cadr args))) + cddr + args + comparator)) (define (hashmap-unfold stop? mapper successor seed comparator) (assume (procedure? stop?)) @@ -90,13 +90,13 @@ (assume (procedure? successor)) (assume (comparator? comparator)) (let loop ((hashmap (make-empty-hashmap comparator)) - (seed seed)) + (seed seed)) (if (stop? seed) - hashmap - (receive (key value) - (mapper seed) - (loop (hashmap-adjoin hashmap key value) - (successor seed)))))) + hashmap + (receive (key value) + (mapper seed) + (loop (hashmap-adjoin hashmap key value) + (successor seed)))))) ;; Predicates @@ -109,11 +109,11 @@ (call/cc (lambda (return) (hashmap-search hashmap - key - (lambda (insert ignore) - (return #f)) - (lambda (key value update remove) - (return #t)))))) + key + (lambda (insert ignore) + (return #f)) + (lambda (key value update remove) + (return #t)))))) (define (hashmap-disjoint? hashmap1 hashmap2) (assume (hashmap? hashmap1)) @@ -121,9 +121,9 @@ (call/cc (lambda (return) (hashmap-for-each (lambda (key value) - (when (hashmap-contains? hashmap2 key) - (return #f))) - hashmap1) + (when (hashmap-contains? hashmap2 key) + (return #f))) + hashmap1) #t))) ;; Accessors @@ -133,24 +133,24 @@ ((hashmap key) (assume (hashmap? hashmap)) (hashmap-ref hashmap key (lambda () - (error "hashmap-ref: key not in hashmap" key)))) + (error "hashmap-ref: key not in hashmap" key)))) ((hashmap key failure) (assume (hashmap? hashmap)) (assume (procedure? failure)) (hashmap-ref hashmap key failure (lambda (value) - value))) + value))) ((hashmap key failure success) (assume (hashmap? hashmap)) (assume (procedure? failure)) (assume (procedure? success)) ((call/cc (lambda (return-thunk) - (hashmap-search hashmap - key - (lambda (insert ignore) - (return-thunk failure)) - (lambda (key value update remove) - (return-thunk (lambda () (success value))))))))))) + (hashmap-search hashmap + key + (lambda (insert ignore) + (return-thunk failure)) + (lambda (key value update remove) + (return-thunk (lambda () (success value))))))))))) (define (hashmap-ref/default hashmap key default) (assume (hashmap? hashmap)) @@ -161,25 +161,25 @@ (define (hashmap-adjoin hashmap . args) (assume (hashmap? hashmap)) (let loop ((args args) - (hashmap hashmap)) + (hashmap hashmap)) (if (null? args) - hashmap - (receive (hashmap value) - (hashmap-intern hashmap (car args) (lambda () (cadr args))) - (loop (cddr args) hashmap))))) + hashmap + (receive (hashmap value) + (hashmap-intern hashmap (car args) (lambda () (cadr args))) + (loop (cddr args) hashmap))))) (define hashmap-adjoin! hashmap-adjoin) (define (hashmap-set hashmap . args) (assume (hashmap? hashmap)) (let loop ((args args) - (hashmap hashmap)) + (hashmap hashmap)) (if (null? args) - hashmap - (receive (hashmap) - (hashmap-update hashmap (car args) (lambda (value) (cadr args)) (lambda () #f)) - (loop (cddr args) - hashmap))))) + hashmap + (receive (hashmap) + (hashmap-update hashmap (car args) (lambda (value) (cadr args)) (lambda () #f)) + (loop (cddr args) + hashmap))))) (define hashmap-set! hashmap-set) @@ -187,11 +187,11 @@ (assume (hashmap? hashmap)) (receive (hashmap obj) (hashmap-search hashmap - key - (lambda (insert ignore) - (ignore #f)) - (lambda (old-key old-value update remove) - (update key value #f))) + key + (lambda (insert ignore) + (ignore #f)) + (lambda (old-key old-value update remove) + (update key value #f))) hashmap)) (define hashmap-replace! hashmap-replace) @@ -206,15 +206,15 @@ (assume (hashmap? hashmap)) (assume (list? keys)) (fold (lambda (key hashmap) - (receive (hashmap obj) - (hashmap-search hashmap - key - (lambda (insert ignore) - (ignore #f)) - (lambda (old-key old-value update remove) - (remove #f))) - hashmap)) - hashmap keys)) + (receive (hashmap obj) + (hashmap-search hashmap + key + (lambda (insert ignore) + (ignore #f)) + (lambda (old-key old-value update remove) + (remove #f))) + hashmap)) + hashmap keys)) (define hashmap-delete-all! hashmap-delete-all) @@ -224,13 +224,13 @@ (call/cc (lambda (return) (hashmap-search hashmap - key - (lambda (insert ignore) - (receive (value) - (failure) - (insert value value))) - (lambda (old-key old-value update remove) - (return hashmap old-value)))))) + key + (lambda (insert ignore) + (receive (value) + (failure) + (insert value value))) + (lambda (old-key old-value update remove) + (return hashmap old-value)))))) (define hashmap-intern! hashmap-intern) @@ -238,22 +238,22 @@ (case-lambda ((hashmap key updater) (hashmap-update hashmap key updater (lambda () - (error "hashmap-update: key not found in hashmap" key)))) + (error "hashmap-update: key not found in hashmap" key)))) ((hashmap key updater failure) (hashmap-update hashmap key updater failure (lambda (value) - value))) + value))) ((hashmap key updater failure success) (assume (hashmap? hashmap)) (assume (procedure? updater)) (assume (procedure? failure)) (assume (procedure? success)) (receive (hashmap obj) - (hashmap-search hashmap - key - (lambda (insert ignore) - (insert (updater (failure)) #f)) - (lambda (old-key old-value update remove) - (update key (updater (success old-value)) #f))) + (hashmap-search hashmap + key + (lambda (insert ignore) + (insert (updater (failure)) #f)) + (lambda (old-key old-value update remove) + (update key (updater (success old-value)) #f))) hashmap)))) (define hashmap-update! hashmap-update) @@ -267,16 +267,16 @@ (case-lambda ((hashmap) (hashmap-pop hashmap (lambda () - (error "hashmap-pop: hashmap has no association")))) + (error "hashmap-pop: hashmap has no association")))) ((hashmap failure) (assume (hashmap? hashmap)) (assume (procedure? failure)) ((call/cc (lambda (return-thunk) - (receive (key value) - (hashmap-find (lambda (key value) #t) hashmap (lambda () (return-thunk failure))) - (lambda () - (values (hashmap-delete hashmap key) key value))))))))) + (receive (key value) + (hashmap-find (lambda (key value) #t) hashmap (lambda () (return-thunk failure))) + (lambda () + (values (hashmap-delete hashmap key) key value))))))))) (define hashmap-pop! hashmap-pop) @@ -287,20 +287,20 @@ (call/cc (lambda (return) (let*-values - (((comparator) - (hashmap-key-comparator hashmap)) - ((tree obj) - (tree-search comparator - (hashmap-tree hashmap) - key - (lambda (insert ignore) - (failure (lambda (value obj) - (insert key value obj)) - (lambda (obj) - (return hashmap obj)))) - success))) + (((comparator) + (hashmap-key-comparator hashmap)) + ((tree obj) + (tree-search comparator + (hashmap-tree hashmap) + key + (lambda (insert ignore) + (failure (lambda (value obj) + (insert key value obj)) + (lambda (obj) + (return hashmap obj)))) + success))) (values (%make-hashmap comparator tree) - obj))))) + obj))))) (define hashmap-search! hashmap-search) @@ -309,8 +309,8 @@ (define (hashmap-size hashmap) (assume (hashmap? hashmap)) (hashmap-count (lambda (key value) - #t) - hashmap)) + #t) + hashmap)) (define (hashmap-find predicate hashmap failure) (assume (procedure? predicate)) @@ -319,19 +319,19 @@ (call/cc (lambda (return) (hashmap-for-each (lambda (key value) - (when (predicate key value) - (return key value))) - hashmap) + (when (predicate key value) + (return key value))) + hashmap) (failure)))) (define (hashmap-count predicate hashmap) (assume (procedure? predicate)) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value count) - (if (predicate key value) - (+ 1 count) - count)) - 0 hashmap)) + (if (predicate key value) + (+ 1 count) + count)) + 0 hashmap)) (define (hashmap-any? predicate hashmap) (assume (procedure? predicate)) @@ -339,34 +339,34 @@ (call/cc (lambda (return) (hashmap-for-each (lambda (key value) - (when (predicate key value) - (return #t))) - hashmap) + (when (predicate key value) + (return #t))) + hashmap) #f))) (define (hashmap-every? predicate hashmap) (assume (procedure? predicate)) (assume (hashmap? hashmap)) (not (hashmap-any? (lambda (key value) - (not (predicate key value))) - hashmap))) + (not (predicate key value))) + hashmap))) (define (hashmap-keys hashmap) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value keys) - (cons key keys)) - '() hashmap)) + (cons key keys)) + '() hashmap)) (define (hashmap-values hashmap) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value values) - (cons value values)) - '() hashmap)) + (cons value values)) + '() hashmap)) (define (hashmap-entries hashmap) (assume (hashmap? hashmap)) (values (hashmap-keys hashmap) - (hashmap-values hashmap))) + (hashmap-values hashmap))) ;; Hashmap and folding @@ -375,11 +375,11 @@ (assume (comparator? comparator)) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value hashmap) - (receive (key value) - (proc key value) - (hashmap-set hashmap key value))) - (make-empty-hashmap comparator) - hashmap)) + (receive (key value) + (proc key value) + (hashmap-set hashmap key value))) + (make-empty-hashmap comparator) + hashmap)) (define (hashmap-for-each proc hashmap) (assume (procedure? proc)) @@ -395,19 +395,19 @@ (assume (procedure? proc)) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value lst) - (cons (proc key value) lst)) - '() - hashmap)) + (cons (proc key value) lst)) + '() + hashmap)) (define (hashmap-filter predicate hashmap) (assume (procedure? predicate)) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value hashmap) - (if (predicate key value) - (hashmap-set hashmap key value) - hashmap)) - (make-empty-hashmap (hashmap-key-comparator hashmap)) - hashmap)) + (if (predicate key value) + (hashmap-set hashmap key value) + hashmap)) + (make-empty-hashmap (hashmap-key-comparator hashmap)) + hashmap)) (define hashmap-filter! hashmap-filter) @@ -415,8 +415,8 @@ (assume (procedure? predicate)) (assume (hashmap? hashmap)) (hashmap-filter (lambda (key value) - (not (predicate key value))) - hashmap)) + (not (predicate key value))) + hashmap)) (define hashmap-remove! hashmap-remove) @@ -424,7 +424,7 @@ (assume (procedure? predicate)) (assume (hashmap? hashmap)) (values (hashmap-filter predicate hashmap) - (hashmap-remove predicate hashmap))) + (hashmap-remove predicate hashmap))) (define hashmap-partition! hashmap-partition) @@ -437,30 +437,30 @@ (define (hashmap->alist hashmap) (assume (hashmap? hashmap)) (hashmap-fold (lambda (key value alist) - (cons (cons key value) alist)) - '() hashmap)) + (cons (cons key value) alist)) + '() hashmap)) (define (alist->hashmap comparator alist) (assume (comparator? comparator)) (assume (list? alist)) (hashmap-unfold null? - (lambda (alist) - (let ((key (caar alist)) - (value (cdar alist))) - (values key value))) - cdr - alist - comparator)) + (lambda (alist) + (let ((key (caar alist)) + (value (cdar alist))) + (values key value))) + cdr + alist + comparator)) (define (alist->hashmap! hashmap alist) (assume (hashmap? hashmap)) (assume (list? alist)) (fold (lambda (association hashmap) - (let ((key (car association)) - (value (cdr association))) - (hashmap-set hashmap key value))) - hashmap - alist)) + (let ((key (car association)) + (value (cdr association))) + (hashmap-set hashmap key value))) + hashmap + alist)) ;; Subhashmaps @@ -500,12 +500,12 @@ (assume (hashmap? hashmap1)) (assume (hashmap? hashmap2)) (hashmap-every? (lambda (key value) - (hashmap-ref hashmap2 key - (lambda () - #f) - (lambda (stored-value) - (=? comparator value stored-value)))) - hashmap1)) + (hashmap-ref hashmap2 key + (lambda () + #f) + (lambda (stored-value) + (=? comparator value stored-value)))) + hashmap1)) (define hashmap>? (case-lambda @@ -580,44 +580,44 @@ (define (%hashmap-union hashmap1 hashmap2) (hashmap-fold (lambda (key2 value2 hashmap) - (receive (hashmap obj) - (hashmap-search hashmap - key2 - (lambda (insert ignore) - (insert value2 #f)) - (lambda (key1 value1 update remove) - (update key1 value1 #f))) - hashmap)) - hashmap1 hashmap2)) + (receive (hashmap obj) + (hashmap-search hashmap + key2 + (lambda (insert ignore) + (insert value2 #f)) + (lambda (key1 value1 update remove) + (update key1 value1 #f))) + hashmap)) + hashmap1 hashmap2)) (define (%hashmap-intersection hashmap1 hashmap2) (hashmap-filter (lambda (key1 value1) - (hashmap-contains? hashmap2 key1)) - hashmap1)) + (hashmap-contains? hashmap2 key1)) + hashmap1)) (define (%hashmap-difference hashmap1 hashmap2) (hashmap-fold (lambda (key2 value2 hashmap) - (receive (hashmap obj) - (hashmap-search hashmap - key2 - (lambda (insert ignore) - (ignore #f)) - (lambda (key1 value1 update remove) - (remove #f))) - hashmap)) - hashmap1 hashmap2)) + (receive (hashmap obj) + (hashmap-search hashmap + key2 + (lambda (insert ignore) + (ignore #f)) + (lambda (key1 value1 update remove) + (remove #f))) + hashmap)) + hashmap1 hashmap2)) (define (%hashmap-xor hashmap1 hashmap2) (hashmap-fold (lambda (key2 value2 hashmap) - (receive (hashmap obj) - (hashmap-search hashmap - key2 - (lambda (insert ignore) - (insert value2 #f)) - (lambda (key1 value1 update remove) - (remove #f))) - hashmap)) - hashmap1 hashmap2)) + (receive (hashmap obj) + (hashmap-search hashmap + key2 + (lambda (insert ignore) + (insert value2 #f)) + (lambda (key1 value1 update remove) + (remove #f))) + hashmap)) + hashmap1 hashmap2)) (define hashmap-union (case-lambda @@ -695,9 +695,9 @@ (define (make-hashmap-comparator comparator) (make-comparator hashmap? - (hashmap-equality comparator) - #f - (hashmap-hash-function comparator))) + (hashmap-equality comparator) + #f + (hashmap-hash-function comparator))) (define hashmap-comparator (make-hashmap-comparator (make-default-comparator))) diff --git a/lib/srfi/146/mapping.scm b/lib/srfi/146/mapping.scm index 48698cf1..992e707d 100644 --- a/lib/srfi/146/mapping.scm +++ b/lib/srfi/146/mapping.scm @@ -40,12 +40,12 @@ (define (mapping comparator . args) (assume (comparator? comparator)) (mapping-unfold null? - (lambda (args) - (values (car args) - (cadr args))) - cddr - args - comparator)) + (lambda (args) + (values (car args) + (cadr args))) + cddr + args + comparator)) (define (mapping-unfold stop? mapper successor seed comparator) (assume (procedure? stop?)) @@ -53,13 +53,13 @@ (assume (procedure? successor)) (assume (comparator? comparator)) (let loop ((mapping (make-empty-mapping comparator)) - (seed seed)) + (seed seed)) (if (stop? seed) - mapping - (receive (key value) - (mapper seed) - (loop (mapping-adjoin mapping key value) - (successor seed)))))) + mapping + (receive (key value) + (mapper seed) + (loop (mapping-adjoin mapping key value) + (successor seed)))))) (define mapping/ordered mapping) (define mapping-unfold/ordered mapping-unfold) @@ -75,11 +75,11 @@ (call/cc (lambda (return) (mapping-search mapping - key - (lambda (insert ignore) - (return #f)) - (lambda (key value update remove) - (return #t)))))) + key + (lambda (insert ignore) + (return #f)) + (lambda (key value update remove) + (return #t)))))) (define (mapping-disjoint? mapping1 mapping2) (assume (mapping? mapping1)) @@ -87,9 +87,9 @@ (call/cc (lambda (return) (mapping-for-each (lambda (key value) - (when (mapping-contains? mapping2 key) - (return #f))) - mapping1) + (when (mapping-contains? mapping2 key) + (return #f))) + mapping1) #t))) ;; Accessors @@ -99,24 +99,24 @@ ((mapping key) (assume (mapping? mapping)) (mapping-ref mapping key (lambda () - (error "mapping-ref: key not in mapping" key)))) + (error "mapping-ref: key not in mapping" key)))) ((mapping key failure) (assume (mapping? mapping)) (assume (procedure? failure)) (mapping-ref mapping key failure (lambda (value) - value))) + value))) ((mapping key failure success) (assume (mapping? mapping)) (assume (procedure? failure)) (assume (procedure? success)) ((call/cc (lambda (return-thunk) - (mapping-search mapping - key - (lambda (insert ignore) - (return-thunk failure)) - (lambda (key value update remove) - (return-thunk (lambda () (success value))))))))))) + (mapping-search mapping + key + (lambda (insert ignore) + (return-thunk failure)) + (lambda (key value update remove) + (return-thunk (lambda () (success value))))))))))) (define (mapping-ref/default mapping key default) (assume (mapping? mapping)) @@ -127,25 +127,25 @@ (define (mapping-adjoin mapping . args) (assume (mapping? mapping)) (let loop ((args args) - (mapping mapping)) + (mapping mapping)) (if (null? args) - mapping - (receive (mapping value) - (mapping-intern mapping (car args) (lambda () (cadr args))) - (loop (cddr args) mapping))))) + mapping + (receive (mapping value) + (mapping-intern mapping (car args) (lambda () (cadr args))) + (loop (cddr args) mapping))))) (define mapping-adjoin! mapping-adjoin) (define (mapping-set mapping . args) (assume (mapping? mapping)) (let loop ((args args) - (mapping mapping)) + (mapping mapping)) (if (null? args) - mapping - (receive (mapping) - (mapping-update mapping (car args) (lambda (value) (cadr args)) (lambda () #f)) - (loop (cddr args) - mapping))))) + mapping + (receive (mapping) + (mapping-update mapping (car args) (lambda (value) (cadr args)) (lambda () #f)) + (loop (cddr args) + mapping))))) (define mapping-set! mapping-set) @@ -153,11 +153,11 @@ (assume (mapping? mapping)) (receive (mapping obj) (mapping-search mapping - key - (lambda (insert ignore) - (ignore #f)) - (lambda (old-key old-value update remove) - (update key value #f))) + key + (lambda (insert ignore) + (ignore #f)) + (lambda (old-key old-value update remove) + (update key value #f))) mapping)) (define mapping-replace! mapping-replace) @@ -172,15 +172,15 @@ (assume (mapping? mapping)) (assume (list? keys)) (fold (lambda (key mapping) - (receive (mapping obj) - (mapping-search mapping - key - (lambda (insert ignore) - (ignore #f)) - (lambda (old-key old-value update remove) - (remove #f))) - mapping)) - mapping keys)) + (receive (mapping obj) + (mapping-search mapping + key + (lambda (insert ignore) + (ignore #f)) + (lambda (old-key old-value update remove) + (remove #f))) + mapping)) + mapping keys)) (define mapping-delete-all! mapping-delete-all) @@ -190,13 +190,13 @@ (call/cc (lambda (return) (mapping-search mapping - key - (lambda (insert ignore) - (receive (value) - (failure) - (insert value value))) - (lambda (old-key old-value update remove) - (return mapping old-value)))))) + key + (lambda (insert ignore) + (receive (value) + (failure) + (insert value value))) + (lambda (old-key old-value update remove) + (return mapping old-value)))))) (define mapping-intern! mapping-intern) @@ -204,22 +204,22 @@ (case-lambda ((mapping key updater) (mapping-update mapping key updater (lambda () - (error "mapping-update: key not found in mapping" key)))) + (error "mapping-update: key not found in mapping" key)))) ((mapping key updater failure) (mapping-update mapping key updater failure (lambda (value) - value))) + value))) ((mapping key updater failure success) (assume (mapping? mapping)) (assume (procedure? updater)) (assume (procedure? failure)) (assume (procedure? success)) (receive (mapping obj) - (mapping-search mapping - key - (lambda (insert ignore) - (insert (updater (failure)) #f)) - (lambda (old-key old-value update remove) - (update key (updater (success old-value)) #f))) + (mapping-search mapping + key + (lambda (insert ignore) + (insert (updater (failure)) #f)) + (lambda (old-key old-value update remove) + (update key (updater (success old-value)) #f))) mapping)))) (define mapping-update! mapping-update) @@ -233,16 +233,16 @@ (case-lambda ((mapping) (mapping-pop mapping (lambda () - (error "mapping-pop: mapping has no association")))) + (error "mapping-pop: mapping has no association")))) ((mapping failure) (assume (mapping? mapping)) (assume (procedure? failure)) ((call/cc (lambda (return-thunk) - (receive (key value) - (mapping-find (lambda (key value) #t) mapping (lambda () (return-thunk failure))) - (lambda () - (values (mapping-delete mapping key) key value))))))))) + (receive (key value) + (mapping-find (lambda (key value) #t) mapping (lambda () (return-thunk failure))) + (lambda () + (values (mapping-delete mapping key) key value))))))))) (define mapping-pop! mapping-pop) @@ -253,20 +253,20 @@ (call/cc (lambda (return) (let*-values - (((comparator) - (mapping-key-comparator mapping)) - ((tree obj) - (tree-search comparator - (mapping-tree mapping) - key - (lambda (insert ignore) - (failure (lambda (value obj) - (insert key value obj)) - (lambda (obj) - (return mapping obj)))) - success))) + (((comparator) + (mapping-key-comparator mapping)) + ((tree obj) + (tree-search comparator + (mapping-tree mapping) + key + (lambda (insert ignore) + (failure (lambda (value obj) + (insert key value obj)) + (lambda (obj) + (return mapping obj)))) + success))) (values (%make-mapping comparator tree) - obj))))) + obj))))) (define mapping-search! mapping-search) @@ -275,8 +275,8 @@ (define (mapping-size mapping) (assume (mapping? mapping)) (mapping-count (lambda (key value) - #t) - mapping)) + #t) + mapping)) (define (mapping-find predicate mapping failure) (assume (procedure? predicate)) @@ -285,19 +285,19 @@ (call/cc (lambda (return) (mapping-for-each (lambda (key value) - (when (predicate key value) - (return key value))) - mapping) + (when (predicate key value) + (return key value))) + mapping) (failure)))) (define (mapping-count predicate mapping) (assume (procedure? predicate)) (assume (mapping? mapping)) (mapping-fold (lambda (key value count) - (if (predicate key value) - (+ 1 count) - count)) - 0 mapping)) + (if (predicate key value) + (+ 1 count) + count)) + 0 mapping)) (define (mapping-any? predicate mapping) (assume (procedure? predicate)) @@ -305,34 +305,34 @@ (call/cc (lambda (return) (mapping-for-each (lambda (key value) - (when (predicate key value) - (return #t))) - mapping) + (when (predicate key value) + (return #t))) + mapping) #f))) (define (mapping-every? predicate mapping) (assume (procedure? predicate)) (assume (mapping? mapping)) (not (mapping-any? (lambda (key value) - (not (predicate key value))) - mapping))) + (not (predicate key value))) + mapping))) (define (mapping-keys mapping) (assume (mapping? mapping)) (mapping-fold/reverse (lambda (key value keys) - (cons key keys)) - '() mapping)) + (cons key keys)) + '() mapping)) (define (mapping-values mapping) (assume (mapping? mapping)) (mapping-fold/reverse (lambda (key value values) - (cons value values)) - '() mapping)) + (cons value values)) + '() mapping)) (define (mapping-entries mapping) (assume (mapping? mapping)) (values (mapping-keys mapping) - (mapping-values mapping))) + (mapping-values mapping))) ;; Mapping and folding @@ -341,11 +341,11 @@ (assume (comparator? comparator)) (assume (mapping? mapping)) (mapping-fold (lambda (key value mapping) - (receive (key value) - (proc key value) - (mapping-set mapping key value))) - (make-empty-mapping comparator) - mapping)) + (receive (key value) + (proc key value) + (mapping-set mapping key value))) + (make-empty-mapping comparator) + mapping)) (define (mapping-for-each proc mapping) (assume (procedure? proc)) @@ -361,19 +361,19 @@ (assume (procedure? proc)) (assume (mapping? mapping)) (mapping-fold/reverse (lambda (key value lst) - (cons (proc key value) lst)) - '() - mapping)) + (cons (proc key value) lst)) + '() + mapping)) (define (mapping-filter predicate mapping) (assume (procedure? predicate)) (assume (mapping? mapping)) (mapping-fold (lambda (key value mapping) - (if (predicate key value) - (mapping-set mapping key value) - mapping)) - (make-empty-mapping (mapping-key-comparator mapping)) - mapping)) + (if (predicate key value) + (mapping-set mapping key value) + mapping)) + (make-empty-mapping (mapping-key-comparator mapping)) + mapping)) (define mapping-filter! mapping-filter) @@ -381,8 +381,8 @@ (assume (procedure? predicate)) (assume (mapping? mapping)) (mapping-filter (lambda (key value) - (not (predicate key value))) - mapping)) + (not (predicate key value))) + mapping)) (define mapping-remove! mapping-remove) @@ -390,7 +390,7 @@ (assume (procedure? predicate)) (assume (mapping? mapping)) (values (mapping-filter predicate mapping) - (mapping-remove predicate mapping))) + (mapping-remove predicate mapping))) (define mapping-partition! mapping-partition) @@ -404,30 +404,30 @@ (assume (mapping? mapping)) (reverse (mapping-fold (lambda (key value alist) - (cons (cons key value) alist)) - '() mapping))) + (cons (cons key value) alist)) + '() mapping))) (define (alist->mapping comparator alist) (assume (comparator? comparator)) (assume (list? alist)) (mapping-unfold null? - (lambda (alist) - (let ((key (caar alist)) - (value (cdar alist))) - (values key value))) - cdr - alist - comparator)) + (lambda (alist) + (let ((key (caar alist)) + (value (cdar alist))) + (values key value))) + cdr + alist + comparator)) (define (alist->mapping! mapping alist) (assume (mapping? mapping)) (assume (list? alist)) (fold (lambda (association mapping) - (let ((key (car association)) - (value (cdr association))) - (mapping-set mapping key value))) - mapping - alist)) + (let ((key (car association)) + (value (cdr association))) + (mapping-set mapping key value))) + mapping + alist)) (define alist->mapping/ordered alist->mapping) (define alist->mapping/ordered! alist->mapping!) @@ -470,28 +470,28 @@ (assume (mapping? mapping1)) (assume (mapping? mapping2)) (let ((less? (comparator-ordering-predicate (mapping-key-comparator mapping1))) - (equality-predicate (comparator-equality-predicate comparator)) - (gen1 (tree-generator (mapping-tree mapping1))) - (gen2 (tree-generator (mapping-tree mapping2)))) + (equality-predicate (comparator-equality-predicate comparator)) + (gen1 (tree-generator (mapping-tree mapping1))) + (gen2 (tree-generator (mapping-tree mapping2)))) (let loop ((item1 (gen1)) - (item2 (gen2))) + (item2 (gen2))) (cond ((eof-object? item1) - #t) + #t) ((eof-object? item2) - #f) + #f) (else - (let ((key1 (car item1)) (value1 (cadr item1)) - (key2 (car item2)) (value2 (cadr item2))) - (cond - ((less? key1 key2) - #f) - ((less? key2 key1) - (loop item1 (gen2))) - ((equality-predicate value1 value2) - (loop (gen1) (gen2))) - (else - #f)))))))) + (let ((key1 (car item1)) (value1 (cadr item1)) + (key2 (car item2)) (value2 (cadr item2))) + (cond + ((less? key1 key2) + #f) + ((less? key2 key1) + (loop item1 (gen2))) + ((equality-predicate value1 value2) + (loop (gen1) (gen2))) + (else + #f)))))))) (define mapping>? (case-lambda @@ -566,44 +566,44 @@ (define (%mapping-union mapping1 mapping2) (mapping-fold (lambda (key2 value2 mapping) - (receive (mapping obj) - (mapping-search mapping - key2 - (lambda (insert ignore) - (insert value2 #f)) - (lambda (key1 value1 update remove) - (update key1 value1 #f))) - mapping)) - mapping1 mapping2)) + (receive (mapping obj) + (mapping-search mapping + key2 + (lambda (insert ignore) + (insert value2 #f)) + (lambda (key1 value1 update remove) + (update key1 value1 #f))) + mapping)) + mapping1 mapping2)) (define (%mapping-intersection mapping1 mapping2) (mapping-filter (lambda (key1 value1) - (mapping-contains? mapping2 key1)) - mapping1)) + (mapping-contains? mapping2 key1)) + mapping1)) (define (%mapping-difference mapping1 mapping2) (mapping-fold (lambda (key2 value2 mapping) - (receive (mapping obj) - (mapping-search mapping - key2 - (lambda (insert ignore) - (ignore #f)) - (lambda (key1 value1 update remove) - (remove #f))) - mapping)) - mapping1 mapping2)) + (receive (mapping obj) + (mapping-search mapping + key2 + (lambda (insert ignore) + (ignore #f)) + (lambda (key1 value1 update remove) + (remove #f))) + mapping)) + mapping1 mapping2)) (define (%mapping-xor mapping1 mapping2) (mapping-fold (lambda (key2 value2 mapping) - (receive (mapping obj) - (mapping-search mapping - key2 - (lambda (insert ignore) - (insert value2 #f)) - (lambda (key1 value1 update remove) - (remove #f))) - mapping)) - mapping1 mapping2)) + (receive (mapping obj) + (mapping-search mapping + key2 + (lambda (insert ignore) + (insert value2 #f)) + (lambda (key1 value1 update remove) + (remove #f))) + mapping)) + mapping1 mapping2)) (define mapping-union (case-lambda @@ -672,8 +672,8 @@ (call/cc (lambda (return) (mapping-fold (lambda (key value acc) - (return key)) - #f mapping) + (return key)) + #f mapping) (error "mapping-min-key: empty map")))) (define (mapping-max-key mapping) @@ -681,8 +681,8 @@ (call/cc (lambda (return) (mapping-fold/reverse (lambda (key value acc) - (return key)) - #f mapping) + (return key)) + #f mapping) (error "mapping-max-key: empty map")))) (define (mapping-min-value mapping) @@ -690,8 +690,8 @@ (call/cc (lambda (return) (mapping-fold (lambda (key value acc) - (return value)) - #f mapping) + (return value)) + #f mapping) (error "mapping-min-value: empty map")))) (define (mapping-max-value mapping) @@ -699,8 +699,8 @@ (call/cc (lambda (return) (mapping-fold/reverse (lambda (key value acc) - (return value)) - #f mapping) + (return value)) + #f mapping) (error "mapping-max-value: empty map")))) (define (mapping-key-predecessor mapping obj failure) @@ -717,28 +717,28 @@ (assume (mapping? mapping)) (let ((comparator (mapping-key-comparator mapping))) (receive (tree< tree<= tree= tree>= tree>) - (tree-split comparator (mapping-tree mapping) obj) + (tree-split comparator (mapping-tree mapping) obj) (%make-mapping comparator tree=)))) (define (mapping-range< mapping obj) (assume (mapping? mapping)) (let ((comparator (mapping-key-comparator mapping))) (receive (tree< tree<= tree= tree>= tree>) - (tree-split comparator (mapping-tree mapping) obj) + (tree-split comparator (mapping-tree mapping) obj) (%make-mapping comparator tree<)))) (define (mapping-range<= mapping obj) (assume (mapping? mapping)) (let ((comparator (mapping-key-comparator mapping))) (receive (tree< tree<= tree= tree>= tree>) - (tree-split comparator (mapping-tree mapping) obj) + (tree-split comparator (mapping-tree mapping) obj) (%make-mapping comparator tree<=)))) (define (mapping-range> mapping obj) (assume (mapping? mapping)) (let ((comparator (mapping-key-comparator mapping))) (receive (tree< tree<= tree= tree>= tree>) - (tree-split comparator (mapping-tree mapping) obj) + (tree-split comparator (mapping-tree mapping) obj) (%make-mapping comparator tree>)))) (define (mapping-range>= mapping obj) @@ -746,7 +746,7 @@ (assume (mapping? mapping)) (let ((comparator (mapping-key-comparator mapping))) (receive (tree< tree<= tree= tree>= tree>) - (tree-split comparator (mapping-tree mapping) obj) + (tree-split comparator (mapping-tree mapping) obj) (%make-mapping comparator tree>=)))) (define mapping-range=! mapping-range=) @@ -759,21 +759,21 @@ (assume (mapping? mapping)) (let ((comparator (mapping-key-comparator mapping))) (receive (tree< tree<= tree= tree>= tree>) - (tree-split comparator (mapping-tree mapping) obj) + (tree-split comparator (mapping-tree mapping) obj) (values (%make-mapping comparator tree<) - (%make-mapping comparator tree<=) - (%make-mapping comparator tree=) - (%make-mapping comparator tree>=) - (%make-mapping comparator tree>))))) + (%make-mapping comparator tree<=) + (%make-mapping comparator tree=) + (%make-mapping comparator tree>=) + (%make-mapping comparator tree>))))) (define (mapping-catenate comparator mapping1 pivot-key pivot-value mapping2) (assume (comparator? comparator)) (assume (mapping? mapping1)) (assume (mapping? mapping2)) (%make-mapping comparator (tree-catenate (mapping-tree mapping1) - pivot-key - pivot-value - (mapping-tree mapping2)))) + pivot-key + pivot-value + (mapping-tree mapping2)))) (define mapping-catenate! mapping-catenate) @@ -800,30 +800,30 @@ (define (mapping-ordering comparator) (assume (comparator? comparator)) (let ((value-equality (comparator-equality-predicate comparator)) - (value-ordering (comparator-ordering-predicate comparator))) + (value-ordering (comparator-ordering-predicate comparator))) (lambda (mapping1 mapping2) (let* ((key-comparator (mapping-key-comparator mapping1)) - (equality (comparator-equality-predicate key-comparator)) - (ordering (comparator-ordering-predicate key-comparator)) - (gen1 (tree-generator (mapping-tree mapping1))) - (gen2 (tree-generator (mapping-tree mapping2)))) - (let loop () - (let ((item1 (gen1)) (item2 (gen2))) - (cond - ((eof-object? item1) - (not (eof-object? item2))) - ((eof-object? item2) - #f) - (else - (let ((key1 (car item1)) (value1 (cadr item1)) - (key2 (car item2)) (value2 (cadr item2))) - (cond - ((equality key1 key2) - (if (value-equality value1 value2) - (loop) - (value-ordering value1 value2))) - (else - (ordering key1 key2)))))))))))) + (equality (comparator-equality-predicate key-comparator)) + (ordering (comparator-ordering-predicate key-comparator)) + (gen1 (tree-generator (mapping-tree mapping1))) + (gen2 (tree-generator (mapping-tree mapping2)))) + (let loop () + (let ((item1 (gen1)) (item2 (gen2))) + (cond + ((eof-object? item1) + (not (eof-object? item2))) + ((eof-object? item2) + #f) + (else + (let ((key1 (car item1)) (value1 (cadr item1)) + (key2 (car item2)) (value2 (cadr item2))) + (cond + ((equality key1 key2) + (if (value-equality value1 value2) + (loop) + (value-ordering value1 value2))) + (else + (ordering key1 key2)))))))))))) (define (make-mapping-comparator comparator) (make-comparator mapping? (mapping-equality comparator) (mapping-ordering comparator) #f)) diff --git a/lib/srfi/146/rbtree.scm b/lib/srfi/146/rbtree.scm index 3a8c884f..940a23cb 100644 --- a/lib/srfi/146/rbtree.scm +++ b/lib/srfi/146/rbtree.scm @@ -57,16 +57,16 @@ ((compile-patterns (expression* ...) tree (clauses ...) ()) (call-with-current-continuation (lambda (return) - (or (and-let* clauses - (call-with-values - (lambda () . expression*) - return)) - ... - (error "tree does not match any pattern" tree))))) + (or (and-let* clauses + (call-with-values + (lambda () . expression*) + return)) + ... + (error "tree does not match any pattern" tree))))) ((compile-patterns e tree clauses* (pattern . pattern*)) (compile-pattern tree pattern - (add-pattern e tree clauses* pattern*))))) + (add-pattern e tree clauses* pattern*))))) (define-syntax add-pattern (syntax-rules () @@ -93,23 +93,23 @@ ((compile-pattern tree (and pt ...) k*) (compile-subpatterns () ((t pt) ...) - (compile-and-pattern tree t k*))) + (compile-and-pattern tree t k*))) ((compile-pattern tree (node pc pa px pb) k*) (compile-subpatterns () ((c pc) (a pa) (x px) (b pb)) - (compile-node-pattern tree c a x b k*))) + (compile-node-pattern tree c a x b k*))) ((compile-pattern tree (red pa px pb) k*) (compile-subpatterns () ((a pa) (x px) (b pb)) - (compile-color-pattern red? tree a x b k*))) + (compile-color-pattern red? tree a x b k*))) ((compile-pattern tree (black pa px pb) k*) (compile-subpatterns () ((a pa) (x px) (b pb)) - (compile-color-pattern black? tree a x b k*))) + (compile-color-pattern black? tree a x b k*))) ((compile-pattern tree (white pa px pb) k*) (compile-subpatterns () ((a pa) (x px) (b pb)) - (compile-color-pattern white? tree a x b k*))) + (compile-color-pattern white? tree a x b k*))) ((compile-pattern tree _ (k ...)) (k ... ())) @@ -126,19 +126,19 @@ (syntax-rules () ((compile-node-pattern tree c a x b (k ...) clauses) (k ... (((item tree)) - (c (color tree)) - (a (left tree)) - (x (item tree)) - (b (right tree)) . clauses))))) + (c (color tree)) + (a (left tree)) + (x (item tree)) + (b (right tree)) . clauses))))) (define-syntax compile-color-pattern (syntax-rules () ((compile-color-pattern pred? tree a x b (k ...) clauses) (k ... (((item tree)) - ((pred? tree)) - (a (left tree)) - (x (item tree)) - (b (right tree)) . clauses))))) + ((pred? tree)) + (a (left tree)) + (x (item tree)) + (b (right tree)) . clauses))))) (define-syntax compile-subpatterns (syntax-rules () @@ -186,10 +186,10 @@ acc) ((node _ a x b) (let* - ((acc (loop acc a)) - (acc (proc (item-key x) (item-value x) acc)) - (acc (loop acc b))) - acc))))) + ((acc (loop acc a)) + (acc (proc (item-key x) (item-value x) acc)) + (acc (loop acc b))) + acc))))) (define (tree-fold/reverse proc seed tree) (let loop ((acc seed) (tree tree)) @@ -198,15 +198,15 @@ acc) ((node _ a x b) (let* - ((acc (loop acc b)) - (acc (proc (item-key x) (item-value x) acc)) - (acc (loop acc a))) - acc))))) + ((acc (loop acc b)) + (acc (proc (item-key x) (item-value x) acc)) + (acc (loop acc a))) + acc))))) (define (tree-for-each proc tree) (tree-fold (lambda (key value acc) - (proc key value)) - #f tree)) + (proc key value)) + #f tree)) (define (tree-generator tree) (make-coroutine-generator @@ -218,51 +218,51 @@ (define (tree-search comparator tree obj failure success) (receive (tree ret op) (let search ((tree (redden tree))) - (tree-match tree - ((black) - (failure - ;; insert - (lambda (new-key new-value ret) - (values (red (black-leaf) (make-item new-key new-value) (black-leaf)) - ret - balance)) - ;; ignore - (lambda (ret) - (values (black-leaf) ret identity)))) - - ((and t (node c a x b)) - (let ((key (item-key x))) - (comparator-if<=> comparator obj key - - (receive (a ret op) (search a) - (values (op (node c a x b)) ret op)) - - (success - key - (item-value x) - ;; update - (lambda (new-key new-value ret) - (values (node c a (make-item new-key new-value) b) - ret - identity)) - ;; remove - (lambda (ret) - (values - (tree-match t - ((red (black) x (black)) - (black-leaf)) - ((black (red a x b) _ (black)) - (black a x b)) - ((black (black) _ (black)) - (white-leaf)) - (_ - (receive (x b) (min+delete b) - (rotate (node c a x b))))) - ret - rotate))) - - (receive (b ret op) (search b) - (values (op (node c a x b)) ret op))))))) + (tree-match tree + ((black) + (failure + ;; insert + (lambda (new-key new-value ret) + (values (red (black-leaf) (make-item new-key new-value) (black-leaf)) + ret + balance)) + ;; ignore + (lambda (ret) + (values (black-leaf) ret identity)))) + + ((and t (node c a x b)) + (let ((key (item-key x))) + (comparator-if<=> comparator obj key + + (receive (a ret op) (search a) + (values (op (node c a x b)) ret op)) + + (success + key + (item-value x) + ;; update + (lambda (new-key new-value ret) + (values (node c a (make-item new-key new-value) b) + ret + identity)) + ;; remove + (lambda (ret) + (values + (tree-match t + ((red (black) x (black)) + (black-leaf)) + ((black (red a x b) _ (black)) + (black a x b)) + ((black (black) _ (black)) + (white-leaf)) + (_ + (receive (x b) (min+delete b) + (rotate (node c a x b))))) + ret + rotate))) + + (receive (b ret op) (search b) + (values (op (node c a x b)) ret op))))))) (values (blacken tree) ret))) @@ -273,10 +273,10 @@ (return)) ((node _ a x b) (let ((key (item-key x))) - (comparator-if<=> comparator key obj - (loop return b) - (loop return b) - (loop (lambda () key) a))))))) + (comparator-if<=> comparator key obj + (loop return b) + (loop return b) + (loop (lambda () key) a))))))) (define (tree-key-predecessor comparator tree obj failure) (let loop ((return failure) (tree tree)) @@ -285,10 +285,10 @@ (return)) ((node _ a x b) (let ((key (item-key x))) - (comparator-if<=> comparator key obj - (loop (lambda () key) b) - (loop return a) - (loop return a))))))) + (comparator-if<=> comparator key obj + (loop (lambda () key) b) + (loop return a) + (loop return a))))))) (define (tree-map proc tree) (let loop ((tree tree)) @@ -297,64 +297,64 @@ (black-leaf)) ((node c a x b) (receive (key value) - (proc (item-key x) (item-value x)) - (node c (loop a) (make-item key value) (loop b))))))) + (proc (item-key x) (item-value x)) + (node c (loop a) (make-item key value) (loop b))))))) (define (tree-catenate tree1 pivot-key pivot-value tree2) (let ((pivot (make-item pivot-key pivot-value)) - (height1 (black-height tree1)) - (height2 (black-height tree2))) + (height1 (black-height tree1)) + (height2 (black-height tree2))) (cond ((= height1 height2) (black tree1 pivot tree2)) ((< height1 height2) (blacken (let loop ((tree tree2) (depth (- height2 height1))) - (if (zero? depth) - (balance (red tree1 pivot tree)) - (balance - (node (color tree) (loop (left tree) (- depth 1)) (item tree) (right tree))))))) + (if (zero? depth) + (balance (red tree1 pivot tree)) + (balance + (node (color tree) (loop (left tree) (- depth 1)) (item tree) (right tree))))))) (else (blacken (let loop ((tree tree1) (depth (- height1 height2))) - (if (zero? depth) - (balance (red tree pivot tree2)) - (balance - (node (color tree) (left tree) (item tree) (loop (right tree) (- depth 1))))))))))) + (if (zero? depth) + (balance (red tree pivot tree2)) + (balance + (node (color tree) (left tree) (item tree) (loop (right tree) (- depth 1))))))))))) (define (tree-split comparator tree obj) (let loop ((tree1 (black-leaf)) - (tree2 (black-leaf)) - (pivot1 #f) - (pivot2 #f) - (tree tree)) + (tree2 (black-leaf)) + (pivot1 #f) + (pivot2 #f) + (tree tree)) (tree-match tree ((black) (let ((tree1 (catenate-left tree1 pivot1 (black-leaf))) - (tree2 (catenate-right (black-leaf) pivot2 tree2))) - (values tree1 tree1 (black-leaf) tree2 tree2))) + (tree2 (catenate-right (black-leaf) pivot2 tree2))) + (values tree1 tree1 (black-leaf) tree2 tree2))) ((node _ a x b) (comparator-if<=> comparator obj (item-key x) - (loop tree1 - (catenate-right (blacken b) pivot2 tree2) - pivot1 - x - (blacken a)) - (let* ((tree1 (catenate-left tree1 pivot1 (blacken a))) - (tree1+ (catenate-left tree1 x (black-leaf))) - (tree2 (catenate-right (blacken b) pivot2 tree2)) - (tree2+ (catenate-right (black-leaf) x tree2))) - (values tree1 - tree1+ - (black (black-leaf) x (black-leaf)) - tree2+ - tree2)) - (loop (catenate-left tree1 pivot1 (blacken a)) - tree2 - x - pivot2 - (blacken b))))))) + (loop tree1 + (catenate-right (blacken b) pivot2 tree2) + pivot1 + x + (blacken a)) + (let* ((tree1 (catenate-left tree1 pivot1 (blacken a))) + (tree1+ (catenate-left tree1 x (black-leaf))) + (tree2 (catenate-right (blacken b) pivot2 tree2)) + (tree2+ (catenate-right (black-leaf) x tree2))) + (values tree1 + tree1+ + (black (black-leaf) x (black-leaf)) + tree2+ + tree2)) + (loop (catenate-left tree1 pivot1 (blacken a)) + tree2 + x + pivot2 + (blacken b))))))) (define (catenate-left tree1 item tree2) (if item @@ -379,14 +379,14 @@ (define (left-tree tree depth) (let loop ((parent #f) (tree tree) (depth depth)) (if (zero? depth) - (values parent tree) - (loop tree (left tree) (- depth 1))))) + (values parent tree) + (loop tree (left tree) (- depth 1))))) (define (right-tree tree depth) (let loop ((parent #f) (tree tree) (depth depth)) (if (zero? depth) - (values parent tree) - (loop tree (right tree) (- depth 1))))) + (values parent tree) + (loop tree (right tree) (- depth 1))))) ;;; Helper procedures for deleting and balancing diff --git a/lib/srfi/146/test.sld b/lib/srfi/146/test.sld index 8f269701..a71b214b 100644 --- a/lib/srfi/146/test.sld +++ b/lib/srfi/146/test.sld @@ -144,7 +144,7 @@ (receive (mapping value) (mapping-intern mapping1 'd (lambda () 42)) (list value (mapping-ref mapping 'd)))) - + (test "mapping-update" 4 (mapping-ref mapping3 'b)) diff --git a/lib/srfi/146/vector-edit-test.scm b/lib/srfi/146/vector-edit-test.scm index fa1419aa..651d5e22 100644 --- a/lib/srfi/146/vector-edit-test.scm +++ b/lib/srfi/146/vector-edit-test.scm @@ -28,7 +28,7 @@ (test-group "(vector-without)" (define (check expected start end) (let ((v #(0 1 2 3 4))) - (test expected (vector-without v start end)))) + (test expected (vector-without v start end)))) (check #(0 1 2 3 4) 0 0) (check #() 0 5) (check #(1 2 3 4) 0 1) @@ -46,24 +46,24 @@ (test-group "(vector-edit adjacent-adds)" (let ((array (vector 0 1 2))) (test #(0 1 2 3 4) - (vector-edit array - (add 3 3) - (add 3 4))))) + (vector-edit array + (add 3 3) + (add 3 4))))) (test-group "(vector-edit adjacent-drops)" (let ((array (vector 0 1 2 3 4 5))) (test #(0 1 2) - (vector-edit array - (drop 3 1) - (drop 4 2))))) + (vector-edit array + (drop 3 1) + (drop 4 2))))) (test-group "(vector-edit alternating-add-drop)" (let ((array (vector 0 1 2 2 2 3 4 6 6 6 6 7 9))) (test #(0 1 2 3 4 5 6 7 8 9) - (vector-edit array - (drop 3 2) - (add 7 5) - (drop 8 3) - (add 12 8))))) + (vector-edit array + (drop 3 2) + (add 7 5) + (drop 8 3) + (add 12 8))))) (test-end)) \ No newline at end of file diff --git a/lib/srfi/146/vector-edit.scm b/lib/srfi/146/vector-edit.scm index 9c2a6ed1..f5806419 100644 --- a/lib/srfi/146/vector-edit.scm +++ b/lib/srfi/146/vector-edit.scm @@ -31,9 +31,9 @@ (define (vector-without v start end) "Return a copy of vector `v' without the elements with indices [start, end)." (let* ((size (vector-length v)) - (gap-size (- end start)) - (new-size (- size gap-size)) - (result (make-vector new-size))) + (gap-size (- end start)) + (new-size (- size gap-size)) + (result (make-vector new-size))) (vector-copy! result 0 v 0 start) (vector-copy! result start v end size) result)) @@ -63,14 +63,14 @@ (vector-copy! r (+ o s) v o index) (vector-set! r (+ s index) e) (let ((skew (+ s 1))) - (vector-edit-code v r index skew . rest)))) + (vector-edit-code v r index skew . rest)))) ((_ v r o s (drop i c) . rest) (let ((index i)) (vector-copy! r (+ o s) v o index) (let* ((dropped c) - (offset (+ index dropped)) - (skew (- s dropped))) - (vector-edit-code v r offset skew . rest)))))) + (offset (+ index dropped)) + (skew (- s dropped))) + (vector-edit-code v r offset skew . rest)))))) ;; <> Optimize this by allowing one to supply more than one value in ;; `add' sub-expressions so that adjacent values can be inserted @@ -89,5 +89,5 @@ (syntax-rules () ((_ v . rest) (let ((result (make-vector (+ (vector-length v) - (vector-edit-total-skew 0 . rest))))) + (vector-edit-total-skew 0 . rest))))) (vector-edit-code v result 0 0 . rest))))) \ No newline at end of file