   (SAS-Precond-HLA var dst-val (atom {})))
 
 (defn extend-precond-hla! [hla init-sets]
-  (let [{:keys [var dst-val src-map-atom] hla}]
+  (let [{:keys [var dst-val src-map-atom]} hla]
     (doseq [src-val (util/safe-get init-sets var)]
       (when-not (contains? @src-map-atom src-val)
         (swap! src-map-atom assoc src-val (get-current-vv-hla var src-val dst-val)))

;; Watch out: what happens when single action establishes multiple preconditions, e.g. .. 
;; TODO: need to treat subsets (i.e., transitive closure edges) specially.

(defn induce-action-hla- [a init-sets ]
  (util/print-debug 2 "Inducing HLA for preconds + action" (:name a))
  (let [first-bits (doall (for [[pvar pval] (:precond-map a)
                                :when (not (= (init-sets pvar) #{pval}))]
                            (induce-vv-hla pvar pval init-sets )))]
;    (println (:name a) (count first-bits))
;    (doseq [b first-bits] (println "\n" (env/action-name b) "\n\n"))
    (when (every? identity first-bits)
     (if (empty? first-bits)
         a
       (let [bit (util/safe-singleton first-bits)]
         (assert (= ((effect-sets bit) (:var bit)) #{(:val bit)}))
         (SAS-Action-HLA 
          a 
          (clojure.set/union (util/keyset (:precond-map a)) (precond-var-set bit))
          init-sets
          (merge (effect-sets bit) (util/map-vals (fn [x] #{x}) (:effect-map a)))
          [[bit a]]))))))


;; Getting/extending HLA, extracting best-effort info for these init-sets, must be separate.




;;;;;;;;;;;;;;;;;;;;;;;;;;;; Precondition Set Nodes ;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Each precond HLA is not cached, and is owned by a particular action.
;; It just aggregates sets of src vv-hla nodes, more or less.
;; src-map-atom maps from src vals to sas-vv-hla instances.  Init-sets describes current init-sets.

(deftype SAS-Precond-Set-HLA [hard-preconds soft-precond?] :as this
  SAS-Induced-Action
    (precond-var-set [] (if soft-precond? (precond-var-set soft-precond?) #{}))
    (effect-sets     [] (if soft-precond? (effect-sets     soft-precond?)  {}))
  env/Action
    (action-name [] (throw (UnsupportedOperationException.)))
    (primitive?  [] false)
  env/ContextualAction 
    (precondition-context [s] (precond-var-set this))
  hierarchy/HighLevelAction
    (immediate-refinements- [s] (assert (env/state-matches-map? s hard-preconds)) (if soft-precond? [soft-precond?] []))
    (cycle-level-           [s] nil))

(defn make-precond-set-hla [hard-preconds soft-precond?] 
  (SAS-Precond-Set-HLA hard-preconds soft-precond?))

(defn extend-precond-set-hla! [hla init-sets]
  (assert (every? (fn [[k v]] (contains? (get init-sets k) v)) (:hard-preconds hla)))
  (when-let [p (:soft-precond? hla)] (extend-precond-hla! p init-sets)))




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Action Nodes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; An action.  
;; TODO: think about splitting this based on which var it's being used for.
;; TODO: make fancier.
;; TODO: how do we go in parallel? Need to simulate parallel execution, look at pairs of choice points, ETC ? 
;; For now, assume at most one unsatisfied precond.

(defn action-hla-name [action] [:!A (env/action-name action)])

(deftype SAS-Action-HLA [action precond-set-hla init-sets-atom precond-vars-atom effect-sets-atom]
  SAS-Induced-Action
    (precond-var-set [] @precond-vars-atom)
    (effect-sets     [] @effect-sets-atom)
  env/Action
    (action-name     [] (action-hla-name action))
    (primitive?      [] false)
  env/ContextualAction 
    (precondition-context [s] @precond-vars-atom)
  hierarchy/HighLevelAction
    (immediate-refinements- [s] [precond-set-hla action])
    (cycle-level-           [s] nil))


(defn get-current-action-hla [action var]
  (let [preconds     (:precond-map action)
        rem-preconds (dissoc preconds var)]
    (assert (<= (count rem-preconds) 1))
    (util/cache-with *hla-cache* (action-hla-name action)
      (SAS-Action-HLA action
        (make-precond-set-hla (select-keys preconds [var]) (make-precond-hla (key (first rem-preconds)) (val (first rem-preconds))))
        (atom {}) (atom (util/keyset preconds)) (atom {})))))

(defn extend-action-hla! [hla init-sets]
  (let [{:keys [action precond-set-hla init-sets-atom precond-vars-atom effect-sets-atom]} hla
        new-inits? (not= (select-keys @init-sets-atom @precond-vars-atom)
                         (select-keys (swap! @init-sets-atom #(merge-with clojure.set/union % init-sets)) @precond-vars-atom))]
    (when new-inits?
      (extend-precond-set-hla! precond-set-hla init-sets)
      (reset! precond-vars-atom (clojure.set/union (precond-var-set precond-set-hla) (util/keyset (:precond-map action))))
      (reset! effect-sets-atom  (sequence-effect-set-maps (effect-sets precond-set-hla)
                                                          (util/map-vals (fn [x] #{x}) (:effect-map action)))))))



