 
   (.get-or-create-index kn "know" "heights" #js ["height" "name"])
 
+  (.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"]])
+
+  (def edge-flow
+    (Join. #js ["magic_iterator"] #js [#js [(.get-or-create-index kn "know" "edge" #js ["x" "y"]) #js [0 1]]]
+           #js ["know"] #js ["connected"] #js [#js ["x" "y"]]))
+
+  (def connected-flow
+    (Join. #js ["magic_iterator" "magic_iterator"] #js [#js [(.get-or-create-index kn "know" "edge" #js ["x" "y"]) #js [0 1 nil]]
+                                                        #js [(.get-or-create-index kn "know" "connected" #js ["x" "y"]) #js [nil 0 1]]]
+           #js ["know"] #js ["connected"] #js [#js ["x" nil "y"]]))
+
+  (def transitive-flow
+    (Chain. #js [edge-flow (Fixpoint. connected-flow)]))
+
+  (.run transitive-flow kn)
+
+  (.get-or-create-index kn "know" "connected" #js ["x" "y"])
   )

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

(defn keymap [from-fields to-fields]
  (let [keymap (make-array (alength to-fields))]

(defn knowledge []
  (Knowledge. {} 0))

;; FLOWS

(deftype Join [input-types input-args output-kinds output-names output-fields]
  Object
  (run [this kn]
       (let [input-iters (amap input-types i _
                               (.apply (aget js/aurora.join (aget input-types i)) nil (aget input-args i)))
             join-iter (join/join-iterator input-iters)
             facts (btree/iterator->keys join-iter)]
         (dotimes [i (alength output-kinds)]
           (.add-facts kn (aget output-kinds i) (aget output-names i) (aget output-fields i) facts)))))

(deftype Chain [flows]
  Object
  (run [this kn]
       (dotimes [i (alength flows)]
         (.run (aget flows i) kn))))

(deftype Fixpoint [flow]
  Object
  (run [this kn]
       (loop [old-version (.-version kn)]
         (.run flow kn)
         (let [new-version (.-version kn)]
           (when (not (== old-version new-version))
             (recur new-version))))))

(comment

