Evolve 5.0 Blog
VOLVE    5.0

Newer Posts Older Posts

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.




Newer Posts Older Posts