 
 
 
+(defn evaluate-path-cost [path]
+  (transduce
+   (map :cost)
+   +
+   0.0
+   path))
+
 (defn- shortest-path [dst b]
   (if (empty? dst)
     [b]
-    (let [dst-n (count (first dst))
-          b-n (count b)]
+    (let [dst-cost (evaluate-path-cost (first dst))
+          b-cost (evaluate-path-cost b)]
       (cond
-        (= dst-n b-n) (conj dst b)
-        (< dst-n b-n) dst
+        (= dst-cost b-cost) (conj dst b)
+        (< dst-cost b-cost) dst
         :default [b]))))
 
 
 (defn- promotion-path-sub [visited arg-spec x]
   (cond
     (contains? visited arg-spec) nil
-    (matches-arg-spec? arg-spec x) (transient [])
+    (matches-arg-spec? arg-spec x) []
     :default
     (do
       (let [visited (conj visited arg-spec)


(spec/def ::promoter fn?)

(spec/def ::promotions (spec/map-of ::key ::promoter))

(spec/def ::arg-spec (spec/keys :req-un [::pred
                                         ::pos

                              (filter identity)
                              cat
                              (map (fn [kv]
                                     (let [[k v] kv
                                           v (assoc v :key k)]
                                       (when-let
                                           [p (promotion-path-sub
                                               visited k x)]
                                         (conj p v)))))
                              (filter identity))
                        (completing shortest-path)
                        nil
