diff options
Diffstat (limited to 'fuzzylite/src/rule/Consequent.cpp')
-rw-r--r-- | fuzzylite/src/rule/Consequent.cpp | 117 |
1 files changed, 59 insertions, 58 deletions
diff --git a/fuzzylite/src/rule/Consequent.cpp b/fuzzylite/src/rule/Consequent.cpp index 28d3390..a90b1a9 100644 --- a/fuzzylite/src/rule/Consequent.cpp +++ b/fuzzylite/src/rule/Consequent.cpp @@ -1,25 +1,17 @@ /* - Author: Juan Rada-Vilela, Ph.D. - Copyright (C) 2010-2014 FuzzyLite Limited - All rights reserved + fuzzylite (R), a fuzzy logic control library in C++. + Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. + Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> This file is part of fuzzylite. fuzzylite is free software: you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. + the terms of the FuzzyLite License included with the software. - fuzzylite is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - for more details. - - You should have received a copy of the GNU Lesser General Public License - along with fuzzylite. If not, see <http://www.gnu.org/licenses/>. - - fuzzyliteâ„¢ is a trademark of FuzzyLite Limited. + You should have received a copy of the FuzzyLite License along with + fuzzylite. If not, see <http://www.fuzzylite.com/license/>. + fuzzylite is a registered trademark of FuzzyLite Limited. */ #include "fl/rule/Consequent.h" @@ -27,24 +19,21 @@ #include "fl/Engine.h" #include "fl/factory/HedgeFactory.h" #include "fl/factory/FactoryManager.h" -#include "fl/hedge/Hedge.h" #include "fl/hedge/Any.h" -#include "fl/norm/TNorm.h" #include "fl/rule/Expression.h" #include "fl/rule/Rule.h" -#include "fl/term/Accumulated.h" -#include "fl/term/Activated.h" +#include "fl/term/Aggregated.h" #include "fl/variable/OutputVariable.h" -#include <algorithm> - namespace fl { - Consequent::Consequent() { - } + Consequent::Consequent() { } Consequent::~Consequent() { - unload(); + for (std::size_t i = 0; i < _conclusions.size(); ++i) { + delete _conclusions.at(i); + } + _conclusions.clear(); } std::string Consequent::getText() const { @@ -59,9 +48,29 @@ namespace fl { return this->_conclusions; } - void Consequent::modify(scalar activationDegree, const TNorm* activation) { + std::vector<Proposition*>& Consequent::conclusions() { + return this->_conclusions; + } + + Complexity Consequent::complexity(const TNorm* implication) const { + Complexity result; + result.comparison(1); + + for (std::size_t i = 0; i < _conclusions.size(); ++i) { + Proposition* proposition = _conclusions.at(i); + result.comparison(2); + for (std::size_t h = 0; h < proposition->hedges.size(); ++h) { + result += proposition->hedges.at(h)->complexity(); + } + result += static_cast<OutputVariable*> (proposition->variable) + ->complexity(Activated(proposition->term, fl::nan, implication)); + } + return result; + } + + void Consequent::modify(scalar activationDegree, const TNorm* implication) { if (not isLoaded()) { - throw fl::Exception("[consequent error] consequent <" + _text + "> is not loaded", FL_AT); + throw Exception("[consequent error] consequent <" + getText() + "> is not loaded", FL_AT); } for (std::size_t i = 0; i < _conclusions.size(); ++i) { Proposition* proposition = _conclusions.at(i); @@ -72,10 +81,9 @@ namespace fl { activationDegree = (*rit)->hedge(activationDegree); } } - Activated* term = new Activated(_conclusions.at(i)->term, activationDegree, activation); - OutputVariable* outputVariable = dynamic_cast<OutputVariable*> (proposition->variable); - outputVariable->fuzzyOutput()->addTerm(term); - FL_DBG("Accumulating " << term->toString()); + + static_cast<OutputVariable*> (proposition->variable)->fuzzyOutput() + ->addTerm(proposition->term, activationDegree, implication); } } } @@ -91,16 +99,16 @@ namespace fl { _conclusions.clear(); } - void Consequent::load(Rule* rule, const Engine* engine) { - load(_text, rule, engine); + void Consequent::load(const Engine* engine) { + load(getText(), engine); } - void Consequent::load(const std::string& consequent, Rule* rule, const Engine* engine) { + void Consequent::load(const std::string& consequent, const Engine* engine) { unload(); - this->_text = consequent; + setText(consequent); - if (fl::Op::trim(consequent).empty()) { - throw fl::Exception("[syntax error] consequent is empty", FL_AT); + if (Op::trim(consequent).empty()) { + throw Exception("[syntax error] consequent is empty", FL_AT); } /** @@ -129,8 +137,7 @@ namespace fl { if (engine->hasOutputVariable(token)) { proposition = new Proposition; proposition->variable = engine->getOutputVariable(token); - _conclusions.push_back(proposition); - + conclusions().push_back(proposition); state = S_IS; continue; } @@ -144,15 +151,9 @@ namespace fl { } if (state bitand S_HEDGE) { - Hedge* hedge = rule->getHedge(token); - if (not hedge) { - HedgeFactory* factory = FactoryManager::instance()->hedge(); - if (factory->hasConstructor(token)){ - hedge = factory->constructObject(token); - rule->addHedge(hedge); - } - } - if (hedge) { + HedgeFactory* factory = FactoryManager::instance()->hedge(); + if (factory->hasConstructor(token)) { + Hedge* hedge = factory->constructObject(token); proposition->hedges.push_back(hedge); state = S_HEDGE bitor S_TERM; continue; @@ -178,19 +179,19 @@ namespace fl { if (state bitand S_VARIABLE) { std::ostringstream ex; ex << "[syntax error] consequent expected output variable, but found <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } if (state bitand S_IS) { std::ostringstream ex; ex << "[syntax error] consequent expected keyword <" << Rule::isKeyword() << ">, " "but found <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } if ((state bitand S_HEDGE) or (state bitand S_TERM)) { std::ostringstream ex; ex << "[syntax error] consequent expected hedge or term, but found <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } if ((state bitand S_AND) or (state bitand S_WITH)) { @@ -198,30 +199,30 @@ namespace fl { ex << "[syntax error] consequent expected operator <" << Rule::andKeyword() << "> " << "or keyword <" << Rule::withKeyword() << ">, " << "but found <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } std::ostringstream ex; ex << "[syntax error] unexpected token <" << token << "> in consequent"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } if (not ((state bitand S_AND) or (state bitand S_WITH))) { //only acceptable final state if (state bitand S_VARIABLE) { std::ostringstream ex; ex << "[syntax error] consequent expected output variable after <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } if (state bitand S_IS) { std::ostringstream ex; ex << "[syntax error] consequent expected keyword <" << Rule::isKeyword() << "> " "after <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } if ((state bitand S_HEDGE) or (state bitand S_TERM)) { std::ostringstream ex; ex << "[syntax error] consequent expected hedge or term after <" << token << ">"; - throw fl::Exception(ex.str(), FL_AT); + throw Exception(ex.str(), FL_AT); } } } catch (...) { @@ -232,9 +233,9 @@ namespace fl { std::string Consequent::toString() const { std::stringstream ss; - for (std::size_t i = 0; i < _conclusions.size(); ++i) { - ss << _conclusions.at(i)->toString(); - if (i + 1 < _conclusions.size()) + for (std::size_t i = 0; i < conclusions().size(); ++i) { + ss << conclusions().at(i)->toString(); + if (i + 1 < conclusions().size()) ss << " " << Rule::andKeyword() << " "; } return ss.str(); |