Technical


Each animal in EvolveJs is written in a specialised assembly code. This assembly language was designed with some inspiration from Tierra. Each thread is essentially a stack machine and each operation operates on that stack.
An assembly operation is a pair of [operation, operand].

One of the key concepts is in markers used for jumping. To make the animal’s code more robust to modification, all jump targets (such as for loops and branches) are marked as a series of nops, and the jump command specifies the jump target as the number of nops to search for.

So as a concrete example I will show a simple process that can reproduce itself.

This is the 5 label. The nop function does not require an argument, so is by convention set to 0.

["nop",0],["nop",0],["nop",0],["nop",0],["nop",0], //label 5

Now we initialise the read pointer to point to the start of the parent, and the write pointer to point to the end of the parent. The jmp*PtrB functions jump the pointer to the start of the nop template, and the jmp*PtrF functions jump to the end of the nop template. In this code all templates are unique, but it is not necessarily so. The jmp*PtrF functions search forward and wrap around, and the jmp*PtrB functions search backward and wrap around.

["jmpReadPtrB",5], //jmp to start of template 5
["jmpWritePtrF",2], //jmp to end of template 2

Get the parents memory size, allocate memory at the end of the parent, and move the write pointer to the start of the new memory.

["pushMemSize",0],
["alloc",0],
["incWritePtr",0], //inc write pointer to start of new animal

The copy loop. Copy from the read pointer to the write pointer, and increment both pointers.

["nop",0], //start copy loop
["copy",0],
["incReadPtr",0],
["incWritePtr",0],

Push the value for the write pointer and the animals total memory size (including the new child memory) to the stack and compare them using the lt operator.

["pushWritePtr",0],
["pushMemSize",0], //if writeptr < memSize
["lt",0],

Then, if write pointer is less than memory size, jump back to start of template 1.
If write pointer is not less than memory size, then the execution pointer gets incremented by 1 + operand (in this case 1), which means that the copying process has finished.

["ifdo",1],
["jmpB",1], //if not finished copying

This is the division loop. When a parent divides, the parent attempts to put the child in the square immediately in front of them. If this position is already occupied, then division fails, and the parent gets to try again.

["nop",0],["nop",0],["nop",0],["nop",0],["nop",0],["nop",0], //template 6

Divide attempts division and pushes a boolean result onto the stack indicating success. If division succeeds, then jump all the way back to template 5, and start making a new baby.

["divide",0],
["ifdo",1],
["jmpB",5], //if division successful

Here, we are using one of those nop templates to store data.
The memory pointer jumps to the first memory address in the 6template. The data that is stored in the operand is pushed onto the stack, incremented, stored back in the memory slot and compared to 4 (number of cardinal directions)

["jmpMemPtrB",6],// jump the mem pointer to a location to store some data
["pushM",0],
["add",1],
["popM",0],
["pushM",0],
["push",4],
["gte",0],

If it has already tried this 4 times, then this animal is surrounded and can’t reproduce at the moment. So it sleeps, and we reset the counter. Otherwise, the ifdo,3 increments the execution pointer by an extra 3.

["ifdo",3],
["sleep",450],
["push",0],
["popM",0],

The divide didn’t work, try again facing in a new direction.

["turnR",0], //turn around and try again
["jmpB",6],

The end tag

["nop",0],["nop",0]

This application is a “proof of concept” evolution simulator. Each animal (process) has the following properties

  • Memory: This is both readable and writable memory addresses starting from address 0 for each animal.
  • Threads: Each animal can have multiple threads that communicate via it’s memory.
  • CpuTime: Each animal is granted cputime by it’s parent when it is born, and after that is given cputime by the environment (like sunshine) each cycle.
  • Position: Each animal has a current position in the grid
  • Direction: Each animal is pointing in a certain direction (this is not currently shown in the display.

Each thread in each animal has the following properties:

  • Stack: this is essentially current memory. Operations can put information on the stack, manipulate the top item on the stack, or pop information off the stack.
  • Execution Pointer: Each thread is executing the same program, but potentially at a different address (different function) in memory.
  • Read Pointer and Write Pointer: These are used for copying operations.
  • Memory Pointer: This is used for writing operands only.
  • Speed: An animal can choose to operate faster, multiple operations per second. This is expensive for the animal.
  • SleepCycles: The thread can sleep for a set number of cycles. It will be woken when this counter reaches 0.

There have so far been two Ancestors created:

  1. A simple non-mobile vegetable. This has a single thread that is devoted to reproduction.
    Once all 8 slots around the animal are full, it sleeps for a period and then checks again.
  2. A simple mobile vegetable. This has two threads: one is devoted to reproduction, the other moves in a straight line forever.
    When it reproduces, it turns right.

Animals reproduce by allocating memory at the end of their memory, then copying their code into the new memory, and then dividing the new memory.
This creates a new process.
The copying process has a non-0 random chance of failing to accurately copy the data requested.
This results in the child not always being the same as the parent, and the chance for evolution is created.
Successful species (when a species has had enough animals with the same code, occurs at powers of 10) are sent to the server.
When the application starts it requests the 10 best animals from the server.
Things you can do:

  • Click on an individual to see information about it on the “Process Details” tab
  • View code of species on server to see what has evolved from the “Progenitors”

Future features:

  • Ability to examine the code of any individual.
  • Allow the user to insert new processes (with new code) into the environment.

I have been playing with javascript a bit lately, testing out techniques that I might use for doing a full web 2.0 business application (if any clients would agree…). The application that I have written is a game along the same sort of lines as RoboCode. 

It allows users to implement "animals" in custom written assembly code ("genomes"), which compete for resources and can move around and eat each other. I have currently written two simple genome, a vegetable (it doesn't move) and a predator (it does move). They are both using almost the simplest algorithms for each of these tasks as possible.

The animals run virtual cpu's and also implement virtual threading. The predator animal has a reproductive thread and a movement thread. The vegetable has only a reproductive thread. And as the last real feature, the animals also have a non-zero chance of their mem-copy commands (part of the requirement of reproduction) failing to copy correctly. This introduces mutations and hopefully mutation.

The javascript application is backed on the server by a ruby on rails application that stores successful animals (animals that survive to reproduce).

I have a few problems with the current implementation that limits it's usefulness.

  1. First, the application is pretty slow. It runs at about 600hz on my computer in firefox 3b2. (This means that it executes 500 virtual cpu instructions per second.) Compare this to my actual machine running at 2 billion instructions per second, and there is a factor of 4 million difference. Some of this can be explained by the fact that each virtual instruction is implemented as a block of javascript code that does stuff to memory in the cpu. Some more is probably explained by me not using javascript to its full potential. The rest must be explained by javascript being s l o w. I have used firebug to do some profiling of the code to find hotspots and have been able to find some issues. To make the evolution part of the application do anything useful it would need to be 10x faster at least. But I think that to make it a factor of 10 faster i would need to radically change the architecture.
  2. Another issue is that the application occasionally just freezes. I imagine it is doing some sort of garbage collection in the background. I would love to be able to get more control over this, so that I could see what was happening, or at least predict when it might happen.

These are the same issues that I would face implementing a large javascript client in a web 2.0 application, so I am glad to have found them now rather than later.

An early alpha version (where it isn't possible to inject new animals into the application, except by editing the source directly, and the server communication isn't working properly) is available. The source is all on the page in easily read code, if anyone is interested.

Firefox is a much better browser than MS Internet Explorer. It has lots of little benefits for me:

  • Tabbed browsing
  • More standards compliant
  • Easier to develop in
  • Better bookmark management

and there are plenty more. But the main benefit is the extensions. The things that you can do with them are amazing. Literally changing your browser into whatever you want it to be. Optimising your web browsing experience for whatever you think is easiest.

Here is a list of the extensions that I have installed:

Challenge Manager is now ready for public use. It is currently being used on selfPortraitChallenge and Whipup.

If you are happy with using this plugin, please link back to me on your blog, and put your address in the comments. I'll add a blog entry soon listing all the people that are using it.

Please put all feedback into the comments. I will try to be prompt with replies.

Thanks 

Well, it turned out to be remarkably simple to switch my not very technically adept parents from Windows XP to Ubuntu (Breezy Badger). We did this on the basis that it was getting increasingly difficult to manage their computer difficulties from Melbourne, and their Windows XP installation was incredibly spamware and adware ridden.

So at the moment I have put Ubuntu on as a second boot option, just in case they ABSOLUTELY NEED TO use windows. But they tell me that they are only using Ubuntu.  In Linux, I have given their user accounts the standard (low) level of access, and I have made sure that I can get ssh access externally. Now I just need to set up VNC and dynamic domain registration so that I don't have to keep getting dad to lookup his modems external IP address.

Mark that one up as another successful switch to Linux. It was a lot easier than I thought. Their main applications that they used are Firefox, Outlook and some Microsoft Word. 

Interesting essay by George Dyson talking about Google, information and Artificial Intelligence. This is an excerpt:

For 30 years I have been wondering, what indication of its existence might we expect from a true AI? Certainly not any explicit revelation, which might spark a movement to pull the plug. Anomalous accumulation or creation of wealth might be a sign, or an unquenchable thirst for raw information, storage space, and processing cycles, or a concerted attempt to secure an uninterrupted, autonomous power supply. But the real sign, I suspect, would be a circle of cheerful, contented, intellectually and physically well-nourished people surrounding the AI. There wouldn’t be any need for True Believers, or the downloading of human brains or anything sinister like that: just a gradual, gentle, pervasive and mutually beneficial contact between us and a growing something else.

How far away is the moment that we will find ourselves acknowledging GoogleAI as a new species?

Sir Tim Berners Lee is interviewed about the web, and the semantic web. Interesting discussion.

Ever since I first read about Tom Ray's Tierra artificial evolution system, I have been very interested in where it would go. The idea of the software evolving and creating unplanned complexity seemed like a really good idea. However it never really seemed to go anywhere, and Tom seems to have started researching other things, such as evolvability. I am starting to think that the reason that he did so is that it is very hard to get software to evolve. I have written an artificial evolution environment in Python that runs animals written in my own stack implementation of a Virtual Machine. It has network communication, so separated environments can talk to each other. This is implemented as a P2P sort of service, where there is no central server required, and all the peers tell each other about peers in the network, this part isn't completely tested yet. I am happy with where the whole thing is going, but am having problems with the basic design. There are a few problems that have to be solved to get an environment that encourages evolution working:

  • A virtual machine (done for now)
  • An Ancestor animal that is able to reproduce (done)
  • A mechanism for communication between genepools (mostly done)
  • Mutation (done for now)
  • Environmental pressures that encourage fitness, and allow new species to breed (problems)
  • A user interface, so that we can see what is happening (partly done)

My problem has been, that once a species becomes dominant, it is hard for a new species to make a niche. Various Reaper strategies can help with this, but it isn't ideal. I need to have a bit more of a think about what the environment is for. The Tierra idea is to create an artificial ecosystem, where animals live and evolve, not as a place to optimise a solution to a problem. So the idea of every generation taking the most 'fit' animals and mutating them doesn't quite fit. I am not quite ready to release the source code publically but if anyone is interested you can certainly have it.

Ok, I wrote my first WordPress plugin for my sister's very popular Self-Portrait Tuesday. It is a plugin to allow the members of a site to upload links that can be used in ongoing competitions of communities. I have called it "PicLinks" because it is initially for that, but it could be used for anything.Here is a link to the very first stable version of it. Piclinks v0.1. Some feedback will no doubt take off its rough edges. I have to give thanks to the author of WP-Quotes which I used for inspiration (in fact I blatantly used the entire structure of his code…). This is the first time that I have done any PHP, and I can't say that I completely enjoyed the experience. After using Python, it just seems a little cludgy.