@fraczak/k 7.1.0 → 8.0.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/CHANGELOG.md +99 -0
- package/DOCS/BIG_PICTURE.md +54 -7
- package/DOCS/CODECS.md +47 -2
- package/DOCS/CODEC_ARCHITECTURE.md +14 -5
- package/DOCS/DICTIONARY.md +13 -4
- package/DOCS/FILE_FORMATS.md +3 -2
- package/DOCS/JSON_APPROACHES_COMPARISON.md +306 -0
- package/DOCS/NAMED_PATTERNS.md +317 -0
- package/DOCS/PATTERNS.md +59 -11
- package/DOCS/REPL.md +24 -5
- package/DOCS/WEB_REPL_REQUIREMENTS.md +4 -2
- package/Examples/arithmetics.k +22 -17
- package/Examples/bnat.k +21 -11
- package/Examples/buda.k +37 -20
- package/Examples/byte.k +3 -1
- package/Examples/code.k +38 -39
- package/Examples/djson-btrie.k +414 -0
- package/Examples/djson-ptrie.k +663 -0
- package/Examples/djson.k +323 -0
- package/Examples/esc.k +1 -1
- package/Examples/karatsuba-mult.k +16 -13
- package/Examples/list.k +8 -4
- package/Examples/nat.k +17 -11
- package/Examples/poly.k +11 -3
- package/Examples/vhdl_to_k.k +43 -31
- package/README.md +42 -15
- package/Value.mjs +28 -3
- package/backend-api.mjs +5 -1
- package/browser/repl-browser.mjs +6 -0
- package/browser/tree-view.mjs +82 -24
- package/browser/vfs-data.mjs +21 -12
- package/codecs/README.md +3 -0
- package/codecs/djson-btrie.mjs +560 -0
- package/codecs/djson-ptrie.mjs +587 -0
- package/codecs/djson.mjs +270 -0
- package/codecs/int.mjs +2 -1
- package/codecs/json.mjs +7 -2
- package/codecs/k-parse.mjs +7 -1
- package/codecs/k-print.mjs +4 -0
- package/codecs/runtime/codec-sdk.mjs +16 -2
- package/codecs/runtime/pattern-json.mjs +80 -1
- package/codecs/runtime/prefix-codec.mjs +629 -67
- package/codecs/runtime/show-value.mjs +93 -51
- package/codecs/runtime/unicode-string.mjs +29 -6
- package/codecs/show.mjs +4 -0
- package/codecs/utf16.mjs +2 -1
- package/core.k +79 -115
- package/index.mjs +3 -0
- package/named-patterns.mjs +267 -0
- package/object.mjs +31 -3
- package/package.json +5 -1
- package/parser.jison +68 -5
- package/parser.mjs +111 -60
- package/pretty.mjs +5 -0
- package/repl.mjs +245 -28
- package/scripts/build-repl-html.mjs +76 -5
- package/scripts/perf-djson.mjs +1142 -0
- package/scripts/run-tests.mjs +5 -0
- package/symbol-table.mjs +20 -2
- package/tests/bench-djson-tries.mjs +340 -0
- package/tests/test-codecs.mjs +211 -0
- package/tests/test-named-patterns.mjs +189 -0
- package/tests/test-repl-html.mjs +52 -4
- package/tests/test-repl.mjs +223 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Named Patterns and Parameterized Type Schemes in k
|
|
2
|
+
|
|
3
|
+
## 1. Overview and Motivation
|
|
4
|
+
|
|
5
|
+
Following commit `a4eec258`, type code expressions (`$ code`) were
|
|
6
|
+
removed in favor of pure filter relations (`? <...> = Self;`).
|
|
7
|
+
While this eliminated the redundant dual syntax of static codes versus
|
|
8
|
+
runtime filters, practical development (notably in `djson` variants and
|
|
9
|
+
standard libraries) revealed a major drawback: **loss of pattern
|
|
10
|
+
composition and reuse**.
|
|
11
|
+
|
|
12
|
+
Without named, reusable patterns:
|
|
13
|
+
- Monolithic structures (such as UTF-8 decoding and IEEE-754 bit
|
|
14
|
+
partitions) had to be copy-pasted inline across dozens of files.
|
|
15
|
+
- Common algebraic shapes like linked lists, pairs, dictionaries, and
|
|
16
|
+
tries could not be defined generically; each variant had to inline
|
|
17
|
+
its own structural definition.
|
|
18
|
+
- Filter relations (`rel?(x)`) perform runtime filtering but cannot be
|
|
19
|
+
used directly as structural type shapes inside other pattern
|
|
20
|
+
definitions.
|
|
21
|
+
|
|
22
|
+
This document establishes the specification for **Named Patterns**:
|
|
23
|
+
parameterized, compositional regular tree grammar templates that re-enable
|
|
24
|
+
reusable type definitions with zero syntax bloat, guaranteed
|
|
25
|
+
termination, and full integration with k's graph-based type system.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. The Core Model: Patterns as Open Directed Graphs
|
|
30
|
+
|
|
31
|
+
In k, all values, patterns, and type codes are directed graphs
|
|
32
|
+
representing regular tree languages. A named pattern definition:
|
|
33
|
+
|
|
34
|
+
```k
|
|
35
|
+
name[ P1, P2, ... Pn ] = pattern_graph;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
defines an **open directed graph** with an explicit boundary interface.
|
|
39
|
+
|
|
40
|
+
### 2.1 The Three Classes of Variables
|
|
41
|
+
|
|
42
|
+
Within a pattern definition, every variable identifier falls into one
|
|
43
|
+
of three orthogonal categories:
|
|
44
|
+
|
|
45
|
+
1. **External Ports ($\forall$ / Parameters)**:
|
|
46
|
+
Any variable listed in the header brackets `[ P1, ... Pn ]` is an
|
|
47
|
+
**external port**. These represent open inputs to be supplied by the
|
|
48
|
+
caller upon instantiation.
|
|
49
|
+
|
|
50
|
+
2. **Internal Variables ($\exists$ / Unification Nodes)**:
|
|
51
|
+
Any variable appearing on the right-hand side that is **not** listed
|
|
52
|
+
in `[ P1, ... Pn ]` is an **internal variable**.
|
|
53
|
+
- If an internal variable appears in multiple locations, it asserts
|
|
54
|
+
**structural type equality (unification)** between those sites.
|
|
55
|
+
- Internal variables are existentially quantified ($\exists$) and
|
|
56
|
+
scoped strictly to the pattern definition.
|
|
57
|
+
|
|
58
|
+
3. **Cycle Knots ($\mu$ / Fixpoints)**:
|
|
59
|
+
Any variable bound via `= KnotName` is an internal recursive knot.
|
|
60
|
+
It creates a back-edge in the directed graph, closing a loop.
|
|
61
|
+
Its scope is purely local: callers cannot see or reference it.
|
|
62
|
+
|
|
63
|
+
### 2.2 Knot and Variable Hiding ($\alpha$-Equivalence)
|
|
64
|
+
|
|
65
|
+
In:
|
|
66
|
+
|
|
67
|
+
```k
|
|
68
|
+
list[X] = < {}nil, { X car, Y cdr } cons > = Y;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- `X` is listed in `list[X]` $\implies$ **External Port**.
|
|
72
|
+
- `Y` is bound by `= Y` and omitted from `list[X]` $\implies$
|
|
73
|
+
**Internal Knot**.
|
|
74
|
+
|
|
75
|
+
`Y` is strictly encapsulated. It can be $\alpha$-renamed to any
|
|
76
|
+
internal node ID (`#knot_0`) without changing the pattern's external
|
|
77
|
+
interface or behavior. Callers only interact with the port `X`.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 3. The Four-Bracket Symmetry of k
|
|
82
|
+
|
|
83
|
+
Named patterns introduce square brackets `[...]` into k's grammar.
|
|
84
|
+
This completes an orthogonal four-bracket architecture where each
|
|
85
|
+
bracket style has a dedicated, non-overlapping semantic domain:
|
|
86
|
+
|
|
87
|
+
| Bracket Pair | Semantic Domain | Concrete Purpose |
|
|
88
|
+
| :--- | :--- | :--- |
|
|
89
|
+
| **`{ ... }`** | **Products** | Records, tuples, structs |
|
|
90
|
+
| **`< ... >`** | **Unions** | Variants, sums, choices |
|
|
91
|
+
| **`( ... )`** | **Relations** | Composition, grouping, identity |
|
|
92
|
+
| **`[ ... ]`** | **Patterns** | Type templates, instantiations |
|
|
93
|
+
|
|
94
|
+
No dollar prefix (`$`) is needed anywhere in the language.
|
|
95
|
+
|
|
96
|
+
### 3.1 Unambiguous Lexical Distinction
|
|
97
|
+
|
|
98
|
+
Because all pattern references carry `[...]`, the lexical distinction
|
|
99
|
+
between variables and patterns is 100% deterministic:
|
|
100
|
+
|
|
101
|
+
- **Identifier without `[...]`** (`X`, `T`, `car`, `Y`):
|
|
102
|
+
- In label position: field or variant tag (`car`, `cdr`, `nil`).
|
|
103
|
+
- In pattern position: variable node (`X`, `T`, knot `Y`).
|
|
104
|
+
- **Identifier with `[...]`** (`bit[]`, `list[T]`, `pair[A, B]`):
|
|
105
|
+
- Always a pattern template lookup or instantiation.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 4. Internal Variables as Unification Knots
|
|
110
|
+
|
|
111
|
+
A critical insight of k's graph-based model is that unparameterized
|
|
112
|
+
patterns can contain internal variables to express equality
|
|
113
|
+
constraints across fields:
|
|
114
|
+
|
|
115
|
+
```k
|
|
116
|
+
byte[] = { bit 0, bit 1, ... };
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Here:
|
|
120
|
+
- `bit` does not have `[]`, so it is a **variable**, not a pattern.
|
|
121
|
+
- `bit` is not in the parameter list `byte[]`, so it is an **internal
|
|
122
|
+
node**.
|
|
123
|
+
- Because `bit` appears at both field `0` and field `1`, it asserts
|
|
124
|
+
that **field `0` and field `1` must share the exact same type**,
|
|
125
|
+
without constraining what that type must be.
|
|
126
|
+
|
|
127
|
+
### 4.1 Comparison of Pattern Declarations
|
|
128
|
+
|
|
129
|
+
```k
|
|
130
|
+
-- 1. Homogeneous pair of two fields of the SAME arbitrary type:
|
|
131
|
+
same_pair[] = { T first, T second };
|
|
132
|
+
|
|
133
|
+
-- 2. Heterogeneous pair parameterized by the caller:
|
|
134
|
+
pair[A, B] = { A first, B second };
|
|
135
|
+
|
|
136
|
+
-- 3. Pair of concrete bits:
|
|
137
|
+
bit_pair[] = { bit[] first, bit[] second };
|
|
138
|
+
|
|
139
|
+
-- 4. Instantiation enforcing equality via shared variable:
|
|
140
|
+
diagonal_pair[] = pair[T, T];
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
In `diagonal_pair[] = pair[T, T]`:
|
|
144
|
+
- `T` is an internal variable.
|
|
145
|
+
- Instantiating `pair` with `T` for both arguments unifies both ports,
|
|
146
|
+
producing a closed pattern requiring equal elements.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 5. Instantiation Semantics (Option B)
|
|
151
|
+
|
|
152
|
+
Arguments inside `[...]` may be either **variables** or **patterns**:
|
|
153
|
+
|
|
154
|
+
1. **Passing a Variable (`T`, `X`)**:
|
|
155
|
+
Connects the template's input port directly to that existing node in
|
|
156
|
+
the pattern graph, enabling node sharing, unification, and
|
|
157
|
+
polymorphic relations.
|
|
158
|
+
|
|
159
|
+
2. **Passing an Inline Pattern (`int[]`, `pair[K, V]`, `<{}0, {}1>`)**:
|
|
160
|
+
Creates an anonymous node representing the pattern and connects the
|
|
161
|
+
input port to it.
|
|
162
|
+
|
|
163
|
+
### 5.1 Equivalence to Variable Binding
|
|
164
|
+
|
|
165
|
+
Passing an inline pattern `P` is semantically equivalent to introducing
|
|
166
|
+
a fresh internal node variable:
|
|
167
|
+
|
|
168
|
+
$$name[P] \;\;\Longleftrightarrow\;\; (P = \_anon) \; name[\_anon]$$
|
|
169
|
+
|
|
170
|
+
Both forms construct isomorphic graph structures that minimize to the
|
|
171
|
+
exact same canonical DFA representation in `codes.mjs`.
|
|
172
|
+
|
|
173
|
+
### 5.2 Single-Step Finite Graph Substitution
|
|
174
|
+
|
|
175
|
+
Because recursive cycles are closed internally via knots (`= Y`),
|
|
176
|
+
instantiating a template does **not** require recursive unrolling or
|
|
177
|
+
fixpoint searching.
|
|
178
|
+
|
|
179
|
+
Instantiation is a single-step graph substitution:
|
|
180
|
+
1. Copy the template's graph structure (fresh private IDs for internal
|
|
181
|
+
knots).
|
|
182
|
+
2. Substitute the caller's arguments into the designated open port nodes.
|
|
183
|
+
3. Minimize via Hopcroft/Moore DFA partition refinement in `codes.mjs`.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 6. Safety Invariants and Termination
|
|
188
|
+
|
|
189
|
+
To guarantee decidability and termination:
|
|
190
|
+
|
|
191
|
+
1. **Acyclic Template Dependency Rule**:
|
|
192
|
+
A pattern template `$ name[...]` cannot reference `name` in its own
|
|
193
|
+
definition.
|
|
194
|
+
- All recursion **must** be expressed through internal knots (`= Y`).
|
|
195
|
+
- Consequently, the template dependency graph is a Strictly Acyclic
|
|
196
|
+
Directed Graph (DAG).
|
|
197
|
+
- Non-regular polymorphic recursion (nested datatypes) is structurally
|
|
198
|
+
impossible, guaranteeing that every instantiated pattern is a
|
|
199
|
+
finite regular tree automaton.
|
|
200
|
+
|
|
201
|
+
2. **Lexical Scope Independence**:
|
|
202
|
+
Internal variable names and knot names are strictly private to each
|
|
203
|
+
definition. Two patterns may both use knot name `Y` or variable `T`
|
|
204
|
+
without collision.
|
|
205
|
+
|
|
206
|
+
3. **Canonical Confluence**:
|
|
207
|
+
In k, type codes are structural, not nominal. Any two instantiations
|
|
208
|
+
that yield isomorphic regular tree automata produce identical
|
|
209
|
+
canonical hashes and wire encoders.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 7. Concrete Library Examples
|
|
214
|
+
|
|
215
|
+
### 7.1 Core Data Types
|
|
216
|
+
|
|
217
|
+
```k
|
|
218
|
+
-- Canonical bit and bit-path numbers:
|
|
219
|
+
bit[] = < {}0, {}1 >;
|
|
220
|
+
bits[] = < {} _, B 0, B 1 > = B;
|
|
221
|
+
|
|
222
|
+
-- Byte as an 8-bit octet product:
|
|
223
|
+
byte[] = {
|
|
224
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3,
|
|
225
|
+
bit[] 4, bit[] 5, bit[] 6, bit[] 7
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
-- 7-bit ASCII code points:
|
|
229
|
+
ascii[] = {
|
|
230
|
+
bit[] 6, bit[] 5, bit[] 4, bit[] 3,
|
|
231
|
+
bit[] 2, bit[] 1, bit[] 0
|
|
232
|
+
};
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 7.2 Generic Data Structures
|
|
236
|
+
|
|
237
|
+
```k
|
|
238
|
+
-- Generic pair:
|
|
239
|
+
pair[A, B] = { A fst, B snd };
|
|
240
|
+
|
|
241
|
+
-- Generic singly-linked list:
|
|
242
|
+
list[X] = < {}nil, { X car, Y cdr } cons > = Y;
|
|
243
|
+
|
|
244
|
+
-- Generic dictionary:
|
|
245
|
+
dict[K, V] = list[pair[K, V]];
|
|
246
|
+
|
|
247
|
+
-- Generic binary tree with internal knot T:
|
|
248
|
+
tree[X] = < {}nil, { X val, T left, T right } node > = T;
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### 7.3 Usage in Relations
|
|
252
|
+
|
|
253
|
+
```k
|
|
254
|
+
-- Type guard filter:
|
|
255
|
+
int? = ? int[];
|
|
256
|
+
|
|
257
|
+
-- Polymorphic list destructuring with type unification:
|
|
258
|
+
head = ? { X car, list[X] cdr } X;
|
|
259
|
+
|
|
260
|
+
-- Concrete typed list destructuring:
|
|
261
|
+
sum = ? { int[] = T car, list[T] cdr } ...;
|
|
262
|
+
|
|
263
|
+
-- Anonymous pattern matching:
|
|
264
|
+
validate_ints = ? list[int[]];
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 8. Summary of Grammar Extensions
|
|
270
|
+
|
|
271
|
+
### 8.1 Lexer Tokens
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
"[" return 'LB';
|
|
275
|
+
"]" return 'RB';
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### 8.2 Top-Level Definitions
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
defs
|
|
282
|
+
: /* empty */
|
|
283
|
+
| defs name eq comp sc
|
|
284
|
+
| defs name lb pattern_params rb eq filter sc
|
|
285
|
+
;
|
|
286
|
+
|
|
287
|
+
pattern_params
|
|
288
|
+
: /* empty */
|
|
289
|
+
| non_empty_pattern_params
|
|
290
|
+
;
|
|
291
|
+
|
|
292
|
+
non_empty_pattern_params
|
|
293
|
+
: name
|
|
294
|
+
| non_empty_pattern_params comma name
|
|
295
|
+
;
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### 8.3 Pattern References and Instantiations
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
filter_
|
|
302
|
+
: lp dots rp
|
|
303
|
+
| la labelled_filters ra
|
|
304
|
+
| lc labelled_filters rc
|
|
305
|
+
| name lb pattern_args rb
|
|
306
|
+
;
|
|
307
|
+
|
|
308
|
+
pattern_args
|
|
309
|
+
: /* empty */
|
|
310
|
+
| non_empty_pattern_args
|
|
311
|
+
;
|
|
312
|
+
|
|
313
|
+
non_empty_pattern_args
|
|
314
|
+
: filter
|
|
315
|
+
| non_empty_pattern_args comma filter
|
|
316
|
+
;
|
|
317
|
+
```
|
package/DOCS/PATTERNS.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# Schemas and Pattern Graphs
|
|
2
2
|
|
|
3
|
-
In `k`, an algebraic **schema** describes the shape of payload trees
|
|
4
|
-
through a relation. In compiler artifacts and
|
|
5
|
-
as property-list arrays of
|
|
3
|
+
In `k`, an algebraic **schema** describes the shape of payload trees
|
|
4
|
+
that may flow through a relation. In compiler artifacts and
|
|
5
|
+
serialization, schemas are represented as property-list arrays of
|
|
6
|
+
automata nodes. Schemas are used by:
|
|
6
7
|
|
|
7
8
|
- the contract-derivation engine
|
|
8
9
|
- the binary codec
|
|
9
10
|
- runtime framed values `(schema, payload)`
|
|
10
|
-
- filter expressions (`?schema`)
|
|
11
|
+
- filter expressions (`?schema` or `?name[...]`)
|
|
11
12
|
|
|
12
13
|
## Pattern Kinds
|
|
13
14
|
|
|
@@ -46,26 +47,68 @@ Example:
|
|
|
46
47
|
|
|
47
48
|
This is not the wire format. It is the canonical readable export form.
|
|
48
49
|
|
|
49
|
-
##
|
|
50
|
+
## Named Patterns and Templates
|
|
51
|
+
|
|
52
|
+
Named patterns define reusable, modular regular tree grammars using
|
|
53
|
+
square brackets `[...]`:
|
|
54
|
+
|
|
55
|
+
```k
|
|
56
|
+
name[ P1, P2, ... Pn ] = filter;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For 0-arity patterns (no parameters), empty brackets `[]` are used:
|
|
60
|
+
|
|
61
|
+
```k
|
|
62
|
+
bit[] = < {} 0, {} 1 >;
|
|
63
|
+
bits[] = < {} _, B 0, B 1 > = B;
|
|
64
|
+
byte[] = {
|
|
65
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3,
|
|
66
|
+
bit[] 4, bit[] 5, bit[] 6, bit[] 7
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Parameterized patterns declare external ports in the bracket list:
|
|
71
|
+
|
|
72
|
+
```k
|
|
73
|
+
list[X] = < {} nil, { X car, Y cdr } cons > = Y;
|
|
74
|
+
pair[A, B] = { A first, B second };
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Callers instantiate a named pattern:
|
|
78
|
+
- As a standalone filter: `? list[X]` or `? bits[]`
|
|
79
|
+
- Within relation guards: `?{ nat[] = N x, ... }`
|
|
80
|
+
- As template arguments: `list[byte[]]` or `pair[A, B]`
|
|
81
|
+
|
|
82
|
+
Inside a definition, knot identifiers (`= Y`) close internal recursive
|
|
83
|
+
loops. Recursive loops are private and alpha-renamed during expansion.
|
|
84
|
+
Direct or mutual recursion among templates (`bits[]` calling `bits[]`)
|
|
85
|
+
is disallowed to ensure every template dependency graph is an acyclic
|
|
86
|
+
DAG, guaranteeing finite regular tree automaton compilation.
|
|
87
|
+
|
|
88
|
+
## Filters and Terminal Positions
|
|
50
89
|
|
|
51
90
|
A k script can describe a pattern through:
|
|
52
91
|
|
|
53
92
|
- a relation in terminal position
|
|
54
93
|
- a filter expression in terminal position
|
|
94
|
+
- a named pattern invocation (`? name[...]`)
|
|
55
95
|
|
|
56
96
|
Examples:
|
|
57
97
|
|
|
58
98
|
```k
|
|
59
|
-
bits
|
|
60
|
-
list
|
|
99
|
+
bits[] = < {} _, B 0, B 1 > = B;
|
|
100
|
+
list[X] = < {} nil, { X car, Y cdr } cons > = Y;
|
|
101
|
+
list? = ? list[bits[]];
|
|
61
102
|
list?
|
|
62
103
|
```
|
|
63
104
|
|
|
105
|
+
Or anonymously:
|
|
106
|
+
|
|
64
107
|
```k
|
|
65
|
-
|
|
108
|
+
? list[bits[]]
|
|
66
109
|
```
|
|
67
110
|
|
|
68
|
-
In
|
|
111
|
+
In all cases, the compiler derives a root pattern from `__main__`.
|
|
69
112
|
|
|
70
113
|
## Pattern Export Helper
|
|
71
114
|
|
|
@@ -86,13 +129,18 @@ It:
|
|
|
86
129
|
Example:
|
|
87
130
|
|
|
88
131
|
```bash
|
|
89
|
-
echo '?< {} nil, {
|
|
132
|
+
echo '?< {} nil, { {} car, X cdr } cons > = X' | \
|
|
133
|
+
node ./patterns/from-k.mjs
|
|
90
134
|
```
|
|
91
135
|
|
|
92
136
|
Typical output:
|
|
93
137
|
|
|
94
138
|
```json
|
|
95
|
-
[
|
|
139
|
+
[
|
|
140
|
+
["closed-union", [["nil", 1], ["cons", 2]]],
|
|
141
|
+
["closed-product", []],
|
|
142
|
+
["closed-product", [["car", 1], ["cdr", 0]]]
|
|
143
|
+
]
|
|
96
144
|
```
|
|
97
145
|
|
|
98
146
|
## Schemas in the Codec
|
package/DOCS/REPL.md
CHANGED
|
@@ -33,10 +33,13 @@ is complete.
|
|
|
33
33
|
| Command | Meaning |
|
|
34
34
|
| --- | --- |
|
|
35
35
|
| `:help` | Show command summary |
|
|
36
|
-
| `:engine [wasm
|
|
37
|
-
| `:wasm` / `:js` | Shortcut to switch engine |
|
|
36
|
+
| `:engine [wasm\|pkir\|js]` | Display or switch evaluation engine (`wasm`, `pkir`, or `js`) |
|
|
37
|
+
| `:wasm` / `:pkir` / `:js` | Shortcut to switch engine |
|
|
38
38
|
| `:rel name` | Show relation definition |
|
|
39
39
|
| `:rels` | List relation aliases |
|
|
40
|
+
| `:pattern name` | Show named pattern definition (alias: `:pat`) |
|
|
41
|
+
| `:patterns` | List defined named pattern templates (alias: `:pats`) |
|
|
42
|
+
| `:limit [num\|none]` | Set maximum characters for value output (default: 4096) |
|
|
40
43
|
| `:codec load file` | Load a codec from an ES module file (e.g. `:codec load codecs/int.mjs`) |
|
|
41
44
|
| `:codec unload name` | Unload a registered codec |
|
|
42
45
|
| `:codec list` | List loaded REPL codecs (alias: `:codecs`) |
|
|
@@ -50,6 +53,8 @@ is complete.
|
|
|
50
53
|
## Raw Snippets
|
|
51
54
|
|
|
52
55
|
Raw input is compiled as k source on top of the current state.
|
|
56
|
+
Both relation definitions (`name = expr;`) and named pattern templates
|
|
57
|
+
(`name[...] = filter;`) can be introduced incrementally.
|
|
53
58
|
|
|
54
59
|
Examples:
|
|
55
60
|
|
|
@@ -58,11 +63,17 @@ Examples:
|
|
|
58
63
|
```
|
|
59
64
|
|
|
60
65
|
```k
|
|
61
|
-
> bool
|
|
66
|
+
> bool[] = < {} true, {} false >;
|
|
67
|
+
> bool? = ? bool[];
|
|
62
68
|
```
|
|
63
69
|
|
|
64
70
|
```k
|
|
65
|
-
>
|
|
71
|
+
> list[X] = < {} nil, { X car, Y cdr } cons > = Y;
|
|
72
|
+
> ? list[bool[]]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```k
|
|
76
|
+
> not = ? bool[] < /true | false, /false | true >;
|
|
66
77
|
{} |true not
|
|
67
78
|
```
|
|
68
79
|
|
|
@@ -92,6 +103,7 @@ The interpreter keeps:
|
|
|
92
103
|
|
|
93
104
|
- `rels`: canonical compiled relations
|
|
94
105
|
- `relAliases`: human relation names to canonical hashes
|
|
106
|
+
- `patterns`: defined named pattern templates
|
|
95
107
|
- `value`: current value, initially `{}`
|
|
96
108
|
|
|
97
109
|
Definitions are content-addressed. Rebinding an alias changes the
|
|
@@ -231,11 +243,13 @@ The REPL supports two evaluation engines:
|
|
|
231
243
|
|
|
232
244
|
### CLI Options
|
|
233
245
|
|
|
234
|
-
When starting `k-repl`, choose the engine with:
|
|
246
|
+
When starting `k-repl`, choose the engine or output limit with:
|
|
235
247
|
|
|
236
248
|
```bash
|
|
237
249
|
k-repl --engine=js # or k-repl --js
|
|
250
|
+
k-repl --engine=pkir # or k-repl --pkir
|
|
238
251
|
k-repl --engine=wasm # or k-repl --wasm (default)
|
|
252
|
+
k-repl --limit=8192 # set max characters for rendered output
|
|
239
253
|
```
|
|
240
254
|
|
|
241
255
|
## Timing and Profiling
|
|
@@ -297,6 +311,11 @@ Evaluated values print in k syntax together with the inferred envelope:
|
|
|
297
311
|
{}|0|+1 ?<<{} 0, ...> +1, ...>
|
|
298
312
|
```
|
|
299
313
|
|
|
314
|
+
Large values are rendered iteratively and truncated at `maxChars`
|
|
315
|
+
(default: `4096` characters) so deeply nested or large values print
|
|
316
|
+
instantly without exhausting stack or terminal buffers. Use
|
|
317
|
+
`:limit <num>` or `:limit none` to adjust or disable the limit.
|
|
318
|
+
|
|
300
319
|
`undefined` prints as:
|
|
301
320
|
|
|
302
321
|
```text
|
|
@@ -112,8 +112,10 @@ The bundled VFS and UI examples must include only verified useful files:
|
|
|
112
112
|
|
|
113
113
|
#### 1. Curated Files Explorer
|
|
114
114
|
In the Web REPL "Files" (VFS) explorer, the visible files are strictly curated to verified examples and codecs:
|
|
115
|
-
- **k-codes**: `core.k`, `arithmetics.k`, `ieee.k`
|
|
116
|
-
-
|
|
115
|
+
- **k-codes**: `core.k`, `arithmetics.k`, `ieee.k`, `djson.k`,
|
|
116
|
+
`djson-btrie.k`, `djson-ptrie.k`
|
|
117
|
+
- **codecs**: `json.mjs`, `djson.mjs`, `djson-btrie.mjs`,
|
|
118
|
+
`djson-ptrie.mjs`, `utf8.mjs`, `int.mjs`, `unit.mjs`, `ieee.mjs`
|
|
117
119
|
- User-created or uploaded files remain visible.
|
|
118
120
|
- Internal runtime artifacts (`backends/wasm/runtime.wat`) and redundant directory prefixes (`Examples/`, `codecs/`) are kept accessible internally but hidden from the default file listing.
|
|
119
121
|
- Clicking "Load" on a `.mjs` file automatically executes `:codec load <filename>`.
|
package/Examples/arithmetics.k
CHANGED
|
@@ -3,7 +3,8 @@ swap_yes_no = < /yes |no, /no |yes >;
|
|
|
3
3
|
yes = {}|yes;
|
|
4
4
|
no = yes swap_yes_no;
|
|
5
5
|
|
|
6
|
-
bits
|
|
6
|
+
bits[] = < {} _, B 0, B 1 > = B;
|
|
7
|
+
bits? = ? bits[];
|
|
7
8
|
|
|
8
9
|
0b = {} | _;
|
|
9
10
|
-- |1 = | 1;
|
|
@@ -28,7 +29,7 @@ empty = < /_ yes, no >;
|
|
|
28
29
|
empty? = {empty /yes if, () then} .then;
|
|
29
30
|
|
|
30
31
|
concat = {.x inv x, .y y} concat_;
|
|
31
|
-
concat_ = ?{
|
|
32
|
+
concat_ = ?{ bits[] = X x, ... }
|
|
32
33
|
<
|
|
33
34
|
{.x empty? if, .y then} .then,
|
|
34
35
|
<
|
|
@@ -37,7 +38,7 @@ concat_ = ?{ <X 0, X 1, {} _>=X x, ... }
|
|
|
37
38
|
> concat_
|
|
38
39
|
>;
|
|
39
40
|
inv = {()x, 0b r} _inv;
|
|
40
|
-
_inv = ?{
|
|
41
|
+
_inv = ?{ bits[] = X x, ... }
|
|
41
42
|
<
|
|
42
43
|
{.x empty? if, .r then} .then,
|
|
43
44
|
<
|
|
@@ -47,7 +48,7 @@ _inv = ?{ <X 0, X 1, {} _>=X x, ... }
|
|
|
47
48
|
>;
|
|
48
49
|
|
|
49
50
|
inOrder = {.x inv x, .y inv y, yes inOrder} inOrder_;
|
|
50
|
-
inOrder_ = ?{
|
|
51
|
+
inOrder_ = ?{ bits[] = X x, ... }
|
|
51
52
|
<
|
|
52
53
|
{.x </0,/1> if1, .y /_ if2, .inOrder swap_yes_no then} .then,
|
|
53
54
|
{.x /_ if, .inOrder then} .then,
|
|
@@ -64,7 +65,8 @@ GT = {inOrder /no if, () then} . then;
|
|
|
64
65
|
EQ = {inOrder /yes if, {.x y, .y x} inOrder /yes and, () then} .then;
|
|
65
66
|
|
|
66
67
|
--------------------------------------
|
|
67
|
-
int
|
|
68
|
+
int[] = < bits[] "+", bits[] "-" >;
|
|
69
|
+
int? = ? int[];
|
|
68
70
|
|
|
69
71
|
remove_leading_zeros = <
|
|
70
72
|
/0 remove_leading_zeros,
|
|
@@ -85,7 +87,7 @@ inc = <
|
|
|
85
87
|
/'-' {inv x, 0b y} _dec nat |'-'
|
|
86
88
|
>;
|
|
87
89
|
|
|
88
|
-
_inc = ?{
|
|
90
|
+
_inc = ?{ bits[] = X x, ... } <
|
|
89
91
|
{.x empty? if, .y |1 then} .then,
|
|
90
92
|
{.x /0 x, .y |1 y} concat_,
|
|
91
93
|
{.x /1 x, .y |0 y} _inc
|
|
@@ -97,7 +99,7 @@ dec = <
|
|
|
97
99
|
/'-' {inv x, 0b y} _inc nat |'-'
|
|
98
100
|
>;
|
|
99
101
|
|
|
100
|
-
_dec = ?{
|
|
102
|
+
_dec = ?{ bits[] = X x, ... } <
|
|
101
103
|
{.x /1 x, .y |0 y} concat_,
|
|
102
104
|
{.x /0 x, .y |1 y} _dec
|
|
103
105
|
>;
|
|
@@ -128,7 +130,7 @@ _plus = {.x x, .y y, .c c, 0b r} _plus_;
|
|
|
128
130
|
|
|
129
131
|
_plus_ =
|
|
130
132
|
-- least significant bit first addition with carry
|
|
131
|
-
?{
|
|
133
|
+
?{ bits[] = X x, ... }
|
|
132
134
|
<
|
|
133
135
|
{.x empty? if, .y empty? and, .c/0 c, .r inv then} .then,
|
|
134
136
|
{.x empty? if, .y empty? and, {.r x, 1 r} _inv then} .then,
|
|
@@ -156,7 +158,7 @@ _minus = {.x x, .y y, .c c, 0b r} _minus_;
|
|
|
156
158
|
|
|
157
159
|
_minus_ =
|
|
158
160
|
-- least significant bit first substraction with carry
|
|
159
|
-
?{
|
|
161
|
+
?{ bits[] = X x, ... }
|
|
160
162
|
<
|
|
161
163
|
{.y empty? if, .c/0 and, {.r x, .x r} _inv then} .then,
|
|
162
164
|
<
|
|
@@ -199,7 +201,7 @@ times =
|
|
|
199
201
|
;
|
|
200
202
|
|
|
201
203
|
_times =
|
|
202
|
-
?{
|
|
204
|
+
?{ bits[] = Y y, ... }
|
|
203
205
|
<
|
|
204
206
|
{ .y empty? if, .result then } .then,
|
|
205
207
|
<
|
|
@@ -226,7 +228,7 @@ shift_in_1 = inv |1 inv nat;
|
|
|
226
228
|
sub_bits = {.x inv x, .y inv y, c0 c} _minus inv nat;
|
|
227
229
|
|
|
228
230
|
_div_restoring =
|
|
229
|
-
?{
|
|
231
|
+
?{ bits[] = X x, ... }
|
|
230
232
|
<
|
|
231
233
|
{.x empty? if, {.q inv int div, .r rem} then} .then,
|
|
232
234
|
<
|
|
@@ -241,13 +243,16 @@ _div_restoring =
|
|
|
241
243
|
{.y x, .r y} inOrder test
|
|
242
244
|
}
|
|
243
245
|
<
|
|
244
|
-
{
|
|
246
|
+
{
|
|
247
|
+
.test /yes if,
|
|
248
|
+
{.x x, .y y, .q |1 q, {.r x, .y y} sub_bits r} then
|
|
249
|
+
} .then,
|
|
245
250
|
{.test /no if, {.x x, .y y, .q |0 q, .r r} then} .then
|
|
246
251
|
>
|
|
247
252
|
_div_restoring
|
|
248
253
|
>;
|
|
249
254
|
|
|
250
|
-
_pad_down = ?{
|
|
255
|
+
_pad_down = ?{ bits[] = X x, bits[] = S steps, ... }
|
|
251
256
|
<
|
|
252
257
|
{.x empty? if, {._y _y, .steps steps} then} .then,
|
|
253
258
|
{
|
|
@@ -257,7 +262,7 @@ _pad_down = ?{ <X 0, X 1, {} _>=X x, <S 0, S 1, {} _>=S steps, ... }
|
|
|
257
262
|
} _pad_down
|
|
258
263
|
>;
|
|
259
264
|
|
|
260
|
-
_align_down = ?{
|
|
265
|
+
_align_down = ?{ bits[] = X x, bits[] = Y y, ... }
|
|
261
266
|
<
|
|
262
267
|
{
|
|
263
268
|
.x </0, /1> x,
|
|
@@ -277,7 +282,7 @@ _align_down = ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y, ... }
|
|
|
277
282
|
} .then
|
|
278
283
|
>;
|
|
279
284
|
|
|
280
|
-
_div_down = ?{
|
|
285
|
+
_div_down = ?{ bits[] = X steps, ... }
|
|
281
286
|
{
|
|
282
287
|
.x x,
|
|
283
288
|
._y _y,
|
|
@@ -321,7 +326,7 @@ _div_down = ?{ <X 0, X 1, {} _>=X steps, ... }
|
|
|
321
326
|
} _div_down
|
|
322
327
|
>;
|
|
323
328
|
|
|
324
|
-
_check_2y = ?{
|
|
329
|
+
_check_2y = ?{ bits[] = X x, bits[] = Y y, ... }
|
|
325
330
|
<
|
|
326
331
|
{.x empty? if, {} | down_shift then} .then,
|
|
327
332
|
{.y empty? if, {} | restore then} .then,
|
|
@@ -393,7 +398,7 @@ gcd =
|
|
|
393
398
|
> _gcd
|
|
394
399
|
;
|
|
395
400
|
|
|
396
|
-
_gcd = ?{
|
|
401
|
+
_gcd = ?{ bits[] = X x, ... } <
|
|
397
402
|
{ .y remove_leading_zeros empty? if, .x nat then } .then,
|
|
398
403
|
{ .y x, mod y } _gcd
|
|
399
404
|
>;
|