From 5531cb72ba963a41d243832afefa8baee703ff97 Mon Sep 17 00:00:00 2001 From: konard Date: Fri, 6 Feb 2026 21:16:03 +0100 Subject: [PATCH 1/3] Initial commit with task details Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/netkeep80/avm/issues/21 --- CLAUDE.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..db1a576 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +Issue to solve: https://github.com/netkeep80/avm/issues/21 +Your prepared branch: issue-21-9aa1aab34bc9 +Your prepared working directory: /tmp/gh-issue-solver-1770408958092 +Your forked repository: konard/netkeep80-avm +Original repository (upstream): netkeep80/avm + +Proceed. From b705f4fbb6a8b093876b106659d034a98e7cf800 Mon Sep 17 00:00:00 2001 From: konard Date: Fri, 6 Feb 2026 21:25:12 +0100 Subject: [PATCH 2/3] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80?= =?UTF-8?q?=D1=82=D0=BD=D0=BE=D0=B9=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE?= =?UTF-8?q?=D1=82=D0=B5=D0=BA=D0=B8=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D1=81=D0=BA=D0=B8=D1=85=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B8=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B8=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D0=B8=20=D0=B4=D0=BE=200.0.6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- CMakeLists.txt | 2 +- README.md | 46 +++++++-- analysis.md | 11 ++- include/avm.h | 112 +++++++++++++++++++-- plan.md | 7 +- src/main.cpp | 20 +++- test/expr_eq.json | 1 + test/expr_implies.json | 1 + test/expr_nand.json | 1 + test/expr_nor.json | 1 + test/expr_xor.json | 1 + test/unit_test.cpp | 214 ++++++++++++++++++++++++++++++++++++++++- 12 files changed, 391 insertions(+), 26 deletions(-) create mode 100644 test/expr_eq.json create mode 100644 test/expr_implies.json create mode 100644 test/expr_nand.json create mode 100644 test/expr_nor.json create mode 100644 test/expr_xor.json diff --git a/CMakeLists.txt b/CMakeLists.txt index b6d0c34..175b650 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) message( "Configuring: ${CMAKE_CURRENT_SOURCE_DIR}") -set(CMAKE_PROJECT_VERSION 0.0.5 ) +set(CMAKE_PROJECT_VERSION 0.0.6 ) # Project name project( avm diff --git a/README.md b/README.md index f26f6ac..6018017 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ The Associative Relations Model (ARM) is a mathematical model for storing and pr - Support for structured data (arrays and associative arrays) - JSON serialization/deserialization (null, boolean, array, number, string, object) - Logical operations (NOT, AND, OR) defined as truth tables in entity maps +- Standard library of logical operations (XOR, NAND, NOR, Implies, Eq) as truth tables - Conditional construct `If` with lazy evaluation of then/else branches - Recursive functions via `Def`/`Call` with named parameters and recursion depth protection - Relative addressing operator `[]` for evaluating functions via `eval()` @@ -52,17 +53,18 @@ The Associative Relations Model (ARM) is a mathematical model for storing and pr ### Current Status -**Version: 0.0.5** (Alpha) +**Version: 0.0.6** (Alpha) Implemented: - JSON null, boolean, array, number (unsigned, integer, float), string, object serialization/deserialization -- Base vocabulary initialization (R, E, True, False, Unsigned, Integer, Float, String, Object, Not, And, Or, If, Def, Call) +- Base vocabulary initialization (R, E, True, False, Unsigned, Integer, Float, String, Object, Not, And, Or, If, Def, Call, Xor, Nand, Nor, Implies, Eq) - Logical operations NOT, AND, OR with truth tables via entity map +- Standard library: XOR, NAND, NOR, Implies (a → b), Eq (a ↔ b) with truth tables via entity map - Conditional construct If with lazy evaluation (e.g. `{"If": [true, "yes", "no"]}` → `"yes"`) - Recursive functions via Def/Call (e.g. `[{"Def": ["f", ["x"], body]}, {"Call": ["f", arg]}]`) - Relative addressing operator `[]` via `eval()` function for computing logical functions - Expression interpreter for evaluating logical, conditional and recursive expressions from JSON -- 179 unit tests + 16 JSON roundtrip tests +- 240 unit tests + 16 JSON roundtrip tests - CI/CD pipeline (GitHub Actions) for Linux, macOS, Windows In Progress: @@ -127,6 +129,21 @@ echo '[{"Def": ["myNot", ["x"], {"Not": ["x"]}]}, {"Call": ["myNot", true]}]' > cat res.json # false ``` +Standard library operations (XOR, NAND, NOR, Implies, Eq): +```bash +echo '{"Xor": [true, false]}' > xor.json +./avm xor.json +cat res.json # true + +echo '{"Implies": [true, false]}' > imp.json +./avm imp.json +cat res.json # false + +echo '{"Eq": [true, true]}' > eq.json +./avm eq.json +cat res.json # true +``` + ### Dependencies - C++20 compatible compiler @@ -173,6 +190,7 @@ AVM (Associative Virtual Machine) — проект, реализующий ви - Поддержка структурированных данных (массивы и ассоциативные массивы) - Сериализация/десериализация JSON (null, boolean, array, number, string, object) - Логические операции (NOT, AND, OR), определённые как таблицы истинности в entity map +- Стандартная библиотека логических операций (XOR, NAND, NOR, Implies, Eq) как таблицы истинности - Условная конструкция `If` с ленивым вычислением веток then/else - Рекурсивные функции через `Def`/`Call` с именованными параметрами и защитой от бесконечной рекурсии - Оператор относительной адресации `[]` для вычисления функций через `eval()` @@ -182,17 +200,18 @@ AVM (Associative Virtual Machine) — проект, реализующий ви ### Текущее состояние -**Версия: 0.0.5** (Альфа) +**Версия: 0.0.6** (Альфа) Реализовано: - Сериализация/десериализация JSON null, boolean, array, number (unsigned, integer, float), string, object -- Инициализация базового словаря (R, E, True, False, Unsigned, Integer, Float, String, Object, Not, And, Or, If, Def, Call) +- Инициализация базового словаря (R, E, True, False, Unsigned, Integer, Float, String, Object, Not, And, Or, If, Def, Call, Xor, Nand, Nor, Implies, Eq) - Логические операции NOT, AND, OR с таблицами истинности через entity map +- Стандартная библиотека: XOR, NAND, NOR, Implies (a → b), Eq (a ↔ b) с таблицами истинности - Условная конструкция If с ленивым вычислением (например `{"If": [true, "да", "нет"]}` → `"да"`) - Рекурсивные функции через Def/Call (например `[{"Def": ["f", ["x"], тело]}, {"Call": ["f", арг]}]`) - Оператор относительной адресации `[]` через функцию `eval()` для вычисления логических функций - Интерпретатор выражений для вычисления логических, условных и рекурсивных выражений из JSON -- 179 модульных тестов + 16 JSON roundtrip тестов +- 240 модульных тестов + 16 JSON roundtrip тестов - CI/CD пайплайн (GitHub Actions) для Linux, macOS, Windows В разработке: @@ -257,6 +276,21 @@ echo '[{"Def": ["myNot", ["x"], {"Not": ["x"]}]}, {"Call": ["myNot", true]}]' > cat res.json # false ``` +Операции стандартной библиотеки (XOR, NAND, NOR, Implies, Eq): +```bash +echo '{"Xor": [true, false]}' > xor.json +./avm xor.json +cat res.json # true + +echo '{"Implies": [true, false]}' > imp.json +./avm imp.json +cat res.json # false + +echo '{"Eq": [true, true]}' > eq.json +./avm eq.json +cat res.json # true +``` + ### Зависимости - Компилятор с поддержкой C++20 diff --git a/analysis.md b/analysis.md index 0c4a809..5279d51 100644 --- a/analysis.md +++ b/analysis.md @@ -132,8 +132,8 @@ AVM (Associative Virtual Machine) — это проект, реализующи | Заголовочный файл | ~473 строки (avm.h) | | Внешние зависимости | nlohmann/json, LinksPlatform, str_switch | | Лицензия | MIT | -| Unit-тесты | 179 модульных тестов | -| Тестовые файлы | 27 JSON файлов | +| Unit-тесты | 240 модульных тестов | +| Тестовые файлы | 32 JSON файла | --- @@ -142,9 +142,9 @@ AVM (Associative Virtual Machine) — это проект, реализующи Проект находится на стадии альфа-версии: - **Концепция**: Хорошо проработана теоретически -- **Реализация**: JSON roundtrip полностью работает, логические операции реализованы, интерпретатор выражений работает, условная конструкция If с ленивым вычислением, рекурсивные функции через Def/Call +- **Реализация**: JSON roundtrip полностью работает, логические операции реализованы, интерпретатор выражений работает, условная конструкция If с ленивым вычислением, рекурсивные функции через Def/Call, стандартная библиотека (XOR, NAND, NOR, Implies, Eq) - **Документация**: Двуязычная документация, описание алгоритма сериализации -- **Тестирование**: 179 модульных тестов + 16 интеграционных, CI/CD на 3 платформах +- **Тестирование**: 240 модульных тестов + 16 интеграционных, CI/CD на 3 платформах - **Готовность к использованию**: Прототип с работающей базовой функциональностью --- @@ -160,9 +160,10 @@ AVM представляет собой интересный исследова 4. Пакеты для менеджеров зависимостей (vcpkg, Conan) 5. ~~Условные конструкции~~ ✅ If с ленивым вычислением (PR #28) 6. ~~Рекурсивные функции~~ ✅ Def/Call с параметрами и защитой от бесконечной рекурсии (PR #29) +7. ~~Стандартная библиотека~~ ✅ XOR, NAND, NOR, Implies, Eq как таблицы истинности (PR #30) --- *Дата анализа: январь 2026* *Последнее обновление: февраль 2026* -*Версия проекта: 0.0.5* +*Версия проекта: 0.0.6* diff --git a/include/avm.h b/include/avm.h index bbecf1a..500d26b 100644 --- a/include/avm.h +++ b/include/avm.h @@ -280,6 +280,11 @@ struct rel_t : obj_aspect, static inline rel_t *If; static inline rel_t *Def; static inline rel_t *Call; + static inline rel_t *Xor; + static inline rel_t *Nand; + static inline rel_t *Nor; + static inline rel_t *Implies; + static inline rel_t *Eq; protected: rel_t() @@ -369,13 +374,23 @@ struct rel_t : obj_aspect, add_rel(If); add_rel(Def); add_rel(Call); - - Not->update(Not, E); // (NOT, Ent) — NOT есть сущность - And->update(And, E); // (AND, Ent) — AND есть сущность - Or->update(Or, E); // (OR, Ent) — OR есть сущность - If->update(If, E); // (IF, Ent) — IF есть сущность - Def->update(Def, E); // (DEF, Ent) — DEF есть сущность - Call->update(Call, E); // (CALL, Ent) — CALL есть сущность + add_rel(Xor); + add_rel(Nand); + add_rel(Nor); + add_rel(Implies); + add_rel(Eq); + + Not->update(Not, E); // (NOT, Ent) — NOT есть сущность + And->update(And, E); // (AND, Ent) — AND есть сущность + Or->update(Or, E); // (OR, Ent) — OR есть сущность + If->update(If, E); // (IF, Ent) — IF есть сущность + Def->update(Def, E); // (DEF, Ent) — DEF есть сущность + Call->update(Call, E); // (CALL, Ent) — CALL есть сущность + Xor->update(Xor, E); // (XOR, Ent) — XOR есть сущность + Nand->update(Nand, E); // (NAND, Ent) — NAND есть сущность + Nor->update(Nor, E); // (NOR, Ent) — NOR есть сущность + Implies->update(Implies, E); // (IMPLIES, Ent) — IMPLIES есть сущность + Eq->update(Eq, E); // (EQ, Ent) — EQ есть сущность // NOT: таблица истинности через entity map // NOT[True] = False, NOT[False] = True @@ -421,6 +436,89 @@ struct rel_t : obj_aspect, // IF[True] = True, IF[False] = False (*If)[True] = True; (*If)[False] = False; + + // === Стандартная библиотека логических операций === + // Standard library of logical operations + + // XOR: исключающее ИЛИ через вложенные entity map + // XOR[arg1][arg2] = result + auto xor_true = rel_t::rel(); // XOR[True] + auto xor_false = rel_t::rel(); // XOR[False] + + (*Xor)[True] = xor_true; + (*Xor)[False] = xor_false; + + // XOR[True][True] = False, XOR[True][False] = True + (*xor_true)[True] = False; + (*xor_true)[False] = True; + + // XOR[False][True] = True, XOR[False][False] = False + (*xor_false)[True] = True; + (*xor_false)[False] = False; + + // NAND: НЕ-И через вложенные entity map + // NAND[arg1][arg2] = NOT[AND[arg1][arg2]] + auto nand_true = rel_t::rel(); // NAND[True] + auto nand_false = rel_t::rel(); // NAND[False] + + (*Nand)[True] = nand_true; + (*Nand)[False] = nand_false; + + // NAND[True][True] = False, NAND[True][False] = True + (*nand_true)[True] = False; + (*nand_true)[False] = True; + + // NAND[False][True] = True, NAND[False][False] = True + (*nand_false)[True] = True; + (*nand_false)[False] = True; + + // NOR: НЕ-ИЛИ через вложенные entity map + // NOR[arg1][arg2] = NOT[OR[arg1][arg2]] + auto nor_true = rel_t::rel(); // NOR[True] + auto nor_false = rel_t::rel(); // NOR[False] + + (*Nor)[True] = nor_true; + (*Nor)[False] = nor_false; + + // NOR[True][True] = False, NOR[True][False] = False + (*nor_true)[True] = False; + (*nor_true)[False] = False; + + // NOR[False][True] = False, NOR[False][False] = True + (*nor_false)[True] = False; + (*nor_false)[False] = True; + + // IMPLIES: логическая импликация через вложенные entity map + // IMPLIES[arg1][arg2] = OR[NOT[arg1]][arg2] = (¬a ∨ b) + auto imp_true = rel_t::rel(); // IMPLIES[True] + auto imp_false = rel_t::rel(); // IMPLIES[False] + + (*Implies)[True] = imp_true; + (*Implies)[False] = imp_false; + + // IMPLIES[True][True] = True, IMPLIES[True][False] = False + (*imp_true)[True] = True; + (*imp_true)[False] = False; + + // IMPLIES[False][True] = True, IMPLIES[False][False] = True + (*imp_false)[True] = True; + (*imp_false)[False] = True; + + // EQ: логическая эквивалентность (биконденсация) через entity map + // EQ[arg1][arg2] = (a → b) ∧ (b → a) = NOT[XOR[a][b]] + auto eq_true = rel_t::rel(); // EQ[True] + auto eq_false = rel_t::rel(); // EQ[False] + + (*Eq)[True] = eq_true; + (*Eq)[False] = eq_false; + + // EQ[True][True] = True, EQ[True][False] = False + (*eq_true)[True] = True; + (*eq_true)[False] = False; + + // EQ[False][True] = False, EQ[False][False] = True + (*eq_false)[True] = False; + (*eq_false)[False] = True; } ~base_voc() { diff --git a/plan.md b/plan.md index 46f3e50..89049ee 100644 --- a/plan.md +++ b/plan.md @@ -55,7 +55,7 @@ #### Средний приоритет 4. ~~**Реализовать условные конструкции**~~ ✅ — If с ленивым вычислением через entity map и `interpret()` (PR #28) 5. ~~**Добавить поддержку рекурсии**~~ ✅ — рекурсивные определения функций через `Def`/`Call` с параметрами и защитой от бесконечной рекурсии (PR #29) -6. **Создать стандартную библиотеку** — базовые функции и операции +6. ~~**Создать стандартную библиотеку**~~ ✅ — XOR, NAND, NOR, Implies, Eq как таблицы истинности в базовом словаре (PR #30) #### Низкий приоритет 7. **Оптимизация вычислений** — кэширование результатов, ленивые вычисления @@ -135,7 +135,7 @@ ### Задачи по приоритетам #### Критический приоритет (сделать в первую очередь) -1. ~~**Добавить unit-тесты**~~ ✅ — 179 модульных тестов (PR #9, #19, #20, #28, #29) +1. ~~**Добавить unit-тесты**~~ ✅ — 240 модульных тестов (PR #9, #19, #20, #28, #29, #30) 2. ~~**Настроить CI/CD**~~ ✅ — GitHub Actions для Ubuntu, Windows, macOS (PR #6) 3. ~~**Обеспечить кроссплатформенность**~~ ✅ — сборка для Linux, macOS, Windows (PR #6, #14) 4. ~~**Улучшить README**~~ ✅ — двуязычная документация (PR #2) @@ -182,6 +182,7 @@ - ~~Интерпретатор выражений~~ ✅ вычисление логических выражений из JSON через `interpret()` (PR #20) - ~~Условные конструкции~~ ✅ If с ленивым вычислением через entity map (PR #28) - ~~Рекурсивные функции~~ ✅ Def/Call с параметрами и защитой от бесконечной рекурсии (PR #29) +- ~~Стандартная библиотека~~ ✅ XOR, NAND, NOR, Implies, Eq (PR #30) - Персистентное хранение - API для программного использования - Примеры и руководства @@ -210,4 +211,4 @@ *Дата создания: январь 2026* *Последнее обновление: февраль 2026* -*Версия плана: 1.3* +*Версия плана: 1.4* diff --git a/src/main.cpp b/src/main.cpp index f86d536..7cb9b2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -188,6 +188,11 @@ rel_t *import_json(const json &j) // {"Not": [expr]} — логическое НЕ // {"And": [expr1, expr2]} — логическое И // {"Or": [expr1, expr2]} — логическое ИЛИ +// {"Xor": [expr1, expr2]} — исключающее ИЛИ +// {"Nand": [expr1, expr2]} — НЕ-И +// {"Nor": [expr1, expr2]} — НЕ-ИЛИ +// {"Implies": [expr1, expr2]} — логическая импликация (a → b) +// {"Eq": [expr1, expr2]} — логическая эквивалентность (a ↔ b) // {"If": [cond, then, else]} — условная конструкция // {"Def": ["name", ["param1", ...], body]} — определение рекурсивной функции // {"Call": ["name", arg1, ...]} — вызов определённой функции @@ -208,6 +213,16 @@ rel_t *resolve_operator(const string &name) return rel_t::Def; if (name == "Call") return rel_t::Call; + if (name == "Xor") + return rel_t::Xor; + if (name == "Nand") + return rel_t::Nand; + if (name == "Nor") + return rel_t::Nor; + if (name == "Implies") + return rel_t::Implies; + if (name == "Eq") + return rel_t::Eq; return nullptr; } @@ -626,7 +641,7 @@ int main(int argc, char *argv[]) break; default: cout << R"(https://github.com/netkeep80/avm - Associative Virtual Machine [Version 0.0.5] + Associative Virtual Machine [Version 0.0.6] _____________ / \ / \ @@ -665,7 +680,8 @@ Copyright (c) 2022 Vertushkin Roman Pavlovich res = json::object(); // parse_json(root, res); // Проверяем, является ли вход выражением для интерпретации - // Выражение — JSON объект с одним ключом-оператором (Not, And, Or, If, Def, Call) + // Выражение — JSON объект с одним ключом-оператором + // (Not, And, Or, Xor, Nand, Nor, Implies, Eq, If, Def, Call) // или JSON массив выражений (для Def + Call последовательностей) bool is_expression = (root.is_object() && root.size() == 1 && resolve_operator(root.begin().key()) != nullptr) || diff --git a/test/expr_eq.json b/test/expr_eq.json new file mode 100644 index 0000000..87e1527 --- /dev/null +++ b/test/expr_eq.json @@ -0,0 +1 @@ +{"Eq": [true, true]} \ No newline at end of file diff --git a/test/expr_implies.json b/test/expr_implies.json new file mode 100644 index 0000000..145c59c --- /dev/null +++ b/test/expr_implies.json @@ -0,0 +1 @@ +{"Implies": [true, false]} \ No newline at end of file diff --git a/test/expr_nand.json b/test/expr_nand.json new file mode 100644 index 0000000..ee27a34 --- /dev/null +++ b/test/expr_nand.json @@ -0,0 +1 @@ +{"Nand": [true, true]} \ No newline at end of file diff --git a/test/expr_nor.json b/test/expr_nor.json new file mode 100644 index 0000000..2cd1481 --- /dev/null +++ b/test/expr_nor.json @@ -0,0 +1 @@ +{"Nor": [false, false]} \ No newline at end of file diff --git a/test/expr_xor.json b/test/expr_xor.json new file mode 100644 index 0000000..d9a048d --- /dev/null +++ b/test/expr_xor.json @@ -0,0 +1 @@ +{"Xor": [true, false]} \ No newline at end of file diff --git a/test/unit_test.cpp b/test/unit_test.cpp index e563143..711a597 100644 --- a/test/unit_test.cpp +++ b/test/unit_test.cpp @@ -457,8 +457,8 @@ void test_interpret_error_cases() check(interpret(multi_key) == rel_t::E, "interpret(multi-key object) = E"); // Неизвестный оператор - json unknown = {{"Xor", json::array({true, false})}}; - check(interpret(unknown) == rel_t::E, "interpret({Xor: [...]}) = E"); + json unknown = {{"Unknown", json::array({true, false})}}; + check(interpret(unknown) == rel_t::E, "interpret({Unknown: [...]}) = E"); // Пустой массив аргументов json empty_args = {{"Not", json::array()}}; @@ -817,6 +817,203 @@ void test_interpret_array_sequential() clear_func_env(); } +// === Тесты стандартной библиотеки логических операций === + +void test_stdlib_vocabulary() +{ + check(rel_t::Xor != nullptr, "Xor is not null"); + check(rel_t::Nand != nullptr, "Nand is not null"); + check(rel_t::Nor != nullptr, "Nor is not null"); + check(rel_t::Implies != nullptr, "Implies is not null"); + check(rel_t::Eq != nullptr, "Eq is not null"); + + // Все операции стандартной библиотеки должны быть различными + check(rel_t::Xor != rel_t::And, "Xor != And"); + check(rel_t::Xor != rel_t::Or, "Xor != Or"); + check(rel_t::Nand != rel_t::And, "Nand != And"); + check(rel_t::Nor != rel_t::Or, "Nor != Or"); + check(rel_t::Implies != rel_t::Eq, "Implies != Eq"); + + // Все операции стандартной библиотеки являются сущностями (sub == E) + check(rel_t::Xor->sub == rel_t::E, "Xor->sub == E"); + check(rel_t::Nand->sub == rel_t::E, "Nand->sub == E"); + check(rel_t::Nor->sub == rel_t::E, "Nor->sub == E"); + check(rel_t::Implies->sub == rel_t::E, "Implies->sub == E"); + check(rel_t::Eq->sub == rel_t::E, "Eq->sub == E"); +} + +void test_xor_eval() +{ + // XOR[True][True] = False + check(eval(rel_t::Xor, rel_t::True, rel_t::True) == rel_t::False, "XOR[True][True] = False"); + // XOR[True][False] = True + check(eval(rel_t::Xor, rel_t::True, rel_t::False) == rel_t::True, "XOR[True][False] = True"); + // XOR[False][True] = True + check(eval(rel_t::Xor, rel_t::False, rel_t::True) == rel_t::True, "XOR[False][True] = True"); + // XOR[False][False] = False + check(eval(rel_t::Xor, rel_t::False, rel_t::False) == rel_t::False, "XOR[False][False] = False"); +} + +void test_nand_eval() +{ + // NAND[True][True] = False + check(eval(rel_t::Nand, rel_t::True, rel_t::True) == rel_t::False, "NAND[True][True] = False"); + // NAND[True][False] = True + check(eval(rel_t::Nand, rel_t::True, rel_t::False) == rel_t::True, "NAND[True][False] = True"); + // NAND[False][True] = True + check(eval(rel_t::Nand, rel_t::False, rel_t::True) == rel_t::True, "NAND[False][True] = True"); + // NAND[False][False] = True + check(eval(rel_t::Nand, rel_t::False, rel_t::False) == rel_t::True, "NAND[False][False] = True"); +} + +void test_nor_eval() +{ + // NOR[True][True] = False + check(eval(rel_t::Nor, rel_t::True, rel_t::True) == rel_t::False, "NOR[True][True] = False"); + // NOR[True][False] = False + check(eval(rel_t::Nor, rel_t::True, rel_t::False) == rel_t::False, "NOR[True][False] = False"); + // NOR[False][True] = False + check(eval(rel_t::Nor, rel_t::False, rel_t::True) == rel_t::False, "NOR[False][True] = False"); + // NOR[False][False] = True + check(eval(rel_t::Nor, rel_t::False, rel_t::False) == rel_t::True, "NOR[False][False] = True"); +} + +void test_implies_eval() +{ + // IMPLIES[True][True] = True (T → T = T) + check(eval(rel_t::Implies, rel_t::True, rel_t::True) == rel_t::True, "IMPLIES[True][True] = True"); + // IMPLIES[True][False] = False (T → F = F) + check(eval(rel_t::Implies, rel_t::True, rel_t::False) == rel_t::False, "IMPLIES[True][False] = False"); + // IMPLIES[False][True] = True (F → T = T) + check(eval(rel_t::Implies, rel_t::False, rel_t::True) == rel_t::True, "IMPLIES[False][True] = True"); + // IMPLIES[False][False] = True (F → F = T) + check(eval(rel_t::Implies, rel_t::False, rel_t::False) == rel_t::True, "IMPLIES[False][False] = True"); +} + +void test_eq_eval() +{ + // EQ[True][True] = True + check(eval(rel_t::Eq, rel_t::True, rel_t::True) == rel_t::True, "EQ[True][True] = True"); + // EQ[True][False] = False + check(eval(rel_t::Eq, rel_t::True, rel_t::False) == rel_t::False, "EQ[True][False] = False"); + // EQ[False][True] = False + check(eval(rel_t::Eq, rel_t::False, rel_t::True) == rel_t::False, "EQ[False][True] = False"); + // EQ[False][False] = True + check(eval(rel_t::Eq, rel_t::False, rel_t::False) == rel_t::True, "EQ[False][False] = True"); +} + +void test_interpret_xor() +{ + // XOR: {"Xor": [arg1, arg2]} + json xor_tt = {{"Xor", json::array({true, true})}}; + json xor_tf = {{"Xor", json::array({true, false})}}; + json xor_ft = {{"Xor", json::array({false, true})}}; + json xor_ff = {{"Xor", json::array({false, false})}}; + + check(interpret(xor_tt) == rel_t::False, "interpret({Xor: [true, true]}) = False"); + check(interpret(xor_tf) == rel_t::True, "interpret({Xor: [true, false]}) = True"); + check(interpret(xor_ft) == rel_t::True, "interpret({Xor: [false, true]}) = True"); + check(interpret(xor_ff) == rel_t::False, "interpret({Xor: [false, false]}) = False"); +} + +void test_interpret_nand() +{ + // NAND: {"Nand": [arg1, arg2]} + json nand_tt = {{"Nand", json::array({true, true})}}; + json nand_tf = {{"Nand", json::array({true, false})}}; + json nand_ft = {{"Nand", json::array({false, true})}}; + json nand_ff = {{"Nand", json::array({false, false})}}; + + check(interpret(nand_tt) == rel_t::False, "interpret({Nand: [true, true]}) = False"); + check(interpret(nand_tf) == rel_t::True, "interpret({Nand: [true, false]}) = True"); + check(interpret(nand_ft) == rel_t::True, "interpret({Nand: [false, true]}) = True"); + check(interpret(nand_ff) == rel_t::True, "interpret({Nand: [false, false]}) = True"); +} + +void test_interpret_nor() +{ + // NOR: {"Nor": [arg1, arg2]} + json nor_tt = {{"Nor", json::array({true, true})}}; + json nor_tf = {{"Nor", json::array({true, false})}}; + json nor_ft = {{"Nor", json::array({false, true})}}; + json nor_ff = {{"Nor", json::array({false, false})}}; + + check(interpret(nor_tt) == rel_t::False, "interpret({Nor: [true, true]}) = False"); + check(interpret(nor_tf) == rel_t::False, "interpret({Nor: [true, false]}) = False"); + check(interpret(nor_ft) == rel_t::False, "interpret({Nor: [false, true]}) = False"); + check(interpret(nor_ff) == rel_t::True, "interpret({Nor: [false, false]}) = True"); +} + +void test_interpret_implies() +{ + // IMPLIES: {"Implies": [arg1, arg2]} + json imp_tt = {{"Implies", json::array({true, true})}}; + json imp_tf = {{"Implies", json::array({true, false})}}; + json imp_ft = {{"Implies", json::array({false, true})}}; + json imp_ff = {{"Implies", json::array({false, false})}}; + + check(interpret(imp_tt) == rel_t::True, "interpret({Implies: [true, true]}) = True"); + check(interpret(imp_tf) == rel_t::False, "interpret({Implies: [true, false]}) = False"); + check(interpret(imp_ft) == rel_t::True, "interpret({Implies: [false, true]}) = True"); + check(interpret(imp_ff) == rel_t::True, "interpret({Implies: [false, false]}) = True"); +} + +void test_interpret_eq() +{ + // EQ: {"Eq": [arg1, arg2]} + json eq_tt = {{"Eq", json::array({true, true})}}; + json eq_tf = {{"Eq", json::array({true, false})}}; + json eq_ft = {{"Eq", json::array({false, true})}}; + json eq_ff = {{"Eq", json::array({false, false})}}; + + check(interpret(eq_tt) == rel_t::True, "interpret({Eq: [true, true]}) = True"); + check(interpret(eq_tf) == rel_t::False, "interpret({Eq: [true, false]}) = False"); + check(interpret(eq_ft) == rel_t::False, "interpret({Eq: [false, true]}) = False"); + check(interpret(eq_ff) == rel_t::True, "interpret({Eq: [false, false]}) = True"); +} + +void test_stdlib_nested() +{ + // XOR с вложенными выражениями: XOR[NOT[false], AND[true, true]] = XOR[true, true] = false + json xor_nested = {{"Xor", json::array({{{"Not", json::array({false})}}, {{"And", json::array({true, true})}}})}}; + check(interpret(xor_nested) == rel_t::False, "interpret({Xor: [{Not: [false]}, {And: [true, true]}]}) = False"); + + // IMPLIES с вложенными: IMPLIES[AND[true, true], OR[false, true]] = IMPLIES[true, true] = true + json imp_nested = {{"Implies", json::array({{{"And", json::array({true, true})}}, {{"Or", json::array({false, true})}}})}}; + check(interpret(imp_nested) == rel_t::True, "interpret({Implies: [{And: [true, true]}, {Or: [false, true]}]}) = True"); + + // EQ[XOR[true, false], true] = EQ[true, true] = true + json eq_xor = {{"Eq", json::array({{{"Xor", json::array({true, false})}}, true})}}; + check(interpret(eq_xor) == rel_t::True, "interpret({Eq: [{Xor: [true, false]}, true]}) = True"); + + // NAND[IMPLIES[false, true], NOR[true, false]] = NAND[true, false] = true + json nand_complex = {{"Nand", json::array({{{"Implies", json::array({false, true})}}, {{"Nor", json::array({true, false})}}})}}; + check(interpret(nand_complex) == rel_t::True, "interpret({Nand: [{Implies: [false, true]}, {Nor: [true, false]}]}) = True"); +} + +void test_stdlib_with_def_call() +{ + clear_func_env(); + + // Определяем функцию myXor через стандартную библиотеку и вызываем + json program = json::array({ + {{"Def", json::array({"myXor", json::array({"a", "b"}), {{"Xor", json::array({"a", "b"})}}})}}, + {{"Call", json::array({"myXor", true, false})}} + }); + check(interpret(program) == rel_t::True, "myXor(true, false) = True"); + + clear_func_env(); + + // Определяем функцию implies и используем в условном выражении + json program2 = json::array({ + {{"Def", json::array({"myImpl", json::array({"a", "b"}), {{"Implies", json::array({"a", "b"})}}})}}, + {{"If", json::array({{{"Call", json::array({"myImpl", true, true})}}, true, false})}} + }); + check(interpret(program2) == rel_t::True, "If[myImpl(true, true), true, false] = True"); + + clear_func_env(); +} + // === Тесты счётчиков памяти === void test_memory_counters() @@ -883,6 +1080,19 @@ int main() test_def_call_error_cases(); test_def_call_recursion_depth_limit(); test_interpret_array_sequential(); + test_stdlib_vocabulary(); + test_xor_eval(); + test_nand_eval(); + test_nor_eval(); + test_implies_eval(); + test_eq_eval(); + test_interpret_xor(); + test_interpret_nand(); + test_interpret_nor(); + test_interpret_implies(); + test_interpret_eq(); + test_stdlib_nested(); + test_stdlib_with_def_call(); test_memory_counters(); cout << endl; From b5c2130ecdc93e92dd01bea3edc081ba93c70fa6 Mon Sep 17 00:00:00 2001 From: konard Date: Fri, 6 Feb 2026 21:27:57 +0100 Subject: [PATCH 3/3] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D1=91=D0=BD=20?= =?UTF-8?q?=D1=81=D0=BB=D1=83=D0=B6=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9=20=D1=84?= =?UTF-8?q?=D0=B0=D0=B9=D0=BB=20CLAUDE.md=20=D0=B8=D0=B7=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index db1a576..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,7 +0,0 @@ -Issue to solve: https://github.com/netkeep80/avm/issues/21 -Your prepared branch: issue-21-9aa1aab34bc9 -Your prepared working directory: /tmp/gh-issue-solver-1770408958092 -Your forked repository: konard/netkeep80-avm -Original repository (upstream): netkeep80/avm - -Proceed.