Skip to content
Snippets Groups Projects
Commit 84dfa083 authored by Guilhem Gamard's avatar Guilhem Gamard
Browse files

First readme

parent 500c61ff
No related branches found
No related tags found
No related merge requests found
# 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`.
```Python
>>> 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment