Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicExpressionImporter.cs @ 6769

Last change on this file since 6769 was 6769, checked in by gkronber, 13 years ago

#1640 fixed a bug in the interpretation of lagged variables introduced with r6740.

File size: 7.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Diagnostics;
25using System.Linq;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
27
28namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tests {
29  internal class SymbolicExpressionImporter {
30    private const string VARSTART = "VAR";
31    private const string LAGGEDVARSTART = "LAG";
32    private const string DEFUNSTART = "DEFUN";
33    private const string ARGSTART = "ARG";
34    private const string INVOKESTART = "CALL";
35    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>()
36      {
37        {"+", new Addition()},
38        {"/", new Division()},
39        {"*", new Multiplication()},
40        {"-", new Subtraction()},
41        {"EXP", new Exponential()},
42        {"LOG", new Logarithm()},
43        {"POW", new Power()},
44        {"ROOT", new Root()},
45        {"SIN",new Sine()},
46        {"COS", new Cosine()},
47        {"TAN", new Tangent()},
48        {"MEAN", new Average()},
49        {"IF", new IfThenElse()},
50        {">", new GreaterThan()},
51        {"<", new LessThan()},
52        {"AND", new And()},
53        {"OR", new Or()},
54        {"NOT", new Not()},
55        {"PROG", new ProgramRootSymbol()},
56        {"MAIN", new StartSymbol()},
57      };
58
59    Constant constant = new Constant();
60    Variable variable = new Variable();
61    LaggedVariable laggedVariable = new LaggedVariable();
62    Defun defun = new Defun();
63
64    ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
65    StartSymbol startSymbol = new StartSymbol();
66
67    public SymbolicExpressionImporter() {
68    }
69
70    internal ISymbolicExpressionTree Import(string str) {
71      str = str.Replace("(", " ( ").Replace(")", " ) ");
72      ISymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode();
73      ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
74      ISymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str)));
75      if (mainBranch.Symbol is ProgramRootSymbol) {
76        // when a root symbol was parsed => use main branch as root
77        root = mainBranch;
78      } else {
79        // only a main branch was given => insert the main branch into the default tree template
80        root.AddSubtree(start);
81        start.AddSubtree(mainBranch);
82      }
83      return new SymbolicExpressionTree(root);
84    }
85
86    private IEnumerable<Token> GetTokenStream(string str) {
87      return
88             from strToken in str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).AsEnumerable()
89             let t = Token.Parse(strToken)
90             where t != null
91             select t;
92    }
93
94    private ISymbolicExpressionTreeNode ParseSexp(Queue<Token> tokens) {
95      if (tokens.Peek().Symbol == TokenSymbol.LPAR) {
96        ISymbolicExpressionTreeNode tree;
97        Expect(Token.LPAR, tokens);
98        if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
99          tree = ParseVariable(tokens);
100        } else if (tokens.Peek().StringValue.StartsWith(LAGGEDVARSTART)) {
101          tree = ParseLaggedVariable(tokens);
102        } else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART)) {
103          tree = ParseDefun(tokens);
104          while (!tokens.Peek().Equals(Token.RPAR)) {
105            tree.AddSubtree(ParseSexp(tokens));
106          }
107        } else if (tokens.Peek().StringValue.StartsWith(ARGSTART)) {
108          tree = ParseArgument(tokens);
109        } else if (tokens.Peek().StringValue.StartsWith(INVOKESTART)) {
110          tree = ParseInvoke(tokens);
111          while (!tokens.Peek().Equals(Token.RPAR)) {
112            tree.AddSubtree(ParseSexp(tokens));
113          }
114        } else {
115          Token curToken = tokens.Dequeue();
116          tree = CreateTree(curToken);
117          while (!tokens.Peek().Equals(Token.RPAR)) {
118            tree.AddSubtree(ParseSexp(tokens));
119          }
120        }
121        Expect(Token.RPAR, tokens);
122        return tree;
123      } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
124        ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode();
125        t.Value = tokens.Dequeue().DoubleValue;
126        return t;
127      } else throw new FormatException("Expected function or constant symbol");
128    }
129
130    private ISymbolicExpressionTreeNode ParseInvoke(Queue<Token> tokens) {
131      Token invokeTok = tokens.Dequeue();
132      Debug.Assert(invokeTok.StringValue == "CALL");
133      InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
134      ISymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();
135      return invokeNode;
136    }
137
138    private ISymbolicExpressionTreeNode ParseArgument(Queue<Token> tokens) {
139      Token argTok = tokens.Dequeue();
140      Debug.Assert(argTok.StringValue == "ARG");
141      Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
142      ISymbolicExpressionTreeNode argNode = argument.CreateTreeNode();
143      return argNode;
144    }
145
146    private ISymbolicExpressionTreeNode ParseDefun(Queue<Token> tokens) {
147      Token defTok = tokens.Dequeue();
148      Debug.Assert(defTok.StringValue == "DEFUN");
149      DefunTreeNode t = (DefunTreeNode)defun.CreateTreeNode();
150      t.FunctionName = tokens.Dequeue().StringValue;
151      return t;
152    }
153
154    private ISymbolicExpressionTreeNode ParseVariable(Queue<Token> tokens) {
155      Token varTok = tokens.Dequeue();
156      Debug.Assert(varTok.StringValue == "VARIABLE");
157      VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode();
158      t.Weight = tokens.Dequeue().DoubleValue;
159      t.VariableName = tokens.Dequeue().StringValue;
160      return t;
161    }
162
163    private ISymbolicExpressionTreeNode ParseLaggedVariable(Queue<Token> tokens) {
164      Token varTok = tokens.Dequeue();
165      Debug.Assert(varTok.StringValue == "LAGVARIABLE");
166      LaggedVariableTreeNode t = (LaggedVariableTreeNode)laggedVariable.CreateTreeNode();
167      t.Weight = tokens.Dequeue().DoubleValue;
168      t.VariableName = tokens.Dequeue().StringValue;
169      t.Lag = (int)tokens.Dequeue().DoubleValue;
170      return t;
171    }
172
173    private ISymbolicExpressionTreeNode CreateTree(Token token) {
174      if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
175      return knownSymbols[token.StringValue].CreateTreeNode();
176    }
177
178    private void Expect(Token token, Queue<Token> tokens) {
179      Token cur = tokens.Dequeue();
180      if (!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got: " + cur.StringValue);
181    }
182  }
183}
Note: See TracBrowser for help on using the repository browser.