                           (map (fn [ha]
                                  [(:id ha) (:ha-type ha)])
                                (vals ha-vals))))
-          ;todo: two more things to try before linearizing:
-          ; 1. verbose output to see if something dumb is happening in tactics
-          ; 2. symbolic domain to symx only one time step at a time, removing a lot of nonlinearity at the cost of some precision. shortest path to each symbolic domain refinement can be saved and used as the witness.
-          ;    2a. doing 2. will help with doing backwards symx as well, right?
-          ; 3. lazy linearization using flow constraints and chained ITEs
-
-          ;ha-defs (ha/spy "linearize time" (time (desugar/linearize ha-defs)))
-          ;z3 (update-ha-defs z3 ha-defs)
-
-          ;todo: translate target edges and states to (disjunction among) linearized edges and states
-
           entry-time (apply max (map :entry-time (vals ha-vals)))
           [ha-vals tr-caches] (heval/init-has ha-defs (vals ha-vals) entry-time)
           config {:objects    ha-vals

      (let [flow0 (get v0-vars flow)
            dflow (get flows flow)]
        (cond
          (= dflow 0) [:eq f1 [:+ f0 [:* flow0 dt]]]
          (vector? dflow)
          (let [[acc limit] dflow

                                     (single-jump-constraints z3 ha-type ha-id in-state (:edges state-def) out-edge vT-vars next-vars last-t new-t)))
                                 has))
            (println "try" opt-edges-by-ha-id)
            (let [symx-result (symx!- z3
                                      (dec bound)
                                      target-states
                                      (conj time-steps new-t)
                                      (ha/spy "new path" (conj edge-states opt-edges-by-ha-id)))]
              (pop! z3)
              (if (= (second symx-result) :witness)
                (reduced symx-result)
