From 90dcf7a8eb61ccce1e00e767533bc76dac9b5a4d Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Thu, 25 Jul 2024 19:12:31 +0300 Subject: [PATCH] R: restructure backend Warning! This will reset database migrations. Data should be imported manually --- rsconcept/backend/apps/library/__init__.py | 0 rsconcept/backend/apps/library/admin.py | 62 + rsconcept/backend/apps/library/apps.py | 8 + .../apps/library/migrations/0001_initial.py | 92 + .../apps/library/migrations/__init__.py | 0 .../apps/{rsform => library}/models/Editor.py | 2 +- .../{rsform => library}/models/LibraryItem.py | 3 +- .../models/LibraryTemplate.py | 2 +- .../models/Subscription.py | 2 +- .../{rsform => library}/models/Version.py | 2 +- .../backend/apps/library/models/__init__.py | 7 + .../apps/library/serializers/__init__.py | 14 + .../apps/library/serializers/basics.py | 32 + .../apps/library/serializers/data_access.py | 94 + .../apps/library/serializers/responses.py | 8 + .../backend/apps/library/tests/__init__.py | 3 + .../apps/library/tests/s_models/__init__.py | 4 + .../tests/s_models/t_Editor.py | 6 +- .../tests/s_models/t_LibraryItem.py | 4 +- .../tests/s_models/t_Subscription.py | 3 +- .../apps/library/tests/s_views/__init__.py | 3 + .../tests/s_views/t_library.py | 25 +- .../tests/s_views/t_versions.py | 70 +- rsconcept/backend/apps/library/urls.py | 21 + .../backend/apps/library/views/__init__.py | 3 + .../apps/{rsform => library}/views/library.py | 21 +- .../{rsform => library}/views/versions.py | 158 +- rsconcept/backend/apps/oss/admin.py | 2 +- rsconcept/backend/apps/oss/apps.py | 2 +- .../apps/oss/migrations/0001_initial.py | 32 +- ...002_operationschema_alter_operation_oss.py | 31 - ...ration_sync_text_alter_operation_result.py | 25 - .../backend/apps/oss/models/Inheritance.py | 32 + .../backend/apps/oss/models/Operation.py | 4 +- .../apps/oss/models/OperationSchema.py | 54 +- ...nthesisSubstitution.py => Substitution.py} | 4 +- rsconcept/backend/apps/oss/models/__init__.py | 4 +- .../backend/apps/oss/serializers/__init__.py | 4 +- .../apps/oss/serializers/data_access.py | 15 +- .../{schema_typing.py => responses.py} | 0 .../apps/oss/tests/s_models/__init__.py | 2 +- .../apps/oss/tests/s_models/t_Argument.py | 20 +- .../apps/oss/tests/s_models/t_Operation.py | 33 +- ...hesisSubstitution.py => t_Substitution.py} | 48 +- .../backend/apps/oss/tests/s_views/t_oss.py | 49 +- rsconcept/backend/apps/oss/urls.py | 6 +- rsconcept/backend/apps/oss/views/oss.py | 39 +- rsconcept/backend/apps/rsform/admin.py | 56 - .../apps/rsform/migrations/0001_initial.py | 48 +- .../rsform/migrations/0002_librarytemplate.py | 25 - ...er_constituenta_definition_raw_and_more.py | 23 - .../apps/rsform/migrations/0004_version.py | 30 - ...scription_options_alter_version_options.py | 21 - .../apps/rsform/migrations/0006_editor.py | 30 - .../migrations/0007_location_and_flags.py | 65 - .../0008_alter_libraryitem_item_type.py | 18 - ...form_alter_constituenta_schema_and_more.py | 35 - .../apps/rsform/models/Constituenta.py | 8 +- .../backend/apps/rsform/models/RSForm.py | 51 +- .../backend/apps/rsform/models/__init__.py | 14 +- .../apps/rsform/serializers/__init__.py | 19 +- .../backend/apps/rsform/serializers/basics.py | 30 - .../apps/rsform/serializers/data_access.py | 131 +- .../apps/rsform/serializers/io_files.py | 19 +- .../{schema_typing.py => responses.py} | 6 - .../apps/rsform/tests/s_models/__init__.py | 3 - .../rsform/tests/s_models/t_Constituenta.py | 20 +- .../apps/rsform/tests/s_models/t_RSForm.py | 33 +- .../apps/rsform/tests/s_views/__init__.py | 5 +- .../rsform/tests/s_views/t_constituents.py | 10 +- .../apps/rsform/tests/s_views/t_operations.py | 18 +- .../apps/rsform/tests/s_views/t_rsforms.py | 63 +- rsconcept/backend/apps/rsform/urls.py | 10 +- rsconcept/backend/apps/rsform/utils.py | 20 - .../backend/apps/rsform/views/__init__.py | 2 - .../backend/apps/rsform/views/operations.py | 10 +- .../backend/apps/rsform/views/rsforms.py | 121 +- rsconcept/backend/apps/users/serializers.py | 2 +- rsconcept/backend/fixtures/InitialData.json | 7356 ++++++++--------- rsconcept/backend/project/settings.py | 1 + rsconcept/backend/project/urls.py | 1 + rsconcept/backend/shared/EndpointTester.py | 2 +- rsconcept/backend/shared/permissions.py | 10 +- rsconcept/backend/shared/testing_utils.py | 2 +- rsconcept/backend/shared/utility.py | 21 + rsconcept/frontend/src/backend/library.ts | 12 +- rsconcept/frontend/src/backend/rsforms.ts | 14 +- .../frontend/src/context/RSFormContext.tsx | 4 +- 88 files changed, 4639 insertions(+), 4785 deletions(-) create mode 100644 rsconcept/backend/apps/library/__init__.py create mode 100644 rsconcept/backend/apps/library/admin.py create mode 100644 rsconcept/backend/apps/library/apps.py create mode 100644 rsconcept/backend/apps/library/migrations/0001_initial.py create mode 100644 rsconcept/backend/apps/library/migrations/__init__.py rename rsconcept/backend/apps/{rsform => library}/models/Editor.py (98%) rename rsconcept/backend/apps/{rsform => library}/models/LibraryItem.py (98%) rename rsconcept/backend/apps/{rsform => library}/models/LibraryTemplate.py (92%) rename rsconcept/backend/apps/{rsform => library}/models/Subscription.py (97%) rename rsconcept/backend/apps/{rsform => library}/models/Version.py (96%) create mode 100644 rsconcept/backend/apps/library/models/__init__.py create mode 100644 rsconcept/backend/apps/library/serializers/__init__.py create mode 100644 rsconcept/backend/apps/library/serializers/basics.py create mode 100644 rsconcept/backend/apps/library/serializers/data_access.py create mode 100644 rsconcept/backend/apps/library/serializers/responses.py create mode 100644 rsconcept/backend/apps/library/tests/__init__.py create mode 100644 rsconcept/backend/apps/library/tests/s_models/__init__.py rename rsconcept/backend/apps/{rsform => library}/tests/s_models/t_Editor.py (92%) rename rsconcept/backend/apps/{rsform => library}/tests/s_models/t_LibraryItem.py (98%) rename rsconcept/backend/apps/{rsform => library}/tests/s_models/t_Subscription.py (95%) create mode 100644 rsconcept/backend/apps/library/tests/s_views/__init__.py rename rsconcept/backend/apps/{rsform => library}/tests/s_views/t_library.py (95%) rename rsconcept/backend/apps/{rsform => library}/tests/s_views/t_versions.py (83%) create mode 100644 rsconcept/backend/apps/library/urls.py create mode 100644 rsconcept/backend/apps/library/views/__init__.py rename rsconcept/backend/apps/{rsform => library}/views/library.py (94%) rename rsconcept/backend/apps/{rsform => library}/views/versions.py (80%) delete mode 100644 rsconcept/backend/apps/oss/migrations/0002_operationschema_alter_operation_oss.py delete mode 100644 rsconcept/backend/apps/oss/migrations/0003_operation_sync_text_alter_operation_result.py create mode 100644 rsconcept/backend/apps/oss/models/Inheritance.py rename rsconcept/backend/apps/oss/models/{SynthesisSubstitution.py => Substitution.py} (93%) rename rsconcept/backend/apps/oss/serializers/{schema_typing.py => responses.py} (100%) rename rsconcept/backend/apps/oss/tests/s_models/{t_SynthesisSubstitution.py => t_Substitution.py} (54%) delete mode 100644 rsconcept/backend/apps/rsform/migrations/0002_librarytemplate.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0003_alter_constituenta_definition_raw_and_more.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0004_version.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0005_alter_subscription_options_alter_version_options.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0006_editor.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0007_location_and_flags.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py delete mode 100644 rsconcept/backend/apps/rsform/migrations/0009_rsform_alter_constituenta_schema_and_more.py rename rsconcept/backend/apps/rsform/serializers/{schema_typing.py => responses.py} (80%) create mode 100644 rsconcept/backend/shared/utility.py diff --git a/rsconcept/backend/apps/library/__init__.py b/rsconcept/backend/apps/library/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rsconcept/backend/apps/library/admin.py b/rsconcept/backend/apps/library/admin.py new file mode 100644 index 00000000..70a87062 --- /dev/null +++ b/rsconcept/backend/apps/library/admin.py @@ -0,0 +1,62 @@ +''' Admin view: Library. ''' +from django.contrib import admin + +from . import models + + +class LibraryItemAdmin(admin.ModelAdmin): + ''' Admin model: LibraryItem. ''' + date_hierarchy = 'time_update' + list_display = [ + 'alias', 'title', 'owner', + 'visible', 'read_only', 'access_policy', 'location', + 'time_update' + ] + list_filter = ['visible', 'read_only', 'access_policy', 'location', 'time_update'] + search_fields = ['alias', 'title', 'location'] + + +class LibraryTemplateAdmin(admin.ModelAdmin): + ''' Admin model: LibraryTemplate. ''' + list_display = ['id', 'alias'] + list_select_related = ['lib_source'] + + def alias(self, template: models.LibraryTemplate): + if template.lib_source: + return template.lib_source.alias + else: + return 'N/A' + + +class SubscriptionAdmin(admin.ModelAdmin): + ''' Admin model: Subscriptions. ''' + list_display = ['id', 'item', 'user'] + search_fields = [ + 'item__title', 'item__alias', + 'user__username', 'user__first_name', 'user__last_name' + ] + + +class EditorAdmin(admin.ModelAdmin): + ''' Admin model: Editors. ''' + list_display = ['id', 'item', 'editor'] + search_fields = [ + 'item__title', 'item__alias', + 'editor__username', 'editor__first_name', 'editor__last_name' + ] + + +class VersionAdmin(admin.ModelAdmin): + ''' Admin model: Versions. ''' + list_display = ['id', 'item', 'version', 'description', 'time_create'] + search_fields = [ + 'item__title', 'item__alias' + ] + + + +admin.site.register(models.LibraryItem, LibraryItemAdmin) +admin.site.register(models.LibraryTemplate, LibraryTemplateAdmin) +admin.site.register(models.Subscription, SubscriptionAdmin) +admin.site.register(models.Version, VersionAdmin) +admin.site.register(models.Editor, EditorAdmin) diff --git a/rsconcept/backend/apps/library/apps.py b/rsconcept/backend/apps/library/apps.py new file mode 100644 index 00000000..d18ce807 --- /dev/null +++ b/rsconcept/backend/apps/library/apps.py @@ -0,0 +1,8 @@ +''' Application: Operation Schema. ''' +from django.apps import AppConfig + + +class RsformConfig(AppConfig): + ''' Application config. ''' + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.library' diff --git a/rsconcept/backend/apps/library/migrations/0001_initial.py b/rsconcept/backend/apps/library/migrations/0001_initial.py new file mode 100644 index 00000000..33dd9e40 --- /dev/null +++ b/rsconcept/backend/apps/library/migrations/0001_initial.py @@ -0,0 +1,92 @@ +# Generated by Django 5.0.7 on 2024-07-25 16:06 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='LibraryItem', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item_type', models.CharField(choices=[('rsform', 'Rsform'), ('oss', 'Operation Schema')], default='rsform', max_length=50, verbose_name='Тип')), + ('title', models.TextField(verbose_name='Название')), + ('alias', models.CharField(blank=True, max_length=255, verbose_name='Шифр')), + ('comment', models.TextField(blank=True, verbose_name='Комментарий')), + ('visible', models.BooleanField(default=True, verbose_name='Отображаемая')), + ('read_only', models.BooleanField(default=False, verbose_name='Запретить редактирование')), + ('access_policy', models.CharField(choices=[('public', 'Public'), ('protected', 'Protected'), ('private', 'Private')], default='public', max_length=500, verbose_name='Политика доступа')), + ('location', models.TextField(default='/U', max_length=500, verbose_name='Расположение')), + ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), + ('time_update', models.DateTimeField(auto_now=True, verbose_name='Дата изменения')), + ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Владелец')), + ], + options={ + 'verbose_name': 'Схема', + 'verbose_name_plural': 'Схемы', + }, + ), + migrations.CreateModel( + name='LibraryTemplate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('lib_source', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='library.libraryitem', verbose_name='Источник')), + ], + options={ + 'verbose_name': 'Шаблон', + 'verbose_name_plural': 'Шаблоны', + }, + ), + migrations.CreateModel( + name='Editor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата добавления')), + ('editor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Редактор')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library.libraryitem', verbose_name='Схема')), + ], + options={ + 'verbose_name': 'Редактор', + 'verbose_name_plural': 'Редакторы', + 'unique_together': {('item', 'editor')}, + }, + ), + migrations.CreateModel( + name='Subscription', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library.libraryitem', verbose_name='Элемент')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')), + ], + options={ + 'verbose_name': 'Подписка', + 'verbose_name_plural': 'Подписки', + 'unique_together': {('user', 'item')}, + }, + ), + migrations.CreateModel( + name='Version', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('version', models.CharField(max_length=20, verbose_name='Версия')), + ('description', models.TextField(blank=True, verbose_name='Описание')), + ('data', models.JSONField(verbose_name='Содержание')), + ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library.libraryitem', verbose_name='Схема')), + ], + options={ + 'verbose_name': 'Версия', + 'verbose_name_plural': 'Версии', + 'unique_together': {('item', 'version')}, + }, + ), + ] diff --git a/rsconcept/backend/apps/library/migrations/__init__.py b/rsconcept/backend/apps/library/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rsconcept/backend/apps/rsform/models/Editor.py b/rsconcept/backend/apps/library/models/Editor.py similarity index 98% rename from rsconcept/backend/apps/rsform/models/Editor.py rename to rsconcept/backend/apps/library/models/Editor.py index d43ae17c..16656250 100644 --- a/rsconcept/backend/apps/rsform/models/Editor.py +++ b/rsconcept/backend/apps/library/models/Editor.py @@ -14,7 +14,7 @@ class Editor(Model): ''' Editor list. ''' item: ForeignKey = ForeignKey( verbose_name='Схема', - to='rsform.LibraryItem', + to='library.LibraryItem', on_delete=CASCADE ) editor: ForeignKey = ForeignKey( diff --git a/rsconcept/backend/apps/rsform/models/LibraryItem.py b/rsconcept/backend/apps/library/models/LibraryItem.py similarity index 98% rename from rsconcept/backend/apps/rsform/models/LibraryItem.py rename to rsconcept/backend/apps/library/models/LibraryItem.py index 11f5f90e..e72757ae 100644 --- a/rsconcept/backend/apps/rsform/models/LibraryItem.py +++ b/rsconcept/backend/apps/library/models/LibraryItem.py @@ -54,7 +54,8 @@ class LibraryItem(Model): item_type: CharField = CharField( verbose_name='Тип', max_length=50, - choices=LibraryItemType.choices + choices=LibraryItemType.choices, + default=LibraryItemType.RSFORM ) owner: ForeignKey = ForeignKey( verbose_name='Владелец', diff --git a/rsconcept/backend/apps/rsform/models/LibraryTemplate.py b/rsconcept/backend/apps/library/models/LibraryTemplate.py similarity index 92% rename from rsconcept/backend/apps/rsform/models/LibraryTemplate.py rename to rsconcept/backend/apps/library/models/LibraryTemplate.py index a38e4f67..d454f1b3 100644 --- a/rsconcept/backend/apps/rsform/models/LibraryTemplate.py +++ b/rsconcept/backend/apps/library/models/LibraryTemplate.py @@ -6,7 +6,7 @@ class LibraryTemplate(Model): ''' Template for library items and constituents. ''' lib_source: ForeignKey = ForeignKey( verbose_name='Источник', - to='rsform.RSForm', + to='library.LibraryItem', on_delete=CASCADE, null=True ) diff --git a/rsconcept/backend/apps/rsform/models/Subscription.py b/rsconcept/backend/apps/library/models/Subscription.py similarity index 97% rename from rsconcept/backend/apps/rsform/models/Subscription.py rename to rsconcept/backend/apps/library/models/Subscription.py index 6199ad38..a57499f9 100644 --- a/rsconcept/backend/apps/rsform/models/Subscription.py +++ b/rsconcept/backend/apps/library/models/Subscription.py @@ -18,7 +18,7 @@ class Subscription(Model): ) item: ForeignKey = ForeignKey( verbose_name='Элемент', - to='rsform.LibraryItem', + to='library.LibraryItem', on_delete=CASCADE ) diff --git a/rsconcept/backend/apps/rsform/models/Version.py b/rsconcept/backend/apps/library/models/Version.py similarity index 96% rename from rsconcept/backend/apps/rsform/models/Version.py rename to rsconcept/backend/apps/library/models/Version.py index 0f9174fc..c12f3315 100644 --- a/rsconcept/backend/apps/rsform/models/Version.py +++ b/rsconcept/backend/apps/library/models/Version.py @@ -14,7 +14,7 @@ class Version(Model): ''' Library item version archive. ''' item: ForeignKey = ForeignKey( verbose_name='Схема', - to='rsform.LibraryItem', + to='library.LibraryItem', on_delete=CASCADE ) version = CharField( diff --git a/rsconcept/backend/apps/library/models/__init__.py b/rsconcept/backend/apps/library/models/__init__.py new file mode 100644 index 00000000..5c71dcba --- /dev/null +++ b/rsconcept/backend/apps/library/models/__init__.py @@ -0,0 +1,7 @@ +''' Django: Models. ''' + +from .Editor import Editor +from .LibraryItem import AccessPolicy, LibraryItem, LibraryItemType, LocationHead, validate_location +from .LibraryTemplate import LibraryTemplate +from .Subscription import Subscription +from .Version import Version diff --git a/rsconcept/backend/apps/library/serializers/__init__.py b/rsconcept/backend/apps/library/serializers/__init__.py new file mode 100644 index 00000000..3347a3cf --- /dev/null +++ b/rsconcept/backend/apps/library/serializers/__init__.py @@ -0,0 +1,14 @@ +''' REST API: Serializers. ''' + +from .basics import AccessPolicySerializer, LocationSerializer +from .data_access import ( + LibraryItemBaseSerializer, + LibraryItemCloneSerializer, + LibraryItemDetailsSerializer, + LibraryItemSerializer, + UsersListSerializer, + UserTargetSerializer, + VersionCreateSerializer, + VersionSerializer +) +from .responses import NewVersionResponse diff --git a/rsconcept/backend/apps/library/serializers/basics.py b/rsconcept/backend/apps/library/serializers/basics.py new file mode 100644 index 00000000..adf623b8 --- /dev/null +++ b/rsconcept/backend/apps/library/serializers/basics.py @@ -0,0 +1,32 @@ +''' Basic serializers that do not interact with database. ''' +from rest_framework import serializers + +from shared import messages as msg + +from ..models import AccessPolicy, validate_location + + +class LocationSerializer(serializers.Serializer): + ''' Serializer: Item location. ''' + location = serializers.CharField(max_length=500) + + def validate(self, attrs): + attrs = super().validate(attrs) + if not validate_location(attrs['location']): + raise serializers.ValidationError({ + 'location': msg.invalidLocation() + }) + return attrs + + +class AccessPolicySerializer(serializers.Serializer): + ''' Serializer: Constituenta renaming. ''' + access_policy = serializers.CharField() + + def validate(self, attrs): + attrs = super().validate(attrs) + if not attrs['access_policy'] in AccessPolicy.values: + raise serializers.ValidationError({ + 'access_policy': msg.invalidEnum(attrs['access_policy']) + }) + return attrs diff --git a/rsconcept/backend/apps/library/serializers/data_access.py b/rsconcept/backend/apps/library/serializers/data_access.py new file mode 100644 index 00000000..b91c37fa --- /dev/null +++ b/rsconcept/backend/apps/library/serializers/data_access.py @@ -0,0 +1,94 @@ +''' Serializers for persistent data manipulation. ''' +from django.contrib.auth.models import User +from rest_framework import serializers +from rest_framework.serializers import PrimaryKeyRelatedField as PKField + +from apps.rsform.models import Constituenta + +from ..models import LibraryItem, Version + + +class LibraryItemBaseSerializer(serializers.ModelSerializer): + ''' Serializer: LibraryItem entry full access. ''' + class Meta: + ''' serializer metadata. ''' + model = LibraryItem + fields = '__all__' + read_only_fields = ('id',) + + +class LibraryItemSerializer(serializers.ModelSerializer): + ''' Serializer: LibraryItem entry limited access. ''' + class Meta: + ''' serializer metadata. ''' + model = LibraryItem + fields = '__all__' + read_only_fields = ('id', 'item_type', 'owner', 'location', 'access_policy') + + +class LibraryItemCloneSerializer(serializers.ModelSerializer): + ''' Serializer: LibraryItem cloning. ''' + items = PKField(many=True, required=False, queryset=Constituenta.objects.all()) + + class Meta: + ''' serializer metadata. ''' + model = LibraryItem + exclude = ['id', 'item_type', 'owner'] + + +class VersionSerializer(serializers.ModelSerializer): + ''' Serializer: Version data. ''' + class Meta: + ''' serializer metadata. ''' + model = Version + fields = 'id', 'version', 'item', 'description', 'time_create' + read_only_fields = ('id', 'item', 'time_create') + + +class VersionInnerSerializer(serializers.ModelSerializer): + ''' Serializer: Version data for list of versions. ''' + class Meta: + ''' serializer metadata. ''' + model = Version + fields = 'id', 'version', 'description', 'time_create' + read_only_fields = ('id', 'item', 'time_create') + + +class VersionCreateSerializer(serializers.ModelSerializer): + ''' Serializer: Version create data. ''' + class Meta: + ''' serializer metadata. ''' + model = Version + fields = 'version', 'description' + + +class LibraryItemDetailsSerializer(serializers.ModelSerializer): + ''' Serializer: LibraryItem detailed data. ''' + subscribers = serializers.SerializerMethodField() + editors = serializers.SerializerMethodField() + versions = serializers.SerializerMethodField() + + class Meta: + ''' serializer metadata. ''' + model = LibraryItem + fields = '__all__' + read_only_fields = ('owner', 'id', 'item_type') + + def get_subscribers(self, instance: LibraryItem) -> list[int]: + return [item.pk for item in instance.subscribers()] + + def get_editors(self, instance: LibraryItem) -> list[int]: + return [item.pk for item in instance.editors()] + + def get_versions(self, instance: LibraryItem) -> list: + return [VersionInnerSerializer(item).data for item in instance.versions()] + + +class UserTargetSerializer(serializers.Serializer): + ''' Serializer: Target single User. ''' + user = PKField(many=False, queryset=User.objects.all()) + + +class UsersListSerializer(serializers.Serializer): + ''' Serializer: List of Users. ''' + users = PKField(many=True, queryset=User.objects.all()) diff --git a/rsconcept/backend/apps/library/serializers/responses.py b/rsconcept/backend/apps/library/serializers/responses.py new file mode 100644 index 00000000..347a3df6 --- /dev/null +++ b/rsconcept/backend/apps/library/serializers/responses.py @@ -0,0 +1,8 @@ +''' Utility serializers for REST API schema - SHOULD NOT BE ACCESSED DIRECTLY. ''' +from rest_framework import serializers + + +class NewVersionResponse(serializers.Serializer): + ''' Serializer: Create version response. ''' + version = serializers.IntegerField() + schema = serializers.JSONField() diff --git a/rsconcept/backend/apps/library/tests/__init__.py b/rsconcept/backend/apps/library/tests/__init__.py new file mode 100644 index 00000000..a27a6767 --- /dev/null +++ b/rsconcept/backend/apps/library/tests/__init__.py @@ -0,0 +1,3 @@ +''' Tests. ''' +from .s_models import * +from .s_views import * diff --git a/rsconcept/backend/apps/library/tests/s_models/__init__.py b/rsconcept/backend/apps/library/tests/s_models/__init__.py new file mode 100644 index 00000000..d95b4745 --- /dev/null +++ b/rsconcept/backend/apps/library/tests/s_models/__init__.py @@ -0,0 +1,4 @@ +''' Tests for Django Models. ''' +from .t_Editor import * +from .t_LibraryItem import * +from .t_Subscription import * diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_Editor.py b/rsconcept/backend/apps/library/tests/s_models/t_Editor.py similarity index 92% rename from rsconcept/backend/apps/rsform/tests/s_models/t_Editor.py rename to rsconcept/backend/apps/library/tests/s_models/t_Editor.py index 1e64e645..b02b75f5 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/t_Editor.py +++ b/rsconcept/backend/apps/library/tests/s_models/t_Editor.py @@ -1,7 +1,8 @@ ''' Testing models: Editor. ''' from django.test import TestCase -from apps.rsform.models import Editor, LibraryItemType, RSForm, User +from apps.library.models import Editor, LibraryItem, LibraryItemType +from apps.users.models import User class TestEditor(TestCase): @@ -10,7 +11,8 @@ class TestEditor(TestCase): def setUp(self): self.user1 = User.objects.create(username='User1') self.user2 = User.objects.create(username='User2') - self.item = RSForm.objects.create( + self.item = LibraryItem.objects.create( + item_type=LibraryItemType.RSFORM, title='Test', alias='КС1', owner=self.user1 diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_LibraryItem.py b/rsconcept/backend/apps/library/tests/s_models/t_LibraryItem.py similarity index 98% rename from rsconcept/backend/apps/rsform/tests/s_models/t_LibraryItem.py rename to rsconcept/backend/apps/library/tests/s_models/t_LibraryItem.py index e9922a9c..2935a8f3 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/t_LibraryItem.py +++ b/rsconcept/backend/apps/library/tests/s_models/t_LibraryItem.py @@ -1,15 +1,15 @@ ''' Testing models: LibraryItem. ''' from django.test import TestCase -from apps.rsform.models import ( +from apps.library.models import ( AccessPolicy, LibraryItem, LibraryItemType, LocationHead, Subscription, - User, validate_location ) +from apps.users.models import User class TestLibraryItem(TestCase): diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_Subscription.py b/rsconcept/backend/apps/library/tests/s_models/t_Subscription.py similarity index 95% rename from rsconcept/backend/apps/rsform/tests/s_models/t_Subscription.py rename to rsconcept/backend/apps/library/tests/s_models/t_Subscription.py index 95ee8380..259c7ed9 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/t_Subscription.py +++ b/rsconcept/backend/apps/library/tests/s_models/t_Subscription.py @@ -1,7 +1,8 @@ ''' Testing models: Subscription. ''' from django.test import TestCase -from apps.rsform.models import LibraryItem, LibraryItemType, Subscription, User +from apps.library.models import LibraryItem, LibraryItemType, Subscription +from apps.users.models import User class TestSubscription(TestCase): diff --git a/rsconcept/backend/apps/library/tests/s_views/__init__.py b/rsconcept/backend/apps/library/tests/s_views/__init__.py new file mode 100644 index 00000000..8675f1f9 --- /dev/null +++ b/rsconcept/backend/apps/library/tests/s_views/__init__.py @@ -0,0 +1,3 @@ +''' Tests for REST API. ''' +from .t_library import * +from .t_versions import * diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py b/rsconcept/backend/apps/library/tests/s_views/t_library.py similarity index 95% rename from rsconcept/backend/apps/rsform/tests/s_views/t_library.py rename to rsconcept/backend/apps/library/tests/s_views/t_library.py index 6d48aa08..8482f9c5 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py +++ b/rsconcept/backend/apps/library/tests/s_views/t_library.py @@ -1,16 +1,16 @@ ''' Testing API: Library. ''' from rest_framework import status -from apps.rsform.models import ( +from apps.library.models import ( AccessPolicy, Editor, LibraryItem, LibraryItemType, LibraryTemplate, LocationHead, - RSForm, Subscription ) +from apps.rsform.models import RSForm from shared.EndpointTester import EndpointTester, decl_endpoint from shared.testing_utils import response_contains @@ -20,16 +20,16 @@ class TestLibraryViewset(EndpointTester): def setUp(self): super().setUp() - self.owned = RSForm.objects.create( + self.owned = LibraryItem.objects.create( title='Test', alias='T1', owner=self.user ) - self.unowned = RSForm.objects.create( + self.unowned = LibraryItem.objects.create( title='Test2', alias='T2' ) - self.common = RSForm.objects.create( + self.common = LibraryItem.objects.create( title='Test3', alias='T3', location=LocationHead.COMMON @@ -44,12 +44,16 @@ class TestLibraryViewset(EndpointTester): 'title': 'Title', 'alias': 'alias', } - self.executeBadData(data=data) + response = self.executeCreated(data=data) + self.assertEqual(response.data['owner'], self.user.pk) + self.assertEqual(response.data['item_type'], LibraryItemType.RSFORM) + self.assertEqual(response.data['title'], data['title']) + self.assertEqual(response.data['alias'], data['alias']) data = { 'item_type': LibraryItemType.OPERATION_SCHEMA, - 'title': 'Title', - 'alias': 'alias', + 'title': 'Title2', + 'alias': 'alias2', 'access_policy': AccessPolicy.PROTECTED, 'visible': False, 'read_only': True @@ -359,12 +363,13 @@ class TestLibraryViewset(EndpointTester): @decl_endpoint('/api/library/{item}/clone', method='post') def test_clone_rsform(self): - x12 = self.owned.insert_new( + schema = RSForm(self.owned) + x12 = schema.insert_new( alias='X12', term_raw='человек', term_resolved='человек' ) - d2 = self.owned.insert_new( + d2 = schema.insert_new( alias='D2', term_raw='@{X12|plur}', term_resolved='люди' diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py b/rsconcept/backend/apps/library/tests/s_views/t_versions.py similarity index 83% rename from rsconcept/backend/apps/rsform/tests/s_views/t_versions.py rename to rsconcept/backend/apps/library/tests/s_views/t_versions.py index 5ea85c49..2842773a 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py +++ b/rsconcept/backend/apps/library/tests/s_views/t_versions.py @@ -15,51 +15,72 @@ class TestVersionViews(EndpointTester): def setUp(self): super().setUp() - self.owned = RSForm.objects.create(title='Test', alias='T1', owner=self.user) - self.unowned = RSForm.objects.create(title='Test2', alias='T2') + self.owned = RSForm.create(title='Test', alias='T1', owner=self.user) + self.owned_id = self.owned.model.pk + self.unowned = RSForm.create(title='Test2', alias='T2') + self.unowned_id = self.unowned.model.pk self.x1 = self.owned.insert_new( alias='X1', convention='testStart' ) - @decl_endpoint('/api/rsforms/{schema}/versions/create', method='post') + @decl_endpoint('/api/library/{schema}/create-version', method='post') def test_create_version(self): invalid_data = {'description': 'test'} invalid_id = 1338 data = {'version': '1.0.0', 'description': 'test'} self.executeNotFound(data=data, schema=invalid_id) - self.executeForbidden(data=data, schema=self.unowned.pk) - self.executeBadData(data=invalid_data, schema=self.owned.pk) + self.executeForbidden(data=data, schema=self.unowned_id) + self.executeBadData(data=invalid_data, schema=self.owned_id) - response = self.executeCreated(data=data, schema=self.owned.pk) + response = self.executeCreated(data=data, schema=self.owned_id) self.assertTrue('version' in response.data) self.assertTrue('schema' in response.data) self.assertTrue(response.data['version'] in [v['id'] for v in response.data['schema']['versions']]) - @decl_endpoint('/api/rsforms/{schema}/versions/{version}', method='get') + @decl_endpoint('/api/library/{schema}/versions/{version}', method='get') def test_retrieve_version(self): version_id = self._create_version({'version': '1.0.0', 'description': 'test'}) invalid_id = version_id + 1337 self.executeNotFound(schema=invalid_id, version=invalid_id) - self.executeNotFound(schema=self.owned.pk, version=invalid_id) + self.executeNotFound(schema=self.owned_id, version=invalid_id) self.executeNotFound(schema=invalid_id, version=version_id) - self.executeNotFound(schema=self.unowned.pk, version=version_id) + self.executeNotFound(schema=self.unowned_id, version=version_id) - self.owned.alias = 'NewName' + self.owned.model.alias = 'NewName' self.owned.save() self.x1.alias = 'X33' self.x1.save() - response = self.executeOK(schema=self.owned.pk, version=version_id) - self.assertNotEqual(response.data['alias'], self.owned.alias) + response = self.executeOK(schema=self.owned_id, version=version_id) + self.assertNotEqual(response.data['alias'], self.owned.model.alias) self.assertNotEqual(response.data['items'][0]['alias'], self.x1.alias) self.assertEqual(response.data['version'], version_id) + @decl_endpoint('/api/library/{schema}/versions/{version}', method='get') + def test_retrieve_version_details(self): + a1 = Constituenta.objects.create( + schema=self.owned.model, + alias='A1', + cst_type='axiom', + definition_formal='X1=X1', + order=2 + ) + version_id = self._create_version({'version': '1.0.0', 'description': 'test'}) + a1.definition_formal = 'X1=X2' + a1.save() + + response = self.executeOK(schema=self.owned_id, version=version_id) + loaded_a1 = response.data['items'][1] + self.assertEqual(loaded_a1['definition_formal'], 'X1=X1') + self.assertEqual(loaded_a1['parse']['status'], 'verified') + + @decl_endpoint('/api/versions/{version}', method='get') def test_access_version(self): data = {'version': '1.0.0', 'description': 'test'} @@ -73,7 +94,7 @@ class TestVersionViews(EndpointTester): response = self.executeOK() self.assertEqual(response.data['version'], data['version']) self.assertEqual(response.data['description'], data['description']) - self.assertEqual(response.data['item'], self.owned.pk) + self.assertEqual(response.data['item'], self.owned_id) data = {'version': '1.2.0', 'description': 'test1'} self.method = 'patch' @@ -95,25 +116,6 @@ class TestVersionViews(EndpointTester): self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) - @decl_endpoint('/api/rsforms/{schema}/versions/{version}', method='get') - def test_retrieve_version_details(self): - a1 = Constituenta.objects.create( - schema=self.owned, - alias='A1', - cst_type='axiom', - definition_formal='X1=X1', - order=2 - ) - version_id = self._create_version({'version': '1.0.0', 'description': 'test'}) - a1.definition_formal = 'X1=X2' - a1.save() - - response = self.executeOK(schema=self.owned.pk, version=version_id) - loaded_a1 = response.data['items'][1] - self.assertEqual(loaded_a1['definition_formal'], 'X1=X1') - self.assertEqual(loaded_a1['parse']['status'], 'verified') - - @decl_endpoint('/api/versions/{version}/export-file', method='get') def test_export_version(self): invalid_id = 1338 @@ -123,7 +125,7 @@ class TestVersionViews(EndpointTester): response = self.executeOK(version=version_id) self.assertEqual( response.headers['Content-Disposition'], - f'attachment; filename={self.owned.alias}.trs' + f'attachment; filename={self.owned.model.alias}.trs' ) with io.BytesIO(response.content) as stream: with ZipFile(stream, 'r') as zipped_file: @@ -165,7 +167,7 @@ class TestVersionViews(EndpointTester): def _create_version(self, data) -> int: response = self.client.post( - f'/api/rsforms/{self.owned.pk}/versions/create', + f'/api/library/{self.owned_id}/create-version', data=data, format='json' ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) diff --git a/rsconcept/backend/apps/library/urls.py b/rsconcept/backend/apps/library/urls.py new file mode 100644 index 00000000..e6138440 --- /dev/null +++ b/rsconcept/backend/apps/library/urls.py @@ -0,0 +1,21 @@ +''' Routing: Operation Schema. ''' +from django.urls import include, path +from rest_framework import routers + +from . import views + +library_router = routers.SimpleRouter(trailing_slash=False) +library_router.register('library', views.LibraryViewSet, 'Library') +library_router.register('versions', views.VersionViewset, 'Version') + +urlpatterns = [ + path('library/active', views.LibraryActiveView.as_view()), + path('library/all', views.LibraryAdminView.as_view()), + path('library/templates', views.LibraryTemplatesView.as_view(), name='templates'), + path('library//create-version', views.create_version), + path('library//versions/', views.retrieve_version), + + path('versions//export-file', views.export_file), + + path('', include(library_router.urls)), +] diff --git a/rsconcept/backend/apps/library/views/__init__.py b/rsconcept/backend/apps/library/views/__init__.py new file mode 100644 index 00000000..83809330 --- /dev/null +++ b/rsconcept/backend/apps/library/views/__init__.py @@ -0,0 +1,3 @@ +''' REST API: Endpoint processors. ''' +from .library import LibraryActiveView, LibraryAdminView, LibraryTemplatesView, LibraryViewSet +from .versions import VersionViewset, create_version, export_file, retrieve_version diff --git a/rsconcept/backend/apps/rsform/views/library.py b/rsconcept/backend/apps/library/views/library.py similarity index 94% rename from rsconcept/backend/apps/rsform/views/library.py rename to rsconcept/backend/apps/library/views/library.py index cbbb937f..cd5fbbd1 100644 --- a/rsconcept/backend/apps/rsform/views/library.py +++ b/rsconcept/backend/apps/library/views/library.py @@ -13,6 +13,9 @@ from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response +from apps.rsform.models import RSForm +from apps.rsform.serializers import RSFormParseSerializer +from apps.users.models import User from shared import permissions from .. import models as m @@ -73,7 +76,7 @@ class LibraryViewSet(viewsets.ModelViewSet): tags=['Library'], request=s.LibraryItemCloneSerializer, responses={ - c.HTTP_201_CREATED: s.RSFormParseSerializer, + c.HTTP_201_CREATED: RSFormParseSerializer, c.HTTP_400_BAD_REQUEST: None, c.HTTP_403_FORBIDDEN: None, c.HTTP_404_NOT_FOUND: None @@ -88,8 +91,7 @@ class LibraryViewSet(viewsets.ModelViewSet): if item.item_type != m.LibraryItemType.RSFORM: return Response(status=c.HTTP_400_BAD_REQUEST) - schema = m.RSForm.objects.get(pk=item.pk) - clone = deepcopy(schema) + clone = deepcopy(item) clone.pk = None clone.owner = self.request.user clone.title = serializer.validated_data['title'] @@ -103,14 +105,14 @@ class LibraryViewSet(viewsets.ModelViewSet): with transaction.atomic(): clone.save() need_filter = 'items' in request.data - for cst in schema.constituents(): + for cst in RSForm(item).constituents(): if not need_filter or cst.pk in request.data['items']: cst.pk = None cst.schema = clone cst.save() return Response( status=c.HTTP_201_CREATED, - data=s.RSFormParseSerializer(clone).data + data=RSFormParseSerializer(clone).data ) @extend_schema( @@ -127,7 +129,7 @@ class LibraryViewSet(viewsets.ModelViewSet): def subscribe(self, request: Request, pk): ''' Endpoint: Subscribe current user to item. ''' item = self._get_item() - m.Subscription.subscribe(user=cast(m.User, self.request.user), item=item) + m.Subscription.subscribe(user=cast(User, self.request.user), item=item) return Response(status=c.HTTP_200_OK) @extend_schema( @@ -144,7 +146,7 @@ class LibraryViewSet(viewsets.ModelViewSet): def unsubscribe(self, request: Request, pk): ''' Endpoint: Unsubscribe current user from item. ''' item = self._get_item() - m.Subscription.unsubscribe(user=cast(m.User, self.request.user), item=item) + m.Subscription.unsubscribe(user=cast(User, self.request.user), item=item) return Response(status=c.HTTP_200_OK) @extend_schema( @@ -184,7 +186,8 @@ class LibraryViewSet(viewsets.ModelViewSet): item = self._get_item() serializer = s.AccessPolicySerializer(data=request.data) serializer.is_valid(raise_exception=True) - m.LibraryItem.objects.filter(pk=item.pk).update(access_policy=serializer.validated_data['access_policy']) + new_policy = serializer.validated_data['access_policy'] + m.LibraryItem.objects.filter(pk=item.pk).update(access_policy=new_policy) return Response(status=c.HTTP_200_OK) @extend_schema( @@ -286,7 +289,7 @@ class LibraryActiveView(generics.ListAPIView): .filter(is_public) \ .filter(common_location).order_by('-time_update') else: - user = cast(m.User, self.request.user) + user = cast(User, self.request.user) # pylint: disable=unsupported-binary-operation return m.LibraryItem.objects.filter( (is_public & common_location) | diff --git a/rsconcept/backend/apps/rsform/views/versions.py b/rsconcept/backend/apps/library/views/versions.py similarity index 80% rename from rsconcept/backend/apps/rsform/views/versions.py rename to rsconcept/backend/apps/library/views/versions.py index 2cdefdde..7ce06bf8 100644 --- a/rsconcept/backend/apps/rsform/views/versions.py +++ b/rsconcept/backend/apps/library/views/versions.py @@ -10,11 +10,13 @@ from rest_framework.decorators import action, api_view, permission_classes from rest_framework.request import Request from rest_framework.response import Response -from shared import permissions +from apps.rsform import utils +from apps.rsform.models import RSForm +from apps.rsform.serializers import RSFormParseSerializer, RSFormSerializer, RSFormTRSSerializer +from shared import permissions, utility from .. import models as m from .. import serializers as s -from .. import utils @extend_schema(tags=['Version']) @@ -32,7 +34,7 @@ class VersionViewset( summary='restore version data into current item', request=None, responses={ - c.HTTP_200_OK: s.RSFormParseSerializer, + c.HTTP_200_OK: RSFormParseSerializer, c.HTTP_403_FORBIDDEN: None, c.HTTP_404_NOT_FOUND: None } @@ -42,84 +44,13 @@ class VersionViewset( ''' Restore version data into current item. ''' version = cast(m.Version, self.get_object()) item = cast(m.LibraryItem, version.item) - schema = m.RSForm.objects.get(pk=item.pk) - s.RSFormSerializer(schema).restore_from_version(version.data) + RSFormSerializer(item).restore_from_version(version.data) return Response( status=c.HTTP_200_OK, - data=s.RSFormParseSerializer(schema).data + data=RSFormParseSerializer(item).data ) -@extend_schema( - summary='save version for RSForm copying current content', - tags=['Version'], - request=s.VersionCreateSerializer, - responses={ - c.HTTP_201_CREATED: s.NewVersionResponse, - c.HTTP_400_BAD_REQUEST: None, - c.HTTP_403_FORBIDDEN: None, - c.HTTP_404_NOT_FOUND: None - } -) -@api_view(['POST']) -@permission_classes([permissions.GlobalUser]) -def create_version(request: Request, pk_item: int): - ''' Endpoint: Create new version for RSForm copying current content. ''' - try: - item = m.RSForm.objects.get(pk=pk_item) - except m.LibraryItem.DoesNotExist: - return Response(status=c.HTTP_404_NOT_FOUND) - creator = request.user - if not creator.is_staff and creator != item.owner: - return Response(status=c.HTTP_403_FORBIDDEN) - - version_input = s.VersionCreateSerializer(data=request.data) - version_input.is_valid(raise_exception=True) - data = s.RSFormSerializer(item).to_versioned_data() - result = item.create_version( - version=version_input.validated_data['version'], - description=version_input.validated_data['description'], - data=data - ) - return Response( - status=c.HTTP_201_CREATED, - data={ - 'version': result.pk, - 'schema': s.RSFormParseSerializer(item).data - } - ) - - -@extend_schema( - summary='retrieve versioned data for RSForm', - tags=['Version'], - request=None, - responses={ - c.HTTP_200_OK: s.RSFormParseSerializer, - c.HTTP_404_NOT_FOUND: None - } -) -@api_view(['GET']) -def retrieve_version(request: Request, pk_item: int, pk_version: int): - ''' Endpoint: Retrieve version for RSForm. ''' - try: - item = m.RSForm.objects.get(pk=pk_item) - except m.RSForm.DoesNotExist: - return Response(status=c.HTTP_404_NOT_FOUND) - try: - version = m.Version.objects.get(pk=pk_version) - except m.Version.DoesNotExist: - return Response(status=c.HTTP_404_NOT_FOUND) - if version.item != item: - return Response(status=c.HTTP_404_NOT_FOUND) - - data = s.RSFormParseSerializer(item).from_versioned_data(version.pk, version.data) - return Response( - status=c.HTTP_200_OK, - data=data - ) - - @extend_schema( summary='export versioned data as file', tags=['Version'], @@ -136,10 +67,79 @@ def export_file(request: Request, pk: int): version = m.Version.objects.get(pk=pk) except m.Version.DoesNotExist: return Response(status=c.HTTP_404_NOT_FOUND) - schema = m.RSForm.objects.get(pk=version.item.pk) - data = s.RSFormTRSSerializer(schema).from_versioned_data(version.data) - file = utils.write_zipped_json(data, utils.EXTEOR_INNER_FILENAME) + data = RSFormTRSSerializer(version.item).from_versioned_data(version.data) + file = utility.write_zipped_json(data, utils.EXTEOR_INNER_FILENAME) filename = utils.filename_for_schema(data['alias']) response = HttpResponse(file, content_type='application/zip') response['Content-Disposition'] = f'attachment; filename={filename}' return response + + +@extend_schema( + summary='save version for RSForm copying current content', + tags=['Version'], + request=s.VersionCreateSerializer, + responses={ + c.HTTP_201_CREATED: s.NewVersionResponse, + c.HTTP_400_BAD_REQUEST: None, + c.HTTP_403_FORBIDDEN: None, + c.HTTP_404_NOT_FOUND: None + } +) +@api_view(['POST']) +@permission_classes([permissions.GlobalUser]) +def create_version(request: Request, pk_item: int): + ''' Endpoint: Create new version for RSForm copying current content. ''' + try: + item = m.LibraryItem.objects.get(pk=pk_item) + except m.LibraryItem.DoesNotExist: + return Response(status=c.HTTP_404_NOT_FOUND) + creator = request.user + if not creator.is_staff and creator != item.owner: + return Response(status=c.HTTP_403_FORBIDDEN) + + version_input = s.VersionCreateSerializer(data=request.data) + version_input.is_valid(raise_exception=True) + data = RSFormSerializer(item).to_versioned_data() + result = RSForm(item).create_version( + version=version_input.validated_data['version'], + description=version_input.validated_data['description'], + data=data + ) + return Response( + status=c.HTTP_201_CREATED, + data={ + 'version': result.pk, + 'schema': RSFormParseSerializer(item).data + } + ) + + +@extend_schema( + summary='retrieve versioned data for RSForm', + tags=['Version'], + request=None, + responses={ + c.HTTP_200_OK: RSFormParseSerializer, + c.HTTP_404_NOT_FOUND: None + } +) +@api_view(['GET']) +def retrieve_version(request: Request, pk_item: int, pk_version: int): + ''' Endpoint: Retrieve version for RSForm. ''' + try: + item = m.LibraryItem.objects.get(pk=pk_item) + except m.LibraryItem.DoesNotExist: + return Response(status=c.HTTP_404_NOT_FOUND) + try: + version = m.Version.objects.get(pk=pk_version) + except m.Version.DoesNotExist: + return Response(status=c.HTTP_404_NOT_FOUND) + if version.item != item: + return Response(status=c.HTTP_404_NOT_FOUND) + + data = RSFormParseSerializer(item).from_versioned_data(version.pk, version.data) + return Response( + status=c.HTTP_200_OK, + data=data + ) diff --git a/rsconcept/backend/apps/oss/admin.py b/rsconcept/backend/apps/oss/admin.py index 813d4bfa..78759597 100644 --- a/rsconcept/backend/apps/oss/admin.py +++ b/rsconcept/backend/apps/oss/admin.py @@ -27,4 +27,4 @@ class SynthesisSubstitutionAdmin(admin.ModelAdmin): admin.site.register(models.Operation, OperationAdmin) admin.site.register(models.Argument, ArgumentAdmin) -admin.site.register(models.SynthesisSubstitution, SynthesisSubstitutionAdmin) +admin.site.register(models.Substitution, SynthesisSubstitutionAdmin) diff --git a/rsconcept/backend/apps/oss/apps.py b/rsconcept/backend/apps/oss/apps.py index 540eca26..67a7f2ee 100644 --- a/rsconcept/backend/apps/oss/apps.py +++ b/rsconcept/backend/apps/oss/apps.py @@ -2,7 +2,7 @@ from django.apps import AppConfig -class RsformConfig(AppConfig): +class OssConfig(AppConfig): ''' Application config. ''' default_auto_field = 'django.db.models.BigAutoField' name = 'apps.oss' diff --git a/rsconcept/backend/apps/oss/migrations/0001_initial.py b/rsconcept/backend/apps/oss/migrations/0001_initial.py index e5fc31f8..22aa25ae 100644 --- a/rsconcept/backend/apps/oss/migrations/0001_initial.py +++ b/rsconcept/backend/apps/oss/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.7 on 2024-07-17 09:51 +# Generated by Django 5.0.7 on 2024-07-25 16:06 import django.db.models.deletion from django.db import migrations, models @@ -9,7 +9,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('rsform', '0008_alter_libraryitem_item_type'), + ('library', '0001_initial'), + ('rsform', '0001_initial'), ] operations = [ @@ -17,17 +18,15 @@ class Migration(migrations.Migration): name='Operation', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('operation_type', models.CharField(choices=[ - ('input', 'Input'), ('synthesis', 'Synthesis')], default='input', max_length=10, verbose_name='Тип')), + ('operation_type', models.CharField(choices=[('input', 'Input'), ('synthesis', 'Synthesis')], default='input', max_length=10, verbose_name='Тип')), + ('sync_text', models.BooleanField(default=True, verbose_name='Синхронизация')), ('alias', models.CharField(blank=True, max_length=255, verbose_name='Шифр')), ('title', models.TextField(blank=True, verbose_name='Название')), ('comment', models.TextField(blank=True, verbose_name='Комментарий')), ('position_x', models.FloatField(default=0, verbose_name='Положение по горизонтали')), ('position_y', models.FloatField(default=0, verbose_name='Положение по вертикали')), - ('oss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - related_name='items', to='rsform.libraryitem', verbose_name='Схема синтеза')), - ('result', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, - related_name='producer', to='rsform.libraryitem', verbose_name='Связанная КС')), + ('oss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='library.libraryitem', verbose_name='Схема синтеза')), + ('result', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='producer', to='library.libraryitem', verbose_name='Связанная КС')), ], options={ 'verbose_name': 'Операция', @@ -35,16 +34,13 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='SynthesisSubstitution', + name='Substitution', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('transfer_term', models.BooleanField(default=False, verbose_name='Перенос термина')), - ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - to='oss.operation', verbose_name='Операция')), - ('original', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - related_name='as_original', to='rsform.constituenta', verbose_name='Удаляемая конституента')), - ('substitution', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - related_name='as_substitute', to='rsform.constituenta', verbose_name='Замещающая конституента')), + ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='oss.operation', verbose_name='Операция')), + ('original', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='as_original', to='rsform.constituenta', verbose_name='Удаляемая конституента')), + ('substitution', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='as_substitute', to='rsform.constituenta', verbose_name='Замещающая конституента')), ], options={ 'verbose_name': 'Отождествление синтеза', @@ -55,10 +51,8 @@ class Migration(migrations.Migration): name='Argument', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('argument', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - related_name='descendants', to='oss.operation', verbose_name='Аргумент')), - ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, - related_name='arguments', to='oss.operation', verbose_name='Операция')), + ('argument', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='descendants', to='oss.operation', verbose_name='Аргумент')), + ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='arguments', to='oss.operation', verbose_name='Операция')), ], options={ 'verbose_name': 'Аргумент', diff --git a/rsconcept/backend/apps/oss/migrations/0002_operationschema_alter_operation_oss.py b/rsconcept/backend/apps/oss/migrations/0002_operationschema_alter_operation_oss.py deleted file mode 100644 index c965de6e..00000000 --- a/rsconcept/backend/apps/oss/migrations/0002_operationschema_alter_operation_oss.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-22 13:23 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('oss', '0001_initial'), - ('rsform', '0008_alter_libraryitem_item_type'), - ] - - operations = [ - migrations.CreateModel( - name='OperationSchema', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('rsform.libraryitem',), - ), - migrations.AlterField( - model_name='operation', - name='oss', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='oss.operationschema', verbose_name='Схема синтеза'), - ), - ] diff --git a/rsconcept/backend/apps/oss/migrations/0003_operation_sync_text_alter_operation_result.py b/rsconcept/backend/apps/oss/migrations/0003_operation_sync_text_alter_operation_result.py deleted file mode 100644 index 0bb63a04..00000000 --- a/rsconcept/backend/apps/oss/migrations/0003_operation_sync_text_alter_operation_result.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-24 18:12 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('oss', '0002_operationschema_alter_operation_oss'), - ('rsform', '0009_rsform_alter_constituenta_schema_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='operation', - name='sync_text', - field=models.BooleanField(default=True, verbose_name='Синхронизация'), - ), - migrations.AlterField( - model_name='operation', - name='result', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='producer', to='rsform.rsform', verbose_name='Связанная КС'), - ), - ] diff --git a/rsconcept/backend/apps/oss/models/Inheritance.py b/rsconcept/backend/apps/oss/models/Inheritance.py new file mode 100644 index 00000000..1292acbd --- /dev/null +++ b/rsconcept/backend/apps/oss/models/Inheritance.py @@ -0,0 +1,32 @@ +''' Models: Synthesis Inheritance. ''' +from django.db.models import CASCADE, ForeignKey, Model + + +class Inheritance(Model): + ''' Inheritance links parent and child constituents in synthesis operation.''' + operation: ForeignKey = ForeignKey( + verbose_name='Операция', + to='oss.Operation', + on_delete=CASCADE + ) + + parent: ForeignKey = ForeignKey( + verbose_name='Исходная конституента', + to='rsform.Constituenta', + on_delete=CASCADE, + related_name='as_parent' + ) + child: ForeignKey = ForeignKey( + verbose_name='Наследованная конституента', + to='rsform.Constituenta', + on_delete=CASCADE, + related_name='as_child' + ) + + class Meta: + ''' Model metadata. ''' + verbose_name = 'Наследование синтеза' + verbose_name_plural = 'Отношение наследования конституент' + + def __str__(self) -> str: + return f'{self.parent} -> {self.child}' diff --git a/rsconcept/backend/apps/oss/models/Operation.py b/rsconcept/backend/apps/oss/models/Operation.py index cd1d9b24..2be9b728 100644 --- a/rsconcept/backend/apps/oss/models/Operation.py +++ b/rsconcept/backend/apps/oss/models/Operation.py @@ -22,7 +22,7 @@ class Operation(Model): ''' Operational schema Unit.''' oss: ForeignKey = ForeignKey( verbose_name='Схема синтеза', - to='oss.OperationSchema', + to='library.LibraryItem', on_delete=CASCADE, related_name='items' ) @@ -34,7 +34,7 @@ class Operation(Model): ) result: ForeignKey = ForeignKey( verbose_name='Связанная КС', - to='rsform.RSForm', + to='library.LibraryItem', null=True, on_delete=SET_NULL, related_name='producer' diff --git a/rsconcept/backend/apps/oss/models/OperationSchema.py b/rsconcept/backend/apps/oss/models/OperationSchema.py index ef922c13..72c08b56 100644 --- a/rsconcept/backend/apps/oss/models/OperationSchema.py +++ b/rsconcept/backend/apps/oss/models/OperationSchema.py @@ -3,47 +3,53 @@ from typing import Optional from django.core.exceptions import ValidationError from django.db import transaction -from django.db.models import Manager, QuerySet +from django.db.models import QuerySet -from apps.rsform.models import LibraryItem, LibraryItemType +from apps.library.models import LibraryItem, LibraryItemType from shared import messages as msg from .Argument import Argument from .Operation import Operation -from .SynthesisSubstitution import SynthesisSubstitution +from .Substitution import Substitution -class OperationSchema(LibraryItem): +class OperationSchema: ''' Operations schema API. ''' - class Meta: - ''' Model metadata. ''' - proxy = True + def __init__(self, model: LibraryItem): + self.model = model - class InternalManager(Manager): - ''' Object manager. ''' + @staticmethod + def create(**kwargs) -> 'OperationSchema': + ''' Create LibraryItem via OperationSchema. ''' + model = LibraryItem.objects.create(item_type=LibraryItemType.OPERATION_SCHEMA, **kwargs) + return OperationSchema(model) - def get_queryset(self) -> QuerySet: - return super().get_queryset().filter(item_type=LibraryItemType.OPERATION_SCHEMA) + @staticmethod + def from_id(pk: int) -> 'OperationSchema': + ''' Get LibraryItem by pk. ''' + model = LibraryItem.objects.get(pk=pk) + return OperationSchema(model) - def create(self, **kwargs): - kwargs.update({'item_type': LibraryItemType.OPERATION_SCHEMA}) - return super().create(**kwargs) + def save(self, *args, **kwargs): + ''' Save wrapper. ''' + self.model.save(*args, **kwargs) - # Legit overriding object manager - objects = InternalManager() # type: ignore[misc] + def refresh_from_db(self): + ''' Model wrapper. ''' + self.model.refresh_from_db() def operations(self) -> QuerySet[Operation]: ''' Get QuerySet containing all operations of current OSS. ''' - return Operation.objects.filter(oss=self) + return Operation.objects.filter(oss=self.model) def arguments(self) -> QuerySet[Argument]: ''' Operation arguments. ''' - return Argument.objects.filter(operation__oss=self) + return Argument.objects.filter(operation__oss=self.model) - def substitutions(self) -> QuerySet[SynthesisSubstitution]: + def substitutions(self) -> QuerySet[Substitution]: ''' Operation substitutions. ''' - return SynthesisSubstitution.objects.filter(operation__oss=self) + return Substitution.objects.filter(operation__oss=self.model) def update_positions(self, data: list[dict]): ''' Update positions. ''' @@ -60,7 +66,7 @@ class OperationSchema(LibraryItem): ''' Insert new operation. ''' if kwargs['alias'] != '' and self.operations().filter(alias=kwargs['alias']).exists(): raise ValidationError(msg.aliasTaken(kwargs['alias'])) - result = Operation.objects.create(oss=self, **kwargs) + result = Operation.objects.create(oss=self.model, **kwargs) self.save() result.refresh_from_db() return result @@ -109,7 +115,7 @@ class OperationSchema(LibraryItem): return Argument.objects.filter(operation=target).delete() - SynthesisSubstitution.objects.filter(operation=target).delete() + Substitution.objects.filter(operation=target).delete() # trigger on_change effects @@ -118,9 +124,9 @@ class OperationSchema(LibraryItem): @transaction.atomic def set_substitutions(self, target: Operation, substitutes: list[dict]): ''' Clear all arguments for operation. ''' - SynthesisSubstitution.objects.filter(operation=target).delete() + Substitution.objects.filter(operation=target).delete() for sub in substitutes: - SynthesisSubstitution.objects.create( + Substitution.objects.create( operation=target, original=sub['original'], substitution=sub['substitution'], diff --git a/rsconcept/backend/apps/oss/models/SynthesisSubstitution.py b/rsconcept/backend/apps/oss/models/Substitution.py similarity index 93% rename from rsconcept/backend/apps/oss/models/SynthesisSubstitution.py rename to rsconcept/backend/apps/oss/models/Substitution.py index 6dae6329..589041f6 100644 --- a/rsconcept/backend/apps/oss/models/SynthesisSubstitution.py +++ b/rsconcept/backend/apps/oss/models/Substitution.py @@ -1,8 +1,8 @@ -''' Models: SynthesisSubstitution. ''' +''' Models: Synthesis Substitution. ''' from django.db.models import CASCADE, BooleanField, ForeignKey, Model -class SynthesisSubstitution(Model): +class Substitution(Model): ''' Substitutions as part of Synthesis operation in OSS.''' operation: ForeignKey = ForeignKey( verbose_name='Операция', diff --git a/rsconcept/backend/apps/oss/models/__init__.py b/rsconcept/backend/apps/oss/models/__init__.py index 23435594..cb389382 100644 --- a/rsconcept/backend/apps/oss/models/__init__.py +++ b/rsconcept/backend/apps/oss/models/__init__.py @@ -1,8 +1,6 @@ ''' Django: Models. ''' -from apps.rsform.models import LibraryItem, LibraryItemType - from .Argument import Argument from .Operation import Operation, OperationType from .OperationSchema import OperationSchema -from .SynthesisSubstitution import SynthesisSubstitution +from .Substitution import Substitution diff --git a/rsconcept/backend/apps/oss/serializers/__init__.py b/rsconcept/backend/apps/oss/serializers/__init__.py index 0b02f26a..a1e9c339 100644 --- a/rsconcept/backend/apps/oss/serializers/__init__.py +++ b/rsconcept/backend/apps/oss/serializers/__init__.py @@ -1,7 +1,5 @@ ''' REST API: Serializers. ''' -from apps.rsform.serializers import LibraryItemSerializer - from .basics import OperationPositionSerializer, PositionsSerializer, SubstitutionExSerializer from .data_access import ( ArgumentSerializer, @@ -10,4 +8,4 @@ from .data_access import ( OperationSchemaSerializer, OperationSerializer ) -from .schema_typing import NewOperationResponse +from .responses import NewOperationResponse diff --git a/rsconcept/backend/apps/oss/serializers/data_access.py b/rsconcept/backend/apps/oss/serializers/data_access.py index 0211ff62..a08d4a50 100644 --- a/rsconcept/backend/apps/oss/serializers/data_access.py +++ b/rsconcept/backend/apps/oss/serializers/data_access.py @@ -5,8 +5,8 @@ from django.db.models import F from rest_framework import serializers from rest_framework.serializers import PrimaryKeyRelatedField as PKField -from apps.rsform.models import LibraryItem -from apps.rsform.serializers import LibraryItemDetailsSerializer +from apps.library.models import LibraryItem +from apps.library.serializers import LibraryItemDetailsSerializer from shared import messages as msg from ..models import Argument, Operation, OperationSchema, OperationType @@ -85,19 +85,20 @@ class OperationSchemaSerializer(serializers.ModelSerializer): class Meta: ''' serializer metadata. ''' - model = OperationSchema + model = LibraryItem fields = '__all__' - def to_representation(self, instance: OperationSchema): + def to_representation(self, instance: LibraryItem): result = LibraryItemDetailsSerializer(instance).data + oss = OperationSchema(instance) result['items'] = [] - for operation in instance.operations(): + for operation in oss.operations(): result['items'].append(OperationSerializer(operation).data) result['arguments'] = [] - for argument in instance.arguments(): + for argument in oss.arguments(): result['arguments'].append(ArgumentSerializer(argument).data) result['substitutions'] = [] - for substitution in instance.substitutions().values( + for substitution in oss.substitutions().values( 'operation', 'original', 'substitution', diff --git a/rsconcept/backend/apps/oss/serializers/schema_typing.py b/rsconcept/backend/apps/oss/serializers/responses.py similarity index 100% rename from rsconcept/backend/apps/oss/serializers/schema_typing.py rename to rsconcept/backend/apps/oss/serializers/responses.py diff --git a/rsconcept/backend/apps/oss/tests/s_models/__init__.py b/rsconcept/backend/apps/oss/tests/s_models/__init__.py index f30b6e45..9fd813b0 100644 --- a/rsconcept/backend/apps/oss/tests/s_models/__init__.py +++ b/rsconcept/backend/apps/oss/tests/s_models/__init__.py @@ -1,4 +1,4 @@ ''' Tests for Django Models. ''' from .t_Argument import * from .t_Operation import * -from .t_SynthesisSubstitution import * +from .t_Substitution import * diff --git a/rsconcept/backend/apps/oss/tests/s_models/t_Argument.py b/rsconcept/backend/apps/oss/tests/s_models/t_Argument.py index 8a8a288b..43b36c70 100644 --- a/rsconcept/backend/apps/oss/tests/s_models/t_Argument.py +++ b/rsconcept/backend/apps/oss/tests/s_models/t_Argument.py @@ -8,11 +8,23 @@ class TestArgument(TestCase): ''' Testing Argument model. ''' def setUp(self): - self.oss = OperationSchema.objects.create(alias='T1') + self.oss = OperationSchema.create(alias='T1') - self.operation1 = Operation.objects.create(oss=self.oss, alias='KS1', operation_type=OperationType.INPUT) - self.operation2 = Operation.objects.create(oss=self.oss, alias='KS2', operation_type=OperationType.SYNTHESIS) - self.operation3 = Operation.objects.create(oss=self.oss, alias='KS3', operation_type=OperationType.INPUT) + self.operation1 = Operation.objects.create( + oss=self.oss.model, + alias='KS1', + operation_type=OperationType.INPUT + ) + self.operation2 = Operation.objects.create( + oss=self.oss.model, + alias='KS2', + operation_type=OperationType.SYNTHESIS + ) + self.operation3 = Operation.objects.create( + oss=self.oss.model, + alias='KS3', + operation_type=OperationType.INPUT + ) self.argument = Argument.objects.create( operation=self.operation2, argument=self.operation1 diff --git a/rsconcept/backend/apps/oss/tests/s_models/t_Operation.py b/rsconcept/backend/apps/oss/tests/s_models/t_Operation.py index 18b9dd9a..213337ca 100644 --- a/rsconcept/backend/apps/oss/tests/s_models/t_Operation.py +++ b/rsconcept/backend/apps/oss/tests/s_models/t_Operation.py @@ -1,7 +1,8 @@ ''' Testing models: Operation. ''' from django.test import TestCase -from apps.oss.models import LibraryItem, LibraryItemType, Operation, OperationSchema, OperationType +from apps.library.models import LibraryItem, LibraryItemType +from apps.oss.models import Operation, OperationSchema, OperationType from apps.rsform.models import RSForm @@ -9,9 +10,9 @@ class TestOperation(TestCase): ''' Testing Operation model. ''' def setUp(self): - self.oss = OperationSchema.objects.create(alias='T1') + self.oss = OperationSchema.create(alias='T1') self.operation = Operation.objects.create( - oss=self.oss, + oss=self.oss.model, alias='KS1' ) @@ -22,7 +23,7 @@ class TestOperation(TestCase): def test_create_default(self): - self.assertEqual(self.operation.oss, self.oss) + self.assertEqual(self.operation.oss, self.oss.model) self.assertEqual(self.operation.operation_type, OperationType.INPUT) self.assertEqual(self.operation.result, None) self.assertEqual(self.operation.alias, 'KS1') @@ -34,29 +35,29 @@ class TestOperation(TestCase): def test_sync_from_result(self): - schema = RSForm.objects.create(alias=self.operation.alias) - self.operation.result = schema + schema = RSForm.create(alias=self.operation.alias) + self.operation.result = schema.model self.operation.save() - schema.alias = 'KS2' - schema.comment = 'Comment' - schema.title = 'Title' + schema.model.alias = 'KS2' + schema.model.comment = 'Comment' + schema.model.title = 'Title' schema.save() self.operation.refresh_from_db() - self.assertEqual(self.operation.result, schema) - self.assertEqual(self.operation.alias, schema.alias) - self.assertEqual(self.operation.title, schema.title) - self.assertEqual(self.operation.comment, schema.comment) + self.assertEqual(self.operation.result, schema.model) + self.assertEqual(self.operation.alias, schema.model.alias) + self.assertEqual(self.operation.title, schema.model.title) + self.assertEqual(self.operation.comment, schema.model.comment) self.operation.sync_text = False self.operation.save() - schema.alias = 'KS3' + schema.model.alias = 'KS3' schema.save() self.operation.refresh_from_db() - self.assertEqual(self.operation.result, schema) - self.assertNotEqual(self.operation.alias, schema.alias) + self.assertEqual(self.operation.result, schema.model) + self.assertNotEqual(self.operation.alias, schema.model.alias) def test_sync_from_library_item(self): schema = LibraryItem.objects.create(alias=self.operation.alias, item_type=LibraryItemType.RSFORM) diff --git a/rsconcept/backend/apps/oss/tests/s_models/t_SynthesisSubstitution.py b/rsconcept/backend/apps/oss/tests/s_models/t_Substitution.py similarity index 54% rename from rsconcept/backend/apps/oss/tests/s_models/t_SynthesisSubstitution.py rename to rsconcept/backend/apps/oss/tests/s_models/t_Substitution.py index 6e871282..a81b5d49 100644 --- a/rsconcept/backend/apps/oss/tests/s_models/t_SynthesisSubstitution.py +++ b/rsconcept/backend/apps/oss/tests/s_models/t_Substitution.py @@ -1,40 +1,40 @@ -''' Testing models: SynthesisSubstitution. ''' +''' Testing models: Synthesis Substitution. ''' from unittest import result from django.test import TestCase -from apps.oss.models import ( - Argument, - Operation, - OperationSchema, - OperationType, - SynthesisSubstitution -) +from apps.oss.models import Argument, Operation, OperationSchema, OperationType, Substitution from apps.rsform.models import RSForm class TestSynthesisSubstitution(TestCase): - ''' Testing SynthesisSubstitution model. ''' + ''' Testing Synthesis Substitution model. ''' def setUp(self): - self.oss = OperationSchema.objects.create(alias='T1') + self.oss = OperationSchema.create(alias='T1') - self.ks1 = RSForm.objects.create(alias='KS1', title='Test1') + self.ks1 = RSForm.create(alias='KS1', title='Test1') self.ks1x1 = self.ks1.insert_new('X1', term_resolved='X1_1') - self.ks2 = RSForm.objects.create(alias='KS2', title='Test2') + self.ks2 = RSForm.create(alias='KS2', title='Test2') self.ks2x1 = self.ks2.insert_new('X2', term_resolved='X1_2') self.operation1 = Operation.objects.create( - oss=self.oss, + oss=self.oss.model, alias='KS1', operation_type=OperationType.INPUT, - result=self.ks1) + result=self.ks1.model + ) self.operation2 = Operation.objects.create( - oss=self.oss, + oss=self.oss.model, alias='KS2', operation_type=OperationType.INPUT, - result=self.ks1) - self.operation3 = Operation.objects.create(oss=self.oss, alias='KS3', operation_type=OperationType.SYNTHESIS) + result=self.ks1.model + ) + self.operation3 = Operation.objects.create( + oss=self.oss.model, + alias='KS3', + operation_type=OperationType.SYNTHESIS + ) Argument.objects.create( operation=self.operation3, argument=self.operation1 @@ -44,7 +44,7 @@ class TestSynthesisSubstitution(TestCase): argument=self.operation2 ) - self.substitution = SynthesisSubstitution.objects.create( + self.substitution = Substitution.objects.create( operation=self.operation3, original=self.ks1x1, substitution=self.ks2x1, @@ -58,18 +58,18 @@ class TestSynthesisSubstitution(TestCase): def test_cascade_delete_operation(self): - self.assertEqual(SynthesisSubstitution.objects.count(), 1) + self.assertEqual(Substitution.objects.count(), 1) self.operation3.delete() - self.assertEqual(SynthesisSubstitution.objects.count(), 0) + self.assertEqual(Substitution.objects.count(), 0) def test_cascade_delete_original(self): - self.assertEqual(SynthesisSubstitution.objects.count(), 1) + self.assertEqual(Substitution.objects.count(), 1) self.ks1x1.delete() - self.assertEqual(SynthesisSubstitution.objects.count(), 0) + self.assertEqual(Substitution.objects.count(), 0) def test_cascade_delete_substitution(self): - self.assertEqual(SynthesisSubstitution.objects.count(), 1) + self.assertEqual(Substitution.objects.count(), 1) self.ks2x1.delete() - self.assertEqual(SynthesisSubstitution.objects.count(), 0) + self.assertEqual(Substitution.objects.count(), 0) diff --git a/rsconcept/backend/apps/oss/tests/s_views/t_oss.py b/rsconcept/backend/apps/oss/tests/s_views/t_oss.py index 3c9eb990..c25b0b4f 100644 --- a/rsconcept/backend/apps/oss/tests/s_views/t_oss.py +++ b/rsconcept/backend/apps/oss/tests/s_views/t_oss.py @@ -2,8 +2,9 @@ from rest_framework import status +from apps.library.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead from apps.oss.models import Operation, OperationSchema, OperationType -from apps.rsform.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead, RSForm +from apps.rsform.models import RSForm from shared.EndpointTester import EndpointTester, decl_endpoint @@ -12,29 +13,29 @@ class TestOssViewset(EndpointTester): def setUp(self): super().setUp() - self.owned = OperationSchema.objects.create(title='Test', alias='T1', owner=self.user) - self.owned_id = self.owned.pk - self.unowned = OperationSchema.objects.create(title='Test2', alias='T2') - self.unowned_id = self.unowned.pk - self.private = OperationSchema.objects.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE) - self.private_id = self.private.pk - self.invalid_id = self.private.pk + 1337 + self.owned = OperationSchema.create(title='Test', alias='T1', owner=self.user) + self.owned_id = self.owned.model.pk + self.unowned = OperationSchema.create(title='Test2', alias='T2') + self.unowned_id = self.unowned.model.pk + self.private = OperationSchema.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE) + self.private_id = self.private.model.pk + self.invalid_id = self.private.model.pk + 1337 def populateData(self): - self.ks1 = RSForm.objects.create(alias='KS1', title='Test1') + self.ks1 = RSForm.create(alias='KS1', title='Test1', owner=self.user) self.ks1x1 = self.ks1.insert_new('X1', term_resolved='X1_1') - self.ks2 = RSForm.objects.create(alias='KS2', title='Test2') + self.ks2 = RSForm.create(alias='KS2', title='Test2', owner=self.user) self.ks2x1 = self.ks2.insert_new('X2', term_resolved='X1_2') self.operation1 = self.owned.create_operation( alias='1', operation_type=OperationType.INPUT, - result=self.ks1 + result=self.ks1.model ) self.operation2 = self.owned.create_operation( alias='2', operation_type=OperationType.INPUT, - result=self.ks2 + result=self.ks2.model ) self.operation3 = self.owned.create_operation( alias='3', @@ -53,12 +54,12 @@ class TestOssViewset(EndpointTester): self.populateData() response = self.executeOK(item=self.owned_id) - self.assertEqual(response.data['owner'], self.owned.owner.pk) - self.assertEqual(response.data['title'], self.owned.title) - self.assertEqual(response.data['alias'], self.owned.alias) - self.assertEqual(response.data['location'], self.owned.location) - self.assertEqual(response.data['access_policy'], self.owned.access_policy) - self.assertEqual(response.data['visible'], self.owned.visible) + self.assertEqual(response.data['owner'], self.owned.model.owner.pk) + self.assertEqual(response.data['title'], self.owned.model.title) + self.assertEqual(response.data['alias'], self.owned.model.alias) + self.assertEqual(response.data['location'], self.owned.model.location) + self.assertEqual(response.data['access_policy'], self.owned.model.access_policy) + self.assertEqual(response.data['visible'], self.owned.model.visible) self.assertEqual(response.data['item_type'], LibraryItemType.OPERATION_SCHEMA) @@ -121,12 +122,12 @@ class TestOssViewset(EndpointTester): self.assertEqual(self.operation2.position_y, data['positions'][1]['position_y']) self.executeForbidden(data=data, item=self.unowned_id) - self.executeForbidden(item=self.private_id) + self.executeForbidden(data=data, item=self.private_id) @decl_endpoint('/api/oss/{item}/create-operation', method='post') def test_create_operation(self): - self.executeNotFound(item=self.invalid_id) + self.populateData() self.executeBadData(item=self.owned_id) @@ -150,7 +151,9 @@ class TestOssViewset(EndpointTester): self.executeBadData(data=data) data['item_data']['operation_type'] = OperationType.INPUT - response = self.executeCreated(data=data) + self.executeNotFound(data=data, item=self.invalid_id) + + response = self.executeCreated(data=data, item=self.owned_id) self.assertEqual(len(response.data['oss']['items']), 4) new_operation = response.data['new_operation'] self.assertEqual(new_operation['alias'], data['item_data']['alias']) @@ -195,14 +198,14 @@ class TestOssViewset(EndpointTester): 'item_data': { 'alias': 'Test4', 'operation_type': OperationType.INPUT, - 'result': self.ks1.pk + 'result': self.ks1.model.pk }, 'positions': [], } response = self.executeCreated(data=data, item=self.owned_id) self.owned.refresh_from_db() new_operation = response.data['new_operation'] - self.assertEqual(new_operation['result'], self.ks1.pk) + self.assertEqual(new_operation['result'], self.ks1.model.pk) @decl_endpoint('/api/oss/{item}/delete-operation', method='patch') diff --git a/rsconcept/backend/apps/oss/urls.py b/rsconcept/backend/apps/oss/urls.py index 04f3a316..c00df77d 100644 --- a/rsconcept/backend/apps/oss/urls.py +++ b/rsconcept/backend/apps/oss/urls.py @@ -4,9 +4,9 @@ from rest_framework import routers from . import views -library_router = routers.SimpleRouter(trailing_slash=False) -library_router.register('oss', views.OssViewSet, 'OSS') +oss_router = routers.SimpleRouter(trailing_slash=False) +oss_router.register('oss', views.OssViewSet, 'OSS') urlpatterns = [ - path('', include(library_router.urls)), + path('', include(oss_router.urls)), ] diff --git a/rsconcept/backend/apps/oss/views/oss.py b/rsconcept/backend/apps/oss/views/oss.py index 6828d868..784dc576 100644 --- a/rsconcept/backend/apps/oss/views/oss.py +++ b/rsconcept/backend/apps/oss/views/oss.py @@ -10,6 +10,8 @@ from rest_framework.decorators import action from rest_framework.request import Request from rest_framework.response import Response +from apps.library.models import LibraryItem, LibraryItemType +from apps.library.serializers import LibraryItemSerializer from shared import permissions from .. import models as m @@ -20,11 +22,11 @@ from .. import serializers as s @extend_schema_view() class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.RetrieveAPIView): ''' Endpoint: OperationSchema. ''' - queryset = m.OperationSchema.objects.all() - serializer_class = s.LibraryItemSerializer + queryset = LibraryItem.objects.filter(item_type=LibraryItemType.OPERATION_SCHEMA) + serializer_class = LibraryItemSerializer - def _get_schema(self) -> m.OperationSchema: - return cast(m.OperationSchema, self.get_object()) + def _get_item(self) -> LibraryItem: + return cast(LibraryItem, self.get_object()) def get_permissions(self): ''' Determine permission class. ''' @@ -52,7 +54,7 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev @action(detail=True, methods=['get'], url_path='details') def details(self, request: Request, pk): ''' Endpoint: Detailed OSS data. ''' - serializer = s.OperationSchemaSerializer(self._get_schema()) + serializer = s.OperationSchemaSerializer(self._get_item()) return Response( status=c.HTTP_200_OK, data=serializer.data @@ -71,10 +73,9 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev @action(detail=True, methods=['patch'], url_path='update-positions') def update_positions(self, request: Request, pk): ''' Endpoint: Update operations positions. ''' - schema = self._get_schema() serializer = s.PositionsSerializer(data=request.data) serializer.is_valid(raise_exception=True) - schema.update_positions(serializer.validated_data['positions']) + m.OperationSchema(self.get_object()).update_positions(serializer.validated_data['positions']) return Response(status=c.HTTP_200_OK) @extend_schema( @@ -91,23 +92,23 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev @action(detail=True, methods=['post'], url_path='create-operation') def create_operation(self, request: Request, pk): ''' Create new operation. ''' - schema = self._get_schema() serializer = s.OperationCreateSerializer(data=request.data) serializer.is_valid(raise_exception=True) + oss = m.OperationSchema(self.get_object()) with transaction.atomic(): - schema.update_positions(serializer.validated_data['positions']) - new_operation = schema.create_operation(**serializer.validated_data['item_data']) + oss.update_positions(serializer.validated_data['positions']) + new_operation = oss.create_operation(**serializer.validated_data['item_data']) if new_operation.operation_type != m.OperationType.INPUT and 'arguments' in serializer.validated_data: for argument in serializer.validated_data['arguments']: - schema.add_argument(operation=new_operation, argument=argument) - schema.refresh_from_db() + oss.add_argument(operation=new_operation, argument=argument) + oss.refresh_from_db() response = Response( status=c.HTTP_201_CREATED, data={ 'new_operation': s.OperationSerializer(new_operation).data, - 'oss': s.OperationSchemaSerializer(schema).data + 'oss': s.OperationSchemaSerializer(oss.model).data } ) return response @@ -126,19 +127,19 @@ class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retriev @action(detail=True, methods=['patch'], url_path='delete-operation') def delete_operation(self, request: Request, pk): ''' Endpoint: Delete operation. ''' - schema = self._get_schema() serializer = s.OperationDeleteSerializer( data=request.data, - context={'oss': schema} + context={'oss': self.get_object()} ) serializer.is_valid(raise_exception=True) + oss = m.OperationSchema(self.get_object()) with transaction.atomic(): - schema.update_positions(serializer.validated_data['positions']) - schema.delete_operation(serializer.validated_data['target']) - schema.refresh_from_db() + oss.update_positions(serializer.validated_data['positions']) + oss.delete_operation(serializer.validated_data['target']) + oss.refresh_from_db() return Response( status=c.HTTP_200_OK, - data=s.OperationSchemaSerializer(schema).data + data=s.OperationSchemaSerializer(oss.model).data ) diff --git a/rsconcept/backend/apps/rsform/admin.py b/rsconcept/backend/apps/rsform/admin.py index e99c50b1..7161107b 100644 --- a/rsconcept/backend/apps/rsform/admin.py +++ b/rsconcept/backend/apps/rsform/admin.py @@ -10,60 +10,4 @@ class ConstituentaAdmin(admin.ModelAdmin): list_display = ['schema', 'alias', 'term_resolved', 'definition_resolved'] search_fields = ['term_resolved', 'definition_resolved'] - -class LibraryItemAdmin(admin.ModelAdmin): - ''' Admin model: LibraryItem. ''' - date_hierarchy = 'time_update' - list_display = [ - 'alias', 'title', 'owner', - 'visible', 'read_only', 'access_policy', 'location', - 'time_update' - ] - list_filter = ['visible', 'read_only', 'access_policy', 'location', 'time_update'] - search_fields = ['alias', 'title', 'location'] - - -class LibraryTemplateAdmin(admin.ModelAdmin): - ''' Admin model: LibraryTemplate. ''' - list_display = ['id', 'alias'] - list_select_related = ['lib_source'] - - def alias(self, template: models.LibraryTemplate): - if template.lib_source: - return template.lib_source.alias - else: - return 'N/A' - - -class SubscriptionAdmin(admin.ModelAdmin): - ''' Admin model: Subscriptions. ''' - list_display = ['id', 'item', 'user'] - search_fields = [ - 'item__title', 'item__alias', - 'user__username', 'user__first_name', 'user__last_name' - ] - - -class EditorAdmin(admin.ModelAdmin): - ''' Admin model: Editors. ''' - list_display = ['id', 'item', 'editor'] - search_fields = [ - 'item__title', 'item__alias', - 'editor__username', 'editor__first_name', 'editor__last_name' - ] - - -class VersionAdmin(admin.ModelAdmin): - ''' Admin model: Versions. ''' - list_display = ['id', 'item', 'version', 'description', 'time_create'] - search_fields = [ - 'item__title', 'item__alias' - ] - - admin.site.register(models.Constituenta, ConstituentaAdmin) -admin.site.register(models.LibraryItem, LibraryItemAdmin) -admin.site.register(models.LibraryTemplate, LibraryTemplateAdmin) -admin.site.register(models.Subscription, SubscriptionAdmin) -admin.site.register(models.Version, VersionAdmin) -admin.site.register(models.Editor, EditorAdmin) diff --git a/rsconcept/backend/apps/rsform/migrations/0001_initial.py b/rsconcept/backend/apps/rsform/migrations/0001_initial.py index 8bc733a7..536be9fc 100644 --- a/rsconcept/backend/apps/rsform/migrations/0001_initial.py +++ b/rsconcept/backend/apps/rsform/migrations/0001_initial.py @@ -1,10 +1,8 @@ -# Generated by Django 4.2.4 on 2023-08-26 10:09 +# Generated by Django 5.0.7 on 2024-07-25 16:06 -import apps.rsform.models -from django.conf import settings import django.core.validators -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): @@ -12,29 +10,10 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('library', '0001_initial'), ] operations = [ - migrations.CreateModel( - name='LibraryItem', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('item_type', models.CharField(choices=[('rsform', 'Rsform'), ('oss', 'Operations Schema')], max_length=50, verbose_name='Тип')), - ('title', models.TextField(verbose_name='Название')), - ('alias', models.CharField(blank=True, max_length=255, verbose_name='Шифр')), - ('comment', models.TextField(blank=True, verbose_name='Комментарий')), - ('is_common', models.BooleanField(default=False, verbose_name='Общая')), - ('is_canonical', models.BooleanField(default=False, verbose_name='Каноничная')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('time_update', models.DateTimeField(auto_now=True, verbose_name='Дата изменения')), - ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Владелец')), - ], - options={ - 'verbose_name': 'Схема', - 'verbose_name_plural': 'Схемы', - }, - ), migrations.CreateModel( name='Constituenta', fields=[ @@ -45,28 +24,15 @@ class Migration(migrations.Migration): ('convention', models.TextField(blank=True, default='', verbose_name='Комментарий/Конвенция')), ('term_raw', models.TextField(blank=True, default='', verbose_name='Термин (с отсылками)')), ('term_resolved', models.TextField(blank=True, default='', verbose_name='Термин')), - ('term_forms', models.JSONField(default=apps.rsform.models._empty_forms, verbose_name='Словоформы')), + ('term_forms', models.JSONField(default=list, verbose_name='Словоформы')), ('definition_formal', models.TextField(blank=True, default='', verbose_name='Родоструктурное определение')), - ('definition_raw', models.TextField(blank=True, default='', verbose_name='Текстовое определние (с отсылками)')), - ('definition_resolved', models.TextField(blank=True, default='', verbose_name='Текстовое определние')), - ('schema', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.libraryitem', verbose_name='Концептуальная схема')), + ('definition_raw', models.TextField(blank=True, default='', verbose_name='Текстовое определение (с отсылками)')), + ('definition_resolved', models.TextField(blank=True, default='', verbose_name='Текстовое определение')), + ('schema', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='library.libraryitem', verbose_name='Концептуальная схема')), ], options={ 'verbose_name': 'Конституента', 'verbose_name_plural': 'Конституенты', }, ), - migrations.CreateModel( - name='Subscription', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.libraryitem', verbose_name='Элемент')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')), - ], - options={ - 'verbose_name': 'Подписки', - 'verbose_name_plural': 'Подписка', - 'unique_together': {('user', 'item')}, - }, - ), ] diff --git a/rsconcept/backend/apps/rsform/migrations/0002_librarytemplate.py b/rsconcept/backend/apps/rsform/migrations/0002_librarytemplate.py deleted file mode 100644 index 00bc2699..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0002_librarytemplate.py +++ /dev/null @@ -1,25 +0,0 @@ -# Generated by Django 4.2.6 on 2023-10-18 16:12 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='LibraryTemplate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('lib_source', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='rsform.libraryitem', verbose_name='Источник')), - ], - options={ - 'verbose_name': 'Шаблон', - 'verbose_name_plural': 'Шаблоны', - }, - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0003_alter_constituenta_definition_raw_and_more.py b/rsconcept/backend/apps/rsform/migrations/0003_alter_constituenta_definition_raw_and_more.py deleted file mode 100644 index 18aaeb15..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0003_alter_constituenta_definition_raw_and_more.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.2.7 on 2023-12-27 08:47 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0002_librarytemplate'), - ] - - operations = [ - migrations.AlterField( - model_name='constituenta', - name='definition_raw', - field=models.TextField(blank=True, default='', verbose_name='Текстовое определение (с отсылками)'), - ), - migrations.AlterField( - model_name='constituenta', - name='definition_resolved', - field=models.TextField(blank=True, default='', verbose_name='Текстовое определение'), - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0004_version.py b/rsconcept/backend/apps/rsform/migrations/0004_version.py deleted file mode 100644 index db57b43b..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0004_version.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 4.2.10 on 2024-03-03 10:57 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0003_alter_constituenta_definition_raw_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Version', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('version', models.CharField(max_length=20, verbose_name='Версия')), - ('description', models.TextField(blank=True, verbose_name='Описание')), - ('data', models.JSONField(verbose_name='Содержание')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.libraryitem', verbose_name='Схема')), - ], - options={ - 'verbose_name': 'Версии', - 'verbose_name_plural': 'Версия', - 'unique_together': {('item', 'version')}, - }, - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0005_alter_subscription_options_alter_version_options.py b/rsconcept/backend/apps/rsform/migrations/0005_alter_subscription_options_alter_version_options.py deleted file mode 100644 index e21e509d..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0005_alter_subscription_options_alter_version_options.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-20 14:39 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0004_version'), - ] - - operations = [ - migrations.AlterModelOptions( - name='subscription', - options={'verbose_name': 'Подписка', 'verbose_name_plural': 'Подписки'}, - ), - migrations.AlterModelOptions( - name='version', - options={'verbose_name': 'Версия', 'verbose_name_plural': 'Версии'}, - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0006_editor.py b/rsconcept/backend/apps/rsform/migrations/0006_editor.py deleted file mode 100644 index 75403aaa..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0006_editor.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 5.0.6 on 2024-05-20 14:40 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0005_alter_subscription_options_alter_version_options'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Editor', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('time_create', models.DateTimeField(auto_now_add=True, verbose_name='Дата добавления')), - ('editor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Редактор')), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.libraryitem', verbose_name='Схема')), - ], - options={ - 'verbose_name': 'Редактор', - 'verbose_name_plural': 'Редакторы', - 'unique_together': {('item', 'editor')}, - }, - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0007_location_and_flags.py b/rsconcept/backend/apps/rsform/migrations/0007_location_and_flags.py deleted file mode 100644 index 2f4f4821..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0007_location_and_flags.py +++ /dev/null @@ -1,65 +0,0 @@ -# Hand written migration 20240531 - -from django.db import migrations, models - -from .. import models as m - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0006_editor'), - ] - - def calculate_location(apps, schema_editor): - LibraryItem = apps.get_model('rsform', 'LibraryItem') - db_alias = schema_editor.connection.alias - for item in LibraryItem.objects.using(db_alias).all(): - if item.is_canonical: - location = m.LocationHead.LIBRARY - elif item.is_common: - location = m.LocationHead.COMMON - else: - location = m.LocationHead.USER - item.location = location - item.save(update_fields=['location']) - - operations = [ - migrations.AddField( - model_name='libraryitem', - name='access_policy', - field=models.CharField( - choices=[ - ('public', 'Public'), - ('protected', 'Protected'), - ('private', 'Private') - ], - default='public', - max_length=500, - verbose_name='Политика доступа'), - ), - migrations.AddField( - model_name='libraryitem', - name='location', - field=models.TextField(default='/U', max_length=500, verbose_name='Расположение'), - ), - migrations.AddField( - model_name='libraryitem', - name='read_only', - field=models.BooleanField(default=False, verbose_name='Запретить редактирование'), - ), - migrations.AddField( - model_name='libraryitem', - name='visible', - field=models.BooleanField(default=True, verbose_name='Отображаемая'), - ), - migrations.RunPython(calculate_location, migrations.RunPython.noop), # type: ignore - migrations.RemoveField( - model_name='libraryitem', - name='is_canonical', - ), - migrations.RemoveField( - model_name='libraryitem', - name='is_common', - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py b/rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py deleted file mode 100644 index ef7f844d..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-17 09:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0007_location_and_flags'), - ] - - operations = [ - migrations.AlterField( - model_name='libraryitem', - name='item_type', - field=models.CharField(choices=[('rsform', 'Rsform'), ('oss', 'Operation Schema')], max_length=50, verbose_name='Тип'), - ), - ] diff --git a/rsconcept/backend/apps/rsform/migrations/0009_rsform_alter_constituenta_schema_and_more.py b/rsconcept/backend/apps/rsform/migrations/0009_rsform_alter_constituenta_schema_and_more.py deleted file mode 100644 index d1c5d460..00000000 --- a/rsconcept/backend/apps/rsform/migrations/0009_rsform_alter_constituenta_schema_and_more.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-22 14:21 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('rsform', '0008_alter_libraryitem_item_type'), - ] - - operations = [ - migrations.CreateModel( - name='RSForm', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('rsform.libraryitem',), - ), - migrations.AlterField( - model_name='constituenta', - name='schema', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rsform.rsform', verbose_name='Концептуальная схема'), - ), - migrations.AlterField( - model_name='librarytemplate', - name='lib_source', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='rsform.rsform', verbose_name='Источник'), - ), - ] diff --git a/rsconcept/backend/apps/rsform/models/Constituenta.py b/rsconcept/backend/apps/rsform/models/Constituenta.py index fac888e3..03baa666 100644 --- a/rsconcept/backend/apps/rsform/models/Constituenta.py +++ b/rsconcept/backend/apps/rsform/models/Constituenta.py @@ -20,10 +20,6 @@ _REF_ENTITY_PATTERN = re.compile(r'@{([^0-9\-].*?)\|.*?}') _GLOBAL_ID_PATTERN = re.compile(r'([XCSADFPT][0-9]+)') # cspell:disable-line -def _empty_forms(): - return [] - - class CstType(TextChoices): ''' Type of constituenta. ''' BASE = 'basic' @@ -40,7 +36,7 @@ class Constituenta(Model): ''' Constituenta is the base unit for every conceptual schema. ''' schema: ForeignKey = ForeignKey( verbose_name='Концептуальная схема', - to='rsform.RSForm', + to='library.LibraryItem', on_delete=CASCADE ) order: PositiveIntegerField = PositiveIntegerField( @@ -76,7 +72,7 @@ class Constituenta(Model): ) term_forms: JSONField = JSONField( verbose_name='Словоформы', - default=_empty_forms + default=list ) definition_formal: TextField = TextField( verbose_name='Родоструктурное определение', diff --git a/rsconcept/backend/apps/rsform/models/RSForm.py b/rsconcept/backend/apps/rsform/models/RSForm.py index 959d6dd2..06531b90 100644 --- a/rsconcept/backend/apps/rsform/models/RSForm.py +++ b/rsconcept/backend/apps/rsform/models/RSForm.py @@ -5,8 +5,9 @@ from typing import Optional, cast from cctext import Entity, Resolver, TermForm, extract_entities, split_grams from django.core.exceptions import ValidationError from django.db import transaction -from django.db.models import Manager, QuerySet +from django.db.models import QuerySet +from apps.library.models import LibraryItem, LibraryItemType, Version from shared import messages as msg from ..graph import Graph @@ -22,35 +23,39 @@ from .api_RSLanguage import ( split_template ) from .Constituenta import Constituenta, CstType -from .LibraryItem import LibraryItem, LibraryItemType -from .Version import Version _INSERT_LAST: int = -1 -class RSForm(LibraryItem): +class RSForm: ''' RSForm is math form of conceptual schema. ''' - class Meta: - ''' Model metadata. ''' - proxy = True + def __init__(self, model: LibraryItem): + self.model = model - class InternalManager(Manager): - ''' Object manager. ''' + @staticmethod + def create(**kwargs) -> 'RSForm': + ''' Create LibraryItem via RSForm. ''' + model = LibraryItem.objects.create(item_type=LibraryItemType.RSFORM, **kwargs) + return RSForm(model) - def get_queryset(self) -> QuerySet: - return super().get_queryset().filter(item_type=LibraryItemType.RSFORM) + @staticmethod + def from_id(pk: int) -> 'RSForm': + ''' Get LibraryItem by pk. ''' + model = LibraryItem.objects.get(pk=pk) + return RSForm(model) - def create(self, **kwargs): - kwargs.update({'item_type': LibraryItemType.RSFORM}) - return super().create(**kwargs) + def save(self, *args, **kwargs): + ''' Model wrapper. ''' + self.model.save(*args, **kwargs) - # Legit overriding object manager - objects = InternalManager() # type: ignore[misc] + def refresh_from_db(self): + ''' Model wrapper. ''' + self.model.refresh_from_db() def constituents(self) -> QuerySet[Constituenta]: ''' Get QuerySet containing all constituents of current RSForm. ''' - return Constituenta.objects.filter(schema=self.pk) + return Constituenta.objects.filter(schema=self.model) def resolver(self) -> Resolver: ''' Create resolver for text references based on schema terms. ''' @@ -106,7 +111,7 @@ class RSForm(LibraryItem): ''' Get maximum alias index for specific CstType. ''' result: int = 0 items = Constituenta.objects \ - .filter(schema=self, cst_type=cst_type) \ + .filter(schema=self.model, cst_type=cst_type) \ .order_by('-alias') \ .values_list('alias', flat=True) for alias in items: @@ -158,7 +163,7 @@ class RSForm(LibraryItem): cst_type = guess_type(alias) self._shift_positions(position, 1) result = Constituenta.objects.create( - schema=self, + schema=self.model, order=position, alias=alias, cst_type=cst_type, @@ -191,7 +196,7 @@ class RSForm(LibraryItem): result = deepcopy(items) for cst in result: cst.pk = None - cst.schema = self + cst.schema = self.model cst.order = position cst.alias = mapping[cst.alias] cst.apply_mapping(mapping) @@ -304,7 +309,7 @@ class RSForm(LibraryItem): def create_version(self, version: str, description: str, data) -> Version: ''' Creates version for current state. ''' return Version.objects.create( - item=self, + item=self.model, version=version, description=description, data=data @@ -330,7 +335,7 @@ class RSForm(LibraryItem): prefix = get_type_prefix(cst_type) for text in expressions: new_item = Constituenta.objects.create( - schema=self, + schema=self.model, order=position, alias=f'{prefix}{free_index}', definition_formal=text, @@ -349,7 +354,7 @@ class RSForm(LibraryItem): update_list = \ Constituenta.objects \ .only('id', 'order', 'schema') \ - .filter(schema=self.pk, order__gte=start) + .filter(schema=self.model, order__gte=start) for cst in update_list: cst.order += shift Constituenta.objects.bulk_update(update_list, ['order']) diff --git a/rsconcept/backend/apps/rsform/models/__init__.py b/rsconcept/backend/apps/rsform/models/__init__.py index d6a5bc27..132f6d46 100644 --- a/rsconcept/backend/apps/rsform/models/__init__.py +++ b/rsconcept/backend/apps/rsform/models/__init__.py @@ -1,16 +1,4 @@ ''' Django: Models. ''' +from .Constituenta import Constituenta, CstType from .RSForm import RSForm -from .Constituenta import Constituenta, CstType, _empty_forms -from .Editor import Editor -from .LibraryItem import ( - AccessPolicy, - LibraryItem, - LibraryItemType, - LocationHead, - User, - validate_location -) -from .LibraryTemplate import LibraryTemplate -from .Subscription import Subscription -from .Version import Version diff --git a/rsconcept/backend/apps/rsform/serializers/__init__.py b/rsconcept/backend/apps/rsform/serializers/__init__.py index 897a27c9..1ede4f4b 100644 --- a/rsconcept/backend/apps/rsform/serializers/__init__.py +++ b/rsconcept/backend/apps/rsform/serializers/__init__.py @@ -1,11 +1,9 @@ ''' REST API: Serializers. ''' from .basics import ( - AccessPolicySerializer, ASTNodeSerializer, ExpressionParseSerializer, ExpressionSerializer, - LocationSerializer, MultiFormSerializer, ResolverSerializer, TextSerializer, @@ -20,22 +18,9 @@ from .data_access import ( CstSubstituteSerializer, CstTargetSerializer, InlineSynthesisSerializer, - LibraryItemBaseSerializer, - LibraryItemCloneSerializer, - LibraryItemDetailsSerializer, - LibraryItemSerializer, RSFormParseSerializer, - RSFormSerializer, - UsersListSerializer, - UserTargetSerializer, - VersionCreateSerializer, - VersionSerializer + RSFormSerializer ) from .io_files import FileSerializer, RSFormTRSSerializer, RSFormUploadSerializer from .io_pyconcept import PyConceptAdapter -from .schema_typing import ( - NewCstResponse, - NewMultiCstResponse, - NewVersionResponse, - ResultTextResponse -) +from .responses import NewCstResponse, NewMultiCstResponse, ResultTextResponse diff --git a/rsconcept/backend/apps/rsform/serializers/basics.py b/rsconcept/backend/apps/rsform/serializers/basics.py index a7a19c3b..40afd0a5 100644 --- a/rsconcept/backend/apps/rsform/serializers/basics.py +++ b/rsconcept/backend/apps/rsform/serializers/basics.py @@ -4,10 +4,6 @@ from typing import cast from cctext import EntityReference, Reference, ReferenceType, Resolver, SyntacticReference from rest_framework import serializers -from shared import messages as msg - -from ..models import AccessPolicy, validate_location - class ExpressionSerializer(serializers.Serializer): ''' Serializer: RSLang expression. ''' @@ -20,32 +16,6 @@ class WordFormSerializer(serializers.Serializer): grams = serializers.CharField() -class LocationSerializer(serializers.Serializer): - ''' Serializer: Item location. ''' - location = serializers.CharField(max_length=500) - - def validate(self, attrs): - attrs = super().validate(attrs) - if not validate_location(attrs['location']): - raise serializers.ValidationError({ - 'location': msg.invalidLocation() - }) - return attrs - - -class AccessPolicySerializer(serializers.Serializer): - ''' Serializer: Constituenta renaming. ''' - access_policy = serializers.CharField() - - def validate(self, attrs): - attrs = super().validate(attrs) - if not attrs['access_policy'] in AccessPolicy.values: - raise serializers.ValidationError({ - 'access_policy': msg.invalidEnum(attrs['access_policy']) - }) - return attrs - - class MultiFormSerializer(serializers.Serializer): ''' Serializer: inflect request. ''' items = serializers.ListField( diff --git a/rsconcept/backend/apps/rsform/serializers/data_access.py b/rsconcept/backend/apps/rsform/serializers/data_access.py index 68d9e1a1..aaecfd2f 100644 --- a/rsconcept/backend/apps/rsform/serializers/data_access.py +++ b/rsconcept/backend/apps/rsform/serializers/data_access.py @@ -7,89 +7,15 @@ from django.db import transaction from rest_framework import serializers from rest_framework.serializers import PrimaryKeyRelatedField as PKField +from apps.library.models import LibraryItem +from apps.library.serializers import LibraryItemBaseSerializer, LibraryItemDetailsSerializer from shared import messages as msg -from ..models import Constituenta, CstType, LibraryItem, RSForm, Version +from ..models import Constituenta, CstType, RSForm from .basics import CstParseSerializer from .io_pyconcept import PyConceptAdapter -class LibraryItemBaseSerializer(serializers.ModelSerializer): - ''' Serializer: LibraryItem entry full access. ''' - class Meta: - ''' serializer metadata. ''' - model = LibraryItem - fields = '__all__' - read_only_fields = ('id',) - - -class LibraryItemSerializer(serializers.ModelSerializer): - ''' Serializer: LibraryItem entry limited access. ''' - class Meta: - ''' serializer metadata. ''' - model = LibraryItem - fields = '__all__' - read_only_fields = ('id', 'item_type', 'owner', 'location', 'access_policy') - - -class LibraryItemCloneSerializer(serializers.ModelSerializer): - ''' Serializer: LibraryItem cloning. ''' - items = PKField(many=True, required=False, queryset=Constituenta.objects.all()) - - class Meta: - ''' serializer metadata. ''' - model = LibraryItem - exclude = ['id', 'item_type', 'owner'] - - -class VersionSerializer(serializers.ModelSerializer): - ''' Serializer: Version data. ''' - class Meta: - ''' serializer metadata. ''' - model = Version - fields = 'id', 'version', 'item', 'description', 'time_create' - read_only_fields = ('id', 'item', 'time_create') - - -class VersionInnerSerializer(serializers.ModelSerializer): - ''' Serializer: Version data for list of versions. ''' - class Meta: - ''' serializer metadata. ''' - model = Version - fields = 'id', 'version', 'description', 'time_create' - read_only_fields = ('id', 'item', 'time_create') - - -class VersionCreateSerializer(serializers.ModelSerializer): - ''' Serializer: Version create data. ''' - class Meta: - ''' serializer metadata. ''' - model = Version - fields = 'version', 'description' - - -class LibraryItemDetailsSerializer(serializers.ModelSerializer): - ''' Serializer: LibraryItem detailed data. ''' - subscribers = serializers.SerializerMethodField() - editors = serializers.SerializerMethodField() - versions = serializers.SerializerMethodField() - - class Meta: - ''' serializer metadata. ''' - model = LibraryItem - fields = '__all__' - read_only_fields = ('owner', 'id', 'item_type') - - def get_subscribers(self, instance: LibraryItem) -> list[int]: - return [item.pk for item in instance.subscribers()] - - def get_editors(self, instance: LibraryItem) -> list[int]: - return [item.pk for item in instance.editors()] - - def get_versions(self, instance: LibraryItem) -> list: - return [VersionInnerSerializer(item).data for item in instance.versions()] - - class CstBaseSerializer(serializers.ModelSerializer): ''' Serializer: Constituenta all data. ''' class Meta: @@ -112,18 +38,19 @@ class CstSerializer(serializers.ModelSerializer): definition: Optional[str] = data['definition_raw'] if 'definition_raw' in data else None term: Optional[str] = data['term_raw'] if 'term_raw' in data else None term_changed = 'term_forms' in data + schema = RSForm(instance.schema) if definition is not None and definition != instance.definition_raw: - data['definition_resolved'] = instance.schema.resolver().resolve(definition) + data['definition_resolved'] = schema.resolver().resolve(definition) if term is not None and term != instance.term_raw: - data['term_resolved'] = instance.schema.resolver().resolve(term) + data['term_resolved'] = schema.resolver().resolve(term) if data['term_resolved'] != instance.term_resolved and 'term_forms' not in data: data['term_forms'] = [] term_changed = data['term_resolved'] != instance.term_resolved result: Constituenta = super().update(instance, data) if term_changed: - instance.schema.on_term_change([result.id]) + schema.on_term_change([result.id]) result.refresh_from_db() - instance.schema.save() + schema.save() return result @@ -169,16 +96,16 @@ class RSFormSerializer(serializers.ModelSerializer): model = LibraryItem fields = '__all__' - def to_representation(self, instance: RSForm) -> dict: + def to_representation(self, instance: LibraryItem) -> dict: result = LibraryItemDetailsSerializer(instance).data result['items'] = [] - for cst in instance.constituents().order_by('order'): + for cst in RSForm(instance).constituents().order_by('order'): result['items'].append(CstSerializer(cst).data) return result def to_versioned_data(self) -> dict: ''' Create serializable version representation without redundant data. ''' - result = self.to_representation(cast(RSForm, self.instance)) + result = self.to_representation(cast(LibraryItem, self.instance)) del result['versions'] del result['subscribers'] del result['editors'] @@ -195,14 +122,14 @@ class RSFormSerializer(serializers.ModelSerializer): def from_versioned_data(self, version: int, data: dict) -> dict: ''' Load data from version. ''' - result = self.to_representation(cast(RSForm, self.instance)) + result = self.to_representation(cast(LibraryItem, self.instance)) result['version'] = version return result | data @transaction.atomic def restore_from_version(self, data: dict): ''' Load data from version. ''' - schema = cast(RSForm, self.instance) + schema = RSForm(cast(LibraryItem, self.instance)) items: list[dict] = data['items'] ids: list[int] = [item['id'] for item in items] processed: list[int] = [] @@ -256,13 +183,13 @@ class RSFormParseSerializer(serializers.ModelSerializer): model = LibraryItem fields = '__all__' - def to_representation(self, instance: RSForm): + def to_representation(self, instance: LibraryItem): result = RSFormSerializer(instance).data return self._parse_data(result) def from_versioned_data(self, version: int, data: dict) -> dict: ''' Load data from version and parse. ''' - item = cast(RSForm, self.instance) + item = cast(LibraryItem, self.instance) result = RSFormSerializer(item).from_versioned_data(version, data) return self._parse_data(result) @@ -281,7 +208,7 @@ class CstTargetSerializer(serializers.Serializer): target = PKField(many=False, queryset=Constituenta.objects.all()) def validate(self, attrs): - schema = cast(RSForm, self.context['schema']) + schema = cast(LibraryItem, self.context['schema']) cst = cast(Constituenta, attrs['target']) if schema and cst.schema != schema: raise serializers.ValidationError({ @@ -295,16 +222,6 @@ class CstTargetSerializer(serializers.Serializer): return attrs -class UserTargetSerializer(serializers.Serializer): - ''' Serializer: Target single User. ''' - user = PKField(many=False, queryset=User.objects.all()) - - -class UsersListSerializer(serializers.Serializer): - ''' Serializer: List of Users. ''' - users = PKField(many=True, queryset=User.objects.all()) - - class CstRenameSerializer(serializers.Serializer): ''' Serializer: Constituenta renaming. ''' target = PKField(many=False, queryset=Constituenta.objects.all()) @@ -313,7 +230,7 @@ class CstRenameSerializer(serializers.Serializer): def validate(self, attrs): attrs = super().validate(attrs) - schema = cast(RSForm, self.context['schema']) + schema = cast(LibraryItem, self.context['schema']) cst = cast(Constituenta, attrs['target']) if cst.schema != schema: raise serializers.ValidationError({ @@ -324,7 +241,7 @@ class CstRenameSerializer(serializers.Serializer): raise serializers.ValidationError({ 'alias': msg.renameTrivial(new_alias) }) - if schema.constituents().filter(alias=new_alias).exists(): + if RSForm(schema).constituents().filter(alias=new_alias).exists(): raise serializers.ValidationError({ 'alias': msg.aliasTaken(new_alias) }) @@ -336,7 +253,7 @@ class CstListSerializer(serializers.Serializer): items = PKField(many=True, queryset=Constituenta.objects.all()) def validate(self, attrs): - schema = cast(RSForm, self.context['schema']) + schema = cast(LibraryItem, self.context['schema']) if not schema: return attrs @@ -368,7 +285,7 @@ class CstSubstituteSerializer(serializers.Serializer): ) def validate(self, attrs): - schema = cast(RSForm, self.context['schema']) + schema = cast(LibraryItem, self.context['schema']) deleted = set() for item in attrs['substitutions']: original_cst = cast(Constituenta, item['original']) @@ -395,8 +312,8 @@ class CstSubstituteSerializer(serializers.Serializer): class InlineSynthesisSerializer(serializers.Serializer): ''' Serializer: Inline synthesis operation input. ''' - receiver = PKField(many=False, queryset=RSForm.objects.all()) - source = PKField(many=False, queryset=RSForm.objects.all()) # type: ignore + receiver = PKField(many=False, queryset=LibraryItem.objects.all()) + source = PKField(many=False, queryset=LibraryItem.objects.all()) # type: ignore items = PKField(many=True, queryset=Constituenta.objects.all()) substitutions = serializers.ListField( child=CstSubstituteSerializerBase() @@ -404,8 +321,8 @@ class InlineSynthesisSerializer(serializers.Serializer): def validate(self, attrs): user = cast(User, self.context['user']) - schema_in = cast(RSForm, attrs['source']) - schema_out = cast(RSForm, attrs['receiver']) + schema_in = cast(LibraryItem, attrs['source']) + schema_out = cast(LibraryItem, attrs['receiver']) if user.is_anonymous or (schema_out.owner != user and not user.is_staff): raise PermissionDenied({ 'message': msg.schemaNotOwned(), diff --git a/rsconcept/backend/apps/rsform/serializers/io_files.py b/rsconcept/backend/apps/rsform/serializers/io_files.py index bfb68894..c57ad279 100644 --- a/rsconcept/backend/apps/rsform/serializers/io_files.py +++ b/rsconcept/backend/apps/rsform/serializers/io_files.py @@ -2,6 +2,7 @@ from django.db import transaction from rest_framework import serializers +from apps.library.models import LibraryItem from shared import messages as msg from ..models import Constituenta, RSForm @@ -29,14 +30,14 @@ class RSFormTRSSerializer(serializers.Serializer): ''' Serializer: TRS file production and loading for RSForm. ''' def to_representation(self, instance: RSForm) -> dict: - result = self._prepare_json_rsform(instance) + result = self._prepare_json_rsform(instance.model) items = instance.constituents().order_by('order') for cst in items: result['items'].append(self._prepare_json_constituenta(cst)) return result @staticmethod - def _prepare_json_rsform(schema: RSForm) -> dict: + def _prepare_json_rsform(schema: LibraryItem) -> dict: return { 'type': _TRS_TYPE, 'title': schema.title, @@ -125,7 +126,7 @@ class RSFormTRSSerializer(serializers.Serializer): result['comment'] = data.get('comment', '') if 'id' in data: result['id'] = data['id'] - self.instance = RSForm.objects.get(pk=result['id']) + self.instance = RSForm.from_id(result['id']) return result def validate(self, attrs: dict): @@ -139,7 +140,7 @@ class RSFormTRSSerializer(serializers.Serializer): @transaction.atomic def create(self, validated_data: dict) -> RSForm: - self.instance: RSForm = RSForm.objects.create( + self.instance: RSForm = RSForm.create( owner=validated_data.get('owner', None), alias=validated_data['alias'], title=validated_data['title'], @@ -154,7 +155,7 @@ class RSFormTRSSerializer(serializers.Serializer): for cst_data in validated_data['items']: cst = Constituenta( alias=cst_data['alias'], - schema=self.instance, + schema=self.instance.model, order=order, cst_type=cst_data['cstType'], ) @@ -167,11 +168,11 @@ class RSFormTRSSerializer(serializers.Serializer): @transaction.atomic def update(self, instance: RSForm, validated_data) -> RSForm: if 'alias' in validated_data: - instance.alias = validated_data['alias'] + instance.model.alias = validated_data['alias'] if 'title' in validated_data: - instance.title = validated_data['title'] + instance.model.title = validated_data['title'] if 'comment' in validated_data: - instance.comment = validated_data['comment'] + instance.model.comment = validated_data['comment'] order = 1 prev_constituents = instance.constituents() @@ -188,7 +189,7 @@ class RSFormTRSSerializer(serializers.Serializer): else: cst = Constituenta( alias=cst_data['alias'], - schema=instance, + schema=instance.model, order=order, cst_type=cst_data['cstType'], ) diff --git a/rsconcept/backend/apps/rsform/serializers/schema_typing.py b/rsconcept/backend/apps/rsform/serializers/responses.py similarity index 80% rename from rsconcept/backend/apps/rsform/serializers/schema_typing.py rename to rsconcept/backend/apps/rsform/serializers/responses.py index 43ff4e53..ec11ba95 100644 --- a/rsconcept/backend/apps/rsform/serializers/schema_typing.py +++ b/rsconcept/backend/apps/rsform/serializers/responses.py @@ -21,9 +21,3 @@ class NewMultiCstResponse(serializers.Serializer): child=serializers.IntegerField() ) schema = RSFormParseSerializer() - - -class NewVersionResponse(serializers.Serializer): - ''' Serializer: Create cst response. ''' - version = serializers.IntegerField() - schema = RSFormParseSerializer() diff --git a/rsconcept/backend/apps/rsform/tests/s_models/__init__.py b/rsconcept/backend/apps/rsform/tests/s_models/__init__.py index 44295f0f..00e25b86 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/__init__.py +++ b/rsconcept/backend/apps/rsform/tests/s_models/__init__.py @@ -1,6 +1,3 @@ ''' Tests for Django Models. ''' from .t_Constituenta import * -from .t_Editor import * -from .t_LibraryItem import * from .t_RSForm import * -from .t_Subscription import * diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_Constituenta.py b/rsconcept/backend/apps/rsform/tests/s_models/t_Constituenta.py index 83d56973..0d254249 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/t_Constituenta.py +++ b/rsconcept/backend/apps/rsform/tests/s_models/t_Constituenta.py @@ -3,42 +3,42 @@ from django.db.utils import IntegrityError from django.forms import ValidationError from django.test import TestCase -from apps.rsform.models import Constituenta, CstType, LibraryItemType, RSForm +from apps.rsform.models import Constituenta, CstType, RSForm class TestConstituenta(TestCase): ''' Testing Constituenta model. ''' def setUp(self): - self.schema1 = RSForm.objects.create(title='Test1') - self.schema2 = RSForm.objects.create(title='Test2') + self.schema1 = RSForm.create(title='Test1') + self.schema2 = RSForm.create(title='Test2') def test_str(self): testStr = 'X1' - cst = Constituenta.objects.create(alias=testStr, schema=self.schema1, order=1, convention='Test') + cst = Constituenta.objects.create(alias=testStr, schema=self.schema1.model, order=1, convention='Test') self.assertEqual(str(cst), testStr) def test_url(self): testStr = 'X1' - cst = Constituenta.objects.create(alias=testStr, schema=self.schema1, order=1, convention='Test') + cst = Constituenta.objects.create(alias=testStr, schema=self.schema1.model, order=1, convention='Test') self.assertEqual(cst.get_absolute_url(), f'/api/constituents/{cst.pk}') def test_order_not_null(self): with self.assertRaises(IntegrityError): - Constituenta.objects.create(alias='X1', schema=self.schema1) + Constituenta.objects.create(alias='X1', schema=self.schema1.model) def test_order_positive_integer(self): with self.assertRaises(IntegrityError): - Constituenta.objects.create(alias='X1', schema=self.schema1, order=-1) + Constituenta.objects.create(alias='X1', schema=self.schema1.model, order=-1) def test_order_min_value(self): with self.assertRaises(ValidationError): - cst = Constituenta.objects.create(alias='X1', schema=self.schema1, order=0) + cst = Constituenta.objects.create(alias='X1', schema=self.schema1.model, order=0) cst.full_clean() @@ -50,10 +50,10 @@ class TestConstituenta(TestCase): def test_create_default(self): cst = Constituenta.objects.create( alias='X1', - schema=self.schema1, + schema=self.schema1.model, order=1 ) - self.assertEqual(cst.schema, self.schema1) + self.assertEqual(cst.schema, self.schema1.model) self.assertEqual(cst.order, 1) self.assertEqual(cst.alias, 'X1') self.assertEqual(cst.cst_type, CstType.BASE) diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py b/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py index 9c47a3ac..28333d03 100644 --- a/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py +++ b/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py @@ -2,7 +2,8 @@ from django.forms import ValidationError from django.test import TestCase -from apps.rsform.models import Constituenta, CstType, RSForm, User +from apps.rsform.models import Constituenta, CstType, RSForm +from apps.users.models import User class TestRSForm(TestCase): @@ -11,49 +12,49 @@ class TestRSForm(TestCase): def setUp(self): self.user1 = User.objects.create(username='User1') self.user2 = User.objects.create(username='User2') - self.schema = RSForm.objects.create(title='Test') + self.schema = RSForm.create(title='Test') self.assertNotEqual(self.user1, self.user2) def test_constituents(self): - schema1 = RSForm.objects.create(title='Test1') - schema2 = RSForm.objects.create(title='Test2') + schema1 = RSForm.create(title='Test1') + schema2 = RSForm.create(title='Test2') self.assertFalse(schema1.constituents().exists()) self.assertFalse(schema2.constituents().exists()) - Constituenta.objects.create(alias='X1', schema=schema1, order=1) - Constituenta.objects.create(alias='X2', schema=schema1, order=2) + Constituenta.objects.create(alias='X1', schema=schema1.model, order=1) + Constituenta.objects.create(alias='X2', schema=schema1.model, order=2) self.assertTrue(schema1.constituents().exists()) self.assertFalse(schema2.constituents().exists()) self.assertEqual(schema1.constituents().count(), 2) def test_get_max_index(self): - schema1 = RSForm.objects.create(title='Test1') - Constituenta.objects.create(alias='X1', schema=schema1, order=1) - Constituenta.objects.create(alias='D2', cst_type=CstType.TERM, schema=schema1, order=2) + schema1 = RSForm.create(title='Test1') + Constituenta.objects.create(alias='X1', schema=schema1.model, order=1) + Constituenta.objects.create(alias='D2', cst_type=CstType.TERM, schema=schema1.model, order=2) self.assertEqual(schema1.get_max_index(CstType.BASE), 1) self.assertEqual(schema1.get_max_index(CstType.TERM), 2) self.assertEqual(schema1.get_max_index(CstType.AXIOM), 0) def test_insert_at(self): - schema = RSForm.objects.create(title='Test') + schema = RSForm.create(title='Test') x1 = schema.insert_new('X1') self.assertEqual(x1.order, 1) - self.assertEqual(x1.schema, schema) + self.assertEqual(x1.schema, schema.model) x2 = schema.insert_new('X2', position=1) x1.refresh_from_db() self.assertEqual(x2.order, 1) - self.assertEqual(x2.schema, schema) + self.assertEqual(x2.schema, schema.model) self.assertEqual(x1.order, 2) x3 = schema.insert_new('X3', position=4) x2.refresh_from_db() x1.refresh_from_db() self.assertEqual(x3.order, 3) - self.assertEqual(x3.schema, schema) + self.assertEqual(x3.schema, schema.model) self.assertEqual(x2.order, 1) self.assertEqual(x1.order, 2) @@ -62,7 +63,7 @@ class TestRSForm(TestCase): x2.refresh_from_db() x1.refresh_from_db() self.assertEqual(x4.order, 3) - self.assertEqual(x4.schema, schema) + self.assertEqual(x4.schema, schema.model) self.assertEqual(x3.order, 4) self.assertEqual(x2.order, 1) self.assertEqual(x1.order, 2) @@ -94,11 +95,11 @@ class TestRSForm(TestCase): def test_insert_last(self): x1 = self.schema.insert_new('X1') self.assertEqual(x1.order, 1) - self.assertEqual(x1.schema, self.schema) + self.assertEqual(x1.schema, self.schema.model) x2 = self.schema.insert_new('X2') self.assertEqual(x2.order, 2) - self.assertEqual(x2.schema, self.schema) + self.assertEqual(x2.schema, self.schema.model) self.assertEqual(x1.order, 1) def test_create_cst(self): diff --git a/rsconcept/backend/apps/rsform/tests/s_views/__init__.py b/rsconcept/backend/apps/rsform/tests/s_views/__init__.py index 376add39..1a564c03 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/__init__.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/__init__.py @@ -1,9 +1,6 @@ ''' Tests for REST API. ''' -from .t_library import * +from .t_cctext import * from .t_constituents import * from .t_operations import * from .t_rsforms import * -from .t_versions import * - -from .t_cctext import * from .t_rslang import * diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py b/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py index a166a8af..24159ea3 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py @@ -8,12 +8,12 @@ class TestConstituentaAPI(EndpointTester): def setUp(self): super().setUp() - self.rsform_owned = RSForm.objects.create(title='Test', alias='T1', owner=self.user) - self.rsform_unowned = RSForm.objects.create(title='Test2', alias='T2') + self.rsform_owned = RSForm.create(title='Test', alias='T1', owner=self.user) + self.rsform_unowned = RSForm.create(title='Test2', alias='T2') self.cst1 = Constituenta.objects.create( alias='X1', cst_type=CstType.BASE, - schema=self.rsform_owned, + schema=self.rsform_owned.model, order=1, convention='Test', term_raw='Test1', @@ -22,7 +22,7 @@ class TestConstituentaAPI(EndpointTester): self.cst2 = Constituenta.objects.create( alias='X2', cst_type=CstType.BASE, - schema=self.rsform_unowned, + schema=self.rsform_unowned.model, order=1, convention='Test1', term_raw='Test2', @@ -30,7 +30,7 @@ class TestConstituentaAPI(EndpointTester): ) self.cst3 = Constituenta.objects.create( alias='X3', - schema=self.rsform_owned, + schema=self.rsform_owned.model, order=2, term_raw='Test3', term_resolved='Test3', diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py b/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py index 38b7e003..dc0e3eb9 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py @@ -10,16 +10,16 @@ class TestInlineSynthesis(EndpointTester): @decl_endpoint('/api/operations/inline-synthesis', method='patch') def setUp(self): super().setUp() - self.schema1 = RSForm.objects.create(title='Test1', alias='T1', owner=self.user) - self.schema2 = RSForm.objects.create(title='Test2', alias='T2', owner=self.user) - self.unowned = RSForm.objects.create(title='Test3', alias='T3') + self.schema1 = RSForm.create(title='Test1', alias='T1', owner=self.user) + self.schema2 = RSForm.create(title='Test2', alias='T2', owner=self.user) + self.unowned = RSForm.create(title='Test3', alias='T3') def test_inline_synthesis_inputs(self): invalid_id = 1338 data = { - 'receiver': self.unowned.pk, - 'source': self.schema1.pk, + 'receiver': self.unowned.model.pk, + 'source': self.schema1.model.pk, 'items': [], 'substitutions': [] } @@ -28,11 +28,11 @@ class TestInlineSynthesis(EndpointTester): data['receiver'] = invalid_id self.executeBadData(data=data) - data['receiver'] = self.schema1.pk + data['receiver'] = self.schema1.model.pk data['source'] = invalid_id self.executeBadData(data=data) - data['source'] = self.schema1.pk + data['source'] = self.schema1.model.pk self.executeOK(data=data) data['items'] = [invalid_id] @@ -51,8 +51,8 @@ class TestInlineSynthesis(EndpointTester): ks2_a1 = self.schema2.insert_new('A1', definition_formal='1=1') # -> not included in items data = { - 'receiver': self.schema1.pk, - 'source': self.schema2.pk, + 'receiver': self.schema1.model.pk, + 'source': self.schema2.model.pk, 'items': [ks2_x1.pk, ks2_x2.pk, ks2_s1.pk, ks2_d1.pk], 'substitutions': [ { diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py index 27383b7a..f8f76fc5 100644 --- a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py +++ b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py @@ -6,15 +6,8 @@ from zipfile import ZipFile from cctext import ReferenceType from rest_framework import status -from apps.rsform.models import ( - AccessPolicy, - Constituenta, - CstType, - LibraryItem, - LibraryItemType, - LocationHead, - RSForm -) +from apps.library.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead +from apps.rsform.models import Constituenta, CstType, RSForm from shared.EndpointTester import EndpointTester, decl_endpoint from shared.testing_utils import response_contains @@ -24,12 +17,12 @@ class TestRSFormViewset(EndpointTester): def setUp(self): super().setUp() - self.owned = RSForm.objects.create(title='Test', alias='T1', owner=self.user) - self.owned_id = self.owned.pk - self.unowned = RSForm.objects.create(title='Test2', alias='T2') - self.unowned_id = self.unowned.pk - self.private = RSForm.objects.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE) - self.private_id = self.private.pk + self.owned = RSForm.create(title='Test', alias='T1', owner=self.user) + self.owned_id = self.owned.model.pk + self.unowned = RSForm.create(title='Test2', alias='T2') + self.unowned_id = self.unowned.model.pk + self.private = RSForm.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE) + self.private_id = self.private.model.pk @decl_endpoint('/api/rsforms/create-detailed', method='post') @@ -57,25 +50,25 @@ class TestRSFormViewset(EndpointTester): @decl_endpoint('/api/rsforms', method='get') def test_list_rsforms(self): - non_schema = LibraryItem.objects.create( + oss = LibraryItem.objects.create( item_type=LibraryItemType.OPERATION_SCHEMA, title='Test3' ) response = self.executeOK() - self.assertFalse(response_contains(response, non_schema)) - self.assertTrue(response_contains(response, self.unowned)) - self.assertTrue(response_contains(response, self.owned)) + self.assertFalse(response_contains(response, oss)) + self.assertTrue(response_contains(response, self.unowned.model)) + self.assertTrue(response_contains(response, self.owned.model)) @decl_endpoint('/api/rsforms/{item}/contents', method='get') def test_contents(self): response = self.executeOK(item=self.owned_id) - self.assertEqual(response.data['owner'], self.owned.owner.pk) - self.assertEqual(response.data['title'], self.owned.title) - self.assertEqual(response.data['alias'], self.owned.alias) - self.assertEqual(response.data['location'], self.owned.location) - self.assertEqual(response.data['access_policy'], self.owned.access_policy) - self.assertEqual(response.data['visible'], self.owned.visible) + self.assertEqual(response.data['owner'], self.owned.model.owner.pk) + self.assertEqual(response.data['title'], self.owned.model.title) + self.assertEqual(response.data['alias'], self.owned.model.alias) + self.assertEqual(response.data['location'], self.owned.model.location) + self.assertEqual(response.data['access_policy'], self.owned.model.access_policy) + self.assertEqual(response.data['visible'], self.owned.model.visible) @decl_endpoint('/api/rsforms/{item}/details', method='get') @@ -92,12 +85,12 @@ class TestRSFormViewset(EndpointTester): ) response = self.executeOK(item=self.owned_id) - self.assertEqual(response.data['owner'], self.owned.owner.pk) - self.assertEqual(response.data['title'], self.owned.title) - self.assertEqual(response.data['alias'], self.owned.alias) - self.assertEqual(response.data['location'], self.owned.location) - self.assertEqual(response.data['access_policy'], self.owned.access_policy) - self.assertEqual(response.data['visible'], self.owned.visible) + self.assertEqual(response.data['owner'], self.owned.model.owner.pk) + self.assertEqual(response.data['title'], self.owned.model.title) + self.assertEqual(response.data['alias'], self.owned.model.alias) + self.assertEqual(response.data['location'], self.owned.model.location) + self.assertEqual(response.data['access_policy'], self.owned.model.access_policy) + self.assertEqual(response.data['visible'], self.owned.model.visible) self.assertEqual(len(response.data['items']), 2) self.assertEqual(response.data['items'][0]['id'], x1.pk) @@ -176,9 +169,9 @@ class TestRSFormViewset(EndpointTester): @decl_endpoint('/api/rsforms/{item}/export-trs', method='get') def test_export_trs(self): - schema = RSForm.objects.create(title='Test') + schema = RSForm.create(title='Test') schema.insert_new('X1') - response = self.executeOK(item=schema.pk) + response = self.executeOK(item=schema.model.pk) self.assertEqual(response.headers['Content-Disposition'], 'attachment; filename=Schema.trs') with io.BytesIO(response.content) as stream: with ZipFile(stream, 'r') as zipped_file: @@ -458,7 +451,7 @@ class TestRSFormViewset(EndpointTester): @decl_endpoint('/api/rsforms/{item}/load-trs', method='patch') def test_load_trs(self): self.set_params(item=self.owned_id) - self.owned.title = 'Test11' + self.owned.model.title = 'Test11' self.owned.save() x1 = self.owned.insert_new('X1') work_dir = os.path.dirname(os.path.abspath(__file__)) @@ -467,7 +460,7 @@ class TestRSFormViewset(EndpointTester): response = self.client.patch(self.endpoint, data=data, format='multipart') self.owned.refresh_from_db() self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(self.owned.title, 'Test11') + self.assertEqual(self.owned.model.title, 'Test11') self.assertEqual(len(response.data['items']), 25) self.assertEqual(self.owned.constituents().count(), 25) self.assertFalse(Constituenta.objects.filter(pk=x1.pk).exists()) diff --git a/rsconcept/backend/apps/rsform/urls.py b/rsconcept/backend/apps/rsform/urls.py index d4df9cb0..4cd7e04d 100644 --- a/rsconcept/backend/apps/rsform/urls.py +++ b/rsconcept/backend/apps/rsform/urls.py @@ -5,22 +5,14 @@ from rest_framework import routers from . import views library_router = routers.SimpleRouter(trailing_slash=False) -library_router.register('library', views.LibraryViewSet, 'Library') library_router.register('rsforms', views.RSFormViewSet, 'RSForm') -library_router.register('versions', views.VersionViewset, 'Version') + urlpatterns = [ - path('library/active', views.LibraryActiveView.as_view()), - path('library/all', views.LibraryAdminView.as_view()), - path('library/templates', views.LibraryTemplatesView.as_view(), name='templates'), path('constituents/', views.ConstituentAPIView.as_view(), name='constituenta-detail'), path('rsforms/import-trs', views.TrsImportView.as_view()), path('rsforms/create-detailed', views.create_rsform), - path('versions//export-file', views.export_file), - path('rsforms//versions/create', views.create_version), - path('rsforms//versions/', views.retrieve_version), - path('operations/inline-synthesis', views.inline_synthesis), path('rslang/parse-expression', views.parse_expression), diff --git a/rsconcept/backend/apps/rsform/utils.py b/rsconcept/backend/apps/rsform/utils.py index 5b3e1d80..b7ccbc72 100644 --- a/rsconcept/backend/apps/rsform/utils.py +++ b/rsconcept/backend/apps/rsform/utils.py @@ -1,8 +1,5 @@ ''' Utility functions ''' -import json import re -from io import BytesIO -from zipfile import ZipFile # Name for JSON inside Exteor files archive EXTEOR_INNER_FILENAME = 'document.json' @@ -11,23 +8,6 @@ EXTEOR_INNER_FILENAME = 'document.json' _REF_OLD_PATTERN = re.compile(r'@{([^0-9\-][^\}\|\{]*?)\|([^\}\|\{]*?)\|([^\}\|\{]*?)}') -def read_zipped_json(data, json_filename: str) -> dict: - ''' Read JSON from zipped data ''' - with ZipFile(data, 'r') as archive: - json_data = archive.read(json_filename) - result: dict = json.loads(json_data) - return result - - -def write_zipped_json(json_data: dict, json_filename: str) -> bytes: - ''' Write json JSON to bytes buffer ''' - content = BytesIO() - data = json.dumps(json_data, indent=4, ensure_ascii=False) - with ZipFile(content, 'w') as archive: - archive.writestr(json_filename, data=data) - return content.getvalue() - - def apply_pattern(text: str, mapping: dict[str, str], pattern: re.Pattern[str]) -> str: ''' Apply mapping to matching in regular expression pattern subgroup 1 ''' if text == '' or pattern == '': diff --git a/rsconcept/backend/apps/rsform/views/__init__.py b/rsconcept/backend/apps/rsform/views/__init__.py index 61c0a1d0..df6a6b85 100644 --- a/rsconcept/backend/apps/rsform/views/__init__.py +++ b/rsconcept/backend/apps/rsform/views/__init__.py @@ -1,8 +1,6 @@ ''' REST API: Endpoint processors. ''' from .cctext import generate_lexeme, inflect, parse_text from .constituents import ConstituentAPIView -from .library import LibraryActiveView, LibraryAdminView, LibraryTemplatesView, LibraryViewSet from .operations import inline_synthesis from .rsforms import RSFormViewSet, TrsImportView, create_rsform from .rslang import convert_to_ascii, convert_to_math, parse_expression -from .versions import VersionViewset, create_version, export_file, retrieve_version diff --git a/rsconcept/backend/apps/rsform/views/operations.py b/rsconcept/backend/apps/rsform/views/operations.py index 51e441e8..5b2a01a4 100644 --- a/rsconcept/backend/apps/rsform/views/operations.py +++ b/rsconcept/backend/apps/rsform/views/operations.py @@ -27,11 +27,11 @@ def inline_synthesis(request: Request): ) serializer.is_valid(raise_exception=True) - schema = cast(m.RSForm, serializer.validated_data['receiver']) + receiver = m.RSForm(serializer.validated_data['receiver']) items = cast(list[m.Constituenta], serializer.validated_data['items']) with transaction.atomic(): - new_items = schema.insert_copy(items) + new_items = receiver.insert_copy(items) for substitution in serializer.validated_data['substitutions']: original = cast(m.Constituenta, substitution['original']) replacement = cast(m.Constituenta, substitution['substitution']) @@ -41,10 +41,10 @@ def inline_synthesis(request: Request): else: index = next(i for (i, cst) in enumerate(items) if cst == replacement) replacement = new_items[index] - schema.substitute(original, replacement, substitution['transfer_term']) - schema.restore_order() + receiver.substitute(original, replacement, substitution['transfer_term']) + receiver.restore_order() return Response( status=c.HTTP_200_OK, - data=s.RSFormParseSerializer(schema).data + data=s.RSFormParseSerializer(receiver.model).data ) diff --git a/rsconcept/backend/apps/rsform/views/rsforms.py b/rsconcept/backend/apps/rsform/views/rsforms.py index 030de8ce..0c7908f8 100644 --- a/rsconcept/backend/apps/rsform/views/rsforms.py +++ b/rsconcept/backend/apps/rsform/views/rsforms.py @@ -13,8 +13,11 @@ from rest_framework.decorators import action, api_view from rest_framework.request import Request from rest_framework.response import Response +from apps.library.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead +from apps.library.serializers import LibraryItemSerializer +from apps.users.models import User from shared import messages as msg -from shared import permissions +from shared import permissions, utility from .. import models as m from .. import serializers as s @@ -25,11 +28,11 @@ from .. import utils @extend_schema_view() class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.RetrieveAPIView): ''' Endpoint: RSForm operations. ''' - queryset = m.RSForm.objects.all() - serializer_class = s.LibraryItemSerializer + queryset = LibraryItem.objects.filter(item_type=LibraryItemType.RSFORM) + serializer_class = LibraryItemSerializer - def _get_schema(self) -> m.RSForm: - return cast(m.RSForm, self.get_object()) + def _get_item(self) -> LibraryItem: + return cast(LibraryItem, self.get_object()) def get_permissions(self): ''' Determine permission class. ''' @@ -71,18 +74,18 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['post'], url_path='create-cst') def create_cst(self, request: Request, pk): ''' Create new constituenta. ''' - schema = self._get_schema() + schema = self._get_item() serializer = s.CstCreateSerializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.validated_data if 'insert_after' in data and data['insert_after'] is not None: try: insert_after = m.Constituenta.objects.get(pk=data['insert_after']) - except m.LibraryItem.DoesNotExist: + except LibraryItem.DoesNotExist: return Response(status=c.HTTP_404_NOT_FOUND) else: insert_after = None - new_cst = schema.create_cst(data, insert_after) + new_cst = m.RSForm(schema).create_cst(data, insert_after) schema.refresh_from_db() response = Response( @@ -109,7 +112,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='produce-structure') def produce_structure(self, request: Request, pk): ''' Produce a term for every element of the target constituenta typification. ''' - schema = self._get_schema() + schema = self._get_item() serializer = s.CstTargetSerializer(data=request.data, context={'schema': schema}) serializer.is_valid(raise_exception=True) @@ -123,7 +126,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr data={f'{cst.id}': msg.constituentaNoStructure()} ) - result = schema.produce_structure(cst, cst_parse) + result = m.RSForm(schema).produce_structure(cst, cst_parse) return Response( status=c.HTTP_200_OK, data={ @@ -146,7 +149,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='rename-cst') def rename_cst(self, request: Request, pk): ''' Rename constituenta possibly changing type. ''' - schema = self._get_schema() + schema = self._get_item() serializer = s.CstRenameSerializer(data=request.data, context={'schema': schema}) serializer.is_valid(raise_exception=True) @@ -158,10 +161,10 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr with transaction.atomic(): cst.save() - schema.apply_mapping(mapping={old_alias: cst.alias}, change_aliases=False) - schema.refresh_from_db() - cst.refresh_from_db() + m.RSForm(schema).apply_mapping(mapping={old_alias: cst.alias}, change_aliases=False) + schema.refresh_from_db() + cst.refresh_from_db() return Response( status=c.HTTP_200_OK, data={ @@ -184,7 +187,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='substitute') def substitute(self, request: Request, pk): ''' Substitute occurrences of constituenta with another one. ''' - schema = self._get_schema() + schema = self._get_item() serializer = s.CstSubstituteSerializer( data=request.data, context={'schema': schema} @@ -195,8 +198,9 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr for substitution in serializer.validated_data['substitutions']: original = cast(m.Constituenta, substitution['original']) replacement = cast(m.Constituenta, substitution['substitution']) - schema.substitute(original, replacement, substitution['transfer_term']) - schema.refresh_from_db() + m.RSForm(schema).substitute(original, replacement, substitution['transfer_term']) + + schema.refresh_from_db() return Response( status=c.HTTP_200_OK, data=s.RSFormParseSerializer(schema).data @@ -216,13 +220,14 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='delete-multiple-cst') def delete_multiple_cst(self, request: Request, pk): ''' Endpoint: Delete multiple constituents. ''' - schema = self._get_schema() + schema = self._get_item() serializer = s.CstListSerializer( data=request.data, context={'schema': schema} ) serializer.is_valid(raise_exception=True) - schema.delete_cst(serializer.validated_data['items']) + m.RSForm(schema).delete_cst(serializer.validated_data['items']) + schema.refresh_from_db() return Response( status=c.HTTP_200_OK, @@ -243,13 +248,13 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='move-cst') def move_cst(self, request: Request, pk): ''' Endpoint: Move multiple constituents. ''' - schema = self._get_schema() + schema = self._get_item() serializer = s.CstMoveSerializer( data=request.data, context={'schema': schema} ) serializer.is_valid(raise_exception=True) - schema.move_cst( + m.RSForm(schema).move_cst( listCst=serializer.validated_data['items'], target=serializer.validated_data['move_to'] ) @@ -271,8 +276,8 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='reset-aliases') def reset_aliases(self, request: Request, pk): ''' Endpoint: Recreate all aliases based on order. ''' - schema = self._get_schema() - schema.reset_aliases() + schema = self._get_item() + m.RSForm(schema).reset_aliases() return Response( status=c.HTTP_200_OK, data=s.RSFormParseSerializer(schema).data @@ -291,8 +296,8 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['patch'], url_path='restore-order') def restore_order(self, request: Request, pk): ''' Endpoint: Restore order based on types and term graph. ''' - schema = self._get_schema() - schema.restore_order() + schema = self._get_item() + m.RSForm(schema).restore_order() return Response( status=c.HTTP_200_OK, data=s.RSFormParseSerializer(schema).data @@ -314,9 +319,10 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr ''' Endpoint: Load data from file and replace current schema. ''' input_serializer = s.RSFormUploadSerializer(data=request.data) input_serializer.is_valid(raise_exception=True) - schema = self._get_schema() + + schema = self._get_item() load_metadata = input_serializer.validated_data['load_metadata'] - data = utils.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME) + data = utility.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME) data['id'] = schema.pk serializer = s.RSFormTRSSerializer( @@ -324,10 +330,10 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr context={'load_meta': load_metadata} ) serializer.is_valid(raise_exception=True) - result = serializer.save() + result: m.RSForm = serializer.save() return Response( status=c.HTTP_200_OK, - data=s.RSFormParseSerializer(result).data + data=s.RSFormParseSerializer(result.model).data ) @extend_schema( @@ -342,10 +348,10 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['get'], url_path='contents') def contents(self, request: Request, pk): ''' Endpoint: View schema db contents (including constituents). ''' - schema = s.RSFormSerializer(self.get_object()) + serializer = s.RSFormSerializer(self.get_object()) return Response( status=c.HTTP_200_OK, - data=schema.data + data=serializer.data ) @extend_schema( @@ -360,7 +366,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['get'], url_path='details') def details(self, request: Request, pk): ''' Endpoint: Detailed schema view including statuses and parse. ''' - serializer = s.RSFormParseSerializer(self._get_schema()) + serializer = s.RSFormParseSerializer(self.get_object()) return Response( status=c.HTTP_200_OK, data=serializer.data @@ -381,8 +387,8 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr serializer = s.ExpressionSerializer(data=request.data) serializer.is_valid(raise_exception=True) expression = serializer.validated_data['expression'] - schema = s.PyConceptAdapter(self._get_schema()) - result = pyconcept.check_expression(json.dumps(schema.data), expression) + pySchema = s.PyConceptAdapter(m.RSForm(self.get_object())) + result = pyconcept.check_expression(json.dumps(pySchema.data), expression) return Response( status=c.HTTP_200_OK, data=json.loads(result) @@ -403,7 +409,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr serializer = s.TextSerializer(data=request.data) serializer.is_valid(raise_exception=True) text = serializer.validated_data['text'] - resolver = self._get_schema().resolver() + resolver = m.RSForm(self.get_object()).resolver() resolver.resolve(text) return Response( status=c.HTTP_200_OK, @@ -422,9 +428,10 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr @action(detail=True, methods=['get'], url_path='export-trs') def export_trs(self, request: Request, pk): ''' Endpoint: Download Exteor compatible file. ''' - data = s.RSFormTRSSerializer(self._get_schema()).data - file = utils.write_zipped_json(data, utils.EXTEOR_INNER_FILENAME) - filename = utils.filename_for_schema(self._get_schema().alias) + schema = self._get_item() + data = s.RSFormTRSSerializer(m.RSForm(schema)).data + file = utility.write_zipped_json(data, utils.EXTEOR_INNER_FILENAME) + filename = utils.filename_for_schema(schema.alias) response = HttpResponse(file, content_type='application/zip') response['Content-Disposition'] = f'attachment; filename={filename}' return response @@ -440,33 +447,32 @@ class TrsImportView(views.APIView): tags=['RSForm'], request=s.FileSerializer, responses={ - c.HTTP_201_CREATED: s.LibraryItemSerializer, + c.HTTP_201_CREATED: LibraryItemSerializer, c.HTTP_403_FORBIDDEN: None } ) def post(self, request: Request): - data = utils.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME) - owner = cast(m.User, self.request.user) + data = utility.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME) + owner = cast(User, self.request.user) _prepare_rsform_data(data, request, owner) serializer = s.RSFormTRSSerializer( data=data, context={'load_meta': True} ) serializer.is_valid(raise_exception=True) - schema = serializer.save() - result = s.LibraryItemSerializer(schema) + schema: m.RSForm = serializer.save() return Response( status=c.HTTP_201_CREATED, - data=result.data + data=LibraryItemSerializer(schema.model).data ) @extend_schema( summary='create new RSForm empty or from file', tags=['RSForm'], - request=s.LibraryItemSerializer, + request=LibraryItemSerializer, responses={ - c.HTTP_201_CREATED: s.LibraryItemSerializer, + c.HTTP_201_CREATED: LibraryItemSerializer, c.HTTP_400_BAD_REQUEST: None, c.HTTP_403_FORBIDDEN: None } @@ -474,26 +480,25 @@ class TrsImportView(views.APIView): @api_view(['POST']) def create_rsform(request: Request): ''' Endpoint: Create RSForm from user input and/or trs file. ''' - owner = cast(m.User, request.user) if not request.user.is_anonymous else None + owner = cast(User, request.user) if not request.user.is_anonymous else None if 'file' not in request.FILES: return Response( status=c.HTTP_400_BAD_REQUEST, data={'file': msg.missingFile()} ) - else: - data = utils.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME) - _prepare_rsform_data(data, request, owner) - serializer_rsform = s.RSFormTRSSerializer(data=data, context={'load_meta': True}) - serializer_rsform.is_valid(raise_exception=True) - schema = serializer_rsform.save() - result = s.LibraryItemSerializer(schema) + + data = utility.read_zipped_json(request.FILES['file'].file, utils.EXTEOR_INNER_FILENAME) + _prepare_rsform_data(data, request, owner) + serializer_rsform = s.RSFormTRSSerializer(data=data, context={'load_meta': True}) + serializer_rsform.is_valid(raise_exception=True) + schema: m.RSForm = serializer_rsform.save() return Response( status=c.HTTP_201_CREATED, - data=result.data + data=LibraryItemSerializer(schema.model).data ) -def _prepare_rsform_data(data: dict, request: Request, owner: Union[m.User, None]): +def _prepare_rsform_data(data: dict, request: Request, owner: Union[User, None]): data['owner'] = owner if 'title' in request.data and request.data['title'] != '': data['title'] = request.data['title'] @@ -514,5 +519,5 @@ def _prepare_rsform_data(data: dict, request: Request, owner: Union[m.User, None read_only = request.data['read_only'] == 'true' data['read_only'] = read_only - data['access_policy'] = request.data.get('access_policy', m.AccessPolicy.PUBLIC) - data['location'] = request.data.get('location', m.LocationHead.USER) + data['access_policy'] = request.data.get('access_policy', AccessPolicy.PUBLIC) + data['location'] = request.data.get('location', LocationHead.USER) diff --git a/rsconcept/backend/apps/users/serializers.py b/rsconcept/backend/apps/users/serializers.py index 31f9c2e0..2bffed65 100644 --- a/rsconcept/backend/apps/users/serializers.py +++ b/rsconcept/backend/apps/users/serializers.py @@ -3,7 +3,7 @@ from django.contrib.auth import authenticate from django.contrib.auth.password_validation import validate_password from rest_framework import serializers -from apps.rsform.models import Editor, Subscription +from apps.library.models import Editor, Subscription from shared import messages as msg from . import models diff --git a/rsconcept/backend/fixtures/InitialData.json b/rsconcept/backend/fixtures/InitialData.json index cfb7982c..510deb98 100644 --- a/rsconcept/backend/fixtures/InitialData.json +++ b/rsconcept/backend/fixtures/InitialData.json @@ -1,4786 +1,4786 @@ [ -{ + { "model": "auth.user", "pk": 1, "fields": { - "password": "pbkdf2_sha256$720000$gFZkaBswurtL0naQKiUnW7$3b6SUN3fY2Xl1H7erAszVpQl2LpoKusan+yJP7Bp3JA=", - "last_login": "2024-06-03T20:57:02.522Z", - "is_superuser": true, - "username": "admin", - "first_name": "Администратор", - "last_name": "", - "email": "admin@mail.ru", - "is_staff": true, - "is_active": true, - "date_joined": "2024-05-27T18:31:48.913Z", - "groups": [], - "user_permissions": [] + "password": "pbkdf2_sha256$720000$gFZkaBswurtL0naQKiUnW7$3b6SUN3fY2Xl1H7erAszVpQl2LpoKusan+yJP7Bp3JA=", + "last_login": "2024-06-03T20:57:02.522Z", + "is_superuser": true, + "username": "admin", + "first_name": "Администратор", + "last_name": "", + "email": "admin@mail.ru", + "is_staff": true, + "is_active": true, + "date_joined": "2024-05-27T18:31:48.913Z", + "groups": [], + "user_permissions": [] } -}, -{ + }, + { "model": "auth.user", "pk": 3, "fields": { - "password": "pbkdf2_sha256$720000$UrGOcoUoKyC5A0nCXwNszp$UR3FdvkB9EkQ8PT+mJ7CtCyrwbmmz3tYZcZKTaxyzoM=", - "last_login": "2024-06-03T20:57:25.539Z", - "is_superuser": false, - "username": "User1", - "first_name": "User1", - "last_name": "", - "email": "User1@test.ru", - "is_staff": false, - "is_active": true, - "date_joined": "2024-06-03T20:52:55.670Z", - "groups": [], - "user_permissions": [] + "password": "pbkdf2_sha256$720000$UrGOcoUoKyC5A0nCXwNszp$UR3FdvkB9EkQ8PT+mJ7CtCyrwbmmz3tYZcZKTaxyzoM=", + "last_login": "2024-06-03T20:57:25.539Z", + "is_superuser": false, + "username": "User1", + "first_name": "User1", + "last_name": "", + "email": "User1@test.ru", + "is_staff": false, + "is_active": true, + "date_joined": "2024-06-03T20:52:55.670Z", + "groups": [], + "user_permissions": [] } -}, -{ + }, + { "model": "auth.user", "pk": 4, "fields": { - "password": "pbkdf2_sha256$720000$2gYTKuX3Wiap5y3AokUpub$PExwc31nwYTLFOZDwHpg5loC8WOi//EZvSJ8V9TCmIs=", - "last_login": null, - "is_superuser": false, - "username": "User2", - "first_name": "User2", - "last_name": "", - "email": "User2@test.ru", - "is_staff": false, - "is_active": true, - "date_joined": "2024-06-03T20:53:20.356Z", - "groups": [], - "user_permissions": [] + "password": "pbkdf2_sha256$720000$2gYTKuX3Wiap5y3AokUpub$PExwc31nwYTLFOZDwHpg5loC8WOi//EZvSJ8V9TCmIs=", + "last_login": null, + "is_superuser": false, + "username": "User2", + "first_name": "User2", + "last_name": "", + "email": "User2@test.ru", + "is_staff": false, + "is_active": true, + "date_joined": "2024-06-03T20:53:20.356Z", + "groups": [], + "user_permissions": [] } -}, -{ + }, + { "model": "auth.user", "pk": 5, "fields": { - "password": "pbkdf2_sha256$720000$uoCzGQ7zxoJOqZ3d8y99nl$d0frHrK9a4ydo0iNp4kGLAsq5eZ4QpQl1lU2bXR3elI=", - "last_login": "2024-06-03T20:53:51.231Z", - "is_superuser": false, - "username": "User3", - "first_name": "User3", - "last_name": "", - "email": "User3@test.ru", - "is_staff": false, - "is_active": true, - "date_joined": "2024-06-03T20:53:45.900Z", - "groups": [], - "user_permissions": [] + "password": "pbkdf2_sha256$720000$uoCzGQ7zxoJOqZ3d8y99nl$d0frHrK9a4ydo0iNp4kGLAsq5eZ4QpQl1lU2bXR3elI=", + "last_login": "2024-06-03T20:53:51.231Z", + "is_superuser": false, + "username": "User3", + "first_name": "User3", + "last_name": "", + "email": "User3@test.ru", + "is_staff": false, + "is_active": true, + "date_joined": "2024-06-03T20:53:45.900Z", + "groups": [], + "user_permissions": [] } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 589, "fields": { - "schema": 34, - "order": 1, - "alias": "T1", - "cst_type": "theorem", - "convention": "", - "term_raw": "Управляющие конструкции", - "term_resolved": "Управляющие конструкции", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 1, + "alias": "T1", + "cst_type": "theorem", + "convention": "", + "term_raw": "Управляющие конструкции", + "term_resolved": "Управляющие конструкции", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 590, "fields": { - "schema": 34, - "order": 2, - "alias": "F1", - "cst_type": "function", - "convention": "", - "term_raw": "схема ограниченного выделения", - "term_resolved": "схема ограниченного выделения", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1)] D{ ξ∈α | ξ=ξ }", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 2, + "alias": "F1", + "cst_type": "function", + "convention": "", + "term_raw": "схема ограниченного выделения", + "term_resolved": "схема ограниченного выделения", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1)] D{ ξ∈α | ξ=ξ }", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 591, "fields": { - "schema": 34, - "order": 3, - "alias": "F2", - "cst_type": "function", - "convention": "", - "term_raw": "условный переход", - "term_resolved": "условный переход", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1)] debool(I{ α | 1=1} ∪ I{ α\\α | 1≠1})", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 3, + "alias": "F2", + "cst_type": "function", + "convention": "", + "term_raw": "условный переход", + "term_resolved": "условный переход", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1)] debool(I{ α | 1=1} ∪ I{ α\\α | 1≠1})", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 592, "fields": { - "schema": 34, - "order": 4, - "alias": "F3", - "cst_type": "function", - "convention": "", - "term_raw": "рекурсивное определение", - "term_resolved": "рекурсивное определение", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1)] R{ ξ:=α | ξ≠∅ | ξ\\ξ }", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 4, + "alias": "F3", + "cst_type": "function", + "convention": "", + "term_raw": "рекурсивное определение", + "term_resolved": "рекурсивное определение", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1)] R{ ξ:=α | ξ≠∅ | ξ\\ξ }", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 593, "fields": { - "schema": 34, - "order": 5, - "alias": "T2", - "cst_type": "theorem", - "convention": "", - "term_raw": "Бинарные отношения двух множеств", - "term_resolved": "Бинарные отношения двух множеств", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 5, + "alias": "T2", + "cst_type": "theorem", + "convention": "", + "term_raw": "Бинарные отношения двух множеств", + "term_resolved": "Бинарные отношения двух множеств", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 594, "fields": { - "schema": 34, - "order": 6, - "alias": "F4", - "cst_type": "function", - "convention": "", - "term_raw": "обратное отношение", - "term_resolved": "обратное отношение", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R2)] Pr2,1(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 6, + "alias": "F4", + "cst_type": "function", + "convention": "", + "term_raw": "обратное отношение", + "term_resolved": "обратное отношение", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R2)] Pr2,1(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 595, "fields": { - "schema": 34, - "order": 7, - "alias": "P1", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство всюдуопределенности", - "term_resolved": "свойство всюдуопределенности", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R2)] Pr1(σ) = α", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 7, + "alias": "P1", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство всюдуопределенности", + "term_resolved": "свойство всюдуопределенности", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R2)] Pr1(σ) = α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 596, "fields": { - "schema": 34, - "order": 8, - "alias": "P2", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство всюдузначности", - "term_resolved": "свойство всюдузначности", - "term_forms": [], - "definition_formal": "[α∈ℬ(R2), σ∈ℬ(R1×R2)] Pr2(σ) = α", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 8, + "alias": "P2", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство всюдузначности", + "term_resolved": "свойство всюдузначности", + "term_forms": [], + "definition_formal": "[α∈ℬ(R2), σ∈ℬ(R1×R2)] Pr2(σ) = α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 597, "fields": { - "schema": 34, - "order": 9, - "alias": "P3", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство прямой однозначности", - "term_resolved": "свойство прямой однозначности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R2)] card(Pr1(σ)) = card(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 9, + "alias": "P3", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство прямой однозначности", + "term_resolved": "свойство прямой однозначности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R2)] card(Pr1(σ)) = card(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 598, "fields": { - "schema": 34, - "order": 10, - "alias": "P4", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство обратной однозначности", - "term_resolved": "свойство обратной однозначности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R2)] card(Pr2(σ)) = card(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 10, + "alias": "P4", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство обратной однозначности", + "term_resolved": "свойство обратной однозначности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R2)] card(Pr2(σ)) = card(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 599, "fields": { - "schema": 34, - "order": 11, - "alias": "P5", - "cst_type": "predicate", - "convention": "", - "term_raw": "функция", - "term_resolved": "функция", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R2)] card(Pr1(σ)) = card(σ) & Pr1(σ) = α", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 11, + "alias": "P5", + "cst_type": "predicate", + "convention": "", + "term_raw": "функция", + "term_resolved": "функция", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R2)] card(Pr1(σ)) = card(σ) & Pr1(σ) = α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 600, "fields": { - "schema": 34, - "order": 12, - "alias": "F5", - "cst_type": "function", - "convention": "", - "term_raw": "образ элемента", - "term_resolved": "образ элемента", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R2)] debool(Pr2(Fi1[{α}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 12, + "alias": "F5", + "cst_type": "function", + "convention": "", + "term_raw": "образ элемента", + "term_resolved": "образ элемента", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R2)] debool(Pr2(Fi1[{α}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 601, "fields": { - "schema": 34, - "order": 13, - "alias": "F6", - "cst_type": "function", - "convention": "", - "term_raw": "сечение по элементу", - "term_resolved": "сечение по элементу", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R2)] Pr2(Fi1[{α}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 13, + "alias": "F6", + "cst_type": "function", + "convention": "", + "term_raw": "сечение по элементу", + "term_resolved": "сечение по элементу", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R2)] Pr2(Fi1[{α}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 602, "fields": { - "schema": 34, - "order": 14, - "alias": "F7", - "cst_type": "function", - "convention": "", - "term_raw": "прообраз значения", - "term_resolved": "прообраз значения", - "term_forms": [], - "definition_formal": "[α∈R2, σ∈ℬ(R1×R2)] debool(Pr1(Fi2[{α}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 14, + "alias": "F7", + "cst_type": "function", + "convention": "", + "term_raw": "прообраз значения", + "term_resolved": "прообраз значения", + "term_forms": [], + "definition_formal": "[α∈R2, σ∈ℬ(R1×R2)] debool(Pr1(Fi2[{α}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 603, "fields": { - "schema": 34, - "order": 15, - "alias": "F8", - "cst_type": "function", - "convention": "", - "term_raw": "сечение по значению", - "term_resolved": "сечение по значению", - "term_forms": [], - "definition_formal": "[α∈R2, σ∈ℬ(R1×R2)] Pr1(Fi2[{α}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 15, + "alias": "F8", + "cst_type": "function", + "convention": "", + "term_raw": "сечение по значению", + "term_resolved": "сечение по значению", + "term_forms": [], + "definition_formal": "[α∈R2, σ∈ℬ(R1×R2)] Pr1(Fi2[{α}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 604, "fields": { - "schema": 34, - "order": 16, - "alias": "F9", - "cst_type": "function", - "convention": "", - "term_raw": "образ множества", - "term_resolved": "образ множества", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R2)] Pr2(Fi1[α](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 16, + "alias": "F9", + "cst_type": "function", + "convention": "", + "term_raw": "образ множества", + "term_resolved": "образ множества", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R2)] Pr2(Fi1[α](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 605, "fields": { - "schema": 34, - "order": 17, - "alias": "F10", - "cst_type": "function", - "convention": "", - "term_raw": "прообраз множества", - "term_resolved": "прообраз множества", - "term_forms": [], - "definition_formal": "[α∈ℬ(R2), σ∈ℬ(R1×R2)] Pr1(Fi2[α](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 17, + "alias": "F10", + "cst_type": "function", + "convention": "", + "term_raw": "прообраз множества", + "term_resolved": "прообраз множества", + "term_forms": [], + "definition_formal": "[α∈ℬ(R2), σ∈ℬ(R1×R2)] Pr1(Fi2[α](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 606, "fields": { - "schema": 34, - "order": 18, - "alias": "F11", - "cst_type": "function", - "convention": "", - "term_raw": "композиция отношений", - "term_resolved": "композиция отношений", - "term_forms": [], - "definition_formal": "[σ1∈ℬ(R1×R2), σ2∈ℬ(R2×R3)] \nI{(ξ1, ξ3) | (ξ1,ξ2):∈σ1; ξ3:∈Pr2(Fi1[{ξ2}](σ2))}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 18, + "alias": "F11", + "cst_type": "function", + "convention": "", + "term_raw": "композиция отношений", + "term_resolved": "композиция отношений", + "term_forms": [], + "definition_formal": "[σ1∈ℬ(R1×R2), σ2∈ℬ(R2×R3)] \nI{(ξ1, ξ3) | (ξ1,ξ2):∈σ1; ξ3:∈Pr2(Fi1[{ξ2}](σ2))}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 607, "fields": { - "schema": 34, - "order": 19, - "alias": "T3", - "cst_type": "theorem", - "convention": "", - "term_raw": "Бинарные отношения на множестве", - "term_resolved": "Бинарные отношения на множестве", - "term_forms": [], - "definition_formal": "T2", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 19, + "alias": "T3", + "cst_type": "theorem", + "convention": "", + "term_raw": "Бинарные отношения на множестве", + "term_resolved": "Бинарные отношения на множестве", + "term_forms": [], + "definition_formal": "T2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 608, "fields": { - "schema": 34, - "order": 20, - "alias": "F12", - "cst_type": "function", - "convention": "", - "term_raw": "участники отношения", - "term_resolved": "участники отношения", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1(σ)∪Pr2(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 20, + "alias": "F12", + "cst_type": "function", + "convention": "", + "term_raw": "участники отношения", + "term_resolved": "участники отношения", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1(σ)∪Pr2(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 609, "fields": { - "schema": 34, - "order": 21, - "alias": "P6", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство полноты (линейности)", - "term_resolved": "свойство полноты (линейности)", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] σ∪Pr2,1(σ)∪Pr1,1(σ)∪Pr2,2(σ) = α×α", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 21, + "alias": "P6", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство полноты (линейности)", + "term_resolved": "свойство полноты (линейности)", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] σ∪Pr2,1(σ)∪Pr1,1(σ)∪Pr2,2(σ) = α×α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 610, "fields": { - "schema": 34, - "order": 22, - "alias": "P7", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство симметричности", - "term_resolved": "свойство симметричности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr2,1(σ) = σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 22, + "alias": "P7", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство симметричности", + "term_resolved": "свойство симметричности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr2,1(σ) = σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 611, "fields": { - "schema": 34, - "order": 23, - "alias": "P8", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство антисимметричности", - "term_resolved": "свойство антисимметричности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] (Pr2,1(σ)∩σ)\\Pr1,1(σ) = ∅", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 23, + "alias": "P8", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство антисимметричности", + "term_resolved": "свойство антисимметричности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] (Pr2,1(σ)∩σ)\\Pr1,1(σ) = ∅", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 612, "fields": { - "schema": 34, - "order": 24, - "alias": "P9", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство рефлексивности", - "term_resolved": "свойство рефлексивности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ) ⊆ σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 24, + "alias": "P9", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство рефлексивности", + "term_resolved": "свойство рефлексивности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ) ⊆ σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 613, "fields": { - "schema": 34, - "order": 25, - "alias": "P10", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство антирефлексивности", - "term_resolved": "свойство антирефлексивности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ)∩σ = ∅", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 25, + "alias": "P10", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство антирефлексивности", + "term_resolved": "свойство антирефлексивности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ)∩σ = ∅", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 614, "fields": { - "schema": 34, - "order": 26, - "alias": "P11", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство транзитивности", - "term_resolved": "свойство транзитивности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] ∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 26, + "alias": "P11", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство транзитивности", + "term_resolved": "свойство транзитивности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] ∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 615, "fields": { - "schema": 34, - "order": 27, - "alias": "P12", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство фундированности", - "term_resolved": "свойство фундированности", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] ∀γ∈ℬ(α) (γ≠∅ ⇒ card(F13[γ,σ])>0)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 27, + "alias": "P12", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство фундированности", + "term_resolved": "свойство фундированности", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] ∀γ∈ℬ(α) (γ≠∅ ⇒ card(F13[γ,σ])>0)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 616, "fields": { - "schema": 34, - "order": 28, - "alias": "P13", - "cst_type": "predicate", - "convention": "", - "term_raw": "существование infinum для отношения на данном !подмножестве!", - "term_resolved": "существование infinum для отношения на данном !подмножестве!", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] ∀ξ1,ξ2∈α ∃ε∈α ((ε,ξ1)∈σ & (ε,ξ2)∈σ & ∀ξ3∈α\\{ε} ((ξ3,ξ1)∈σ & (ξ3,ξ2)∈σ ⇒ (ξ3,ε)∈σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 28, + "alias": "P13", + "cst_type": "predicate", + "convention": "", + "term_raw": "существование infinum для отношения на данном !подмножестве!", + "term_resolved": "существование infinum для отношения на данном !подмножестве!", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] ∀ξ1,ξ2∈α ∃ε∈α ((ε,ξ1)∈σ & (ε,ξ2)∈σ & ∀ξ3∈α\\{ε} ((ξ3,ξ1)∈σ & (ξ3,ξ2)∈σ ⇒ (ξ3,ε)∈σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 617, "fields": { - "schema": 34, - "order": 29, - "alias": "P14", - "cst_type": "predicate", - "convention": "", - "term_raw": "существование supremum для отношения на данном !подмножестве!", - "term_resolved": "существование supremum для отношения на данном !подмножестве!", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] ∀ξ1,ξ2∈α ∃π∈α ((ξ1,π)∈σ & (ξ2,π)∈σ & ∀ξ3∈α\\{π} ((ξ1,ξ3)∈σ & (ξ2,ξ3)∈σ ⇒ (π,ξ3)∈σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 29, + "alias": "P14", + "cst_type": "predicate", + "convention": "", + "term_raw": "существование supremum для отношения на данном !подмножестве!", + "term_resolved": "существование supremum для отношения на данном !подмножестве!", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] ∀ξ1,ξ2∈α ∃π∈α ((ξ1,π)∈σ & (ξ2,π)∈σ & ∀ξ3∈α\\{π} ((ξ1,ξ3)∈σ & (ξ2,ξ3)∈σ ⇒ (π,ξ3)∈σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 618, "fields": { - "schema": 34, - "order": 30, - "alias": "P15", - "cst_type": "predicate", - "convention": "", - "term_raw": "частичный порядок", - "term_resolved": "частичный порядок", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)]\nPr2,1(σ)∩σ\\Pr1,1(σ) = ∅ & \n(Pr1,1(σ)∩σ = ∅ ∨ Pr1,1(σ) ⊆ σ) & \n∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 30, + "alias": "P15", + "cst_type": "predicate", + "convention": "", + "term_raw": "частичный порядок", + "term_resolved": "частичный порядок", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)]\nPr2,1(σ)∩σ\\Pr1,1(σ) = ∅ & \n(Pr1,1(σ)∩σ = ∅ ∨ Pr1,1(σ) ⊆ σ) & \n∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 619, "fields": { - "schema": 34, - "order": 31, - "alias": "P16", - "cst_type": "predicate", - "convention": "", - "term_raw": "линейный порядок", - "term_resolved": "линейный порядок", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)]\nPr2,1(σ)∩σ\\Pr1,1(σ) = ∅ & \n(Pr1,1(σ)∩σ = ∅ ∨ Pr1,1(σ) ⊆ σ) & \n∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ) & \nσ∪Pr2,1(σ)∪Pr1,1(σ)∪Pr2,2(σ) = α×α", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 31, + "alias": "P16", + "cst_type": "predicate", + "convention": "", + "term_raw": "линейный порядок", + "term_resolved": "линейный порядок", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)]\nPr2,1(σ)∩σ\\Pr1,1(σ) = ∅ & \n(Pr1,1(σ)∩σ = ∅ ∨ Pr1,1(σ) ⊆ σ) & \n∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ) & \nσ∪Pr2,1(σ)∪Pr1,1(σ)∪Pr2,2(σ) = α×α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 620, "fields": { - "schema": 34, - "order": 32, - "alias": "F13", - "cst_type": "function", - "convention": "альтернативное определение:\n[α∈ℬ(R1), σ∈ℬ(R1×R1)] D{ξ∈α | ∀ω∈α\\{ξ} (ω, ξ)∉σ}", - "term_raw": "минимальные элементы !порядка! на данном !подмножестве!", - "term_resolved": "минимальные элементы !порядка! на данном !подмножестве!", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] α \\ Pr2(Fi1,2[α, α](σ))", - "definition_raw": "элементы, для которых отсутствуют большие их элементы", - "definition_resolved": "элементы, для которых отсутствуют большие их элементы" + "schema": 34, + "order": 32, + "alias": "F13", + "cst_type": "function", + "convention": "альтернативное определение:\n[α∈ℬ(R1), σ∈ℬ(R1×R1)] D{ξ∈α | ∀ω∈α\\{ξ} (ω, ξ)∉σ}", + "term_raw": "минимальные элементы !порядка! на данном !подмножестве!", + "term_resolved": "минимальные элементы !порядка! на данном !подмножестве!", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] α \\ Pr2(Fi1,2[α, α](σ))", + "definition_raw": "элементы, для которых отсутствуют большие их элементы", + "definition_resolved": "элементы, для которых отсутствуют большие их элементы" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 621, "fields": { - "schema": 34, - "order": 33, - "alias": "F14", - "cst_type": "function", - "convention": "альтернативное определение:\n[α∈ℬ(R1), σ∈ℬ(R1×R1)] debool(D{ξ∈α | ∀ω∈α\\{ξ} (ξ, ω)∈σ})", - "term_raw": "наименьший элемент !порядка! на данном !подмножестве!", - "term_resolved": "наименьший элемент !порядка! на данном !подмножестве!", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] debool(I{ β | δ1:=Fi1,2[α, α](σ); δ2:=δ1\\Pr1,1(δ1); β:=Pr1(δ2)\\Pr2(δ2) })", - "definition_raw": "элементы, меньшие или равные всем остальным", - "definition_resolved": "элементы, меньшие или равные всем остальным" + "schema": 34, + "order": 33, + "alias": "F14", + "cst_type": "function", + "convention": "альтернативное определение:\n[α∈ℬ(R1), σ∈ℬ(R1×R1)] debool(D{ξ∈α | ∀ω∈α\\{ξ} (ξ, ω)∈σ})", + "term_raw": "наименьший элемент !порядка! на данном !подмножестве!", + "term_resolved": "наименьший элемент !порядка! на данном !подмножестве!", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] debool(I{ β | δ1:=Fi1,2[α, α](σ); δ2:=δ1\\Pr1,1(δ1); β:=Pr1(δ2)\\Pr2(δ2) })", + "definition_raw": "элементы, меньшие или равные всем остальным", + "definition_resolved": "элементы, меньшие или равные всем остальным" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 622, "fields": { - "schema": 34, - "order": 34, - "alias": "P17", - "cst_type": "predicate", - "convention": "", - "term_raw": "эквивалентность", - "term_resolved": "эквивалентность", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ) ⊆ σ & Pr2,1(σ) = σ & \n∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ)", - "definition_raw": "транзитивное рефлексивное симметричное бинарное отношение", - "definition_resolved": "транзитивное рефлексивное симметричное бинарное отношение" + "schema": 34, + "order": 34, + "alias": "P17", + "cst_type": "predicate", + "convention": "", + "term_raw": "эквивалентность", + "term_resolved": "эквивалентность", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ) ⊆ σ & Pr2,1(σ) = σ & \n∀(α1,α2),(β1,β2)∈σ (α2=β1 ⇒ (α1,β2)∈σ)", + "definition_raw": "транзитивное рефлексивное симметричное бинарное отношение", + "definition_resolved": "транзитивное рефлексивное симметричное бинарное отношение" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 623, "fields": { - "schema": 34, - "order": 35, - "alias": "F15", - "cst_type": "function", - "convention": "", - "term_raw": "класс эквивалентности !элемента!", - "term_resolved": "класс эквивалентности !элемента!", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] Pr2(Fi1[{α}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 35, + "alias": "F15", + "cst_type": "function", + "convention": "", + "term_raw": "класс эквивалентности !элемента!", + "term_resolved": "класс эквивалентности !элемента!", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] Pr2(Fi1[{α}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 624, "fields": { - "schema": 34, - "order": 36, - "alias": "P18", - "cst_type": "predicate", - "convention": "", - "term_raw": "толерантность", - "term_resolved": "толерантность", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ) ⊆ σ & Pr2,1(σ) = σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 36, + "alias": "P18", + "cst_type": "predicate", + "convention": "", + "term_raw": "толерантность", + "term_resolved": "толерантность", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1,1(σ) ⊆ σ & Pr2,1(σ) = σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 625, "fields": { - "schema": 34, - "order": 37, - "alias": "T4", - "cst_type": "theorem", - "convention": "", - "term_raw": "Цепочки", - "term_resolved": "Цепочки", - "term_forms": [], - "definition_formal": "T2 & T3", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 37, + "alias": "T4", + "cst_type": "theorem", + "convention": "", + "term_raw": "Цепочки", + "term_resolved": "Цепочки", + "term_forms": [], + "definition_formal": "T2 & T3", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 626, "fields": { - "schema": 34, - "order": 38, - "alias": "P19", - "cst_type": "predicate", - "convention": "", - "term_raw": "условие связности цепочки", - "term_resolved": "условие связности цепочки", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)]\ncard(Pr1(σ)) = card(σ) & card(Pr2(σ)) = card(σ) &\ncard(Pr1(σ) \\ Pr2(σ)) = 1 & card(Pr2(σ) \\ Pr1(σ)) = 1", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 38, + "alias": "P19", + "cst_type": "predicate", + "convention": "", + "term_raw": "условие связности цепочки", + "term_resolved": "условие связности цепочки", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)]\ncard(Pr1(σ)) = card(σ) & card(Pr2(σ)) = card(σ) &\ncard(Pr1(σ) \\ Pr2(σ)) = 1 & card(Pr2(σ) \\ Pr1(σ)) = 1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 627, "fields": { - "schema": 34, - "order": 39, - "alias": "F16", - "cst_type": "function", - "convention": "", - "term_raw": "начало цепочки", - "term_resolved": "начало цепочки", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] debool(Pr1(σ) \\ Pr2(σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 39, + "alias": "F16", + "cst_type": "function", + "convention": "", + "term_raw": "начало цепочки", + "term_resolved": "начало цепочки", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] debool(Pr1(σ) \\ Pr2(σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 628, "fields": { - "schema": 34, - "order": 40, - "alias": "F17", - "cst_type": "function", - "convention": "", - "term_raw": "конец цепочки", - "term_resolved": "конец цепочки", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] debool(Pr2(σ) \\ Pr1(σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 40, + "alias": "F17", + "cst_type": "function", + "convention": "", + "term_raw": "конец цепочки", + "term_resolved": "конец цепочки", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] debool(Pr2(σ) \\ Pr1(σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 629, "fields": { - "schema": 34, - "order": 41, - "alias": "F18", - "cst_type": "function", - "convention": "", - "term_raw": "следующий за данным !элемент! цепочки", - "term_resolved": "следующий за данным !элемент! цепочки", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] debool(Pr2(Fi1[{α}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 41, + "alias": "F18", + "cst_type": "function", + "convention": "", + "term_raw": "следующий за данным !элемент! цепочки", + "term_resolved": "следующий за данным !элемент! цепочки", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] debool(Pr2(Fi1[{α}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 630, "fields": { - "schema": 34, - "order": 42, - "alias": "F19", - "cst_type": "function", - "convention": "", - "term_raw": "предшествующий данному !элемент! цепочки", - "term_resolved": "предшествующий данному !элемент! цепочки", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] debool(Pr1(Fi2[{α}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 42, + "alias": "F19", + "cst_type": "function", + "convention": "", + "term_raw": "предшествующий данному !элемент! цепочки", + "term_resolved": "предшествующий данному !элемент! цепочки", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] debool(Pr1(Fi2[{α}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 631, "fields": { - "schema": 34, - "order": 43, - "alias": "T5", - "cst_type": "theorem", - "convention": "", - "term_raw": "Графы", - "term_resolved": "Графы", - "term_forms": [], - "definition_formal": "T2 & T3", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 43, + "alias": "T5", + "cst_type": "theorem", + "convention": "", + "term_raw": "Графы", + "term_resolved": "Графы", + "term_forms": [], + "definition_formal": "T2 & T3", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 632, "fields": { - "schema": 34, - "order": 44, - "alias": "P20", - "cst_type": "predicate", - "convention": "", - "term_raw": "неориентированный граф", - "term_resolved": "неориентированный граф", - "term_forms": [], - "definition_formal": "[γ∈ℬ(R1)×ℬ(R1×R1)] pr2(γ) = Pr2,1(pr2(γ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 44, + "alias": "P20", + "cst_type": "predicate", + "convention": "", + "term_raw": "неориентированный граф", + "term_resolved": "неориентированный граф", + "term_forms": [], + "definition_formal": "[γ∈ℬ(R1)×ℬ(R1×R1)] pr2(γ) = Pr2,1(pr2(γ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 633, "fields": { - "schema": 34, - "order": 45, - "alias": "F20", - "cst_type": "function", - "convention": "", - "term_raw": "истоки", - "term_resolved": "истоки", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1(σ) \\ Pr2(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 45, + "alias": "F20", + "cst_type": "function", + "convention": "", + "term_raw": "истоки", + "term_resolved": "истоки", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1(σ) \\ Pr2(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 634, "fields": { - "schema": 34, - "order": 46, - "alias": "F21", - "cst_type": "function", - "convention": "", - "term_raw": "стоки", - "term_resolved": "стоки", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr2(σ) \\ Pr1(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 46, + "alias": "F21", + "cst_type": "function", + "convention": "", + "term_raw": "стоки", + "term_resolved": "стоки", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr2(σ) \\ Pr1(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 635, "fields": { - "schema": 34, - "order": 47, - "alias": "F22", - "cst_type": "function", - "convention": "", - "term_raw": "изолированные вершины", - "term_resolved": "изолированные вершины", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] α \\ (Pr2(σ) ∪ Pr1(σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 47, + "alias": "F22", + "cst_type": "function", + "convention": "", + "term_raw": "изолированные вершины", + "term_resolved": "изолированные вершины", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] α \\ (Pr2(σ) ∪ Pr1(σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 636, "fields": { - "schema": 34, - "order": 48, - "alias": "F23", - "cst_type": "function", - "convention": "", - "term_raw": "потребители", - "term_resolved": "потребители", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] Pr2(Fi1[{α}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 48, + "alias": "F23", + "cst_type": "function", + "convention": "", + "term_raw": "потребители", + "term_resolved": "потребители", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] Pr2(Fi1[{α}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 637, "fields": { - "schema": 34, - "order": 49, - "alias": "F24", - "cst_type": "function", - "convention": "", - "term_raw": "поставщики", - "term_resolved": "поставщики", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] Pr1(Fi2[{α}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 49, + "alias": "F24", + "cst_type": "function", + "convention": "", + "term_raw": "поставщики", + "term_resolved": "поставщики", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] Pr1(Fi2[{α}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 638, "fields": { - "schema": 34, - "order": 50, - "alias": "F25", - "cst_type": "function", - "convention": "", - "term_raw": "зависимые вершины", - "term_resolved": "зависимые вершины", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] R{ ξ:=Pr2(Fi1[{α}](σ)) | ξ ∪ Pr2(Fi1[ξ](σ)) }", - "definition_raw": "вершины, достижимые из данной", - "definition_resolved": "вершины, достижимые из данной" + "schema": 34, + "order": 50, + "alias": "F25", + "cst_type": "function", + "convention": "", + "term_raw": "зависимые вершины", + "term_resolved": "зависимые вершины", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] R{ ξ:=Pr2(Fi1[{α}](σ)) | ξ ∪ Pr2(Fi1[ξ](σ)) }", + "definition_raw": "вершины, достижимые из данной", + "definition_resolved": "вершины, достижимые из данной" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 639, "fields": { - "schema": 34, - "order": 51, - "alias": "F26", - "cst_type": "function", - "convention": "", - "term_raw": "зависимые вершины совокупности", - "term_resolved": "зависимые вершины совокупности", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] R{ ξ:=Pr2(Fi1[α](σ)) | ξ ∪ Pr2(Fi1[ξ](σ)) }", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 51, + "alias": "F26", + "cst_type": "function", + "convention": "", + "term_raw": "зависимые вершины совокупности", + "term_resolved": "зависимые вершины совокупности", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] R{ ξ:=Pr2(Fi1[α](σ)) | ξ ∪ Pr2(Fi1[ξ](σ)) }", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 640, "fields": { - "schema": 34, - "order": 52, - "alias": "F27", - "cst_type": "function", - "convention": "", - "term_raw": "влияющие вершины", - "term_resolved": "влияющие вершины", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] R{ ξ:=Pr1(Fi2[{α}](σ)) | ξ ∪ Pr1(Fi2[ξ](σ)) }", - "definition_raw": "вершины, из которых данная вершина достижима", - "definition_resolved": "вершины, из которых данная вершина достижима" + "schema": 34, + "order": 52, + "alias": "F27", + "cst_type": "function", + "convention": "", + "term_raw": "влияющие вершины", + "term_resolved": "влияющие вершины", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ(R1×R1)] R{ ξ:=Pr1(Fi2[{α}](σ)) | ξ ∪ Pr1(Fi2[ξ](σ)) }", + "definition_raw": "вершины, из которых данная вершина достижима", + "definition_resolved": "вершины, из которых данная вершина достижима" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 641, "fields": { - "schema": 34, - "order": 53, - "alias": "F28", - "cst_type": "function", - "convention": "", - "term_raw": "влияющие вершины совокупности", - "term_resolved": "влияющие вершины совокупности", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] R{ ξ:=Pr1(Fi2[α](σ)) | ξ ∪ Pr1(Fi2[ξ](σ)) }", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 53, + "alias": "F28", + "cst_type": "function", + "convention": "", + "term_raw": "влияющие вершины совокупности", + "term_resolved": "влияющие вершины совокупности", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ(R1×R1)] R{ ξ:=Pr1(Fi2[α](σ)) | ξ ∪ Pr1(Fi2[ξ](σ)) }", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 642, "fields": { - "schema": 34, - "order": 54, - "alias": "P21", - "cst_type": "predicate", - "convention": "", - "term_raw": "цикл", - "term_resolved": "цикл", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] Pr1(σ) = Pr2(σ)", - "definition_raw": "совокупность связей, в которой из каждой вершины в каждую другую есть путь", - "definition_resolved": "совокупность связей, в которой из каждой вершины в каждую другую есть путь" + "schema": 34, + "order": 54, + "alias": "P21", + "cst_type": "predicate", + "convention": "", + "term_raw": "цикл", + "term_resolved": "цикл", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] Pr1(σ) = Pr2(σ)", + "definition_raw": "совокупность связей, в которой из каждой вершины в каждую другую есть путь", + "definition_resolved": "совокупность связей, в которой из каждой вершины в каждую другую есть путь" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 643, "fields": { - "schema": 34, - "order": 55, - "alias": "P22", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство ацикличности", - "term_resolved": "свойство ацикличности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] ∀γ∈Pr1(σ) γ∉R{ ξ:=Pr2(Fi1[{γ}](σ)) | ξ ∪ Pr2(Fi1[ξ](σ)) }", - "definition_raw": "в ацикличном графе никакая вершина не является собственной зависимой вершиной", - "definition_resolved": "в ацикличном графе никакая вершина не является собственной зависимой вершиной" + "schema": 34, + "order": 55, + "alias": "P22", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство ацикличности", + "term_resolved": "свойство ацикличности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] ∀γ∈Pr1(σ) γ∉R{ ξ:=Pr2(Fi1[{γ}](σ)) | ξ ∪ Pr2(Fi1[ξ](σ)) }", + "definition_raw": "в ацикличном графе никакая вершина не является собственной зависимой вершиной", + "definition_resolved": "в ацикличном графе никакая вершина не является собственной зависимой вершиной" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 644, "fields": { - "schema": 34, - "order": 56, - "alias": "P23", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство ацикличности (декларативная формулировка)", - "term_resolved": "свойство ацикличности (декларативная формулировка)", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] ∀γ∈ℬ(σ) Pr1(γ) ≠ Pr2(γ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 56, + "alias": "P23", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство ацикличности (декларативная формулировка)", + "term_resolved": "свойство ацикличности (декларативная формулировка)", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] ∀γ∈ℬ(σ) Pr1(γ) ≠ Pr2(γ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 645, "fields": { - "schema": 34, - "order": 57, - "alias": "F29", - "cst_type": "function", - "convention": "", - "term_raw": "транзитивное замыкание", - "term_resolved": "транзитивное замыкание", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] I{(ξ1, ξ2) | ξ1:∈Pr1(σ); ξ2:∈F25[ξ1, σ]}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 57, + "alias": "F29", + "cst_type": "function", + "convention": "", + "term_raw": "транзитивное замыкание", + "term_resolved": "транзитивное замыкание", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] I{(ξ1, ξ2) | ξ1:∈Pr1(σ); ξ2:∈F25[ξ1, σ]}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 646, "fields": { - "schema": 34, - "order": 58, - "alias": "F30", - "cst_type": "function", - "convention": "", - "term_raw": "транзитивная редукция", - "term_resolved": "транзитивная редукция", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] σ \\ I{(ξ1, ξ2) | ξ1:∈Pr1(σ); γ:=F23[ξ1, σ]; ξ2:∈γ∩F26[γ, σ]}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 58, + "alias": "F30", + "cst_type": "function", + "convention": "", + "term_raw": "транзитивная редукция", + "term_resolved": "транзитивная редукция", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] σ \\ I{(ξ1, ξ2) | ξ1:∈Pr1(σ); γ:=F23[ξ1, σ]; ξ2:∈γ∩F26[γ, σ]}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 647, "fields": { - "schema": 34, - "order": 59, - "alias": "P24", - "cst_type": "predicate", - "convention": "1", - "term_raw": "дерево", - "term_resolved": "дерево", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R1)] card(Pr1(σ)\\Pr2(σ)) = 1 & card(Pr2(σ)) = card(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 59, + "alias": "P24", + "cst_type": "predicate", + "convention": "1", + "term_raw": "дерево", + "term_resolved": "дерево", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R1)] card(Pr1(σ)\\Pr2(σ)) = 1 & card(Pr2(σ)) = card(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 648, "fields": { - "schema": 34, - "order": 60, - "alias": "T6", - "cst_type": "theorem", - "convention": "", - "term_raw": "Целые числа", - "term_resolved": "Целые числа", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 60, + "alias": "T6", + "cst_type": "theorem", + "convention": "", + "term_raw": "Целые числа", + "term_resolved": "Целые числа", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 649, "fields": { - "schema": 34, - "order": 61, - "alias": "F31", - "cst_type": "function", - "convention": "", - "term_raw": "минимум набора чисел", - "term_resolved": "минимум набора чисел", - "term_forms": [], - "definition_formal": "[σ∈ℬ(Z)] debool(D{ξ∈σ | ∀α∈σ α ≤ ξ})", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 61, + "alias": "F31", + "cst_type": "function", + "convention": "", + "term_raw": "минимум набора чисел", + "term_resolved": "минимум набора чисел", + "term_forms": [], + "definition_formal": "[σ∈ℬ(Z)] debool(D{ξ∈σ | ∀α∈σ α ≤ ξ})", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 650, "fields": { - "schema": 34, - "order": 62, - "alias": "F32", - "cst_type": "function", - "convention": "", - "term_raw": "максимум набора чисел", - "term_resolved": "максимум набора чисел", - "term_forms": [], - "definition_formal": "[σ∈ℬ(Z)] debool(D{ξ∈σ | ∀α∈σ α ≥ ξ})", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 62, + "alias": "F32", + "cst_type": "function", + "convention": "", + "term_raw": "максимум набора чисел", + "term_resolved": "максимум набора чисел", + "term_forms": [], + "definition_formal": "[σ∈ℬ(Z)] debool(D{ξ∈σ | ∀α∈σ α ≥ ξ})", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 651, "fields": { - "schema": 34, - "order": 63, - "alias": "F33", - "cst_type": "function", - "convention": "", - "term_raw": "натуральные числа, меньшие или равные данному", - "term_resolved": "натуральные числа, меньшие или равные данному", - "term_forms": [], - "definition_formal": "[α∈Z] R{(ξ,σ):=(0, {0}) | ξ<α | (ξ+1, σ ∪ {ξ+1})}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 63, + "alias": "F33", + "cst_type": "function", + "convention": "", + "term_raw": "натуральные числа, меньшие или равные данному", + "term_resolved": "натуральные числа, меньшие или равные данному", + "term_forms": [], + "definition_formal": "[α∈Z] R{(ξ,σ):=(0, {0}) | ξ<α | (ξ+1, σ ∪ {ξ+1})}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 652, "fields": { - "schema": 34, - "order": 64, - "alias": "P25", - "cst_type": "predicate", - "convention": "", - "term_raw": "набор чисел, удовлетворяющий данному периоду", - "term_resolved": "набор чисел, удовлетворяющий данному периоду", - "term_forms": [], - "definition_formal": "[σ∈ℬ(Z), τ∈Z] ∀α∈σ (α+τ ≤ F32[σ] ⇒ α+τ∈σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 64, + "alias": "P25", + "cst_type": "predicate", + "convention": "", + "term_raw": "набор чисел, удовлетворяющий данному периоду", + "term_resolved": "набор чисел, удовлетворяющий данному периоду", + "term_forms": [], + "definition_formal": "[σ∈ℬ(Z), τ∈Z] ∀α∈σ (α+τ ≤ F32[σ] ⇒ α+τ∈σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 653, "fields": { - "schema": 34, - "order": 65, - "alias": "F34", - "cst_type": "function", - "convention": "", - "term_raw": "периоды данного набора чисел", - "term_resolved": "периоды данного набора чисел", - "term_forms": [], - "definition_formal": "[σ∈ℬ(Z)] pr1(R{\n(γ, τ) := (∅, F31[σ]) | \nτ ≠ F32[σ] | \n(γ ∪ I{τ | P25[σ, τ]}, τ + 1)})", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 65, + "alias": "F34", + "cst_type": "function", + "convention": "", + "term_raw": "периоды данного набора чисел", + "term_resolved": "периоды данного набора чисел", + "term_forms": [], + "definition_formal": "[σ∈ℬ(Z)] pr1(R{\n(γ, τ) := (∅, F31[σ]) | \nτ ≠ F32[σ] | \n(γ ∪ I{τ | P25[σ, τ]}, τ + 1)})", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 654, "fields": { - "schema": 34, - "order": 66, - "alias": "T7", - "cst_type": "theorem", - "convention": "", - "term_raw": "Последовательности", - "term_resolved": "Последовательности", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 66, + "alias": "T7", + "cst_type": "theorem", + "convention": "", + "term_raw": "Последовательности", + "term_resolved": "Последовательности", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 655, "fields": { - "schema": 34, - "order": 67, - "alias": "P26", - "cst_type": "predicate", - "convention": "", - "term_raw": "корректная последовательность (позиции нумеруются с нуля)", - "term_resolved": "корректная последовательность (позиции нумеруются с нуля)", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] card(σ)=card(Pr2(σ)) & ∀λ∈Pr2(σ) λ < card(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 67, + "alias": "P26", + "cst_type": "predicate", + "convention": "", + "term_raw": "корректная последовательность (позиции нумеруются с нуля)", + "term_resolved": "корректная последовательность (позиции нумеруются с нуля)", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] card(σ)=card(Pr2(σ)) & ∀λ∈Pr2(σ) λ < card(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 656, "fields": { - "schema": 34, - "order": 68, - "alias": "P27", - "cst_type": "predicate", - "convention": "", - "term_raw": "корректная последовательность (позиции нумеруются с единицы)", - "term_resolved": "корректная последовательность (позиции нумеруются с единицы)", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] card(σ)=card(Pr2(σ)) & ∀λ∈Pr2(σ) (λ ≤ card(σ) & λ > 0)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 68, + "alias": "P27", + "cst_type": "predicate", + "convention": "", + "term_raw": "корректная последовательность (позиции нумеруются с единицы)", + "term_resolved": "корректная последовательность (позиции нумеруются с единицы)", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] card(σ)=card(Pr2(σ)) & ∀λ∈Pr2(σ) (λ ≤ card(σ) & λ > 0)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 657, "fields": { - "schema": 34, - "order": 69, - "alias": "F35", - "cst_type": "function", - "convention": "", - "term_raw": "начало последовательности", - "term_resolved": "начало последовательности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] debool(Pr1(Fi2[{0}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 69, + "alias": "F35", + "cst_type": "function", + "convention": "", + "term_raw": "начало последовательности", + "term_resolved": "начало последовательности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] debool(Pr1(Fi2[{0}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 658, "fields": { - "schema": 34, - "order": 70, - "alias": "F36", - "cst_type": "function", - "convention": "", - "term_raw": "конец последовательности", - "term_resolved": "конец последовательности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] debool(Pr1(Fi2[{card(σ) - 1}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 70, + "alias": "F36", + "cst_type": "function", + "convention": "", + "term_raw": "конец последовательности", + "term_resolved": "конец последовательности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] debool(Pr1(Fi2[{card(σ) - 1}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 659, "fields": { - "schema": 34, - "order": 71, - "alias": "F37", - "cst_type": "function", - "convention": "", - "term_raw": "следующий за данным !элемент! последовательности", - "term_resolved": "следующий за данным !элемент! последовательности", - "term_forms": [], - "definition_formal": "[α∈R1×Z, σ∈ℬ(R1×Z)] debool(Fi2[{pr2(α) + 1}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 71, + "alias": "F37", + "cst_type": "function", + "convention": "", + "term_raw": "следующий за данным !элемент! последовательности", + "term_resolved": "следующий за данным !элемент! последовательности", + "term_forms": [], + "definition_formal": "[α∈R1×Z, σ∈ℬ(R1×Z)] debool(Fi2[{pr2(α) + 1}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 660, "fields": { - "schema": 34, - "order": 72, - "alias": "F38", - "cst_type": "function", - "convention": "", - "term_raw": "предыдущий данному !элемент! последовательности", - "term_resolved": "предыдущий данному !элемент! последовательности", - "term_forms": [], - "definition_formal": "[α∈R1×Z, σ∈ℬ(R1×Z)] debool(Fi2[{pr2(α) - 1}](σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 72, + "alias": "F38", + "cst_type": "function", + "convention": "", + "term_raw": "предыдущий данному !элемент! последовательности", + "term_resolved": "предыдущий данному !элемент! последовательности", + "term_forms": [], + "definition_formal": "[α∈R1×Z, σ∈ℬ(R1×Z)] debool(Fi2[{pr2(α) - 1}](σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 661, "fields": { - "schema": 34, - "order": 73, - "alias": "F39", - "cst_type": "function", - "convention": "", - "term_raw": "обращенная последовательность", - "term_resolved": "обращенная последовательность", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] I{(α, λ) | (α,μ):∈σ; λ := card(σ) - μ - 1}", - "definition_raw": "не определен для последнего элемента", - "definition_resolved": "не определен для последнего элемента" + "schema": 34, + "order": 73, + "alias": "F39", + "cst_type": "function", + "convention": "", + "term_raw": "обращенная последовательность", + "term_resolved": "обращенная последовательность", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] I{(α, λ) | (α,μ):∈σ; λ := card(σ) - μ - 1}", + "definition_raw": "не определен для последнего элемента", + "definition_resolved": "не определен для последнего элемента" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 662, "fields": { - "schema": 34, - "order": 74, - "alias": "P28", - "cst_type": "predicate", - "convention": "", - "term_raw": "подпоследовательность", - "term_resolved": "подпоследовательность", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] card(σ) = card(Pr2(σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 74, + "alias": "P28", + "cst_type": "predicate", + "convention": "", + "term_raw": "подпоследовательность", + "term_resolved": "подпоследовательность", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] card(σ) = card(Pr2(σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 663, "fields": { - "schema": 34, - "order": 75, - "alias": "F40", - "cst_type": "function", - "convention": "", - "term_raw": "последовательность, построенная из данной подпоследовательности", - "term_resolved": "последовательность, построенная из данной подпоследовательности", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×Z)] pr1(R{\n(γ, α):=(∅, σ) | α≠∅ | \ndebool(I{(γ2, α2) | τ := F31[Pr2(α)]; ξ := debool(F8[τ,σ]); \nγ2 := γ ∪ {(ξ, card(γ))}; α2 := α \\ {(ξ,τ)}})})", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 75, + "alias": "F40", + "cst_type": "function", + "convention": "", + "term_raw": "последовательность, построенная из данной подпоследовательности", + "term_resolved": "последовательность, построенная из данной подпоследовательности", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×Z)] pr1(R{\n(γ, α):=(∅, σ) | α≠∅ | \ndebool(I{(γ2, α2) | τ := F31[Pr2(α)]; ξ := debool(F8[τ,σ]); \nγ2 := γ ∪ {(ξ, card(γ))}; α2 := α \\ {(ξ,τ)}})})", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 664, "fields": { - "schema": 34, - "order": 76, - "alias": "T8", - "cst_type": "theorem", - "convention": "Условия для \"левых\" и \"правых\" свойств через конкатенацию", - "term_raw": "Групповые операции", - "term_resolved": "Групповые операции", - "term_forms": [], - "definition_formal": "T10", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 76, + "alias": "T8", + "cst_type": "theorem", + "convention": "Условия для \"левых\" и \"правых\" свойств через конкатенацию", + "term_raw": "Групповые операции", + "term_resolved": "Групповые операции", + "term_forms": [], + "definition_formal": "T10", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 665, "fields": { - "schema": 34, - "order": 77, - "alias": "F41", - "cst_type": "function", - "convention": "", - "term_raw": "результат операции для данных аргументов", - "term_resolved": "результат операции для данных аргументов", - "term_forms": [], - "definition_formal": "[α∈R1, β∈R1, σ∈ℬ((R1×R1)×R1)] debool(Pr2(Fi1[{(α,β)}](σ)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 77, + "alias": "F41", + "cst_type": "function", + "convention": "", + "term_raw": "результат операции для данных аргументов", + "term_resolved": "результат операции для данных аргументов", + "term_forms": [], + "definition_formal": "[α∈R1, β∈R1, σ∈ℬ((R1×R1)×R1)] debool(Pr2(Fi1[{(α,β)}](σ)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 666, "fields": { - "schema": 34, - "order": 78, - "alias": "F42", - "cst_type": "function", - "convention": "например ноль для операции умножения целых чисел", - "term_raw": "инвариантные элементы", - "term_resolved": "инвариантные элементы", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] D{ξ∈Pr1(Pr1(σ)) | ∀α∈Pr1(Pr1(σ)) \n(((α,ξ),ξ)∈σ & ((ξ,α),ξ)∈σ)}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 78, + "alias": "F42", + "cst_type": "function", + "convention": "например ноль для операции умножения целых чисел", + "term_raw": "инвариантные элементы", + "term_resolved": "инвариантные элементы", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] D{ξ∈Pr1(Pr1(σ)) | ∀α∈Pr1(Pr1(σ)) \n(((α,ξ),ξ)∈σ & ((ξ,α),ξ)∈σ)}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 667, "fields": { - "schema": 34, - "order": 79, - "alias": "F43", - "cst_type": "function", - "convention": "", - "term_raw": "нейтральные элементы", - "term_resolved": "нейтральные элементы", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] D{ξ∈Pr1(Pr1(σ)) | ∀α∈Pr1(Pr1(σ)) \n(((α,ξ),α)∈σ & ((ξ,α),α)∈σ)}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 79, + "alias": "F43", + "cst_type": "function", + "convention": "", + "term_raw": "нейтральные элементы", + "term_resolved": "нейтральные элементы", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] D{ξ∈Pr1(Pr1(σ)) | ∀α∈Pr1(Pr1(σ)) \n(((α,ξ),α)∈σ & ((ξ,α),α)∈σ)}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 668, "fields": { - "schema": 34, - "order": 80, - "alias": "F44", - "cst_type": "function", - "convention": "", - "term_raw": "идемпотентные элементы", - "term_resolved": "идемпотентные элементы", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] D{ξ∈Pr1(Pr1(σ)) | ((ξ,ξ),ξ)∈σ}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 80, + "alias": "F44", + "cst_type": "function", + "convention": "", + "term_raw": "идемпотентные элементы", + "term_resolved": "идемпотентные элементы", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] D{ξ∈Pr1(Pr1(σ)) | ((ξ,ξ),ξ)∈σ}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 669, "fields": { - "schema": 34, - "order": 81, - "alias": "F45", - "cst_type": "function", - "convention": "", - "term_raw": "обратные элементы для данного элемента", - "term_resolved": "обратные элементы для данного элемента", - "term_forms": [], - "definition_formal": "[α∈R1, σ∈ℬ((R1×R1)×R1)] D{ω∈Pr1(Pr1(σ)) | F41[α,ω,σ]∈F43[σ] & F41[ω,α,σ]∈F43[σ]}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 81, + "alias": "F45", + "cst_type": "function", + "convention": "", + "term_raw": "обратные элементы для данного элемента", + "term_resolved": "обратные элементы для данного элемента", + "term_forms": [], + "definition_formal": "[α∈R1, σ∈ℬ((R1×R1)×R1)] D{ω∈Pr1(Pr1(σ)) | F41[α,ω,σ]∈F43[σ] & F41[ω,α,σ]∈F43[σ]}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 670, "fields": { - "schema": 34, - "order": 82, - "alias": "F46", - "cst_type": "function", - "convention": "", - "term_raw": "элемент, являющийся данной степенью данного элемента", - "term_resolved": "элемент, являющийся данной степенью данного элемента", - "term_forms": [], - "definition_formal": "[α∈R1, λ∈Z, σ∈ℬ((R1×R1)×R1)] pr1(R{(ξ, μ) := (α, 1) | μ<λ & λ>0 | (F41[ξ,α,σ], μ + 1)})", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 82, + "alias": "F46", + "cst_type": "function", + "convention": "", + "term_raw": "элемент, являющийся данной степенью данного элемента", + "term_resolved": "элемент, являющийся данной степенью данного элемента", + "term_forms": [], + "definition_formal": "[α∈R1, λ∈Z, σ∈ℬ((R1×R1)×R1)] pr1(R{(ξ, μ) := (α, 1) | μ<λ & λ>0 | (F41[ξ,α,σ], μ + 1)})", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 671, "fields": { - "schema": 34, - "order": 83, - "alias": "P29", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство замкнутости и однозначности", - "term_resolved": "свойство замкнутости и однозначности", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] Pr1(σ) = α×α & card(σ) = card(Pr1(σ))", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 83, + "alias": "P29", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство замкнутости и однозначности", + "term_resolved": "свойство замкнутости и однозначности", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] Pr1(σ) = α×α & card(σ) = card(Pr1(σ))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 672, "fields": { - "schema": 34, - "order": 84, - "alias": "P30", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство ассоциативности", - "term_resolved": "свойство ассоциативности", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀α,β,γ∈Pr1(Pr1(σ)) F41[F41[α,β,σ],γ,σ] = F41[α,F41[β,γ,σ],σ]", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 84, + "alias": "P30", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство ассоциативности", + "term_resolved": "свойство ассоциативности", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀α,β,γ∈Pr1(Pr1(σ)) F41[F41[α,β,σ],γ,σ] = F41[α,F41[β,γ,σ],σ]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 673, "fields": { - "schema": 34, - "order": 85, - "alias": "P31", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство коммутативности", - "term_resolved": "свойство коммутативности", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀((α1,α2),γ)∈σ ((α2,α1),γ)∈σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 85, + "alias": "P31", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство коммутативности", + "term_resolved": "свойство коммутативности", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀((α1,α2),γ)∈σ ((α2,α1),γ)∈σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 674, "fields": { - "schema": 34, - "order": 86, - "alias": "P32", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство идемпотентности", - "term_resolved": "свойство идемпотентности", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀α∈Pr1(Pr1(σ)) ((α,α),α)∈σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 86, + "alias": "P32", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство идемпотентности", + "term_resolved": "свойство идемпотентности", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀α∈Pr1(Pr1(σ)) ((α,α),α)∈σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 675, "fields": { - "schema": 34, - "order": 87, - "alias": "P33", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство цикличности", - "term_resolved": "свойство цикличности", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∃α∈Pr1(Pr1(σ)) ∀β∈Pr1(Pr1(σ)) ∃μ∈Z F46[α,μ,σ] = β", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 87, + "alias": "P33", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство цикличности", + "term_resolved": "свойство цикличности", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∃α∈Pr1(Pr1(σ)) ∀β∈Pr1(Pr1(σ)) ∃μ∈Z F46[α,μ,σ] = β", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 676, "fields": { - "schema": 34, - "order": 88, - "alias": "P34", - "cst_type": "predicate", - "convention": "", - "term_raw": "группоид", - "term_resolved": "группоид", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ]", - "definition_raw": "всюдуопределенная замкнутая функция пары элементов некоторого множества", - "definition_resolved": "всюдуопределенная замкнутая функция пары элементов некоторого множества" + "schema": 34, + "order": 88, + "alias": "P34", + "cst_type": "predicate", + "convention": "", + "term_raw": "группоид", + "term_resolved": "группоид", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ]", + "definition_raw": "всюдуопределенная замкнутая функция пары элементов некоторого множества", + "definition_resolved": "всюдуопределенная замкнутая функция пары элементов некоторого множества" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 677, "fields": { - "schema": 34, - "order": 89, - "alias": "P35", - "cst_type": "predicate", - "convention": "", - "term_raw": "полугруппа", - "term_resolved": "полугруппа", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ]", - "definition_raw": "ассоциативный группоид", - "definition_resolved": "ассоциативный группоид" + "schema": 34, + "order": 89, + "alias": "P35", + "cst_type": "predicate", + "convention": "", + "term_raw": "полугруппа", + "term_resolved": "полугруппа", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ]", + "definition_raw": "ассоциативный группоид", + "definition_resolved": "ассоциативный группоид" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 678, "fields": { - "schema": 34, - "order": 90, - "alias": "P36", - "cst_type": "predicate", - "convention": "", - "term_raw": "моноид", - "term_resolved": "моноид", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ] & card(F43[σ]) > 0", - "definition_raw": "полугруппа, в которой существует нейтральный элемент", - "definition_resolved": "полугруппа, в которой существует нейтральный элемент" + "schema": 34, + "order": 90, + "alias": "P36", + "cst_type": "predicate", + "convention": "", + "term_raw": "моноид", + "term_resolved": "моноид", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ] & card(F43[σ]) > 0", + "definition_raw": "полугруппа, в которой существует нейтральный элемент", + "definition_resolved": "полугруппа, в которой существует нейтральный элемент" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 679, "fields": { - "schema": 34, - "order": 91, - "alias": "P37", - "cst_type": "predicate", - "convention": "", - "term_raw": "группа", - "term_resolved": "группа", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ] & card(F43[σ]) > 0 & ∀ξ∈α card(F45[ξ, σ]) > 0", - "definition_raw": "моноид, в котором для каждого элемента существует обратный", - "definition_resolved": "моноид, в котором для каждого элемента существует обратный" + "schema": 34, + "order": 91, + "alias": "P37", + "cst_type": "predicate", + "convention": "", + "term_raw": "группа", + "term_resolved": "группа", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ] & card(F43[σ]) > 0 & ∀ξ∈α card(F45[ξ, σ]) > 0", + "definition_raw": "моноид, в котором для каждого элемента существует обратный", + "definition_resolved": "моноид, в котором для каждого элемента существует обратный" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 680, "fields": { - "schema": 34, - "order": 92, - "alias": "P38", - "cst_type": "predicate", - "convention": "", - "term_raw": "абелева группа", - "term_resolved": "абелева группа", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ] & card(F43[σ]) > 0 & ∀ξ∈α card(F45[ξ, σ]) > 0 & P31[σ]", - "definition_raw": "коммутативная группа", - "definition_resolved": "коммутативная группа" + "schema": 34, + "order": 92, + "alias": "P38", + "cst_type": "predicate", + "convention": "", + "term_raw": "абелева группа", + "term_resolved": "абелева группа", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬ((R1×R1)×R1)] P29[α, σ] & P30[σ] & card(F43[σ]) > 0 & ∀ξ∈α card(F45[ξ, σ]) > 0 & P31[σ]", + "definition_raw": "коммутативная группа", + "definition_resolved": "коммутативная группа" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 681, "fields": { - "schema": 34, - "order": 93, - "alias": "T9", - "cst_type": "theorem", - "convention": "Условия для \"левых\" и \"правых\" свойств через конкатенацию\nОперации по умолчанию считаются группоидами", - "term_raw": "Кольца", - "term_resolved": "Кольца", - "term_forms": [], - "definition_formal": "T8", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 93, + "alias": "T9", + "cst_type": "theorem", + "convention": "Условия для \"левых\" и \"правых\" свойств через конкатенацию\nОперации по умолчанию считаются группоидами", + "term_raw": "Кольца", + "term_resolved": "Кольца", + "term_forms": [], + "definition_formal": "T8", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 682, "fields": { - "schema": 34, - "order": 94, - "alias": "P39", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство дистрибутивности φψ", - "term_resolved": "свойство дистрибутивности φψ", - "term_forms": [], - "definition_formal": "[φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] ∀α,β,γ∈Pr1(Pr1(φ)) (\n F41[α, F41[β, γ, φ], ψ] = F41[F41[α, β, ψ], F41[α, γ, ψ], φ] &\n F41[F41[α, β, φ], γ, ψ] = F41[F41[α, γ, ψ], F41[β, γ, ψ], φ]\n)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 94, + "alias": "P39", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство дистрибутивности φψ", + "term_resolved": "свойство дистрибутивности φψ", + "term_forms": [], + "definition_formal": "[φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] ∀α,β,γ∈Pr1(Pr1(φ)) (\n F41[α, F41[β, γ, φ], ψ] = F41[F41[α, β, ψ], F41[α, γ, ψ], φ] &\n F41[F41[α, β, φ], γ, ψ] = F41[F41[α, γ, ψ], F41[β, γ, ψ], φ]\n)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 683, "fields": { - "schema": 34, - "order": 95, - "alias": "P40", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство поглощения φψ", - "term_resolved": "свойство поглощения φψ", - "term_forms": [], - "definition_formal": "[φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] ∀α,β∈Pr1(Pr1(φ)) (\n F41[α, F41[α, β, φ], ψ] = α & F41[F41[α, β, φ], α, ψ] = α &\n F41[α, F41[β, α, φ], ψ] = α & F41[F41[β, α, φ], α, ψ] = α\n)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 95, + "alias": "P40", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство поглощения φψ", + "term_resolved": "свойство поглощения φψ", + "term_forms": [], + "definition_formal": "[φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] ∀α,β∈Pr1(Pr1(φ)) (\n F41[α, F41[α, β, φ], ψ] = α & F41[F41[α, β, φ], α, ψ] = α &\n F41[α, F41[β, α, φ], ψ] = α & F41[F41[β, α, φ], α, ψ] = α\n)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 684, "fields": { - "schema": 34, - "order": 96, - "alias": "P41", - "cst_type": "predicate", - "convention": "", - "term_raw": "полукольцо", - "term_resolved": "полукольцо", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)]\nP36[α, φ] & P31[φ] & P35[α, ψ] & P39[φ, ψ]", - "definition_raw": "сложение – моноид + коммутативность; умножение – полугруппа; дистрибутивность сложения относительно умножения", - "definition_resolved": "сложение – моноид + коммутативность; умножение – полугруппа; дистрибутивность сложения относительно умножения" + "schema": 34, + "order": 96, + "alias": "P41", + "cst_type": "predicate", + "convention": "", + "term_raw": "полукольцо", + "term_resolved": "полукольцо", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)]\nP36[α, φ] & P31[φ] & P35[α, ψ] & P39[φ, ψ]", + "definition_raw": "сложение – моноид + коммутативность; умножение – полугруппа; дистрибутивность сложения относительно умножения", + "definition_resolved": "сложение – моноид + коммутативность; умножение – полугруппа; дистрибутивность сложения относительно умножения" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 685, "fields": { - "schema": 34, - "order": 97, - "alias": "P42", - "cst_type": "predicate", - "convention": "", - "term_raw": "кольцо", - "term_resolved": "кольцо", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)]\nP38[α, φ] & P35[α, ψ] & P39[φ, ψ]", - "definition_raw": "полукольцо, в котором для умножения существуют обратные элементы", - "definition_resolved": "полукольцо, в котором для умножения существуют обратные элементы" + "schema": 34, + "order": 97, + "alias": "P42", + "cst_type": "predicate", + "convention": "", + "term_raw": "кольцо", + "term_resolved": "кольцо", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)]\nP38[α, φ] & P35[α, ψ] & P39[φ, ψ]", + "definition_raw": "полукольцо, в котором для умножения существуют обратные элементы", + "definition_resolved": "полукольцо, в котором для умножения существуют обратные элементы" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 686, "fields": { - "schema": 34, - "order": 98, - "alias": "P43", - "cst_type": "predicate", - "convention": "", - "term_raw": "тело", - "term_resolved": "тело", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)]\nP38[α, φ] & P35[α, ψ] & P39[φ, ψ] & \ncard(F43[ψ]) > 0 & ∀ξ∈α\\F43[φ] card(F45[ξ, ψ]) > 0", - "definition_raw": "кольцо, в котором умножение обладает нейтральным элементов и обратными элементами для всех элементов, кроме нейтральных элементов сложения", - "definition_resolved": "кольцо, в котором умножение обладает нейтральным элементов и обратными элементами для всех элементов, кроме нейтральных элементов сложения" + "schema": 34, + "order": 98, + "alias": "P43", + "cst_type": "predicate", + "convention": "", + "term_raw": "тело", + "term_resolved": "тело", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)]\nP38[α, φ] & P35[α, ψ] & P39[φ, ψ] & \ncard(F43[ψ]) > 0 & ∀ξ∈α\\F43[φ] card(F45[ξ, ψ]) > 0", + "definition_raw": "кольцо, в котором умножение обладает нейтральным элементов и обратными элементами для всех элементов, кроме нейтральных элементов сложения", + "definition_resolved": "кольцо, в котором умножение обладает нейтральным элементов и обратными элементами для всех элементов, кроме нейтральных элементов сложения" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 687, "fields": { - "schema": 34, - "order": 99, - "alias": "P44", - "cst_type": "predicate", - "convention": "", - "term_raw": "поле", - "term_resolved": "поле", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] \nP38[α, φ] & P35[α, ψ] & P31[ψ] & P39[φ, ψ] & \ncard(F43[ψ]) > 0 & ∀ξ∈α\\F43[φ] card(F45[ξ, ψ]) > 0", - "definition_raw": "тело, в котором умножение обладает коммутативностью", - "definition_resolved": "тело, в котором умножение обладает коммутативностью" + "schema": 34, + "order": 99, + "alias": "P44", + "cst_type": "predicate", + "convention": "", + "term_raw": "поле", + "term_resolved": "поле", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] \nP38[α, φ] & P35[α, ψ] & P31[ψ] & P39[φ, ψ] & \ncard(F43[ψ]) > 0 & ∀ξ∈α\\F43[φ] card(F45[ξ, ψ]) > 0", + "definition_raw": "тело, в котором умножение обладает коммутативностью", + "definition_resolved": "тело, в котором умножение обладает коммутативностью" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 688, "fields": { - "schema": 34, - "order": 100, - "alias": "P45", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство покрытия", - "term_resolved": "свойство покрытия", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] α⊆red(σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 100, + "alias": "P45", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство покрытия", + "term_resolved": "свойство покрытия", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] α⊆red(σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 689, "fields": { - "schema": 34, - "order": 101, - "alias": "P46", - "cst_type": "predicate", - "convention": "", - "term_raw": "алгебраическая решетка", - "term_resolved": "алгебраическая решетка", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] \nP35[α, φ] & P31[φ] & P35[α, ψ] & P31[ψ] & P40[φ, ψ] & P40[ψ, φ]", - "definition_raw": "обе операции - коммутативные полугруппы с идемпотентностью и взаимным поглощением", - "definition_resolved": "обе операции - коммутативные полугруппы с идемпотентностью и взаимным поглощением" + "schema": 34, + "order": 101, + "alias": "P46", + "cst_type": "predicate", + "convention": "", + "term_raw": "алгебраическая решетка", + "term_resolved": "алгебраическая решетка", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), φ∈ℬ((R1×R1)×R1), ψ∈ℬ((R1×R1)×R1)] \nP35[α, φ] & P31[φ] & P35[α, ψ] & P31[ψ] & P40[φ, ψ] & P40[ψ, φ]", + "definition_raw": "обе операции - коммутативные полугруппы с идемпотентностью и взаимным поглощением", + "definition_resolved": "обе операции - коммутативные полугруппы с идемпотентностью и взаимным поглощением" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 690, "fields": { - "schema": 34, - "order": 102, - "alias": "T10", - "cst_type": "theorem", - "convention": "", - "term_raw": "Множества подмножеств", - "term_resolved": "Множества подмножеств", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 102, + "alias": "T10", + "cst_type": "theorem", + "convention": "", + "term_raw": "Множества подмножеств", + "term_resolved": "Множества подмножеств", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 691, "fields": { - "schema": 34, - "order": 103, - "alias": "P47", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство попарного непересечения", - "term_resolved": "свойство попарного непересечения", - "term_forms": [], - "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ (α≠β ⇒ α∩β=∅)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 103, + "alias": "P47", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство попарного непересечения", + "term_resolved": "свойство попарного непересечения", + "term_forms": [], + "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ (α≠β ⇒ α∩β=∅)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 692, "fields": { - "schema": 34, - "order": 104, - "alias": "P48", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство замкнутости по объединению", - "term_resolved": "свойство замкнутости по объединению", - "term_forms": [], - "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ α∪β∈σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 104, + "alias": "P48", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство замкнутости по объединению", + "term_resolved": "свойство замкнутости по объединению", + "term_forms": [], + "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ α∪β∈σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 693, "fields": { - "schema": 34, - "order": 105, - "alias": "P49", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство замкнутости по пересечению", - "term_resolved": "свойство замкнутости по пересечению", - "term_forms": [], - "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ α∩β∈σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 105, + "alias": "P49", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство замкнутости по пересечению", + "term_resolved": "свойство замкнутости по пересечению", + "term_forms": [], + "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ α∩β∈σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 694, "fields": { - "schema": 34, - "order": 106, - "alias": "P50", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство замкнутости по надмножеству", - "term_resolved": "свойство замкнутости по надмножеству", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] ∀ξ∈σ (ξ≠∅ ⇒ ∀δ∈α\\ξ ξ∪{δ}∈σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 106, + "alias": "P50", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство замкнутости по надмножеству", + "term_resolved": "свойство замкнутости по надмножеству", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] ∀ξ∈σ (ξ≠∅ ⇒ ∀δ∈α\\ξ ξ∪{δ}∈σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 695, "fields": { - "schema": 34, - "order": 107, - "alias": "P51", - "cst_type": "predicate", - "convention": "", - "term_raw": "свойство полноты подмножеств", - "term_resolved": "свойство полноты подмножеств", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] ∀ξ∈ℬ(α) ¬(ξ∈σ ⇔ α\\ξ∈σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 107, + "alias": "P51", + "cst_type": "predicate", + "convention": "", + "term_raw": "свойство полноты подмножеств", + "term_resolved": "свойство полноты подмножеств", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] ∀ξ∈ℬ(α) ¬(ξ∈σ ⇔ α\\ξ∈σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 696, "fields": { - "schema": 34, - "order": 108, - "alias": "P52", - "cst_type": "predicate", - "convention": "", - "term_raw": "разбиение", - "term_resolved": "разбиение", - "term_forms": [], - "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] α⊆red(σ) & ∀ξ1,ξ2∈σ (ξ1≠ξ2 ⇒ ξ1∩ξ2=∅)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 108, + "alias": "P52", + "cst_type": "predicate", + "convention": "", + "term_raw": "разбиение", + "term_resolved": "разбиение", + "term_forms": [], + "definition_formal": "[α∈ℬ(R1), σ∈ℬℬ(R1)] α⊆red(σ) & ∀ξ1,ξ2∈σ (ξ1≠ξ2 ⇒ ξ1∩ξ2=∅)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 697, "fields": { - "schema": 34, - "order": 109, - "alias": "F47", - "cst_type": "function", - "convention": "", - "term_raw": "множество-пересечение", - "term_resolved": "множество-пересечение", - "term_forms": [], - "definition_formal": "[σ∈ℬℬ(R1)] D{ξ∈red(σ) | ∀β∈σ (ξ∈β)}", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 109, + "alias": "F47", + "cst_type": "function", + "convention": "", + "term_raw": "множество-пересечение", + "term_resolved": "множество-пересечение", + "term_forms": [], + "definition_formal": "[σ∈ℬℬ(R1)] D{ξ∈red(σ) | ∀β∈σ (ξ∈β)}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 698, "fields": { - "schema": 34, - "order": 110, - "alias": "P53", - "cst_type": "predicate", - "convention": "", - "term_raw": "вложенные подмножества", - "term_resolved": "вложенные подмножества", - "term_forms": [], - "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ (card(α)≤card(β) ⇒ α⊆β)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 110, + "alias": "P53", + "cst_type": "predicate", + "convention": "", + "term_raw": "вложенные подмножества", + "term_resolved": "вложенные подмножества", + "term_forms": [], + "definition_formal": "[σ∈ℬℬ(R1)] ∀α,β∈σ (card(α)≤card(β) ⇒ α⊆β)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 699, "fields": { - "schema": 34, - "order": 111, - "alias": "P54", - "cst_type": "predicate", - "convention": "", - "term_raw": "вложенные подмножества (декларативно)", - "term_resolved": "вложенные подмножества (декларативно)", - "term_forms": [], - "definition_formal": "[σ∈ℬℬ(R1)] ∀γ∈ℬ(σ) (σ≠∅ ⇒ red(σ)∈σ)", - "definition_raw": "", - "definition_resolved": "" + "schema": 34, + "order": 111, + "alias": "P54", + "cst_type": "predicate", + "convention": "", + "term_raw": "вложенные подмножества (декларативно)", + "term_resolved": "вложенные подмножества (декларативно)", + "term_forms": [], + "definition_formal": "[σ∈ℬℬ(R1)] ∀γ∈ℬ(σ) (σ≠∅ ⇒ red(σ)∈σ)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 700, "fields": { - "schema": 35, - "order": 1, - "alias": "X1", - "cst_type": "basic", - "convention": "", - "term_raw": "элементы", - "term_resolved": "элементы", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 1, + "alias": "X1", + "cst_type": "basic", + "convention": "", + "term_raw": "элементы", + "term_resolved": "элементы", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 701, "fields": { - "schema": 35, - "order": 2, - "alias": "S1", - "cst_type": "structure", - "convention": "", - "term_raw": "операция", - "term_resolved": "операция", - "term_forms": [], - "definition_formal": "ℬ((X1×X1)×X1)", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 2, + "alias": "S1", + "cst_type": "structure", + "convention": "", + "term_raw": "операция", + "term_resolved": "операция", + "term_forms": [], + "definition_formal": "ℬ((X1×X1)×X1)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 702, "fields": { - "schema": 35, - "order": 3, - "alias": "F1", - "cst_type": "function", - "convention": "", - "term_raw": "результат операции для данных аргументов", - "term_resolved": "результат операции для данных аргументов", - "term_forms": [], - "definition_formal": "[α∈X1, β∈X1] debool(Pr2(Fi1[{(α,β)}](S1)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 3, + "alias": "F1", + "cst_type": "function", + "convention": "", + "term_raw": "результат операции для данных аргументов", + "term_resolved": "результат операции для данных аргументов", + "term_forms": [], + "definition_formal": "[α∈X1, β∈X1] debool(Pr2(Fi1[{(α,β)}](S1)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 703, "fields": { - "schema": 35, - "order": 4, - "alias": "A1", - "cst_type": "axiom", - "convention": "", - "term_raw": "свойство замкнутости", - "term_resolved": "свойство замкнутости", - "term_forms": [], - "definition_formal": "Pr1(S1) = X1×X1 & card(S1) = card(Pr1(S1))", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 4, + "alias": "A1", + "cst_type": "axiom", + "convention": "", + "term_raw": "свойство замкнутости", + "term_resolved": "свойство замкнутости", + "term_forms": [], + "definition_formal": "Pr1(S1) = X1×X1 & card(S1) = card(Pr1(S1))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 704, "fields": { - "schema": 35, - "order": 5, - "alias": "A2", - "cst_type": "axiom", - "convention": "", - "term_raw": "свойство ассоциативности", - "term_resolved": "свойство ассоциативности", - "term_forms": [], - "definition_formal": "∀α,β,γ∈X1 F1[F1[α,β],γ]=F1[α,F1[β,γ]]", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 5, + "alias": "A2", + "cst_type": "axiom", + "convention": "", + "term_raw": "свойство ассоциативности", + "term_resolved": "свойство ассоциативности", + "term_forms": [], + "definition_formal": "∀α,β,γ∈X1 F1[F1[α,β],γ]=F1[α,F1[β,γ]]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 705, "fields": { - "schema": 35, - "order": 6, - "alias": "D1", - "cst_type": "term", - "convention": "", - "term_raw": "нейтральные элементы", - "term_resolved": "нейтральные элементы", - "term_forms": [], - "definition_formal": "D{ξ∈X1 | ∀α∈X1 F1[ξ,α]=α}", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 6, + "alias": "D1", + "cst_type": "term", + "convention": "", + "term_raw": "нейтральные элементы", + "term_resolved": "нейтральные элементы", + "term_forms": [], + "definition_formal": "D{ξ∈X1 | ∀α∈X1 F1[ξ,α]=α}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 706, "fields": { - "schema": 35, - "order": 7, - "alias": "A3", - "cst_type": "axiom", - "convention": "", - "term_raw": "существование нейтрального элемента", - "term_resolved": "существование нейтрального элемента", - "term_forms": [], - "definition_formal": "card(D1)>0", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 7, + "alias": "A3", + "cst_type": "axiom", + "convention": "", + "term_raw": "существование нейтрального элемента", + "term_resolved": "существование нейтрального элемента", + "term_forms": [], + "definition_formal": "card(D1)>0", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 707, "fields": { - "schema": 35, - "order": 8, - "alias": "F2", - "cst_type": "function", - "convention": "", - "term_raw": "обратный данному элементу элемент", - "term_resolved": "обратный данному элементу элемент", - "term_forms": [], - "definition_formal": "[αα∈X1] D{αω∈X1 | F1[αα,αω]∈D1 & F1[αω,αα]∈D1}", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 8, + "alias": "F2", + "cst_type": "function", + "convention": "", + "term_raw": "обратный данному элементу элемент", + "term_resolved": "обратный данному элементу элемент", + "term_forms": [], + "definition_formal": "[αα∈X1] D{αω∈X1 | F1[αα,αω]∈D1 & F1[αω,αα]∈D1}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 708, "fields": { - "schema": 35, - "order": 9, - "alias": "D3", - "cst_type": "term", - "convention": "", - "term_raw": "инвариантные элементы", - "term_resolved": "инвариантные элементы", - "term_forms": [], - "definition_formal": "D{ξ∈X1 | ∀α∈X1 F1[ξ,α]=ξ}", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 9, + "alias": "D3", + "cst_type": "term", + "convention": "", + "term_raw": "инвариантные элементы", + "term_resolved": "инвариантные элементы", + "term_forms": [], + "definition_formal": "D{ξ∈X1 | ∀α∈X1 F1[ξ,α]=ξ}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 709, "fields": { - "schema": 35, - "order": 10, - "alias": "A4", - "cst_type": "axiom", - "convention": "", - "term_raw": "существования всех обратных элементов", - "term_resolved": "существования всех обратных элементов", - "term_forms": [], - "definition_formal": "∀α∈X1 card(F2[α])>0", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 10, + "alias": "A4", + "cst_type": "axiom", + "convention": "", + "term_raw": "существования всех обратных элементов", + "term_resolved": "существования всех обратных элементов", + "term_forms": [], + "definition_formal": "∀α∈X1 card(F2[α])>0", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 710, "fields": { - "schema": 35, - "order": 11, - "alias": "D2", - "cst_type": "term", - "convention": "", - "term_raw": "коммутативные совокупности аргументов", - "term_resolved": "коммутативные совокупности аргументов", - "term_forms": [], - "definition_formal": "I{{α, β} | α:∈X1; β:∈X1; α≠β; F1[α,β]=F1[β,α]}", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 11, + "alias": "D2", + "cst_type": "term", + "convention": "", + "term_raw": "коммутативные совокупности аргументов", + "term_resolved": "коммутативные совокупности аргументов", + "term_forms": [], + "definition_formal": "I{{α, β} | α:∈X1; β:∈X1; α≠β; F1[α,β]=F1[β,α]}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 711, "fields": { - "schema": 35, - "order": 12, - "alias": "A5", - "cst_type": "axiom", - "convention": "", - "term_raw": "условие коммутативности", - "term_resolved": "условие коммутативности", - "term_forms": [], - "definition_formal": "∀α,β∈X1 F1[α,β]=F1[β,α]", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 12, + "alias": "A5", + "cst_type": "axiom", + "convention": "", + "term_raw": "условие коммутативности", + "term_resolved": "условие коммутативности", + "term_forms": [], + "definition_formal": "∀α,β∈X1 F1[α,β]=F1[β,α]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 712, "fields": { - "schema": 35, - "order": 13, - "alias": "A6", - "cst_type": "axiom", - "convention": "", - "term_raw": "условие идемпотентности", - "term_resolved": "условие идемпотентности", - "term_forms": [], - "definition_formal": "∀α∈X1 F1[α,α]=α", - "definition_raw": "", - "definition_resolved": "" + "schema": 35, + "order": 13, + "alias": "A6", + "cst_type": "axiom", + "convention": "", + "term_raw": "условие идемпотентности", + "term_resolved": "условие идемпотентности", + "term_forms": [], + "definition_formal": "∀α∈X1 F1[α,α]=α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 713, "fields": { - "schema": 36, - "order": 1, - "alias": "X1", - "cst_type": "basic", - "convention": "", - "term_raw": "элементы", - "term_resolved": "элементы", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 1, + "alias": "X1", + "cst_type": "basic", + "convention": "", + "term_raw": "элементы", + "term_resolved": "элементы", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 714, "fields": { - "schema": 36, - "order": 2, - "alias": "S1", - "cst_type": "structure", - "convention": "", - "term_raw": "операция И", - "term_resolved": "операция И", - "term_forms": [], - "definition_formal": "ℬ((X1×X1)×X1)", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 2, + "alias": "S1", + "cst_type": "structure", + "convention": "", + "term_raw": "операция И", + "term_resolved": "операция И", + "term_forms": [], + "definition_formal": "ℬ((X1×X1)×X1)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 715, "fields": { - "schema": 36, - "order": 3, - "alias": "S2", - "cst_type": "structure", - "convention": "", - "term_raw": "операция ИЛИ", - "term_resolved": "операция ИЛИ", - "term_forms": [], - "definition_formal": "ℬ((X1×X1)×X1)", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 3, + "alias": "S2", + "cst_type": "structure", + "convention": "", + "term_raw": "операция ИЛИ", + "term_resolved": "операция ИЛИ", + "term_forms": [], + "definition_formal": "ℬ((X1×X1)×X1)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 716, "fields": { - "schema": 36, - "order": 4, - "alias": "S3", - "cst_type": "structure", - "convention": "", - "term_raw": "операция НЕ", - "term_resolved": "операция НЕ", - "term_forms": [], - "definition_formal": "ℬ(X1×X1)", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 4, + "alias": "S3", + "cst_type": "structure", + "convention": "", + "term_raw": "операция НЕ", + "term_resolved": "операция НЕ", + "term_forms": [], + "definition_formal": "ℬ(X1×X1)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 717, "fields": { - "schema": 36, - "order": 5, - "alias": "S4", - "cst_type": "structure", - "convention": "", - "term_raw": "значение ИСТИНА", - "term_resolved": "значение ИСТИНА", - "term_forms": [], - "definition_formal": "X1", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 5, + "alias": "S4", + "cst_type": "structure", + "convention": "", + "term_raw": "значение ИСТИНА", + "term_resolved": "значение ИСТИНА", + "term_forms": [], + "definition_formal": "X1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 718, "fields": { - "schema": 36, - "order": 6, - "alias": "S5", - "cst_type": "structure", - "convention": "", - "term_raw": "значение ЛОЖЬ", - "term_resolved": "значение ЛОЖЬ", - "term_forms": [], - "definition_formal": "X1", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 6, + "alias": "S5", + "cst_type": "structure", + "convention": "", + "term_raw": "значение ЛОЖЬ", + "term_resolved": "значение ЛОЖЬ", + "term_forms": [], + "definition_formal": "X1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 719, "fields": { - "schema": 36, - "order": 7, - "alias": "F2", - "cst_type": "function", - "convention": "", - "term_raw": "результат операции И для данных аргументов", - "term_resolved": "результат операции И для данных аргументов", - "term_forms": [], - "definition_formal": "[α∈X1, β∈X1] debool(Pr2(Fi1[{(α,β)}](S1)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 7, + "alias": "F2", + "cst_type": "function", + "convention": "", + "term_raw": "результат операции И для данных аргументов", + "term_resolved": "результат операции И для данных аргументов", + "term_forms": [], + "definition_formal": "[α∈X1, β∈X1] debool(Pr2(Fi1[{(α,β)}](S1)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 720, "fields": { - "schema": 36, - "order": 8, - "alias": "F3", - "cst_type": "function", - "convention": "", - "term_raw": "результат операции ИЛИ для данных аргументов", - "term_resolved": "результат операции ИЛИ для данных аргументов", - "term_forms": [], - "definition_formal": "[α∈X1, β∈X1] debool(Pr2(Fi1[{(α,β)}](S2)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 8, + "alias": "F3", + "cst_type": "function", + "convention": "", + "term_raw": "результат операции ИЛИ для данных аргументов", + "term_resolved": "результат операции ИЛИ для данных аргументов", + "term_forms": [], + "definition_formal": "[α∈X1, β∈X1] debool(Pr2(Fi1[{(α,β)}](S2)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 721, "fields": { - "schema": 36, - "order": 9, - "alias": "F4", - "cst_type": "function", - "convention": "", - "term_raw": "результат операции НЕ для данного аргумента", - "term_resolved": "результат операции НЕ для данного аргумента", - "term_forms": [], - "definition_formal": "[α∈X1] debool(Pr2(Fi1[{α}](S3)))", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 9, + "alias": "F4", + "cst_type": "function", + "convention": "", + "term_raw": "результат операции НЕ для данного аргумента", + "term_resolved": "результат операции НЕ для данного аргумента", + "term_forms": [], + "definition_formal": "[α∈X1] debool(Pr2(Fi1[{α}](S3)))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 722, "fields": { - "schema": 36, - "order": 10, - "alias": "P1", - "cst_type": "predicate", - "convention": "", - "term_raw": "прямая однозначность", - "term_resolved": "прямая однозначность", - "term_forms": [], - "definition_formal": "[σ∈ℬ(R1×R2)] ∀α∈Pr1(σ) card(Pr2(Fi1[{α}](σ))) = 1", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 10, + "alias": "P1", + "cst_type": "predicate", + "convention": "", + "term_raw": "прямая однозначность", + "term_resolved": "прямая однозначность", + "term_forms": [], + "definition_formal": "[σ∈ℬ(R1×R2)] ∀α∈Pr1(σ) card(Pr2(Fi1[{α}](σ))) = 1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 723, "fields": { - "schema": 36, - "order": 11, - "alias": "P2", - "cst_type": "predicate", - "convention": "", - "term_raw": "идемпотентность", - "term_resolved": "идемпотентность", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀α∈Pr1(Pr1(σ)) ((α,α),α)∈σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 11, + "alias": "P2", + "cst_type": "predicate", + "convention": "", + "term_raw": "идемпотентность", + "term_resolved": "идемпотентность", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀α∈Pr1(Pr1(σ)) ((α,α),α)∈σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 724, "fields": { - "schema": 36, - "order": 12, - "alias": "P3", - "cst_type": "predicate", - "convention": "", - "term_raw": "коммутативность", - "term_resolved": "коммутативность", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀((α1,α2),γ)∈σ ((α2,α1),γ)∈σ", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 12, + "alias": "P3", + "cst_type": "predicate", + "convention": "", + "term_raw": "коммутативность", + "term_resolved": "коммутативность", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] ∀((α1,α2),γ)∈σ ((α2,α1),γ)∈σ", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 725, "fields": { - "schema": 36, - "order": 13, - "alias": "P4", - "cst_type": "predicate", - "convention": "", - "term_raw": "ассоциативность", - "term_resolved": "ассоциативность", - "term_forms": [], - "definition_formal": "[σ∈ℬ((R1×R1)×R1)] \n∀α1,α2,α3∈Pr1(Pr1(σ)) F1[(F1[(α1, α2),σ],α3),σ] = F1[(α1,F1[(α2, α3), σ]),σ]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 13, + "alias": "P4", + "cst_type": "predicate", + "convention": "", + "term_raw": "ассоциативность", + "term_resolved": "ассоциативность", + "term_forms": [], + "definition_formal": "[σ∈ℬ((R1×R1)×R1)] \n∀α1,α2,α3∈Pr1(Pr1(σ)) F1[(F1[(α1, α2),σ],α3),σ] = F1[(α1,F1[(α2, α3), σ]),σ]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 726, "fields": { - "schema": 36, - "order": 14, - "alias": "P5", - "cst_type": "predicate", - "convention": "", - "term_raw": "поглощение бинарных операций", - "term_resolved": "поглощение бинарных операций", - "term_forms": [], - "definition_formal": "[σ1∈ℬ((R1×R1)×R1), σ2∈ℬ((R1×R1)×R1)] \n∀(α1,α2)∈Pr1(σ1) F1[(F1[(α1, α2),σ1],α1),σ2] = α1", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 14, + "alias": "P5", + "cst_type": "predicate", + "convention": "", + "term_raw": "поглощение бинарных операций", + "term_resolved": "поглощение бинарных операций", + "term_forms": [], + "definition_formal": "[σ1∈ℬ((R1×R1)×R1), σ2∈ℬ((R1×R1)×R1)] \n∀(α1,α2)∈Pr1(σ1) F1[(F1[(α1, α2),σ1],α1),σ2] = α1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 727, "fields": { - "schema": 36, - "order": 15, - "alias": "A1", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P1|nomn,sing} @{S1|gent,sing}", - "term_resolved": "прямая однозначность операции И", - "term_forms": [], - "definition_formal": "P1[S1]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 15, + "alias": "A1", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P1|nomn,sing} @{S1|gent,sing}", + "term_resolved": "прямая однозначность операции И", + "term_forms": [], + "definition_formal": "P1[S1]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 728, "fields": { - "schema": 36, - "order": 16, - "alias": "A2", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P1|nomn,sing} @{S2|gent,sing}", - "term_resolved": "прямая однозначность операции ИЛИ", - "term_forms": [], - "definition_formal": "P1[S2]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 16, + "alias": "A2", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P1|nomn,sing} @{S2|gent,sing}", + "term_resolved": "прямая однозначность операции ИЛИ", + "term_forms": [], + "definition_formal": "P1[S2]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 729, "fields": { - "schema": 36, - "order": 17, - "alias": "A3", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P2|nomn,sing} @{S1|gent,sing}", - "term_resolved": "идемпотентность операции И", - "term_forms": [], - "definition_formal": "P2[S1]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 17, + "alias": "A3", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P2|nomn,sing} @{S1|gent,sing}", + "term_resolved": "идемпотентность операции И", + "term_forms": [], + "definition_formal": "P2[S1]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 730, "fields": { - "schema": 36, - "order": 18, - "alias": "A4", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P2|nomn,sing} @{S2|gent,sing}", - "term_resolved": "идемпотентность операции ИЛИ", - "term_forms": [], - "definition_formal": "P2[S2]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 18, + "alias": "A4", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P2|nomn,sing} @{S2|gent,sing}", + "term_resolved": "идемпотентность операции ИЛИ", + "term_forms": [], + "definition_formal": "P2[S2]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 731, "fields": { - "schema": 36, - "order": 19, - "alias": "A5", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P3|nomn,sing} @{S1|gent,sing}", - "term_resolved": "коммутативность операции И", - "term_forms": [], - "definition_formal": "P3[S1]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 19, + "alias": "A5", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P3|nomn,sing} @{S1|gent,sing}", + "term_resolved": "коммутативность операции И", + "term_forms": [], + "definition_formal": "P3[S1]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 732, "fields": { - "schema": 36, - "order": 20, - "alias": "A6", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P3|nomn,sing} @{S2|gent,sing}", - "term_resolved": "коммутативность операции ИЛИ", - "term_forms": [], - "definition_formal": "P3[S2]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 20, + "alias": "A6", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P3|nomn,sing} @{S2|gent,sing}", + "term_resolved": "коммутативность операции ИЛИ", + "term_forms": [], + "definition_formal": "P3[S2]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 733, "fields": { - "schema": 36, - "order": 21, - "alias": "A7", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P4|nomn,sing} @{S1|gent,sing}", - "term_resolved": "ассоциативность операции И", - "term_forms": [], - "definition_formal": "P4[S1]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 21, + "alias": "A7", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P4|nomn,sing} @{S1|gent,sing}", + "term_resolved": "ассоциативность операции И", + "term_forms": [], + "definition_formal": "P4[S1]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 734, "fields": { - "schema": 36, - "order": 22, - "alias": "A8", - "cst_type": "axiom", - "convention": "", - "term_raw": "@{P4|nomn,sing} @{S2|gent,sing}", - "term_resolved": "ассоциативность операции ИЛИ", - "term_forms": [], - "definition_formal": "P4[S2]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 22, + "alias": "A8", + "cst_type": "axiom", + "convention": "", + "term_raw": "@{P4|nomn,sing} @{S2|gent,sing}", + "term_resolved": "ассоциативность операции ИЛИ", + "term_forms": [], + "definition_formal": "P4[S2]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 735, "fields": { - "schema": 36, - "order": 23, - "alias": "A9", - "cst_type": "axiom", - "convention": "", - "term_raw": "поглощение @{S1|gent,sing} @{S2|ablt,sing}", - "term_resolved": "поглощение операции И операцией ИЛИ", - "term_forms": [], - "definition_formal": "P5[S1,S2]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 23, + "alias": "A9", + "cst_type": "axiom", + "convention": "", + "term_raw": "поглощение @{S1|gent,sing} @{S2|ablt,sing}", + "term_resolved": "поглощение операции И операцией ИЛИ", + "term_forms": [], + "definition_formal": "P5[S1,S2]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 736, "fields": { - "schema": 36, - "order": 24, - "alias": "A10", - "cst_type": "axiom", - "convention": "", - "term_raw": "поглощение @{S2|gent,sing} @{S1|ablt,sing}", - "term_resolved": "поглощение операции ИЛИ операцией И", - "term_forms": [], - "definition_formal": "P5[S2,S1]", - "definition_raw": "", - "definition_resolved": "" + "schema": 36, + "order": 24, + "alias": "A10", + "cst_type": "axiom", + "convention": "", + "term_raw": "поглощение @{S2|gent,sing} @{S1|ablt,sing}", + "term_resolved": "поглощение операции ИЛИ операцией И", + "term_forms": [], + "definition_formal": "P5[S2,S1]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 737, "fields": { - "schema": 37, - "order": 1, - "alias": "X1", - "cst_type": "basic", - "convention": "Различимые в предметной области люди", - "term_raw": "индивиды", - "term_resolved": "индивиды", - "term_forms": [], - "definition_formal": "", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 1, + "alias": "X1", + "cst_type": "basic", + "convention": "Различимые в предметной области люди", + "term_raw": "индивиды", + "term_resolved": "индивиды", + "term_forms": [], + "definition_formal": "", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 738, "fields": { - "schema": 37, - "order": 2, - "alias": "S1", - "cst_type": "structure", - "convention": "Пол человека устанавливается в соответствии с документами", - "term_raw": "мужчины", - "term_resolved": "мужчины", - "term_forms": [], - "definition_formal": "ℬ(X1)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 2, + "alias": "S1", + "cst_type": "structure", + "convention": "Пол человека устанавливается в соответствии с документами", + "term_raw": "мужчины", + "term_resolved": "мужчины", + "term_forms": [], + "definition_formal": "ℬ(X1)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 739, "fields": { - "schema": 37, - "order": 3, - "alias": "S2", - "cst_type": "structure", - "convention": "Пол человека устанавливается в соответствии с документами", - "term_raw": "женщины", - "term_resolved": "женщины", - "term_forms": [], - "definition_formal": "ℬ(X1)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 3, + "alias": "S2", + "cst_type": "structure", + "convention": "Пол человека устанавливается в соответствии с документами", + "term_raw": "женщины", + "term_resolved": "женщины", + "term_forms": [], + "definition_formal": "ℬ(X1)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 740, "fields": { - "schema": 37, - "order": 4, - "alias": "A1", - "cst_type": "axiom", - "convention": "", - "term_raw": "условие разбиения индивидов на @{S1|gent,plur} и @{S2|gent,plur}", - "term_resolved": "условие разбиения индивидов на мужчин и женщин", - "term_forms": [], - "definition_formal": "S1∪S2=X1 & S1∩S2=∅", - "definition_raw": "каждый индивид является либо мужчиной либо женщиной", - "definition_resolved": "каждый индивид является либо мужчиной либо женщиной" + "schema": 37, + "order": 4, + "alias": "A1", + "cst_type": "axiom", + "convention": "", + "term_raw": "условие разбиения индивидов на @{S1|gent,plur} и @{S2|gent,plur}", + "term_resolved": "условие разбиения индивидов на мужчин и женщин", + "term_forms": [], + "definition_formal": "S1∪S2=X1 & S1∩S2=∅", + "definition_raw": "каждый индивид является либо мужчиной либо женщиной", + "definition_resolved": "каждый индивид является либо мужчиной либо женщиной" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 741, "fields": { - "schema": 37, - "order": 5, - "alias": "S3", - "cst_type": "structure", - "convention": "устанавливается на основе документов, подтверждающих факт рождения или паспорта родителя", - "term_raw": "отношение @{D2|nomn,sing} - @{D1|nomn,sing}", - "term_resolved": "отношение родитель - ребёнок", - "term_forms": [ - { - "tags": "sing,ablt", - "text": "отношением родитель - ребёнок" - }, - { - "tags": "sing,accs", - "text": "отношение родитель - ребёнок" - }, - { - "tags": "sing,datv", - "text": "отношению родитель - ребёнок" - }, - { - "tags": "sing,gent", - "text": "отношения родитель - ребёнок" - }, - { - "tags": "sing,nomn", - "text": "отношение родитель - ребёнок" - }, - { - "tags": "sing,loct", - "text": "отношение родителе - ребёнок" - }, - { - "tags": "plur,nomn", - "text": "отношение родители - ребёнок" - }, - { - "tags": "plur,gent", - "text": "отношение родителей - ребёнок" - }, - { - "tags": "plur,datv", - "text": "отношение родителям - ребёнок" - }, - { - "tags": "plur,accs", - "text": "отношение родителей - ребёнок" - }, - { - "tags": "plur,ablt", - "text": "отношение родителями - ребёнок" - }, - { - "tags": "plur,loct", - "text": "отношение родителях - ребёнок" - } - ], - "definition_formal": "ℬ(X1×X1)", - "definition_raw": "множество пар: @{D2|nomn,sing} и его @{D1|nomn,sing}", - "definition_resolved": "множество пар: родитель и его ребёнок" + "schema": 37, + "order": 5, + "alias": "S3", + "cst_type": "structure", + "convention": "устанавливается на основе документов, подтверждающих факт рождения или паспорта родителя", + "term_raw": "отношение @{D2|nomn,sing} - @{D1|nomn,sing}", + "term_resolved": "отношение родитель - ребёнок", + "term_forms": [ + { + "tags": "sing,ablt", + "text": "отношением родитель - ребёнок" + }, + { + "tags": "sing,accs", + "text": "отношение родитель - ребёнок" + }, + { + "tags": "sing,datv", + "text": "отношению родитель - ребёнок" + }, + { + "tags": "sing,gent", + "text": "отношения родитель - ребёнок" + }, + { + "tags": "sing,nomn", + "text": "отношение родитель - ребёнок" + }, + { + "tags": "sing,loct", + "text": "отношение родителе - ребёнок" + }, + { + "tags": "plur,nomn", + "text": "отношение родители - ребёнок" + }, + { + "tags": "plur,gent", + "text": "отношение родителей - ребёнок" + }, + { + "tags": "plur,datv", + "text": "отношение родителям - ребёнок" + }, + { + "tags": "plur,accs", + "text": "отношение родителей - ребёнок" + }, + { + "tags": "plur,ablt", + "text": "отношение родителями - ребёнок" + }, + { + "tags": "plur,loct", + "text": "отношение родителях - ребёнок" + } + ], + "definition_formal": "ℬ(X1×X1)", + "definition_raw": "множество пар: @{D2|nomn,sing} и его @{D1|nomn,sing}", + "definition_resolved": "множество пар: родитель и его ребёнок" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 742, "fields": { - "schema": 37, - "order": 6, - "alias": "D1", - "cst_type": "term", - "convention": "", - "term_raw": "дети", - "term_resolved": "дети", - "term_forms": [], - "definition_formal": "Pr2(S3)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 6, + "alias": "D1", + "cst_type": "term", + "convention": "", + "term_raw": "дети", + "term_resolved": "дети", + "term_forms": [], + "definition_formal": "Pr2(S3)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 743, "fields": { - "schema": 37, - "order": 7, - "alias": "D2", - "cst_type": "term", - "convention": "", - "term_raw": "родители", - "term_resolved": "родители", - "term_forms": [], - "definition_formal": "Pr1(S3)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 7, + "alias": "D2", + "cst_type": "term", + "convention": "", + "term_raw": "родители", + "term_resolved": "родители", + "term_forms": [], + "definition_formal": "Pr1(S3)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 744, "fields": { - "schema": 37, - "order": 8, - "alias": "F1", - "cst_type": "function", - "convention": "", - "term_raw": "@{D2|nomn,plur} @{X1|sing,gent}", - "term_resolved": "родители индивида", - "term_forms": [], - "definition_formal": "[α∈X1] Pr1(Fi2[{α}](S3))", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 8, + "alias": "F1", + "cst_type": "function", + "convention": "", + "term_raw": "@{D2|nomn,plur} @{X1|sing,gent}", + "term_resolved": "родители индивида", + "term_forms": [], + "definition_formal": "[α∈X1] Pr1(Fi2[{α}](S3))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 745, "fields": { - "schema": 37, - "order": 9, - "alias": "F2", - "cst_type": "function", - "convention": "", - "term_raw": "@{D2|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "родители группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] Pr1(Fi2[α](S3))", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 9, + "alias": "F2", + "cst_type": "function", + "convention": "", + "term_raw": "@{D2|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "родители группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] Pr1(Fi2[α](S3))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 746, "fields": { - "schema": 37, - "order": 10, - "alias": "F3", - "cst_type": "function", - "convention": "", - "term_raw": "@{D1|nomn,plur} @{X1|gent,sing}", - "term_resolved": "дети индивида", - "term_forms": [], - "definition_formal": "[α∈X1] Pr2(Fi1[{α}](S3))", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 10, + "alias": "F3", + "cst_type": "function", + "convention": "", + "term_raw": "@{D1|nomn,plur} @{X1|gent,sing}", + "term_resolved": "дети индивида", + "term_forms": [], + "definition_formal": "[α∈X1] Pr2(Fi1[{α}](S3))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 747, "fields": { - "schema": 37, - "order": 11, - "alias": "F4", - "cst_type": "function", - "convention": "", - "term_raw": "@{D1|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "дети группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] Pr2(Fi1[α](S3))", - "definition_raw": "совокупность @{D1|plur,gent}, одним из родителей которых является индивиди из данной группы индивидов", - "definition_resolved": "совокупность детей, одним из родителей которых является индивиди из данной группы индивидов" + "schema": 37, + "order": 11, + "alias": "F4", + "cst_type": "function", + "convention": "", + "term_raw": "@{D1|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "дети группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] Pr2(Fi1[α](S3))", + "definition_raw": "совокупность @{D1|plur,gent}, одним из родителей которых является индивиди из данной группы индивидов", + "definition_resolved": "совокупность детей, одним из родителей которых является индивиди из данной группы индивидов" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 748, "fields": { - "schema": 37, - "order": 12, - "alias": "F5", - "cst_type": "function", - "convention": "", - "term_raw": "сиблинги", - "term_resolved": "сиблинги", - "term_forms": [ - { - "tags": "plur,gent", - "text": "сиблингов" - } - ], - "definition_formal": "[α∈X1] Pr2(Fi1[F1[α]](S3))\\{α}", - "definition_raw": "@{D1|plur,nomn} @{D2|plur,gent} данного @{X1|sing,gent} за исключением его самого", - "definition_resolved": "дети родителей данного индивида за исключением его самого" + "schema": 37, + "order": 12, + "alias": "F5", + "cst_type": "function", + "convention": "", + "term_raw": "сиблинги", + "term_resolved": "сиблинги", + "term_forms": [ + { + "tags": "plur,gent", + "text": "сиблингов" + } + ], + "definition_formal": "[α∈X1] Pr2(Fi1[F1[α]](S3))\\{α}", + "definition_raw": "@{D1|plur,nomn} @{D2|plur,gent} данного @{X1|sing,gent} за исключением его самого", + "definition_resolved": "дети родителей данного индивида за исключением его самого" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 749, "fields": { - "schema": 37, - "order": 13, - "alias": "F6", - "cst_type": "function", - "convention": "", - "term_raw": "@{F5|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "сиблинги группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] Pr2(Fi1[F2[α]](S3))\\α", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 13, + "alias": "F6", + "cst_type": "function", + "convention": "", + "term_raw": "@{F5|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "сиблинги группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] Pr2(Fi1[F2[α]](S3))\\α", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 750, "fields": { - "schema": 37, - "order": 14, - "alias": "F7", - "cst_type": "function", - "convention": "", - "term_raw": "прадети", - "term_resolved": "прадети", - "term_forms": [], - "definition_formal": "[α∈X1] F4[F3[α]]", - "definition_raw": "@{D1|nomn,plur} @{F3|gent,plur}", - "definition_resolved": "дети детей индивида" + "schema": 37, + "order": 14, + "alias": "F7", + "cst_type": "function", + "convention": "", + "term_raw": "прадети", + "term_resolved": "прадети", + "term_forms": [], + "definition_formal": "[α∈X1] F4[F3[α]]", + "definition_raw": "@{D1|nomn,plur} @{F3|gent,plur}", + "definition_resolved": "дети детей индивида" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 751, "fields": { - "schema": 37, - "order": 15, - "alias": "F8", - "cst_type": "function", - "convention": "", - "term_raw": "прародители", - "term_resolved": "прародители", - "term_forms": [], - "definition_formal": "[α∈X1] F2[F1[α]]", - "definition_raw": "@{D2|nomn,plur} @{D2|gent,plur} данного @{X1|sing,gent}", - "definition_resolved": "родители родителей данного индивида" + "schema": 37, + "order": 15, + "alias": "F8", + "cst_type": "function", + "convention": "", + "term_raw": "прародители", + "term_resolved": "прародители", + "term_forms": [], + "definition_formal": "[α∈X1] F2[F1[α]]", + "definition_raw": "@{D2|nomn,plur} @{D2|gent,plur} данного @{X1|sing,gent}", + "definition_resolved": "родители родителей данного индивида" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 752, "fields": { - "schema": 37, - "order": 16, - "alias": "S4", - "cst_type": "structure", - "convention": "действующие браки", - "term_raw": "браки", - "term_resolved": "браки", - "term_forms": [], - "definition_formal": "ℬ(S1×S2)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 16, + "alias": "S4", + "cst_type": "structure", + "convention": "действующие браки", + "term_raw": "браки", + "term_resolved": "браки", + "term_forms": [], + "definition_formal": "ℬ(S1×S2)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 753, "fields": { - "schema": 37, - "order": 17, - "alias": "D3", - "cst_type": "term", - "convention": "", - "term_raw": "мужья", - "term_resolved": "мужья", - "term_forms": [], - "definition_formal": "Pr1(S4)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 17, + "alias": "D3", + "cst_type": "term", + "convention": "", + "term_raw": "мужья", + "term_resolved": "мужья", + "term_forms": [], + "definition_formal": "Pr1(S4)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 754, "fields": { - "schema": 37, - "order": 18, - "alias": "D4", - "cst_type": "term", - "convention": "", - "term_raw": "жены", - "term_resolved": "жены", - "term_forms": [], - "definition_formal": "Pr2(S4)", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 18, + "alias": "D4", + "cst_type": "term", + "convention": "", + "term_raw": "жены", + "term_resolved": "жены", + "term_forms": [], + "definition_formal": "Pr2(S4)", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 755, "fields": { - "schema": 37, - "order": 19, - "alias": "D5", - "cst_type": "term", - "convention": "", - "term_raw": "супруги", - "term_resolved": "супруги", - "term_forms": [], - "definition_formal": "Pr1(S4)∪Pr2(S4)", - "definition_raw": "множество множеств @{X1|gent,plur}, состоящих в @{S4|loct,sing}", - "definition_resolved": "множество множеств индивидов, состоящих в браке" + "schema": 37, + "order": 19, + "alias": "D5", + "cst_type": "term", + "convention": "", + "term_raw": "супруги", + "term_resolved": "супруги", + "term_forms": [], + "definition_formal": "Pr1(S4)∪Pr2(S4)", + "definition_raw": "множество множеств @{X1|gent,plur}, состоящих в @{S4|loct,sing}", + "definition_resolved": "множество множеств индивидов, состоящих в браке" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 756, "fields": { - "schema": 37, - "order": 20, - "alias": "A2", - "cst_type": "axiom", - "convention": "", - "term_raw": "единственность @{S4|gent,plur}", - "term_resolved": "единственность браков", - "term_forms": [], - "definition_formal": "card(S4)=card(D3) & card(S4)=card(D4)", - "definition_raw": "каждый @{X1|nomn,sing} может состоять только в одном @{S4|loct,sing}", - "definition_resolved": "каждый индивид может состоять только в одном браке" + "schema": 37, + "order": 20, + "alias": "A2", + "cst_type": "axiom", + "convention": "", + "term_raw": "единственность @{S4|gent,plur}", + "term_resolved": "единственность браков", + "term_forms": [], + "definition_formal": "card(S4)=card(D3) & card(S4)=card(D4)", + "definition_raw": "каждый @{X1|nomn,sing} может состоять только в одном @{S4|loct,sing}", + "definition_resolved": "каждый индивид может состоять только в одном браке" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 757, "fields": { - "schema": 37, - "order": 21, - "alias": "F9", - "cst_type": "function", - "convention": "", - "term_raw": "@{D3|nomn,sing} @{D4|gent,sing}", - "term_resolved": "муж жены", - "term_forms": [], - "definition_formal": "[α∈D4] debool(F11[{α}])", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 21, + "alias": "F9", + "cst_type": "function", + "convention": "", + "term_raw": "@{D3|nomn,sing} @{D4|gent,sing}", + "term_resolved": "муж жены", + "term_forms": [], + "definition_formal": "[α∈D4] debool(F11[{α}])", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 758, "fields": { - "schema": 37, - "order": 22, - "alias": "F10", - "cst_type": "function", - "convention": "", - "term_raw": "@{D4|nomn,sing} @{D3|gent,sing}", - "term_resolved": "жена мужа", - "term_forms": [], - "definition_formal": "[α∈D3] debool(F12[{α}])", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 22, + "alias": "F10", + "cst_type": "function", + "convention": "", + "term_raw": "@{D4|nomn,sing} @{D3|gent,sing}", + "term_resolved": "жена мужа", + "term_forms": [], + "definition_formal": "[α∈D3] debool(F12[{α}])", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 759, "fields": { - "schema": 37, - "order": 23, - "alias": "F11", - "cst_type": "function", - "convention": "", - "term_raw": "@{D3|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "мужья группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] Pr1(Fi2[α](S4))", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 23, + "alias": "F11", + "cst_type": "function", + "convention": "", + "term_raw": "@{D3|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "мужья группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] Pr1(Fi2[α](S4))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 760, "fields": { - "schema": 37, - "order": 24, - "alias": "F12", - "cst_type": "function", - "convention": "", - "term_raw": "@{D4|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "жены группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] Pr2(Fi1[α](S4))", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 24, + "alias": "F12", + "cst_type": "function", + "convention": "", + "term_raw": "@{D4|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "жены группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] Pr2(Fi1[α](S4))", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 761, "fields": { - "schema": 37, - "order": 25, - "alias": "F13", - "cst_type": "function", - "convention": "", - "term_raw": "@{D5|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "супруги группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F11[α]∪F12[α]", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 25, + "alias": "F13", + "cst_type": "function", + "convention": "", + "term_raw": "@{D5|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "супруги группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F11[α]∪F12[α]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 762, "fields": { - "schema": 37, - "order": 26, - "alias": "F14", - "cst_type": "function", - "convention": "", - "term_raw": "потомки", - "term_resolved": "потомки", - "term_forms": [], - "definition_formal": "[α∈X1] R{ξ:=F3[α] | ξ∪F4[ξ]}", - "definition_raw": "@{D1|nomn,plur} данного @{X1|sing,gent} или @{D1|nomn,plur} его @{F14|gent,plur}", - "definition_resolved": "дети данного индивида или дети его потомков" + "schema": 37, + "order": 26, + "alias": "F14", + "cst_type": "function", + "convention": "", + "term_raw": "потомки", + "term_resolved": "потомки", + "term_forms": [], + "definition_formal": "[α∈X1] R{ξ:=F3[α] | ξ∪F4[ξ]}", + "definition_raw": "@{D1|nomn,plur} данного @{X1|sing,gent} или @{D1|nomn,plur} его @{F14|gent,plur}", + "definition_resolved": "дети данного индивида или дети его потомков" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 763, "fields": { - "schema": 37, - "order": 27, - "alias": "F15", - "cst_type": "function", - "convention": "", - "term_raw": "@{F14|nomn,plur} данной группы @{X1|gent,plur}", - "term_resolved": "потомки данной группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] R{ξ:=F4[α] | ξ∪F4[ξ]}", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 27, + "alias": "F15", + "cst_type": "function", + "convention": "", + "term_raw": "@{F14|nomn,plur} данной группы @{X1|gent,plur}", + "term_resolved": "потомки данной группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] R{ξ:=F4[α] | ξ∪F4[ξ]}", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 764, "fields": { - "schema": 37, - "order": 28, - "alias": "A3", - "cst_type": "axiom", - "convention": "", - "term_raw": "ацикличность @{S3|sing,gent}", - "term_resolved": "ацикличность отношение родителя - ребёнок", - "term_forms": [], - "definition_formal": "∀ξ∈X1 ξ∉F14[ξ]", - "definition_raw": "@{X1|sing,nomn} не может быть своим @{F14|sing,ablt}", - "definition_resolved": "индивид не может быть своим потомком" + "schema": 37, + "order": 28, + "alias": "A3", + "cst_type": "axiom", + "convention": "", + "term_raw": "ацикличность @{S3|sing,gent}", + "term_resolved": "ацикличность отношение родителя - ребёнок", + "term_forms": [], + "definition_formal": "∀ξ∈X1 ξ∉F14[ξ]", + "definition_raw": "@{X1|sing,nomn} не может быть своим @{F14|sing,ablt}", + "definition_resolved": "индивид не может быть своим потомком" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 765, "fields": { - "schema": 37, - "order": 29, - "alias": "D6", - "cst_type": "term", - "convention": "", - "term_raw": "отцы", - "term_resolved": "отцы", - "term_forms": [], - "definition_formal": "D2∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 29, + "alias": "D6", + "cst_type": "term", + "convention": "", + "term_raw": "отцы", + "term_resolved": "отцы", + "term_forms": [], + "definition_formal": "D2∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 766, "fields": { - "schema": 37, - "order": 30, - "alias": "D7", - "cst_type": "term", - "convention": "", - "term_raw": "матери", - "term_resolved": "матери", - "term_forms": [ - { - "tags": "sing,nomn", - "text": "мать" - } - ], - "definition_formal": "D2∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 30, + "alias": "D7", + "cst_type": "term", + "convention": "", + "term_raw": "матери", + "term_resolved": "матери", + "term_forms": [ + { + "tags": "sing,nomn", + "text": "мать" + } + ], + "definition_formal": "D2∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 767, "fields": { - "schema": 37, - "order": 31, - "alias": "F16", - "cst_type": "function", - "convention": "", - "term_raw": "@{D6|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "отцы группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F2[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 31, + "alias": "F16", + "cst_type": "function", + "convention": "", + "term_raw": "@{D6|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "отцы группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F2[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 768, "fields": { - "schema": 37, - "order": 32, - "alias": "F17", - "cst_type": "function", - "convention": "", - "term_raw": "@{D6|nomn,plur} @{X1|sing,gent}", - "term_resolved": "отцы индивида", - "term_forms": [], - "definition_formal": "[α∈X1] F1[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 32, + "alias": "F17", + "cst_type": "function", + "convention": "", + "term_raw": "@{D6|nomn,plur} @{X1|sing,gent}", + "term_resolved": "отцы индивида", + "term_forms": [], + "definition_formal": "[α∈X1] F1[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 769, "fields": { - "schema": 37, - "order": 33, - "alias": "F18", - "cst_type": "function", - "convention": "", - "term_raw": "@{D7|nomn,plur} @{X1|gent,sing}", - "term_resolved": "матери индивида", - "term_forms": [], - "definition_formal": "[α∈X1] F1[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 33, + "alias": "F18", + "cst_type": "function", + "convention": "", + "term_raw": "@{D7|nomn,plur} @{X1|gent,sing}", + "term_resolved": "матери индивида", + "term_forms": [], + "definition_formal": "[α∈X1] F1[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 770, "fields": { - "schema": 37, - "order": 34, - "alias": "F19", - "cst_type": "function", - "convention": "", - "term_raw": "@{D7|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "матери группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F2[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 34, + "alias": "F19", + "cst_type": "function", + "convention": "", + "term_raw": "@{D7|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "матери группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F2[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 771, "fields": { - "schema": 37, - "order": 35, - "alias": "D8", - "cst_type": "term", - "convention": "", - "term_raw": "сироты", - "term_resolved": "сироты", - "term_forms": [], - "definition_formal": "X1\\D1", - "definition_raw": "@{X1|plur,nomn}, не имеющие являющиеся @{D1|plur,ablt}", - "definition_resolved": "индивиды, не имеющие являющиеся детьми" + "schema": 37, + "order": 35, + "alias": "D8", + "cst_type": "term", + "convention": "", + "term_raw": "сироты", + "term_resolved": "сироты", + "term_forms": [], + "definition_formal": "X1\\D1", + "definition_raw": "@{X1|plur,nomn}, не имеющие являющиеся @{D1|plur,ablt}", + "definition_resolved": "индивиды, не имеющие являющиеся детьми" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 772, "fields": { - "schema": 37, - "order": 36, - "alias": "A4", - "cst_type": "axiom", - "convention": "", - "term_raw": "ограничение @{D2|plur,gent}", - "term_resolved": "ограничение родителей", - "term_forms": [], - "definition_formal": "∀α∈X1 (card(F17[α])≤1 & card(F18[α])≤1)", - "definition_raw": "у @{D1|sing,gent} может быть максимум один @{D6|sing,nomn} и одна @{D7|sing,nomn}", - "definition_resolved": "у ребёнка может быть максимум один отец и одна мать" + "schema": 37, + "order": 36, + "alias": "A4", + "cst_type": "axiom", + "convention": "", + "term_raw": "ограничение @{D2|plur,gent}", + "term_resolved": "ограничение родителей", + "term_forms": [], + "definition_formal": "∀α∈X1 (card(F17[α])≤1 & card(F18[α])≤1)", + "definition_raw": "у @{D1|sing,gent} может быть максимум один @{D6|sing,nomn} и одна @{D7|sing,nomn}", + "definition_resolved": "у ребёнка может быть максимум один отец и одна мать" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 773, "fields": { - "schema": 37, - "order": 37, - "alias": "F20", - "cst_type": "function", - "convention": "", - "term_raw": "сыновья", - "term_resolved": "сыновья", - "term_forms": [ - { - "tags": "plur,gent", - "text": "сыновей" - } - ], - "definition_formal": "[α∈X1] F3[α]∩S1", - "definition_raw": "@{D1|plur,nomn} данного @{X1|sing,gent}, являющиеся @{S1|plur,ablt}", - "definition_resolved": "дети данного индивида, являющиеся мужчинами" + "schema": 37, + "order": 37, + "alias": "F20", + "cst_type": "function", + "convention": "", + "term_raw": "сыновья", + "term_resolved": "сыновья", + "term_forms": [ + { + "tags": "plur,gent", + "text": "сыновей" + } + ], + "definition_formal": "[α∈X1] F3[α]∩S1", + "definition_raw": "@{D1|plur,nomn} данного @{X1|sing,gent}, являющиеся @{S1|plur,ablt}", + "definition_resolved": "дети данного индивида, являющиеся мужчинами" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 774, "fields": { - "schema": 37, - "order": 38, - "alias": "F21", - "cst_type": "function", - "convention": "", - "term_raw": "@{F20|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "сыновья группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F4[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 38, + "alias": "F21", + "cst_type": "function", + "convention": "", + "term_raw": "@{F20|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "сыновья группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F4[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 775, "fields": { - "schema": 37, - "order": 39, - "alias": "F22", - "cst_type": "function", - "convention": "", - "term_raw": "дочери", - "term_resolved": "дочери", - "term_forms": [], - "definition_formal": "[α∈X1] F3[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 39, + "alias": "F22", + "cst_type": "function", + "convention": "", + "term_raw": "дочери", + "term_resolved": "дочери", + "term_forms": [], + "definition_formal": "[α∈X1] F3[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 776, "fields": { - "schema": 37, - "order": 40, - "alias": "F23", - "cst_type": "function", - "convention": "", - "term_raw": "@{F22|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "дочери группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F4[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 40, + "alias": "F23", + "cst_type": "function", + "convention": "", + "term_raw": "@{F22|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "дочери группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F4[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 777, "fields": { - "schema": 37, - "order": 41, - "alias": "F24", - "cst_type": "function", - "convention": "", - "term_raw": "внуки", - "term_resolved": "внуки", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F3[α]]", - "definition_raw": "@{F20|nomn,plur} @{D1|gent,plur}", - "definition_resolved": "сыновья детей" + "schema": 37, + "order": 41, + "alias": "F24", + "cst_type": "function", + "convention": "", + "term_raw": "внуки", + "term_resolved": "внуки", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F3[α]]", + "definition_raw": "@{F20|nomn,plur} @{D1|gent,plur}", + "definition_resolved": "сыновья детей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 778, "fields": { - "schema": 37, - "order": 42, - "alias": "F25", - "cst_type": "function", - "convention": "", - "term_raw": "внучки", - "term_resolved": "внучки", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F3[α]]", - "definition_raw": "@{F22|nomn,plur} @{D1|gent,plur}", - "definition_resolved": "дочери детей" + "schema": 37, + "order": 42, + "alias": "F25", + "cst_type": "function", + "convention": "", + "term_raw": "внучки", + "term_resolved": "внучки", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F3[α]]", + "definition_raw": "@{F22|nomn,plur} @{D1|gent,plur}", + "definition_resolved": "дочери детей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 779, "fields": { - "schema": 37, - "order": 43, - "alias": "F26", - "cst_type": "function", - "convention": "", - "term_raw": "дедушки", - "term_resolved": "дедушки", - "term_forms": [], - "definition_formal": "[α∈X1] F16[F1[α]]", - "definition_raw": "@{D6|nomn,plur} @{D2|gent,plur}", - "definition_resolved": "отцы родителей" + "schema": 37, + "order": 43, + "alias": "F26", + "cst_type": "function", + "convention": "", + "term_raw": "дедушки", + "term_resolved": "дедушки", + "term_forms": [], + "definition_formal": "[α∈X1] F16[F1[α]]", + "definition_raw": "@{D6|nomn,plur} @{D2|gent,plur}", + "definition_resolved": "отцы родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 780, "fields": { - "schema": 37, - "order": 44, - "alias": "F27", - "cst_type": "function", - "convention": "", - "term_raw": "бабушки", - "term_resolved": "бабушки", - "term_forms": [], - "definition_formal": "[α∈X1] F19[F1[α]]", - "definition_raw": "@{D7|nomn,plur} @{D2|gent,plur}", - "definition_resolved": "матери родителей" + "schema": 37, + "order": 44, + "alias": "F27", + "cst_type": "function", + "convention": "", + "term_raw": "бабушки", + "term_resolved": "бабушки", + "term_forms": [], + "definition_formal": "[α∈X1] F19[F1[α]]", + "definition_raw": "@{D7|nomn,plur} @{D2|gent,plur}", + "definition_resolved": "матери родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 781, "fields": { - "schema": 37, - "order": 45, - "alias": "F28", - "cst_type": "function", - "convention": "", - "term_raw": "братья", - "term_resolved": "братья", - "term_forms": [ - { - "tags": "plur,gent", - "text": "братьев" - } - ], - "definition_formal": "[α∈X1] F5[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 45, + "alias": "F28", + "cst_type": "function", + "convention": "", + "term_raw": "братья", + "term_resolved": "братья", + "term_forms": [ + { + "tags": "plur,gent", + "text": "братьев" + } + ], + "definition_formal": "[α∈X1] F5[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 782, "fields": { - "schema": 37, - "order": 46, - "alias": "F29", - "cst_type": "function", - "convention": "", - "term_raw": "@{F28|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "братья группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F6[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 46, + "alias": "F29", + "cst_type": "function", + "convention": "", + "term_raw": "@{F28|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "братья группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F6[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 783, "fields": { - "schema": 37, - "order": 47, - "alias": "F30", - "cst_type": "function", - "convention": "", - "term_raw": "сёстры", - "term_resolved": "сёстры", - "term_forms": [], - "definition_formal": "[α∈X1] F5[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 47, + "alias": "F30", + "cst_type": "function", + "convention": "", + "term_raw": "сёстры", + "term_resolved": "сёстры", + "term_forms": [], + "definition_formal": "[α∈X1] F5[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 784, "fields": { - "schema": 37, - "order": 48, - "alias": "F31", - "cst_type": "function", - "convention": "", - "term_raw": "@{F30|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "сёстры группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F6[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 48, + "alias": "F31", + "cst_type": "function", + "convention": "", + "term_raw": "@{F30|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "сёстры группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F6[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 785, "fields": { - "schema": 37, - "order": 49, - "alias": "F32", - "cst_type": "function", - "convention": "", - "term_raw": "полнородные @{F5|nomn,plur}", - "term_resolved": "полнородные сиблинги", - "term_forms": [], - "definition_formal": "[α∈X1] D{ξ∈F5[α] | F1[α]=F1[ξ] }", - "definition_raw": "@{F5|plur,nomn} данного @{X1|sing,gent}, @{D2|plur,nomn} которых полностью совпадают с его @{D2|plur,gent}", - "definition_resolved": "сиблинги данного индивида, родители которых полностью совпадают с его родителей" + "schema": 37, + "order": 49, + "alias": "F32", + "cst_type": "function", + "convention": "", + "term_raw": "полнородные @{F5|nomn,plur}", + "term_resolved": "полнородные сиблинги", + "term_forms": [], + "definition_formal": "[α∈X1] D{ξ∈F5[α] | F1[α]=F1[ξ] }", + "definition_raw": "@{F5|plur,nomn} данного @{X1|sing,gent}, @{D2|plur,nomn} которых полностью совпадают с его @{D2|plur,gent}", + "definition_resolved": "сиблинги данного индивида, родители которых полностью совпадают с его родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 786, "fields": { - "schema": 37, - "order": 50, - "alias": "F33", - "cst_type": "function", - "convention": "", - "term_raw": "полнородные @{F28|nomn,plur} @{X1|gent,sing}", - "term_resolved": "полнородные братья индивида", - "term_forms": [], - "definition_formal": "[α∈X1] F32[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 50, + "alias": "F33", + "cst_type": "function", + "convention": "", + "term_raw": "полнородные @{F28|nomn,plur} @{X1|gent,sing}", + "term_resolved": "полнородные братья индивида", + "term_forms": [], + "definition_formal": "[α∈X1] F32[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 787, "fields": { - "schema": 37, - "order": 51, - "alias": "F34", - "cst_type": "function", - "convention": "", - "term_raw": "полнородные @{F30|nomn,plur} @{X1|gent,sing}", - "term_resolved": "полнородные сёстры индивида", - "term_forms": [], - "definition_formal": "[α∈X1] F32[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 51, + "alias": "F34", + "cst_type": "function", + "convention": "", + "term_raw": "полнородные @{F30|nomn,plur} @{X1|gent,sing}", + "term_resolved": "полнородные сёстры индивида", + "term_forms": [], + "definition_formal": "[α∈X1] F32[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 788, "fields": { - "schema": 37, - "order": 52, - "alias": "F35", - "cst_type": "function", - "convention": "", - "term_raw": "единокровные @{F5|nomn,plur}", - "term_resolved": "единокровные сиблинги", - "term_forms": [], - "definition_formal": "[α∈X1] D{ξ∈F5[α] | F17[α]=F17[ξ] & F18[α]≠F18[ξ] }", - "definition_raw": "@{F5|nomn,plur}, у которых @{1|общий} @{D6|nomn,sing}, но разные @{D7|nomn,plur}", - "definition_resolved": "сиблинги, у которых общий отец, но разные матери" + "schema": 37, + "order": 52, + "alias": "F35", + "cst_type": "function", + "convention": "", + "term_raw": "единокровные @{F5|nomn,plur}", + "term_resolved": "единокровные сиблинги", + "term_forms": [], + "definition_formal": "[α∈X1] D{ξ∈F5[α] | F17[α]=F17[ξ] & F18[α]≠F18[ξ] }", + "definition_raw": "@{F5|nomn,plur}, у которых @{1|общий} @{D6|nomn,sing}, но разные @{D7|nomn,plur}", + "definition_resolved": "сиблинги, у которых общий отец, но разные матери" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 789, "fields": { - "schema": 37, - "order": 53, - "alias": "F36", - "cst_type": "function", - "convention": "", - "term_raw": "единокровные @{F28|nomn,plur}", - "term_resolved": "единокровные братья", - "term_forms": [], - "definition_formal": "[α∈X1] F35[α]∩S1", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 53, + "alias": "F36", + "cst_type": "function", + "convention": "", + "term_raw": "единокровные @{F28|nomn,plur}", + "term_resolved": "единокровные братья", + "term_forms": [], + "definition_formal": "[α∈X1] F35[α]∩S1", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 790, "fields": { - "schema": 37, - "order": 54, - "alias": "F37", - "cst_type": "function", - "convention": "", - "term_raw": "единокровные @{F30|nomn,plur}", - "term_resolved": "единокровные сёстры", - "term_forms": [], - "definition_formal": "[α∈X1] F35[α]∩S2", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 54, + "alias": "F37", + "cst_type": "function", + "convention": "", + "term_raw": "единокровные @{F30|nomn,plur}", + "term_resolved": "единокровные сёстры", + "term_forms": [], + "definition_formal": "[α∈X1] F35[α]∩S2", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 791, "fields": { - "schema": 37, - "order": 55, - "alias": "F38", - "cst_type": "function", - "convention": "", - "term_raw": "единоутробные @{F5|nomn,plur}", - "term_resolved": "единоутробные сиблинги", - "term_forms": [], - "definition_formal": "[α∈X1] D{ξ∈F5[α] | F17[α]≠F17[ξ] & F18[α]=F18[ξ] }", - "definition_raw": "@{F5|nomn,plur}, у которых @{1|общий} @{D7|nomn,sing}, но разные @{D6|nomn,plur}", - "definition_resolved": "сиблинги, у которых общая мать, но разные отцы" + "schema": 37, + "order": 55, + "alias": "F38", + "cst_type": "function", + "convention": "", + "term_raw": "единоутробные @{F5|nomn,plur}", + "term_resolved": "единоутробные сиблинги", + "term_forms": [], + "definition_formal": "[α∈X1] D{ξ∈F5[α] | F17[α]≠F17[ξ] & F18[α]=F18[ξ] }", + "definition_raw": "@{F5|nomn,plur}, у которых @{1|общий} @{D7|nomn,sing}, но разные @{D6|nomn,plur}", + "definition_resolved": "сиблинги, у которых общая мать, но разные отцы" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 792, "fields": { - "schema": 37, - "order": 56, - "alias": "F39", - "cst_type": "function", - "convention": "", - "term_raw": "единоутробные @{F28|nomn,plur}", - "term_resolved": "единоутробные братья", - "term_forms": [], - "definition_formal": "[α∈X1] F38[α]∩F28[α]", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 56, + "alias": "F39", + "cst_type": "function", + "convention": "", + "term_raw": "единоутробные @{F28|nomn,plur}", + "term_resolved": "единоутробные братья", + "term_forms": [], + "definition_formal": "[α∈X1] F38[α]∩F28[α]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 793, "fields": { - "schema": 37, - "order": 57, - "alias": "F40", - "cst_type": "function", - "convention": "", - "term_raw": "единоутробные @{F30|nomn,plur}", - "term_resolved": "единоутробные сёстры", - "term_forms": [], - "definition_formal": "[α∈X1] F38[α]∩F30[α]", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 57, + "alias": "F40", + "cst_type": "function", + "convention": "", + "term_raw": "единоутробные @{F30|nomn,plur}", + "term_resolved": "единоутробные сёстры", + "term_forms": [], + "definition_formal": "[α∈X1] F38[α]∩F30[α]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 794, "fields": { - "schema": 37, - "order": 58, - "alias": "F41", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F5|nomn,plur}", - "term_resolved": "двоюродные сиблинги", - "term_forms": [ - { - "tags": "plur,gent", - "text": "двоюродных сиблингов" - } - ], - "definition_formal": "[α∈X1] F15[F6[F1[α]]]", - "definition_raw": "@{D1|nomn,plur} @{F5|gent,plur} @{D2|gent,plur}", - "definition_resolved": "дети сиблингов родителей" + "schema": 37, + "order": 58, + "alias": "F41", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F5|nomn,plur}", + "term_resolved": "двоюродные сиблинги", + "term_forms": [ + { + "tags": "plur,gent", + "text": "двоюродных сиблингов" + } + ], + "definition_formal": "[α∈X1] F15[F6[F1[α]]]", + "definition_raw": "@{D1|nomn,plur} @{F5|gent,plur} @{D2|gent,plur}", + "definition_resolved": "дети сиблингов родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 795, "fields": { - "schema": 37, - "order": 59, - "alias": "F42", - "cst_type": "function", - "convention": "", - "term_raw": "@{F41|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "двоюродные сиблинги группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F15[F6[F2[α]]]", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 59, + "alias": "F42", + "cst_type": "function", + "convention": "", + "term_raw": "@{F41|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "двоюродные сиблинги группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F15[F6[F2[α]]]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 796, "fields": { - "schema": 37, - "order": 60, - "alias": "F43", - "cst_type": "function", - "convention": "", - "term_raw": "@{F41|nomn,plur} по @{D6|datv,sing}", - "term_resolved": "двоюродные сиблинги по отцу", - "term_forms": [], - "definition_formal": "[α∈X1] F15[F6[F17[α]]]", - "definition_raw": "@{D1|nomn,plur} @{F5|gent,plur} @{D6|gent,sing}", - "definition_resolved": "дети сиблингов отца" + "schema": 37, + "order": 60, + "alias": "F43", + "cst_type": "function", + "convention": "", + "term_raw": "@{F41|nomn,plur} по @{D6|datv,sing}", + "term_resolved": "двоюродные сиблинги по отцу", + "term_forms": [], + "definition_formal": "[α∈X1] F15[F6[F17[α]]]", + "definition_raw": "@{D1|nomn,plur} @{F5|gent,plur} @{D6|gent,sing}", + "definition_resolved": "дети сиблингов отца" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 797, "fields": { - "schema": 37, - "order": 61, - "alias": "F44", - "cst_type": "function", - "convention": "", - "term_raw": "@{F41|nomn,plur} по @{D7|datv,sing}", - "term_resolved": "двоюродные сиблинги по матери", - "term_forms": [], - "definition_formal": "[α∈X1] F15[F6[F18[α]]]", - "definition_raw": "@{D1|nomn,plur} @{F5|gent,plur} @{D7|gent,sing}", - "definition_resolved": "дети сиблингов матери" + "schema": 37, + "order": 61, + "alias": "F44", + "cst_type": "function", + "convention": "", + "term_raw": "@{F41|nomn,plur} по @{D7|datv,sing}", + "term_resolved": "двоюродные сиблинги по матери", + "term_forms": [], + "definition_formal": "[α∈X1] F15[F6[F18[α]]]", + "definition_raw": "@{D1|nomn,plur} @{F5|gent,plur} @{D7|gent,sing}", + "definition_resolved": "дети сиблингов матери" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 798, "fields": { - "schema": 37, - "order": 62, - "alias": "F45", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F28|nomn,plur}", - "term_resolved": "двоюродные братья", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F6[F1[α]]]", - "definition_raw": "@{F20|nomn,plur} @{F5|gent,plur} @{D2|gent,plur}", - "definition_resolved": "сыновья сиблингов родителей" + "schema": 37, + "order": 62, + "alias": "F45", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F28|nomn,plur}", + "term_resolved": "двоюродные братья", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F6[F1[α]]]", + "definition_raw": "@{F20|nomn,plur} @{F5|gent,plur} @{D2|gent,plur}", + "definition_resolved": "сыновья сиблингов родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 799, "fields": { - "schema": 37, - "order": 63, - "alias": "F46", - "cst_type": "function", - "convention": "", - "term_raw": "@{F45|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "двоюродные братья группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F21[F6[F2[α]]]", - "definition_raw": "", - "definition_resolved": "" + "schema": 37, + "order": 63, + "alias": "F46", + "cst_type": "function", + "convention": "", + "term_raw": "@{F45|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "двоюродные братья группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F21[F6[F2[α]]]", + "definition_raw": "", + "definition_resolved": "" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 800, "fields": { - "schema": 37, - "order": 64, - "alias": "F47", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F30|nomn,plur}", - "term_resolved": "двоюродные сёстры", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F6[F1[α]]]", - "definition_raw": "@{F41|nomn,plur}, являющиеся @{S2|ablt,plur}", - "definition_resolved": "двоюродные сиблинги, являющиеся женщинами" + "schema": 37, + "order": 64, + "alias": "F47", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F30|nomn,plur}", + "term_resolved": "двоюродные сёстры", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F6[F1[α]]]", + "definition_raw": "@{F41|nomn,plur}, являющиеся @{S2|ablt,plur}", + "definition_resolved": "двоюродные сиблинги, являющиеся женщинами" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 801, "fields": { - "schema": 37, - "order": 65, - "alias": "F48", - "cst_type": "function", - "convention": "", - "term_raw": "@{F47|nomn,plur} группы @{X1|gent,plur}", - "term_resolved": "двоюродные сёстры группы индивидов", - "term_forms": [], - "definition_formal": "[α∈ℬ(X1)] F23[F6[F2[α]]]", - "definition_raw": "@{F22|nomn,plur} @{F5|gent,plur} @{D2|gent,plur}", - "definition_resolved": "дочери сиблингов родителей" + "schema": 37, + "order": 65, + "alias": "F48", + "cst_type": "function", + "convention": "", + "term_raw": "@{F47|nomn,plur} группы @{X1|gent,plur}", + "term_resolved": "двоюродные сёстры группы индивидов", + "term_forms": [], + "definition_formal": "[α∈ℬ(X1)] F23[F6[F2[α]]]", + "definition_raw": "@{F22|nomn,plur} @{F5|gent,plur} @{D2|gent,plur}", + "definition_resolved": "дочери сиблингов родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 802, "fields": { - "schema": 37, - "order": 66, - "alias": "F49", - "cst_type": "function", - "convention": "", - "term_raw": "стрыйчичи", - "term_resolved": "стрыйчичи", - "term_forms": [], - "definition_formal": "[α∈X1] F45[α]∩F43[α]", - "definition_raw": "@{F45|nomn,plur} по @{D6|datv,sing}", - "definition_resolved": "двоюродные братья по отцу" + "schema": 37, + "order": 66, + "alias": "F49", + "cst_type": "function", + "convention": "", + "term_raw": "стрыйчичи", + "term_resolved": "стрыйчичи", + "term_forms": [], + "definition_formal": "[α∈X1] F45[α]∩F43[α]", + "definition_raw": "@{F45|nomn,plur} по @{D6|datv,sing}", + "definition_resolved": "двоюродные братья по отцу" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 803, "fields": { - "schema": 37, - "order": 67, - "alias": "F50", - "cst_type": "function", - "convention": "", - "term_raw": "стрыечки", - "term_resolved": "стрыечки", - "term_forms": [], - "definition_formal": "[α∈X1] F47[α]∩F43[α]", - "definition_raw": "@{F47|nomn,plur} по @{D6|datv,sing}", - "definition_resolved": "двоюродные сёстры по отцу" + "schema": 37, + "order": 67, + "alias": "F50", + "cst_type": "function", + "convention": "", + "term_raw": "стрыечки", + "term_resolved": "стрыечки", + "term_forms": [], + "definition_formal": "[α∈X1] F47[α]∩F43[α]", + "definition_raw": "@{F47|nomn,plur} по @{D6|datv,sing}", + "definition_resolved": "двоюродные сёстры по отцу" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 804, "fields": { - "schema": 37, - "order": 68, - "alias": "F51", - "cst_type": "function", - "convention": "", - "term_raw": "уйчичи", - "term_resolved": "уйчичи", - "term_forms": [], - "definition_formal": "[α∈X1] F45[α]∩F44[α]", - "definition_raw": "@{F45|nomn,plur} по @{D7|datv,sing}", - "definition_resolved": "двоюродные братья по матери" + "schema": 37, + "order": 68, + "alias": "F51", + "cst_type": "function", + "convention": "", + "term_raw": "уйчичи", + "term_resolved": "уйчичи", + "term_forms": [], + "definition_formal": "[α∈X1] F45[α]∩F44[α]", + "definition_raw": "@{F45|nomn,plur} по @{D7|datv,sing}", + "definition_resolved": "двоюродные братья по матери" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 805, "fields": { - "schema": 37, - "order": 69, - "alias": "F52", - "cst_type": "function", - "convention": "", - "term_raw": "дяди", - "term_resolved": "дяди", - "term_forms": [], - "definition_formal": "[α∈X1] F29[F1[α]]", - "definition_raw": "@{F28|nomn,plur} @{D2|gent,plur}", - "definition_resolved": "братья родителей" + "schema": 37, + "order": 69, + "alias": "F52", + "cst_type": "function", + "convention": "", + "term_raw": "дяди", + "term_resolved": "дяди", + "term_forms": [], + "definition_formal": "[α∈X1] F29[F1[α]]", + "definition_raw": "@{F28|nomn,plur} @{D2|gent,plur}", + "definition_resolved": "братья родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 806, "fields": { - "schema": 37, - "order": 70, - "alias": "F53", - "cst_type": "function", - "convention": "", - "term_raw": "стрыи", - "term_resolved": "стрыи", - "term_forms": [], - "definition_formal": "[α∈D1] F29[F17[α]]", - "definition_raw": "@{F28|nomn,plur} @{D6|gent,sing}", - "definition_resolved": "братья отца" + "schema": 37, + "order": 70, + "alias": "F53", + "cst_type": "function", + "convention": "", + "term_raw": "стрыи", + "term_resolved": "стрыи", + "term_forms": [], + "definition_formal": "[α∈D1] F29[F17[α]]", + "definition_raw": "@{F28|nomn,plur} @{D6|gent,sing}", + "definition_resolved": "братья отца" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 807, "fields": { - "schema": 37, - "order": 71, - "alias": "F54", - "cst_type": "function", - "convention": "", - "term_raw": "вуи", - "term_resolved": "вуи", - "term_forms": [ - { - "tags": "sing,nomn", - "text": "вуй" - }, - { - "tags": "sing,gent", - "text": "вуя" - }, - { - "tags": "sing,datv", - "text": "вую" - }, - { - "tags": "plur,gent", - "text": "вуёв" - } - ], - "definition_formal": "[α∈D1] F29[F18[α]]", - "definition_raw": "@{F28|nomn,plur} @{D7|gent,sing}", - "definition_resolved": "братья матери" + "schema": 37, + "order": 71, + "alias": "F54", + "cst_type": "function", + "convention": "", + "term_raw": "вуи", + "term_resolved": "вуи", + "term_forms": [ + { + "tags": "sing,nomn", + "text": "вуй" + }, + { + "tags": "sing,gent", + "text": "вуя" + }, + { + "tags": "sing,datv", + "text": "вую" + }, + { + "tags": "plur,gent", + "text": "вуёв" + } + ], + "definition_formal": "[α∈D1] F29[F18[α]]", + "definition_raw": "@{F28|nomn,plur} @{D7|gent,sing}", + "definition_resolved": "братья матери" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 808, "fields": { - "schema": 37, - "order": 72, - "alias": "F55", - "cst_type": "function", - "convention": "", - "term_raw": "тёти", - "term_resolved": "тёти", - "term_forms": [], - "definition_formal": "[α∈X1] F31[F1[α]]", - "definition_raw": "@{F30|nomn,plur} @{D2|gent,plur}", - "definition_resolved": "сёстры родителей" + "schema": 37, + "order": 72, + "alias": "F55", + "cst_type": "function", + "convention": "", + "term_raw": "тёти", + "term_resolved": "тёти", + "term_forms": [], + "definition_formal": "[α∈X1] F31[F1[α]]", + "definition_raw": "@{F30|nomn,plur} @{D2|gent,plur}", + "definition_resolved": "сёстры родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 809, "fields": { - "schema": 37, - "order": 73, - "alias": "F56", - "cst_type": "function", - "convention": "", - "term_raw": "стрыйны", - "term_resolved": "стрыйны", - "term_forms": [], - "definition_formal": "[α∈D1] F31[F17[α]]", - "definition_raw": "@{F30|nomn,plur} @{D6|gent,sing}", - "definition_resolved": "сёстры отца" + "schema": 37, + "order": 73, + "alias": "F56", + "cst_type": "function", + "convention": "", + "term_raw": "стрыйны", + "term_resolved": "стрыйны", + "term_forms": [], + "definition_formal": "[α∈D1] F31[F17[α]]", + "definition_raw": "@{F30|nomn,plur} @{D6|gent,sing}", + "definition_resolved": "сёстры отца" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 810, "fields": { - "schema": 37, - "order": 74, - "alias": "F57", - "cst_type": "function", - "convention": "", - "term_raw": "вуйны", - "term_resolved": "вуйны", - "term_forms": [], - "definition_formal": "[α∈D1] F31[F18[α]]", - "definition_raw": "@{F30|nomn,plur} @{D7|gent,sing}", - "definition_resolved": "сёстры матери" + "schema": 37, + "order": 74, + "alias": "F57", + "cst_type": "function", + "convention": "", + "term_raw": "вуйны", + "term_resolved": "вуйны", + "term_forms": [], + "definition_formal": "[α∈D1] F31[F18[α]]", + "definition_raw": "@{F30|nomn,plur} @{D7|gent,sing}", + "definition_resolved": "сёстры матери" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 811, "fields": { - "schema": 37, - "order": 75, - "alias": "F58", - "cst_type": "function", - "convention": "", - "term_raw": "племянники", - "term_resolved": "племянники", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F5[α]]", - "definition_raw": "@{F20|nomn,plur} @{F5|gent,plur}", - "definition_resolved": "сыновья сиблингов" + "schema": 37, + "order": 75, + "alias": "F58", + "cst_type": "function", + "convention": "", + "term_raw": "племянники", + "term_resolved": "племянники", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F5[α]]", + "definition_raw": "@{F20|nomn,plur} @{F5|gent,plur}", + "definition_resolved": "сыновья сиблингов" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 812, "fields": { - "schema": 37, - "order": 76, - "alias": "F59", - "cst_type": "function", - "convention": "", - "term_raw": "братычи", - "term_resolved": "братычи", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F28[α]]", - "definition_raw": "@{F20|nomn,plur} @{F28|gent,plur}", - "definition_resolved": "сыновья братьев" + "schema": 37, + "order": 76, + "alias": "F59", + "cst_type": "function", + "convention": "", + "term_raw": "братычи", + "term_resolved": "братычи", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F28[α]]", + "definition_raw": "@{F20|nomn,plur} @{F28|gent,plur}", + "definition_resolved": "сыновья братьев" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 813, "fields": { - "schema": 37, - "order": 77, - "alias": "F60", - "cst_type": "function", - "convention": "", - "term_raw": "сестричи", - "term_resolved": "сестричи", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F30[α]]", - "definition_raw": "@{F20|nomn,plur} @{F30|gent,plur}", - "definition_resolved": "сыновья сестёр" + "schema": 37, + "order": 77, + "alias": "F60", + "cst_type": "function", + "convention": "", + "term_raw": "сестричи", + "term_resolved": "сестричи", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F30[α]]", + "definition_raw": "@{F20|nomn,plur} @{F30|gent,plur}", + "definition_resolved": "сыновья сестёр" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 814, "fields": { - "schema": 37, - "order": 78, - "alias": "F61", - "cst_type": "function", - "convention": "", - "term_raw": "племянницы", - "term_resolved": "племянницы", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F5[α]]", - "definition_raw": "@{F22|gent,sing} @{F5|gent,plur}", - "definition_resolved": "дочери сиблингов" + "schema": 37, + "order": 78, + "alias": "F61", + "cst_type": "function", + "convention": "", + "term_raw": "племянницы", + "term_resolved": "племянницы", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F5[α]]", + "definition_raw": "@{F22|gent,sing} @{F5|gent,plur}", + "definition_resolved": "дочери сиблингов" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 815, "fields": { - "schema": 37, - "order": 79, - "alias": "F62", - "cst_type": "function", - "convention": "", - "term_raw": "братанины", - "term_resolved": "братанины", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F28[α]]", - "definition_raw": "@{F22|gent,sing} @{F28|gent,plur}", - "definition_resolved": "дочери братьев" + "schema": 37, + "order": 79, + "alias": "F62", + "cst_type": "function", + "convention": "", + "term_raw": "братанины", + "term_resolved": "братанины", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F28[α]]", + "definition_raw": "@{F22|gent,sing} @{F28|gent,plur}", + "definition_resolved": "дочери братьев" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 816, "fields": { - "schema": 37, - "order": 80, - "alias": "F63", - "cst_type": "function", - "convention": "", - "term_raw": "сестрины", - "term_resolved": "сестрины", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F30[α]]", - "definition_raw": "@{F22|gent,sing} @{F30|gent,plur}", - "definition_resolved": "дочери сестёр" + "schema": 37, + "order": 80, + "alias": "F63", + "cst_type": "function", + "convention": "", + "term_raw": "сестрины", + "term_resolved": "сестрины", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F30[α]]", + "definition_raw": "@{F22|gent,sing} @{F30|gent,plur}", + "definition_resolved": "дочери сестёр" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 817, "fields": { - "schema": 37, - "order": 81, - "alias": "F64", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F52|nomn,plur}", - "term_resolved": "двоюродные дяди", - "term_forms": [], - "definition_formal": "[α∈X1] F46[F1[α]]", - "definition_raw": "@{F45|nomn,plur} @{D2|gent,plur}", - "definition_resolved": "двоюродные братья родителей" + "schema": 37, + "order": 81, + "alias": "F64", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F52|nomn,plur}", + "term_resolved": "двоюродные дяди", + "term_forms": [], + "definition_formal": "[α∈X1] F46[F1[α]]", + "definition_raw": "@{F45|nomn,plur} @{D2|gent,plur}", + "definition_resolved": "двоюродные братья родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 818, "fields": { - "schema": 37, - "order": 82, - "alias": "F65", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F55|nomn,plur}", - "term_resolved": "двоюродные тёти", - "term_forms": [], - "definition_formal": "[α∈X1] F48[F1[α]]", - "definition_raw": "@{F47|nomn,plur} @{D2|gent,plur}", - "definition_resolved": "двоюродные сёстры родителей" + "schema": 37, + "order": 82, + "alias": "F65", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F55|nomn,plur}", + "term_resolved": "двоюродные тёти", + "term_forms": [], + "definition_formal": "[α∈X1] F48[F1[α]]", + "definition_raw": "@{F47|nomn,plur} @{D2|gent,plur}", + "definition_resolved": "двоюродные сёстры родителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 819, "fields": { - "schema": 37, - "order": 83, - "alias": "F66", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F58|nomn,plur}", - "term_resolved": "двоюродные племянники", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F41[α]]", - "definition_raw": "@{F20|nomn,plur} @{F41|gent,plur}", - "definition_resolved": "сыновья двоюродных сиблингов" + "schema": 37, + "order": 83, + "alias": "F66", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F58|nomn,plur}", + "term_resolved": "двоюродные племянники", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F41[α]]", + "definition_raw": "@{F20|nomn,plur} @{F41|gent,plur}", + "definition_resolved": "сыновья двоюродных сиблингов" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 820, "fields": { - "schema": 37, - "order": 84, - "alias": "F67", - "cst_type": "function", - "convention": "", - "term_raw": "дщеричи", - "term_resolved": "дщеричи", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F47[α]]", - "definition_raw": "@{F58|nomn,plur} по @{F55|datv,sing}", - "definition_resolved": "племянники по тёте" + "schema": 37, + "order": 84, + "alias": "F67", + "cst_type": "function", + "convention": "", + "term_raw": "дщеричи", + "term_resolved": "дщеричи", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F47[α]]", + "definition_raw": "@{F58|nomn,plur} по @{F55|datv,sing}", + "definition_resolved": "племянники по тёте" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 821, "fields": { - "schema": 37, - "order": 85, - "alias": "F68", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F61|nomn,plur}", - "term_resolved": "двоюродные племянницы", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F41[α]]", - "definition_raw": "@{F22|nomn,plur} @{F41|gent,plur}", - "definition_resolved": "дочери двоюродных сиблингов" + "schema": 37, + "order": 85, + "alias": "F68", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F61|nomn,plur}", + "term_resolved": "двоюродные племянницы", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F41[α]]", + "definition_raw": "@{F22|nomn,plur} @{F41|gent,plur}", + "definition_resolved": "дочери двоюродных сиблингов" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 822, "fields": { - "schema": 37, - "order": 86, - "alias": "F69", - "cst_type": "function", - "convention": "", - "term_raw": "дщерши", - "term_resolved": "дщерши", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F47[α]]", - "definition_raw": "@{F22|nomn,plur} @{F47|gent,plur}", - "definition_resolved": "дочери двоюродных сестёр" + "schema": 37, + "order": 86, + "alias": "F69", + "cst_type": "function", + "convention": "", + "term_raw": "дщерши", + "term_resolved": "дщерши", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F47[α]]", + "definition_raw": "@{F22|nomn,plur} @{F47|gent,plur}", + "definition_resolved": "дочери двоюродных сестёр" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 823, "fields": { - "schema": 37, - "order": 87, - "alias": "F70", - "cst_type": "function", - "convention": "альтернативное определение: великий дядя - дядя родителя", - "term_raw": "двоюродные @{F26|nomn,plur}", - "term_resolved": "двоюродные дедушки", - "term_forms": [], - "definition_formal": "[α∈X1] F29[F8[α]]", - "definition_raw": "@{F28|nomn,plur} @{F8|gent,plur}", - "definition_resolved": "братья прародителей" + "schema": 37, + "order": 87, + "alias": "F70", + "cst_type": "function", + "convention": "альтернативное определение: великий дядя - дядя родителя", + "term_raw": "двоюродные @{F26|nomn,plur}", + "term_resolved": "двоюродные дедушки", + "term_forms": [], + "definition_formal": "[α∈X1] F29[F8[α]]", + "definition_raw": "@{F28|nomn,plur} @{F8|gent,plur}", + "definition_resolved": "братья прародителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 824, "fields": { - "schema": 37, - "order": 88, - "alias": "F71", - "cst_type": "function", - "convention": "", - "term_raw": "двоюродные @{F27|nomn,plur}", - "term_resolved": "двоюродные бабушки", - "term_forms": [], - "definition_formal": "[α∈X1] F31[F8[α]]", - "definition_raw": "@{F30|nomn,plur} @{F8|gent,plur}", - "definition_resolved": "сёстры прародителей" + "schema": 37, + "order": 88, + "alias": "F71", + "cst_type": "function", + "convention": "", + "term_raw": "двоюродные @{F27|nomn,plur}", + "term_resolved": "двоюродные бабушки", + "term_forms": [], + "definition_formal": "[α∈X1] F31[F8[α]]", + "definition_raw": "@{F30|nomn,plur} @{F8|gent,plur}", + "definition_resolved": "сёстры прародителей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 825, "fields": { - "schema": 37, - "order": 89, - "alias": "F72", - "cst_type": "function", - "convention": "альтернативное определение: внук родного брата или сестры", - "term_raw": "внучатые @{F58|nomn,plur}", - "term_resolved": "внучатые племянники", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F58[α]∪F61[α]]", - "definition_raw": "@{F20|nomn,plur} @{F58|gent,plur} и @{F61|gent,plur}", - "definition_resolved": "сыновья племянников и племянниц" + "schema": 37, + "order": 89, + "alias": "F72", + "cst_type": "function", + "convention": "альтернативное определение: внук родного брата или сестры", + "term_raw": "внучатые @{F58|nomn,plur}", + "term_resolved": "внучатые племянники", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F58[α]∪F61[α]]", + "definition_raw": "@{F20|nomn,plur} @{F58|gent,plur} и @{F61|gent,plur}", + "definition_resolved": "сыновья племянников и племянниц" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 826, "fields": { - "schema": 37, - "order": 90, - "alias": "F73", - "cst_type": "function", - "convention": "", - "term_raw": "внучатые @{F61|nomn,plur}", - "term_resolved": "внучатые племянницы", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F58[α]∪F61[α]]", - "definition_raw": "@{F22|nomn,plur} @{F58|gent,plur} и @{F61|gent,plur}", - "definition_resolved": "дочери племянников и племянниц" + "schema": 37, + "order": 90, + "alias": "F73", + "cst_type": "function", + "convention": "", + "term_raw": "внучатые @{F61|nomn,plur}", + "term_resolved": "внучатые племянницы", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F58[α]∪F61[α]]", + "definition_raw": "@{F22|nomn,plur} @{F58|gent,plur} и @{F61|gent,plur}", + "definition_resolved": "дочери племянников и племянниц" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 827, "fields": { - "schema": 37, - "order": 91, - "alias": "F74", - "cst_type": "function", - "convention": "", - "term_raw": "свёкр", - "term_resolved": "свёкр", - "term_forms": [], - "definition_formal": "[α∈D4] F17[F9[α]]", - "definition_raw": "@{D6|nomn,sing} @{D3|gent,sing}", - "definition_resolved": "отец мужа" + "schema": 37, + "order": 91, + "alias": "F74", + "cst_type": "function", + "convention": "", + "term_raw": "свёкр", + "term_resolved": "свёкр", + "term_forms": [], + "definition_formal": "[α∈D4] F17[F9[α]]", + "definition_raw": "@{D6|nomn,sing} @{D3|gent,sing}", + "definition_resolved": "отец мужа" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 828, "fields": { - "schema": 37, - "order": 92, - "alias": "F75", - "cst_type": "function", - "convention": "", - "term_raw": "свекровь", - "term_resolved": "свекровь", - "term_forms": [], - "definition_formal": "[α∈D4] F18[F9[α]]", - "definition_raw": "@{D7|nomn,sing} @{D3|gent,sing}", - "definition_resolved": "мать мужа" + "schema": 37, + "order": 92, + "alias": "F75", + "cst_type": "function", + "convention": "", + "term_raw": "свекровь", + "term_resolved": "свекровь", + "term_forms": [], + "definition_formal": "[α∈D4] F18[F9[α]]", + "definition_raw": "@{D7|nomn,sing} @{D3|gent,sing}", + "definition_resolved": "мать мужа" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 829, "fields": { - "schema": 37, - "order": 93, - "alias": "F76", - "cst_type": "function", - "convention": "", - "term_raw": "тесть", - "term_resolved": "тесть", - "term_forms": [], - "definition_formal": "[α∈D3] F17[F10[α]]", - "definition_raw": "@{D6|nomn,sing} @{D4|gent,sing}", - "definition_resolved": "отец жены" + "schema": 37, + "order": 93, + "alias": "F76", + "cst_type": "function", + "convention": "", + "term_raw": "тесть", + "term_resolved": "тесть", + "term_forms": [], + "definition_formal": "[α∈D3] F17[F10[α]]", + "definition_raw": "@{D6|nomn,sing} @{D4|gent,sing}", + "definition_resolved": "отец жены" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 830, "fields": { - "schema": 37, - "order": 94, - "alias": "F77", - "cst_type": "function", - "convention": "", - "term_raw": "тёща", - "term_resolved": "тёща", - "term_forms": [], - "definition_formal": "[α∈D3] F18[F10[α]]", - "definition_raw": "@{D7|nomn,sing} @{D4|gent,sing}", - "definition_resolved": "мать жены" + "schema": 37, + "order": 94, + "alias": "F77", + "cst_type": "function", + "convention": "", + "term_raw": "тёща", + "term_resolved": "тёща", + "term_forms": [], + "definition_formal": "[α∈D3] F18[F10[α]]", + "definition_raw": "@{D7|nomn,sing} @{D4|gent,sing}", + "definition_resolved": "мать жены" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 831, "fields": { - "schema": 37, - "order": 95, - "alias": "F78", - "cst_type": "function", - "convention": "", - "term_raw": "сваты", - "term_resolved": "сваты", - "term_forms": [], - "definition_formal": "[α∈X1] F16[F13[F3[α]]]", - "definition_raw": "@{D6|nomn,plur} @{D5|gent,plur} @{D1|gent,plur}", - "definition_resolved": "отцы супругов детей" + "schema": 37, + "order": 95, + "alias": "F78", + "cst_type": "function", + "convention": "", + "term_raw": "сваты", + "term_resolved": "сваты", + "term_forms": [], + "definition_formal": "[α∈X1] F16[F13[F3[α]]]", + "definition_raw": "@{D6|nomn,plur} @{D5|gent,plur} @{D1|gent,plur}", + "definition_resolved": "отцы супругов детей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 832, "fields": { - "schema": 37, - "order": 96, - "alias": "F79", - "cst_type": "function", - "convention": "", - "term_raw": "сватьи", - "term_resolved": "сватьи", - "term_forms": [], - "definition_formal": "[α∈X1] F19[F13[F3[α]]]", - "definition_raw": "@{D7|gent,sing} @{D5|gent,plur} @{D1|gent,plur}", - "definition_resolved": "матери супругов детей" + "schema": 37, + "order": 96, + "alias": "F79", + "cst_type": "function", + "convention": "", + "term_raw": "сватьи", + "term_resolved": "сватьи", + "term_forms": [], + "definition_formal": "[α∈X1] F19[F13[F3[α]]]", + "definition_raw": "@{D7|gent,sing} @{D5|gent,plur} @{D1|gent,plur}", + "definition_resolved": "матери супругов детей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 833, "fields": { - "schema": 37, - "order": 97, - "alias": "F80", - "cst_type": "function", - "convention": "", - "term_raw": "девери", - "term_resolved": "девери", - "term_forms": [], - "definition_formal": "[α∈D4] F28[F9[α]]", - "definition_raw": "@{F28|nomn,plur} @{D3|gent,sing}", - "definition_resolved": "братья мужа" + "schema": 37, + "order": 97, + "alias": "F80", + "cst_type": "function", + "convention": "", + "term_raw": "девери", + "term_resolved": "девери", + "term_forms": [], + "definition_formal": "[α∈D4] F28[F9[α]]", + "definition_raw": "@{F28|nomn,plur} @{D3|gent,sing}", + "definition_resolved": "братья мужа" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 834, "fields": { - "schema": 37, - "order": 98, - "alias": "F81", - "cst_type": "function", - "convention": "", - "term_raw": "золовки", - "term_resolved": "золовки", - "term_forms": [], - "definition_formal": "[α∈D4] F30[F9[α]]", - "definition_raw": "@{F30|nomn,plur} @{D3|gent,sing}", - "definition_resolved": "сёстры мужа" + "schema": 37, + "order": 98, + "alias": "F81", + "cst_type": "function", + "convention": "", + "term_raw": "золовки", + "term_resolved": "золовки", + "term_forms": [], + "definition_formal": "[α∈D4] F30[F9[α]]", + "definition_raw": "@{F30|nomn,plur} @{D3|gent,sing}", + "definition_resolved": "сёстры мужа" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 835, "fields": { - "schema": 37, - "order": 99, - "alias": "F82", - "cst_type": "function", - "convention": "", - "term_raw": "шурины", - "term_resolved": "шурины", - "term_forms": [], - "definition_formal": "[α∈D3] F28[F10[α]]", - "definition_raw": "@{F28|nomn,plur} @{D4|gent,sing}", - "definition_resolved": "братья жены" + "schema": 37, + "order": 99, + "alias": "F82", + "cst_type": "function", + "convention": "", + "term_raw": "шурины", + "term_resolved": "шурины", + "term_forms": [], + "definition_formal": "[α∈D3] F28[F10[α]]", + "definition_raw": "@{F28|nomn,plur} @{D4|gent,sing}", + "definition_resolved": "братья жены" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 836, "fields": { - "schema": 37, - "order": 100, - "alias": "F83", - "cst_type": "function", - "convention": "", - "term_raw": "свояченицы", - "term_resolved": "свояченицы", - "term_forms": [], - "definition_formal": "[α∈D3] F30[F10[α]]", - "definition_raw": "@{F30|nomn,plur} @{D4|gent,sing}", - "definition_resolved": "сёстры жены" + "schema": 37, + "order": 100, + "alias": "F83", + "cst_type": "function", + "convention": "", + "term_raw": "свояченицы", + "term_resolved": "свояченицы", + "term_forms": [], + "definition_formal": "[α∈D3] F30[F10[α]]", + "definition_raw": "@{F30|nomn,plur} @{D4|gent,sing}", + "definition_resolved": "сёстры жены" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 837, "fields": { - "schema": 37, - "order": 101, - "alias": "F84", - "cst_type": "function", - "convention": "", - "term_raw": "шуричи", - "term_resolved": "шуричи", - "term_forms": [], - "definition_formal": "[α∈D3] F21[F82[α]]", - "definition_raw": "@{F20|nomn,plur} @{F82|gent,plur}", - "definition_resolved": "сыновья шуринов" + "schema": 37, + "order": 101, + "alias": "F84", + "cst_type": "function", + "convention": "", + "term_raw": "шуричи", + "term_resolved": "шуричи", + "term_forms": [], + "definition_formal": "[α∈D3] F21[F82[α]]", + "definition_raw": "@{F20|nomn,plur} @{F82|gent,plur}", + "definition_resolved": "сыновья шуринов" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 838, "fields": { - "schema": 37, - "order": 102, - "alias": "F85", - "cst_type": "function", - "convention": "", - "term_raw": "снохи", - "term_resolved": "снохи", - "term_forms": [], - "definition_formal": "[α∈X1] F12[F20[α]]", - "definition_raw": "@{D4|nomn,plur} @{F20|gent,plur}", - "definition_resolved": "жены сыновей" + "schema": 37, + "order": 102, + "alias": "F85", + "cst_type": "function", + "convention": "", + "term_raw": "снохи", + "term_resolved": "снохи", + "term_forms": [], + "definition_formal": "[α∈X1] F12[F20[α]]", + "definition_raw": "@{D4|nomn,plur} @{F20|gent,plur}", + "definition_resolved": "жены сыновей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 839, "fields": { - "schema": 37, - "order": 103, - "alias": "F86", - "cst_type": "function", - "convention": "", - "term_raw": "свояки", - "term_resolved": "свояки", - "term_forms": [], - "definition_formal": "[α∈D3] F11[F83[α]]", - "definition_raw": "@{D3|nomn,plur} @{F83|gent,plur}", - "definition_resolved": "мужья своячениц" + "schema": 37, + "order": 103, + "alias": "F86", + "cst_type": "function", + "convention": "", + "term_raw": "свояки", + "term_resolved": "свояки", + "term_forms": [], + "definition_formal": "[α∈D3] F11[F83[α]]", + "definition_raw": "@{D3|nomn,plur} @{F83|gent,plur}", + "definition_resolved": "мужья своячениц" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 840, "fields": { - "schema": 37, - "order": 104, - "alias": "F87", - "cst_type": "function", - "convention": "", - "term_raw": "ятровки", - "term_resolved": "ятровки", - "term_forms": [], - "definition_formal": "[α∈D4] F12[F80[α]]", - "definition_raw": "@{D4|nomn,plur} @{F80|gent,plur}", - "definition_resolved": "жены деверей" + "schema": 37, + "order": 104, + "alias": "F87", + "cst_type": "function", + "convention": "", + "term_raw": "ятровки", + "term_resolved": "ятровки", + "term_forms": [], + "definition_formal": "[α∈D4] F12[F80[α]]", + "definition_raw": "@{D4|nomn,plur} @{F80|gent,plur}", + "definition_resolved": "жены деверей" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 841, "fields": { - "schema": 37, - "order": 105, - "alias": "F88", - "cst_type": "function", - "convention": "", - "term_raw": "зятья", - "term_resolved": "зятья", - "term_forms": [], - "definition_formal": "[α∈X1] F11[F22[α]∪F30[α]∪F81[α]∪F61[α]]", - "definition_raw": "@{D3|nomn,plur} @{F22|gent,plur}, @{F30|gent,plur}, @{F81|gent,plur} или @{F61|gent,plur}", - "definition_resolved": "мужья дочерей, сестёр, золовок или племянниц" + "schema": 37, + "order": 105, + "alias": "F88", + "cst_type": "function", + "convention": "", + "term_raw": "зятья", + "term_resolved": "зятья", + "term_forms": [], + "definition_formal": "[α∈X1] F11[F22[α]∪F30[α]∪F81[α]∪F61[α]]", + "definition_raw": "@{D3|nomn,plur} @{F22|gent,plur}, @{F30|gent,plur}, @{F81|gent,plur} или @{F61|gent,plur}", + "definition_resolved": "мужья дочерей, сестёр, золовок или племянниц" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 842, "fields": { - "schema": 37, - "order": 106, - "alias": "F89", - "cst_type": "function", - "convention": "", - "term_raw": "невестки", - "term_resolved": "невестки", - "term_forms": [], - "definition_formal": "[α∈X1] F12[F20[α]∪F28[α]∪F80[α]∪F58[α]]", - "definition_raw": "@{D4|nomn,plur} @{F20|gent,plur}, @{F28|gent,plur}, @{F80|gent,plur} или @{F58|gent,plur}", - "definition_resolved": "жены сыновей, братьев, деверей или племянников" + "schema": 37, + "order": 106, + "alias": "F89", + "cst_type": "function", + "convention": "", + "term_raw": "невестки", + "term_resolved": "невестки", + "term_forms": [], + "definition_formal": "[α∈X1] F12[F20[α]∪F28[α]∪F80[α]∪F58[α]]", + "definition_raw": "@{D4|nomn,plur} @{F20|gent,plur}, @{F28|gent,plur}, @{F80|gent,plur} или @{F58|gent,plur}", + "definition_resolved": "жены сыновей, братьев, деверей или племянников" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 843, "fields": { - "schema": 37, - "order": 107, - "alias": "F90", - "cst_type": "function", - "convention": "", - "term_raw": "вуйки", - "term_resolved": "вуйки", - "term_forms": [], - "definition_formal": "[α∈X1] F12[F54[α]]", - "definition_raw": "@{D4|nomn,plur} @{F54|gent,plur}", - "definition_resolved": "жены вуи" + "schema": 37, + "order": 107, + "alias": "F90", + "cst_type": "function", + "convention": "", + "term_raw": "вуйки", + "term_resolved": "вуйки", + "term_forms": [], + "definition_formal": "[α∈X1] F12[F54[α]]", + "definition_raw": "@{D4|nomn,plur} @{F54|gent,plur}", + "definition_resolved": "жены вуи" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 844, "fields": { - "schema": 37, - "order": 108, - "alias": "F91", - "cst_type": "function", - "convention": "", - "term_raw": "братанихи", - "term_resolved": "братанихи", - "term_forms": [], - "definition_formal": "[α∈X1] F12[F45[α]]", - "definition_raw": "@{D4|nomn,plur} @{F45|gent,plur}", - "definition_resolved": "жены двоюродных братьев" + "schema": 37, + "order": 108, + "alias": "F91", + "cst_type": "function", + "convention": "", + "term_raw": "братанихи", + "term_resolved": "братанихи", + "term_forms": [], + "definition_formal": "[α∈X1] F12[F45[α]]", + "definition_raw": "@{D4|nomn,plur} @{F45|gent,plur}", + "definition_resolved": "жены двоюродных братьев" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 845, "fields": { - "schema": 37, - "order": 109, - "alias": "D9", - "cst_type": "term", - "convention": "", - "term_raw": "законные @{D1|nomn,plur}", - "term_resolved": "законные дети", - "term_forms": [], - "definition_formal": "D{ξ∈D1 | F13[F1[ξ]]=F1[ξ]}", - "definition_raw": "@{D1|nomn,plur}, @{D2|nomn,plur} которых состоят в @{S4|loct,sing}", - "definition_resolved": "дети, родители которых состоят в браке" + "schema": 37, + "order": 109, + "alias": "D9", + "cst_type": "term", + "convention": "", + "term_raw": "законные @{D1|nomn,plur}", + "term_resolved": "законные дети", + "term_forms": [], + "definition_formal": "D{ξ∈D1 | F13[F1[ξ]]=F1[ξ]}", + "definition_raw": "@{D1|nomn,plur}, @{D2|nomn,plur} которых состоят в @{S4|loct,sing}", + "definition_resolved": "дети, родители которых состоят в браке" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 846, "fields": { - "schema": 37, - "order": 110, - "alias": "D10", - "cst_type": "term", - "convention": "", - "term_raw": "бастарды", - "term_resolved": "бастарды", - "term_forms": [], - "definition_formal": "D1\\D9", - "definition_raw": "@{D1|nomn,plur}, @{D2|nomn,plur} которых не состоят в @{S4|loct,sing}", - "definition_resolved": "дети, родители которых не состоят в браке" + "schema": 37, + "order": 110, + "alias": "D10", + "cst_type": "term", + "convention": "", + "term_raw": "бастарды", + "term_resolved": "бастарды", + "term_forms": [], + "definition_formal": "D1\\D9", + "definition_raw": "@{D1|nomn,plur}, @{D2|nomn,plur} которых не состоят в @{S4|loct,sing}", + "definition_resolved": "дети, родители которых не состоят в браке" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 847, "fields": { - "schema": 37, - "order": 111, - "alias": "F92", - "cst_type": "function", - "convention": "", - "term_raw": "сводные @{F5|nomn,plur}", - "term_resolved": "сводные сиблинги", - "term_forms": [], - "definition_formal": "[α∈X1] F4[F13[F1[α]]] \\ F5[α] \\ {α}", - "definition_raw": "@{D1|nomn,plur} @{D5|gent,plur} @{D2|gent,plur}, не являющиеся @{F5|ablt,plur}", - "definition_resolved": "дети супругов родителей, не являющиеся сиблингами" + "schema": 37, + "order": 111, + "alias": "F92", + "cst_type": "function", + "convention": "", + "term_raw": "сводные @{F5|nomn,plur}", + "term_resolved": "сводные сиблинги", + "term_forms": [], + "definition_formal": "[α∈X1] F4[F13[F1[α]]] \\ F5[α] \\ {α}", + "definition_raw": "@{D1|nomn,plur} @{D5|gent,plur} @{D2|gent,plur}, не являющиеся @{F5|ablt,plur}", + "definition_resolved": "дети супругов родителей, не являющиеся сиблингами" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 848, "fields": { - "schema": 37, - "order": 112, - "alias": "F93", - "cst_type": "function", - "convention": "", - "term_raw": "сводные @{F28|nomn,plur}", - "term_resolved": "сводные братья", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F13[F1[α]]] \\ F28[α] \\ {α}", - "definition_raw": "@{F20|nomn,plur} @{D5|gent,plur} @{D2|gent,plur}, не являющиеся @{F28|ablt,plur}", - "definition_resolved": "сыновья супругов родителей, не являющиеся братьями" + "schema": 37, + "order": 112, + "alias": "F93", + "cst_type": "function", + "convention": "", + "term_raw": "сводные @{F28|nomn,plur}", + "term_resolved": "сводные братья", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F13[F1[α]]] \\ F28[α] \\ {α}", + "definition_raw": "@{F20|nomn,plur} @{D5|gent,plur} @{D2|gent,plur}, не являющиеся @{F28|ablt,plur}", + "definition_resolved": "сыновья супругов родителей, не являющиеся братьями" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 849, "fields": { - "schema": 37, - "order": 113, - "alias": "F94", - "cst_type": "function", - "convention": "", - "term_raw": "сводные @{F30|nomn,plur}", - "term_resolved": "сводные сёстры", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F13[F1[α]]] \\ F30[α] \\ {α}", - "definition_raw": "@{F22|nomn,plur} @{D5|gent,plur} @{D2|gent,plur}, не являющиеся @{F30|ablt,plur}", - "definition_resolved": "дочери супругов родителей, не являющиеся сёстрами" + "schema": 37, + "order": 113, + "alias": "F94", + "cst_type": "function", + "convention": "", + "term_raw": "сводные @{F30|nomn,plur}", + "term_resolved": "сводные сёстры", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F13[F1[α]]] \\ F30[α] \\ {α}", + "definition_raw": "@{F22|nomn,plur} @{D5|gent,plur} @{D2|gent,plur}, не являющиеся @{F30|ablt,plur}", + "definition_resolved": "дочери супругов родителей, не являющиеся сёстрами" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 850, "fields": { - "schema": 37, - "order": 114, - "alias": "F95", - "cst_type": "function", - "convention": "", - "term_raw": "пасынки", - "term_resolved": "пасынки", - "term_forms": [], - "definition_formal": "[α∈X1] F21[F13[{α}]] \\ F20[α]", - "definition_raw": "@{F20|nomn,plur} @{D5|gent,sing}, не являющиеся @{D1|ablt,plur}", - "definition_resolved": "сыновья супруга, не являющиеся детьми" + "schema": 37, + "order": 114, + "alias": "F95", + "cst_type": "function", + "convention": "", + "term_raw": "пасынки", + "term_resolved": "пасынки", + "term_forms": [], + "definition_formal": "[α∈X1] F21[F13[{α}]] \\ F20[α]", + "definition_raw": "@{F20|nomn,plur} @{D5|gent,sing}, не являющиеся @{D1|ablt,plur}", + "definition_resolved": "сыновья супруга, не являющиеся детьми" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 851, "fields": { - "schema": 37, - "order": 115, - "alias": "F96", - "cst_type": "function", - "convention": "", - "term_raw": "падчерицы", - "term_resolved": "падчерицы", - "term_forms": [], - "definition_formal": "[α∈X1] F23[F13[{α}]] \\ F22[α]", - "definition_raw": "@{F22|nomn,plur} @{D5|gent,sing}, не являющиеся @{D1|ablt,plur}", - "definition_resolved": "дочери супруга, не являющиеся детьми" + "schema": 37, + "order": 115, + "alias": "F96", + "cst_type": "function", + "convention": "", + "term_raw": "падчерицы", + "term_resolved": "падчерицы", + "term_forms": [], + "definition_formal": "[α∈X1] F23[F13[{α}]] \\ F22[α]", + "definition_raw": "@{F22|nomn,plur} @{D5|gent,sing}, не являющиеся @{D1|ablt,plur}", + "definition_resolved": "дочери супруга, не являющиеся детьми" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 852, "fields": { - "schema": 37, - "order": 116, - "alias": "F97", - "cst_type": "function", - "convention": "", - "term_raw": "отчимы", - "term_resolved": "отчимы", - "term_forms": [], - "definition_formal": "[α∈X1] F11[F19[{α}]] \\ F16[{α}]", - "definition_raw": "@{D3|nomn,sing} @{D7|gent,sing}, не являющийся @{D6|ablt,sing}", - "definition_resolved": "муж матери, не являющийся отцом" + "schema": 37, + "order": 116, + "alias": "F97", + "cst_type": "function", + "convention": "", + "term_raw": "отчимы", + "term_resolved": "отчимы", + "term_forms": [], + "definition_formal": "[α∈X1] F11[F19[{α}]] \\ F16[{α}]", + "definition_raw": "@{D3|nomn,sing} @{D7|gent,sing}, не являющийся @{D6|ablt,sing}", + "definition_resolved": "муж матери, не являющийся отцом" } -}, -{ + }, + { "model": "rsform.constituenta", "pk": 853, "fields": { - "schema": 37, - "order": 117, - "alias": "F98", - "cst_type": "function", - "convention": "", - "term_raw": "мачехи", - "term_resolved": "мачехи", - "term_forms": [], - "definition_formal": "[α∈X1] F12[F16[{α}]] \\ F19[{α}]", - "definition_raw": "@{D4|nomn,sing} @{D6|gent,sing}, не являющаяся @{D7|ablt,sing}", - "definition_resolved": "жена отца, не являющаяся матерью" + "schema": 37, + "order": 117, + "alias": "F98", + "cst_type": "function", + "convention": "", + "term_raw": "мачехи", + "term_resolved": "мачехи", + "term_forms": [], + "definition_formal": "[α∈X1] F12[F16[{α}]] \\ F19[{α}]", + "definition_raw": "@{D4|nomn,sing} @{D6|gent,sing}, не являющаяся @{D7|ablt,sing}", + "definition_resolved": "жена отца, не являющаяся матерью" } -}, -{ - "model": "rsform.editor", + }, + { + "model": "library.editor", "pk": 2, "fields": { - "item": 35, - "editor": 3, - "time_create": "2024-06-03T20:55:45.359Z" + "item": 35, + "editor": 3, + "time_create": "2024-06-03T20:55:45.359Z" } -}, -{ - "model": "rsform.subscription", + }, + { + "model": "library.subscription", "pk": 11, "fields": { - "user": 1, - "item": 34 + "user": 1, + "item": 34 } -}, -{ - "model": "rsform.subscription", + }, + { + "model": "library.subscription", "pk": 12, "fields": { - "user": 5, - "item": 35 + "user": 5, + "item": 35 } -}, -{ - "model": "rsform.subscription", + }, + { + "model": "library.subscription", "pk": 13, "fields": { - "user": 3, - "item": 36 + "user": 3, + "item": 36 } -}, -{ - "model": "rsform.subscription", + }, + { + "model": "library.subscription", "pk": 14, "fields": { - "user": 3, - "item": 37 + "user": 3, + "item": 37 } -}, -{ - "model": "rsform.libraryitem", + }, + { + "model": "library.libraryitem", "pk": 34, "fields": { - "item_type": "rsform", - "owner": 1, - "title": "Банк выражений", - "alias": "БВ", - "comment": "Банк шаблонов для генерации выражений", - "visible": true, - "read_only": false, - "access_policy": "public", - "location": "/L", - "time_create": "2024-06-03T20:52:06.322Z", - "time_update": "2024-06-03T20:52:06.325Z" + "item_type": "rsform", + "owner": 1, + "title": "Банк выражений", + "alias": "БВ", + "comment": "Банк шаблонов для генерации выражений", + "visible": true, + "read_only": false, + "access_policy": "public", + "location": "/L", + "time_create": "2024-06-03T20:52:06.322Z", + "time_update": "2024-06-03T20:52:06.325Z" } -}, -{ - "model": "rsform.libraryitem", + }, + { + "model": "library.libraryitem", "pk": 35, "fields": { - "item_type": "rsform", - "owner": 5, - "title": "Групповая операция", - "alias": "БК09", - "comment": "", - "visible": true, - "read_only": false, - "access_policy": "public", - "location": "/S", - "time_create": "2024-06-03T20:55:36.489Z", - "time_update": "2024-06-03T20:55:36.492Z" + "item_type": "rsform", + "owner": 5, + "title": "Групповая операция", + "alias": "БК09", + "comment": "", + "visible": true, + "read_only": false, + "access_policy": "public", + "location": "/S", + "time_create": "2024-06-03T20:55:36.489Z", + "time_update": "2024-06-03T20:55:36.492Z" } -}, -{ - "model": "rsform.libraryitem", + }, + { + "model": "library.libraryitem", "pk": 36, "fields": { - "item_type": "rsform", - "owner": 3, - "title": "Булева алгебра", - "alias": "БК12", - "comment": "", - "visible": true, - "read_only": false, - "access_policy": "public", - "location": "/S", - "time_create": "2024-06-03T20:58:30.529Z", - "time_update": "2024-06-03T20:58:32.512Z" + "item_type": "rsform", + "owner": 3, + "title": "Булева алгебра", + "alias": "БК12", + "comment": "", + "visible": true, + "read_only": false, + "access_policy": "public", + "location": "/S", + "time_create": "2024-06-03T20:58:30.529Z", + "time_update": "2024-06-03T20:58:32.512Z" } -}, -{ - "model": "rsform.libraryitem", + }, + { + "model": "library.libraryitem", "pk": 37, "fields": { - "item_type": "rsform", - "owner": 3, - "title": "Генеалогия", - "alias": "D0001", - "comment": "построено на основе понятия \"родство\" из Википедии", - "visible": true, - "read_only": false, - "access_policy": "public", - "location": "/U/test", - "time_create": "2024-06-03T20:59:40.845Z", - "time_update": "2024-06-03T21:00:01.809Z" + "item_type": "rsform", + "owner": 3, + "title": "Генеалогия", + "alias": "D0001", + "comment": "построено на основе понятия \"родство\" из Википедии", + "visible": true, + "read_only": false, + "access_policy": "public", + "location": "/U/test", + "time_create": "2024-06-03T20:59:40.845Z", + "time_update": "2024-06-03T21:00:01.809Z" } -}, -{ - "model": "rsform.librarytemplate", + }, + { + "model": "library.librarytemplate", "pk": 1, "fields": { - "lib_source": 34 + "lib_source": 34 } -} + } ] diff --git a/rsconcept/backend/project/settings.py b/rsconcept/backend/project/settings.py index 99233be4..32e1d5e6 100644 --- a/rsconcept/backend/project/settings.py +++ b/rsconcept/backend/project/settings.py @@ -73,6 +73,7 @@ INSTALLED_APPS = [ 'corsheaders', 'apps.users', + 'apps.library', 'apps.rsform', 'apps.oss', diff --git a/rsconcept/backend/project/urls.py b/rsconcept/backend/project/urls.py index c6c2aa7e..30314095 100644 --- a/rsconcept/backend/project/urls.py +++ b/rsconcept/backend/project/urls.py @@ -8,6 +8,7 @@ from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, Spec urlpatterns = [ path('admin', admin.site.urls), + path('api/', include('apps.library.urls')), path('api/', include('apps.rsform.urls')), path('api/', include('apps.oss.urls')), path('users/', include('apps.users.urls')), diff --git a/rsconcept/backend/shared/EndpointTester.py b/rsconcept/backend/shared/EndpointTester.py index 0f0a6b63..27780aa9 100644 --- a/rsconcept/backend/shared/EndpointTester.py +++ b/rsconcept/backend/shared/EndpointTester.py @@ -2,7 +2,7 @@ from rest_framework import status from rest_framework.test import APIClient, APIRequestFactory, APITestCase -from apps.rsform.models import Editor, LibraryItem +from apps.library.models import Editor, LibraryItem from apps.users.models import User diff --git a/rsconcept/backend/shared/permissions.py b/rsconcept/backend/shared/permissions.py index 87726c4d..d6490dd1 100644 --- a/rsconcept/backend/shared/permissions.py +++ b/rsconcept/backend/shared/permissions.py @@ -11,15 +11,9 @@ from rest_framework.permissions import \ from rest_framework.request import Request from rest_framework.views import APIView +from apps.library.models import AccessPolicy, Editor, LibraryItem, Subscription, Version from apps.oss.models import Operation -from apps.rsform.models import ( - AccessPolicy, - Constituenta, - Editor, - LibraryItem, - Subscription, - Version -) +from apps.rsform.models import Constituenta from apps.users.models import User diff --git a/rsconcept/backend/shared/testing_utils.py b/rsconcept/backend/shared/testing_utils.py index 637b2032..d39d2252 100644 --- a/rsconcept/backend/shared/testing_utils.py +++ b/rsconcept/backend/shared/testing_utils.py @@ -1,6 +1,6 @@ ''' Utilities for testing. ''' -from apps.rsform.models import LibraryItem +from apps.library.models import LibraryItem def response_contains(response, item: LibraryItem) -> bool: diff --git a/rsconcept/backend/shared/utility.py b/rsconcept/backend/shared/utility.py new file mode 100644 index 00000000..5591f095 --- /dev/null +++ b/rsconcept/backend/shared/utility.py @@ -0,0 +1,21 @@ +''' Utility functions. ''' +import json +from io import BytesIO +from zipfile import ZipFile + + +def read_zipped_json(data, json_filename: str) -> dict: + ''' Read JSON from zipped data ''' + with ZipFile(data, 'r') as archive: + json_data = archive.read(json_filename) + result: dict = json.loads(json_data) + return result + + +def write_zipped_json(json_data: dict, json_filename: str) -> bytes: + ''' Write json JSON to bytes buffer ''' + content = BytesIO() + data = json.dumps(json_data, indent=4, ensure_ascii=False) + with ZipFile(content, 'w') as archive: + archive.writestr(json_filename, data=data) + return content.getvalue() diff --git a/rsconcept/frontend/src/backend/library.ts b/rsconcept/frontend/src/backend/library.ts index b75aac44..a836053e 100644 --- a/rsconcept/frontend/src/backend/library.ts +++ b/rsconcept/frontend/src/backend/library.ts @@ -7,9 +7,10 @@ import { ILibraryItem, ILibraryUpdateData, ITargetAccessPolicy, - ITargetLocation + ITargetLocation, + IVersionData } from '@/models/library'; -import { IRSFormCloneData, IRSFormData } from '@/models/rsform'; +import { IRSFormCloneData, IRSFormData, IVersionCreatedResponse } from '@/models/rsform'; import { ITargetUser, ITargetUsers } from '@/models/user'; import { @@ -113,3 +114,10 @@ export function deleteUnsubscribe(target: string, request: FrontAction) { request: request }); } + +export function postCreateVersion(target: string, request: FrontExchange) { + AxiosPost({ + endpoint: `/api/library/${target}/create-version`, + request: request + }); +} diff --git a/rsconcept/frontend/src/backend/rsforms.ts b/rsconcept/frontend/src/backend/rsforms.ts index ce06313b..51e198d6 100644 --- a/rsconcept/frontend/src/backend/rsforms.ts +++ b/rsconcept/frontend/src/backend/rsforms.ts @@ -2,7 +2,7 @@ * Endpoints: rsforms. */ -import { ILibraryCreateData, ILibraryItem, IVersionData } from '@/models/library'; +import { ILibraryCreateData, ILibraryItem } from '@/models/library'; import { ICstSubstituteData } from '@/models/oss'; import { IConstituentaList, @@ -13,8 +13,7 @@ import { IProduceStructureResponse, IRSFormData, IRSFormUploadData, - ITargetCst, - IVersionCreatedResponse + ITargetCst } from '@/models/rsform'; import { IExpressionParse, IRSExpression } from '@/models/rslang'; @@ -40,7 +39,7 @@ export function getRSFormDetails(target: string, version: string, request: Front }); } else { AxiosGet({ - endpoint: `/api/rsforms/${target}/versions/${version}`, + endpoint: `/api/library/${target}/versions/${version}`, request: request }); } @@ -136,10 +135,3 @@ export function patchUploadTRS(target: string, request: FrontExchange) { - AxiosPost({ - endpoint: `/api/rsforms/${target}/versions/create`, - request: request - }); -} diff --git a/rsconcept/frontend/src/context/RSFormContext.tsx b/rsconcept/frontend/src/context/RSFormContext.tsx index 8a59b910..a9a76a24 100644 --- a/rsconcept/frontend/src/context/RSFormContext.tsx +++ b/rsconcept/frontend/src/context/RSFormContext.tsx @@ -11,6 +11,7 @@ import { patchSetEditors, patchSetLocation, patchSetOwner, + postCreateVersion, postSubscribe } from '@/backend/library'; import { patchInlineSynthesis } from '@/backend/operations'; @@ -24,8 +25,7 @@ import { patchRestoreOrder, patchSubstituteConstituents, patchUploadTRS, - postCreateConstituenta, - postCreateVersion + postCreateConstituenta } from '@/backend/rsforms'; import { deleteVersion, patchRestoreVersion, patchVersion } from '@/backend/versions'; import { type ErrorData } from '@/components/info/InfoError';