   (:require
     #_[om.core :as om :include-macros true]
     [clojure.set :refer [union]]
+    [clojure.walk :as walk]
     [sablono.core :as sab :include-macros true])
   (:require-macros
     [devcards.core :as dc :refer [defcard deftest]]))

    (vector? k) (get-var-and-flow has (get-in has [:objects (first k)]) (second k))
    :else (assert (or (nil? k) (keyword? k) (vector? k)) "Unrecognized variable lookup type")))

(defn simple-interval [has ha simple-guard]
  (let [rel (first simple-guard)
        c (last simple-guard)
        v1k (second simple-guard)
        v2k (if (= (count simple-guard) 4) (third simple-guard) nil)
        [v10 v1f] (get-var-and-flow has ha v1k)

(defonce scene-a (atom {}))
(defonce last-time nil)

(defn goomba [id x y speed state others]
  (make-ha id                                               ;id
           {:x     x :y y                                   ;init
            :w     16 :h 16
            :state state}
           (make-state
             :right                                         ;name
             {:x speed}                                     ;flows
             ;edges
             ; x < 16 && x + dx*frame >= 16 --> x >= 16 - dx*frame
             (make-edge :left [[:lt :x 64] [:geq :x '(- 64 [:d :x])]] #{:required})
             ; x + 16 < x2 + dx2*frame && x + dx*frame + 16 >= x2 + dx2*frame
             ; x - x2 < -16 + dx2*frame && x - x2 >= dx2*frame - dx*frame - 16
             (map #(make-edge :left [[:lt :x [% :x] (list '+ -16 [:d % :x])]
                                     [:geq :x [% :x] (list '- [:d % :x] [:d :x] 16)]]
                              #{:required}) others))
           (make-state
             :left                                          ;name
             {:x (- speed)}                                 ;flows
             ;edges
             ; x > 8 && x + dx*frame <= 8 --> x <= 8 - dx*frame
             (make-edge :right [[:gt :x 8] [:leq :x '(- 8 [:d :x])]] #{:required})
             ; x > x2 + 16 + dx2 && x + dx*frame <= x2 + dx2*frame + 16 --> x - x2 > 16 + dx2 && x - x2 <= dx2*frame + 16 - dx*frame
             ; x - x2 > 16 + dx2
             (map #(make-edge :right [[:gt :x [% :x] (list '+ 16 [:d % :x])]
                                      [:leq :x [% :x] (list '+ [:d % :x] 16 (list '- [:d :x]))]]
                              #{:required}) others))))

(defn make-scene-a [x] (let [objects [(goomba :a x 8 8 :right #{:b}) (goomba :b (* x 4) 8 8 :left #{:a})]
                             obj-ids (map :id objects)
                             obj-dict (zipmap obj-ids objects)
                             ; got to let every HA enter its current (initial) state to set up state invariants like
