                                            clause-vars-ixes (map var->ix clause-vars)
                                            clause-keys (map second clause-vars&keys)
                                            index (.get-or-create-index kn "know" name (into-array clause-keys))]
+                                       (swap! kind->name->rules update-in ["know" name] #(conj (or % #{}) rule-id))
                                        [(btree/contains (btree/iterator index)) (into-array clause-vars-ixes)]))))
 
               ;; make solver

                                                                                             #js ["make-str" "constant" "js" "\"edge \" + xx + \" \" + yy"]
                                                                                             #js ["know-str" "variable" "name" "zz"]])

(def rule-id->flow (compile kn))

rule-id->flow

(.run (aget rule-id->flow "single-edge") kn)

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

(.run (aget rule-id->flow "transitive-edge") kn)

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

(.run (aget rule-id->flow "transitive-edge") kn)

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

(.run (aget rule-id->flow "transitive-edge") kn)

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

(.run (aget rule-id->flow "function-edge") kn)

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

        (set!! changed? true)))
    changed?))

(deftype Knowledge [^:mutable kind->name->fields->index]
  Object
  (get-or-create-index [this kind name fields]
                       (assert (or (= kind "know") (= kind "remember") (= kind "forget")) (pr-str kind))
