2024-03-11 18:08:28 +03:00
|
|
|
|
''' Models: Constituenta. '''
|
2024-03-12 20:11:11 +03:00
|
|
|
|
import re
|
|
|
|
|
|
2024-08-09 20:58:28 +03:00
|
|
|
|
from cctext import extract_entities
|
2024-05-24 18:31:14 +03:00
|
|
|
|
from django.core.validators import MinValueValidator
|
2024-03-11 18:08:28 +03:00
|
|
|
|
from django.db.models import (
|
2024-05-24 18:31:14 +03:00
|
|
|
|
CASCADE,
|
|
|
|
|
CharField,
|
|
|
|
|
ForeignKey,
|
|
|
|
|
JSONField,
|
|
|
|
|
Model,
|
|
|
|
|
PositiveIntegerField,
|
|
|
|
|
TextChoices,
|
|
|
|
|
TextField
|
2024-03-11 18:08:28 +03:00
|
|
|
|
)
|
|
|
|
|
|
2024-03-12 20:11:11 +03:00
|
|
|
|
from ..utils import apply_pattern
|
|
|
|
|
|
2024-08-09 20:58:28 +03:00
|
|
|
|
_RE_GLOBALS = r'[XCSADFPT]\d+' # cspell:disable-line
|
2024-03-12 20:11:11 +03:00
|
|
|
|
_REF_ENTITY_PATTERN = re.compile(r'@{([^0-9\-].*?)\|.*?}')
|
2024-05-24 19:06:39 +03:00
|
|
|
|
_GLOBAL_ID_PATTERN = re.compile(r'([XCSADFPT][0-9]+)') # cspell:disable-line
|
2024-03-12 20:11:11 +03:00
|
|
|
|
|
2024-03-11 18:08:28 +03:00
|
|
|
|
|
2024-08-09 20:58:28 +03:00
|
|
|
|
def extract_globals(expression: str) -> set[str]:
|
|
|
|
|
''' Extract all global aliases from expression. '''
|
|
|
|
|
return set(re.findall(_RE_GLOBALS, expression))
|
|
|
|
|
|
|
|
|
|
|
2024-08-10 11:41:52 +03:00
|
|
|
|
def replace_globals(expression: str, mapping: dict[str, str]) -> str:
|
|
|
|
|
''' Replace all global aliases in expression. '''
|
|
|
|
|
return apply_pattern(expression, mapping, _GLOBAL_ID_PATTERN)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def replace_entities(expression: str, mapping: dict[str, str]) -> str:
|
|
|
|
|
''' Replace all entity references in expression. '''
|
|
|
|
|
return apply_pattern(expression, mapping, _REF_ENTITY_PATTERN)
|
|
|
|
|
|
|
|
|
|
|
2024-04-26 00:38:22 +03:00
|
|
|
|
class CstType(TextChoices):
|
|
|
|
|
''' Type of constituenta. '''
|
|
|
|
|
BASE = 'basic'
|
|
|
|
|
CONSTANT = 'constant'
|
|
|
|
|
STRUCTURED = 'structure'
|
|
|
|
|
AXIOM = 'axiom'
|
|
|
|
|
TERM = 'term'
|
|
|
|
|
FUNCTION = 'function'
|
|
|
|
|
PREDICATE = 'predicate'
|
|
|
|
|
THEOREM = 'theorem'
|
|
|
|
|
|
|
|
|
|
|
2024-03-11 18:08:28 +03:00
|
|
|
|
class Constituenta(Model):
|
2024-04-26 00:38:22 +03:00
|
|
|
|
''' Constituenta is the base unit for every conceptual schema. '''
|
2024-03-11 18:08:28 +03:00
|
|
|
|
schema: ForeignKey = ForeignKey(
|
|
|
|
|
verbose_name='Концептуальная схема',
|
2024-07-25 19:12:59 +03:00
|
|
|
|
to='library.LibraryItem',
|
2024-03-11 18:08:28 +03:00
|
|
|
|
on_delete=CASCADE
|
|
|
|
|
)
|
|
|
|
|
order: PositiveIntegerField = PositiveIntegerField(
|
|
|
|
|
verbose_name='Позиция',
|
|
|
|
|
validators=[MinValueValidator(1)],
|
2024-09-04 14:35:17 +03:00
|
|
|
|
default=1,
|
2024-03-11 18:08:28 +03:00
|
|
|
|
)
|
|
|
|
|
alias: CharField = CharField(
|
|
|
|
|
verbose_name='Имя',
|
|
|
|
|
max_length=8,
|
|
|
|
|
default='undefined'
|
|
|
|
|
)
|
|
|
|
|
cst_type: CharField = CharField(
|
|
|
|
|
verbose_name='Тип',
|
|
|
|
|
max_length=10,
|
|
|
|
|
choices=CstType.choices,
|
|
|
|
|
default=CstType.BASE
|
|
|
|
|
)
|
|
|
|
|
convention: TextField = TextField(
|
|
|
|
|
verbose_name='Комментарий/Конвенция',
|
|
|
|
|
default='',
|
|
|
|
|
blank=True
|
|
|
|
|
)
|
|
|
|
|
term_raw: TextField = TextField(
|
|
|
|
|
verbose_name='Термин (с отсылками)',
|
|
|
|
|
default='',
|
|
|
|
|
blank=True
|
|
|
|
|
)
|
|
|
|
|
term_resolved: TextField = TextField(
|
|
|
|
|
verbose_name='Термин',
|
|
|
|
|
default='',
|
|
|
|
|
blank=True
|
|
|
|
|
)
|
|
|
|
|
term_forms: JSONField = JSONField(
|
|
|
|
|
verbose_name='Словоформы',
|
2024-07-25 19:12:59 +03:00
|
|
|
|
default=list
|
2024-03-11 18:08:28 +03:00
|
|
|
|
)
|
|
|
|
|
definition_formal: TextField = TextField(
|
|
|
|
|
verbose_name='Родоструктурное определение',
|
|
|
|
|
default='',
|
|
|
|
|
blank=True
|
|
|
|
|
)
|
|
|
|
|
definition_raw: TextField = TextField(
|
|
|
|
|
verbose_name='Текстовое определение (с отсылками)',
|
|
|
|
|
default='',
|
|
|
|
|
blank=True
|
|
|
|
|
)
|
|
|
|
|
definition_resolved: TextField = TextField(
|
|
|
|
|
verbose_name='Текстовое определение',
|
|
|
|
|
default='',
|
|
|
|
|
blank=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
''' Model metadata. '''
|
|
|
|
|
verbose_name = 'Конституента'
|
|
|
|
|
verbose_name_plural = 'Конституенты'
|
|
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
|
return f'{self.alias}'
|
|
|
|
|
|
|
|
|
|
def set_term_resolved(self, new_term: str):
|
|
|
|
|
''' Set term and reset forms if needed. '''
|
|
|
|
|
self.term_resolved = new_term
|
|
|
|
|
self.term_forms = []
|
2024-03-12 20:11:11 +03:00
|
|
|
|
|
|
|
|
|
def apply_mapping(self, mapping: dict[str, str], change_aliases: bool = False):
|
|
|
|
|
modified = False
|
|
|
|
|
if change_aliases and self.alias in mapping:
|
|
|
|
|
modified = True
|
|
|
|
|
self.alias = mapping[self.alias]
|
2024-08-10 11:41:52 +03:00
|
|
|
|
expression = replace_globals(self.definition_formal, mapping)
|
2024-03-12 20:11:11 +03:00
|
|
|
|
if expression != self.definition_formal:
|
|
|
|
|
modified = True
|
|
|
|
|
self.definition_formal = expression
|
2024-08-10 11:41:52 +03:00
|
|
|
|
term = replace_entities(self.term_raw, mapping)
|
2024-03-12 20:11:11 +03:00
|
|
|
|
if term != self.term_raw:
|
|
|
|
|
modified = True
|
|
|
|
|
self.term_raw = term
|
2024-08-10 11:41:52 +03:00
|
|
|
|
definition = replace_entities(self.definition_raw, mapping)
|
2024-03-12 20:11:11 +03:00
|
|
|
|
if definition != self.definition_raw:
|
|
|
|
|
modified = True
|
|
|
|
|
self.definition_raw = definition
|
|
|
|
|
return modified
|
2024-08-09 20:58:28 +03:00
|
|
|
|
|
|
|
|
|
def extract_references(self) -> set[str]:
|
|
|
|
|
''' Extract all references from term and definition. '''
|
|
|
|
|
result: set[str] = extract_globals(self.definition_formal)
|
|
|
|
|
result.update(extract_entities(self.term_raw))
|
|
|
|
|
result.update(extract_entities(self.definition_raw))
|
|
|
|
|
return result
|