diff --git a/README_or_else.md b/README_or_else.md new file mode 100644 index 0000000000000000000000000000000000000000..536fad28fbaea2a1a6ef257444b7dad7e7c2d0a5 --- /dev/null +++ b/README_or_else.md @@ -0,0 +1,139 @@ +# 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 +