 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Generic Trait  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;; Canonical SPs are Atomic and Pair; wrappers use TS of inner SP.
-(defn canonicalize [sp] (ts-sp (sp-ts sp)))
-(defn canonical? [sp] (identical? sp (ts-sp (sp-ts sp))))
-
-(traits/deftrait simple-subproblem
-  [nm inp-set wrapped-ts eval!-fn ri-fn]
-  [                 ts-atom          (atom wrapped-ts)
-   ^PubSubHub       output-ps        (make-pubsubhub)
-   ^PubSubHub       child-ps         (make-pubsubhub)
-   ^PubSubHub       all-child-ps     (make-pubsubhub) ;; For sub-following -- remove if no help.
-   ^IdentityHashMap subsuming-sp-set (IdentityHashMap.)]
-  [summaries/simple-cached-node]
-  Subproblem
+(defn- canonicalize [sp] (ts-sp (sp-ts sp)))
+(defn- canonical? [sp] (identical? sp (ts-sp (sp-ts sp))))
+
+(defn- make-subproblem [nm inp-set wrapped-ts eval!-fn ri-fn summary-fn]
+ (let [                 ts-atom          (atom wrapped-ts)
+       ^PubSubHub       output-ps        (make-pubsubhub)
+       ^PubSubHub       child-ps         (make-pubsubhub)
+       ^PubSubHub       all-child-ps     (make-pubsubhub) ;; For sub-following -- remove if no help.
+       ^IdentityHashMap subsuming-sp-set (IdentityHashMap.)]
+  (traits/reify-traits [summaries/simple-cached-node]
+   summaries/Summarizable (summarize [s] (summary-fn s))
+   Subproblem
   (sp-name             [s] nm)
   (input-set           [s] inp-set)
   (sp-ts               [s] (or @ts-atom (reset! ts-atom (make-tree-summarizer s))))

      (schedule-increase! (sp-ts s)))    
    (publish! child-ps c))

  (add-all-child-watcher! [s w] (subscribe! all-child-ps w))

    
  (subsuming-sps [s] (keys subsuming-sp-set))
  (add-subsuming-sp! [s subsuming-sp]
    (util/assert-is (canonical? s))
    (util/assert-is (canonical? subsuming-sp))                     
    (util/assert-is (= nm (sp-name subsuming-sp)))
    (util/assert-is (not (identical? s subsuming-sp)))
    (when-not (.containsKey subsuming-sp-set subsuming-sp)
      (.put subsuming-sp-set subsuming-sp true)
      (schedule-subsumption! (sp-ts subsuming-sp) (sp-ts s))
      (when *propagate-subsumption*

              (add-all-child-watcher! subsuming-sp
                (fn [subsuming-child]
                  (let [can-subsuming-child (canonicalize subsuming-child)]
                    (when (= (sp-name can-child) (sp-name can-subsuming-child))
                      (when (add-subsuming-sp! can-child can-subsuming-child)
                        #_ (println [s subsuming-sp] "==>" [child subsuming-child])
                        )))))))))
      true))
  
  (refine-input    [s ni]
    (let [ret (ri-fn s ni)]
      (util/assert-is (= nm (sp-name ret)))
      (when (canonical? s) (add-subsuming-sp! ret s))
      ret)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Utils  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
