         :blocked 1
         :solved  2))
 
-(defrecord Status [max-reward status])
+
+(defrecord SimpleSummary [max-rew status opt-sol]
+  Summary
+  (max-reward       [s] max-rew)
+  (live?            [s] (= status :live))
+  (optimal-solution [s] (when (= status :solved) (assert opt-sol) opt-sol)))
+
+(defn make-live-summary [max-reward] (SimpleSummary. max-reward :live nil))
+(defn make-blocked-summary [max-reward] (SimpleSummary. max-reward :blocked nil))
+(defn make-solved-summary [max-reward opt-sol] (SimpleSummary. max-reward :solved opt-sol))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Common Ops ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
-(def +worst-status+ (Status. is/neg-inf :live))
-(def +best-status+  (Status. is/pos-inf :solved))
-
-(defn better-status? [s1 s2]
+(def +worst-summary+ (make-live-summary is/neg-inf))
+(def +best-summary+  (make-solved-summary is/pos-inf []))
+
+(defn better-summary? [s1 s2]
   (or (> (:max-reward s1)
          (:max-reward s2))
       (and (= (:max-reward s1)

;; TODO: think about loops.  In particular, loop safety.
;; TODO: think about final split.  It is probably *not* always optimal, depending on which ops you count.

(def #^HashMap *subproblem-cache* nil)

;; output-set-cache currently not used. 
(defrecord Subproblem [input-set input-context action ^HashMap output-set-cache])

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Output Set Trees ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; OSP trees contain pointers, which are permenant things representing a SAS combo,
;; and nodes, which contain the current state of the search (including links to child pointers).

;; TODO: put back summary caching!

; Dependencies on plans
(declare make-initial-plan expand-plan)
