/// <summary> /// Метод выделения дубликатов подвыражений. /// Если выражение - дубликат, флаг mustBePrecalculated будет установлен в значение true. /// Флаг устанавливается для ВСЕХ подвыражений, включая первое. /// </summary> /// <param name="expressions">Список подвыражений</param> /// <param name="variablesStorage">Хранилище переменных</param> public static void markDuplicates(List <Subexpression> expressions, VariablesStorage variablesStorage) { List <Subexpression> deduplicatedExpressions = new List <Subexpression>(); foreach (Subexpression exp in expressions) { bool duplicateFound = false; foreach (Subexpression dde in deduplicatedExpressions) { if (exp.Equals(dde)) { dde.mustBePrecalculated = true; exp.mustBePrecalculated = true; duplicateFound = true; //No need to break: we should add all same expressions with different levels } } if (!duplicateFound) { deduplicatedExpressions.Add(exp); } } //Checking semantic and filtering duplicates: if variable already reassigned, we should NOT add subexpression into duplicates foreach (Subexpression exp in expressions) { if (exp.mustBePrecalculated == true) { List <AbstractViewVariable> abstractVariables = LexicalAnalysisService.getVariablesBySubexpression(exp, variablesStorage); foreach (AbstractViewVariable av in abstractVariables) { if (av.firstReassignmentLevel != -1 && av.firstReassignmentLevel < exp.expressionLevel) { exp.mustBePrecalculated = false; break; } } } } }
private void button_process_Click(object sender, EventArgs e) { var watch = Stopwatch.StartNew(); loggingService = new LoggingService(richTextBox_log); loggingService.noLogMode = checkBox_measureExecutionTime.Checked; clearWorkplace(); //Init int and fuzzy variables VariablesStorage variablesStorage = InitVariablesService.initVariables(dataGridView_intVariables.Rows, dataGridView_intVariables.NewRowIndex, loggingService); //Select fuzzy variables by their names FuzzyVariableSelectionResult selectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!selectionResult.isSuccess) { loggingService.logFuzzySelectionError(selectionResult); return; } //Copy int and fuzzy variables into holder variablesStorage_holder.intVariables.AddRange(variablesStorage.intVariables); variablesStorage_holder.fuzzyVariables.AddRange(variablesStorage.fuzzyVariables); //Init expressions expressionsStorage.AddRange( InitExpressionsService.initExpressions(dataGridView_expressions.Rows, dataGridView_expressions.NewRowIndex, loggingService) ); foreach (Expression expression in expressionsStorage) { //Checking IF expression List <Lexeme> ifParserResult = ParserService.parseIfExpression(expression.ifExpressionText); loggingService.logIfParser(expression.ifExpressionText, ifParserResult); //Checking parser result on fuzzy values existence FuzzyVariableSelectionResult ifSelectionResult = fuzzyVariableService.makeSelection(ifParserResult); if (!ifSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(ifSelectionResult); return; } //Checking semantic LexicalAnalysisResult semanticResult = LexicalAnalysisService.makeSemanticAnalysis(ifParserResult, variablesStorage); loggingService.logLexicalAnalysis(semanticResult); //Next steps are available only if semantic analysis is correct if (!semanticResult.isCorrect) { return; } //Sorting by reverse polish notation List <Lexeme> reversePolishNotationLexemeList = ReversePolishNotationService.createNotation(ifParserResult); loggingService.logReversePolishNotation(reversePolishNotationLexemeList); //Creating subexpressions List <Subexpression> currentSubexpressions = subexpressionService.createSubexpressionsList(reversePolishNotationLexemeList, expression.expressionLevel); loggingService.logSubexpressions(currentSubexpressions); subexpressions.AddRange(currentSubexpressions); //Checking THEN expression List <Lexeme> thenParserResult = ParserService.parseThenOrElseExpression(expression.thenExpressionText); loggingService.logThenOrElseParser(expression.thenExpressionText, thenParserResult, true); //Variable assignment //We should assign variables now to correctly mark duplicates //We have no idea now whether THEN or ELSE expression will be executed LexicalAnalysisService.assignVariables(thenParserResult, variablesStorage, expression.expressionLevel); loggingService.logAssignedVariables(variablesStorage, true); //Select fuzzy variables by their names FuzzyVariableSelectionResult thenSelectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!thenSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(thenSelectionResult); return; } //Checking ELSE expression List <Lexeme> elseParserResult = ParserService.parseThenOrElseExpression(expression.elseExpressionText); loggingService.logThenOrElseParser(expression.elseExpressionText, elseParserResult, false); LexicalAnalysisService.assignVariables(elseParserResult, variablesStorage, expression.expressionLevel); loggingService.logAssignedVariables(variablesStorage, true); //Select fuzzy variables by their names FuzzyVariableSelectionResult elseSelectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!elseSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(elseSelectionResult); return; } } //Marking duplicates DuplicateExpressionService.markDuplicates(subexpressions, variablesStorage); loggingService.logDuplicates(subexpressions); if (!checkBox_disableBoosters.Checked) { //Precalculating duplicates subexpressionService.calculateDuplicates(subexpressions, variablesStorage, !checkBox_disableBoosters.Checked); loggingService.logDuplicatesValues(subexpressions); } //Restore int variables storage to init state variablesStorage.Clear(); variablesStorage.intVariables.AddRange(variablesStorage_holder.intVariables); variablesStorage.fuzzyVariables.AddRange(variablesStorage_holder.fuzzyVariables); //Calculating major subexpressions one by one //TODO: check level and compare it with local counter to avoid wrong order foreach (Subexpression subexpression in subexpressions) { if (subexpression.major) { //Calculate subexpression subexpression.value = subexpressionService.calculateSubexpressionValue(subexpression, variablesStorage, !checkBox_disableBoosters.Checked); //Prepare int variables storage to next iteration List <Lexeme> parserResult; if (subexpression.value.Value) { parserResult = ParserService.parseThenOrElseExpression(expressionsStorage[subexpression.expressionLevel - 1].thenExpressionText); } else { parserResult = ParserService.parseThenOrElseExpression(expressionsStorage[subexpression.expressionLevel - 1].elseExpressionText); } LexicalAnalysisService.assignVariables(parserResult, variablesStorage, subexpression.expressionLevel); //Select fuzzy variables by their names FuzzyVariableSelectionResult sfvSelectionResult = fuzzyVariableService.makeSelection(variablesStorage); if (!sfvSelectionResult.isSuccess) { loggingService.logFuzzySelectionError(sfvSelectionResult); return; } } } loggingService.logString("------========РЕЗУЛЬТАТЫ:========---------\n"); loggingService.logSubexpressions(subexpressions); loggingService.noLogMode = false; loggingService.logAssignedVariables(variablesStorage, false); watch.Stop(); if (checkBox_measureExecutionTime.Checked) { loggingService.logExecutionTime(watch.ElapsedMilliseconds); } }