;; Copyright (c) Jeffrey Straszheim. All rights reserved. The use and ;; distribution terms for this software are covered by the Eclipse Public ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can ;; be found in the file epl-v10.html at the root of this distribution. By ;; using this software in any fashion, you are agreeing to be bound by the ;; terms of this license. You must not remove this notice, or any other, ;; from this software. ;; ;; example.clj ;; ;; A Clojure implementation of Datalog - Example ;; ;; straszheimjeffrey (gmail) ;; Created 2 March 2009 (ns clojure.contrib.datalog.example (:use [clojure.contrib.datalog :only (build-work-plan run-work-plan)] [clojure.contrib.datalog.rules :only (<- ?- rules-set)] [clojure.contrib.datalog.database :only (make-database add-tuples)] [clojure.contrib.datalog.util :only (*trace-datalog*)])) (def db-base (make-database (relation :employee [:id :name :position]) (index :employee :name) (relation :boss [:employee-id :boss-id]) (index :boss :employee-id) (relation :can-do-job [:position :job]) (index :can-do-job :position) (relation :job-replacement [:job :can-be-done-by]) ;(index :job-replacement :can-be-done-by) (relation :job-exceptions [:id :job]))) (def db (add-tuples db-base [:employee :id 1 :name "Bob" :position :boss] [:employee :id 2 :name "Mary" :position :chief-accountant] [:employee :id 3 :name "John" :position :accountant] [:employee :id 4 :name "Sameer" :position :chief-programmer] [:employee :id 5 :name "Lilian" :position :programmer] [:employee :id 6 :name "Li" :position :technician] [:employee :id 7 :name "Fred" :position :sales] [:employee :id 8 :name "Brenda" :position :sales] [:employee :id 9 :name "Miki" :position :project-management] [:employee :id 10 :name "Albert" :position :technician] [:boss :employee-id 2 :boss-id 1] [:boss :employee-id 3 :boss-id 2] [:boss :employee-id 4 :boss-id 1] [:boss :employee-id 5 :boss-id 4] [:boss :employee-id 6 :boss-id 4] [:boss :employee-id 7 :boss-id 1] [:boss :employee-id 8 :boss-id 7] [:boss :employee-id 9 :boss-id 1] [:boss :employee-id 10 :boss-id 6] [:can-do-job :position :boss :job :management] [:can-do-job :position :accountant :job :accounting] [:can-do-job :position :chief-accountant :job :accounting] [:can-do-job :position :programmer :job :programming] [:can-do-job :position :chief-programmer :job :programming] [:can-do-job :position :technician :job :server-support] [:can-do-job :position :sales :job :sales] [:can-do-job :position :project-management :job :project-management] [:job-replacement :job :pc-support :can-be-done-by :server-support] [:job-replacement :job :pc-support :can-be-done-by :programming] [:job-replacement :job :payroll :can-be-done-by :accounting] [:job-exceptions :id 4 :job :pc-support])) (def rules (rules-set (<- (:works-for :employee ?x :boss ?y) (:boss :employee-id ?e-id :boss-id ?b-id) (:employee :id ?e-id :name ?x) (:employee :id ?b-id :name ?y)) (<- (:works-for :employee ?x :boss ?y) (:works-for :employee ?x :boss ?z) (:works-for :employee ?z :boss ?y)) (<- (:employee-job* :employee ?x :job ?y) (:employee :name ?x :position ?pos) (:can-do-job :position ?pos :job ?y)) (<- (:employee-job* :employee ?x :job ?y) (:job-replacement :job ?y :can-be-done-by ?z) (:employee-job* :employee ?x :job ?z)) (<- (:employee-job* :employee ?x :job ?y) (:can-do-job :job ?y) (:employee :name ?x :position ?z) (if = ?z :boss)) (<- (:employee-job :employee ?x :job ?y) (:employee-job* :employee ?x :job ?y) (:employee :id ?id :name ?x) (not! :job-exceptions :id ?id :job ?y)) (<- (:bj :name ?x :boss ?y) (:works-for :employee ?x :boss ?y) (not! :employee-job :employee ?y :job :pc-support)))) (def wp-1 (build-work-plan rules (?- :works-for :employee '??name :boss ?x))) (run-work-plan wp-1 db {'??name "Albert"}) (def wp-2 (build-work-plan rules (?- :employee-job :employee '??name :job ?x))) (binding [*trace-datalog* true] (run-work-plan wp-2 db {'??name "Li"})) (def wp-3 (build-work-plan rules (?- :bj :name '??name :boss ?x))) (run-work-plan wp-3 db {'??name "Albert"}) (def wp-4 (build-work-plan rules (?- :works-for :employee ?x :boss ?y))) (run-work-plan wp-4 db {}) ;; End of file