       (let [vars (atom #{})]
 
         ;; collect vars
-        (doseq [[_ _ clause-id _] clauses
-                (get @clause-id->fields clause-id)]
+        (doseq [[_ _ clause-id _] clauses]
           (let [fields (get @clause-id->fields clause-id)]
             (doseq [[_ field-type key val] fields]
               (when (= field-type "variable")
                 (swap! vars conj val)))))
 
-        ;; make ruleset
         (let [var->ix (zipmap @vars (range))
               num-vars (count @vars)
+
+              ;; make input iter
               iters (for [[_ clause-type clause-id name] clauses
                           :when (= clause-type "when")]
                       (let [fields (get @clause-id->fields clause-id)]

  (:require [aurora.btree :as btree]
            [aurora.join :as join])
  (:require-macros [aurora.macros :refer [apush set!!]]))

;; KNOWLEDGE


                                              key)
                                index (.get-or-create-index kn "know" name clause-keys)]
                            (join/magic-iterator index (into-array var-map))))))
              join-iter (join/join-iterator (into-array iterators))

              ;; make output specs
              output-kinds (into-array
                            (for [[_ clause-type clause-id name] clauses
                                  :when (not= clause-type "when")]
                              clause-type))
              output-names (into-array
                            (for [[_ clause-type clause-id name] clauses
                                  :when (not= clause-type "when")]
                              name))
              output-fields (into-array
                             (for [[_ clause-type clause-id name] clauses
                                   :when (not= clause-type "when")]
                               (let [clause-fields (get @clause-id->fields clause-id)
                                     output-fields (make-array num-vars)]
                                 (doseq [[_ field-type key val] fields]
                                   (assert (= field-type "variable"))
                                   (aset output-fields (var->ix val) key)))))]

          (Flow. join-iter output-kinds output-names output-fields))))))

(def kn (knowledge))

(.get-or-create-index kn "know" "edge" #js ["x" "y"])

(.get-or-create-index kn "know" "connected" #js ["x" "y"])

(.add-facts kn "know" "edge" #js ["x" "y"] #js [#js ["a" "b"] #js ["b" "c"] #js ["c" "d"] #js ["d" "b"]])

(.get-or-create-index kn "know" "clauses" #js ["rule-id" "when|pretend|remember|forget" "clause-id" "name"])

(.get-or-create-index kn "know" "clause-fields" #js ["clause-id" "constant|variable" "key" "val"])

(.add-facts kn "know" "clauses" #js ["rule-id" "when|pretend|remember|forget" "clause-id" "name"] #js [#js ["edge->connected" "when" "get-edges" "edge"]
                                                                                                       #js ["edge->connected" "pretend" "output-connected" "edge"]])

(.add-facts kn "know" "clause-fields" #js ["clause-id" "constant|variable" "key" "val"] #js [#js ["get-edges" "variable" "x" "xx"]
                                                                                             #js ["get-edges" "variable" "y" "yy"]
                                                                                             #js ["output-connected" "variable" "x" "xx"]
                                                                                             #js ["output-connected" "variable" "y" "yy"]])

(compile kn)

(comment

