@rsconcept/rstool 0.2.1 → 0.4.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/README.md +3 -1
- package/dist/index-uhkmwruf.d.ts +46 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2 -2
- package/dist/mappers/model-adapter.d.ts +1 -1
- package/dist/mappers/schema-adapter.d.ts +1 -1
- package/dist/models/index.d.ts +5 -4
- package/dist/models/index.js +2 -2
- package/dist/models/rstool-agent.d.ts +1 -1
- package/dist/models/rstool-agent.js +1 -92
- package/dist/models/session.d.ts +1 -1
- package/dist/models/tool-contract.d.ts +1 -1
- package/dist/models/tool-contract.js +1 -1
- package/dist/models/tool-contract.js.map +1 -1
- package/dist/rstool-agent-BZi5jO1y.js +158 -0
- package/dist/rstool-agent-BZi5jO1y.js.map +1 -0
- package/dist/{rstool-agent-DkeH5Qml.d.ts → rstool-agent-pRaPnZay.d.ts} +6 -4
- package/dist/session/session-store.d.ts +2 -1
- package/dist/session/session-store.js +3 -0
- package/dist/session/session-store.js.map +1 -1
- package/dist/{session-BHGCCLfQ.d.ts → session-BPgsE80c.d.ts} +12 -1
- package/dist/{tool-contract-CsGqg_0P.d.ts → tool-contract-n1ghUOrK.d.ts} +5 -3
- package/dist/wrapper/stdio-wrapper.js +13 -1
- package/dist/wrapper/stdio-wrapper.js.map +1 -1
- package/docs/CONCEPTUAL-SCHEMA.md +50 -140
- package/docs/CONSTITUENTA.md +37 -62
- package/docs/DIAGNOSTICS.md +85 -130
- package/docs/DOMAIN.md +68 -91
- package/docs/GRAMMAR-REF.md +35 -86
- package/docs/MODEL-TESTING.md +57 -0
- package/docs/PORTAL-API.md +22 -36
- package/docs/README.md +14 -13
- package/docs/SYNTAX.md +49 -104
- package/docs/TYPIFICATION.md +41 -60
- package/package.json +1 -1
- package/skills/README.md +6 -8
- package/skills/rstool-helper/EXAMPLES.md +91 -105
- package/skills/rstool-helper/GUIDE.md +67 -114
- package/skills/rstool-helper/REFERENCE.md +43 -11
- package/skills/rstool-helper/SKILL.md +5 -8
- package/src/index.ts +6 -0
- package/src/models/index.ts +8 -0
- package/src/models/portal-json.ts +45 -0
- package/src/models/rstool-agent.test.ts +98 -0
- package/src/models/rstool-agent.ts +72 -4
- package/src/models/session.ts +11 -0
- package/src/models/tool-contract.ts +3 -1
- package/src/session/session-store.ts +3 -0
- package/src/wrapper/stdio-wrapper.ts +14 -0
- package/dist/models/rstool-agent.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-wrapper.js","names":[],"sources":["../../src/wrapper/stdio-wrapper.ts"],"sourcesContent":["#!/usr/bin/env node\nimport readline from 'node:readline';\n\nimport { RSToolAgent } from '../models/rstool-agent';\n\ninterface StdioRequest {\n id: string | number;\n method: string;\n params?: unknown;\n}\n\ninterface StdioResponse {\n id: string | number | null;\n ok: boolean;\n result?: unknown;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nconst tool = new RSToolAgent();\n\nconst METHODS = [\n 'createSession',\n 'addOrUpdateConstituenta',\n 'analyzeExpression',\n 'getFormState',\n 'listDiagnostics',\n 'commitStep',\n 'exportSession',\n 'importSession',\n 'setConstituentaValue',\n 'setConstituentaValues',\n 'clearConstituentaValues',\n 'getModelState',\n 'evaluateExpression',\n 'evaluateConstituenta',\n 'recalculateModel'\n] as const;\n\nfunction writeResponse(response: StdioResponse): void {\n if (!process.stdout.writable || process.stdout.destroyed || process.stdout.writableEnded) {\n return;\n }\n try {\n process.stdout.write(`${JSON.stringify(response)}\\n`);\n } catch {\n // The client might have already closed stdout (EPIPE). Safe to ignore.\n }\n}\n\nfunction asObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(input: Record<string, unknown>, key: string): string {\n const value = input[key];\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Missing or invalid \"${key}\"`);\n }\n return value;\n}\n\nasync function handleRequest(request: StdioRequest): Promise<StdioResponse> {\n try {\n const params = asObject(request.params);\n switch (request.method) {\n case 'ping':\n return { id: request.id, ok: true, result: { pong: true } };\n case 'methods':\n return { id: request.id, ok: true, result: METHODS };\n case 'createSession':\n return {\n id: request.id,\n ok: true,\n result: tool.createSession(params.initial as never)\n };\n case 'addOrUpdateConstituenta':\n return {\n id: request.id,\n ok: true,\n result: tool.addOrUpdateConstituenta(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'analyzeExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.analyzeExpression(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'getFormState':\n return {\n id: request.id,\n ok: true,\n result: tool.getFormState(requiredString(params, 'sessionId'))\n };\n case 'listDiagnostics':\n return {\n id: request.id,\n ok: true,\n result: tool.listDiagnostics(requiredString(params, 'sessionId'), params.filters as never)\n };\n case 'commitStep':\n return {\n id: request.id,\n ok: true,\n result: tool.commitStep(requiredString(params, 'sessionId'), params.message as string | undefined)\n };\n case 'exportSession':\n return {\n id: request.id,\n ok: true,\n result: tool.exportSession(requiredString(params, 'sessionId'))\n };\n case 'importSession':\n return {\n id: request.id,\n ok: true,\n result: tool.importSession(requiredString(params, 'payload'))\n };\n case 'setConstituentaValue':\n return {\n id: request.id,\n ok: true,\n result: await tool.setConstituentaValue(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'setConstituentaValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.setConstituentaValues(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'clearConstituentaValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.clearConstituentaValues(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'getModelState':\n return {\n id: request.id,\n ok: true,\n result: tool.getModelState(requiredString(params, 'sessionId'))\n };\n case 'evaluateExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluateExpression(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'evaluateConstituenta':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluateConstituenta(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'recalculateModel':\n return {\n id: request.id,\n ok: true,\n result: tool.recalculateModel(requiredString(params, 'sessionId'))\n };\n default:\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'METHOD_NOT_FOUND',\n message: `Unknown method: ${request.method}`\n }\n };\n }\n } catch (error) {\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error\n }\n };\n }\n}\n\nconst input = readline.createInterface({\n input: process.stdin,\n crlfDelay: Infinity\n});\n\nwriteResponse({\n id: null,\n ok: true,\n result: {\n ready: true,\n wrapper: 'rstool-stdio',\n contractVersion: tool.contractVersion\n }\n});\n\ninput.on('line', line => {\n if (!line.trim()) {\n return;\n }\n try {\n const request = JSON.parse(line) as StdioRequest;\n if (!('id' in request) || !('method' in request)) {\n throw new Error('Request must include \"id\" and \"method\"');\n }\n void handleRequest(request).then(writeResponse);\n } catch (error) {\n writeResponse({\n id: null,\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: error instanceof Error ? error.message : 'Invalid JSON'\n }\n });\n }\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stdio-wrapper.js","names":[],"sources":["../../src/wrapper/stdio-wrapper.ts"],"sourcesContent":["#!/usr/bin/env node\nimport readline from 'node:readline';\n\nimport { RSToolAgent } from '../models/rstool-agent';\n\ninterface StdioRequest {\n id: string | number;\n method: string;\n params?: unknown;\n}\n\ninterface StdioResponse {\n id: string | number | null;\n ok: boolean;\n result?: unknown;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nconst tool = new RSToolAgent();\n\nconst METHODS = [\n 'createSession',\n 'addOrUpdateConstituenta',\n 'analyzeExpression',\n 'getFormState',\n 'listDiagnostics',\n 'commitStep',\n 'exportSession',\n 'exportPortalSchema',\n 'exportPortalModel',\n 'importSession',\n 'setConstituentaValue',\n 'setConstituentaValues',\n 'clearConstituentaValues',\n 'getModelState',\n 'evaluateExpression',\n 'evaluateConstituenta',\n 'recalculateModel'\n] as const;\n\nfunction writeResponse(response: StdioResponse): void {\n if (!process.stdout.writable || process.stdout.destroyed || process.stdout.writableEnded) {\n return;\n }\n try {\n process.stdout.write(`${JSON.stringify(response)}\\n`);\n } catch {\n // The client might have already closed stdout (EPIPE). Safe to ignore.\n }\n}\n\nfunction asObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(input: Record<string, unknown>, key: string): string {\n const value = input[key];\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Missing or invalid \"${key}\"`);\n }\n return value;\n}\n\nasync function handleRequest(request: StdioRequest): Promise<StdioResponse> {\n try {\n const params = asObject(request.params);\n switch (request.method) {\n case 'ping':\n return { id: request.id, ok: true, result: { pong: true } };\n case 'methods':\n return { id: request.id, ok: true, result: METHODS };\n case 'createSession':\n return {\n id: request.id,\n ok: true,\n result: tool.createSession(params.initial as never)\n };\n case 'addOrUpdateConstituenta':\n return {\n id: request.id,\n ok: true,\n result: tool.addOrUpdateConstituenta(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'analyzeExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.analyzeExpression(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'getFormState':\n return {\n id: request.id,\n ok: true,\n result: tool.getFormState(requiredString(params, 'sessionId'))\n };\n case 'listDiagnostics':\n return {\n id: request.id,\n ok: true,\n result: tool.listDiagnostics(requiredString(params, 'sessionId'), params.filters as never)\n };\n case 'commitStep':\n return {\n id: request.id,\n ok: true,\n result: tool.commitStep(requiredString(params, 'sessionId'), params.message as string | undefined)\n };\n case 'exportSession':\n return {\n id: request.id,\n ok: true,\n result: tool.exportSession(requiredString(params, 'sessionId'))\n };\n case 'exportPortalSchema':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortalSchema(requiredString(params, 'sessionId'))\n };\n case 'exportPortalModel':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortalModel(requiredString(params, 'sessionId'))\n };\n case 'importSession':\n return {\n id: request.id,\n ok: true,\n result: tool.importSession(requiredString(params, 'payload'))\n };\n case 'setConstituentaValue':\n return {\n id: request.id,\n ok: true,\n result: await tool.setConstituentaValue(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'setConstituentaValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.setConstituentaValues(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'clearConstituentaValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.clearConstituentaValues(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'getModelState':\n return {\n id: request.id,\n ok: true,\n result: tool.getModelState(requiredString(params, 'sessionId'))\n };\n case 'evaluateExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluateExpression(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'evaluateConstituenta':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluateConstituenta(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'recalculateModel':\n return {\n id: request.id,\n ok: true,\n result: tool.recalculateModel(requiredString(params, 'sessionId'))\n };\n default:\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'METHOD_NOT_FOUND',\n message: `Unknown method: ${request.method}`\n }\n };\n }\n } catch (error) {\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error\n }\n };\n }\n}\n\nconst input = readline.createInterface({\n input: process.stdin,\n crlfDelay: Infinity\n});\n\nwriteResponse({\n id: null,\n ok: true,\n result: {\n ready: true,\n wrapper: 'rstool-stdio',\n contractVersion: tool.contractVersion\n }\n});\n\ninput.on('line', line => {\n if (!line.trim()) {\n return;\n }\n try {\n const request = JSON.parse(line) as StdioRequest;\n if (!('id' in request) || !('method' in request)) {\n throw new Error('Request must include \"id\" and \"method\"');\n }\n void handleRequest(request).then(writeResponse);\n } catch (error) {\n writeResponse({\n id: null,\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: error instanceof Error ? error.message : 'Invalid JSON'\n }\n });\n }\n});\n"],"mappings":"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"}
|
|
@@ -1,168 +1,78 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Концептуальная схема
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Справка про проектирование КС как системы определений. Для механики см. `CONSTITUENTA.md`, `SYNTAX.md`, `TYPIFICATION.md`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `SYNTAX.md` / `TYPIFICATION.md` — how to construct correct RS expressions
|
|
5
|
+
## Цель схемы
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
КС ценна не числом конституент, а различениями, которые она вводит.
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
- Добавляй понятие, если оно дает новый критерий, роль, отношение, инвариант или правило.
|
|
10
|
+
- Если пользователь постоянно переформулирует одно различие, введи отдельную конституенту.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## Текстовые поля
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
- “Diversity” is not the same as “many aliases”. Prefer concepts that introduce **new distinctions** (new criteria, roles, constraints, invariants) instead of synonyms.
|
|
14
|
+
`term`, `definitionText`, `convention` держи в языке схемы и в ее словаре.
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
- `term` — короткое имя понятия.
|
|
17
|
+
- `definitionText` — текстовая интерпретация формального определения.
|
|
18
|
+
- `convention` — соглашение для неопределяемого понятия.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
- If stakeholders keep rephrasing the same thing in different words, the schema likely misses one or more constituents that capture the missing distinction.
|
|
20
|
+
Перед записью `definitionText` проверь существительные: важный предметный термин должен быть введен как `N#`, `X#`, `C#`, `S#` или `D#`.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Номиноиды и атрибутирование
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
`N#` — номиноид: именованная сущность для словаря схемы. Он помогает фиксировать термин до точной родоструктурной формализации.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
Атрибутирование связывает номиноид с другими конституентами через атрибуты. Это отдельная атрибутивная экспликация, не замена `S#`, `D#`, `A#` в родоструктурной экспликации.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Правило для `rstool`: не смешивай атрибутивную и родоструктурную экспликацию. Используй `N#` как словарную опору, но не превращай атрибуты в RS-формулы и не добавляй атрибутивные связи, если пользователь явно не просит совместить эти способы.
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
## Родовые структуры
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
`S#` — родовая структура. Ее `definitionFormal` задает типизацию, а смысл задают конвенция, интерпретация и аксиомы.
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
- Prefer short “closed-world” definitions: explain a concept using already-introduced schema terms plus logical connectives (“and”, “or”, “not”), quantifiers (“for all”, “exists”), and references to RS expressions.
|
|
34
|
+
Паттерн для отношения:
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
1. `X1` — базисное множество.
|
|
37
|
+
2. `S1: ℬ(X1×X1)` — отношение; порядок пары описан в `convention`.
|
|
38
|
+
3. `D# := Pr1(S1)`, `D# := Pr2(S1)` — именованные компоненты.
|
|
39
|
+
4. Сложные термы строятся поверх этих `D#`.
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
Если повторяется цепочка вроде `Pr2(Fi1[D](S7))`, введи промежуточный терм или уточни конвенцию/аксиому для `S7`.
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
## Аксиомы
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
`A#` — логическое требование к модели. Используй аксиомы, чтобы:
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
- фиксировать смысл `S#`;
|
|
48
|
+
- задавать уникальность, тотальность, непересечение, порядок, область и диапазон;
|
|
49
|
+
- оправдывать `debool(...)`: внутреннее множество должно быть гарантированно одноэлементным.
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
- It shortens later formulas and prevents agents from repeating long projection chains differently in different places.
|
|
51
|
+
## Проверка на маленькой модели
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
Когда семантика определения не очевидна, используй концептуальную модель как тестовый стенд: задай минимальные значения для `X#`, `C#`, `S#` и вычисли проверяемые `D#`, `F#`, `P#`, `A#`.
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
- `S1 : ℬ(X1×X1)` — relation as a structure (undefined, meaning via convention)
|
|
54
|
-
- Component terms:
|
|
55
|
-
- `D_dom := Pr1(S1)` — “domain” / “left elements”
|
|
56
|
-
- `D_cod := Pr2(S1)` — “codomain” / “right elements”
|
|
57
|
-
- `D_pairs := red(bool(S1))` is usually nonsense; instead name the parts you truly use
|
|
58
|
-
- For higher-arity structures, define `Pr1`, `Pr2`, … and relevant multi-projections (`Pr1,3`, etc.)
|
|
55
|
+
Это особенно полезно для проекций, фильтров, `red`, `bool` / `debool` и аксиом. Если проверка важна для будущих изменений, перенеси ее в скрипт-тест: собрать маленькую сессию, задать значения неопределяемых конституент, вычислить целевые конституенты и проверить не только `success`, но и ожидаемое `value`.
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
Подробный цикл: `MODEL-TESTING.md`.
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
- **Reduce** (`red`) is useful when a component is a set-of-sets and you need a flattened union; introduce a named `D#` when you use `red` in more than one place.
|
|
59
|
+
## Быстрое ревью
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
- Атрибутивная экспликация не смешана с родоструктурной без явного запроса пользователя.
|
|
62
|
+
- Не добавляй проверки принадлежности к собственной типизации: если `x` уже объявлен в `X1`, `x ∈ X1` избыточно.
|
|
63
|
+
- Покрыты главные предметные сущности, роли, отношения и утверждения.
|
|
64
|
+
- Слои идут так: `X#`/`C#` → `S#` → простые `D#` → сложные `D#`/`F#`/`P#` → `A#`/`T#`.
|
|
65
|
+
- У каждой аксиомы понятная цель.
|
|
66
|
+
- Частые падения аксиом в модели указывают на ошибку данных или семантики схемы.
|
|
67
|
+
- Сомнительные выражения проверены на маленькой КМ, если есть показательные тестовые данные.
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
## Рабочий порядок
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
## Axioms as semantic direction
|
|
78
|
-
|
|
79
|
-
An axiom `A#` is a **true statement** that:
|
|
80
|
-
|
|
81
|
-
- defines the intended semantics of genus structures, and
|
|
82
|
-
- enables safe derivations (“in a certain direction”) by providing guarantees needed for operations.
|
|
83
|
-
|
|
84
|
-
Think of axioms as giving you _permission to use certain operators_ without risking typification/runtime failures or semantic ambiguity.
|
|
85
|
-
|
|
86
|
-
### Example: singleton guarantee for `debool`
|
|
87
|
-
|
|
88
|
-
`debool(S)` is only meaningful when `S` is guaranteed to be a **singleton**.
|
|
89
|
-
|
|
90
|
-
In practice, when you build `S` as a projection/filter result, you often need an axiom that guarantees uniqueness.
|
|
91
|
-
|
|
92
|
-
For example, for a binary relation `S1 : ℬ(X1×X1)` you may want to define a function-like choice:
|
|
93
|
-
|
|
94
|
-
- `D_childOf(x) := debool(Pr2(Fi1[bool(x)](S1)))`
|
|
95
|
-
|
|
96
|
-
This is only valid if for every `x` the filtered projection yields exactly one element.
|
|
97
|
-
That guarantee is provided by an axiom of **right-uniqueness** (functional dependency) for the relation (written in RS logic for your specific structure).
|
|
98
|
-
|
|
99
|
-
Agent rule:
|
|
100
|
-
|
|
101
|
-
- If you see `debool(...)` in a definition, ensure there is an axiom that makes the inner set a singleton on the intended domain.
|
|
102
|
-
- If the axiom is absent, either (a) add the axiom, (b) replace `debool` by keeping the set-valued result, or (c) restrict the domain explicitly so the singleton property holds.
|
|
103
|
-
|
|
104
|
-
## Expression hygiene: avoid tautological membership checks
|
|
105
|
-
|
|
106
|
-
In well-typed/correct RS expressions, you should avoid adding membership predicates that only restate what is already guaranteed by typification and by the correctness model.
|
|
107
|
-
|
|
108
|
-
Specifically, avoid “sanity checks” like:
|
|
109
|
-
|
|
110
|
-
- `x ∈ X1`
|
|
111
|
-
- `x ∈ ℬ(X1)` (and other plain grade constructions such as `X1×X2`, `B(X1)`, etc.)
|
|
112
|
-
|
|
113
|
-
when `x` is already bound/typed as an element compatible with `X1` (or with the intended element structure induced by `ℬ(X1)`, `X1×X2`, …).
|
|
114
|
-
|
|
115
|
-
Why this is usually meaningless:
|
|
116
|
-
|
|
117
|
-
- `AnalysisResult` checks expressions in a **global context** where identifiers must have known typifications and must satisfy **bijective portability**.
|
|
118
|
-
- Under these guarantees, values of an element grade “already belong” to the corresponding set/grade in the semantic sense; so the predicate becomes (effectively) TRUE and adds no discriminating information.
|
|
119
|
-
|
|
120
|
-
Agent rule:
|
|
121
|
-
|
|
122
|
-
- Use membership (`∈` / `Fi*`) to express *nontrivial* schema semantics (e.g. defining/characterising derived sets), not to re-check that a value matches its own typification.
|
|
123
|
-
|
|
124
|
-
## Bijective portability (биективная переносимость)
|
|
125
|
-
|
|
126
|
-
**Bijective portability** means that a formal meaning/definition of a constituent depends only on the *structure* that the schema intends, and not on arbitrary “names” of undefined-concept interpretations.
|
|
127
|
-
|
|
128
|
-
Concretely, if you replace interpretations of undefined concepts by a bijective renaming (structure-preserving renaming), then:
|
|
129
|
-
|
|
130
|
-
- the evaluation result of every bijectively portable definition is unchanged up to the same renaming,
|
|
131
|
-
- therefore definitions are stable and reusable across equivalent models.
|
|
132
|
-
|
|
133
|
-
In rstool’s correctness model this property is not optional for the formal part:
|
|
134
|
-
|
|
135
|
-
- all formal definitions are required to be **bijectively portable**,
|
|
136
|
-
- expression checking assumes bijective portability for every referenced identifier.
|
|
137
|
-
|
|
138
|
-
Because of this, membership checks against base sets/grades become redundant in correct expressions: the type discipline plus portability already guarantee the relevant “belonging” constraints.
|
|
139
|
-
|
|
140
|
-
## Analysis: how to review a schema as a system
|
|
141
|
-
|
|
142
|
-
### Thesaurus health
|
|
143
|
-
|
|
144
|
-
- **Coverage**: do core domain nouns/roles appear as constituents (`N#`, `X#`, `S#`, `D#`)?
|
|
145
|
-
- **Non-synonymy**: if two terms are interchangeable in all axioms/definitions, collapse or differentiate them.
|
|
146
|
-
- **Naming stability**: avoid renaming “public” terms frequently; prefer adding refined terms and marking old ones as deprecated in text (if your workflow supports that).
|
|
147
|
-
|
|
148
|
-
### Term graph health (dependencies)
|
|
149
|
-
|
|
150
|
-
- Prefer a **layered graph**: bases/constants → core structures → derived projections/components → higher-level derived concepts → axioms/statements.
|
|
151
|
-
|
|
152
|
-
### Axiom health
|
|
153
|
-
|
|
154
|
-
- Every axiom should have a clear intent: uniqueness, totality, disjointness, ordering, invariance, domain/range constraints, etc.
|
|
155
|
-
- Prefer a small set of high-leverage axioms that unlock safe derivations, rather than many weak axioms with overlapping meaning.
|
|
156
|
-
- If axioms regularly fail in model evaluation, either the interpretation data violates the intended semantics or the semantics are wrong — in both cases the schema needs revision.
|
|
157
|
-
|
|
158
|
-
## Practical workflow for agents (recommended)
|
|
159
|
-
|
|
160
|
-
1. **Start with a vocabulary list** (domain nouns, roles, relations) → introduce `N#` for stable names when formalisation is not ready yet.
|
|
161
|
-
2. **Introduce bases/constants** (`X#`, `C#`) early with conventions.
|
|
162
|
-
3. **Introduce core structures** (`S#`) with typifications + conventions; immediately add the most important component terms (`Pr*`, `red`-based terms).
|
|
163
|
-
4. **Add derived concepts** (`D#`, `F#`, `P#`) incrementally; keep definitions short by using named components.
|
|
164
|
-
5. **Add axioms** (`A#`) that:
|
|
165
|
-
- encode intended semantics of structures,
|
|
166
|
-
- justify `debool`/functional choices, and
|
|
167
|
-
- restrict domains/ranges so derived concepts remain meaningful.
|
|
168
|
-
6. Run analysis on scratch expressions before committing, and keep text definitions closed-world (schema terms only).
|
|
71
|
+
1. Собери словарь предметной области.
|
|
72
|
+
2. Добавь `X#` и `C#` с конвенциями.
|
|
73
|
+
3. Добавь ключевые `S#` с типизацией и конвенцией.
|
|
74
|
+
4. Назови важные компоненты через `D#`: `Pr*`, `pr*`, `red`.
|
|
75
|
+
5. Добавляй выводимые `D#`, `F#`, `P#` маленькими шагами.
|
|
76
|
+
6. Добавь `A#` и `T#` по необходимости.
|
|
77
|
+
7. Перед upsert проверяй `analyzeExpression`.
|
|
78
|
+
8. Для сомнительной семантики собери маленькую КМ и вычисли ожидаемые значения.
|
package/docs/CONSTITUENTA.md
CHANGED
|
@@ -1,78 +1,53 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Конституенты
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Читай перед `addOrUpdateConstituenta`.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Поля черновика
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| `definitionText` | optional | Natural-language definition / interpretation |
|
|
15
|
-
| `convention` | optional | Convention text for undefined concepts |
|
|
7
|
+
- `id` — стабильный id внутри сессии.
|
|
8
|
+
- `alias` — имя вида `X1`, `D5`, `F2`; префикс должен совпадать с `cstType`.
|
|
9
|
+
- `cstType` — роль конституенты.
|
|
10
|
+
- `definitionFormal` — формальное определение; для `basic` и `constant` строго `''`.
|
|
11
|
+
- `term` — естественно-языковое имя.
|
|
12
|
+
- `definitionText` — текстовая интерпретация формулы.
|
|
13
|
+
- `convention` — соглашение для неопределяемого понятия.
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
Пропущенные текстовые поля сохраняются как `''`. Пиши `term`, `definitionText`, `convention` на одном языке: в языке схемы или, для новой схемы, в языке запроса.
|
|
18
16
|
|
|
19
|
-
##
|
|
17
|
+
## `cstType`
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
- `nominal` / `N#` — номиноид. В родоструктурной экспликации не используется.
|
|
20
|
+
- `basic` / `X#` — базисное множество; формула пустая.
|
|
21
|
+
- `constant` / `C#` — константное множество; формула пустая.
|
|
22
|
+
- `structure` / `S#` — родовая структура; формула задает типизацию.
|
|
23
|
+
- `term` / `D#` — терм; формула задает вычисляемое значение.
|
|
24
|
+
- `function` / `F#` — терм-функция.
|
|
25
|
+
- `predicate` / `P#` — предикат-функция.
|
|
26
|
+
- `axiom` / `A#` — аксиома; нужна типизация `Logic`.
|
|
27
|
+
- `statement` / `T#` — высказывание; нужна типизация `Logic`.
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
- When creating a new schema from scratch, use the **language of the user’s request**.
|
|
29
|
+
`basic`, `constant`, `structure` можно интерпретировать через `setConstituentaValue`. `term`, `axiom`, `statement` вычисляются и напрямую не задаются.
|
|
25
30
|
|
|
26
|
-
## `
|
|
31
|
+
## `S#` и `D#`
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
| ----------------- | ------ | ------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
30
|
-
| `basic` (`X`) | `X#` | **must be empty** | Base set; non-empty formal → `definitionNotAllowed` |
|
|
31
|
-
| `constant` (`C`) | `C#` | **must be empty** | Constant set; same rule |
|
|
32
|
-
| `nominal` (`N`) | `N#` | allowed | Free vocabulary item, no semantic constraint |
|
|
33
|
-
| `structure` (`S`) | `S#` | allowed | **Base** structured concept; `definitionFormal` is its **typification** (grade), not a definition |
|
|
34
|
-
| `term` (`D`) | `D#` | allowed | **Derived** concept; `definitionFormal` is its **definition** (value computed in the model) |
|
|
35
|
-
| `axiom` (`A`) | `A#` | allowed (must be `Logic`) | Logical statement asserting a requirement |
|
|
36
|
-
| `statement` (`T`) | `T#` | allowed (must be `Logic`) | Logical assertion about the model |
|
|
37
|
-
| `function` (`F`) | `F#` | allowed (parameterised) | Term-function |
|
|
38
|
-
| `predicate` (`P`) | `P#` | allowed (parameterised) | Predicate-function |
|
|
33
|
+
`S#` — неопределяемая родовая структура. `definitionFormal: 'ℬ(X1×X1)'` описывает ступень элемента: множество пар над `X1`.
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
`D#` — терм. `definitionFormal: 'X1×X1'` строит полный декартов продукт.
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
- **Inferrable** (computed from definitions, never set directly): `term`, `axiom`, `statement`. Assigning to an inferrable raises an error.
|
|
37
|
+
Для бинарного отношения обычно нужно:
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
1. `X1` — базисное множество.
|
|
40
|
+
2. `S1` — `definitionFormal: 'ℬ(X1×X1)'`; конвенция объясняет порядок пары.
|
|
41
|
+
3. `D#` — проекции и фильтры: `Pr1(S1)`, `Pr2(S1)`, `Fi1[D1](S1)`.
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
Пример: `examples/build-kinship-rsform.ts`.
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
| ------------------ | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
51
|
-
| `definitionFormal` | **Typification** — which grade the elements have (e.g. `ℬ(X1×X1)` = set of pairs over `X1`) | **Definition** — how to obtain the concept (e.g. `Pr1(S1)` = first projection of relation `S1`) |
|
|
52
|
-
| Introduction | `convention` (+ optional axioms); interpretation from the subject domain | Formal expression only; interpretation is **evaluated** |
|
|
53
|
-
| `X1×X1` in context | Inside a grade: **one** pair type `(X1, X1)` | As the whole body: **Cartesian product** `X1 × X1` (all pairs) — rarely what you want for a relation |
|
|
45
|
+
## Валидация
|
|
54
46
|
|
|
55
|
-
|
|
47
|
+
1. Префикс `alias` соответствует `cstType`.
|
|
48
|
+
2. У `basic` и `constant` пустая формула, иначе `definitionNotAllowed` (`0x8862`).
|
|
49
|
+
3. Все глобальные ссылки уже есть в сессии.
|
|
50
|
+
4. `axiom` и `statement` имеют типизацию `Logic`, иначе `expectedLogic`.
|
|
51
|
+
5. Выводимая конституента с пустой формулой дает `cstEmptyDerived`.
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
2. `S1` — `definitionFormal: 'ℬ(X1×X1)'`, `convention` explains pair order (e.g. parent, child).
|
|
59
|
-
3. `D1` — `definitionFormal: 'Pr1(S1)'` (or filters / term-functions), `definitionText` explains the derived set.
|
|
60
|
-
|
|
61
|
-
Worked example: `examples/build-kinship-rsform.ts`.
|
|
62
|
-
|
|
63
|
-
## Validation rules
|
|
64
|
-
|
|
65
|
-
1. **Prefix ↔ `cstType`**: `alias` letter must match the type prefix.
|
|
66
|
-
2. **Empty formal for undefined concepts**: `basic` and `constant` must have `definitionFormal === ''`. Any non-empty value triggers `definitionNotAllowed` (`0x8862`).
|
|
67
|
-
3. **Dependency declaration order**: every global identifier referenced in `definitionFormal` must correspond to an already-upserted constituent in the session.
|
|
68
|
-
4. **Logical-only definitions**: `axiom` and `statement` definitions must typecheck to `Logic`; otherwise `expectedLogic`.
|
|
69
|
-
5. **Empty derived expression**: a derived constituent with empty `definitionFormal` triggers `cstEmptyDerived`.
|
|
70
|
-
|
|
71
|
-
## Recommended upsert order
|
|
72
|
-
|
|
73
|
-
1. All `basic` (`X#`) and `constant` (`C#`) constituents (empty formal).
|
|
74
|
-
2. Core `structure` (`S#`) and crucial concepts.
|
|
75
|
-
3. Topological order of derived concepts: every dependency upserted before its dependent.
|
|
76
|
-
4. Axioms and statements after the constituents they reference.
|
|
77
|
-
|
|
78
|
-
Use `analyzeExpression` on a scratch expression before upsert; use `addOrUpdateConstituenta` only when the expression typechecks. Read `result.diagnostics` for actionable error info and patch by `from`/`to` ranges.
|
|
53
|
+
Цикл: `analyzeExpression` на черновике → исправить `diagnostics[].from/to` → `addOrUpdateConstituenta`.
|