public override IOperation Apply() { ItemArray <BoolArray> cases = CasesParameter.ActualValue; ItemArray <DoubleArray> caseQualities = CaseQualitiesParameter.ActualValue; int length = cases.First().Length; if (cases.Any(x => x.Length != length) || caseQualities.Any(x => x.Length != length)) { throw new ArgumentException("Every individual has to have the same number of cases."); } double count = cases.Count(); int rows = cases.First().Length; ResultCollection results = ResultsParameter.ActualValue; DataTable casesSolvedFrequencies = CasesSolvedFrequenciesParameter.ActualValue; DataTable summedCaseQualities = SummedCaseQualitiesParameter.ActualValue; if (casesSolvedFrequencies == null || summedCaseQualities == null) { casesSolvedFrequencies = new DataTable("Cases solved", "Absolute frequency of cases solved aggregated over the whole population."); casesSolvedFrequencies.VisualProperties.YAxisTitle = "Absolute Cases Solved Frequency"; summedCaseQualities = new DataTable("Summed case qualities", "Absolute frequency of cases solved aggregated over the whole population."); summedCaseQualities.VisualProperties.YAxisTitle = "Summed Cases Qualities"; CasesSolvedFrequenciesParameter.ActualValue = casesSolvedFrequencies; SummedCaseQualitiesParameter.ActualValue = summedCaseQualities; results.Add(new Result("Cases solved", casesSolvedFrequencies)); results.Add(new Result("Summed cases qualities", summedCaseQualities)); } // all rows must have the same number of values so we can just take the first int numberOfValues = casesSolvedFrequencies.Rows.Select(r => r.Values.Count).DefaultIfEmpty().First(); foreach (var triple in Enumerable.Range(0, cases[0].Length).Select(i => new Tuple <string, int, double>("Case " + i, cases.Count(caseArray => caseArray[i]), caseQualities.Sum(casesQualityArray => casesQualityArray[i])))) { if (!casesSolvedFrequencies.Rows.ContainsKey(triple.Item1)) { // initialize a new row for the symbol and pad with zeros DataRow row = new DataRow(triple.Item1, "", Enumerable.Repeat(0.0, numberOfValues)); row.VisualProperties.StartIndexZero = true; casesSolvedFrequencies.Rows.Add(row); row = new DataRow(triple.Item1, "", Enumerable.Repeat(0.0, numberOfValues)); row.VisualProperties.StartIndexZero = true; summedCaseQualities.Rows.Add(row); } casesSolvedFrequencies.Rows[triple.Item1].Values.Add(triple.Item2); summedCaseQualities.Rows[triple.Item1].Values.Add(triple.Item3); } return(base.Apply()); }
private JObject GenerateOriginalJson(CutPoint crossoverPoint0, IEnumerable <string> statementProductionNames, ISymbolicExpressionTree parent0, string variableSettings, ItemArray <PythonStatementSemantic> semantic0, ICFGPythonProblemData problemData, IRandom random, List <string> variables) { ISymbolicExpressionTreeNode statementOriginal = SemanticOperatorHelper.GetStatementNode(crossoverPoint0.Child, statementProductionNames); // statementOriginal is not always the same as statement var statementPos0 = parent0.IterateNodesPrefix().ToList().IndexOf(statementOriginal); if (String.IsNullOrEmpty(variableSettings)) { var curSemantics = semantic0.First(x => x.TreeNodePrefixPos == statementPos0); variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(curSemantics.Before, problemData.Variables.GetVariableTypes()); } return(SemanticOperatorHelper.EvaluateStatementNode(statementOriginal, PyProcess, random, problemData, variables, variableSettings, Timeout)); }
/// <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); } }
protected virtual ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, ItemArray <PythonStatementSemantic> semantic0, ItemArray <PythonStatementSemantic> semantic1, ICFGPythonProblemData problemData, int maxTreeLength, int maxTreeDepth, double internalCrossoverPointProbability, out ItemArray <PythonStatementSemantic> newSemantics) { if (semantic0 == null || semantic1 == null || semantic0.Length == 0 || semantic1.Length == 0) { parent0 = SubtreeCrossover.Cross(random, parent0, parent1, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth); newSemantics = null; return(parent0); } newSemantics = semantic0; // select a random crossover point in the first parent CutPoint crossoverPoint0; SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth, out crossoverPoint0); int childLength = crossoverPoint0.Child != null?crossoverPoint0.Child.GetLength() : 0; // calculate the max length and depth that the inserted branch can have int maxInsertedBranchLength = maxTreeLength - (parent0.Length - childLength); int maxInsertedBranchDepth = maxTreeDepth - parent0.Root.GetBranchLevel(crossoverPoint0.Child); List <ISymbolicExpressionTreeNode> allowedBranches = new List <ISymbolicExpressionTreeNode>(); parent1.Root.ForEachNodePostfix((n) => { if (n.GetLength() <= maxInsertedBranchLength && n.GetDepth() <= maxInsertedBranchDepth && crossoverPoint0.IsMatchingPointType(n)) { allowedBranches.Add(n); } }); // empty branch if (crossoverPoint0.IsMatchingPointType(null)) { allowedBranches.Add(null); } if (allowedBranches.Count == 0) { return(parent0); } // select MaxCompares random crossover points // Use set to avoid having the same node multiple times HashSet <ISymbolicExpressionTreeNode> compBranches; if (allowedBranches.Count < MaxComparesParameter.Value.Value) { compBranches = new HashSet <ISymbolicExpressionTreeNode>(allowedBranches); } else { compBranches = new HashSet <ISymbolicExpressionTreeNode>(); for (int i = 0; i < MaxComparesParameter.Value.Value; i++) { var possibleBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability); allowedBranches.Remove(possibleBranch); compBranches.Add(possibleBranch); } } var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(crossoverPoint0.Parent.Grammar); // find first node that can be used for evaluation in parent0 ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(crossoverPoint0.Child, statementProductionNames); if (statement == null) { newSemantics = SemanticSwap(crossoverPoint0, compBranches.SampleRandom(random), parent0, parent1, semantic0, semantic1); return(parent0); } var statementPos0 = parent0.IterateNodesPrefix().ToList().IndexOf(statement); string variableSettings; if (problemData.VariableSettings.Count == 0) { variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantic0.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes()); } else { variableSettings = String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value)); } var variables = problemData.Variables.GetVariableNames().ToList(); var json0 = SemanticOperatorHelper.EvaluateStatementNode(statement, PyProcess, random, problemData, variables, variableSettings, Timeout); ISymbolicExpressionTreeNode selectedBranch; if (!String.IsNullOrWhiteSpace((string)json0["exception"])) { selectedBranch = compBranches.SampleRandom(random); } else { selectedBranch = SelectBranch(statement, crossoverPoint0, compBranches, random, variables, variableSettings, json0, problemData); } // perform the actual swap newSemantics = SemanticSwap(crossoverPoint0, selectedBranch, parent0, parent1, semantic0, semantic1); return(parent0); }
protected void AddStatistics(ItemArray <PythonStatementSemantic> semantic0, ISymbolicExpressionTree child) { if (NumberOfPossibleBranchesSelectedParameter.ActualValue == null) { NumberOfPossibleBranchesSelected = 0; } if (NumberOfAllowedBranchesParameter.ActualValue == null) { NumberOfAllowedBranches = 0; } if (NumberOfNoChangeDetectedParameter.ActualValue == null) { NumberOfNoChangeDetected = 0; } if (NumberOfCrossoverTriesParameter.ActualValue == null) { NumberOfCrossoverTries = 0; } if (TypeSelectedForSimilarityParameter.ActualValue == null) { TypeSelectedForSimilarityParameter.ActualValue = new StringValue("Random crossover"); } var parentQualities = QualityParameter.ActualValue; double parent0Quality = parentQualities[0].Value; double parent1Quality = parentQualities[1].Value; var pythonSemanticHelper = new PythonProcessSemanticHelper(ProblemData.Variables.GetVariableNames(), 1000); // hardcoded value!!! // TODO: object created for every crossover var childResults = pythonSemanticHelper.EvaluateAndTraceProgram(PythonProcessParameter.ActualValue, PythonHelper.FormatToProgram(child, ProblemData.LoopBreakConst, ProblemData.FullHeader, ProblemData.FullFooter), PythonHelper.ConvertToPythonValues(ProblemData.Input, ProblemData.TrainingIndices), PythonHelper.ConvertToPythonValues(ProblemData.Output, ProblemData.TrainingIndices), ProblemData.TrainingIndices, ProblemData.FullHeader, ProblemData.FullFooter, child, Timeout); var childQuality = childResults.Item3; SemanticLocalityParameter.ActualValue = new DoubleValue(Math.Abs(parent0Quality - childQuality)); ConstructiveEffectParameter.ActualValue = new IntValue(childQuality < parent0Quality ? childQuality < parent1Quality ? 2 : 1 : 0); if (!String.IsNullOrEmpty(childResults.Item4)) { SemanticallyDifferentFromRootedParentParameter.ActualValue = new BoolValue(true); return; // no semantics is available, but the child is different because it failed, which is different from its parent } // first semantic statement is <predefined> which contains all code and therefore all changes to res* var parent0Semantic = semantic0.First(); var childSemantic = childResults.Item5.First(); // check all results var resKeys = parent0Semantic.After.Keys.Where(x => x.StartsWith("res")); SemanticallyDifferentFromRootedParentParameter.ActualValue = new BoolValue(false); foreach (var resKey in resKeys) { var parent0Res = parent0Semantic.After.Keys.Contains(resKey) ? parent0Semantic.After[resKey] : parent0Semantic.Before[resKey]; var child0Res = childSemantic.After.Keys.Contains(resKey) ? childSemantic.After[resKey] : childSemantic.Before[resKey]; var enumParent = parent0Res.GetEnumerator(); var enumChild = child0Res.GetEnumerator(); var type = ProblemData.Variables.GetTypesOfVariables().First(x => x.Value.Contains(resKey)).Key; if (type.IsListType()) { // always move forward both enumerators (do not use short-circuit evaluation!) while (enumParent.MoveNext() & enumChild.MoveNext()) { if (!JToken.EqualityComparer.Equals((JArray)enumParent.Current, (JArray)enumChild.Current)) { SemanticallyDifferentFromRootedParentParameter.ActualValue.Value = true; break; } } if (enumParent.MoveNext() || enumChild.MoveNext()) { SemanticallyDifferentFromRootedParentParameter.ActualValue.Value = true; } } else { // always move forward both enumerators (do not use short-circuit evaluation!) while (enumParent.MoveNext() & enumChild.MoveNext()) { if (!enumParent.Current.Equals(enumChild.Current)) { SemanticallyDifferentFromRootedParentParameter.ActualValue.Value = true; break; } } if (enumParent.MoveNext() || enumChild.MoveNext()) { SemanticallyDifferentFromRootedParentParameter.ActualValue.Value = true; } } // break if a change has already been found if (SemanticallyDifferentFromRootedParentParameter.ActualValue.Value) { break; } } }
protected override ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, ItemArray <PythonStatementSemantic> semantic0, ItemArray <PythonStatementSemantic> semantic1, T problemData, int maxTreeLength, int maxTreeDepth, double internalCrossoverPointProbability, out ItemArray <PythonStatementSemantic> newSemantics) { if (semantic0 == null || semantic1 == null || semantic0.Length == 0 || semantic1.Length == 0) { parent0 = SubtreeCrossover.Cross(random, parent0, parent1, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth); newSemantics = null; AddStatisticsNoCrossover(NoXoNoSemantics); return(parent0); } newSemantics = semantic0; // select andom crossover points in the first parent var crossoverPoints0 = SelectCrossoverPointsOfMatchingType(random, parent0, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth, NumberOfCutPointsFirst); var primaryCrossoverPoint = crossoverPoints0.First(); int childLength = primaryCrossoverPoint.Child != null?primaryCrossoverPoint.Child.GetLength() : 0; // calculate the max length and depth that the inserted branch can have int maxInsertedBranchLength = maxTreeLength - (parent0.Length - childLength); int maxInsertedBranchDepth = maxTreeDepth - parent0.Root.GetBranchLevel(primaryCrossoverPoint.Child); List <ISymbolicExpressionTreeNode> allowedBranches = new List <ISymbolicExpressionTreeNode>(); parent1.Root.ForEachNodePostfix((n) => { if (n.GetLength() <= maxInsertedBranchLength && n.GetDepth() <= maxInsertedBranchDepth && primaryCrossoverPoint.IsMatchingPointType(n)) { allowedBranches.Add(n); } }); // empty branch if (primaryCrossoverPoint.IsMatchingPointType(null)) { allowedBranches.Add(null); } // set NumberOfAllowedBranches NumberOfAllowedBranches = allowedBranches.Count; if (allowedBranches.Count == 0) { AddStatisticsNoCrossover(NoXoNoAllowedBranch); return(parent0); } // select NumberOfCutPointsSecond random crossover points // Ignore internalCrossoverPointProbability, was already used to select cutpoint and the cutpoint child already reduces possibilities var compBranches = allowedBranches.SampleRandomWithoutRepetition(random, NumberOfCutPointsSecond).ToList(); // convert to list so that the linq expression is only executed once, to always get the same branches var allowedBranchesPerCutpoint = new List <IEnumerable <ISymbolicExpressionTreeNode> >() { compBranches }; allowedBranchesPerCutpoint.AddRange(crossoverPoints0.Skip(1).Select(x => FindFittingNodes(x, parent0, compBranches, maxTreeLength, maxTreeDepth))); // set NumberOfPossibleBranchesSelected NumberOfPossibleBranchesSelected = compBranches.Count; var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(primaryCrossoverPoint.Parent.Grammar); // find first node that can be used for evaluation in parent0 ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(primaryCrossoverPoint.Child, statementProductionNames); if (statement == null) { newSemantics = SemanticSwap(primaryCrossoverPoint, compBranches.SampleRandom(random), parent0, parent1, semantic0, semantic1); AddStatisticsNoCrossover(NoXoNoStatement); return(parent0); } var statementPos0 = parent0.IterateNodesPrefix().ToList().IndexOf(statement); string variableSettings; if (problemData.VariableSettings.Count == 0) { variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(semantic0.First(x => x.TreeNodePrefixPos == statementPos0).Before, problemData.Variables.GetVariableTypes()); } else { variableSettings = String.Join(Environment.NewLine, problemData.VariableSettings.Select(x => x.Value)); } var variables = problemData.Variables.GetVariableNames().ToList(); // only used for analyzation, otherwise could be removed var json0 = SemanticOperatorHelper.EvaluateStatementNode(statement, PyProcess, random, problemData, variables, variableSettings, Timeout); ISymbolicExpressionTreeNode selectedBranch; CutPoint selectedCutPoint; if (statement == primaryCrossoverPoint.Child) { SelectBranchFromExecutableNodes(crossoverPoints0.ToList(), allowedBranchesPerCutpoint, random, variables, variableSettings, problemData, out selectedBranch, out selectedCutPoint); } else { //SelectBranchFromNodes1(statement, crossoverPoints0.ToList(), allowedBranchesPerCutpoint, random, variables, variableSettings, problemData, out selectedBranch, out selectedCutPoint); SelectBranchFromNodes2(statementProductionNames, crossoverPoints0.ToList(), allowedBranchesPerCutpoint, random, variables, variableSettings, problemData, out selectedBranch, out selectedCutPoint); } // perform the actual swap if (selectedBranch != null) { newSemantics = SemanticSwap(selectedCutPoint, selectedBranch, parent0, parent1, semantic0, semantic1); AddStatistics(semantic0, parent0, statement == primaryCrossoverPoint.Child ? selectedBranch : statement, selectedCutPoint, json0, selectedBranch, random, problemData, variables, variableSettings); // parent zero has been changed is now considered the child } else { AddStatisticsNoCrossover(NoXoNoSelectedBranch); } return(parent0); }
protected override ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, ItemArray <PythonStatementSemantic> semantic0, ItemArray <PythonStatementSemantic> semantic1, T problemData, int maxTreeLength, int maxTreeDepth, double internalCrossoverPointProbability, out ItemArray <PythonStatementSemantic> newSemantics) { if (semantic0 == null || semantic1 == null || semantic0.Length == 0 || semantic1.Length == 0) { parent0 = SubtreeCrossover.Cross(random, parent0, parent1, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth); newSemantics = null; TypeSelectedForSimilarityParameter.ActualValue = new StringValue("No Semantics; Random Crossover"); AddStatisticsNoCrossover(NoXoNoSemantics); return(parent0); } newSemantics = semantic0; var statementProductionNames = SemanticOperatorHelper.GetSemanticProductionNames(parent0.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)); int maximumSemanticTries = MaxComparesParameter.Value.Value; int semanticTries = 0; var saveOriginalSemantics = new List <JObject>(maximumSemanticTries); var saveReplaceSemantics = new List <JObject>(maximumSemanticTries); var possibleChildren = new List <Tuple <CutPoint, ISymbolicExpressionTreeNode> >(maximumSemanticTries); bool success = false; do { // select a random crossover point in the first parent CutPoint crossoverPoint0; SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth, out crossoverPoint0); int childLength = crossoverPoint0.Child != null?crossoverPoint0.Child.GetLength() : 0; // calculate the max length and depth that the inserted branch can have int maxInsertedBranchLength = Math.Max(0, maxTreeLength - (parent0.Length - childLength)); int maxInsertedBranchDepth = Math.Max(0, maxTreeDepth - parent0.Root.GetBranchLevel(crossoverPoint0.Parent)); List <ISymbolicExpressionTreeNode> allowedBranches = new List <ISymbolicExpressionTreeNode>(); parent1.Root.ForEachNodePostfix((n) => { if (n.GetLength() <= maxInsertedBranchLength && n.GetDepth() <= maxInsertedBranchDepth && crossoverPoint0.IsMatchingPointType(n)) { allowedBranches.Add(n); } }); // empty branch if (crossoverPoint0.IsMatchingPointType(null)) { allowedBranches.Add(null); } if (allowedBranches.Count != 0) { var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability); ISymbolicExpressionTreeNode statement = SemanticOperatorHelper.GetStatementNode(crossoverPoint0.Child, statementProductionNames); var statementPos0 = parent0.IterateNodesPrefix().ToList().IndexOf(statement); PythonStatementSemantic curSemantics = null; if (String.IsNullOrEmpty(variableSettings)) { curSemantics = semantic0.First(x => x.TreeNodePrefixPos == statementPos0); variableSettings = SemanticOperatorHelper.SemanticToPythonVariableSettings(curSemantics.Before, problemData.Variables.GetVariableTypes()); } var jsonOriginal = SemanticOperatorHelper.EvaluateStatementNode(statement, PyProcess, random, problemData, variables, variableSettings, Timeout); JObject jsonReplaced; if (statement == crossoverPoint0.Child) { // selectedBranch is also executable jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(selectedBranch, PyProcess, random, problemData, variables, variableSettings, Timeout); } else { crossoverPoint0.Parent.RemoveSubtree(crossoverPoint0.ChildIndex); var parent = selectedBranch.Parent; // save parent crossoverPoint0.Parent.InsertSubtree(crossoverPoint0.ChildIndex, selectedBranch); // this will affect node.Parent jsonReplaced = SemanticOperatorHelper.EvaluateStatementNode(statement, PyProcess, random, problemData, variables, variableSettings, Timeout); crossoverPoint0.Parent.RemoveSubtree(crossoverPoint0.ChildIndex); // removes intermediate parent from node selectedBranch.Parent = parent; // restore parent crossoverPoint0.Parent.InsertSubtree(crossoverPoint0.ChildIndex, crossoverPoint0.Child); // restore cutPoint } var exception = jsonOriginal["exception"] != null || jsonReplaced["exception"] != null; if (exception) { if (jsonOriginal["exception"] != null) { CrossoverExceptionsParameter.ActualValue.Add(new StringValue(jsonOriginal["exception"].ToString())); } if (jsonReplaced["exception"] != null) { CrossoverExceptionsParameter.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)) { newSemantics = SemanticSwap(crossoverPoint0, selectedBranch, parent0, parent1, semantic0, semantic1); SemanticallyEquivalentCrossoverParameter.ActualValue = new IntValue(2); TypeSelectedForSimilarityParameter.ActualValue = new StringValue("First Semantic"); AddStatistics(semantic0, parent0, statement == crossoverPoint0.Child ? selectedBranch : statement, crossoverPoint0, jsonOriginal, selectedBranch, random, problemData, variables, variableSettings); // parent zero has been changed is now considered the child success = true; } else { saveOriginalSemantics.Add(jsonOriginal); saveReplaceSemantics.Add(jsonReplaced); possibleChildren.Add(new Tuple <CutPoint, ISymbolicExpressionTreeNode>(crossoverPoint0, selectedBranch)); } } semanticTries++; #region try second semantic comparison if (!success && semanticTries >= maximumSemanticTries) { for (int index = 0; index < saveOriginalSemantics.Count; index++) { var exception = saveOriginalSemantics[index]["exception"] == null && saveReplaceSemantics[index]["exception"] == null; if (!exception && AdditionalSemanticMeasure(saveOriginalSemantics[index], saveReplaceSemantics[index])) { var crossover = possibleChildren[index]; crossoverPoint0 = crossover.Item1; // Recreate jsonOriginal as it might have changed due to ReplaceNotExecutedCases and ProduceDifference var jsonOriginal = GenerateOriginalJson(crossoverPoint0, statementProductionNames, parent0, variableSettings, semantic0, problemData, random, variables); newSemantics = SemanticSwap(crossoverPoint0, crossover.Item2, parent0, parent1, semantic0, semantic1); var statement = SemanticOperatorHelper.GetStatementNode(crossover.Item2, statementProductionNames); SemanticallyEquivalentCrossoverParameter.ActualValue = new IntValue(2); TypeSelectedForSimilarityParameter.ActualValue = new StringValue("Second Semantic"); AddStatistics(semantic0, parent0, statement, crossoverPoint0, jsonOriginal, crossover.Item2, random, problemData, variables, variableSettings); // parent zero has been changed is now considered the child success = true; break; } } } #endregion } while (!success && semanticTries < maximumSemanticTries); if (!success) { // Last change. If any possible crossover was found, do a crossover with the first one if (saveOriginalSemantics.Any()) { var crossover = possibleChildren.First(); var crossoverPoint0 = crossover.Item1; // Recreate jsonOriginal as it might have changed due to ReplaceNotExecutedCases and ProduceDifference var jsonOriginal = GenerateOriginalJson(crossoverPoint0, statementProductionNames, parent0, variableSettings, semantic0, problemData, random, variables); newSemantics = SemanticSwap(crossoverPoint0, crossover.Item2, parent0, parent1, semantic0, semantic1); var statement = SemanticOperatorHelper.GetStatementNode(crossover.Item2, statementProductionNames); TypeSelectedForSimilarityParameter.ActualValue = new StringValue("Random Crossover; Reached Max Semantic Tries"); AddStatistics(semantic0, parent0, statement, crossoverPoint0, jsonOriginal, crossover.Item2, random, problemData, variables, variableSettings); // parent zero has been changed is now considered the child } else { AddStatisticsNoCrossover(NoXoNoAllowedBranch); } } saveOriginalSemantics.Clear(); saveReplaceSemantics.Clear(); possibleChildren.Clear(); NumberOfCrossoverTries = semanticTries; return(parent0); }
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); } }