void AddSynVariantsWithUnusedHomonyms(CClause& C, vector<CBuildingUnit>& BuildingUnits) { CMorphVariant synVariant(C.GetOpt()->GetGramTab()); bool FoundUnusedHomonym; do { FoundUnusedHomonym = false; for (int UnitNo=0; UnitNo < BuildingUnits.size();UnitNo++) { int HomonymNo = 0; if (BuildingUnits[UnitNo].m_MaxUsedHomonymNo+1 < BuildingUnits[UnitNo].m_HomonymsCount) { BuildingUnits[UnitNo].m_MaxUsedHomonymNo++; HomonymNo = BuildingUnits[UnitNo].m_MaxUsedHomonymNo; FoundUnusedHomonym = true; }; if (BuildingUnits[UnitNo].m_ChildClauseNo != -1) AddUnitAsClause(BuildingUnits.begin()+UnitNo, HomonymNo, C, synVariant); else AddUnitAsWord(BuildingUnits.begin()+UnitNo, HomonymNo, C, synVariant); }; if (FoundUnusedHomonym) { if (C.IsGoodVariant(synVariant)) C.m_SynVariants.push_back(synVariant); synVariant.Reset(); }; } while (FoundUnusedHomonym); };
static void TranslateCoordClauseForGroup(const CClause& C, CGroup& pGrp) { pGrp.m_iFirstWord = C.UnitNoByWordNo(pGrp.m_iFirstWord); pGrp.m_iLastWord = C.UnitNoByWordNo(pGrp.m_iLastWord); pGrp.m_MainGroup.m_iFirstWord = C.UnitNoByWordNo(pGrp.m_MainGroup.m_iFirstWord); pGrp.m_MainGroup.m_iLastWord = C.UnitNoByWordNo(pGrp.m_MainGroup.m_iLastWord); pGrp.m_MainWordNo = C.UnitNoByWordNo(pGrp.m_MainWordNo); }
/* Эта функция вызывается только из RuleForEmptyClauses. Проверяет, может ли клауза войти в левостоящую. Если не может, тогда возвращает истину. */ bool CRusSentence::HasStrictBorderLeft(int iClauseNum) { CClause* pAbstClause = &GetClause(iClauseNum); if( HasStrictestLeftClauseBorder(iClauseNum) ) return true; if( iClauseNum == 0) return true; if( pAbstClause->HasLeftStarter() ) return true; return false; }
int HasSubConjWithInfinitiveGovernment(const CClause& C) { for(int i = 0; i < C.m_vectorConjs.size() ; i++ ) { const SConjIndex& conj = C.m_vectorConjs[i]; if( (conj.m_FromWhere == FROM_OBOR_DIC) && (C.GetOpt()->m_pOborDic->m_Entries[conj.m_index].m_ConjType == sub_conj) && (C.GetOpt()->m_pOborDic->m_Entries[conj.m_index].m_bConjWithInfinitiveSubord) ) return i; } return -1; }
int AddUnitAsWord (vector<CBuildingUnit>::const_iterator pUnit, int CurrentHomonymNo, const CClause& C, CMorphVariant& synVariant) { synVariant.PushHomonymNum(CurrentHomonymNo); const CSynWord& W = C.GetWords()[pUnit->m_WordNo]; synVariant.m_SynUnits.back().CopyAncodePattern( W.m_Homonyms[CurrentHomonymNo] ); synVariant.m_SynUnits.back().m_SentPeriod = CPeriod(pUnit->m_WordNo); return pUnit->m_WordNo+1; };
void CreateGroupsForTermins(CClause& C, CFormatCaller& FormatCaller, CMorphVariant& synVariant) { vector<int> SynVarHomonyms; for (int j = 0; j < synVariant.GetUnitsCount(); j++) SynVarHomonyms.push_back( synVariant.GetHomNum(j) ); FormatCaller.BuildOborotGroups(); for (size_t TerminNo=0; TerminNo< C.m_pSent->m_vectorTermins.size(); TerminNo++) { SFoundTermin T = C.m_pSent->m_vectorTermins[TerminNo]; if (!T.is_part_of(C)) continue; T.m_iFirstWord = C.UnitNoByWordNo(T.m_iFirstWord); T.m_iLastWord = C.UnitNoByWordNo(T.m_iLastWord); // вставлено из-за примера "печатной информации, фильмов, компьютерных банков данных, ничего. " /* bool bSubClause = false; for (size_t i=T.m_iFirstWord; i <= T.m_iLastWord; i++) if (FormatCaller.sent[i].m_UnitType == EClause) { bSubClause = true; break; } if (bSubClause) continue;*/ if (FormatCaller.create_groups_from_termin( T)) { C.m_pSent->m_vectorTermins[TerminNo].m_bGroupsChecked = true; /*int WordNo = 0; for (int UnitNo = T.m_iFirstWord; UnitNo <= T.m_iLastWord; UnitNo++, WordNo++) { CSynWord& W = C.GetWords()[C.m_pSent->m_vectorTermins[TerminNo].m_iFirstWord+WordNo]; //W.SetAllOtherHomsDel(SynVarHomonyms[UnitNo]); }; */ } }; };
int AddUnitAsClause (vector<CBuildingUnit>::const_iterator pUnit, int CurrentHomonymNo, const CClause& C, CMorphVariant& synVariant) { const CClause& Child = C.m_pSent->m_Clauses[pUnit->m_ChildClauseNo]; CSynUnit SClauseHomonym(C.GetOpt()->GetGramTab()); SClauseHomonym.m_Type = EClause; SClauseHomonym.m_iClauseTypeNum = (CurrentHomonymNo >= Child.m_vectorTypes.size())? -1 : CurrentHomonymNo; SClauseHomonym.m_SentPeriod = (CPeriod)Child; synVariant.m_SynUnits.push_back(SClauseHomonym); return Child.m_iLastWord + 1; };
tstring CLogicThread::GetErrorText(int32 CharPos) { tstring s; deque<CSentence*>::reverse_iterator SentenceIt = m_Text.m_SentenceList.rbegin(); while(SentenceIt!=m_Text.m_SentenceList.rend() && CharPos< (*SentenceIt)->m_BeginPos )SentenceIt++; if(SentenceIt == m_Text.m_SentenceList.rend())return s; CSentence* Sentence = *SentenceIt; //再找到当前逻辑场景所包含的句子,子句,Token CharPos = CharPos - Sentence->m_BeginPos; deque<CClause*>::reverse_iterator ClauseIt = m_Text.m_ClauseList.rbegin(); while(ClauseIt!=m_Text.m_ClauseList.rend() && CharPos< (*ClauseIt)->m_BeginPos )ClauseIt++; if(ClauseIt == m_Text.m_ClauseList.rend())return s; CClause* Clause = *ClauseIt; CharPos = CharPos- Clause->m_BeginPos; deque<CToken*>::reverse_iterator It = m_Text.m_TokenList.rbegin(); while(It!=m_Text.m_TokenList.rend() && CharPos< (*It)->m_BeginPos )It++; if(It == m_Text.m_TokenList.rend())return s; CToken* Token = *It; int i = 0; if(!Token->IsOK()){ i = Token->m_MemoryID; } else if(!Clause->IsOK()){ i = Clause->m_MemoryID; } assert(i<LAST_ERROR); s = ANALYSE_ERROR[i]; return s; }
int CGerSentence::GetCountOfStrongRoots(const CClause& C, const CMorphVariant& synVar) const { int iHypPredk = 0; int Infinitives = 0; bool bInfinitiveConstruction = false; for (int i = 0; i < synVar.GetUnitsCount(); i++) { if ( synVar.GetUnitType(i) == EClause ) continue; int iWord = synVar.m_SynUnits[i].m_SentPeriod.m_iFirstWord; const CSynHomonym& Hom = C.GetWords()[iWord].GetSynHomonym(synVar.GetHomNum(i)); if ( C.GetOpt()->GetGramTab()->IsStrongClauseRoot( Hom.m_iPoses ) ) { iHypPredk++; if (Hom.m_bInfinitiveConstruction) bInfinitiveConstruction = true; else if (Hom.HasGrammem(gInfinitiv) && Hom.HasPos(gVER)) Infinitives++; }; } if (iHypPredk > 1) if (bInfinitiveConstruction) iHypPredk -= max(1, iHypPredk-Infinitives); return iHypPredk; };
void CTopClauses::AddValsToSubClauses(CClauseNode* pNode, SClauseFuncArg& arg) { CClause* clause = pNode->GetMainClause(); clause->AddValsToType(arg.m_NewValencies2, arg.m_iClause2TypeNum); if (clause->m_ClauseWords.size() != 0) return; yvector<CClause*> clauses; pNode->m_pClauseTree->GetIncludedClauses(clauses); for (size_t i = 0; i < clauses.size(); i++) { CClause& cl = *clauses[i]; //такая заплатка: когда сочиняется клауза уже сочиненная и еще какая-то, //то новую валентность (обычно подлежащее) надо прописать и во все непосредственные подклаузы сочиняемой кл. if ((cl.GetTypesCount() == 1) && (arg.m_NewValencies2.size() == 1)) { if (!cl.GetType(0).HasSubjVal()) { SValency val = arg.m_NewValencies2[0]; val.m_ValNum = cl.FindSubjVal(0); if (val.m_ValNum > -1) cl.AddValToType(val, 0); } } } }
bool CRusSentence::RuleForEmptyClauses(int iClauseNum) { const CClause& Clause = GetClause(iClauseNum); int iWord = Clause.m_iFirstWord; if( !IsGoodEmptyClause( &Clause ) ) return false; bool bStrictPrevClauseBorder = HasStrictBorderLeft(iClauseNum); //берем тот фрагмент, который стоит справа от найденной цепочки // если в текущую клаузу была вложена другая клауза, которая заканчивается там же, где текущая клауза // тогда не будем добавлять пустыху направо (неоднозначность границ ), int iNext = GetMaxClauseByFirstWord(m_Clauses[iClauseNum].m_iLastWord+1); CClause* pAbstClauseRight = NULL; if( iNext != -1 ) pAbstClauseRight = &GetClause(iNext); bool bCanConnectRight = pAbstClauseRight && CanBeMainClauseOfTheLeftGoodEmptyClause(pAbstClauseRight, bStrictPrevClauseBorder) && (GetMinClauseByLastWord(Clause.m_iLastWord) == iClauseNum) && !HasStrictBorderLeft(iNext); //берем тот фрагмент, который стоит слева от найденной цепочки CClause* pAbstClauseLeft = NULL; int iPrev = GetMinClauseByLastWord(Clause.m_iFirstWord-1); if( iPrev != -1 ) pAbstClauseLeft = &GetClause(iPrev); // если предыщая клауза была вложена в другую клаузу, тогда не будем добавлять пустыху налево, // поскольку пустыха может войти обе клаузы (в меньшую и в большую"), // например: // "интервью, опубликованное в четверг, 12 апреля" // "12 апреля" надо вкладывать в причастный оборот // "упал кран, который нам подарили японцы, 12 апреля" // "12 апреля" надо вкладывать в главную клаузу // мы имеем здесь абсолютныю неоднозначноть bool bCanConnectLeft = pAbstClauseLeft && !pAbstClauseLeft->HasType(INP_T) && !Clause.HasLeftStarter() && !IsEnclosedClause(iPrev) && !HasStrictestLeftClauseBorder(iClauseNum); // соединение влево будем считать более приоритетным if(bCanConnectLeft) { /* если объединяется пустыха с инфинитивом, тогда тип объединенной клаузы должен быть инфинитовом если объединяется пустыха со сравном, тогда тип объединенной клаузы должен быть СРАВН */ if ( ( Clause.HasType(INFINITIVE_T) || Clause.HasType(COMPARATIVE_T) ) && pAbstClauseLeft->m_vectorTypes.empty() && 1 == pAbstClauseLeft->m_vectorTypes.size() ) UniteClauses(iPrev, iClauseNum, RightClauseParams); else UniteClauses(iPrev, iClauseNum, LeftClauseParams); return true; } if(bCanConnectRight) { UniteClauses(iClauseNum, iNext, RightClauseParams); return true; } return false; }
bool CRusSentence::RuleForParticiples(int iClauseNum) { CClause* pAbstClause = &GetClause(iClauseNum); int iWord = pAbstClause->m_iFirstWord; if ( IsEnclosedClause (iClauseNum) ) return false; if ( pAbstClause->HasUnambiguousStrongRootWithoutWeakHomonyms()) return false; int iParticipleType; if( (iParticipleType = pAbstClause->FindType(PARTICIPLE_T)) == -1 ) return false; assert(!pAbstClause->m_vectorTypes[iParticipleType].m_Root.IsEmpty()); CSynWord& pParticiple = m_Words[pAbstClause->m_vectorTypes[iParticipleType].m_Root.m_WordNo]; int iPart = pParticiple.GetHomonymByPOS(PARTICIPLE); if( iPart == -1 ) return false; //пытаемся найти слева int iPrev = FindNounFromTheLeftOfParticiple(pAbstClause, pParticiple.GetSynHomonym(iPart)); //пытаемся найти слева подходящее сущ.(тогда причастие после определяемого слова) if ( ( m_Words[iWord].m_SubordinateConjNo == -1 ) && ( (pAbstClause->m_iFirstWord != pAbstClause->m_iLastWord ) || ( (iWord+1<m_Words.size()) && (m_Words[iWord+1].m_SubordinateConjNo != -1 ) ) ) && (iPrev != -1) && ( pAbstClause->m_iLastWord+1 == m_Words.size() // проверка правой границы (должен быть знак препинания) || m_Words[pAbstClause->m_iLastWord+1].HasDes(OPun) ) ) { /* Поскольку мы собираемся вкладывать клаузу, нам приходится удалять все вершины клаузы, кроме найденного причастия и все омонимы причастия */ // уничтожаем другие вершины клаузы int k = 0; for( ; k < pAbstClause->m_vectorTypes.size() ; k++) { if(iParticipleType == k) continue; if(k < iParticipleType) iParticipleType--; int WordNo = pAbstClause->m_vectorTypes[k].m_Root.m_WordNo; // не будем удалять омоним, если он единственный у слова if (pAbstClause->GetWords()[WordNo].GetHomonymsCount() > 1) pAbstClause->DeleteHomonym(pAbstClause->m_vectorTypes[k].m_Root.m_WordNo, pAbstClause->m_vectorTypes[k].m_Root.m_HomonymNo); else pAbstClause->DeleteClauseType( k ); k--; } // заново надо найти омоними причастия, поскольку мы в предыдущем цикле удалили некоторые омонимы iPart = pParticiple.GetHomonymByPOS(PARTICIPLE); int PartWordNo = pAbstClause->m_vectorTypes[iParticipleType].m_Root.m_WordNo; // уничтожаем омонимы причастия (прилагательное или существительное), for(k = 0 ; k < pParticiple.GetHomonymsCount() ; k++) { if(iPart == k) continue; if(k < iPart) iPart--; pAbstClause->DeleteHomonym(PartWordNo, k); k--; } return EncloseClauseAsWord(iClauseNum, iPrev); } else // пытаемся найти справа (причастие не отделено запятой) if( FindNounFromTheRightOfParticiple(pAbstClause, pParticiple.GetSynHomonym(iPart) ) ) { // тогда нужно удалить клаузный вариант причастия, а если вариант только один, тогда // нужно его отконвертировать в пустыху if(pAbstClause->m_vectorTypes.size() == 1) { assert (pAbstClause->m_vectorTypes[0].m_Type == PARTICIPLE_T); pAbstClause->ChangeAllClauseTypesToOneType( SClauseType(UnknownSyntaxElement,-1,-1) ); } else { assert( iParticipleType >= 0); pAbstClause->DeleteClauseType( iParticipleType ); } } return false; }
void CClause::AssignVariantWeight(CMorphVariant& synVariant) { try { int iWeight = 0; // adding weight by each maximal group int i = synVariant.m_vectorGroups.GetGroups().size() - 1; bool bSubjIsInsideGroup = false; bool bPredicateIsInsideGroup = false; while( i >= 0 ) { const CGroup& group = synVariant.m_vectorGroups.GetGroups()[i]; CPeriod PeriodInSentenceCoords = synVariant.GetSentenceCoordinates(group); // if the last or the first word in the group is indeclinable, bool bStartsOrEndsWithIndeclinable = false; { const CSynUnit& UnitStart = synVariant.m_SynUnits[group.m_iFirstWord]; if ( (UnitStart.m_Type == EWord) && (GetOpt()->m_IndeclinableMask & GetWords()[PeriodInSentenceCoords.m_iFirstWord].m_Homonyms[UnitStart.m_iHomonymNum].m_iGrammems) ) bStartsOrEndsWithIndeclinable = true; const CSynUnit& UnitEnd = synVariant.m_SynUnits[group.m_iLastWord]; if ( (UnitEnd.m_Type == EWord) && (GetOpt()->m_IndeclinableMask & GetWords()[PeriodInSentenceCoords.m_iLastWord].m_Homonyms[UnitEnd.m_iHomonymNum].m_iGrammems) ) bStartsOrEndsWithIndeclinable = true; }; if ( GetOpt()->IsGroupWithoutWeight(group.m_GroupType, group.m_Cause ) || ( (group.size() == 2) && bStartsOrEndsWithIndeclinable ) ) { i--; // go to the subgroup or to the next group continue; }; // adding weight (size of the group in words) Note, that the group can contain a clause iWeight += PeriodInSentenceCoords.size(); // if the last or the first word in the group is indeclinable, if (bStartsOrEndsWithIndeclinable) iWeight--; if ( !synVariant.m_Subjects.empty() || CPeriod(synVariant.GetFirstSubject()).is_part_of(group) ) bSubjIsInsideGroup = true; if (CPeriod(synVariant.m_iPredk).is_part_of(group)) bPredicateIsInsideGroup = true; // go to the subclauses and add weight by each subclause for (long k=group.m_iFirstWord; k <= group.m_iLastWord; k++) if( synVariant.m_SynUnits[k].m_Type == EClause ) { CPeriod p = synVariant.m_SynUnits[k].m_SentPeriod; CClause* clause = m_pSent->FindClauseByPeriod(p); assert(clause != NULL); vector<CMorphVariant*> clause_vars = clause->GetSynVariantIndexesByTypeNum(synVariant.m_SynUnits[k].m_iClauseTypeNum); for (long j=0; j < clause_vars.size(); j++) if( clause_vars[j]->m_iWeight != -1) clause_vars[j]->m_iWeight += iWeight; }; // go to the next groups for (i--; i >=0 && synVariant.m_vectorGroups.GetGroups()[i].is_part_of(group); i--); } if (!bSubjIsInsideGroup) if (synVariant.m_bGoodSubject) iWeight += 1; if (!bPredicateIsInsideGroup) if (synVariant.m_bGoodSubject) iWeight += 1; synVariant.m_iWeight = iWeight; } catch(...) { return; } }
void CLogicThread::Think(CTaskDialog* Dialog,CSentence* Sentence, int32 AlterClausePos) { assert(m_Text.m_ClauseList.size() != 0); vector<int64> TempList; //如果修改的子句还没有输入完毕则不做处理 assert(AlterClausePos<m_Text.m_ClauseList.size()); CClause* Clause = m_Text.m_ClauseList[AlterClausePos]; int32 EndPos = Clause->m_BeginPos+Clause->m_TokenNum -1; if(EndPos<0)return ; //空句子? 可能吗? CToken* Token = m_Text.m_TokenList[EndPos]; if(!Token->IsClauseFlag())return; //回取逻辑场景 SentenceLogicSense* sls = &m_SentenceSense; //如果当前句子不是之前修改的句子,或者不能继续使用之前的分析结果,则重置 int32 pos = Sentence->m_BeginPos; if(sls->BelongSentence != Sentence){ sls->BelongSentence = Sentence; } else{ //sls->BelongSentence == Sentence if(AlterClausePos == sls->NextClausePos){ pos=AlterClausePos; //正常分析 } else if(AlterClausePos > sls->NextClausePos){ //因为前一个Clause已经出错,不用分析也是错, assert(!Sentence->IsOK()); return; } } if(pos==Sentence->m_BeginPos){ sls->FatherList.clear(); Sentence->m_AnalyseResult.Clear(); } EndPos = Sentence->m_BeginPos+Sentence->m_ClauseNum; bool HasError = false; //检查句子含有的子句之间是否有逻辑冲突 //如果没有冲突,则试图把这些子句联系起来,推测下一句 for(pos; pos<EndPos; pos++) { Clause = m_Text.m_ClauseList[pos]; assert(!Clause->IsBlank()); if(!Clause->IsOK()){ HasError = true; break; } //并联关系词的前一子句不能是set label 和 goto label操作 if(Clause->m_LogicRelation == SHUNT_RELATION){ if(pos==Sentence->m_BeginPos) //如果第一个子句是并联,警告,但继续执行 { //NotifyTokenWarning(m_Text.m_TokenList.at(0),i,SentenceIndex); //return false; } else{ CClause* PreClause = m_Text.m_ClauseList.at(pos-1); if(PreClause->m_MemoryID == INSTINCT_SET_LABEL || PreClause->m_MemoryID == INSTINCT_GOTO_LABEL) { Clause->m_MemoryID = ERROR_12; NotifyClauseError(Dialog,Clause,ERROR_12); HasError = true; break; } } } Energy* Param = NULL; if( BelongInstinct(Clause->m_MemoryID) ){ if(BelongIndeInterAction(Clause->m_MemoryID) ){ Clause->m_ActionType = INDE_INTER_ACTION; } else if(BelongInterAction(Clause->m_MemoryID)){ //外部 Clause->m_ActionType = INTER_ACTION; } else Clause->m_ActionType = COMMON_ACTION; //如果本能是USE LOGIC, 需要检查临时逻辑是否和目前行为类型冲突 //用法: use logic srcName:NewlogicName //注意:USE_LOGIC不属于IsInterOperator()的检查 if( INSTINCT_USE_LOGIC == Clause->m_MemoryID ){ eSTRING* s = (eSTRING*)Clause->m_Param; assert(s!= NULL); tstring LogicName = *(tstring*)s->Value(); //重用逻辑的格式为 原逻辑名:新逻辑名 /*不强制要求 tstring::size_type n = LogicName.find(':'); if(n == tstring::npos || n==LogicName.size()-1){ Clause->m_MemoryID = ERROR_23; NotifyClauseError(srcMsg,Clause,ERROR_23); return ; } */ /* 转到执行阶段 LogicName.resize(n); LogicName=TriToken(LogicName); CLogicItem* lg = FindLogic(LogicName); if(lg == NULL) { Clause->m_MemoryID = ERROR_10; NotifyClauseError(Clause,ERROR_10); return; } if(!lg->IsValid()) { Clause->m_MemoryID = ERROR_14; NotifyClauseError(Clause,ERROR_14); HasError = true; break; } Clause->m_ActionType = lg->m_ActionState; ePipeline NewLogic(lg->m_LogicData); *Pipe<< NewLogic; Param = Pipe; */ } if(Clause->m_Param){ Param = Clause->m_Param->Clone(); } } else {//处理非本能,也就是逻辑行为 Clause->m_ActionType = OUTER_ACTION; //检查是否此子句表达的意思是否正确(思考:需要这样吗?) //if(MEMORY.IsOK(ClauseID)) // throw tstring("cannot understand you inputed clause,Please learn it first"); //如果非本能有补语 则在本逻辑之前加入一个或多个定义字符串的行为。 if(Clause->m_Param != NULL){ assert(Clause->m_Param->EnergyType()==TYPE_PIPELINE); ePipeline* Pipe = (ePipeline*)Clause->m_Param; for(int i=0; i<Pipe->Size(); i++) { tstring* str = (tstring*)Pipe->GetData(i); ePipeline* Clause = new ePipeline; Clause->PushInt(INSTINCT_DEFINE_STRING); Clause->PushString(*str); Sentence->m_AnalyseResult.Push_Directly(Clause); } } } if(Clause->m_LogicRelation == SHUNT_RELATION ){ Clause->m_MemoryID = -Clause->m_MemoryID; } ePipeline* ClausePipe = new ePipeline; ClausePipe->PushInt(Clause->m_MemoryID); if(Param != NULL)ClausePipe->Push_Directly(Param); Sentence->m_AnalyseResult.Push_Directly(ClausePipe); } sls->NextClausePos = pos; Sentence->m_IsError = HasError; if(!HasError)SetForecast(Dialog,SENTENCE,Sentence); return; }
void CTopClauses::NewClause(CClauseNode* pNode1, CClauseNode* pNode2, SClauseFuncArg& arg) { //try { CClause* clause1 = pNode1->GetMainClause(); CClause* clause2 = pNode2->GetMainClause(); bool clause1WordsCountZero = (clause1->m_ClauseWords.size() == 0); bool clause2WordsCountZero = (clause2->m_ClauseWords.size() == 0); bool bIncludeOp = clause1WordsCountZero || clause2WordsCountZero; CClauseNode* pClonedNode1 = NULL; CClauseNode* pClonedNode2 = NULL; if (!bIncludeOp) { int size1 = pNode1->m_outNodes.size(); int size2 = pNode2->m_inNodes.size(); if (size1 > 1) pClonedNode1 = pNode1->Clone(); if (size2 > 1) pClonedNode2 = pNode2->Clone(); if (arg.m_iClause2TypeNum != -1) clause2->AddValsToType(arg.m_NewValencies2, arg.m_iClause2TypeNum); } if (clause1WordsCountZero) { arg.m_bMainFirst = true; IncludeClause(pNode1, pNode2, arg); pNode1->GetMainClause()->RunSynAn(); return; } if (clause2WordsCountZero) { arg.m_bMainFirst = false; IncludeClause(pNode1, pNode2, arg); pNode2->GetMainClause()->RunSynAn(); return; } CClause* pNewClause = CClause::Create(m_Words); pNewClause->SetPair(clause1->FirstWord(), clause2->LastWord()); if (arg.m_bMainFirst) pNewClause->m_Types = clause1->m_Types; else pNewClause->m_Types = clause2->m_Types; pNewClause->AddBadWeight(arg.m_BadWeight); pNewClause->m_Conjs = clause1->m_Conjs; //if( arg.m_BadWeightForCommas > 0 ) // pNewClause->m_BadCommas.push_back(SBadComma(clause1->LastWord(), arg.m_BadWeightForCommas) ); //MultiplyBadCommaWeight(*pNewClause, arg.m_PairForBadCoef, arg.m_CoefficientToIncreaseBadWeightForCommas); pNewClause->AddBadComma(clause1->LastWord(),arg.m_BadWeightForCommas, arg.m_PairForBadCoef, arg.m_CoefficientToIncreaseBadWeightForCommas); //pNewClause->m_BadWeightForCommas += arg.m_BadWeightForCommas; //pNewClause->m_BadWeightForCommas *= arg.m_CoefficientToIncreaseBadWeightForCommas; pNode1->m_pClauseTree->AddSubClauses(pNode2->m_pClauseTree, pNewClause); pNode1->GetMainClause()->RunSynAn(); UpdateNodes(pNode1, pNode2, pClonedNode1, pClonedNode2, true); } /*catch(...) { ythrow yexception() << "Error in \"CTopClauses::NewClause\""; }*/ }