void CPrimitiveGroup::SetActiveSymbol(int iS)
{
    CGroup::SetActiveSymbol(iS);
    for (CWord::SHomIt it = m_pWord->IterHomonyms(); it.Ok32(); ++it)
        if (it->HasTerminalSymbol(iS))
            m_ActiveHomonyms |= (1 << it.GetID());

    ResetGrammems();
}
bool CAnalyticFormBuilder::CheckAnalyticalVerbForm(int iVWrd, int iSWrd)
{
    int VerbHomNo;
    yvector<int> AnalyticHom;

    bool b_AddAuxVerbHom;
    if (!IsAnalyticalVerbForm(iVWrd, iSWrd, VerbHomNo, AnalyticHom, b_AddAuxVerbHom))
        return false;

    if (AnalyticHom.size() == 0)
        return false;

    CWord& _Be = m_Words.GetWord(m_ClauseWords.at(iVWrd));
    CWord& _Predik = m_Words.GetWord(m_ClauseWords.at(iSWrd));

    //nim: в версии Диалинга у потенциального предиката (второй компоненты аналитической формы)
    //удалялись все омонимы, которые не могли образовать настоящую аналитическую форму,
    //например, для "хорошо" удалялись омонимы "Н" и "ЧАСТ".
    //в текущей версии покамест оставляем все омонимы. :nim

    for (size_t j = 0; j < AnalyticHom.size(); j++) {
        ChangeGrammemsAsAnalyticForm(_Predik.GetRusHomonym(AnalyticHom[j]), _Be.GetRusHomonym(VerbHomNo));
    }

    if (b_AddAuxVerbHom) {
        THomonymPtr pAuxHom = _Be.GetRusHomonym(VerbHomNo).Clone();
        pAuxHom->Grammems.Add(gAuxVerb);
        _Be.AddRusHomonym(pAuxHom);
        VerbHomNo = _Be.HasPOSi(gAuxVerb);
    } else
        _Be.GetRusHomonym(VerbHomNo).Grammems.Add(gAuxVerb);

    //удаляются омонимы не AuxVerb
    //так для слф. "были" будет убит омоним "быль"
    //пример: "были спровоцированы скандалы"
    yvector<int> HomsToDel;
    for (CWord::SHomIt it = _Be.IterHomonyms(); it.Ok(); ++it)
        if (!it->HasGrammem(gAuxVerb))
            HomsToDel.push_back(it.GetID());

    YASSERT(HomsToDel.size() < _Be.GetRusHomonymsCount());
    for (size_t i = 0; i < HomsToDel.size(); ++i)
        _Be.DeleteHomonym(HomsToDel[i]);
    //так как если вызывается из фрагментации и с синтаксисом, то
    //уже все символы были построены, а мы удаляем омоним с приписанными терминалами
    _Be.UniteHomonymsTerminalSymbols();
    for (size_t j = 0; j < AnalyticHom.size(); j++)
        _Predik.GetRusHomonym(AnalyticHom[j]).SetAnalyticMainVerbHom(&(_Be.GetRusHomonym(VerbHomNo)));

    return true;
}
static bool FindBestHomonym(const CWord& word, TWtringBuf lemma, TKeyWordType kwtype, THomonymGrammems grammems, int& homId) {
    // search if we already have a multiword homonym with such text
    bool found = false;
    bool foundSameKwType = false;
    for (CWord::SHomIt it = word.IterHomonyms(); it.Ok(); ++it)
        if (it->CHomonymBase::GetLemma() == lemma) {
            if (it->HasKWType(kwtype, KW_DICT)) {
                if (it->Grammems == grammems) {
                    homId = it.GetID();     // prefer homonyms with same kwtype and same grammems
                    return true;
                } else if (!foundSameKwType) {
                    homId = it.GetID(); // prefer homonyms with same kwtype
                    found = true;
                    foundSameKwType = true;
                }
            } else  if (!found) {
                homId = it.GetID();   // otherwise, return the first one having @lemma text
                found = true;
            }
        }

    return found;
}
//check an agreement between aux. verbs and predicates of analitical form.
bool CAnalyticFormBuilder::IsAnalyticalVerbForm(int iVerbWrd, int iSWrd, int& VerbHomNo,
                                                yvector<int>& AnalyticHom, bool& b_AddAuxVerbHom)
{
    b_AddAuxVerbHom = false;
    AnalyticHom.clear();

    const CWord& _Be = m_Words.GetWord(m_ClauseWords.at(iVerbWrd));
    const CWord& _Predik = m_Words.GetWord(m_ClauseWords.at(iSWrd));

    //с предикативными значениями "много" и "мало" анал. форм не строить : DIALING
    //с предикативными значениями "много" и "мало" анал. форм строится, но клонируется омоним для вспомогательного глагола
    //if ( ( m_Words[iSWrd].FindLemma("МНОГО") || m_Words[iSWrd].FindLemma("МАЛО") ) && ... )
    if (_Predik.HasPOS(gNumeral) && _Predik.HasPOS(gPraedic))
            b_AddAuxVerbHom = true;

    //14.07.04: отсутствие синтаксиса порождает заплатку:
    //если у потенциального предиката есть омоним Noun, то добавить омоним AuxVerb для вспомогательного глагола,
    //в противном случае, просто изменить часть речи на AuxVerb.
    if (_Predik.HasMorphNoun())
        b_AddAuxVerbHom = true;

    //masks used later (to avoid constructing them repeatedly in loop)
    const TGramBitSet Verb_Infinitive(gVerb, gInfinitive),
                      Infinitive_Imperfect(gInfinitive, gImperfect),
                      Person3_Singular(gPerson3, gSingular),
                      Infinitive_Gerund(gInfinitive, gGerund);

    for (CWord::SHomIt it = _Be.IterHomonyms(); it.Ok(); ++it) {
        VerbHomNo = it.GetID();
        const CHomonym& VerbHom = _Be.GetRusHomonym(VerbHomNo);

        if (VerbHom.Lemma == kByt || (VerbHom.Lemma == kStat && VerbHom.HasAnyOfPOS(Verb_Infinitive))) {
            for (CWord::SHomIt it_predik = _Predik.IterHomonyms(); it_predik.Ok(); ++it_predik) {
                int j = it_predik.GetID();

                const CHomonym& ShortFormHom = _Predik.GetRusHomonym(j);
                if (ShortFormHom.Grammems.HasAll(Infinitive_Imperfect) && (VerbHom.IsFutureTense() || VerbHom.Lemma == kStat))
                    AnalyticHom.push_back(j);

                else if ((ShortFormHom.HasGrammem(gPraedic)) &&
                         (VerbHom.HasGrammem(gNeuter) || (VerbHom.IsFutureTense() && VerbHom.Grammems.HasAll(Person3_Singular))))
                    AnalyticHom.push_back(j);

                else if (ShortFormHom.HasGrammem(gComparative) && ShortFormHom.IsFullAdjective())
                    AnalyticHom.push_back(j);

                else if (ShortFormHom.IsShortAdjectiveOrParticiple()) {
                    // "была", "стал", "был", "было" ...
                    if ((VerbHom.HasGrammem(gSingular) && VerbHom.IsPastTense() &&
                         ShortFormHom.HasGrammem(gSingular) &&
                         (VerbHom.Grammems.All() & ShortFormHom.Grammems.All()).HasAny(NSpike::AllGenders))
                        || (VerbHom.HasGrammem(gPlural) && ShortFormHom.HasGrammem(gPlural))
                        || (!VerbHom.IsPastTense() && VerbHom.HasGrammem(gSingular) && ShortFormHom.HasGrammem(gSingular))
                        || VerbHom.Grammems.HasAny(Infinitive_Gerund))

                        AnalyticHom.push_back(j);
                }
            }
            return AnalyticHom.size() > 0;
        }
    }
    return false;
}