       (recur new-flow-plan new-shape (filter #(not= clause %) clauses))
       (do (assert (empty? clauses) (str "Cannot join " (pr-str shape) " with " (pr-str clauses)))
         flow-plan))))
-
-;; TODO !!! test

;; CLAUSES

(defrecord Recall [memory pattern]) ;; memory is one of :known :pretended :remembered :forgotten :known&pretended
(defrecord Filter [expr])
(defrecord Let [name expr])
(defrecord Set [name vars clauses])
(defrecord Output [memory pattern]) ;; memory is one of :pretended :remembered :forgotten
(defrecord OutputMany [memory expr]) ;; memory is one of :pretended :remembered :forgotten

(defn clause->flow-plan [flow-plan shape clause]
  (condp = (type clause)
    ;; TODO !!! keep going here
    ))

;; RULES

(defrecord Rule [clauses])

(defn rule->flow-plan [flow-plan rule]
  (loop [flow-plan flow-plan

(defrecord FilterMap [nodes fun])
(defrecord Index [nodes key-ixes])
(defrecord Lookup [nodes index-node key-ixes val-ixes])

(defn flow->nodes [flow]
  (:nodes flow))

;; FLOW PLAN

