   (let [cache (make-array (count plan))
         result (transient #{})]
     (run-plan plan cache kn)
-    (doseq [assert-ix assert-ixes
-            fact (aget cache assert-ix)]
-      (conj!! result fact))
-    (doseq [retract-ix retract-ixes
-            fact (aget cache retract-ix)]
-      (disj!! result fact))
+    (console-time "query asserts" profile?
+                  (doseq [assert-ix assert-ixes
+                          fact (aget cache assert-ix)]
+                    (conj!! result fact)))
+    (console-time "query retracts" profile?
+                  (doseq [retract-ix retract-ixes
+                          fact (aget cache retract-ix)]
+                    (disj!! result fact)))
     (persistent! result)))
 
 (comment

        asserted-now (transient (:asserted-now kn))
        retracted-now (transient (:retracted-now kn))]
    (run-plan plan cache kn)
    (doseq [assert-ix assert-ixes
            fact (aget cache assert-ix)]
      (conj!! asserted-now fact)
      (when (or (contains? prev fact) (not (contains? retracted-now fact)))
        (conj!! now fact)))
    (doseq [retract-ix retract-ixes
            fact (aget cache retract-ix)]
      (conj!! retracted-now fact)
      (when (or (not (contains? prev fact)) (not (contains? asserted-now fact)))
        (disj!! now fact)))
    (->Knowledge prev (persistent! asserted-now) (persistent! retracted-now) (persistent! now))))

(comment

  (-s vars fn)
  )

(def profile? false)

;; TODO
;; query optimisation (starting with clause sorting)
;; aggregates (conj? sorting?)
