Exemple #1
0
std::string NodeTree::generateNodeName(NodeTypeID typeID) const
{
    // Generate unique name - defaultNodeName() method guarantees there won't be any '/' char
    std::string defaultNodeTitle = _nodeSystem->defaultNodeName(typeID);
    std::string nodeTitle = defaultNodeTitle;
    int num = 1;
    while(resolveNode(nodeTitle) != InvalidNodeID)
    {
        nodeTitle = defaultNodeTitle + " " + std::to_string(num);
        ++num;
    }
    return nodeTitle;
}
Exemple #2
0
QString AIMLParser::getResponse(QString input, QList<long> &categoriesId, const bool &srai)
{
    //debug
    if (srai)
        _indent ++;

    QString indentSpace = QString().fill(' ', 2*_indent);
    _logStream << (!srai ? "\n" : "") + indentSpace + (srai ? "::SRAI: " : "::User Input: ") +
        input + "\n";

    //perform substitutions for input string
    QVALUELIST_CLASSNAME<QRegExp>::Iterator itOld = _subOld.begin();
    QStringList::Iterator itNew = _subNew.begin();
    for (; itOld != _subOld.end(); ++itOld, ++itNew )
        input.replace(*itOld, *itNew);

    if (!srai)
    {
        _inputList.prepend(input);
        if (_inputList.count() > MAX_LIST_LENGTH)
            _inputList.pop_back();
    }

    QStringList capturedTexts, capturedThatTexts, capturedTopicTexts;
    QString curTopic = _parameterValue["topic"];
    normalizeString(curTopic);

    _logStream << "::Current Topic: " << curTopic;

    Leaf *leaf = NULL;
    QString result("");
    QStringList sentences = QStringList::split(QRegExp("[\\.\\?!,;\\x061f]"), input);
    QStringList::Iterator sentence = sentences.begin();

    while (sentence != sentences.end())
    {
        if (sentence != sentences.begin())
            result += " ";

        //normalizeString(*sentence);
        *sentence = (*sentence).lower();
        QStringList inputWords = QStringList::split(' ', *sentence);
        QStringList::ConstIterator it = inputWords.begin();

        if (!_root.match(it, inputWords, _thatList.count() && _thatList[0].count() ?
            _thatList[0][0] : QString(""), curTopic, capturedThatTexts, capturedTopicTexts, categoriesId, &leaf)) {

            // start lvk - force match with current topic, if no match retry without topic
            if (curTopic.isEmpty()) {
            // end lvk
                return "Internal Error!";
            // start lvk - force match with current topic, if no match retry without topic
            } else {
                _parameterValue["topic"] = "";
                return getResponse(input, categoriesId, srai);
            }
            // end lvk
        }

        Node *parentNode = leaf->parent;
        QString matchedPattern = parentNode->word;

        while (parentNode->parent->parent)
        {
            parentNode = parentNode->parent;
            matchedPattern = parentNode->word + " " + matchedPattern;
        }

        _logStream << indentSpace + "::Matched pattern: [" + matchedPattern + "]";

        if (!leaf->that.isEmpty())
           _logStream << " - Matched that: [" + leaf->that + "]";
        if (!leaf->topic.isEmpty())
           _logStream << " - Matched topic: [" + leaf->topic + "]";
        _logStream << "\n";

        capturedTexts.clear();
        exactMatch(matchedPattern, *sentence, capturedTexts);

        //strip whitespaces from the beggining and the end of result
        if (_visitedNodeList.contains(&leaf->tmplate))
            result += "ProgramQ: Infinite loop detected!";
        else
        {
            _visitedNodeList.append(&leaf->tmplate);
            categoriesId.append(leaf->id);
            result += resolveNode(&leaf->tmplate, categoriesId, capturedTexts, capturedThatTexts, capturedTopicTexts).stripWhiteSpace();
        }

        ++sentence;
    }

    if (!srai)
    {
        QString tempResult = result.simplifyWhiteSpace();
        //get the sentences of the result splitted by: . ? ! ; and "arabic ?"
        QStringList thatSentencesList = QStringList::split(QRegExp("[\\.\\?!;\\x061f]"), tempResult);
        QStringList inversedList;
        for (QStringList::Iterator it = thatSentencesList.begin(); it != thatSentencesList.end(); ++it)
        {
            //perform substitutions for that string
            itOld = _subOld.begin();
            itNew = _subNew.begin();
            for (; itOld != _subOld.end(); ++itOld, ++itNew )
                tempResult.replace(*itOld, *itNew);
            normalizeString(*it);
            inversedList.prepend(*it);
        }
        _thatList.prepend(inversedList);
        if (_thatList.count() > MAX_LIST_LENGTH)
            _thatList.pop_back();
        _visitedNodeList.clear();
    }

    //debug
    _logStream << indentSpace + "::Result: " + result + "\n";
    if (srai)
        _indent --;

    return result;
}
Exemple #3
0
//recursively replace all the values & return the QString result
QString AIMLParser::resolveNode(QDomNode* node, QList<long> &categoriesId, const QStringList &capturedTexts,
    const QStringList &capturedThatTexts, const QStringList &capturedTopicTexts)
{
    QString result("");
    QString nodeName = node->nodeName();
    QDomElement element = node->toElement();
    if (nodeName == "random")
    {
        QVALUELIST_CLASSNAME<QDomNode> childNodes = elementsByTagName(node, "li");
        uint childCount = childNodes.count();
        uint random = rand() % childCount;
        QDomNode child = childNodes[random];
        result = resolveNode(&child, categoriesId, capturedTexts, capturedThatTexts, capturedTopicTexts);
    }
    else if (nodeName == "condition")
    {
        QString name("");
        uint condType = 2;
        if (element.hasAttribute("name"))
        {
            condType = 1;
            name = element.attribute("name");
            if (element.hasAttribute("value"))
            {
                condType = 0;
                QString value = element.attribute("value").upper();
                QStringList dummy;
                if (exactMatch(value, _parameterValue[name].upper(), dummy))
                {
                    //dirty trick to avoid infinite loop !
                    element.setTagName("parsedCondition");
                    result = resolveNode(&element, categoriesId, capturedTexts, capturedThatTexts, capturedTopicTexts);
                    element.setTagName("condition");
                }
            }
        }
        if (condType)
        {
            QVALUELIST_CLASSNAME<QDomNode> childNodes = elementsByTagName(node, "li");
            for (int i = 0; i < childNodes.count(); i++)
            {
                QDomNode n = childNodes[i];
                if (n.toElement().hasAttribute("value"))
                {
                    if (condType == 2)
                        name = n.toElement().attribute("name");
                    QString value = n.toElement().attribute("value").upper();
                    QStringList dummy;
                    if (exactMatch(value, _parameterValue[name].upper(), dummy))
                    {
                        result = resolveNode(&n, categoriesId, capturedTexts, capturedThatTexts, capturedTopicTexts);
                        break;
                    }
                }
                else
                {
                    result = resolveNode(&n, categoriesId, capturedTexts, capturedThatTexts, capturedTopicTexts);
                    break;
                }
            }
        }
    }
    else
    {
        QDomNode n = node->firstChild();
        while (!n.isNull())
        {
            result += resolveNode(&n, categoriesId, capturedTexts, capturedThatTexts, capturedTopicTexts);
            n = n.nextSibling();
        }
        if (node->isText())
            result = node->toText().nodeValue();
        else if (nodeName == "set")
            _parameterValue[element.attribute("name")] = result.stripWhiteSpace();
        else if (nodeName == "srai")
            result = getResponse(result, categoriesId, true);
        else if (nodeName == "think")
            result = "";
        else if (nodeName == "system")
            //lvk: Remvoved for security reasons
            //result = executeCommand(result);
            ;
        else if (nodeName == "learn")
        {
            loadAiml(result);
            result = "";
        }
        else if (nodeName == "uppercase")
        {
            result = result.upper();
        }
        else if (nodeName == "lowercase")
        {
            result = result.lower();
        }
        else if (!node->hasChildNodes())
        {
            if (nodeName == "star")
            {
                int index = element.attribute("index", "1").toUInt() - 1;
                result = index < capturedTexts.count() ? capturedTexts[index] : QString("");
            }
            else if (nodeName == "thatstar")
            {
                int index = element.attribute("index", "1").toUInt() - 1;
                result = index < capturedThatTexts.count() ? capturedThatTexts[index] : QString("");
            }
            else if (nodeName == "topicstar")
            {
                int index = element.attribute("index", "1").toUInt() - 1;
                result = index < capturedTopicTexts.count() ? capturedTopicTexts[index] : QString("");
            }
            else if (nodeName == "that")
            {
                QString indexStr = element.attribute("index", "1,1");
                if (!indexStr.contains(","))
                   indexStr = "1," + indexStr;
                int index1 = indexStr.section(',', 0, 0).toInt()-1;
                int index2 = indexStr.section(',', 1, 1).toInt()-1;
                result = (index1 < _thatList.count()) && (index2 < _thatList[index1].count()) ?
                   _thatList[index1][index2] : QString("");
            }
            else if (nodeName == "sr")
                result = getResponse(capturedTexts.count() ? capturedTexts[0] : QString(""), categoriesId, true);
            else if ( (nodeName == "br") || (nodeName == "html:br") )
                result = "\n";
            else if ( nodeName == "get" )
                result = _parameterValue[element.attribute("name")];
            else if ( nodeName == "bot")
                result = _botVarValue[element.attribute("name")];
            else if ( (nodeName == "person") || (nodeName == "person2") || (nodeName == "gender") )
                result = capturedTexts.count() ? capturedTexts[0] : QString("");
            else if (nodeName == "input")
            {
                int index = element.attribute("index", "1").toUInt() - 1;
                result = index < _inputList.count() ? _inputList[index] : QString("");
            }
            //the following just to avoid warnings !
            else if (nodeName == "li")
                ;
            else
                _logStream << "Warning: unknown tag \"" + nodeName + "\"\n";
        }
        //the following just to avoid warnings !
        else if ((nodeName == "template") || (nodeName == "pattern") || (nodeName == "li")
                 || (nodeName == "person") || (nodeName == "person2") || (nodeName == "gender")
                 || (nodeName == "parsedCondition"))
            ;
        else
            _logStream << "Warning: unknown tag \"" + nodeName + "\"\n";
    }
    return result;
}
Exemple #4
0
//parses a category and creates a correspondant element
void AIMLParser::parseCategory(QDomNode* categoryNode)
{
    QDomNode patternNode = categoryNode->namedItem("pattern");

    QList<long> categoriesId;
    QString pattern = resolveNode(&patternNode, categoriesId);
    normalizeString(pattern);

    //find where to insert the new node

    Node *whereToInsert = &_root;
    QStringList words = QStringList::split(' ', pattern);

    for ( QStringList::ConstIterator it = words.begin(); it != words.end(); ++it )
    {
        bool found = false;
        for (Node* child = whereToInsert->childs.first(); child; child = whereToInsert->childs.next())
        {
            if (child->word == *it)
            {
                whereToInsert = child;
                found = true;
                break;
            }
        }
        if (!found)
        {
            for (; it != words.end(); ++it )
            {
                Node *n = new Node;
                n->word = *it;
                n->parent = whereToInsert;
                int index = 0;
                if (*it == "*")
                   index = whereToInsert->childs.count();
                else if ((*it != "_") && whereToInsert->childs.count() &&
                   (whereToInsert->childs.at(0)->word == "_"))
                   index = 1;
                whereToInsert->childs.insert(index, n);
                whereToInsert = n;
            }
            break;
        }
    }

    //Now insert the leaf

    Leaf *leaf = new Leaf;
    leaf->parent = whereToInsert;

    // lvk extension
    QDomNode idNode = categoryNode->namedItem("id");
    if (!idNode.isNull())
    {
        leaf->id = idNode.firstChild().toText().nodeValue().toInt();
    }
    // end lvk extension

    QDomNode thatNode = categoryNode->namedItem("that");
    if (!thatNode.isNull())
    {
        leaf->that = thatNode.firstChild().toText().nodeValue();
        normalizeString(leaf->that);
    }

    leaf->tmplate = categoryNode->namedItem("template");

    QDomNode parentNode = categoryNode->parentNode();
    if (!parentNode.isNull() && (parentNode.nodeName() == "topic"))
    {
        leaf->topic = parentNode.toElement().attribute("name");
        normalizeString(leaf->topic);
    }

    int index = 0;
    int leafWeight = !leaf->that.isEmpty() + !leaf->topic.isEmpty() * 2;
    for (Leaf* childLeaf = whereToInsert->leafs.first(); childLeaf;
        childLeaf = whereToInsert->leafs.next())
    {
        int childLeafWeight = !childLeaf->that.isEmpty() + !childLeaf->topic.isEmpty() * 2;
        if (leafWeight >= childLeafWeight)
           break;
       index++;
    }
    whereToInsert->leafs.insert(index, leaf);
}