   (reduce #(when %1 (.op ds %2 %1)) D idxs))
 
 (defn chain-end [ds D i j]
+  "Returns the result of alternately applying operators indexed i and j,
+   starting with the element D, until the end of the chain is reached.
+   In case of a cycle, nil is returned."
   (loop [E (walk ds D i)]
     (let [E* (walk ds E j)]
       (cond

        (= D E*) nil
        :else (recur (walk ds E j i))))))

(defn boundary-chambers [ds D i j k]
  (iterate-cycle [#(walk ds %1 i) #(chain-end ds %1 j k)] D))

(defn traversal [ds indices seeds]
  (let [stacks (map #(vector % ()) (take 2 indices))
        queues (map #(vector % empty-queue) (drop 2 indices))
        as-root #(vector % :root)


(defn orbit-reps
  ([ds indices seeds]
    (for [[D i] (pretty-traversal ds indices seeds) :when (= :root i)] D))
  ([ds indices]
    (orbit-reps ds indices (iterator-seq (.elements ds)))))

(defn orbit-loopless? [ds indices D]
  (empty? (for [[D i] (pretty-traversal ds indices [D])
                :when (and (not= i :root) (or (nil? D) (= D (walk ds D i))))]
            D)))

