 (defn add-clause [plan nodes vars clause]
   (condp = (type clause)
     Recall (let [{:keys [memory pattern]} clause
-                 [plan node-a] (add-flow plan (FilterMap. (memory->nodes memory) (pattern->filter pattern)))
-                 [plan node-b] (add-flow plan (FilterMap. [node-a] (pattern->deconstructor pattern)))]
-             [plan [node-b] (pattern->vars pattern)])
+                 [plan node] (add-flow plan (FilterMap. #{} (pattern->deconstructor pattern)))
+                 plan (add-input plan node memory (.-shape pattern))]
+             [plan [node] (pattern->vars pattern)])
     Compute (let [{:keys [pattern]} clause]
               (condp = (.-shape pattern)
                 Let (when (every? (set vars) (:vars pattern))


;; FLOW PLAN

(defrecord FlowPlan [node->flow flow->node])

(defn flow-plan->flow-state [{:keys [node->flow]}]
  (let [node->state (into-array (for [_ node->flow] nil))
        node->out-nodes (into-array (for [_ node->flow] #js []))
        node->facts (into-array (for [_ node->flow] #js []))

                Lookup (lookup-update! (:index-node flow) (:key-ixes flow) (:val-ixes flow))))))
    (FlowState. node->state node->out-nodes node->facts node->update! trace plan)))

(def empty-flow-plan
  (FlowPlan. [] {} {} {}))

(defn add-flow-without-memo [{:keys [node->flow flow->node] :as flow-plan} flow]
  (let [node (count node->flow)
        node->flow (conj node->flow flow)
        flow->node (assoc flow->node flow node)]
    [(assoc flow-plan :node->flow node->flow :flow->node flow->node) node]))

(defn add-flow [{:keys [node->flow flow->node] :as flow-plan} flow]
  (if-let [node (get flow->node flow)]
    [flow-plan node]
    (add-flow-without-memo flow-plan flow)))

(defn memory! [memory]
  (assert (#{:known|pretended :remembered :forgotten} memory) (pr-str memory)))

(defn add-memory [{:keys [node->flow memory->shape->node] :as flow-plan} memory shape]
  (memory! memory)
  (let [[flow-plan node] (add-flow-without-memo flow-plan (Union. #{}))
        memory->shape->node (assoc-in memory->shape->node [memory shape] node)]
    (assoc flow-plan :memory->shape->node memory->shape->node)))

(defn add-shape [flow-plan kind shape]
  (case kind
    :pretended (-> flow-plan
                   (add-memory :known|pretended shape)
                   (update-in [:kind->shape kind] #(conj (or % #{}) shape)))
    :known (-> flow-plan
               (add-memory :known|pretended shape)
               (add-memory :remembered shape)
               (add-memory :forgotten shape)
               (update-in [:kind->shape kind] #(conj (or % #{}) shape)))))

(defn get-memory [{:keys [memory->shape->node]} memory shape]
  (memory! memory)
  (or (get-in memory->shape->node [memory shape])
      (assert false (str "No node for " (pr-str memory) " " (pr-str shape)))))

(defn add-input [flow-plan output-node memory shape]
  (update-in flow-plan [:node->flow output-node :nodes] conj (get-memory flow-plan memory shape)))

(defn add-output [flow-plan input-node memory shape]
  (update-in flow-plan [:node->flow (get-memory flow-plan memory shape) :nodes] conj input-node))


;; IXES

