 
 (defrecord Plan     [input-constraint input-set plan-nodes output-set summary])
 
+(defn plan-str [p]
+  (clojure.string/join ", " (map plan-node-str (:plan-nodes p))))
+(defmethod print-method Plan [p o] (print-method (plan-str p) o))
+
 (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,

  "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

    (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)]
        (assert-valid-summary-change (:output-summary pn) new-output-summary)
        (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)]
        (assert-valid-summary-change (:output-summary pn) (second new-output-pair))
        (when (viable-output-set-and-summary? new-output-pair)
          [(cons (not (= (:output-set new-pn) output-set)) new-output-pair) new-pn])))))

