From 81dd1a48c71b7e08b00c62af76d9595c299b8e0c Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Fri, 3 Sep 2010 18:01:30 -0600 Subject: [PATCH] adding tangled source files to the repo --- .gitignore | 2 +- src/graphs.clj | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/heron.clj | 16 +++++++++++++++ src/propagator.clj | 41 +++++++++++++++++++++++++++++++++++++ src/web.clj | 41 +++++++++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/graphs.clj create mode 100644 src/heron.clj create mode 100644 src/propagator.clj create mode 100644 src/web.clj diff --git a/.gitignore b/.gitignore index d21792f..35d3411 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ *-source.org # tangled source file -src/* +# src/* # lets add these to the repo so user's don't need Babel # libraries and classes lib/* diff --git a/src/graphs.clj b/src/graphs.clj new file mode 100644 index 0000000..2a1d723 --- /dev/null +++ b/src/graphs.clj @@ -0,0 +1,59 @@ + +(in-ns 'propagator) +(use 'vijual) +(import '(javax.swing JFrame JPanel) + '(java.awt Color Graphics) + '(java.awt.image BufferedImage)) + +;; saving graph information +;; record keeping for graphing propagators +(def prop-graph {}) +(defmacro remember-prop [name in-cells out-cells] + `(def prop-graph + (assoc prop-graph + (quote ~name) + {:in-cells (map (fn [x#] (name x#)) (quote ~in-cells)) + :out-cells (map (fn [x#] (name x#)) (quote ~out-cells))}))) + +(defmacro propagator "Define a new propagator." + [name in-cells out-cells & body] + `(do + (remember-prop ~name ~in-cells ~out-cells) + (defn ~(with-meta name + (assoc (meta name) + :in-cells in-cells :out-cells out-cells)) + ~in-cells ~@body) + (doseq [cell# ~in-cells] (add-neighbor cell# ~name)) + ~name)) + +;; stuff for graphing +(def dim [300 300]) + +(def frame (JFrame.)) + +(defn view "Display a graph generated by vijual" [img] + (let [mult 1.5 + width (* (.getWidth img) mult) + height (* (.getHeight img) mult) + offset 50 + panel (doto (proxy [JPanel] [] + (paint [g] + (.drawImage g img offset offset nil))))] + (doto frame (.add panel) .pack (.setSize (+ offset width) (+ offset height)).show))) + +(defn graph-propagators [] + (vec (set + (apply concat + (map (fn [key] + (let [hsh (get prop-graph key)] + (concat + (map #(vec (list % (name key))) (get hsh :in-cells)) + (map #(vec (list (name key) %)) (get hsh :out-cells))))) + (keys prop-graph)))))) + +(defn view-network [] + (view (draw-directed-graph-image (graph-propagators)))) + +(defn clear-network [] + (def prop-graph {}) + (def frame (JFrame.))) diff --git a/src/heron.clj b/src/heron.clj new file mode 100644 index 0000000..dffe5ae --- /dev/null +++ b/src/heron.clj @@ -0,0 +1,16 @@ + +(in-ns 'propagator) +(cell guess 1) +(cell x 9) +(cell done false) +(cell margin 0.1) + +(propagator enough [x guess] [done] + (Thread/sleep 1000) + (if (< (abs (- (* guess guess) x)) @margin) true false)) + +(propagator heron [x done guess] [guess] + (Thread/sleep 1000) + (if done + guess + (/ (+ guess (/ x guess)) 2.0))) diff --git a/src/propagator.clj b/src/propagator.clj new file mode 100644 index 0000000..6fcf7fd --- /dev/null +++ b/src/propagator.clj @@ -0,0 +1,41 @@ + +(ns + #^{:author "Eric Schulte", + :license "GPLV3", + :doc "Simple concurrent propagator system."} + propagator + (:use clojure.contrib.repl-utils clojure.contrib.math)) + +(defmacro cell "Define a new cell." + [name state] + `(def ~name (agent ~state))) + +(defn set-cell "Set the value of a cell" [cell value] + (send cell (fn [_] value))) + +(defmacro propagator "Define a new propagator." + [name in-cells out-cells & body] + `(do + (defn ~(with-meta name + (assoc (meta name) + :in-cells in-cells :out-cells out-cells)) + ~in-cells ~@body) + (doseq [cell# ~in-cells] (add-neighbor cell# ~name)) + ~name)) + +(defmacro run-propagator + "Run a propagator, first collect the most recent values from all +cells associated with the propagator, then evaluate." + [propagator] + `(let [results# (apply ~propagator (map deref (:in-cells ^#'~propagator)))] + (doseq [cell# (:out-cells ^#'~propagator)] + (when (not (= @cell# results#)) + (send cell# (fn [_#] results#)))) + results#)) + +(defmacro add-neighbor "Add a neighbor to the given cell." + [cell neighbor] + `(add-watcher + ~cell :send + (agent nil :validator (fn [_#] (do (future (run-propagator ~neighbor)) true))) + (fn [_# _#]))) diff --git a/src/web.clj b/src/web.clj new file mode 100644 index 0000000..97a9e81 --- /dev/null +++ b/src/web.clj @@ -0,0 +1,41 @@ + +(load-file "/home/eschulte/src/propagator/src/propagator.clj") +(in-ns 'propagator) +(use 'ring.adapter.jetty) +(use 'clojure.contrib.seq-utils) +(import 'java.util.Date 'java.text.SimpleDateFormat) + +;; cells +(cell names '()) +(cell input "") + +(propagator adder [input names] [names] + (when (> (count (seq input)) 0) + (set (cons (str input " :1") names)))) + +(defn app [req] + (or + ;; page to accept input + (when (= "/" (:uri req)) + {:status 200 + :headers {"Content-Type" "text/html" + "Title" "3000"} + :body (apply str + "
" + "Word: " + "" + "
")}) + ;; dump value into "input" cell + (when (re-matches #"/add" (:uri req)) + (set-cell input (second (re-matches #".+=(.+)" (:query-string req)))) + {:status 303 :headers {"Location" "../list"}}) + ;; render the value of the "list" cell + (when-let [matched (re-matches #"/list" (:uri req))] + {:status 200 + :headers {"Content-Type" "text/html"} + :body (apply str (flatten (list "" + "

another word

")))}))) + +(run-jetty #'app {:port 3000}) -- 2.11.4.GIT