anchor.diff:  ;;;          (sees ...)
   ;;;           anything that depends on only these or lower
   ;;;
  +;;; Within each layer the ordering is arbitrary, EXCEPT that if a rule X that
  +;;; relies on the negation of a rule Y, then Y must come before X.
   
   
  -;;;; Ordering -----------------------------------------------------------------
  +;;;; Utils --------------------------------------------------------------------
   (defun-match bare-term (term)
     (`(not ,x) x)
     (x x))
  
positive.code: (in-readtable :fare-quasiquote)
  
  
  ;;;; Overview
  ;;; We start with a set of grounded rules like: ((next bar) x y (true foo)).
  ;;;
  ;;; We need to turn map each term to a unique integer, making sure that they end
  
negative.code:   (_ nil))
  
  
  (defun-match normalize-term (term)
    (`(not ,body) `(not ,(normalize-term body)))
    (_ (ensure-list term)))
  
  (defun normalize-rule (rule)
    (mapcar #'normalize-term (ensure-list rule)))
  
  (defun normalize-rules (rules)
    (mapcar #'normalize-rule rules))
  
  
  ;;;; Dependency Graph ---------------------------------------------------------
  (defun build-dependency-graph (rules &key negations-only)
    (let ((graph (digraph:make-digraph :test #'equal)))
      (labels
          ((mark-dependency (head-pred body-pred)
             (digraph:insert-vertex graph head-pred)
             (digraph:insert-vertex graph body-pred)
             (digraph:insert-edge graph head-pred body-pred))
           (mark-dependencies (head body)
             (iterate (for b :in body)
                      (when (or (negationp b)
                                (not negations-only))
                        (mark-dependency head b)))))
        (iterate (for rule :in rules)
                 (for (head . body) = (ensure-list rule))
                 (mark-dependencies head body)))
      graph))
  
  
  ;;;; Layer Partitioning -------------------------------------------------------
  (defun mark (layers layer term)
    (setf (gethash term layers) layer)
    (pushnew term (gethash layer layers) :test #'equal))
  
  
  (defun extract-simple (predicates layer layers terms)
    (iterate (for term :in terms)
             (if (member (car term) predicates)
               (mark layers layer term)
               (collect term))))
  
  
  (defun extract-base (layers terms)
    (extract-simple '(true) :base layers terms))
  
  (defun extract-does (layers terms)
    (extract-simple '(does) :does layers terms))
  
  
  (defun extract-possible% (layers dependencies terms)
    (labels ((find-dependencies (term)
               (mapcar (rcurry #'gethash layers)
                       (digraph:successors dependencies term)))
             (find-eligible (terms)
               (iterate (for term :in terms)
                        (for deps = (find-dependencies term))
                        (for unmet = (set-difference deps '(:base :possible)))
                        (when (null unmet)
                          (collect term)))))
      (iterate
        (with remaining = terms)
        (for next = (find-eligible remaining))
        (while next)
        (mapcar (curry #'mark layers :possible) next)
        (zapf remaining (set-difference % next :test #'equal))
        (finally (return remaining)))))
  
  (defun extract-possible (layers dependencies terms)
    (-<> terms
      (extract-simple '(legal goal terminal) :possible layers <>)
      (extract-possible% layers dependencies <>)))
  
  
  (defun extract-happens (layers terms)
    (mapcar (curry #'mark layers :happens) terms)
    nil)
  
  
  (defun partition-predicates (rules)
    (let* ((rules (normalize-rules rules))
           (dependencies (build-dependency-graph rules))
           (terms (-<> rules
                    (mapcan #'identity <>)
                    (mapcar #'bare-term <>)))
           (layers (make-hash-table :test #'equal)))
      (-<> terms
        (extract-base layers <>)
        (extract-does layers <>)
        (extract-possible layers dependencies <>)
        (extract-happens layers <>))
      layers))
  
  
  ;;;; Intra-Layer Ordering -----------------------------------------------------
  (defun build-layer-graph (rules)
    (let ((graph (digraph:make-digraph :test #'equal
                                       :initial-vertices (mapcar #'first rules))))
  