Archive for November, 2009

Status Report

Wednesday, November 18th, 2009

While John has been working on Erlush (more of a rabbit hole than he expected, I’m sure), I’ve been bouncing around between a few different ideas for interacting with Erlush from other language environments and for launching Erlush programs across cluster nodes. Coming up to the end of the semester, here’s a look at the current state of affairs in both of these areas:

  • Foreign language interfaces: I futzed around for a while with the (probably doomed-from-the-get-go) idea of using standard input/output and the cluster’s filesystem as transports, but then John told me that he had figured out how to use Erlang’s message-passing/marshaling system. He wrote a Python library for writing fitness evaluators for Erlush, and I employed Erlectricity to do something similar in Ruby. These things both work, on computers where everything is properly installed. (At the time of this writing this does not include the cluster, but we’ll get there.)
  • Launching jobs on the cluster: I’ve pretty much finished a fairly straightforward Ruby program to generate Tractor scriptsthat can be spooled to the Tractor job queue. It needs to be more configurable, and I need to work with John to figure out how to collect results from the worker nodes when they finish running.

While it may seem like we’ve been treading water a bit here, I think we’re making real progress, and as our understanding of the best way to put together this infrastructure has evolved, we’ve come a lot closer to our ultimate goal of making running GP experiments on the cluster a one-command operation. Or really, an edit-a-configuration-file-then-run-a-command operation. And we’re really and truly nearly there!

Erlush evolves its first non-trivial program!

Wednesday, November 4th, 2009

It computes factorial. Here it is:

[{exec,pop}, [[[{exec,do_star_times},{integer,yank}],[[-9,{integer,yankdup}]]], [{boolean,stackdepth}, [[{integer,flush},{exec,b},{exec,k}], {exec,y}, [[[[{boolean,rot},{exec,do_star_times}]]], {integer,divide}, {integer,yank}]], [[[[{exec,do_star_count},{integer,lessthan}]]]]]], {integer,equal}, [{exec,do_star_times}, [[{exec,s},{exec,do_star_times}],[{integer,max},{boolean,yankdup}],{exec,c}], {exec,k}, {integer,multiply}]]

And the same program after simplification (by hand):

[{exec,do_star_times}, [[{exec,do_star_times}],{exec,c},[[],{exec,c}]], {exec,k}, {integer,multiply}]

And again in nicer, lispy, Push3 syntax

(EXEC.DO*TIMES ((EXEC.DO*TIMES) EXEC.C (() EXEC.C)) EXEC.K INTEGER.*)

I was pretty excited to see C combinators in there, perhaps they’re a worthwhile addition to the language.. No worries if you can’t figure out what’s going on here, I’ve single stepped through it with Erlush in debugger mode and still can’t say for sure that I know how it works. I did, however, discover that it’s exploiting a bug in my implementation of EXEC.DO*TIMES — which is discouraging and exciting at the same time.

More to come.

John

UPDATE: I fixed the EXEC.DO*TIMES bug and reran the factorial evolver, and got (after simplification and Push3ifying)

(EXEC.STACKDEPTH INTEGER.DUP INTEGER./ EXEC.DO*RANGE INTEGER.*)

Which is much clearer. The first three instructions just put a 1 on the stack on top of input and then EXEC.DO*RANGE INTEGER.* iterates from the input value down to 1 multiplying the loop counter and the value beneath it each time.