annotate src/clojure/contrib/datalog/util.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 ;; Copyright (c) Jeffrey Straszheim. All rights reserved. The use and
rlm@10 2 ;; distribution terms for this software are covered by the Eclipse Public
rlm@10 3 ;; License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
rlm@10 4 ;; be found in the file epl-v10.html at the root of this distribution. By
rlm@10 5 ;; using this software in any fashion, you are agreeing to be bound by the
rlm@10 6 ;; terms of this license. You must not remove this notice, or any other,
rlm@10 7 ;; from this software.
rlm@10 8 ;;
rlm@10 9 ;; util.clj
rlm@10 10 ;;
rlm@10 11 ;; A Clojure implementation of Datalog -- Utilities
rlm@10 12 ;;
rlm@10 13 ;; straszheimjeffrey (gmail)
rlm@10 14 ;; Created 3 Feburary 2009
rlm@10 15
rlm@10 16
rlm@10 17 (ns clojure.contrib.datalog.util
rlm@10 18 (:use [clojure.contrib.seq :only (separate)]))
rlm@10 19
rlm@10 20
rlm@10 21
rlm@10 22 ;;; Bindings and logic vars. A binding in a hash of logic vars to
rlm@10 23 ;;; bound values. Logic vars are any symbol prefixed with a \?.
rlm@10 24
rlm@10 25 (defn is-var?
rlm@10 26 "Is this a logic variable: e.g. a symbol prefixed with a ?"
rlm@10 27 [sym]
rlm@10 28 (when (symbol? sym)
rlm@10 29 (let [name (name sym)]
rlm@10 30 (and (= \? (first name))
rlm@10 31 (not= \? (fnext name))))))
rlm@10 32
rlm@10 33 (defn is-query-var?
rlm@10 34 "Is this a query variable: e.g. a symbol prefixed with ??"
rlm@10 35 [sym]
rlm@10 36 (when (symbol? sym)
rlm@10 37 (let [name (name sym)]
rlm@10 38 (and (= \? (first name))
rlm@10 39 (= \? (fnext name))))))
rlm@10 40
rlm@10 41 (defn map-values
rlm@10 42 "Like map, but works over the values of a hash map"
rlm@10 43 [f hash]
rlm@10 44 (let [key-vals (map (fn [[key val]] [key (f val)]) hash)]
rlm@10 45 (if (seq key-vals)
rlm@10 46 (apply conj (empty hash) key-vals)
rlm@10 47 hash)))
rlm@10 48
rlm@10 49 (defn keys-to-vals
rlm@10 50 "Given a map and a collection of keys, return the collection of vals"
rlm@10 51 [m ks]
rlm@10 52 (vals (select-keys m ks)))
rlm@10 53
rlm@10 54 (defn reverse-map
rlm@10 55 "Reverse the keys/values of a map"
rlm@10 56 [m]
rlm@10 57 (into {} (map (fn [[k v]] [v k]) m)))
rlm@10 58
rlm@10 59
rlm@10 60 ;;; Preduce -- A parallel reduce over hashes
rlm@10 61
rlm@10 62 (defn preduce
rlm@10 63 "Similar to merge-with, but the contents of each key are merged in
rlm@10 64 parallel using f.
rlm@10 65
rlm@10 66 f - a function of 2 arguments.
rlm@10 67 data - a collection of hashes."
rlm@10 68 [f data]
rlm@10 69 (let [data-1 (map (fn [h] (map-values #(list %) h)) data)
rlm@10 70 merged (doall (apply merge-with concat data-1))
rlm@10 71 ; Groups w/ multiple elements are identified for parallel processing
rlm@10 72 [complex simple] (separate (fn [[key vals]] (> (count vals) 1)) merged)
rlm@10 73 fold-group (fn [[key vals]] {key (reduce f vals)})
rlm@10 74 fix-single (fn [[key [val]]] [key val])]
rlm@10 75 (apply merge (concat (pmap fold-group merged) (map fix-single simple)))))
rlm@10 76
rlm@10 77
rlm@10 78 ;;; Debuging and Tracing
rlm@10 79
rlm@10 80 (def *trace-datalog* nil)
rlm@10 81
rlm@10 82 (defmacro trace-datalog
rlm@10 83 "If *test-datalog* is set to true, run the enclosed commands"
rlm@10 84 [& body]
rlm@10 85 `(when *trace-datalog*
rlm@10 86 ~@body))
rlm@10 87
rlm@10 88
rlm@10 89 ;; End of file