 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Subproblem Impl  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (defn set-stub-output! [stub sp]
+  (assert (empty? (get-outputs stub)))
   (summaries/summary-changed-local! stub)
   (add-output! stub sp))
 
-;; Would be nice to assert consistency, but hard to get before-summary...
-;; This version keeps children with same input inside.
-;; Actually makes things worse sometimes (more evaluations?!) -- with first, better with last.
-;; TODO: this solution does not work with decomposition -- infinite loops
-;; TODO: the check commented out below works, but adds 50% overhead.
-;; TODO: also, it doesn't seem to work... -- see dm 2-3
-;;  (Since we don't keep only first solution)
 (defn add-sp-child! [sp child-sp]
   (assert (not (terminal? sp)))
   (summaries/summary-changed-local! sp)
   (add-output! sp child-sp))
 
 
-;; Note: All nonterminal subproblems use or-summary for ri-fn
-(defn make-simple-subproblem
-  [stub subsuming-sp out-set terminal? summary-fn ri-fn init-bound]
-  (let [ts-atom (atom nil)
-        ret (traits/reify-traits [simple-cached-node simple-watched]
-             summaries/Summarizable (summarize       [s] (summary-fn s (top-down-bound @ts-atom)))
-             Subproblem             (stub            [s] stub)
-                                    (output-set      [s] out-set)
-                                    (tree-summarizer [s] @ts-atom)
-                                    (terminal?       [s] terminal?)
-                                    (refine-input    [s ni] ;; Note ni may have different context.
-                                      (if (= ni (input-set stub)) stub (ri-fn s ni))))]
-    (reset! ts-atom (make-tree-summarizer ret init-bound))
-    (when subsuming-sp (summaries/connect! @ts-atom (tree-summarizer subsuming-sp) true))
-    ret))
-
-;; TODO: better grouping -- allow adding etc?
-;; I lie about my stub ...
+(traits/deftrait simple-subproblem
+  [stb out-set ts term? ri-fn] []
+  [simple-cached-node simple-watched]
+  Subproblem (stub            [s] stb)
+             (output-set      [s] out-set)
+             (tree-summarizer [s] ts)
+             (terminal?       [s] term?)
+             (refine-input    [s ni] (ri-fn s ni)))
+
+
+(defn make-simple-subproblem [stub subsuming-sp out-set terminal? summary-fn ri-fn init-bound]
+  (let [ts  (make-tree-summarizer init-bound)
+        ret (traits/reify-traits [(simple-subproblem stub out-set ts terminal? ;; Note ni may have different context.
+                                                     (fn [s ni] (if (= ni (input-set stub)) stub (ri-fn s ni))))]
+              summaries/Summarizable (summarize       [s] (summary-fn s (top-down-bound ts))))]
+    (init-tree-summarizer! ts ret subsuming-sp)
+    ret))
+
+;; TODO: collect children too ?
 
 (declare make-output-collecting-subproblem)
 (defn make-output-collecting-stub [inner-stub]
   (assert (not (= (first (stub-name inner-stub)) :OS)))
   (assert (not (= (first (stub-name inner-stub)) :SA)))  
   (let [in-set (input-set inner-stub)
-        ret (traits/reify-traits
-             [simple-cached-node simple-watched or-summarizable
-              (simple-stub [:OS (stub-name inner-stub) in-set] in-set)])]
+        ret (traits/reify-traits [or-summarizable (simple-stub [:OS (stub-name inner-stub) in-set] in-set)])]
     (connect-and-watch! ret inner-stub #(set-stub-output! ret (make-output-collecting-subproblem ret %)))
     ret))
 

    ret))

(defn- make-pair-stub1 [subsuming-sp left-stub right-name right-stub-fn]
  (let [ret (traits/reify-traits [simple-cached-node simple-watched or-summarizable
                                  (simple-stub [:Pair1 (stub-name left-stub) right-name]
                                               (input-set left-stub))])]
    (connect-subsuming! ret subsuming-sp)

(defn- make-atomic-stub [name subsuming-sp inp-set function-set]
  (let [state (atom :ready) ;; set to [out-set reward] after first eval, then :go after second.
        ret
        (traits/reify-traits [(simple-stub name inp-set)]
         summaries/Summarizable
         (summarize [s]
           (cond (= :ready @state) (summary/make-live-simple-summary (subsuming-bound s) s)
