Mercurial > lasercutter
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