anchor.diff:            (find-rule (current-engine) query-name))
         (values nil))))
   
  +;;; NORMALIZE-QUERY transforms a query body like this: An incoming body,
  +;;;
  +;;;  ((?x (frodo (name ?name)))
  +;;;   (?y (ring-bearer (name ?name))))
  +;;;
  +;;; will normalize to,
  +;;;
  +;;;  (("#:?_1" "#:?_2" "FRODO" "NAME") 
  +;;;   ("#:?_2" "#:?_3" "NAME" "RING-BEARER"))
  +;;;
  +;;; Note how the variable relationships are preserved.
  +
   (defun normalize-query (body)
  +  "Takes a query body (BODY), which really just has the same structure as a
  +  rule LHS, and normalizes it such that semantically equivalent bodies will
  +  hash to the same value. Each pattern within the body is considered
  +  individually and transformed like this: 1) the pattern (a list) is
  +  flattened; 2) variables are replaced with symbols composed of a
  +  monotonically increasing integer, with their semantic relationships
  +  preserved; 3) other objects are replaced with their string representations;
  +  4) the pattern is sorted. The result is a list of 'flattened' patterns
  +  suitable for use as a hash key. See this function's source file for a
  +  concrete example."
     (let ((varlist '())
           (index 0))
       (labels ((map-variable (var)
  
positive.code: ;;; Description: Macros and functions implementing LISA's initial query
  ;;; language implementation.
  
  ;;; $Id: retrieve.lisp,v 1.13 2002/04/08 20:12:46 youngde Exp $
  
  (in-package "LISA")
  
  
negative.code:       (values *query-result* ?name))))
  
  (defun define-query (name body)
    "The actual query definition function. Creates a RULE instance identified by
    the symbol NAME, with BODY as its LHS and RHS, and adds the new rule to the
    rete network."
    (let ((rule (define-rule name body)))
      (add-rule (current-engine) rule)
      (values rule)))
  
  (defmacro defquery (name &body body)
    "Defines a new query identified by the symbol NAME."
    `(define-query ,name ',body))
  
  (defmacro retrieve ((&rest varlist) &body body)
    "Issues a query against the knowledge base. First, the query body is
    normalized to produce a hash code. Next, the cache is checked to see if the
    query already exists; if it doesn't, then a new query (rule) is created,
    cached and added to the rete network. Finally, the query is run."
    (flet ((make-query-binding (var)
             `(cons ',var (instance-of-shadow-fact ,var))))
      (let ((query-name (gensym))
            (hash (gensym))
            (query (gensym)))
        `(let* ((,hash (sxhash (normalize-query ',body)))
                (,query-name (gensym))
                (,query (find-query ,hash)))
           (when (null ,query)
             (setf ,query
  