Пример #1
0
MLNetNode::MLNetNode(
    const MLNetNode* prev,
    int ifrom,
    int nword,
    int tot_len,
    const MCollect<MLProjJob*> &proj,
    const MCollect<MLProjList*> &job_list,
    const MCollect<int> &word_job,
    const MCollect<Lexem> &words,
    Dictionary &dict
)
{
    // Наш узел описывает мультилексемы, начнающиеся с позиции ifrom и
    // содержащие nword лексем.
    previous = prev;
    from = ifrom;
    n = nword;

    const int njob = CastSizeToInt(job_list.size());

    // Собираем пробные мультилексемы, начиная с позиции from предложения.
    // Общая длина предложения задана как tot_len, максимальная длина
    // создаваемых мультилексем равна max_ml_len. Информация о пробных
    // мультилексемах будет хранится в подключаемых узлах.
    const int iFrom = ifrom + nword; // Индекс начала следующих мультилексем.

    if (iFrom == tot_len)
        return;

    int IPROJ_found = UNKNOWN;
    bool PROJ_found = false;

    int max_ml_len = dict.GetSynGram().IsMultiLexemBegin(words[iFrom]);
    if (max_ml_len <= 0)
        max_ml_len = 1;

    Lexem ml;

    SynGram &sg = dict.GetSynGram();

    for (int len = 1; len <= max_ml_len && (iFrom + len) <= tot_len; len++)
    {
        if (len == 1)
        {
            PROJ_found = true;

            const int m0 = tot_len - iFrom;
            const int m1 = std::min(m0, max_ml_len);
            if (m1 == 2)
            {
                if (!sg.IsWordForm(words[iFrom]))
                {
                    ml = words[iFrom];
                    ml.Add(words[iFrom + 1]);
                    if (sg.IsMultiLexem(ml))
                        continue;
                }
                else if (!sg.IsWordForm(words[iFrom + 1]))
                {
                    ml = words[iFrom];
                    ml.Add(words[iFrom + 1]);
                    if (sg.IsMultiLexem(ml))
                        continue;
                }
            }
            else if (m1 == 3)
            {
                ml = words[iFrom];
                ml.Add(words[iFrom + 1]);
                ml.Add(words[iFrom + 2]);
                if (sg.IsMultiLexem(ml))
                {
                    ml = words[iFrom + 1];
                    ml.Add(words[iFrom + 2]);
                    if (!sg.IsMultiLexem(ml))
                    {
                        if (!sg.IsWordForm(words[iFrom + 1]) || !sg.IsWordForm(words[iFrom + 2]))
                            continue;
                    }
                }
            }
        }
        else
        {
            PROJ_found = false;
            IPROJ_found = UNKNOWN;

            ml.clear();
            for (int ii = 0; ii < len; ii++)
                ml.Add(words[iFrom + ii]);

            if (dict.GetSynGram().IsMultiLexem(ml))
            {
                // Если в списке job_list заданий на проекцию мультилексем фразоблока
                // удастся найти задание для нашей мультилексемы и эта мультилексема
                // хоть раз спроецирована, то имеет смысл продолжать построение сети
                // далее.
                for (int ijob = 0; ijob < njob; ijob++)
                {
                    if (
                        *(job_list[ijob]->GetContent()) == ml &&
                        job_list[ijob]->IsProjected()
                        )
                    {
                        PROJ_found = true;
                        IPROJ_found = ijob;
                        break;
                    }
                }
            }
        }

        if (!PROJ_found)
            continue;

        MLNetNode *to_add = new MLNetNode(
            this,
            iFrom,
            len,
            tot_len,
            proj,
            job_list,
            word_job,
            words,
            dict
        );

        child.push_back(to_add);

        // Выставим для узла to_add значение достоверности и индекса задания на
        // проекцию.
        if (len == 1)
        {
            const MLProjJob &prj = *proj[word_job[iFrom]];
            to_add->val = prj.GetVal();
            to_add->proj_job_i = prj.GetiJob();

            //mout.printf( "ml=%us val=%f\n",  proj[word_job[iFrom]].GetContent()->string().c_str(), prj.GetVal().GetFloat() );
        }
        else
        {
            Real1 VAL(100);
            to_add->val = VAL;
            to_add->proj_job_i = IPROJ_found;
        }
    }

    return;
}