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 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 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 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;
    }