⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ruleparser.cs

📁 在.net环境下用C#开发的模糊控制函数库
💻 CS
📖 第 1 页 / 共 2 页
字号:
        {
            //
            // Extract single conditions
            //
            List<IExpression> expressions = ExtractSingleCondidtions(conditionExpression, input, lexems);

            if (expressions.Count == 0)
            {
                throw new Exception("No valid conditions found in conditions part of the rule.");
            }

            ICondition cond = ParseConditionsRecurse(expressions, lexems);

            //
            // Return conditions
            //
            if (cond is Conditions)
            {
                return (Conditions)cond;
            }
            else
            {
                Conditions conditions = new Conditions();
                return conditions;
            }
        }

        static private int FindPairBracket(List<IExpression> expressions, Dictionary<string, Lexem> lexems)
        {
            //
            // Assume that '(' stands at first place
            //

            int bracketsOpened = 1;
            int closeBracket = -1;
            for (int i = 1; i < expressions.Count; i++)
            {
                if (expressions[i] == lexems["("])
                {
                    bracketsOpened++;
                }
                else if (expressions[i] == lexems[")"])
                {
                    bracketsOpened--;
                    if (bracketsOpened == 0)
                    {
                        closeBracket = i;
                        break;
                    }
                }
            }

            return closeBracket;
        }

        static private ICondition ParseConditionsRecurse(List<IExpression> expressions, Dictionary<string, Lexem> lexems)
        {
            if (expressions.Count < 1)
            {
                throw new Exception("Empty condition found.");
            }

            if (expressions[0] == lexems["("] && FindPairBracket(expressions, lexems) == expressions.Count)
            {
                //
                // Remove extra brackets
                //
                return ParseConditionsRecurse(expressions.GetRange(1, expressions.Count - 2), lexems);
            }
            else if (expressions.Count == 1 && expressions[0] is ConditionExpression)
            {
                //
                // Return single conditions
                //
                return ((ConditionExpression)expressions[0]).Condition;
            }
            else
            {
                //
                // Parse list of one level conditions connected by or/and
                //
                List<IExpression> copyExpressions = expressions.GetRange(0, expressions.Count);
                Conditions conds = new Conditions();
                bool setOrAnd = false;
                while (copyExpressions.Count > 0)
                {
                    ICondition cond = null;
                    if (copyExpressions[0] == lexems["("])
                    {
                        //
                        // Find pair bracket
                        //
                        int closeBracket = FindPairBracket(copyExpressions, lexems);
                        if (closeBracket == -1)
                        {
                            throw new Exception("Parenthesis error.");
                        }

                        cond = ParseConditionsRecurse(copyExpressions.GetRange(1, closeBracket - 1), lexems);
                        copyExpressions.RemoveRange(0, closeBracket + 1);
                    }
                    else if (copyExpressions[0] is ConditionExpression)
                    {
                        cond = ((ConditionExpression)copyExpressions[0]).Condition;
                        copyExpressions.RemoveAt(0);
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("Wrong expression in condition part at '{0}'"),copyExpressions[0].Text );
                    }

                    //
                    // And condition to the list
                    //
                    conds.Conditins.Add(cond);

                    if (copyExpressions.Count > 0)
                    {
                        if (copyExpressions[0] == lexems["and"] || copyExpressions[0] == lexems["or"])
                        {
                            if (copyExpressions.Count < 2)
                            {
                                throw new Exception(string.Format("Error at {0} in condition part.", copyExpressions[0].Text));
                            }

                            //
                            // Set and/or for conditions list
                            //
                            OperatorType newOp = (copyExpressions[0] == lexems["and"]) ? OperatorType.And : OperatorType.Or;

                            if (setOrAnd)
                            {
                                if (conds.Op != newOp)
                                {
                                    throw new Exception("At the one nesting level cannot be mixed and/or operations.");
                                }
                            }
                            else
                            {
                                conds.Op = newOp;
                                setOrAnd = true;
                            }
                            copyExpressions.RemoveAt(0);
                        }
                        else
                        {
                            throw new Exception(string.Format("{1} cannot goes after {0}", copyExpressions[0].Text, copyExpressions[1].Text));
                        }
                    }
                }

                return conds;
            }
        }

        static private SingleCondition ParseConclusion(List<IExpression> conditionExpression, List<FuzzyVariable> output, Dictionary<string, Lexem> lexems)
        {

            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))
            {
                throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprVariable.Text));
            }

            VarLexem varLexem = (VarLexem)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 TermLexem))
            {
                throw new Exception(string.Format("Wrong identifier '{0}' in conclusion part of the rule.", exprTerm.Text));
            }

            TermLexem termLexem = (TermLexem)exprTerm;
            if (!varLexem.Var.Terms.Contains(termLexem.Term))
            {
                throw new Exception(string.Format("The term ({0}) in conclusion part does not belong to the specified variable ({1}).", termLexem.Text, varLexem.Text));
            }

            //
            // Return fuzzy rule's conclusion
            //
            return new SingleCondition(varLexem.Var, termLexem.Term, false);
        }

        static public FuzzyRule Parse(string rule, List<FuzzyVariable> input, List<FuzzyVariable> output)
        {
            if (rule.Length == 0)
            {
                throw new ArgumentException("Rule cannot be empty.");
            }

            //
            // Surround brakes with spaces, remove double spaces
            //
            System.Text.StringBuilder sb = new StringBuilder();
            foreach (char ch in rule)
            {
                if (ch == ')' || ch == '(')
                {
                    if (sb.Length > 0 && sb[sb.Length - 1] == ' ')
                    {
                        // Do not duplicate spaces
                    }
                    else
                    {
                        sb.Append(' ');
                    }

                    sb.Append(ch);
                    sb.Append(' ');
                }
                else
                {
                    if (ch == ' ' && sb.Length > 0 && sb[sb.Length - 1] == ' ')
                    {
                        // Do not duplicate spaces
                    }
                    else
                    {
                        sb.Append(ch);
                    }
                }
            }

            //
            // Remove spaces
            //
            string prepRule = sb.ToString().Trim();

            //
            // Build lexems dictionary
            //
            List<Lexem> lexems = BuildLexemsList(input, output);
            Dictionary<string, Lexem> lexemsDict = new Dictionary<string, Lexem>();
            foreach (Lexem lexem in lexems)
            {
                lexemsDict.Add(lexem.Text, lexem);
            }

            //
            // At first we parse lexems
            //
            List<IExpression> expressions = ParseLexems(prepRule, lexemsDict);
            if (expressions.Count == 0)
            {
                throw new System.Exception("No valid identifiers found.");
            }
            
            //
            // Find condition & conclusion parts part
            //
            if (expressions[0] != lexemsDict["if"])
            {
                throw new System.Exception("'if' should be the first identifier.");
            }

            int thenIndex = -1;
            for (int i = 1; i < expressions.Count; i++)
            {
                if (expressions[i] == lexemsDict["then"])
                {
                    thenIndex = i;
                    break;
                }
            }

            if (thenIndex == -1)
            {
                throw new System.Exception("'then' identifier not found.");
            }

            int conditionLen = thenIndex - 1;
            if (conditionLen < 1)
            {
                throw new System.Exception("Condition part of the rule not found.");
            }

            int conclusionLen = expressions.Count - thenIndex - 1;
            if (conclusionLen < 1)
            {
                throw new System.Exception("Conclusion part of the rule not found.");
            }

            List<IExpression> conditionExpressions = expressions.GetRange(1, conditionLen);
            List<IExpression> conclusionExpressions = expressions.GetRange(thenIndex + 1, conclusionLen);

            Conditions conditions = ParseConditions(conditionExpressions, input, lexemsDict);
            SingleCondition conclusion = ParseConclusion(conclusionExpressions, output, lexemsDict);

            FuzzyRule resultRule = new FuzzyRule(input, output);
            resultRule.Condition = conditions;
            resultRule.Conclusion = conclusion;
            return resultRule;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -