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);
        }
        /// <summary>
        /// Evaluate fuzzy condition (or conditions)
        /// </summary>
        /// <param name="condition">Condition that should be evaluated</param>
        /// <param name="fuzzifiedInput">Input in fuzzified form</param>
        /// <returns>Result of evaluation</returns>
        protected double EvaluateCondition(ICondition condition, Dictionary <FuzzyVariable, Dictionary <FuzzyTerm, double> > fuzzifiedInput)
        {
            if (condition is Conditions)
            {
                double     result = 0.0;
                Conditions conds  = (Conditions)condition;

                if (conds.ConditionsList.Count == 0)
                {
                    throw new Exception("Inner exception.");
                }
                else if (conds.ConditionsList.Count == 1)
                {
                    result = EvaluateCondition(conds.ConditionsList[0], fuzzifiedInput);
                }
                else
                {
                    result = EvaluateCondition(conds.ConditionsList[0], fuzzifiedInput);
                    for (int i = 1; i < conds.ConditionsList.Count; i++)
                    {
                        result = EvaluateConditionPair(result, EvaluateCondition(conds.ConditionsList[i], fuzzifiedInput), conds.Op);
                    }
                }

                if (conds.Not)
                {
                    result = 1.0 - result;
                }

                return(result);
            }
            else if (condition is FuzzyCondition)
            {
                FuzzyCondition cond   = (FuzzyCondition)condition;
                double         result = fuzzifiedInput[(FuzzyVariable)cond.Var][(FuzzyTerm)cond.Term];

                switch (cond.Hedge)
                {
                case HedgeType.Slightly:
                    result = Math.Pow(result, 1.0 / 3.0);     //Cube root
                    break;

                case HedgeType.Somewhat:
                    result = Math.Sqrt(result);
                    break;

                case HedgeType.Very:
                    result = result * result;
                    break;

                case HedgeType.Extremely:
                    result = result * result * result;
                    break;

                default:
                    break;
                }

                if (cond.Not)
                {
                    result = 1.0 - result;
                }
                return(result);
            }
            else
            {
                throw new Exception("Internal exception.");
            }
        }
 public ConditionExpression(List <IExpression> expressions, FuzzyCondition condition)
 {
     _expressions = expressions;
     _condition   = condition;
 }