/// <summary>
        ///     Construct the program node.
        /// </summary>
        /// <param name="theOwner">The owner of the node.</param>
        /// <param name="theTemplate">The opcode that this node is based on.</param>
        /// <param name="theArgs">The child nodes to this node.</param>
        public ProgramNode(EncogProgram theOwner,
                           IProgramExtensionTemplate theTemplate,
                           ITreeNode[] theArgs)
        {
            _owner = theOwner;
            _data = new ExpressionValue[theTemplate.DataSize];
            _template = theTemplate;
            AddChildNodes(theArgs);

            for (int i = 0; i < _data.Length; i++)
            {
                _data[i] = new ExpressionValue((long) 0);
            }
        }
Exemple #2
0
        /// <summary>
        ///     This method is used when parsing an expression. Consider x>=2. The parser
        ///     first sees the > symbol. But it must also consider the =. So we first
        ///     look for a 2-char operator, in this case there is one.
        /// </summary>
        /// <param name="ch1">The first character of the potential operator.</param>
        /// <param name="ch2">The second character of the potential operator. Zero if none.</param>
        /// <returns>The expression template for the operator found.</returns>
        public IProgramExtensionTemplate FindOperator(char ch1, char ch2)
        {
            // if ch2==0 then we are only looking for a single char operator.
            // this is rare, but supported.
            if (ch2 == 0)
            {
                return(FindOperatorExact("" + ch1));
            }

            // first, see if we can match an operator with both ch1 and ch2
            IProgramExtensionTemplate result = FindOperatorExact("" + ch1 + ch2) ?? FindOperatorExact("" + ch1);

            // return the operator if we have one.
            return(result);
        }
        /// <summary>
        ///     Factor a new program node, based on an opcode name and arguments.
        /// </summary>
        /// <param name="name">The name of the opcode.</param>
        /// <param name="program">The program to factor for.</param>
        /// <param name="args">The arguements.</param>
        /// <returns>The newly created ProgramNode.</returns>
        public ProgramNode FactorProgramNode(String name,
                                             EncogProgram program, ProgramNode[] args)
        {
            String key = EncogOpcodeRegistry.CreateKey(name, args.Length);

            if (!_templateMap.ContainsKey(key))
            {
                throw new EACompileError("Undefined function/operator: " + name
                                         + " with " + args.Length + " args.");
            }

            IProgramExtensionTemplate temp = _templateMap[key];

            return(new ProgramNode(program, temp, args));
        }
        /// <summary>
        ///     Add an opcode to the function factory from the opcode registry.
        /// </summary>
        /// <param name="name">The name of the opcode.</param>
        /// <param name="args">The number of arguments.</param>
        public void AddExtension(String name, int args)
        {
            String key = EncogOpcodeRegistry.CreateKey(name, args);

            if (!_templateMap.ContainsKey(key))
            {
                IProgramExtensionTemplate temp = EncogOpcodeRegistry.Instance
                                                 .FindOpcode(name, args);
                if (temp == null)
                {
                    throw new EACompileError("Unknown extension " + name + " with "
                                             + args + " arguments.");
                }
                _opcodes.Add(temp);
                _templateMap[key] = temp;
            }
        }
Exemple #5
0
        private void handleSymbol()
        {
            char ch1 = this.parser.ReadChar();

            // handle unary
            if (this.unary)
            {
                if (ch1 == '+')
                {
                    return;
                }
                else if (ch1 == '-')
                {
                    this.functionStack.Push(StandardExtensions.EXTENSION_NEG);
                    return;
                }
            }

            // handle regular operator
            char ch2 = (char)0;

            if (!this.parser.EOL())
            {
                ch2 = this.parser.Peek();
            }

            IProgramExtensionTemplate temp = this.holder.Functions.FindOperator(ch1, ch2);

            // did we find anything?
            if (temp != null)
            {
                // if we found a 2-char operator, then advance beyond the 2nd
                // char
                if (temp.Name.Length > 1)
                {
                    this.parser.Advance();
                }
                functionQueue(temp);
            }
            else
            {
                throw new EACompileError("Unknown symbol: " + ch1);
            }
        }
Exemple #6
0
        private void functionQueue(IProgramExtensionTemplate f)
        {
            // while there is an operator token, o2, at the top of the stack, and
            // either o1 is left-associative and o1 has precedence less than or
            // equal to that of o2,
            // or o1 has precedence less than that of o2,

            while (this.functionStack.Count != 0 &&
                   this.functionStack.Peek().NodeType != NodeType.None &&
                   ((f.NodeType == NodeType.OperatorLeft && f
                     .Precedence >= this.functionStack.Peek()
                     .Precedence) || f.Precedence > this.functionStack
                    .Peek().Precedence))
            {
                OutputQueue(this.functionStack.Pop());
            }

            functionStack.Push(f);
        }
        /// <summary>
        ///     Create a terminal node.
        /// </summary>
        /// <param name="rnd">A random number generator.</param>
        /// <param name="program">The program to generate for.</param>
        /// <param name="types">The types that we might generate.</param>
        /// <returns>The terminal program node.</returns>
        public ProgramNode CreateTerminalNode(EncogRandom rnd,
                                              EncogProgram program, IList <EPLValueType> types)
        {
            IProgramExtensionTemplate temp = GenerateRandomOpcode(
                rnd,
                Context.Functions.FindOpcodes(types, _context,
                                              true, false));

            if (temp == null)
            {
                throw new EACompileError("No opcodes exist for the type: "
                                         + types);
            }
            var result = new ProgramNode(program, temp,
                                         new ProgramNode[] {});

            temp.Randomize(rnd, types, result, MinConst, MaxConst);
            return(result);
        }
Exemple #8
0
        private void OutputQueue(IProgramExtensionTemplate opp)
        {
            if (opp == this.LEFT_PAREN)
            {
                throw new EACompileError("Unmatched parentheses");
            }

            ProgramNode[] args = new ProgramNode[opp.ChildNodeCount];

            for (int i = args.Length - 1; i >= 0; i--)
            {
                if (this.outputStack.Count == 0)
                {
                    throw new EACompileError("Not enough arguments");
                }
                args[i] = this.outputStack.Pop();
            }

            this.rootNode = this.holder.Functions.FactorProgramNode(opp,
                                                                    this.holder, args);
            outputStack.Push(rootNode);
        }
 /// <summary>
 ///     Factor a new program node, based in a template object.
 /// </summary>
 /// <param name="temp">The opcode.</param>
 /// <param name="program">The program.</param>
 /// <param name="args">The arguments for this node.</param>
 /// <returns>The newly created ProgramNode.</returns>
 public ProgramNode FactorProgramNode(IProgramExtensionTemplate temp,
                                      EncogProgram program, ProgramNode[] args)
 {
     return(new ProgramNode(program, temp, args));
 }
Exemple #10
0
        public ProgramNode Parse(String expression)
        {
            this.parser = new SimpleParser(expression);
            this.unary  = true;

            while (!parser.EOL())
            {
                parser.EatWhiteSpace();
                char ch = parser.Peek();
                if (ch == '.' || char.IsDigit(ch))
                {
                    HandleNumeric();
                    this.unary = false;
                }
                else if (char.IsLetter(ch))
                {
                    handleAlpha(false);
                    this.unary = false;
                }
                else if (ch == '(')
                {
                    this.parser.Advance();
                    this.functionStack.Push(LEFT_PAREN);
                    this.unary = true;
                }
                else if (ch == ')')
                {
                    handleRightParen();
                    this.unary = false;
                }
                else if ("<>^*/+-=&|".IndexOf(ch) != -1)
                {
                    handleSymbol();
                    this.unary = true;
                }
                else if (ch == '\"')
                {
                    handleString();
                    this.unary = false;
                }
                else if (ch == ',')
                {
                    HandleFunctionSeparator();
                    this.unary = true;
                }
                else
                {
                    throw new EACompileError("Unparsable character: " + ch);
                }
            }

            // pop off any functions still on the stack
            while (this.functionStack.Count > 0)
            {
                IProgramExtensionTemplate f = this.functionStack.Pop();
                OutputQueue(f);
            }

            // were there no operators?
            if (this.rootNode == null)
            {
                this.rootNode = this.outputStack.Pop();
            }

            return(this.rootNode);
        }
Exemple #11
0
        public ProgramNode Parse(String expression)
        {
            this.parser = new SimpleParser(expression);

            while (!this.parser.EOL())
            {
                this.parser.EatWhiteSpace();

                // read in the command
                if (this.parser.ReadChar() != '[')
                {
                    throw new EACompileError("Expected [");
                }
                this.parser.EatWhiteSpace();
                StringBuilder cmd = new StringBuilder();
                while (this.parser.Peek() != ']' && !this.parser.EOL())
                {
                    cmd.Append(this.parser.ReadChar());
                }

                if (this.parser.Peek() != ']')
                {
                    throw new EACompileError("Expected ]");
                }
                this.parser.Advance();

                // parse out the command
                string[] tok                   = cmd.ToString().Split(':');
                int      idx                   = 0;
                String   name                  = tok[idx++];
                int      childCount            = int.Parse(tok[idx++]);
                IProgramExtensionTemplate temp = EncogOpcodeRegistry.Instance.FindOpcode(name, childCount);
                if (temp == null)
                {
                    throw new EACompileError("Invalid instruction: " + name);
                }

                // build the arguments
                ProgramNode[] args = new ProgramNode[childCount];
                for (int i = args.Length - 1; i >= 0; i--)
                {
                    args[i] = this.nodeStack.Pop();
                }

                // factor the node
                ProgramNode node = this.holder.Functions.FactorProgramNode(name, this.holder, args);
                this.nodeStack.Push(node);

                // add any needed data to the node
                for (int i = 0; i < temp.DataSize; i++)
                {
                    String str    = tok[idx++].Trim();
                    int    strIdx = str.IndexOf('#');
                    if (strIdx != -1)
                    {
                        int enumType = int.Parse(str.Substring(0, strIdx));
                        int enumVal  = int.Parse(str.Substring(strIdx + 1));
                        node.Data[0] = new ExpressionValue(enumType, enumVal);
                    }
                    // is it boolean?
                    else if (str.Length == 1 && "tf".IndexOf(char.ToLower(str[0])) != -1)
                    {
                        node.Data[i] = new ExpressionValue(string.Compare(str, "t", true));
                    }
                    // is it a string?
                    else if (str[0] == '\"')
                    {
                        node.Data[i] = new ExpressionValue(str.Substring(1, str.Length - 1));
                    }
                    // is it an integer
                    else if (str.IndexOf('.') == -1 && str.ToLower().IndexOf('e') == -1)
                    {
                        long l;
                        try
                        {
                            l = long.Parse(str);
                        }
                        catch (FormatException ex)
                        {
                            // sometimes C# will output a long value that is larger than can be parsed
                            // this is very likely not a useful genome and we just set it to zero so that
                            // the population load does not fail.
                            l = 0;
                        }
                        node.Data[i] = new ExpressionValue(l);
                    }
                    // At this point, must be a float
                    else
                    {
                        node.Data[i] = new ExpressionValue(CSVFormat.EgFormat.Parse(str));
                    }
                }
            }

            return(this.nodeStack.Pop());
        }
 /// <summary>
 ///     Factor a new program node, based in a template object.
 /// </summary>
 /// <param name="temp">The opcode.</param>
 /// <param name="program">The program.</param>
 /// <param name="args">The arguments for this node.</param>
 /// <returns>The newly created ProgramNode.</returns>
 public ProgramNode FactorProgramNode(IProgramExtensionTemplate temp,
                                      EncogProgram program, ProgramNode[] args)
 {
     return new ProgramNode(program, temp, args);
 }
 /// <summary>
 ///     Add an opcode to the function factory. The opcode must exist in the
 ///     opcode registry.
 /// </summary>
 /// <param name="ext">The opcode to add.</param>
 public void AddExtension(IProgramExtensionTemplate ext)
 {
     AddExtension(ext.Name, ext.ChildNodeCount);
 }
        private void OutputQueue(IProgramExtensionTemplate opp)
        {
            if (opp == this.LEFT_PAREN)
            {
                throw new EACompileError("Unmatched parentheses");
            }

            ProgramNode[] args = new ProgramNode[opp.ChildNodeCount];

            for (int i = args.Length - 1; i >= 0; i--)
            {
                if (this.outputStack.Count == 0)
                {
                    throw new EACompileError("Not enough arguments");
                }
                args[i] = this.outputStack.Pop();
            }

            this.rootNode = this.holder.Functions.FactorProgramNode(opp,
                    this.holder, args);
            outputStack.Push(rootNode);
        }
        private void functionQueue(IProgramExtensionTemplate f)
        {
            // while there is an operator token, o2, at the top of the stack, and
            // either o1 is left-associative and o1 has precedence less than or
            // equal to that of o2,
            // or o1 has precedence less than that of o2,

            while (this.functionStack.Count != 0
                    && this.functionStack.Peek().NodeType != NodeType.None
                    && ((f.NodeType == NodeType.OperatorLeft && f
                            .Precedence >= this.functionStack.Peek()
                            .Precedence) || f.Precedence > this.functionStack
                            .Peek().Precedence))
            {
                OutputQueue(this.functionStack.Pop());
            }

            functionStack.Push(f);
        }
 /// <summary>
 ///     Add an opcode. User programs should add opcodes here.
 /// </summary>
 /// <param name="ext">The opcode to add.</param>
 public void Add(IProgramExtensionTemplate ext)
 {
     _registry[
         CreateKey(ext.Name,
                   ext.ChildNodeCount)] = ext;
 }
 /// <summary>
 ///     Add an opcode. User programs should add opcodes here.
 /// </summary>
 /// <param name="ext">The opcode to add.</param>
 public void Add(IProgramExtensionTemplate ext)
 {
     _registry[
         CreateKey(ext.Name,
                   ext.ChildNodeCount)] = ext;
 }
        /// <summary>
        ///     Create a random note according to the specified paramaters.
        /// </summary>
        /// <param name="rnd">A random number generator.</param>
        /// <param name="program">The program to generate for.</param>
        /// <param name="depthRemaining">The depth remaining to generate.</param>
        /// <param name="types">The types to generate.</param>
        /// <param name="includeTerminal">Should we include terminal nodes.</param>
        /// <param name="includeFunction">Should we include function nodes.</param>
        /// <returns>The generated program node.</returns>
        public ProgramNode CreateRandomNode(EncogRandom rnd,
                                            EncogProgram program, int depthRemaining,
                                            IList <EPLValueType> types, bool includeTerminal,
                                            bool includeFunction)
        {
            // if we've hit the max depth, then create a terminal nodes, so it stops
            // here
            if (depthRemaining == 0)
            {
                return(CreateTerminalNode(rnd, program, types));
            }

            // choose which opcode set we might create the node from
            IList <IProgramExtensionTemplate> opcodeSet = Context.Functions.FindOpcodes(types, Context,
                                                                                        includeTerminal, includeFunction);

            // choose a random opcode
            IProgramExtensionTemplate temp = GenerateRandomOpcode(rnd,
                                                                  opcodeSet);

            if (temp == null)
            {
                throw new EACompileError(
                          "Trying to generate a random opcode when no opcodes exist.");
            }

            // create the child nodes
            int childNodeCount = temp.ChildNodeCount;
            var children       = new ProgramNode[childNodeCount];

            if (EncogOpcodeRegistry.IsOperator(temp.NodeType) && children.Length >= 2)
            {
                // for an operator of size 2 or greater make sure all children are
                // the same time
                IList <EPLValueType> childTypes = temp.Params[0]
                                                  .DetermineArgumentTypes(types);
                EPLValueType selectedType = childTypes[rnd
                                                       .Next(childTypes.Count)];
                childTypes.Clear();
                childTypes.Add(selectedType);

                // now create the children of a common type
                for (int i = 0; i < children.Length; i++)
                {
                    children[i] = CreateNode(rnd, program, depthRemaining - 1,
                                             childTypes);
                }
            }
            else
            {
                // otherwise, let the children have their own types
                for (int i = 0; i < children.Length; i++)
                {
                    IList <EPLValueType> childTypes = temp.Params[i]
                                                      .DetermineArgumentTypes(types);
                    children[i] = CreateNode(rnd, program, depthRemaining - 1,
                                             childTypes);
                }
            }

            // now actually create the node
            var result = new ProgramNode(program, temp, children);

            temp.Randomize(rnd, types, result, MinConst, MaxConst);
            return(result);
        }
 /// <summary>
 ///     Construct using an extension template.
 /// </summary>
 /// <param name="temp">The template.</param>
 public ScriptOpcode(IProgramExtensionTemplate temp)
     : this(temp.Name, temp.ChildNodeCount)
 {
 }
Exemple #20
0
        private void handleAlpha(bool neg)
        {
            StringBuilder varName = new StringBuilder();

            while (char.IsLetterOrDigit(this.parser.Peek()))
            {
                varName.Append(this.parser.ReadChar());
            }

            this.parser.EatWhiteSpace();

            if (varName.ToString().Equals("true"))
            {
                if (neg)
                {
                    throw new EACompileError("Invalid negative sign.");
                }
                ProgramNode v = this.holder.Functions.FactorProgramNode("#const",
                                                                        holder, new ProgramNode[] { });
                v.Data[0] = new ExpressionValue(true);
                OutputQueue(v);
            }
            else if (varName.ToString().Equals("false"))
            {
                if (neg)
                {
                    throw new EACompileError("Invalid negative sign.");
                }
                ProgramNode v = this.holder.Functions.FactorProgramNode("#const",
                                                                        holder, new ProgramNode[] { });
                v.Data[0] = new ExpressionValue(false);
                OutputQueue(v);
            }
            else if (this.parser.Peek() != '(')
            {
                ProgramNode v;
                // either a variable or a const, see which
                if (this.holder.Functions.IsDefined(varName.ToString(), 0))
                {
                    v = this.holder.Functions.FactorProgramNode(
                        varName.ToString(), holder, new ProgramNode[] { });
                }
                else
                {
                    this.holder.Variables.SetVariable(varName.ToString(),
                                                      new ExpressionValue((long)0));
                    v = this.holder.Functions.FactorProgramNode("#var", holder,
                                                                new ProgramNode[] { });
                    v.Data[0] = new ExpressionValue((int)this.holder.Variables
                                                    .GetVariableIndex(varName.ToString()));
                }

                if (neg)
                {
                    v = this.holder.Functions.FactorProgramNode("-", holder,
                                                                new ProgramNode[] { v });
                }
                OutputQueue(v);
            }
            else
            {
                IProgramExtensionTemplate temp = this.holder.Functions
                                                 .FindFunction(varName.ToString());
                if (temp == null)
                {
                    throw new EACompileError("Undefined function: "
                                             + varName.ToString());
                }
                functionQueue(temp);
            }
        }
 /// <summary>
 ///     Add an opcode to the function factory. The opcode must exist in the
 ///     opcode registry.
 /// </summary>
 /// <param name="ext">The opcode to add.</param>
 public void AddExtension(IProgramExtensionTemplate ext)
 {
     AddExtension(ext.Name, ext.ChildNodeCount);
 }
 /// <summary>
 ///     Construct using an extension template.
 /// </summary>
 /// <param name="temp">The template.</param>
 public ScriptOpcode(IProgramExtensionTemplate temp)
     : this(temp.Name, temp.ChildNodeCount)
 {
 }