Compare commits
5 Commits
31195cdd60
...
0149f98c8b
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0149f98c8b | ||
![]() |
d33f3e02b4 | ||
![]() |
3555db3edf | ||
![]() |
fc669b8b3a | ||
![]() |
495493bbbb |
|
@ -58,7 +58,6 @@ class TestChangeAttributes(EndpointTester):
|
||||||
self.operation3.refresh_from_db()
|
self.operation3.refresh_from_db()
|
||||||
self.ks3 = RSForm(self.operation3.result)
|
self.ks3 = RSForm(self.operation3.result)
|
||||||
|
|
||||||
|
|
||||||
@decl_endpoint('/api/library/{item}/set-owner', method='patch')
|
@decl_endpoint('/api/library/{item}/set-owner', method='patch')
|
||||||
def test_set_owner(self):
|
def test_set_owner(self):
|
||||||
data = {'user': self.user3.pk}
|
data = {'user': self.user3.pk}
|
||||||
|
|
|
@ -57,6 +57,33 @@ class TestChangeConstituents(EndpointTester):
|
||||||
self.ks3 = RSForm(self.operation3.result)
|
self.ks3 = RSForm(self.operation3.result)
|
||||||
self.assertEqual(self.ks3.constituents().count(), 4)
|
self.assertEqual(self.ks3.constituents().count(), 4)
|
||||||
|
|
||||||
|
@decl_endpoint('/api/rsforms/{item}/details', method='get')
|
||||||
|
def test_retrieve_inheritance(self):
|
||||||
|
response = self.executeOK(item=self.ks3.model.pk)
|
||||||
|
self.assertEqual(response.data['oss'], [{'id': self.owned.model.pk, 'alias': 'T1'}])
|
||||||
|
self.assertEqual(response.data['inheritance'], [
|
||||||
|
{
|
||||||
|
'child': Constituenta.objects.get(as_child__parent_id=self.ks1X1.pk).pk,
|
||||||
|
'child_source': self.ks3.model.pk,
|
||||||
|
'parent': self.ks1X1.pk, 'parent_source': self.ks1.model.pk
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'child': Constituenta.objects.get(as_child__parent_id=self.ks1X2.pk).pk,
|
||||||
|
'child_source': self.ks3.model.pk,
|
||||||
|
'parent': self.ks1X2.pk, 'parent_source': self.ks1.model.pk
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'child': Constituenta.objects.get(as_child__parent_id=self.ks2X1.pk).pk,
|
||||||
|
'child_source': self.ks3.model.pk,
|
||||||
|
'parent': self.ks2X1.pk, 'parent_source': self.ks2.model.pk
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'child': Constituenta.objects.get(as_child__parent_id=self.ks2D1.pk).pk,
|
||||||
|
'child_source': self.ks3.model.pk,
|
||||||
|
'parent': self.ks2D1.pk, 'parent_source': self.ks2.model.pk
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
@decl_endpoint('/api/rsforms/{schema}/create-cst', method='post')
|
@decl_endpoint('/api/rsforms/{schema}/create-cst', method='post')
|
||||||
def test_create_constituenta(self):
|
def test_create_constituenta(self):
|
||||||
data = {
|
data = {
|
||||||
|
|
|
@ -4,6 +4,7 @@ from .basics import (
|
||||||
ASTNodeSerializer,
|
ASTNodeSerializer,
|
||||||
ExpressionParseSerializer,
|
ExpressionParseSerializer,
|
||||||
ExpressionSerializer,
|
ExpressionSerializer,
|
||||||
|
InheritanceDataSerializer,
|
||||||
MultiFormSerializer,
|
MultiFormSerializer,
|
||||||
ResolverSerializer,
|
ResolverSerializer,
|
||||||
TextSerializer,
|
TextSerializer,
|
||||||
|
|
|
@ -122,6 +122,14 @@ class ReferenceSerializer(serializers.Serializer):
|
||||||
pos_output = TextPositionSerializer()
|
pos_output = TextPositionSerializer()
|
||||||
|
|
||||||
|
|
||||||
|
class InheritanceDataSerializer(serializers.Serializer):
|
||||||
|
''' Serializer: inheritance data. '''
|
||||||
|
child = serializers.IntegerField()
|
||||||
|
child_source = serializers.IntegerField()
|
||||||
|
parent = serializers.IntegerField() # type: ignore
|
||||||
|
parent_source = serializers.IntegerField()
|
||||||
|
|
||||||
|
|
||||||
class ResolverSerializer(serializers.Serializer):
|
class ResolverSerializer(serializers.Serializer):
|
||||||
''' Serializer: Resolver results serializer. '''
|
''' Serializer: Resolver results serializer. '''
|
||||||
input = serializers.CharField()
|
input = serializers.CharField()
|
||||||
|
|
|
@ -17,7 +17,7 @@ from apps.oss.models import Inheritance
|
||||||
from shared import messages as msg
|
from shared import messages as msg
|
||||||
|
|
||||||
from ..models import Constituenta, CstType, RSForm
|
from ..models import Constituenta, CstType, RSForm
|
||||||
from .basics import CstParseSerializer
|
from .basics import CstParseSerializer, InheritanceDataSerializer
|
||||||
from .io_pyconcept import PyConceptAdapter
|
from .io_pyconcept import PyConceptAdapter
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class RSFormSerializer(serializers.ModelSerializer):
|
||||||
child=CstSerializer()
|
child=CstSerializer()
|
||||||
)
|
)
|
||||||
inheritance = serializers.ListField(
|
inheritance = serializers.ListField(
|
||||||
child=serializers.ListField(child=serializers.IntegerField())
|
child=InheritanceDataSerializer()
|
||||||
)
|
)
|
||||||
oss = serializers.ListField(
|
oss = serializers.ListField(
|
||||||
child=LibraryItemReferenceSerializer()
|
child=LibraryItemReferenceSerializer()
|
||||||
|
@ -116,8 +116,17 @@ class RSFormSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
def to_representation(self, instance: LibraryItem) -> dict:
|
def to_representation(self, instance: LibraryItem) -> dict:
|
||||||
result = self.to_base_data(instance)
|
result = self.to_base_data(instance)
|
||||||
for link in Inheritance.objects.filter(Q(child__schema=instance) | Q(parent__schema=instance)):
|
inheritances = Inheritance.objects \
|
||||||
result['inheritance'].append([link.child.pk, link.parent.pk])
|
.filter(Q(child__schema=instance) | Q(parent__schema=instance)) \
|
||||||
|
.select_related('parent__schema', 'child__schema') \
|
||||||
|
.only('parent__id', 'parent__schema__id', 'child__id', 'child__schema__id')
|
||||||
|
for link in inheritances:
|
||||||
|
result['inheritance'].append({
|
||||||
|
'child': link.child_id,
|
||||||
|
'child_source': link.child.schema_id,
|
||||||
|
'parent': link.parent_id,
|
||||||
|
'parent_source': link.parent.schema_id
|
||||||
|
})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def to_base_data(self, instance: LibraryItem) -> dict:
|
def to_base_data(self, instance: LibraryItem) -> dict:
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { styleTags, tags } from '@lezer/highlight';
|
import { styleTags, tags } from '@lezer/highlight';
|
||||||
|
|
||||||
export const highlighting = styleTags({
|
export const highlighting = styleTags({
|
||||||
'Index': tags.unit,
|
|
||||||
'ComplexIndex': tags.unit,
|
'ComplexIndex': tags.unit,
|
||||||
'Literal': tags.literal,
|
'Literal': tags.literal,
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,14 @@
|
||||||
export const
|
export const
|
||||||
Expression = 1,
|
Expression = 1,
|
||||||
Local = 2,
|
Local = 2,
|
||||||
Index = 3,
|
Literal = 4,
|
||||||
Literal = 5,
|
Global = 5,
|
||||||
Global = 6,
|
Radical = 6,
|
||||||
Radical = 7,
|
Filter = 19,
|
||||||
Filter = 20,
|
ComplexIndex = 20,
|
||||||
ComplexIndex = 21,
|
PrefixD = 25,
|
||||||
PrefixD = 26,
|
PrefixI = 26,
|
||||||
PrefixI = 27,
|
PrefixR = 28,
|
||||||
PrefixR = 29,
|
Function = 30,
|
||||||
Function = 31,
|
TextFunction = 31,
|
||||||
TextFunction = 32,
|
Predicate = 44
|
||||||
Predicate = 45
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { printTree } from '@/utils/codemirror';
|
||||||
import { parser } from './parser';
|
import { parser } from './parser';
|
||||||
|
|
||||||
const testData = [
|
const testData = [
|
||||||
['a1', '[Expression[Local[Index]]]'],
|
['a1', '[Expression[Local]]'],
|
||||||
['A1', '[Expression[Global]]'],
|
['A1', '[Expression[Global]]'],
|
||||||
['∅', '[Expression[Literal]]'],
|
['∅', '[Expression[Literal]]'],
|
||||||
['Z', '[Expression[Literal]]'],
|
['Z', '[Expression[Literal]]'],
|
||||||
|
@ -15,7 +15,7 @@ const testData = [
|
||||||
['¬2=2', '[Expression[¬][Literal][=][Literal]]'],
|
['¬2=2', '[Expression[¬][Literal][=][Literal]]'],
|
||||||
['12+41', '[Expression[Literal][+][Literal]]'],
|
['12+41', '[Expression[Literal][+][Literal]]'],
|
||||||
['1+2*5', '[Expression[Literal][+][Literal][*][Literal]]'],
|
['1+2*5', '[Expression[Literal][+][Literal][*][Literal]]'],
|
||||||
['a1∪Z', '[Expression[Local[Index]][∪][Literal]]'],
|
['a1∪Z', '[Expression[Local][∪][Literal]]'],
|
||||||
['Pr1(X1)', '[Expression[TextFunction[ComplexIndex]][(][Global][)]]'],
|
['Pr1(X1)', '[Expression[TextFunction[ComplexIndex]][(][Global][)]]'],
|
||||||
['Pr11(X1)', '[Expression[TextFunction[ComplexIndex]][(][Global][)]]'],
|
['Pr11(X1)', '[Expression[TextFunction[ComplexIndex]][(][Global][)]]'],
|
||||||
['Pr11,21(X1)', '[Expression[TextFunction[ComplexIndex]][(][Global][)]]'],
|
['Pr11,21(X1)', '[Expression[TextFunction[ComplexIndex]][(][Global][)]]'],
|
||||||
|
@ -41,8 +41,9 @@ const testData = [
|
||||||
['∀ξ∈∅ 1=1', '[Expression[∀][Local][∈][Literal][Literal][=][Literal]]'],
|
['∀ξ∈∅ 1=1', '[Expression[∀][Local][∈][Literal][Literal][=][Literal]]'],
|
||||||
[
|
[
|
||||||
'∀ξ1∈β (ξ1≠∅ & ∀ξ2∈β ξ1∩ξ2=∅)',
|
'∀ξ1∈β (ξ1≠∅ & ∀ξ2∈β ξ1∩ξ2=∅)',
|
||||||
'[Expression[∀][Local[Index]][∈][Local][(][Local[Index]][≠][Literal][&][∀][Local[Index]][∈][Local][Local[Index]][∩][Local[Index]][=][Literal][)]]'
|
'[Expression[∀][Local][∈][Local][(][Local][≠][Literal][&][∀][Local][∈][Local][Local][∩][Local][=][Literal][)]]'
|
||||||
]
|
],
|
||||||
|
['∀α1∈α2 1=1', '[Expression[∀][Local][∈][Local][Literal][=][Literal]]']
|
||||||
];
|
];
|
||||||
|
|
||||||
describe('Testing RSParser', () => {
|
describe('Testing RSParser', () => {
|
||||||
|
|
|
@ -3,16 +3,16 @@ import {LRParser} from "@lezer/lr"
|
||||||
import {highlighting} from "./highlight"
|
import {highlighting} from "./highlight"
|
||||||
export const parser = LRParser.deserialize({
|
export const parser = LRParser.deserialize({
|
||||||
version: 14,
|
version: 14,
|
||||||
states: "5lO!sQPOOO!zQPO'#C^OOQO'#Ca'#CaO%uQPO'#DqOOQO'#Dq'#DqO(SQPO'#DeOVQPO'#DrO(ZQPO'#DtO)kQPO'#DuO)sQQO'#DvO)xQPO'#DwO)}QPO'#DxO*SQPO'#DzOOQO'#Ds'#DsO*XQPO'#DsO+uQQO'#C|OOQO'#C|'#C|OOQO'#Dn'#DnO+zQPO'#DnO,PQPO'#DnO,UQPO'#DgOVQPO'#ESO,^QPO'#ESO,cQPO'#ESO,kQPO'#DeOOQO'#Df'#DfO,fQPO'#EVQOQPOOOOQO'#C_'#C_OOQO,58x,58xO(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:^O(ZQPO,5:RO,|QPO'#DmO-TQPO,5:^O.hQPO,5:VO.pQPO'#DlO.uQPO,5:QO/WQPO,5:cO/yQPO'#DmO(ZQPO'#DrO0WQPO,5:`OOQO'#Dm'#DmO(ZQPO,5:aOOQO,5:a,5:aO0`QPO,5:bO,cQPO,5:cO(ZQPO,5:dO,cQPO,5:fOOQO,59h,59hO(ZQPO,5:YO(ZQPO,5:YO&uQPO'#DgOOQO,5:n,5:nO(ZQPO,5:nO(ZQPO'#DkOOQO'#Dh'#DhOOQO'#ET'#ETO0eQPO,5:nOVQPO,5:pOVQPO,5:pOVQPO,5:pOVQPO,5:pO0mQPO'#EXOOQO'#EW'#EWO0rQPO,5:qOOQO1G/x1G/xO2wQPO1G/xO3OQPO1G/xO5SQPO1G/xO7WQPO1G/xO7_QPO1G/xO7fQPO1G/xO8OQPO1G/xO9qQPO1G/mOOQO1G/q1G/qO(ZQPO,5:WOOQO1G/l1G/lO(ZQPO1G/}OOQO1G/z1G/zO:bQPO1G/{O(ZQPO1G/|O:iQPO1G/}O:nQPO1G0OO:uQPO1G0QO:zQPO1G/tO;SQPO1G/tO;ZQPO1G0YO,cQPO,5:oO;cQPO1G0YOOQO1G0[1G0[O=_QPO1G0[O=fQPO1G0[O=mQPO1G0[O(ZQPO,5:sO,fQPO,5:rOVQPO1G0]O>[QPO1G/rO>lQPO7+%iOOQO7+%g7+%gO>sQPO7+%hO(ZQPO7+%iOVQPO7+%jO(ZQPO7+%lOOQO7+%`7+%`OOQO7+%t7+%tOOQO1G0Z1G0ZOOQO'#C^'#C^O>{QPO7+%tO?iQPO1G0_OOQO1G0^1G0^OOQO7+%w7+%wOVQPO<<ITO?sQPO<<ISO?xQPO<<ITO@PQPO'#DyO@eQPO<<IUO@mQPO<<IWO@tQPO<<I`OAcQPOAN>oO(ZQPOAN>nOVQPOAN>oOVQPO,5:eOOQOAN>pAN>pOVQPOAN>rOOQOG24ZG24ZOAtQPOG24YOA{QPOG24ZOB^QPO1G0POBrQPOG24^OByQPOG24^OOQOLD)tLD)tOOQOLD)uLD)uOOQOLD)xLD)xO(ZQPOLD)xOC[QPO!$'MdOOQO!)9CO!)9COO;cQPO,5:^O;cQPO,5:^O;cQPO,5:^O;cQPO,5:^O;cQPO,5:^O;cQPO,5:^O;cQPO,5:^O;cQPO,5:^OCcQPO1G/xOE[QPO1G/xOIWQPO1G/xOKbQPO1G/xOKiQPO1G/xOKpQPO1G/xOKwQPO1G/x",
|
states: "3UO!sQPOOOOQO'#C`'#C`O#lQPO'#DoOOQO'#Do'#DoO%yQPO'#DdOVQPO'#DpO'_QPO'#DrO'fQPO'#DsO'nQQO'#DtO'sQPO'#DuO'xQPO'#DvO'}QPO'#DxOOQO'#Dq'#DqO(SQPO'#DqO)pQQO'#C{OOQO'#C{'#C{OOQO'#Dk'#DkO)uQPO'#DkO)zQPO'#DkO*PQPO'#DfOVQPO'#EQO*XQPO'#EQO*^QPO'#EQO*fQPO'#DdOOQO'#De'#DeO*wQPO'#ETQOQPOOO*|QPO,5:[O*|QPO,5:[O*|QPO,5:[O*|QPO,5:[O*|QPO,5:[O*|QPO,5:[O*|QPO,5:[O*|QPO,5:[O*|QPO,5:QO+TQPO'#DjO+[QPO,5:[O,oQPO,5:SO,wQPO'#DiO,|QPO,5:PO-_QPO,5:aO.QQPO'#DjO*|QPO'#DpO._QPO,5:^OOQO'#Dj'#DjO*|QPO,5:_OOQO,5:_,5:_O.gQPO,5:`O*^QPO,5:aO*|QPO,5:bO*^QPO,5:dOOQO,59g,59gO*|QPO,5:VO*|QPO,5:VO$lQPO'#DfOOQO,5:l,5:lO*|QPO,5:lO*|QPO'#DhOOQO'#Dg'#DgOOQO'#ER'#ERO.lQPO,5:lOVQPO,5:nOVQPO,5:nOVQPO,5:nOVQPO,5:nO.tQPO'#EVOOQO'#EU'#EUO.yQPO,5:oOOQO1G/v1G/vO2jQPO1G/vO2qQPO1G/vO6aQPO1G/vO:PQPO1G/vO:WQPO1G/vO:_QPO1G/vO:fQPO1G/vO>QQPO1G/lOOQO1G/n1G/nO*|QPO,5:TOOQO1G/k1G/kO*|QPO1G/{OOQO1G/x1G/xO>qQPO1G/yO*|QPO1G/zO>xQPO1G/{O>}QPO1G/|O?UQPO1G0OO?ZQPO1G/qO?cQPO1G/qO?jQPO1G0WO*^QPO,5:mO*|QPO1G0WOOQO1G0Y1G0YO@^QPO1G0YO@eQPO1G0YO@lQPO1G0YO*|QPO,5:qO*wQPO,5:pOVQPO1G0ZOAZQPO1G/oOAkQPO7+%gOOQO7+%e7+%eOArQPO7+%fO*|QPO7+%gOVQPO7+%hO*|QPO7+%jOOQO7+%]7+%]OOQO7+%r7+%rOOQO1G0X1G0XOAzQPO7+%rOBhQPO1G0]OOQO1G0[1G0[OOQO7+%u7+%uOVQPO<<IROBrQPO<<IQOBwQPO<<IROCOQPO'#DwOCdQPO<<ISOClQPO<<IUOCsQPO<<I^ODbQPOAN>mO*|QPOAN>lOVQPOAN>mOVQPO,5:cOOQOAN>nAN>nOVQPOAN>pOOQOG24XG24XODsQPOG24WODzQPOG24XOE]QPO1G/}OEqQPOG24[OExQPOG24[OOQOLD)rLD)rOOQOLD)sLD)sOOQOLD)vLD)vO*|QPOLD)vOFZQPO!$'MbOOQO!)9B|!)9B|",
|
||||||
stateData: "NR~O!WOS~OSUOUSOVSOaVOcWOdXOjYOkZOm[OobO|eO}fO!OgO!PgO!]PO!^QO!cQO!dQO!o_O!p_O!q`O!r`O!s`O!t`O~OfjO~PVO!^lOWQXXQXYQXZQX[QX]QX^QX_QXhQXnQXqQXrQXsQXtQXuQXvQXwQXxQXyQXzQX{QX!UQX!uQXbQX!QQX!RQX!SQX!TQX`QXiQXgQXlQX~OW!eXX!eXY!eXZ!eX[!eX]!eX^!eX_!eX!u!eXb!eX~Oh!eXn![Xq![Xr!eXs!eXt!eXu!eXv!eXw!eXx!eXy!eXz!eX{!eX!U!eX~P%TOWnOXoOYpOZqO[rO]sO^tO_uOhvOrvOsvOtvOuvOvvOwvOxvOyvOzvO{vO~O!U!XX~P&uOS!OOUSOVSOaVOcWOdXOjYOkZOm[OobO!]PO!^QO!cQO!dQO!o_O!p_O!q`O!r`O!s`O!t`O~OS!ROcWO~Oe!TO~Oa!UO~Oa!VO~Oa!WO~OW!gXX!gXY!gXZ!gX[!gX]!gX^!gX_!gXh!gXn![Xq![Xr!gXs!gXt!gXu!gXv!gXw!gXx!gXy!gXz!gX{!gX!U!gX!u!gXb!gX~Oe!XO~Of!YO~OS!ZO~OnvOqvO~Of!^O~OS!_O!]PO~O!Q!cO!R!dO!S!eO!T!fO!U!XX~O!u!aX~P&uO`!jOW!bXX!bXY!bXZ!bX[!bX]!bX^!bX_!bXh!bXr!bXs!bXt!bXu!bXv!bXw!bXx!bXy!bXz!bX{!bX!u!bX~O`!sO!u!aX~O!u!tO~O`!uO!Q!cO!R!dO!S!eO!T!fO~Oh!vO~P%TOWnOXoOYpOZqO[rO]sO^tO_uO~Ob!aX!u!aXg!aX~P/_Ob!wO!u!tO~Of!yO~Oh#RO!u#QO~Oh#WO~Og#YO!u#XO~OWnOY!fiZ!fi[!fi]!fi^!fi_!fih!fir!fis!fit!fiu!fiv!fiw!fix!fiy!fiz!fi{!fi!U!fi`!fi!u!fib!fi!Q!fi!R!fi!S!fi!T!fii!fig!fil!fi~OX!fi~P0zOXoO~P0zOWnOXoOYpO_uO[!fi]!fi^!fih!fir!fis!fit!fiu!fiv!fiw!fix!fiy!fiz!fi{!fi!U!fi`!fi!u!fib!fi!Q!fi!R!fi!S!fi!T!fii!fig!fil!fi~OZ!fi~P3VOWnOXoOYpOZqO^tO_uO]!fih!fir!fis!fit!fiu!fiv!fiw!fix!fiy!fiz!fi{!fi!U!fi`!fi!u!fib!fi!Q!fi!R!fi!S!fi!T!fii!fig!fil!fi~O[!fi~P5ZO[rO~P5ZOZqO~P3VOZ!fi[!fi]!fi^!fi_!fi~OWnOXoOYpOh!fir!fis!fit!fiu!fiv!fiw!fix!fiy!fiz!fi{!fi!U!fi`!fi!u!fib!fi!Q!fi!R!fi!S!fi!T!fii!fig!fil!fi~P7mO!Q!Zi!R!Zi!S!Zi!T!Zi!U!Zi`!Zib!Zil!Zii!Zi~P/_O`#]O~P/_Oh#_O~Oi#`O~P/_On#aO~Og#bO!u!tO~O`#bO~P/_Og#cO!u!tO~OS!OOUSOVSOaVOcWOdXOjYOkZOm[OobO!]#eO!^QO!cQO!dQO!o_O!p_O!q`O!r`O!s`O!t`O~O!Q!cO!S!xi!T!xi!U!xi`!xib!xil!xii!xi~O!R!xi~P<sO!R!dO~P<sO!Q!cO!R!dO!S!eO!T!xi!U!xi`!xib!xil!xii!xi~O`!`i!u!`ib!`ig!`i~P/_Oi#jO~P/_Og#kO!u!tO~OW$TOX$UOY$VOZ$WO[$XO]$YO^$ZO_$[O~PVOg!{i!u!{i~P/_OS#rO~Oi#sO~P/_O!Q!cO!R!dO!S!eO!T!fOb!mXl!mX~Ob#uOl#tO~Oi#vO~P/_O!Q!cO!R!dO!S!eO!T!fO!U!vy`!vyb!vyl!vyi!vy~Ob#wO!Q!cO!R!dO!S!eO!T!fO~O`#}O~P/_Ob$OO!Q!cO!R!dO!S!eO!T!fO~O!Q!cO!R!dO!S!eO!T!fOb!mil!mi~Ob$PO~P&uOi$QO!Q!cO!R!dO!S!eO!T!fO~Ob$SO~P/_OW$TOS!fiU!fiV!fiX!fiY!fia!fic!fid!fij!fik!fim!fio!fi|!fi}!fi!O!fi!P!fi!]!fi!^!fi!c!fi!d!fi!o!fi!p!fi!q!fi!r!fi!s!fi!t!fi~P7mOW$TOX$UOS!fiU!fiV!fiY!fia!fic!fid!fij!fik!fim!fio!fi|!fi}!fi!O!fi!P!fi!]!fi!^!fi!c!fi!d!fi!o!fi!p!fi!q!fi!r!fi!s!fi!t!fi~P7mOW$TOX$UOY$VO_$[OS!fiU!fiV!fi[!fi]!fi^!fia!fic!fid!fij!fik!fim!fio!fi|!fi}!fi!O!fi!P!fi!]!fi!^!fi!c!fi!d!fi!o!fi!p!fi!q!fi!r!fi!s!fi!t!fi~OZ!fi~PGTOW$TOX$UOY$VOZ$WO^$ZO_$[OS!fiU!fiV!fi]!fia!fic!fid!fij!fik!fim!fio!fi|!fi}!fi!O!fi!P!fi!]!fi!^!fi!c!fi!d!fi!o!fi!p!fi!q!fi!r!fi!s!fi!t!fi~O[!fi~PI_O[$XO~PI_OZ$WO~PGTOW$TOX$UOY$VOS!fiU!fiV!fia!fic!fid!fij!fik!fim!fio!fi|!fi}!fi!O!fi!P!fi!]!fi!^!fi!c!fi!d!fi!o!fi!p!fi!q!fi!r!fi!s!fi!t!fi~P7mOd!o}oUV!q!r!s!t!p!]mkjk~",
|
stateData: "Fs~O!VOS~OQQORTOTROURO`UObVOcWOiXOjYOlZOnaO{dO|eO}fO!OfO!`PO!aPO!bPO!m^O!n^O!o_O!p_O!q_O!r_O~OeiO~PVOV!cXW!cXX!cXY!cXZ!cX[!cX]!cX^!cX!s!cXa!cX~Og!cXm!ZXp!ZXq!cXr!cXs!cXt!cXu!cXv!cXw!cXx!cXy!cXz!cX!T!cX~P!zOVkOWlOXmOYnOZoO[pO]qO^rOgsOqsOrsOssOtsOusOvsOwsOxsOysOzsO~O!T!WX~P$lOR{OTROURO`UObVOcWOiXOjYOlZOnaO!`PO!aPO!bPO!m^O!n^O!o_O!p_O!q_O!r_O~OQyO~P&QOR!OObVO~Od!QO~O`!RO~O`!SO~O`!TO~OV!eXW!eXX!eXY!eXZ!eX[!eX]!eX^!eXg!eXm!ZXp!ZXq!eXr!eXs!eXt!eXu!eXv!eXw!eXx!eXy!eXz!eX!T!eX!s!eXa!eX~Od!UO~Oe!VO~OR!WO~OmsOpsO~Oe!ZO~OQ!]OR![O~O!P!`O!Q!aO!R!bO!S!cO!T!WX~OQ!dO~OQRO~P&QO!s!^X~P$lO_!gOV!_XW!_XX!_XY!_XZ!_X[!_X]!_X^!_Xg!_Xq!_Xr!_Xs!_Xt!_Xu!_Xv!_Xw!_Xx!_Xy!_Xz!_X!s!_X~O_!pO!s!^X~O!s!qO~O_!rO!P!`O!Q!aO!R!bO!S!cO~Og!sO~P!zOVkOWlOXmOYnOZoO[pO]qO^rO~Oa!^X!s!^Xf!^X~P-fOa!tO!s!qO~Oe!vO~Og#OO!s!}O~Og#TO~Of#VO!s#UO~OVkOX!diY!diZ!di[!di]!di^!dig!diq!dir!dis!dit!diu!div!diw!dix!diy!diz!di!T!di_!di!s!dia!di!P!di!Q!di!R!di!S!dih!dif!diQ!diR!diT!diU!di`!dib!dic!dii!dij!dil!din!di{!di|!di}!di!O!di!`!di!a!di!b!di!m!di!n!di!o!di!p!di!q!di!r!dik!di~OW!di~P/ROWlO~P/ROVkOWlOXmO^rOZ!di[!di]!dig!diq!dir!dis!dit!diu!div!diw!dix!diy!diz!di!T!di_!di!s!dia!di!P!di!Q!di!R!di!S!dih!dif!diQ!diR!diT!diU!di`!dib!dic!dii!dij!dil!din!di{!di|!di}!di!O!di!`!di!a!di!b!di!m!di!n!di!o!di!p!di!q!di!r!dik!di~OY!di~P2xOVkOWlOXmOYnO]qO^rO[!dig!diq!dir!dis!dit!diu!div!diw!dix!diy!diz!di!T!di_!di!s!dia!di!P!di!Q!di!R!di!S!dih!dif!diQ!diR!diT!diU!di`!dib!dic!dii!dij!dil!din!di{!di|!di}!di!O!di!`!di!a!di!b!di!m!di!n!di!o!di!p!di!q!di!r!dik!di~OZ!di~P6hOZoO~P6hOYnO~P2xOVkOWlOXmOY!diZ!di[!di]!di^!dig!diq!dir!dis!dit!diu!div!diw!dix!diy!diz!di!T!di_!di!s!dia!di!P!di!Q!di!R!di!S!dih!dif!diQ!diR!diT!diU!di`!dib!dic!dii!dij!dil!din!di{!di|!di}!di!O!di!`!di!a!di!b!di!m!di!n!di!o!di!p!di!q!di!r!dik!di~O!P!Yi!Q!Yi!R!Yi!S!Yi!T!Yi_!Yia!Yik!Yih!Yi~P-fO_#YO~P-fOg#[O~Oh#]O~P-fOm#^O~Of#_O!s!qO~O_#_O~P-fOf#`O!s!qO~O!P!`O!R!vi!S!vi!T!vi_!via!vik!vih!vi~O!Q!vi~P?rO!Q!aO~P?rO!P!`O!Q!aO!R!bO!S!vi!T!vi_!via!vik!vih!vi~O_!]i!s!]ia!]if!]i~P-fOh#fO~P-fOf#gO!s!qO~OVkOWlOXmOYnOZoO[pO]qO^rO~PVOf!yi!s!yi~P-fOR#nO~Oh#oO~P-fO!P!`O!Q!aO!R!bO!S!cOa!kXk!kX~Oa#qOk#pO~Oh#rO~P-fO!P!`O!Q!aO!R!bO!S!cO!T!ty_!tya!tyk!tyh!ty~Oa#sO!P!`O!Q!aO!R!bO!S!cO~O_#yO~P-fOa#zO!P!`O!Q!aO!R!bO!S!cO~O!P!`O!Q!aO!R!bO!S!cOa!kik!ki~Oa#{O~P$lOh#|O!P!`O!Q!aO!R!bO!S!cO~Oa$OO~P-fOc!m|nTU!o!p!q!r!nQljij~",
|
||||||
goto: "0m!|PP!}$aP$dPPPPPPPPPPPPPPPPPPPPPPPPPP%hPPPPPPPPPPPPPPPPPPPPPP&l&r'l'|PP(j)v*R*dPP$d,x$d.O/S.O.O.O0Z.OPPPPPPP'l0^'l0a0d0glROUe!c!d!e!f#Y#`#f#j#s#t#v!dSnopqrstuv!O!R!V!Y!Z!^!_!t!v!y#R#W#_#a#r$Q$T$U$V$W$X$Y$Z$[Q|VW!`g!U!W#QT!gj#XRmP#TaOUVenopqrstuv!O!R!V!Y!Z!^!_!c!d!e!f!t!v!y#R#W#Y#_#`#a#f#j#r#s#t#v$Q$T$U$V$W$X$Y$Z$[#TcOUVenopqrstuv!O!R!V!Y!Z!^!_!c!d!e!f!t!v!y#R#W#Y#_#`#a#f#j#r#s#t#v$Q$T$U$V$W$X$Y$Z$[QkOR#i#YShO#YQ{UQ!]eQ#S!cQ#T!dQ#U!eQ#V!fQ#m#`Q#p#fQ#q#jQ#y#sQ#z#tR#|#vmiOUe!c!d!e!f#Y#`#f#j#s#t#vldOUe!c!d!e!f#Y#`#f#j#s#t#vQ!agQ!z!UQ!|!WR#d#Q!f]Vnopqrstuv!O!R!V!Y!Z!^!_!t!v!y#R#W#_#a#r$Q$T$U$V$W$X$Y$Z$[l^OUe!c!d!e!f#Y#`#f#j#s#t#vX!`g!U!W#QUyU!O!_X!QV!Y!^!yUzU!O!_Q!PVQ!}!YQ#P!^R#^!ySTO#YQwU[}V!O!Y!^!_!yd![e!c!d!e!f#`#f#j#s#tS!jn$TQ!koQ!lpQ!mqQ!nrQ!osQ!ptQ!quQ!rvQ!x!RQ!{!VQ#O!ZQ#Z!tQ#[!vQ#f#RQ#g#WQ#l#_Q#o#aQ#x#rQ#{#vQ$R$QQ$]$UQ$^$VQ$_$WQ$`$XQ$a$YQ$b$ZR$c$[#OaOVenopqrstuv!R!V!Y!Z!^!_!c!d!e!f!t!v!y#R#W#Y#_#`#a#f#j#r#s#t#v$Q$T$U$V$W$X$Y$Z$[TxU!O#T]OUVenopqrstuv!O!R!V!Y!Z!^!_!c!d!e!f!t!v!y#R#W#Y#_#`#a#f#j#r#s#t#v$Q$T$U$V$W$X$Y$Z$[#S]OUVenopqrstuv!O!R!V!Y!Z!^!_!c!d!e!f!t!v!y#R#W#Y#_#`#a#f#j#r#s#t#v$Q$T$U$V$W$X$Y$Z$[R!SWR#n#`R!bgRkOR!ijQ!hjR#h#X",
|
goto: "-l!zPPPP!{PPPPPPPPPPPPPPPPPPPPPPPPPP#wPPPPPPPPPPPPPPPPPPPPPP$s$y%s&T&q'u(Q(cPPP!{*a!{+_,Z+_+_+_-Y+_PPPPPPP%s-]%s-`-c-f!s`OTUdklmnopqrs{!O!S!V!W!Z![!`!a!b!c!q!s!v#O#T#V#[#]#^#b#f#n#o#p#r#|!sbOTUdklmnopqrs{!O!S!V!W!Z![!`!a!b!c!q!s!v#O#T#V#[#]#^#b#f#n#o#p#r#|QjOR#e#VSgO#VQxTQ!YdQ#P!`Q#Q!aQ#R!bQ#S!cQ#i#]Q#l#bQ#m#fQ#u#oQ#v#pR#x#rmhOTd!`!a!b!c#V#]#b#f#o#p#rlcOTd!`!a!b!c#V#]#b#f#o#p#rQ!^fQ!w!RQ!y!TR#a!}!U[Uklmnopqrs{!O!S!V!W!Z![!q!s!v#O#T#[#^#n#|l]OTd!`!a!b!c#V#]#b#f#o#p#rX!]f!R!T!}UvT{![X}U!V!Z!vUwT{![Q|UQ!z!VQ!|!ZR#Z!vSSO#VQtT[zU{!V!Z![!vd!Xd!`!a!b!c#]#b#f#o#pQ!gkQ!hlQ!imQ!jnQ!koQ!lpQ!mqQ!nrQ!osQ!u!OQ!x!SQ!{!WQ#W!qQ#X!sQ#b#OQ#c#TQ#h#[Q#k#^Q#t#nQ#w#rR#}#|!n`OUdklmnopqrs!O!S!V!W!Z![!`!a!b!c!q!s!v#O#T#V#[#]#^#b#f#n#o#p#r#|TuT{!s[OTUdklmnopqrs{!O!S!V!W!Z![!`!a!b!c!q!s!v#O#T#V#[#]#^#b#f#n#o#p#r#|!r[OTUdklmnopqrs{!O!S!V!W!Z![!`!a!b!c!q!s!v#O#T#V#[#]#^#b#f#n#o#p#r#|R!PVR#j#]R!_fRjOR!fiQ!eiR#d#U",
|
||||||
nodeNames: "⚠ Expression Local Index ( Literal Global Radical + - * ∪ \\ ∆ ∩ × ) { } ℬ Filter ComplexIndex [ ] ∈ | PrefixD PrefixI ; PrefixR := Function TextFunction :∈ ∉ ⊆ ⊄ ⊂ > ≥ < ≤ ≠ = ¬ Predicate ∀ ∃ ⇔ ⇒ ∨ &",
|
nodeNames: "⚠ Expression Local ( Literal Global Radical + - * ∪ \\ ∆ ∩ × ) { } ℬ Filter ComplexIndex [ ] ∈ | PrefixD PrefixI ; PrefixR := Function TextFunction :∈ ∉ ⊆ ⊄ ⊂ > ≥ < ≤ ≠ = ¬ Predicate ∀ ∃ ⇔ ⇒ ∨ &",
|
||||||
maxTerm: 89,
|
maxTerm: 87,
|
||||||
propSources: [highlighting],
|
propSources: [highlighting],
|
||||||
skippedNodes: [0],
|
skippedNodes: [0],
|
||||||
repeatNodeCount: 0,
|
repeatNodeCount: 0,
|
||||||
tokenData: "4i~R!jX^%spq%svw&hxy&myz&rz{&w{|&||}'R}!O'W!Q!R']!R[!h!i)d!k!l)z!r!s*P!t!u*g!u!v(|!v!w(|!z!{(|!|!}*w!}#O*|#O#P+R#P#Q+W#R#S+]#T#U+]#U#V+h#V#W,z#W#X.Z#X#d+]#d#e0a#e#f+]#f#g1P#g#o+]#o#p2Q#p#q2V#q#r2[#y#z%s$f$g%s$r$s2a%o%p2f5i6S+]#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s% l% m2k%%Y%%Z2p%%[%%]2u%&Y%&Z2z%&]%&^3P%&_%&`3U%&`%&a3Z%&b%&c3`%&c%&d3e%'S%'T3j%'T%'U3o%'U%'V3t%(^%(_3y%(b%(c4O%(c%(d4T%)Q%)R4Y%)S%)T4_%)U%)V4d&FU&FV%s~%xY!W~X^%spq%s#y#z%s$f$g%s#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s&FU&FV%s~&mO!T~~&rOS~~&wO`~~&|OY~~'ROW~~'WO!u~~']OX~P'bP!^P!Q![']R'lQeQ!^P|}'r!Q!['eQ'uP!R!['xQ'}QeQ|}'r!Q!['x~(WQ!_!`(^%&b%&c(c~(cOn~~(hOq~~(mOl~~(rOx~~(wO{~~(|Ov~~)PP!Q![)S~)XPU~!Q![)S~)aPj~!Q![)S~)gQ!Q![)m#]#^)u~)rPo~!Q![)m~)zOd~~*POk~~*SQ!Q![*Y#f#g*b~*_P}~!Q![*Y~*gO!o~~*lPm~!Q![*o~*tPV~!Q![*o~*|O!d~~+ROf~~+WO[~~+]Og~~+bQ!]~#T#o+]5i6S+]~+mS!]~#T#c+]#c#d+y#d#o+]5i6S+]~,OS!]~#T#c+]#c#d,[#d#o+]5i6S+]~,aS!]~#T#`+]#`#a,m#a#o+]5i6S+]~,tQ!r~!]~#T#o+]5i6S+]~-PR!]~#T#U-Y#U#o+]5i6S+]~-_S!]~#T#f+]#f#g-k#g#o+]5i6S+]~-pS!]~#T#W+]#W#X-|#X#o+]5i6S+]~.TQ!q~!]~#T#o+]5i6S+]~.`S!]~#T#X+]#X#Y.l#Y#o+]5i6S+]~.qS!]~#T#U+]#U#V.}#V#o+]5i6S+]~/SS!]~#T#c+]#c#d/`#d#o+]5i6S+]~/eS!]~#T#c+]#c#d/q#d#o+]5i6S+]~/vS!]~#T#`+]#`#a0S#a#o+]5i6S+]~0ZQ!s~!]~#T#o+]5i6S+]~0fS!]~#T#f+]#f#g0r#g#o+]5i6S+]~0yQ!p~!]~#T#o+]5i6S+]~1US!]~#T#X+]#X#Y1b#Y#o+]5i6S+]~1gS!]~#T#W+]#W#X1s#X#o+]5i6S+]~1zQ!t~!]~#T#o+]5i6S+]~2VOa~~2[Oi~~2aOb~~2fO|~~2kO_~~2pOc~~2uO!R~~2zO!Q~~3PO!O~~3UO!P~~3ZO!c~~3`O]~~3eOh~~3jOr~~3oO!S~~3tO^~~3yOZ~~4OOz~~4TOy~~4YOw~~4_Ou~~4dOt~~4iOs~",
|
tokenData: "6P~R!jX^%spq%svw&hxy&myz&rz{&w{|&||}'R}!O'W!Q!R']!R[!h!i)d!k!l)z!r!s*P!t!u*g!u!v(|!v!w(|!z!{(|!|!}*w!}#O*|#O#P+R#P#Q+W#R#S+]#T#U+]#U#V+s#V#W-c#W#X/O#X#d+]#d#e1h#e#f+]#f#g2^#g#o+]#o#p3h#p#q3m#q#r3r#y#z%s$f$g%s$r$s3w%o%p3|5i6S+]#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s% l% m4R%%Y%%Z4W%%[%%]4]%&Y%&Z4b%&]%&^4g%&_%&`4l%&`%&a4q%&b%&c4v%&c%&d4{%'S%'T5Q%'T%'U5V%'U%'V5[%(^%(_5a%(b%(c5f%(c%(d5k%)Q%)R5p%)S%)T5u%)U%)V5z&FU&FV%s~%xY!V~X^%spq%s#y#z%s$f$g%s#BY#BZ%s$IS$I_%s$I|$JO%s$JT$JU%s$KV$KW%s&FU&FV%s~&mO!S~~&rOR~~&wO_~~&|OX~~'ROV~~'WO!s~~']OW~P'bP!`P!Q![']R'lQdQ!`P|}'r!Q!['eQ'uP!R!['xQ'}QdQ|}'r!Q!['x~(WQ!_!`(^%&b%&c(c~(cOm~~(hOp~~(mOk~~(rOw~~(wOz~~(|Ou~~)PP!Q![)S~)XPT~!Q![)S~)aPi~!Q![)S~)gQ!Q![)m#]#^)u~)rPn~!Q![)m~)zOc~~*POj~~*SQ!Q![*Y#f#g*b~*_P|~!Q![*Y~*gO!m~~*lPl~!Q![*o~*tPU~!Q![*o~*|O!b~~+ROe~~+WOZ~~+]Of~~+bRQ~!Q![+k#T#o+]5i6S+]~+pPQ~!Q![+k~+xTQ~!Q![+k#T#c+]#c#d,X#d#o+]5i6S+]~,^TQ~!Q![+k#T#c+]#c#d,m#d#o+]5i6S+]~,rTQ~!Q![+k#T#`+]#`#a-R#a#o+]5i6S+]~-YR!p~Q~!Q![+k#T#o+]5i6S+]~-hSQ~!Q![+k#T#U-t#U#o+]5i6S+]~-yTQ~!Q![+k#T#f+]#f#g.Y#g#o+]5i6S+]~._TQ~!Q![+k#T#W+]#W#X.n#X#o+]5i6S+]~.uR!o~Q~!Q![+k#T#o+]5i6S+]~/TTQ~!Q![+k#T#X+]#X#Y/d#Y#o+]5i6S+]~/iTQ~!Q![+k#T#U+]#U#V/x#V#o+]5i6S+]~/}TQ~!Q![+k#T#c+]#c#d0^#d#o+]5i6S+]~0cTQ~!Q![+k#T#c+]#c#d0r#d#o+]5i6S+]~0wTQ~!Q![+k#T#`+]#`#a1W#a#o+]5i6S+]~1_R!q~Q~!Q![+k#T#o+]5i6S+]~1mTQ~!Q![+k#T#f+]#f#g1|#g#o+]5i6S+]~2TR!n~Q~!Q![+k#T#o+]5i6S+]~2cTQ~!Q![+k#T#X+]#X#Y2r#Y#o+]5i6S+]~2wTQ~!Q![+k#T#W+]#W#X3W#X#o+]5i6S+]~3_R!r~Q~!Q![+k#T#o+]5i6S+]~3mO`~~3rOh~~3wOa~~3|O{~~4RO^~~4WOb~~4]O!Q~~4bO!P~~4gO}~~4lO!O~~4qO!a~~4vO[~~4{Og~~5QOq~~5VO!R~~5[O]~~5aOY~~5fOy~~5kOx~~5pOv~~5uOt~~5zOs~~6POr~",
|
||||||
tokenizers: [0, 1],
|
tokenizers: [0, 1],
|
||||||
topRules: {"Expression":[0,1]},
|
topRules: {"Expression":[0,1]},
|
||||||
tokenPrec: 2056
|
tokenPrec: 1720
|
||||||
})
|
})
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
log_and @left,
|
log_and @left,
|
||||||
set_decart @left set_union @left set_intersect @left set_minus @left set_symminus @left,
|
set_decart @left set_union @left set_intersect @left set_minus @left set_symminus @left,
|
||||||
set_bool @right,
|
set_bool @right,
|
||||||
quant @right,
|
quant @right
|
||||||
p1, p2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
@ -43,7 +42,7 @@
|
||||||
Function { "F"$[0-9]+ }
|
Function { "F"$[0-9]+ }
|
||||||
Predicate { "P"$[0-9]+ }
|
Predicate { "P"$[0-9]+ }
|
||||||
Radical { "R"$[0-9]+ }
|
Radical { "R"$[0-9]+ }
|
||||||
local { $[_a-zα-ω]($[a-zα-ω])* }
|
Local { $[_a-zα-ω]($[a-zα-ω])*$[0-9]* }
|
||||||
PrefixR { "R" }
|
PrefixR { "R" }
|
||||||
PrefixI { "I" }
|
PrefixI { "I" }
|
||||||
PrefixD { "D" }
|
PrefixD { "D" }
|
||||||
|
@ -77,7 +76,7 @@
|
||||||
debool
|
debool
|
||||||
red
|
red
|
||||||
smallPr
|
smallPr
|
||||||
local
|
Local
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,13 +109,6 @@ arguments {
|
||||||
declaration {
|
declaration {
|
||||||
Local "∈" setexpr
|
Local "∈" setexpr
|
||||||
}
|
}
|
||||||
Local {
|
|
||||||
!p1 local |
|
|
||||||
!p2 local Index
|
|
||||||
}
|
|
||||||
Index {
|
|
||||||
integer
|
|
||||||
}
|
|
||||||
variable {
|
variable {
|
||||||
Local |
|
Local |
|
||||||
tuple
|
tuple
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
@detectDelim
|
|
||||||
@external propSource highlighting from "./highlight"
|
|
||||||
|
|
||||||
@top Expression { token* }
|
|
||||||
|
|
||||||
@skip { space }
|
|
||||||
|
|
||||||
@tokens {
|
|
||||||
space { @whitespace+ }
|
|
||||||
Index { $[0-9]+ }
|
|
||||||
ComplexIndex { $[1-9](","$[1-9])* }
|
|
||||||
Integer { space$[0-9]+space? }
|
|
||||||
|
|
||||||
bigPr { "Pr" }
|
|
||||||
smallPr { "pr" }
|
|
||||||
filter { "Fi" }
|
|
||||||
card { "card" }
|
|
||||||
bool { "bool" }
|
|
||||||
debool { "debool" }
|
|
||||||
red { "red" }
|
|
||||||
|
|
||||||
ConstructPrefix { "D" | "R" | "I" }
|
|
||||||
|
|
||||||
Global { $[XCSDAPTF]$[0-9]+ }
|
|
||||||
Radical { "R"$[0-9]+ }
|
|
||||||
local { $[_a-zα-ω]$[a-zα-ω]* }
|
|
||||||
|
|
||||||
"(" ")"
|
|
||||||
"[" "]"
|
|
||||||
"{" "}"
|
|
||||||
|
|
||||||
@precedence {
|
|
||||||
filter
|
|
||||||
bigPr
|
|
||||||
Global
|
|
||||||
Radical
|
|
||||||
ConstructPrefix
|
|
||||||
}
|
|
||||||
@precedence {
|
|
||||||
card
|
|
||||||
bool
|
|
||||||
debool
|
|
||||||
red
|
|
||||||
smallPr
|
|
||||||
local
|
|
||||||
}
|
|
||||||
@precedence {
|
|
||||||
Integer
|
|
||||||
space
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFunction {
|
|
||||||
bigPr ComplexIndex |
|
|
||||||
smallPr ComplexIndex |
|
|
||||||
filter ComplexIndex |
|
|
||||||
card |
|
|
||||||
bool |
|
|
||||||
debool |
|
|
||||||
red
|
|
||||||
}
|
|
||||||
|
|
||||||
Local {
|
|
||||||
local Index?
|
|
||||||
}
|
|
||||||
|
|
||||||
token {
|
|
||||||
TextFunction |
|
|
||||||
ConstructPrefix |
|
|
||||||
Integer |
|
|
||||||
Global |
|
|
||||||
Radical |
|
|
||||||
Local
|
|
||||||
}
|
|
|
@ -4,8 +4,8 @@ import TextURL from '@/components/ui/TextURL';
|
||||||
import Tooltip, { PlacesType } from '@/components/ui/Tooltip';
|
import Tooltip, { PlacesType } from '@/components/ui/Tooltip';
|
||||||
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
import TopicPage from '@/pages/ManualsPage/TopicPage';
|
||||||
|
|
||||||
import TopicPage from '../../pages/ManualsPage/TopicPage';
|
|
||||||
import { IconHelp } from '../Icons';
|
import { IconHelp } from '../Icons';
|
||||||
import { CProps } from '../props';
|
import { CProps } from '../props';
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,16 @@ function InfoConstituenta({ data, className, ...restProps }: InfoConstituentaPro
|
||||||
{data.definition_resolved}
|
{data.definition_resolved}
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
{data.parent_alias ? (
|
{data.spawner_alias ? (
|
||||||
<p>
|
<p>
|
||||||
<b>Основание: </b>
|
<b>Основание: </b>
|
||||||
{data.parent_alias}
|
{data.spawner_alias}
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
{data.children_alias.length > 0 ? (
|
{data.spawn_alias.length > 0 ? (
|
||||||
<p>
|
<p>
|
||||||
<b>Порождает: </b>
|
<b>Порождает: </b>
|
||||||
{data.children_alias.join(', ')}
|
{data.spawn_alias.join(', ')}
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
{data.convention ? (
|
{data.convention ? (
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Graph } from './Graph';
|
import { Graph } from './Graph';
|
||||||
|
import { LibraryItemID } from './library';
|
||||||
import { ConstituentaID, CstType, IConstituenta, IRSForm, IRSFormData, IRSFormStats } from './rsform';
|
import { ConstituentaID, CstType, IConstituenta, IRSForm, IRSFormData, IRSFormStats } from './rsform';
|
||||||
import { inferClass, inferStatus, inferTemplate, isBaseSet, isFunctional } from './rsformAPI';
|
import { inferClass, inferStatus, inferTemplate, isBaseSet, isFunctional } from './rsformAPI';
|
||||||
import { ParsingStatus, ValueClass } from './rslang';
|
import { ParsingStatus, ValueClass } from './rslang';
|
||||||
|
@ -59,27 +60,39 @@ export class RSFormLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private inferCstAttributes() {
|
private inferCstAttributes() {
|
||||||
const inherit_children = new Set(this.schema.inheritance.map(item => item[0]));
|
const schemaByCst = new Map<ConstituentaID, LibraryItemID>();
|
||||||
const inherit_parents = new Set(this.schema.inheritance.map(item => item[1]));
|
const parents: LibraryItemID[] = [];
|
||||||
|
this.schema.inheritance.forEach(item => {
|
||||||
|
if (item.child_source === this.schema.id) {
|
||||||
|
schemaByCst.set(item.child, item.parent_source);
|
||||||
|
if (!parents.includes(item.parent_source)) {
|
||||||
|
parents.push(item.parent_source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const inherit_children = new Set(this.schema.inheritance.map(item => item.child));
|
||||||
|
const inherit_parents = new Set(this.schema.inheritance.map(item => item.parent));
|
||||||
this.graph.topologicalOrder().forEach(cstID => {
|
this.graph.topologicalOrder().forEach(cstID => {
|
||||||
const cst = this.cstByID.get(cstID)!;
|
const cst = this.cstByID.get(cstID)!;
|
||||||
cst.status = inferStatus(cst.parse.status, cst.parse.valueClass);
|
cst.status = inferStatus(cst.parse.status, cst.parse.valueClass);
|
||||||
cst.is_template = inferTemplate(cst.definition_formal);
|
cst.is_template = inferTemplate(cst.definition_formal);
|
||||||
cst.cst_class = inferClass(cst.cst_type, cst.is_template);
|
cst.cst_class = inferClass(cst.cst_type, cst.is_template);
|
||||||
cst.children = [];
|
cst.spawn = [];
|
||||||
cst.children_alias = [];
|
cst.spawn_alias = [];
|
||||||
|
cst.parent_schema = schemaByCst.get(cst.id);
|
||||||
|
cst.parent_schema_index = cst.parent_schema ? parents.indexOf(cst.parent_schema) + 1 : 0;
|
||||||
cst.is_inherited = inherit_children.has(cst.id);
|
cst.is_inherited = inherit_children.has(cst.id);
|
||||||
cst.is_inherited_parent = inherit_parents.has(cst.id);
|
cst.has_inherited_children = inherit_parents.has(cst.id);
|
||||||
cst.is_simple_expression = this.inferSimpleExpression(cst);
|
cst.is_simple_expression = this.inferSimpleExpression(cst);
|
||||||
if (!cst.is_simple_expression || cst.cst_type === CstType.STRUCTURED) {
|
if (!cst.is_simple_expression || cst.cst_type === CstType.STRUCTURED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cst.parent = this.inferParent(cst);
|
cst.spawner = this.inferParent(cst);
|
||||||
if (cst.parent) {
|
if (cst.spawner) {
|
||||||
const parent = this.cstByID.get(cst.parent)!;
|
const parent = this.cstByID.get(cst.spawner)!;
|
||||||
cst.parent_alias = parent.alias;
|
cst.spawner_alias = parent.alias;
|
||||||
parent.children.push(cst.id);
|
parent.spawn.push(cst.id);
|
||||||
parent.children_alias.push(cst.alias);
|
parent.spawn_alias.push(cst.alias);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -107,7 +120,7 @@ export class RSFormLoader {
|
||||||
if (sources.size !== 1 || sources.has(target.id)) {
|
if (sources.size !== 1 || sources.has(target.id)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const parent_id = sources.values().next().value as ConstituentaID;
|
const parent_id = sources.values().next().value!;
|
||||||
const parent = this.cstByID.get(parent_id);
|
const parent = this.cstByID.get(parent_id);
|
||||||
if (parent && isBaseSet(parent.cst_type)) {
|
if (parent && isBaseSet(parent.cst_type)) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -122,7 +135,7 @@ export class RSFormLoader {
|
||||||
node.inputs.forEach(id => {
|
node.inputs.forEach(id => {
|
||||||
const parent = this.cstByID.get(id)!;
|
const parent = this.cstByID.get(id)!;
|
||||||
if (!parent.is_template || !parent.is_simple_expression) {
|
if (!parent.is_template || !parent.is_simple_expression) {
|
||||||
sources.add(parent.parent ?? id);
|
sources.add(parent.spawner ?? id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return sources;
|
return sources;
|
||||||
|
@ -133,7 +146,7 @@ export class RSFormLoader {
|
||||||
bodyDependencies.forEach(alias => {
|
bodyDependencies.forEach(alias => {
|
||||||
const parent = this.cstByAlias.get(alias);
|
const parent = this.cstByAlias.get(alias);
|
||||||
if (parent && (!parent.is_template || !parent.is_simple_expression)) {
|
if (parent && (!parent.is_template || !parent.is_simple_expression)) {
|
||||||
sources.add(this.cstByID.get(parent.id)!.parent ?? parent.id);
|
sources.add(this.cstByID.get(parent.id)!.spawner ?? parent.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const needCheckHead = () => {
|
const needCheckHead = () => {
|
||||||
|
@ -142,7 +155,7 @@ export class RSFormLoader {
|
||||||
} else if (sources.size !== 1) {
|
} else if (sources.size !== 1) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
const base = this.cstByID.get(sources.values().next().value as ConstituentaID)!;
|
const base = this.cstByID.get(sources.values().next().value!)!;
|
||||||
return !isFunctional(base.cst_type) || splitTemplateDefinition(base.definition_formal).head !== expression.head;
|
return !isFunctional(base.cst_type) || splitTemplateDefinition(base.definition_formal).head !== expression.head;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -151,7 +164,7 @@ export class RSFormLoader {
|
||||||
headDependencies.forEach(alias => {
|
headDependencies.forEach(alias => {
|
||||||
const parent = this.cstByAlias.get(alias);
|
const parent = this.cstByAlias.get(alias);
|
||||||
if (parent && !isBaseSet(parent.cst_type) && (!parent.is_template || !parent.is_simple_expression)) {
|
if (parent && !isBaseSet(parent.cst_type) && (!parent.is_template || !parent.is_simple_expression)) {
|
||||||
sources.add(parent.parent ?? parent.id);
|
sources.add(parent.spawner ?? parent.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export interface OssNodeInternal {
|
||||||
/**
|
/**
|
||||||
* Represents graph node coloring scheme.
|
* Represents graph node coloring scheme.
|
||||||
*/
|
*/
|
||||||
export type GraphColoring = 'none' | 'status' | 'type';
|
export type GraphColoring = 'none' | 'status' | 'type' | 'schemas';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents graph node sizing scheme.
|
* Represents graph node sizing scheme.
|
||||||
|
|
|
@ -44,6 +44,6 @@ export function applyNodeSizing(target: IConstituenta, sizing: GraphSizing): num
|
||||||
} else if (sizing === 'complex') {
|
} else if (sizing === 'complex') {
|
||||||
return target.is_simple_expression ? 1 : 2;
|
return target.is_simple_expression ? 1 : 2;
|
||||||
} else {
|
} else {
|
||||||
return target.parent ? 1 : 2;
|
return target.spawner ? 1 : 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,16 +101,35 @@ export interface IConstituentaData extends IConstituentaMeta {
|
||||||
* Represents Constituenta.
|
* Represents Constituenta.
|
||||||
*/
|
*/
|
||||||
export interface IConstituenta extends IConstituentaData {
|
export interface IConstituenta extends IConstituentaData {
|
||||||
|
/** {@link CstClass} of this {@link IConstituenta}. */
|
||||||
cst_class: CstClass;
|
cst_class: CstClass;
|
||||||
|
/** {@link ExpressionStatus} of this {@link IConstituenta}. */
|
||||||
status: ExpressionStatus;
|
status: ExpressionStatus;
|
||||||
|
|
||||||
|
/** Indicates if this {@link IConstituenta} is a template. */
|
||||||
is_template: boolean;
|
is_template: boolean;
|
||||||
|
/** Indicates if this {@link IConstituenta} has a simple expression. */
|
||||||
is_simple_expression: boolean;
|
is_simple_expression: boolean;
|
||||||
|
|
||||||
|
/** Index of {@link LibraryItemID} that contains this cst (or inheritance parent).
|
||||||
|
* 0 - not inherited, 1 - inherited by 1st schema, 2 - inherited by 2nd schema, etc.
|
||||||
|
*/
|
||||||
|
parent_schema_index: number;
|
||||||
|
/** {@link LibraryItemID} that contains parent of this inherited {@link IConstituenta}. */
|
||||||
|
parent_schema?: LibraryItemID;
|
||||||
|
/** Indicates if this {@link IConstituenta} is inherited. */
|
||||||
is_inherited: boolean;
|
is_inherited: boolean;
|
||||||
is_inherited_parent: boolean;
|
/** Indicates if this {@link IConstituenta} has children that are inherited. */
|
||||||
parent?: ConstituentaID;
|
has_inherited_children: boolean;
|
||||||
parent_alias?: string;
|
|
||||||
children: number[];
|
/** {@link IConstituenta} that spawned this one. */
|
||||||
children_alias: string[];
|
spawner?: ConstituentaID;
|
||||||
|
/** Alias of {@link IConstituenta} that spawned this one. */
|
||||||
|
spawner_alias?: string;
|
||||||
|
/** List of {@link IConstituenta} that are spawned by this one. */
|
||||||
|
spawn: number[];
|
||||||
|
/** List of aliases of {@link IConstituenta} that are spawned by this one. */
|
||||||
|
spawn_alias: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,12 +217,22 @@ export interface IRSFormStats {
|
||||||
count_theorem: number;
|
count_theorem: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents inheritance data for {@link IRSForm}.
|
||||||
|
*/
|
||||||
|
export interface IInheritanceData {
|
||||||
|
child: ConstituentaID;
|
||||||
|
child_source: LibraryItemID;
|
||||||
|
parent: ConstituentaID;
|
||||||
|
parent_source: LibraryItemID;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents data for {@link IRSForm} provided by backend.
|
* Represents data for {@link IRSForm} provided by backend.
|
||||||
*/
|
*/
|
||||||
export interface IRSFormData extends ILibraryItemVersioned {
|
export interface IRSFormData extends ILibraryItemVersioned {
|
||||||
items: IConstituentaData[];
|
items: IConstituentaData[];
|
||||||
inheritance: ConstituentaID[][];
|
inheritance: IInheritanceData[];
|
||||||
oss: ILibraryItemReference[];
|
oss: ILibraryItemReference[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,9 +117,9 @@ export function inferClass(type: CstType, isTemplate: boolean = false): CstClass
|
||||||
export function createMockConstituenta(id: ConstituentaID, alias: string, comment: string): IConstituenta {
|
export function createMockConstituenta(id: ConstituentaID, alias: string, comment: string): IConstituenta {
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: id,
|
||||||
parent: id,
|
spawner: id,
|
||||||
children: [],
|
spawn: [],
|
||||||
children_alias: [],
|
spawn_alias: [],
|
||||||
is_simple_expression: false,
|
is_simple_expression: false,
|
||||||
schema: -1,
|
schema: -1,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
|
@ -132,9 +132,10 @@ export function createMockConstituenta(id: ConstituentaID, alias: string, commen
|
||||||
definition_raw: '',
|
definition_raw: '',
|
||||||
definition_resolved: '',
|
definition_resolved: '',
|
||||||
status: ExpressionStatus.INCORRECT,
|
status: ExpressionStatus.INCORRECT,
|
||||||
|
parent_schema_index: 0,
|
||||||
is_template: false,
|
is_template: false,
|
||||||
is_inherited: false,
|
is_inherited: false,
|
||||||
is_inherited_parent: false,
|
has_inherited_children: false,
|
||||||
cst_class: CstClass.DERIVED,
|
cst_class: CstClass.DERIVED,
|
||||||
parse: {
|
parse: {
|
||||||
status: ParsingStatus.INCORRECT,
|
status: ParsingStatus.INCORRECT,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { urls } from '@/app/urls';
|
|
||||||
import { IconLibrary2, IconManuals, IconUser2 } from '@/components/Icons';
|
|
||||||
import LinkTopic from '@/components/ui/LinkTopic';
|
import LinkTopic from '@/components/ui/LinkTopic';
|
||||||
import TextURL from '@/components/ui/TextURL';
|
import TextURL from '@/components/ui/TextURL';
|
||||||
import { HelpTopic } from '@/models/miscellaneous';
|
import { HelpTopic } from '@/models/miscellaneous';
|
||||||
|
@ -22,20 +20,6 @@ function HelpMain() {
|
||||||
<LinkTopic text='Операционной схеме синтеза' topic={HelpTopic.CC_OSS} />.
|
<LinkTopic text='Операционной схеме синтеза' topic={HelpTopic.CC_OSS} />.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Разделы Портала</h2>
|
|
||||||
<li>
|
|
||||||
<IconLibrary2 size='1.25rem' className='inline-icon' /> <TextURL text='Библиотека' href={urls.library} /> –
|
|
||||||
библиотека концептуальных схем
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<IconManuals size='1.25rem' className='inline-icon' /> <TextURL text='Справка' href={urls.manuals} /> –
|
|
||||||
справочные материалы
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<IconUser2 size='1.25rem' className='inline-icon' /> <TextURL text='Профиль' href={urls.profile} /> – данные
|
|
||||||
пользователя и смена пароля
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<h2>Разделы Справки</h2>
|
<h2>Разделы Справки</h2>
|
||||||
{[
|
{[
|
||||||
HelpTopic.THESAURUS,
|
HelpTopic.THESAURUS,
|
||||||
|
|
|
@ -249,7 +249,7 @@ function FormConstituenta({
|
||||||
icon={<IconSave size='1.25rem' />}
|
icon={<IconSave size='1.25rem' />}
|
||||||
/>
|
/>
|
||||||
<Overlay position='top-[0.1rem] left-[0.4rem]' className='cc-icons'>
|
<Overlay position='top-[0.1rem] left-[0.4rem]' className='cc-icons'>
|
||||||
{state.is_inherited_parent && !state.is_inherited ? (
|
{state.has_inherited_children && !state.is_inherited ? (
|
||||||
<Indicator
|
<Indicator
|
||||||
icon={<IconPredecessor size='1.25rem' className='clr-text-primary' />}
|
icon={<IconPredecessor size='1.25rem' className='clr-text-primary' />}
|
||||||
titleHtml='Внимание!</br> Конституента имеет потомков<br/> в операционной схеме синтеза'
|
titleHtml='Внимание!</br> Конституента имеет потомков<br/> в операционной схеме синтеза'
|
||||||
|
|
|
@ -165,7 +165,11 @@ function EditorRSExpression({
|
||||||
toggleControls={() => setShowControls(prev => !prev)}
|
toggleControls={() => setShowControls(prev => !prev)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Overlay position='top-[-0.5rem]' className='pl-[8.5rem] xs:pl-[2rem] flex justify-center w-full gap-1'>
|
<Overlay
|
||||||
|
position='top-[-0.5rem]'
|
||||||
|
layer='z-pop'
|
||||||
|
className='pl-[8.5rem] xs:pl-[2rem] flex justify-center w-full gap-1'
|
||||||
|
>
|
||||||
<StatusBar
|
<StatusBar
|
||||||
processing={parser.processing}
|
processing={parser.processing}
|
||||||
isModified={isModified}
|
isModified={isModified}
|
||||||
|
|
|
@ -15,7 +15,7 @@ function ToolbarRSExpression({ disabled, showControls, toggleControls, showAST }
|
||||||
const model = useRSForm();
|
const model = useRSForm();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Overlay position='top-[-0.5rem] right-0' className='cc-icons'>
|
<Overlay position='top-[-0.5rem] right-0' layer='z-sticky' className='cc-icons'>
|
||||||
{!disabled || model.processing ? (
|
{!disabled || model.processing ? (
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Отображение специальной клавиатуры'
|
title='Отображение специальной клавиатуры'
|
||||||
|
|
|
@ -261,6 +261,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
|
||||||
const selectors = useMemo(
|
const selectors = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<GraphSelectors
|
<GraphSelectors
|
||||||
|
schema={controller.schema}
|
||||||
coloring={coloring}
|
coloring={coloring}
|
||||||
layout={layout}
|
layout={layout}
|
||||||
sizing={sizing}
|
sizing={sizing}
|
||||||
|
@ -269,7 +270,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
|
||||||
setSizing={setSizing}
|
setSizing={setSizing}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
[coloring, layout, sizing, handleChangeLayout, setColoring, setSizing]
|
[coloring, controller.schema, layout, sizing, handleChangeLayout, setColoring, setSizing]
|
||||||
);
|
);
|
||||||
const viewHidden = useMemo(
|
const viewHidden = useMemo(
|
||||||
() => (
|
() => (
|
||||||
|
|
|
@ -3,10 +3,14 @@ import { GraphLayout } from '@/components/ui/GraphUI';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
import SelectSingle from '@/components/ui/SelectSingle';
|
import SelectSingle from '@/components/ui/SelectSingle';
|
||||||
import { GraphColoring, GraphSizing, HelpTopic } from '@/models/miscellaneous';
|
import { GraphColoring, GraphSizing, HelpTopic } from '@/models/miscellaneous';
|
||||||
|
import { IRSForm } from '@/models/rsform';
|
||||||
import { mapLabelColoring, mapLabelLayout, mapLabelSizing } from '@/utils/labels';
|
import { mapLabelColoring, mapLabelLayout, mapLabelSizing } from '@/utils/labels';
|
||||||
import { SelectorGraphColoring, SelectorGraphLayout, SelectorGraphSizing } from '@/utils/selectors';
|
import { SelectorGraphColoring, SelectorGraphLayout, SelectorGraphSizing } from '@/utils/selectors';
|
||||||
|
|
||||||
|
import SchemasGuide from './SchemasGuide';
|
||||||
|
|
||||||
interface GraphSelectorsProps {
|
interface GraphSelectorsProps {
|
||||||
|
schema?: IRSForm;
|
||||||
coloring: GraphColoring;
|
coloring: GraphColoring;
|
||||||
layout: GraphLayout;
|
layout: GraphLayout;
|
||||||
sizing: GraphSizing;
|
sizing: GraphSizing;
|
||||||
|
@ -16,7 +20,7 @@ interface GraphSelectorsProps {
|
||||||
setSizing: (newValue: GraphSizing) => void;
|
setSizing: (newValue: GraphSizing) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function GraphSelectors({ coloring, setColoring, layout, setLayout, sizing, setSizing }: GraphSelectorsProps) {
|
function GraphSelectors({ schema, coloring, setColoring, layout, setLayout, sizing, setSizing }: GraphSelectorsProps) {
|
||||||
return (
|
return (
|
||||||
<div className='border rounded-b-none select-none clr-input rounded-t-md'>
|
<div className='border rounded-b-none select-none clr-input rounded-t-md'>
|
||||||
<SelectSingle
|
<SelectSingle
|
||||||
|
@ -30,6 +34,7 @@ function GraphSelectors({ coloring, setColoring, layout, setLayout, sizing, setS
|
||||||
<Overlay position='right-[2.5rem] top-[0.5rem]'>
|
<Overlay position='right-[2.5rem] top-[0.5rem]'>
|
||||||
{coloring === 'status' ? <BadgeHelp topic={HelpTopic.UI_CST_STATUS} className='min-w-[25rem]' /> : null}
|
{coloring === 'status' ? <BadgeHelp topic={HelpTopic.UI_CST_STATUS} className='min-w-[25rem]' /> : null}
|
||||||
{coloring === 'type' ? <BadgeHelp topic={HelpTopic.UI_CST_CLASS} className='min-w-[25rem]' /> : null}
|
{coloring === 'type' ? <BadgeHelp topic={HelpTopic.UI_CST_CLASS} className='min-w-[25rem]' /> : null}
|
||||||
|
{coloring === 'schemas' && !!schema ? <SchemasGuide schema={schema} /> : null}
|
||||||
</Overlay>
|
</Overlay>
|
||||||
<SelectSingle
|
<SelectSingle
|
||||||
className='my-1'
|
className='my-1'
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { IconHelp } from '@/components/Icons';
|
||||||
|
import Tooltip from '@/components/ui/Tooltip';
|
||||||
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
||||||
|
import { useLibrary } from '@/context/LibraryContext';
|
||||||
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
import { IRSForm } from '@/models/rsform';
|
||||||
|
import { colorBgSchemas } from '@/styling/color';
|
||||||
|
import { globals, prefixes } from '@/utils/constants';
|
||||||
|
|
||||||
|
interface SchemasGuideProps {
|
||||||
|
schema: IRSForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SchemasGuide({ schema }: SchemasGuideProps) {
|
||||||
|
const { colors } = useConceptOptions();
|
||||||
|
const library = useLibrary();
|
||||||
|
|
||||||
|
const schemas = useMemo(() => {
|
||||||
|
const processed = new Set<LibraryItemID>();
|
||||||
|
const aliases: string[] = [];
|
||||||
|
const indexes: number[] = [];
|
||||||
|
schema.items.forEach(cst => {
|
||||||
|
if (cst.parent_schema && !processed.has(cst.parent_schema)) {
|
||||||
|
const item = library.items.find(item => item.id === cst.parent_schema);
|
||||||
|
if (item) {
|
||||||
|
aliases.push(item.alias);
|
||||||
|
} else {
|
||||||
|
aliases.push(`Схема ${cst.parent_schema_index}`);
|
||||||
|
}
|
||||||
|
processed.add(cst.parent_schema);
|
||||||
|
indexes.push(cst.parent_schema_index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const result: string[] = [];
|
||||||
|
for (let i = 1; i <= aliases.length; i++) {
|
||||||
|
const trueIndex = indexes.findIndex(index => index === i);
|
||||||
|
result.push(aliases[trueIndex]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}, [schema, library.items]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div tabIndex={-1} id={globals.graph_schemas} className='p-1'>
|
||||||
|
<IconHelp size='1.25rem' className='icon-primary' />
|
||||||
|
<Tooltip
|
||||||
|
anchorSelect={`#${globals.graph_schemas}`}
|
||||||
|
layer='z-modalTooltip'
|
||||||
|
place='right'
|
||||||
|
className='max-w-[25rem] break-words text-base'
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
className='min-w-[0.6rem] min-h-[0.6rem] border inline-block mr-1 rounded-full'
|
||||||
|
style={{ backgroundColor: colorBgSchemas(0, colors) }}
|
||||||
|
/>
|
||||||
|
Текущая схема
|
||||||
|
</div>
|
||||||
|
{schemas.map((alias, index) => (
|
||||||
|
<div key={`${prefixes.schemas_list}${index}`}>
|
||||||
|
<span
|
||||||
|
className='min-w-[0.6rem] min-h-[0.6rem] border inline-block mr-1 rounded-full'
|
||||||
|
style={{ backgroundColor: colorBgSchemas(index + 1, colors) }}
|
||||||
|
/>
|
||||||
|
{alias}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SchemasGuide;
|
|
@ -1,6 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { RefObject, useCallback, useLayoutEffect, useMemo } from 'react';
|
import { RefObject, useCallback, useLayoutEffect } from 'react';
|
||||||
|
|
||||||
import GraphUI, {
|
import GraphUI, {
|
||||||
CollapseProps,
|
CollapseProps,
|
||||||
|
@ -107,12 +107,8 @@ function TermGraph({
|
||||||
setSelections(newSelections);
|
setSelections(newSelections);
|
||||||
}, [selectedIDs, setSelections, nodes]);
|
}, [selectedIDs, setSelections, nodes]);
|
||||||
|
|
||||||
const canvasWidth = useMemo(() => {
|
|
||||||
return 'calc(100vw - 1rem)';
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='relative outline-none' style={{ width: canvasWidth, height: mainHeight }}>
|
<div className='relative outline-none w-[100dvw]' style={{ height: mainHeight }}>
|
||||||
<GraphUI
|
<GraphUI
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
|
|
|
@ -45,7 +45,7 @@ function useGraphFilter(schema: IRSForm | undefined, params: GraphFilterParams,
|
||||||
}
|
}
|
||||||
if (!focusCst && params.foldDerived) {
|
if (!focusCst && params.foldDerived) {
|
||||||
schema.items.forEach(cst => {
|
schema.items.forEach(cst => {
|
||||||
if (cst.parent) {
|
if (cst.spawner) {
|
||||||
graph.foldNode(cst.id);
|
graph.foldNode(cst.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -53,7 +53,7 @@ function useGraphFilter(schema: IRSForm | undefined, params: GraphFilterParams,
|
||||||
if (focusCst) {
|
if (focusCst) {
|
||||||
const includes: ConstituentaID[] = [
|
const includes: ConstituentaID[] = [
|
||||||
focusCst.id,
|
focusCst.id,
|
||||||
...focusCst.children,
|
...focusCst.spawn,
|
||||||
...(params.focusShowInputs ? schema.graph.expandInputs([focusCst.id]) : []),
|
...(params.focusShowInputs ? schema.graph.expandInputs([focusCst.id]) : []),
|
||||||
...(params.focusShowOutputs ? schema.graph.expandOutputs([focusCst.id]) : [])
|
...(params.focusShowOutputs ? schema.graph.expandOutputs([focusCst.id]) : [])
|
||||||
];
|
];
|
||||||
|
|
|
@ -109,13 +109,13 @@ function TableSideConstituents({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
when: (cst: IConstituenta) => !!activeCst && cst.parent === activeCst?.id && cst.id !== activeCst?.id,
|
when: (cst: IConstituenta) => !!activeCst && cst.spawner === activeCst?.id && cst.id !== activeCst?.id,
|
||||||
style: {
|
style: {
|
||||||
backgroundColor: colors.bgOrange50
|
backgroundColor: colors.bgOrange50
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
when: (cst: IConstituenta) => activeCst?.id !== undefined && cst.children.includes(activeCst.id),
|
when: (cst: IConstituenta) => activeCst?.id !== undefined && cst.spawn.includes(activeCst.id),
|
||||||
style: {
|
style: {
|
||||||
backgroundColor: colors.bgGreen50
|
backgroundColor: colors.bgGreen50
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,6 +416,23 @@ export function colorBgCstClass(cstClass: CstClass, colors: IColorTheme): string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines background color for {@link IConstituenta} depending on its parent schema index.
|
||||||
|
*/
|
||||||
|
export function colorBgSchemas(schema_index: number, colors: IColorTheme): string {
|
||||||
|
if (schema_index === 0) {
|
||||||
|
return colors.bgGreen;
|
||||||
|
}
|
||||||
|
// prettier-ignore
|
||||||
|
switch (schema_index % 4) {
|
||||||
|
case 1: return colors.bgPurple;
|
||||||
|
case 2: return colors.bgOrange;
|
||||||
|
case 3: return colors.bgTeal;
|
||||||
|
case 0: return colors.bgBlue;
|
||||||
|
}
|
||||||
|
return colors.bgBlue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines background color for {@link GramData}.
|
* Determines background color for {@link GramData}.
|
||||||
*/
|
*/
|
||||||
|
@ -462,5 +479,8 @@ export function colorBgGraphNode(cst: IConstituenta, coloringScheme: GraphColori
|
||||||
if (coloringScheme === 'status') {
|
if (coloringScheme === 'status') {
|
||||||
return colorBgCstStatus(cst.status, colors);
|
return colorBgCstStatus(cst.status, colors);
|
||||||
}
|
}
|
||||||
|
if (coloringScheme === 'schemas') {
|
||||||
|
return colorBgSchemas(cst.parent_schema_index, colors);
|
||||||
|
}
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,15 +215,15 @@ export function domTooltipConstituenta(cst?: IConstituenta, canClick?: boolean):
|
||||||
dom.appendChild(convention);
|
dom.appendChild(convention);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cst.parent_alias) {
|
if (cst.spawner_alias) {
|
||||||
const derived = document.createElement('p');
|
const derived = document.createElement('p');
|
||||||
derived.innerHTML = `<b>Основание:</b> ${cst.parent_alias}`;
|
derived.innerHTML = `<b>Основание:</b> ${cst.spawner_alias}`;
|
||||||
dom.appendChild(derived);
|
dom.appendChild(derived);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cst.children_alias.length > 0) {
|
if (cst.spawn_alias.length > 0) {
|
||||||
const children = document.createElement('p');
|
const children = document.createElement('p');
|
||||||
children.innerHTML = `<b>Порождает:</b> ${cst.children_alias.join(', ')}`;
|
children.innerHTML = `<b>Порождает:</b> ${cst.spawn_alias.join(', ')}`;
|
||||||
dom.appendChild(children);
|
dom.appendChild(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,8 @@ export const globals = {
|
||||||
email_tooltip: 'email_tooltip',
|
email_tooltip: 'email_tooltip',
|
||||||
main_scroll: 'main_scroll',
|
main_scroll: 'main_scroll',
|
||||||
library_item_editor: 'library_item_editor',
|
library_item_editor: 'library_item_editor',
|
||||||
constituenta_editor: 'constituenta_editor'
|
constituenta_editor: 'constituenta_editor',
|
||||||
|
graph_schemas: 'graph_schemas_tooltip'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,6 +166,7 @@ export const prefixes = {
|
||||||
cst_source_list: 'cst_source_list_',
|
cst_source_list: 'cst_source_list_',
|
||||||
cst_delete_list: 'cst_delete_list_',
|
cst_delete_list: 'cst_delete_list_',
|
||||||
cst_dependant_list: 'cst_dependant_list_',
|
cst_dependant_list: 'cst_dependant_list_',
|
||||||
|
schemas_list: 'schemas_list_',
|
||||||
operation_list: 'operation_list_',
|
operation_list: 'operation_list_',
|
||||||
csttype_list: 'csttype_',
|
csttype_list: 'csttype_',
|
||||||
policy_list: 'policy_list_',
|
policy_list: 'policy_list_',
|
||||||
|
|
|
@ -315,7 +315,8 @@ export const mapLabelLayout = new Map<GraphLayout, string>([
|
||||||
export const mapLabelColoring = new Map<GraphColoring, string>([
|
export const mapLabelColoring = new Map<GraphColoring, string>([
|
||||||
['none', 'Цвет: Моно'],
|
['none', 'Цвет: Моно'],
|
||||||
['status', 'Цвет: Статус'],
|
['status', 'Цвет: Статус'],
|
||||||
['type', 'Цвет: Класс']
|
['type', 'Цвет: Класс'],
|
||||||
|
['schemas', 'Цвет: Схемы']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user