/// <summary> /// Creates a compact representation of the two trees as a directed acyclic graph /// </summary> /// <param name="n1">The root of the first tree</param> /// <param name="n2">The root of the second tree</param> /// <returns>The compacted DAG representing the two trees</returns> private Dictionary <ISymbolicExpressionTreeNode, GraphNode> Compact(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { var nodeMap = new Dictionary <ISymbolicExpressionTreeNode, GraphNode>(); // K var labelMap = new Dictionary <string, GraphNode>(); // L var nodes = n1.IterateNodesPostfix().Concat(n2.IterateNodesPostfix()); // the disjoint union F var graph = new List <GraphNode>(); IEnumerable <GraphNode> Subtrees(GraphNode g, bool commutative) { var subtrees = g.SymbolicExpressionTreeNode.Subtrees.Select(x => nodeMap[x]); return(commutative ? subtrees.OrderBy(x => x.Hash) : subtrees); } foreach (var node in nodes) { var label = GetLabel(node); if (node.SubtreeCount == 0) { if (!labelMap.ContainsKey(label)) { labelMap[label] = new GraphNode(node, label); } nodeMap[node] = labelMap[label]; } else { var v = new GraphNode(node, label); bool found = false; var commutative = node.SubtreeCount > 1 && commutativeSymbols.Contains(label); var vv = Subtrees(v, commutative); foreach (var w in graph) { if (v.Depth != w.Depth || v.SubtreeCount != w.SubtreeCount || v.Length != w.Length || v.Label != w.Label) { continue; } var ww = Subtrees(w, commutative); found = vv.SequenceEqual(ww); if (found) { nodeMap[node] = w; break; } } if (!found) { nodeMap[node] = v; graph.Add(v); } } } return(nodeMap); }
private void copySubtree() { if (tempNode != null) { foreach (var subtree in tempNode.IterateNodesPostfix()) { var visualNode = GetVisualSymbolicExpressionTreeNode(subtree); visualNode.LineColor = Color.Black; visualNode.TextColor = Color.Black; if (subtree.Parent != null) { var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(subtree.Parent, subtree); visualLine.LineColor = Color.Black; } } } tempNode = currSelected.Content; foreach (var node in tempNode.IterateNodesPostfix()) { var visualNode = GetVisualSymbolicExpressionTreeNode(node); visualNode.LineColor = Color.LightGray; visualNode.TextColor = Color.LightGray; foreach (var subtree in node.Subtrees) { var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node, subtree); visualLine.LineColor = Color.LightGray; } } currSelected = null; RepaintNodes(); // no need to redo the layout and repaint everything since this operation does not change the tree }
public IEnumerable <ISymbolicExpressionTreeNode> IterateNodesPostfix() { if (root == null) { return(Enumerable.Empty <SymbolicExpressionTreeNode>()); } return(root.IterateNodesPostfix()); }
public Dictionary <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> ComputeBottomUpMapping(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { var compactedGraph = Compact(n1, n2); IEnumerable <ISymbolicExpressionTreeNode> Subtrees(ISymbolicExpressionTreeNode node, bool commutative) { var subtrees = node.IterateNodesPrefix(); return(commutative ? subtrees.OrderBy(x => compactedGraph[x].Hash) : subtrees); } var nodes1 = n1.IterateNodesPostfix().OrderByDescending(x => x.GetLength()); // by descending length so that largest subtrees are mapped first var nodes2 = (List <ISymbolicExpressionTreeNode>)n2.IterateNodesPostfix(); var forward = new NodeMap(); var reverse = new NodeMap(); foreach (ISymbolicExpressionTreeNode v in nodes1) { if (forward.ContainsKey(v)) { continue; } var kv = compactedGraph[v]; var commutative = v.SubtreeCount > 1 && commutativeSymbols.Contains(kv.Label); foreach (ISymbolicExpressionTreeNode w in nodes2) { if (w.GetLength() != kv.Length || w.GetDepth() != kv.Depth || reverse.ContainsKey(w) || compactedGraph[w] != kv) { continue; } // map one whole subtree to the other foreach (var t in Subtrees(v, commutative).Zip(Subtrees(w, commutative), Tuple.Create)) { forward[t.Item1] = t.Item2; reverse[t.Item2] = t.Item1; } break; } } return(forward); }
/// <summary> /// Creates a compact representation of the two trees as a directed acyclic graph /// </summary> /// <param name="n1">The root of the first tree</param> /// <param name="n2">The root of the second tree</param> /// <returns>The compacted DAG representing the two trees</returns> private Dictionary <ISymbolicExpressionTreeNode, GraphNode> Compact(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { var nodeMap = new Dictionary <ISymbolicExpressionTreeNode, GraphNode>(); // K var labelMap = new Dictionary <string, GraphNode>(); // L var childrenCount = new Dictionary <ISymbolicExpressionTreeNode, int>(); // Children var nodes = n1.IterateNodesPostfix().Concat(n2.IterateNodesPostfix()); // the disjoint union F var list = new List <GraphNode>(); var queue = new Queue <ISymbolicExpressionTreeNode>(); foreach (var n in nodes) { if (n.SubtreeCount == 0) { var label = GetLabel(n); if (!labelMap.ContainsKey(label)) { var z = new GraphNode { SymbolicExpressionTreeNode = n, Label = label }; labelMap[z.Label] = z; } nodeMap[n] = labelMap[label]; queue.Enqueue(n); } else { childrenCount[n] = n.SubtreeCount; } } while (queue.Any()) { var n = queue.Dequeue(); if (n.SubtreeCount > 0) { bool found = false; var label = n.Symbol.Name; var depth = n.GetDepth(); bool sort = n.SubtreeCount > 1 && commutativeSymbols.Contains(label); var nSubtrees = n.Subtrees.Select(x => nodeMap[x]).ToList(); if (sort) { nSubtrees.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label)); } for (int i = list.Count - 1; i >= 0; --i) { var w = list[i]; if (!(n.SubtreeCount == w.SubtreeCount && label == w.Label && depth == w.Depth)) { continue; } // sort V and W when the symbol is commutative because we are dealing with unordered trees var m = w.SymbolicExpressionTreeNode; var mSubtrees = m.Subtrees.Select(x => nodeMap[x]).ToList(); if (sort) { mSubtrees.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label)); } found = nSubtrees.SequenceEqual(mSubtrees); if (found) { nodeMap[n] = w; break; } } if (!found) { var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth }; list.Add(w); nodeMap[n] = w; } } if (n == n1 || n == n2) { continue; } var p = n.Parent; if (p == null) { continue; } childrenCount[p]--; if (childrenCount[p] == 0) { queue.Enqueue(p); } } return(nodeMap); }
/// <summary> /// Creates a compact representation of the two trees as a directed acyclic graph /// </summary> /// <param name="n1">The root of the first tree</param> /// <param name="n2">The root of the second tree</param> /// <returns>The compacted DAG representing the two trees</returns> private Dictionary<ISymbolicExpressionTreeNode, GraphNode> Compact(ISymbolicExpressionTreeNode n1, ISymbolicExpressionTreeNode n2) { var nodeMap = new Dictionary<ISymbolicExpressionTreeNode, GraphNode>(); // K var labelMap = new Dictionary<string, GraphNode>(); // L var childrenCount = new Dictionary<ISymbolicExpressionTreeNode, int>(); // Children var nodes = n1.IterateNodesPostfix().Concat(n2.IterateNodesPostfix()); // the disjoint union F var list = new List<GraphNode>(); var queue = new Queue<ISymbolicExpressionTreeNode>(); foreach (var n in nodes) { if (n.SubtreeCount == 0) { var label = GetLabel(n); if (!labelMap.ContainsKey(label)) { var z = new GraphNode { SymbolicExpressionTreeNode = n, Label = label }; labelMap[z.Label] = z; } nodeMap[n] = labelMap[label]; queue.Enqueue(n); } else { childrenCount[n] = n.SubtreeCount; } } while (queue.Any()) { var n = queue.Dequeue(); if (n.SubtreeCount > 0) { bool found = false; var label = n.Symbol.Name; var depth = n.GetDepth(); bool sort = n.SubtreeCount > 1 && commutativeSymbols.Contains(label); var nSubtrees = n.Subtrees.Select(x => nodeMap[x]).ToList(); if (sort) nSubtrees.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label)); for (int i = list.Count - 1; i >= 0; --i) { var w = list[i]; if (!(n.SubtreeCount == w.SubtreeCount && label == w.Label && depth == w.Depth)) continue; // sort V and W when the symbol is commutative because we are dealing with unordered trees var m = w.SymbolicExpressionTreeNode; var mSubtrees = m.Subtrees.Select(x => nodeMap[x]).ToList(); if (sort) mSubtrees.Sort((a, b) => string.CompareOrdinal(a.Label, b.Label)); found = nSubtrees.SequenceEqual(mSubtrees); if (found) { nodeMap[n] = w; break; } } if (!found) { var w = new GraphNode { SymbolicExpressionTreeNode = n, Label = label, Depth = depth }; list.Add(w); nodeMap[n] = w; } } if (n == n1 || n == n2) continue; var p = n.Parent; if (p == null) continue; childrenCount[p]--; if (childrenCount[p] == 0) queue.Enqueue(p); } return nodeMap; }
public static HashNode <ISymbolicExpressionTreeNode>[] MakeNodes(this ISymbolicExpressionTreeNode node, bool strict = false) { return(node.IterateNodesPostfix().Select(x => x.ToHashNode(strict)).ToArray().UpdateNodeSizes()); }