#lang racket/base ;; Bags and Deltas (which are Bags where item-counts can be negative). (provide make-bag bag-change! bag-ref bag-clear! bag-member? in-bag in-bag/count) ;; A `(Bagof 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. (define make-bag make-hash) (define (bag-change! b x delta) (define old-count (bag-ref b x)) (define new-count (+ old-count delta)) (if (zero? new-count) (begin (hash-remove! b x) (if (zero? old-count) 'absent->absent 'present->absent)) (begin (hash-set! b x new-count) (if (zero? old-count) 'absent->present 'present->present)))) (define (bag-ref b x) (hash-ref b x 0)) (define bag-clear! hash-clear!) (define bag-member? hash-has-key?) (define-syntax-rule (in-bag piece ...) (in-hash-keys piece ...)) (define-syntax-rule (in-bag/count piece ...) (in-hash piece ...))