public void CreateLinks(bool afterPart = false) { for (int i = 0; i < Items.Count; i++) { Items[i].Order = i; Items[i].Prepare(); } NGLink li = null; for (int i = 0; i < Items.Count; i++) { NGItem it = Items[i]; if (it.Source.Typ == SentItemType.Adverb) { continue; } bool ignoreBefore = false; double mult = (double)1; if (it.CommaBefore || it.AndBefore) { for (int j = i - 1; j >= 0; j--) { if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.List; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } if (it.Source.Typ == SentItemType.PartBefore || it.Source.Typ == SentItemType.SubSent || it.Source.Typ == SentItemType.Deepart) { if (it.CommaBefore) { if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Participle; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } } } if ((!it.AndBefore && it.Source.Typ == SentItemType.Noun && Items[j].Source.Typ == SentItemType.Noun) && Items[i - 1].Source.Typ == SentItemType.PartBefore) { bool ok = true; for (int jj = j + 1; jj < i; jj++) { if ((Items[jj].Source.Typ == SentItemType.Delim || Items[jj].Source.Typ == SentItemType.Noun || Items[jj].Source.Typ == SentItemType.SubSent) || Items[jj].Source.Typ == SentItemType.PartBefore) { } else { ok = false; break; } } if (ok) { if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Genetive; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } } } } ignoreBefore = true; } else { for (int j = i - 1; j >= 0; j--) { if (Items[j].Source.Typ == SentItemType.SubSent) { continue; } if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Genetive; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Name; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } bool nodelim = true; for (int jj = j + 1; jj <= i; jj++) { if (Items[jj].CommaBefore || Items[jj].AndBefore) { nodelim = false; break; } } if (nodelim) { if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Be; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } } if (it.Source.Typ == SentItemType.PartBefore || it.Source.Typ == SentItemType.SubSent || it.Source.Typ == SentItemType.Deepart) { bool hasDelim = false; for (int jj = i - 1; jj > j; jj--) { if (Items[jj].Source.CanBeCommaEnd) { hasDelim = true; break; } } if (hasDelim) { if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Participle; li.From = it; li.To = Items[j]; li.ToVerb = null; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); li = null; } } } if (Items[j].Source.Typ == SentItemType.PartBefore) { mult *= 0.5; } if (Items[j].Source.Typ == SentItemType.Verb) { ignoreBefore = true; break; } } if (BeforeVerb != null && !ignoreBefore && it.Source.Typ != SentItemType.Deepart) { bool ok = false; if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Agent; li.From = it; li.To = null; li.ToVerb = BeforeVerb; li.CalcCoef(false); li.Coef *= mult; if (li.Coef >= 0) { it.Links.Add(li); ok = true; li = null; } if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Pacient; li.From = it; li.To = null; li.ToVerb = BeforeVerb; li.CalcCoef(false); li.Coef *= mult; if (li.Coef >= 0) { it.Links.Add(li); ok = true; li = null; } { if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Actant; li.From = it; li.To = null; li.ToVerb = BeforeVerb; li.CalcCoef(false); li.Coef *= mult; if (ok) { li.Coef /= 2; } if (li.Coef >= 0) { it.Links.Add(li); ok = true; li = null; } } } } if (AfterVerb != null && it.Source.Typ != SentItemType.Deepart) { bool ok = false; if (afterPart && BeforeVerb != null) { foreach (NGLink l in it.Links) { if (l.ToVerb == BeforeVerb && ((l.Typ == NGLinkType.Agent || l.Typ == NGLinkType.Pacient))) { ok = true; } } if (ok) { continue; } } if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Agent; li.From = it; li.To = null; li.ToVerb = AfterVerb; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); ok = true; li = null; } if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Pacient; li.From = it; li.To = null; li.ToVerb = AfterVerb; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); ok = true; li = null; } if (li == null) { li = new NGLink(); } li.Typ = NGLinkType.Actant; li.From = it; li.To = null; li.ToVerb = AfterVerb; li.CalcCoef(false); if (li.Coef >= 0) { it.Links.Add(li); ok = true; li = null; } } } for (int i = 1; i < Items.Count; i++) { NGItem it = Items[i]; if (it.Source.Typ != SentItemType.Noun) { continue; } NGItem it0 = Items[i - 1]; if (it0.Source.Typ != SentItemType.Noun) { continue; } if (it0.Links.Count > 0) { continue; } li = new NGLink() { Typ = NGLinkType.Genetive, From = it0, To = it, Reverce = true }; li.CalcCoef(true); if (li.Coef > 0) { it0.Links.Add(li); } } }
static List <SentItem> ParseParticiples(Pullenti.Ner.Core.VerbPhraseToken vb, Pullenti.Ner.Token t1, int lev) { List <Sentence> sents = Sentence.ParseVariants(vb.EndToken.Next, t1, lev + 1, 20, SentItemType.PartBefore) ?? new List <Sentence>(); NGLinkType typ = NGLinkType.Agent; if (vb.FirstVerb.Morph.ContainsAttr("страд.з.", null)) { typ = NGLinkType.Pacient; } else if (vb.FirstVerb.Morph.ContainsAttr("возвр.", null)) { typ = NGLinkType.Pacient; } List <int> endpos = new List <int>(); List <SentItem> res = new List <SentItem>(); bool changed = false; foreach (Sentence s in sents) { if (vb.FirstVerb.IsDeeParticiple) { break; } for (int i = 0; i < s.Items.Count; i++) { SentItem it = s.Items[i]; if (!it.CanBeNoun || it.Typ == SentItemType.Verb) { continue; } if (!string.IsNullOrEmpty(it.Prep)) { continue; } if (it.Typ == SentItemType.PartBefore || it.Typ == SentItemType.PartAfter) { continue; } NGLink li = new NGLink() { Typ = typ, From = new NGItem() { Source = it }, ToVerb = vb }; li.CalcCoef(true); if (li.Coef < 0) { continue; } if (endpos.Contains(it.EndToken.EndChar)) { continue; } Sentence ss = new Sentence() { LastNounToFirstVerb = typ }; ss.Items.Add(new SentItem(vb)); for (int j = 0; j <= i; j++) { SentItem si = new SentItem(null); si.CopyFrom(s.Items[j]); ss.Items.Add(si); } ss.CalcCoef(false); changed = true; if (ss.Coef < 0) { continue; } SentItem part = new SentItem(it.Source); part.Typ = SentItemType.PartAfter; part.SubSent = ss; if (vb.Preposition != null) { part.Prep = vb.Preposition.Normal; } part.BeginToken = vb.BeginToken; part.EndToken = it.Source.EndToken; if ((i + 1) < ss.Items.Count) { part.Result = ss.Items[i + 1].Result; } endpos.Add(it.EndToken.EndChar); res.Add(part); } } endpos.Clear(); if (changed) { sents = Sentence.ParseVariants(vb.EndToken.Next, t1, lev + 1, 20, SentItemType.PartBefore) ?? new List <Sentence>(); } foreach (Sentence s in sents) { s.Items.Insert(0, new SentItem(vb)); s.CalcCoef(true); s.TruncOborot(true); int end = s.Items[s.Items.Count - 1].EndToken.EndChar; endpos.Add(end); s.NotLastNounToFirstVerb = typ; s.CalcCoef(false); SentItem part = new SentItem(vb); part.PartVerbTyp = typ; part.Typ = (vb.FirstVerb.IsDeeParticiple ? SentItemType.Deepart : SentItemType.PartBefore); part.SubSent = s; part.Result = s.Items[0].Result; part.ResultVerbLast = s.Items[0].ResultVerbLast; part.EndToken = s.Items[s.Items.Count - 1].EndToken; res.Add(part); } if (res.Count == 0 && sents.Count == 0) { SentItem part = new SentItem(vb); part.PartVerbTyp = typ; part.Typ = (vb.FirstVerb.IsDeeParticiple ? SentItemType.Deepart : SentItemType.PartBefore); res.Add(part); } return(res); }
public double CalcCoef() { Coef = 0; foreach (NGLink it in Links) { if (it != null) { Coef += it.Coef; } } for (int i = 0; i < Links.Count; i++) { NGLink li1 = Links[i]; if (li1 == null || li1.To == null) { continue; } if (li1.Reverce) { continue; } int i0 = li1.To.Order; if (i0 >= li1.From.Order) { return(Coef = -1); } for (int k = i0 + 1; k < i; k++) { NGLink li = Links[k]; if (li == null) { continue; } if (li.ToVerb != null) { return(Coef = -1); } int i1 = li.To.Order; if ((i1 < i0) || i1 > i) { return(Coef = -1); } if (li.Typ == NGLinkType.List && li1.Typ == NGLinkType.List && i0 == i1) { return(Coef = -1); } } } for (int i = 0; i < Links.Count; i++) { List <NGItem> list = this.GetList(i); if (list == null) { continue; } int k; for (k = 1; k < (list.Count - 1); k++) { if (list[k].AndBefore) { break; } } if (k >= (list.Count - 1) && list[k].AndBefore) { Coef += Pullenti.Semantic.SemanticService.Params.List; } else { int ors = 0; int ands = 0; for (k = 1; k < list.Count; k++) { if (list[k].OrBefore) { ors++; } else if (list[k].AndBefore) { ands++; } } if (ands > 0 && ors > 0) { return(Coef = -1); } for (k = 1; k < list.Count; k++) { if (!list[k].AndBefore) { break; } } if (k >= list.Count) { } else { return(Coef = -1); } } NGLink ngli = new NGLink() { Typ = NGLinkType.List }; for (k = 0; k < (list.Count - 2); k++) { for (int kk = k + 2; kk < list.Count; kk++) { ngli.From = list[kk]; ngli.To = list[k]; ngli.CalcCoef(false); if (ngli.Coef < 0) { return(Coef = -1); } } } bool prepIsNotExiAll = false; for (k = 0; k < (list.Count - 1); k++) { for (int kk = k + 1; kk < list.Count; kk++) { if (!_compareListItemTails(list[k].Source.Source, list[kk].Source.Source)) { Coef /= 2; } if (string.IsNullOrEmpty(list[k].Source.Prep) != string.IsNullOrEmpty(list[kk].Source.Prep)) { string str1 = list[k].Source.EndToken.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false); string str2 = list[kk].Source.EndToken.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false); if (str1 != str2) { prepIsNotExiAll = true; } } } } if (prepIsNotExiAll) { Coef /= 2; } NGItem last = list[list.Count - 1]; bool ok = true; NGLink lalink = null; foreach (NGLink ll in Links) { if (ll != null && ll.Typ == NGLinkType.Genetive) { if (ll.To == last) { lalink = ll; } else if (list.Contains(ll.To)) { ok = false; break; } } } if (!ok || lalink == null) { continue; } NGLink test = new NGLink() { From = lalink.From, Typ = lalink.Typ }; int j; for (j = 0; j < (list.Count - 1); j++) { test.To = list[j]; int ord = test.To.Order; test.To.Order = last.Order; test.CalcCoef(false); test.To.Order = ord; if (test.Coef < 0) { break; } } if (j >= (list.Count - 1)) { lalink.ToAllListItems = true; } } int befAg = 0; int befPac = 0; int aftAg = 0; int aftPac = 0; for (int i = 0; i < Links.Count; i++) { NGLink li = Links[i]; if (li == null) { continue; } if (li.Typ == NGLinkType.List) { continue; } if (li.Typ == NGLinkType.Participle) { if (li.From.Source.PartVerbTyp != NGLinkType.Undefined) { } } if ((li.Typ == NGLinkType.Agent || li.Typ == NGLinkType.Pacient || li.Typ == NGLinkType.Genetive) || li.Typ == NGLinkType.Participle) { if (li.Plural == 1) { bool ok = false; if (li.Typ == NGLinkType.Participle && li.To != null && this.GetList(li.To.Order) != null) { ok = true; } else if (li.Typ != NGLinkType.Participle && this.GetList(i) != null) { ok = true; } else { double co = li.Coef; li.CalcCoef(true); if (li.Coef > 0) { ok = true; } li.Coef = co; li.Plural = 1; } if (!ok) { return(Coef = -1); } } else if (li.Plural == 0) { if (li.Typ != NGLinkType.Participle && this.GetList(i) != null) { return(Coef = -1); } if (li.Typ == NGLinkType.Participle && li.To != null && this.GetList(li.To.Order) != null) { return(Coef = -1); } } } if (li.Typ == NGLinkType.Agent || li.Typ == NGLinkType.Pacient || li.Typ == NGLinkType.Actant) { } else { continue; } if (li.ToVerb != null && li.ToVerb == Source.BeforeVerb) { if (Source.AfterVerb != null && !Source.BeforeVerb.FirstVerb.IsParticiple) { bool hasDelim = false; int ind = li.From.Order; List <NGItem> list = this.GetList(ind); if (list != null) { ind = list[list.Count - 1].Order; } for (int ii = ind; ii < Source.Items.Count; ii++) { if (Source.Items[ii].AndAfter || Source.Items[ii].CommaAfter) { hasDelim = true; } } if (!hasDelim) { return(Coef = -1); } } if (li.Typ == NGLinkType.Agent && li.ToVerb.FirstVerb.IsDeeParticiple) { bool hasDelim = false; for (int ii = 0; ii <= li.From.Order; ii++) { if (Source.Items[ii].AndBefore || Source.Items[ii].CommaBefore) { hasDelim = true; } } if (!hasDelim) { return(Coef = -1); } } if (li.Typ == NGLinkType.Agent) { befAg++; } else if (li.Typ == NGLinkType.Pacient) { befPac++; } if (li.From.Source.SubSent != null) { continue; } } else if (li.ToVerb != null && li.ToVerb == Source.AfterVerb) { if (Source.BeforeVerb != null && !Source.BeforeVerb.FirstVerb.IsParticiple) { bool hasDelim = false; for (int ii = 0; ii <= li.From.Order; ii++) { if (Source.Items[ii].AndBefore || Source.Items[ii].CommaBefore) { hasDelim = true; } } if (!hasDelim) { return(Coef = -1); } } if (li.From.Source.SubSent != null) { continue; } if (li.Typ == NGLinkType.Agent) { aftAg++; } else if (li.Typ == NGLinkType.Pacient) { aftPac++; } } if (li.Typ == NGLinkType.Actant) { continue; } } if ((befAg > 1 || befPac > 1 || aftAg > 1) || aftPac > 1) { return(Coef = -1); } for (int i = 0; i < Links.Count; i++) { NGLink li = Links[i]; if (li == null) { continue; } if (li.Typ != NGLinkType.Actant || li.ToVerb == null) { continue; } } for (int i = 0; i < Links.Count; i++) { NGLink li = Links[i]; if (li == null) { continue; } if (li.Typ != NGLinkType.Genetive || li.To == null) { continue; } if (li.From.Source.Typ == SentItemType.Formula) { foreach (NGLink li0 in Links) { if ((li0 != null && li0 != li && li0.Typ == NGLinkType.Genetive) && li0.From == li.To) { Coef /= 2; } } } if (li.To.Source.Typ == SentItemType.Formula) { foreach (NGLink li0 in Links) { if ((li0 != null && li0 != li && li0.Typ == NGLinkType.Genetive) && li0.To == li.To) { if (li0.From.Order < li.From.Order) { Coef /= 2; } } } } } return(Coef); }