private static void DeleteArgumentByConsolidation(IRandom random, DefunTreeNode branch, int removedArgumentIndex)
        {
            // replace references to the deleted argument with random references to existing arguments
            var possibleArgumentSymbols = (from sym in branch.Grammar.Symbols.OfType <Argument>()
                                           where sym.ArgumentIndex != removedArgumentIndex
                                           select sym).ToList();
            var argNodes = from node in branch.IterateNodesPrefix().OfType <ArgumentTreeNode>()
                           where node.Symbol.ArgumentIndex == removedArgumentIndex
                           select node;

            foreach (var argNode in argNodes)
            {
                var replacementSymbol = possibleArgumentSymbols.SampleRandom(random);
                argNode.Symbol = replacementSymbol;
            }
        }
    private static void DeletionByRandomRegeneration(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, DefunTreeNode selectedDefunBranch) {
      // find first invocation and replace it with a randomly generated tree
      // can't find all invocations in one step because once we replaced a top level invocation
      // the invocations below it are removed already
      var invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix()
                                from subtree in node.Subtrees.OfType<InvokeFunctionTreeNode>()
                                where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName
                                select new CutPoint(node, subtree)).FirstOrDefault();
      while (invocationCutPoint != null) {
        // deletion by random regeneration
        ISymbolicExpressionTreeNode replacementTree = null;
        var allowedSymbolsList = invocationCutPoint.Parent.Grammar.GetAllowedChildSymbols(invocationCutPoint.Parent.Symbol, invocationCutPoint.ChildIndex).ToList();
        var weights = allowedSymbolsList.Select(s => s.InitialFrequency);

#pragma warning disable 612, 618
        var selectedSymbol = allowedSymbolsList.SelectRandom(weights, random);
#pragma warning restore 612, 618


        int minPossibleLength = invocationCutPoint.Parent.Grammar.GetMinimumExpressionLength(selectedSymbol);
        int maxLength = Math.Max(minPossibleLength, invocationCutPoint.Child.GetLength());
        int minPossibleDepth = invocationCutPoint.Parent.Grammar.GetMinimumExpressionDepth(selectedSymbol);
        int maxDepth = Math.Max(minPossibleDepth, invocationCutPoint.Child.GetDepth());
        replacementTree = selectedSymbol.CreateTreeNode();
        if (replacementTree.HasLocalParameters)
          replacementTree.ResetLocalParameters(random);
        invocationCutPoint.Parent.RemoveSubtree(invocationCutPoint.ChildIndex);
        invocationCutPoint.Parent.InsertSubtree(invocationCutPoint.ChildIndex, replacementTree);

        ProbabilisticTreeCreator.PTC2(random, replacementTree, maxLength, maxDepth);

        invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix()
                              from subtree in node.Subtrees.OfType<InvokeFunctionTreeNode>()
                              where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName
                              select new CutPoint(node, subtree)).FirstOrDefault();
      }
    }
        private static void DeletionByRandomRegeneration(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, DefunTreeNode selectedDefunBranch)
        {
            // find first invocation and replace it with a randomly generated tree
            // can't find all invocations in one step because once we replaced a top level invocation
            // the invocations below it are removed already
            var invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix()
                                      from subtree in node.Subtrees.OfType <InvokeFunctionTreeNode>()
                                      where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName
                                      select new CutPoint(node, subtree)).FirstOrDefault();

            while (invocationCutPoint != null)
            {
                // deletion by random regeneration
                ISymbolicExpressionTreeNode replacementTree = null;
                var allowedSymbolsList = invocationCutPoint.Parent.Grammar.GetAllowedChildSymbols(invocationCutPoint.Parent.Symbol, invocationCutPoint.ChildIndex).ToList();
                var weights            = allowedSymbolsList.Select(s => s.InitialFrequency);

#pragma warning disable 612, 618
                var selectedSymbol = allowedSymbolsList.SelectRandom(weights, random);
#pragma warning restore 612, 618


                int minPossibleLength = invocationCutPoint.Parent.Grammar.GetMinimumExpressionLength(selectedSymbol);
                int maxLength         = Math.Max(minPossibleLength, invocationCutPoint.Child.GetLength());
                int minPossibleDepth  = invocationCutPoint.Parent.Grammar.GetMinimumExpressionDepth(selectedSymbol);
                int maxDepth          = Math.Max(minPossibleDepth, invocationCutPoint.Child.GetDepth());
                replacementTree = selectedSymbol.CreateTreeNode();
                if (replacementTree.HasLocalParameters)
                {
                    replacementTree.ResetLocalParameters(random);
                }
                invocationCutPoint.Parent.RemoveSubtree(invocationCutPoint.ChildIndex);
                invocationCutPoint.Parent.InsertSubtree(invocationCutPoint.ChildIndex, replacementTree);

                ProbabilisticTreeCreator.PTC2(random, replacementTree, maxLength, maxDepth);

                invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix()
                                      from subtree in node.Subtrees.OfType <InvokeFunctionTreeNode>()
                                      where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName
                                      select new CutPoint(node, subtree)).FirstOrDefault();
            }
        }
Exemple #4
0
 private DefunTreeNode(DefunTreeNode original, Cloner cloner)
     : base(original, cloner)
 {
     functionName      = original.functionName;
     numberOfArguments = original.numberOfArguments;
 }
        private static bool CreateNewArgumentForDefun(IRandom random, ISymbolicExpressionTree tree, DefunTreeNode defunBranch, ArgumentTreeNode newArgumentNode)
        {
            // select a random cut point in the function defining branch
            // the branch at the cut point is to be replaced by a new argument node
            var cutPoints = (from node in defunBranch.IterateNodesPrefix()
                             where node.Subtrees.Count() > 0 &&
                             !node.IterateNodesPrefix().OfType <ArgumentTreeNode>().Any() &&
                             !node.IterateNodesPrefix().OfType <InvokeFunctionTreeNode>().Any()
                             from subtree in node.Subtrees
                             select new CutPoint(node, subtree)).ToList();

            if (cutPoints.Count() == 0)
            {
                // no cut point found => abort;
                return(false);
            }
            var selectedCutPoint = cutPoints[random.Next(cutPoints.Count)];
            // replace the branch at the cut point with an argument node
            var replacedBranch = selectedCutPoint.Child;

            selectedCutPoint.Parent.RemoveSubtree(selectedCutPoint.ChildIndex);
            selectedCutPoint.Parent.InsertSubtree(selectedCutPoint.ChildIndex, newArgumentNode);

            // find all old invocations of the selected ADF and attach a cloned version of the replaced branch (with all argument-nodes expanded)
            // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed
            var invocationNodes = (from node in tree.IterateNodesPostfix().OfType <InvokeFunctionTreeNode>()
                                   where node.Symbol.FunctionName == defunBranch.FunctionName
                                   where node.Subtrees.Count() == defunBranch.NumberOfArguments
                                   select node).ToList();

            // do this repeatedly until no matching invocations are found
            while (invocationNodes.Count > 0)
            {
                List <ISymbolicExpressionTreeNode> newlyAddedBranches = new List <ISymbolicExpressionTreeNode>();
                foreach (var invocationNode in invocationNodes)
                {
                    // check that the invocation node really has the correct number of arguments
                    if (invocationNode.Subtrees.Count() != defunBranch.NumberOfArguments)
                    {
                        throw new InvalidOperationException();
                    }
                    // append a new argument branch after expanding all argument nodes
                    var clonedBranch = (ISymbolicExpressionTreeNode)replacedBranch.Clone();
                    clonedBranch = ReplaceArgumentsInBranch(clonedBranch, invocationNode.Subtrees);
                    invocationNode.InsertSubtree(newArgumentNode.Symbol.ArgumentIndex, clonedBranch);
                    newlyAddedBranches.Add(clonedBranch);
                }
                // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed
                invocationNodes = (from newlyAddedBranch in newlyAddedBranches
                                   from node in newlyAddedBranch.IterateNodesPostfix().OfType <InvokeFunctionTreeNode>()
                                   where node.Symbol.FunctionName == defunBranch.FunctionName
                                   where node.Subtrees.Count() == defunBranch.NumberOfArguments
                                   select node).ToList();
            }
            // increase expected number of arguments of function defining branch
            // it's possible that the number of actually referenced arguments was reduced (all references were replaced by a single new argument)
            // but the number of expected arguments is increased anyway
            defunBranch.NumberOfArguments++;
            defunBranch.Grammar.AddSymbol(newArgumentNode.Symbol);
            defunBranch.Grammar.SetSubtreeCount(newArgumentNode.Symbol, 0, 0);
            // allow the argument as child of any other symbol
            GrammarModifier.SetAllowedParentSymbols(defunBranch.Grammar, selectedCutPoint.Child.Symbol, newArgumentNode.Symbol);

            foreach (var subtree in tree.Root.Subtrees)
            {
                // when the changed function is known in the branch then update the number of arguments
                var matchingSymbol = subtree.Grammar.Symbols.OfType <InvokeFunction>().Where(s => s.FunctionName == defunBranch.FunctionName).SingleOrDefault();
                if (matchingSymbol != null)
                {
                    subtree.Grammar.SetSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments, defunBranch.NumberOfArguments);
                    foreach (var symb in subtree.Grammar.Symbols)
                    {
                        if (symb is StartSymbol || symb is ProgramRootSymbol)
                        {
                            continue;
                        }
                        if (symb.Name == matchingSymbol.Name)
                        {
                            continue;                       //don't allow invoke as child of invoke
                        }
                        if (subtree.Grammar.IsAllowedChildSymbol(selectedCutPoint.Parent.Symbol, symb, selectedCutPoint.ChildIndex))
                        {
                            subtree.Grammar.AddAllowedChildSymbol(matchingSymbol, symb, newArgumentNode.Symbol.ArgumentIndex);
                        }
                    }
                }
            }

            return(true);
        }
 private DefunTreeNode(DefunTreeNode original, Cloner cloner)
   : base(original, cloner) {
   functionName = original.functionName;
   numberOfArguments = original.numberOfArguments;
 }
 private static void DeleteArgumentByConsolidation(IRandom random, DefunTreeNode branch, int removedArgumentIndex) {
   // replace references to the deleted argument with random references to existing arguments
   var possibleArgumentSymbols = (from sym in branch.Grammar.Symbols.OfType<Argument>()
                                  where sym.ArgumentIndex != removedArgumentIndex
                                  select sym).ToList();
   var argNodes = from node in branch.IterateNodesPrefix().OfType<ArgumentTreeNode>()
                  where node.Symbol.ArgumentIndex == removedArgumentIndex
                  select node;
   foreach (var argNode in argNodes) {
     var replacementSymbol = possibleArgumentSymbols.SampleRandom(random);
     argNode.Symbol = replacementSymbol;
   }
 }
    private static bool CreateNewArgumentForDefun(IRandom random, ISymbolicExpressionTree tree, DefunTreeNode defunBranch, ArgumentTreeNode newArgumentNode) {
      // select a random cut point in the function defining branch
      // the branch at the cut point is to be replaced by a new argument node
      var cutPoints = (from node in defunBranch.IterateNodesPrefix()
                       where node.Subtrees.Count() > 0 &&
                             !node.IterateNodesPrefix().OfType<ArgumentTreeNode>().Any() &&
                             !node.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>().Any()
                       from subtree in node.Subtrees
                       select new CutPoint(node, subtree)).ToList();

      if (cutPoints.Count() == 0)
        // no cut point found => abort;
        return false;
      var selectedCutPoint = cutPoints[random.Next(cutPoints.Count)];
      // replace the branch at the cut point with an argument node
      var replacedBranch = selectedCutPoint.Child;
      selectedCutPoint.Parent.RemoveSubtree(selectedCutPoint.ChildIndex);
      selectedCutPoint.Parent.InsertSubtree(selectedCutPoint.ChildIndex, newArgumentNode);

      // find all old invocations of the selected ADF and attach a cloned version of the replaced branch (with all argument-nodes expanded)
      // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed
      var invocationNodes = (from node in tree.IterateNodesPostfix().OfType<InvokeFunctionTreeNode>()
                             where node.Symbol.FunctionName == defunBranch.FunctionName
                             where node.Subtrees.Count() == defunBranch.NumberOfArguments
                             select node).ToList();
      // do this repeatedly until no matching invocations are found      
      while (invocationNodes.Count > 0) {
        List<ISymbolicExpressionTreeNode> newlyAddedBranches = new List<ISymbolicExpressionTreeNode>();
        foreach (var invocationNode in invocationNodes) {
          // check that the invocation node really has the correct number of arguments
          if (invocationNode.Subtrees.Count() != defunBranch.NumberOfArguments) throw new InvalidOperationException();
          // append a new argument branch after expanding all argument nodes
          var clonedBranch = (ISymbolicExpressionTreeNode)replacedBranch.Clone();
          clonedBranch = ReplaceArgumentsInBranch(clonedBranch, invocationNode.Subtrees);
          invocationNode.InsertSubtree(newArgumentNode.Symbol.ArgumentIndex, clonedBranch);
          newlyAddedBranches.Add(clonedBranch);
        }
        // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed
        invocationNodes = (from newlyAddedBranch in newlyAddedBranches
                           from node in newlyAddedBranch.IterateNodesPostfix().OfType<InvokeFunctionTreeNode>()
                           where node.Symbol.FunctionName == defunBranch.FunctionName
                           where node.Subtrees.Count() == defunBranch.NumberOfArguments
                           select node).ToList();
      }
      // increase expected number of arguments of function defining branch
      // it's possible that the number of actually referenced arguments was reduced (all references were replaced by a single new argument)
      // but the number of expected arguments is increased anyway
      defunBranch.NumberOfArguments++;
      defunBranch.Grammar.AddSymbol(newArgumentNode.Symbol);
      defunBranch.Grammar.SetSubtreeCount(newArgumentNode.Symbol, 0, 0);
      // allow the argument as child of any other symbol
      GrammarModifier.SetAllowedParentSymbols(defunBranch.Grammar, selectedCutPoint.Child.Symbol, newArgumentNode.Symbol);

      foreach (var subtree in tree.Root.Subtrees) {
        // when the changed function is known in the branch then update the number of arguments
        var matchingSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == defunBranch.FunctionName).SingleOrDefault();
        if (matchingSymbol != null) {
          subtree.Grammar.SetSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments, defunBranch.NumberOfArguments);
          foreach (var symb in subtree.Grammar.Symbols) {
            if (symb is StartSymbol || symb is ProgramRootSymbol) continue;
            if (symb.Name == matchingSymbol.Name) continue; //don't allow invoke as child of invoke
            if (subtree.Grammar.IsAllowedChildSymbol(selectedCutPoint.Parent.Symbol, symb, selectedCutPoint.ChildIndex))
              subtree.Grammar.AddAllowedChildSymbol(matchingSymbol, symb, newArgumentNode.Symbol.ArgumentIndex);
          }
        }
      }

      return true;
    }