anchor.diff:  ;; sheep-creation.lisp
   ;;
   ;; Sheep creation, cloning, inspection
  +;;
  +;; TODO - write validate-hierarchy-list, which could be called whenever the parents list changes.
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   (in-package :sheeple)
   (declaim (optimize (debug 1) (safety 1) (speed 3)))
   
  +;; We declare these base vars here so that bootstrapping won't complain.
   (defvar =t=)
   (defvar =dolly=)
  +
  +;;;
  +;;; Sheeple object
  +;;;
   (defclass standard-sheep ()
  -  ((nickname :accessor sheep-nickname :initform nil)
  -   (documentation :accessor sheep-documentation :initform "")
  -   (direct-parents :accessor sheep-parents :initform nil :initarg :direct-parents)
  -   (%direct-children :accessor %direct-children
  -                     :initform  (make-weak-hash-table :weakness :key :test #'eq))
  +  (;;; Core slots
  +   (nickname :accessor sheep-nickname :initform nil
  +             :documentation "Displayed nickname")
  +   (documentation :accessor sheep-documentation :initform ""
  +                  :documentation "Docstring for this sheep.")
  +   (parents :accessor sheep-parents :initform nil :initarg :direct-parents
  +            :documentation "Parents of this sheep object.")
      (property-value-table :accessor sheep-property-value-table
                            :initform (make-hash-table :test #'eq))
      (property-metaobject-table :accessor sheep-property-metaobject-table
                           :initform (make-hash-table :test #'eq))
      (direct-roles :accessor sheep-direct-roles :initform nil)
  -   (hierarchy-list :accessor sheep-hierarchy-list :initform nil)))
  +   ;;; Extra slots for backstage tricks.
  +   ;; The reason we keep these references is to alert children recursively whenever the
  +   ;; hierarchy-list changes for a sheep, which means we can memoize the thing.
  +   (%children :accessor %children :initform  (make-weak-hash-table :weakness :key :test #'eq)
  +              :documentation "This is a special slot kept around mostly to make memoization
  +                              easy (possible?) by keeping references to children.")
  +   ;; I think the following would be unnecessary if there was a generator that spit out the
  +   ;; sheep's parents one by one that the implementation could use, instead of either
  +   ;; recalculating the whole thing each time, or saving the whole thing.
  +   (hierarchy-list :accessor sheep-hierarchy-list :initform nil
  +                   :documentation "A pre-calculated hierarchy list, so we don't have to run all
  +                                   of sheep-direct-parents every time.")))
   
   (defun allocate-sheep (&optional (class 'standard-sheep))
     (make-instance class))
   
  -(defgeneric sheep-p (obj))
  -(defmethod sheep-p (obj)
  -  (declare (ignore obj))
  -  nil)
  -(defmethod sheep-p ((obj standard-sheep))
  -  (declare (ignore obj))
  -  t)
  +(defgeneric sheep-p (obj)
  +  (:method (obj) (declare (ignore obj)) nil)
  +  (:method ((obj standard-sheep)) (declare (ignore obj)) t))
   
   ;;;
   ;;; Cloning
   ;;;
  +(defgeneric copy-sheep (model)
  +  ;; todo
  +  (:documentation "Makes a direct copy of MODEL."))
  +
  +(defgeneric finalize-sheep (sheep)
  +  (:documentation "Performs any needed finalization on SHEEP."))
  +
   (defun spawn-sheep (sheep-or-sheeple &rest all-keys
                       &key (metaclass 'standard-sheep)
                       &allow-other-keys)
  
positive.code:                              (sheep-parents child)))
                 (finalize-sheep child)
                 (error 'sheep-hierarchy-error
                           :format-control "A circular precedence graph was generated for ~A"
                           :format-args (list child)))))
           child)))
  
  (defun add-parents (parents sheep)
    (loop for parent in (reverse parents) do (add-parent parent sheep))
    sheep)
  
  (defgeneric remove-parent (parent sheep))
  (defmethod remove-parent (unsheepish-parent (child standard-sheep))
    (remove-parent (sheepify unsheepish-parent) child))
  (defmethod remove-parent ((parent standard-sheep) (child standard-sheep))
    (if (member parent (sheep-parents child))
        (progn
          (setf (sheep-parents child)
                (delete parent (sheep-parents child)))
          (remhash child (%direct-children parent))
          (finalize-sheep child)
          child)
        (error "~A is not a parent of ~A" parent child)))
  
  ;;; Inheritance predicates
  (defun parent-p (maybe-parent child)
    (when (member maybe-parent (sheep-parents child))
      t))
  
  (defun ancestor-p (maybe-ancestor descendant)
    (when (and (not (eql maybe-ancestor descendant))
               (member maybe-ancestor (collect-parents descendant)))
      t))
  
  (defun child-p (maybe-child parent)
    (parent-p parent maybe-child))
  
  (defun descendant-p (maybe-descendant ancestor)
    (ancestor-p ancestor maybe-descendant))
  
  ;;;
  ;;; Hierarchy Resolution
  ;;;
  ;;; Most of this is taken almost verbatim from closette
  (defun collect-parents (sheep)
    (labels ((all-parents-loop (seen parents)
                (let ((to-be-processed
  
negative.code:          (handler-case
               (progn
                 (push new-parent (sheep-parents child))
                 (setf (gethash child (%children new-parent)) t)
                 (finalize-sheep child)
                 child)
             ;; This error is signaled by compute-sheep-hierarchy-list, which right now
             ;; is called from inside finalize-sheep (this is probably a bad idea, move
             ;; c-s-h-l in here just to do the check?)
             (sheep-hierarchy-error ()
               (progn
                 (setf (sheep-parents child)
  