Exemplo n.º 1
0
 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())
             ss << " " << Rule::andKeyword() << " ";
     }
     return ss.str();
 }
Exemplo n.º 2
0
 void Consequent::unload() {
     for (std::size_t i = 0; i < conclusions().size(); ++i) {
         delete conclusions().at(i);
     }
     conclusions().clear();
 }
Exemplo n.º 3
0
    void Consequent::load(const std::string& consequent, const Engine* engine) {
        unload();
        setText(consequent);

        if (Op::trim(consequent).empty()) {
            throw Exception("[syntax error] consequent is empty", FL_AT);
        }

        /**
         Extracts the list of propositions from the consequent
         The rules are:
         1) After a variable comes 'is' or '=',
         2) After 'is' comes a hedge or a term
         3) After a hedge comes a hedge or a term
         4) After a term comes operators 'and' or 'with'
         5) After operator 'and' comes a variable
         6) After operator 'with' comes a float
         */
        enum FSM {
            S_VARIABLE = 1, S_IS = 2, S_HEDGE = 4, S_TERM = 8,
            S_AND = 16, S_WITH = 32
        };
        int state = S_VARIABLE;

        Proposition* proposition = fl::null;

        std::stringstream tokenizer(consequent);
        std::string token;
        try {
            while (tokenizer >> token) {
                if (state bitand S_VARIABLE) {
                    if (engine->hasOutputVariable(token)) {
                        proposition = new Proposition;
                        proposition->variable = engine->getOutputVariable(token);
                        conclusions().push_back(proposition);
                        state = S_IS;
                        continue;
                    }
                }

                if (state bitand S_IS) {
                    if (token == Rule::isKeyword()) {
                        state = S_HEDGE bitor S_TERM;
                        continue;
                    }
                }

                if (state bitand S_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;
                    }
                }

                if (state bitand S_TERM) {
                    if (proposition->variable->hasTerm(token)) {
                        proposition->term = proposition->variable->getTerm(token);
                        state = S_AND bitor S_WITH;
                        continue;
                    }
                }

                if (state bitand S_AND) {
                    if (token == Rule::andKeyword()) {
                        state = S_VARIABLE;
                        continue;
                    }
                }

                //if reached this point, there was an error:
                if (state bitand S_VARIABLE) {
                    std::ostringstream ex;
                    ex << "[syntax error] consequent expected output variable, but found <" << token << ">";
                    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 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 Exception(ex.str(), FL_AT);
                }

                if ((state bitand S_AND) or (state bitand S_WITH)) {
                    std::ostringstream ex;
                    ex << "[syntax error] consequent expected operator <" << Rule::andKeyword() << "> "
                            << "or keyword <" << Rule::withKeyword() << ">, "
                            << "but found <" << token << ">";
                    throw Exception(ex.str(), FL_AT);
                }

                std::ostringstream ex;
                ex << "[syntax error] unexpected token <" << token << "> in consequent";
                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 Exception(ex.str(), FL_AT);
                }
                if (state bitand S_IS) {
                    std::ostringstream ex;
                    ex << "[syntax error] consequent expected keyword <" << Rule::isKeyword() << "> "
                            "after <" << token << ">";
                    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 Exception(ex.str(), FL_AT);
                }
            }
        } catch (...) {
            unload();
            throw;
        }
    }
Exemplo n.º 4
0
 bool Consequent::isLoaded() {
     return not conclusions().empty();
 }