public override void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation, double qualityForImpactsCalculation = Double.NaN) { var classificationModel = (ISymbolicClassificationModel)model; var classificationProblemData = (IClassificationProblemData)problemData; if (double.IsNaN(qualityForImpactsCalculation)) qualityForImpactsCalculation = CalculateQualityForImpacts(classificationModel, classificationProblemData, rows); replacementValue = CalculateReplacementValue(classificationModel, node, classificationProblemData, rows); var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue }; var cloner = new Cloner(); var tempModel = cloner.Clone(classificationModel); var tempModelNode = (ISymbolicExpressionTreeNode)cloner.GetClone(node); var tempModelParentNode = tempModelNode.Parent; int i = tempModelParentNode.IndexOfSubtree(tempModelNode); tempModelParentNode.RemoveSubtree(i); tempModelParentNode.InsertSubtree(i, constantNode); OnlineCalculatorError errorState; var dataset = classificationProblemData.Dataset; var targetClassValues = dataset.GetDoubleValues(classificationProblemData.TargetVariable, rows); var estimatedClassValues = tempModel.GetEstimatedClassValues(dataset, rows); newQualityForImpactsCalculation = OnlineAccuracyCalculator.Calculate(targetClassValues, estimatedClassValues, out errorState); if (errorState != OnlineCalculatorError.None) newQualityForImpactsCalculation = 0.0; impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation; }
private string FormatRecursively(ISymbolicExpressionTreeNode node, int indentLength, ref int nodeId) { // save id of current node int currentNodeId = nodeId; // increment id for next node nodeId++; StringBuilder strBuilder = new StringBuilder(); if (Indent) strBuilder.Append(' ', indentLength); // get label for node and map if necessary string nodeLabel = node.ToString(); if (symbolNameMap.ContainsKey(nodeLabel)) { nodeLabel = symbolNameMap[nodeLabel]; } strBuilder.Append("node" + currentNodeId + "[label=\"" + nodeLabel + "\""); // leaf nodes should have box shape if (node.SubtreeCount == 0) { strBuilder.AppendLine(", shape=\"box\"];"); } else { strBuilder.AppendLine("];"); } // internal nodes or leaf nodes? foreach (ISymbolicExpressionTreeNode subTree in node.Subtrees) { // add an edge if (Indent) strBuilder.Append(' ', indentLength); strBuilder.AppendLine("node" + currentNodeId + " -- node" + nodeId + ";"); // format the whole subtree strBuilder.Append(FormatRecursively(subTree, indentLength + 2, ref nodeId)); } return strBuilder.ToString(); }
public static void Create(IRandom random, ISymbolicExpressionTreeNode seedNode, int maxDepth) { // make sure it is possible to create a trees smaller than maxDepth if (seedNode.Grammar.GetMinimumExpressionDepth(seedNode.Symbol) > maxDepth) throw new ArgumentException("Cannot create trees of depth " + maxDepth + " or smaller because of grammar constraints.", "maxDepth"); var arity = SampleArity(random, seedNode); // throw an exception if the seedNode happens to be a terminal, since in this case we cannot grow a tree if (arity <= 0) throw new ArgumentException("Cannot grow tree. Seed node shouldn't have arity zero."); var allowedSymbols = seedNode.Grammar.AllowedSymbols.Where(s => s.InitialFrequency > 0.0).ToList(); for (var i = 0; i < arity; i++) { var possibleSymbols = allowedSymbols.Where(s => seedNode.Grammar.IsAllowedChildSymbol(seedNode.Symbol, s, i)).ToList(); var weights = possibleSymbols.Select(s => s.InitialFrequency).ToList(); #pragma warning disable 612, 618 var selectedSymbol = possibleSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 var tree = selectedSymbol.CreateTreeNode(); if (tree.HasLocalParameters) tree.ResetLocalParameters(random); seedNode.AddSubtree(tree); } // Only iterate over the non-terminal nodes (those which have arity > 0) // Start from depth 2 since the first two levels are formed by the rootNode and the seedNode foreach (var subTree in seedNode.Subtrees) if (subTree.Grammar.GetMaximumSubtreeCount(subTree.Symbol) > 0) RecursiveCreate(random, subTree, 2, maxDepth); }
/// <summary> /// Genotype-to-Phenotype mapper (iterative breath-first approach, by using a queue -> FIFO). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapBreathFirstIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { Queue<Tuple<ISymbolicExpressionTreeNode, int>> queue = new Queue<Tuple<ISymbolicExpressionTreeNode, int>>(); // tuples of <node, arity> int genotypeIndex = 0; queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(startNode, 1)); while (queue.Count > 0) { Tuple<ISymbolicExpressionTreeNode, int> current = queue.Dequeue(); // foreach subtree of the current node, create a new node and enqueue it, if it is no terminal node for (int i = 0; i < current.Item2; ++i) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random)); } else { var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.Item1.AddSubtree(newNode); genotypeIndex++; if (arity > 0) { // new node has subtrees so enqueue the node queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(newNode, arity)); } } } } }
private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { // TODO: adapt to interpreter semantics. The HL interpreter also allows Boolean operations on reals if (node.Subtrees.Any()) { if (node.Symbol is Addition) { FormatOperator(node, "+", strBuilder); } else if (node.Symbol is And) { FormatOperator(node, "&&", strBuilder); } else if (node.Symbol is Average) { FormatFunction(node, "Average", strBuilder); } else if (node.Symbol is Cosine) { FormatFunction(node, "Math.Cos", strBuilder); } else if (node.Symbol is Division) { FormatDivision(node, strBuilder); } else if (node.Symbol is Exponential) { FormatFunction(node, "Math.Exp", strBuilder); } else if (node.Symbol is GreaterThan) { FormatOperator(node, ">", strBuilder); } else if (node.Symbol is IfThenElse) { FormatFunction(node, "EvaluateIf", strBuilder); } else if (node.Symbol is LessThan) { FormatOperator(node, "<", strBuilder); } else if (node.Symbol is Logarithm) { FormatFunction(node, "Math.Log", strBuilder); } else if (node.Symbol is Multiplication) { FormatOperator(node, "*", strBuilder); } else if (node.Symbol is Not) { FormatOperator(node, "!", strBuilder); } else if (node.Symbol is Or) { FormatOperator(node, "||", strBuilder); } else if (node.Symbol is Xor) { FormatOperator(node, "^", strBuilder); } else if (node.Symbol is Sine) { FormatFunction(node, "Math.Sin", strBuilder); } else if (node.Symbol is Subtraction) { FormatSubtraction(node, strBuilder); } else if (node.Symbol is Tangent) { FormatFunction(node, "Math.Tan", strBuilder); } else if (node.Symbol is Square) { FormatSquare(node, strBuilder); } else if (node.Symbol is SquareRoot) { FormatFunction(node, "Math.Sqrt", strBuilder); } else if (node.Symbol is Power) { FormatFunction(node, "Math.Pow", strBuilder); } else if (node.Symbol is Root) { FormatRoot(node, strBuilder); } else { throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter."); } } else { if (node is VariableTreeNode) { var varNode = node as VariableTreeNode; strBuilder.AppendFormat("{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 + " not supported for C# symbolic expression tree formatter."); } } }
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(); }
private static string FormatRecursively(ISymbolicExpressionTreeNode node) { StringBuilder strBuilder = new StringBuilder(); if (node.Subtrees.Count() > 0) { // node var symbol = node.Symbol as CFGSymbol; if (symbol != null) { var partsEnumerator = symbol.GetTerminalParts().GetEnumerator(); var subtreeEnumerator = node.Subtrees.GetEnumerator(); while (partsEnumerator.MoveNext() && subtreeEnumerator.MoveNext()) { strBuilder.Append(partsEnumerator.Current); strBuilder.Append(FormatRecursively(subtreeEnumerator.Current)); } strBuilder.Append(partsEnumerator.Current); } else { // ProgramRoot or StartSymbol foreach (var subtree in node.Subtrees) { strBuilder.Append(FormatRecursively(subtree)); } } } else { // leaf var symbol = node.Symbol as CFGSymbol; if (symbol != null) { var parts = symbol.GetTerminalParts(); strBuilder.Append(parts.First()); } } return strBuilder.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 string FormatRecursively(ISymbolicExpressionTreeNode node, int indentLength) { StringBuilder strBuilder = new StringBuilder(); if (Indent) strBuilder.Append(' ', indentLength); if (node.Subtrees.Count() > 0) { // internal node strBuilder.Append("("); if (node.Symbol is Addition) { strBuilder.AppendLine("+"); } else if (node.Symbol is And) { strBuilder.AppendLine("&&"); } else if (node.Symbol is Average) { strBuilder.AppendLine("avg"); } else if (node.Symbol is Cosine) { strBuilder.AppendLine("cos"); } else if (node.Symbol is Division) { strBuilder.AppendLine("/"); } else if (node.Symbol is Exponential) { strBuilder.AppendLine("exp"); } else if (node.Symbol is GreaterThan) { strBuilder.AppendLine(">"); } else if (node.Symbol is IfThenElse) { strBuilder.AppendLine("if"); } else if (node.Symbol is LessThan) { strBuilder.AppendLine("<"); } else if (node.Symbol is Logarithm) { strBuilder.AppendLine("ln"); } else if (node.Symbol is Multiplication) { strBuilder.AppendLine("*"); } else if (node.Symbol is Not) { strBuilder.AppendLine("!"); } else if (node.Symbol is Or) { strBuilder.AppendLine("||"); } else if (node.Symbol is Sine) { strBuilder.AppendLine("sin"); } else if (node.Symbol is Subtraction) { strBuilder.AppendLine("-"); } else if (node.Symbol is Tangent) { strBuilder.AppendLine("tan"); } else { throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for external evaluation."); } // each subtree expression on a new line // and closing ')' also on new line foreach (var subtree in node.Subtrees) { strBuilder.AppendLine(FormatRecursively(subtree, indentLength + 2)); } if (Indent) strBuilder.Append(' ', indentLength); strBuilder.Append(")"); } else { if (node is VariableTreeNode) { var varNode = node as VariableTreeNode; strBuilder.AppendFormat("(* {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 + " not supported for external evaluation."); } } return strBuilder.ToString(); }
public static int CompareNodes(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { var ta = a as SymbolicExpressionTreeTerminalNode; var tb = b as SymbolicExpressionTreeTerminalNode; if (ta == null) return tb == null ? String.CompareOrdinal(a.Symbol.Name, b.Symbol.Name) : -1; if (tb == null) return 1; // at this point we know a and b are both terminals var va = a as VariableTreeNode; var vb = b as VariableTreeNode; if (va != null) return vb == null ? -1 : CompareVariables(va, vb); if (vb != null) return 1; // at this point we know a and b are not variables var ca = a as ConstantTreeNode; var cb = b as ConstantTreeNode; if (ca != null && cb != null) return ca.Value.CompareTo(cb.Value); // for other unknown terminal types, compare strings return string.CompareOrdinal(a.ToString(), b.ToString()); }
public VariableNodeEditDialog(ISymbolicExpressionTreeNode node) { InitializeComponent(); oldValueTextBox.TabStop = false; // cannot receive focus using tab key NewNode = (VariableTreeNode)node; // will throw an invalid cast exception if node is not of the correct type InitializeFields(); }
public static IEnumerable<ISymbolicExpressionTreeNode> FindMatches(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode subtree, SymbolicExpressionTreeNodeEqualityComparer comp) { var fragmentLength = subtree.GetLength(); // below, we use ">=" for Match(n, subtree, comp) >= fragmentLength because in case of relaxed conditions, // we can have multiple matches of the same node return root.IterateNodesBreadth().Where(n => n.GetLength() >= fragmentLength && Match(n, subtree, comp) == fragmentLength); }
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))); }
/// <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 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 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)))); }
// version 1 // only use primary cut point private void SelectBranchFromNodes1(ISymbolicExpressionTreeNode statementNode, IList <CutPoint> crossoverPoints0, IList <IEnumerable <ISymbolicExpressionTreeNode> > allowedBranchesPerCutpoint, IRandom random, List <string> variables, string variableSettings, ICFGPythonProblemData problemData, out ISymbolicExpressionTreeNode selectedBranch, out CutPoint selectedCutPoint) { var jsonOutput = new Dictionary <ISymbolicExpressionTreeNode, JObject>(); var primaryCutPoint = crossoverPoints0[0]; primaryCutPoint.Parent.RemoveSubtree(primaryCutPoint.ChildIndex); // removes parent from child for (int i = 0; i < crossoverPoints0.Count; i++) { var cutPoint = crossoverPoints0[i]; primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, cutPoint.Child); // this will affect cutPoint.Parent var jsonCur = SemanticOperatorHelper.EvaluateStatementNode(statementNode, PyProcess, random, problemData, variables, variableSettings, Timeout); primaryCutPoint.Parent.RemoveSubtree(primaryCutPoint.ChildIndex); // removes intermediate parent from node cutPoint.Child.Parent = cutPoint.Parent; // restore parent if (!String.IsNullOrWhiteSpace((string)jsonCur["exception"])) { continue; } foreach (var possibleBranch in allowedBranchesPerCutpoint[i]) { JObject jsonPossibleBranch; if (!jsonOutput.ContainsKey(possibleBranch)) { var parent = possibleBranch.Parent; // save parent primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, possibleBranch); // this will affect node.Parent jsonPossibleBranch = SemanticOperatorHelper.EvaluateStatementNode(statementNode, PyProcess, random, problemData, variables, variableSettings, Timeout); primaryCutPoint.Parent.RemoveSubtree(primaryCutPoint.ChildIndex); // removes intermediate parent from node possibleBranch.Parent = parent; // restore parent jsonOutput.Add(possibleBranch, jsonPossibleBranch); } else { jsonPossibleBranch = jsonOutput[possibleBranch]; } if (!String.IsNullOrWhiteSpace((string)jsonPossibleBranch["exception"])) { continue; } if (!JToken.EqualityComparer.Equals(jsonCur, jsonPossibleBranch)) { primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, primaryCutPoint.Child); // restore primaryCutPoint selectedBranch = possibleBranch; selectedCutPoint = cutPoint; return; } } } primaryCutPoint.Parent.InsertSubtree(primaryCutPoint.ChildIndex, primaryCutPoint.Child); // restore primaryCutPoint // no difference was found with any comparison, select random selectedBranch = allowedBranchesPerCutpoint[0].SampleRandom(random); selectedCutPoint = crossoverPoints0[0]; }
/// <summary> /// Takes two parent individuals P0 and P1. /// Randomly choose a node i from the first parent, then test all nodes j from the second parent to determine the best child that would be obtained by swapping i for j. /// </summary> public static ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, IExecutionContext context, ISymbolicDataAnalysisSingleObjectiveEvaluator <T> evaluator, T problemData, List <int> rows, int maxDepth, int maxLength) { var crossoverPoints0 = new List <CutPoint>(); parent0.Root.ForEachNodePostfix((n) => { if (n.Parent != null && n.Parent != parent0.Root) { crossoverPoints0.Add(new CutPoint(n.Parent, n)); } }); CutPoint crossoverPoint0 = crossoverPoints0.SampleRandom(random); int level = parent0.Root.GetBranchLevel(crossoverPoint0.Child); int length = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength(); var allowedBranches = new List <ISymbolicExpressionTreeNode>(); parent1.Root.ForEachNodePostfix((n) => { if (n.Parent != null && n.Parent != parent1.Root) { if (n.GetDepth() + level <= maxDepth && n.GetLength() + length <= maxLength && crossoverPoint0.IsMatchingPointType(n)) { allowedBranches.Add(n); } } }); if (allowedBranches.Count == 0) { return(parent0); } // create symbols in order to improvize an ad-hoc tree so that the child can be evaluated ISymbolicExpressionTreeNode selectedBranch = null; var nodeQualities = new List <Tuple <ISymbolicExpressionTreeNode, double> >(); var originalChild = crossoverPoint0.Child; foreach (var node in allowedBranches) { var parent = node.Parent; Swap(crossoverPoint0, node); // the swap will set the nodes parent to crossoverPoint0.Parent IExecutionContext childContext = new ExecutionContext(context, evaluator, context.Scope); double quality = evaluator.Evaluate(childContext, parent0, problemData, rows); Swap(crossoverPoint0, originalChild); // swap the child back (so that the next swap will not affect the currently swapped node from parent1) nodeQualities.Add(new Tuple <ISymbolicExpressionTreeNode, double>(node, quality)); node.Parent = parent; // restore correct parent } nodeQualities.Sort((a, b) => a.Item2.CompareTo(b.Item2)); selectedBranch = evaluator.Maximization ? nodeQualities.Last().Item1 : nodeQualities.First().Item1; // swap the node that would create the best offspring Swap(crossoverPoint0, selectedBranch); return(parent0); }
public Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { var comparer = new SymbolicExpressionTreeNodeComparer(); // use a node comparer because it's faster than calling node.ToString() (strings are expensive) and comparing strings var compactedGraph = Compact(n1, n2); var forwardMap = new Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t1 => nodes of t2 var reverseMap = new Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t2 => nodes of t1 // visit nodes in order of decreasing height to ensure correct mapping var nodes1 = n1.IterateNodesPrefix().OrderByDescending(x => x.GetDepth()).ToList(); var nodes2 = n2.IterateNodesPrefix().ToList(); for (int i = 0; i < nodes1.Count; ++i) { var v = nodes1[i]; if (forwardMap.ContainsKey(v)) { continue; } var kv = compactedGraph[v]; ISymbolicExpressionTreeNode w = null; for (int j = 0; j < nodes2.Count; ++j) { var t = nodes2[j]; if (reverseMap.ContainsKey(t) || compactedGraph[t] != kv) { continue; } w = t; break; } if (w == null) { continue; } // at this point we know that v and w are isomorphic, however, the mapping cannot be done directly // (as in the paper) because the trees are unordered (subtree order might differ). the solution is // to sort subtrees from under commutative labels (this will work because the subtrees are isomorphic!) // while iterating over the two subtrees var vv = IterateBreadthOrdered(v, comparer).ToList(); var ww = IterateBreadthOrdered(w, comparer).ToList(); int len = Math.Min(vv.Count, ww.Count); for (int j = 0; j < len; ++j) { var s = vv[j]; var t = ww[j]; Debug.Assert(!reverseMap.ContainsKey(t)); forwardMap[s] = t; reverseMap[t] = s; } } return(forwardMap); }
private void SwapVariableWithTree(VariableTreeNode variableNode, ISymbolicExpressionTreeNode treeNode) { var parent = variableNode.Parent; int index = parent.IndexOfSubtree(variableNode); parent.RemoveSubtree(index); if (!variableNode.Weight.IsAlmost(1.0)) treeNode = CreateNodeFromWeight(treeNode, variableNode); parent.InsertSubtree(index, treeNode); }
public static ISymbolicExpressionTreeNode GetStatementNode(ISymbolicExpressionTreeNode parent, IEnumerable <string> statementProductionNames) { ISymbolicExpressionTreeNode statement = parent; while (statement != null && !statementProductionNames.Contains(statement.Symbol.Name)) { statement = statement.Parent; } return(statement); }
public void SortSubtrees(ISymbolicExpressionTreeNode node) { if (node.SubtreeCount == 0) return; var subtrees = node.Subtrees as List<ISymbolicExpressionTreeNode> ?? node.Subtrees.ToList(); if (IsSymmetric(node.Symbol)) { var comparer = new SymbolicExpressionTreeNodeComparer(); subtrees.Sort(comparer); } foreach (var s in subtrees) SortSubtrees(s); }
public static double ComputeSimilarity(ISymbolicExpressionTreeNode t1, ISymbolicExpressionTreeNode t2, bool simplify = false, bool strict = false) { var lh = t1.Hash(simplify, strict); var rh = t2.Hash(simplify, strict); Array.Sort(lh); Array.Sort(rh); return(ComputeSimilarity(lh, rh)); }
private ISymbolicExpressionTreeNode ParseArgument(Queue <Token> tokens) { Token argTok = tokens.Dequeue(); Debug.Assert(argTok.StringValue == "ARG"); Argument argument = new Argument((int)tokens.Dequeue().DoubleValue); ISymbolicExpressionTreeNode argNode = argument.CreateTreeNode(); return(argNode); }
public static string InterpretOnBulletMissed(ISymbolicExpressionTreeNode node) { string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret)); return(string.Format( @"public void onBulletMissed(BulletMissedEvent e) {{ {0} execute(); }}", code)); }
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 ISymbolicExpressionTreeNode ParseInvoke(Queue <Token> tokens) { Token invokeTok = tokens.Dequeue(); Debug.Assert(invokeTok.StringValue == "CALL"); InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue); ISymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode(); return(invokeNode); }
public static string InterpretOnBulletHit(ISymbolicExpressionTreeNode node) { var Prefix = "public void onBulletHit(BulletHitEvent e) {"; var Suffix = @"execute(); }"; string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret)); return(Prefix + code + Environment.NewLine + Suffix); }
private static int SampleArity(IRandom random, ISymbolicExpressionTreeNode node, int targetLength, int maxDepth) { // select actualArity randomly with the constraint that the sub-trees in the minimal arity can become large enough int minArity = node.Grammar.GetMinimumSubtreeCount(node.Symbol); int maxArity = node.Grammar.GetMaximumSubtreeCount(node.Symbol); if (maxArity > targetLength) { maxArity = targetLength; } if (minArity == maxArity) { return(minArity); } // the min number of sub-trees has to be set to a value that is large enough so that the largest possible tree is at least tree length // if 1..3 trees are possible and the largest possible first sub-tree is smaller larger than the target length then minArity should be at least 2 long aggregatedLongestExpressionLength = 0; for (int i = 0; i < maxArity; i++) { aggregatedLongestExpressionLength += (from s in node.Grammar.GetAllowedChildSymbols(node.Symbol, i) where s.InitialFrequency > 0.0 select node.Grammar.GetMaximumExpressionLength(s, maxDepth)).Max(); if (i > minArity && aggregatedLongestExpressionLength < targetLength) { minArity = i + 1; } else { break; } } // the max number of sub-trees has to be set to a value that is small enough so that the smallest possible tree is at most tree length // if 1..3 trees are possible and the smallest possible first sub-tree is already larger than the target length then maxArity should be at most 0 long aggregatedShortestExpressionLength = 0; for (int i = 0; i < maxArity; i++) { aggregatedShortestExpressionLength += (from s in node.Grammar.GetAllowedChildSymbols(node.Symbol, i) where s.InitialFrequency > 0.0 select node.Grammar.GetMinimumExpressionLength(s)).Min(); if (aggregatedShortestExpressionLength > targetLength) { maxArity = i; break; } } if (minArity > maxArity) { return(-1); } return(random.Next(minArity, maxArity + 1)); }
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 removeNodeToolStripMenuItem_Click(object sender, EventArgs e) { var node = currSelected.Content; if (node == tempNode) { tempNode = null; } ModifyTree(Tree, node.Parent, node, null, removeSubtree: false); currSelected = null; // because the currently selected node was just deleted }
public static string InterpretBinaryOperator(string opSy, ISymbolicExpressionTreeNode node) { if (node.SubtreeCount < 2) { throw new ArgumentException(string.Format("Expected at least two children in {0}.", node.Symbol), "node"); } string result = string.Join(opSy, node.Subtrees.Select(Interpret)); return("(" + result + ")"); }
public static ulong[] Hash(this ISymbolicExpressionTreeNode node, bool simplify = false, bool strict = false) { var hashNodes = simplify ? node.MakeNodes(strict).Simplify(HashFunction) : node.MakeNodes(strict).Sort(HashFunction); var hashes = new ulong[hashNodes.Length]; for (int i = 0; i < hashes.Length; ++i) { hashes[i] = hashNodes[i].CalculatedHashValue; } return(hashes); }
public static byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) { if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out byte opCode)) { return(opCode); } else { throw new NotSupportedException("Symbol: " + treeNode.Symbol); } }
private ISymbolicExpressionTreeNode CreateNodeFromWeight(ISymbolicExpressionTreeNode transformationTree, VariableTreeNode variableNode) { var multiplicationNode = new SymbolicExpressionTreeNode(new Multiplication()); multiplicationNode.AddSubtree(new ConstantTreeNode(new Constant()) { Value = variableNode.Weight }); multiplicationNode.AddSubtree(transformationTree); return(multiplicationNode); }
public ISymbolicExpressionTree Parse(string str) { ISymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode(); ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode(); var allTokens = GetAllTokens(str).ToArray(); ISymbolicExpressionTreeNode mainBranch = ParseS(new Queue <Token>(allTokens)); // only a main branch was given => insert the main branch into the default tree template root.AddSubtree(start); start.AddSubtree(mainBranch); return(new SymbolicExpressionTree(root)); }
private JObject GenerateOriginalJson(CutPoint crossoverPoint0, IEnumerable <string> statementProductionNames, ISymbolicExpressionTree parent0, string variableSettings, ItemArray <PythonStatementSemantic> semantic0, ICFGPythonProblemData problemData, IRandom random, List <string> variables) { ISymbolicExpressionTreeNode statementOriginal = SemanticOperatorHelper.GetStatementNode(crossoverPoint0.Child, statementProductionNames); // statementOriginal is not always the same as statement var statementPos0 = parent0.IterateNodesPrefix().ToList().IndexOf(statementOriginal); if (String.IsNullOrEmpty(variableSettings)) { var curSemantics = semantic0.First(x => x.TreeNodePrefixPos == statementPos0); variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(curSemantics.Before, problemData.Variables.GetVariableTypes()); } return(SemanticOperatorHelper.EvaluateStatementNode(statementOriginal, PyProcess, random, problemData, variables, variableSettings, Timeout)); }
private void removeSubtreeToolStripMenuItem_Click(object sender, EventArgs e) { var node = currSelected.Content; if (node.IterateNodesPostfix().Contains(tempNode)) { tempNode = null; } ModifyTree(Tree, node.Parent, node, null, removeSubtree: true); currSelected = null; // because the currently selected node was just deleted contextMenuStrip.Close(); // avoid display of submenus since the action has already been performed }
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; } } }
public static string InterpretRun(ISymbolicExpressionTreeNode node) { string code = string.Join(Environment.NewLine, node.Subtrees.Select(Interpret)); return(string.Format( @"public void run() {{ setAdjustGunForRobotTurn(true); turnRadarRightRadians(Double.POSITIVE_INFINITY); {0} execute(); }}", code)); }
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("}]"); }
// version 2 // check the statement node of every cut point in the parent // takes longer, but really checks for differences private void SelectBranchFromNodes2(IEnumerable <string> statementProductionNames, IList <CutPoint> crossoverPoints0, IList <IEnumerable <ISymbolicExpressionTreeNode> > allowedBranchesPerCutpoint, IRandom random, List <string> variables, string variableSettings, ICFGPythonProblemData problemData, out ISymbolicExpressionTreeNode selectedBranch, out CutPoint selectedCutPoint) { for (int i = 0; i < crossoverPoints0.Count; i++) { var cutPoint = crossoverPoints0[i]; ISymbolicExpressionTreeNode curStatementNode = SemanticOperatorHelper.GetStatementNode(cutPoint.Child, statementProductionNames); var jsonCur = SemanticOperatorHelper.EvaluateStatementNode(curStatementNode, PyProcess, random, problemData, variables, variableSettings, Timeout); if (!String.IsNullOrWhiteSpace((string)jsonCur["exception"])) { continue; } cutPoint.Parent.RemoveSubtree(cutPoint.ChildIndex); // removes parent from node foreach (var possibleBranch in allowedBranchesPerCutpoint[i]) { JObject jsonPossibleBranch; if (curStatementNode == cutPoint.Child) { // shouldn't actually happen jsonPossibleBranch = SemanticOperatorHelper.EvaluateStatementNode(possibleBranch, PyProcess, random, problemData, variables, variableSettings, Timeout); } else { var parent = possibleBranch.Parent; // save parent cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, possibleBranch); // this will affect node.Parent jsonPossibleBranch = SemanticOperatorHelper.EvaluateStatementNode(curStatementNode, PyProcess, random, problemData, variables, variableSettings, Timeout); cutPoint.Parent.RemoveSubtree(cutPoint.ChildIndex); // removes intermediate parent from node possibleBranch.Parent = parent; // restore parent } if (!String.IsNullOrWhiteSpace((string)jsonPossibleBranch["exception"])) { continue; } if (JToken.EqualityComparer.Equals(jsonCur, jsonPossibleBranch)) { continue; } // equal json, therefore continue cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, cutPoint.Child); // restore cutPoint selectedBranch = possibleBranch; selectedCutPoint = cutPoint; return; } cutPoint.Parent.InsertSubtree(cutPoint.ChildIndex, cutPoint.Child); // restore cutPoint } // no difference was found with any comparison, select randomly // only select form the first cut point, as the other cut points might not have allowedBranchesPerCutpoint selectedBranch = allowedBranchesPerCutpoint[0].SampleRandom(random); selectedCutPoint = crossoverPoints0[0]; }
public static void Create(IRandom random, ISymbolicExpressionTreeNode seedNode, int maxDepth) { // make sure it is possible to create a trees smaller than maxDepth if (seedNode.Grammar.GetMinimumExpressionDepth(seedNode.Symbol) > maxDepth) { throw new ArgumentException("Cannot create trees of depth " + maxDepth + " or smaller because of grammar constraints.", "maxDepth"); } int arity = seedNode.Grammar.GetMaximumSubtreeCount(seedNode.Symbol); // Throw an exception if the seedNode happens to be a terminal, since in this case we cannot grow a tree. if (arity <= 0) { throw new ArgumentException("Cannot grow tree. Seed node shouldn't have arity zero."); } var allowedSymbols = seedNode.Grammar.AllowedSymbols .Where(s => s.InitialFrequency > 0.0 && seedNode.Grammar.GetMaximumSubtreeCount(s) > 0) .ToList(); for (var i = 0; i < arity; i++) { var possibleSymbols = allowedSymbols .Where(s => seedNode.Grammar.IsAllowedChildSymbol(seedNode.Symbol, s, i) && seedNode.Grammar.GetMinimumExpressionDepth(s) <= maxDepth && seedNode.Grammar.GetMaximumExpressionDepth(s) >= maxDepth) .ToList(); var weights = possibleSymbols.Select(s => s.InitialFrequency).ToList(); #pragma warning disable 612, 618 var selectedSymbol = possibleSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 var tree = selectedSymbol.CreateTreeNode(); if (tree.HasLocalParameters) { tree.ResetLocalParameters(random); } seedNode.AddSubtree(tree); } // Only iterate over the non-terminal nodes (those which have arity > 0) // Start from depth 2 since the first two levels are formed by the rootNode and the seedNode foreach (var subTree in seedNode.Subtrees) { if (subTree.Grammar.GetMaximumSubtreeCount(subTree.Symbol) > 0) { RecursiveCreate(random, subTree, 2, maxDepth); } } }
private static string FormatRecursively(ISymbolicExpressionTreeNode node) { StringBuilder strBuilder = new StringBuilder(); if (node.Subtrees.Count() > 0) { // node foreach (var subtree in node.Subtrees) { strBuilder.Append(FormatRecursively(subtree)); } } else { // leaf strBuilder.Append(node.ToString()); } return strBuilder.ToString(); }
///<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 static ISymbolicExpressionTreeNode Difference(this ISymbolicExpressionTreeNode node, ISymbolicExpressionTreeNode other) { var a = node.IterateNodesPrefix().ToList(); var b = other.IterateNodesPrefix().ToList(); var list = new List<ISymbolicExpressionTreeNode>(); for (int i = 0, j = 0; i < a.Count && j < b.Count; ++i, ++j) { var s1 = a[i].ToString(); var s2 = b[j].ToString(); if (s1 == s2) continue; list.Add(a[i]); // skip subtrees since the parents are already different i += a[i].SubtreeCount; j += b[j].SubtreeCount; } ISymbolicExpressionTreeNode result = list.Count > 0 ? LowestCommonAncestor(node, list) : null; return result; }
/// <summary> /// Randomly returns a terminal node for the given <paramref name="parentNode"/>. /// (A terminal has got a minimum and maximum arity of 0.) /// </summary> /// <param name="parentNode">parent node for which a child node is returned randomly</param> /// <param name="grammar">grammar to determine the allowed child symbols for parentNode</param> /// <param name="random">random number generator</param> /// <returns>randomly chosen terminal node with arity 0 or null, if no terminal node exists</returns> protected ISymbolicExpressionTreeNode GetRandomTerminalNode(ISymbolicExpressionTreeNode parentNode, ISymbolicExpressionGrammar grammar, IRandom random) { // only select specific symbols, which can be interpreted ... var possibleSymbolsList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol) where s.InitialFrequency > 0.0 where s.MaximumArity == 0 where s.MinimumArity == 0 select s).ToList(); // no terminal node exists for the given parent node if (!possibleSymbolsList.Any()) return null; var newNode = possibleSymbolsList.SampleRandom(random).CreateTreeNode(); if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random); return newNode; }
private static IEnumerable<Instruction> Compile(ISymbolicExpressionTreeNode branch, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) { foreach (var node in branch.IterateNodesPrefix()) { Instruction instr = new Instruction(); int subtreesCount = node.SubtreeCount; if (subtreesCount > 255) throw new ArgumentException("Number of subtrees is too big (>255)"); instr.nArguments = (byte)subtreesCount; instr.opCode = opCodeMapper(node); if (node.Symbol is Argument) { var argNode = (ArgumentTreeNode)node; instr.data = (ushort)argNode.Symbol.ArgumentIndex; } instr.dynamicNode = node; foreach (var hook in postInstructionCompiledHooks) { instr = hook(instr); } yield return instr; } }
protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset dataset, IEnumerable<int> rows) { //optimization: constant nodes return always the same value ConstantTreeNode constantNode = node as ConstantTreeNode; if (constantNode != null) return constantNode.Value; var rootSymbol = new ProgramRootSymbol().CreateTreeNode(); var startSymbol = new StartSymbol().CreateTreeNode(); rootSymbol.AddSubtree(startSymbol); startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone()); var tempTree = new SymbolicExpressionTree(rootSymbol); // clone ADFs of source tree for (int i = 1; i < sourceTree.Root.SubtreeCount; i++) { tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone()); } return interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median(); }
public Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { var comparer = new SymbolicExpressionTreeNodeComparer(); // use a node comparer because it's faster than calling node.ToString() (strings are expensive) and comparing strings var compactedGraph = Compact(n1, n2); var forwardMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t1 => nodes of t2 var reverseMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>(); // nodes of t2 => nodes of t1 // visit nodes in order of decreasing height to ensure correct mapping var nodes1 = n1.IterateNodesPrefix().OrderByDescending(x => x.GetDepth()).ToList(); var nodes2 = n2.IterateNodesPrefix().ToList(); for (int i = 0; i < nodes1.Count; ++i) { var v = nodes1[i]; if (forwardMap.ContainsKey(v)) continue; var kv = compactedGraph[v]; ISymbolicExpressionTreeNode w = null; for (int j = 0; j < nodes2.Count; ++j) { var t = nodes2[j]; if (reverseMap.ContainsKey(t) || compactedGraph[t] != kv) continue; w = t; break; } if (w == null) continue; // at this point we know that v and w are isomorphic, however, the mapping cannot be done directly // (as in the paper) because the trees are unordered (subtree order might differ). the solution is // to sort subtrees from under commutative labels (this will work because the subtrees are isomorphic!) // while iterating over the two subtrees var vv = IterateBreadthOrdered(v, comparer).ToList(); var ww = IterateBreadthOrdered(w, comparer).ToList(); int len = Math.Min(vv.Count, ww.Count); for (int j = 0; j < len; ++j) { var s = vv[j]; var t = ww[j]; Debug.Assert(!reverseMap.ContainsKey(t)); forwardMap[s] = t; reverseMap[t] = s; } } return forwardMap; }
public bool Equals(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { if (!(a is SymbolicExpressionTreeTerminalNode)) // if a and b are non terminal nodes, check equality of symbol names return !(b is SymbolicExpressionTreeTerminalNode) && a.Symbol.Name.Equals(b.Symbol.Name); var va = a as VariableTreeNode; if (va != null) { var vb = b as VariableTreeNode; if (vb == null) return false; return (!MatchVariableNames || va.VariableName.Equals(vb.VariableName)) && (!MatchVariableWeights || va.Weight.Equals(vb.Weight)); } var ca = a as ConstantTreeNode; if (ca != null) { var cb = b as ConstantTreeNode; if (cb == null) return false; return (!MatchConstantValues || ca.Value.Equals(cb.Value)); } return false; }
/// <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 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 string FormatRecursively(ISymbolicExpressionTreeNode node, int indentLength) { StringBuilder strBuilder = new StringBuilder(); if (Indent) strBuilder.Append(' ', indentLength); strBuilder.Append("("); // internal nodes or leaf nodes? if (node.Subtrees.Count() > 0) { // symbol on same line as '(' strBuilder.AppendLine(node.ToString()); // each subtree expression on a new line // and closing ')' also on new line foreach (var subtree in node.Subtrees) { strBuilder.AppendLine(FormatRecursively(subtree, indentLength + 2)); } if (Indent) strBuilder.Append(' ', indentLength); strBuilder.Append(")"); } else { // symbol in the same line with as '(' and ')' strBuilder.Append(node.ToString()); strBuilder.Append(")"); } return strBuilder.ToString(); }
// the argumentTrees list contains already expanded trees used as arguments for invocations private ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node, IList<ISymbolicExpressionTreeNode> argumentTrees) { List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees); while (node.SubtreeCount > 0) node.RemoveSubtree(0); if (node.Symbol is InvokeFunction) { var invokeSym = node.Symbol as InvokeFunction; var defunNode = FindFunctionDefinition(root, invokeSym.FunctionName); var macroExpandedArguments = new List<ISymbolicExpressionTreeNode>(); foreach (var subtree in subtrees) { macroExpandedArguments.Add(MacroExpand(root, subtree, argumentTrees)); } return MacroExpand(root, defunNode, macroExpandedArguments); } else if (node.Symbol is Argument) { var argSym = node.Symbol as Argument; // return the correct argument sub-tree (already macro-expanded) return (SymbolicExpressionTreeNode)argumentTrees[argSym.ArgumentIndex].Clone(); } else { // recursive application foreach (var subtree in subtrees) { node.AddSubtree(MacroExpand(root, subtree, argumentTrees)); } return node; } }
/// <summary> /// Returns a randomly chosen child node for the given <paramref name="parentNode"/>. /// </summary> /// <param name="parentNode">parent node to find a child node randomly for</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar used to define the allowed child symbols</param> /// <param name="genotypeIndex">index in the integer vector; can be greater than vector length</param> /// <param name="random">random number generator</param> /// <returns>randomly chosen child node or null, if no child node exits</returns> protected ISymbolicExpressionTreeNode GetNewChildNode(ISymbolicExpressionTreeNode parentNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int genotypeIndex, IRandom random) { // only select specific symbols, which can be interpreted ... IEnumerable<ISymbol> symbolList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol) where s.InitialFrequency > 0.0 select s).ToList(); int prodRuleCount = symbolList.Count(); // no child node exists for the given parent node if (prodRuleCount < 1) return null; // genotypeIndex % genotype.Length, if wrapping is allowed int prodRuleIndex = genotype[genotypeIndex] % prodRuleCount; var newNode = symbolList.ElementAt(prodRuleIndex).CreateTreeNode(); if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random); return newNode; }
public bool IsMatchingPointType(ISymbolicExpressionTreeNode newChild) { var parent = this.Parent; if (newChild == null) { // make sure that one subtree can be removed and that only the last subtree is removed return grammar.GetMinimumSubtreeCount(parent.Symbol) < parent.SubtreeCount && this.ChildIndex == parent.SubtreeCount - 1; } else { // check syntax constraints of direct parent - child relation if (!grammar.ContainsSymbol(newChild.Symbol) || !grammar.IsAllowedChildSymbol(parent.Symbol, newChild.Symbol, this.ChildIndex)) return false; bool result = true; // check point type for the whole branch newChild.ForEachNodePostfix((n) => { result = result && grammar.ContainsSymbol(n.Symbol) && n.SubtreeCount >= grammar.GetMinimumSubtreeCount(n.Symbol) && n.SubtreeCount <= grammar.GetMaximumSubtreeCount(n.Symbol); }); return result; } }
private static int SampleArity(IRandom random, ISymbolicExpressionTreeNode node) { var minArity = node.Grammar.GetMinimumSubtreeCount(node.Symbol); var maxArity = node.Grammar.GetMaximumSubtreeCount(node.Symbol); return random.Next(minArity, maxArity + 1); }
private static void RecursiveCreate(IRandom random, ISymbolicExpressionTreeNode root, int currentDepth, int maxDepth) { var arity = SampleArity(random, root); if (arity == 0) return; var allowedSymbols = root.Grammar.AllowedSymbols.Where(s => s.InitialFrequency > 0.0).ToList(); for (var i = 0; i < arity; i++) { var possibleSymbols = allowedSymbols.Where(s => root.Grammar.IsAllowedChildSymbol(root.Symbol, s, i) && root.Grammar.GetMinimumExpressionDepth(s) - 1 <= maxDepth - currentDepth).ToList(); if (!possibleSymbols.Any()) throw new InvalidOperationException("No symbols are available for the tree."); var weights = possibleSymbols.Select(s => s.InitialFrequency).ToList(); #pragma warning disable 612, 618 var selectedSymbol = possibleSymbols.SelectRandom(weights, random); #pragma warning restore 612, 618 var tree = selectedSymbol.CreateTreeNode(); if (tree.HasLocalParameters) tree.ResetLocalParameters(random); root.AddSubtree(tree); } if (maxDepth > currentDepth) foreach (var subTree in root.Subtrees) if (subTree.Grammar.GetMaximumSubtreeCount(subTree.Symbol) != 0) RecursiveCreate(random, subTree, currentDepth + 1, maxDepth); }