               (/ (s D) (v D)))))
   ([ds]
     (curvature ds 0)))
+
+;; Azulenoid-specific functions
 
 (def template
   (DSymbol. (str "1.1:60:"

           (org.gavrog.joss.dsyms.generators CombineTiles DefineBranching2d))
  (:gen-class))

(defn iterate-cycle [coll x]
  (reductions #(%2 %1) x (cycle coll)))

(defn unique [coll key-fun]
  (letfn [(step [[seen _] x]
                (let [key (key-fun x)]
                  (if (seen key)
                    [seen false]
                    [(conj seen key) x])))]
         (filter identity (map second (reductions step [#{} false] coll)))))

(defn walk [ds D & idxs]
  (reduce #(.op ds %2 %1) D idxs))

(defn chain-end [ds D i j]


(def azul-syms
  (let [raw (for [ds octa-syms o2t boundary-mappings] (on-template ds o2t))]
    (for [ds (unique #(-> %1 .minimal .invariant) raw)]
      (-> ds .dual .minimal .canonical))))

;; Main entry point when used as a script

(defn -main []
  (do
