Inheritance: IDisposable
 public void LoadDictionary(string filepath)
 {
     gren = new SolarixGrammarEngineNET.GrammarEngine2();
     gren.Load(filepath, false);
     Init();
     return;
 }
    public int DumpRule(System.IO.TextWriter dest, int LanguageID, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        dest.WriteLine("\n\n#region\n// This rules has {0} successful checks:", success_count);

        // Выведем список эталонов, которые подтверждают правило:
        foreach (MatchedContextInfo sample in success_samples)
        {
            dest.WriteLine("// {0}", sample.ToString());
        }

        dest.WriteLine("#endregion");

        // теперь само правило
        string lang = string.Empty;;

        switch (LanguageID)
        {
        case SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE: lang = "Russian"; break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.ENGLISH_LANGUAGE: lang = "English"; break;
        }

        dest.WriteLine("colloc_filter auto_rule_{1} language={0}", lang, id);
        dest.WriteLine("{");
        dest.WriteLine(" if context {{{0} }} then accept", rule_context_str);
        dest.WriteLine("}\n");

        return(1);
    }
Example #3
0
 static bool IsPronoun_1s_nom(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode node)
 {
     return(GetPOS(gren, node) == SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN_ru &&
            node.GetCoordState(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru) == SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_1_ru &&
            node.GetCoordState(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru) == SolarixGrammarEngineNET.GrammarEngineAPI.NOMINATIVE_CASE_ru &&
            node.GetCoordState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru) == SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru);
 }
Example #4
0
    static int GetPOS(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode node)
    {
        int id_entry = node.GetEntryID();
        int pos_id   = gren.GetEntryClass(id_entry);

        return(pos_id);
    }
Example #5
0
    static string GetFeatures(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.AnalysisResults words, int focus_index)
    {
        List <string> features = new List <string>();

        for (int offset = -window; offset <= window; ++offset)
        {
            int word_index = focus_index + offset;
            if (word_index >= 1 && word_index < words.Count - 1)
            {
                features.AddRange(GetWordFeatures(gren, words[word_index], offset.ToString()));

                if (word_index == 1)
                {
                    features.Add($"start[{offset}]");
                }

                if (word_index == words.Count - 2)
                {
                    features.Add($"end[{offset}]");
                }
            }
        }

        return(string.Join("\t", features));
    }
Example #6
0
    static List <string> GetWordFeatures(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode word, string feature_prefix)
    {
        List <string> features = new List <string>();

        if (emit_shingles)
        {
            // шинглы
            features.AddRange(GetShingles(word.GetWord()).Select(z => $"shingle[{feature_prefix}]={z}"));
        }

        if (emit_morphtags)
        {
            // морфологические фичи
            int id_class = gren.GetEntryClass(word.GetEntryID());
            features.Add(string.Format("class[{0}]={1}", feature_prefix, id_class));

            int nfeat = SolarixGrammarEngineNET.GrammarEngine.sol_GetNodePairsCount(word.hNode);
            for (int i = 0; i < nfeat; ++i)
            {
                int id_coord = SolarixGrammarEngineNET.GrammarEngine.sol_GetNodePairCoord(word.hNode, i);
                int id_state = SolarixGrammarEngineNET.GrammarEngine.sol_GetNodePairState(word.hNode, i);
                features.Add(string.Format("{0}[{2}]={1}", id_coord, id_state, feature_prefix));
            }
        }

        return(features);
    }
    public int Match(SolarixGrammarEngineNET.AnalysisResults tokens, int left_i, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        // Проверяем, что не-омонимичные термы сопоставляются.
        bool m = true;

        for (int iterm = 0; iterm < points.Count; ++iterm)
        {
            if (points[iterm] != null)
            {
                SolarixGrammarEngineNET.SyntaxTreeNode token = tokens[left_i + iterm];
                if (!points[iterm].Match(token, gren))
                {
                    m = false;
                    break;
                }
            }
        }

        if (m)
        {
            // Осталось проверить, правильно ли снята омонимия.
            SolarixGrammarEngineNET.SyntaxTreeNode omonym_token = tokens[left_i + omonym_point.GetPosition()];
            return(omonym_point.Match(omonym_token) ? 1 : 0);
        }

        return(-1);
    }
Example #8
0
 public FootPrint(SolarixGrammarEngineNET.GrammarEngine2 gren, List <SolarixGrammarEngineNET.SyntaxTreeNode> terms)
 {
     tokens = new List <FootPrintToken>();
     foreach (var term in terms)
     {
         tokens.Add(new FootPrintToken(gren, term));
     }
 }
    public bool Match(SolarixGrammarEngineNET.SyntaxTreeNode proj, int iver, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        if (lexeme != null)
        {
            return(proj.GetWord().Equals(lexeme, StringComparison.InvariantCultureIgnoreCase));
        }

        if (id_lemma != null)
        {
            int ekey = proj.GetVersionEntryID(iver);
            if (id_lemma.Contains(ekey))
            {
                return(true);
            }

            return(false);
        }

        if (pos != null)
        {
            bool pos_matched = false;

            int ekey = proj.GetVersionEntryID(iver);
            if (ekey != -1)
            {
                int id_class = gren.GetEntryClass(ekey);
                pos_matched = pos.Contains(id_class);
            }

            if (!pos_matched)
            {
                return(false);
            }
        }

        if (pairs != null)
        {
            bool contains_all_required_pairs = true;
            foreach (SolarixGrammarEngineNET.CoordPair p in pairs)
            {
                if (!proj.VersionContains(iver, p))
                {
                    contains_all_required_pairs = false;
                    break;
                }
            }

            if (!contains_all_required_pairs)
            {
                return(false);
            }
        }

        return(true);
    }
    public int DumpRules(System.IO.TextWriter dest, int LanguageID, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        int counter = 0;

        foreach (var r in rules)
        {
            counter += r.Value.DumpRules(dest, LanguageID, gren);
        }

        return(counter);
    }
Example #11
0
  public SyntaxTreeNode( GrammarEngine2 _gren, IntPtr _hNode )
  {
   gren = _gren;
   hNode = _hNode;

   int nleaf = GrammarEngine.sol_CountLeafs( hNode );
   leafs = new List<SyntaxTreeNode>();
   for( int i = 0; i < nleaf; ++i )
    leafs.Add( new SyntaxTreeNode( gren, GrammarEngine.sol_GetLeaf( hNode, i ) ) );

   return;
  }
Example #12
0
        public AnalysisResults( GrammarEngine2 gren, IntPtr _hPack, bool release_handle )
        {
            hPack = new AnalysisResultsSafeHandle( _hPack, release_handle );
               nodes = new List<SyntaxTreeNode>();

               int n = SolarixGrammarEngineNET.GrammarEngine.sol_CountRoots( hPack.DangerousGetHandle(), 0 );
               for( int i = 0; i < n; ++i )
               {
            SyntaxTreeNode node = new SyntaxTreeNode( gren, SolarixGrammarEngineNET.GrammarEngine.sol_GetRoot( hPack.DangerousGetHandle(), 0, i ) );
            nodes.Add( node );
               }
        }
Example #13
0
    static string ChangePronounTo(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode node, string to_person)
    {
        List <int> coords = new List <int>();
        List <int> states = new List <int>();

        if (to_person == "1s")
        {
            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru);

            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru);
            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_1_ru);
        }
        else if (to_person == "2s")
        {
            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru);

            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru);
            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_2_ru);
        }
        else if (to_person == "3s")
        {
            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru);

            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru);
            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_2_ru);
        }
        else
        {
            throw new ArgumentException("to_person");
        }


        coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
        states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NOMINATIVE_CASE_ru);

        string        new_word = "";
        List <string> fx       = SolarixGrammarEngineNET.GrammarEngine.sol_GenerateWordformsFX(gren.GetEngineHandle(), node.GetEntryID(), coords, states);

        if (fx != null && fx.Count > 0)
        {
            new_word = fx[0].ToLower();
        }
        else
        {
            new_word = null;
        }

        return(new_word);
    }
Example #14
0
        public AnalysisResults(GrammarEngine2 gren, IntPtr _hPack, bool release_handle)
        {
            hPack = new AnalysisResultsSafeHandle(_hPack, release_handle);
            nodes = new List <SyntaxTreeNode>();

            int n = SolarixGrammarEngineNET.GrammarEngine.sol_CountRoots(hPack.DangerousGetHandle(), 0);

            for (int i = 0; i < n; ++i)
            {
                SyntaxTreeNode node = new SyntaxTreeNode(gren, SolarixGrammarEngineNET.GrammarEngine.sol_GetRoot(hPack.DangerousGetHandle(), 0, i));
                nodes.Add(node);
            }
        }
    private static string TermToString(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode term)
    {
        int id_entry = term.GetEntryID();

        if (gren.GetEntryName(id_entry) == "???")
        {
            return(term.GetWord());
        }

        string res_word = gren.RestoreCasing(id_entry, term.GetWord());

        return(res_word);
    }
Example #16
0
    public string Preprocess(string phrase0, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        string phrase = phrase0;

        if (phrase.EndsWith(".."))
        {
            phrase = phrase.Substring(0, phrase.Length - 2);
        }

        if (phrase.EndsWith("!"))
        {
            phrase = phrase.Substring(0, phrase.Length - 1);
        }


        string[]      tokens     = gren.Tokenize(phrase, SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE);
        List <string> res_tokens = tokens.ToList();
        bool          changed    = false;

        string s = string.Join("|", tokens).ToLower();

        foreach (string prefix in prefixes)
        {
            if (s.StartsWith(prefix))
            {
                // Ну и жара нынче стоит!
                res_tokens = res_tokens.Skip(prefix.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length).ToList();
                changed    = true;
                break;
            }
        }

        foreach (string infix in infixes)
        {
            if (res_tokens.Contains(infix))
            {
                res_tokens.Remove(infix);
                changed = true;
            }
        }


        if (changed)
        {
            return(string.Join(" ", res_tokens));
        }
        else
        {
            return(phrase);
        }
    }
Example #17
0
    static bool IsVerb_1s(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode node)
    {
        if (GetPOS(gren, node) == SolarixGrammarEngineNET.GrammarEngineAPI.VERB_ru)
        {
            if (node.GetCoordState(SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru) == SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_1_ru &&
                node.GetCoordState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru) == SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru &&
                node.GetCoordState(SolarixGrammarEngineNET.GrammarEngineAPI.VERB_FORM_ru) == SolarixGrammarEngineNET.GrammarEngineAPI.VB_INF_ru)
            {
                return(true);
            }
        }

        return(false);
    }
    public string GetContextPoint(SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        System.Text.StringBuilder b = new StringBuilder();

        if (!string.IsNullOrEmpty(lexem))
        {
            b.AppendFormat("\"{0}\"", lexem);
        }
        else
        {
            if (id_class != -1)
            {
                b.AppendFormat("{0}:*", gren.GetClassName(id_class));
            }
            else
            {
                int pos = gren.GetEntryClass(id_entry);
                b.AppendFormat("{0}:{1}", gren.GetClassName(pos), gren.GetEntryName(id_entry));
            }

            b.Append("{");

            // выводим список координатных пар
            foreach (SolarixGrammarEngineNET.CoordPair p in pairs)
            {
                string CoordName = gren.GetCoordName(p.CoordID);
                if (gren.CountCoordStates(p.CoordID) == 0)
                {
                    if (p.StateID == 1)
                    {
                        b.AppendFormat(" {0}", CoordName);
                    }
                    else
                    {
                        b.AppendFormat(" ~{0}", CoordName);
                    }
                }
                else
                {
                    string StateName = gren.GetCoordStateName(p.CoordID, p.StateID);
                    b.AppendFormat(" {0}:{1}", CoordName, StateName);
                }
            }

            b.Append(" }");
        }

        return(b.ToString());
    }
Example #19
0
        public SyntaxTreeNode(GrammarEngine2 _gren, IntPtr _hNode)
        {
            gren  = _gren;
            hNode = _hNode;

            int nleaf = GrammarEngine.sol_CountLeafs(hNode);

            leafs = new List <SyntaxTreeNode>();
            for (int i = 0; i < nleaf; ++i)
            {
                leafs.Add(new SyntaxTreeNode(gren, GrammarEngine.sol_GetLeaf(hNode, i)));
            }

            return;
        }
Example #20
0
    static void Build_Morphology_CRF(SolarixGrammarEngineNET.GrammarEngine2 gren, List <string> model_params)
    {
        Builder_CRF builder = new Builder_CRF(SUFFIX_LEN, CONTEXT_SPAN);

        builder.SetModelParams(model_params);

        builder.SetDictionary(gren);

        builder.SetTmpFolder(tmp_folder);

        if (!string.IsNullOrEmpty(sematags_path))
        {
            builder.LoadSemanticTags(sematags_path);
        }

        int counter   = 0;
        int MAX_COUNT = NSAMPLE;

        int TEST_SHARE = 10; // каждый такой пример идет на валидацию

        foreach (var corpus in corpora)
        {
            foreach (SentenceData sample in corpus.Read(gren))
            {
                counter++;
                if (counter >= MAX_COUNT)
                {
                    break;
                }
                Console.WriteLine("{0}: {1}", counter, sample.GetSentenceStr());

                if ((counter % TEST_SHARE) == 0)
                {
                    builder.ProcessValidationSample(sample);
                }
                else
                {
                    builder.ProcessTrainingSample(sample);
                }
            }
        }

        builder.FinishLearning();
        Console.WriteLine("Storing the model files...");
        builder.FinishTesting();

        return;
    }
    public OmonymContextEnumerator(SolarixGrammarEngineNET.AnalysisResults tokens, int _omonym_position, int _left_i, int _len, SolarixGrammarEngineNET.GrammarEngine2 _gren)
    {
        gren            = _gren;
        left_i          = _left_i;
        len             = _len;
        omonym_position = _omonym_position;

        recognizers = new List <ContextRecognizer>();

        // Для каждого токена, кроме омонимичной формы, генерируем список вариантов.

        // ... пока только код для контекстов длины=2
        if (len == 2)
        {
            SolarixGrammarEngineNET.SyntaxTreeNode omonym_token = tokens[left_i + omonym_position];

            OmonymTokenRecognizer omonym_point = new OmonymTokenRecognizer(omonym_position, omonym_token);

            if (omonym_position == 0)
            {
                TokenTagsEnumerator tte = new TokenTagsEnumerator(IsBoundaryToken(tokens, left_i + 1), tokens[left_i + 1], gren);

                int n = tte.Count;
                for (int i = 0; i < n; ++i)
                {
                    List <TokenRecognizer> points = new List <TokenRecognizer>();
                    points.Add(null); // это омонимичная форма
                    points.Add(tte[i]);
                    ContextRecognizer ctx_recognizer = new ContextRecognizer(points, omonym_point, gren);
                    recognizers.Add(ctx_recognizer);
                }
            }
            else
            {
                TokenTagsEnumerator tte = new TokenTagsEnumerator(IsBoundaryToken(tokens, left_i), tokens[left_i], gren);

                int n = tte.Count;
                for (int i = 0; i < n; ++i)
                {
                    List <TokenRecognizer> points = new List <TokenRecognizer>();
                    points.Add(tte[i]);
                    points.Add(null); // это омонимичная форма
                    ContextRecognizer ctx_recognizer = new ContextRecognizer(points, omonym_point, gren);
                    recognizers.Add(ctx_recognizer);
                }
            }
        }
    }
    private string PrintContext(SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        System.Text.StringBuilder ctx_str = new StringBuilder();
        foreach (var point in points)
        {
            if (point == null)
            {
                ctx_str.AppendFormat(" {0}", omonym_point.GetContextPoint(gren));
            }
            else
            {
                ctx_str.AppendFormat(" {0}", point.GetContextPoint(gren));
            }
        }

        return(ctx_str.ToString());
    }
    public int DumpRules(System.IO.TextWriter dest, int LanguageID, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        int counter = 0;

        // Выводим все правила (todo - надо только самые общие из возможных), которые ни разу не ошиблись.
        List <ContextRecognizer> good = new List <ContextRecognizer>();

        foreach (ContextRecognizer r in recognizers)
        {
            if (!r.HasEverFailed())
            {
                good.Add(r);
            }
        }

        // теперь оставим в этом списке только ортогональные правила.
        List <ContextRecognizer> orthogonal = new List <ContextRecognizer>();

        for (int i = 0; i < good.Count; ++i)
        {
            ContextRecognizer x = good[i];

            bool is_orthogonal = true;

            for (int j = 0; j < good.Count; ++j)
            {
                if (i != j && good[j].IncludesY(x))
                {
                    is_orthogonal = false;
                    break;
                }
            }

            if (is_orthogonal)
            {
                orthogonal.Add(x);
            }
        }

        foreach (ContextRecognizer r in orthogonal)
        {
            counter += r.DumpRule(dest, LanguageID, gren);
        }

        return(counter);
    }
    public int MatchTags(SolarixGrammarEngineNET.SyntaxTreeNode token, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        foreach (TagMatcher m in matchers)
        {
            if (m.Match(token, gren))
            {
                return(m.GetId());
            }
        }

        int    entry_id       = token.GetEntryID();
        int    pos_id         = gren.GetEntryClass(entry_id);
        string part_of_speech = gren.GetClassName(pos_id);
        string tags           = string.Join(" ", token.GetPairs().Select(z => string.Format("{0}={1}", gren.GetCoordName(z.CoordID), gren.GetCoordStateName(z.CoordID, z.StateID))).ToArray());
        string msg            = string.Format("Can not find tag for {0} {{ {1} {2} }}", token.GetWord(), part_of_speech, tags);

        throw new ApplicationException(msg);
    }
    public bool Match(SolarixGrammarEngineNET.SyntaxTreeNode token, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        if (!string.IsNullOrEmpty(lexem))
        {
            return(lexem.Equals(token.GetWord(), StringComparison.CurrentCultureIgnoreCase));
        }

        // Признаём сопоставимость с любой версией токена.
        int nver = token.VersionCount();

        for (int iver = 0; iver < nver; ++iver)
        {
            int version_ekey = token.GetVersionEntryID(iver);

            if (id_entry != -1 && version_ekey == id_entry)
            {
                return(true);
            }

            if (id_class != -1 && gren.GetEntryClass(version_ekey) == id_class)
            {
                return(true);
            }

            bool pairs_matched = true;
            foreach (SolarixGrammarEngineNET.CoordPair p in pairs)
            {
                if (!token.VersionContains(iver, p))
                {
                    pairs_matched = false;
                    break;
                }
            }

            if (pairs_matched)
            {
                return(true);
            }
        }

        return(true);
    }
    private static void Build_LemmByPostags(SolarixGrammarEngineNET.GrammarEngine2 gren, List <string> model_params)
    {
        Builder_LEMM_ByPOSTag builder = new Builder_LEMM_ByPOSTag();

        builder.ChangeModelParams(model_params);
        builder.SetDictionary(gren);
        builder.SetTmpFolder(tmp_folder);
        builder.Init();

        int counter   = 0;
        int MAX_COUNT = NSAMPLE == 0 ? int.MaxValue : NSAMPLE;

        int TEST_SHARE = 10; // каждый такой пример идет на валидацию

        foreach (var corpus in corpora)
        {
            foreach (SentenceData sample in corpus.Read(gren))
            {
                counter++;
                if (counter >= MAX_COUNT)
                {
                    break;
                }
                Console.WriteLine("{0}: {1}", counter, sample.GetSentenceStr());

                if ((counter % TEST_SHARE) == 0)
                {
                    builder.ProcessValidationSample(sample);
                }
                else
                {
                    builder.ProcessTrainingSample(sample);
                }
            }
        }


        builder.FinishLearning();
        builder.StartTesting();
        builder.PrintTestResults();
        return;
    }
    public int MatchTags(SolarixGrammarEngineNET.SyntaxTreeNode proj, int iproj, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        foreach (TagMatcher m in matchers)
        {
            if (m.Match(proj, iproj, gren))
            {
                // ---~~~~~ DEBUG ~~~---
#if DEBUG
                string matcher = m.ToString();
                string form    = "";

                int npair = SolarixGrammarEngineNET.GrammarEngine.sol_GetNodeVerPairsCount(proj.hNode, iproj);
                for (int j = 0; j < npair; ++j)
                {
                    int id_coord = SolarixGrammarEngineNET.GrammarEngine.sol_GetNodeVerPairCoord(proj.hNode, iproj, j);
                    int id_state = SolarixGrammarEngineNET.GrammarEngine.sol_GetNodeVerPairState(proj.hNode, iproj, j);

                    string coord_name = gren.GetCoordName(id_coord);

                    string state_name = null;
                    if (gren.CountCoordStates(id_coord) == 0)
                    {
                        state_name = id_state.ToString();
                    }
                    else
                    {
                        state_name = gren.GetCoordStateName(id_coord, id_state);
                    }

                    form += string.Format(" {0}:{1}", coord_name, state_name);
                }
#endif
                // ---~~~~~ ..... ~~~---

                return(m.GetId());
            }
        }

        return(-1);
    }
    public void Load(string lines, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        matchers   = new List <TagMatcher>();
        id2matcher = new Dictionary <int, TagMatcher>();
        id2index   = new Dictionary <int, int>();
        index2id   = new Dictionary <int, int>();

        foreach (string line in lines.Split('\n'))
        {
            string l = line.Trim();
            if (!string.IsNullOrEmpty(l))
            {
                TagMatcher m = new TagMatcher(line, gren);
                matchers.Add(m);
                id2matcher.Add(m.GetId(), m);
                id2index.Add(m.GetId(), matchers.Count - 1);
                index2id.Add(matchers.Count - 1, m.GetId());
            }
        }

        return;
    }
    private void ProcessTree(SolarixGrammarEngineNET.SyntaxTreeNode node, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        int p_ekey   = node.GetEntryID();
        int id_class = gren.GetEntryClass(p_ekey);

        if (
            id_class == SolarixGrammarEngineNET.GrammarEngineAPI.NOUN_ru ||
            id_class == SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN2_ru ||
            id_class == SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN_ru
            )
        {
            SetLabel(node, string.Format("NP:{0}", chunk_num++), true);

            for (int ileaf = 0; ileaf < node.leafs.Count; ++ileaf)
            {
                SolarixGrammarEngineNET.SyntaxTreeNode leaf = node.leafs[ileaf];

                if (
                    node.GetLinkType(ileaf) == SolarixGrammarEngineNET.GrammarEngineAPI.RIGHT_GENITIVE_OBJECT_link ||
                    node.GetLinkType(ileaf) == SolarixGrammarEngineNET.GrammarEngineAPI.OBJECT_link
                    )
                {
                    SetLabel(leaf, string.Format("NP:{0}", chunk_num++), true);
                }
            }
        }
        else if (id_class == SolarixGrammarEngineNET.GrammarEngineAPI.PREPOS_ru)
        {
            SetLabel(node, string.Format("PN:{0}", chunk_num++), true);

            for (int ileaf = 0; ileaf < node.leafs.Count; ++ileaf)
            {
                SolarixGrammarEngineNET.SyntaxTreeNode leaf = node.leafs[ileaf];

                int p_ekey2   = leaf.GetEntryID();
                int id_class2 = gren.GetEntryClass(p_ekey2);
                if (
                    id_class2 == SolarixGrammarEngineNET.GrammarEngineAPI.NOUN_ru ||
                    id_class2 == SolarixGrammarEngineNET.GrammarEngineAPI.ADJ_ru ||
                    id_class2 == SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN_ru ||
                    id_class2 == SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN2_ru ||
                    id_class2 == SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru
                    )
                {
                    SetLabel(leaf, string.Format("NP:{0}", chunk_num++), true);
                }
            }
        }
        else if (
            id_class == SolarixGrammarEngineNET.GrammarEngineAPI.IMPERSONAL_VERB_ru ||
            id_class == SolarixGrammarEngineNET.GrammarEngineAPI.VERB_ru ||
            id_class == SolarixGrammarEngineNET.GrammarEngineAPI.INFINITIVE_ru
            )
        {
            SetLabel(node, string.Format("VP:{0}", chunk_num++), true);
            SetLabel(node, string.Format("VX:{0}", chunk_num++), false); // корневой глагол отмечаем как VX

            for (int ileaf = 0; ileaf < node.leafs.Count; ++ileaf)
            {
                SolarixGrammarEngineNET.SyntaxTreeNode leaf = node.leafs[ileaf];

                if (node.GetLinkType(ileaf) == SolarixGrammarEngineNET.GrammarEngineAPI.SUBJECT_link)
                {
                    SetLabel(leaf, string.Format("NP:{0}", chunk_num++), true);
                }
                else if (node.GetLinkType(ileaf) == SolarixGrammarEngineNET.GrammarEngineAPI.OBJECT_link)
                {
                    SetLabel(leaf, string.Format("NP:{0}", chunk_num++), true);
                }
            }
        }

        for (int ileaf = 0; ileaf < node.leafs.Count; ++ileaf)
        {
            SolarixGrammarEngineNET.SyntaxTreeNode leaf = node.leafs[ileaf];
            ProcessTree(leaf, gren);
        }

        return;
    }
    public void Collect(SolarixGrammarEngineNET.AnalysisResults tokens, SolarixGrammarEngineNET.AnalysisResults trees, SolarixGrammarEngineNET.GrammarEngine2 gren)
    {
        if (trees.Count == 3)
        {
            SolarixGrammarEngineNET.SyntaxTreeNode root = trees[1];
            int p_ekey   = root.GetEntryID();
            int id_class = gren.GetEntryClass(p_ekey);

            if (
                id_class == SolarixGrammarEngineNET.GrammarEngineAPI.IMPERSONAL_VERB_ru ||
                id_class == SolarixGrammarEngineNET.GrammarEngineAPI.VERB_ru ||
                id_class == SolarixGrammarEngineNET.GrammarEngineAPI.INFINITIVE_ru
                )
            {
                ok = true;
            }
        }

        if (ok)
        {
            int N = tokens.Count;

            labels = new List <List <string> >();
            for (int iroot = 0; iroot < N; ++iroot)
            {
                List <string> x = new List <string>();
                x.Add("O");
                labels.Add(x);
            }

            for (int iroot = 1; iroot < trees.Count - 1; ++iroot)
            {
                ProcessTree(trees[iroot], gren);
            }

            // -----------------------------------------------
            // Уточняем разметку для групп существительных
            // -----------------------------------------------
            for (int i = 1; i < N - 1; ++i)
            {
                List <string> l = labels[i];

                if (l[0].StartsWith("NP"))
                {
                    string NP = l[0];

                    // меняем метку у первого токена на B-NP
                    l.RemoveAt(0);
                    l.Insert(0, "B-NP");

                    // идем вправо до появления другой NP-метки.
                    for (int k = i + 1; k < N; ++k)
                    {
                        if (labels[k][0] == NP)
                        {
                            labels[k].RemoveAt(0);
                            labels[k].Insert(0, "I-NP");
                        }
                        else
                        {
                            // Удалим все появления NP-метки далее вправо.
                            for (int q = k; q < N; ++q)
                            {
                                labels[q].Remove(NP);
                            }

                            break;
                        }
                    }
                }
            }


            // Уточняем разметку для глагольных групп.
            for (int i = 1; i < N - 1; ++i)
            {
                List <string> l = labels[i];

                if (l[0].StartsWith("VX"))
                {
                    // Корневой глагол в сказуемом.
                    // Цепочка токенов в группе может быть разорвана из-за того, что наречный оборот, привязанный к сказуемому,
                    // стоит справа от глагольного дополнения. Поэтому проверим наличие таких разрывов.
                    l.RemoveAt(0); // под VX лежит VP, который мы сейчас поднимем
                    string VP = l[0];

                    int vp_begin = i;
                    // ищем разрыв слева
                    for (int k = i - 1; k >= 0; --k)
                    {
                        if (labels[k][0] != VP)
                        {
                            // слева - конец цепочки токенов для этого сказуемого. Удалим все более левые упоминания этого VP.
                            for ( ; k >= 0; --k)
                            {
                                labels[k].Remove(VP);
                            }

                            break;
                        }
                        else
                        {
                            vp_begin = k;
                        }
                    }

                    int vp_end = i;
                    // ищем разрыв справа
                    for (int k = i + 1; k < N; ++k)
                    {
                        if (labels[k][0] != VP)
                        {
                            // справа - конец цепочки токенов для этого сказуемого. Удалим все более правые упоминания этого VP.
                            for ( ; k < N; ++k)
                            {
                                labels[k].Remove(VP);
                            }
                            break;
                        }
                        else
                        {
                            vp_end = k;
                        }
                    }

                    // поставим отметку на первый VP-токен
                    labels[vp_begin].RemoveAt(0);
                    labels[vp_begin].Insert(0, "B-VP");

                    // а остальные пометим как I-VP
                    for (int j = vp_begin + 1; j <= vp_end; ++j)
                    {
                        labels[j].Remove(VP);
                        labels[j].Insert(0, "I-VP");
                    }
                }
            }


            for (int i = 0; i < labels.Count; ++i)
            {
                string   l = labels[i][0];
                string[] t = l.Split(':');
                labels[i].Clear();
                labels[i].Add(t[0]);
            }
        }

        return;
    }
Example #31
0
    public FootPrintToken(SolarixGrammarEngineNET.GrammarEngine2 gren, SolarixGrammarEngineNET.SyntaxTreeNode root)
    {
        Contract.Ensures(!string.IsNullOrEmpty(this.word));
        Contract.Ensures(this.node != null);
        Contract.Ensures(this.tags != null);

        this.word = root.GetWord();
        this.tags = new List <string>();
        this.node = root;

        this.tags.Add(root.GetWord().ToLower());

        if (root.GetWord().Equals("не", StringComparison.OrdinalIgnoreCase))
        {
            this.tags.Add("neg");
        }


        int part_of_speech = gren.GetEntryClass(root.GetEntryID());

        switch (part_of_speech)
        {
        case SolarixGrammarEngineNET.GrammarEngineAPI.CONJ_ru: this.tags.Add("conj"); break;     // союз

        case SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN_ru: this.tags.Add("pr"); break;    // местоимение Я

        case SolarixGrammarEngineNET.GrammarEngineAPI.NOUN_ru: this.tags.Add("n"); break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.ADJ_ru: this.tags.Add("adj"); break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.VERB_ru: this.tags.Add("v"); break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.INFINITIVE_ru: this.tags.Add("v"); break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.GERUND_2_ru: this.tags.AddRange("adv adv_v".Split(' ')); break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.ADVERB_ru:
        {
            this.tags.Add("adv");
            if (StringExtender.InCI(word, "очень крайне наиболее наименее чрезвычайно почти".Split()))         // модификаторы наречий и прилагательных
            {
                this.tags.Add("a_modif");
            }

            string adv_cat = AdverbCategory.GetQuestionWordForAdverb(word);
            if (!string.IsNullOrEmpty(adv_cat))
            {
                this.tags.Add("adv_" + adv_cat);
            }

            break;
        }

        case SolarixGrammarEngineNET.GrammarEngineAPI.PREPOS_ru: this.tags.Add("p"); break;

        case SolarixGrammarEngineNET.GrammarEngineAPI.PRONOUN2_ru: this.tags.Add("pr"); break;

        default: this.tags.Add("x"); break;
        }

        foreach (var p in root.GetPairs())
        {
            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.NOMINATIVE_CASE_ru: this.tags.Add("nom"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.GENITIVE_CASE_ru: this.tags.Add("gen"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.ACCUSATIVE_CASE_ru: this.tags.Add("acc"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.DATIVE_CASE_ru: this.tags.Add("dat"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.PREPOSITIVE_CASE_ru: this.tags.Add("prep"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.PARTITIVE_CASE_ru: this.tags.Add("part"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.LOCATIVE_CASE_ru: this.tags.Add("loc"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.INSTRUMENTAL_CASE_ru: this.tags.Add("instr"); break;
                }
            }

            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.SINGULAR_NUMBER_ru: this.tags.Add("sing"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.PLURAL_NUMBER_ru: this.tags.Add("pl"); break;
                }
            }

            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.TENSE_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.PAST_ru: this.tags.Add("past"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.PRESENT_ru: this.tags.Add("pres"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.FUTURE_ru: this.tags.Add("future"); break;
                }
            }

            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.FORM_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.ANIMATIVE_FORM_ru: this.tags.Add("anim"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.INANIMATIVE_FORM_ru: this.tags.Add("inanim"); break;
                }
            }

            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.MASCULINE_GENDER_ru: this.tags.Add("masc"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.FEMININE_GENDER_ru: this.tags.Add("fem"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.NEUTRAL_GENDER_ru: this.tags.Add("neut"); break;
                }
            }


            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_1_ru: this.tags.Add("1"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_2_ru: this.tags.Add("2"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.PERSON_3_ru: this.tags.Add("3"); break;
                }
            }


            if (p.CoordID == SolarixGrammarEngineNET.GrammarEngineAPI.VERB_FORM_ru)
            {
                switch (p.StateID)
                {
                case SolarixGrammarEngineNET.GrammarEngineAPI.VB_INF_ru: this.tags.Add("vf1"); break;

                case SolarixGrammarEngineNET.GrammarEngineAPI.VB_ORDER_ru: this.tags.Add("imper"); break;
                }
            }
        }
    }
    static void Main(string[] args)
    {
        string parsed_sentences = @"F:\Corpus\parsing\ru\SENT4.parsing.txt";
        string result_path = @"f:\tmp\negative3.dat";
        string dict_path = @"e:\MVoice\lem\bin-windows64\dictionary.xml";

        // Загрузим морфологический словарь, он нам понадобится для смены падежей слов.
        SolarixGrammarEngineNET.GrammarEngine2 gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dict_path, true);


        string[] files = null;
        if (System.IO.Directory.Exists(parsed_sentences))
            files = System.IO.Directory.GetFiles(parsed_sentences, "*.parsing.txt");
        else
            files = new string[1] { parsed_sentences };

        List<TreeTemplate> templates = new List<TreeTemplate>();
        templates.Add(new TreeTemplate("[class:ГЛАГОЛ]( <PREPOS_ADJUNCT>[class:ПРЕДЛОГ].<OBJECT>[class:МЕСТОИМЕНИЕ,СУЩЕСТВИТЕЛЬНОЕ,ПРИЛАГАТЕЛЬНОЕ] )"));

        sample_count = 0;

        using (wrt = new System.IO.StreamWriter(result_path))
        {
            foreach (string file in files)
            {
                Console.WriteLine("Processing {0}...", file);

                using (Sentences src = new Sentences(file))
                {
                    while (src.Next())
                    {
                        Sentence sent = src.GetFetched();
                        if (sent.root != null)
                        {
                            #region AdjNounAdjNoun

                            for (int i1 = 0; i1 < sent.Tokens.Count; ++i1)
                            {
                                if (sent.Tokens[i1].part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                {
                                    SNode node1 = sent.Nodes.Where(z => z.index == i1).First();
                                    if (node1.edge_types.Count > 0)
                                    {
                                        int edge1 = -1;

                                        for (int j1 = 0; j1 < node1.edge_types.Count; ++j1)
                                        {
                                            if (node1.edge_types[j1] == "ATTRIBUTE")
                                            {
                                                if (sent.Tokens[node1.children[j1].index].part_of_speech == "ПРИЛАГАТЕЛЬНОЕ")
                                                {
                                                    edge1 = j1;
                                                    break;
                                                }
                                            }
                                        }

                                        if (edge1 != -1)
                                        {
                                            // Нашли первое существительное с атрибутирующим прилагательным.
                                            int noun_ie1 = gren.FindEntry(sent.Tokens[i1].word, gren.FindPartOfSpeech(sent.Tokens[i1].part_of_speech));

                                            SToken adj1 = sent.Tokens[node1.children[edge1].index];
                                            adj1.word = adj1.word.ToLower();


                                            for (int i2 = i1 + 2; i2 < sent.Tokens.Count; ++i2)
                                            {
                                                if (sent.Tokens[i2].part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                                {
                                                    int noun_ie2 = gren.FindEntry(sent.Tokens[i2].word, gren.FindPartOfSpeech(sent.Tokens[i2].part_of_speech));

                                                    if (noun_ie1 != noun_ie2)
                                                    {
                                                        int gender1 = gren.GetEntryAttrState(noun_ie1, SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru);
                                                        int gender2 = gren.GetEntryAttrState(noun_ie2, SolarixGrammarEngineNET.GrammarEngineAPI.GENDER_ru);
                                                        if (gender1 == gender2)
                                                        {
                                                            string number1 = sent.Tokens[i1].tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                            string number2 = sent.Tokens[i2].tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];

                                                            if (number1 == number2)
                                                            {
                                                                SNode node2 = sent.Nodes.Where(z => z.index == i2).First();
                                                                if (node2.edge_types.Count > 0)
                                                                {
                                                                    int edge2 = -1;

                                                                    for (int j2 = 0; j2 < node2.edge_types.Count; ++j2)
                                                                    {
                                                                        if (node2.edge_types[j2] == "ATTRIBUTE")
                                                                        {
                                                                            if (sent.Tokens[node2.children[j2].index].part_of_speech == "ПРИЛАГАТЕЛЬНОЕ")
                                                                            {
                                                                                edge2 = j2;
                                                                                break;
                                                                            }
                                                                        }
                                                                    }

                                                                    if (edge2 != -1)
                                                                    {
                                                                        // Нашли второе существительное с атрибутирующим прилагательным.
                                                                        SToken adj2 = sent.Tokens[node2.children[edge2].index];
                                                                        adj2.word = adj2.word.ToLower();


                                                                        // Сгенерируем предложение, в котором эти прилагательные поменяны местами.
                                                                        List<SToken> tokens2 = new List<SToken>();
                                                                        foreach (SToken t in sent.Tokens)
                                                                        {
                                                                            if (t.index == adj1.index)
                                                                            {
                                                                                tokens2.Add(adj2);
                                                                            }
                                                                            else if (t.index == adj2.index)
                                                                            {
                                                                                tokens2.Add(adj1);
                                                                            }
                                                                            else
                                                                            {
                                                                                tokens2.Add(t);
                                                                            }
                                                                        }

                                                                        StoreSample(sent, tokens2);
                                                                    }
                                                                    else
                                                                    {
                                                                        // у второго существительного нет атрибутирующего прилагательного.
                                                                        // перенесем прилагательное от первого ко второму существительному.

                                                                        List<SToken> tokens2 = new List<SToken>();
                                                                        foreach (SToken t in sent.Tokens)
                                                                        {
                                                                            if (t.index == adj1.index)
                                                                            {
                                                                                continue;
                                                                            }
                                                                            else if (t.index == i2)
                                                                            {
                                                                                tokens2.Add(adj1);
                                                                                tokens2.Add(sent.Tokens[i2]);
                                                                            }
                                                                            else
                                                                            {
                                                                                tokens2.Add(t);
                                                                            }
                                                                        }

                                                                        StoreSample(sent, tokens2);

                                                                    }

                                                                }

                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            #endregion AdjNounAdjNoun


                            #region NounNoun
                            // Ищем два существительных, связанных в конструкцию родительного дополнения:
                            // "восход солнца"
                            // Генерируем предложение с перестановкой слов и сменой падежей:
                            // "солнце восхода"
                            foreach (SNode n1 in sent.Nodes)
                            {
                                SToken t1 = sent.Tokens[n1.index]; // восход
                                if (t1.part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                {
                                    if (n1.children.Count > 0)
                                    {
                                        int gen_edge_index = n1.edge_types.IndexOf("RIGHT_GENITIVE_OBJECT");
                                        if (gen_edge_index != -1)
                                        {
                                            SToken t2 = sent.Tokens[n1.children[gen_edge_index].index]; // солнца

                                            if (gen_edge_index != -1 && t2.part_of_speech == "СУЩЕСТВИТЕЛЬНОЕ")
                                            {
                                                List<SToken> tokens2 = new List<SToken>();
                                                bool t12_ok = true;
                                                foreach (SToken t in sent.Tokens)
                                                {
                                                    if (t.index == t1.index)
                                                    {
                                                        // сюда вставляем слово "солнца" и меняем его падеж на падеж слова t
                                                        string t_case = t.tags.Where(z => z.StartsWith("ПАДЕЖ:")).First().Split(':')[1];
                                                        string t_number = t2.tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                        int ie_t2 = gren.FindEntry(t2.lemma, gren.FindPartOfSpeech(t2.part_of_speech));
                                                        if (ie_t2 != -1)
                                                        {
                                                            List<int> coords = new List<int>();
                                                            List<int> states = new List<int>();
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru, t_case));
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru, t_number));
                                                            List<string> forms = gren.GenerateWordforms(ie_t2, coords, states);
                                                            if (forms.Count > 0)
                                                            {
                                                                string new_word = gren.RestoreCasing(ie_t2, forms[0]);
                                                                SToken new_t = new SToken();
                                                                new_t.index = t.index;
                                                                new_t.word = new_word;
                                                                new_t.lemma = t.lemma;
                                                                new_t.part_of_speech = t1.part_of_speech;
                                                                tokens2.Add(new_t);
                                                            }
                                                            else
                                                            {
                                                                t12_ok = false;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            t12_ok = false;
                                                        }
                                                    }
                                                    else if (t.index == t2.index)
                                                    {
                                                        // сюда вставляем слово "восход" и меняем его падеж на родительный
                                                        string t_number = t1.tags.Where(z => z.StartsWith("ЧИСЛО:")).First().Split(':')[1];
                                                        int ie_t1 = gren.FindEntry(t1.lemma, gren.FindPartOfSpeech(t1.part_of_speech));
                                                        if (ie_t1 != -1)
                                                        {
                                                            List<int> coords = new List<int>();
                                                            List<int> states = new List<int>();
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.CASE_ru);
                                                            states.Add(SolarixGrammarEngineNET.GrammarEngineAPI.GENITIVE_CASE_ru);
                                                            coords.Add(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru);
                                                            states.Add(gren.FindState(SolarixGrammarEngineNET.GrammarEngineAPI.NUMBER_ru, t_number));
                                                            List<string> forms = gren.GenerateWordforms(ie_t1, coords, states);
                                                            if (forms.Count > 0)
                                                            {
                                                                string new_word = gren.RestoreCasing(ie_t1, forms[0]);
                                                                SToken new_t = new SToken();
                                                                new_t.index = t.index;
                                                                new_t.word = new_word;
                                                                new_t.lemma = t.lemma;
                                                                new_t.part_of_speech = t.part_of_speech;
                                                                tokens2.Add(new_t);
                                                            }
                                                            else
                                                            {
                                                                t12_ok = false;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            t12_ok = false;
                                                        }

                                                    }
                                                    else
                                                    {
                                                        tokens2.Add(t);
                                                    }
                                                }

                                                if (t12_ok)
                                                {
                                                    StoreSample(sent, tokens2);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            #endregion NounNoun


                            #region PrepObject
                            // Ищем предлог.
                            foreach (SToken token_prepos in sent.Tokens)
                            {
                                if (token_prepos.part_of_speech == "ПРЕДЛОГ")
                                {
                                    // Нашли предлог. Теперь перенесем его в другую позицию.
                                    List<Tuple<SToken, float>> tokens2 = sent.Tokens.Where(z => z.index != token_prepos.index).Select(z => new Tuple<SToken, float>(z, z.index)).ToList();

                                    foreach (var t2 in tokens2.Where(z => z.Item1.index != token_prepos.index + 1))
                                    {
                                        // Ставим предлог в позицию ПЕРЕД токеном t2 и генерируем предложение.
                                        List<Tuple<SToken, float>> tokens3 = new List<Tuple<SToken, float>>();
                                        tokens3.AddRange(tokens2);
                                        tokens3.Add(new Tuple<SToken, float>(token_prepos, t2.Item2 - 0.5f));

                                        StoreSample(sent, tokens3.OrderBy(z => z.Item2).Select(z => z.Item1).ToList());
                                    }
                                }
                            }
                            #endregion PrepObject


                            /*
                                                        foreach (TreeTemplate t in templates)
                                                        {
                                                            if (t.Match(sent))
                                                            {
                                                            }
                                                        }
                            */
                        }
                    }
                }
            }
        }

        Console.WriteLine("\nsample_count={0}", sample_count);

        return;
    }
Example #33
0
 public TextSegmenter( GrammarEngine2 _gren, IntPtr _hObject )
 {
  gren = _gren;
  hObject = _hObject;
 }
    public static string tmp_folder    = "."; // папка для генерируемых временных файлов - логи, датасеты.

    static void Main(string[] args)
    {
        List <string> model_params = new List <string>();

        if (args.Length > 0)
        {
            for (int i = 0; i < args.Length; ++i)
            {
                if (args[i] == "-dict")
                {
                    // Путь к файлу с конфигурацией словарной базы.
                    dictionary_path = args[i + 1];
                    ++i;
                }
                else if (args[i] == "-tmp")
                {
                    // Временный каталог для сохранения датасетов.
                    tmp_folder = args[i + 1];
                    ++i;
                }
                else if (args[i] == "-corpus")
                {
                    // Путь к бинарному корпусу в формате Solarix.
                    string corpus_path = args[i + 1];
                    corpora.Add(new SolarixBinaryCorpusReader(corpus_path));
                    ++i;
                }
                else if (args[i] == "-conllu_corpus")
                {
                    // Путь к корпусу в формате ConllU
                    string corpus_path = args[i + 1];
                    corpora.Add(new ConlluCorpusReader(corpus_path));
                    ++i;
                }
                else if (args[i] == "-nsample")
                {
                    NSAMPLE = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-minsentlen")
                {
                    MIN_SENT_LEN = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-suffix_len")
                {
                    SUFFIX_LEN = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-context_span")
                {
                    // полуразмер контекста - число слов вправо или влево от текущего слова.
                    CONTEXT_SPAN = int.Parse(args[i + 1]);
                    ++i;
                }
                else if (args[i] == "-params")
                {
                    string[] px = args[i + 1].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    model_params.AddRange(px);
                    ++i;
                }
                else
                {
                    throw new ApplicationException(string.Format("Unknown option [{0}] in command line", args[i]));
                }
            }
        }

        Console.WriteLine("Loading dictionary from {0}...", dictionary_path);
        SolarixGrammarEngineNET.GrammarEngine2 gren;
        gren = new SolarixGrammarEngineNET.GrammarEngine2();
        gren.Load(dictionary_path, true);

        Build_LemmByPostags(gren, model_params);

        return;
    }
Example #35
0
    static void Execute( string[] args )
    {
        string dictionary_path = @"e:\MVoice\lem\bin-windows\dictionary.xml"; // путь к словарной базе
          string samples_path = @"E:\MVoice\lem\Слова\rus\SENT5.plain.txt"; // путь к файлу со списком предложений (одно предложение на одной строке)
          int NSAMPLE = 20000; // сколько предложений максимум обработать
          int START_INDEX = 0; // порядковый номер первого обрабатываемого предложений в исходном файле
          int MAXARGS = 20; // beam size
          bool append_result = false; // если леммы надо добавлять к существующему файлу, а не формировать файл с нуля
          string save_path = null; // путь к файлу, куда будут записаны леммы
          int source_format = 0; // 0 - token per line, 1 - sentence per line
          bool output_lemmas = true; // в результат записывать леммы с приведением к нижнему регистру
          bool output_suffix = false;
          bool output_words = false; // в результат записывать исходные слова с приведением к нижнему регистру
          int suffix_len = 0;
          int min_sentence_length = 0; // фильтр по минимальной длине предложений
          int max_sentence_length = int.MaxValue; // фильтр по максимальной длине предложений
          bool reject_unknown = false; // отбрасывать предложения с несловарными токенами
          bool emit_eol = false; // добавлять в выходной файл токены <EOL> для маркировки конца предложения
          int eol_count = 0; // кол-во вставляемых <EOL>, гарантированно перекрывающее размер окна в word2vec

          List<System.Text.RegularExpressions.Regex> rx_stop = new List<System.Text.RegularExpressions.Regex>();

          for( int i = 0; i < args.Length; ++i )
          {
           if( args[i] == "-dict" )
           {
        ++i;
        dictionary_path = args[i];
           }
           else if( args[i] == "-samples" )
           {
        ++i;
        samples_path = args[i];
           }
           else if( args[i] == "-source_format" )
           {
        ++i;
        source_format = int.Parse( args[i] );
           }
           else if( args[i] == "-append" )
           {
        // Добавлять в конец существующего файла
        append_result = true;
           }
           else if( args[i] == "-emit_eol" )
           {
        ++i;
        eol_count = int.Parse( args[i] );
        if( eol_count > 0 )
         emit_eol = true;
           }
           else if( args[i] == "-result" )
           {
        // Способ обработки токенов:
        // lemma  => лемматизация
        // suffix => усечение до псевдосуффикса длиной -suffix_len
        // raw    => исходные слова
        ++i;
        output_lemmas = false;
        output_suffix = false;
        output_words = false;

        if( args[i] == "suffix" )
        {
         output_suffix = true;
        }
        else if( args[i] == "lemma" )
        {
         output_lemmas = true;
        }
        else if( args[i] == "raw" )
        {
         output_words = true;
        }
        else throw new ApplicationException( string.Format( "Unknown result format: {0}", args[i] ) );
           }
           else if( args[i] == "-save" )
           {
        // Путь к файлу, куда будут записываться результаты обработки
        ++i;
        save_path = args[i];
           }
           else if( args[i] == "-nsample" )
           {
        // кол-во обрабатываемых предложений, начиная с -start_index
        ++i;
        NSAMPLE = int.Parse( args[i] );
           }
           else if( args[i] == "-min_sent_len" )
           {
        // Обрабатывать только предложения, содержащие не менее NNN токенов
        ++i;
        min_sentence_length = int.Parse( args[i] );
           }
           else if( args[i] == "-max_sent_len" )
           {
        // Обрабатывать только предложения, содержащие не более NNN токенов
        ++i;
        max_sentence_length = int.Parse( args[i] );
           }
           else if( args[i] == "-suffix_len" )
           {
        ++i;
        suffix_len = int.Parse( args[i] );
           }
           else if( args[i] == "-start_index" )
           {
        // Начинать обработку с предложения с указанным индексом
        ++i;
        START_INDEX = int.Parse( args[i] );
           }
           else if( args[i] == "-reject_unknown" )
           {
        reject_unknown = true;
           }
           else if( args[i] == "-rx_stop" )
           {
        ++i;
        using( System.IO.StreamReader rdr = new System.IO.StreamReader( args[i] ) )
        {
         while( !rdr.EndOfStream )
         {
          string line = rdr.ReadLine();
          if( line == null )
           break;

          line = line.Trim();
          if( line.Length > 0 )
          {
           rx_stop.Add( new System.Text.RegularExpressions.Regex( line ) );
          }
         }
        }
           }
           else
        throw new ApplicationException( string.Format( "Unknown option {0}", args[i] ) );
          }

          Samples sources = null;
          if( source_format == 1 )
           sources = new Samples1( samples_path );
          else
           sources = new Samples2( samples_path );

          sources.SetMinSentenceLen( min_sentence_length );
          sources.SetMaxSentenceLen( max_sentence_length );

          if( output_suffix || output_words )
           sources.SetTokenDelimiter( '|' );

          SolarixGrammarEngineNET.GrammarEngine2 gren = null;
          gren = new SolarixGrammarEngineNET.GrammarEngine2();

          if( output_lemmas )
          {
           gren.Load( dictionary_path, true );
          }

          int counter = -1;
          int n_processed = 1;
          int MAX_COUNT = NSAMPLE;

          int LanguageID = SolarixGrammarEngineNET.GrammarEngineAPI.RUSSIAN_LANGUAGE;
          int Constraints = 120000 | ( MAXARGS << 22 ); // 2 мин и 20 альтернатив

          SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags Flags = SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL_ONLY |
        SolarixGrammarEngineNET.GrammarEngine.MorphologyFlags.SOL_GREN_MODEL;

          // сколько всего предложений
          Console.WriteLine( "Counting lines in source file {0}...", samples_path );
          int n_total_lines = sources.TotalCount();
          Console.WriteLine( "Total number of lines={0}", n_total_lines.ToString( "N0", new System.Globalization.CultureInfo( "en-US" ) ) );

          System.IO.StreamWriter wrt = new System.IO.StreamWriter( save_path, append_result, new UTF8Encoding( false ) );

          sources.Start();
          while( true )
          {
           string sample = sources.Next();
           if( sample == null )
        break;

           sample = sample.Trim();

           counter++;

           if( counter < START_INDEX )
        continue;

           if( n_processed >= MAX_COUNT )
        break;

           bool contains_insane_chars = false;
           foreach( char c in sample )
        if( c < 32 )
        {
         contains_insane_chars = true;
         break;
        }

           if( contains_insane_chars )
           {
        System.Text.StringBuilder b = new StringBuilder( sample.Length );
        foreach( char c in sample )
         if( c >= 32 )
          b.Append( c );

        sample = b.ToString();
           }

           n_processed++;

           if( sample.Length == 0 )
        continue;

           if( rx_stop.Count > 0 )
           {
        bool reject_this_sample = false;
        foreach( var rx in rx_stop )
         if( rx.Match( sample ).Success )
         {
          reject_this_sample = true;
          break;
         }

        if( reject_this_sample )
         continue;
           }

           if( output_lemmas )
           {
        using( SolarixGrammarEngineNET.AnalysisResults tokens = gren.AnalyzeMorphology( sample, LanguageID, Flags, Constraints ) )
        {
         for( int i = 1; i < tokens.Count - 1; ++i )
         {
          if( char.IsPunctuation( tokens[i].GetWord()[0] ) )
           continue;

          int id_entry = tokens[i].GetEntryID();
          string lemma = gren.GetEntryName( id_entry );
          if( lemma == "???" || lemma.Equals( "UNKNOWNENTRY", StringComparison.InvariantCultureIgnoreCase ) || lemma.Equals( "number_", StringComparison.InvariantCultureIgnoreCase ) )
           lemma = tokens[i].GetWord();

          lemma = lemma.ToLower();
          wrt.Write( " {0}", lemma );
         }
        }
           }
           else if( output_words )
           {
        string[] tokens = sample.Split( "|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries );

        foreach( string token in tokens )
        {
         if( token.Length >= 1 && char.IsPunctuation( token[0] ) )
          continue;

         string norma = token.ToLower();
         wrt.Write( " {0}", norma );
        }
           }
           else if( output_suffix )
           {
        string[] tokens = sample.Split( "|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries );

        foreach( string token in tokens )
        {
         if( token.Length == 0 || ( token.Length == 1 && char.IsPunctuation( token[0] ) ) )
          continue;

         string suffix = token;

         int num;
         if( int.TryParse( token, out num ) )
          suffix = token.Substring( token.Length - 1 );
         else if( token.Length > suffix_len + 1 )
          suffix = "~" + token.Substring( token.Length - suffix_len );

         wrt.Write( " {0}", suffix.ToLower() );
        }
           }

           if( emit_eol )
        for( int k = 0; k < eol_count; ++k )
         wrt.Write( " <EOL>" );

           Console.WriteLine( "[{1}/{2}] {0}", sample, counter, n_total_lines );

           wrt.Flush();
          }

          wrt.Close();

          return;
    }