   (when-let [[[_ out-set out-summary] out-nodes]
              (map-state
               update-pn-input
-              (cons set-changed? (plan-node-output-set-and-summary (last prefix-nodes))))]
+              (cons set-changed? (plan-node-output-set-and-summary (last prefix-nodes)))
+              remaining-nodes)]
     (Plan. input-constraint input-set (concat prefix-nodes out-nodes) out-set out-summary)))
 
 ;; Need some meta-level basis to choose what to do...
 ;; For now, just pick a node at random, try to refine it, then try to split on its output.
 (defn expand-plan [plan min-reward]
-  (let [{:keys [input-constraint input-set plan-nodes output-set summary]} plan
-        [pre-nodes [ref-node & post-nodes]] (split-at (rand-int (count plan-nodes)) plan-nodes)
-        [pre-set pre-summary]  (if (seq pre-nodes) (plan-node-output-set-and-summary (last pre-nodes)) [input-set zero-summary])
-        sub-min-reward (- min-reward
-                          (- (max-reward summary)
-                             (- (max-reward (:out-summary ref-node)) (max-reward pre-summary))))]
-    (filter identity
-            (for [next-pn (split-pn-output (refine-pn ref-node pre-summary sub-min-reward) pre-set pre-summary sub-min-reward)]
-              (propagate-plan-changes input-constraint input-set (concat pre-nodes [next-pn]) post-nodes)))))
+  (if (not (refinable-summary? (:summary plan) min-reward)) [plan]
+      (let [{:keys [input-constraint input-set plan-nodes output-set summary]} plan
+            [pre-nodes [ref-node & post-nodes]] (split-at (rand-int (count plan-nodes)) plan-nodes)
+;            _ (println summary (count pre-nodes) (class ref-node) (count post-nodes))       
+            [pre-set pre-summary]  (if (seq pre-nodes) (plan-node-output-set-and-summary (last pre-nodes)) [input-set zero-summary])
+            sub-min-reward (- min-reward
+                              (- (max-reward summary)
+                                 (- (max-reward (:output-summary ref-node)) (max-reward pre-summary))))]
+        (filter identity
+                (for [next-pn (split-pn-output (refine-pn ref-node pre-summary sub-min-reward) pre-set pre-summary sub-min-reward)]
+                  (propagate-plan-changes input-constraint input-set (concat pre-nodes [next-pn]) post-nodes
+                                          (not= (:output-set next-pn) (:output-set ref-node))))))))
+
 
 
 

        init (env-util/initial-logging-state e)
        tla  (hierarchy-util/make-top-level-action e [(hierarchy/initial-plan henv)])]
    (binding [*subproblem-cache*    (HashMap.)]
      (let [root (get-subproblem-root-pointer (state-set/make-logging-factored-state-set [init]) tla (constantly is/pos-inf))]
        (refine-osp! root is/neg-inf nil)
        (let [sum (osp-summary root nil)]
          (println sum)
          (assert (not (refinable-summary? sum is/neg-inf)))
          (when-let [sol (optimal-solution sum)]

       (viable-summary? summary)))


;;;;;;;;;;;;;;;;;;;;;;;;;;;; Refining Plan Nodes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn refine-pn [pn input-summary min-reward]
  (let [{:keys [sub-osn excluded-child-set reward-bound]} pn]
    (refine-osn! sub-osn min-reward excluded-child-set)
    (assoc pn :output-summary
           (compute-plan-node-output-summary input-summary sub-osn excluded-child-set reward-bound))))


;;;;;;;;;;;;;;;;;;;;;;;;;;; Splitting Plan Nodes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn split-pn-output
  "Split this plan node into a seq of plan nodes, all but 0-1 of which will have
   refined output sets."
  [pn input-set input-summary min-step-reward]
  (let [{:keys [sub-osn excluded-child-set]} pn]
    (let [split-children (split-osn sub-osn min-step-reward excluded-child-set)
          new-ecs        (into excluded-child-set split-children)
          new-summary    (broom-summary sub-osn new-ecs)]
      (concat
       (when (viable-summary? new-summary)
         [(assoc pn :excluded-child-set new-ecs :output-summary new-summary)])
       (for [child split-children]
         (make-plan-node input-set input-summary child nil {} is/pos-inf))))))


(defn update-pn-input
  "Take a tuple describing updated inputs and a plan node, and return a tuple
   describing updated outputs and the updated plan node.  Returns nil for dead-ends."
  [[set-changed? new-input-set new-input-summary] pn]
  (let [{:keys [sub-osn excluded-child-set output-constraint reward-bound output-set]} pn
        new-osn (if set-changed? (refine-osn-input sub-osn new-input-set) sub-osn)]
    (if (identical? new-osn sub-osn)
      (let [new-output-summary (compute-plan-node-output-summary
                                new-input-summary sub-osn excluded-child-set reward-bound)]
        (when (viable-summary? new-output-summary)
          [[false output-set new-output-summary] (assoc pn :output-summary new-output-summary)]))
      (let [new-pn (make-plan-node new-input-set new-input-summary new-osn nil
                                   (osn-output-set sub-osn)
                                   (max-reward (broom-summary sub-osn)))
            new-output-pair (plan-node-output-set-and-summary new-pn)]
        (when (viable-output-set-and-summary? new-output-pair)
          [(cons (not (= (:output-set new-pn) output-set)) new-output-pair) new-pn])))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Plans ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Plan is effectively a sequence of plan nodes.

(defrecord Plan     [input-constraint input-set plan-nodes output-set summary])

(def plan-summary :summary)
(def plan-output-set :output-set)

(defn map-state
  "Transform a sequence via a state-machine.  transition-fn takes a state and input item,
