 (defn canonical [ds]
   (let [ds (dsymbol ds)
         update (fn [m data D]
-                 (reduce (fn [m [i val]] (assoc-in m [i D] val))
+                 (reduce (fn [m [i val]]
+                           (if (= 0 val) m (assoc-in m [i D] val)))
                          m
                          (map-indexed list data)))]
     (loop [todo (invariant ds), ops {}, vs {}, n 0]

  (is (= (dsymbol "<1.1:2>")
         (DSymbol. 2 2
                   {}
                   {})))
  )


(defn- protocol [ds indices traversal]
  (let [imap (zipmap indices (range (count indices)))
        ipairs (map vector indices (rest indices))
        spins (fn [D] (for [[i j] ipairs] (or (v ds i j D) 0)))
        step (fn step [xs emap n]
               (when (seq xs)
                 (let [[[Di i D] & xs] xs]
                   (if (nil? D)
                     (recur xs emap n)
                     (let [[Ei E] (sort [(emap Di) (or (emap D) n)])
                           new? (= E n)
                           emap (if new? (assoc emap D n) emap)
                           n (if new? (inc n) n)
                           head (if (= i :root) [-1] [(imap i) Ei])
                           tail (if new? (spins D) [])]
                       (concat head [E] tail (step xs emap n)))))))]
    (step traversal {} 1)))

(defn invariant [ds]
