Skip to content

Instantly share code, notes, and snippets.

@jonase
Created August 1, 2012 06:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jonase/3224348 to your computer and use it in GitHub Desktop.
Save jonase/3224348 to your computer and use it in GitHub Desktop.
(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 daughter"
:db/id #db/id[:db.part/db]
:db/ident :daughter
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db.install/_attribute :db.part/db}
{:db/doc "A persons son"
:db/id #db/id[:db.part/db]
:db/ident :son
: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/id victor :name "Victor"
:son [joseph harry]
:daughter [grace]}
{:db/id joseph :name "Joseph"
:son [william]
:daughter [rosa wendy]}
{:db/id grace :name "Grace"
:son [jeffrey]}
{:db/id kathleen :name "Kathleen"}
{:db/id wendy :name "Wendy"}
{:db/id jeffrey :name "Jeffrey"}
{:db/id rosa :name "Rosa"}
{:db/id harry :name "Harry"}
{:db/id william :name "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))))
;; 'child' is derived
(def child
'[[[child ?parent ?child]
[?parent :daughter ?child]]
[[child ?parent ?child]
[?parent :son ?child]]])
;; Who are the children of Joseph?
(q '[:find ?child-name
:in $ % ?parent-name
:where
[?child :name ?child-name]
[?parent :name ?parent-name]
[child ?parent ?child]]
genealogy
child
"Joseph")
;; #<HashSet [["Wendy"], ["Rosa"], ["William"]]>
(def ancestor
'[[[ancestor ?a ?d]
[child ?a ?d]]
[[ancestor ?a ?d]
[child ?a ?x]
[ancestor ?x ?d]]])
;; Who are the ancestors of Victor?
(q '[:find ?dname
:in $ % ?aname
:where
[?ae :name ?aname]
[?d :name ?dname]
[ancestor ?ae ?d]]
genealogy
(concat ancestor child)
"Victor")
;; #<HashSet [["Joseph"], ["Wendy"], ["Grace"], ["William"],
;; ["Rosa"], ["Harry"], ["Jeffrey"]]>
;; Exact copy of previous query, but the ?ae variable changed to ?a
(q '[:find ?dname
:in $ % ?aname
:where
[?a :name ?aname]
[?d :name ?dname]
[ancestor ?a ?d]]
genealogy
(concat ancestor child)
"Victor")
;; #<HashSet []>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment