Given the following tree (or any other form in Clojure including maps and vectors):

'( (a b) (c d) )

I would like to generate a map in Clojure that indexes each sub-form according to a depth-first traversal of the entire form and also provides a vector (or list) of the indices of the form's children (if any).

0 -> a []
1 -> b []
2 -> (a b) [0 1]
3 -> c []
4 -> d []
5 -> (c d) [3 4]
6 -> ( (a b) (c d) ) [2 5]

I have so far only managed to use clojure.walk to produce the first part (indexing the subforms) but I am baffled as to how to generate the indices of the children as well. My code is appended at the end and produces:

user=> (depthFirstIndexing '( (a b) (c d) ))
{6 ((a b) (c d)), 5 (c d), 4 d, 3 c, 2 (a b), 1 b, 0 a}

So the indexes to the sub-forms are generated correctly according to depth-first traversal but I don't see how I can obtain the indices of the children of every sub-form. I tried to use the zippers module but I couldn't see how to perform a depth-first traversal to collect the indices.

half-way there code

(use 'clojure.walk)
(defn depthFirstIndexing [aform]
  (let [counter       (atom -1)
        idxToSubform  (atom {})
        ]
    (postwalk (fn [x]
                (def idx (swap! counter inc))
                (swap! idxToSubform assoc idx x)
                x)
    aform)
  @idxToSubform))
Edit
Report