diff --git a/doc/relations-model-en.md b/doc/relations-model-en.md index 5af4d783..f3fc721c 100644 --- a/doc/relations-model-en.md +++ b/doc/relations-model-en.md @@ -251,16 +251,42 @@ The structure of the Relations Model is fractal: each entity contains three othe ### 7.2. Executable Constructs -An entity in JSON representation is defined by an object with fields: +An entity in JSON representation can be defined using two equivalent formats. + +**Format 1: Expanded notation (named fields)** + +```json +{ + "$rel": "", + "$obj": "", + "$sub": "" +} +``` + +**Format 2: Compact notation using ordered pairs (ordered pair format)** + +Based on the mathematical representation of a triplet as nested ordered pairs: +`ent = (rel, (obj, sub))` ```json { - "$rel": "", - "$sub": "", - "$obj": "" + "<<": "", + ">>": { + "<<": "", + ">>": "" + } } ``` +Field correspondence between formats: +| Format 1 | Format 2 | Role | +|----------|----------|------| +| `$rel` | `<<` | Relation-controller (Controller) | +| `$obj` | `>>/<<` | Object-model (Model) | +| `$sub` | `>>/>>` | Subject-view (View) | + +Note: in Format 2, the value of `>>` is an ordered pair `(obj, sub)`. If the `>>` field is absent or not an object, the object and subject are inherited from the parent context. + ## 8. Conclusion The mathematical formalization of the Relations Model in terms of set theory shows that: diff --git a/doc/relations-model-ru.md b/doc/relations-model-ru.md index ff7ff203..fb750465 100644 --- a/doc/relations-model-ru.md +++ b/doc/relations-model-ru.md @@ -251,16 +251,42 @@ anetl : L → NP ### 7.2. Исполняемые конструкции -Сущность в JSON-представлении определяется объектом с полями: +Сущность в JSON-представлении может быть задана двумя эквивалентными форматами. + +**Формат 1: Расширенная запись (с именованными полями)** + +```json +{ + "$rel": "<отношение-контроллер>", + "$obj": "<объект-модель>", + "$sub": "<субъект-представление>" +} +``` + +**Формат 2: Компактная запись через упорядоченные пары (ordered pair format)** + +Основан на математическом представлении триплета как вложенных упорядоченных пар: +`ent = (rel, (obj, sub))` ```json { - "$rel": "<отношение>", - "$sub": "<субъект>", - "$obj": "<объект>" + "<<": "<отношение-контроллер>", + ">>": { + "<<": "<объект-модель>", + ">>": "<субъект-представление>" + } } ``` +Соответствие полей между форматами: +| Формат 1 | Формат 2 | Роль | +|----------|----------|------| +| `$rel` | `<<` | Отношение-контроллер (Controller) | +| `$obj` | `>>/<<` | Объект-модель (Model) | +| `$sub` | `>>/>>` | Субъект-представление (View) | + +Примечание: в формате 2 значение `>>` является упорядоченной парой `(obj, sub)`. Если поле `>>` отсутствует или не является объектом, объект и субъект остаются унаследованными из родительского контекста. + ## 8. Заключение Математическая формализация Модели Отношений в терминах теории множеств показывает, что: diff --git a/examples/ordered_pair_format.json b/examples/ordered_pair_format.json new file mode 100644 index 00000000..4f86c72f --- /dev/null +++ b/examples/ordered_pair_format.json @@ -0,0 +1,26 @@ +{ + "_comment": "Example of ordered pair format (<>) for Relations Model", + "_description": "Demonstrates ent = (rel, (obj, sub)) representation", + "_format": { + "<<": "", + ">>": { + "<<": "", + ">>": "" + } + }, + "_equivalent_old_format": { + "$rel": "", + "$obj": "", + "$sub": "" + }, + "version_example": { + "<<": "rmvm/version" + }, + "addition_example": { + "<<": "+", + ">>": { + "<<": 1, + ">>": 1 + } + } +} diff --git a/modules/common/include/vm.rm.h b/modules/common/include/vm.rm.h index 6e6f0117..883558d3 100644 --- a/modules/common/include/vm.rm.h +++ b/modules/common/include/vm.rm.h @@ -567,6 +567,35 @@ namespace rm throw json({{"$rel"s, j}}); } } + else if (auto relop = ent.find("<<"); relop != end) + { // ordered pair format: ent = (rel, (obj, sub)) + // "<<" = relation (controller), ">>" = { "<<": obj (model), ">>": sub (view) } + json *obj_ptr = nullptr; + json *sub_ptr = nullptr; + + if (auto duplet = ent.find(">>"); duplet != end && duplet->is_object()) + { + if (auto obj_it = duplet->find("<<"); obj_it != duplet->end()) + obj_ptr = &(*obj_it); + if (auto sub_it = duplet->find(">>"); sub_it != duplet->end()) + sub_ptr = &(*sub_it); + } + + try + { + vm_ctx ctx( + $.rel, + obj_ptr ? val_or_ref_to($, *obj_ptr) : $.rel, + sub_ptr ? val_or_ref_to($, *sub_ptr) : $.rel, + ent, + $); + exec_ent(ctx, val_or_ref_to($, *relop)); + } + catch (json &j) + { + throw json({{"<<"s, j}}); + } + } else { // контроллер это лямбда структура, которая управляет параллельным проецированием сущностей auto it = ent.begin(); diff --git a/modules/console/test/main.cpp b/modules/console/test/main.cpp index aaa60d59..50380140 100644 --- a/modules/console/test/main.cpp +++ b/modules/console/test/main.cpp @@ -197,6 +197,62 @@ TEST_CASE("testing base entity 'where'") { } +TEST_CASE("testing ordered pair format (<>) - version") { + MESSAGE("result:"); + file_database_t db("./"); + vm root(&db); + // base vocabulary + import_relations_model_to(root); + json res; + const char* fileNameInput = "ordered_pair_format.json"; + + try + { + std::ifstream in(fileNameInput); + REQUIRE(in.good()); + json& root_json = static_cast(root); + in >> root_json[""]; + + vm_ctx $(res, root_json[""]); + root.exec_ent($, root_json[""]); + cout << res.dump(2) << endl; + CHECK(res.get_ref() == "3.0.0"s); + } + catch (json& j) { throw json({ { __func__, j } }); } + catch (json::exception& e) { throw json({ { __func__, "json::exception: "s + e.what() + ", id: "s + to_string(e.id) } }); } + catch (std::exception& e) { throw json({ { __func__, "std::exception: "s + e.what() } }); } + catch (...) { throw json({ { __func__, "unknown exception"s } }); } +} + + +TEST_CASE("testing ordered pair format (<>) - where filter") { + MESSAGE("result:"); + file_database_t db("./"); + vm root(&db); + // base vocabulary + import_relations_model_to(root); + json res; + const char* fileNameInput = "ordered_pair_format_where.json"; + + try + { + std::ifstream in(fileNameInput); + REQUIRE(in.good()); + json& root_json = static_cast(root); + in >> root_json[""]; + + vm_ctx $(res, root_json[""]); + root.exec_ent($, root_json[""]); + cout << res.dump(2) << endl; + CHECK(res[0].get_ref() == "4"s); + } + catch (json& j) { throw json({ { __func__, j } }); } + catch (json::exception& e) { throw json({ { __func__, "json::exception: "s + e.what() + ", id: "s + to_string(e.id) } }); } + catch (std::exception& e) { throw json({ { __func__, "std::exception: "s + e.what() } }); } + catch (...) { throw json({ { __func__, "unknown exception"s } }); } +} + + TEST_CASE("performance test") { MESSAGE("result:"); file_database_t db("./"); diff --git a/modules/console/test/ordered_pair_format.json b/modules/console/test/ordered_pair_format.json new file mode 100644 index 00000000..3e674ce5 --- /dev/null +++ b/modules/console/test/ordered_pair_format.json @@ -0,0 +1,3 @@ +{ + "<<": "rmvm/version" +} diff --git a/modules/console/test/ordered_pair_format_where.json b/modules/console/test/ordered_pair_format_where.json new file mode 100644 index 00000000..b3927caa --- /dev/null +++ b/modules/console/test/ordered_pair_format_where.json @@ -0,0 +1,12 @@ +{ + "<<": "where", + ">>": { + "<<": [ null, 2, false, "4", {} ], + ">>": { + "<<": "is_string", + ">>": { + "<<": {"$ref": "$obj"} + } + } + } +}