private IOrderedEnumerable<SentenceElement> _compileMainPart(Stage4ResultElement mainPart) { var result = new List<SentenceElement> { mainPart }; result.AddRange(mainPart.ServiceParts); result.AddRange(mainPart.AddedWordsCase1); result.AddRange(mainPart.AddedWordsCase2); return result.OrderBy(word => word.Order); }
public override void ProcessSentence(Sentence sentence) { _sentence = sentence; Debug.Assert(sentence.ElementList != null); Debug.Assert(sentence.ElementList.Count > 0); List<SentenceElement> words = sentence.ElementList; // разворачиваем все, что добавили на 3-м этапе в список резльтатов 4-го и после этого плюсуем к ним СЧР foreach (var itemStage3 in _mainPartsStage3Result.Items.FindAll(x => x.SyntacticRole.Value != SyntacticRole.Predicate.Value)) { Stage4ResultElement item = new Stage4ResultElement(); item.CopyFromSourceWord(itemStage3); item.SimpleSentenceNr = itemStage3.SimpleSentenceNr; Result.Items.Add(item); foreach (var substantivatorItem in itemStage3.AddedWordsCase1) { Stage4ResultElement sItem = new Stage4ResultElement(); sItem.CopyFromSourceWord(substantivatorItem); sItem.IsSubstantivator = true; // проверяем, что элемента еще нет if (Result.Items.Find(x => x.Id == sItem.Id) == null) Result.Items.Add(sItem); } foreach (var quantativeItem in itemStage3.AddedWordsCase2) { Stage4ResultElement qItem = new Stage4ResultElement(); qItem.CopyFromSourceWord(quantativeItem); qItem.IsQuantativePart = true; // проверяем, что элемента еще нет if (Result.Items.Find(x => x.Id == qItem.Id) == null) Result.Items.Add(qItem); } } // для сказуемых сложнее, другая обработка foreach (var itemStage3 in _mainPartsStage3Result.Items.FindAll(x => x.SyntacticRole.Value == SyntacticRole.Predicate.Value)) { Stage4ResultElement item = new Stage4ResultElement(); item.CopyFromSourceWord(itemStage3); item.SimpleSentenceNr = itemStage3.SimpleSentenceNr; item.AddedWordsCase1 = itemStage3.AddedWordsCase1; item.AddedWordsCase2 = itemStage3.AddedWordsCase2; Result.Items.Add(item); } foreach (var itemStage4 in Result.Items.FindAll(x => x.SyntacticRole.Value == SyntacticRole.Predicate.Value)) { // находим id элемента, который должен остаться в текущем сказуемом var addedWords = itemStage4.AddedWordsCase1.Concat(itemStage4.AddedWordsCase2).ToList(); string specialId; if (addedWords.Count() > 0) { SentenceElement e = addedWords.OrderBy(x => System.Math.Abs(x.Order - itemStage4.Order)).First(); specialId = sentence.ElementList.Find(y => y.Order == e.Order).Id; } else specialId = "-1"; // все элементы, которые не являются специальными добавляем в корень результатов и удаляем из доп слов var addedWordsIds = new List<string>(); addedWordsIds.AddRange(itemStage4.AddedWordsCase1.Concat(itemStage4.AddedWordsCase2).Select(x => x.Id)); foreach (var additionalItem in addedWordsIds) { Stage4ResultElement sItem = new Stage4ResultElement(); sItem.CopyFromSourceWord(_sentence.ElementList.Find(x => x.Id == additionalItem)); // проверяем, что элемент может быть добавлен как отдельный if (sItem.Id != specialId) { if (Result.Items.Find(x => x.Id == sItem.Id) == null) { // удаляем элемент из AddedWords if (itemStage4.AddedWordsCase1.Find(x => x.Id == sItem.Id) != null) itemStage4.AddedWordsCase1.RemoveAll(x => x.Id == sItem.Id); if (itemStage4.AddedWordsCase2.Find(x => x.Id == sItem.Id) != null) itemStage4.AddedWordsCase2.RemoveAll(x => x.Id == sItem.Id); Result.Items.Add(sItem); } } } } // для всех элементов делаем двойной проход по СЧР с учетом addedwords foreach (var itemStage4 in Result.Items.FindAll(x => !x.IsRestored)) { itemStage4.ServiceParts.AddRange(words.FindAll(x => (x.SyntacticParentWordId == itemStage4.Id || itemStage4.AddedWordsCase1.Concat(itemStage4.AddedWordsCase2).ToList().Find(y => y.Id == x.SyntacticParentWordId) != null) && (x.IsServicePart))); // добавляем второй проход по выявленным СЧР, чтобы выявить ситуации "не были удовлетворены" (частица + вспом.глагол + СЧР) List<SentenceElement> servicePartsSecondLevel = new List<SentenceElement>(); foreach (var servicePart in itemStage4.ServiceParts) servicePartsSecondLevel.AddRange(words.FindAll(x => (x.SyntacticParentWordId == servicePart.Id) && (x.IsServicePart))); itemStage4.ServiceParts.AddRange(servicePartsSecondLevel); itemStage4.ServiceParts.AddRange(itemStage4.AddedWordsCase1); itemStage4.ServiceParts.AddRange(itemStage4.AddedWordsCase2); } // определяем финальный тип foreach (var itemStage4 in Result.Items) { if (itemStage4.IsQuantativePart) itemStage4.FinalSyntacticRole = "Подлежащее(Q)"; else if (itemStage4.IsSubstantivator) itemStage4.FinalSyntacticRole = "Подлежащее(S)"; else if (itemStage4.SyntacticRole.Value == SyntacticRole.Predicate.Value) itemStage4.FinalSyntacticRole = "Сказуемое"; else if ((itemStage4.SyntacticRole.Value == SyntacticRole.Subject.Value) || (itemStage4.GrammarInfo.PartOfSpeech.Value == GrammarInfoPartOfSpeech.Noun.Value)) itemStage4.FinalSyntacticRole = "Подлежащее"; else itemStage4.FinalSyntacticRole = ""; } // добавляем номера ПП и удаляем addedwords foreach (var resultItem in Result.Items) { resultItem.AddedWordsCase1.Clear(); resultItem.AddedWordsCase2.Clear(); var allIdsOfSimpleSentences = new List<string>(); resultItem.SimpleSentenceNr = -1; foreach (var ssItem in _simpleSentenceStage3Result.Items.FindAll(x => x.IsCorrect)) { allIdsOfSimpleSentences.Clear(); allIdsOfSimpleSentences.Add(ssItem.Id); allIdsOfSimpleSentences.AddRange(ssItem.ChainWordsIds.All.Values); if (allIdsOfSimpleSentences.Contains(resultItem.Id)) { resultItem.SimpleSentenceNr = ssItem.SimpleSentenceNr; break; } } } }