Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler/SymbolicExpressionTreeCompiler.cs @ 3742

Last change on this file since 3742 was 3462, checked in by gkronber, 14 years ago

Refactored symbolic expression tree encoding and problem classes for symbolic regression. #937 , #938

File size: 4.0 KB
RevLine 
[3294]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
[3376]25using HeuristicLab.Common;
[3294]26using HeuristicLab.Core;
27using System.Collections.Generic;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
[3462]29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
[3294]30
[3462]31namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Compiler {
[3294]32  public class SymbolicExpressionTreeCompiler {
[3462]33    private Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>();
34    private List<Func<Instruction, Instruction>> postInstructionCompiledHooks = new List<Func<Instruction, Instruction>>();
[3294]35
[3462]36    public Instruction[] Compile(SymbolicExpressionTree tree, Func<SymbolicExpressionTreeNode, byte> opCodeMapper) {
[3294]37      List<Instruction> code = new List<Instruction>();
38      entryPoint.Clear();
39      // compile main body
[3462]40      code.AddRange(Compile(tree.Root.SubTrees[0].SubTrees[0], opCodeMapper));
[3294]41      // compile branches
42      var functionBranches = from node in tree.IterateNodesPrefix()
43                             where node.Symbol is Defun
44                             select node;
45      foreach (DefunTreeNode branch in functionBranches) {
[3462]46        if (code.Count > ushort.MaxValue) throw new ArgumentException("Code for the tree is too long (> ushort.MaxValue).");
47        entryPoint[branch.FunctionName] = (ushort)code.Count;
48        code.AddRange(Compile(branch.SubTrees[0], opCodeMapper));
[3294]49      }
[3442]50      // address of all functions is fixed now
51      // iterate through code again and fill in the jump locations
52      for (int i = 0; i < code.Count; i++) {
53        Instruction instr = code[i];
[3462]54        if (instr.dynamicNode.Symbol is InvokeFunction) {
[3442]55          var invokeNode = (InvokeFunctionTreeNode)instr.dynamicNode;
56          instr.iArg0 = entryPoint[invokeNode.Symbol.FunctionName];
57          code[i] = instr;
58        }
59      }
60
[3294]61      return code.ToArray();
62    }
63
[3462]64    private IEnumerable<Instruction> Compile(SymbolicExpressionTreeNode branch, Func<SymbolicExpressionTreeNode, byte> opCodeMapper) {
65      foreach (var node in branch.IterateNodesPrefix()) {
[3294]66        Instruction instr = new Instruction();
[3462]67        if (node.SubTrees.Count > 255) throw new ArgumentException("Number of subtrees is too big (>255)");
[3294]68        instr.nArguments = (byte)node.SubTrees.Count;
[3462]69        instr.opCode = opCodeMapper(node);
70        if (branch.Symbol is Argument) {
71          var argNode = (ArgumentTreeNode)node;
72          instr.iArg0 = (ushort)argNode.Symbol.ArgumentIndex;
[3294]73        }
[3462]74        instr.dynamicNode = node;
75        foreach (var hook in postInstructionCompiledHooks) {
76          instr = hook(instr);
77        }
[3294]78        yield return instr;
79      }
80    }
81
[3462]82    /// <summary>
83    /// Adds a function that will be called every time an instruction is compiled.
84    /// The compiled will insert the instruction returned by the hook into the code.
85    /// </summary>
86    /// <param name="hook">The hook that should be called for each compiled instruction.</param>
87    public void AddInstructionPostProcessingHook(Func<Instruction, Instruction> hook) {
88      postInstructionCompiledHooks.Add(hook);
[3294]89    }
90  }
91}
Note: See TracBrowser for help on using the repository browser.