mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Add cctext python module
This commit is contained in:
parent
7b9128ef60
commit
48c70cd8d9
20
.vscode/settings.json
vendored
20
.vscode/settings.json
vendored
|
@ -1,5 +1,23 @@
|
||||||
{
|
{
|
||||||
"python.linting.flake8Enabled": true,
|
"python.testing.unittestArgs": [
|
||||||
|
"-v",
|
||||||
|
"-s",
|
||||||
|
"./tests",
|
||||||
|
"-p",
|
||||||
|
"test*.py"
|
||||||
|
],
|
||||||
|
"python.testing.pytestEnabled": false,
|
||||||
|
"python.testing.unittestEnabled": true,
|
||||||
|
"python.linting.pylintEnabled": true,
|
||||||
"python.linting.enabled": true,
|
"python.linting.enabled": true,
|
||||||
|
"python.linting.pylintArgs": [
|
||||||
|
"--max-line-length=120",
|
||||||
|
"--disable=invalid-name",
|
||||||
|
"--disable=line-too-long",
|
||||||
|
"--disable=no-else-return",
|
||||||
|
"--disable=too-many-return-statements",
|
||||||
|
"--disable=no-else-break",
|
||||||
|
"--disable=no-else-continue"
|
||||||
|
],
|
||||||
"eslint.workingDirectories": [{ "mode": "auto" }]
|
"eslint.workingDirectories": [{ "mode": "auto" }]
|
||||||
}
|
}
|
11
rsconcept/backend/cctext/__init__.py
Normal file
11
rsconcept/backend/cctext/__init__.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
'''Concept core text processing library'''
|
||||||
|
from .syntax import RuSyntax, Capitalization
|
||||||
|
from .rumodel import Morphology, SemanticRole, NamedEntityRole, WordTag, morpho
|
||||||
|
from .ruparser import RuParser, WordToken, Collation
|
||||||
|
|
||||||
|
from .conceptapi import (
|
||||||
|
parse, normalize,
|
||||||
|
get_all_forms, inflect, inflect_context, inflect_substitute, inflect_dependant,
|
||||||
|
match_all_morpho, find_substr,
|
||||||
|
split_tags
|
||||||
|
)
|
89
rsconcept/backend/cctext/conceptapi.py
Normal file
89
rsconcept/backend/cctext/conceptapi.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
'''
|
||||||
|
Concept API Python functions.
|
||||||
|
|
||||||
|
::guarantee:: doesnt raise exceptions and returns workable outputs in situations where empty string would be returned
|
||||||
|
'''
|
||||||
|
from cctext.rumodel import Morphology
|
||||||
|
from .syntax import RuSyntax
|
||||||
|
from .ruparser import RuParser
|
||||||
|
|
||||||
|
parser = RuParser()
|
||||||
|
|
||||||
|
|
||||||
|
def split_tags(tags: str) -> frozenset[str]:
|
||||||
|
''' Split grammemes string into set of items. '''
|
||||||
|
return frozenset([tag.strip() for tag in filter(None, tags.split(','))])
|
||||||
|
|
||||||
|
|
||||||
|
def parse(text: str, require_tags: str = '') -> str:
|
||||||
|
''' Determine morpho tags for input text.
|
||||||
|
::returns:: string of comma separated grammar tags or empty string '''
|
||||||
|
model = parser.parse(text, require_tags=split_tags(require_tags))
|
||||||
|
if model is None:
|
||||||
|
return ''
|
||||||
|
result = model.get_morpho().as_str()
|
||||||
|
return result if result != 'UNKN' else ''
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_forms(text_normal: str) -> list[tuple[str, str]]:
|
||||||
|
''' Get all infeclted forms. '''
|
||||||
|
model = parser.parse(text_normal)
|
||||||
|
if not model:
|
||||||
|
return []
|
||||||
|
result = []
|
||||||
|
for form in model.get_form().lexeme:
|
||||||
|
result.append((form.word, Morphology(form.tag).as_str()))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def normalize(text: str) -> str:
|
||||||
|
''' Generate normal form.
|
||||||
|
::returns:: normal form of input text or text itself if no parse is available '''
|
||||||
|
model = parser.parse(text)
|
||||||
|
if model is None:
|
||||||
|
return text
|
||||||
|
return model.normal_form()
|
||||||
|
|
||||||
|
|
||||||
|
def inflect(text: str, target_tags: str) -> str:
|
||||||
|
''' Inflect text to match required tags.
|
||||||
|
::returns:: infected text or initial text if infection failed '''
|
||||||
|
target_set = split_tags(target_tags)
|
||||||
|
model = parser.parse(text)
|
||||||
|
if model is None:
|
||||||
|
return text
|
||||||
|
return model.inflect(target_set)
|
||||||
|
|
||||||
|
|
||||||
|
def inflect_context(target: str, cntxt_before: str = '', cntxt_after: str = '') -> str:
|
||||||
|
''' Inflect text in accordance to context before and after. '''
|
||||||
|
return parser.inflect_context(target, cntxt_before, cntxt_after)
|
||||||
|
|
||||||
|
|
||||||
|
def inflect_substitute(substitute_normal: str, original: str) -> str:
|
||||||
|
''' Inflect substitute to match original form. '''
|
||||||
|
return parser.inflect_substitute(substitute_normal, original)
|
||||||
|
|
||||||
|
|
||||||
|
def inflect_dependant(dependant_normal: str, master: str) -> str:
|
||||||
|
''' Inflect dependant to coordinate with master text. '''
|
||||||
|
return parser.inflect_dependant(dependant_normal, master)
|
||||||
|
|
||||||
|
|
||||||
|
def match_all_morpho(text: str, filter_tags: str) -> list[list[int]]:
|
||||||
|
''' Search for all words corresponding to tags. '''
|
||||||
|
target_set = split_tags(filter_tags)
|
||||||
|
if len(target_set) == 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for elem in RuSyntax.tokenize(text):
|
||||||
|
model = parser.parse(elem.text, require_tags=target_set)
|
||||||
|
if model:
|
||||||
|
result.append([elem.start, elem.stop])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def find_substr(text: str, sub: str) -> tuple[int, int]:
|
||||||
|
''' Search for substring position in text regardless of morphology. '''
|
||||||
|
return parser.find_substr(text, sub)
|
146
rsconcept/backend/cctext/rumodel.py
Normal file
146
rsconcept/backend/cctext/rumodel.py
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
''' Russian language models. '''
|
||||||
|
from __future__ import annotations
|
||||||
|
from enum import Enum, IntEnum, unique
|
||||||
|
|
||||||
|
from pymorphy2 import MorphAnalyzer
|
||||||
|
from pymorphy2.tagset import OpencorporaTag as WordTag
|
||||||
|
|
||||||
|
# ''' Morphology parser. '''
|
||||||
|
morpho = MorphAnalyzer()
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class NamedEntityRole(IntEnum):
|
||||||
|
''' Enumerating NER types. '''
|
||||||
|
unknwn = 0
|
||||||
|
loc = 1
|
||||||
|
per = 2
|
||||||
|
org = 3
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_str(text: str) -> NamedEntityRole:
|
||||||
|
''' From text to ID. '''
|
||||||
|
if text == 'LOC':
|
||||||
|
return NamedEntityRole.loc
|
||||||
|
elif text == 'PER':
|
||||||
|
return NamedEntityRole.per
|
||||||
|
elif text == 'ORG':
|
||||||
|
return NamedEntityRole.org
|
||||||
|
return NamedEntityRole.unknwn
|
||||||
|
|
||||||
|
def as_str(self) -> str:
|
||||||
|
''' From ID to text. '''
|
||||||
|
if self.value == NamedEntityRole.loc:
|
||||||
|
return 'LOC'
|
||||||
|
elif self.value == NamedEntityRole.per:
|
||||||
|
return 'PER'
|
||||||
|
elif self.value == NamedEntityRole.org:
|
||||||
|
return 'ORG'
|
||||||
|
return 'UNKN'
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class SemanticRole(Enum):
|
||||||
|
''' Enumerating semantic types for different parse patterns. '''
|
||||||
|
unknwn = 0
|
||||||
|
term = 1
|
||||||
|
action = 2
|
||||||
|
definition = 3
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_pos(pos: str) -> SemanticRole:
|
||||||
|
''' Fabric method to produce types from part of speech. '''
|
||||||
|
if pos in ['NOUN', 'NPRO']:
|
||||||
|
return SemanticRole.term
|
||||||
|
elif pos in ['VERB', 'INFN', 'PRTF', 'PRTS']:
|
||||||
|
return SemanticRole.action
|
||||||
|
elif pos in ['ADJF', 'ADJS']:
|
||||||
|
return SemanticRole.definition
|
||||||
|
return SemanticRole.unknwn
|
||||||
|
|
||||||
|
|
||||||
|
class Morphology:
|
||||||
|
''' Wrapper for OpencorporaTag expanding functionality for multiword.
|
||||||
|
Full morphology tags see http://opencorpora.org/dict.php?act=gram
|
||||||
|
'''
|
||||||
|
def __init__(self, tag: WordTag, semantic=SemanticRole.unknwn):
|
||||||
|
self.tag = tag
|
||||||
|
self.semantic = semantic if semantic != SemanticRole.unknwn else SemanticRole.from_pos(tag.POS)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
_TAGS_IMMUTABLE = frozenset(['INFN', 'ADVB', 'COMP', 'PNCT', 'PREP', 'CONJ', 'PRCL', 'INTJ'])
|
||||||
|
|
||||||
|
_TAGS_NO_TENSE = frozenset(['NOUN', 'NPRO', 'ADJF', 'ADJS'])
|
||||||
|
_TAGS_NO_CASE = frozenset(['GRND', 'VERB', 'ADJS', 'PRTS'])
|
||||||
|
_TAGS_NO_NUMBER = frozenset(['GRND'])
|
||||||
|
_TAGS_NO_GENDER = frozenset(['GRND', 'NOUN', 'NPRO', 'plur'])
|
||||||
|
_TAGS_NO_PERSON = frozenset(['GRND', 'NOUN', 'ADJF', 'ADJS', 'PRTF', 'PRTS', 'past'])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def can_coordinate(self) -> bool:
|
||||||
|
''' Check if coordination can change text. '''
|
||||||
|
return self.tag.POS in ['NOUN', 'NPRO', 'NUMR', 'ADJF', 'ADJS', 'PRTF', 'PRTS']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_dependable(pos: str):
|
||||||
|
''' Check if this morphology can be dependant. '''
|
||||||
|
return pos in ['ADJF', 'ADJS', 'PRTF', 'PRTS']
|
||||||
|
|
||||||
|
@property
|
||||||
|
def effective_pos(self) -> str:
|
||||||
|
''' Access part of speech. Pronouns are considered as nouns '''
|
||||||
|
pos = self.tag.POS
|
||||||
|
if pos and self.tag.POS == 'NPRO':
|
||||||
|
return 'NOUN'
|
||||||
|
return pos
|
||||||
|
|
||||||
|
def complete_tags(self, tags: frozenset[str]) -> set[str]:
|
||||||
|
''' Add missing tags before inflection. '''
|
||||||
|
result = set(tags)
|
||||||
|
pos = self.tag.POS
|
||||||
|
if pos and result.isdisjoint(WordTag.PARTS_OF_SPEECH):
|
||||||
|
result.add(pos if pos != 'INFN' or len(result) == 0 else 'VERB')
|
||||||
|
if not result.isdisjoint(self._TAGS_IMMUTABLE):
|
||||||
|
return result
|
||||||
|
if self.tag.case and result.isdisjoint(WordTag.CASES) and result.isdisjoint(self._TAGS_NO_CASE):
|
||||||
|
result.add(self.tag.case)
|
||||||
|
if self.tag.tense and result.isdisjoint(WordTag.TENSES) and result.isdisjoint(self._TAGS_NO_TENSE):
|
||||||
|
if (self.tag.tense != 'past' or result.isdisjoint(WordTag.PERSONS)) \
|
||||||
|
and (self.tag.tense != 'pres' or result.isdisjoint(WordTag.GENDERS)):
|
||||||
|
result.add(self.tag.tense)
|
||||||
|
if self.tag.number and result.isdisjoint(WordTag.NUMBERS) and result.isdisjoint(self._TAGS_NO_NUMBER):
|
||||||
|
if self.tag.number != 'plur' or result.isdisjoint(WordTag.GENDERS):
|
||||||
|
result.add(self.tag.number)
|
||||||
|
if self.tag.gender and result.isdisjoint(WordTag.GENDERS) and result.isdisjoint(self._TAGS_NO_GENDER):
|
||||||
|
if 'PRTF' in result or 'pres' not in result:
|
||||||
|
result.add(self.tag.gender)
|
||||||
|
if self.tag.person and result.isdisjoint(WordTag.PERSONS) and result.isdisjoint(self._TAGS_NO_PERSON):
|
||||||
|
result.add(self.tag.person)
|
||||||
|
if 'plur' in result and not result.isdisjoint(WordTag.GENDERS):
|
||||||
|
result = result.difference(WordTag.GENDERS)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def coordination_tags(self) -> set[str]:
|
||||||
|
''' Return set of grammemes for inflection to keep coordination . '''
|
||||||
|
result = set()
|
||||||
|
if self.tag.case:
|
||||||
|
result.add(self.tag.case)
|
||||||
|
if self.tag:
|
||||||
|
number = self.tag.number
|
||||||
|
result.add(number)
|
||||||
|
if self.tag.gender and 'plur' not in result:
|
||||||
|
result.add(self.tag.gender)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def as_str(self) -> str:
|
||||||
|
''' Produce string of all grammemes. '''
|
||||||
|
grammemes = self.tag.grammemes
|
||||||
|
count = len(grammemes)
|
||||||
|
if count == 0:
|
||||||
|
return ''
|
||||||
|
elif count == 1:
|
||||||
|
return next(iter(grammemes))
|
||||||
|
else:
|
||||||
|
return ','.join(grammemes)
|
484
rsconcept/backend/cctext/ruparser.py
Normal file
484
rsconcept/backend/cctext/ruparser.py
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
''' Parsing russian language using pymorphy2 and natasha libraries. '''
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from razdel.substring import Substring as Segment
|
||||||
|
from pymorphy2.analyzer import Parse as WordForm
|
||||||
|
|
||||||
|
from .syntax import RuSyntax, Capitalization
|
||||||
|
from .rumodel import SemanticRole, Morphology, WordTag, morpho
|
||||||
|
|
||||||
|
INDEX_NONE = -1
|
||||||
|
NO_COORDINATION = -1
|
||||||
|
WORD_NONE = -1
|
||||||
|
|
||||||
|
|
||||||
|
class WordToken:
|
||||||
|
''' Minimal text token. '''
|
||||||
|
def __init__(self, segment: Segment, forms: list[WordForm], main_form: int = 0):
|
||||||
|
self.segment: Segment = segment
|
||||||
|
self.forms: list[WordForm] = forms
|
||||||
|
self.main: int = main_form
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_morpho(self) -> Morphology:
|
||||||
|
''' Return morphology for current token. '''
|
||||||
|
return Morphology(self.get_form().tag)
|
||||||
|
|
||||||
|
def get_form(self) -> WordForm:
|
||||||
|
''' Access main form. '''
|
||||||
|
return self.forms[self.main]
|
||||||
|
|
||||||
|
def inflect(self, inflection_tags: set[str]):
|
||||||
|
''' Apply inflection to segment text. Does not modify forms '''
|
||||||
|
inflected = self.get_form().inflect(inflection_tags)
|
||||||
|
if not inflected:
|
||||||
|
return None
|
||||||
|
self.segment.text = Capitalization.from_text(self.segment.text).apply_to(inflected.word)
|
||||||
|
return inflected
|
||||||
|
|
||||||
|
|
||||||
|
class Collation:
|
||||||
|
''' Parsed data for input coordinated text. '''
|
||||||
|
def __init__(self, text: str):
|
||||||
|
self.text = text
|
||||||
|
self.words = []
|
||||||
|
self.coordination = []
|
||||||
|
self.main_word: int = WORD_NONE
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_form(self) -> WordForm:
|
||||||
|
''' Access main form. '''
|
||||||
|
return self.words[self.main_word].get_form()
|
||||||
|
|
||||||
|
def get_morpho(self) -> Morphology:
|
||||||
|
''' Access parsed main mrophology. '''
|
||||||
|
if self.main_word == WORD_NONE:
|
||||||
|
return None
|
||||||
|
return self.words[self.main_word].get_morpho()
|
||||||
|
|
||||||
|
def add_word(self, segment, forms: list, main_form: int, need_coordination: bool = True):
|
||||||
|
''' Add word information. '''
|
||||||
|
self.words.append(WordToken(segment, forms, main_form))
|
||||||
|
self.coordination.append(NO_COORDINATION if not need_coordination else 0)
|
||||||
|
|
||||||
|
def inflect(self, target_tags: frozenset[str]) -> str:
|
||||||
|
''' Inflect text to match required tags. '''
|
||||||
|
origin = self.get_morpho()
|
||||||
|
if not origin or origin.tag.grammemes.issuperset(target_tags):
|
||||||
|
return self.text
|
||||||
|
if not self._apply_inflection(origin, target_tags):
|
||||||
|
return self.text
|
||||||
|
new_text = self._generate_text()
|
||||||
|
return new_text
|
||||||
|
|
||||||
|
def inflect_like(self, base_model: Collation) -> str:
|
||||||
|
''' Create inflection to substitute base_model form. '''
|
||||||
|
morph = base_model.get_morpho()
|
||||||
|
if morph.effective_pos is None:
|
||||||
|
return self.text
|
||||||
|
tags = set()
|
||||||
|
tags.add(morph.effective_pos)
|
||||||
|
tags = morph.complete_tags(tags)
|
||||||
|
return self.inflect(tags)
|
||||||
|
|
||||||
|
def inflect_dependant(self, master_model: Collation) -> str:
|
||||||
|
''' Create inflection to coordinate with master_model form. '''
|
||||||
|
morph = master_model.get_morpho()
|
||||||
|
tags = morph.coordination_tags()
|
||||||
|
tags = self.get_morpho().complete_tags(tags)
|
||||||
|
return self.inflect(tags)
|
||||||
|
|
||||||
|
def normal_form(self) -> str:
|
||||||
|
''' Generate normal form. '''
|
||||||
|
main_form = self.get_form()
|
||||||
|
if not main_form:
|
||||||
|
return self.text
|
||||||
|
new_morpho = Morphology(main_form.normalized.tag)
|
||||||
|
new_tags = new_morpho.complete_tags(frozenset())
|
||||||
|
return self.inflect(new_tags)
|
||||||
|
|
||||||
|
def _iterate_coordinated(self):
|
||||||
|
words_count = len(self.words)
|
||||||
|
current_word = self.coordination[words_count]
|
||||||
|
while current_word != words_count:
|
||||||
|
yield self.words[current_word]
|
||||||
|
current_word += self.coordination[current_word]
|
||||||
|
|
||||||
|
def _inflect_main_word(self, origin: Morphology, target_tags: frozenset[str]) -> Morphology:
|
||||||
|
# TODO: implement Part of speech transition for VERB <-> NOUN
|
||||||
|
full_tags = origin.complete_tags(target_tags)
|
||||||
|
inflected = self.words[self.main_word].inflect(full_tags)
|
||||||
|
if not inflected:
|
||||||
|
return None
|
||||||
|
return Morphology(inflected.tag)
|
||||||
|
|
||||||
|
def _apply_inflection(self, origin: Morphology, target_tags: frozenset[str]) -> bool:
|
||||||
|
new_moprho = self._inflect_main_word(origin, target_tags)
|
||||||
|
if not new_moprho:
|
||||||
|
return False
|
||||||
|
inflection_tags = new_moprho.coordination_tags()
|
||||||
|
if len(inflection_tags) == 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
for word in self._iterate_coordinated():
|
||||||
|
word.inflect(inflection_tags)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _generate_text(self) -> str:
|
||||||
|
current_pos = 0
|
||||||
|
result = ''
|
||||||
|
for token in self.words:
|
||||||
|
if token.segment.start > current_pos:
|
||||||
|
result += self.text[current_pos: token.segment.start]
|
||||||
|
result += token.segment.text
|
||||||
|
current_pos = token.segment.stop
|
||||||
|
if current_pos + 1 < len(self.text):
|
||||||
|
result += self.text[current_pos:]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class RuParser:
|
||||||
|
''' Russian grammar parser. '''
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
_FILTER_SCORE = 0.005
|
||||||
|
_SINGLE_SCORE_SEARCH = 0.2
|
||||||
|
_PRIORITY_NONE = NO_COORDINATION
|
||||||
|
|
||||||
|
_MAIN_WAIT_LIMIT = 10 # count words untill fixing main
|
||||||
|
_MAIN_MAX_FOLLOWERS = 3 # count words after main as coordination candidates
|
||||||
|
|
||||||
|
def parse(self, text: str, require_index: int = INDEX_NONE, require_tags: frozenset[str] = None) -> Collation:
|
||||||
|
''' Determine morpho tags for input text.
|
||||||
|
::returns:: Morphology of a text or None if no suitable form is available '''
|
||||||
|
if text == '':
|
||||||
|
return None
|
||||||
|
segments = list(RuSyntax.tokenize(text))
|
||||||
|
if len(segments) == 1:
|
||||||
|
return self._parse_single(segments[0], require_index, require_tags)
|
||||||
|
else:
|
||||||
|
return self._parse_multiword(text, segments, require_index, require_tags)
|
||||||
|
|
||||||
|
def normalize(self, text: str):
|
||||||
|
''' Get normal form for target text. '''
|
||||||
|
processed = self.parse(text)
|
||||||
|
if not processed:
|
||||||
|
return text
|
||||||
|
return processed.normal_form()
|
||||||
|
|
||||||
|
def find_substr(self, text: str, sub: str) -> tuple[int, int]:
|
||||||
|
''' Search for substring position in text regardless of morphology. '''
|
||||||
|
if not text or not sub:
|
||||||
|
return (0, 0)
|
||||||
|
query = [self.normalize(elem.text) for elem in RuSyntax.tokenize(sub)]
|
||||||
|
query_len = len(query)
|
||||||
|
start = 0
|
||||||
|
current_index = 0
|
||||||
|
for token in RuSyntax.tokenize(text):
|
||||||
|
text_word = self.normalize(token.text)
|
||||||
|
if text_word != query[current_index]:
|
||||||
|
current_index = 0
|
||||||
|
else:
|
||||||
|
if current_index == 0:
|
||||||
|
start = token.start
|
||||||
|
current_index += 1
|
||||||
|
if current_index == query_len:
|
||||||
|
return (start, token.stop)
|
||||||
|
return (0, 0)
|
||||||
|
|
||||||
|
def inflect_context(self, text: str, cntxt_before: str = '', cntxt_after: str = '') -> str:
|
||||||
|
''' Inflect text in accordance to context before and after. '''
|
||||||
|
target = self.parse(text)
|
||||||
|
if not target:
|
||||||
|
return text
|
||||||
|
target_morpho = target.get_morpho()
|
||||||
|
if not target_morpho or not target_morpho.can_coordinate:
|
||||||
|
return text
|
||||||
|
|
||||||
|
model_after = self.parse(cntxt_after)
|
||||||
|
model_before = self.parse(cntxt_before)
|
||||||
|
etalon = RuParser._choose_context_etalon(target_morpho, model_before, model_after)
|
||||||
|
if not etalon:
|
||||||
|
return text
|
||||||
|
etalon_moprho = etalon.get_morpho()
|
||||||
|
if not etalon_moprho.can_coordinate:
|
||||||
|
return text
|
||||||
|
|
||||||
|
new_form = RuParser._combine_morpho(target_morpho, etalon_moprho.tag)
|
||||||
|
return target.inflect(new_form)
|
||||||
|
|
||||||
|
def inflect_substitute(self, substitute_normal: str, original: str) -> str:
|
||||||
|
''' Inflect substitute to match original form. '''
|
||||||
|
original_model = self.parse(original)
|
||||||
|
if not original_model:
|
||||||
|
return substitute_normal
|
||||||
|
substitute_model = self.parse(substitute_normal)
|
||||||
|
if not substitute_model:
|
||||||
|
return substitute_normal
|
||||||
|
return substitute_model.inflect_like(original_model)
|
||||||
|
|
||||||
|
def inflect_dependant(self, dependant_normal: str, master: str) -> str:
|
||||||
|
''' Inflect dependant to coordinate with master text. '''
|
||||||
|
master_model = self.parse(master)
|
||||||
|
if not master_model:
|
||||||
|
return dependant_normal
|
||||||
|
dependant_model = self.parse(dependant_normal)
|
||||||
|
if not dependant_model:
|
||||||
|
return dependant_normal
|
||||||
|
return dependant_model.inflect_dependant(master_model)
|
||||||
|
|
||||||
|
def _parse_single(self, segment, require_index: int, require_tags: frozenset[str]) -> Collation:
|
||||||
|
forms = list(self._filtered_parse(segment.text))
|
||||||
|
parse_index = INDEX_NONE
|
||||||
|
if len(forms) == 0 or require_index >= len(forms):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if require_index != INDEX_NONE:
|
||||||
|
tags = forms[require_index].tag
|
||||||
|
if require_tags and not tags.grammemes.issuperset(require_tags):
|
||||||
|
return None
|
||||||
|
parse_index = require_index
|
||||||
|
else:
|
||||||
|
current_score = 0
|
||||||
|
for (index, form) in enumerate(forms):
|
||||||
|
if not require_tags or form.tag.grammemes.issuperset(require_tags):
|
||||||
|
if form.tag.case == 'nomn':
|
||||||
|
parse_index = index
|
||||||
|
break
|
||||||
|
elif parse_index == INDEX_NONE:
|
||||||
|
current_score = form.score
|
||||||
|
parse_index = index
|
||||||
|
elif form.score / current_score < self._SINGLE_SCORE_SEARCH:
|
||||||
|
break
|
||||||
|
|
||||||
|
if parse_index == INDEX_NONE:
|
||||||
|
return None
|
||||||
|
result = Collation(segment.text)
|
||||||
|
result.add_word(segment, [forms[parse_index]], main_form=0, need_coordination=False)
|
||||||
|
result.coordination.append(len(result.words))
|
||||||
|
result.main_word = 0
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _parse_multiword(self, text: str, segments: list, require_index: int, require_tags: frozenset[str]):
|
||||||
|
result = Collation(text)
|
||||||
|
priority_main = self._PRIORITY_NONE
|
||||||
|
segment_index = 0
|
||||||
|
main_wait = 0
|
||||||
|
word_index = 0
|
||||||
|
for segment in segments:
|
||||||
|
if main_wait > RuParser._MAIN_WAIT_LIMIT:
|
||||||
|
break
|
||||||
|
segment_index += 1
|
||||||
|
priority = self._parse_segment(result, segment, require_index, require_tags)
|
||||||
|
if priority is None:
|
||||||
|
continue # skip non-parsable entities
|
||||||
|
main_wait += 1
|
||||||
|
if priority > priority_main:
|
||||||
|
result.main_word = word_index
|
||||||
|
priority_main = priority
|
||||||
|
word_index += 1
|
||||||
|
if result.main_word == INDEX_NONE:
|
||||||
|
return None
|
||||||
|
self._finalize_coordination(result)
|
||||||
|
if segment_index < len(segments):
|
||||||
|
pass # finish to parse segments after main if needed
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _parse_segment(self,
|
||||||
|
output: Collation,
|
||||||
|
segment: Segment,
|
||||||
|
require_index: int,
|
||||||
|
require_tags: frozenset[str]) -> float:
|
||||||
|
''' Return priority for this can be a new main word '''
|
||||||
|
forms = list(self._filtered_parse(segment.text))
|
||||||
|
if len(forms) == 0:
|
||||||
|
return None
|
||||||
|
main_index = INDEX_NONE
|
||||||
|
segment_score = self._PRIORITY_NONE
|
||||||
|
needs_coordination = False
|
||||||
|
local_sum = 0
|
||||||
|
score_sum = 0
|
||||||
|
if require_index != INDEX_NONE:
|
||||||
|
form = forms[require_index]
|
||||||
|
if not require_tags or form.tag.grammemes.issuperset(require_tags):
|
||||||
|
(local_max, segment_score) = RuParser._get_priority_for(form.tag)
|
||||||
|
main_index = require_index
|
||||||
|
needs_coordination = Morphology.is_dependable(form.tag.POS)
|
||||||
|
else:
|
||||||
|
local_max = self._PRIORITY_NONE
|
||||||
|
for (index, form) in enumerate(forms):
|
||||||
|
if require_tags and not form.tag.grammemes.issuperset(require_tags):
|
||||||
|
continue
|
||||||
|
(local_priority, global_priority) = RuParser._get_priority_for(form.tag)
|
||||||
|
needs_coordination = needs_coordination or Morphology.is_dependable(form.tag.POS)
|
||||||
|
local_sum += global_priority * form.score
|
||||||
|
score_sum += form.score
|
||||||
|
if local_priority > local_max:
|
||||||
|
local_max = local_priority
|
||||||
|
# segment_score = global_priority
|
||||||
|
main_index = index
|
||||||
|
if score_sum == 0:
|
||||||
|
return None
|
||||||
|
segment_score = local_sum / score_sum
|
||||||
|
output.add_word(segment, forms, main_index, needs_coordination)
|
||||||
|
return segment_score
|
||||||
|
# Alternative: return segment_score
|
||||||
|
# penalty_suspicoius = 0 if local_max == 0 else (1 - local_sum / local_max) * self._PRIORITY_PENALTY
|
||||||
|
# return segment_score - penalty_suspicoius
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _finalize_coordination(cls, target: Collation):
|
||||||
|
main_morpho: Morphology = target.get_morpho()
|
||||||
|
main_coordinate = main_morpho.can_coordinate
|
||||||
|
target.coordination[target.main_word] = NO_COORDINATION
|
||||||
|
first_change = INDEX_NONE
|
||||||
|
current_len = 0
|
||||||
|
for (index, word) in enumerate(target.words):
|
||||||
|
if target.coordination[index] == NO_COORDINATION or index - target.main_word > cls._MAIN_MAX_FOLLOWERS:
|
||||||
|
needs_change = False
|
||||||
|
if index != target.main_word:
|
||||||
|
word.main = INDEX_NONE
|
||||||
|
else:
|
||||||
|
word.main = RuParser._find_coordination(word.forms, main_morpho.tag, index < target.main_word)
|
||||||
|
needs_change = word.main != INDEX_NONE
|
||||||
|
if not needs_change or not main_coordinate:
|
||||||
|
target.coordination[index] = NO_COORDINATION
|
||||||
|
current_len += 1
|
||||||
|
if needs_change and main_coordinate:
|
||||||
|
target.coordination[index] = current_len
|
||||||
|
current_len = 0
|
||||||
|
if first_change == INDEX_NONE:
|
||||||
|
first_change = index
|
||||||
|
if first_change == INDEX_NONE:
|
||||||
|
target.coordination.append(len(target.words))
|
||||||
|
return
|
||||||
|
previous_reference = first_change
|
||||||
|
current_word = len(target.words)
|
||||||
|
target.coordination.append(current_len + 1)
|
||||||
|
while target.coordination[current_word] != INDEX_NONE:
|
||||||
|
previous_word = current_word - target.coordination[current_word]
|
||||||
|
target.coordination[current_word] = previous_reference
|
||||||
|
previous_reference = current_word - previous_word
|
||||||
|
current_word = previous_word
|
||||||
|
if previous_reference == 0 or current_word < 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _find_coordination(forms: list, main_tag: WordTag, before_main: bool) -> int:
|
||||||
|
for (index, form) in enumerate(forms):
|
||||||
|
pos = form.tag.POS
|
||||||
|
case = form.tag.case
|
||||||
|
if pos not in ['ADJF', 'ADJS', 'PRTF', 'PRTS']:
|
||||||
|
continue
|
||||||
|
if SemanticRole.from_pos(pos) == SemanticRole.term and case == 'gent':
|
||||||
|
if before_main:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return INDEX_NONE
|
||||||
|
if case == main_tag.case:
|
||||||
|
return index
|
||||||
|
elif main_tag.case in ['accs', 'gent'] and case in ['accs', 'gent']:
|
||||||
|
return index
|
||||||
|
return INDEX_NONE
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _filtered_parse(text: str):
|
||||||
|
capital = Capitalization.from_text(text)
|
||||||
|
score_filter = RuParser._filter_score(morpho.parse(text))
|
||||||
|
for form in RuParser._filter_capital(score_filter, capital):
|
||||||
|
yield form
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _filter_score(generator):
|
||||||
|
for form in generator:
|
||||||
|
if form.score < RuParser._FILTER_SCORE:
|
||||||
|
break
|
||||||
|
yield form
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _filter_capital(generator, capital: Capitalization):
|
||||||
|
if capital in [Capitalization.upper_case, Capitalization.mixed]:
|
||||||
|
for form in generator:
|
||||||
|
if 'Abbr' not in form.tag.grammemes:
|
||||||
|
continue
|
||||||
|
yield form
|
||||||
|
else:
|
||||||
|
for form in generator:
|
||||||
|
yield form
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_word(text: str, require_index: int = INDEX_NONE, require_tags: frozenset[str] = None) -> Morphology:
|
||||||
|
parsed_variants = morpho.parse(text)
|
||||||
|
if not parsed_variants or require_index >= len(parsed_variants):
|
||||||
|
return None
|
||||||
|
if require_index != INDEX_NONE:
|
||||||
|
tags = parsed_variants[require_index].tag
|
||||||
|
if not require_tags or tags.grammemes.issuperset(require_tags):
|
||||||
|
return Morphology(tags)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
for variant in parsed_variants:
|
||||||
|
tags = variant.tag
|
||||||
|
if not require_tags or tags.grammemes.issuperset(require_tags):
|
||||||
|
return Morphology(tags)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_priority_for(tag: WordTag) -> tuple[float, float]:
|
||||||
|
''' Return pair of local and global priorities. '''
|
||||||
|
if tag.POS in ['VERB', 'INFN']:
|
||||||
|
return (9, 10)
|
||||||
|
if tag.POS in ['NOUN', 'NPRO']:
|
||||||
|
return (10, 9) if 'nomn' in tag.grammemes and 'Fixd' not in tag.grammemes else (8, 8)
|
||||||
|
if tag.POS in ['PRTF', 'PRTS']:
|
||||||
|
return (6, 6)
|
||||||
|
if tag.POS in ['ADJF', 'ADJS']:
|
||||||
|
return (5, 5)
|
||||||
|
if tag.POS == 'ADVB':
|
||||||
|
return (7, 4)
|
||||||
|
return (0, 0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _choose_context_etalon(target: Morphology, before: Collation, after: Collation) -> Collation:
|
||||||
|
if not before or not before.get_morpho().can_coordinate:
|
||||||
|
return after
|
||||||
|
if not after or not after.get_morpho().can_coordinate:
|
||||||
|
return before
|
||||||
|
|
||||||
|
before_semantic = before.get_morpho().semantic
|
||||||
|
after_semantic = after.get_morpho().semantic
|
||||||
|
if target.semantic == SemanticRole.definition:
|
||||||
|
if after_semantic == SemanticRole.term:
|
||||||
|
return after
|
||||||
|
if before_semantic == SemanticRole.term:
|
||||||
|
return before
|
||||||
|
if before_semantic == SemanticRole.definition:
|
||||||
|
return before
|
||||||
|
return after
|
||||||
|
|
||||||
|
if target.semantic == SemanticRole.term:
|
||||||
|
if before_semantic == SemanticRole.definition:
|
||||||
|
return before
|
||||||
|
if after_semantic == SemanticRole.definition:
|
||||||
|
return after
|
||||||
|
|
||||||
|
return before
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _combine_morpho(target: Morphology, etalon: WordTag) -> str:
|
||||||
|
part_of_speech = target.tag.POS
|
||||||
|
number = etalon.number
|
||||||
|
if number == 'plur':
|
||||||
|
return frozenset([part_of_speech, number, etalon.case])
|
||||||
|
else:
|
||||||
|
gender = etalon.gender if target.semantic != SemanticRole.term else target.tag.gender
|
||||||
|
return frozenset([part_of_speech, number, gender, etalon.case])
|
83
rsconcept/backend/cctext/syntax.py
Normal file
83
rsconcept/backend/cctext/syntax.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
''' Russian language synthax incapsulation. '''
|
||||||
|
from __future__ import annotations
|
||||||
|
from enum import Enum, unique
|
||||||
|
|
||||||
|
from razdel import tokenize
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class Capitalization(Enum):
|
||||||
|
''' Enumerating capitalization types. '''
|
||||||
|
unknwn = 0
|
||||||
|
lower_case = 1
|
||||||
|
upper_case = 2
|
||||||
|
first_capital = 3
|
||||||
|
mixed = 4
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_text(text: str) -> Capitalization:
|
||||||
|
''' Fabric method to identify capitalization in text. '''
|
||||||
|
if len(text) == 0:
|
||||||
|
return Capitalization.unknwn
|
||||||
|
first_capital = Capitalization._is_capital(text[0])
|
||||||
|
has_mid_capital = False
|
||||||
|
has_lower = not first_capital
|
||||||
|
for symbol in text[1:]:
|
||||||
|
if Capitalization._is_capital(symbol):
|
||||||
|
if has_lower:
|
||||||
|
return Capitalization.mixed
|
||||||
|
has_mid_capital = True
|
||||||
|
else:
|
||||||
|
if has_mid_capital:
|
||||||
|
return Capitalization.mixed
|
||||||
|
else:
|
||||||
|
has_lower = True
|
||||||
|
if has_mid_capital:
|
||||||
|
return Capitalization.upper_case
|
||||||
|
elif first_capital:
|
||||||
|
return Capitalization.first_capital
|
||||||
|
else:
|
||||||
|
return Capitalization.lower_case
|
||||||
|
|
||||||
|
def apply_to(self, text: str) -> str:
|
||||||
|
''' Apply capitalization to text. '''
|
||||||
|
if not text or self in [Capitalization.unknwn, Capitalization.mixed]:
|
||||||
|
return text
|
||||||
|
elif self == Capitalization.lower_case:
|
||||||
|
return text.lower()
|
||||||
|
elif self == Capitalization.upper_case:
|
||||||
|
return text.upper()
|
||||||
|
else:
|
||||||
|
return text[0].upper() + text[1:]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_capital(symbol: str) -> bool:
|
||||||
|
return 'А' <= symbol <= 'Я' or 'A' <= symbol <= 'Z'
|
||||||
|
|
||||||
|
|
||||||
|
class RuSyntax:
|
||||||
|
''' Russian language synthax parser. '''
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_single_word(text: str) -> bool:
|
||||||
|
''' Test if text is a single word. '''
|
||||||
|
try:
|
||||||
|
gen = tokenize(text)
|
||||||
|
return next(gen) == '' or next(gen) == ''
|
||||||
|
except StopIteration:
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def tokenize(text: str):
|
||||||
|
''' Split text into words. Returns list[(start, stop, text)]. '''
|
||||||
|
return tokenize(text)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def split_words(text: str) -> list[str]:
|
||||||
|
''' Split text into words. '''
|
||||||
|
return [elem.text for elem in tokenize(text)]
|
0
rsconcept/backend/cctext/tests/__init__.py
Normal file
0
rsconcept/backend/cctext/tests/__init__.py
Normal file
1819
rsconcept/backend/cctext/tests/data/functions.txt
Normal file
1819
rsconcept/backend/cctext/tests/data/functions.txt
Normal file
File diff suppressed because it is too large
Load Diff
866
rsconcept/backend/cctext/tests/data/thesaurus.txt
Normal file
866
rsconcept/backend/cctext/tests/data/thesaurus.txt
Normal file
|
@ -0,0 +1,866 @@
|
||||||
|
тектологические состояния
|
||||||
|
первые здания
|
||||||
|
доска
|
||||||
|
структуры
|
||||||
|
тектологические состояния
|
||||||
|
тектологические переходы
|
||||||
|
уникомплексные тектологические переходы
|
||||||
|
поликомплексные переходы
|
||||||
|
процессы
|
||||||
|
разрушаемые оружием структуры
|
||||||
|
создаваемые оружием структуры
|
||||||
|
неразрушаемые оружием структуры
|
||||||
|
несоздаваемые оружием структуры
|
||||||
|
формы движения
|
||||||
|
объекты
|
||||||
|
систенты
|
||||||
|
субъекты
|
||||||
|
системные классы
|
||||||
|
системные субъекты
|
||||||
|
системное сознание
|
||||||
|
системно познаные объекты
|
||||||
|
обсубъект
|
||||||
|
системно непознанные объекты
|
||||||
|
оценки
|
||||||
|
шкала оценок
|
||||||
|
альтернативы
|
||||||
|
критерии
|
||||||
|
сеть альтернатив
|
||||||
|
предъявление
|
||||||
|
субъект актуализации
|
||||||
|
основание
|
||||||
|
актуализированная альтернатива
|
||||||
|
цепи актуализаций
|
||||||
|
Сечения актуализации
|
||||||
|
комплексы
|
||||||
|
квазиконфликтанты
|
||||||
|
консистенции
|
||||||
|
квазиконфликтантные комплексы
|
||||||
|
коструктурный слой
|
||||||
|
коструктурное окружение
|
||||||
|
квазиконфликты
|
||||||
|
шкалы оценок квазиконфликтанта
|
||||||
|
ущемленная сторона конфликтного перехода
|
||||||
|
кооперативный переход
|
||||||
|
конфликты
|
||||||
|
консистенты
|
||||||
|
цепи нагнетания напряженности
|
||||||
|
состояние напряженности
|
||||||
|
конфликтное состояние
|
||||||
|
структурный дифференциал
|
||||||
|
конфликтоген
|
||||||
|
основание конфликта
|
||||||
|
конфликтанты
|
||||||
|
Уникомплексный переход
|
||||||
|
структурный дифференциал перехода
|
||||||
|
рабочий процесс оружия
|
||||||
|
приемы
|
||||||
|
натуральные числа
|
||||||
|
складские операции
|
||||||
|
группа организационных единиц
|
||||||
|
полные описания издений
|
||||||
|
разбиения
|
||||||
|
номера договорных поставок
|
||||||
|
номера приходных ордеров поставок
|
||||||
|
дни приходных ордеров поставок
|
||||||
|
дни
|
||||||
|
выбранное число
|
||||||
|
организационные единицы
|
||||||
|
изделия
|
||||||
|
операции
|
||||||
|
группа организаций
|
||||||
|
предприятия
|
||||||
|
организация
|
||||||
|
склад
|
||||||
|
отрезки времени
|
||||||
|
прошлые состояния склада
|
||||||
|
подразделения
|
||||||
|
поступления партий изделий
|
||||||
|
отпуск партий изделий
|
||||||
|
типы изделий
|
||||||
|
виды изделий
|
||||||
|
договорные поставки
|
||||||
|
поставки
|
||||||
|
начальные отрезки натуральных чисел
|
||||||
|
абсолютные нумерации разбиений
|
||||||
|
относительные нумерации разбиений
|
||||||
|
календари
|
||||||
|
солнечные календари
|
||||||
|
григорианские календари
|
||||||
|
квартальные григорианские календари
|
||||||
|
календарные годы
|
||||||
|
календарные кварталы
|
||||||
|
отрезки нумерации складских операций
|
||||||
|
поступление
|
||||||
|
отпуск
|
||||||
|
классы изделий
|
||||||
|
текущее состояние склада
|
||||||
|
спецификация
|
||||||
|
единицы учета, заданные спецификациями изделий
|
||||||
|
Единицы учета, заданные множествами изделий
|
||||||
|
единицы учета
|
||||||
|
прием партий изделий
|
||||||
|
отпуск изделий
|
||||||
|
характеристики
|
||||||
|
единицы измерения
|
||||||
|
числовые индексы
|
||||||
|
полные описания изделий
|
||||||
|
полные описания
|
||||||
|
самое мелкое разбиение
|
||||||
|
самое крупное разбиение
|
||||||
|
виды операций
|
||||||
|
Складские операции, выраженные в единицах учета
|
||||||
|
Поступления изделий, выраженные в единицах учета
|
||||||
|
Отпуск изделий, выраженный в единицах учета
|
||||||
|
високосные годы
|
||||||
|
невисокосные годы
|
||||||
|
годы
|
||||||
|
месяцы
|
||||||
|
кварталы
|
||||||
|
номера фондовых извещений
|
||||||
|
номера договоров
|
||||||
|
фондовые извещения
|
||||||
|
Нумерация складских операций
|
||||||
|
фонды
|
||||||
|
договора
|
||||||
|
дата
|
||||||
|
номер приходного ордера
|
||||||
|
поставки по техпомощи
|
||||||
|
Тезаурус кафедры КАиП:
|
||||||
|
Н-арное отношение
|
||||||
|
Н-местное отношение
|
||||||
|
R-интерпретация
|
||||||
|
Абельность
|
||||||
|
Абсолютное дополнение
|
||||||
|
Абстрагирование
|
||||||
|
Абстрактная система
|
||||||
|
Абстрактный процесс
|
||||||
|
Абстракция
|
||||||
|
Автоматизированная система проектирования систем организационного управления
|
||||||
|
Адаптивная система
|
||||||
|
Адекватность
|
||||||
|
Аксиома
|
||||||
|
Аксиома связности
|
||||||
|
Аксиома структуры
|
||||||
|
Аксиоматизация
|
||||||
|
Аксиоматика теории
|
||||||
|
Аксиоматическая теория
|
||||||
|
Аксиомы группы
|
||||||
|
Аксиомы синтеза
|
||||||
|
Актуальность
|
||||||
|
Алгебраическая структура
|
||||||
|
Алгебра конструктов
|
||||||
|
Альтернатива
|
||||||
|
Альтернативные методы
|
||||||
|
Анализ
|
||||||
|
Аналитическая теория
|
||||||
|
Аналогия
|
||||||
|
Аспект
|
||||||
|
Аспектная теория
|
||||||
|
АСП СОУ
|
||||||
|
АТ
|
||||||
|
Атрибут
|
||||||
|
Атрибутивная форма
|
||||||
|
Атрибутивное мышление
|
||||||
|
База данных
|
||||||
|
Базис множеств
|
||||||
|
Базисное множество
|
||||||
|
Библиотека моделей
|
||||||
|
Бинарная операция
|
||||||
|
Бинарное отношение
|
||||||
|
Богданов
|
||||||
|
Большая проекция
|
||||||
|
Боулдинг
|
||||||
|
Булеан
|
||||||
|
Бурбаки
|
||||||
|
Вершина
|
||||||
|
Взаимно дополнительные теории
|
||||||
|
Видообразование
|
||||||
|
Включение
|
||||||
|
Власть
|
||||||
|
Внешность предметной области
|
||||||
|
Внутренние термы ядра теории
|
||||||
|
Возможность
|
||||||
|
Восхождение
|
||||||
|
Вспомогательные базисные множества
|
||||||
|
Вторичная функция
|
||||||
|
Вторичный метод
|
||||||
|
Вход
|
||||||
|
Вход процесса
|
||||||
|
Выбор
|
||||||
|
Выразимость
|
||||||
|
Выразительная сила
|
||||||
|
Выразительные средства теории
|
||||||
|
Высказывание
|
||||||
|
Выход
|
||||||
|
Выход процесса
|
||||||
|
ГДМ
|
||||||
|
Генезис
|
||||||
|
Гипертеория
|
||||||
|
Гипотеза
|
||||||
|
Гипотетико-дедуктивные требования
|
||||||
|
Гипотетико-дедуктивный метод
|
||||||
|
Главная функция
|
||||||
|
Глубина проникновения
|
||||||
|
Гносеология
|
||||||
|
Гомоморфизм
|
||||||
|
ГП РС
|
||||||
|
Границы сети процессов
|
||||||
|
Граф
|
||||||
|
Граф термов
|
||||||
|
Группа
|
||||||
|
Двухместное отношение
|
||||||
|
Дебуленизация
|
||||||
|
Дедуктивная теория
|
||||||
|
Декартово произведение
|
||||||
|
Декомпозиция
|
||||||
|
Дескриптивное использование теории
|
||||||
|
Дескриптивный подход
|
||||||
|
Диаграмма Венна
|
||||||
|
Динамическая система
|
||||||
|
Дихотомия
|
||||||
|
Доказательство
|
||||||
|
Дуга
|
||||||
|
Желаемая система
|
||||||
|
Жизненный цикл
|
||||||
|
Жизненный цикл интереса
|
||||||
|
Жизненный цикл угрозы
|
||||||
|
Зависимое множество аксиом
|
||||||
|
Задача
|
||||||
|
Закон композиции
|
||||||
|
Знаковая система
|
||||||
|
Идентификация
|
||||||
|
Идеолог
|
||||||
|
Идея
|
||||||
|
Идея абстрактного выбора
|
||||||
|
Иерархическая структура
|
||||||
|
Измельчение графа термов
|
||||||
|
Изменение
|
||||||
|
Изоморфизм
|
||||||
|
Изофункциональные методы
|
||||||
|
Ильковский
|
||||||
|
Имплицитная форма
|
||||||
|
Интегрированные объекты
|
||||||
|
Интенсионализация
|
||||||
|
Интересы
|
||||||
|
Интерпретант
|
||||||
|
Интерпретатор
|
||||||
|
Интерпретация
|
||||||
|
Интерпретированная теория
|
||||||
|
Информационная система
|
||||||
|
Инцесс
|
||||||
|
Инцессант
|
||||||
|
Искусственная система
|
||||||
|
Исследовательский подход
|
||||||
|
Истинное подмножество
|
||||||
|
Исток графа термов
|
||||||
|
Исходная сущность
|
||||||
|
Исходное отношение
|
||||||
|
Исходное понятие
|
||||||
|
Исходное утверждение
|
||||||
|
КА
|
||||||
|
КАК-ориентированная система
|
||||||
|
КАНС
|
||||||
|
Карта понятий
|
||||||
|
Картезиан
|
||||||
|
Каталог методов
|
||||||
|
Категорическая теория
|
||||||
|
Качественная проблема
|
||||||
|
Качественные характеристики теории
|
||||||
|
Квазиаксиома
|
||||||
|
Классификация
|
||||||
|
Классификация множества объектов
|
||||||
|
Классы концептуальных схем
|
||||||
|
Классы систем
|
||||||
|
Класс эквивалентности
|
||||||
|
Количественная проблема
|
||||||
|
Комплексное управление развитием систем
|
||||||
|
Композиция
|
||||||
|
Композиция-2
|
||||||
|
Конвенция
|
||||||
|
Конкрест
|
||||||
|
Конкретант
|
||||||
|
Конкретизация
|
||||||
|
Конкретор
|
||||||
|
Конкреция
|
||||||
|
Конституента
|
||||||
|
Конструкт
|
||||||
|
Конструкт-конструктные конструкции
|
||||||
|
Конструкт-содержантные конструкции
|
||||||
|
Конструкция
|
||||||
|
Концепт
|
||||||
|
Концептуализация
|
||||||
|
Концептуализм
|
||||||
|
Концептуальная конструкция
|
||||||
|
Концептуальная модель
|
||||||
|
Концептуальная схема
|
||||||
|
Концептуальное мышление
|
||||||
|
Концептуальное проектирование
|
||||||
|
Концептуальный анализ
|
||||||
|
Концептуальный анализ и синтез
|
||||||
|
Концептуальный аппарат
|
||||||
|
Корректировка целей
|
||||||
|
Кортеж
|
||||||
|
КП
|
||||||
|
Критерий
|
||||||
|
Критический элемент
|
||||||
|
Круги Эйлера
|
||||||
|
КС
|
||||||
|
КТО-ориентированная система
|
||||||
|
КУРС
|
||||||
|
Лингвистическая интерпретация
|
||||||
|
Логика
|
||||||
|
Логические средства
|
||||||
|
Логическое мышление
|
||||||
|
ЛПР
|
||||||
|
Максимальное измельчение
|
||||||
|
МАКС система
|
||||||
|
Малая проекция
|
||||||
|
Математическая структура
|
||||||
|
Математическая теория
|
||||||
|
Математические средства КП СОУ
|
||||||
|
Материальная интерпретация
|
||||||
|
Машинные средства КП СОУ
|
||||||
|
М-граф
|
||||||
|
Мегатеория
|
||||||
|
Мезотеория
|
||||||
|
Меновая власть
|
||||||
|
Мероприятия по достижению частных целей
|
||||||
|
Метатеорема
|
||||||
|
Метатеория
|
||||||
|
Метаязык
|
||||||
|
Метод
|
||||||
|
Метод КП СОУ
|
||||||
|
Методология
|
||||||
|
Механизм
|
||||||
|
Механизм парирования угрозы
|
||||||
|
Микротеория
|
||||||
|
Минимальный род структуры
|
||||||
|
Множество
|
||||||
|
Множество сечений
|
||||||
|
Множество-степень
|
||||||
|
Модель
|
||||||
|
Модель желаемого выхода
|
||||||
|
Морфологическое отношение
|
||||||
|
Мощность множества
|
||||||
|
Мультиграф
|
||||||
|
Мышление
|
||||||
|
Нагрузка
|
||||||
|
Надпроцесс
|
||||||
|
Надсистема
|
||||||
|
Направления развёртывания
|
||||||
|
Н-арное отношение
|
||||||
|
Независимое множество аксиом
|
||||||
|
Непересекающиеся множества
|
||||||
|
Непротиворечивая теория
|
||||||
|
Нереализованные функции
|
||||||
|
Несовместная теория
|
||||||
|
Неформальная аксиоматическая теория
|
||||||
|
Нижнее замыкание вершины графа
|
||||||
|
Н-местное отношение
|
||||||
|
Нормативная методология
|
||||||
|
Нормативная теория
|
||||||
|
Нормативное мышление
|
||||||
|
Нормативный подход
|
||||||
|
Область значений
|
||||||
|
Область определения
|
||||||
|
Область отправления
|
||||||
|
Область прибытия
|
||||||
|
Обратная связь
|
||||||
|
Обстоятельства
|
||||||
|
Общая теория систем
|
||||||
|
Общезначимая формула
|
||||||
|
Объединение
|
||||||
|
Объект
|
||||||
|
Объектная регламентация
|
||||||
|
Объектные теории
|
||||||
|
Объект управления
|
||||||
|
Объём теории
|
||||||
|
Объяснительная теория
|
||||||
|
Объясняемая теория
|
||||||
|
Ограничение
|
||||||
|
Онтологизация
|
||||||
|
Онтология
|
||||||
|
Оператор
|
||||||
|
Операции КАНС
|
||||||
|
Операциональная схема синтеза
|
||||||
|
Операциональное понятие
|
||||||
|
Операция
|
||||||
|
Операция малая проекция
|
||||||
|
Операция повышения размерности
|
||||||
|
Определяющее свойство множества
|
||||||
|
Оптимизация
|
||||||
|
Организационное управление
|
||||||
|
Организация
|
||||||
|
Ориентированный путь
|
||||||
|
Основание классификации
|
||||||
|
Отвлечённые теории
|
||||||
|
Открытая система
|
||||||
|
Относительное дополнение
|
||||||
|
Отношение
|
||||||
|
Отношение порядка
|
||||||
|
Отношение эквивалентности
|
||||||
|
Отображение
|
||||||
|
Отождествление
|
||||||
|
Отрицание множества
|
||||||
|
ОТСУ
|
||||||
|
ПВР
|
||||||
|
Первичная функция
|
||||||
|
Первичные термины теории
|
||||||
|
Перепостулирование
|
||||||
|
Пересекающиеся множества
|
||||||
|
Пересечение множеств
|
||||||
|
Петля
|
||||||
|
ПО
|
||||||
|
Поддержание
|
||||||
|
Подмножество
|
||||||
|
Подсистема
|
||||||
|
Подтеория
|
||||||
|
Подфункция
|
||||||
|
Политика
|
||||||
|
Полифункциональные методы
|
||||||
|
Полная согласованная интерпретация
|
||||||
|
Полная теория
|
||||||
|
Полный вход
|
||||||
|
Полный выход
|
||||||
|
Понятие
|
||||||
|
Порождающие структуры
|
||||||
|
Постулирование
|
||||||
|
Потенциальная связь
|
||||||
|
Потенциально связанные процессы
|
||||||
|
Потенциальный критический элемент системы
|
||||||
|
Предмет
|
||||||
|
Предметная область
|
||||||
|
Предметный язык
|
||||||
|
Предположение
|
||||||
|
Преобразование
|
||||||
|
Препятствие
|
||||||
|
Прескриптивное использование теории
|
||||||
|
Прескриптивный подход
|
||||||
|
Приложение теории
|
||||||
|
Принадлежность
|
||||||
|
Принцип дополнительности
|
||||||
|
ПРО
|
||||||
|
Проблема
|
||||||
|
Прогнозный сценарий
|
||||||
|
Проект
|
||||||
|
Проектирование СОУ
|
||||||
|
Проектный подход
|
||||||
|
Проект СОУ
|
||||||
|
Проекция родовой структуры
|
||||||
|
Произведение множеств
|
||||||
|
Производное понятие
|
||||||
|
Производные понятия n-го ранга
|
||||||
|
Производные термы
|
||||||
|
Противоречивая теория
|
||||||
|
Процесс
|
||||||
|
Процесс КП конкретной СОУ
|
||||||
|
Процесс ограничения
|
||||||
|
Процессор
|
||||||
|
Процесс с необеспеченными связями
|
||||||
|
Процесс с ролевыми отношениями
|
||||||
|
ПРС
|
||||||
|
ПТ
|
||||||
|
Пустое множество
|
||||||
|
Разбиение множества объектов
|
||||||
|
Разбиение множества объектов по явному основанию
|
||||||
|
Развёрнутое графовое представление
|
||||||
|
Развёрнутый род структуры
|
||||||
|
Развёртывание теории
|
||||||
|
Развивающаяся система
|
||||||
|
Развитие
|
||||||
|
Разнообразие
|
||||||
|
Ранг
|
||||||
|
Ранжирование
|
||||||
|
Расчленённые множества
|
||||||
|
Редукционизм
|
||||||
|
Редукция
|
||||||
|
Реконструкция
|
||||||
|
Ресурс
|
||||||
|
Рефлексивное отношение
|
||||||
|
Решение
|
||||||
|
Р-интерпретация
|
||||||
|
Родовая структура
|
||||||
|
Родовое отношение
|
||||||
|
Родоструктурная экспликация
|
||||||
|
Род структуры
|
||||||
|
Рост
|
||||||
|
Рутинная операция
|
||||||
|
СА
|
||||||
|
Самоорганизующаяся система
|
||||||
|
САПР
|
||||||
|
Свободное мышление
|
||||||
|
Свойство
|
||||||
|
Свойство икса
|
||||||
|
Связь
|
||||||
|
Семантическая сеть
|
||||||
|
Сеть
|
||||||
|
Сеть ПРО
|
||||||
|
Сеть процессов
|
||||||
|
Сеть процессов с ролевыми отношениями
|
||||||
|
Сеть частных целей
|
||||||
|
Сечение
|
||||||
|
Сильные и слабые формы концептуализации
|
||||||
|
Симметричное отношение
|
||||||
|
Синтаксический язык
|
||||||
|
Синтез
|
||||||
|
Синтез родов структур
|
||||||
|
С-интерпретация
|
||||||
|
Система
|
||||||
|
Система автоматизированного проектирования
|
||||||
|
Система восстановления
|
||||||
|
Система организационного управления
|
||||||
|
Система поддержания
|
||||||
|
Система процессов
|
||||||
|
Система развития
|
||||||
|
Система стратегического планирования
|
||||||
|
Система стратегического управления
|
||||||
|
Система управления базами данных
|
||||||
|
Система функционирования
|
||||||
|
Системные классы
|
||||||
|
Системные объекты
|
||||||
|
Системный анализ
|
||||||
|
Слабоструктурированная проблема
|
||||||
|
Словесная форма
|
||||||
|
Сложная система
|
||||||
|
Сложная структура
|
||||||
|
Событие
|
||||||
|
Совершенствование
|
||||||
|
Совместимая теория
|
||||||
|
Содержание
|
||||||
|
Содержант
|
||||||
|
Содержательно-дедуктивное развёртывание
|
||||||
|
Соединение
|
||||||
|
Соединение множеств
|
||||||
|
Соискатель ресурсов
|
||||||
|
Соответствие
|
||||||
|
Состояние организации
|
||||||
|
СОУ
|
||||||
|
Сравнение
|
||||||
|
Среда
|
||||||
|
Средства КП СОУ
|
||||||
|
Срез графа термов
|
||||||
|
Срез подграфа термов
|
||||||
|
Сток графа термов
|
||||||
|
Стратегические цели
|
||||||
|
Стратегическое планирование
|
||||||
|
Стратегическое состояние
|
||||||
|
Стратегия
|
||||||
|
Стратификация
|
||||||
|
Строгое включение
|
||||||
|
Структ
|
||||||
|
Структура
|
||||||
|
Структура, определённая отношением порядка
|
||||||
|
Ступень
|
||||||
|
СУБД
|
||||||
|
Субъект
|
||||||
|
Субъектная регламентация
|
||||||
|
Субъект целеполагания
|
||||||
|
Сумма
|
||||||
|
Сущность
|
||||||
|
Схема
|
||||||
|
Схематизация
|
||||||
|
Творческая операция
|
||||||
|
Тектология
|
||||||
|
Тело теории
|
||||||
|
Теорема
|
||||||
|
Теоретико-множественная интерпретация
|
||||||
|
Теоретико-множественная экспликация
|
||||||
|
Теоретико-множественные операции
|
||||||
|
Теоретико-системная экспликация
|
||||||
|
Теоретико-системное мышление
|
||||||
|
Теоретическое описание объекта
|
||||||
|
Теория
|
||||||
|
Теория множеств
|
||||||
|
Теория систем
|
||||||
|
Терм
|
||||||
|
Терминальная теория
|
||||||
|
Терм-функция
|
||||||
|
Термы n-го ранга
|
||||||
|
Техническая система
|
||||||
|
Техногенема n-го порядка
|
||||||
|
Технология КП СОУ
|
||||||
|
Типизация
|
||||||
|
Типология
|
||||||
|
Типы мышления
|
||||||
|
ТМИ
|
||||||
|
ТМФ
|
||||||
|
Толчок Ильковского
|
||||||
|
Топология
|
||||||
|
Точка зрения
|
||||||
|
Транзитивное отношение
|
||||||
|
Требование проблемы
|
||||||
|
Требования к проекту СОУ
|
||||||
|
Треугольник Фреге
|
||||||
|
ТСК
|
||||||
|
Угроза
|
||||||
|
Универсальное множество
|
||||||
|
Универсум
|
||||||
|
Упорядоченная n-ка
|
||||||
|
Упорядоченная пара
|
||||||
|
Управление
|
||||||
|
Управление процессом достижения цели
|
||||||
|
Урманцев
|
||||||
|
Уровень эксплицитности
|
||||||
|
Условие проблемы
|
||||||
|
Фактормножество
|
||||||
|
Фактор-структура
|
||||||
|
Фактор-структура n-го ранга
|
||||||
|
Феноменология
|
||||||
|
Формализация
|
||||||
|
Формальная система
|
||||||
|
Формальная теория
|
||||||
|
Формально-дедуктивное развёртывание
|
||||||
|
Формальное мышление
|
||||||
|
Форма от x
|
||||||
|
Формы концептуализации
|
||||||
|
Формы мышления
|
||||||
|
Функционально-методное отношение
|
||||||
|
Функциональные свойства
|
||||||
|
Функционирование
|
||||||
|
Функция
|
||||||
|
Целевой выход
|
||||||
|
Целевой терм
|
||||||
|
Целенаправленная система
|
||||||
|
Целенаправленная система с ОС
|
||||||
|
Целеустремлённая система
|
||||||
|
Цель
|
||||||
|
Цикл
|
||||||
|
ЦНС
|
||||||
|
Частная цель
|
||||||
|
Член множества
|
||||||
|
Членство
|
||||||
|
Шкала множеств
|
||||||
|
Шкала ступеней
|
||||||
|
Эквивалентность
|
||||||
|
Экспликация
|
||||||
|
Эксплицитное мышление
|
||||||
|
Экстенсионализация
|
||||||
|
Элемент
|
||||||
|
Элементарная теория
|
||||||
|
Элементарный объект
|
||||||
|
Элемент входа
|
||||||
|
Элемент выхода
|
||||||
|
Эмпирический материал
|
||||||
|
Эпистемология
|
||||||
|
Этапы разработки концептуальной схемы
|
||||||
|
Этиология
|
||||||
|
Ядро
|
||||||
|
Язык-объект
|
||||||
|
Ярус графа
|
||||||
|
Тезаурус по экологии:
|
||||||
|
жизнедеятельность человека
|
||||||
|
технологический процесс
|
||||||
|
пространственный объем
|
||||||
|
естественная экологическая система
|
||||||
|
ценность природного объекта
|
||||||
|
ценность природной среды
|
||||||
|
субъект сохраняемой природной среды
|
||||||
|
экологически значимый отход
|
||||||
|
естественный состав природной среды
|
||||||
|
искусственное изменение природной среды
|
||||||
|
повреждение природного объекта
|
||||||
|
восстановление природного объекта
|
||||||
|
восстановление природной среды
|
||||||
|
восстановимое изменение природной среды
|
||||||
|
физически необратимое изменение природной среды
|
||||||
|
источник воздействия хозяйственной деятельности
|
||||||
|
благоприятный экологический эффект хозяйственной деятельности
|
||||||
|
резерв ресурса целевой экологической зоны под декларации
|
||||||
|
установленный запас ресурса целевой экологической зоны
|
||||||
|
заявленное воздействие
|
||||||
|
экологический аудит
|
||||||
|
благоприятная природная среда жизнедеятельности
|
||||||
|
благоприятная природная среда хозяйственной деятельности
|
||||||
|
благоприятная экологическая зона
|
||||||
|
виды экологической экспертизы
|
||||||
|
государственное оперативное экологическое управление
|
||||||
|
государственное экологическое управление
|
||||||
|
границы применимости методики
|
||||||
|
деклараций о выбросах, сбросах и физических воздействиях
|
||||||
|
декларируемые воздействия
|
||||||
|
декларируемые опосредованные воздействия
|
||||||
|
документы методического обеспечения экологических отношений
|
||||||
|
документы оценки воздействия
|
||||||
|
документы экологического планирования
|
||||||
|
Единый экологический реестр
|
||||||
|
законодательство в области экологических отношений
|
||||||
|
заключение экологического нормоконтроля
|
||||||
|
зона экологического бедствия
|
||||||
|
информационное обеспечение ЭО
|
||||||
|
карта экологического зонирования
|
||||||
|
муниципальное оперативное экологическое управление
|
||||||
|
муниципальное экологическое управление
|
||||||
|
муниципальный экологический контроль
|
||||||
|
муниципальный экологический мониторинг
|
||||||
|
научное обеспечение экологических отношений
|
||||||
|
научный экологический совет
|
||||||
|
неблагоприятная экологическая зона
|
||||||
|
неопределенная экологическая зона
|
||||||
|
неприемлемая экологическая зона
|
||||||
|
общественное экологическое управление
|
||||||
|
общественные экологические объединения
|
||||||
|
общественный экологический контроль
|
||||||
|
общественный экологический мониторинг
|
||||||
|
объект оценки
|
||||||
|
объект экологического нормоконтроля
|
||||||
|
объект, подлежащий обязательному экологическому страхованию
|
||||||
|
обязательное экологическое страхование
|
||||||
|
опасная экологическая зона
|
||||||
|
организации, осуществляющие научное обеспечение экологических отношений
|
||||||
|
основания для ответственности в области экологических отношений
|
||||||
|
приемлемая экологическая зона
|
||||||
|
программа мероприятий по благоприятному изменению природной среды и снижению риска возникновения негативных экологических последствий
|
||||||
|
производственное оперативное экологическое управление
|
||||||
|
производственное экологическое управление
|
||||||
|
производственный экологический контроль
|
||||||
|
производственный экологический мониторинг
|
||||||
|
прокурорский экологический надзор
|
||||||
|
разрешение на воздействие на природную среду
|
||||||
|
разрешение на выбросы, сбросы и физические воздействия
|
||||||
|
разрешенные воздействия
|
||||||
|
разрешенные опосредованные воздействия
|
||||||
|
региональный экологический нормоконтроль
|
||||||
|
региональное оперативное экологическое управление
|
||||||
|
региональное экологическое нормирование
|
||||||
|
региональное экологическое управление
|
||||||
|
региональные экологические советы
|
||||||
|
региональный экологический контроль
|
||||||
|
региональный экологический мониторинг
|
||||||
|
региональный экологический надзор
|
||||||
|
способы возмещения экологического вреда
|
||||||
|
стратегическая экологическая оценка
|
||||||
|
субъект обязательного экологического страхования
|
||||||
|
схема экологического зонирования
|
||||||
|
технические и технологические экологические нормативы
|
||||||
|
территория зонирования
|
||||||
|
условия применимости норматива
|
||||||
|
участники экологических отношений
|
||||||
|
федеральный экологический нормоконтроль
|
||||||
|
федеральное оперативное экологическое управление
|
||||||
|
федеральное экологическое нормирование
|
||||||
|
федеральное экологическое управление
|
||||||
|
федеральный экологический контроль
|
||||||
|
федеральный экологический мониторинг
|
||||||
|
федеральный экологический надзор
|
||||||
|
первичные нормативы благоприятной природной среды жизнедеятельности
|
||||||
|
первичные нормативы благоприятной природной среды хозяйственной деятельности
|
||||||
|
первичные нормативы опасной природной среды жизнедеятельности
|
||||||
|
первичные нормативы приемлемой природной среды жизнедеятельности
|
||||||
|
первичные нормативы сохраняемой природной среды
|
||||||
|
целевая экологическая зона
|
||||||
|
экологическая плата
|
||||||
|
экологическая экспертиза
|
||||||
|
экологический нормоконтроль
|
||||||
|
экологические нормативы воздействия хозяйственной деятельности
|
||||||
|
экологические нормативы последствий воздействия
|
||||||
|
экологические нормативы природной среды
|
||||||
|
экологическое зонирование по нормативам
|
||||||
|
экологическое зонирование по целям
|
||||||
|
экологическое нормирование
|
||||||
|
экологическое управление
|
||||||
|
экспертное экологическое заключение
|
||||||
|
Муниципальный экологический план
|
||||||
|
Ежегодный отчет о состоянии природной среды на территории Российской Федерации
|
||||||
|
Ежегодный отчет о состоянии природной среды на территории муниципальных образований
|
||||||
|
Порядок государственной аккредитации организаций, осуществляющих научное обеспечение экологических отношений
|
||||||
|
Порядок государственной аккредитации экспертных организаций и экспертов в области экологических отношений
|
||||||
|
Порядок научного обеспечения экологических отношений
|
||||||
|
Положение о Научном экологическом совете
|
||||||
|
Положение об экологическом нормоконтроле
|
||||||
|
Положение об экологической экспертизе
|
||||||
|
Методика расчета совокупного опосредованного воздействия на природную среду
|
||||||
|
Положение об Едином экологическом реестре
|
||||||
|
Методика оценки воздействия на природную среду
|
||||||
|
Положение о мерах по благоприятному изменению природной среды и снижению риска возникновения негативных экологических последствий
|
||||||
|
Перечень видов хозяйственной деятельности, для которых устанавливаются экологические нормативы природной среды хозяйственной деятельности
|
||||||
|
Порядок утверждения экологических нормативов природной среды хозяйственной деятельности
|
||||||
|
Порядок утверждения технических и технологических экологических нормативов
|
||||||
|
Порядок утверждения экологических нормативов хозяйственной деятельности
|
||||||
|
Методические рекомендации по разработке муниципальных экологических планов
|
||||||
|
Методические рекомендации по разработке производственных экологических планов
|
||||||
|
Федеральный экологический план
|
||||||
|
Порядок разработки федеральных экологических планов
|
||||||
|
Порядок проведения стратегической экологической оценки
|
||||||
|
Методика расчета воздействия по опосредованному воздействию
|
||||||
|
Порядок оформления разрешений на воздействие на природную среду
|
||||||
|
Методика определения и изменения размера экологической платы
|
||||||
|
Методика экологического мониторинга
|
||||||
|
Методика оперативного экологического управления
|
||||||
|
Методика экологического контроля
|
||||||
|
Методика оценки экологического ущерба
|
||||||
|
Правила экологического страхования
|
||||||
|
Ежегодный отчет о состоянии природной среды на территории субъекта Российской Федерации
|
||||||
|
Положение о Региональном экологическом совете субъекта Российской Федерации
|
||||||
|
Порядок создания региональных экологических советов
|
||||||
|
Порядок проведения публичных слушаний при рассмотрении проектов региональных схем экологического зонирования
|
||||||
|
Региональный экологический план
|
||||||
|
Порядок разработки региональных экологических планов
|
||||||
|
Производственный экологический план
|
||||||
|
жизнедеятельность
|
||||||
|
технология
|
||||||
|
хозяйственная деятельность
|
||||||
|
производственная инфраструктура
|
||||||
|
объект хозяйственной деятельности
|
||||||
|
природный объект
|
||||||
|
природная среда
|
||||||
|
природная среда жизнедеятельности
|
||||||
|
природная среда хозяйственной деятельности
|
||||||
|
природный объект особого значения
|
||||||
|
особо охраняемая природная территория
|
||||||
|
сохраняемая природная среда
|
||||||
|
действующий объект хозяйственной деятельности
|
||||||
|
новый объект хозяйственной деятельности
|
||||||
|
субъект хозяйственной деятельности
|
||||||
|
работник субъекта хозяйственной деятельности
|
||||||
|
отход
|
||||||
|
выброс
|
||||||
|
сброс
|
||||||
|
размещение отходов
|
||||||
|
размещенные отходы
|
||||||
|
объект размещения отходов
|
||||||
|
воздействие хозяйственной деятельности
|
||||||
|
физическое воздействие
|
||||||
|
мероприятие по благоприятному изменению природной среды
|
||||||
|
технологически невосстановимое изменение природной среды
|
||||||
|
опосредующая природная среда
|
||||||
|
опосредующие свойства природной среды
|
||||||
|
опосредованное воздействие
|
||||||
|
территория опосредованного воздействия хозяйственной деятельности
|
||||||
|
совокупное опосредованное воздействие на природную среду
|
||||||
|
экологический эффект хозяйственной деятельности
|
||||||
|
экологическое последствие
|
||||||
|
экологическое правонарушение
|
||||||
|
экологический вред
|
||||||
|
экологический ущерб
|
||||||
|
наилучшая доступная технология
|
||||||
|
негативный экологический эффект хозяйственной деятельности
|
||||||
|
негативное экологическое последствие хозяйственной деятельности
|
||||||
|
реципиент воздействия
|
||||||
|
мероприятие по снижению риска возникновения негативных экологических последствий
|
||||||
|
мера по благоприятному изменению природной среды и снижению риска возникновения негативных экологических последствий
|
||||||
|
экологическое отношение
|
||||||
|
субъекты
|
||||||
|
критерий незначительности воздействия
|
||||||
|
незначительное воздействие хозяйственной деятельности
|
||||||
|
критерий декларирования опосредованного воздействия
|
||||||
|
первичный норматив
|
||||||
|
экологический норматив
|
||||||
|
баланс интересов
|
||||||
|
экологическое зонирование
|
||||||
|
экологических зон
|
||||||
|
базовое состояние природной среды
|
||||||
|
ресурс природной среды
|
||||||
|
распределяемый ресурс природной ресурс
|
||||||
|
квота опосредованного воздействия
|
||||||
|
утраченный экологический ресурс
|
||||||
|
критерий корректировки программ мероприятий
|
||||||
|
экологическая экспертная оценка
|
||||||
|
экологический экспертный расчет
|
||||||
|
экологический нормоконтроль
|
||||||
|
управленческое решение
|
||||||
|
экологический мониторинг
|
||||||
|
оперативное экологическое управление
|
||||||
|
экологический контроль
|
||||||
|
экологический надзор
|
||||||
|
|
94
rsconcept/backend/cctext/tests/manual/TestNotebook.ipynb
Normal file
94
rsconcept/backend/cctext/tests/manual/TestNotebook.ipynb
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"\n",
|
||||||
|
"import pymorphy2\n",
|
||||||
|
"import cctext as ct\n",
|
||||||
|
"\n",
|
||||||
|
"from nltk.stem import SnowballStemmer\n",
|
||||||
|
"stemmer = SnowballStemmer(language=\"russian\")\n",
|
||||||
|
"# https://www.langust.ru/rus_gram/rus_gr06.shtml\n",
|
||||||
|
"# stemmer.stem(\"обеспечение\")\n",
|
||||||
|
"\n",
|
||||||
|
"morpho = pymorphy2.MorphAnalyzer()\n",
|
||||||
|
"parser = ct.RuParser()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"butyavka = morpho.parse('мюсли')\n",
|
||||||
|
"butyavka[0].lexeme"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"ct.get_all_forms('танк')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# thesaurus = open('tests/data/thesaurus.txt', mode='r', encoding='UTF-8')\n",
|
||||||
|
"thesaurus = open('tests/data/functions.txt', mode='r', encoding='UTF-8')\n",
|
||||||
|
"content = [term.strip() for term in thesaurus.readlines()]\n",
|
||||||
|
"thesaurus.close()\n",
|
||||||
|
"\n",
|
||||||
|
"inflect_datv = [ct.inflect(term, 'datv') for term in content]\n",
|
||||||
|
"inflect_nomn1 = [ct.inflect(term, 'nomn') for term in inflect_datv]\n",
|
||||||
|
"inflect_gent = [ct.inflect(term, 'gent') for term in content]\n",
|
||||||
|
"inflect_nomn2 = [ct.inflect(term, 'nomn') for term in inflect_gent]\n",
|
||||||
|
"\n",
|
||||||
|
"data = zip(content, inflect_datv, inflect_nomn1, inflect_gent, inflect_nomn2)\n",
|
||||||
|
"df = pd.DataFrame(data, columns =['Term', 'Datv', 'Inverse1', 'Gent', 'Inverse2'])\n",
|
||||||
|
"df.to_excel('output.xlsx')"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"interpreter": {
|
||||||
|
"hash": "11938c6bc6919ae2720b4d5011047913343b08a43b18698fd82dedb0d4417594"
|
||||||
|
},
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3.9.5 64-bit",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.9.5"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"interpreter": {
|
||||||
|
"hash": "b8488343e509b415c98a857491a9b4c90395f9a45992da0bb6102fdf120e22ce"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"orig_nbformat": 2
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
BIN
rsconcept/backend/cctext/tests/manual/functions_mark.xlsx
Normal file
BIN
rsconcept/backend/cctext/tests/manual/functions_mark.xlsx
Normal file
Binary file not shown.
BIN
rsconcept/backend/cctext/tests/manual/output.xlsx
Normal file
BIN
rsconcept/backend/cctext/tests/manual/output.xlsx
Normal file
Binary file not shown.
BIN
rsconcept/backend/cctext/tests/manual/terms_mark.xlsx
Normal file
BIN
rsconcept/backend/cctext/tests/manual/terms_mark.xlsx
Normal file
Binary file not shown.
78
rsconcept/backend/cctext/tests/testConceptAPI.py
Normal file
78
rsconcept/backend/cctext/tests/testConceptAPI.py
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
'''Test Concept Text API'''
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import cctext as cc
|
||||||
|
|
||||||
|
|
||||||
|
class TestConceptAPI(unittest.TestCase):
|
||||||
|
'''Test class for Concept API.'''
|
||||||
|
def _assert_tags(self, actual: str, expected: str):
|
||||||
|
self.assertEqual(cc.split_tags(actual), cc.split_tags(expected))
|
||||||
|
|
||||||
|
def test_parse(self):
|
||||||
|
''' Test parsing. '''
|
||||||
|
self._assert_tags(cc.parse(''), '')
|
||||||
|
self._assert_tags(cc.parse('1'), 'intg,NUMB')
|
||||||
|
self._assert_tags(cc.parse('слон', require_tags='masc'), 'NOUN,anim,masc,sing,nomn')
|
||||||
|
|
||||||
|
def test_normalize_word(self):
|
||||||
|
''' Test normalize for single word. '''
|
||||||
|
self.assertEqual(cc.normalize(''), '')
|
||||||
|
self.assertEqual(cc.normalize('первого'), 'первый')
|
||||||
|
self.assertEqual(cc.normalize('диких людей'), 'дикий человек')
|
||||||
|
|
||||||
|
def test_get_all_forms(self):
|
||||||
|
''' Test all lexical forms. '''
|
||||||
|
self.assertEqual(cc.get_all_forms(''), [])
|
||||||
|
|
||||||
|
forms = cc.get_all_forms('наверное')
|
||||||
|
self.assertEqual(len(forms), 1)
|
||||||
|
self.assertEqual(forms[0][0], 'наверное')
|
||||||
|
self._assert_tags(forms[0][1], 'CONJ,Prnt')
|
||||||
|
|
||||||
|
def test_inflect(self):
|
||||||
|
''' Test inflection. '''
|
||||||
|
self.assertEqual(cc.inflect('', ''), '')
|
||||||
|
self.assertEqual(cc.inflect('слона', 'nomn'), 'слон')
|
||||||
|
self.assertEqual(cc.inflect('слона', 'ADJF'), 'слона')
|
||||||
|
self.assertEqual(cc.inflect('слона', 'nomn,plur'), 'слоны')
|
||||||
|
self.assertEqual(cc.inflect('слона', 'nomn, plur'), 'слоны')
|
||||||
|
self.assertEqual(cc.inflect('шкала оценок', 'loct,plur'), 'шкалах оценок')
|
||||||
|
|
||||||
|
def test_find_substr(self):
|
||||||
|
'''Test substring search'''
|
||||||
|
self.assertEqual(cc.find_substr('', ''), (0, 0))
|
||||||
|
self.assertEqual(cc.find_substr('сложного красивого слона', 'красивые слоном'), (9, 24))
|
||||||
|
|
||||||
|
def test_inflect_context(self):
|
||||||
|
'''Test contex inflection'''
|
||||||
|
self.assertEqual(cc.inflect_context('', '', ''), '')
|
||||||
|
self.assertEqual(cc.inflect_context('красивый', '', 'чашка'), 'красивая')
|
||||||
|
|
||||||
|
def test_inflect_substitute(self):
|
||||||
|
'''Test substitute inflection'''
|
||||||
|
self.assertEqual(cc.inflect_substitute('', ''), '')
|
||||||
|
self.assertEqual(cc.inflect_substitute('', 'слон'), '')
|
||||||
|
self.assertEqual(cc.inflect_substitute('слон', ''), 'слон')
|
||||||
|
self.assertEqual(cc.inflect_substitute('красивый бантик', 'кошкой'), 'красивым бантиком')
|
||||||
|
|
||||||
|
def test_inflect_dependant(self):
|
||||||
|
''' Test coordination inflection. '''
|
||||||
|
self.assertEqual(cc.inflect_dependant('', ''), '')
|
||||||
|
self.assertEqual(cc.inflect_dependant('', 'слон'), '')
|
||||||
|
self.assertEqual(cc.inflect_dependant('слон', ''), 'слон')
|
||||||
|
self.assertEqual(cc.inflect_dependant('общий', 'мать'), 'общая')
|
||||||
|
self.assertEqual(cc.inflect_dependant('синий', 'слонов'), 'синих')
|
||||||
|
|
||||||
|
def test_match_all_morpho(self):
|
||||||
|
''' Test extracting matching morpho. '''
|
||||||
|
self.assertEqual(cc.match_all_morpho('', ''), [])
|
||||||
|
self.assertEqual(cc.match_all_morpho('горит город', ''), [])
|
||||||
|
self.assertEqual(cc.match_all_morpho('горит город', 'NOUN'), [[6, 11]])
|
||||||
|
self.assertEqual(cc.match_all_morpho('горит город', 'VERB'), [[0, 5]])
|
||||||
|
self.assertEqual(cc.match_all_morpho('столица страны', 'NOUN'), [[0, 7], [8, 14]])
|
||||||
|
self.assertEqual(cc.match_all_morpho('столица страны', 'NOUN,sing,nomn'), [[0, 7]])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
441
rsconcept/backend/cctext/tests/testRuParser.py
Normal file
441
rsconcept/backend/cctext/tests/testRuParser.py
Normal file
|
@ -0,0 +1,441 @@
|
||||||
|
''' Test russian language parsing. '''
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cctext import RuParser
|
||||||
|
|
||||||
|
parser = RuParser()
|
||||||
|
|
||||||
|
|
||||||
|
class TestRuParser(unittest.TestCase):
|
||||||
|
''' Test class for russian parsing. '''
|
||||||
|
|
||||||
|
def _assert_parse(self, text: str, expected: list[str], require_index: int = -1, require_tags: list[str] = None):
|
||||||
|
phrase = parser.parse(text, require_index, require_tags)
|
||||||
|
self.assertEqual(phrase.get_morpho().tag.grammemes, set(expected))
|
||||||
|
|
||||||
|
def _assert_inflect(self, text: str, tags: list[str], expected: str):
|
||||||
|
model = parser.parse(text)
|
||||||
|
if not model:
|
||||||
|
result = text
|
||||||
|
else:
|
||||||
|
result = model.inflect(set(tags))
|
||||||
|
self.assertEqual(result, expected)
|
||||||
|
|
||||||
|
def test_parse_word(self):
|
||||||
|
''' Test parse for single word. '''
|
||||||
|
self._assert_parse('1', ['NUMB', 'intg'])
|
||||||
|
self._assert_parse('пять', ['NUMR', 'nomn'])
|
||||||
|
self._assert_parse('трёх', ['NUMR', 'gent'])
|
||||||
|
self._assert_parse('трех', ['NUMR', 'gent'])
|
||||||
|
self._assert_parse('круча', ['NOUN', 'femn', 'sing', 'nomn', 'inan'])
|
||||||
|
self._assert_parse('круть', ['NOUN', 'femn', 'sing', 'nomn', 'inan', 'Sgtm', 'Geox'])
|
||||||
|
self._assert_parse('ПВО', ['NOUN', 'femn', 'sing', 'nomn', 'inan', 'Sgtm', 'Abbr', 'Fixd'])
|
||||||
|
self._assert_parse('СМИ', ['NOUN', 'plur', 'nomn', 'inan', 'Pltm', 'Abbr', 'Fixd', 'GNdr'])
|
||||||
|
self._assert_parse('ему', ['NPRO', 'masc', 'sing', 'datv', '3per', 'Anph'])
|
||||||
|
self._assert_parse('крутит', ['VERB', 'sing', '3per', 'pres', 'impf', 'tran', 'indc'])
|
||||||
|
self._assert_parse('смеркалось', ['VERB', 'neut', 'sing', 'Impe', 'past', 'impf', 'intr', 'indc'])
|
||||||
|
self._assert_parse('крутить', ['INFN', 'impf', 'tran'])
|
||||||
|
self._assert_parse('крученый', ['ADJF', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('крут', ['ADJS', 'masc', 'sing', 'Qual'])
|
||||||
|
self._assert_parse('крутящего', ['PRTF', 'masc', 'sing', 'gent', 'pres', 'impf', 'tran', 'actv'])
|
||||||
|
self._assert_parse('откручен', ['PRTS', 'masc', 'sing', 'past', 'perf', 'pssv'])
|
||||||
|
self._assert_parse('крутя', ['GRND', 'pres', 'impf', 'tran'])
|
||||||
|
self._assert_parse('круто', ['ADVB'])
|
||||||
|
self._assert_parse('круче', ['COMP', 'Qual'])
|
||||||
|
self._assert_parse(',', ['PNCT'])
|
||||||
|
self._assert_parse('32-', ['intg', 'NUMB'])
|
||||||
|
|
||||||
|
self._assert_parse('слон', ['NOUN', 'anim', 'masc', 'sing', 'nomn'], require_index=0)
|
||||||
|
self._assert_parse('слон', ['NOUN', 'anim', 'masc', 'sing', 'nomn'], require_tags=['masc'])
|
||||||
|
self._assert_parse('прямой', ['ADJF', 'gent', 'sing', 'femn', 'Qual'], require_index=0)
|
||||||
|
self._assert_parse('прямой', ['ADJF', 'datv', 'Qual', 'sing', 'femn'], require_index=1)
|
||||||
|
self._assert_parse('прямой', ['NOUN', 'sing', 'inan', 'femn', 'gent'], require_tags=['NOUN'])
|
||||||
|
|
||||||
|
self._assert_parse('консистенции', ['NOUN', 'inan', 'femn', 'plur', 'nomn'])
|
||||||
|
self._assert_parse('тест', ['NOUN', 'sing', 'masc', 'inan', 'nomn'])
|
||||||
|
self._assert_parse('петля', ['NOUN', 'inan', 'femn', 'sing', 'nomn'])
|
||||||
|
|
||||||
|
self._assert_parse('Слон', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('СМИ', ['NOUN', 'Pltm', 'GNdr', 'Fixd', 'inan', 'Abbr', 'plur', 'nomn'])
|
||||||
|
self.assertEqual(parser.parse('КАиП'), None)
|
||||||
|
self.assertEqual(parser.parse('СЛОН'), None)
|
||||||
|
self.assertEqual(parser.parse(''), None)
|
||||||
|
self.assertEqual(parser.parse('слон', require_tags=set(['femn'])), None)
|
||||||
|
self.assertEqual(parser.parse('32', require_tags=set(['NOUN'])), None)
|
||||||
|
self.assertEqual(parser.parse('32-', require_tags=set(['NOUN'])), None)
|
||||||
|
self.assertEqual(parser.parse('слон', require_index=42), None)
|
||||||
|
|
||||||
|
def test_parse_text(self):
|
||||||
|
''' Test parse for multiword sequences. '''
|
||||||
|
self._assert_parse(', ,', ['PNCT'])
|
||||||
|
self._assert_parse('слон,', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
|
||||||
|
self._assert_parse('синий слон', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('слон синий', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('тихий Дон', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('слон, лежащий на траве', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('лежащий на траве слон', ['NOUN', 'anim', 'masc', 'sing', 'nomn'])
|
||||||
|
self._assert_parse('города улиц', ['NOUN', 'nomn', 'plur', 'masc', 'inan'])
|
||||||
|
self._assert_parse('первый дом улиц города', ['NOUN', 'inan', 'masc', 'nomn', 'sing'])
|
||||||
|
self._assert_parse('быстро едет', ['VERB', 'intr', 'impf', '3per', 'sing', 'indc', 'pres'])
|
||||||
|
self._assert_parse('летучий 1-2-пептид', ['NOUN', 'masc', 'nomn', 'sing', 'inan'])
|
||||||
|
|
||||||
|
self._assert_parse('прямой угол', ['NOUN', 'masc', 'nomn', 'inan', 'sing'])
|
||||||
|
self._assert_parse('прямого угла', ['NOUN', 'sing', 'inan', 'masc', 'gent'])
|
||||||
|
self._assert_parse('угла прямой', ['NOUN', 'sing', 'inan', 'masc', 'gent'])
|
||||||
|
self._assert_parse('бесконечной прямой', ['NOUN', 'gent', 'femn', 'sing', 'inan'])
|
||||||
|
self._assert_parse('складские операции', ['NOUN', 'femn', 'plur', 'inan', 'nomn'])
|
||||||
|
self._assert_parse('незначительному воздействию хозяйственной деятельности',
|
||||||
|
['NOUN', 'datv', 'sing', 'neut', 'inan'])
|
||||||
|
|
||||||
|
self._assert_parse('варить овсянку', ['INFN', 'tran', 'impf'])
|
||||||
|
self._assert_parse('варить рис', ['INFN', 'tran', 'impf'])
|
||||||
|
|
||||||
|
self._assert_parse('нарочито сложный', ['ADJF', 'sing', 'masc', 'nomn', 'Qual'])
|
||||||
|
self._assert_parse('части программы', ['NOUN', 'femn', 'plur', 'nomn', 'inan'])
|
||||||
|
self._assert_parse('летучий 1-2-фторметил', ['NOUN', 'nomn', 'sing', 'masc', 'inan'])
|
||||||
|
self._assert_parse('отрезок времени', ['NOUN', 'nomn', 'sing', 'masc', 'inan'])
|
||||||
|
self._assert_parse('портки сушить', ['INFN', 'impf', 'tran'])
|
||||||
|
self._assert_parse('портки вешай', ['VERB', 'tran', 'impr', 'impf', 'sing', 'excl'])
|
||||||
|
self._assert_parse('Анализирует состояние организации.',
|
||||||
|
['VERB', 'sing', 'tran', 'pres', '3per', 'impf', 'indc'])
|
||||||
|
self._assert_parse('Во взаимодействии с подразделениями Генеральной прокуратуры формирует перечень показателей',
|
||||||
|
['VERB', 'sing', 'tran', 'pres', '3per', 'impf', 'indc'])
|
||||||
|
|
||||||
|
def test_parse_coordination(self):
|
||||||
|
''' Test parse coordination info. '''
|
||||||
|
self.assertEqual(parser.parse('говорить').coordination, [-1, 1])
|
||||||
|
self.assertEqual(parser.parse('ворчливая карга').coordination, [2, -1, 0])
|
||||||
|
self.assertEqual(parser.parse('страна, объятая пожаром').coordination, [-1, -1, 2, -1, 2])
|
||||||
|
self.assertEqual(parser.parse('тихо говорил').coordination, [-1, -1, 2])
|
||||||
|
|
||||||
|
def test_normalize_word(self):
|
||||||
|
''' Test normalize for single word. '''
|
||||||
|
self.assertEqual(parser.normalize(''), '')
|
||||||
|
self.assertEqual(parser.normalize('123'), '123')
|
||||||
|
self.assertEqual(parser.normalize('test'), 'test')
|
||||||
|
self.assertEqual(parser.normalize('первого'), 'первый')
|
||||||
|
self.assertEqual(parser.normalize('слону'), 'слон')
|
||||||
|
self.assertEqual(parser.normalize('слонам'), 'слон')
|
||||||
|
self.assertEqual(parser.normalize('обеспечил'), 'обеспечить')
|
||||||
|
self.assertEqual(parser.normalize('сильную'), 'сильный')
|
||||||
|
self.assertEqual(parser.normalize('бежавший'), 'бежать')
|
||||||
|
self.assertEqual(parser.normalize('1 2 3'), '1 2 3')
|
||||||
|
|
||||||
|
def test_normalize_text(self):
|
||||||
|
''' Test normalize for multiword collation. '''
|
||||||
|
self.assertEqual(parser.normalize('синего слона'), 'синий слон')
|
||||||
|
self.assertEqual(parser.normalize('тихо говоривший'), 'тихо говорить')
|
||||||
|
self.assertEqual(parser.normalize('канавой квартала'), 'канава квартала')
|
||||||
|
|
||||||
|
def test_inflect_word(self):
|
||||||
|
''' Test inflection for single word. '''
|
||||||
|
self._assert_inflect('', [], '')
|
||||||
|
self._assert_inflect('invalid', [], 'invalid')
|
||||||
|
self._assert_inflect('invalid', ['nomn'], 'invalid')
|
||||||
|
self._assert_inflect('', ['nomn'], '')
|
||||||
|
self._assert_inflect('123', ['nomn'], '123')
|
||||||
|
self._assert_inflect('слона', [], 'слона')
|
||||||
|
self._assert_inflect('слона', ['ADJF'], 'слона')
|
||||||
|
|
||||||
|
self._assert_inflect('слона', ['nomn'], 'слон')
|
||||||
|
self._assert_inflect('объектоид', ['datv'], 'объектоиду')
|
||||||
|
self._assert_inflect('терм-функция', ['datv'], 'терм-функции')
|
||||||
|
|
||||||
|
self._assert_inflect('Слона', ['nomn'], 'Слон')
|
||||||
|
self._assert_inflect('СМИ', ['datv'], 'СМИ')
|
||||||
|
self._assert_inflect('КАНС', ['datv'], 'КАНС')
|
||||||
|
self._assert_inflect('КАиП', ['datv'], 'КАиП')
|
||||||
|
self._assert_inflect('АТ', ['datv'], 'АТ')
|
||||||
|
self._assert_inflect('А-проекция', ['datv'], 'А-проекции')
|
||||||
|
|
||||||
|
def test_inflect_noun(self):
|
||||||
|
''' Test inflection for single noun. '''
|
||||||
|
self._assert_inflect('книга', ['nomn'], 'книга')
|
||||||
|
self._assert_inflect('книга', ['gent'], 'книги')
|
||||||
|
self._assert_inflect('книга', ['datv'], 'книге')
|
||||||
|
self._assert_inflect('книга', ['accs'], 'книгу')
|
||||||
|
self._assert_inflect('книга', ['ablt'], 'книгой')
|
||||||
|
self._assert_inflect('книга', ['loct'], 'книге')
|
||||||
|
self._assert_inflect('люди', ['loct'], 'людях')
|
||||||
|
|
||||||
|
self._assert_inflect('книга', ['plur'], 'книги')
|
||||||
|
self._assert_inflect('люди', ['sing'], 'человек')
|
||||||
|
self._assert_inflect('человек', ['plur'], 'люди')
|
||||||
|
self._assert_inflect('человек', ['plur', 'loct'], 'людях')
|
||||||
|
|
||||||
|
self._assert_inflect('человеку', ['masc'], 'человеку')
|
||||||
|
self._assert_inflect('человеку', ['neut'], 'человеку')
|
||||||
|
self._assert_inflect('человека', ['femn'], 'человека')
|
||||||
|
self._assert_inflect('человека', ['past'], 'человека')
|
||||||
|
|
||||||
|
def test_inflect_npro(self):
|
||||||
|
''' Test inflection for single pronoun. '''
|
||||||
|
self._assert_inflect('меня', ['nomn'], 'я')
|
||||||
|
self._assert_inflect('я', ['gent'], 'меня')
|
||||||
|
self._assert_inflect('я', ['datv'], 'мне')
|
||||||
|
self._assert_inflect('я', ['accs'], 'меня')
|
||||||
|
self._assert_inflect('я', ['ablt'], 'мной')
|
||||||
|
self._assert_inflect('я', ['loct'], 'мне')
|
||||||
|
|
||||||
|
self._assert_inflect('я', ['ADJF'], 'я')
|
||||||
|
self._assert_inflect('я', ['NOUN'], 'я')
|
||||||
|
self._assert_inflect('я', ['2per'], 'я')
|
||||||
|
self._assert_inflect('я', ['past'], 'я')
|
||||||
|
|
||||||
|
def test_inflect_numr(self):
|
||||||
|
''' Test inflection for single numeric. '''
|
||||||
|
self._assert_inflect('трёх', ['nomn'], 'три')
|
||||||
|
self._assert_inflect('три', ['gent'], 'трёх')
|
||||||
|
self._assert_inflect('три', ['datv'], 'трём')
|
||||||
|
self._assert_inflect('три', ['accs', 'inan'], 'три')
|
||||||
|
self._assert_inflect('три', ['accs', 'anim'], 'трёх')
|
||||||
|
self._assert_inflect('три', ['ablt'], 'тремя')
|
||||||
|
self._assert_inflect('три', ['loct'], 'трёх')
|
||||||
|
|
||||||
|
def test_inflect_adjf(self):
|
||||||
|
''' Test inflection for single adjectif. '''
|
||||||
|
self._assert_inflect('хороший', ['nomn'], 'хороший')
|
||||||
|
self._assert_inflect('хороший', ['gent'], 'хорошего')
|
||||||
|
self._assert_inflect('хороший', ['datv'], 'хорошему')
|
||||||
|
self._assert_inflect('хороший', ['accs'], 'хорошего')
|
||||||
|
self._assert_inflect('хороший', ['ablt'], 'хорошим')
|
||||||
|
self._assert_inflect('хороший', ['loct'], 'хорошем')
|
||||||
|
|
||||||
|
self._assert_inflect('хороший', ['plur'], 'хорошие')
|
||||||
|
self._assert_inflect('хорошие', ['sing'], 'хороший')
|
||||||
|
self._assert_inflect('хорошие', ['sing', 'datv'], 'хорошему')
|
||||||
|
self._assert_inflect('хорошие', ['plur', 'masc', 'datv'], 'хорошим')
|
||||||
|
|
||||||
|
self._assert_inflect('хорошая', ['masc'], 'хороший')
|
||||||
|
self._assert_inflect('перепончатокрылое', ['masc'], 'перепончатокрылый')
|
||||||
|
self._assert_inflect('хороший', ['neut'], 'хорошее')
|
||||||
|
self._assert_inflect('хорошая', ['neut'], 'хорошее')
|
||||||
|
self._assert_inflect('хороший', ['femn'], 'хорошая')
|
||||||
|
self._assert_inflect('перепончатокрылое', ['femn'], 'перепончатокрылая')
|
||||||
|
|
||||||
|
self._assert_inflect('хороший', ['masc', 'femn'], 'хороший')
|
||||||
|
self._assert_inflect('хороший', ['plur', 'femn'], 'хорошие')
|
||||||
|
self._assert_inflect('хороший', ['past'], 'хороший')
|
||||||
|
|
||||||
|
def test_inflect_prtf(self):
|
||||||
|
''' Test inflection for single participle. '''
|
||||||
|
self._assert_inflect('бегущего', ['nomn'], 'бегущий')
|
||||||
|
self._assert_inflect('бегущий', ['gent'], 'бегущего')
|
||||||
|
self._assert_inflect('бегущий', ['datv'], 'бегущему')
|
||||||
|
self._assert_inflect('бегущий', ['accs'], 'бегущего')
|
||||||
|
self._assert_inflect('бегущий', ['ablt'], 'бегущим')
|
||||||
|
self._assert_inflect('бегущий', ['loct'], 'бегущем')
|
||||||
|
self._assert_inflect('бегущая', ['loct'], 'бегущей')
|
||||||
|
self._assert_inflect('бежавшая', ['loct'], 'бежавшей')
|
||||||
|
|
||||||
|
self._assert_inflect('бегущий', ['plur'], 'бегущие')
|
||||||
|
self._assert_inflect('бегущие', ['sing'], 'бегущий')
|
||||||
|
self._assert_inflect('бегущие', ['sing', 'datv'], 'бегущему')
|
||||||
|
|
||||||
|
self._assert_inflect('бегущий', ['femn'], 'бегущая')
|
||||||
|
self._assert_inflect('бегущий', ['neut'], 'бегущее')
|
||||||
|
self._assert_inflect('бегущая', ['masc'], 'бегущий')
|
||||||
|
|
||||||
|
self._assert_inflect('бегущий', ['past'], 'бежавший')
|
||||||
|
self._assert_inflect('бежавших', ['pres'], 'бегущих')
|
||||||
|
|
||||||
|
self._assert_inflect('бегущий', ['masc', 'femn'], 'бегущий')
|
||||||
|
self._assert_inflect('бегущий', ['plur', 'femn'], 'бегущие')
|
||||||
|
|
||||||
|
def test_inflect_verb(self):
|
||||||
|
''' Test inflection for single verb. '''
|
||||||
|
self._assert_inflect('говорить', ['1per'], 'говорю')
|
||||||
|
self._assert_inflect('говорить', ['2per'], 'говоришь')
|
||||||
|
self._assert_inflect('говорить', ['2per', 'plur'], 'говорите')
|
||||||
|
self._assert_inflect('говорить', ['3per'], 'говорит')
|
||||||
|
|
||||||
|
self._assert_inflect('говорите', ['1per'], 'говорим')
|
||||||
|
self._assert_inflect('говорите', ['3per'], 'говорят')
|
||||||
|
|
||||||
|
self._assert_inflect('говорит', ['plur'], 'говорят')
|
||||||
|
self._assert_inflect('говорят', ['sing'], 'говорит')
|
||||||
|
|
||||||
|
self._assert_inflect('говорит', ['past'], 'говорил')
|
||||||
|
self._assert_inflect('говорил', ['pres'], 'говорю')
|
||||||
|
|
||||||
|
self._assert_inflect('говорили', ['sing'], 'говорил')
|
||||||
|
self._assert_inflect('говорил', ['plur'], 'говорили')
|
||||||
|
|
||||||
|
self._assert_inflect('говорила', ['masc'], 'говорил')
|
||||||
|
self._assert_inflect('говорили', ['masc'], 'говорил')
|
||||||
|
self._assert_inflect('говорил', ['neut'], 'говорило')
|
||||||
|
self._assert_inflect('говорил', ['femn'], 'говорила')
|
||||||
|
|
||||||
|
self._assert_inflect('говорить', ['datv'], 'говорить')
|
||||||
|
|
||||||
|
def test_inflect_text_nominal(self):
|
||||||
|
''' Test inflection for multiword text in nominal form. '''
|
||||||
|
self._assert_inflect('синий короткий', ['accs', 'sing', 'femn'], 'синюю короткую')
|
||||||
|
self._assert_inflect('красивые слоны', ['accs', 'sing'], 'красивого слона')
|
||||||
|
self._assert_inflect('вход процесса', ['loct', 'plur'], 'входах процесса')
|
||||||
|
self._assert_inflect('нарочито сложный тест', ['datv', 'sing'], 'нарочито сложному тесту')
|
||||||
|
self._assert_inflect('первый дом улиц города', ['loct', 'plur'], 'первых домах улиц города')
|
||||||
|
self._assert_inflect('шкала оценок', ['loct', 'plur'], 'шкалах оценок')
|
||||||
|
self._assert_inflect('складские операции', ['sing', 'datv'], 'складской операции')
|
||||||
|
self._assert_inflect('стороны конфликтного перехода', ['loct', 'sing'], 'стороне конфликтного перехода')
|
||||||
|
self._assert_inflect('уникомплексные тектологические переходы', ['loct', 'sing'],
|
||||||
|
'уникомплексном тектологическом переходе')
|
||||||
|
|
||||||
|
self._assert_inflect('слабый НИР', ['datv', 'sing'], 'слабому НИР')
|
||||||
|
self._assert_inflect('слабый НИР', ['accs', 'plur'], 'слабых НИР')
|
||||||
|
self._assert_inflect('летучий 1-2-бутан', ['ablt', 'sing'], 'летучим 1-2-бутаном')
|
||||||
|
self._assert_inflect('летучий 1-2-фторметил', ['ablt', 'sing'], 'летучим 1-2-фторметилом')
|
||||||
|
|
||||||
|
self._assert_inflect('красивые процессы', ['accs', 'sing'], 'красивого процесс')
|
||||||
|
self._assert_inflect('красивые процессы', ['gent', 'sing'], 'красивого процесса')
|
||||||
|
self._assert_inflect('части программы', ['ablt', 'sing'], 'части программой')
|
||||||
|
self._assert_inflect('первые здания', ['ablt', 'sing'], 'первым зданием')
|
||||||
|
self._assert_inflect('прямой слон', ['ablt', 'sing'], 'прямым слоном')
|
||||||
|
|
||||||
|
self._assert_inflect('тихо говорить', ['past', 'masc'], 'тихо говорил')
|
||||||
|
self._assert_inflect('быть готовым', ['past', 'masc'], 'был готовым')
|
||||||
|
self._assert_inflect('уметь готовить', ['pres', '2per'], 'умеешь готовить')
|
||||||
|
self._assert_inflect('готовить рис', ['pres', '1per'], 'готовлю рис')
|
||||||
|
|
||||||
|
# self._assert_inflect('десять миллионов', ['datv'], 'десяти миллионам')
|
||||||
|
# self._assert_inflect('десять апельсинов', ['datv'], 'десяти апельсинов')
|
||||||
|
# self._assert_inflect('два миллиона', ['datv'], 'двум миллионам')
|
||||||
|
|
||||||
|
self._assert_inflect('техногенема n-го порядка', ['datv'], 'техногенеме n-го порядка')
|
||||||
|
self._assert_inflect('Положение об органе АБВ', ['datv'], 'Положению об органе АБВ')
|
||||||
|
|
||||||
|
def test_inflect_text_cross(self):
|
||||||
|
''' Test inflection for multiword text in multiple forms. '''
|
||||||
|
self._assert_inflect('слона кота', ['nomn'], 'слон кота')
|
||||||
|
self._assert_inflect('готовкой риса', ['nomn'], 'готовка риса')
|
||||||
|
|
||||||
|
# self._assert_inflect('реципиенту воздействия', ['nomn'], 'реципиент воздействия')
|
||||||
|
|
||||||
|
def test_inflect_complex_mainword(self):
|
||||||
|
''' Test inflection of mainword conmprised of multiple words. '''
|
||||||
|
# Do not parse complex main words
|
||||||
|
self._assert_inflect('слона и кота', ['nomn'], 'слон и кота')
|
||||||
|
self._assert_inflect('сказал и поехал', ['INFN'], 'сказать и поехал')
|
||||||
|
|
||||||
|
def test_inflect_word_pos(self):
|
||||||
|
''' Test inflection for word changing pars of speech. '''
|
||||||
|
self._assert_inflect('обеспечит', ['INFN'], 'обеспечить')
|
||||||
|
self._assert_inflect('обеспечить', ['VERB', '1per'], 'обеспечу')
|
||||||
|
# self._assert_inflect('обеспечить', ['NOUN', 'sing','nomn'], 'обеспечение')
|
||||||
|
# self._assert_inflect('обеспечить', ['NOUN', 'plur','datv'], 'обеспечениям')
|
||||||
|
# self._assert_inflect('синеть', ['NOUN'], 'синь')
|
||||||
|
# self._assert_inflect('готовить', ['NOUN', 'sing'], 'готовка')
|
||||||
|
# self._assert_inflect('обеспечить', ['ADJF'], '???')
|
||||||
|
# self._assert_inflect('обеспечить', ['ADJS'], '???')
|
||||||
|
# self._assert_inflect('синеть', ['ADJF'], 'синий')
|
||||||
|
# self._assert_inflect('готовить', ['ADJF', 'sing', 'femn'], 'готовая')
|
||||||
|
self._assert_inflect('обеспечить', ['PRTF', 'plur', 'past'], 'обеспечившие')
|
||||||
|
self._assert_inflect('обеспечить', ['PRTS', 'plur'], 'обеспечены')
|
||||||
|
self._assert_inflect('обеспечить', ['GRND', 'past'], 'обеспечив')
|
||||||
|
# self._assert_inflect('обеспечить', ['ADVB'], 'обеспечённо')
|
||||||
|
# self._assert_inflect('обеспечить', ['COMP'], 'обеспеченнее')
|
||||||
|
|
||||||
|
# self._assert_inflect('обеспечение', ['INFN'], 'обеспечить')
|
||||||
|
# self._assert_inflect('обеспечение', ['VERB','1per'], 'обеспечу')
|
||||||
|
self._assert_inflect('обеспечение', ['NOUN', 'plur', 'nomn'], 'обеспечения')
|
||||||
|
self._assert_inflect('обеспечение', ['NOUN', 'plur', 'datv'], 'обеспечениям')
|
||||||
|
# self._assert_inflect('синь', ['ADJF'], 'синий')
|
||||||
|
# self._assert_inflect('обеспечение', ['PRTF', 'plur', 'past'], 'обеспечившие')
|
||||||
|
# self._assert_inflect('обеспечение', ['PRTS', 'plur'], 'обеспечены')
|
||||||
|
# self._assert_inflect('обеспечение', ['GRND', 'past'], 'обеспечив')
|
||||||
|
# self._assert_inflect('обеспечение', ['ADVB'], 'обеспечённо')
|
||||||
|
# self._assert_inflect('обеспечение', ['COMP'], 'обеспеченнее')
|
||||||
|
|
||||||
|
# self._assert_inflect('синий', ['INFN'], 'синеть')
|
||||||
|
# self._assert_inflect('синий', ['VERB','1per'], 'синею')
|
||||||
|
# self._assert_inflect('синий', ['NOUN', 'plur','nomn'], 'синьки')
|
||||||
|
# self._assert_inflect('синий', ['NOUN', 'plur','datv'], 'синькам')
|
||||||
|
self._assert_inflect('синий', ['ADJS'], 'синь')
|
||||||
|
self._assert_inflect('хороший', ['ADJS'], 'хорош')
|
||||||
|
# self._assert_inflect('синий', ['PRTF', 'plur', 'past'], 'синевшие')
|
||||||
|
# self._assert_inflect('синий', ['PRTS', 'plur'], '??')
|
||||||
|
# self._assert_inflect('синий', ['GRND', 'past'], 'синев')
|
||||||
|
# self._assert_inflect('хороший', ['ADVB'], 'хорошо')
|
||||||
|
self._assert_inflect('синий', ['COMP'], 'синее')
|
||||||
|
|
||||||
|
self._assert_inflect('обеспечащий', ['INFN'], 'обеспечить')
|
||||||
|
self._assert_inflect('обеспечивающий', ['INFN'], 'обеспечивать')
|
||||||
|
self._assert_inflect('бегущий', ['INFN'], 'бежать')
|
||||||
|
self._assert_inflect('бегущий', ['VERB'], 'бегу')
|
||||||
|
self._assert_inflect('бежавшего', ['VERB'], 'бежал')
|
||||||
|
# self._assert_inflect('обеспечащий', ['NOUN', 'plur','datv'], 'обеспечениям')
|
||||||
|
# self._assert_inflect('синеющий', ['NOUN'], 'синь')
|
||||||
|
# self._assert_inflect('готовящий', ['NOUN', 'sing'], 'готовка')
|
||||||
|
# self._assert_inflect('синеющий', ['ADJF'], 'синий')
|
||||||
|
self._assert_inflect('обеспечащий', ['PRTF', 'plur', 'past'], 'обеспечившие')
|
||||||
|
self._assert_inflect('обеспечащий', ['PRTS', 'plur'], 'обеспечимы')
|
||||||
|
self._assert_inflect('обеспечащий', ['GRND', 'past'], 'обеспечив')
|
||||||
|
# self._assert_inflect('обеспечащий', ['ADVB'], 'обеспечённо')
|
||||||
|
# self._assert_inflect('обеспечащий', ['COMP'], 'обеспеченнее')
|
||||||
|
|
||||||
|
def test_inflect_text_pos(self):
|
||||||
|
''' Test inflection for multiword text changing parts of speech. '''
|
||||||
|
# self._assert_inflect('готовить еду', ['NOUN', 'sing'], 'готовка еды')
|
||||||
|
# self._assert_inflect('обеспечение безопасности', ['INFN'], 'обеспечить безопасность')
|
||||||
|
# self._assert_inflect('сильный удар по мячу', ['INFN'], 'сильно ударить по мячу')
|
||||||
|
self._assert_inflect('сильно обиженный', ['INFN'], 'сильно обидеть')
|
||||||
|
# self._assert_inflect('сильно обиженный', ['NOUN'], 'сильная обида')
|
||||||
|
# self._assert_inflect('надежно обеспечить', ['NOUN'], 'надежное обеспечение')
|
||||||
|
|
||||||
|
def test_inflect_invalid_text(self):
|
||||||
|
''' Test inflection for multiword not coordinated text. '''
|
||||||
|
self._assert_inflect('синими слоны', ['nomn', 'sing'], 'синими слон')
|
||||||
|
|
||||||
|
def test_inflect_context(self):
|
||||||
|
''' Test content inflection. '''
|
||||||
|
self.assertEqual(parser.inflect_context('', '', ''), '')
|
||||||
|
self.assertEqual(parser.inflect_context('', 'красивый', ''), '')
|
||||||
|
self.assertEqual(parser.inflect_context('', '', 'в'), '')
|
||||||
|
self.assertEqual(parser.inflect_context('слон', '', ''), 'слон')
|
||||||
|
|
||||||
|
self.assertEqual(parser.inflect_context('красивый', '', 'чашка'), 'красивая')
|
||||||
|
self.assertEqual(parser.inflect_context('красивый', '', 'черного'), 'красивого')
|
||||||
|
self.assertEqual(parser.inflect_context('слон', '', 'черного'), 'слона')
|
||||||
|
self.assertEqual(parser.inflect_context('слоны', 'сильный', 'черную'), 'слон')
|
||||||
|
self.assertEqual(parser.inflect_context('город', 'огня', ''), 'города')
|
||||||
|
# self.assertEqual(parser.inflect_context('улица', 'дом', ''), 'улицы')
|
||||||
|
|
||||||
|
self.assertEqual(parser.inflect_context('большой город', 'стильного', 'необъятной страны'), 'большого города')
|
||||||
|
self.assertEqual(parser.inflect_context('город', '', ', расположенного неподалеку'), 'города')
|
||||||
|
|
||||||
|
def test_inflect_substitute(self):
|
||||||
|
''' Test substitute inflection. '''
|
||||||
|
self.assertEqual(parser.inflect_substitute('', ''), '')
|
||||||
|
self.assertEqual(parser.inflect_substitute('123', '123'), '123')
|
||||||
|
self.assertEqual(parser.inflect_substitute('', 'слон'), '')
|
||||||
|
self.assertEqual(parser.inflect_substitute('слон', ''), 'слон')
|
||||||
|
self.assertEqual(parser.inflect_substitute('слон', 'слон'), 'слон')
|
||||||
|
self.assertEqual(parser.inflect_substitute('слон', 'слоны'), 'слоны')
|
||||||
|
self.assertEqual(parser.inflect_substitute('слон', 'кошкой'), 'слоном')
|
||||||
|
self.assertEqual(parser.inflect_substitute('синий слон', 'стильного чайника'), 'синего слона')
|
||||||
|
self.assertEqual(parser.inflect_substitute('варить клюкву', 'осуществляет'), 'варит клюкву')
|
||||||
|
|
||||||
|
def test_inflect_dependant(self):
|
||||||
|
''' Test coordination inflection. '''
|
||||||
|
self.assertEqual(parser.inflect_dependant('', ''), '')
|
||||||
|
self.assertEqual(parser.inflect_dependant('', 'слон'), '')
|
||||||
|
self.assertEqual(parser.inflect_dependant('слон', ''), 'слон')
|
||||||
|
self.assertEqual(parser.inflect_dependant('общий', 'мать'), 'общая')
|
||||||
|
self.assertEqual(parser.inflect_dependant('синий', 'слонов'), 'синих')
|
||||||
|
self.assertEqual(parser.inflect_dependant('белый длинный', 'столами'), 'белыми длинными')
|
||||||
|
|
||||||
|
def test_find_substr(self):
|
||||||
|
''' Test substring search. '''
|
||||||
|
self.assertEqual(parser.find_substr('', ''), (0, 0))
|
||||||
|
self.assertEqual(parser.find_substr('слон', ''), (0, 0))
|
||||||
|
self.assertEqual(parser.find_substr('', 'слон'), (0, 0))
|
||||||
|
self.assertEqual(parser.find_substr('слон', 'слон'), (0, 4))
|
||||||
|
self.assertEqual(parser.find_substr('сложного слона', 'слон'), (9, 14))
|
||||||
|
self.assertEqual(parser.find_substr('сложного слона', 'слоном'), (9, 14))
|
||||||
|
self.assertEqual(parser.find_substr('сложного красивого слона', 'красивые слоном'), (9, 24))
|
||||||
|
self.assertEqual(parser.find_substr('человек', 'люди'), (0, 7))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
62
rsconcept/backend/cctext/tests/testSyntax.py
Normal file
62
rsconcept/backend/cctext/tests/testSyntax.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
'''Test module for Russian syntax'''
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cctext import RuSyntax, Capitalization
|
||||||
|
|
||||||
|
|
||||||
|
class TestRusParser(unittest.TestCase):
|
||||||
|
''' Test class for russian syntax. '''
|
||||||
|
|
||||||
|
def test_capitalization(self):
|
||||||
|
''' Testing capitalization. '''
|
||||||
|
self.assertEqual(Capitalization.from_text(''), Capitalization.unknwn)
|
||||||
|
self.assertEqual(Capitalization.from_text('Альфа'), Capitalization.first_capital)
|
||||||
|
self.assertEqual(Capitalization.from_text('АЛЬФА'), Capitalization.upper_case)
|
||||||
|
self.assertEqual(Capitalization.from_text('альфа'), Capitalization.lower_case)
|
||||||
|
self.assertEqual(Capitalization.from_text('альФа'), Capitalization.mixed)
|
||||||
|
self.assertEqual(Capitalization.from_text('альфА'), Capitalization.mixed)
|
||||||
|
self.assertEqual(Capitalization.from_text('КАиП'), Capitalization.mixed)
|
||||||
|
|
||||||
|
self.assertEqual(Capitalization.upper_case.apply_to('альфа'), 'АЛЬФА')
|
||||||
|
self.assertEqual(Capitalization.lower_case.apply_to('АльФа'), 'альфа')
|
||||||
|
self.assertEqual(Capitalization.first_capital.apply_to('альфа'), 'Альфа')
|
||||||
|
self.assertEqual(Capitalization.first_capital.apply_to('АльФа'), 'АльФа')
|
||||||
|
self.assertEqual(Capitalization.unknwn.apply_to('АльФа'), 'АльФа')
|
||||||
|
self.assertEqual(Capitalization.mixed.apply_to('АльФа'), 'АльФа')
|
||||||
|
|
||||||
|
def test_is_single_word(self):
|
||||||
|
''' Testing single word identification. '''
|
||||||
|
self.assertTrue(RuSyntax.is_single_word(''))
|
||||||
|
self.assertTrue(RuSyntax.is_single_word('word'))
|
||||||
|
self.assertTrue(RuSyntax.is_single_word('слово'))
|
||||||
|
self.assertTrue(RuSyntax.is_single_word(' word '), 'Whitespace doesnt count')
|
||||||
|
self.assertTrue(RuSyntax.is_single_word('1001'), 'Numbers are words')
|
||||||
|
self.assertTrue(RuSyntax.is_single_word('кое-как'), 'Hyphen doesnt break work')
|
||||||
|
self.assertTrue(RuSyntax.is_single_word('1-2-метилбутан'), 'Complex words')
|
||||||
|
self.assertFalse(RuSyntax.is_single_word('one two'))
|
||||||
|
self.assertFalse(RuSyntax.is_single_word('синий слон'))
|
||||||
|
|
||||||
|
def test_tokenize(self):
|
||||||
|
''' Testing tokenization. '''
|
||||||
|
self.assertEqual(list(RuSyntax.tokenize('')), [])
|
||||||
|
self.assertEqual(list(RuSyntax.tokenize(' ')), [])
|
||||||
|
self.assertEqual(self._list_tokenize('test'), [(0, 4, 'test')])
|
||||||
|
self.assertEqual(self._list_tokenize(' test '), [(1, 5, 'test')])
|
||||||
|
self.assertEqual(self._list_tokenize('синий слон'), [(0, 5, 'синий'), (6, 10, 'слон')])
|
||||||
|
|
||||||
|
def test_split_words(self):
|
||||||
|
''' Testing splitting text into words. '''
|
||||||
|
self.assertEqual([], list(RuSyntax.split_words('')))
|
||||||
|
self.assertEqual([], list(RuSyntax.split_words(' ')))
|
||||||
|
self.assertEqual(RuSyntax.split_words('test'), ['test'])
|
||||||
|
self.assertEqual(RuSyntax.split_words(' test '), ['test'])
|
||||||
|
self.assertEqual(RuSyntax.split_words('синий слон'), ['синий', 'слон'])
|
||||||
|
self.assertEqual(RuSyntax.split_words('синий, большой слон'), ['синий', ',', 'большой', 'слон'])
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _list_tokenize(text: str):
|
||||||
|
return [(token.start, token.stop, token.text) for token in RuSyntax.tokenize(text)]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
|
@ -5,4 +5,8 @@ django-cors-headers
|
||||||
django-filter
|
django-filter
|
||||||
psycopg2-binary
|
psycopg2-binary
|
||||||
gunicorn
|
gunicorn
|
||||||
coreapi
|
coreapi
|
||||||
|
pymorphy2
|
||||||
|
pymorphy2-dicts-ru
|
||||||
|
pymorphy2-dicts-uk
|
||||||
|
razdel
|
|
@ -4,4 +4,8 @@ djangorestframework
|
||||||
django-cors-headers
|
django-cors-headers
|
||||||
django-filter
|
django-filter
|
||||||
coverage
|
coverage
|
||||||
coreapi
|
coreapi
|
||||||
|
pymorphy2
|
||||||
|
pymorphy2-dicts-ru
|
||||||
|
pymorphy2-dicts-uk
|
||||||
|
razdel
|
Loading…
Reference in New Issue
Block a user