aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/datalog/util.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/clojure/contrib/datalog/util.clj')
-rw-r--r--src/clojure/contrib/datalog/util.clj89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/clojure/contrib/datalog/util.clj b/src/clojure/contrib/datalog/util.clj
new file mode 100644
index 00000000..b887f85c
--- /dev/null
+++ b/src/clojure/contrib/datalog/util.clj
@@ -0,0 +1,89 @@
+;; 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.
+;;
+;; util.clj
+;;
+;; A Clojure implementation of Datalog -- Utilities
+;;
+;; straszheimjeffrey (gmail)
+;; Created 3 Feburary 2009
+
+
+(ns clojure.contrib.datalog.util
+ (:use [clojure.contrib.seq-utils :only (separate)]))
+
+
+
+;;; Bindings and logic vars. A binding in a hash of logic vars to
+;;; bound values. Logic vars are any symbol prefixed with a \?.
+
+(defn is-var?
+ "Is this a logic variable: e.g. a symbol prefixed with a ?"
+ [sym]
+ (when (symbol? sym)
+ (let [name (name sym)]
+ (and (= \? (first name))
+ (not= \? (fnext name))))))
+
+(defn is-query-var?
+ "Is this a query variable: e.g. a symbol prefixed with ??"
+ [sym]
+ (when (symbol? sym)
+ (let [name (name sym)]
+ (and (= \? (first name))
+ (= \? (fnext name))))))
+
+(defn map-values
+ "Like map, but works over the values of a hash map"
+ [f hash]
+ (let [key-vals (map (fn [[key val]] [key (f val)]) hash)]
+ (if (seq key-vals)
+ (apply conj (empty hash) key-vals)
+ hash)))
+
+(defn keys-to-vals
+ "Given a map and a collection of keys, return the collection of vals"
+ [m ks]
+ (vals (select-keys m ks)))
+
+(defn reverse-map
+ "Reverse the keys/values of a map"
+ [m]
+ (into {} (map (fn [[k v]] [v k]) m)))
+
+
+;;; Preduce -- A parallel reduce over hashes
+
+(defn preduce
+ "Similar to merge-with, but the contents of each key are merged in
+ parallel using f.
+
+ f - a function of 2 arguments.
+ data - a collection of hashes."
+ [f data]
+ (let [data-1 (map (fn [h] (map-values #(list %) h)) data)
+ merged (doall (apply merge-with concat data-1))
+ ; Groups w/ multiple elements are identified for parallel processing
+ [complex simple] (separate (fn [[key vals]] (> (count vals) 1)) merged)
+ fold-group (fn [[key vals]] {key (reduce f vals)})
+ fix-single (fn [[key [val]]] [key val])]
+ (apply merge (concat (pmap fold-group merged) (map fix-single simple)))))
+
+
+;;; Debuging and Tracing
+
+(def *trace-datalog* nil)
+
+(defmacro trace-datalog
+ "If *test-datalog* is set to true, run the enclosed commands"
+ [& body]
+ `(when *trace-datalog*
+ ~@body))
+
+
+;; End of file