Giter VIP home page Giter VIP logo

devs's Introduction

DEVS - Discrete Event System Specification

This library provides a state machine as data. There is a single, generic "evolve" function that takes the state machine and an input, and produces a new state machine.

Formally, the state machine is specified as a tuple of the following:

  • S - The state alphabet
  • s - The current state
  • A_i - The input alphabet
  • A_o - The output alphabet
  • F - The transition function from (s, A_i) -> n, where n is the next state
  • O - The output function from (C_n+1, A_o) -> o, where o is a symbol from A_o

An easy way to think of this is that the state machine accepts any symbol in the input and "transitions" to a new state based on the current state and that input symbol. As it "transitions," it produces an output from the output alphabet.

In implementation terms, the state machine at any point is immutable. Evolving the state machine means returning a new instance derived from the old one.

This means that you can actually change the transition function when the state machine moves to new states. You can also change the input or output alphabets.

Describing the state machine

Here is an example from an "echo" server:

(defn echo-server-state-machine
  "Construct a DEVS data structure for the echo server protocol."
  [socket]
  (-> {:input-alphabet         #{:read :write :empty :close :empty-buffers}
       :output-alphabet        #{:read :write}
       :state-alphabet         #{:reading :writing :draining :closed}
       :state                  :reading
       :socket                 socket}
      (on-event :read
            (in-state? :reading)
            (new-state :writing))
      (on-event :read
            (in-state? :writing)
            (new-state :writing))
      (on-event :write
            (in-state? :writing)
            (new-state :writing))
      (on-event :write
            (in-state? :draining)
            (guard all-data-drained?
                (generate-event :empty-buffers))
            (new-state :draining))
      (on-event :empty-buffers
            (in-state? :writing)
            (new-state :reading))
      (on-event :empty-buffers
            (in-state? :draining)
            (new-state :closed))
      (on-event :close
            (in-state? :reading)
            (new-state :closed))
      (on-event :close
            (in-state? :writing)
            (new-state :draining))
      (outputs  :reading  (generate [:read]))
      (outputs  :writing  (generate [:read :write]))
      (outputs  :draining (generate [:write]))
      (outputs  :closed   (generate []))))

This code builds a state machine definition by passing maps in to various high-level "builder" functions like on-event. on-event builds up the transition function as a relation over the cross product of S and A_i. This allows a much more compact representation than writing the total function F!

Likewise, outputs is a builder function for the output function. It accumulates states and "generators" for the output tape.

Evolving the state machine

No matter what your alphabets or functions, there is just one function to evolve from one state to the next:

(defn evolve [state-machine input-symbol])

It returns a new state machine. Keep it in an Agent, an Atom, or just a locally bound variable. For example, to process a (hopefully finite) seq of inputs:

(reduce evolve state-machine inputs)

Then when you're done, you can examine the output tape, which is bound to the key :output.

More Info

For more detail about Atomic DEVS, see http://en.wikipedia.org/wiki/DEVS#Atomic_DEVS.

A couple of nuances about this library's implementation:

  • It implements the reactive portion of an Atomic DEVS state machine, but does not handle internal transitions triggered by "collapse" of states from their lifespans elapsing.
  • It allows a series of automatic state transitions to happen atomically. Each automatic transition can generate an output symbol. Thus a single input symbol may result in a series of outputs.

License

Copyright © 2013-2021 Michael T. Nygard

Distributed under the Eclipse Public License.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.