anchor.diff:  (defpackage #:atn
     (:use #:cl #:alexandria #:eager-future2)
     (:export #:make-atn
  +
  +           #:defstate
  +           #:defrule
   
              #:rule
              #:state
  
positive.code:          (progn ,@body)
         (apply-delta atn::*atn* atn::*delta*))))
  
  (defun add-rule (atn rule state options)
    "Add rule into atn"
    (setf (gethash rule (atn-rules atn)) (make-rule :state state :options options)))
  
  (defun @add-rule (rule state options)
    "Add rule into current atn"
    (if *atn*
        (add-rule *delta* rule state options)
        (error "@ functions must be used inside of WITH-ATN")))
  
  (defun get-rule (atn rule)
  
negative.code: 
  (defstruct atn
    (table (make-hash-table))
    (rules (make-hash-table))
    (extra (make-hash-table)))
  
  ;;; Rule
  
  (eval-when (:compile-toplevel :load-toplevel)
    (defun make-et-accessor (raw-accessor element-getter)
      (let ((et-accessor (symbolicate "@" raw-accessor)))
        `(progn
           (defun ,et-accessor (rule)
             (,raw-accessor (,element-getter rule)))
           (export ',et-accessor)
           (define-setf-expander ,et-accessor (x &environment env)
             (multiple-value-bind (dummies vals newval setter getter)
                 (get-setf-expansion x env)
               (declare (ignorable newval setter))
               (let ((store (gensym)))
                 (values dummies
                         vals
                         `(,store)
                         `(progn (setf (,',raw-accessor (,',element-getter ,getter)) ,store) ,store)
                         `(,',et-accessor ,getter)))))))))
  
  (defmacro defrule (name direct-superclasses direct-slots &rest options)
    (let ((accessors (mapcar (lambda (slot)
                               (getf (rest slot) :accessor))
                             direct-slots)))
      `(progn
         (defclass ,name ,direct-superclasses
           ,direct-slots
           ,@options)
         ,@(mapcar (rcurry #'make-et-accessor '@get-rule) accessors))))
  
  (defrule rule ()
    ((state :accessor rule-state
            :initarg :state)
     (options :accessor rule-options
              :initarg :options)))
  
  ;;; Possible states
  
  (defmacro defstate (name direct-superclasses direct-slots &rest options)
    (let ((accessors (mapcar (lambda (slot)
                               (getf (rest slot) :accessor))
                             direct-slots)))
      `(progn
         (defclass ,name ,direct-superclasses
           ,direct-slots
           ,@options)
         ,@(mapcar (rcurry #'make-et-accessor '@get-state) accessors))))
  
  (defstate state ()
    ((cond :accessor state-cond
           :initarg :cond
           :initform t)
  