Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

90 lines (69 sloc) 2.594 kb
;; Copyright (c) Jeffrey Straszheim. All rights reserved. The use and
;; distribution terms for this software are covered by the Eclipse Public
;; License 1.0 ( 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 :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 ?"
(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 ??"
(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)
(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"
(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*
;; End of file
Jump to Line
Something went wrong with that request. Please try again.