 (defn make-incremental-dijkstra-search [initial-nodes]
   (let [q (make-queue initial-nodes)]
     (reify IncrementalSearch
-      (next-partial-solution [min-reward]
-        (incremental-dijkstra q min-reward expand-node extract-goal-state)))))
+           (next-partial-solution [min-reward]
+             (incremental-dijkstra q min-reward expand-node extract-goal-state)))))
+
 
 
 ;; TODO: need "generalized-goal" dijkstra search.  
+;; TODO: single-goal.
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Exhaustive Search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 

  (hashCode [] (hash name))
  SearchNode
  (extract-goal-state []  nil)
  (expand-node        [min-reward] (expand-fn min-reward)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Recursive Node ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(declare make-sp-recursive-node)

(defn make-initial-sp-nodes [state action]
  (make-descendents state action 
    (fn [ss sr] [(GoalNode ss) sr]) 
    (fn [ref] (make-sp-recursive-node [state 0] ref))))    

(defn make-sp-recursive-node [[state reward] remaining-actions]
  [(if-let [[f & r] (seq remaining-actions)]
     (let [context (env/precondition-context f state)
           sp      (delay 
                    (make-search-in-context 
                     (get-cached-search [(env/extract-context state context) (env/action-name f)] 
                       (make-incremental-dijkstra-search
                        (make-initial-sp-nodes (env/get-logger state context) f)))
                     state reward))]
       (NamedNode [state (map env/action-name remaining-actions)] 
          (fn sp-recursive-expand [min-reward]
            (let [{:keys [result-pairs max-reward]} (next-partial-solution (force sp) min-reward)]
              (PartialResult (map #(make-sp-recursive-node % r) result-pairs) max-reward)))))   
     (GoalNode state))
   reward])


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Transparent Node ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn make-sp-transparent-node [[state reward] remaining-actions]
  [(if-let [[f & r] (seq remaining-actions)]
       (NamedNode [state (map env/action-name remaining-actions)]
         (fn sp-transparent-expand [min-reward]
           (PartialResult
            (make-descendents state f 
              (fn [ss sr] (make-sp-transparent-node [ss (+ sr reward)] r))
              (fn [ref]   (make-sp-transparent-node [state reward] (concat ref r))))
            Double/NEGATIVE_INFINITY)))
     (GoalNode state))
   reward])


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Semi-Transparent Node ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  (expand-node        [se new-threshold]
    "Returns PartialResult of SearchNodes."))



(deftype GoalNode [goal-state]
  SearchNode
  (extract-goal-state []           goal-state)
  (expand-node        [min-reward] (throw (UnsupportedOperationException.))))

;; Named node is simple non-terminal node whose equality semantics are given by name.
(deftype NamedNode [name expand-fn] :as this
