   (fixpoint! state-0)
   (for [state (take 5 (iterate #(tick&fixpoint plan %) state-0))]
     (count (get-facts state :known))))
-  )
+
+  (let [rules [(Rule. [
+                       (aurora.language.Recall. :known&pretended, (js/aurora.language.fact :http/response #js ['content "google" 'some]))
+                       (aurora.language.Output. :remembered (js/aurora.language.fact "1df7454c_069e_40ab_b117_b8d43212b473" #js ['value74]))
+                       (aurora.language.Output. :forgotten (js/aurora.language.fact "1df7454c_069e_40ab_b117_b8d43212b473" #js ['value]))
+                       (aurora.language.Recall. :known&pretended, (js/aurora.language.fact "1df7454c_069e_40ab_b117_b8d43212b473" #js ['value]))
+                       (aurora.language.Compute. (->Let 'value74  #{'value} "value + \"hey\""))])]
+        plan (add-rules empty-flow-plan rules)
+        state (flow-plan->flow-state plan)]
+    (add-facts state :known [(fact. "1df7454c_069e_40ab_b117_b8d43212b473" #js ["Click me"])])
+    (add-facts state :pretended [(fact. :http/response #js ["yo" "google" 1234])])
+    (fixpoint! state)
+    (-> state
+        (get-facts :known)
+        first
+        (.-values))
+  )
+  )

                  (let [sink (make-array (alength var-ixes))]
                    (dotimes [i (alength var-ixes)]
                      (aset sink i (aget source (aget var-ixes i))))
                    (Fact. nil sink)))))))))))

(comment
  (deffact eg "[a] has a [b] with a [c]")

        [plan index-b] (add-flow plan (->Index nodes-b key-ixes-b))
        [plan lookup-a] (add-flow plan (->Lookup [index-a] index-b key-ixes-a val-ixes-a))
        [plan lookup-b] (add-flow plan (->Lookup [index-b] index-a key-ixes-b val-ixes-b))]
    [plan [lookup-a lookup-b] (distinct (concat vars-a vars-b))]))

(comment

  (let [plan empty-flow-plan
        [plan nodes-a vars-a] (add-clause plan nil nil (Recall. :known&pretended (->edge 'x 'y)))
        [plan nodes-b vars-b] (add-clause plan nil nil (Recall. :known (->connected 'y 'z)))
        [plan nodes-c vars-c] (join-clauses plan nodes-a vars-a #{} nodes-b vars-b #{})]
    [plan nodes-c vars-c])
  )

(defn add-rule [plan rule]
  (let [recalls (filter #(= Recall (type %)) (:clauses rule))
        computes (set (filter #(= Compute (type %)) (:clauses rule)))
        outputs (filter #(= Output (type %)) (:clauses rule))
        main-plan (atom plan)
        nodes&vars (for [recall recalls]
                     (let [[plan node vars] (add-computes (add-clause @main-plan nil nil recall) computes)]
                       (reset! main-plan plan)
                       [node vars]))
        [nodes vars] (reduce (fn [[nodes-a vars-a] [nodes-b vars-b]]
                               (let [computes-unapplied (difference computes
                                                                    (filter #(add-clause @main-plan nodes-a vars-a %) computes)
                                                                    (filter #(add-clause @main-plan nodes-b vars-b %) computes))
                                     [plan nodes vars] (add-computes
                                                        (join-clauses @main-plan nodes-a vars-a nodes-b vars-b)
                                                        computes-unapplied)]
                                 (reset! main-plan plan)
                                 [nodes vars]))
                             nodes&vars)
        computes-unapplied (filter #(not (add-clause @main-plan nodes vars %)) computes)]
    (assert (empty? computes-unapplied) (str "Could not apply " (pr-str computes-unapplied) " to " (pr-str vars)))
    (doseq [output outputs]
      (let [[plan node vars] (add-clause @main-plan nodes vars output)]
        (reset! main-plan plan)))
    @main-plan))

(defn add-rules [plan rules]
