Skip to content
Snippets Groups Projects
Select Git revision
  • 84dfa08350e8407b7e46e29294e6691abdf2b5d0
  • master default protected
2 results

README_or_else.md

Blame
  • user avatar
    Guilhem Gamard authored
    84dfa083
    History

    Intro

    Simra is a general simulator for automata networks.

    It is a Python library intended to be used interactively: start a REPL, import Simra, type commands (really Python instructions) to build your favourite AN, then call foo.update() to advance one step of the simulation. It is also possible to call foo.unupdate() to roll back in time, how cool is that.

    For now the only output channel is the terminal. If F is an instance of the class AN, then just typing F at the prompt will print a representation of the current state of F. Of course, print(F) also works—Python knows how to change an AN to a sensible string.

    Everything is carefully documented in docstrings, so don't hesitate to type help(something) at a python prompt to get more information about it. Please read at least the docstrings of the classes AN and Node before starting. Beyond that, the source code should be simple and short enough to be read in a few minutes.

    Of course, it is also possible to use Simra as an actual library, i.e., to load it from a script. This is useful to save a complicated AN that you have spent lots of time building, for instance. However, keep in mind that Simra was designed with “interactive usage” performance in mind: don't expect to simulate zillions of steps in 3 seconds. (If more performance is needed, ask Guilhem about Brutal, which serves exactly this purpose.)

    GUI is planned in the future, with the same usage pattern: we'll have a method F.gui() that opens a graphical window displaying the current state of F (and keeps it up to date), maybe with a few key bindings to call methods on F. The console will always be there in the background for complicated maneuvers.

    I recommend using a text editor that pairs with a Python shell, something like Spyder (pretty sure Emacs and Vim can do it as well).

    Example

    Read the docstrings of cycle() and and_not() for explainations. The source of those functions is also a good example of how to use AN and Node.

    >>> from simra import *
    >>> c = cycle([False, True, True], [True, True, True])
    >>> c
    {AN
        {node 0: True}
        {node 1: True}
        {node 2: True}
    }
    >>> c.update()
    >>> c
    {AN
        {node 0: False}
        {node 1: True}
        {node 2: True}
    }
    >>> c.update()
    >>> c
    {AN
        {node 0: False}
        {node 1: False}
        {node 2: True}
    }
    >>> c.unupdate()
    >>> c
    {AN
        {node 0: False}
        {node 1: True}
        {node 2: True}
    }
    >>>
    >>> a = and_not([None, [-2], [-1]], [None, True, True], [[1,2]])
    >>> a
    {AN
        {node 1: True}
        {node 2: True}
    }
    >>> a.update()
    >>> a
    {AN
        {node 1: False}
        {node 2: False}
    }

    Design choices

    There are two classes of interest: Node and AN.

    Each node has a name, that may be any hashable python value and that must be unique in the AN. Nodes are always referenced by names. For instance, a node holds its set of neighbours (dependencies in Simra parlance), and that set is implemented as a list of neighbour names. In the same vein, the update function of a node takes a single argument: a dictionary mapping dependency names to their current state. (Don't worry: update functions are called with a dictionary that contains only the values of the neighbours, nothing else; there is no information leakage.) A node also holds its current state and initial state. Node states may be any Python value, not even necessarily hashable.

    An automata network is just a glorified dictionary mapping names to nodes. It also holds an update mode, which is a list of sets of names—all UMs are represented as periodic UMs. The update pointer, or UP for short, is an index in the UM pointing to the next update to perform. An AN keep deep copies of all its previous states in a history, so it is easy to roll back. Performance is terrible, but that is OK for interactive use.

    Bugs

    No disjoint union

    There is no easy way to merge (in the sense: “disjoint union”) two automata networks for now, although that would be highly desirable. The reason is that we must ensure all names are unique. If we generate two cycles with the cycle() function, for instance, both will have node names 0,…,k-1, so node names will be shared. That will confuse the AN class.

    Although a gensym (generator of unique names) is available, node renaming is not that simple, because we should also change update functions accordingly.

    The solution I am working on is to make node names tuples: the first element is meaningful (like i in a cycle), and the second one marks the connected component of the node. Any better idea is very welcome.

    Your bug here

    Contact

    guilhem.gamard@normale.fr