Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1418: Reintegrated branch into trunk.

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