/// <summary> /// Executes the fuzzy inference, obtaining the <see cref="FuzzyOutput"/> of the system for the required /// <see cref="LinguisticVariable"/>. /// </summary> /// /// <param name="variableName">Name of the <see cref="LinguisticVariable"/> to evaluate.</param> /// /// <returns>A <see cref="FuzzyOutput"/> containing the fuzzy output of the system for the /// <see cref="LinguisticVariable"/> specified in <paramref name="variableName"/>.</returns> /// /// <exception cref="KeyNotFoundException">The variable indicated was not found in the database.</exception> /// public FuzzyOutput ExecuteInference(string variableName) { // gets the variable LinguisticVariable lingVar = database.GetVariable(variableName); // object to store the fuzzy output FuzzyOutput fuzzyOutput = new FuzzyOutput(lingVar); // select only rules with the variable as output Rule[] rules = rulebase.GetRules( ); foreach (Rule r in rules) { if (r.Output.Variable.Name == variableName) { string labelName = r.Output.Label.Name; float firingStrength = r.EvaluateFiringStrength( ); if (firingStrength > 0) { fuzzyOutput.AddOutput(labelName, firingStrength); } } } // returns the fuzzy output obtained return(fuzzyOutput); }
/// <summary> /// Initializes a new instance of the <see cref="FuzzyOutput"/> class. /// </summary> /// /// <param name="outputVar">A <see cref="LinguisticVariable"/> representing a Fuzzy Inference System's output.</param> /// internal FuzzyOutput(LinguisticVariable outputVar) { // instance of the constraints list this.outputList = new List <OutputConstraint>(20); // output linguistic variable this.outputVar = outputVar; }
/// <summary> /// Initializes a new instance of the <see cref="Clause"/> class. /// </summary> /// /// <param name="variable">Linguistic variable of the clause. </param> /// /// <param name="label">Label of the linguistic variable, a fuzzy set used as label into the linguistic variable.</param> /// /// <exception cref="KeyNotFoundException">The label indicated was not found in the linguistic variable.</exception> /// public Clause(LinguisticVariable variable, FuzzySet label) { // check if label belongs to var. variable.GetLabel(label.Name); // initializing attributes this.label = label; this.variable = variable; }
/// <summary> /// Adds a linguistic variable to the database. /// </summary> /// /// <param name="variable">A linguistic variable to add.</param> /// /// <exception cref="NullReferenceException">The linguistic variable was not initialized.</exception> /// <exception cref="ArgumentException">The linguistic variable name already exists in the database.</exception> /// public void AddVariable( LinguisticVariable variable ) { // checking for existing name if ( this.variables.ContainsKey( variable.Name ) ) throw new ArgumentException( "The linguistic variable name already exists in the database." ); // adding label this.variables.Add( variable.Name, variable ); }
/// <summary> /// Adds a linguistic variable to the database. /// </summary> /// /// <param name="variable">A linguistic variable to add.</param> /// /// <exception cref="NullReferenceException">The linguistic variable was not initialized.</exception> /// <exception cref="ArgumentException">The linguistic variable name already exists in the database.</exception> /// public void AddVariable(LinguisticVariable variable) { // checking for existing name if (this.variables.ContainsKey(variable.Name)) { throw new ArgumentException("The linguistic variable name already exists in the database."); } // adding label this.variables.Add(variable.Name, variable); }
/// <summary> /// Initializes a new instance of the <see cref="Clause"/> class. /// </summary> /// /// <param name="variable">Linguistic variable of the clause. </param> /// /// <param name="label">Label of the linguistic variable, a fuzzy set used as label into the linguistic variable.</param> /// /// <exception cref="KeyNotFoundException">The label indicated was not found in the linguistic variable.</exception> /// public Clause( LinguisticVariable variable, FuzzySet label ) { // check if label belongs to var. variable.GetLabel( label.Name ); // initializing attributes this.label = label; this.variable = variable; }
/// <summary> /// Converts the Fuzzy Rule to RPN (Reverse Polish Notation). For debug proposes, the string representation of the /// RPN expression can be acessed by calling <see cref="GetRPNExpression"/> method. /// </summary> /// private void ParseRule( ) { // flag to incicate we are on consequent state bool consequent = false; // tokens like IF and THEN will be searched always in upper case string upRule = rule.ToUpper( ); // the rule must start with IF, and must have a THEN somewhere if (!upRule.StartsWith("IF")) { throw new ArgumentException("A Fuzzy Rule must start with an IF statement."); } if (upRule.IndexOf("THEN") < 0) { throw new ArgumentException("Missing the consequent (THEN) statement."); } // building a list with all the expression (rule) string tokens string spacedRule = rule.Replace("(", " ( ").Replace(")", " ) "); // getting the tokens list string[] tokensList = GetRuleTokens(spacedRule); // stack to convert to RPN Stack <string> s = new Stack <string>( ); // storing the last token string lastToken = "IF"; // linguistic var read, used to build clause LinguisticVariable lingVar = null; // verifying each token for (int i = 0; i < tokensList.Length; i++) { // removing spaces string token = tokensList[i].Trim( ); // getting upper case string upToken = token.ToUpper( ); // ignoring these tokens if (upToken == "" || upToken == "IF") { continue; } // if the THEN is found, the rule is now on consequent if (upToken == "THEN") { lastToken = upToken; consequent = true; continue; } // if we got a linguistic variable, an IS statement and a label is needed if (lastToken == "VAR") { if (upToken == "IS") { lastToken = upToken; } else { throw new ArgumentException("An IS statement is expected after a linguistic variable."); } } // if we got an IS statement, a label must follow it else if (lastToken == "IS") { try { FuzzySet fs = lingVar.GetLabel(token); Clause c = new Clause(lingVar, fs); if (consequent) { output = c; } else { rpnTokenList.Add(c); } lastToken = "LAB"; } catch (KeyNotFoundException) { throw new ArgumentException("Linguistic label " + token + " was not found on the variable " + lingVar.Name + "."); } } // not VAR and not IS statement else { // openning new scope if (upToken == "(") { // if we are on consequent, only variables can be found if (consequent) { throw new ArgumentException("Linguistic variable expected after a THEN statement."); } // if its a (, just push it s.Push(upToken); lastToken = upToken; } // operators else if (upToken == "AND" || upToken == "OR" || unaryOperators.IndexOf(upToken) >= 0) { // if we are on consequent, only variables can be found if (consequent) { throw new ArgumentException("Linguistic variable expected after a THEN statement."); } // pop all the higher priority operators until the stack is empty while ((s.Count > 0) && (Priority(s.Peek( )) > Priority(upToken))) { rpnTokenList.Add(s.Pop( )); } // pushing the operator s.Push(upToken); lastToken = upToken; } // closing the scope else if (upToken == ")") { // if we are on consequent, only variables can be found if (consequent) { throw new ArgumentException("Linguistic variable expected after a THEN statement."); } // if there is nothing on the stack, an oppening parenthesis is missing. if (s.Count == 0) { throw new ArgumentException("Openning parenthesis missing."); } // pop the tokens and copy to output until openning is found while (s.Peek( ) != "(") { rpnTokenList.Add(s.Pop( )); if (s.Count == 0) { throw new ArgumentException("Openning parenthesis missing."); } } s.Pop( ); // saving last token... lastToken = upToken; } // finally, the token is a variable else { // find the variable try { lingVar = database.GetVariable(token); lastToken = "VAR"; } catch (KeyNotFoundException) { throw new ArgumentException("Linguistic variable " + token + " was not found on the database."); } } } } // popping all operators left in stack while (s.Count > 0) { rpnTokenList.Add(s.Pop( )); } }