       (l/== q [e2 a2 v2 t2])))
 #_(get-entity 1)
 
+#_(get-user 2)
+
 #_(lp/with-db (get-logic-db)
     (l/run* [q]
       (l/fresh [eu vu


(defn project-facts [facts]
  "Projects given facts to a given timestamp."
  (let [facts* (volatile! {})
        xf (fn [xf]
             (fn
               ([] (xf))
               ([result] (xf result))
               ([result [e a v t action :as input]]
                (case action
                  :add (case (get-in @facts* [e a])
                         true result
                         ::retracted (do (vswap! facts* #(update-in % [e] dissoc a))
                                         result)
                         nil (do (vswap! facts* #(assoc-in % [e a] true))
                                 (xf result (take 4 input))))
                  :retract (do (vswap! facts* #(assoc-in % [e a] ::retracted))
                               result)))))]
    (into [] xf facts)))

(defn get-entity [eid]
  "Retrieves entire entity."
  (let [facts (-> (get-facts :where-criteria {:eid eid})
                  project-facts)]
    (reduce (fn [s [e a v t]]
              (if-not (contains? s a)
                (assoc s a v)
                s))
            {}
            facts)))

(defn- new-eid []
  #_(str (java.util.UUID/randomUUID))



;;;
;;; GENERIC ENTITY-AWARE STUFF:
;;;

(defn get-entity [eid]
  "Retrieves entire entity."
  (let [db (get-logic-db)
        efacts (lp/with-db db
                 (l/run* [q]
                   (l/fresh [e a v]
                     (fact e a v (l/lvar))
                     (l/== e eid)
                     (l/== q [e a v (l/lvar)]))))]
    (reduce (fn [s [e a v t]]
              (assoc s a v))
            {}
            efacts)))


;;;
;;; APPLICATION SPECIFIC STUFF
;;;

(defrecord User [])
(defrecord Comment [])

(defmethod print-method User [v ^java.io.Writer w]
  (print-method (into {} (dissoc v :comments)) w))

(defmethod print-method Comment [v ^java.io.Writer w]
  (print-method (into {} (dissoc v :users)) w))

(declare get-user)
(declare get-comment)

(defn get-user [eid]
  (map->User (merge (get-entity eid)
                    {:comments (lazy-seq [(get-comment 3)])})))

(defn get-comment [eid]
  (map->Comment (get-entity eid)))


#_(evdb/open)
