예제 #1
0
        public void ReplaceBranchManipulationDistributionsTest()
        {
            SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
            var trees   = new List <ISymbolicExpressionTree>();
            var grammar = Grammars.CreateArithmeticAndAdfGrammar();
            var random  = new MersenneTwister(31415);

            for (int i = 0; i < POPULATION_SIZE; i++)
            {
                var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
                string originalTree = formatter.Format(tree);
                ReplaceBranchManipulation.ReplaceRandomBranch(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
                string manipulatedTree = formatter.Format(tree);
                Assert.IsFalse(originalTree == manipulatedTree);
                Util.IsValid(tree);
                trees.Add(tree);
            }
            Console.WriteLine("ReplaceBranchManipulation: " + Environment.NewLine +
                              Util.GetSizeDistributionString(trees, 105, 5) + Environment.NewLine +
                              Util.GetFunctionDistributionString(trees) + Environment.NewLine +
                              Util.GetNumberOfSubtreesDistributionString(trees) + Environment.NewLine +
                              Util.GetTerminalDistributionString(trees) + Environment.NewLine
                              );
        }
예제 #2
0
        /// <summary>
        /// 1. find a mutation point
        /// 2. generate new random tree
        /// 3. calculate semantic of old and new subtree (or of the closest parent)
        /// 4. do mutation if semantically different
        /// 5. retry until a certain number of tries is reached
        ///
        /// if no mutation has happened, do random mutation
        /// </summary>
        public static void ReplaceSemanticallyDifferentBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, ICFGPythonProblemData problemData, ItemArray <PythonStatementSemantic> semantics, PythonProcess pythonProcess, double timeout, int maxTreeLength, int maxTreeDepth, int maximumSemanticTries)
        {
            if (semantics == null || semantics.Length == 0)
            {
                ReplaceBranchManipulation.ReplaceRandomBranch(random, symbolicExpressionTree, maxTreeLength, maxTreeDepth);
                return;
            }

            var    statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(symbolicExpressionTree.Root.Grammar);
            var    variables        = problemData.Variables.GetVariableNames().ToList();
            string variableSettings = problemData.VariableSettings.Count == 0 ? String.Empty : String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value));

            var allowedSymbols = new List <ISymbol>();
            // repeat until a fitting parent and child are found (MAX_TRIES times)
            int tries         = 0;
            int semanticTries = 0;

            do
            {
                #region find mutation point
#pragma warning disable 612, 618
                ISymbolicExpressionTreeNode parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random);
#pragma warning restore 612, 618

                int childIndex = random.Next(parent.SubtreeCount);
                var child      = parent.GetSubtree(childIndex);
                int maxLength  = maxTreeLength - symbolicExpressionTree.Length + child.GetLength();
                int maxDepth   = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child);

                allowedSymbols.Clear();
                foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex))
                {
                    // check basic properties that the new symbol must have
                    if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) &&
                        symbol.InitialFrequency > 0 &&
                        parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth &&
                        parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength)
                    {
                        allowedSymbols.Add(symbol);
                    }
                }
                #endregion

                #region check for semantic difference with a new random tree
                if (allowedSymbols.Count > 0)
                {
                    if (semanticTries <= maximumSemanticTries)
                    {
                        // do semantic mutation
                        #region calculate original json output
                        ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames);
                        var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement);
                        if (String.IsNullOrEmpty(variableSettings))
                        {
                            variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantics.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes());
                        }

                        var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        #endregion

                        var seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth);

                        #region calculate new json output
                        JObject jsonReplaced;
                        if (child == statement)
                        {
                            // child is executable, so is the new child
                            jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        }
                        else
                        {
                            jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        }

                        if (JToken.EqualityComparer.Equals(jsonOriginal, jsonReplaced))
                        {
                            // semantically equivalent. undo mutation
                            parent.RemoveSubtree(childIndex);
                            parent.InsertSubtree(childIndex, child);
                            allowedSymbols.Clear();
                        }
                        else
                        {
                            Console.WriteLine("never happens?");
                        }

                        if (problemData.VariableSettings.Count == 0)
                        {
                            // reset variableSettings
                            variableSettings = String.Empty;
                        }
                        semanticTries++;
                        #endregion
                    }
                    else
                    {
                        // do random mutation
                        GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth);
                    }
                }
                #endregion
                tries++;
            } while (tries < MAX_TRIES && allowedSymbols.Count == 0 && semanticTries <= maximumSemanticTries);
        }
        public override void ReplaceBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, ICFGPythonProblemData problemData, ItemArray <PythonStatementSemantic> semantics, PythonProcess pythonProcess, double timeout, int maxTreeLength, int maxTreeDepth, int maximumSemanticTries)
        {
            if (semantics == null || semantics.Length == 0)
            {
                ReplaceBranchManipulation.ReplaceRandomBranch(random, symbolicExpressionTree, maxTreeLength, maxTreeDepth);
                SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(NoSemantics);
                MutationTypeParameter.ActualValue = new IntValue(RandomMutation);
                return;
            }

            var    statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(symbolicExpressionTree.Root.Grammar);
            var    variables        = problemData.Variables.GetVariableNames().ToList();
            string variableSettings = problemData.VariableSettings.Count == 0 ? String.Empty : String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value));

            var allowedSymbols = new List <ISymbol>();
            // repeat until a fitting parent and child are found (MAX_TRIES times)
            int tries         = 0;
            int semanticTries = 0;

            List <JObject> saveOriginalSemantics = null;
            List <JObject> saveReplaceSemantics  = null;
            List <Tuple <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, int> > possibleChildren = null; // Item1 = parent, Item2 = seedNode, Item3 = childIndex

            if (UsesAdditionalSemanticMeasure())
            {
                saveOriginalSemantics = new List <JObject>(semanticTries);
                saveReplaceSemantics  = new List <JObject>(semanticTries);
                possibleChildren      = new List <Tuple <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, int> >(semanticTries);
            }
            bool success = false;

            do
            {
                #region find mutation point
#pragma warning disable 612, 618
                ISymbolicExpressionTreeNode parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random);
#pragma warning restore 612, 618

                int childIndex = random.Next(parent.SubtreeCount);
                var child      = parent.GetSubtree(childIndex);
                int maxLength  = maxTreeLength - symbolicExpressionTree.Length + child.GetLength();
                int maxDepth   = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child);

                allowedSymbols.Clear();
                foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex))
                {
                    // check basic properties that the new symbol must have
                    if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) &&
                        symbol.InitialFrequency > 0 &&
                        parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth &&
                        parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength)
                    {
                        allowedSymbols.Add(symbol);
                    }
                }
                #endregion
                #region check for semantic difference with a new random tree
                if (allowedSymbols.Count > 0)
                {
                    if (semanticTries <= maximumSemanticTries)
                    {
                        // do semantic mutation
                        #region calculate original json output
                        ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames);
                        var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement);
                        PythonStatementSemantic curSemantics = null;
                        if (String.IsNullOrEmpty(variableSettings))
                        {
                            curSemantics     = semantics.First(x => x.TreeNodePrefixPos == statementPos0);
                            variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(curSemantics.Before, problemData.Variables.GetVariableTypes());
                        }

                        var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);

                        // compare jsonOriginal to semantic after! Maybe avoid additional evaluation.
                        #endregion

                        var seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth);

                        #region calculate new json output
                        JObject jsonReplaced;
                        if (child == statement)
                        {
                            // child is executable, so is the new child
                            jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        }
                        else
                        {
                            jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        }

                        var exception = jsonOriginal["exception"] != null || jsonReplaced["exception"] != null;

                        if (exception)
                        {
                            if (jsonOriginal["exception"] != null)
                            {
                                MutationExceptionsParameter.ActualValue.Add(new StringValue(jsonOriginal["exception"].ToString()));
                            }
                            if (jsonReplaced["exception"] != null)
                            {
                                MutationExceptionsParameter.ActualValue.Add(new StringValue(jsonReplaced["exception"].ToString()));
                            }
                        }

                        if (curSemantics != null && !exception)
                        {
                            jsonOriginal = PythonSemanticComparer.ReplaceNotExecutedCases(jsonOriginal, curSemantics.Before, curSemantics.ExecutedCases);
                            jsonReplaced = PythonSemanticComparer.ReplaceNotExecutedCases(jsonReplaced, curSemantics.Before, curSemantics.ExecutedCases);

                            jsonOriginal = PythonSemanticComparer.ProduceDifference(jsonOriginal, curSemantics.Before);
                            jsonReplaced = PythonSemanticComparer.ProduceDifference(jsonReplaced, curSemantics.Before);
                        }

                        if (!exception && SemanticMeasure(jsonOriginal, jsonReplaced))
                        {
                            success = true;
                            SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different);
                            TypeSelectedForSimilarityParameter.ActualValue      = new StringValue("First Semantic");
                            MutationTypeParameter.ActualValue = new IntValue(SemanticMutation);
                        }
                        else
                        {
                            // undo mutation
                            parent.RemoveSubtree(childIndex);
                            parent.InsertSubtree(childIndex, child);
                            allowedSymbols.Clear();

                            if (!exception && UsesAdditionalSemanticMeasure())
                            {
                                saveOriginalSemantics.Add(jsonOriginal);
                                saveReplaceSemantics.Add(jsonReplaced);
                                possibleChildren.Add(new Tuple <ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode, int>(parent, seedNode, childIndex));
                            }
                        }

                        if (problemData.VariableSettings.Count == 0)
                        {
                            // reset variableSettings
                            variableSettings = String.Empty;
                        }
                        semanticTries++;
                        #endregion

                        #region try second semantic comparison
                        if (!success && semanticTries >= maximumSemanticTries && UsesAdditionalSemanticMeasure())
                        {
                            for (int index = 0; index < saveOriginalSemantics.Count; index++)
                            {
                                if (AdditionalSemanticMeasure(saveOriginalSemantics[index], saveReplaceSemantics[index]))
                                {
                                    var mutation = possibleChildren[index];
                                    mutation.Item1.RemoveSubtree(mutation.Item3);
                                    mutation.Item1.InsertSubtree(mutation.Item3, mutation.Item2);
                                    success = true;
                                    SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different);
                                    TypeSelectedForSimilarityParameter.ActualValue      = new StringValue("Second Semantic");
                                    MutationTypeParameter.ActualValue = new IntValue(SemanticMutation);
                                    break;
                                }
                            }
                        }
                        #endregion
                    }
                    else
                    {
                        // do random mutation
                        #region calculate original json output
                        ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames);
                        var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement);
                        if (String.IsNullOrEmpty(variableSettings))
                        {
                            variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantics.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes());
                        }

                        var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        #endregion

                        var     seedNode = GenerateAndInsertNewSubtree(random, parent, allowedSymbols, childIndex, maxLength, maxDepth);
                        JObject jsonReplaced;
                        if (child == statement)
                        {
                            // child is executable, so is the new child
                            jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        }
                        else
                        {
                            jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                        }
                        if (JToken.EqualityComparer.Equals(jsonOriginal, jsonReplaced))
                        {
                            SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Equvivalent);
                        }
                        else
                        {
                            SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different);
                        }
                        TypeSelectedForSimilarityParameter.ActualValue = new StringValue("Random Crossover; Reached Max Semantic Tries");
                        MutationTypeParameter.ActualValue = new IntValue(RandomMutation);
                        success = true;
                    }
                }
                #endregion
                tries++;
            } while (tries < MAX_TRIES && !success);

            NumberOfTriesParameter.ActualValue = new IntValue(semanticTries);
            if (SemanticallyEquivalentMutationParameter.ActualValue == null)
            {
                SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(NoMutation);
                TypeSelectedForSimilarityParameter.ActualValue      = new StringValue("No mutation");
                MutationTypeParameter.ActualValue = new IntValue(NoMutation);
            }
        }
예제 #4
0
        public override void ReplaceBranch(IRandom random, ISymbolicExpressionTree symbolicExpressionTree, ICFGPythonProblemData problemData, ItemArray <PythonStatementSemantic> semantics, PythonProcess pythonProcess, double timeout, int maxTreeLength, int maxTreeDepth, int maximumSemanticTries)
        {
            if (semantics == null || semantics.Length == 0)
            {
                ReplaceBranchManipulation.ReplaceRandomBranch(random, symbolicExpressionTree, maxTreeLength, maxTreeDepth);
                SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(NoSemantics);
                MutationTypeParameter.ActualValue = new IntValue(RandomMutation);
                return;
            }

            var allowedSymbols = new List <ISymbol>();
            ISymbolicExpressionTreeNode parent;
            int childIndex;
            int maxLength;
            int maxDepth;
            // repeat until a fitting parent and child are found (MAX_TRIES times)
            int tries = 0;
            ISymbolicExpressionTreeNode child;

            do
            {
#pragma warning disable 612, 618
                parent = symbolicExpressionTree.Root.IterateNodesPrefix().Skip(1).Where(n => n.SubtreeCount > 0).SelectRandom(random);
#pragma warning restore 612, 618

                childIndex = random.Next(parent.SubtreeCount);
                child      = parent.GetSubtree(childIndex);
                maxLength  = maxTreeLength - symbolicExpressionTree.Length + child.GetLength();
                maxDepth   = maxTreeDepth - symbolicExpressionTree.Root.GetBranchLevel(child);

                allowedSymbols.Clear();
                foreach (var symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex))
                {
                    // check basic properties that the new symbol must have
                    if ((symbol.Name != child.Symbol.Name || symbol.MinimumArity > 0) &&
                        symbol.InitialFrequency > 0 &&
                        parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth &&
                        parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength)
                    {
                        allowedSymbols.Add(symbol);
                    }
                }
                tries++;
            } while (tries < MAX_TRIES && allowedSymbols.Count == 0);

            NumberOfTriesParameter.ActualValue = new IntValue(tries); //normal tries. not semantic tries

            if (tries < MAX_TRIES)
            {
                var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(symbolicExpressionTree.Root.Grammar);
                var variables = problemData.Variables.GetVariableNames().ToList();

                #region calculate original json output
                ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(child, statementProductionNames);
                string variableSettings = problemData.VariableSettings.Count == 0 ? String.Empty : String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value));

                var statementPos0 = symbolicExpressionTree.IterateNodesPrefix().ToList().IndexOf(statement);
                if (String.IsNullOrEmpty(variableSettings))
                {
                    variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantics.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes());
                }

                var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                #endregion

                var weights = allowedSymbols.Select(s => s.InitialFrequency).ToList();
#pragma warning disable 612, 618
                var seedSymbol = allowedSymbols.SelectRandom(weights, random);
#pragma warning restore 612, 618

                // replace the old node with the new node
                var seedNode = seedSymbol.CreateTreeNode();
                if (seedNode.HasLocalParameters)
                {
                    seedNode.ResetLocalParameters(random);
                }

                parent.RemoveSubtree(childIndex);
                parent.InsertSubtree(childIndex, seedNode);
                ProbabilisticTreeCreator.PTC2(random, seedNode, maxLength, maxDepth);

                JObject jsonReplaced;
                if (child == statement)
                {
                    // child is executable, so is the new child
                    jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(seedNode, pythonProcess, random, problemData, variables, variableSettings, timeout);
                }
                else
                {
                    jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, pythonProcess, random, problemData, variables, variableSettings, timeout);
                }
                if (JToken.EqualityComparer.Equals(jsonOriginal, jsonReplaced))
                {
                    SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Equvivalent);
                }
                else
                {
                    SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(Different);
                }

                MutationTypeParameter.ActualValue = new IntValue(RandomMutation);
            }
            else
            {
                SemanticallyEquivalentMutationParameter.ActualValue = new IntValue(NoMutation);
                MutationTypeParameter.ActualValue = new IntValue(NoMutation);
            }
        }