VOLVE 5.0
ALIFE: Simulator Flaws
July 1st 2006
The sim continues... For the last 2 weeks I was in St. Petersburg, Russia. I left the simulator running all
that time and when I got back it was still running. The power even went out (all my clocks were
blinking "12:00"). This means my UPS worked. Yee haw, whoo hooo! I have identified two signifigant flaws with the current
version of the Evolve simulator (ver 4.5). First, instruction-level mutations only add/remove a single instruction. This seems like a good
idea. This seems to reflect the gradualism of Darwinism. However, if you examine the KFORTH language you'll notice that inserting
or removing just a single instruction is rarely a useful thing. In a universe in which stack space cost energy,
and lack of energy equals death. No creature can afford to be wasteful with stack space, and therefore cannot tolerate
stack unfriendly instructions. But adding a single instruction is almost always stack unfriendly in KFORTH.... I have observed the following
trends in many long-term sim. Early on a certain behavior evolves in creatures. It becomes a widespread/universal behavior. And the
for many days this behavior remains. It's not a bad behavior, but it just cannot be pushed out of this
local optima. Why? Because any distruption to these "tight looped" algorithmic behaviors, spells certain death to the organism. There is
simply no single instruction mutation that CAN EVER change this status quo. I am reminded of Richard Dawkins' description of
biomorph space (in "Climbing Mount Improbable"). He compares this space as a 2-D surface. With bumps, hills, even mountains. Most
evolution occurs along the gradual smooth surfaces and rarely jump ups cliffs. My "yellow-square-morph-space" had a very big plane with
lots of awsome innovative hills and mountains all over the place. However, to begin climbing any of these cool mountains
requires a 2, 3, or 4 instruction mutation -- all at once. A macro-mutation if you will. Maybe an example
will clarify my point. For example, this could very well be a cool sequence of instructions for a creature to
have:
1 1 LOOK ?exit
But in the current version, this would have had to accumulate one instruction at a time: [pre] 1
; death 1 1 ; super fast death 1 1 LOOK ; hmmm, maybe something good 1 1 LOOK ?exit
; again, maybe something good [/pre] In KFORTH a single inserted instruction usually means run away stack growth and death.
But if you allow 2 for mutations of 2, 3 or 4 instructions long, then there are lot of possibilities
that won't mean death, and could be improvements. [pre] 1 pop pop 1 0 SEND EAT pop .. [/pre] Many
2 instruction combinations are possible, which can be inserted into a code block and will not screw up the stack.
Gradulism is still part of Evolve's mutation mechanism, this is why my mutation strand length will be kept low (1
to 4). If I had chosen a strand length of (1 to 100), then most mutations would be on average
50 instructions long, and that would harldy result in improvements in survival. So my new mutation mechanism has been modified
to reflect the realities of the KFORTH laguage, and its stack based properties. A mutation length of 4 seems like
a nice balance between being too drastic, and being too miniscule. So fatal flaw #1 was, "1 instruction mutations are
too small". Solution: increase mutations to use instruction stands of length 1 to 4. The second fatal flaw involved something
I was quite proud of in KFORTH. I thought the design of KFORTH was such that instructions could be added
and removed without being overly destructive. For example,
X Y Z ?loop A B C D ?loop E F G H ?exit M N O ?loop
I have used X, Y, Z, ... for regular instructions. But
the flow control ones are shown. Notice that even if instruction are added or removed, the ?loop and ?exit instructions
continue to refer to the same places they always did before (the beginning and end of the code block). This
is similar to "position independent code". Position independence means the physical bytes of the machine code can occupy any physical
address in memory and work correctly unchanged. KFORTH, at least for the instructions inside of a code block enjoyed a
form of "mutation independent code". Meaning instructions could be added and removed and the flow control stuff would still kind
of work. So where's the fatal flaw? It has to do with calling other code blocks. I used absolute code
block numbers, when I should have used relative code blocks. I see that now! Here's a recursive code block:
{ X Y Z ?exit 49 call } ; <-- code block 49
'49' is the absolute code block number of this code block. This isn't a problem when humans write KFORTH. As
the compiler handles the label. But when code is re-arranged due to mutations, then this code block will not always
live at code block address '49'. With relative code block addressing, the above would look like this:
{ X Y Z ?exit 0 call } ; <-- code block 49
Ahh. The
beauty! "0 call" means call oneself! I love it!!!! It will alway mean "call myself" no matter where this code
is moved. This also means one or more related code blocks will continue to work, even if a code block
was inserted above them. Consider this,
{ .... }
{ .... }
{ X Y Z 2 3 ifelse }
{ .... }
{ true-block }
{ false-block }
If a mutation occured that shoved in a new code block above these,
{ .... }
{ .... } ; <-- added
{ .... }
{ X Y Z 2 3 ifelse }
{ .... }
{ true-block }
{ false-block }
Then this code will continue to work. So there you have it. Fatal flaw #2 was absolute code block
addressing. SOLUTION: Switch to relative addressing. This change does not change anything about writting KFORTH using labels. As the compiler
automatically generates the proper relative address from the label. For example,
factorial: { ..... factorial call }
Therefore to call the code block before you:
{ -1 call }
To call yourself:
{ 0 call }
To call the code block after you:
{ 1 call }
Wow! Awsome. Now groups of code blocks
can evolve and enjoy a little bit of independence from mutations happening around them. So given all these discoveries... (1)
Evolve version 4.6 will be much different, and much, much better. And, (2) One Year of ALife will have to
be restarted using this version :-( It saddens me to lose 30+ days of simulation effort. But the changes made
are so much in the best interests of this project that I have to do it. This may happen in
a couple days from now.