コード例 #1
0
 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 > ushort.MaxValue)
         {
             throw new ArgumentException("Number of subtrees is too big (> 65.535)");
         }
         instr.nArguments = (ushort)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);
     }
 }
コード例 #2
0
 public IEnumerable <ISymbolicExpressionTreeNode> IterateNodesPrefix()
 {
     if (root == null)
     {
         return(Enumerable.Empty <SymbolicExpressionTreeNode>());
     }
     return(root.IterateNodesPrefix());
 }
        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);
        }
コード例 #4
0
 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;
 }
コード例 #5
0
 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;
   }
 }
        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);
        }
コード例 #7
0
        public static bool CreateSubroutine(
            IRandom random,
            ISymbolicExpressionTree symbolicExpressionTree,
            int maxTreeLength, int maxTreeDepth,
            int maxFunctionDefinitions, int maxFunctionArguments)
        {
            var functionDefiningBranches = symbolicExpressionTree.IterateNodesPrefix().OfType <DefunTreeNode>();

            if (functionDefiningBranches.Count() >= maxFunctionDefinitions)
            {
                // allowed maximum number of ADF reached => abort
                return(false);
            }
            if (symbolicExpressionTree.Length + 4 > maxTreeLength)
            {
                // defining a new function causes an length increase by 4 nodes (max) if the max tree length is reached => abort
                return(false);
            }
            string formatString         = new StringBuilder().Append('0', (int)Math.Log10(maxFunctionDefinitions * 10 - 1)).ToString(); // >= 100 functions => ###
            var    allowedFunctionNames = from index in Enumerable.Range(0, maxFunctionDefinitions)
                                          select "ADF" + index.ToString(formatString);

            // select a random body (either the result producing branch or an ADF branch)
            var bodies = from node in symbolicExpressionTree.Root.Subtrees
                         select new { Tree = node, Length = node.GetLength() };
            var totalNumberOfBodyNodes = bodies.Select(x => x.Length).Sum();
            int r = random.Next(totalNumberOfBodyNodes);
            int aggregatedNumberOfBodyNodes          = 0;
            ISymbolicExpressionTreeNode selectedBody = null;

            foreach (var body in bodies)
            {
                aggregatedNumberOfBodyNodes += body.Length;
                if (aggregatedNumberOfBodyNodes > r)
                {
                    selectedBody = body.Tree;
                }
            }
            // sanity check
            if (selectedBody == null)
            {
                throw new InvalidOperationException();
            }

            // select a random cut point in the selected branch
            var allCutPoints = (from parent in selectedBody.IterateNodesPrefix()
                                from subtree in parent.Subtrees
                                select new CutPoint(parent, subtree)).ToList();

            if (!allCutPoints.Any())
            {
                // no cut points => abort
                return(false);
            }
            string newFunctionName  = allowedFunctionNames.Except(functionDefiningBranches.Select(x => x.FunctionName)).First();
            var    selectedCutPoint = allCutPoints.SampleRandom(random);

            // select random branches as argument cut-off points (replaced by argument terminal nodes in the function)
            List <CutPoint>             argumentCutPoints = SelectRandomArgumentBranches(selectedCutPoint.Child, random, ARGUMENT_CUTOFF_PROBABILITY, maxFunctionArguments);
            ISymbolicExpressionTreeNode functionBody      = selectedCutPoint.Child;

            // disconnect the function body from the tree
            selectedCutPoint.Parent.RemoveSubtree(selectedCutPoint.ChildIndex);
            // disconnect the argument branches from the function
            functionBody = DisconnectBranches(functionBody, argumentCutPoints);
            // insert a function invocation symbol instead
            var invokeNode = (InvokeFunctionTreeNode)(new InvokeFunction(newFunctionName)).CreateTreeNode();

            selectedCutPoint.Parent.InsertSubtree(selectedCutPoint.ChildIndex, invokeNode);
            // add the branches selected as argument as subtrees of the function invocation node
            foreach (var argumentCutPoint in argumentCutPoints)
            {
                invokeNode.AddSubtree(argumentCutPoint.Child);
            }

            // insert a new function defining branch
            var defunNode = (DefunTreeNode)(new Defun()).CreateTreeNode();

            defunNode.FunctionName = newFunctionName;
            defunNode.AddSubtree(functionBody);
            symbolicExpressionTree.Root.AddSubtree(defunNode);
            // the grammar in the newly defined function is a clone of the grammar of the originating branch
            defunNode.SetGrammar((ISymbolicExpressionTreeGrammar)selectedBody.Grammar.Clone());

            var allowedChildSymbols = selectedBody.Grammar.GetAllowedChildSymbols(selectedBody.Symbol);

            foreach (var allowedChildSymbol in allowedChildSymbols)
            {
                defunNode.Grammar.AddAllowedChildSymbol(defunNode.Symbol, allowedChildSymbol);
            }
            var maxSubtrees = selectedBody.Grammar.GetMaximumSubtreeCount(selectedBody.Symbol);

            for (int i = 0; i < maxSubtrees; i++)
            {
                foreach (var allowedChildSymbol in selectedBody.Grammar.GetAllowedChildSymbols(selectedBody.Symbol, i))
                {
                    defunNode.Grammar.AddAllowedChildSymbol(defunNode.Symbol, allowedChildSymbol);
                }
            }

            // remove all argument symbols from grammar except that one contained in cutpoints
            var oldArgumentSymbols = selectedBody.Grammar.Symbols.OfType <Argument>().ToList();

            foreach (var oldArgSymb in oldArgumentSymbols)
            {
                defunNode.Grammar.RemoveSymbol(oldArgSymb);
            }
            // find unique argument indexes and matching symbols in the function defining branch
            var newArgumentIndexes = (from node in defunNode.IterateNodesPrefix().OfType <ArgumentTreeNode>()
                                      select node.Symbol.ArgumentIndex).Distinct();

            // add argument symbols to grammar of function defining branch
            GrammarModifier.AddArgumentSymbol(selectedBody.Grammar, defunNode.Grammar, newArgumentIndexes, argumentCutPoints);
            defunNode.NumberOfArguments = newArgumentIndexes.Count();
            if (defunNode.NumberOfArguments != argumentCutPoints.Count)
            {
                throw new InvalidOperationException();
            }
            // add invoke symbol for newly defined function to the original branch
            GrammarModifier.AddInvokeSymbol(selectedBody.Grammar, defunNode.FunctionName, defunNode.NumberOfArguments, selectedCutPoint, argumentCutPoints);

            // when the new function body was taken from another function definition
            // add invoke symbol for newly defined function to all branches that are allowed to invoke the original branch
            if (selectedBody.Symbol is Defun)
            {
                var originalFunctionDefinition = selectedBody as DefunTreeNode;
                foreach (var subtree in symbolicExpressionTree.Root.Subtrees)
                {
                    var originalBranchInvokeSymbol = (from symb in subtree.Grammar.Symbols.OfType <InvokeFunction>()
                                                      where symb.FunctionName == originalFunctionDefinition.FunctionName
                                                      select symb).SingleOrDefault();
                    // when the original branch can be invoked from the subtree then also allow invocation of the function
                    if (originalBranchInvokeSymbol != null)
                    {
                        GrammarModifier.AddInvokeSymbol(subtree.Grammar, defunNode.FunctionName, defunNode.NumberOfArguments, selectedCutPoint, argumentCutPoints);
                    }
                }
            }
            return(true);
        }
    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;
    }