Genetic Madlibs
Posted by Jeremy Voorhis Fri, 06 Apr 2007 20:47:00 GMT
Inspired by the eigenclass language generator, I’ve thrown together an example of how it would be implemented with the Directed Ruby Programming library. Directed programming is an interesting hybrid of genetic programming and the recently discovered grammatical evolution technique which generates a program tree according to a grammar.
This example may not be very interesting for those familiar with evolutionary programming techniques, but it created a fun diversion, highlights how the DRP library is to be used, and shows a different solution for a language generator.
class DrpGenerator
extend DRP::RuleEngine
begin_rules
def main() "#{hello}\n#{ex1}\n#{ex2}" end
def hello() "Hello, #{somebody}!" end
def somebody() "matz" end
def somebody() "world" end
def ex1() "This is a more #{adj1} #{example}." end
def adj1() "complex" end
def adj1() "elaborate" end
def example() "example" end
def example() "test" end
def ex2() "Some simple sentence." end
def ex2() "Another, involving harder stuff." end
def ex2() "Another, involving a more complex #{exp}." end
def ex2() "Yet another possibility; each one is chosen with an evolutionary algorithm." end
def exp() "expression" end
def exp() "disjunction" end
def exp() example end
end_rules
end
g = DrpGenerator.new
3.times { puts g.main }
Hello, matz!
This is a more elaborate example.
Another, involving a more complex disjunction.
Hello, world!
This is a more elaborate test.
Another, involving harder stuff.
Hello, world!
This is a more complex example.
Yet another possibility; each one is chosen with an evolutionary algorithm.
My DrpGenerator isn’t as readable or attractive as the eigenclass DSL, and multiple definitions of the same method will likely confuse most Rubyists at first glance, but makes it easy to see the underlying grammar.

Since you mention it… What does the multiple method definitions do? Besides confuse most of us. ;) I would have thought that only the last definition would be “available” but your examples show that’s not the case.
Good question. DRP uses the exotic and undocumented
Module#method_addedcallback to alias the method with a unique name and change its access to private. This behavior takes effect between thebegin_rulesandend_rulesinvocations. Whenend_rulesis called, methods are defined that forward the call to DRP’s dispatching system, which in turn dispatches to one of the original methods.Here is a closer look at what’s going on in my DrpGenerator class.
Take a peek at Module#method_added for a good look at how this works.