Print

Print


So what you're seeing is a warning, not an error.  ECJ is telling you that by not including any boolean terminals, you may run afoul of tree builders if they suddenly need one.  This is because nearly all of these builders are greedy.  As one simple example, what if a tree builder needs to build a tree consisting of a single node?  In your current configuration this is impossible.  

ECJ's "Uniform" tree builder is non-greedy and might do better -- but I should warn you that it's suffering from bit-rot and might not work quite right with multiple types (you'll have to check).

What I'd do as an alternative is simply add two boolean literals, "true" and "false", as terminals in your boolean function set.

Sean

On Sep 19, 2012, at 3:52 PM, Warren Henning wrote:

> I'm trying to use strongly-typed Koza-style GP with two data types:
> booleans and doubles. The terminals return doubles and the booleans
> take the doubles and return true or false, which allows the formation
> of comprehensible rules like "X > Y", assuming X and Y were terminals
> returning doubles.
> 
> So my boolean functions are logical functions and comparison
> functions. I want those at the top and the number-returning terminals
> at the bottom of the individuals being created.
> 
> So I have node constraints in my params file that I wished to try to
> achieve this (an excerpt follows):
> 
> gp.type.a.size = 2
> gp.type.a.0.name = boolean
> gp.type.a.1.name = nil
> 
> # IfElse
> 
> gp.nc.3 = ec.gp.GPNodeConstraints
> gp.nc.3.name = booldoubledouble
> gp.nc.3.returns = nil
> gp.nc.3.size = 3
> gp.nc.3.child.0 = boolean
> gp.nc.3.child.1 = nil
> gp.nc.3.child.2 = nil
> 
> # And, Or, Xor
> 
> gp.nc.4 = ec.gp.GPNodeConstraints
> gp.nc.4.name = boolbool
> gp.nc.4.returns = boolean
> gp.nc.4.size = 2
> gp.nc.4.child.0 = boolean
> gp.nc.4.child.1 = boolean
> 
> etc.
> 
> Then my function set returns nil or boolean:
> 
> gp.fs.0.func.0 = ec.app.liarsevolution.main.functions.arithmetic.Sub
> gp.fs.0.func.0.nc = nc2
> gp.fs.0.func.1 = ec.app.liarsevolution.main.functions.arithmetic.Mul
> gp.fs.0.func.1.nc = nc2
> ...
> gp.fs.0.func.5 = ec.app.liarsevolution.main.functions.bool.And
> gp.fs.0.func.5.nc = boolbool
> ...
> 
> But then when I run the Evolve class with this configuration file, I
> get these warnings that I did not expect:
> 
> 
> WARNING:
> In function set f0 for the GPTreeConstraints tc0, no terminals are
> given with the return type boolean which is required by other
> functions in the function set or by the tree's return type.  Nearly
> all tree-builders in ECJ require the ability to add a terminal of any
> type for which there is a nonterminal, and at any time.  Without
> terminals, your code may not work.  One common indication that a
> tree-builder has failed due to this problem is if you get the
> MersenneTwister error 'n must be positive'.
> PARAMETER: gp.tc.0
> WARNING:
> In function set f0 for the GPTreeConstraints tc1, no terminals are
> given with the return type boolean which is required by other
> functions in the function set or by the tree's return type.  Nearly
> all tree-builders in ECJ require the ability to add a terminal of any
> type for which there is a nonterminal, and at any time.  Without
> terminals, your code may not work.  One common indication that a
> tree-builder has failed due to this problem is if you get the
> MersenneTwister error 'n must be positive'.
> 
> (As you can see, each individual has two trees, both of which use the
> same function set.) I figured it was acceptable to not have the
> terminals return boolean, as they return doubles which the comparison
> functions i have ("greater than", "less than", etc) take these doubles
> and return a boolean, the way i want. The node constraint I have for
> this is:
> 
> gp.nc.6 = ec.gp.GPNodeConstraints
> gp.nc.6.name = comparison
> gp.nc.6.returns = boolean
> gp.nc.6.size = 2
> gp.nc.6.child.0 = nil
> gp.nc.6.child.1 = nil
> 
> Then the comparison functions are set up like so:
> 
> gp.fs.0.func.9 = ec.app.liarsevolution.main.functions.comparison.Equal
> gp.fs.0.func.9.nc = comparison
> 
> My GPData class just has a double and a boolean variable. The
> double-returning terminals set the double variable and the logical
> functions set the boolean variable in my GPData-inheriting class. The
> GP individual itself is ultimately meant to return a boolean (i.e., it
> can be interpreted as a true/false rule).
> 
> I appreciate any help. Please let me know if I need to clarify/post
> more information. Thank you!
> 
> Best regards,
> Warren Henning