                   (seq (get sources-by-type :greedy))
                   (greedy-fire-actions s (first sources) possible-actions-fn)
 
-                  (seq (get sources-by-type :bottom-up))
-                  (let [[p-var children] (apply max-key (comp tsi first) (identity #_ canonicalize sources))] 
+                  (seq (canonicalize s (get sources-by-type :bottom-up)))
+                  (let [[p-var children] (apply max-key (comp tsi first) sources)] 
                     (bottom-up-expand-actions s p-var children child-var-map prevail-cvm auxiliary-map possible-actions-fn)) 
                
-                  :else (do (util/assert-is (empty? sources-by-type) "%s" [(do (print-state s) (clojure.inspector/inspect-tree (state/as-map s))
-                                                                               s)])
+                  :else (do (util/assert-is (empty? (:other sources-by-type))
+                                            "%s" [(do (print-state s) (inspect-state s)
+                                                      s)])
                             (util/print-debug 1 "Pruning since nothing to do?!"))))
                
                (util/print-debug 1 "Pruning due to deadlock")))))

;;;;;;;;;;;;;;;;;;;;; Misc TODOs 
;; TODO: add clusters -- leave out for now.
;; TODO: add top-down, leave out for now.
;; TODO: we can generate cyclic plans -- figure out how to avoid this.
;; TODO: heuristic costs for commitments.  At minimum, heuristic is sum of min costs of action intentions.
;; TODO: identify superflous resources -- i.e., over-capacity trucks.
;; TODO: state abstraction / teleportation / generalized goal.


;;;;;;;;;;;;;;;;;;;;; Partition ordering

  [(asplan-solution-name sol) rew])


;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Fancier search ;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Just hte cost of committed actions
(defn committed-actions-heuristic [s]
  (reduce +
          (for [[var val] (state/as-map s)
                :when (and (= (first var) :actions)
                           (not (= :wait val))
                           (not (empty? val)))]
            (apply min (map :reward val)))))

;; Committed actions + shortest paths to target values.
(defn domain-paths-heuristic [s]
  0)

;; Committed actions + shortest paths + matching for preconds.
(defn all-committments-heuristic [s]
  0)

(defn canonicalize-state [s]
  (into {} (for [[var val] (state/as-map s)
                 :when (not (#{:actions :child} (first var)))]
             [var val])))

;; Keeps a separate closed list for canonical state pruning.
(defn asplan-search
  ([env] (asplan-search env (constantly 0)))
  ([env heuristic]
     (let [q       (queues/make-graph-search-pq)
           actions (env/actions-fn env) 
           goal    (env/goal-fn env)
           init    (env/initial-state env)
           closed  (HashMap.)]
        (queues/pq-add! q init (heuristic init))
        (loop []
          (when-not (queues/pq-empty? q)
            (let [[s c] (queues/pq-remove-min-with-cost! q)
                  s-r     (or (:reward (meta s)) 0)
                  canon-s (canonicalize-state s)
                  canon-r (get closed canon-s Double/NEGATIVE_INFINITY)]
              (util/print-debug 3 "dequeueing " (:act-seq (meta s)) c s "\n")
              (or (and (goal s) [(asplan-solution-name (reverse (:act-seq (meta s))))
                                 (:reward (meta s)) #_ (println s)])
                  (if (< s-r canon-r)
                    (recur)
                    (do
                      (when (> s-r canon-r) (.put closed canon-s s-r))
                      (let [acts (actions s)]
                        (util/print-debug 4 "Actions are:" (map env/action-name acts) "\n")
                        (util/print-debug 4 (for [a acts :when (not (env/applicable? a s))] (str (:name a) (:precond-map a) "not applicable" )))
                        (doseq [a acts :when (env/applicable? a s)]
                          (let [[ss sc] (env/successor a s)
                                f-val (+ (:reward (meta ss)) (heuristic ss))]
                            (when (> f-val Double/NEGATIVE_INFINITY)
                              #_(util/print-debug 1 "warning: pruning " ss)
                              (queues/pq-add! q ss (- 0 f-val ))))))
                      (recur))))))))))


;; (do (use 'angelic.env 'angelic.hierarchy 'angelic.search.textbook 'angelic.domains.taxi-infinite 'angelic.domains.sas-problems 'angelic.sas 'angelic.sas.analysis 'angelic.util 'angelic.sas.hm-heuristic 'angelic.search.interactive) (require '[angelic.search.action-set.gasplan2 :as gap2] '[angelic.search.action-set.asplan-r :as rap]))
