internal static string InterpretIf(ISymbolicExpressionTreeNode node) { ISymbolicExpressionTreeNode condition = null, truePart = null, falsePart = null; string[] parts = new string[3]; if (node.SubtreeCount < 2 || node.SubtreeCount > 3) { throw new Exception("Unexpected number of children. Expected 2 or 3 children."); } condition = node.GetSubtree(0); truePart = node.GetSubtree(1); if (node.SubtreeCount == 3) { falsePart = node.GetSubtree(2); } parts[0] = Interpret(condition); parts[1] = Interpret(truePart); if (falsePart != null) { parts[2] = Interpret(falsePart); } return(string.Format("if ({0}) {{ {1} }} else {{ {2} }}", Interpret(condition), Interpret(truePart), falsePart == null ? string.Empty : Interpret(falsePart))); }
internal static string InterpretWhile(ISymbolicExpressionTreeNode node) { var cond = Interpret(node.GetSubtree(0)); var body = Interpret(node.GetSubtree(1)); return(string.Format("while ({0}) {{ {2} {1} {2} }} {2}", cond, body, Environment.NewLine)); }
/// Evaluate a whole tree branch, each branch returns an integer vector. /// Evaluation algorithm-> transform tree to graph /// 1. Recursive decention within node /// - if current node is a end node then return /// - else if current node is regular node then add the type to the builder /// and if node has futher nodes create new builder for branches /// 2. Use the NetworkBuilder to transform into vertices and relashionships /// 3. Send result via Rest API to external Evaluation Endpoint /// 4. Return final result private void EvaluateNetworkProgram(ISymbolicExpressionTreeNode node) { // The program-root and start symbols are predefined symbols // in each problem using the symbolic expression tree encoding. // These symbols must be handled by the interpreter. Here simply // evaluate the whole sub-tree if (node.Symbol is ProgramRootSymbol) { EvaluateNetworkProgram(node.GetSubtree(0)); } else if (node.Symbol is StartSymbol) { EvaluateNetworkProgram(node.GetSubtree(0)); } else if (node.Symbol is ConvolutionalLayerSymbol) { // TODO currentScore += 1; } else if (node.Symbol is FullyConnectedLayerSymbol) { // TODO currentScore += 0.5; } else if (node.Symbol is PoolingLayerSymbol) { // TODO currentScore += 2; } currentTimeSteps++; }
private void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.Append("Power["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", Divide[1,"); FormatRecursively(node.GetSubtree(1), strBuilder); strBuilder.Append("]]"); }
private void FormatRoot(int level, ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.AppendLine("POWER("); FormatRecursively(level, node.GetSubtree(0), strBuilder); strBuilder.AppendLineIndented(level, " , 1.0 / ("); FormatRecursively(level, node.GetSubtree(1), strBuilder); strBuilder.AppendLineIndented(level, "))"); }
private void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.Append("Math.Pow("); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", 1.0 / ("); FormatRecursively(node.GetSubtree(1), strBuilder); strBuilder.Append("))"); }
private void FormatIf(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.Append("If[Greater["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", 0], "); FormatRecursively(node.GetSubtree(1), strBuilder); strBuilder.Append(", "); FormatRecursively(node.GetSubtree(2), strBuilder); strBuilder.Append("]"); }
private void FormatAverage(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { // mean function needs a list of values strBuilder.Append("Mean[{"); FormatRecursively(node.GetSubtree(0), strBuilder); for (int i = 1; i < node.SubtreeCount; i++) { strBuilder.Append(","); FormatRecursively(node.GetSubtree(i), strBuilder); } strBuilder.Append("}]"); }
private void FormatIfThenElse(int level, ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.Append("CASE ISNULL((SELECT 1 WHERE"); FormatRecursively(level, node.GetSubtree(0), strBuilder); strBuilder.AppendLine("),0)"); strBuilder.AppendIndented(level, "WHEN 1 THEN "); FormatRecursively(level, node.GetSubtree(1), strBuilder); strBuilder.AppendLine(); strBuilder.AppendIndented(level, "WHEN 0 THEN "); FormatRecursively(level, node.GetSubtree(2), strBuilder); strBuilder.AppendLine(); strBuilder.AppendIndented(level, "END"); }
private IEnumerable <double> InterpretRec(ISymbolicExpressionTreeNode node, IDataset dataset, IEnumerable <int> rows) { Func <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, Func <double, double, double>, IEnumerable <double> > binaryEval = (left, right, f) => InterpretRec(left, dataset, rows).Zip(InterpretRec(right, dataset, rows), f); switch (node.Symbol.Name) { case "+": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x + y)); case "*": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x * y)); case "-": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x - y)); case "%": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => y.IsAlmost(0.0) ? 0.0 : x / y)); // protected division default: { double erc; if (double.TryParse(node.Symbol.Name, out erc)) { return(rows.Select(_ => erc)); } else { // assume that this is a variable name return(dataset.GetDoubleValues(node.Symbol.Name, rows)); } } } }
public static string InterpretComparison(string compSy, ISymbolicExpressionTreeNode node) { ISymbolicExpressionTreeNode lhs = null, rhs = null; if (node.SubtreeCount != 2) { throw new ArgumentException(string.Format("Expected exactly two children in {0}.", node.Symbol), "node"); } lhs = node.GetSubtree(0); rhs = node.GetSubtree(1); return(Interpret(lhs) + compSy + Interpret(rhs)); }
private static IEnumerable <bool> InterpretRec(ISymbolicExpressionTreeNode node, IEnumerable <int> bs) { Func <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, Func <bool, bool, bool>, IEnumerable <bool> > binaryEval = (left, right, f) => InterpretRec(left, bs).Zip(InterpretRec(right, bs), f); switch (node.Symbol.Name) { case "AND": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x & y)); case "OR": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x | y)); case "NAND": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => !(x & y))); case "NOR": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => !(x | y))); default: { byte bitPos; if (byte.TryParse(node.Symbol.Name, out bitPos)) { return(bs.Select(b => GetBits(b, bitPos))); } else { throw new NotSupportedException(string.Format("Found unexpected symbol {0}", node.Symbol.Name)); } } } }
///<summary> /// Finds the longest common subsequence in quadratic time and linear space /// Variant of: /// D. S. Hirschberg. A linear space algorithm for or computing maximal common subsequences. 1975. /// http://dl.acm.org/citation.cfm?id=360861 /// </summary> /// <returns>Number of pairs that were matched</returns> public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeSimilarityComparer comp) { if (!comp.Equals(a, b)) { return(0); } int m = a.SubtreeCount; int n = b.SubtreeCount; if (m == 0 || n == 0) { return(1); } var matrix = new int[m + 1, n + 1]; for (int i = 1; i <= m; ++i) { var ai = a.GetSubtree(i - 1); for (int j = 1; j <= n; ++j) { var bj = b.GetSubtree(j - 1); int match = Match(ai, bj, comp); matrix[i, j] = Math.Max(Math.Max(matrix[i, j - 1], matrix[i - 1, j]), matrix[i - 1, j - 1] + match); } } return(matrix[m, n] + 1); }
public string FormatOnlyExpression(ISymbolicExpressionTreeNode expressionNode) { var stringBuilder = new StringBuilder(); stringBuilder.AppendLine(" for " + CurrentIndexVariable + " = 1:1:rows"); stringBuilder.AppendLine(" estimated(" + CurrentIndexVariable + ") = " + FormatRecursively(expressionNode.GetSubtree(0)) + ";"); stringBuilder.AppendLine(" end;"); return stringBuilder.ToString(); }
public static void RenderNode(TextWriter writer, ISymbolicExpressionTreeNode node, string prefix) { string label = node.ToString(); writer.Write(label); if (node.SubtreeCount > 0) { var padding = prefix + new string(' ', label.Length); for (int i = 0; i != node.SubtreeCount; ++i) { char connector, extender = ' '; if (i == 0) { if (node.SubtreeCount > 1) { connector = RenderChars.JunctionDown; extender = RenderChars.VerticalLine; } else { connector = RenderChars.HorizontalLine; extender = ' '; } } else { writer.Write(padding); if (i == node.SubtreeCount - 1) { connector = RenderChars.CornerRight; extender = ' '; } else { connector = RenderChars.JunctionRight; extender = RenderChars.VerticalLine; } } writer.Write(string.Concat(connector, RenderChars.HorizontalLine)); var newPrefix = string.Concat(padding, extender, ' '); RenderNode(writer, node.GetSubtree(i), newPrefix); } } else writer.WriteLine(); }
private static string GetTextualRepresentationFromSubtreeOfDepth(ISymbolicExpressionTreeNode tree, int d) { if (d == 0) { return(""); } StringBuilder builder = new StringBuilder(); var varTreeNode = tree as VariableTreeNode; var constTreeNode = tree as ConstantTreeNode; if (varTreeNode != null) { builder.Append("(var " + varTreeNode.VariableName); } else if (constTreeNode != null) { builder.Append("(const"); } else { builder.Append("(" + tree.ToString()); } for (int i = 0; i < tree.SubtreeCount; i++) { builder.Append(" " + GetTextualRepresentationFromSubtreeOfDepth(tree.GetSubtree(i), d - 1)); } builder.Append(")"); return(builder.ToString()); }
private string FormatRecursively(ISymbolicExpressionTreeNode node) { StringBuilder strBuilder = new StringBuilder(); currentLag = 0; FormatBegin(node, strBuilder); if (node.SubtreeCount > 0) { strBuilder.Append(FormatRecursively(node.GetSubtree(0))); } int i = 1; foreach (var subTree in node.Subtrees.Skip(1)) { FormatSep(node, strBuilder, i); // format the whole subtree strBuilder.Append(FormatRecursively(subTree)); i++; } FormatEnd(node, strBuilder); return(strBuilder.ToString()); }
private static void GetVariableReferences(Dictionary <string, int> references, ISymbolicExpressionTreeNode node, int currentLag) { if (node.Symbol is LaggedVariable) { var laggedVarNode = node as LaggedVariableTreeNode; IncReferenceCount(references, laggedVarNode.VariableName, currentLag + laggedVarNode.Lag); } else if (node.Symbol is Variable) { var varNode = node as VariableTreeNode; IncReferenceCount(references, varNode.VariableName, currentLag); } else if (node.Symbol is VariableCondition) { var varCondNode = node as VariableConditionTreeNode; IncReferenceCount(references, varCondNode.VariableName, currentLag); GetVariableReferences(references, node.GetSubtree(0), currentLag); GetVariableReferences(references, node.GetSubtree(1), currentLag); } else if (node.Symbol is Integral) { var laggedNode = node as LaggedTreeNode; for (int l = laggedNode.Lag; l <= 0; l++) { GetVariableReferences(references, node.GetSubtree(0), currentLag + l); } } else if (node.Symbol is Derivative) { for (int l = -4; l <= 0; l++) { GetVariableReferences(references, node.GetSubtree(0), currentLag + l); } } else if (node.Symbol is TimeLag) { var laggedNode = node as LaggedTreeNode; GetVariableReferences(references, node.GetSubtree(0), currentLag + laggedNode.Lag); } else { foreach (var subtree in node.Subtrees) { GetVariableReferences(references, subtree, currentLag); } } }
public static string InterpretFunc1(string functionId, ISymbolicExpressionTreeNode node) { if (node.SubtreeCount != 1) { throw new ArgumentException(string.Format("Expected 1 child in {0}.", node.Symbol.Name), "node"); } return(string.Format("{0}({1})", functionId, Interpret(node.GetSubtree(0)))); }
/// <summary> /// Remove, Replace or Insert subtrees /// </summary> /// <param name="tree">The symbolic expression tree</param> /// <param name="parent">The insertion point (ie, the parent node who will receive a new child)</param> /// <param name="oldChild">The subtree to be replaced</param> /// <param name="newChild">The replacement subtree</param> /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param> private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) { if (oldChild == null && newChild == null) { throw new ArgumentNullException("Cannot deduce operation type from the arguments. Please provide non null operands."); } if (oldChild == null) { // insertion operation parent.AddSubtree(newChild); newChild.Parent = parent; } else if (newChild == null) { // removal operation parent.RemoveSubtree(parent.IndexOfSubtree(oldChild)); if (!removeSubtree) { for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) { var subtree = oldChild.GetSubtree(i); oldChild.RemoveSubtree(i); parent.AddSubtree(subtree); } } } else { // replacement operation var replacementIndex = parent.IndexOfSubtree(oldChild); parent.RemoveSubtree(replacementIndex); parent.InsertSubtree(replacementIndex, newChild); newChild.Parent = parent; if (changedNodes.ContainsKey(oldChild)) { changedNodes.Add(newChild, changedNodes[oldChild]); // so that on double click the original node is restored changedNodes.Remove(oldChild); } else { changedNodes.Add(newChild, oldChild); } } treeState = IsValid(tree) ? TreeState.Valid : TreeState.Invalid; switch (treeState) { case TreeState.Valid: this.grpViewHost.Enabled = true; UpdateModel(Content.Model.SymbolicExpressionTree); break; case TreeState.Invalid: this.grpViewHost.Enabled = false; break; } }
public static string InterpretChild(ISymbolicExpressionTreeNode node) { if (node.SubtreeCount != 1) { throw new ArgumentException(string.Format("Expected exactly one child in {0}.", node.Symbol), "node"); } return(Interpret(node.GetSubtree(0))); }
private void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { if (node.SubtreeCount == 1) { strBuilder.Append("-"); FormatRecursively(node.GetSubtree(0), strBuilder); return; } //Default case: more than 1 child FormatOperator(node, "-", strBuilder); }
private void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.Append("Subtract["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", Times[-1"); foreach (var t in node.Subtrees) { strBuilder.Append(","); FormatRecursively(t, strBuilder); } strBuilder.Append("]]"); }
private void SwitchNode(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode oldBranch, ISymbolicExpressionTreeNode newBranch) { for (int i = 0; i < root.SubtreeCount; i++) { if (root.GetSubtree(i) == oldBranch) { root.RemoveSubtree(i); root.InsertSubtree(i, newBranch); return; } } }
private void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { if (node.SubtreeCount == 1) { strBuilder.Append("Divide[1, "); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append("]"); } else { strBuilder.Append("Divide["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", Times["); FormatRecursively(node.GetSubtree(1), strBuilder); for (int i = 2; i < node.SubtreeCount; i++) { strBuilder.Append(","); FormatRecursively(node.GetSubtree(i), strBuilder); } strBuilder.Append("]]"); } }
private void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { if (node.SubtreeCount == 1) { strBuilder.Append("1.0 / "); FormatRecursively(node.GetSubtree(0), strBuilder); } else { FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append("/ ("); for (int i = 1; i < node.SubtreeCount; i++) { if (i > 1) { strBuilder.Append(" * "); } FormatRecursively(node.GetSubtree(i), strBuilder); } strBuilder.Append(")"); } }
private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) { ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex); if (foldedNodes.ContainsKey(subTree)) { parent.RemoveSubtree(subTreeIndex); var replacementNode = foldedNodes[subTree]; parent.InsertSubtree(subTreeIndex, replacementNode); // exchange key and value foldedNodes.Remove(subTree); foldedNodes.Add(replacementNode, subTree); } }
public static void IsValid(ISymbolicExpressionTreeNode treeNode) { var matchingSymbol = (from symb in treeNode.Grammar.Symbols where symb.Name == treeNode.Symbol.Name select symb).SingleOrDefault(); Assert.IsTrue(treeNode.Subtrees.Count() >= treeNode.Grammar.GetMinimumSubtreeCount(matchingSymbol)); Assert.IsTrue(treeNode.Subtrees.Count() <= treeNode.Grammar.GetMaximumSubtreeCount(matchingSymbol)); Assert.AreNotEqual(0.0, matchingSymbol.InitialFrequency); // check that no deactivated symbols occur in the tree for (int i = 0; i < treeNode.Subtrees.Count(); i++) { Assert.IsTrue(treeNode.Grammar.GetAllowedChildSymbols(treeNode.Symbol, i).Select(x => x.Name).Contains(treeNode.GetSubtree(i).Symbol.Name)); IsValid(treeNode.GetSubtree(i)); } }
public static void RenderNode(TextWriter writer, ISymbolicExpressionTreeNode node, string prefix) { string label = node.ToString(); writer.Write(label); if (node.SubtreeCount > 0) { var padding = prefix + new string(' ', label.Length); for (int i = 0; i != node.SubtreeCount; ++i) { char connector, extender = ' '; if (i == 0) { if (node.SubtreeCount > 1) { connector = RenderChars.JunctionDown; extender = RenderChars.VerticalLine; } else { connector = RenderChars.HorizontalLine; extender = ' '; } } else { writer.Write(padding); if (i == node.SubtreeCount - 1) { connector = RenderChars.CornerRight; extender = ' '; } else { connector = RenderChars.JunctionRight; extender = RenderChars.VerticalLine; } } writer.Write(string.Concat(connector, RenderChars.HorizontalLine)); var newPrefix = string.Concat(padding, extender, ' '); RenderNode(writer, node.GetSubtree(i), newPrefix); } } else { writer.WriteLine(); } }
private static void FindCrossoverPoint(ISymbolicExpressionTreeNode childNode, ISymbolicExpressionTreeNode parentNode, int curDepth, IList <Tuple <ISymbolicExpressionTreeNode, int> > possibleCrossoverPoints) { if (childNode.Symbol.Name != parentNode.Symbol.Name) { possibleCrossoverPoints.Add(new Tuple <ISymbolicExpressionTreeNode, int>(childNode, curDepth)); return; } if (childNode.Subtrees != null) { for (int i = 0; i < childNode.SubtreeCount; i++) { FindCrossoverPoint(childNode.GetSubtree(i), parentNode.GetSubtree(i), curDepth + 1, possibleCrossoverPoints); } } }
///<summary> /// Finds the longest common subsequence in quadratic time and linear space /// Variant of: /// D. S. Hirschberg. A linear space algorithm for or computing maximal common subsequences. 1975. /// http://dl.acm.org/citation.cfm?id=360861 /// </summary> /// <returns>Number of pairs that were matched</returns> public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeSimilarityComparer comp) { if (!comp.Equals(a, b)) return 0; int m = a.SubtreeCount; int n = b.SubtreeCount; if (m == 0 || n == 0) return 1; var matrix = new int[m + 1, n + 1]; for (int i = 1; i <= m; ++i) { var ai = a.GetSubtree(i - 1); for (int j = 1; j <= n; ++j) { var bj = b.GetSubtree(j - 1); int match = Match(ai, bj, comp); matrix[i, j] = Math.Max(Math.Max(matrix[i, j - 1], matrix[i - 1, j]), matrix[i - 1, j - 1] + match); } } return matrix[m, n] + 1; }
/// <summary> /// Remove, Replace or Insert subtrees /// </summary> /// <param name="tree">The symbolic expression tree</param> /// <param name="parent">The insertion point (ie, the parent node who will receive a new child)</param> /// <param name="oldChild">The subtree to be replaced</param> /// <param name="newChild">The replacement subtree</param> /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param> private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) { if (oldChild == null && newChild == null) throw new ArgumentNullException("Cannot deduce operation type from the arguments. Please provide non null operands."); if (oldChild == null) { // insertion operation parent.AddSubtree(newChild); newChild.Parent = parent; } else if (newChild == null) { // removal operation parent.RemoveSubtree(parent.IndexOfSubtree(oldChild)); if (!removeSubtree) { for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) { var subtree = oldChild.GetSubtree(i); oldChild.RemoveSubtree(i); parent.AddSubtree(subtree); } } } else { // replacement operation var replacementIndex = parent.IndexOfSubtree(oldChild); parent.RemoveSubtree(replacementIndex); parent.InsertSubtree(replacementIndex, newChild); newChild.Parent = parent; if (changedNodes.ContainsKey(oldChild)) { changedNodes.Add(newChild, changedNodes[oldChild]); // so that on double click the original node is restored changedNodes.Remove(oldChild); } else { changedNodes.Add(newChild, oldChild); } } treeState = IsValid(tree) ? TreeState.Valid : TreeState.Invalid; switch (treeState) { case TreeState.Valid: this.grpViewHost.Enabled = true; UpdateModel(Content.Model.SymbolicExpressionTree); break; case TreeState.Invalid: this.grpViewHost.Enabled = false; break; } }
private static IEnumerable <bool> InterpretRec(ISymbolicExpressionTreeNode node, IEnumerable <int> bs, byte addrBits) { Func <ISymbolicExpressionTreeNode, Func <bool, bool>, IEnumerable <bool> > unaryEval = (child, f) => InterpretRec(child, bs, addrBits).Select(f); Func <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, Func <bool, bool, bool>, IEnumerable <bool> > binaryEval = (left, right, f) => InterpretRec(left, bs, addrBits).Zip(InterpretRec(right, bs, addrBits), f); switch (node.Symbol.Name) { case "AND": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x & y)); case "OR": return(binaryEval(node.GetSubtree(0), node.GetSubtree(1), (x, y) => x | y)); case "NOT": return(unaryEval(node.GetSubtree(0), (x) => !x)); case "IF": return(EvalIf(node.GetSubtree(0), node.GetSubtree(1), node.GetSubtree(2), bs, addrBits)); default: { if (node.Symbol.Name[0] == 'a') { byte bitPos; if (byte.TryParse(node.Symbol.Name.Substring(1), out bitPos)) { return(bs.Select(b => GetBits(b, bitPos))); } } else if (node.Symbol.Name[0] == 'd') { byte bitPos; if (byte.TryParse(node.Symbol.Name.Substring(1), out bitPos)) { return(bs.Select(b => GetBits(b, (byte)(bitPos + addrBits)))); // offset of input line bits } } throw new NotSupportedException(string.Format("Found unexpected symbol {0}", node.Symbol.Name)); } } }
private string FormatRecursively(ISymbolicExpressionTreeNode node) { StringBuilder strBuilder = new StringBuilder(); currentLag = 0; FormatBegin(node, strBuilder); if (node.SubtreeCount > 0) { strBuilder.Append(FormatRecursively(node.GetSubtree(0))); } int i = 1; foreach (SymbolicExpressionTreeNode subTree in node.Subtrees.Skip(1)) { FormatSep(node, strBuilder, i); // format the whole subtree strBuilder.Append(FormatRecursively(subTree)); i++; } FormatEnd(node, strBuilder); return strBuilder.ToString(); }
private void FormatSquare(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { strBuilder.Append("Power["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", 2]"); }
private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) { if (node.Symbol is Constant) { var var = new AutoDiff.Variable(); variables.Add(var); term = var; return true; } if (node.Symbol is Variable) { var varNode = node as VariableTreeNode; var par = new AutoDiff.Variable(); parameters.Add(par); variableNames.Add(varNode.VariableName); var w = new AutoDiff.Variable(); variables.Add(w); term = AutoDiff.TermBuilder.Product(w, par); return true; } if (node.Symbol is Addition) { List<AutoDiff.Term> terms = new List<Term>(); foreach (var subTree in node.Subtrees) { AutoDiff.Term t; if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) { term = null; return false; } terms.Add(t); } term = AutoDiff.TermBuilder.Sum(terms); return true; } if (node.Symbol is Subtraction) { List<AutoDiff.Term> terms = new List<Term>(); for (int i = 0; i < node.SubtreeCount; i++) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) { term = null; return false; } if (i > 0) t = -t; terms.Add(t); } term = AutoDiff.TermBuilder.Sum(terms); return true; } if (node.Symbol is Multiplication) { AutoDiff.Term a, b; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) || !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) { term = null; return false; } else { List<AutoDiff.Term> factors = new List<Term>(); foreach (var subTree in node.Subtrees.Skip(2)) { AutoDiff.Term f; if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) { term = null; return false; } factors.Add(f); } term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray()); return true; } } if (node.Symbol is Division) { // only works for at least two subtrees AutoDiff.Term a, b; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) || !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) { term = null; return false; } else { List<AutoDiff.Term> factors = new List<Term>(); foreach (var subTree in node.Subtrees.Skip(2)) { AutoDiff.Term f; if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) { term = null; return false; } factors.Add(1.0 / f); } term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray()); return true; } } if (node.Symbol is Logarithm) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Log(t); return true; } } if (node.Symbol is Exponential) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Exp(t); return true; } } if (node.Symbol is Square) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Power(t, 2.0); return true; } } if (node.Symbol is SquareRoot) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Power(t, 0.5); return true; } } if (node.Symbol is Sine) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = sin(t); return true; } } if (node.Symbol is Cosine) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = cos(t); return true; } } if (node.Symbol is Tangent) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = tan(t); return true; } } if (node.Symbol is Erf) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = erf(t); return true; } } if (node.Symbol is Norm) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) { term = null; return false; } else { term = norm(t); return true; } } if (node.Symbol is StartSymbol) { var alpha = new AutoDiff.Variable(); var beta = new AutoDiff.Variable(); variables.Add(beta); variables.Add(alpha); AutoDiff.Term branchTerm; if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) { term = branchTerm * alpha + beta; return true; } else { term = null; return false; } } term = null; return false; }
public static string InterpretFunc1(string functionId, ISymbolicExpressionTreeNode node) { if (node.SubtreeCount != 1) throw new ArgumentException(string.Format("Expected 1 child in {0}.", node.Symbol.Name), "node"); return string.Format("{0}({1})", functionId, Interpret(node.GetSubtree(0))); }
public static string InterpretChild(ISymbolicExpressionTreeNode node) { if (node.SubtreeCount != 1) throw new ArgumentException(string.Format("Expected exactly one child in {0}.", node.Symbol), "node"); return Interpret(node.GetSubtree(0)); }
internal static string InterpretIf(ISymbolicExpressionTreeNode node) { ISymbolicExpressionTreeNode condition = null, truePart = null, falsePart = null; string[] parts = new string[3]; if (node.SubtreeCount < 2 || node.SubtreeCount > 3) throw new Exception("Unexpected number of children. Expected 2 or 3 children."); condition = node.GetSubtree(0); truePart = node.GetSubtree(1); if (node.SubtreeCount == 3) falsePart = node.GetSubtree(2); parts[0] = Interpret(condition); parts[1] = Interpret(truePart); if (falsePart != null) parts[2] = Interpret(falsePart); return string.Format("if ({0}) {{ {1} }} else {{ {2} }}", Interpret(condition), Interpret(truePart), falsePart == null ? string.Empty : Interpret(falsePart)); }
private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { if (node.Subtrees.Any()) { if (node.Symbol is Addition) { FormatFunction(node, "Plus", strBuilder); } else if (node.Symbol is Average) { FormatAverage(node, strBuilder); } else if (node.Symbol is Multiplication) { FormatFunction(node, "Times", strBuilder); } else if (node.Symbol is Subtraction) { FormatSubtraction(node, strBuilder); } else if (node.Symbol is Division) { FormatDivision(node, strBuilder); } else if (node.Symbol is Sine) { FormatFunction(node, "Sin", strBuilder); } else if (node.Symbol is Cosine) { FormatFunction(node, "Cos", strBuilder); } else if (node.Symbol is Tangent) { FormatFunction(node, "Tan", strBuilder); } else if (node.Symbol is Exponential) { FormatFunction(node, "Exp", strBuilder); } else if (node.Symbol is Logarithm) { FormatFunction(node, "Log", strBuilder); } else if (node.Symbol is IfThenElse) { FormatIf(node, strBuilder); } else if (node.Symbol is GreaterThan) { strBuilder.Append("If[Greater["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(","); FormatRecursively(node.GetSubtree(1), strBuilder); strBuilder.Append("], 1, -1]"); } else if (node.Symbol is LessThan) { strBuilder.Append("If[Less["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(","); FormatRecursively(node.GetSubtree(1), strBuilder); strBuilder.Append("], 1, -1]"); } else if (node.Symbol is And) { FormatAnd(node, strBuilder); } else if (node.Symbol is Not) { strBuilder.Append("If[Greater["); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(", 0], -1, 1]"); } else if (node.Symbol is Or) { FormatOr(node, strBuilder); } else if (node.Symbol is Xor) { FormatXor(node, strBuilder); } else if (node.Symbol is Square) { FormatSquare(node, strBuilder); } else if (node.Symbol is SquareRoot) { FormatFunction(node, "Sqrt", strBuilder); } else if (node.Symbol is Power) { FormatFunction(node, "Power", strBuilder); } else if (node.Symbol is Root) { FormatRoot(node, strBuilder); } else { throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " is not supported."); } } else { if (node is VariableTreeNode) { var varNode = node as VariableTreeNode; strBuilder.AppendFormat("Times[{0}, {1}]", varNode.VariableName, varNode.Weight.ToString("G17", CultureInfo.InvariantCulture)); } else if (node is ConstantTreeNode) { var constNode = node as ConstantTreeNode; strBuilder.Append(constNode.Value.ToString("G17", CultureInfo.InvariantCulture)); } else { throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " is not supported."); } } }
private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, bool updateVariableWeights, out AutoDiff.Term term) { if (node.Symbol is Constant) { var var = new AutoDiff.Variable(); variables.Add(var); term = var; return true; } if (node.Symbol is Variable) { var varNode = node as VariableTreeNode; var par = new AutoDiff.Variable(); parameters.Add(par); variableNames.Add(varNode.VariableName); if (updateVariableWeights) { var w = new AutoDiff.Variable(); variables.Add(w); term = AutoDiff.TermBuilder.Product(w, par); } else { term = par; } return true; } if (node.Symbol is Addition) { List<AutoDiff.Term> terms = new List<Term>(); foreach (var subTree in node.Subtrees) { AutoDiff.Term t; if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } terms.Add(t); } term = AutoDiff.TermBuilder.Sum(terms); return true; } if (node.Symbol is Subtraction) { List<AutoDiff.Term> terms = new List<Term>(); for (int i = 0; i < node.SubtreeCount; i++) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } if (i > 0) t = -t; terms.Add(t); } if (terms.Count == 1) term = -terms[0]; else term = AutoDiff.TermBuilder.Sum(terms); return true; } if (node.Symbol is Multiplication) { List<AutoDiff.Term> terms = new List<Term>(); foreach (var subTree in node.Subtrees) { AutoDiff.Term t; if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } terms.Add(t); } if (terms.Count == 1) term = terms[0]; else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b)); return true; } if (node.Symbol is Division) { List<AutoDiff.Term> terms = new List<Term>(); foreach (var subTree in node.Subtrees) { AutoDiff.Term t; if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } terms.Add(t); } if (terms.Count == 1) term = 1.0 / terms[0]; else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b)); return true; } if (node.Symbol is Logarithm) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Log(t); return true; } } if (node.Symbol is Exponential) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Exp(t); return true; } } if (node.Symbol is Square) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Power(t, 2.0); return true; } } if (node.Symbol is SquareRoot) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = AutoDiff.TermBuilder.Power(t, 0.5); return true; } } if (node.Symbol is Sine) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = sin(t); return true; } } if (node.Symbol is Cosine) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = cos(t); return true; } } if (node.Symbol is Tangent) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = tan(t); return true; } } if (node.Symbol is Erf) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = erf(t); return true; } } if (node.Symbol is Norm) { AutoDiff.Term t; if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) { term = null; return false; } else { term = norm(t); return true; } } if (node.Symbol is StartSymbol) { var alpha = new AutoDiff.Variable(); var beta = new AutoDiff.Variable(); variables.Add(beta); variables.Add(alpha); AutoDiff.Term branchTerm; if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out branchTerm)) { term = branchTerm * alpha + beta; return true; } else { term = null; return false; } } term = null; return false; }
// MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree private ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { if (IsConstant(a) && IsConstant(b)) { // fold constants return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value); } if (IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0)) { return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a))); } else if (IsVariable(a) && IsConstant(b)) { // merge constant values into variable weights var constB = ((ConstantTreeNode)b).Value; ((VariableTreeNode)a).Weight /= constB; return a; } else if (IsVariable(a) && IsVariable(b) && AreSameVariable(a, b)) { // cancel variables var aVar = a as VariableTreeNode; var bVar = b as VariableTreeNode; return MakeConstant(aVar.Weight / bVar.Weight); } else if (IsAddition(a) && IsConstant(b)) { return a.Subtrees .Select(x => GetSimplifiedTree(x)) .Select(x => MakeFraction(x, b)) .Aggregate((c, d) => MakeSum(c, d)); } else if (IsMultiplication(a) && IsConstant(b)) { return MakeProduct(a, Invert(b)); } else if (IsDivision(a) && IsConstant(b)) { // (a1 / a2) / c => (a1 / (a2 * c)) return MakeFraction(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b)); } else if (IsDivision(a) && IsDivision(b)) { // (a1 / a2) / (b1 / b2) => return MakeFraction(MakeProduct(a.GetSubtree(0), b.GetSubtree(1)), MakeProduct(a.GetSubtree(1), b.GetSubtree(0))); } else if (IsDivision(a)) { // (a1 / a2) / b => (a1 / (a2 * b)) return MakeFraction(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b)); } else if (IsDivision(b)) { // a / (b1 / b2) => (a * b2) / b1 return MakeFraction(MakeProduct(a, b.GetSubtree(1)), b.GetSubtree(0)); } else { var div = divSymbol.CreateTreeNode(); div.AddSubtree(a); div.AddSubtree(b); return div; } }
private ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { if (IsConstant(a) && IsConstant(b)) { // fold constants ((ConstantTreeNode)a).Value += ((ConstantTreeNode)b).Value; return a; } else if (IsConstant(a)) { // c + x => x + c // b is not constant => make sure constant is on the right return MakeSum(b, a); } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) { // x + 0 => x return a; } else if (IsAddition(a) && IsAddition(b)) { // merge additions var add = addSymbol.CreateTreeNode(); // add all sub trees except for the last for (int i = 0; i < a.Subtrees.Count() - 1; i++) add.AddSubtree(a.GetSubtree(i)); for (int i = 0; i < b.Subtrees.Count() - 1; i++) add.AddSubtree(b.GetSubtree(i)); if (IsConstant(a.Subtrees.Last()) && IsConstant(b.Subtrees.Last())) { add.AddSubtree(MakeSum(a.Subtrees.Last(), b.Subtrees.Last())); } else if (IsConstant(a.Subtrees.Last())) { add.AddSubtree(b.Subtrees.Last()); add.AddSubtree(a.Subtrees.Last()); } else { add.AddSubtree(a.Subtrees.Last()); add.AddSubtree(b.Subtrees.Last()); } MergeVariablesInSum(add); if (add.Subtrees.Count() == 1) { return add.GetSubtree(0); } else { return add; } } else if (IsAddition(b)) { return MakeSum(b, a); } else if (IsAddition(a) && IsConstant(b)) { // a is an addition and b is a constant => append b to a and make sure the constants are merged var add = addSymbol.CreateTreeNode(); // add all sub trees except for the last for (int i = 0; i < a.Subtrees.Count() - 1; i++) add.AddSubtree(a.GetSubtree(i)); if (IsConstant(a.Subtrees.Last())) add.AddSubtree(MakeSum(a.Subtrees.Last(), b)); else { add.AddSubtree(a.Subtrees.Last()); add.AddSubtree(b); } return add; } else if (IsAddition(a)) { // a is already an addition => append b var add = addSymbol.CreateTreeNode(); add.AddSubtree(b); foreach (var subtree in a.Subtrees) { add.AddSubtree(subtree); } MergeVariablesInSum(add); if (add.Subtrees.Count() == 1) { return add.GetSubtree(0); } else { return add; } } else { var add = addSymbol.CreateTreeNode(); add.AddSubtree(a); add.AddSubtree(b); MergeVariablesInSum(add); if (add.Subtrees.Count() == 1) { return add.GetSubtree(0); } else { return add; } } }
private ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { if (IsConstant(a) && IsConstant(b)) { // fold constants ((ConstantTreeNode)a).Value *= ((ConstantTreeNode)b).Value; return a; } else if (IsConstant(a)) { // a * $ => $ * a return MakeProduct(b, a); } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(1.0)) { // $ * 1.0 => $ return a; } else if (IsConstant(b) && IsVariable(a)) { // multiply constants into variables weights ((VariableTreeNode)a).Weight *= ((ConstantTreeNode)b).Value; return a; } else if (IsConstant(b) && IsAddition(a)) { // multiply constants into additions return a.Subtrees.Select(x => MakeProduct(x, b)).Aggregate((c, d) => MakeSum(c, d)); } else if (IsDivision(a) && IsDivision(b)) { // (a1 / a2) * (b1 / b2) => (a1 * b1) / (a2 * b2) return MakeFraction(MakeProduct(a.GetSubtree(0), b.GetSubtree(0)), MakeProduct(a.GetSubtree(1), b.GetSubtree(1))); } else if (IsDivision(a)) { // (a1 / a2) * b => (a1 * b) / a2 return MakeFraction(MakeProduct(a.GetSubtree(0), b), a.GetSubtree(1)); } else if (IsDivision(b)) { // a * (b1 / b2) => (b1 * a) / b2 return MakeFraction(MakeProduct(b.GetSubtree(0), a), b.GetSubtree(1)); } else if (IsMultiplication(a) && IsMultiplication(b)) { // merge multiplications (make sure constants are merged) var mul = mulSymbol.CreateTreeNode(); for (int i = 0; i < a.Subtrees.Count(); i++) mul.AddSubtree(a.GetSubtree(i)); for (int i = 0; i < b.Subtrees.Count(); i++) mul.AddSubtree(b.GetSubtree(i)); MergeVariablesAndConstantsInProduct(mul); return mul; } else if (IsMultiplication(b)) { return MakeProduct(b, a); } else if (IsMultiplication(a)) { // a is already an multiplication => append b a.AddSubtree(b); MergeVariablesAndConstantsInProduct(a); return a; } else { var mul = mulSymbol.CreateTreeNode(); mul.AddSubtree(a); mul.AddSubtree(b); MergeVariablesAndConstantsInProduct(mul); return mul; } }
private static Tuple<int, int> EvaluateLawnMowerProgram(ISymbolicExpressionTreeNode node, MowerState mowerState, bool[,] lawn, IEnumerable<ISymbolicExpressionTreeNode> adfs) { if (mowerState.Energy <= 0) return Tuple.Create(0, 0); if (node.Symbol is ProgramRootSymbol) { return EvaluateLawnMowerProgram(node.GetSubtree(0), mowerState, lawn, adfs); } else if (node.Symbol is StartSymbol) { return EvaluateLawnMowerProgram(node.GetSubtree(0), mowerState, lawn, adfs); } else if (node.Symbol.Name == "Left") { switch (mowerState.Heading) { case Heading.East: mowerState.Heading = Heading.North; break; case Heading.North: mowerState.Heading = Heading.West; break; case Heading.West: mowerState.Heading = Heading.South; break; case Heading.South: mowerState.Heading = Heading.East; break; } return new Tuple<int, int>(0, 0); } else if (node.Symbol.Name == "Forward") { int dRow = 0; int dCol = 0; switch (mowerState.Heading) { case Heading.East: dCol++; break; case Heading.North: dRow--; break; case Heading.West: dCol--; break; case Heading.South: dRow++; break; } uint newRow = (uint)((mowerState.Position.Item1 + lawn.GetLength(0) + dRow) % lawn.GetLength(0)); uint newColumn = (uint)((mowerState.Position.Item2 + lawn.GetLength(1) + dCol) % lawn.GetLength(1)); mowerState.Position = Tuple.Create(newRow, newColumn); mowerState.Energy = mowerState.Energy - 1; lawn[newRow, newColumn] = true; return Tuple.Create(0, 0); } else if (node.Symbol.Name == "Sum") { var p = EvaluateLawnMowerProgram(node.GetSubtree(0), mowerState, lawn, adfs); var q = EvaluateLawnMowerProgram(node.GetSubtree(1), mowerState, lawn, adfs); return Tuple.Create(p.Item1 + q.Item1, p.Item2 + q.Item2); } else if (node.Symbol.Name == "Prog") { EvaluateLawnMowerProgram(node.GetSubtree(0), mowerState, lawn, adfs); return EvaluateLawnMowerProgram(node.GetSubtree(1), mowerState, lawn, adfs); } else if (node.Symbol.Name == "Frog") { var p = EvaluateLawnMowerProgram(node.GetSubtree(0), mowerState, lawn, adfs); int x = p.Item1; int y = p.Item2; while (x < 0) x += lawn.GetLength(0); while (y < 0) y += lawn.GetLength(1); var newRow = (uint)((mowerState.Position.Item1 + x) % lawn.GetLength(0)); var newCol = (uint)((mowerState.Position.Item2 + y) % lawn.GetLength(1)); mowerState.Position = Tuple.Create(newRow, newCol); mowerState.Energy = mowerState.Energy - 1; lawn[newRow, newCol] = true; return Tuple.Create(0, 0); } else if (node.Symbol is InvokeFunction) { var invokeNode = node as InvokeFunctionTreeNode; // find the function definition for the invoke call var functionDefinition = (from adf in adfs.Cast<DefunTreeNode>() where adf.FunctionName == invokeNode.Symbol.FunctionName select adf).Single(); // clone the function definition because we are replacing the argument nodes functionDefinition = (DefunTreeNode)functionDefinition.Clone(); // find the argument tree nodes and their parents in the original function definition // toList is necessary to prevent that newly inserted branches are iterated var argumentCutPoints = (from parent in functionDefinition.IterateNodesPrefix() from subtree in parent.Subtrees where subtree is ArgumentTreeNode select new { Parent = parent, Argument = subtree.Symbol as Argument, ChildIndex = parent.IndexOfSubtree(subtree) }) .ToList(); // replace all argument tree ndoes with the matching argument of the invoke node foreach (var cutPoint in argumentCutPoints) { cutPoint.Parent.RemoveSubtree(cutPoint.ChildIndex); cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, (SymbolicExpressionTreeNode)invokeNode.GetSubtree(cutPoint.Argument.ArgumentIndex).Clone()); } return EvaluateLawnMowerProgram(functionDefinition.GetSubtree(0), mowerState, lawn, adfs); } else { // try to parse as ephemeral random const with format: "x,y" (x, y in [0..32[) int x, y; var tokens = node.Symbol.Name.Split(','); if (tokens.Length == 2 && int.TryParse(tokens[0], out x) && int.TryParse(tokens[1], out y)) { return Tuple.Create(x, y); } else { throw new ArgumentException("Invalid symbol in the lawn mower program."); } } }
private static List<CutPoint> SelectRandomArgumentBranches(ISymbolicExpressionTreeNode selectedRoot, IRandom random, double cutProbability, int maxArguments) { // breadth first determination of argument cut-off points // we must make sure that we cut off all original argument nodes and that the number of new argument is smaller than the limit List<CutPoint> argumentBranches = new List<CutPoint>(); if (selectedRoot is ArgumentTreeNode) { argumentBranches.Add(new CutPoint(selectedRoot.Parent, selectedRoot)); return argumentBranches; } else { // get the number of argument nodes (which must be cut-off) in the sub-trees var numberOfArgumentsInSubtrees = (from subtree in selectedRoot.Subtrees let nArgumentsInTree = subtree.IterateNodesPrefix().OfType<ArgumentTreeNode>().Count() select nArgumentsInTree).ToList(); // determine the minimal number of new argument nodes for each sub-tree //if we exceed the maxArguments return the same cutpoint as the start cutpoint to create a ADF that returns only its argument var minNewArgumentsForSubtrees = numberOfArgumentsInSubtrees.Select(x => x > 0 ? 1 : 0).ToList(); if (minNewArgumentsForSubtrees.Sum() > maxArguments) { argumentBranches.Add(new CutPoint(selectedRoot.Parent, selectedRoot)); return argumentBranches; } // cut-off in the sub-trees in random order var randomIndexes = (from index in Enumerable.Range(0, selectedRoot.Subtrees.Count()) select new { Index = index, OrderValue = random.NextDouble() }) .OrderBy(x => x.OrderValue) .Select(x => x.Index); foreach (var subtreeIndex in randomIndexes) { var subtree = selectedRoot.GetSubtree(subtreeIndex); minNewArgumentsForSubtrees[subtreeIndex] = 0; // => cut-off at 0..n points somewhere in the current sub-tree // determine the maximum number of new arguments that should be created in the branch // as the maximum for the whole branch minus already added arguments minus minimal number of arguments still left int maxArgumentsFromBranch = maxArguments - argumentBranches.Count - minNewArgumentsForSubtrees.Sum(); // when no argument is allowed from the current branch then we have to include the whole branch into the function // otherwise: choose randomly wether to cut off immediately or wether to extend the function body into the branch if (maxArgumentsFromBranch == 0) { // don't cut at all => the whole sub-tree branch is included in the function body // (we already checked ahead of time that there are no arguments left over in the subtree) } else if (random.NextDouble() >= cutProbability) { argumentBranches.AddRange(SelectRandomArgumentBranches(subtree, random, cutProbability, maxArgumentsFromBranch)); } else { // cut-off at current sub-tree argumentBranches.Add(new CutPoint(subtree.Parent, subtree)); } } return argumentBranches; } }
internal static string InterpretStat(ISymbolicExpressionTreeNode node) { // must only have one sub-tree Contract.Assert(node.SubtreeCount == 1); return Interpret(node.GetSubtree(0)) + " ;" + Environment.NewLine; }
private string FormatRecursively(ISymbolicExpressionTreeNode node) { ISymbol symbol = node.Symbol; StringBuilder stringBuilder = new StringBuilder(); if (symbol is ProgramRootSymbol) { stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0))); } else if (symbol is StartSymbol) return FormatRecursively(node.GetSubtree(0)); else if (symbol is Addition) { stringBuilder.Append("("); for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("+"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } stringBuilder.Append(")"); } else if (symbol is Average) { stringBuilder.Append("(1/"); stringBuilder.Append(node.SubtreeCount); stringBuilder.Append(")*("); for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("+"); stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); stringBuilder.Append(")"); } stringBuilder.Append(")"); } else if (symbol is Constant) { ConstantTreeNode constantTreeNode = node as ConstantTreeNode; stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture)); } else if (symbol is Cosine) { stringBuilder.Append("COS("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Division) { if (node.SubtreeCount == 1) { stringBuilder.Append("1/"); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); } else { stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append("/("); for (int i = 1; i < node.SubtreeCount; i++) { if (i > 1) stringBuilder.Append("*"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } stringBuilder.Append(")"); } } else if (symbol is Exponential) { stringBuilder.Append("EXP("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Square) { stringBuilder.Append("POWER("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(",2)"); } else if (symbol is SquareRoot) { stringBuilder.Append("SQRT("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Logarithm) { stringBuilder.Append("LN("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Multiplication) { for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("*"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } } else if (symbol is Sine) { stringBuilder.Append("SIN("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Subtraction) { stringBuilder.Append("("); if (node.SubtreeCount == 1) { stringBuilder.Append("-"); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); } else { stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); for (int i = 1; i < node.SubtreeCount; i++) { stringBuilder.Append("-"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } } stringBuilder.Append(")"); } else if (symbol is Tangent) { stringBuilder.Append("TAN("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Variable) { VariableTreeNode variableTreeNode = node as VariableTreeNode; stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture)); stringBuilder.Append("*"); stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName));// + LagToString(currentLag)); } else if (symbol is Power) { stringBuilder.Append("POWER("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(",ROUND("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append(",0))"); } else if (symbol is Root) { stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")^(1 / ROUND("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append(",0))"); } else if (symbol is IfThenElse) { stringBuilder.Append("IF("); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + " ) > 0"); stringBuilder.Append(","); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append(","); stringBuilder.Append(FormatRecursively(node.GetSubtree(2))); stringBuilder.Append(")"); } else if (symbol is VariableCondition) { VariableConditionTreeNode variableConditionTreeNode = node as VariableConditionTreeNode; double threshold = variableConditionTreeNode.Threshold; double slope = variableConditionTreeNode.Slope; string p = "(1 / (1 + EXP(-" + slope.ToString(CultureInfo.InvariantCulture) + " * (" + GetColumnToVariableName(variableConditionTreeNode.VariableName) + "-" + threshold.ToString(CultureInfo.InvariantCulture) + "))))"; stringBuilder.Append("(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append("*"); stringBuilder.Append(p); stringBuilder.Append(") + ("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append("*("); stringBuilder.Append("1 - " + p + ")"); stringBuilder.Append("))"); } else if (symbol is Xor) { stringBuilder.Append("IF("); stringBuilder.Append("XOR("); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,"); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0"); stringBuilder.Append("), 1.0, -1.0)"); } else if (symbol is Or) { stringBuilder.Append("IF("); stringBuilder.Append("OR("); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,"); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0"); stringBuilder.Append("), 1.0, -1.0)"); } else if (symbol is And) { stringBuilder.Append("IF("); stringBuilder.Append("AND("); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,"); stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0"); stringBuilder.Append("), 1.0, -1.0)"); } else if (symbol is Not) { stringBuilder.Append("IF("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(" > 0, -1.0, 1.0)"); } else if (symbol is GreaterThan) { stringBuilder.Append("IF(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(") > ("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append("), 1.0, -1.0)"); } else if (symbol is LessThan) { stringBuilder.Append("IF(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(") < ("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append("), 1.0, -1.0)"); } else { throw new NotImplementedException("Excel export of " + node.Symbol + " is not implemented."); } return stringBuilder.ToString(); }
internal static string InterpretWhile(ISymbolicExpressionTreeNode node) { var cond = Interpret(node.GetSubtree(0)); var body = Interpret(node.GetSubtree(1)); return string.Format("while ({0}) {{ {2} {1} {2} }} {2}", cond, body, Environment.NewLine); }
public static string InterpretComparison(string compSy, ISymbolicExpressionTreeNode node) { ISymbolicExpressionTreeNode lhs = null, rhs = null; if (node.SubtreeCount != 2) throw new ArgumentException(string.Format("Expected exactly two children in {0}.", node.Symbol), "node"); lhs = node.GetSubtree(0); rhs = node.GetSubtree(1); return Interpret(lhs) + compSy + Interpret(rhs); }
private string FormatRecursively(ISymbolicExpressionTreeNode node) { ISymbol symbol = node.Symbol; StringBuilder stringBuilder = new StringBuilder(); if (symbol is ProgramRootSymbol) { stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0))); } else if (symbol is StartSymbol) return FormatRecursively(node.GetSubtree(0)); else if (symbol is Addition) { stringBuilder.Append("("); for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("+"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } stringBuilder.Append(")"); } else if (symbol is And) { stringBuilder.Append("(("); for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("&"); stringBuilder.Append("(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); stringBuilder.Append(")>0)"); } stringBuilder.Append(")-0.5)*2"); // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp. } else if (symbol is Average) { stringBuilder.Append("(1/"); stringBuilder.Append(node.SubtreeCount); stringBuilder.Append(")*("); for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("+"); stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); stringBuilder.Append(")"); } stringBuilder.Append(")"); } else if (symbol is Constant) { ConstantTreeNode constantTreeNode = node as ConstantTreeNode; stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture)); } else if (symbol is Cosine) { stringBuilder.Append("cos("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Division) { if (node.SubtreeCount == 1) { stringBuilder.Append("1/"); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); } else { stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append("/("); for (int i = 1; i < node.SubtreeCount; i++) { if (i > 1) stringBuilder.Append("*"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } stringBuilder.Append(")"); } } else if (symbol is Exponential) { stringBuilder.Append("exp("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Square) { stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(").^2"); } else if (symbol is SquareRoot) { stringBuilder.Append("sqrt("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is GreaterThan) { stringBuilder.Append("(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(">"); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append(")-0.5)*2"); // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp. } else if (symbol is IfThenElse) { stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(">0)*"); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append("+"); stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append("<=0)*"); stringBuilder.Append(FormatRecursively(node.GetSubtree(2))); } else if (symbol is LaggedVariable) { // this if must be checked before if(symbol is LaggedVariable) LaggedVariableTreeNode laggedVariableTreeNode = node as LaggedVariableTreeNode; stringBuilder.Append(laggedVariableTreeNode.Weight.ToString(CultureInfo.InvariantCulture)); stringBuilder.Append("*"); stringBuilder.Append(laggedVariableTreeNode.VariableName + LagToString(currentLag + laggedVariableTreeNode.Lag)); } else if (symbol is LessThan) { stringBuilder.Append("(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append("<"); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append(")-0.5)*2"); // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp. } else if (symbol is Logarithm) { stringBuilder.Append("log_("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Multiplication) { for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("*"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } } else if (symbol is Not) { stringBuilder.Append("~("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(" > 0 )"); } else if (symbol is Or) { stringBuilder.Append("(("); for (int i = 0; i < node.SubtreeCount; i++) { if (i > 0) stringBuilder.Append("|"); stringBuilder.Append("(("); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); stringBuilder.Append(")>0)"); } stringBuilder.Append(")-0.5)*2"); // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp. } else if (symbol is Sine) { stringBuilder.Append("sin("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is Subtraction) { stringBuilder.Append("("); if (node.SubtreeCount == 1) { stringBuilder.Append("-"); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); } else { stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); for (int i = 1; i < node.SubtreeCount; i++) { stringBuilder.Append("-"); stringBuilder.Append(FormatRecursively(node.GetSubtree(i))); } } stringBuilder.Append(")"); } else if (symbol is Tangent) { stringBuilder.Append("tan("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is AiryA) { stringBuilder.Append("airy("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is AiryB) { stringBuilder.Append("airy(2, "); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is Bessel) { stringBuilder.Append("besseli(0.0,"); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is CosineIntegral) { stringBuilder.Append("cosint("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is Dawson) { stringBuilder.Append("dawson("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is Erf) { stringBuilder.Append("erf("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is ExponentialIntegralEi) { stringBuilder.Append("expint("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is FresnelCosineIntegral) { stringBuilder.Append("FresnelC("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is FresnelSineIntegral) { stringBuilder.Append("FresnelS("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is Gamma) { stringBuilder.Append("gamma("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is HyperbolicCosineIntegral) { stringBuilder.Append("Chi("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is HyperbolicSineIntegral) { stringBuilder.Append("Shi("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is Norm) { stringBuilder.Append("normpdf("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is Psi) { stringBuilder.Append("psi("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (node.Symbol is SineIntegral) { stringBuilder.Append("sinint("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); } else if (symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable) { VariableTreeNode variableTreeNode = node as VariableTreeNode; stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture)); stringBuilder.Append("*"); stringBuilder.Append(variableTreeNode.VariableName + LagToString(currentLag)); } else if (symbol is Power) { stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")^round("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append(")"); } else if (symbol is Root) { stringBuilder.Append("("); stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")^(1 / round("); stringBuilder.Append(FormatRecursively(node.GetSubtree(1))); stringBuilder.Append("))"); } else if (symbol is Derivative) { stringBuilder.Append("fivePoint("); // f0 stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(", "); // f1 currentLag--; stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(", "); // f3 currentLag -= 2; stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(", "); currentLag--; // f4 stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); stringBuilder.Append(")"); currentLag += 4; } else if (symbol is Integral) { var laggedNode = node as LaggedTreeNode; string prevCounterVariable = CurrentIndexVariable; string counterVariable = AllocateIndexVariable(); stringBuilder.AppendLine(" sum (map(@(" + counterVariable + ") " + FormatRecursively(node.GetSubtree(0)) + ", (" + prevCounterVariable + "+" + laggedNode.Lag + "):" + prevCounterVariable + "))"); ReleaseIndexVariable(); } else if (symbol is TimeLag) { var laggedNode = node as LaggedTreeNode; currentLag += laggedNode.Lag; stringBuilder.Append(FormatRecursively(node.GetSubtree(0))); currentLag -= laggedNode.Lag; } else { stringBuilder.Append("ERROR"); } return stringBuilder.ToString(); }
/// <summary> /// 1. find a mutation point /// 2. generate new random tree /// 3. calculate semantic of old and new subtree (or of the closest parent) /// 4. do mutation if semantically different /// 5. retry until a certain number of tries is reached /// /// if no mutation has happened, do random mutation /// </summary> public static void ReplaceSemanticallyDifferentBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, ICFGPythonProblemData problemData, ItemArray <PythonStatementSemantic> semantics, PythonProcess pythonProcess, double timeout, int maxTreeLength, int maxTreeDepth, int maximumSemanticTries) { if (semantics == null || semantics.Length == 0) { ReplaceBranchManipulation.ReplaceRandomBranch(random, symbolicExpressionTree, maxTreeLength, maxTreeDepth); return; } var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(symbolicExpressionTree.Root.Grammar); var variables = problemData.Variables.GetVariableNames().ToList(); string variableSettings = problemData.VariableSettings.Count == 0 ? String.Empty : String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value)); var allowedSymbols = new List <ISymbol>(); // repeat until a fitting parent and child are found (MAX_TRIES times) int tries = 0; int semanticTries = 0; do { #region find mutation point #pragma warning disable 612, 618 ISymbolicExpressionTreeNode parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random); #pragma warning restore 612, 618 int childIndex = random.Next(parent.SubtreeCount); var child = parent.GetSubtree(childIndex); int maxLength = maxTreeLength - symbolicExpressionTree.Length + child.GetLength(); int maxDepth = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child); allowedSymbols.Clear(); foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)) { // check basic properties that the new symbol must have if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) && symbol.InitialFrequency > 0 && parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth && parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength) { allowedSymbols.Add(symbol); } } #endregion #region check for semantic difference with a new random tree if (allowedSymbols.Count > 0) { if (semanticTries <= maximumSemanticTries) { // do semantic mutation #region calculate original json output ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames); var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement); if (String.IsNullOrEmpty(variableSettings)) { variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantics.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes()); } var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); #endregion var seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth); #region calculate new json output JObject jsonReplaced; if (child == statement) { // child is executable, so is the new child jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout); } else { jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout); } if (JToken.EqualityComparer.Equals(jsonOriginal, jsonReplaced)) { // semantically equivalent. undo mutation parent.RemoveSubtree(childIndex); parent.InsertSubtree(childIndex, child); allowedSymbols.Clear(); } else { Console.WriteLine("never happens?"); } if (problemData.VariableSettings.Count == 0) { // reset variableSettings variableSettings = String.Empty; } semanticTries++; #endregion } else { // do random mutation GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth); } } #endregion tries++; } while (tries < MAX_TRIES && allowedSymbols.Count == 0 && semanticTries <= maximumSemanticTries); }
private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { if (node.SubtreeCount > 1) { var token = GetToken(node.Symbol); if (token == "+" || token == "-" || token == "OR" || token == "XOR") { strBuilder.Append("("); FormatRecursively(node.Subtrees.First(), strBuilder); foreach (var subtree in node.Subtrees.Skip(1)) { strBuilder.Append(" ").Append(token).Append(" "); FormatRecursively(subtree, strBuilder); } strBuilder.Append(")"); } else if (token == "*" || token == "/" || token == "AND") { strBuilder.Append("("); FormatRecursively(node.Subtrees.First(), strBuilder); foreach (var subtree in node.Subtrees.Skip(1)) { strBuilder.Append(" ").Append(token).Append(" "); FormatRecursively(subtree, strBuilder); } strBuilder.Append(")"); } } else if (node.SubtreeCount == 1) { var token = GetToken(node.Symbol); if (token == "-" || token == "NOT") { strBuilder.Append("(").Append(token).Append("("); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append("))"); } else if (token == "/") { strBuilder.Append("1/"); FormatRecursively(node.GetSubtree(0), strBuilder); } else if (token == "+" || token == "*") { FormatRecursively(node.GetSubtree(0), strBuilder); } else { // function strBuilder.Append(token).Append("("); FormatRecursively(node.GetSubtree(0), strBuilder); strBuilder.Append(")"); } } else { // no subtrees if (node.Symbol is Variable) { var varNode = node as VariableTreeNode; if (!varNode.Weight.IsAlmost(1.0)) { strBuilder.Append("("); strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight); strBuilder.Append("*"); } if (varNode.VariableName.Contains("'")) { strBuilder.AppendFormat("\"{0}\"", varNode.VariableName); } else { strBuilder.AppendFormat("'{0}'", varNode.VariableName); } if (!varNode.Weight.IsAlmost(1.0)) { strBuilder.Append(")"); } } else if (node.Symbol is Constant) { var constNode = node as ConstantTreeNode; if (constNode.Value >= 0.0) strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value); else strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1) } } }