 (declare *state-abstraction*     ) ;; Use state abstraction?  Requires *decompose-cache*
 (declare *propagate-subsumption* ) ;; Automatically propagate subsumption links to corresponding children
 
+(defmacro cache-under [ks body]
+  `(if-let [^HashMap dc# *decompose-cache*]
+     (util/cache-with dc# ~ks ~body)
+     ~body))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;       Utilities      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;; TODO: can we factor out ri equality check?


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       Options      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn- canonical? [sp] (identical? sp (canonicalize sp)))




(defn list-children        [s] (channel/publications (:child-channel s)))

(defn subscribe-children!  [s w] (channel/subscribe! (:child-channel s) w))

(defn- connect-and-watch! [p c child-f]
  (sg/connect! p c)
  (subscribe-children! c child-f))

(defn- connect-ts! [p c]
  (sg/connect! p (sp-ts c)))

(defn publish-child! [sp child-sp]
  (when child-sp			
    (util/print-debug 2 "AC" sp child-sp)
    (util/assert-is (not (identical? sp child-sp)))
    (if (and *collect-equal-outputs*
             (fs/=-state-sets (:output-set sp) (:output-set child-sp)))
      (do (schedule-increase! sp)
          (connect-and-watch! sp child-sp (partial publish-child! sp)))
      (do (when (canonical? sp)
            (schedule-subsumption! (sp-ts sp) (sp-ts child-sp))
            (sg/connect! (sp-ts sp) (sp-ts child-sp))
            (schedule-increase! (sp-ts sp)))    
          (channel/publish! (:child-channel sp) child-sp)))))


(defn subsuming-sps        [s] (keys (:subsuming-sp-set s)))
