Python, Evolving, Learning
I’ve always been interested in the idea of software that evolves on it’s own; software that can write itself. I’ve come up with all sorts of ways this can happen, from neurons to dynamic methods, to my latest effort, a sudo assembly language.
Note: I’m not trying to replicate or create an actually assembly language. I’m just using concepts from it to achieve my own goals.
The idea is that the assembly would act as sort of a DNA for the programs. They run the code and are ranked by their effectiveness. The most effective will continue to live and be breed to start a new generation. Those that aren’t effective will be deleted.
First step is to build the sudo assembler. I figured being able to print out the Fibonacci sequence would be a good test. My assembler doesn’t have any predefined variables, just a stack you can push things onto. The different methods would just pop what they need off the stack.
Alright enough talk, here is the code.
#
# Simple byte-ish interperter.
# No real assembly or byte code, just made up stuff.
# By Chris Richards 2009.
#
class ByteInterpreter:
"""Runs predefined Byte commands"""
stack = [] #Varables that can be used by the ByteCode
command_index = 0 #The command to be evaluated next
once = True;
def Run(self, command_list):
"""Run the commands from the start to end"""
while self.command_index < len(command_list):
self.Interpret(command_list[self.command_index])
self.command_index += 1
def Interpret(self, command):
"""Interprate the command and run the correct method."""
#Break the command into it's parts
parts = command.partition(" ")
#get the method they want
method = getattr(self, parts[0])
#call it
method(parts[2])
def push(self, value):
"""Store the value on the top of the stack."""
self.stack.append(value)
def pop(self, ignored=True):
"""Remove and Return the top value on the stack."""
if( 0 < len(self.stack) ):
return self.stack.pop()
else:
return None
def peek(self, ignored=True):
"""Return the top value on the stack without removing it."""
if( 0 < len(self.stack) ):
return self.stack[len(self.stack)-1]
else:
return None
def duplicate(self, times):
"""Duplicates the top of the stack the number of times specified."""
times = int(times)
for i in range(times):
self.push(self.peek())
def add(self, ignored=True):
"""Pops two values, converts them to ints and then pushes the result back on the stack"""
val1 = int(self.pop())
val2 = int(self.pop())
self.push( val1 + val2 )
def subtract(self, ignored=True):
"""Pops two values, subtracts them, then pushes the result onto the stack."""
val1 = int(self.pop())
val2 = int(self.pop())
self.push( val1 - val2 )
def jumpnz(self, line):
"""Peeks the top value, if it's not zero it will jump to the line."""
line = int(line)
val1 = int(self.peek())
if( 0 != int(val1) ):
self.command_index = line-1
def shift(self, amount):
"""Shifts the top value back the amount specified."""
amount = int(amount)
self.stack.insert( len(self.stack) - amount-1, self.stack.pop() )
def prnt(self, ignored=True):
"""Does a peek and prints that value to the screen."""
print "print " + str(self.peek())
if __name__ == "__main__":
fibonacci = ["push 1"
, "push 0"
, "push 10"
, "shift 2"
, "shift 1"
, "duplicate 1"
, "shift 2"
, "add"
, "prnt"
, "shift 2"
, "shift 1"
, "push 1"
, "shift 1"
, "subtract"
, "jumpnz 3"]
runner = ByteInterpreter()
runner.Run(fibonacci)
That prints out the first 10 Fibonacci numbers. So Now I know the assember works properly. The next step is to create a program that can create critters with random code. Then we can run their code and see if they can evolve into producing the Fibonacci sequence.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

[...] and this – just a random blog/site with two posts that follow very closely to mine, though a little [...]