Skip to content

Instantly share code, notes, and snippets.

@martintrojer
Created July 20, 2012 14:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martintrojer/3150994 to your computer and use it in GitHub Desktop.
Save martintrojer/3150994 to your computer and use it in GitHub Desktop.
Datalog in core.logic
(ns clog
(:refer-clojure :exclude [==])
(:use clojure.core.logic))
;; ------------------
(def db
#{
[#uuid "9d6280a3-7043-4e7e-9187-ad800743406a" :last-name "Downey"]
[#uuid "9d6280a3-7043-4e7e-9187-ad800743406a" :street "Hanam"]
[#uuid "a99b3f8c-e81f-450d-97b6-527d5db4c877" :name "Foo"]
[#uuid "87408604-bc27-4650-adb4-cd36ef4e054a" :owners-name "Kevin"]
[#uuid "a99b3f8c-e81f-450d-97b6-527d5db4c877" :url "http://foo"]
[#uuid "5d416576-9c6c-49c3-98ad-70f44b525004" :owners-name "Michael"]
[#uuid "ee3f8ced-d0ff-432b-b479-03aa7e8e0e4f" :last-name "Downey"]
[#uuid "33005ea0-e284-4b0e-b120-e4d5b828630e" :street "Lake City Way NE"]
[#uuid "5d416576-9c6c-49c3-98ad-70f44b525004" :name "Bar"]
[#uuid "87408604-bc27-4650-adb4-cd36ef4e054a" :name "Bar"]
[#uuid "5d416576-9c6c-49c3-98ad-70f44b525004" :url "http://bar"]
[#uuid "9d6280a3-7043-4e7e-9187-ad800743406a" :first-name "Michael"]
[#uuid "87408604-bc27-4650-adb4-cd36ef4e054a" :url "http://bar"]
[#uuid "33005ea0-e284-4b0e-b120-e4d5b828630e" :last-name "Abelseth"]
[#uuid "ee3f8ced-d0ff-432b-b479-03aa7e8e0e4f" :first-name "Kevin"]
[#uuid "ee3f8ced-d0ff-432b-b479-03aa7e8e0e4f" :street "Lake City Way NE"]
[#uuid "33005ea0-e284-4b0e-b120-e4d5b828630e" :first-name "Ariella"]
[#uuid "a99b3f8c-e81f-450d-97b6-527d5db4c877" :owners-name "Ariella"]
["bill" :parent "mary"]
["mary" :parent "john"]
["john" :parent "jack"]
["jack" :parent "george"]
["tom" :parent "jack"]})
(defrel eav entity attribute value)
(doseq [d db] (apply fact eav d))
;; ------------------
;;(q '[?p1-first-name ?p1-last-name ?p2-first-name]
;; '[[?person1 :street "Lake City Way NE"]
;; [?person1 :last-name ?p1-last-name]
;; [?person1 :first-name ?p1-first-name]
;; [?person2 :last-name ?p1-last-name]
;; [?person2 :first-name ?p2-first-name]]
;; [] db)
(run* [q]
(fresh [p1 p2 p1-first-name p1-last-name p2-first-name]
(eav p1 :street "Lake City Way NE")
(eav p1 :last-name p1-last-name)
(eav p1 :first-name p1-first-name)
(eav p2 :last-name p1-last-name)
(eav p2 :first-name p2-first-name)
(== q [p1-first-name p1-last-name p2-first-name])))
;; ------------------
;;(q '[?p2-first-name ?p1-last-name ?p1-name ?place1]
;; '[[?person1 :street "Lake City Way NE"]
;; [?person1 :last-name ?p1-last-name]
;; [?person2 :last-name ?p1-last-name]
;; [?person2 :street "Hanam"]
;; [?person2 :first-name ?p2-first-name]
;; [?place1 :owners-name ?p2-first-name]
;; [?place1 :name ?p1-name]]
;; [] db)
(run* [q]
(fresh [p1 p2 pl1 p1-name p1-last-name p2-first-name]
(eav p1 :street "Lake City Way NE")
(eav p1 :last-name p1-last-name)
(eav p2 :last-name p1-last-name)
(eav p2 :street "Hanam")
(eav p2 :first-name p2-first-name)
(eav pl1 :owners-name p2-first-name)
(eav pl1 :name p1-name)
(== q [p2-first-name p1-last-name p1-name pl1])))
;; ------------------
;;(q '[?a]
;; '[(ancestor "bill" ?a)]
;; '[[[ancestor ?X ?Y] [?X :parent ?Y]]
;; [[ancestor ?X ?Y] [?X :parent ?Z] (ancestor ?Z ?Y)]]
;; db)
(defne ancestorso [x y]
([x y]
(eav x :parent y))
([x y]
(fresh [z]
(eav x :parent z)
(ancestorso z y))))
(run* [q]
(ancestorso "bill" q))
;; ------------------
;;(q '[?ancestor]
;; '[(sibling "tom" ?ancestor)]
;; '[[[sibling ?X ?Y]
;; [?X :parent ?Z]
;; [?Y :parent ?Z]
;; (not= ?X ?Y)]]
;; db)
(defn siblingso [x y]
(fresh [z]
(eav x :parent z)
(eav y :parent z)
(!= x y)))
(run* [q]
(siblingso "tom" q))
;;(q '[?fname ?f]
;; '[[?person :street "Lake City Way NE"]
;; (family ?person ?relative)
;; [?person :first-name ?f]
;; [?relative :first-name ?fname]]
;; '[[[family ?X ?Y]
;; [?X :last-name ?Z]
;; [?Y :last-name ?Z]
;; (not= ?X ?Y)]]
;; db)
(defn familyo [x y]
(fresh [z]
(eav x :last-name z)
(eav y :last-name z)
(!= x y)))
(run* [q]
(fresh [fname f p1 relative]
(eav p1 :street "Lake City Way NE")
(familyo p1 relative)
(eav p1 :first-name f)
(eav relative :first-name fname)
(== q [fname f])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment