(defn
build-topo-sort
[get-deps]
(let
[get-deps (memoize get-deps)]
(letfn
[(topo-sort-helper*
[x depth state]
(let
[deps (get-deps x)]
(when-not (empty? deps) (topo-sort* deps depth state))))
(topo-sort*
([deps] (topo-sort* deps 0 (atom (sorted-map))))
([deps depth state]
(swap! state update-in [depth] (fnil into #{}) deps)
(doseq
[dep deps]
(when
(and dep (not (in-upper-level? @state depth dep)))
(topo-sort-helper* dep (inc depth) state)))
(when (= depth 0) (elim-dups* (reverse (vals @state))))))
(elim-dups*
[[x & xs]]
(if
(nil? x)
(list)
(cons
x
(elim-dups*
(map (fn* [p1__18484#] (difference p1__18484# x)) xs)))))]
topo-sort*)))