Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicExpressionImporter.cs @ 6844

Last change on this file since 6844 was 6844, checked in by mkommend, 13 years ago

#1653: Restructured unit tests.

File size: 8.5 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 = "LAGVARIABLE";
32    private const string INTEGRALSTART = "INTEG";
33    private const string DEFUNSTART = "DEFUN";
34    private const string ARGSTART = "ARG";
35    private const string INVOKESTART = "CALL";
36    private const string TIMELAGSTART = "LAG";
37    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>()
38      {
39        {"+", new Addition()},
40        {"/", new Division()},
41        {"*", new Multiplication()},
42        {"-", new Subtraction()},
43        {"EXP", new Exponential()},
44        {"LOG", new Logarithm()},
45        {"POW", new Power()},
46        {"ROOT", new Root()},
47        {"SIN",new Sine()},
48        {"COS", new Cosine()},
49        {"TAN", new Tangent()},
50        {"MEAN", new Average()},
51        {"IF", new IfThenElse()},
52        {">", new GreaterThan()},
53        {"<", new LessThan()},
54        {"AND", new And()},
55        {"OR", new Or()},
56        {"NOT", new Not()},
57        {"DIFF", new Derivative()},
58        {"PROG", new ProgramRootSymbol()},
59        {"MAIN", new StartSymbol()},
60      };
61
62    Constant constant = new Constant();
63    Variable variable = new Variable();
64    LaggedVariable laggedVariable = new LaggedVariable();
65    Defun defun = new Defun();
66    TimeLag timeLag = new TimeLag();
67    Integral integral = new Integral();
68
69    ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
70    StartSymbol startSymbol = new StartSymbol();
71
72    public SymbolicExpressionImporter() {
73    }
74
75    internal ISymbolicExpressionTree Import(string str) {
76      str = str.Replace("(", " ( ").Replace(")", " ) ");
77      ISymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode();
78      ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
79      ISymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str)));
80      if (mainBranch.Symbol is ProgramRootSymbol) {
81        // when a root symbol was parsed => use main branch as root
82        root = mainBranch;
83      } else {
84        // only a main branch was given => insert the main branch into the default tree template
85        root.AddSubtree(start);
86        start.AddSubtree(mainBranch);
87      }
88      return new SymbolicExpressionTree(root);
89    }
90
91    private IEnumerable<Token> GetTokenStream(string str) {
92      return
93             from strToken in str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).AsEnumerable()
94             let t = Token.Parse(strToken)
95             where t != null
96             select t;
97    }
98
99    private ISymbolicExpressionTreeNode ParseSexp(Queue<Token> tokens) {
100      if (tokens.Peek().Symbol == TokenSymbol.LPAR) {
101        ISymbolicExpressionTreeNode tree;
102        Expect(Token.LPAR, tokens);
103        if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
104          tree = ParseVariable(tokens);
105        } else if (tokens.Peek().StringValue.StartsWith(LAGGEDVARSTART)) {
106          tree = ParseLaggedVariable(tokens);
107        } else if (tokens.Peek().StringValue.StartsWith(TIMELAGSTART)) {
108          tree = ParseTimeLag(tokens);
109          tree.AddSubtree(ParseSexp(tokens));
110        } else if (tokens.Peek().StringValue.StartsWith(INTEGRALSTART)) {
111          tree = ParseIntegral(tokens);
112          tree.AddSubtree(ParseSexp(tokens));
113        } else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART)) {
114          tree = ParseDefun(tokens);
115          while (!tokens.Peek().Equals(Token.RPAR)) {
116            tree.AddSubtree(ParseSexp(tokens));
117          }
118        } else if (tokens.Peek().StringValue.StartsWith(ARGSTART)) {
119          tree = ParseArgument(tokens);
120        } else if (tokens.Peek().StringValue.StartsWith(INVOKESTART)) {
121          tree = ParseInvoke(tokens);
122          while (!tokens.Peek().Equals(Token.RPAR)) {
123            tree.AddSubtree(ParseSexp(tokens));
124          }
125        } else {
126          Token curToken = tokens.Dequeue();
127          tree = CreateTree(curToken);
128          while (!tokens.Peek().Equals(Token.RPAR)) {
129            tree.AddSubtree(ParseSexp(tokens));
130          }
131        }
132        Expect(Token.RPAR, tokens);
133        return tree;
134      } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
135        ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode();
136        t.Value = tokens.Dequeue().DoubleValue;
137        return t;
138      } else throw new FormatException("Expected function or constant symbol");
139    }
140
141    private ISymbolicExpressionTreeNode ParseInvoke(Queue<Token> tokens) {
142      Token invokeTok = tokens.Dequeue();
143      Debug.Assert(invokeTok.StringValue == "CALL");
144      InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
145      ISymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();
146      return invokeNode;
147    }
148
149    private ISymbolicExpressionTreeNode ParseArgument(Queue<Token> tokens) {
150      Token argTok = tokens.Dequeue();
151      Debug.Assert(argTok.StringValue == "ARG");
152      Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
153      ISymbolicExpressionTreeNode argNode = argument.CreateTreeNode();
154      return argNode;
155    }
156
157    private ISymbolicExpressionTreeNode ParseDefun(Queue<Token> tokens) {
158      Token defTok = tokens.Dequeue();
159      Debug.Assert(defTok.StringValue == "DEFUN");
160      DefunTreeNode t = (DefunTreeNode)defun.CreateTreeNode();
161      t.FunctionName = tokens.Dequeue().StringValue;
162      return t;
163    }
164
165    private ISymbolicExpressionTreeNode ParseTimeLag(Queue<Token> tokens) {
166      Token varTok = tokens.Dequeue();
167      Debug.Assert(varTok.StringValue == "LAG");
168      LaggedTreeNode t = (LaggedTreeNode)timeLag.CreateTreeNode();
169      t.Lag = (int)tokens.Dequeue().DoubleValue;
170      return t;
171    }
172
173    private ISymbolicExpressionTreeNode ParseIntegral(Queue<Token> tokens) {
174      Token varTok = tokens.Dequeue();
175      Debug.Assert(varTok.StringValue == "INTEGRAL");
176      LaggedTreeNode t = (LaggedTreeNode)integral.CreateTreeNode();
177      t.Lag = (int)tokens.Dequeue().DoubleValue;
178      return t;
179    }
180
181    private ISymbolicExpressionTreeNode ParseVariable(Queue<Token> tokens) {
182      Token varTok = tokens.Dequeue();
183      Debug.Assert(varTok.StringValue == "VARIABLE");
184      VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode();
185      t.Weight = tokens.Dequeue().DoubleValue;
186      t.VariableName = tokens.Dequeue().StringValue;
187      return t;
188    }
189
190    private ISymbolicExpressionTreeNode ParseLaggedVariable(Queue<Token> tokens) {
191      Token varTok = tokens.Dequeue();
192      Debug.Assert(varTok.StringValue == "LAGVARIABLE");
193      LaggedVariableTreeNode t = (LaggedVariableTreeNode)laggedVariable.CreateTreeNode();
194      t.Weight = tokens.Dequeue().DoubleValue;
195      t.VariableName = tokens.Dequeue().StringValue;
196      t.Lag = (int)tokens.Dequeue().DoubleValue;
197      return t;
198    }
199
200    private ISymbolicExpressionTreeNode CreateTree(Token token) {
201      if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
202      return knownSymbols[token.StringValue].CreateTreeNode();
203    }
204
205    private void Expect(Token token, Queue<Token> tokens) {
206      Token cur = tokens.Dequeue();
207      if (!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got: " + cur.StringValue);
208    }
209  }
210}
Note: See TracBrowser for help on using the repository browser.