0

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;
        }
    }
erik
  • 3,810
  • 6
  • 32
  • 63
  • Are you adding the terminals dynamically before creating the Grammar object? If so, can you post that part of the grammar too, if not - that's probably the problem. – Tom Castle Aug 09 '13 at 13:33
  • Sure, did just that. Basically I hijacked the even parity inputs for now and renamed them. The intention is to move them over to objects (similar to the Ant problem), but for now I figured it could evaluate Booleans just to run the tree and get my grammar in shape. – erik Aug 09 '13 at 14:20

1 Answers1

1

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/).

Tom Castle
  • 2,198
  • 1
  • 16
  • 20
  • Thanks...I will try that out. I have a followup question regarding this since I have you here. I had to go back to version 1.33.1 in order to add in the custom primitives...in 1.41.1 I could not get the new primitive classes I created to trigger any sort of breakpoint in their instantiation or evaluation. I tried the `declareFunction` and couldn't get that going... – erik Aug 09 '13 at 17:23
  • Actually, furthermore, I have been declaring those functions as `} else if (name.equals("FUNCTION")) { node = new FUNCTION(obj);` – erik Aug 09 '13 at 17:44
  • Sorry, I don't really understand the followup question. What do you mean by custom primatives? Do you mean you've created new types of Node? – Tom Castle Aug 11 '13 at 17:40
  • My mistake, was using the internal wording we had for our project. I managed to get 1.41.1 working with a modified version of our BNF grammar that we have been using. Out of curiosity, is the Google Group no longer active? I'd tried posting on there as well but it seems my questions got held up in moderation. – erik Aug 12 '13 at 00:34