/* 1. Если слева от Иг1 (SF (Иг1 = МЕСТО) стоит Иг2 без локативного предлога так, что SF (Г (Иг2)) = МЕСТО, то Иг1 обьединяется с Иг2 в одну GEO, а составляющимприписывается отношение LOK (Иг1, Иг2). EXM = Снохомишская публичная библиотека в штате Вашингтон 2. Если слева от Иг1 (SF (Иг1) = МЕСТО) стоит Иг2 с локативным предлогом так, что SF (Г (Иг2)) = МЕСТО, то Иг1 обьединяется с Иг2 в одну GEO, а составляющимприписывается отношение LOK (Иг2, Иг1). EXM = в доме на компьютере */ void CRusSemStructure :: PutLocRelations(long ClauseNo) { for (long NodeNo=m_Clauses[ClauseNo].m_BeginNodeNo+1; NodeNo < m_Clauses[ClauseNo].m_EndNodeNo; NodeNo++) if ( (m_Nodes[NodeNo].m_ClauseNo == m_Nodes[NodeNo-1].m_ClauseNo) && IsLocNode(NodeNo) && IsLocNode(NodeNo-1) ) { string RelationStr; long PrepNo; GetLocSemRel(NodeNo-1, RelationStr, PrepNo); CValency V (RelationStr, A_C); if (V.m_RelationStr == "LOK") if (m_Nodes[NodeNo-1].HasSomePrep()) { AddRelation(CRusSemRelation(V, NodeNo, NodeNo-1, "")); m_Nodes[NodeNo].m_Vals.push_back(V); } else { AddRelation(CRusSemRelation(V, NodeNo-1, NodeNo, "")); m_Nodes[NodeNo-1].m_Vals.push_back(V); }; }; };
long CRusSemStructure::FindLocHost (long NodeNo, long ClauseNo) { vector <CLocHostHypot> HypotNodes; for (size_t i=0; i < m_Nodes.size(); i++) if (m_Nodes[i].IsWordContainer()) if (IsInClause(i, ClauseNo)) if ( ( m_Nodes[i].GetMinWordNo() < m_Nodes[NodeNo].GetMinWordNo() && ( IsLocNode(i) || HasSemFet(m_Nodes[i], "ORG") ) ) ) { CLocHostHypot Hypot (i, HasSemFet(m_Nodes[i], "ORG"), GetDistance(i, NodeNo), m_Nodes[i].GetUnitNo() != ErrUnitNo, false); HypotNodes.push_back(Hypot); }; sort (HypotNodes.begin(), HypotNodes.end()); if (HypotNodes.size() == 1) return HypotNodes[0].m_NodeNo; if (HypotNodes.size() == 0) return -1; for (size_t i = 0; i < HypotNodes.size(); i++) { string Q = Format ("Loc Host Weight %i \n", HypotNodes[i].GetWeightOfLocHypot()); size_t SaveRelSize = m_Relations.size(); CValency V (string("test_loc"), A_C); AddRelation(CRusSemRelation(V, HypotNodes[i].m_NodeNo, NodeNo, "")); if (m_Clauses[ClauseNo].m_ClauseSyntaxTop != -1) for (size_t k=0; k <m_Nodes.size(); k++) if ( IsInClause(k, ClauseNo) ) if (m_Clauses[ClauseNo].m_ClauseSyntaxTop != k) if (GetIncomingRelationsCount(k) == 0) { CRusSemRelation R (V, m_Clauses[ClauseNo].m_ClauseSyntaxTop, k, ""); R.m_bSituatRelation = true; AddRelation(R); }; bool bProject = IsProjectedNew (SetTagToClause(ClauseNo)); for (long j = SaveRelSize; j < m_Relations.size(); ) EraseRelation(SaveRelSize); if (bProject) return HypotNodes[i].m_NodeNo; }; return -1; };
void CRusSemStructure::ConvertFreeCoordConjToMNA (long ClauseNo) { try { for (long i=m_Clauses[ClauseNo].m_BeginNodeNo+1; i < m_Clauses[ClauseNo].m_EndNodeNo - 1; i++) if ( IsCoordConj (i) && (m_Nodes[i].m_NodeType != MNA) ) { long NodeNo = GetDefiniteRightHostByNotWeakSynRelation(i+1); if (NodeNo == -1) continue; if ( !HasRichPOS (NodeNo , NOUN) && !HasRichPOS (NodeNo , ADV) && !HasRichPOS (NodeNo , INFINITIVE) && !m_Nodes[NodeNo].m_bCompAdj ) continue; m_Nodes[i].m_NodeType = MNA; m_Nodes[i].m_MNAType = SimpleMNA; AddRelation(CRusSemRelation(CValency(), i, NodeNo, "")); m_Relations[m_Relations.size() - 1].m_CannotHaveOnlyCommaBetween = true; }; } catch (...) { ErrorMessage ("ConvertFreeCoordConjToMNA"); throw; }; };
// создает узел с MUA по синтаксической структуре// Петр и Василий void CRusSemStructure::InterpretSimilarNounGroups (long ClauseNo) { for (size_t i = 0; i<m_SynRelations.size(); i++) if ( ( ( m_SynRelations[i].m_SynRelName == "ОДНОР_ИГ" ) || ( m_SynRelations[i].m_SynRelName == "ОДНОР_ИНФ" ) || ( m_SynRelations[i].m_SynRelName == "ОДНОР_ЧИСЛ" ) || ( m_SynRelations[i].m_SynRelName == "РАЗРЫВ_СОЮЗ" ) || ( m_SynRelations[i].m_SynRelName == "ОДНОР" ) ) && IsInClause(m_SynRelations[i].m_SourceNodeNo, ClauseNo) ) { long MNANodeNo = m_SynRelations[i].m_SourceNodeNo; // не устанавливаем тип SimpleMNA для разрыв. союзов, которые были уже // обработаны в CRusSemStructure::InterpretRepeatConj if (m_Nodes[MNANodeNo].m_NodeType != MNA) { m_Nodes[MNANodeNo].m_NodeType = MNA; m_Nodes[MNANodeNo].m_MNAType = SimpleMNA; }; { long Target = m_SynRelations[i].m_TargetNodeNo; AddRelation(CRusSemRelation (CValency(), MNANodeNo, Target, string("") )); m_Relations.back().m_CannotHaveOnlyCommaBetween = ( m_SynRelations[i].m_SynRelName != "РАЗРЫВ_СОЮЗ"); } }; };
void CLabel::AddRelation( char *name, int rel_id ) { int i; i = Search( name ); if ( i < 0 ) return; AddRelation( i, rel_id ); }
void CRusSemStructure::NumeralAdverbRule() { for (long NumNodeNo=0; NumNodeNo < m_Nodes.size();NumNodeNo++) if (m_Nodes[NumNodeNo].IsPrimitive()) { string Word = m_Nodes[NumNodeNo].m_Words[0].m_Word; EngRusMakeUpper(Word); long NumeralValue = IsAdverbRule(Word); if (NumeralValue == -1) continue; m_Nodes[NumNodeNo].m_Words[0].m_Lemma = ""; m_Nodes[NumNodeNo].m_Words[0].m_Word = IntToStr(NumeralValue); m_Nodes[NumNodeNo].m_Words[0].m_ParadigmId = -1; m_Nodes[NumNodeNo].SetMainWordNo(0); long ClauseNo = m_Nodes[NumNodeNo].m_ClauseNo; vector<long> Hypots; for (long i=NumNodeNo - 1; i >= m_Clauses[ClauseNo].m_BeginNodeNo; i--) if ( CanBeNumeralAdverbHostMorph(m_Nodes[i]) ) Hypots.push_back(i); // вшестером мы этого не сделаем if (Hypots.empty()) for (long i=NumNodeNo + 1; i < m_Clauses[ClauseNo].m_EndNodeNo; i++) if ( CanBeNumeralAdverbHostMorph(m_Nodes[i]) ) Hypots.push_back(i); if (Hypots.empty()) continue; long HypotNodeNo; if (Hypots.size() == 1) HypotNodeNo = Hypots[0]; else { long i=0; for (i=0;i < Hypots.size(); i++) if ( HasSemFetOrLower(m_Nodes[Hypots[i]], "ANIM") ) break; if (i < Hypots.size()) HypotNodeNo = Hypots[i]; else HypotNodeNo = Hypots[0]; }; vector<long> Rels; GetIncomingInClauseRelations(NumNodeNo, Rels); if (Rels.size() == 1) { m_Relations[Rels[0]].m_SourceNodeNo = HypotNodeNo; m_Relations[Rels[0]].m_Valency = CValency("QUANTIT",A_C); } else AddRelation(CRusSemRelation(CValency("QUANTIT",A_C), HypotNodeNo, NumNodeNo , "")); }; };
CFilter* CDataManager::ProcessBrush( unsigned int _itemidx, unsigned int _valueidx ) { CFilter *curFilter = NULL; CFilteredData *filteredData = NULL; if ( m_BrushType >= Brush_One_EX && m_BrushType <= Brush_OR_EX ) curFilter = m_ExclusiveFilter; else if (m_BrushType >= Brush_Neg_One_EX && m_BrushType <= Brush_Neg_OR_EX ) curFilter = m_NegExclusiveFilter; else // select filters { vector<pair<t_color,CFilter*>>::iterator it_color = m_colorTable.begin(); for(; it_color != m_colorTable.end(); it_color++) { if(IsSameColor(it_color->first,m_color)) break; } t_color color; if ( ColorConflict( _itemidx, _valueidx, color) ) { if(!IsSameColor(color,m_color)) return NULL; } if(it_color == m_colorTable.end()) // new color { curFilter = new CFilter(); filteredData = new CFilteredData(); AddRelation(curFilter, filteredData, true); AddRelation(m_BasedFilteredData, filteredData, false); m_FilteredDataList.push_back( filteredData); m_Filters.push_back(curFilter); m_colorTable.push_back(pair<t_color,CFilter*>(m_color,curFilter)); } else curFilter = it_color->second; } curFilter->SetIndex(_itemidx, _valueidx); curFilter->SetLogicType((t_LogicType)((unsigned int)m_BrushType % 3)); return curFilter; }
CDataManager::CDataManager() : m_ifDataReady(false), m_MinTime(0), m_MaxTime(0), /*m_CurTime(0), m_TimeRange(0),*/ \ m_CurTimeData(NULL),m_TimeRangeData(NULL), m_TimeWindowData(NULL), m_TimeStepData(NULL), \ /*m_StartIdx(0), m_EndIdx(0),*/ /*m_TimeStep(TIMESTEP),*/ /*m_RangeStep(RANGESTEP), */\ m_RangeRatio(RANGERATIO), m_BrushType(Brush_One), m_filterType(NONE), m_CurrentTimesliderIdx(0), \ m_ifSkip(false),m_dataUpdateStyle(UPDATE_STYLE), m_RawData(NULL), \ m_CurrentFilter(-1),m_CurrentFilterEX(-1),m_CurrentFilterNEX(-1), \ m_BasedFilteredData(NULL), m_ExclusiveFilter(NULL), m_NegExclusiveFilter(NULL) { gpuDeviceInit(0); cudaGLSetGLDevice(0); m_ExclusiveFilter = new CFilter(); m_NegExclusiveFilter = new CFilter(); m_RawData = new CRawData(); m_RawData->SetDataManager(this); m_BasedFilteredData = new CFilteredData(); m_CurTimeData = new CCurTime(); m_TimeRangeData = new CTimeRange(); m_TimeWindowData = new CTimeWindow(); m_TimeStepData = new CTimeStep(); AddRelation( m_CurTimeData, m_TimeWindowData, false); AddRelation( m_TimeRangeData, m_TimeWindowData, false); m_TimeStepData->SetTimeStep(TIMESTEP); //Registeration AddRelation( m_RawData, m_BasedFilteredData, true ); AddRelation( m_ExclusiveFilter, m_BasedFilteredData, false ); AddRelation( m_NegExclusiveFilter, m_BasedFilteredData, false ); AddRelation( m_TimeWindowData, m_BasedFilteredData, false); }
/* Функция вставляет узел "сам" или "один" и проводит отношения ASPECT к нему для всех потециальных подлежащих. Если ни одного отношения не удалось провести, тогда возвращаем ложь. Между подлежащим и узлом сам проверяется согласование. */ bool CRusSemStructure::InsertSAMNode(long ClauseNo, CRusSemNode& SamNode) { /* если ничего вставлять не надо, выйдем с истиной */ if (SamNode.m_Words.size() == 0) return true; long SamNodeNo = InsertNode (SamNode); bool bResult = false; for (long i=0; i < m_Nodes.size(); i++) if ( IsInClause(i, ClauseNo) ) { CRelSet R = GetIncomingRelations(i, false); for (long l=0; l < R.m_RelsCount; l++) if ( m_Relations[R.m_Rels[l]].m_SyntacticRelation == "подл" ) // проверяем согласование по числу/роду if ( ( ( (_QM(rPlural) | _QM(rSingular)) & SamNode.GetGrammems() & m_Nodes[m_Relations[R.m_Rels[l]].m_SourceNodeNo].GetGrammems() )> 0 ) && ( ( ( rAllGenders & m_Nodes[m_Relations[R.m_Rels[l]].m_SourceNodeNo].GetGrammems() & SamNode.GetGrammems() ) > 0 ) || ( ( rAllGenders & m_Nodes[m_Relations[R.m_Rels[l]].m_SourceNodeNo].GetGrammems()) == 0 ) ) ) { AddRelation(CRusSemRelation(CValency("ASPECT", A_C), m_Relations[R.m_Rels[l]].m_SourceNodeNo, SamNodeNo, "")); // оно должно быть реверсивным, чтобы не отличаться от простых // наречий, чтобы занять правильное место в англ. предложении. m_Relations[m_Relations.size()-1].m_bReverseRel = true; m_DopRelations.push_back(CRusSemRelation(CValency("THESAME", A_C), SamNodeNo, m_Relations[R.m_Rels[l]].m_TargetNodeNo, "анафора")); bResult = true; } else { // удаляем субъектную стрелку, которая не согласовалась со словом "САМ" EraseRelation(R.m_Rels[l]); // получаем новый набор выходящих отношений R = GetIncomingRelations(i, false); l=-1; }; }; return bResult; };
void CRusSemStructure::BuildMNA_KAK(long ClauseNo) { try { // Все "как" без запятой перед ним объявляем узлами MUA // Например, "Протокол обрабатывает датаграмму как независимую единицу" // например, "Она, как последняя дура, заплакала." for (long NodeNo = m_Clauses[ClauseNo].m_BeginNodeNo; NodeNo < m_Clauses[ClauseNo].m_EndNodeNo; NodeNo++) if ( m_Nodes[NodeNo].IsPrimitive() && (m_Nodes[NodeNo].m_Words[0].m_Lemma == "КАК") && (m_Nodes[NodeNo].GetType() == OborRoss) && (m_Nodes[NodeNo].m_MNAType != RepeatMNA) ) { // проходим все прилагательные и другие жестко синтаксические зависимые long l=NodeNo+1; for (; l < m_Clauses[ClauseNo].m_EndNodeNo; l++) if ( !HasIncomingNotWeakSynRelation (l)) break; if (l == m_Clauses[ClauseNo].m_EndNodeNo) continue; if (!m_Nodes[l].IsWordContainer()) continue; m_Nodes[NodeNo].m_NodeType = MNA; m_Nodes[NodeNo].m_MNAType = KAK_MNA; if (HasCommaBefore (NodeNo)) { /* здесь нужно перевести интерпретацию на как3, чтобы "как" переводился в "like" */ m_Nodes[NodeNo].GetInterp()->m_UnitNo = GetRossHolder(OborRoss)->LocateUnit("как",3); assert (m_Nodes[NodeNo].GetInterp()->m_UnitNo != ErrUnitNo); }; AddRelation(CRusSemRelation(CValency(), NodeNo, l, "")); }; } catch (...) { ErrorMessage ("BuildMNA_KAK Failed"); throw; }; };
RELATION CloneRelation(RELATION id, RELATION cloneId) { register struct relationDef *rd; if ((rd = FindRelation(id))) { if (AddRelation(cloneId) || FindRelation(cloneId)) { register struct relation *r; for (r = rd->rd_relationsTable; r; r = r->r_next) { SetP(r->r_leftKey, cloneId, r->r_rightKey, r->r_parameter); } return cloneId; } } return 0; }
// предлог "c" bool CRusSemStructure::DealWithNodePrepS(long NodeNo) { long nd = NodeNo; if (m_Nodes[NodeNo].m_NodeType == MNA) nd = GetFirstMNAMemberIfHas(NodeNo); long PrepNo; if (!CheckGroupBeginAndCase("с+Т",nd, PrepNo)) return false; long SourceNodeNo = FindLeftClosestNode(nd); if (SourceNodeNo == -1) return false; if (!IsInClause (SourceNodeNo, m_Nodes[nd].m_ClauseNo)) return false; if (!HasRichPOS (SourceNodeNo, NOUN) && !HasPOS(SourceNodeNo, PRONOUN) ) return false; CValency V ("TOGETHER", A_C,0); assert(PrepNo != -1); AddRelation(CRusSemRelation(V, SourceNodeNo, NodeNo, "")); m_Relations[m_Relations.size() - 1].m_SynReal.m_Preps.push_back(m_Nodes[NodeNo].m_SynReal.m_Preps[PrepNo]); m_Nodes[SourceNodeNo].m_Vals.push_back(V); return true; }
void InfoTreeCtrl::SetInfo(TileWay *ways) { if (m_canvas) { m_canvas->SelectWay(NULL); } DeleteAllItems(); wxTreeItemId root = AddRoot(wxT("this node is a member of:")); for (TileWay *w = ways; w ; w = static_cast<TileWay *>(w->m_next)) { wxTreeItemId wayId = AddWay(root, w->m_way); for (OsmRelationList *rl = w->m_way->m_relations; rl; rl = (OsmRelationList *)(rl->m_next)) { AddRelation(wayId, rl->m_relation); } } ExpandAll(); }
void CRusSemStructure::ApplySynStr (long ClauseNo) { try { for (long j=0; j < m_Relations.size(); j++) { for (long l=0; l < m_SynRelations.size(); l++) if (IsPragmaticallyStrongSynRel(l) ) if ( (m_Relations[j].m_TargetNodeNo == m_SynRelations[l].m_SourceNodeNo) && (m_Relations[j].m_SourceNodeNo == m_SynRelations[l].m_TargetNodeNo) ) { EraseRelation(j); j--; break; }; }; for (long i=0; i < GetNodesSize(); i++) if ( IsInClause(i, ClauseNo) && m_Nodes[i].IsWordContainer() ) { vector<long> SynRels; GetIncomingSynRelations(i, SynRels); for (long l=0; l < SynRels.size(); l++) { if (!IsPragmaticallyStrongSynRel(SynRels[l]) ) continue; string SynRelStr = m_SynRelations[SynRels[l]].m_SynRelName; CRelSet R = GetIncomingRelations(i, false); bool RelFound = false; for (long j=0; j < R.m_RelsCount; j++) if (m_Relations[R.m_Rels[j]].m_SourceNodeNo == m_SynRelations[SynRels[l]].m_SourceNodeNo) { RelFound = true; m_Relations[R.m_Rels[j]].m_SyntacticRelation = m_SynRelations[SynRels[l]].m_SynRelName; R.Erase(j); j--; }; DeleteRelSet(R); if (!RelFound) { if (!m_Nodes[m_SynRelations[SynRels[l]].m_SourceNodeNo].IsWordContainer()) continue; string SemRelStr; if (SynRelStr == "ЧИСЛ_СУЩ") SemRelStr = "QUANTIT"; CRusSemRelation NewRelation(CValency(SemRelStr, A_C), m_SynRelations[SynRels[l]].m_SourceNodeNo, i, m_SynRelations[SynRels[l]].m_SynRelName); if ( SynRelStr == "ПРИЛ_СУЩ" || SynRelStr == "ЧИСЛ_СУЩ" || SynRelStr == "ПРИЧ_СУЩ" // можно что-нибудь еще добавить... ) { NewRelation.m_bReverseRel = true; NewRelation.m_Valency.m_RelationStr = "PROPERT"; } assert (NewRelation.m_SourceNodeNo < m_Nodes.size()); assert (NewRelation.m_TargetNodeNo < m_Nodes.size()); AddRelation(NewRelation); }; }; }; } catch (...) { ErrorMessage ("ApplySynStr"); throw; }; };
int LoadRelations(char *file, U16 disk_id) { RELATION rd; PARAMETER parameter; char buffer[256]; char left[256]; char right[256]; U8 goOn; FILE *fh = NULL; U32 dummy; buffer[0] = '\0'; left[0] = '\0'; right[0] = '\0'; if (EncodeKey) { if ((fh = dskOpen(file, "rb"))) { dskGetLine(buffer, sizeof(buffer), fh); if (strcmp(buffer, REL_FILE_MARK) == 0) { dskGetLine(buffer, sizeof(buffer), fh); while (!feof(fh) && strcmp(buffer, REL_TABLE_MARK) == 0) { fscanf(fh, "%" SCNu32 "\r\n", &rd); goOn = 0; if (FindRelation(rd)) goOn = 1; else { if (AddRelation(rd)) goOn = 1; } if (goOn) { while (dskGetLine(left, sizeof(left), fh)) { if (strcmp(left, REL_TABLE_MARK) == 0) { strcpy(buffer, left); break; } if (sscanf(left, "%" SCNu32, &dummy) != 1) break; dskGetLine(right, sizeof(right), fh); if (sscanf(right, "%" SCNu32, &dummy) != 1) break; if (fscanf(fh, "%" SCNu32 "\r\n", ¶meter) != 1) break; if (!SetP (EncodeKey(left), rd, EncodeKey(right), parameter)) { dskClose(fh); return 0; } } } else { dskClose(fh); return 0; } } dskClose(fh); return 1; } dskClose(fh); } } return 0; }
void CRusSemStructure::BuildMNAOutcoming(long ClauseNo) { try { for (long NodeNo = 0; NodeNo < m_Nodes.size(); NodeNo++) if ( IsInClause(NodeNo, ClauseNo) && ( m_Nodes[NodeNo].m_NodeType == MNA ) && ( m_Nodes[NodeNo].m_MNAType != CHEMOborot) ) { long PatternPoses; QWORD Grammems; GetMNAPattern(NodeNo, PatternPoses, Grammems); bool bAdjMNA = HasOutcomingSynRelation(NodeNo,"ОДНОР_ПРИЛ"); // мы начинаем поиск левых потомков от оператора однородности // (единственный правый потомок уже был присоединен в процедуре, которая ищет оператор однородности ) for (long LeftChildNo=NodeNo; LeftChildNo >= m_Clauses[ClauseNo].m_BeginNodeNo; LeftChildNo--) { // ищем запятую, союз или какой другой оператор однородности for (; LeftChildNo >= m_Clauses[ClauseNo].m_BeginNodeNo; LeftChildNo--) if (IsFiniteVerb(LeftChildNo)) goto NoMoreLeftChilds; else if ( IsCoordConj(LeftChildNo) || m_Nodes[LeftChildNo].HaveCommaAfter() || (m_Nodes[LeftChildNo].m_NodeType == MNA) ) break; if (LeftChildNo < m_Clauses[ClauseNo].m_BeginNodeNo) break; // не нашли // ищем слово, которое согласовано со словом, которое стоит сразу же за оператором однородности, по падежу // или вообще не имеет граммем (ИЛЕ) for (; LeftChildNo >= m_Clauses[ClauseNo].m_BeginNodeNo; LeftChildNo--) if (IsFiniteVerb(LeftChildNo)) goto NoMoreLeftChilds; else if ( (m_Nodes[LeftChildNo].m_MainWordNo != -1) && ( !m_Nodes[LeftChildNo].IsTimeRossNode() || m_Nodes[LeftChildNo].IsMainTimeRossNode() ) && ( ((m_Nodes[LeftChildNo].m_Words[m_Nodes[LeftChildNo].m_MainWordNo].m_Poses & PatternPoses) > 0) || ( ( ( PatternPoses & (1<<ADV) ) > 0) && ( m_Nodes[LeftChildNo].HasSomePrep() // в лесу || m_Nodes[LeftChildNo].IsMainTimeRossNode() // 9 мая ) && !HasIncomingNotWeakSynRelation(LeftChildNo) ) ) && ( ((m_Nodes[LeftChildNo].GetGrammems() & Grammems & rAllCases) > 0) || (Grammems == 0) || (( PatternPoses & (1<<ADV) ) > 0) || ( m_Nodes[LeftChildNo].GetGrammems() & Grammems & _QM(rComparative)) || ( HasSynRelation (LeftChildNo, "АНАТ_СРАВН") && (Grammems & _QM(rComparative))) ) && (!bAdjMNA || ( m_Nodes[LeftChildNo].HasPOS(ADJ_FULL) || m_Nodes[LeftChildNo].HasPOS(ADJ_SHORT)) ) ) break; if (LeftChildNo < m_Clauses[ClauseNo].m_BeginNodeNo) break; if (FindFirstRelation(NodeNo, LeftChildNo) == -1) { AddRelation(CRusSemRelation(CValency(), NodeNo, LeftChildNo, "")); m_Relations[m_Relations.size() - 1].m_CannotHaveOnlyCommaBetween = true; }; }; NoMoreLeftChilds:; }; } catch (...) { ErrorMessage ("BuildMNAOutcoming Failed"); throw; }; };
void CRusSemStructure::BuildMNAIncoming(long ClauseNo) { UpdateBlockedRelations(); try { for (long NodeNo = m_Clauses[ClauseNo].m_BeginNodeNo; NodeNo < m_Clauses[ClauseNo].m_EndNodeNo; NodeNo++) if (m_Nodes[NodeNo].m_NodeType == MNA) for (long i = m_Clauses[ClauseNo].m_BeginNodeNo; i < m_Clauses[ClauseNo].m_EndNodeNo; i++) if (i != NodeNo) for (size_t j=0; j < m_Nodes[i].m_OutRels.size();j++) { long Count = 0; /* считаем кол-во отношений с одинаковым названием (это варианты заполнения одной валентности) идущих из узла i (потенциальный хозяин однородного ряда) в в члены однородного ряда. Норамально, когда все члены однородного ряда подчиняются узлу i. */ for (size_t l=j; l < m_Nodes[i].m_OutRels.size();l++) if(m_Relations[m_Nodes[i].m_OutRels[j]].m_Valency == m_Relations[m_Nodes[i].m_OutRels[l]].m_Valency) { long k=0; for (; k < m_Nodes[NodeNo].m_OutRels.size(); k++) if (m_Relations[m_Nodes[NodeNo].m_OutRels[k]].m_TargetNodeNo == m_Relations[m_Nodes[i].m_OutRels[l]].m_TargetNodeNo) break; if (k < m_Nodes[NodeNo].m_OutRels.size()) Count++; }; // Для простых операторов однородности нужно, чтобы хотя бы один узел входил // в член однородного ряда,чтобы подчинить весь однородный ряд. Это сделано из-за случая: // 'я жил в Америке и России'. Здесь пропущен прдлог 'в' после союза, поэтому // 'России'не подсоединится к 'жить'. // Для сравнительного оборота такой эллипсис не возможен, например: // Я жил в Америке дольше, чем в России. // но возможны обороты: // Я не знаю человека, больше чем Вася (здесь "Вася" не стоит в рд. или вн.) // Я не отдаю тебе охотнее его (здесь "его" стоит в рд.) if ( ( (Count > 0) // && (m_Nodes[NodeNo].m_MNAType != CHEMOborot) ) /*|| ( (Count > 1) // && (m_Nodes[NodeNo].m_MNAType == CHEMOborot) )*/ ) { // если валентность слова А - непредложная, а оператору однородности приписан предлог // (такой предлог может придти из синтаксиса), тогда считаем, что слово А // не может управлят этим однородным рядом if (m_Relations[m_Nodes[i].m_OutRels[j]].m_Valency.IsFromDict()) { const CRossHolder* RossHolder = m_Relations[m_Nodes[i].m_OutRels[j]].m_Valency.m_RossHolder; const TCortege& C = m_Relations[m_Nodes[i].m_OutRels[j]].m_SynReal.m_Cortege; bool IsPrepCortege = RossHolder->IsLemGroupBegining(RossHolder->GetSynFet(C)) || (RossHolder->GetSynRel(C) == RossHolder->AdverbialGrpNo); if (!IsPrepCortege && m_Nodes[NodeNo].HasSomePrep()) continue; }; AddRelation(CRusSemRelation(m_Relations[m_Nodes[i].m_OutRels[j]].m_Valency, i, NodeNo, "")); m_Relations[m_Relations.size() - 1].m_CannotHaveOnlyCommaBetween = true; m_Relations[m_Relations.size() - 1].m_SynReal = m_Relations[m_Nodes[i].m_OutRels[j]].m_SynReal; m_Relations[m_Relations.size() - 1].m_SyntacticRelation = m_Relations[m_Nodes[i].m_OutRels[j]].m_SyntacticRelation; if (m_Nodes[NodeNo].m_MNAType == CHEMOborot) m_Relations[m_Relations.size() - 1].m_SemFets = GetSemFetsOfFirstValency(NodeNo); }; }; } catch (...) { ErrorMessage ("BuildMNAIncoming Failed"); throw; }; };