Let’s use artificial life to evolve intelligence. Because AI is hard; evolution is easy.
I’m not the first one to think of this idea. Quite a few people have taken a stab at it. It’s not even the first time I’ve implemented something to play with the notion—nymphs, grubs, figures… It’s very important that whatever else happens with the project, it will have a nifty name! This time, thanks to a conversation with my brother and co-host, they’re called “dorg.” It’s short for “digital organisms,” because, that’s what they are. They’re little bits of running software that sit on my computer and pretend to be alive.
A dorg has three parts—memory, interpreter, and ports.
The memory is a list of numbers. (an int array for code folk.) It’s somewhat like DNA. Like DNA by itself, the memory means nothing and does nothing. DNA has to be inside the right kind of cell or it just lays around at the crime scene. In the same way, the number stored in memory won’t do anything unless they’re inside a dorg with its interpreter and the right set of ports.
The interpreter takes the numbers from the memory and interprets them as commands. It’s actually the simplest part of the program, only 14 lines of code. The interpreter passes information from one place to another within the memory, between the ports, and back and forth from memory to ports and ports to memory. I have a biological metaphor for the interpreter, but it’s more complicated than what I’m trying to explain… so…
The ports do everything else! They’re like the rest of the machinery within a cell—build proteins, wave cilia, sniff for food, sense light, move the cell around, change which part of the DNA is being read, walk your dog, clean your house, and do your taxes—pretty much anything else you think your creation should do.
To make sure things were acting how I wanted them to, I hacked together a small set of ports. The goal was to make the interpreter run a loop 13 times, and then stop. For the code people, I wanted the equivalent of a for loop.
The DNA, which I wrote by hand, looked like this:
14, -4, 15, -6, 16, -1, -1, 16, 16, -3, -3, -5, 1, -2, 13, 4, 0
That’s 17 numbers long, to do the same thing as if I wrote:
for(int c=0; c<13; c++) “ that’s 23 characters long. One of the ports I wrote would add one to any number that was sent to it, and print that result to the console. If I run it, here’s what happens: “ Really? Fat babies... again? memory= 14, -4, 15, -6, 16, -1, -1, 16, 16, -3, -3, -5, 1, -2, 13, 4, 0 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, and done! memory= 14, -4, 15, -6, 16, -1, -1, 16, 16, -3, -3, -5, 1, -2, 13, 4, 13 “ Everything works, and just as it should. However, those numbers will only work if I use the same set of ports, placed in the same order within the dorg. Otherwise, there’s no telling what might happen. You can tack new ports on, but if you want your creatures’ DNA to make sense , they’ll need the ports they’re used to having, in the places they’re used to having them. “So,” You may be asking, “what’s the point of this? You’ve gone to a lot of trouble to make something that with a lot of extra trouble does what any other programming language could do. I don’t see much life in your artificial life, fancy metaphors aside.” Right, the next trick was and is to get it to evolve, which has already happened, including, a way to make the dorg evolve without death. I’ll talk about that in the next post about this.