1 /* 2 fuzzylite (R), a fuzzy logic control library in C++. 3 Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved. 4 Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com> 5 6 This file is part of fuzzylite. 7 8 fuzzylite is free software: you can redistribute it and/or modify it under 9 the terms of the FuzzyLite License included with the software. 10 11 You should have received a copy of the FuzzyLite License along with 12 fuzzylite. If not, see <http://www.fuzzylite.com/license/>. 13 14 fuzzylite is a registered trademark of FuzzyLite Limited. 15 */ 16 17 #include "fl/rule/RuleBlock.h" 18 19 #include "fl/activation/General.h" 20 #include "fl/imex/FllExporter.h" 21 #include "fl/norm/TNorm.h" 22 #include "fl/norm/SNorm.h" 23 #include "fl/rule/Rule.h" 24 #include "fl/Operation.h" 25 26 namespace fl { 27 RuleBlock(const std::string & name)28 RuleBlock::RuleBlock(const std::string& name) 29 : _enabled(true), _name(name), _description("") { } 30 RuleBlock(const RuleBlock & other)31 RuleBlock::RuleBlock(const RuleBlock& other) : _enabled(true), _name(other._name), 32 _description(other._description) { 33 copyFrom(other); 34 } 35 operator =(const RuleBlock & other)36 RuleBlock& RuleBlock::operator=(const RuleBlock& other) { 37 if (this != &other) { 38 for (std::size_t i = 0; i < _rules.size(); ++i) { 39 delete _rules.at(i); 40 } 41 _rules.clear(); 42 _conjunction.reset(fl::null); 43 _disjunction.reset(fl::null); 44 _implication.reset(fl::null); 45 _activation.reset(fl::null); 46 47 copyFrom(other); 48 } 49 return *this; 50 } 51 copyFrom(const RuleBlock & source)52 void RuleBlock::copyFrom(const RuleBlock& source) { 53 _enabled = source._enabled; 54 _name = source._name; 55 _description = source._description; 56 if (source._conjunction.get()) _conjunction.reset(source._conjunction->clone()); 57 if (source._disjunction.get()) _disjunction.reset(source._disjunction->clone()); 58 if (source._implication.get()) _implication.reset(source._implication->clone()); 59 if (source._activation.get()) _activation.reset(source._activation->clone()); 60 for (std::size_t i = 0; i < source._rules.size(); ++i) { 61 _rules.push_back(source._rules.at(i)->clone()); 62 } 63 } 64 ~RuleBlock()65 RuleBlock::~RuleBlock() { 66 for (std::size_t i = 0; i < _rules.size(); ++i) { 67 delete _rules.at(i); 68 } 69 _rules.clear(); 70 } 71 complexity() const72 Complexity RuleBlock::complexity() const { 73 Complexity result; 74 result.comparison(1); 75 if (_activation.get()) { 76 result += _activation->complexity(this); 77 } else { 78 for (std::size_t i = 0; i < _rules.size(); ++i) { 79 result += _rules.at(i)->complexity( 80 _conjunction.get(), _disjunction.get(), _implication.get()); 81 } 82 } 83 return result; 84 } 85 activate()86 void RuleBlock::activate() { 87 if (not _activation.get()) { 88 _activation.reset(new General); 89 } 90 _activation->activate(this); 91 } 92 unloadRules() const93 void RuleBlock::unloadRules() const { 94 for (std::size_t i = 0; i < _rules.size(); ++i) { 95 _rules.at(i)->unload(); 96 } 97 } 98 loadRules(const Engine * engine)99 void RuleBlock::loadRules(const Engine* engine) { 100 std::ostringstream exceptions; 101 bool throwException = false; 102 for (std::size_t i = 0; i < _rules.size(); ++i) { 103 Rule* rule = _rules.at(i); 104 if (rule->isLoaded()) { 105 rule->unload(); 106 } 107 try { 108 rule->load(engine); 109 } catch (std::exception& ex) { 110 throwException = true; 111 exceptions << ex.what() << "\n"; 112 } 113 } 114 if (throwException) { 115 Exception exception("[ruleblock error] the following " 116 "rules could not be loaded:\n" + exceptions.str(), FL_AT); 117 throw exception; 118 } 119 } 120 reloadRules(const Engine * engine)121 void RuleBlock::reloadRules(const Engine* engine) { 122 unloadRules(); 123 loadRules(engine); 124 } 125 setName(std::string name)126 void RuleBlock::setName(std::string name) { 127 this->_name = name; 128 } 129 getName() const130 std::string RuleBlock::getName() const { 131 return this->_name; 132 } 133 setDescription(const std::string & description)134 void RuleBlock::setDescription(const std::string& description) { 135 this->_description = description; 136 } 137 getDescription() const138 std::string RuleBlock::getDescription() const { 139 return this->_description; 140 } 141 setConjunction(TNorm * tnorm)142 void RuleBlock::setConjunction(TNorm* tnorm) { 143 this->_conjunction.reset(tnorm); 144 } 145 getConjunction() const146 TNorm* RuleBlock::getConjunction() const { 147 return this->_conjunction.get(); 148 } 149 setDisjunction(SNorm * snorm)150 void RuleBlock::setDisjunction(SNorm* snorm) { 151 this->_disjunction.reset(snorm); 152 } 153 getDisjunction() const154 SNorm* RuleBlock::getDisjunction() const { 155 return this->_disjunction.get(); 156 } 157 setImplication(TNorm * implication)158 void RuleBlock::setImplication(TNorm* implication) { 159 this->_implication.reset(implication); 160 } 161 getImplication() const162 TNorm* RuleBlock::getImplication() const { 163 return this->_implication.get(); 164 } 165 setActivation(Activation * activation)166 void RuleBlock::setActivation(Activation* activation) { 167 this->_activation.reset(activation); 168 } 169 getActivation() const170 Activation* RuleBlock::getActivation() const { 171 return this->_activation.get(); 172 } 173 setEnabled(bool enabled)174 void RuleBlock::setEnabled(bool enabled) { 175 this->_enabled = enabled; 176 } 177 isEnabled() const178 bool RuleBlock::isEnabled() const { 179 return this->_enabled; 180 } 181 toString() const182 std::string RuleBlock::toString() const { 183 return FllExporter().toString(this); 184 } 185 186 /** 187 * Operations for std::vector _rules 188 */ addRule(Rule * rule)189 void RuleBlock::addRule(Rule* rule) { 190 _rules.push_back(rule); 191 } 192 insertRule(Rule * rule,std::size_t index)193 void RuleBlock::insertRule(Rule* rule, std::size_t index) { 194 _rules.insert(_rules.begin() + index, rule); 195 } 196 getRule(std::size_t index) const197 Rule* RuleBlock::getRule(std::size_t index) const { 198 return _rules.at(index); 199 } 200 removeRule(std::size_t index)201 Rule* RuleBlock::removeRule(std::size_t index) { 202 Rule* result = _rules.at(index); 203 _rules.erase(_rules.begin() + index); 204 return result; 205 } 206 numberOfRules() const207 std::size_t RuleBlock::numberOfRules() const { 208 return _rules.size(); 209 } 210 rules() const211 const std::vector<Rule*>& RuleBlock::rules() const { 212 return this->_rules; 213 } 214 setRules(const std::vector<Rule * > & rules)215 void RuleBlock::setRules(const std::vector<Rule*>& rules) { 216 this->_rules = rules; 217 } 218 rules()219 std::vector<Rule*>& RuleBlock::rules() { 220 return this->_rules; 221 } 222 clone() const223 RuleBlock* RuleBlock::clone() const { 224 return new RuleBlock(*this); 225 } 226 227 } 228