You control the space explored by your evolving programs by specifying a grammar for their construction. This is done in Grammar.pm in a fairly standard way, except that the production rules are split into functions and terminals. The following sections explain some of the concepts and how the grammar is converted into a real Perl program. But first I explain some strange Perl syntax that you may not have seen before:
$F{ROOT} = [ <<'___', package Individual; sub evaluateOutput { my ($self, $data) = @_; my ($x, $y, $z, @output); foreach $input (@$data) { $x = $input->{x}; # begin evolved bit $y = {NUM}; # end evolved bit push @output, { 'y'=> $y }; } return \@output; } ___ ];
The right hand side of this assignment is an anonymous array (or
reference to an array) containing a single string element. The
contents of that string are everything on the lines between
the <<'___'
and the following ___
. This is known as
here-text, and is often used in shell scripts. In Perl there
are different flavours of here-text, the one used here is
single-quoted here-text, which means things that look like variables
(like $x) are not interpolated.
Why not just put single quotes round this string? Well there are some single quotes in the string and we like those and don't want to mess around with backslashes. OK, so why not use q() or q//? Then we have to make sure that the delimiter is not in the string anywhere, which is a pain. Here-text does just fine thanks, and tends not to mess up emacs colouring too!
Note that the following, with the square brackets closed before the here-text, is also correct:
$F{FOO} = [ <<'___' ]; foreach $foo (@foo) { $foo->{FUNC}(); } ___
Now read on for a short explanation of what's going on with hashes and grammar definition (modified from my EuroGP2003 paper/poster).