Final Project - Progress Report 1
Forrest Sondahl
Multi-Agent Modeling (2005)

Summary:

So far work has been done on the underlying framework, with few visible results.  However, I have been making several important design decisions (that hopefully won't come back to bite me somehow...)  The main progress  this week was in the tree representations of netlogo programs.  Currently, I can build random arithmetic expression trees, print them back out in human readable form, and execute them (while checking for errors) and return the result.

Details:

First, let's talk about the structure of these program trees.  In my original design document, I noted that there are several types of statements in netlogo, which behave differently and have different syntaxes -- e.g. operators, reporters, commands.  To deal with this in my program tree structure, I have classified some of the peices from which netlogo is built.  Each node has an associated TYPE and RETURN TYPE, which are represented in my program by constants (actually NetLogo doesn't seem to allow you to define constants, so they are actually just global variables that I am treating as constants).

The types (so far) are:

  TYPE_COMMANDBLOCK
  TYPE_COMMAND
  TYPE_OPERATOR
  TYPE_REPORTER
  TYPE_TERMINAL

The return types (so far) are:
  RTYPE_VOID
  RTYPE_VOIDBLOCK
  RTYPE_NUMERIC
  RTYPE_BOOLEAN
  RTYPE_VARIABLE (the "set" and "let" primitives require a variable (l-value) for their first argument)
  RTYPE_AGENT   (?)
  RTYPE_AGENTSET  (?)

Before you start scratching your head, and saying "this won't cover X" and "you can't build Y with that, can you?", I must remind you that it is not my goal to represent the entire NetLogo language.  Rather, I am trying to represent a reasonable subset of the turtle-commands and control structures, so that fruitful genetic programming can be performed.  The question marks after the agent constants are because I am not sure if they will be worth implementing or not.  Certainly we won't want our code-turtles to be able to ask other code-turtles to do things, and we don't want to modify other turtles' variables, etc.  Sometimes we may want to get information about nearby agents, but we can write little wrapper reporters to do this for us, and then give the names of these reporters to our code-turtles as primitives to use.  This question is something I will be thinking more about in the next week.

Currently, the basic structure for a node looks like:

[Value Return_type Type Child1 Child2 ...]  where ChildX is itself a node.

Terminal nodes (leaves of the tree) are represented as
[Value Return_type TYPE_TERMINAL]  and have no children.

Thus, a sample tree for the expression 2 + 5 would look like:
["+" RTYPE_NUMERIC TYPE_OPERATOR
     ["2" RTYPE_NUMERIC TYPE_TERMINAL]
     ["5" RTYPE_NUMERIC TYPE_TERMINAL]]

All of the allowed choices for functions and terminals are being kept in a list of lists which have a similar structure to that of the nodes.  Just replace "ChildX" with the Return_typeX, which is the return type of the node that could go in that spot.

For example, here is the list of operators I have defined so far: 

set syntaxf_operators_num (list
(list "+" RTYPE_NUMERIC TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC)
(list "-" RTYPE_NUMERIC TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC)
(list "*" RTYPE_NUMERIC TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC)
(list "/" RTYPE_NUMERIC TYPE_OPERATOR RTYPE_NUMERIC RTYPE_NUMERIC)
)

(I noted that when I'm building these lists, I have to use the "list" primitive, rather than just using nested [] brackets, because the square brackets notation only takes constants, and not variables.)

Currently, I have seperate lists for commands, numeric reporters, numeric operators, boolean operators, and numeric terminals.  The lists are really just used for random tree generation.  But random tree generation is important.  It is how the whole initial population of code-turtles is created, and it is also used every time a mutation occurs.

I've written several useful functions for dealing with program trees:


Random Notes:

It took me a while to figure out how to append lists together.  I was looking for a function named something like "append" or "concat".  I eventually just went one by one through the list primitives until I ran across "sentence".  It wasn't a big deal at all, but it seems likely to me that other people will have similar difficulty, and might find it much easier if it were called something like "append".

Conclusion:

Clearly, there is still an enormous amount of work to be done.  However, this week's progress leaves me feeling positive about the project as a whole.  The final goal feels possible -- it will just take time.  And in the end, I think it could be rather cool. 
Plans for the upcoming week: 

Back to Forrest's NetLogo Main Page.