// Copyright (C) 2000 Dominic Letourneau (doumdi@yahoo.com)
// FuzzyRule.cc: implementation of the FuzzyRule class.
//
//////////////////////////////////////////////////////////////////////
#include "FuzzyRule.h"
#include "Tokenizer.h"
#include <string>
#include "Vector.h"
#include "FuzzyOperators.h"
using namespace std;
namespace FD {
DECLARE_NODE(FuzzyRule)
DECLARE_TYPE(FuzzyRule)
/*Node
*
* @name FuzzyRule
* @category Fuzzy
* @description A Rule containing ANTECEDANTS (IF) and CONSEQUENTS(THEN)
*
* @parameter_name IF
* @parameter_description Antecedant of the rule seperated by spaces
* @parameter_type string
*
* @parameter_name THEN
* @parameter_description Consequent of the rule seperated by spaces
* @parameter_type string
*
* @output_name RULE
* @output_description The FuzzyRule Object
* @output_type Vector<ObjectRef>
*
END*/
//////////////////////////////////////////////////////////////////////
// Construction
//////////////////////////////////////////////////////////////////////
FuzzyRule::FuzzyRule()
:BufferedNode("INVALID",ParameterSet()), m_rule_number(-1) {
}
FuzzyRule::FuzzyRule(istream &in)
:BufferedNode("INVALID",ParameterSet()), m_rule_number(-1) {
readFrom(in);
}
FuzzyRule::FuzzyRule(int rule_number)
: BufferedNode("INVALID",ParameterSet()), m_rule_number(rule_number) {
}
FuzzyRule::FuzzyRule(const FuzzyRule& cpy)
:BufferedNode(cpy.name, ParameterSet()), m_rule_number(cpy.m_rule_number) {
for (int i = 0; i < cpy.m_antecedant.size(); i++) {
m_antecedant.push_back(cpy.m_antecedant[i]);
}
for (int i = 0; i < cpy.m_consequent.size(); i++) {
m_consequent.push_back(cpy.m_consequent[i]);
}
}
FuzzyRule::FuzzyRule(string nodeName, ParameterSet params)
: BufferedNode(nodeName,params), m_rule_number(-1) {
m_ruleID = addOutput("RULE");
String antecedant = object_cast<String>(parameters.get("IF"));
String consequent = object_cast<String>(parameters.get("THEN"));
if (antecedant.size() == 0 || consequent.size() == 0) {
throw new GeneralException("Antecedant or consequent not specified",__FILE__,__LINE__);
}
Vector<char> discardToken(3);
Vector<char> keepToken;
discardToken[0]= ' ';
discardToken[1]= ':';
discardToken[2]= ';';
Vector<string> tokens;
string_to_token(tokens,antecedant,keepToken,discardToken);
if (tokens.size() %2 == 0 && tokens.size() != 0) {
for (int i = 0; i < tokens.size(); i+= 2) {
m_antecedant.push_back(make_pair(tokens[i],tokens[i+1]));
}
}
else {
throw new GeneralException("Use VARIABLE1:VALUE VARIABLE2:VALUE as antecedant",__FILE__,__LINE__);
}
string_to_token(tokens,consequent,keepToken,discardToken);
if (tokens.size() %2 == 0 && tokens.size() != 0) {
for (int i = 0; i < tokens.size(); i+=2) {
m_consequent.push_back(make_pair(tokens[i],tokens[i+1]));
}
}
else {
throw new GeneralException("Use VARIABLE1:VALUE VARIABLE2:VALUE as consequent",__FILE__,__LINE__);
}
//print_rule(cerr);
}
//////////////////////////////////////////////////////////////////////
// Destruction
//////////////////////////////////////////////////////////////////////
FuzzyRule::~FuzzyRule() {
}
//////////////////////////////////////////////////////////////////////
// Adding an antecedant to the rule
//////////////////////////////////////////////////////////////////////
void FuzzyRule::add_antecedant(const string &set_name, const string &funct_name) {
m_antecedant.push_back(pair<string,string>(set_name,funct_name));
}
//////////////////////////////////////////////////////////////////////
// Adding a consequent to the rule
//////////////////////////////////////////////////////////////////////
void FuzzyRule::add_consequent(const string &set_name, const string &funct_name) {
m_consequent.push_back(pair<string,string>(set_name,funct_name));
}
//////////////////////////////////////////////////////////////////////
// Printing the rule on a standard stream
//////////////////////////////////////////////////////////////////////
void FuzzyRule::print_rule(ostream &out) {
out<<"Rule #"<<m_rule_number<<" IF ";
for (int i = 0; i < m_antecedant.size(); i++) {
out<<m_antecedant[i].first<< " IS " << m_antecedant[i].second;
if (i < m_antecedant.size() - 1) {
out <<" AND ";
}
}
out<<" THEN ";
for (int j = 0; j < m_consequent.size(); j++) {
out<<m_consequent[j].first<< " IS " << m_consequent[j].second;
if (j < m_consequent.size() - 1) {
out <<" AND ";
}
}
out<<endl;
}
//////////////////////////////////////////////////////////////////////
// calculate
//////////////////////////////////////////////////////////////////////
void FuzzyRule::calculate(int output_id, int count, Buffer &out) {
//cloning ourself as a Object not a node!
out[count] = ObjectRef(new Vector<ObjectRef>(1,clone()));
}
ObjectRef FuzzyRule::clone() {
FuzzyRule *my_clone = new FuzzyRule(m_rule_number);
for (int i = 0; i < m_antecedant.size(); i++) {
my_clone->m_antecedant.push_back(m_antecedant[i]);
}
for (int i = 0; i < m_consequent.size(); i++) {
my_clone->m_consequent.push_back(m_consequent[i]);
}
return ObjectRef(my_clone);
}
void FuzzyRule::printOn(ostream &out) const {
out <<"<FuzzyRule "<<endl;
out <<"<Number "<<m_rule_number<<" >"<<endl;
for (int i = 0; i < m_antecedant.size(); i++) {
out<<"<Antecedant "<<m_antecedant[i].first<<" "<<m_antecedant[i].second<<" >"<<endl;
}
for (int i = 0; i < m_consequent.size(); i++) {
out<<"<Consequent "<<m_consequent[i].first<<" "<<m_consequent[i].second<<" >"<<endl;
}
out <<" >\n";
}
void FuzzyRule::readFrom(istream &in) {
string tag;
int antecedant_size;
int consequent_size;
while (1)
{
char ch;
in >> ch;
if (ch == '>') break;
else if (ch != '<') {
throw new ParsingException ("FuzzyRule::readFrom : Parse error: '<' expected");
}
in >> tag;
if (tag == "Number") {
in >> m_rule_number;
}
else if (tag == "Antecedant") {
string first,second;
in >>first;
in >>second;
m_antecedant.push_back(make_pair(first,second));
}
else if (tag == "Consequent") {
string first,second;
in >>first;
in >>second;
m_consequent.push_back(make_pair(first,second));
}
else {
throw new ParsingException ("FuzzyRule::readFrom : unknown argument: " + tag);
}
if (!in) throw new ParsingException ("FuzzyRule::readFrom : Parse error trying to build " + tag);
in >> tag;
if (tag != ">")
throw new ParsingException ("FuzzyRule::readFrom : Parse error: '>' expected ");
}
}
}//namespace FD
syntax highlighted by Code2HTML, v. 0.9.1