@rsconcept/rstool 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/SYNTAX.md CHANGED
@@ -1,139 +1,84 @@
1
- # RSLang syntax reference
1
+ # Синтаксис RSLang
2
2
 
3
- Use this when constructing or repairing RSLang expressions. For full grammar tokens see `GRAMMAR-REF.md`. For typification rules see `TYPIFICATION.md`.
3
+ Читай, когда строишь или исправляешь `definitionFormal`. Токены и приоритеты в `GRAMMAR-REF.md`, типизация в `TYPIFICATION.md`.
4
4
 
5
- ## Identifier rules
5
+ ## Имена и литералы
6
6
 
7
- - **Globals** (concept aliases): uppercase Latin letter + digits — `X1`, `C2`, `S3`, `D11`, `F7`, `P4`, `A6`, `T9`, `N12`. The leading letter must match the constituent's role.
8
- - **Radicals**: identifiers starting with `R` — used inside template parameterised expressions to denote arbitrary typifications (`R1`, `R2`).
9
- - **Locals** (bound variables): lowercase Latin or Greek letter, optionally with digits — `x`, `ξ`, `μ2`, `y1`.
10
- - **Special identifiers** reserved tokens (`Z`, `∅`, operators).
7
+ - Глобальные алиасы: `X1`, `C2`, `S3`, `D11`, `F7`, `P4`, `A6`, `T9`; буква совпадает с ролью.
8
+ - Радикалы: `R1`, `R2` — шаблонные ступени в параметрах.
9
+ - Локальные переменные: `x`, `ξ`, `μ2`, `y1`.
10
+ - Целые: `0`, `42`; отрицательного литерала нет, пиши `0 - 5`.
11
+ - `Z` — множество целых, `∅` — пустое множество с типизацией `ℬ(R0)`.
11
12
 
12
- ## Literals
13
+ ## Теоретико-множественные выражения (STE)
13
14
 
14
- - **Integers**: digit sequence, no negative literal: `0`, `42`. Negation is a binary subtraction `0 - n`.
15
- - **Integer set**: `Z`.
16
- - **Empty set**: `∅` (typification `ℬ(R0)` — set of arbitrary element structure).
15
+ - `D1 D2`, `D1 D2`, `D1 \ D2`, `D1 D2` операции над множествами.
16
+ - `X1 × X2` — декартово произведение.
17
+ - `ℬ(X1)` — булеан, множество всех подмножеств.
18
+ - `(a, b, c)` — кортеж, арность минимум 2.
19
+ - `{a, b, c}` — перечисление.
20
+ - `bool(a)` — синглетон, `debool(S)` — извлечение единственного элемента.
21
+ - `red(S)` — суммарное множество; `S` должно иметь ступень `ℬ(ℬ(H))`.
22
+ - `pr1(tuple)` — малая проекция кортежа.
23
+ - `Pr1(S)` — большая проекция множества кортежей.
24
+ - `Fi1[D](S)` — фильтр по принадлежности выбранной проекции в `D`.
17
25
 
18
- ## Set-theoretic expressions
26
+ Мультииндексы разрешены: `pr1,3(...)`, `Pr2,4(S1)`, `Fi1,2[D1](S1)`.
19
27
 
20
- | Construct | Syntax | Notes |
21
- | -------------------- | ------------------- | ----------------------------------------------- |
22
- | Union | `D1 ∪ D2` | |
23
- | Intersection | `D1 ∩ D2` | |
24
- | Difference | `D1 \ D2` | |
25
- | Symmetric difference | `D1 ∆ D2` | |
26
- | Cartesian product | `X1 × X2` | typification: tuple |
27
- | Boolean / power set | `ℬ(X1)` | set of all subsets |
28
- | Tuple | `(a, b, c)` | ordered, n ≥ 2 |
29
- | Enumeration | `{a, b, c}` | unordered, n ≥ 1 |
30
- | Singleton | `bool(a)` ≡ `{a}` | |
31
- | Desingleton | `debool({a})` ≡ `a` | only for one-element sets |
32
- | Sum set | `red(S1)` | union of inner sets; `S1` must be a set of sets |
33
- | Small projection | `pr1((a1, …, an))` | returns `a1` |
34
- | Large projection | `Pr1(S1)` | set of first components of tuples in `S1` |
35
- | Filter | `Fi1[D1](S1)` | subset of `S1` whose first projection ∈ `D1` |
28
+ ## Логические выражения (LE)
36
29
 
37
- Indices `1` may be any natural number or comma-separated multi-index (`pr1,3((a1, a2, a3, a4)) = (a1, a3)`, `Fi1,2[D1](S1)`).
30
+ - Предикаты множеств: S`, S`, `S1 = S2`, `S1 S2`, `S1 S2`, `S1 ⊂ S2`, `S1 ⊄ S2`.
31
+ - Арифметические предикаты: `=`, `≠`, `<`, `≤`, `>`, `≥` над `Z`.
32
+ - Связки: `¬A`, `A & B`, `A ∨ B`, `A ⇒ B`, `A ⇔ B`.
38
33
 
39
- ## Logical expressions
34
+ `TRUE` и `FALSE` в экспликации КС не используют.
40
35
 
41
- ### Set-theoretic predicates
36
+ ## Кванторы
42
37
 
43
- | Predicate | Syntax |
44
- | ---------------- | --------- |
45
- | Membership | S` |
46
- | Non-membership | S` |
47
- | Set equality | `S1 = S2` |
48
- | Set inequality | `S1 ≠ S2` |
49
- | Inclusion | `S1 ⊆ S2` |
50
- | Strict inclusion | `S1 ⊂ S2` |
51
- | Non-inclusion | `S1 ⊄ S2` |
38
+ - `∀ξ∈D1 (LE(ξ))` — всеобщность.
39
+ - `∃ξ∈D1 (LE(ξ))` существование.
40
+ - `∀(ξ1, ξ2)S1 (LE(ξ1, ξ2))` — объявление кортежа.
41
+ - `∀ξ1, ξ2∈D1 (LE(ξ1, ξ2))` — сокращение вложенных кванторов.
52
42
 
53
- ### Arithmetic predicates (typification `Logic`)
43
+ Скобки вокруг `LE` можно опустить для атомарного логического выражения.
54
44
 
55
- `a = b`, `a ≠ b`, `a < b`, `a ≤ b`, `a > b`, `a ≥ b`.
45
+ ## Арифметика
56
46
 
57
- ### Connectives
47
+ `a + b`, `a - b`, `a * b` дают `Z`. `card(S)` возвращает мощность конечного множества.
58
48
 
59
- | Connective | Syntax |
60
- | ----------- | ------- |
61
- | Negation | `¬A` |
62
- | Conjunction | `A & B` |
63
- | Disjunction | `A ∨ B` |
64
- | Implication | `A ⇒ B` |
65
- | Equivalence | `A ⇔ B` |
49
+ ## Параметризованные выражения
66
50
 
67
- The constants `TRUE` and `FALSE` are **not** used inside schema explications.
68
-
69
- ## Quantifiers
70
-
71
- | Form | Syntax |
72
- | ------------- | ---------------------------- |
73
- | Universal | `∀ξ∈STE (LE(ξ))` |
74
- | Existential | `∃ξ∈STE (LE(ξ))` |
75
- | Tuple binding | `∀(ξ1, ξ2)∈STE (LE(ξ1, ξ2))` |
76
- | Variable list | `∀ξ1, ξ2 ∈ STE (LE(ξ1, ξ2))` |
77
-
78
- Parentheses around `LE` may be omitted for atomic logical expressions.
79
-
80
- ## Arithmetic
81
-
82
- Operations `a + b`, `a - b`, `a * b` form set-theoretic expressions with typification `Z`. Negative numbers are computed, never literal.
83
-
84
- `card(S)` returns the integer cardinality of `S` (always finite in practice).
85
-
86
- ## Parameterised expressions
87
-
88
- ### Term-function declaration
89
-
90
- ```
51
+ ```text
91
52
  F1 ::= [α1∈STE1, α2∈STE2(α1)] STE(α1, α2)
92
- ```
93
-
94
- - Inside `[]` is an ordered list of parameter declarations separated by commas.
95
- - A parameter is declared with `∈`: `local_var ∈ domain`.
96
- - A declared variable can appear in subsequent parameter domains and in the result STE.
97
-
98
- ### Predicate-function declaration
99
-
100
- ```
101
53
  P1 ::= [α1∈STE1, α2∈STE2(α1)] LE(α1, α2)
102
54
  ```
103
55
 
104
- The only difference from a term-function is that the body is a logical expression.
56
+ - В `[]` идут параметры через `∈`.
57
+ - Параметр доступен в следующих доменах и теле.
58
+ - Вызов позиционный: `F1[ξ1, S1]`, `P1[ξ1\ξ2, ξ3]`.
59
+ - `F#` возвращает теоретико-множественное выражение, `P#` — логическое.
105
60
 
106
- ### Calling parameterised functions
61
+ ## Радикалы
107
62
 
108
- `F1[ξ1, S1]`, `P1[ξ1\ξ2, ξ3]` — arguments are positional and listed in square brackets after the function name. Argument typifications are checked against parameter typifications. Result is an STE (term-function) or LE (predicate-function).
109
-
110
- ### Template expressions
111
-
112
- Functions that use radicals as parameter typifications are templates:
113
-
114
- ```
63
+ ```text
115
64
  F2 ::= [α1∈R1×R2, α2∈R1] α2 = pr1(α1)
116
65
  ```
117
66
 
118
- - Radical values are **inferred** from the call-site argument typifications. All inferred values for the same radical index must agree.
119
- - Different radical indices are independent.
120
- - Radicals may only appear in parameter domains — never in the result expression.
67
+ - `R#` выводится по типизациям аргументов в месте вызова.
68
+ - Все вхождения одного `R#` должны совпасть.
69
+ - Радикалы допустимы только в доменах параметров.
121
70
 
122
- ## Examples
71
+ ## Примеры
123
72
 
124
73
  - `¬α ∈ S1`
125
- - `D1 ∈ S1 ⇒ 2 + 2 = 5`
126
74
  - `D1 ⊆ D2 ⇔ ∀x∈D1 x∈D2`
127
75
  - `∀x∈D1 ∃y∈D2 (x, y)∈S1 & (x, x)∈S1`
128
76
  - `(4 + 5) * 3`, `card(X1) > 5`
129
- - `ℬ(2) = {{}, {1}, {2}, {1, 2}}`
130
77
  - `pr2((5, 4, 3, 2, 1)) = 4`
131
78
  - `red({{1, 2, 3}, {3, 4}}) = {1, 2, 3, 4}`
132
- - `Fi2[{2, 4}]({((1, 2), (3, 4), (5, 6))}) = {((1, 2), (3, 4))}`
133
79
 
134
- ## Correctness model
80
+ ## Корректность
135
81
 
136
- - Expression checking happens in the **global context**: known typifications and bijective portability of every referenced identifier. Unknown identifiers are errors.
137
- - Set-theoretic rules follow from bijective portability of the membership predicate — an element must match the typification of the set it is tested against.
138
- - Logical consistency cannot generally be checked automatically. The existence of an interpretation example in a conceptual model is a basis for accepting consistency.
139
- - All formal definitions must be **bijectively portable**: values are independent of any bijective replacement of undefined-concept interpretations.
82
+ - Анализ идет в глобальном контексте: все алиасы должны быть известны и типизированы.
83
+ - Формальные определения должны быть биективно переносимыми (гарантируется семантическим анализатором).
84
+ - Логическая непротиворечивость проверяется примером интерпретации в модели.
@@ -1,84 +1,65 @@
1
- # Typification reference
1
+ # Типизация
2
2
 
3
- Distilled from `help-rslang-typification`, `help-rslang-expression-structure`, and `help-rslang-expression-parameter`. Agents must understand grades to interpret `AnalysisResult.type` and to construct correct expressions.
3
+ Читай, когда разбираешь `AnalysisResult.type`, `valueClass` или радикалы.
4
4
 
5
- ## Grades
5
+ ## Ступени
6
6
 
7
- A genus-structure expression `ξ` has typification (a _structure_) if `ξ ∈ H` holds, where `H` is a valid **grade**. Grades are built recursively:
7
+ Выражение типизировано, если его значения принадлежат ступени `H`.
8
8
 
9
- | Grade | Form | Notes |
10
- | ---------------- | -------------------- | ------------------------------------ |
11
- | Element | `Xi`, `Ci` | grade of a basic concept's elements |
12
- | Integer | `Z` | grade of integer |
13
- | Tuple of arity n | `(H1 × H2 × … × Hn)` | ordered structured grade |
14
- | Set | `ℬ(H)` | unordered set of values of grade `H` |
9
+ - `Xi`, `Ci` — элемент базисного или константного множества.
10
+ - `Z` целое число.
11
+ - `(H1 × H2 × ... × Hn)` — кортеж.
12
+ - `ℬ(H)` множество значений ступени `H`.
15
13
 
16
- The empty set `∅` has typification `ℬ(R0)` a set with arbitrary element structure. The radical `R0` ensures it conforms to any element grade in context.
14
+ `∅` имеет типизацию `ℬ(R0)`: пустое множество подстраивается под контекст.
17
15
 
18
- ## Extended typifications
16
+ ## Дополнительные типизации
19
17
 
20
- Beyond set-theoretic grades, RSLang uses two additional grade-like markers:
18
+ - `Logic` логические выражения: аксиомы, высказывания, тела предикат-функций.
19
+ - `Hr <- [H1, H2, ..., Hi]` — параметризованная типизация функций: результат и аргументы.
21
20
 
22
- - **Logic** — typification of logical expressions (axioms, statements, predicate bodies) that evaluate to TRUE or FALSE.
23
- - **Parameterised** — typification of term-functions and predicate-functions:
21
+ ## Радикалы
24
22
 
25
- ```
26
- Hr 🠔 [H1, H2, …, Hi]
27
- ```
23
+ `R1`, `R2`, ... — шаблонные ступени.
28
24
 
29
- where `Hr` is the result typification (an STE grade or `Logic`) and `H1 Hi` are the argument typifications.
25
+ - Значение `R#` выводится по аргументам в месте вызова.
26
+ - Все вхождения одного `R#` должны дать одну ступень.
27
+ - Разные `R#` независимы.
28
+ - Радикалы можно писать только в доменах параметров; в теле результата будет `radicalUsage`.
30
29
 
31
- ## Radicals
30
+ ## `AnalysisResult.type`
32
31
 
33
- Template parameterised expressions may contain notations `R1, R2, …` (and `R0` for `∅`). Each radical corresponds to an arbitrary grade that is **inferred** from the typifications of the arguments at the point of use.
32
+ `type` приходит как JSON анализатора: `Record<string, unknown> | null`.
34
33
 
35
- - All occurrences of the same radical index must resolve to the same grade.
36
- - Radicals with different indices are independent.
37
- - Radicals may only appear in parameter domains, **not in the result expression**.
34
+ Правила:
38
35
 
39
- ## Encoded shape in `AnalysisResult.type`
36
+ 1. Сначала проверь `analysis.success === true` и `analysis.type !== null`.
37
+ 2. Не разбирай объект вручную; используй helpers из `@rsconcept/domain`.
38
+ 3. `valueClass` уточняет вычислимость: `Value`, `Property`, `Invalid`.
40
39
 
41
- The contract exposes `type: Record<string, unknown> | null` because typifications are JSON-encoded by the analyzer. Useful properties exposed by `@rsconcept/domain` helpers:
40
+ Полезные API: `TypeID`, `TypePath`, `makeTypePath`, `parseTypeText(...)`.
42
41
 
43
- - `TypeID` enum: `Element`, `Integer`, `Tuple`, `Boolean`, `Logic`, `Functional` — discriminates the top-level shape.
44
- - `TypePath` (sequence of indices) addresses positions inside a tuple-of-sets-of-tuples structure; use `makeTypePath` to construct.
45
- - `parseTypeText(...)` parses an ASCII representation `B(X1)`, `(X1×X2)`, etc., into a `Typification`.
42
+ ## `S#` и `D#`
46
43
 
47
- For agents inspecting types from rstool output:
44
+ - У `structure` (`S#`) `definitionFormal` читается как типизация. `ℬ(X1×X1)` описывает множество пар.
45
+ - У `term` (`D#`) `definitionFormal` читается как определение. `X1×X1` строит декартов продукт.
48
46
 
49
- 1. Check `analysis.success === true` and `analysis.type !== null`.
50
- 2. Use `analysis.type` (object) only as opaque input to `@rsconcept/domain` helpers — do not pattern-match it manually.
51
- 3. The `valueClass` companion indicates `Value`, `Property` (non-computable membership only), or `Invalid`.
47
+ Для отношений предпочитай `S#` с `ℬ(X1×X1)` и конвенцией; выводимые понятия делай через `Pr*`, `Fi*`, фильтры и функции.
52
48
 
53
- ## Typification on `S#` vs definition on `D#`
49
+ ## Операции
54
50
 
55
- - On a **`structure`** (`S#`), `definitionFormal` is read as **typification**. Subexpressions such as `X1×X1` describe **element shape** (here: one pair of base elements).
56
- - On a **`term`** (`D#`), the same token sequence is a **definition** evaluated in the model. `X1×X1` alone is the Cartesian product — all ordered pairs from `X1` — not the typification of a relation stored in `S#`.
51
+ Создают ступень: `ℬ(H)`, `H1 × H2`, `(a, b)`, `{a, b}`, `bool(a)`.
57
52
 
58
- Prefer `S#` with `ℬ(X1×X1)` plus `convention` for relations; derive `D#` with `Pr*`, `Fi*`, filters, etc.
53
+ Требуют подходящую ступень:
59
54
 
60
- ## Forming structures vs. derived structures
55
+ - `red(S)` нужно `S : ℬ(ℬ(H))`.
56
+ - `debool(S)` — нужно одноэлементное множество.
57
+ - `pr1(tuple)`, `Pr1(S)` — нужна достаточная арность.
58
+ - `Fi1[D](S)` — `D` должен соответствовать выбранной проекции.
61
59
 
62
- Forming operations build a new grade:
60
+ ## Частые ошибки
63
61
 
64
- - `ℬ(H)` power set
65
- - `H1 × H2` Cartesian product
66
- - `(a, b, c)` tuple
67
- - `{a, b, c}` enumeration
68
- - `bool(a)` — singleton
69
-
70
- Derived structures consume a grade:
71
-
72
- - `red(S)` — union of inner sets; requires `S : ℬ(ℬ(H))`
73
- - `debool({a})` — extracts the single element of a singleton
74
- - `pr1((a1, …, an))`, `Pr1(S)` — projections (multi-indices allowed: `pr1,3`, `Pr2,4`)
75
- - `Fi1[D](S)` — filters by membership in `D`; multi-index variants must match parameter arity
76
-
77
- ## Common typification pitfalls
78
-
79
- - Negative integer literals do not exist — use `0 - n`.
80
- - `debool(S)` fails if `S` is not a singleton.
81
- - Tuple projections require the argument to be a tuple of sufficient arity; `pr3((a, b))` is an error.
82
- - Filter parameter list arity must match the multi-index in `Fi[...]`.
83
- - A radical in the **result expression** of a template is a hard error (`radicalUsage`).
84
- - An `axiom` or `statement` must have typification `Logic`; non-logical formal definitions raise `expectedLogic`.
62
+ - `debool(S)` без гарантии синглетона.
63
+ - `pr3((a, b))`: индекс вне арности.
64
+ - `Fi1,2[D](S)`: параметр `D` не совпал с двумя проекциями.
65
+ - `A#` и `T#` не имеют `Logic`: будет `expectedLogic`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsconcept/rstool",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Agent-facing library for incremental RSForm construction, RSLang analysis, diagnostics, modeling, and evaluation. Wraps @rsconcept/domain with a deterministic session contract and stdio wrapper.",
5
5
  "license": "MIT",
6
6
  "author": "IRBorisov",
package/skills/README.md CHANGED
@@ -4,14 +4,12 @@ Each skill lives in its own subdirectory: `skills/<skill-name>/SKILL.md` (plus r
4
4
 
5
5
  ## Layout
6
6
 
7
- | Path | Role |
8
- | :--- | :--- |
9
- | `INSTALL.md` | **Agent procedure** after `npm install` |
10
- | `rstool-helper/SKILL.md` | Thin **entry** skill — copy into the project’s agent skills folder (see `INSTALL.md`) |
11
- | `rstool-helper/GUIDE.md` | Canonical workflow and language primer |
12
- | `rstool-helper/REFERENCE.md` | API, stdio, contract |
13
- | `rstool-helper/EXAMPLES.md` | Worked examples and pitfalls |
14
- | `../docs/*.md` | Language reference (DOMAIN, SYNTAX, DIAGNOSTICS, …) |
7
+ - `INSTALL.md`: agent procedure after `npm install`
8
+ - `rstool-helper/SKILL.md`: thin entry skill — copy into the project’s agent skills folder (see `INSTALL.md`)
9
+ - `rstool-helper/GUIDE.md`: canonical workflow and language primer
10
+ - `rstool-helper/REFERENCE.md`: API, stdio, contract
11
+ - `rstool-helper/EXAMPLES.md`: worked examples and pitfalls
12
+ - `../docs/*.md`: language reference (DOMAIN, SYNTAX, DIAGNOSTICS, …)
15
13
 
16
14
  ## npm workflow
17
15
 
@@ -1,16 +1,10 @@
1
- # rstool — worked examples
1
+ # rstool Examples
2
2
 
3
- Install first:
3
+ Short examples for agents. For full scripts, see `../../examples/`.
4
4
 
5
- ```bash
6
- npm install @rsconcept/rstool
7
- ```
8
-
9
- ## Kinship-lite: structure vs term
10
-
11
- `S1` carries **typification** `ℬ(X1×X1)` (pairs over people); `D1` is a **definition** `Pr1(S1)` (parents). Do not put `X1×X1` on a `term` — that is the full Cartesian product.
5
+ ## Minimal Session
12
6
 
13
- ## In-process
7
+ `S1` carries typification `ℬ(X1×X1)` for relation pairs. `D1` computes `Pr1(S1)`. Do not put bare `X1×X1` on a `term` when you mean a relation structure.
14
8
 
15
9
  ```ts
16
10
  import { CstType, RSToolAgent } from '@rsconcept/rstool';
@@ -18,12 +12,10 @@ import { CstType, RSToolAgent } from '@rsconcept/rstool';
18
12
  const tool = new RSToolAgent();
19
13
  const { sessionId } = tool.createSession();
20
14
 
21
- // Base set — formal must be empty
22
15
  tool.addOrUpdateConstituenta(sessionId, {
23
16
  draft: { id: 1, alias: 'X1', cstType: CstType.BASE, definitionFormal: '' }
24
17
  });
25
18
 
26
- // Structure: typification of parent–child pairs (undefined; convention in real schemas)
27
19
  tool.addOrUpdateConstituenta(sessionId, {
28
20
  draft: {
29
21
  id: 2,
@@ -34,32 +26,33 @@ tool.addOrUpdateConstituenta(sessionId, {
34
26
  }
35
27
  });
36
28
 
37
- // Term: derived definition — first projection of S1
38
29
  const { state, diagnostics } = tool.addOrUpdateConstituenta(sessionId, {
39
30
  draft: { id: 3, alias: 'D1', cstType: CstType.TERM, definitionFormal: 'Pr1(S1)' }
40
31
  });
41
32
 
42
33
  console.log(state.analysis.success, diagnostics.length);
34
+ ```
43
35
 
44
- // Scratch check
45
- tool.analyzeExpression(sessionId, {
46
- expression: '(',
47
- cstType: CstType.TERM
48
- }); // success: false, syntax diagnostics
36
+ ## Analyze Before Upsert
49
37
 
50
- // Set base binding and evaluate a scratch arithmetic term
51
- tool.setConstituentaValue(sessionId, {
52
- target: 1,
53
- value: { 0: 'zero', 1: 'one' }
54
- });
55
- const evalResult = tool.evaluateExpression(sessionId, {
56
- expression: '1+2',
38
+ Use scratch analysis when syntax or `cstType` is uncertain.
39
+
40
+ ```ts
41
+ const analysis = tool.analyzeExpression(sessionId, {
42
+ expression: 'Pr1(S1)',
57
43
  cstType: CstType.TERM
58
44
  });
59
- console.log(evalResult.success, evalResult.value); // true, 3
45
+
46
+ if (!analysis.success) {
47
+ console.log(analysis.diagnostics.map(({ code, from, to }) => ({ code, from, to })));
48
+ }
60
49
  ```
61
50
 
62
- ## Wrapper client
51
+ Fix the reported `from` / `to` range, then re-run analysis. Do not retry unchanged input.
52
+
53
+ ## Wrapper Client
54
+
55
+ Use the wrapper when the agent talks to a separate `rstool-wrapper` process.
63
56
 
64
57
  ```ts
65
58
  import { CstType } from '@rsconcept/rstool';
@@ -69,29 +62,13 @@ const client = new RSToolWrapperClient();
69
62
  await client.waitUntilReady();
70
63
 
71
64
  const { sessionId } = await client.call<{ sessionId: string }>('createSession');
65
+
72
66
  await client.call('addOrUpdateConstituenta', {
73
67
  sessionId,
74
68
  input: {
75
69
  draft: { id: 1, alias: 'X1', cstType: CstType.BASE, definitionFormal: '' }
76
70
  }
77
71
  });
78
- await client.call('addOrUpdateConstituenta', {
79
- sessionId,
80
- input: {
81
- draft: {
82
- id: 2,
83
- alias: 'S1',
84
- cstType: CstType.STRUCTURED,
85
- definitionFormal: 'ℬ(X1×X1)'
86
- }
87
- }
88
- });
89
- await client.call('addOrUpdateConstituenta', {
90
- sessionId,
91
- input: {
92
- draft: { id: 3, alias: 'D1', cstType: CstType.TERM, definitionFormal: 'Pr1(S1)' }
93
- }
94
- });
95
72
 
96
73
  const diagnostics = await client.call('listDiagnostics', { sessionId });
97
74
  console.log(diagnostics);
@@ -99,34 +76,48 @@ console.log(diagnostics);
99
76
  await client.close();
100
77
  ```
101
78
 
102
- ## Manual stdio
79
+ Manual stdio is one JSON request per line:
103
80
 
104
- Start wrapper in one terminal:
105
-
106
- ```bash
107
- npx rstool-wrapper
81
+ ```jsonl
82
+ { "id": "1", "method": "createSession", "params": {} }
83
+ { "id": "2", "method": "addOrUpdateConstituenta", "params": { "sessionId": "...", "input": { "draft": { "id": 1, "alias": "X1", "cstType": "basic", "definitionFormal": "" } } } }
108
84
  ```
109
85
 
110
- Paste one JSON request per line after the ready line appears:
86
+ ## Export / Import
111
87
 
112
- ```json
113
- { "id": "1", "method": "createSession", "params": {} }
88
+ ```ts
89
+ const payload = tool.exportSession(sessionId);
90
+ const restored = tool.importSession(payload);
114
91
  ```
115
92
 
116
- Use the returned `sessionId` in subsequent lines:
93
+ Export includes session state and model values.
117
94
 
118
- ```json
119
- { "id": "2", "method": "addOrUpdateConstituenta", "params": { "sessionId": "...", "input": { "draft": { "id": 1, "alias": "X1", "cstType": "basic", "definitionFormal": "" } } } }
120
- { "id": "3", "method": "addOrUpdateConstituenta", "params": { "sessionId": "...", "input": { "draft": { "id": 2, "alias": "S1", "cstType": "structure", "definitionFormal": "ℬ(X1×X1)" } } } }
121
- { "id": "4", "method": "addOrUpdateConstituenta", "params": { "sessionId": "...", "input": { "draft": { "id": 3, "alias": "D1", "cstType": "term", "definitionFormal": "Pr1(S1)" } } } }
122
- { "id": "5", "method": "listDiagnostics", "params": { "sessionId": "..." } }
95
+ ## Evaluation
96
+
97
+ ```ts
98
+ tool.setConstituentaValue(sessionId, {
99
+ target: 1,
100
+ value: { 0: 'zero', 1: 'one' }
101
+ });
102
+
103
+ const scratch = tool.evaluateExpression(sessionId, {
104
+ expression: '1+2',
105
+ cstType: CstType.TERM
106
+ });
107
+
108
+ console.log(scratch.success, scratch.value); // true, 3
123
109
  ```
124
110
 
125
- ## Export a small RSForm session
111
+ For stored definitions, set values for `basic`, `constant`, and `structure`, then call `evaluateConstituenta` or `recalculateModel`.
112
+
113
+ ## Semantic Smoke Test
114
+
115
+ When syntax is valid but meaning is uncertain, build a tiny model and assert the value.
126
116
 
127
117
  ```ts
128
- import { CstType, RSToolAgent } from '@rsconcept/rstool';
118
+ import { CstType, EvalStatus, RSToolAgent } from '@rsconcept/rstool';
129
119
 
120
+ const TUPLE_ID = -111;
130
121
  const tool = new RSToolAgent();
131
122
  const { sessionId } = tool.createSession();
132
123
 
@@ -134,62 +125,48 @@ tool.addOrUpdateConstituenta(sessionId, {
134
125
  draft: { id: 1, alias: 'X1', cstType: CstType.BASE, definitionFormal: '' }
135
126
  });
136
127
  tool.addOrUpdateConstituenta(sessionId, {
137
- draft: { id: 2, alias: 'C1', cstType: CstType.CONSTANT, definitionFormal: '' }
138
- });
139
- tool.addOrUpdateConstituenta(sessionId, {
140
- draft: {
141
- id: 3,
142
- alias: 'S1',
143
- cstType: CstType.STRUCTURED,
144
- definitionFormal: 'ℬ(X1×X1)',
145
- convention: 'Pairs (parent, child) over X1.'
146
- }
147
- });
148
- tool.addOrUpdateConstituenta(sessionId, {
149
- draft: { id: 4, alias: 'D1', cstType: CstType.TERM, definitionFormal: 'Pr1(S1)' }
128
+ draft: { id: 2, alias: 'S1', cstType: CstType.STRUCTURED, definitionFormal: 'ℬ(X1×X1)' }
150
129
  });
151
130
  tool.addOrUpdateConstituenta(sessionId, {
152
- draft: { id: 5, alias: 'A1', cstType: CstType.AXIOM, definitionFormal: '1=1' }
131
+ draft: { id: 3, alias: 'D1', cstType: CstType.TERM, definitionFormal: 'Pr1(S1)' }
153
132
  });
154
133
 
155
- const payload = tool.exportSession(sessionId);
156
- console.log(payload);
157
- ```
158
-
159
- ## Model and evaluation
160
-
161
- Full kinship modeling (`S1` values as tuples, `Pr1(S1)`, …): `examples/build-kinship-rsmodel.ts`.
162
-
163
- Minimal evaluation after bindings:
164
-
165
- ```ts
166
- tool.setConstituentaValue(sessionId, {
167
- target: 1,
168
- value: { 0: 'zero', 1: 'one' }
134
+ tool.setConstituentaValues(sessionId, {
135
+ items: [
136
+ { target: 1, value: { 0: 'ann', 1: 'bob', 2: 'cat' } },
137
+ {
138
+ target: 2,
139
+ value: [
140
+ [TUPLE_ID, 0, 1],
141
+ [TUPLE_ID, 0, 2]
142
+ ]
143
+ }
144
+ ]
169
145
  });
170
146
 
171
- const evaluated = tool.evaluateConstituenta(sessionId, {
172
- constituentId: 4 // D1 = Pr1(S1); needs S1 interpreted — see kinship example
173
- });
174
- console.log(evaluated.success, evaluated.value);
147
+ const result = tool.evaluateConstituenta(sessionId, { constituentId: 3 });
148
+
149
+ if (!result.success || result.status !== EvalStatus.HAS_DATA || JSON.stringify(result.value) !== '[0]') {
150
+ throw new Error(`Expected Pr1(S1) to select the first coordinate; got ${JSON.stringify(result)}`);
151
+ }
175
152
  ```
176
153
 
154
+ Use this pattern for tests that protect important definitions. Full kinship model: `../../examples/build-kinship-rsmodel.ts`. More notes: `../../docs/MODEL-TESTING.md`.
155
+
177
156
  ## Common mistakes
178
157
 
179
- | Mistake | Symptom |
180
- | -------------------------------------------------- | ------------------------------------------------ |
181
- | `definitionFormal: 'Z'` on `X1` (`basic`) | `0x8862` definitionNotAllowed |
182
- | `D1` uses `D2` before `D2` exists | globalNotTyped / undeclared global |
183
- | `analyzeExpression` with wrong `cstType` | Role-specific semantic errors |
184
- | Non-empty formal on `C1` (`constant`) | Same as basic definition not allowed |
185
- | `term` with `X1×X1` when modeling a **relation** | Full Cartesian product instead of typed pairs in `S#` |
186
- | `structure` with `Pr1(S1)` instead of a grade | Wrong role — projections belong on `term` / `F#` |
187
- | `setConstituentaValue` on inferrable `D1` (`term`) | Error: inferrable and cannot be set directly |
188
- | Evaluating before base binding set | May fail or return empty depending on expression |
158
+ - `definitionFormal: 'Z'` on `basic` / `constant` → `definitionNotAllowed`.
159
+ - `D1` uses `D2` before `D2` exists → global not typed / undeclared.
160
+ - Wrong `cstType` in `analyzeExpression` role-specific errors.
161
+ - `term` with `X1×X1` for a relation full Cartesian product, not relation typification.
162
+ - `structure` with `Pr1(S1)` → wrong role; projections belong on `term` / `function`.
163
+ - `setConstituentaValue` on `term`, `axiom`, or `statement` cannot set computed constituents directly.
164
+ - Evaluation before base bindings missing value, empty result, or evaluation failure.
189
165
 
190
- ## Fixing a syntax error
166
+ ## Fix Syntax
191
167
 
192
168
  1. `analyzeExpression` with the broken fragment and correct `cstType`.
193
- 2. Read first diagnostic `{ from, to, code }`.
194
- 3. Edit substring of `definitionFormal` at those offsets.
195
- 4. `addOrUpdateConstituenta` again with the same `id` / `alias`.
169
+ 2. Read `{ code, from, to, params }`.
170
+ 3. Edit the substring of `definitionFormal` at those offsets.
171
+ 4. Re-run analysis.
172
+ 5. Upsert with the same `id` / `alias`.