Question

Hopefully there are a few experts in the EpochX framework around here...I'm not sure that the user group is still active.

I am attempting to implement simple recursion within their represention of a BNF grammar and have fun into the following issue:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -9
    at java.lang.String.substring(String.java:1911)
    at org.epochx.epox.EpoxParser.parse(EpoxParser.java:235)
    at org.epochx.epox.EpoxParser.parse(EpoxParser.java:254)
    at org.epochx.tools.eval.EpoxInterpreter.eval(EpoxInterpreter.java:89)
    at org.epochx.ge.model.epox.SAGE.getFitness(SAGE.java:266)
    at org.epochx.ge.representation.GECandidateProgram.getFitness(GECandidateProgram.java:304)
    at org.epochx.stats.StatField$7.getStatValue(StatField.java:97)
    at org.epochx.stats.Stats.getStat(Stats.java:134)
    at org.epochx.stats.StatField$8.getStatValue(StatField.java:117)
    at org.epochx.stats.Stats.getStat(Stats.java:134)
    at org.epochx.stats.Stats.getStats(Stats.java:162)
    at org.epochx.stats.Stats.print(Stats.java:194)
    at org.epochx.stats.Stats.print(Stats.java:178)
    at org.epochx.ge.model.epox.Tester$1.onGenerationEnd(Tester.java:41)
    at org.epochx.life.Life.fireGenerationEndEvent(Life.java:634)
    at org.epochx.core.InitialisationManager.initialise(InitialisationManager.java:207)
    at org.epochx.core.RunManager.run(RunManager.java:166)
    at org.epochx.core.Model.run(Model.java:147)
    at org.epochx.ge.model.GEModel.run(GEModel.java:82)
    at org.epochx.ge.model.epox.Tester.main(Tester.java:55)
Java Result: 1

My simple grammar is structured as follows, where terminals are passed in separately to the evaluation function:

  public static final String GRAMMAR_FRAGMENT = "<program> ::= <node>\n"
          + "<node> ::= <s_list>\n"
          + "<s_list> ::= <s> | <s> <s_list>\n"
          + "<s> ::= FUNCTION( <terminal> )\n"
          + "<terminal> ::= ";

Edit: Terminal creation -

// Generate the input sequences.
inputValues = BoolUtils.generateBoolSequences(4);

argNames = new String[4];
argNames[0] = "void";
argNames[1] = "bubbleSort";
argNames[2] = "int*";
argNames[3] = "numbers";

...

// Evaluate all possible inputValues.

    for (final boolean[] vars: inputValues) {
        // Convert to object array.
        final Boolean[] objVars = ArrayUtils.toObject(vars);

        Boolean result = null;
        try {
                      interpreter.eval(program.getSourceCode(),
                    argNames, objVars);
                      score = (double)program.getParseTreeDepth();
        } catch (final MalformedProgramException e) {
            // Assign worst possible fitness and stop evaluating.
            score = 0;
            break;
        }
    }
Was it helpful?

Solution

The stacktrace shows that the problem is actually in the EpoxParser, this means that its not so much the grammar that is ill-formed, but rather that the programs that get generated cannot be parsed.

Because you're using the EpoxInterpreter, the programs that get generated get parsed as Epox programs. Epox is the name used to refer to the language that the tree representation of EpochX uses (a sort of corrupted form of Lisp which you can add your own literals/functions to). The parsing expects the S-Expression format, and tries to identify each function and terminal and it builds a tree made up of equivalent Node objects (see the org.epochx.epox.* packages). Then the tree can be evaluated to run the program.

But in Epox there's no built-in function called FUNCTION, nor any known literals 'void', 'bubbleSort', 'int*' or 'numbers'. So the parsing fails. So you need to add these constructs to the EpoxParser, so it knows how to parse them into nodes. You can do this with the declareFunction, declareLiteral and declareVariable methods (see the JavaDoc for the EpoxParser http://www.epochx.org/javadoc/1.4/).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top