mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-08-14 04:40:36 +03:00
65 lines
2.4 KiB
Python
65 lines
2.4 KiB
Python
''' Models: RSForm order manager. '''
|
|
|
|
from .Constituenta import Constituenta, CstType
|
|
from .RSFormCached import RSFormCached
|
|
from .SemanticInfo import SemanticInfo
|
|
|
|
|
|
class OrderManager:
|
|
''' Ordering helper class '''
|
|
|
|
def __init__(self, schema: RSFormCached):
|
|
self._semantic = SemanticInfo(schema)
|
|
self._items = schema.cache.constituents
|
|
self._cst_by_ID = schema.cache.by_id
|
|
|
|
def restore_order(self) -> None:
|
|
''' Implement order restoration process. '''
|
|
if len(self._items) <= 1:
|
|
return
|
|
self._fix_kernel()
|
|
self._fix_topological()
|
|
self._fix_semantic_children()
|
|
self._override_order()
|
|
|
|
def _fix_topological(self) -> None:
|
|
sorted_ids = self._semantic.graph.sort_stable([cst.pk for cst in self._items])
|
|
sorted_items = [next(cst for cst in self._items if cst.pk == id) for id in sorted_ids]
|
|
self._items = sorted_items
|
|
|
|
def _fix_kernel(self) -> None:
|
|
result = [cst for cst in self._items if cst.cst_type == CstType.BASE]
|
|
result = result + [cst for cst in self._items if cst.cst_type == CstType.CONSTANT]
|
|
kernel = [
|
|
cst.pk for cst in self._items if
|
|
cst.cst_type in [CstType.STRUCTURED, CstType.AXIOM] or
|
|
self._cst_by_ID[self._semantic.parent(cst.pk)].cst_type == CstType.STRUCTURED
|
|
]
|
|
kernel = kernel + self._semantic.graph.expand_inputs(kernel)
|
|
result = result + [cst for cst in self._items if result.count(cst) == 0 and cst.pk in kernel]
|
|
result = result + [cst for cst in self._items if result.count(cst) == 0]
|
|
self._items = result
|
|
|
|
def _fix_semantic_children(self) -> None:
|
|
result: list[Constituenta] = []
|
|
marked: set[Constituenta] = set()
|
|
for cst in self._items:
|
|
if cst in marked:
|
|
continue
|
|
result.append(cst)
|
|
children = self._semantic[cst.pk]['children']
|
|
if len(children) == 0:
|
|
continue
|
|
for child in self._items:
|
|
if child.pk in children:
|
|
marked.add(child)
|
|
result.append(child)
|
|
self._items = result
|
|
|
|
def _override_order(self) -> None:
|
|
order = 0
|
|
for cst in self._items:
|
|
cst.order = order
|
|
order += 1
|
|
Constituenta.objects.bulk_update(self._items, ['order'])
|