diff --git a/syndicate/bag.rkt b/syndicate/bag.rkt index 984a651..4e4aca8 100644 --- a/syndicate/bag.rkt +++ b/syndicate/bag.rkt @@ -1,21 +1,29 @@ #lang racket/base ;; Bags and Deltas (which are Bags where item-counts can be negative). -(provide make-bag +(provide make-bag ;; mutable + bag ;; immutable bag-change! + bag-change bag-ref bag-clear! bag-member? in-bag - in-bag/count) + in-bag/count + set->bag) -;; A `(Bagof X)` is a `(MutableHash X Nat)`, where the `Nat` against -;; an `X` is its replication count in the bag. +(require racket/set) + +;; A `(MutableBagof X)` is a `(MutableHash X Nat)`, where the `Nat` +;; against an `X` is its replication count in the bag. ;; -;; A `(Deltaof X)` is a `(MutableHash X Int)`, just like a `(Bagof X)` -;; except the replication counts can be negative. +;; A `(Bagof X)` is similar, but immutable. +;; +;; A `(Deltaof X)` is a `(MutableHash X Int)`, just like a +;; `(MutableBagof X)` except the replication counts can be negative. (define make-bag make-hash) +(define bag hash) (define (bag-change! b x delta) (define old-count (bag-ref b x)) @@ -26,6 +34,15 @@ (begin (hash-set! b x new-count) (if (zero? old-count) 'absent->present 'present->present)))) +(define (bag-change b x delta) + (define old-count (bag-ref b x)) + (define new-count (+ old-count delta)) + (if (zero? new-count) + (values (hash-remove b x) + (if (zero? old-count) 'absent->absent 'present->absent)) + (values (hash-set b x new-count) + (if (zero? old-count) 'absent->present 'present->present)))) + (define (bag-ref b x) (hash-ref b x 0)) @@ -34,3 +51,7 @@ (define-syntax-rule (in-bag piece ...) (in-hash-keys piece ...)) (define-syntax-rule (in-bag/count piece ...) (in-hash piece ...)) + +(define (set->bag s) + (for/hash [(e (in-set s))] + (values e 1)))