Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
(require '[metamorphic.api :as m]
'[metamorphic.runtime :as rt])
;; Find a single "a"
(let [runtime (-> (m/new-pattern-sequence "just an a")
(m/begin "a" (fn [event & _] (= event "a")))
(rt/initialize-runtime))
events ["b" "c" "a" "d" "q" "a" "r"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a") ("a")]
;; Find "a" then "b" sequentially
(let [runtime (-> (m/new-pattern-sequence "a -> b")
(m/begin "a" (fn [event & _] (= event "a")))
(m/next "b" (fn [event & _] (= event "b")))
(rt/initialize-runtime))
events ["b" "a" "b" "c" "q" "a" "d" "a" "b"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b") ("a" "b")]
;; Find "a", and eventually find "b"
(let [runtime (-> (m/new-pattern-sequence "a -> b")
(m/begin "a" (fn [event & _] (= event "a")))
(m/followed-by "b" (fn [event & _] (= event "b")))
(rt/initialize-runtime))
events ["q" "r" "a" "z" "t" "b" "v"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b")]
;; Find "a", and eventually find "b" repeatedly.
(let [runtime (-> (m/new-pattern-sequence "a -> b")
(m/begin "a" (fn [event & _] (= event "a")))
(m/followed-by-any "b" (fn [event & _] (= event "b")))
(rt/initialize-runtime))
events ["q" "r" "a" "z" "b" "r" "b" "b"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b") ("a" "b") ("a" "b")]
;; Find "a", optionally find "b", then find "c"
(let [runtime (-> (m/new-pattern-sequence "a -> b -> c")
(m/begin "a" (fn [event & _] (= event "a")))
(m/followed-by "b" (fn [event & _] (= event "b")) {:optional? true})
(m/followed-by "c" (fn [event & _] (= event "c")))
(rt/initialize-runtime))
events ["q" "r" "a" "z" "t" "b" "v" "c"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b" "c") ("a" "c")]
;; Find "a" and loop to find as many "b"'s as possible
(let [runtime (-> (m/new-pattern-sequence "a -> b+")
(m/begin "a" (fn [event & _] (= event "a")))
(m/followed-by "b" (fn [event & _] (= event "b")) {:repetition :one-or-more})
(rt/initialize-runtime))
events ["q" "r" "a" "z" "b" "r" "b" "b"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b") ("a" "b" "b") ("a" "b" "b" "b")]
;; Find "a" and loop to find as many "b"'s consecutively as possible
(let [runtime (-> (m/new-pattern-sequence "a -> b+")
(m/begin "a" (fn [event & _] (= event "a")))
(m/followed-by "b" (fn [event & _] (= event "b")) {:repetition :one-or-more
:consecutive? true})
(rt/initialize-runtime))
events ["q" "r" "a" "z" "b" "b" "r" "b"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b") ("a" "b" "b")]
;; Find "a" and loop to find as many "b"'s as combinations as possible
(let [runtime (-> (m/new-pattern-sequence "a -> b+")
(m/begin "a" (λ [event & _] (= event "a")))
(m/followed-by "b" (λ [event & _] (= (first event) \b))
{:repetition :one-or-more
:allow-combinations? true})
(rt/initialize-runtime))
events ["a" "b1" "q" "b2" "r" "b3" "x" "y" "b4"]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [("a" "b1")
;; ("a" "b1" "b2")
;; ("a" "b1" "b2" "b3")
;; ("a" "b1" "b3")
;; ("a" "b1" "b2" "b3" "b4")
;; ("a" "b1" "b2" "b4")
;; ("a" "b1" "b3" "b4")
;; ("a" "b1" "b4")]
;; Find instances of "n" growing by more than 50%, then more than 100%
(defn grew-by-half? [event history pattern-sequence pattern]
(let [previous (first (get @history "stage-1"))]
(>= event (+ previous (* 0.5 previous)))))
(defn grew-by-whole? [event history pattern-sequence pattern]
(let [previous (first (get @history "stage-2"))]
(>= event (* previous 2))))
(let [runtime (-> (m/new-pattern-sequence "percentage growth")
(m/begin "stage-1" (constantly true))
(m/next "stage-2" grew-by-half?)
(m/next "stage-3" grew-by-whole?)
(rt/initialize-runtime))
events [10 16 45 47 123 400]]
(:matches (reduce rt/evaluate-event runtime events)))
;; => [(10 16 45) (47 123 400)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment