@fraczak/k 5.1.2 → 6.0.1

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.
Files changed (115) hide show
  1. package/.codex +0 -0
  2. package/Code-derivation-tests/blowup.mjs +3 -3
  3. package/Code-derivation-tests/bnat.mjs +2 -2
  4. package/Code-derivation-tests/codec-witness-pattern.mjs +50 -0
  5. package/Code-derivation-tests/convergence-strategy.mjs +24 -0
  6. package/Code-derivation-tests/dot.mjs +12 -9
  7. package/Code-derivation-tests/filter-syntax.mjs +21 -0
  8. package/Code-derivation-tests/loop.mjs +8 -2
  9. package/Code-derivation-tests/nat.mjs +1 -1
  10. package/Code-derivation-tests/not-not.mjs +3 -3
  11. package/Code-derivation-tests/pattern-envelope.mjs +68 -0
  12. package/Code-derivation-tests/rlz.mjs +2 -2
  13. package/{BIG_PICTURE.md → DOCS/BIG_PICTURE.md} +103 -50
  14. package/DOCS/REPL.md +191 -0
  15. package/DOCS/a.html +398 -0
  16. package/DOCS/book/01-introduction.md +51 -0
  17. package/DOCS/book/02-syntax-and-values.md +111 -0
  18. package/DOCS/book/03-types-as-finite-automata.md +156 -0
  19. package/DOCS/book/04-partial-functions-and-composition.md +146 -0
  20. package/DOCS/book/05-typing-filters-and-normalization.md +111 -0
  21. package/DOCS/book-combined.html +3798 -0
  22. package/DOCS/book-combined.md +3745 -0
  23. package/DOCS/book-combined.pdf +0 -0
  24. package/DOCS/book-combined.tex +5682 -0
  25. package/DOCS/book.html +65 -0
  26. package/DOCS/book.md +54 -0
  27. package/DOCS/book.pdf +0 -0
  28. package/DOCS/book.tex +150 -0
  29. package/NAT.k~ +452 -0
  30. package/README.md +204 -508
  31. package/TypeGraph.mjs +43 -0
  32. package/TypePatternGraph.mjs +251 -0
  33. package/Value.mjs +192 -0
  34. package/augmentation.mjs +198 -0
  35. package/codecs/BINARY_FORMAT.html +471 -0
  36. package/codecs/BINARY_FORMAT.md +53 -0
  37. package/codecs/POLYMORPHIC_BINARY_FORMAT.html +355 -0
  38. package/codecs/POLYMORPHIC_BINARY_FORMAT.md +303 -0
  39. package/codecs/README.md +215 -0
  40. package/codecs/example-pipeline.mjs +149 -0
  41. package/codecs/ieee.mjs +140 -0
  42. package/codecs/int.mjs +104 -0
  43. package/codecs/json-codec.mjs +215 -0
  44. package/codecs/json.mjs +40 -0
  45. package/codecs/k-parse.mjs +90 -0
  46. package/codecs/k-pattern.mjs +75 -0
  47. package/codecs/k-print.mjs +46 -0
  48. package/codecs/runtime/codec.mjs +768 -0
  49. package/codecs/runtime/ieee-pattern.mjs +30 -0
  50. package/codecs/runtime/pattern-json.mjs +96 -0
  51. package/codecs/runtime/prefix-codec.mjs +425 -0
  52. package/codecs/runtime/show-value.mjs +68 -0
  53. package/codecs/runtime/typeFromValue.mjs +34 -0
  54. package/codecs/runtime/unicode-string.mjs +220 -0
  55. package/codecs/show.mjs +41 -0
  56. package/codecs/string-codec.mjs +80 -0
  57. package/codecs/unit.mjs +51 -0
  58. package/codecs/utf16.mjs +66 -0
  59. package/codecs/utf8.mjs +37 -0
  60. package/codes.mjs +146 -44
  61. package/compiler.mjs +111 -0
  62. package/convergence.mjs +197 -0
  63. package/core.k +197 -0
  64. package/export.mjs +22 -32
  65. package/hash.mjs +29 -31
  66. package/ieee.klib +0 -0
  67. package/index.mjs +41 -15
  68. package/k-vscode/.vscode/launch.json +14 -0
  69. package/k-vscode/README.md +65 -0
  70. package/k-vscode/language-configuration.json +42 -0
  71. package/k-vscode/package-lock.json +4176 -0
  72. package/k-vscode/package.json +57 -0
  73. package/k-vscode/snippets/k.json +92 -0
  74. package/k-vscode/syntaxes/k.tmLanguage.json +243 -0
  75. package/k.mjs +56 -54
  76. package/object.mjs +517 -0
  77. package/objects/README.md +38 -0
  78. package/objects/compile-lib.mjs +42 -0
  79. package/objects/compile.mjs +42 -0
  80. package/objects/decompile.mjs +32 -0
  81. package/package.json +13 -6
  82. package/parser.jison +27 -46
  83. package/parser.mjs +68 -100
  84. package/pretty.mjs +21 -40
  85. package/repl2.mjs +662 -0
  86. package/run.mjs +264 -231
  87. package/symbol-table.mjs +3 -17
  88. package/test-fingerprint.mjs +7 -7
  89. package/test-hash-fuzz.mjs +107 -0
  90. package/test-hash-normalization.mjs +134 -0
  91. package/test-k-object.mjs +74 -0
  92. package/test-repl2.mjs +106 -0
  93. package/test.mjs +45 -70
  94. package/tests.sh +10 -1
  95. package/type_registry/registry.mjs~ +105 -0
  96. package/type_registry/typeParser.jison~ +132 -0
  97. package/typing.mjs +129 -676
  98. package/unification.mjs +157 -0
  99. package/valueIO.mjs +54 -0
  100. package/valueParser.jison +143 -0
  101. package/valueParser.mjs +713 -0
  102. package/Code-derivation-tests/built-in.mjs +0 -19
  103. package/Code-derivation-tests/vector.mjs +0 -19
  104. package/Filters/bug.k +0 -3
  105. package/Filters/composing.k +0 -15
  106. package/Filters/filter.k +0 -9
  107. package/TODO.md +0 -53
  108. package/TYPING.md +0 -365
  109. package/k-repl.cast +0 -1913
  110. package/k.cast +0 -618
  111. package/my-objects.json +0 -6
  112. package/patterns.mjs +0 -543
  113. package/repl.mjs +0 -213
  114. package/test-filters.mjs +0 -45
  115. package/typing-test.mjs +0 -40
@@ -0,0 +1,355 @@
1
+ <!DOCTYPE html>
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="generator" content="pandoc" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
7
+ <title>POLYMORPHIC_BINARY_FORMAT</title>
8
+ <style>
9
+ code{white-space: pre-wrap;}
10
+ span.smallcaps{font-variant: small-caps;}
11
+ div.columns{display: flex; gap: min(4vw, 1.5em);}
12
+ div.column{flex: auto; overflow-x: auto;}
13
+ div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
14
+ /* The extra [class] is a hack that increases specificity enough to
15
+ override a similar rule in reveal.js */
16
+ ul.task-list[class]{list-style: none;}
17
+ ul.task-list li input[type="checkbox"] {
18
+ font-size: inherit;
19
+ width: 0.8em;
20
+ margin: 0 0.8em 0.2em -1.6em;
21
+ vertical-align: middle;
22
+ }
23
+ .display.math{display: block; text-align: center; margin: 0.5rem auto;}
24
+ </style>
25
+ <link rel="stylesheet" href="pandoc.css" />
26
+ </head>
27
+ <body>
28
+ <h1 id="k-polymorphic-binary-format">K Polymorphic Binary Format</h1>
29
+ <h2 id="purpose">Purpose</h2>
30
+ <p>This document defines a binary format for polymorphic values in
31
+ <code>k</code>.</p>
32
+ <p>The semantic object to be serialized is:</p>
33
+ <pre class="text"><code>(P, v)</code></pre>
34
+ <p>where:</p>
35
+ <ul>
36
+ <li><code>P</code> is a normalized pattern graph,</li>
37
+ <li><code>v</code> is a typed value compatible with <code>P</code>.</li>
38
+ </ul>
39
+ <p>The binary format is designed so that:</p>
40
+ <ul>
41
+ <li>the pattern carries all field and tag names,</li>
42
+ <li>the value payload carries no explicit labels or tags,</li>
43
+ <li>the value payload is friendly to <code>.label</code> and
44
+ <code>/tag</code>,</li>
45
+ <li>closed typed values appear as the singleton-pattern special
46
+ case.</li>
47
+ </ul>
48
+ <h2 id="design-principles">Design Principles</h2>
49
+ <h3 id="pattern-is-the-structural-authority">1. Pattern is the
50
+ structural authority</h3>
51
+ <p>The pattern section is the authoritative description of the structure
52
+ expected by the value section.</p>
53
+ <p>It determines:</p>
54
+ <ul>
55
+ <li>whether a node is product or union,</li>
56
+ <li>whether it is open or closed,</li>
57
+ <li>which fields or tags are present explicitly,</li>
58
+ <li>which subpositions point to the same pattern node,</li>
59
+ <li>which leaves are exact types.</li>
60
+ </ul>
61
+ <h3 id="value-is-interpreted-relative-to-the-pattern">2. Value is
62
+ interpreted relative to the pattern</h3>
63
+ <p>The value payload is not self-describing. It is decoded relative to
64
+ the pattern graph.</p>
65
+ <p>This is why the payload does not need to repeat field names or tag
66
+ names.</p>
67
+ <h3 id="is-not-value-carrying">3. <code>(...)</code> is not
68
+ value-carrying</h3>
69
+ <p>The leaf pattern <code>(...)</code> is allowed in the pattern
70
+ language, but it is <strong>not</strong> allowed to carry serialized
71
+ value content in version 1 of this format.</p>
72
+ <p>This restriction keeps explicit labels out of the value payload.
73
+ Otherwise the missing structure would have to be reintroduced locally in
74
+ the value itself.</p>
75
+ <h3 id="value-dag-is-only-an-optimization">4. Value DAG is only an
76
+ optimization</h3>
77
+ <p>Semantically, the value is a tree. On the wire, it may be encoded as
78
+ a DAG by collapsing equal occurrences relative to the pattern.</p>
79
+ <h2 id="high-level-structure">High-Level Structure</h2>
80
+ <p>The package layout is:</p>
81
+ <pre class="text"><code>| magic | format_version | flags | symbol_table | pattern_section | value_section |</code></pre>
82
+ <p>There is no separate <code>type_section</code>.</p>
83
+ <h2 id="primitive-encodings">Primitive Encodings</h2>
84
+ <h3 id="integers">Integers</h3>
85
+ <ul>
86
+ <li>fixed-width integers are unsigned and big-endian,</li>
87
+ <li>variable-width integers use unsigned LEB128 and are written
88
+ <code>uvarint</code>.</li>
89
+ </ul>
90
+ <h3 id="symbols">Symbols</h3>
91
+ <p>A symbol is a UTF-8 string used as:</p>
92
+ <ul>
93
+ <li>a field name,</li>
94
+ <li>a tag name,</li>
95
+ <li>an exact type identifier when such identifiers are serialized as
96
+ strings.</li>
97
+ </ul>
98
+ <p>Symbols are interned in a symbol table and referred to by symbol
99
+ ID.</p>
100
+ <h2 id="header">Header</h2>
101
+ <pre class="text"><code>| magic:4 bytes | format_version:u8 | flags:u8 |</code></pre>
102
+ <p>Current values:</p>
103
+ <ul>
104
+ <li><code>magic = "KPV2"</code></li>
105
+ <li><code>format_version = 1</code></li>
106
+ </ul>
107
+ <p>All flag bits are reserved in version 1 and must be zero.</p>
108
+ <h2 id="symbol-table">Symbol Table</h2>
109
+ <pre class="text"><code>| symbol_count:uvarint | symbol_0 | ... | symbol_(N-1) |</code></pre>
110
+ <p>Each symbol is:</p>
111
+ <pre class="text"><code>| byte_length:uvarint | utf8_bytes... |</code></pre>
112
+ <h3 id="canonical-ordering">Canonical ordering</h3>
113
+ <p>Symbols are ordered canonically by:</p>
114
+ <ol type="1">
115
+ <li>ascending UTF-8 byte sequence,</li>
116
+ <li>duplicates removed.</li>
117
+ </ol>
118
+ <p>The same symbol table is used by both the pattern and the value
119
+ sections.</p>
120
+ <h2 id="pattern-section">Pattern Section</h2>
121
+ <p>The pattern section serializes a normalized rooted pattern graph.</p>
122
+ <h3 id="pattern-node-kinds">Pattern node kinds</h3>
123
+ <p>There are exactly five semantic node kinds:</p>
124
+ <ul>
125
+ <li><code>(...)</code></li>
126
+ <li><code>{...}</code></li>
127
+ <li><code>&lt;...&gt;</code></li>
128
+ <li><code>{}</code></li>
129
+ <li><code>&lt;&gt;</code></li>
130
+ </ul>
131
+ <p>These are constructor classes of pattern nodes, not leaf/internal
132
+ tags. Only <code>(...)</code> is forced to have no outgoing edges. All
133
+ other node kinds may have zero or more outgoing edges.</p>
134
+ <p>Their meanings are:</p>
135
+ <ul>
136
+ <li><p><code>(...)</code> means unconstrained type,</p></li>
137
+ <li><p><code>{...}</code> with edges
138
+ <code>l1 -&gt; X1, ..., ln -&gt; Xn</code> means</p>
139
+ <pre class="text"><code>{ X1 l1, ..., Xn ln, ... }</code></pre></li>
140
+ <li><p><code>&lt;...&gt;</code> with edges
141
+ <code>t1 -&gt; X1, ..., tn -&gt; Xn</code> means</p>
142
+ <pre class="text"><code>&lt; X1 t1, ..., Xn tn, ... &gt;</code></pre></li>
143
+ <li><p><code>{}</code> with edges
144
+ <code>l1 -&gt; X1, ..., ln -&gt; Xn</code> means</p>
145
+ <pre class="text"><code>{ X1 l1, ..., Xn ln }</code></pre></li>
146
+ <li><p><code>&lt;&gt;</code> with edges
147
+ <code>t1 -&gt; X1, ..., tn -&gt; Xn</code> means</p>
148
+ <pre class="text"><code>&lt; X1 t1, ..., Xn tn &gt;</code></pre></li>
149
+ </ul>
150
+ <p>In particular:</p>
151
+ <ul>
152
+ <li><code>{}</code> with zero edges is the unit type,</li>
153
+ <li><code>&lt;&gt;</code> with zero edges is the empty type,</li>
154
+ <li><code>{...}</code> with zero edges matches any product type,</li>
155
+ <li><code>&lt;...&gt;</code> with zero edges matches any union
156
+ type.</li>
157
+ </ul>
158
+ <h3 id="canonical-node-numbering">Canonical node numbering</h3>
159
+ <p>Pattern nodes are numbered by first discovery in rooted depth-first
160
+ traversal:</p>
161
+ <ol type="1">
162
+ <li>start at the root,</li>
163
+ <li>visit outgoing edges in ascending symbol ID order,</li>
164
+ <li>assign a new node ID on first encounter,</li>
165
+ <li>reuse the existing node ID on revisits.</li>
166
+ </ol>
167
+ <p>The root pattern node is always node <code>0</code>.</p>
168
+ <h3 id="structure">Structure</h3>
169
+ <pre class="text"><code>| pattern_node_count:uvarint | pattern_node_0 | ... | pattern_node_(P-1) |</code></pre>
170
+ <h3 id="pattern-node-record">Pattern node record</h3>
171
+ <p>Every pattern node record starts with:</p>
172
+ <pre class="text"><code>| node_kind:u8 |</code></pre>
173
+ <p>The codes are:</p>
174
+ <ul>
175
+ <li><code>0</code> = <code>(...)</code></li>
176
+ <li><code>1</code> = <code>{...}</code></li>
177
+ <li><code>2</code> = <code>&lt;...&gt;</code></li>
178
+ <li><code>3</code> = <code>{}</code></li>
179
+ <li><code>4</code> = <code>&lt;&gt;</code></li>
180
+ </ul>
181
+ <p>The remainder of every record is:</p>
182
+ <pre class="text"><code>| edge_count:uvarint | edge_0 | ... | edge_(k-1) |</code></pre>
183
+ <p>Each edge is:</p>
184
+ <pre class="text"><code>| symbol_id:uvarint | target_pattern_node:uvarint |</code></pre>
185
+ <p>Edges must be sorted by ascending <code>symbol_id</code> and have no
186
+ duplicates.</p>
187
+ <p>Validation rules for node kinds:</p>
188
+ <ul>
189
+ <li><code>(...)</code> must have <code>edge_count = 0</code>,</li>
190
+ <li>all other node kinds may have any <code>edge_count ≥ 0</code>.</li>
191
+ </ul>
192
+ <p>This document therefore starts without type hashes or exact-type
193
+ leaves. Closed typed values are represented simply as values whose root
194
+ pattern happens to be singleton.</p>
195
+ <h2 id="value-section">Value Section</h2>
196
+ <p>The value section encodes the witness value tree relative to the
197
+ pattern graph. On the wire, it is represented as a DAG of value
198
+ occurrences decorated by pattern-node identity.</p>
199
+ <h3 id="canonical-value-node-identity">Canonical value-node
200
+ identity</h3>
201
+ <p>The canonical key of a value node is:</p>
202
+ <pre class="text"><code>(pattern_node_id, node_shape)</code></pre>
203
+ <p>where:</p>
204
+ <ul>
205
+ <li>for product pattern nodes (<code>{...}</code> or <code>{}</code>),
206
+ <code>node_shape</code> is the ordered list of child node IDs,</li>
207
+ <li>for union pattern nodes (<code>&lt;...&gt;</code> or
208
+ <code>&lt;&gt;</code>), <code>node_shape</code> is
209
+ <code>(tag_ordinal, child_node_id)</code>,</li>
210
+ <li><code>(...)</code> carries no value and therefore cannot appear in
211
+ the value section.</li>
212
+ </ul>
213
+ <p>This is the criterion for canonical DAG sharing in the value
214
+ payload.</p>
215
+ <h3 id="encodability-restriction">Encodability restriction</h3>
216
+ <p>Version 1 forbids serialized values from descending into an
217
+ <code>any-leaf</code> pattern node.</p>
218
+ <p>So if evaluation of a value against a pattern would require
219
+ materializing a subtree at <code>(...)</code>, the value is <strong>not
220
+ encodable</strong> in this format.</p>
221
+ <h3 id="canonical-value-node-numbering">Canonical value-node
222
+ numbering</h3>
223
+ <p>Value nodes are numbered in canonical postorder:</p>
224
+ <ol type="1">
225
+ <li>children before parents,</li>
226
+ <li>for product nodes, children in ascending pattern-edge symbol
227
+ order,</li>
228
+ <li>for union nodes, the selected child before the parent,</li>
229
+ <li>a shared node is emitted only once, at the first completed postorder
230
+ visit.</li>
231
+ </ol>
232
+ <p>The root value node is always the last node.</p>
233
+ <h3 id="structure-1">Structure</h3>
234
+ <pre class="text"><code>| value_node_count:uvarint | value_node_0 | ... | value_node_(V-1) |</code></pre>
235
+ <h3 id="value-node-record">Value node record</h3>
236
+ <p>Each value node starts with:</p>
237
+ <pre class="text"><code>| pattern_node_id:uvarint | body... |</code></pre>
238
+ <p>The body depends on the referenced pattern node kind.</p>
239
+ <h4 id="product-value-node">Product value node</h4>
240
+ <p>If the pattern node is <code>{...}</code> or <code>{}</code> with
241
+ <code>k</code> outgoing edges in ascending symbol order:</p>
242
+ <pre class="text"><code>| child_ref_0:uvarint | child_ref_1:uvarint | ... | child_ref_(k-1):uvarint |</code></pre>
243
+ <p>The value carries exactly the children of the explicitly listed
244
+ fields. Open product patterns do not permit the value section to
245
+ introduce additional unlabeled fields.</p>
246
+ <h4 id="union-value-node">Union value node</h4>
247
+ <p>If the pattern node is <code>&lt;...&gt;</code> or
248
+ <code>&lt;&gt;</code> with <code>m</code> outgoing edges in ascending
249
+ symbol order:</p>
250
+ <pre class="text"><code>| tag_ordinal:uvarint | child_ref:uvarint |</code></pre>
251
+ <p><code>tag_ordinal</code> must be in <code>[0, m)</code>. Open union
252
+ patterns do not permit the value section to introduce additional unnamed
253
+ tags.</p>
254
+ <h4 id="value-node"><code>(...)</code> value node</h4>
255
+ <p>This case is forbidden in version 1.</p>
256
+ <h2 id="child-references">Child References</h2>
257
+ <p>Child references are encoded as back-distances:</p>
258
+ <pre class="text"><code>child_ref = current_value_node_id - 1 - child_value_node_id</code></pre>
259
+ <p>So:</p>
260
+ <ul>
261
+ <li><code>0</code> means the immediately preceding node,</li>
262
+ <li><code>1</code> means two records back,</li>
263
+ <li>and so on.</li>
264
+ </ul>
265
+ <p>The decoder reconstructs:</p>
266
+ <pre class="text"><code>child_value_node_id = current_value_node_id - 1 - child_ref</code></pre>
267
+ <h2 id="validation">Validation</h2>
268
+ <p>After decoding, a package is valid iff all of the following hold.</p>
269
+ <h3 id="pattern-section-1">Pattern section</h3>
270
+ <ul>
271
+ <li>all pattern node IDs referenced by edges are in range,</li>
272
+ <li>all edge symbol IDs are in range,</li>
273
+ <li>edge symbol IDs are strictly increasing within each node,</li>
274
+ <li><code>(...)</code> has no outgoing edges,</li>
275
+ <li>the root node exists.</li>
276
+ </ul>
277
+ <h3 id="value-section-1">Value section</h3>
278
+ <ul>
279
+ <li>every <code>pattern_node_id</code> is in range,</li>
280
+ <li>every child reference points to an earlier value node,</li>
281
+ <li>a product value node references a <code>{...}</code> or
282
+ <code>{}</code> pattern node,</li>
283
+ <li>a union value node references a <code>&lt;...&gt;</code> or
284
+ <code>&lt;&gt;</code> pattern node,</li>
285
+ <li>no value node references <code>(...)</code>,</li>
286
+ <li><code>tag_ordinal</code> is valid for the referenced union pattern
287
+ node,</li>
288
+ <li>the root value node references pattern node <code>0</code>.</li>
289
+ <li>no value node references <code>&lt;&gt;</code> with zero outgoing
290
+ edges, since the empty type has no values.</li>
291
+ </ul>
292
+ <h2 id="example">Example</h2>
293
+ <p>Consider:</p>
294
+ <pre class="k"><code>pattern: &lt; X tag1, {} tag2, ... &gt; = X
295
+ value: {}|tag2|tag1|tag1</code></pre>
296
+ <h3 id="symbols-1">Symbols</h3>
297
+ <pre class="text"><code>0 -&gt; &quot;tag1&quot;
298
+ 1 -&gt; &quot;tag2&quot;</code></pre>
299
+ <h3 id="pattern-graph">Pattern graph</h3>
300
+ <pre class="text"><code>P0: &lt;...&gt;, edges(tag1 -&gt; P0, tag2 -&gt; P1)
301
+ P1: {}, no edges
302
+ root = P0</code></pre>
303
+ <h3 id="value-dag">Value DAG</h3>
304
+ <pre class="text"><code>V0: {} at P1
305
+ V1: V0 | tag2 at P0
306
+ V2: V1 | tag1 at P0
307
+ V3: V2 | tag1 at P0
308
+ root = V3</code></pre>
309
+ <p>This example has no repeated decorated subtrees, so the value DAG is
310
+ the same as the value tree.</p>
311
+ <h2 id="closed-value-specialization">Closed-Value Specialization</h2>
312
+ <p>If the root pattern is singleton, then the whole package represents
313
+ an ordinary closed typed value.</p>
314
+ <p>In that case:</p>
315
+ <ul>
316
+ <li>the pattern section still exists and makes the package
317
+ self-contained,</li>
318
+ <li>a more compact specialization may omit the pattern section and use
319
+ the dedicated closed-value format.</li>
320
+ </ul>
321
+ <p>So the closed-value format is a derived optimization, not the
322
+ semantic foundation.</p>
323
+ <h2 id="operational-properties">Operational Properties</h2>
324
+ <p>The value payload is chosen to support efficient <code>k</code>
325
+ navigation.</p>
326
+ <h3 id="label"><code>.label</code></h3>
327
+ <p>For a product value node:</p>
328
+ <ol type="1">
329
+ <li>inspect the referenced pattern node,</li>
330
+ <li>map <code>label</code> to field ordinal by the pattern edge
331
+ order,</li>
332
+ <li>jump to the corresponding child reference.</li>
333
+ </ol>
334
+ <h3 id="tag"><code>/tag</code></h3>
335
+ <p>For a union value node:</p>
336
+ <ol type="1">
337
+ <li>inspect the referenced pattern node,</li>
338
+ <li>compare the stored <code>tag_ordinal</code> with the requested tag
339
+ ordinal,</li>
340
+ <li>on success follow the child reference.</li>
341
+ </ol>
342
+ <p>So field and tag names stay in the pattern graph, not in the value
343
+ payload.</p>
344
+ <h2 id="future-extensions">Future Extensions</h2>
345
+ <p>Possible future extensions include:</p>
346
+ <ul>
347
+ <li>introducing exact-type leaf nodes and a pattern registry,</li>
348
+ <li>allowing a controlled self-describing payload under
349
+ <code>(...)</code>,</li>
350
+ <li>auxiliary indexes for faster random access,</li>
351
+ <li>optional textual debug envelopes,</li>
352
+ <li>section compression that preserves the decoded semantic object.</li>
353
+ </ul>
354
+ </body>
355
+ </html>
@@ -0,0 +1,303 @@
1
+ # K Prefix-Free Pattern Codec
2
+
3
+ ## Purpose
4
+
5
+ This document defines the new target semantics for binary codecs in `k`.
6
+
7
+ The object to be serialized is:
8
+
9
+ ```text
10
+ (P, v)
11
+ ```
12
+
13
+ where:
14
+
15
+ - `P` is a rooted pattern graph,
16
+ - `v` is a value tree compatible with `P`.
17
+
18
+ This is both the transport semantics and the runtime value semantics. In the
19
+ current JavaScript runtime, the materialized `Value` stores the pattern as
20
+ `value.pattern`; the tree is still represented by `Product` and `Variant`
21
+ nodes.
22
+
23
+ The codec is designed around:
24
+
25
+ 1. compactness,
26
+ 2. efficient structural navigation,
27
+ 3. a clean separation between semantic encoding and optional acceleration
28
+ structures.
29
+
30
+ This document defines the semantic codec and the canonical wire stream.
31
+
32
+ ## Design Principles
33
+
34
+ ### 1. Pattern is the structural authority
35
+
36
+ The pattern determines:
37
+
38
+ - whether a node is a product or union,
39
+ - whether it is open or closed,
40
+ - what field names or tag names exist,
41
+ - how recursive positions are connected.
42
+
43
+ The value payload is interpreted relative to the pattern.
44
+ During execution, the same pattern context is propagated with materialized
45
+ values, so structural operations do not have to reconstruct framing information
46
+ after the fact.
47
+
48
+ ### 2. Values are trees in the base codec
49
+
50
+ The base codec serializes value trees, not value DAGs.
51
+
52
+ DAG compression is not part of the primitive codec. If wanted, it should happen
53
+ as a separate transform above the base value encoding.
54
+
55
+ ### 3. Prefix-free value encoding
56
+
57
+ The value payload is a prefix-free bitstream.
58
+
59
+ Products rely on structural concatenation.
60
+ Unions emit a choice code, then the payload of the selected branch.
61
+
62
+ ### 4. One canonical stream
63
+
64
+ The pattern graph is embedded as an ordinary k `$pattern` value. The canonical
65
+ stream is that encoded pattern followed by the value payload interpreted under
66
+ the decoded pattern.
67
+
68
+ ## Pattern Graph
69
+
70
+ ### Semantic node kinds
71
+
72
+ There are exactly five node kinds:
73
+
74
+ - `any`
75
+ - `open-product`
76
+ - `open-union`
77
+ - `closed-product`
78
+ - `closed-union`
79
+
80
+ Their informal meanings are:
81
+
82
+ - `any`
83
+ unconstrained position,
84
+ - `open-product`
85
+ explicit fields plus possibly more fields in the matched value,
86
+ - `open-union`
87
+ explicit tags plus possibly more tags in the matched value,
88
+ - `closed-product`
89
+ exactly the listed fields,
90
+ - `closed-union`
91
+ exactly the listed tags.
92
+
93
+ In the base codec, `any` is not directly value-carrying.
94
+
95
+ ### Graph structure
96
+
97
+ A pattern graph node is:
98
+
99
+ ```text
100
+ [kind, edges]
101
+ ```
102
+
103
+ where `edges` is a list of:
104
+
105
+ ```text
106
+ [label, target_node_id]
107
+ ```
108
+
109
+ The root node is node `0`.
110
+
111
+ ### Canonical constraints
112
+
113
+ - node `0` is the root,
114
+ - node order is canonical graph-discovery order,
115
+ - edges are sorted by label,
116
+ - no duplicate labels occur within one node,
117
+ - `any` has no outgoing edges.
118
+
119
+ ### Readable property-list notation
120
+
121
+ For documentation and tests, the abstract graph may be rendered as:
122
+
123
+ ```json
124
+ {
125
+ "pattern": [
126
+ ["closed-union", [["nil", 1], ["cons", 2]]],
127
+ ["closed-product", []],
128
+ ["closed-product", [["car", 3], ["cdr", 0]]],
129
+ ["closed-union", [["_", 1], ["0", 3], ["1", 3]]]
130
+ ]
131
+ }
132
+ ```
133
+
134
+ This syntax is only a readable notation for the abstract graph.
135
+
136
+ ## Pattern Construction From A Witness Tree
137
+
138
+ When no external pattern or type is supplied, the codec tools derive a
139
+ pattern from the value tree itself.
140
+
141
+ - `{}` derives the closed product leaf `["closed-product", []]`.
142
+ - A textual tree node with multiple children derives a closed product.
143
+ - A textual tree node with exactly one child derives an open union.
144
+ - If an explicit product pattern is supplied, that pattern can disambiguate the
145
+ same one-child textual node as a singleton product.
146
+
147
+ Example:
148
+
149
+ ```text
150
+ {a:{b:x,c:{}}}
151
+ ```
152
+
153
+ derives:
154
+
155
+ ```json
156
+ [
157
+ ["open-union", [["a", 1]]],
158
+ ["closed-product", [["b", 2], ["c", 3]]],
159
+ ["open-union", [["x", 3]]],
160
+ ["closed-product", []]
161
+ ]
162
+ ```
163
+
164
+ The derived graph is canonicalized by a bottom-up closed-node collapse. Starting
165
+ from the closed empty product, two closed nodes are collapsible only when their
166
+ kind, labels, and already-collapsed children are identical. Open nodes are not
167
+ collapsed, and this rule is not value-DAG compression.
168
+
169
+ ## Value Encoding
170
+
171
+ ### General shape
172
+
173
+ The value encoding is defined recursively relative to the current pattern node.
174
+
175
+ #### Product node
176
+
177
+ For `open-product` or `closed-product`:
178
+
179
+ ```text
180
+ encode(v_0) encode(v_1) ... encode(v_(n-1))
181
+ ```
182
+
183
+ in canonical edge order.
184
+
185
+ There are no separators between children. The pattern determines where each
186
+ child begins and ends.
187
+
188
+ #### Union node
189
+
190
+ For `open-union` or `closed-union`:
191
+
192
+ ```text
193
+ encode-choice(tag_ordinal, tag_count)
194
+ encode(selected_payload)
195
+ ```
196
+
197
+ #### Any node
198
+
199
+ `any` is not directly value-carrying in the base format.
200
+
201
+ If a value would need to descend into an `any` position, the pattern must first
202
+ be refined.
203
+
204
+ ## Choice Encoding
205
+
206
+ The initial concrete choice encoding is fixed-width by cardinality:
207
+
208
+ ```text
209
+ width(cardinality) = ceil(log2(cardinality))
210
+ ```
211
+
212
+ A choice with:
213
+
214
+ - `cardinality = n`
215
+ - `ordinal in [0, n)`
216
+
217
+ is encoded as the binary representation of `ordinal` in `width(n)` bits.
218
+
219
+ Examples:
220
+
221
+ - `n = 1`: `0` bits,
222
+ - `n = 2`: `1` bit,
223
+ - `n = 3`: `2` bits,
224
+ - `n = 4`: `2` bits,
225
+ - `n = 5`: `3` bits.
226
+
227
+ This is the initial canonical rule for the rewrite. More aggressive coding
228
+ schemes may be considered later, but only after the abstract semantics are
229
+ stable.
230
+
231
+ ## Operational Properties
232
+
233
+ ### `/tag`
234
+
235
+ At a union node:
236
+
237
+ 1. read the choice code,
238
+ 2. compare it to the requested tag ordinal,
239
+ 3. if it matches, continue with the selected payload.
240
+
241
+ This makes `/tag` naturally efficient.
242
+
243
+ ### `.field`
244
+
245
+ At a product node, child values appear in canonical field order.
246
+
247
+ So `.field` is resolved by:
248
+
249
+ 1. locating the field ordinal in the pattern,
250
+ 2. decoding or skipping earlier children,
251
+ 3. decoding the requested child subtree.
252
+
253
+ The base codec does not include field-offset indexes. Such indexes may be added
254
+ later as separate higher-level acceleration structures.
255
+
256
+ In the materialized evaluator, `.field` applies the analogous pattern operation:
257
+ the output `Value` carries the subpattern reached by the selected field.
258
+ Likewise, `/tag` carries the subpattern reached by the selected variant tag.
259
+
260
+ ## Recursive Types
261
+
262
+ Recursive pattern graphs are first-class.
263
+
264
+ For example, a bit-list-like recursive type:
265
+
266
+ ```text
267
+ ["closed-union", [["_", 1], ["0", 3], ["1", 3]]]
268
+ ```
269
+
270
+ is encoded as repeated union choices in a value tree, not as a byte-aligned node
271
+ table and not as a built-in primitive integer format.
272
+
273
+ This keeps the codec uniform: recursion is handled by the pattern graph itself.
274
+
275
+ ## Canonical Wire Format
276
+
277
+ The transport format is:
278
+
279
+ ```text
280
+ encode($pattern_value : $pattern) encode(value : decoded_pattern)
281
+ ```
282
+
283
+ The first segment is a normal k value of type `$pattern`, encoded under the
284
+ fixed singleton pattern for `$pattern` defined by `core.k`. The decoded pattern
285
+ is then used as the structural authority for the second segment.
286
+
287
+ Decoding the stream yields `Value(pattern, tree)`. Encoding a runtime `Value`
288
+ uses its carried pattern by default, or an explicit caller-supplied pattern when
289
+ one is provided.
290
+
291
+ ## Out Of Scope For The Base Codec
292
+
293
+ The following are intentionally outside the primitive codec:
294
+
295
+ - DAG compression,
296
+ - subtree deduplication,
297
+ - projection indexes,
298
+ - alternate transport-specific framing,
299
+ - alternate binary pattern serialization,
300
+ - exact-type-only specializations.
301
+
302
+ These may be added later, but they are not part of the base pattern-plus-tree
303
+ prefix codec.