(use '[datomic.api :only [db q] :as d]) (def schema [{:db/doc "A persons name" :db/id #db/id[:db.part/db] :db/ident :name :db/valueType :db.type/string :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db} {:db/doc "A persons children" :db/id #db/id[:db.part/db] :db/ident :child :db/valueType :db.type/ref :db/cardinality :db.cardinality/many :db.install/_attribute :db.part/db}]) (def tx-data (let [[victor kathleen joseph wendy jeffrey rosa harry grace william] (repeatedly #(d/tempid :db.part/user))] [[:db/add victor :name "Victor"] [:db/add kathleen :name "Kathleen"] [:db/add joseph :name "Joseph"] [:db/add wendy :name "Wendy"] [:db/add jeffrey :name "Jeffrey"] [:db/add rosa :name "Rosa"] [:db/add harry :name "Harry"] [:db/add grace :name "Grace"] [:db/add william :name "William"] [:db/add victor :child joseph] [:db/add kathleen :child joseph] [:db/add joseph :child harry] [:db/add wendy :child harry] [:db/add jeffrey :child grace] [:db/add rosa :child grace] [:db/add harry :child william] [:db/add grace :child william]])) (def genealogy (let [uri "datomic:mem://genealogy"] (d/delete-database uri) (d/create-database uri) (let [conn (d/connect uri)] (d/transact conn schema) (d/transact conn tx-data) (db conn)))) (def parent ;; ?a is a parent of ?b '[[[parent ?a ?b] [?a :child ?b]]]) (def ancestor ; ?a is an anscestor of ?b '[[[ancestor ?a ?b] [parent ?a ?b]] [[ancestor ?a ?b] [parent ?a ?x] [ancestor ?x ?b]]]) (def rules (concat parent ancestor)) ;; Who are Wendys children? (q '[:find ?child-name :in $ % :where [?w :name "Wendy"] [parent ?w ?c] [?c :name ?child-name]] genealogy rules) ;; Who are Harry's parents? (q '[:find ?parent-name :in $ % :where [?h :name "Harry"] [parent ?p ?h] [?p :name ?parent-name]] genealogy rules) ;; Who are Harrys ancestors? (q '[:find ?ancestor-name :in $ % :where [?h :name "Harry"] [ancestor ?a ?h] [?a :name ?ancestor-name]] genealogy rules) ;; Who are Jeffreys descendants? (q '[:find ?descendant-name :in $ % :where [?j :name "Jeffrey"] [ancestor ?j ?d] [?d :name ?descendant-name]] genealogy rules)