예제 #1
0
        /// <summary>
        /// Попробовать создать семантическую связь между элементами.
        /// Элементом м.б. именная (NounPhraseToken) или глагольная группа (VerbPhraseToken).
        /// </summary>
        /// <param name="master">основной элемент</param>
        /// <param name="slave">стыкуемый элемент (также м.б. SemanticAbstractSlave)</param>
        /// <param name="onto">дополнительный онтологический словарь</param>
        /// <return>список вариантов (возможно, пустой)</return>
        public static List <SemanticLink> TryCreateLinks(Pullenti.Ner.MetaToken master, Pullenti.Ner.MetaToken slave, ISemanticOnto onto = null)
        {
            List <SemanticLink> res = new List <SemanticLink>();

            Pullenti.Ner.Core.VerbPhraseToken vpt1 = master as Pullenti.Ner.Core.VerbPhraseToken;
            Pullenti.Ner.Core.VerbPhraseToken vpt2 = slave as Pullenti.Ner.Core.VerbPhraseToken;
            Pullenti.Ner.Core.NounPhraseToken npt1 = master as Pullenti.Ner.Core.NounPhraseToken;
            if (slave is Pullenti.Ner.Core.NounPhraseToken)
            {
                slave = SemanticAbstractSlave.CreateFromNoun(slave as Pullenti.Ner.Core.NounPhraseToken);
            }
            SemanticAbstractSlave sla2 = slave as SemanticAbstractSlave;

            if (vpt2 != null)
            {
                if (!vpt2.FirstVerb.IsVerbInfinitive || !vpt2.LastVerb.IsVerbInfinitive)
                {
                    return(res);
                }
            }
            List <Pullenti.Semantic.Utils.DerivateGroup> grs = FindDerivates(master);

            if (grs == null || grs.Count == 0)
            {
                List <SemanticLink> rl = (vpt1 != null ? _tryCreateVerb(vpt1, slave, null) : _tryCreateNoun(npt1, slave, null));
                if (rl != null)
                {
                    res.AddRange(rl);
                }
            }
            else
            {
                foreach (Pullenti.Semantic.Utils.DerivateGroup gr in grs)
                {
                    List <SemanticLink> rl = (vpt1 != null ? _tryCreateVerb(vpt1, slave, gr) : _tryCreateNoun(npt1, slave, gr));
                    if (rl == null || rl.Count == 0)
                    {
                        continue;
                    }
                    res.AddRange(rl);
                }
            }
            if ((npt1 != null && sla2 != null && sla2.Morph.Case.IsGenitive) && sla2.Preposition == null)
            {
                if (npt1.Noun.BeginToken.GetMorphClassInDictionary().IsPersonalPronoun)
                {
                }
                else
                {
                    bool hasGen = false;
                    foreach (SemanticLink r in res)
                    {
                        if (r.Question == Pullenti.Semantic.Utils.ControlModelQuestion.BaseGenetive)
                        {
                            hasGen = true;
                            break;
                        }
                    }
                    if (!hasGen)
                    {
                        res.Add(new SemanticLink()
                        {
                            Modelled = true, Master = npt1, Slave = sla2, Rank = 0.5, Question = Pullenti.Semantic.Utils.ControlModelQuestion.BaseGenetive
                        });
                    }
                }
            }
            if (onto != null)
            {
                string str1 = GetKeyword(master);
                string str2 = GetKeyword(slave);
                if (str2 != null)
                {
                    if (onto.CheckLink(str1, str2))
                    {
                        if (res.Count > 0)
                        {
                            foreach (SemanticLink r in res)
                            {
                                r.Rank += 3;
                                if (r.Role == SemanticRole.Common)
                                {
                                    r.Role = SemanticRole.Strong;
                                }
                            }
                        }
                        else
                        {
                            res.Add(new SemanticLink()
                            {
                                Role = SemanticRole.Strong, Master = master, Slave = slave, Rank = 3
                            });
                        }
                    }
                }
            }
            if (npt1 != null)
            {
                if (((npt1.Adjectives.Count > 0 && npt1.Adjectives[0].BeginToken.Morph.Class.IsPronoun)) || npt1.Anafor != null)
                {
                    foreach (SemanticLink r in res)
                    {
                        if (r.Question == Pullenti.Semantic.Utils.ControlModelQuestion.BaseGenetive)
                        {
                            r.Rank -= 0.5;
                            if (r.Role == SemanticRole.Strong)
                            {
                                r.Role = SemanticRole.Common;
                            }
                        }
                    }
                }
            }
            foreach (SemanticLink r in res)
            {
                if (r.Role == SemanticRole.Strong)
                {
                    foreach (SemanticLink rr in res)
                    {
                        if (rr != r && rr.Role != SemanticRole.Strong)
                        {
                            rr.Rank /= 2;
                        }
                    }
                }
            }
            for (int i = 0; i < res.Count; i++)
            {
                for (int j = 0; j < (res.Count - 1); j++)
                {
                    if (res[j].CompareTo(res[j + 1]) > 0)
                    {
                        SemanticLink r = res[j];
                        res[j]     = res[j + 1];
                        res[j + 1] = r;
                    }
                }
            }
            foreach (SemanticLink r in res)
            {
                r.Master = master;
                r.Slave  = slave;
            }
            return(res);
        }