diff --git a/src/cljc/mw_engine/core.clj b/src/cljc/mw_engine/core.clj index 34e063b..97f65cf 100644 --- a/src/cljc/mw_engine/core.clj +++ b/src/cljc/mw_engine/core.clj @@ -22,8 +22,7 @@ further rules can be applied to that cell." :author "Simon Brooke"} mw-engine.core - (:require [clojure.string :refer [starts-with?]] - [mw-engine.flow :refer [flow-world]] + (:require [mw-engine.flow :refer [flow-world]] [mw-engine.utils :refer [get-int-or-zero map-world rule-type]] [taoensso.timbre :as l])) @@ -67,9 +66,17 @@ e (.getMessage e) (-> rule meta :lisp) - cell))))] + cell)))) + rule-meta (meta rule)] (when result - (merge result (meta rule))))) + (merge result + {:history (concat + (:history result) + (list {:rule (:source rule-meta) + :rule-type (:rule-type rule-meta) + :generation (get-int-or-zero + result + :generation)}))})))) (defn- apply-rules "Derive a cell from this `cell` of this `world` by applying these `rules`." @@ -84,7 +91,7 @@ (l/warn e (format "Error in `apply-rules`: `%s` (%s) while executing rules on cell `%s`" - e + (-> e .getClass .getName) (.getMessage e) cell)))))) cell)) diff --git a/src/cljc/mw_engine/utils.clj b/src/cljc/mw_engine/utils.clj index 684064e..7a06e6f 100644 --- a/src/cljc/mw_engine/utils.clj +++ b/src/cljc/mw_engine/utils.clj @@ -2,8 +2,8 @@ interpretation of MicroWorld rule." :author "Simon Brooke"} mw-engine.utils - (:require - [clojure.math.combinatorics :as combo])) + (:require [clojure.math.combinatorics :as combo] + [clojure.string :refer [join]])) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; @@ -304,3 +304,43 @@ "Return the rule-type of this compiled `rule`." [rule] (:rule-type (meta rule))) + +(defn history-string + "Return the history of this `cell` as a string for presentation to the user." + [cell] + (join "\n" + (map #(format "%6d: %s" (:generation %) (:rule %)) + (:history cell)))) + +(defn- extend-summary [summary rs rl event] + (str summary + (if rs (format "%d-%d (%d occurances): %s\n" rs + (:generation event) + rl + (:rule event)) + (format "%d: %s\n" (:generation event) + (:rule event))))) + +(defn summarise-history + "Return, as a string, a shorter summary of the history of this cell" + [cell] + (loop [history (rest (:history cell)) + event (first (:history cell)) + prev nil + rs nil + rl 0 + summary ""] + (cond (nil? event) (extend-summary summary rs rl prev) + (= (:rule event) (:rule prev)) (recur + (rest history) + (first history) + event + (or rs (:generation event)) + (inc rl) + summary) + :else (recur (rest history) + (first history) + event + nil + 0 + (extend-summary summary rs (inc rl) event)))))