public bool EqualTokens(ContextRecognizer y) { for (int i = 0; i < points.Count; ++i) { if (points[i] != null && !points[i].SameChecker(y.points[i])) { return(false); } } return(true); }
// Вернет true, если данное правило более общее, чем y. public bool IncludesY(ContextRecognizer y) { for (int i = 0; i < points.Count; ++i) { if (points[i] != null) { if (!points[i].DoesIncludeArgument(y.points[i])) { return(false); } } } return(true); }
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); } } } }
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 void ProcessSample(string line, SolarixGrammarEngineNET.AnalysisResults tokens, int left_i, SolarixGrammarEngineNET.GrammarEngine2 gren) { // В контекст входят слова от left_i по left_i+ctx.len. /* * // ---- DEBUG * System.Text.StringBuilder b = new StringBuilder(); * for( int i=0; i<ctx.len; ++i ) * if( i>0 ) * b.AppendFormat( " {0}", tokens[left_i+i].GetWord() ); * else * b.AppendFormat( "{0}", tokens[left_i+i].GetWord() ); * * string context_str = b.ToString(); * // --- END DEBUG */ // ... todo проверяем, не сопоставляются ли слова с уже имеющимися контекстами. for (int i = 0; i < recognizers.Count; ++i) { ContextRecognizer recognizer = recognizers[i]; int match = recognizer.Match(tokens, left_i, gren); if (match == 1) { // правило правильно распознало контекст и сняло омонимию. recognizer.Success(new MatchedContextInfo(line, tokens, left_i, ctx.len)); } else if (match == 0) { // правило распознало контекст, но неправильно сняло омонимию. recognizer.Fail(new MatchedContextInfo(line, tokens, left_i, ctx.len)); } } // Используем сэмпл для генерации правил только в том случае, если омонимичный токен дал 1 вариант словарной статьи. bool generate_rule = true; int omonym_ekey = -1; SolarixGrammarEngineNET.SyntaxTreeNode omonym_token = tokens[left_i + ctx.position]; int omonym_versions = omonym_token.VersionCount(); for (int iver = 0; iver < omonym_versions; ++iver) { int ekey = omonym_token.GetVersionEntryID(iver); if (omonym_ekey == -1) { omonym_ekey = ekey; } else if (omonym_ekey != ekey) { // омонимичный токен распознан как несколько разных лемм, поэтому не будет генерировать для него правила. generate_rule = false; break; } } if (generate_rule) { // Генерируем варианты распознавания контекста, начиная от самого конкретного - через лексемы не-мононимичных слов, для самых // общих - частей речи для них же. OmonymContextEnumerator ctx_generator = new OmonymContextEnumerator(tokens, ctx.position, left_i, ctx.len, gren); for (int i = 0; i < ctx_generator.Count; ++i) { ContextRecognizer recognizer = ctx_generator[i]; // проверим, что такого распознавателя еще нет. bool is_unique = true; foreach (ContextRecognizer r in recognizers) { if (r.EqualTokens(recognizer)) { is_unique = false; break; } } if (is_unique) { recognizer.Success(new MatchedContextInfo(line, tokens, left_i, ctx.len)); recognizers.Add(recognizer); } } } return; }