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.

Share

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.

1 Comment »

 
 

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

CommentLuv Enabled