 ;; 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 status caching!
+;; TODO: put back summary caching!
 
 ; Dependencies on plans
 (declare make-initial-plan expand-plan)

  "Returns a plan by propagating changes starting at the last node in prefix through remaining-nodes.
   Returns nil if the plan becomes infeasible, otherwise a plan."
  [input-constraint input-set prefix-nodes remaining-nodes set-changed?]
  (when-let [[[_ out-set out-summary] out-nodes]
             (map-state
              update-pn-input
              (cons set-changed? (plan-node-output-set-and-summary (last prefix-nodes))))]
    (Plan. input-constraint input-set (concat prefix-nodes out-nodes) out-set out-summary)))

;; Need some meta-level basis to choose what to do...
;; For now, just pick a node at random, try to refine it, then try to split on its output.
(defn expand-plan [plan min-reward]
  (let [{:keys [input-constraint input-set plan-nodes output-set summary]} plan
        [pre-nodes [ref-node & post-nodes]] (split-at (rand-int (count plan-nodes)) plan-nodes)
        [pre-set pre-summary]  (if (seq pre-nodes) (plan-node-output-set-and-summary (last pre-nodes)) [input-set zero-summary])
        sub-min-reward (- min-reward
                          (- (max-reward summary)
                             (- (max-reward (:out-summary ref-node)) (max-reward pre-summary))))]
    (filter identity
            (for [next-pn (split-pn-output (refine-pn ref-node pre-summary sub-min-reward) pre-set pre-summary sub-min-reward)]
              (propagate-plan-changes input-constraint input-set (concat pre-nodes [next-pn]) post-nodes)))))


