anchor.diff:  (defpackage #:diss-counter
     (:use :cl)
  -  (:export #:diss-counter #:next #:diss-counter))
  +  (:export #:diss-counter #:next #:prob-fun #:reset-counts #:map-dc #:ref
  +           #:size #:square-count #:prob-sum #:ref-count #:elem-count))
   
   (in-package #:diss-counter)
   
  
positive.code:   (prob 0.0d0 :type double-float))
  
  (defclass diss-counter ()
    ((elems
      :accessor elems)
     (prob-fun
      :initarg :prob-fun
      :initform #'square-count
      :accessor prob-fun)
     (prob-sum
      :accessor prob-sum
      :type double-float)))
  
  (defmethod initialize-instance :after ((dc diss-counter) &key objs)
    (let* ((prob-fun (slot-value dc 'prob-fun))
  
negative.code:                    (entry-increase entry prob-fun))))))
        chosen)))
  
  (defun update-probs (dc)
    (let ((prob-sum 0.0d0)
          (f (prob-fun dc)))
      (do-entries (entry dc)
        (incf prob-sum (entry-update-prob entry f)))
      (setf (slot-value 'prob-sum dc) prob-sum)))
  
  (defun (setf prob-fun) (f dc)
    (setf (slot-value 'prob-fun dc) f)
    (update-probs dc))
  
  (defun reset-counts (dc &optional (count 1))
    (let ((prob-sum 0.0d0)
          (f (prob-fun dc)))
      (do-entries (entry dc)
        (incf prob-sum (entry-update-count entry count f)))
      (setf (slot-value 'prob-sum dc) prob-sum)))
  
  
  (defun size (dc)
    (length (slot-value 'elems dc)))
  
  (defun ref (dc i)
    (let ((entry (aref (slot-value dc 'elems) i)))
      (values (entry-elem entry) (entry-count entry) (entry-prob entry))))
  
  (defun ref-count (dc i)
    (entry-count (aref (slot-value dc 'elems) i)))
  
  (defun update-count (dc entry count)
    (let ((old (entry-prob entry))
          (new (entry-update-count entry count (prob-fun dc))))
      (incf (slot-value dc 'prob-sum)
            (- new old))))
  
  (defun (setf ref-count) (count dc i)
    (let ((entry (aref (slot-value dc 'elems) i)))
      (update-count dc entry count)))
  
  (defun find-entry (elem dc test key)
    (if key
        (let ((elem-key (funcall key elem)))
          (do-entries (entry dc)
            (when (funcall test elem-key (funcall key (entry-elem entry)))
              (return-from find-entry entry))))
        (do-entries (entry dc)
          (when (funcall test elem (entry-elem entry))
            (return-from find-entry entry)))))
  
  (defun elem-count (dc elem &key (test #'eql) key)
    (let ((entry (find-entry elem dc test key)))
      (when entry
        (entry-count entry))))
  
  (defun (setf elem-count) (count dc elem &key (test #'eql) key)
    (let ((entry (find-entry elem dc test key)))
      (when entry
        (update-count dc entry count))))
  
  (defun map-dc (dc f)
    (do-entries (entry dc dc)
      (funcall f (entry-elem entry) (entry-count entry) (entry-prob entry))))
  