diff 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
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/contrib/datalog/util.clj	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,89 @@
     1.4 +;;  Copyright (c) Jeffrey Straszheim. All rights reserved.  The use and
     1.5 +;;  distribution terms for this software are covered by the Eclipse Public
     1.6 +;;  License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which can
     1.7 +;;  be found in the file epl-v10.html at the root of this distribution.  By
     1.8 +;;  using this software in any fashion, you are agreeing to be bound by the
     1.9 +;;  terms of this license.  You must not remove this notice, or any other,
    1.10 +;;  from this software.
    1.11 +;;
    1.12 +;;  util.clj
    1.13 +;;
    1.14 +;;  A Clojure implementation of Datalog -- Utilities
    1.15 +;;
    1.16 +;;  straszheimjeffrey (gmail)
    1.17 +;;  Created 3 Feburary 2009
    1.18 +
    1.19 +
    1.20 +(ns clojure.contrib.datalog.util
    1.21 +  (:use [clojure.contrib.seq :only (separate)]))
    1.22 +
    1.23 +
    1.24 +
    1.25 +;;; Bindings and logic vars.  A binding in a hash of logic vars to
    1.26 +;;; bound values.  Logic vars are any symbol prefixed with a \?.
    1.27 +
    1.28 +(defn is-var?
    1.29 +  "Is this a logic variable: e.g. a symbol prefixed with a ?"
    1.30 +  [sym]
    1.31 +  (when (symbol? sym)
    1.32 +    (let [name (name sym)]
    1.33 +      (and (= \? (first name))
    1.34 +           (not= \? (fnext name))))))
    1.35 +
    1.36 +(defn is-query-var?
    1.37 +  "Is this a query variable: e.g. a symbol prefixed with ??"
    1.38 +  [sym]
    1.39 +  (when (symbol? sym)
    1.40 +    (let [name (name sym)]
    1.41 +      (and (= \? (first name))
    1.42 +           (= \? (fnext name))))))
    1.43 +
    1.44 +(defn map-values
    1.45 +  "Like map, but works over the values of a hash map"
    1.46 +  [f hash]
    1.47 +  (let [key-vals (map (fn [[key val]] [key (f val)]) hash)]
    1.48 +    (if (seq key-vals)
    1.49 +      (apply conj (empty hash) key-vals)
    1.50 +      hash)))
    1.51 +
    1.52 +(defn keys-to-vals
    1.53 +  "Given a map and a collection of keys, return the collection of vals"
    1.54 +  [m ks]
    1.55 +  (vals (select-keys m ks)))
    1.56 +
    1.57 +(defn reverse-map
    1.58 +  "Reverse the keys/values of a map"
    1.59 +  [m]
    1.60 +  (into {} (map (fn [[k v]] [v k]) m)))
    1.61 +
    1.62 +
    1.63 +;;; Preduce -- A parallel reduce over hashes
    1.64 +  
    1.65 +(defn preduce
    1.66 +  "Similar to merge-with, but the contents of each key are merged in
    1.67 +   parallel using f.
    1.68 +
    1.69 +   f - a function of 2 arguments.
    1.70 +   data - a collection of hashes."
    1.71 +  [f data]
    1.72 +  (let [data-1 (map (fn [h] (map-values #(list %) h)) data)
    1.73 +        merged (doall (apply merge-with concat data-1))
    1.74 +        ; Groups w/ multiple elements are identified for parallel processing
    1.75 +        [complex simple] (separate (fn [[key vals]] (> (count vals) 1)) merged)
    1.76 +        fold-group (fn [[key vals]] {key (reduce f vals)})
    1.77 +        fix-single (fn [[key [val]]] [key val])]
    1.78 +    (apply merge (concat (pmap fold-group merged) (map fix-single simple)))))
    1.79 +  
    1.80 +
    1.81 +;;; Debuging and Tracing
    1.82 +
    1.83 +(def *trace-datalog* nil)
    1.84 +
    1.85 +(defmacro trace-datalog
    1.86 +  "If *test-datalog* is set to true, run the enclosed commands"
    1.87 +  [& body]
    1.88 +  `(when *trace-datalog*
    1.89 +     ~@body))
    1.90 +
    1.91 + 	
    1.92 +;; End of file