static private void BuildLexemsList <VariableType, ValueType>(VariableType var, bool input, Dictionary <string, Lexem> lexems) where VariableType : class, INamedVariable where ValueType : class, INamedValue { VarLexem <VariableType> varLexem = new VarLexem <VariableType>(var, input); lexems.Add(varLexem.Text, varLexem); foreach (ValueType term in var.Values) { TermLexem <ValueType> termLexem = new TermLexem <ValueType>(term, input); Lexem foundLexem = null; if (!lexems.TryGetValue(termLexem.Text, out foundLexem)) { // // There are no lexems with the same text. Just insert new lexem. // lexems.Add(termLexem.Text, termLexem); } else { if (foundLexem is IAltLexem) { // // There can be more than one terms with the same name. // TODO: But only if they belong to defferent variables. // IAltLexem foundTermLexem = (IAltLexem)foundLexem; while (foundTermLexem.Alternative != null) { foundTermLexem = foundTermLexem.Alternative; } foundTermLexem.Alternative = termLexem; } else { // // Only terms of different vatiables can have the same name // throw new System.Exception(string.Format("Found more than one lexems with the same name: {0}", termLexem.Text)); } } } }
static private void BuildLexemsList <VariableType, ValueType>(VariableType var, bool input, Dictionary <string, Lexem> lexems) where VariableType : class, INamedVariable where ValueType : class, INamedValue { VarLexem <VariableType> varLexem = new VarLexem <VariableType>(var, input); lexems.Add(varLexem.Text, varLexem); foreach (ValueType term in var.Values) { TermLexem <ValueType> termLexem = new TermLexem <ValueType>(term, input); Lexem foundLexem = null; if (!lexems.TryGetValue(termLexem.Text, out foundLexem)) { // // Нет лексем с похожим текстом. Только добавление новых лексем // lexems.Add(termLexem.Text, termLexem); } else { if (foundLexem is IAltLexem) { // // Там может быть более одного условия с тем же именем. // TODO: Но только если они принадлежат к разным переменных. // IAltLexem foundTermLexem = (IAltLexem)foundLexem; while (foundTermLexem.Alternative != null) { foundTermLexem = foundTermLexem.Alternative; } foundTermLexem.Alternative = termLexem; } else { // // Только термы различных переменных могут иметь похожие имена // throw new System.Exception(string.Format("Найден более чем одна лексема с похожим именем: {0}", termLexem.Text)); } } } }
static private SingleCondition <VariableType, ValueType> ParseConclusion <VariableType, ValueType>(List <IExpression> conditionExpression, List <VariableType> output, Dictionary <string, Lexem> lexems) where VariableType : class, INamedVariable where ValueType : class, INamedValue { List <IExpression> copyExpression = conditionExpression.GetRange(0, conditionExpression.Count); // // Remove extra brackets // while ( copyExpression.Count >= 2 && (copyExpression[0] == lexems["("] && copyExpression[conditionExpression.Count - 1] == lexems[")"])) { copyExpression = copyExpression.GetRange(1, copyExpression.Count - 2); } if (copyExpression.Count != 3) { throw new Exception("Conclusion part of the rule should be in form: 'variable is term'"); } // // Parse variable // Lexem exprVariable = (Lexem)copyExpression[0]; if (!(exprVariable is VarLexem <VariableType>)) { throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprVariable.Text)); } VarLexem <VariableType> varLexem = (VarLexem <VariableType>)exprVariable; if (varLexem.Input == true) { throw new Exception("The variable in conclusion part must be an output variable."); } // // Parse 'is' lexem // Lexem exprIs = (Lexem)copyExpression[1]; if (exprIs != lexems["is"]) { throw new Exception(string.Format("'is' keyword must go after {0} identifier.", varLexem.Text)); } // // Parse term // Lexem exprTerm = (Lexem)copyExpression[2]; if (!(exprTerm is IAltLexem)) { throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprTerm.Text)); } IAltLexem altLexem = (IAltLexem)exprTerm; TermLexem <ValueType> termLexem = null; do { if (!(altLexem is TermLexem <ValueType>)) { continue; } termLexem = (TermLexem <ValueType>)altLexem; if (!varLexem.Var.Values.Contains(termLexem.Term)) { termLexem = null; continue; } }while ((altLexem = altLexem.Alternative) != null && termLexem == null); if (termLexem == null) { throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprTerm.Text)); } // // Return fuzzy rule's conclusion // return(new SingleCondition <VariableType, ValueType>(varLexem.Var, termLexem.Term, false)); }
static private List <IExpression> ExtractSingleCondidtions(List <IExpression> conditionExpression, List <FuzzyVariable> input, Dictionary <string, Lexem> lexems) { List <IExpression> copyExpressions = conditionExpression.GetRange(0, conditionExpression.Count); List <IExpression> expressions = new List <IExpression>(); while (copyExpressions.Count > 0) { if (copyExpressions[0] is VarLexem <FuzzyVariable> ) { // // Parse variable // VarLexem <FuzzyVariable> varLexem = (VarLexem <FuzzyVariable>)copyExpressions[0]; if (copyExpressions.Count < 3) { throw new Exception(string.Format("Condition strated with '{0}' is incorrect.", varLexem.Text)); } if (varLexem.Input == false) { throw new Exception("The variable in condition part must be an input variable."); } // // Parse 'is' lexem // Lexem exprIs = (Lexem)copyExpressions[1]; if (exprIs != lexems["is"]) { throw new Exception(string.Format("'is' keyword must go after {0} identifier.", varLexem.Text)); } // // Parse 'not' lexem (if exists) // int cur = 2; bool not = false; if (copyExpressions[cur] == lexems["not"]) { not = true; cur++; if (copyExpressions.Count <= cur) { throw new Exception("Error at 'not' in condition part of the rule."); } } //"slightly" //"somewhat" //"very" //"extremely" // // Parse hedge modifier (if exists) // HedgeType hedge = HedgeType.None; if (copyExpressions[cur] == lexems["slightly"]) { hedge = HedgeType.Slightly; } else if (copyExpressions[cur] == lexems["somewhat"]) { hedge = HedgeType.Somewhat; } else if (copyExpressions[cur] == lexems["very"]) { hedge = HedgeType.Very; } else if (copyExpressions[cur] == lexems["extremely"]) { hedge = HedgeType.Extremely; } if (hedge != HedgeType.None) { cur++; if (copyExpressions.Count <= cur) { throw new Exception(string.Format("Error at '{0}' in condition part of the rule.", hedge.ToString().ToLower())); } } // // Parse term // Lexem exprTerm = (Lexem)copyExpressions[cur]; if (!(exprTerm is IAltLexem)) { throw new Exception(string.Format("Wrong identifier '{0}' in conditional part of the rule.", exprTerm.Text)); } IAltLexem altLexem = (IAltLexem)exprTerm; TermLexem <FuzzyTerm> termLexem = null; do { if (!(altLexem is TermLexem <FuzzyTerm>)) { continue; } termLexem = (TermLexem <FuzzyTerm>)altLexem; if (!varLexem.Var.Values.Contains(termLexem.Term)) { termLexem = null; continue; } }while ((altLexem = altLexem.Alternative) != null && termLexem == null); if (termLexem == null) { throw new Exception(string.Format("Wrong identifier '{0}' in conditional part of the rule.", exprTerm.Text)); } // // Add new condition expression // FuzzyCondition condition = new FuzzyCondition(varLexem.Var, termLexem.Term, not, hedge); expressions.Add(new ConditionExpression(copyExpressions.GetRange(0, cur + 1), condition)); copyExpressions.RemoveRange(0, cur + 1); } else { IExpression expr = copyExpressions[0]; if (expr == lexems["and"] || expr == lexems["or"] || expr == lexems["("] || expr == lexems[")"]) { expressions.Add(expr); copyExpressions.RemoveAt(0); } else { Lexem unknownLexem = (Lexem)expr; throw new Exception(string.Format("Lexem '{0}' found at the wrong place in condition part of the rule.", unknownLexem.Text)); } } } return(expressions); }
static private SingleCondition <VariableType, ValueType> ParseConclusion <VariableType, ValueType>(List <IExpression> conditionExpression, List <VariableType> output, Dictionary <string, Lexem> lexems) where VariableType : class, INamedVariable where ValueType : class, INamedValue { List <IExpression> copyExpression = conditionExpression.GetRange(0, conditionExpression.Count); // // Удаление лишних скобок // while ( copyExpression.Count >= 2 && (copyExpression[0] == lexems["("] && copyExpression[conditionExpression.Count - 1] == lexems[")"])) { copyExpression = copyExpression.GetRange(1, copyExpression.Count - 2); } if (copyExpression.Count != 3) { throw new Exception("Вывод часть правила должны быть в форме: 'переменная есть терм'"); } // // Разбор переменной // Lexem exprVariable = (Lexem)copyExpression[0]; if (!(exprVariable is VarLexem <VariableType>)) { throw new Exception(string.Format("Неверный идентификатор '{0}' в состоянии части правила.", exprVariable.Text)); } VarLexem <VariableType> varLexem = (VarLexem <VariableType>)exprVariable; if (varLexem.Input == true) { throw new Exception("Переменная в заключительной части должна быть выходной переменной."); } // // Разбор 'is' лексемы // Lexem exprIs = (Lexem)copyExpression[1]; if (exprIs != lexems["is"]) { throw new Exception(string.Format("'is' ключевое слово после {0} идентификатора.", varLexem.Text)); } // // Parse term // Lexem exprTerm = (Lexem)copyExpression[2]; if (!(exprTerm is IAltLexem)) { throw new Exception(string.Format("Неверный идентификатор '{0}' в заключительной части правила.", exprTerm.Text)); } IAltLexem altLexem = (IAltLexem)exprTerm; TermLexem <ValueType> termLexem = null; do { if (!(altLexem is TermLexem <ValueType>)) { continue; } termLexem = (TermLexem <ValueType>)altLexem; if (!varLexem.Var.Values.Contains(termLexem.Term)) { termLexem = null; continue; } }while ((altLexem = altLexem.Alternative) != null && termLexem == null); if (termLexem == null) { throw new Exception(string.Format("Неверный идентификатор '{0}' в заключительной части правила.", exprTerm.Text)); } // // Возвращение нечеткого правила заключения // return(new SingleCondition <VariableType, ValueType>(varLexem.Var, termLexem.Term, false)); }
static private List <IExpression> ExtractSingleCondidtions(List <IExpression> conditionExpression, List <FuzzyVariable> input, Dictionary <string, Lexem> lexems) { List <IExpression> copyExpressions = conditionExpression.GetRange(0, conditionExpression.Count); List <IExpression> expressions = new List <IExpression>(); while (copyExpressions.Count > 0) { if (copyExpressions[0] is VarLexem <FuzzyVariable> ) { // // Разбор переменной // VarLexem <FuzzyVariable> varLexem = (VarLexem <FuzzyVariable>)copyExpressions[0]; if (copyExpressions.Count < 3) { throw new Exception(string.Format("Состояние начинается с '{0}' не корректно.", varLexem.Text)); } if (varLexem.Input == false) { throw new Exception("Переменная в состоянии должна быть входной переменной."); } // // Разбор "is" лексемы // Lexem exprIs = (Lexem)copyExpressions[1]; if (exprIs != lexems["is"]) { throw new Exception(string.Format("'is' ключевое слово должно идти после {0} идентификатора.", varLexem.Text)); } // // Разбор 'not' лексемы (если существует) // int cur = 2; bool not = false; if (copyExpressions[cur] == lexems["not"]) { not = true; cur++; if (copyExpressions.Count <= cur) { throw new Exception("Ошибка около 'not' в состоянии части правила."); } } //"slightly" - немного //"somewhat" - в некотором роде //"very" - очень //"extremely" - чрезвычайно // // Разбор hedge модификатора (если существует) // HedgeType hedge = HedgeType.None; if (copyExpressions[cur] == lexems["slightly"]) { hedge = HedgeType.Slightly; } else if (copyExpressions[cur] == lexems["somewhat"]) { hedge = HedgeType.Somewhat; } else if (copyExpressions[cur] == lexems["very"]) { hedge = HedgeType.Very; } else if (copyExpressions[cur] == lexems["extremely"]) { hedge = HedgeType.Extremely; } if (hedge != HedgeType.None) { cur++; if (copyExpressions.Count <= cur) { throw new Exception(string.Format("Ошибка около '{0}' в состоянии части правила.", hedge.ToString().ToLower())); } } // // Разбор терма // Lexem exprTerm = (Lexem)copyExpressions[cur]; if (!(exprTerm is IAltLexem)) { throw new Exception(string.Format("Неверный идентификатор '{0}' в стостоянии части правила.", exprTerm.Text)); } IAltLexem altLexem = (IAltLexem)exprTerm; TermLexem <FuzzyTerm> termLexem = null; do { if (!(altLexem is TermLexem <FuzzyTerm>)) { continue; } termLexem = (TermLexem <FuzzyTerm>)altLexem; if (!varLexem.Var.Values.Contains(termLexem.Term)) { termLexem = null; continue; } }while ((altLexem = altLexem.Alternative) != null && termLexem == null); if (termLexem == null) { throw new Exception(string.Format("Неверный идентификатор '{0}' в стостоянии части правила.", exprTerm.Text)); } // // Добавление нового выражения состояния // FuzzyCondition condition = new FuzzyCondition(varLexem.Var, termLexem.Term, not, hedge); expressions.Add(new ConditionExpression(copyExpressions.GetRange(0, cur + 1), condition)); copyExpressions.RemoveRange(0, cur + 1); } else { IExpression expr = copyExpressions[0]; if (expr == lexems["and"] || expr == lexems["or"] || expr == lexems["("] || expr == lexems[")"]) { expressions.Add(expr); copyExpressions.RemoveAt(0); } else { Lexem unknownLexem = (Lexem)expr; throw new Exception(string.Format("Лексема '{0}' найдена в ошибочном месте в состоянии части правила.", unknownLexem.Text)); } } } return(expressions); }