Commits

Michael Lee committed 676a4f7

Cleaning up Clojure baboons & philosophers examples

  • Participants
  • Parent commits 5d97176

Comments (0)

Files changed (2)

File concur/clojure/baboons.clj

   "Create a sequence of baboon agents with random headings.
    Agent state is an instance of the baboon struct."
   [n]
-  (reduce (fn [s x]
-	    (let [side     ([:west :east] (rand-int 2))
-		  side-ref (if (= side :west) west-side east-side)
-		  agt      (agent (struct baboon x side))]
-	      (dosync (alter side-ref conj @agt))
-	      (conj s agt)))
-          []
-          (range n)))
+  (doall
+   (for [id (range n)]
+     (let [side     ([:west :east] (rand-int 2))
+           side-ref (if (= side :west) west-side east-side)
+           agt      (agent (struct baboon id side))]
+       (dosync (alter side-ref conj @agt))
+       agt))))
 
 ;; our baboons!
 (def baboons (create-baboons num-baboons))
   (Thread/sleep animation-sleep-ms)
   nil)
 
-(send-off animator animation)
-
-;(dorun (map #(send-off % behave) baboons))
-
-;(dorun (map #(send-off % behave-with-drain) baboons))
+(defn start []
+  (def running true)
+  (send-off animator animation)
+  (dorun
+   (for [b baboons]
+     (send-off b behave)
+     ;; (send-off b behave-with-drain)
+     )))

File concur/clojure/philosophers.clj

-(ns cs450.philosophers
-  (:use clojure.pprint))
+(require 'clojure.pprint)
 
 (def running true)
 
 
 ;; forks are just refs to boolean values
 (def forks
-  (repeatedly num-philosophers #(ref false)))
+  (for [_ (range  num-philosophers)]
+    (ref false)))
 
 ;; a philosopher has an id and a state
 (defstruct philosopher :id :state)
 
-;; reporting information / functions
-(defstruct report-state :blocked :eating :thinking)
-
-(def reporter
-  (agent
-   (zipmap (range num-philosophers) (repeatedly #(struct report-state 0 0 0)))))
-
-(defn report-state [report-state id state]
-  (let [p (report-state id)]
-    (println "Philosopher" id "in state" state)
-    (assoc report-state id (assoc p state (inc (p state))))))
-
-;; philosophers are agents (~threads) that wrap their state
+;; philosophers are agents that wrap their state
 (def philosophers
-  (map (fn [id]
-         (agent (struct philosopher id :thinking)))
+  (map #(agent (struct philosopher % :thinking))
        (range num-philosophers)))
 
+;; reporter (see below)
+(declare reporter)
+(declare report-state)
+
 ;; Philosopher behavior ... controls transitions between thinking and eating
 (defn philosophize [philosopher]
   (when running
     (send-off *agent* philosophize))
   (Thread/sleep (rand-int 500))
   (let [left-fork  (nth forks (:id philosopher))
-        right-fork (nth forks (mod (inc (:id philosopher)) num-philosophers))]
+        right-fork (nth forks (mod (inc (:id philosopher))
+                                   num-philosophers))]
     (if (= :thinking (:state philosopher))
       (do (send reporter report-state (:id philosopher) :thinking)
           (dosync
-           (println "Philosopher" (:id philosopher) "getting forks")
            ;; check both forks
            (if (and (not @left-fork) (not @right-fork)) 
              (do (ref-set left-fork  true)
            ;; eating -> sleeping
            (assoc philosopher :state :thinking))))))
 
-(dorun (for [p philosophers] (send-off p philosophize)))
-(Thread/sleep (* 5 1000))
-(shutdown-agents)
-(Thread/sleep 500)  ; wait for agents to shut down
-(pprint @reporter)
+;;; reporting information / functions
+
+(defstruct phil-state-counts :blocked :eating :thinking)
+
+;; reporter wraps a map of phil-id -> phil-state-counts
+(def reporter
+  (agent 
+   (zipmap (range num-philosophers)
+           (repeatedly #(struct phil-state-counts 0 0 0)))))
+
+;; increments a state count for a given philosopher
+(defn report-state [psc-map id state]
+  (let [phil      (psc-map id)
+        count     (phil state)
+        next-phil (assoc phil state (inc count))]
+    (assoc psc-map id next-phil)))
+
+(defn start []
+  (dorun
+   (for [p philosophers]
+     (send-off p philosophize))))
+
+;; (pprint @reporter) ; to take "snapshot"
+