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

📄 ruleparser.cs

📁 在.net环境下用C#开发的模糊控制函数库
💻 CS
📖 第 1 页 / 共 2 页
字号:
/*
 * 
 * fuzzynet: Fuzzy Logic Library for Microsoft .NET
 * Copyright (C) 2008 Dmitry Kaluzhny  (kaluzhny_dmitrie@mail.ru)
 * 
 * */

using System;
using System.Collections.Generic;
using System.Text;

namespace AI.Fuzzy.Library
{
    /// <summary>
    /// Class responsible for parsing
    /// </summary>
    internal class RuleParser
    {
        static string[] KEYWORDS = new string[] { "if", "then", "is", "and", "or", "not", "(", ")"};

        #region Public helpers
        /// <summary>
        /// Check the name of variable/term.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        static public bool IsValidName(string name)
        {
            //
            // Empty names are not allowed
            //
            if (name.Length == 0)
            {
                return false;
            }

            for (int i = 0; i < name.Length; i++)
            {
                //
                // Only letters, numbers or '_' are allowed
                //
                if (!System.Char.IsDigit(name, i) ||
                    !System.Char.IsDigit(name, i) ||
                    name[i] != '_')
                {
                    return false;
                }
            }

            //
            // Identifier cannot be a keword
            //
            foreach (string keyword in KEYWORDS)
            {
                if (name == keyword)
                {
                    return false;
                }
            }

            return true;
        }
        #endregion

        #region Rule expression hierarchy
        interface IExpression
        {
            string Text { get; }
        }

        abstract class Lexem : IExpression
        {
            public abstract string Text { get; }
            public override string ToString()
            {
                return this.Text;
            }
        }

        class ConditionExpression : IExpression
        {
            List<IExpression> _expressions = null;
            SingleCondition _condition = null;

            public ConditionExpression(List<IExpression> expressions, SingleCondition condition)
            {
                _expressions = expressions;
                _condition = condition;
            }

            public List<IExpression> Expressions
            {
                get { return _expressions; }
                set { _expressions = value; }
            }

            public SingleCondition Condition
            {
                get { return _condition; }
                set { _condition = value; }
            }

            public string Text
            {
                get
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (IExpression ex in _expressions)
                    {
                        sb.Append(ex.Text);
                    }
                    return sb.ToString();
                }
            }
        }

        class KeywordLexem : Lexem
        {
            string _name;

            public KeywordLexem(string name)
            {
                _name = name;
            }

            public override string Text
            {
                get { return _name; }
            }
        }

        class VarLexem : Lexem
        {
            FuzzyVariable _var = null;
            bool _input = true;

            public VarLexem(FuzzyVariable var, bool input)
            {
                _var = var;
                _input = input;
            }

            public FuzzyVariable Var
            {
                get { return _var; }
                set { _var = value; }
            }

            public override string Text
            {
                get { return _var.Name; }
            }

            public bool Input
            {
                get { return _input; }
                set { _input = value; }
            }
        }

        class TermLexem : Lexem
        {
            FuzzyTerm _term = null;
            bool _input = true;

            public TermLexem(FuzzyTerm term, bool input)
            {
                _term = term;
                _input = input;
            }

            public FuzzyTerm Term
            {
                get { return _term; }
                set { _term = value; }
            }

            public override string Text
            {
                get { return _term.Name; }
            }
        }
        #endregion

        static private List<Lexem> BuildLexemsList(List<FuzzyVariable> input, List<FuzzyVariable> output)
        {
            List<Lexem> lexems = new List<Lexem>();           

            foreach (string keyword in KEYWORDS)
            {
                lexems.Add(new KeywordLexem(keyword));
            }

            foreach (FuzzyVariable var in input)
            {
                lexems.AddRange(BuildLexemsList(var, true));
            }

            foreach (FuzzyVariable var in output)
            {
                lexems.AddRange(BuildLexemsList(var, false));
            }

            return lexems;
        }

        static private List<Lexem> BuildLexemsList(FuzzyVariable var, bool input)
        {
            List<Lexem> lexems = new List<Lexem>();

            lexems.Add(new VarLexem(var, input));
            foreach (FuzzyTerm term in var.Terms)
            {
                lexems.Add(new TermLexem(term, input));
            }

            return lexems;
        }

        static private List<IExpression> ParseLexems(string rule, Dictionary<string, Lexem> lexems)
        {
            List<IExpression> expressions = new List<IExpression>();

            string []words = rule.Split(' ');
            foreach (string word in words)
            {
                Lexem lexem;
                if (lexems.TryGetValue(word, out lexem))
                {
                    expressions.Add(lexem);
                }
                else
                {
                    throw new System.Exception(string.Format("Unknown identifier: {0}", word));
                }
            }

            return expressions;
        }

        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)
                {
                    //
                    // Parse variable
                    //
                    VarLexem varLexem = (VarLexem)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 intput 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.");
                        }
                    }

                    //
                    // Parse term
                    //
                    Lexem exprTerm = (Lexem)copyExpressions[cur];
                    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 condition part does not belong to the specified variable ({1}).", termLexem.Text, varLexem.Text));
                    }

                    //
                    // Add new condition expression
                    //
                    SingleCondition condition = new SingleCondition(varLexem.Var, termLexem.Term, not);
                    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 Conditions ParseConditions(List<IExpression> conditionExpression, List<FuzzyVariable> input, Dictionary<string, Lexem> lexems)

⌨️ 快捷键说明

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