anchor.diff:     input
      :remove-empty-subseqs t))
   
  -(defun finalize-lm (lm &key (ngram-limit 400) remove-singletons)
  +(defun finalize-lm (lm &key (ngram-limit *ngram-limit*) remove-singletons)
     (when remove-singletons
       (maphash (lambda (k v)
                  (when (= v 1)
  
positive.code:   (let ((alist (hash-table-alist lm)))
      (firstn ngram-limit (sort alist #'> :key #'cdr))))
  
  (defun create-lm (input &key remove-singletons (ngram-limit 400))
    (finalize-lm (update-lm (dict) input)
                 :remove-singletons remove-singletons
                 :ngram-limit ngram-limit))
  
negative.code:            collect (cons language (load-model model))))
     t))
  
  (defun input-model (input &key (sample-size *sample-size*)
                                 remove-singletons)
    (check-type input string)
    (let* ((sample
             (if (or (not sample-size)
                     (> sample-size (length input)))
                 input
                 (nsubseq input 0 sample-size)))
           (model (create-lm sample
                             :remove-singletons
                             (if (numberp remove-singletons)
                                 (> (length sample) remove-singletons)
                                 remove-singletons))))
      (map-into model #'car model)))
  
  (defun language-score (unknown model &optional (ngram-limit *ngram-limit*))
    (loop for i from 0
          for ngram in unknown
          for match = (gethash ngram model)
          if match
            sum (abs (- match i))
          else sum ngram-limit))
  
  (defun classify (input &key (ngram-limit *ngram-limit*)
                              (languages *language-models*)
                              remove-singletons
                              (cutoff *cutoff*)
                              (sample-size *sample-size*))
    "Return the language of INPUT.
  
  LANGUAGES is the alist of language models to use; default is
  *LANGUAGE-MODELS*.
  
  SAMPLE-SIZE limits the portion of INPUT used to generate the ngram
  profile to a certain number of characters (default is 20,000, which is
  plenty). NIL means no limit.
  
  REMOVE-SINGLETONS is either NIL (don't), T (always), or a
  number (above this length). It provides a slight increase in speed for
  long texts, but should not be used with short texts.
  
  If a guess is unlikelier than than CUTOFF times the previous guess, it
  is discarded."
    (let* ((unknown (input-model input
                                 :sample-size sample-size
                                 :remove-singletons remove-singletons))
           (distances
             (loop for (language . model) in languages
                   collect (cons language
                                 (language-score unknown model
                                                 ngram-limit))))
           (sorted-distances (sort distances #'< :key #'cdr))
           (results
             (destructuring-bind ((best . score) . rest)
                 sorted-distances
               (cons (alpha-2 best)
                     (let ((base (* score cutoff)))
                       (loop for (lang . score) in rest
                             while (< score base)
                             collect (alpha-2 lang)))))))
      (values (first results) (rest results))))
  
  (defun update-lm (lm input)
    (prog1 lm
  