Initial commit. A start has been made, but nothing works yet.

This commit is contained in:
Simon Brooke 2023-07-18 22:31:57 +01:00
commit 72d9326216
65 changed files with 3179 additions and 0 deletions

155
resources/doc/grammar.md Normal file
View file

@ -0,0 +1,155 @@
## What this is about
MicroWorld is a rule driven cellular automaton. What does that mean? Well, it's
a two dimensional world made up of squares called **cells**. The world develops
in steps, and at each step, each cell is modified by applying the rules.
The demonstration world is a mountain, with snow at the top and the sea at the
bottom. as you watched, you probably saw the bright green of grass on the lower
slopes of the mountain turn to the darker green of forest. You may have seen
some forest fires break out.
That's all controlled by rules. You make the rules. To start Noah's flood,
[go to the rules page](rules) now, and add this rule at the very top:
if altitude is less than 200 then state should be water
then, [go and watch the world](world) again. What happens? You should see water
spread across everywhere except the very top of the mountain. But after the
flood, the waters should drain away again. Go back to [rules](rules) and add
this rule at the very top:
if altitude is more than 9 and state is water then state should be grassland
Now the world alternates between *new* and *grassland*. That's no good! Go back to
[rules](rules) and delete the rule that you first added - the one that says
if altitude is less than 200 then state should be water
And see! The world starts growing again.
## What you can do next
### Change some rules
Change some of the other rules and see what happens. Very likely, one of the
first things that will happen is that you will get a message like this:
I did not understand 'if state is grassland then 1 chance in 10 state will be heath'
That means that you changed a rule in a way that the engine could no longer
understand it. To find out what the engine will understand, have a look at the
[documentation](docs#grammar).
### Invent some rules of your own
What happens when people come into the world? Where would they make their first
camp? Would they want to be near the water, so they could fish? Would they want
be near fertile grassland, to graze their sheep and cattle?
__Write a rule which adds some camps to the world__
What happens to the land around a camp? Do the people burn down forest to make
new grassland? Do they convert the grassland into meadow, or into crop?
Does growing crops reduce the soil fertility? What makes people decide that their
camp is a good enough place to build a proper house?
__Write some rules which describe this__
How many squares of meadow or crop does it take to feed each house full of people?
What happens when there are too many houses and not enough fields? Can houses
catch fire? What happens to a house which is next to a fire?
How many houses do you need for a market place? Where would people build a
harbour?
### Change the rules completely
I've provided rules which use the MicroWorld cellular automaton to make a simple
model of the changes to land in Europe after the ice age. But you don't have to
use it like that, at all.
[Conway's Game of Life](http://en.wikipedia.org/wiki/Conway's_Game_of_Life) is one
of the famous uses of a cellular automaton. The rules for the Game of Life are
very simple. To set up your game of life you'll need some initialisation rules,
one for every cell you want to start live (we'll use *black* for live, and
*white* for dead):
if x is equal to 4 and y is equal to 4 and state is new then state should be black
Add as many of these as you need for your starting pattern. Then add a rule, after
all those:
if state is new then state should be white
I'll leave you to work out what the rules of life are for yourself, from the
Wiki page I linked to.
**CHEAT** *You'll find other rule sets you can explore if you go to the*
*[Parameters](params) page*.
### Change the engine
If you want to modify the engine itself, you will need
[Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed on
your own computer, and you'll need to download the source, and unpack it.
You will find that there are three packages:
+ __mw-engine__ deals with creating worlds, and transforming them;
+ __mw-parser__ deals with turning the rule language into something the engine can work on;
+ __mw-ui__ is the web site which provides you with a user interface.
For each of these packages, you need to run, in the root directory of the package,
the following command:
lein install
Once you've done that, you'll have everything built. To start a web server for
the application, run the following command in the *mw-ui* directory:
lein ring server
Now you have it working, you can start changing things.
#### Add states
Adding new states is easy:
just add new tiles in *mw-ui/resources/public/img/tiles*. The tiles should be
png (Portable Network Graphics) files, and should be 32 pixels square. The name
of the tile should be the name of your new state. It's good to also edit the file
*mw-ui/resources/public/css/states.css* to add a class for your new state.
#### Change the code
Once you've done all that, you're ready to be really ambitious. Change the code.
Implement some new feature I haven't thought of, or fix bugs I've accidentally
left in.
You'll need an editor. I recommend either [NightCode](https://nightcode.info/),
which is quite small and will run on a Raspberry Pi, or
[LightTable](http://www.lighttable.com/), which is extremely helpful but needs
a more powerful computer.
#### Worthwhile projects
If you would like to work on the engine, there's things that would be worth
improving:
1. Better arithmetic in actions
2. Better arithmetic in conditions - it would be useful to be able to say *'if generation is more than 64 - y then state should be snow'*. This would make the ice retreat in the right direction in the iceage rule set.
3. Better error messages when rules don't parse, explaining where the problem occured *(very hard)*.
4. Make this all work in ClojureScript in the browser, so there's less load on the server and one server can support more users *(quite hard)*.
5. Optimisation: MicroWorld runs quite slowly, you can't really do big maps and one server won't support many users. There must be many ways performance can be improved.
If you make changes which you think improve MicroWorld, please [mail them to me](mailto:simon@journeyman.cc).
Have fun!
## License
Copyright © 2014-2023 [Simon Brooke](mailto:simon@journeyman.cc)
Distributed under the terms of the
[GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)

99
resources/doc/grammar.rtf Normal file
View file

@ -0,0 +1,99 @@
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 What this is about\par}
{\pard \ql \f0 \sa180 \li0 \fi0 MicroWorld is a rule driven cellular automaton. What does that mean? Well, it\u8217's a two dimensional world made up of squares called {\b cells}. The world develops in steps, and at each step, each cell is modified by applying the rules.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 The demonstration world is a mountain, with snow at the top and the sea at the bottom. as you watched, you probably saw the bright green of grass on the lower slopes of the mountain turn to the darker green of forest. You may have seen some forest fires break out.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 That\u8217's all controlled by rules. You make the rules. To start Noah\u8217's flood, {\field{\*\fldinst{HYPERLINK "rules"}}{\fldrslt{\ul
go to the rules page
}}}
now, and add this rule at the very top:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 if altitude is less than 200 then state should be water\par}
{\pard \ql \f0 \sa180 \li0 \fi0 then, {\field{\*\fldinst{HYPERLINK "world"}}{\fldrslt{\ul
go and watch the world
}}}
again. What happens? You should see water spread across everywhere except the very top of the mountain. But after the flood, the waters should drain away again. Go back to {\field{\*\fldinst{HYPERLINK "rules"}}{\fldrslt{\ul
rules
}}}
and add this rule at the very top:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 if altitude is more than 9 and state is water then state should be grassland\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Now the world alternates between {\i new} and {\i grassland}. That\u8217's no good! Go back to {\field{\*\fldinst{HYPERLINK "rules"}}{\fldrslt{\ul
rules
}}}
and delete the rule that you first added - the one that says\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 if altitude is less than 200 then state should be water\par}
{\pard \ql \f0 \sa180 \li0 \fi0 And see! The world starts growing again.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 What you can do next\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Change some rules\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Change some of the other rules and see what happens. Very likely, one of the first things that will happen is that you will get a message like this:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 I did not understand 'if state is grassland then 1 chance in 10 state will be heath'\par}
{\pard \ql \f0 \sa180 \li0 \fi0 That means that you changed a rule in a way that the engine could no longer understand it. To find out what the engine will understand, have a look at the {\field{\*\fldinst{HYPERLINK "docs#grammar"}}{\fldrslt{\ul
documentation
}}}
.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Invent some rules of your own\par}
{\pard \ql \f0 \sa180 \li0 \fi0 What happens when people come into the world? Where would they make their first camp? Would they want to be near the water, so they could fish? Would they want be near fertile grassland, to graze their sheep and cattle?\par}
{\pard \ql \f0 \sa180 \li0 \fi0 {\b Write a rule which adds some camps to the world}\par}
{\pard \ql \f0 \sa180 \li0 \fi0 What happens to the land around a camp? Do the people burn down forest to make new grassland? Do they convert the grassland into meadow, or into crop?\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Does growing crops reduce the soil fertility? What makes people decide that their camp is a good enough place to build a proper house?\par}
{\pard \ql \f0 \sa180 \li0 \fi0 {\b Write some rules which describe this}\par}
{\pard \ql \f0 \sa180 \li0 \fi0 How many squares of meadow or crop does it take to feed each house full of people? What happens when there are too many houses and not enough fields? Can houses catch fire? What happens to a house which is next to a fire?\par}
{\pard \ql \f0 \sa180 \li0 \fi0 How many houses do you need for a market place? Where would people build a harbour?\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Change the rules completely\par}
{\pard \ql \f0 \sa180 \li0 \fi0 I\u8217've provided rules which use the MicroWorld cellular automaton to make a simple model of the changes to land in Europe after the ice age. But you don\u8217't have to use it like that, at all.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 {\field{\*\fldinst{HYPERLINK "http://en.wikipedia.org/wiki/Conway's_Game_of_Life"}}{\fldrslt{\ul
Conway\u8217's Game of Life
}}}
is one of the famous uses of a cellular automaton. The rules for the Game of Life are very simple. To set up your game of life you\u8217'll need some initialisation rules, one for every cell you want to start live (we\u8217'll use {\i black} for live, and {\i white} for dead):\par}
{\pard \ql \f0 \sa180 \li0 \fi0 if x is equal to 4 and y is equal to 4 and state is new then state should be black\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Add as many of these as you need for your starting pattern. Then add a rule, after all those:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 if state is new then state should be white\par}
{\pard \ql \f0 \sa180 \li0 \fi0 I\u8217'll leave you to work out what the rules of life are for yourself, from the Wiki page I linked to.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 {\b CHEAT} {\i You\u8217'll find other rule sets you can explore if you go to the} {\i {\field{\*\fldinst{HYPERLINK "params"}}{\fldrslt{\ul
Parameters
}}}
page}.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Change the engine\par}
{\pard \ql \f0 \sa180 \li0 \fi0 If you want to modify the engine itself, you will need {\field{\*\fldinst{HYPERLINK "https://github.com/technomancy/leiningen"}}{\fldrslt{\ul
Leiningen
}}}
2.0 or above installed on your own computer, and you\u8217'll need to download the source, and unpack it.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 You will find that there are three packages:\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\b mw-engine} deals with creating worlds, and transforming them;\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\b mw-parser} deals with turning the rule language into something the engine can work on;\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab {\b mw-ui} is the web site which provides you with a user interface.\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 For each of these packages, you need to run, in the root directory of the package, the following command:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 lein install\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Once you\u8217've done that, you\u8217'll have everything built. To start a web server for the application, run the following command in the {\i mw-ui} directory:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 lein ring server\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Now you have it working, you can start changing things.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs24 Add states\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Adding new states is easy: just add new tiles in {\i mw-ui/resources/public/img/tiles}. The tiles should be png (Portable Network Graphics) files, and should be 32 pixels square. The name of the tile should be the name of your new state. It\u8217's good to also edit the file {\i mw-ui/resources/public/css/states.css} to add a class for your new state.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs24 Change the code\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Once you\u8217've done all that, you\u8217're ready to be really ambitious. Change the code. Implement some new feature I haven\u8217't thought of, or fix bugs I\u8217've accidentally left in.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 You\u8217'll need an editor. I recommend either {\field{\*\fldinst{HYPERLINK "https://nightcode.info/"}}{\fldrslt{\ul
NightCode
}}}
, which is quite small and will run on a Raspberry Pi, or {\field{\*\fldinst{HYPERLINK "http://www.lighttable.com/"}}{\fldrslt{\ul
LightTable
}}}
, which is extremely helpful but needs a more powerful computer.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs24 Worthwhile projects\par}
{\pard \ql \f0 \sa180 \li0 \fi0 If you would like to work on the engine, there\u8217's things that would be worth improving:\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 1.\tx360\tab Better arithmetic in actions\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 2.\tx360\tab Better arithmetic in conditions - it would be useful to be able to say {\i \u8216'if generation is more than 64 - y then state should be snow\u8217'}. This would make the ice retreat in the right direction in the iceage rule set.\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 3.\tx360\tab Better error messages when rules don\u8217't parse, explaining where the problem occured {\i (very hard)}.\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 4.\tx360\tab Make this all work in ClojureScript in the browser, so there\u8217's less load on the server and one server can support more users {\i (quite hard)}.\par}
{\pard \ql \f0 \sa0 \li360 \fi-360 5.\tx360\tab Optimisation: MicroWorld runs quite slowly, you can\u8217't really do big maps and one server won\u8217't support many users. There must be many ways performance can be improved.\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 If you make changes which you think improve MicroWorld, please {\field{\*\fldinst{HYPERLINK "mailto:simon@journeyman.cc"}}{\fldrslt{\ul
mail them to me
}}}
.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Have fun!\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 License\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Copyright \u169? 2014-2023 {\field{\*\fldinst{HYPERLINK "mailto:simon@journeyman.cc"}}{\fldrslt{\ul
Simon Brooke
}}}
\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Distributed under the terms of the {\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/gpl-2.0.html"}}{\fldrslt{\ul
GNU General Public License v2
}}}
\par}

148
resources/doc/markdown.css Normal file
View file

@ -0,0 +1,148 @@
* {
-fx-line-spacing: 4;
-fx-font-family: Ubuntu;
-fx-font-size: 14;
-fx-text-fill: #ddd;
-fx-fill: #ddd;
}
.root {
-fx-background-color: #444;
}
.scroll-pane {
-fx-background-color: transparent;
bottom-padding: 2em;
-fx-bottom-padding: 2em;
}
.scroll-pane > .viewport {
-fx-background-color: transparent;
padding: 3em;
}
.scroll-pane > .scroll-bar {
-fx-background-color: transparent;
}
.scroll-pane > .scroll-bar > .increment-button,
.scroll-pane > .scroll-bar > .increment-button > .increment-arrow,
.scroll-pane > .scroll-bar > .decrement-button,
.scroll-pane > .scroll-bar > .decrement-button > .decrement-arrow {
-fx-padding: 0;
}
.scroll-pane > .corner {
-fx-background-color: transparent;
}
.scroll-pane > .scroll-bar > .thumb {
-fx-background-color: #888;
-fx-background-radius: 10;
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane > .scroll-bar > .track {
-fx-background-color: #0002;
-fx-background-radius: 10;
}
.scroll-pane > .scroll-bar:vertical {
-fx-pref-width: 10;
}
.scroll-pane > .scroll-bar:horizontal {
-fx-pref-height: 10;
}
.document {
-fx-padding: 30;
}
.heading.level-1 {
-fx-padding: 16 0 0 0;
}
.heading.level-1 * {
-fx-font-weight: bold;
-fx-font-size: 30;
}
.heading.level-2 {
-fx-padding: 14 0 0 0;
}
.heading.level-2 * {
-fx-font-weight: bold;
-fx-font-size: 26;
}
.heading.level-3 {
-fx-padding: 12 0 0 0;
}
.heading.level-3 * {
-fx-font-weight: bold;
-fx-font-size: 22;
}
.heading.level-4 {
-fx-padding: 10 0 0 0;
}
.heading.level-4 * {
-fx-font-weight: bold;
-fx-font-size: 20;
}
.heading.level-5 {
-fx-padding: 8 0 0 0;
}
.heading.level-5 * {
-fx-font-weight: bold;
-fx-font-size: 18;
}
.paragraph {
-fx-padding: 10 0 0 0;
}
.code {
-fx-background-color: #0002;
-fx-background-radius: 4;
-fx-background-insets: -1;
}
.code * {
-fx-font-family: "Ubuntu Mono";
}
.code-block {
-fx-padding: 10;
-fx-margin: 10;
-fx-background-color: #0002;
-fx-background-radius: 4;
}
.code-block * {
-fx-font-family: "Ubuntu Mono";
}
.hyperlink {
-fx-border-color: transparent;
-fx-padding: 0;
}
.hyperlink * {
-fx-border-color: transparent;
-fx-padding: 0;
-fx-fill: #9ce;
}
.hyperlink:visited {
-fx-underline: false;
}
.hyperlink:hover {
-fx-underline: true;
}
.md-list {
-fx-padding: 0 0 0 20;
}
.strong-emphasis {
-fx-font-weight: bold;
}
.emphasis {
-fx-font-style: italic;
}
.input {
-fx-font-family: "Ubuntu Mono";
}

216
resources/doc/mw-parser.md Normal file
View file

@ -0,0 +1,216 @@
# mw-parser
A rule parser for MicroWorld
## Part of the overall MicroWorld system
While this code works and is interesting on its own, you also need at least
[mw-engine](https://github.com/simon-brooke/mw-engine) and
[mw-ui](https://github.com/simon-brooke/mw-ui). There will be other
modules in due course.
You can see MicroWorld in action [here](http://www.journeyman.cc/microworld/) -
but please don't be mean to my poor little server. If you want to run big maps
or complex rule-sets, please run it on your own machines.
## Usage
Main entry point is (parse-rule _string_), where string takes a form detailed
in __[grammar](#grammar)__, below. If the rule is interpretted correctly the result will
be the source code of a Clojure anonymous function; if the rule cannot be interpretted,
an error 'I did not understand...' will be shown.
The function (compile-rule _string_) is like parse-rule, except that it returns
a compiled Clojure anonymous function.
### Generated function and evaluation environment
The generated function is a function of two arguments
+ __cell__ a cell in a world as defined in mw-engine.world, q.v.;
+ __world__ the world of which that cell forms part.
It returns a new cell, based on the cell passed.
Actions of the rule will (can only) modify properties of the cell; there are two
properties which are special and SHOULD NOT be modified, namely the properties
__x__ and __y__.
### Execution
Each time the world is transformed, exactly the same set of rules is applied to every
cell. The rules are applied to the cell in turn, in the order in which they are
written in the rule text, until the conditions of one of them match the cell.
The actions of that rule are then used to transform the cell, and the rest of
the rules are not applied.
So, for example, if your first rule is
if x is more than -1 then state should be new
then no matter what your other rules are, your world will never change, because
all cells have x more than -1.
If you are having problems because one of your rules isn't working, look to
see whether there is another rule above it which is 'blocking' it.
### <a name="grammar"></a>Grammar
#### Comments
+ Any line which starts with the hash character (#) is ignored;
+ Any line which starts with a semi-colon (;) is ignored.
#### Rules
A rule comprises:
+ if _conditions_ then _actions_
Each rule must be on a single line. There should be nothing else on that line.
#### Conditions
In rules, _conditions_ is one of:
+ _condition_
+ _condition_ and _conditions_
+ _condition_ or _conditions_
Note that 'and' takes precedence over or, so
conditionA and conditionB or conditionC and conditionD
is interpreted as
(conditionA and (conditionB or (conditionC and conditionD)))
A _condition_ is one of:
+ _property_ is _value_
+ _property_ is not _value_
+ _property_ is in _values_
+ _property_ is not in _values_
+ _property_ is more than _numeric-value_
+ _property_ is less than _numeric-value_
+ _number_ neighbours have _property_ equal to _value_
+ _number_ neighbours have _property_ more than _numeric-value_
+ _number_ neighbours have _property_ less than _numeric-value_
+ more than _number_ neighbours have _property_ equal to _value_
+ fewer than _number_ neighbours have _property_ equal to _value_
+ some neighbours have _property_ equal to _value_
+ more than _number_ neighbours have _property_ more than _numeric-value_
+ fewer than _number_ neighbours have _property_ more than _numeric-value_
+ some neighbours have _property_ more than _numeric-value_
+ more than _number_ neighbours have _property_ less than _numeric-value_
+ fewer than _number_ neighbours have _property_ less than _numeric-value_
+ some neighbours have _property_ less than _numeric-value_
#### About neighbours
Note that everywhere above I've used 'neighbours', you can use 'neighbours
within _distance_', where _distance_ is a (small) positive integer.
A cell has eight immediate neighbours - cells which actually touch it (except
for cells on the edge of the map, which have fewer). If the cell we're
interested in is the cell marked 'X' in the table below, its immediate neighbours
are the ones marked '1'. But outside the ones marked '1', it has more distant
neighbours - those marked '2' and '3' in the table, and still more outside those.
<table style="padding-left: 20%;">
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: green;">1</td><td style="color:white; width: 1.5em; background-color: red;">X</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: green;">1</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: lime;">2</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
<tr><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td><td style="width: 1.5em; background-color: chartreuse;">3</td></tr>
</table>
If a rule just says 'neighbours', and not 'neighbours within', it means
'neighbours within 1'; so
if some neighbours are scrub then state should be scrub
has exactly the same meaning as
if some neighbours within 1 are scrub then state should be scrub
#### Actions
In these rules, _actions_ is one of:
+ _action_
+ _action_ and _actions_
and _action_ is:
+ _property_ should be _value_
+ _number_ chance in _number_ _property_ should be _value_
#### Properties
In the above, _property_ is the name of any property of a cell. Any alpha-numeric
string of characters can form the name of a property. Actions should __NOT__
try to change the reserved properties __x__ and __y__.
#### Values in Conditions
Values in conditions and actions are considered slightly differently. In a
condition, a value is one of:
+ _symbolic-value_
+ _numeric-value_
The '...more than...' and '...less than...' conditions imply a _numeric-value_.
Thus "if altitude is more than fertility..." is interpreted as meaning "if the value
of the property of the current cell called 'altitude' is greater than the value
of the property of the current cell called 'fertility'", whereas the apparently
similar condition 'if altitude is fertility...' is interpreted as meaning
"if the value of the property of the current cell called 'altitude' is the symbol
'fertility'".
Thus _symbolic-value_ is any sequence of alphanumeric characters, whereas
_numeric-value_ is one of:
+ _number_
+ _property_
and _number_ is any sequence of the decimal digits 0...9, the minus character
'-' and the period character '.', provided that the minus character can only be
in the first position, and the period character can only appear once.
#### Values in Actions
A _value_ in an action is one of
+ _symbolic-value_
+ _arithmetic-value_
+ _number_
where _arithmetic-value_ is:
+ _property_ _operator_ _numeric-value_
and _operator_ is one of the simple arithmetic operators '+', '-', '*' and '/'.
### Shorthand
Note that '...neighbours are...' is equivalent to '...neighbours have state equal to...',
and 'some neighbours...' is equivalent to 'more than 0 neighbours...'
### Roadmap
The existing parser, *mw-parser.core*, works but is not well written. A much
better parser which does not yet completely work, *mw-parser.insta*, is also
included for the adventurous.
I intend to replace *mw-parser.core* with *mw-parser.insta* as soon as
*mw-parser.insta* correctly parses all the test rules.
## License
Copyright © 2014 [Simon Brooke](mailto:simon@journeyman.cc)
Distributed under the terms of the
[GNU General Public License v2](http://www.gnu.org/licenses/gpl-2.0.html)

749
resources/doc/mw-parser.rtf Normal file
View file

@ -0,0 +1,749 @@
{\rtf1\ansi\deff4\adeflang1025
{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\froman\fprq2\fcharset0 Cambria;}{\f5\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f6\froman\fprq2\fcharset0 Calibri;}{\f7\froman\fprq2\fcharset0 Consolas;}{\f8\fnil\fprq2\fcharset0 DejaVu Sans;}{\f9\fnil\fprq2\fcharset0 ;}{\f10\fnil\fprq2\fcharset0 Droid Sans Devanagari;}{\f11\fswiss\fprq0\fcharset128 Droid Sans Devanagari;}}
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red52\green90\blue138;\red79\green129\blue189;\red54\green95\blue145;\red186\green33\blue33;\red144\green32\blue0;\red64\green160\blue112;\red0\green112\blue32;\red187\green102\blue136;\red136\green0\blue0;\red64\green112\blue160;\red96\green160\blue176;\red25\green23\blue124;\red6\green40\blue126;\red102\green102\blue102;\red125\green144\blue41;\red188\green122\blue0;}
{\stylesheet{\s0\snext0\rtlch\af9\afs24\alang1025 \ltrch\lang1033\langfe1033\hich\af4\loch\ql\widctlpar\sb0\sa200\ltrpar\hyphpar0\cf0\f4\fs24\lang1033\kerning0\dbch\af12\langfe1033 Normal;}
{\s1\sbasedon0\snext162\rtlch\af9\afs32\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb480\sa0\keepn\ltrpar\cf18\f6\fs32\b\dbch\af9 Heading 1;}
{\s2\sbasedon0\snext162\rtlch\af9\afs28\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs28\b\dbch\af9 Heading 2;}
{\s3\sbasedon0\snext162\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\b\dbch\af9 Heading 3;}
{\s4\sbasedon0\snext162\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9 Heading 4;}
{\s5\sbasedon0\snext162\rtlch\af9\afs24\ai \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\dbch\af9 Heading 5;}
{\s6\sbasedon0\snext162\rtlch\af9\afs24 \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\dbch\af9 Heading 6;}
{\s7\sbasedon0\snext162\rtlch\af9\afs24 \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\dbch\af9 Heading 7;}
{\s8\sbasedon0\snext162\rtlch\af9\afs24 \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\dbch\af9 Heading 8;}
{\s9\sbasedon0\snext162\rtlch\af9\afs24 \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\dbch\af9 Heading 9;}
{\*\cs15\snext15 Default Paragraph Font;}
{\*\cs16\sbasedon15\snext16 Body Text Char;}
{\*\cs17\sbasedon16\snext17\hich\af7\loch\f7\fs22 Verbatim Char;}
{\*\cs18\sbasedon16\snext18 Section Number;}
{\*\cs19\sbasedon16\snext19\loch\super Footnote Characters;}
{\*\cs20\snext20\loch\super Footnote Anchor;}
{\*\cs21\sbasedon16\snext21\loch\cf18 Hyperlink;}
{\*\cs22\sbasedon17\snext22\hich\af7\loch\cf23\f7\fs22\b KeywordTok;}
{\*\cs23\sbasedon17\snext23\hich\af7\loch\cf21\f7\fs22 DataTypeTok;}
{\*\cs24\sbasedon17\snext24\hich\af7\loch\cf22\f7\fs22 DecValTok;}
{\*\cs25\sbasedon17\snext25\hich\af7\loch\cf22\f7\fs22 BaseNTok;}
{\*\cs26\sbasedon17\snext26\hich\af7\loch\cf22\f7\fs22 FloatTok;}
{\*\cs27\sbasedon17\snext27\hich\af7\loch\cf25\f7\fs22 ConstantTok;}
{\*\cs28\sbasedon17\snext28\hich\af7\loch\cf26\f7\fs22 CharTok;}
{\*\cs29\sbasedon17\snext29\hich\af7\loch\cf26\f7\fs22 SpecialCharTok;}
{\*\cs30\sbasedon17\snext30\hich\af7\loch\cf26\f7\fs22 StringTok;}
{\*\cs31\sbasedon17\snext31\hich\af7\loch\cf26\f7\fs22 VerbatimStringTok;}
{\*\cs32\sbasedon17\snext32\hich\af7\loch\cf24\f7\fs22 SpecialStringTok;}
{\*\cs33\sbasedon17\snext33\hich\af7\loch\cf11\f7\fs22\b ImportTok;}
{\*\cs34\sbasedon17\snext34\hich\af7\loch\cf27\f7\fs22\i CommentTok;}
{\*\cs35\sbasedon17\snext35\hich\af7\loch\cf20\f7\fs22\i DocumentationTok;}
{\*\cs36\sbasedon17\snext36\hich\af7\loch\cf27\f7\fs22\i\b AnnotationTok;}
{\*\cs37\sbasedon17\snext37\hich\af7\loch\cf27\f7\fs22\i\b CommentVarTok;}
{\*\cs38\sbasedon17\snext38\hich\af7\loch\cf23\f7\fs22 OtherTok;}
{\*\cs39\sbasedon17\snext39\hich\af7\loch\cf29\f7\fs22 FunctionTok;}
{\*\cs40\sbasedon17\snext40\hich\af7\loch\cf28\f7\fs22 VariableTok;}
{\*\cs41\sbasedon17\snext41\hich\af7\loch\cf23\f7\fs22\b ControlFlowTok;}
{\*\cs42\sbasedon17\snext42\hich\af7\loch\cf30\f7\fs22 OperatorTok;}
{\*\cs43\sbasedon17\snext43\hich\af7\loch\cf11\f7\fs22 BuiltInTok;}
{\*\cs44\sbasedon17\snext44\hich\af7\loch\f7\fs22 ExtensionTok;}
{\*\cs45\sbasedon17\snext45\hich\af7\loch\cf32\f7\fs22 PreprocessorTok;}
{\*\cs46\sbasedon17\snext46\hich\af7\loch\cf31\f7\fs22 AttributeTok;}
{\*\cs47\sbasedon17\snext47\hich\af7\loch\f7\fs22 RegionMarkerTok;}
{\*\cs48\sbasedon17\snext48\hich\af7\loch\cf27\f7\fs22\i\b InformationTok;}
{\*\cs49\sbasedon17\snext49\hich\af7\loch\cf27\f7\fs22\i\b WarningTok;}
{\*\cs50\sbasedon17\snext50\hich\af7\loch\cf6\f7\fs22\b AlertTok;}
{\*\cs51\sbasedon17\snext51\hich\af7\loch\cf6\f7\fs22\b ErrorTok;}
{\*\cs52\sbasedon17\snext52\hich\af7\loch\f7\fs22 NormalTok;}
{\*\cs53\snext53 ListLabel 1;}
{\*\cs54\snext54 ListLabel 2;}
{\*\cs55\snext55 ListLabel 3;}
{\*\cs56\snext56 ListLabel 4;}
{\*\cs57\snext57 ListLabel 5;}
{\*\cs58\snext58 ListLabel 6;}
{\*\cs59\snext59 ListLabel 7;}
{\*\cs60\snext60 ListLabel 8;}
{\*\cs61\snext61 ListLabel 9;}
{\*\cs62\snext62 ListLabel 10;}
{\*\cs63\snext63 ListLabel 11;}
{\*\cs64\snext64 ListLabel 12;}
{\*\cs65\snext65 ListLabel 13;}
{\*\cs66\snext66 ListLabel 14;}
{\*\cs67\snext67 ListLabel 15;}
{\*\cs68\snext68 ListLabel 16;}
{\*\cs69\snext69 ListLabel 17;}
{\*\cs70\snext70 ListLabel 18;}
{\*\cs71\snext71 ListLabel 19;}
{\*\cs72\snext72 ListLabel 20;}
{\*\cs73\snext73 ListLabel 21;}
{\*\cs74\snext74 ListLabel 22;}
{\*\cs75\snext75 ListLabel 23;}
{\*\cs76\snext76 ListLabel 24;}
{\*\cs77\snext77 ListLabel 25;}
{\*\cs78\snext78 ListLabel 26;}
{\*\cs79\snext79 ListLabel 27;}
{\*\cs80\snext80 ListLabel 28;}
{\*\cs81\snext81 ListLabel 29;}
{\*\cs82\snext82 ListLabel 30;}
{\*\cs83\snext83 ListLabel 31;}
{\*\cs84\snext84 ListLabel 32;}
{\*\cs85\snext85 ListLabel 33;}
{\*\cs86\snext86 ListLabel 34;}
{\*\cs87\snext87 ListLabel 35;}
{\*\cs88\snext88 ListLabel 36;}
{\*\cs89\snext89 ListLabel 37;}
{\*\cs90\snext90 ListLabel 38;}
{\*\cs91\snext91 ListLabel 39;}
{\*\cs92\snext92 ListLabel 40;}
{\*\cs93\snext93 ListLabel 41;}
{\*\cs94\snext94 ListLabel 42;}
{\*\cs95\snext95 ListLabel 43;}
{\*\cs96\snext96 ListLabel 44;}
{\*\cs97\snext97 ListLabel 45;}
{\*\cs98\snext98 ListLabel 46;}
{\*\cs99\snext99 ListLabel 47;}
{\*\cs100\snext100 ListLabel 48;}
{\*\cs101\snext101 ListLabel 49;}
{\*\cs102\snext102 ListLabel 50;}
{\*\cs103\snext103 ListLabel 51;}
{\*\cs104\snext104 ListLabel 52;}
{\*\cs105\snext105 ListLabel 53;}
{\*\cs106\snext106 ListLabel 54;}
{\*\cs107\snext107 ListLabel 55;}
{\*\cs108\snext108 ListLabel 56;}
{\*\cs109\snext109 ListLabel 57;}
{\*\cs110\snext110 ListLabel 58;}
{\*\cs111\snext111 ListLabel 59;}
{\*\cs112\snext112 ListLabel 60;}
{\*\cs113\snext113 ListLabel 61;}
{\*\cs114\snext114 ListLabel 62;}
{\*\cs115\snext115 ListLabel 63;}
{\*\cs116\snext116 ListLabel 64;}
{\*\cs117\snext117 ListLabel 65;}
{\*\cs118\snext118 ListLabel 66;}
{\*\cs119\snext119 ListLabel 67;}
{\*\cs120\snext120 ListLabel 68;}
{\*\cs121\snext121 ListLabel 69;}
{\*\cs122\snext122 ListLabel 70;}
{\*\cs123\snext123 ListLabel 71;}
{\*\cs124\snext124 ListLabel 72;}
{\*\cs125\snext125 ListLabel 73;}
{\*\cs126\snext126 ListLabel 74;}
{\*\cs127\snext127 ListLabel 75;}
{\*\cs128\snext128 ListLabel 76;}
{\*\cs129\snext129 ListLabel 77;}
{\*\cs130\snext130 ListLabel 78;}
{\*\cs131\snext131 ListLabel 79;}
{\*\cs132\snext132 ListLabel 80;}
{\*\cs133\snext133 ListLabel 81;}
{\*\cs134\snext134 ListLabel 82;}
{\*\cs135\snext135 ListLabel 83;}
{\*\cs136\snext136 ListLabel 84;}
{\*\cs137\snext137 ListLabel 85;}
{\*\cs138\snext138 ListLabel 86;}
{\*\cs139\snext139 ListLabel 87;}
{\*\cs140\snext140 ListLabel 88;}
{\*\cs141\snext141 ListLabel 89;}
{\*\cs142\snext142 ListLabel 90;}
{\*\cs143\snext143 ListLabel 91;}
{\*\cs144\snext144 ListLabel 92;}
{\*\cs145\snext145 ListLabel 93;}
{\*\cs146\snext146 ListLabel 94;}
{\*\cs147\snext147 ListLabel 95;}
{\*\cs148\snext148 ListLabel 96;}
{\*\cs149\snext149 ListLabel 97;}
{\*\cs150\snext150 ListLabel 98;}
{\*\cs151\snext151 ListLabel 99;}
{\*\cs152\snext152 ListLabel 100;}
{\*\cs153\snext153 ListLabel 101;}
{\*\cs154\snext154 ListLabel 102;}
{\*\cs155\snext155 ListLabel 103;}
{\*\cs156\snext156 ListLabel 104;}
{\*\cs157\snext157 ListLabel 105;}
{\*\cs158\snext158 ListLabel 106;}
{\*\cs159\snext159 ListLabel 107;}
{\*\cs160\snext160 ListLabel 108;}
{\s161\sbasedon0\snext162\rtlch\af10\afs28 \ltrch\hich\af5\loch\ql\widctlpar\sb240\sa120\keepn\ltrpar\f5\fs28\dbch\af8 Heading;}
{\s162\sbasedon0\snext162\loch\ql\widctlpar\sb180\sa180\ltrpar Text Body;}
{\s163\sbasedon162\snext163\rtlch\af11 \ltrch\loch\ql\widctlpar\sb180\sa180\ltrpar List;}
{\s164\sbasedon0\snext164\loch\ql\widctlpar\sb0\sa120\ltrpar\i Caption;}
{\s165\sbasedon0\snext165\rtlch\af11\alang255 \ltrch\lang255\langfe255\loch\ql\widctlpar\sb0\sa200\noline\ltrpar\lang255\dbch\langfe255 Index;}
{\s166\sbasedon162\snext162\loch\ql\widctlpar\sb180\sa180\ltrpar First Paragraph;}
{\s167\sbasedon162\snext167\loch\ql\widctlpar\sb36\sa36\ltrpar Compact;}
{\s168\sbasedon0\snext162\rtlch\af9\afs36\ab \ltrch\hich\af6\loch\qc\keep\widctlpar\sb480\sa240\keepn\ltrpar\cf17\f6\fs36\b\dbch\af9 Title;}
{\s169\sbasedon168\snext162\rtlch\af9\afs30\ab \ltrch\hich\af6\loch\qc\keep\widctlpar\sb240\sa240\keepn\ltrpar\cf17\f6\fs30\b\dbch\af9 Subtitle;}
{\s170\snext162\rtlch\af9\afs24\alang1025 \ltrch\lang1033\langfe1033\hich\af4\loch\qc\keep\widctlpar\sb0\sa200\keepn\ltrpar\hyphpar0\cf0\f4\fs24\lang1033\kerning0\dbch\af12\langfe1033 Author;}
{\s171\snext162\rtlch\af9\afs24\alang1025 \ltrch\lang1033\langfe1033\hich\af4\loch\qc\keep\widctlpar\sb0\sa200\keepn\ltrpar\hyphpar0\cf0\f4\fs24\lang1033\kerning0\dbch\af12\langfe1033 Date;}
{\s172\sbasedon0\snext162\rtlch\afs20 \ltrch\loch\ql\keep\widctlpar\sb300\sa300\keepn\ltrpar\fs20 Abstract;}
{\s173\sbasedon0\snext173\loch\ql\widctlpar\sb0\sa200\ltrpar Bibliography;}
{\s174\sbasedon162\snext162\loch\ql\widctlpar\li480\ri480\lin480\rin480\fi0\sb100\sa100\ltrpar Block Text;}
{\s175\sbasedon0\snext175\loch\ql\widctlpar\sb0\sa200\ltrpar Footnote;}
{\s176\sbasedon0\snext177\loch\ql\keep\widctlpar\sb0\sa0\keepn\ltrpar\b Definition Term;}
{\s177\sbasedon0\snext177\loch\ql\widctlpar\sb0\sa200\ltrpar Definition;}
{\s178\sbasedon164\snext178\loch\ql\widctlpar\sb0\sa120\keepn\ltrpar\i Table Caption;}
{\s179\sbasedon164\snext179\loch\ql\widctlpar\sb0\sa120\ltrpar\i Image Caption;}
{\s180\sbasedon0\snext180\loch\ql\widctlpar\sb0\sa200\ltrpar Figure;}
{\s181\sbasedon180\snext181\loch\ql\widctlpar\sb0\sa200\keepn\ltrpar Captioned Figure;}
{\s182\sbasedon161\snext182\rtlch\af10\afs28 \ltrch\hich\af5\loch\ql\widctlpar\sb240\sa120\keepn\ltrpar\f5\fs28\dbch\af8 Index Heading;}
{\s183\sbasedon1\snext162\rtlch\af9\afs32\ab0 \ltrch\hich\af6\loch\sl259\slmult1\ql\keep\widctlpar\sb240\sa0\keepn\ltrpar\cf19\f6\fs32\b0\dbch\af9 Contents Heading;}
{\s184\sbasedon0\snext184\loch\ql\widctlpar\sb0\sa200\ltrpar Source Code;}
}{\*\listtable{\list\listtemplateid1
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid1}
{\list\listtemplateid2
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid2}
{\list\listtemplateid3
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid3}
{\list\listtemplateid4
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid4}
{\list\listtemplateid5
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid5}
{\list\listtemplateid6
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid6}
{\list\listtemplateid7
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid7}
{\list\listtemplateid8
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid8}
{\list\listtemplateid9
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid9}
{\list\listtemplateid10
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid10}
{\list\listtemplateid11
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8211 ?;}{\levelnumbers;}\f13\fi-480\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat0\levelfollow0{\leveltext \'01\u8226 ?;}{\levelnumbers;}\f13\fi-480\li6480}\listid11}
{\list\listtemplateid12
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}
{\listlevel\levelnfc255\leveljc0\levelstartat1\levelfollow2{\leveltext \'00;}{\levelnumbers;}\fi0\li0}\listid12}
}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}{\listoverride\listid12\listoverridecount0\ls12}}{\*\generator LibreOffice/7.3.7.2$Linux_X86_64 LibreOffice_project/e114eadc50a9ff8d8c8a0567d6da8f454beeb84f}{\info{\creatim\yr2023\mo7\dy17\hr20\min42}{\revtim\yr2023\mo7\dy17\hr20\min42}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops{\propname AppVersion}\proptype30{\staticval 12.0000}}\deftab720\deftab720\deftab720
\hyphauto1\viewscale100
{\*\pgdsctbl
{\pgdsc0\pgdscuse451\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\pgdscnxt0 Default Page Style;}}
\formshade\paperh15840\paperw12240\margl1440\margr1440\margt1440\margb1440\sectd\sbknone\pgndec\sftnnar\saftnnrlc\sectunlocked1\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc\htmautsp
{\*\ftnsep\chftnsep}\pgndec\pard\plain \s1\rtlch\af9\afs32\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb480\sa0\keepn\ltrpar\cf18\f6\fs32\b\dbch\af9\keep\sb480\sa0\keepn{\loch
{\*\bkmkstart mw-parser}mw-parser}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
A rule parser for MicroWorld}
\par \pard\plain \s2\rtlch\af9\afs28\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs28\b\dbch\af9{\loch
{\*\bkmkstart part-of-the-overall-microworld-system}Part of the overall MicroWorld system}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
While this code works and is interesting on its own, you also need at least }{{\field{\*\fldinst HYPERLINK "https://github.com/simon-brooke/mw-engine" }{\fldrslt {\loch\loch\cf18\loch
mw-engine}{}}}\loch
and }{{\field{\*\fldinst HYPERLINK "https://github.com/simon-brooke/mw-ui" }{\fldrslt {\loch\loch\cf18\loch
mw-ui}{}}}\loch
. There will be other modules in due course.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
You can see MicroWorld in action }{{\field{\*\fldinst HYPERLINK "http://www.journeyman.cc/microworld/" }{\fldrslt {\loch\loch\cf18\loch
here}{}}}\loch
- but please don\u8217\'92t be mean to my poor little server. If you want to run big maps or complex rule-sets, please run it on your own machines.{\*\bkmkend part-of-the-overall-microworld-system}}
\par \pard\plain \s2\rtlch\af9\afs28\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs28\b\dbch\af9{\loch
{\*\bkmkstart usage}Usage}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Main entry point is (parse-rule }{\rtlch\ai \ltrch\loch\i\loch
string}{\loch
), where string takes a form detailed in }{{\field{\*\fldinst HYPERLINK "#grammar" }{\fldrslt {\rtlch\ab \ltrch\loch\loch\cf18\b\loch
grammar}{}}}\loch
, below. If the rule is interpretted correctly the result will be the source code of a Clojure anonymous function; if the rule cannot be interpretted, an error \u8216\'91I did not understand\u8230\'85\u8217\'92 will be shown.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
The function (compile-rule }{\rtlch\ai \ltrch\loch\i\loch
string}{\loch
) is like parse-rule, except that it returns a compiled Clojure anonymous function.}
\par \pard\plain \s3\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\b\dbch\af9{\loch
{\*\bkmkstart X5241f4f5246239745859f6b5bf3a3d94d961d2d}Generated function and evaluation environment}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
The generated function is a function of two arguments}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls1 \li720\ri0\lin720\rin0\fi-480{\rtlch\ab \ltrch\loch\b\loch
cell}{\loch
a cell in a world as defined in mw-engine.world, q.v.;}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls1 \li720\ri0\lin720\rin0\fi-480{\rtlch\ab \ltrch\loch\b\loch
world}{\loch
the world of which that cell forms part.}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
It returns a new cell, based on the cell passed.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Actions of the rule will (can only) modify properties of the cell; there are two properties which are special and SHOULD NOT be modified, namely the properties }{\rtlch\ab \ltrch\loch\b\loch
x}{\loch
and }{\rtlch\ab \ltrch\loch\b\loch
y}{\loch
.{\*\bkmkend X5241f4f5246239745859f6b5bf3a3d94d961d2d}}
\par \pard\plain \s3\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\b\dbch\af9{\loch
{\*\bkmkstart execution}Execution}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Each time the world is transformed, exactly the same set of rules is applied to every cell. The rules are applied to the cell in turn, in the order in which they are written in the rule text, until the conditions of one of them match the cell. The actions of that rule are then used to transform the cell, and the rest of the rules are not applied.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
So, for example, if your first rule is}
\par \pard\plain \s184\loch\ql\widctlpar\sb0\sa200\ltrpar{\loch\cs17\hich\af7\loch\f7\fs22\loch
if x is more than -1 then state should be new}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
then no matter what your other rules are, your world will never change, because all cells have x more than -1.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
{\*\bkmkstart execution}If you are having problems because one of your rules isn\u8217\'92t working, look to see whether there is another rule above it which is \u8216\'91blocking\u8217\'92 it.{\*\bkmkend execution}}
\par \pard\plain \s3\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\b\dbch\af9{\loch
{\*\bkmkstart grammar}Grammar}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart comments}Comments}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls2 \li720\ri0\lin720\rin0\fi-480{\loch
Any line which starts with the hash character (#) is ignored;}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls2 \li720\ri0\lin720\rin0\fi-480{\loch
{\*\bkmkstart comments}Any line which starts with a semi-colon (;) is ignored.{\*\bkmkend comments}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart rules}Rules}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
A rule comprises:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls3 \li720\ri0\lin720\rin0\fi-480{\loch
if }{\rtlch\ai \ltrch\loch\i\loch
conditions}{\loch
then }{\rtlch\ai \ltrch\loch\i\loch
actions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
{\*\bkmkstart rules}Each rule must be on a single line. There should be nothing else on that line.{\*\bkmkend rules}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart conditions}Conditions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
In rules, }{\rtlch\ai \ltrch\loch\i\loch
conditions}{\loch
is one of:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls4 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
condition}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls4 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
condition}{\loch
and }{\rtlch\ai \ltrch\loch\i\loch
conditions}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls4 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
condition}{\loch
or }{\rtlch\ai \ltrch\loch\i\loch
conditions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Note that \u8216\'91and\u8217\'92 takes precedence over or, so}
\par \pard\plain \s184\loch\ql\widctlpar\sb0\sa200\ltrpar{\loch\cs17\hich\af7\loch\f7\fs22\loch
conditionA and conditionB or conditionC and conditionD}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
is interpreted as}
\par \pard\plain \s184\loch\ql\widctlpar\sb0\sa200\ltrpar{\loch\cs17\hich\af7\loch\f7\fs22\loch
(conditionA and (conditionB or (conditionC and conditionD)))}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
A }{\rtlch\ai \ltrch\loch\i\loch
condition}{\loch
is one of:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is not }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is in }{\rtlch\ai \ltrch\loch\i\loch
values}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is not in }{\rtlch\ai \ltrch\loch\i\loch
values}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is more than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is less than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
equal to }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
less than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
equal to }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
fewer than }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
equal to }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
some neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
equal to }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
fewer than }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
some neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
more than }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
less than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
fewer than }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
less than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls5 \li720\ri0\lin720\rin0\fi-480{\loch
some neighbours have }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
less than }{\rtlch\ai \ltrch\loch\i\loch
numeric-value{\*\bkmkend conditions}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart about-neighbours}About neighbours}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Note that everywhere above I\u8217\'92ve used \u8216\'91neighbours\u8217\'92, you can use \u8216\'91neighbours within }{\rtlch\ai \ltrch\loch\i\loch
distance}{\loch
\u8217\'92, where }{\rtlch\ai \ltrch\loch\i\loch
distance}{\loch
is a (small) positive integer.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
A cell has eight immediate neighbours - cells which actually touch it (except for cells on the edge of the map, which have fewer). If the cell we\u8217\'92re interested in is the cell marked \u8216\'91X\u8217\'92 in the table below, its immediate neighbours are the ones marked \u8216\'911\u8217\'92. But outside the ones marked \u8216\'911\u8217\'92, it has more distant neighbours - those marked \u8216\'912\u8217\'92 and \u8216\'913\u8217\'92 in the table, and still more outside those.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
X}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
1}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
2}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
3}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
If a rule just says \u8216\'91neighbours\u8217\'92, and not \u8216\'91neighbours within\u8217\'92, it means \u8216\'91neighbours within 1\u8217\'92; so}
\par \pard\plain \s184\loch\ql\widctlpar\sb0\sa200\ltrpar{\loch\cs17\hich\af7\loch\f7\fs22\loch
if some neighbours are scrub then state should be scrub}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
has exactly the same meaning as}
\par \pard\plain \s184\loch\ql\widctlpar\sb0\sa200\ltrpar{\loch\cs17\hich\af7\loch\f7\fs22\loch
{\*\bkmkstart about-neighbours}if some neighbours within 1 are scrub then state should be scrub{\*\bkmkend about-neighbours}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart actions}Actions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
In these rules, }{\rtlch\ai \ltrch\loch\i\loch
actions}{\loch
is one of:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls6 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
action}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls6 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
action}{\loch
and }{\rtlch\ai \ltrch\loch\i\loch
actions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
and }{\rtlch\ai \ltrch\loch\i\loch
action}{\loch
is:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls7 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
should be }{\rtlch\ai \ltrch\loch\i\loch
value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls7 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
chance in }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
}{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
should be }{\rtlch\ai \ltrch\loch\i\loch
value{\*\bkmkend actions}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart properties}Properties}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
In the above, }{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
is the name of any property of a cell. Any alpha-numeric string of characters can form the name of a property. Actions should }{\rtlch\ab \ltrch\loch\b\loch
NOT}{\loch
try to change the reserved properties }{\rtlch\ab \ltrch\loch\b\loch
x}{\loch
and }{\rtlch\ab \ltrch\loch\b\loch
y}{\loch
.{\*\bkmkend properties}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart values-in-conditions}Values in Conditions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Values in conditions and actions are considered slightly differently. In a condition, a value is one of:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls8 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
symbolic-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls8 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
The \u8216\'91\u8230\'85more than\u8230\'85\u8217\'92 and \u8216\'91\u8230\'85less than\u8230\'85\u8217\'92 conditions imply a }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}{\loch
. Thus \u8220\'93if altitude is more than fertility\u8230\'85\u8221\'94 is interpreted as meaning \u8220\'93if the value of the property of the current cell called \u8216\'91altitude\u8217\'92 is greater than the value of the property of the current cell called \u8216\'91fertility\u8217\'92\u8221\'94, whereas the apparently similar condition \u8216\'91if altitude is fertility\u8230\'85\u8217\'92 is interpreted as meaning \u8220\'93if the value of the property of the current cell called \u8216\'91altitude\u8217\'92 is the symbol \u8216\'91fertility\u8217\'92\u8221\'94.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Thus }{\rtlch\ai \ltrch\loch\i\loch
symbolic-value}{\loch
is any sequence of alphanumeric characters, whereas }{\rtlch\ai \ltrch\loch\i\loch
numeric-value}{\loch
is one of:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls9 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
number}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls9 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
and }{\rtlch\ai \ltrch\loch\i\loch
number}{\loch
is any sequence of the decimal digits 0\u8230\'859, the minus character \u8216\'91-\u8217\'92 and the period character \u8216\'91.\u8217\'92, provided that the minus character can only be in the first position, and the period character can only appear once.{\*\bkmkend values-in-conditions}}
\par \pard\plain \s4\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\i\dbch\af9{\loch
{\*\bkmkstart values-in-actions}Values in Actions}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
A }{\rtlch\ai \ltrch\loch\i\loch
value}{\loch
in an action is one of}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls10 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
symbolic-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls10 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
arithmetic-value}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls10 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
number}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
where }{\rtlch\ai \ltrch\loch\i\loch
arithmetic-value}{\loch
is:}
\par \pard\plain \s167\loch\ql\widctlpar\sb36\sa36\ltrpar{\listtext\pard\plain \u8226\'95\tab}\ilvl0\ls11 \li720\ri0\lin720\rin0\fi-480{\rtlch\ai \ltrch\loch\i\loch
property}{\loch
}{\rtlch\ai \ltrch\loch\i\loch
operator}{\loch
}{\rtlch\ai \ltrch\loch\i\loch
numeric-value}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
and }{\rtlch\ai \ltrch\loch\i\loch
operator}{\loch
is one of the simple arithmetic operators \u8216\'91+\u8217\'92, \u8216\'91-\u8217\'92, \u8217\'92*\u8217\'92 and \u8216\'91/\u8217\'92.{\*\bkmkend grammar}{\*\bkmkend values-in-actions}}
\par \pard\plain \s3\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\b\dbch\af9{\loch
{\*\bkmkstart shorthand}Shorthand}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
{\*\bkmkstart shorthand}Note that \u8216\'91\u8230\'85neighbours are\u8230\'85\u8217\'92 is equivalent to \u8216\'91\u8230\'85neighbours have state equal to\u8230\'85\u8217\'92, and \u8216\'91some neighbours\u8230\'85\u8217\'92 is equivalent to \u8216\'91more than 0 neighbours\u8230\'85\u8217\'92{\*\bkmkend shorthand}}
\par \pard\plain \s3\rtlch\af9\afs24\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs24\b\dbch\af9{\loch
{\*\bkmkstart roadmap}Roadmap}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
The existing parser, }{\rtlch\ai \ltrch\loch\i\loch
mw-parser.core}{\loch
, works but is not well written. A much better parser which does not yet completely work, }{\rtlch\ai \ltrch\loch\i\loch
mw-parser.insta}{\loch
, is also included for the adventurous.}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
I intend to replace }{\rtlch\ai \ltrch\loch\i\loch
mw-parser.core}{\loch
with }{\rtlch\ai \ltrch\loch\i\loch
mw-parser.insta}{\loch
as soon as }{\rtlch\ai \ltrch\loch\i\loch
mw-parser.insta}{\loch
correctly parses all the test rules.{\*\bkmkend usage}{\*\bkmkend roadmap}}
\par \pard\plain \s2\rtlch\af9\afs28\ab \ltrch\hich\af6\loch\ql\keep\widctlpar\sb200\sa0\keepn\ltrpar\cf18\f6\fs28\b\dbch\af9{\loch
{\*\bkmkstart license}License}
\par \pard\plain \s166\loch\ql\widctlpar\sb180\sa180\ltrpar{\loch
Copyright \u169\'a9 2014 }{{\field{\*\fldinst HYPERLINK "mailto:simon@journeyman.cc" }{\fldrslt {\loch\loch\cf18\loch
Simon Brooke}}}}
\par \pard\plain \s162\loch\ql\widctlpar\sb180\sa180\ltrpar\sb180\sa180{\loch
Distributed under the terms of the }{{\field{\*\fldinst HYPERLINK "http://www.gnu.org/licenses/gpl-2.0.html" }{\fldrslt {\loch\loch\cf18\loch
GNU General Public License v2}}}{\*\bkmkend mw-parser}{\*\bkmkend license}}
\par }