Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 90 lines (69 sloc) 2.594 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 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 :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
Something went wrong with that request. Please try again.