/// <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);
        }
コード例 #2
0
 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
 }
コード例 #3
0
 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);
        }
 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
 }
        /// <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;
    }
コード例 #8
0
 public static HashNode <ISymbolicExpressionTreeNode>[] MakeNodes(this ISymbolicExpressionTreeNode node, bool strict = false)
 {
     return(node.IterateNodesPostfix().Select(x => x.ToHashNode(strict)).ToArray().UpdateNodeSizes());
 }