Portal/rsconcept/backend/apps/rsform/models/Constituenta.py
Ivan a9edf842d8
Some checks failed
Frontend CI / build (22.x) (push) Waiting to run
Backend CI / build (3.12) (push) Has been cancelled
M: Propagate cst_update
2024-08-10 11:46:08 +03:00

147 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

''' Models: Constituenta. '''
import re
from cctext import extract_entities
from django.core.validators import MinValueValidator
from django.db.models import (
CASCADE,
CharField,
ForeignKey,
JSONField,
Model,
PositiveIntegerField,
TextChoices,
TextField
)
from ..utils import apply_pattern
_RE_GLOBALS = r'[XCSADFPT]\d+' # cspell:disable-line
_REF_ENTITY_PATTERN = re.compile(r'@{([^0-9\-].*?)\|.*?}')
_GLOBAL_ID_PATTERN = re.compile(r'([XCSADFPT][0-9]+)') # cspell:disable-line
def extract_globals(expression: str) -> set[str]:
''' Extract all global aliases from expression. '''
return set(re.findall(_RE_GLOBALS, expression))
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)
class CstType(TextChoices):
''' Type of constituenta. '''
BASE = 'basic'
CONSTANT = 'constant'
STRUCTURED = 'structure'
AXIOM = 'axiom'
TERM = 'term'
FUNCTION = 'function'
PREDICATE = 'predicate'
THEOREM = 'theorem'
class Constituenta(Model):
''' Constituenta is the base unit for every conceptual schema. '''
schema: ForeignKey = ForeignKey(
verbose_name='Концептуальная схема',
to='library.LibraryItem',
on_delete=CASCADE
)
order: PositiveIntegerField = PositiveIntegerField(
verbose_name='Позиция',
validators=[MinValueValidator(1)],
default=-1,
)
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='Словоформы',
default=list
)
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 = []
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]
expression = replace_globals(self.definition_formal, mapping)
if expression != self.definition_formal:
modified = True
self.definition_formal = expression
term = replace_entities(self.term_raw, mapping)
if term != self.term_raw:
modified = True
self.term_raw = term
definition = replace_entities(self.definition_raw, mapping)
if definition != self.definition_raw:
modified = True
self.definition_raw = definition
return modified
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