diff options
Diffstat (limited to 'src/clojure/contrib/datalog/util.clj')
-rw-r--r-- | src/clojure/contrib/datalog/util.clj | 89 |
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 |