     (for [[s t] (util/safe-get simple-dtgs var)
           :when (and (= s cur-val) (not (contains? (backward-sets t) s)))]
       t)))
+
+(defn reachability-map [dtg from-val]
+  (let [q (queues/make-graph-search-pq)]
+    (queues/pq-add! q from-val 0)
+    (while (not (queues/pq-empty? q))
+      (let [[v c] (queues/pq-remove-min-with-cost! q)]
+        (doseq [[nv actions] (util/safe-get dtg v)]
+          (queues/pq-add! q nv (- c (apply max (map :reward actions)))))))
+
+    (assert (:map q))
+    (into {} (:map q))))
+
+
+(defn teleport-to-val [^HashMap cache dtgs var-name from-val to-val]
+  (when-let [cost  (get (util/cache-with cache [var-name from-val]
+                          (reachability-map (dtgs var-name) from-val))       
+                        to-val)]
+    (env-util/make-factored-primitive
+     [::Teleport var-name from-val to-val]
+     {var-name from-val}
+     {var-name to-val, (action-var #{var-name}) :frozen}
+     (- cost))))
+
+
 
 
 

;; (TODO).  if leaves are clustered, need multiple goal states -- see if
;; worth supporthing this case or not.  

;; TODO: cluster successor generators?
;; TODO: state abstraction.

;; meta-vars are defined on clusters.

(ns angelic.search.action-set.asplan-c
  (:require [angelic.util :as util]
            [angelic.util.graphs :as graphs]
            [angelic.util.queues :as queues]            
            [angelic.env :as env]
            [angelic.env.util :as env-util]
            [angelic.env.state :as state]            
