Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions doc/relations-model-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -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": "<relation-controller>",
"$obj": "<object-model>",
"$sub": "<subject-view>"
}
```

**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": "<relation>",
"$sub": "<subject>",
"$obj": "<object>"
"<<": "<relation-controller>",
">>": {
"<<": "<object-model>",
">>": "<subject-view>"
}
}
```

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:
Expand Down
34 changes: 30 additions & 4 deletions doc/relations-model-ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. Заключение

Математическая формализация Модели Отношений в терминах теории множеств показывает, что:
Expand Down
26 changes: 26 additions & 0 deletions examples/ordered_pair_format.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"_comment": "Example of ordered pair format (<</>>) for Relations Model",
"_description": "Demonstrates ent = (rel, (obj, sub)) representation",
"_format": {
"<<": "<relation-controller>",
">>": {
"<<": "<object-model>",
">>": "<subject-view>"
}
},
"_equivalent_old_format": {
"$rel": "<relation-controller>",
"$obj": "<object-model>",
"$sub": "<subject-view>"
},
"version_example": {
"<<": "rmvm/version"
},
"addition_example": {
"<<": "+",
">>": {
"<<": 1,
">>": 1
}
}
}
29 changes: 29 additions & 0 deletions modules/common/include/vm.rm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<rval>($, *obj_ptr) : $.rel,
sub_ptr ? val_or_ref_to<lval>($, *sub_ptr) : $.rel,
ent,
$);
exec_ent(ctx, val_or_ref_to<rval>($, *relop));
}
catch (json &j)
{
throw json({{"<<"s, j}});
}
}
else
{ // контроллер это лямбда структура, которая управляет параллельным проецированием сущностей
auto it = ent.begin();
Expand Down
56 changes: 56 additions & 0 deletions modules/console/test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<json&>(root);
in >> root_json[""];

vm_ctx $(res, root_json[""]);
root.exec_ent($, root_json[""]);
cout << res.dump(2) << endl;
CHECK(res.get_ref<string&>() == "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<json&>(root);
in >> root_json[""];

vm_ctx $(res, root_json[""]);
root.exec_ent($, root_json[""]);
cout << res.dump(2) << endl;
CHECK(res[0].get_ref<string&>() == "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("./");
Expand Down
3 changes: 3 additions & 0 deletions modules/console/test/ordered_pair_format.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"<<": "rmvm/version"
}
12 changes: 12 additions & 0 deletions modules/console/test/ordered_pair_format_where.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"<<": "where",
">>": {
"<<": [ null, 2, false, "4", {} ],
">>": {
"<<": "is_string",
">>": {
"<<": {"$ref": "$obj"}
}
}
}
}