Skip to content

Instantly share code, notes, and snippets.

@jonase
Created August 1, 2012 06:51
Show Gist options
  • Save jonase/3224348 to your computer and use it in GitHub Desktop.
Save jonase/3224348 to your computer and use it in GitHub Desktop.

Revisions

  1. jonase created this gist Aug 1, 2012.
    103 changes: 103 additions & 0 deletions gistfile1.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    (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 []>