Skip to content

Instantly share code, notes, and snippets.

@mtnygard
Created January 7, 2014 17:48
Show Gist options
  • Select an option

  • Save mtnygard/8303387 to your computer and use it in GitHub Desktop.

Select an option

Save mtnygard/8303387 to your computer and use it in GitHub Desktop.
A really, really minimal state machine with validity checking.
(ns sm)
(defn satisfied?
[machine input [txn-state txn-input guard & _]]
(and (= (:state machine) txn-state) (= input txn-input) (if guard (guard machine input) true)))
(defn evolve
[m i]
(let [[_ _ _ next & actions] (first (filter #(satisfied? m i %) (:transitions m)))
_ (println actions)
m (if (seq actions) ((apply comp (reverse actions)) m) m)
m (assoc m :state next)]
m))
(defn cartesian [xs ys] (for [x xs y ys] [x y]))
(defn transitions [m] (map #(take 2 %) (:transitions m)))
(defn state-machine-problems
[m]
{:missing-transitions (reduce disj (into #{} (cartesian (:state-alphabet m) (:input-alphabet m))) (transitions m))
:illegal-transitions (reduce disj (into #{} (transitions m)) (cartesian (:state-alphabet m) (:input-alphabet m)))})
(comment
(defn started [m _] (:connected m))
(defn send-ack [m] (update-in m [:output] conj :ack))
(def pinger
{:state-alphabet #{:receiving :sending}
:input-alphabet #{:ping}
:state :receiving
:transitions [[:receiving :ping started :sending send-ack]
[:receiving :ping nil :sending]
[:sending nil nil :receiving send-ack]
[:sending :ping nil :sending]]})
(state-machine-problems pinger)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment