@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/DOCS/BIG_PICTURE.md +54 -7
  3. package/DOCS/CODECS.md +47 -2
  4. package/DOCS/CODEC_ARCHITECTURE.md +14 -5
  5. package/DOCS/DICTIONARY.md +13 -4
  6. package/DOCS/FILE_FORMATS.md +3 -2
  7. package/DOCS/JSON_APPROACHES_COMPARISON.md +306 -0
  8. package/DOCS/NAMED_PATTERNS.md +317 -0
  9. package/DOCS/PATTERNS.md +59 -11
  10. package/DOCS/REPL.md +24 -5
  11. package/DOCS/WEB_REPL_REQUIREMENTS.md +4 -2
  12. package/Examples/arithmetics.k +22 -17
  13. package/Examples/bnat.k +21 -11
  14. package/Examples/buda.k +37 -20
  15. package/Examples/byte.k +3 -1
  16. package/Examples/code.k +38 -39
  17. package/Examples/djson-btrie.k +414 -0
  18. package/Examples/djson-ptrie.k +663 -0
  19. package/Examples/djson.k +323 -0
  20. package/Examples/esc.k +1 -1
  21. package/Examples/karatsuba-mult.k +16 -13
  22. package/Examples/list.k +8 -4
  23. package/Examples/nat.k +17 -11
  24. package/Examples/poly.k +11 -3
  25. package/Examples/vhdl_to_k.k +43 -31
  26. package/README.md +42 -15
  27. package/Value.mjs +28 -3
  28. package/backend-api.mjs +5 -1
  29. package/browser/repl-browser.mjs +6 -0
  30. package/browser/tree-view.mjs +82 -24
  31. package/browser/vfs-data.mjs +21 -12
  32. package/codecs/README.md +3 -0
  33. package/codecs/djson-btrie.mjs +560 -0
  34. package/codecs/djson-ptrie.mjs +587 -0
  35. package/codecs/djson.mjs +270 -0
  36. package/codecs/int.mjs +2 -1
  37. package/codecs/json.mjs +7 -2
  38. package/codecs/k-parse.mjs +7 -1
  39. package/codecs/k-print.mjs +4 -0
  40. package/codecs/runtime/codec-sdk.mjs +16 -2
  41. package/codecs/runtime/pattern-json.mjs +80 -1
  42. package/codecs/runtime/prefix-codec.mjs +629 -67
  43. package/codecs/runtime/show-value.mjs +93 -51
  44. package/codecs/runtime/unicode-string.mjs +29 -6
  45. package/codecs/show.mjs +4 -0
  46. package/codecs/utf16.mjs +2 -1
  47. package/core.k +79 -115
  48. package/index.mjs +3 -0
  49. package/named-patterns.mjs +267 -0
  50. package/object.mjs +31 -3
  51. package/package.json +5 -1
  52. package/parser.jison +68 -5
  53. package/parser.mjs +111 -60
  54. package/pretty.mjs +5 -0
  55. package/repl.mjs +245 -28
  56. package/scripts/build-repl-html.mjs +76 -5
  57. package/scripts/perf-djson.mjs +1142 -0
  58. package/scripts/run-tests.mjs +5 -0
  59. package/symbol-table.mjs +20 -2
  60. package/tests/bench-djson-tries.mjs +340 -0
  61. package/tests/test-codecs.mjs +211 -0
  62. package/tests/test-named-patterns.mjs +189 -0
  63. package/tests/test-repl-html.mjs +52 -4
  64. package/tests/test-repl.mjs +223 -0
@@ -0,0 +1,323 @@
1
+ -- Examples/djson.k: Universal dynamic JSON schema and helper relations
2
+ -- Works with codecs/djson.mjs (k-djson) and codecs/utf8.mjs (k-utf8).
3
+
4
+ ---------------------------------------------------------------
5
+ -- §1. Named Pattern Definitions & Component Schemas
6
+ ---------------------------------------------------------------
7
+
8
+ bit[] = < {} 0, {} 1 >;
9
+
10
+ sign[] = < {} "+", {} "-" >;
11
+
12
+ exponent[] = {
13
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4,
14
+ bit[] 5, bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10
15
+ };
16
+
17
+ fraction[] = {
18
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4, bit[] 5,
19
+ bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10, bit[] 11,
20
+ bit[] 12, bit[] 13, bit[] 14, bit[] 15, bit[] 16, bit[] 17,
21
+ bit[] 18, bit[] 19, bit[] 20, bit[] 21, bit[] 22, bit[] 23,
22
+ bit[] 24, bit[] 25, bit[] 26, bit[] 27, bit[] 28, bit[] 29,
23
+ bit[] 30, bit[] 31, bit[] 32, bit[] 33, bit[] 34, bit[] 35,
24
+ bit[] 36, bit[] 37, bit[] 38, bit[] 39, bit[] 40, bit[] 41,
25
+ bit[] 42, bit[] 43, bit[] 44, bit[] 45, bit[] 46, bit[] 47,
26
+ bit[] 48, bit[] 49, bit[] 50, bit[] 51
27
+ };
28
+
29
+ number[] = {
30
+ sign[] sign,
31
+ exponent[] exponent,
32
+ fraction[] fraction
33
+ };
34
+
35
+ byte[] = {
36
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
37
+ bit[] 4, bit[] 5, bit[] 6, bit[] 7
38
+ };
39
+
40
+ ascii[] = {
41
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
42
+ bit[] 4, bit[] 5, bit[] 6
43
+ };
44
+
45
+ bmp_hi_common[] = <
46
+ { bit[] 0, bit[] 1, bit[] 2 } h08_0F,
47
+ ascii[] h10_7F,
48
+ ascii[] h80_CF,
49
+ { bit[] 0, bit[] 1, bit[] 2 } hD0_D7,
50
+ {} hF9,
51
+ { bit[] 0 } hFA_FB,
52
+ { bit[] 0 } hFC_FD,
53
+ { bit[] 0 } hFE_FF
54
+ >;
55
+
56
+ bmp_hi_private_use[] = <
57
+ { bit[] 0, bit[] 1, bit[] 2, bit[] 3 } hE0_EF,
58
+ { bit[] 0, bit[] 1, bit[] 2 } hF0_F7,
59
+ {} hF8
60
+ >;
61
+
62
+ plane0[] = {
63
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4,
64
+ bit[] 5, bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10
65
+ };
66
+
67
+ plane_02_10[] = <
68
+ { bit[] 0 } p02_03,
69
+ { bit[] 0, bit[] 1 } p04_07,
70
+ { bit[] 0, bit[] 1, bit[] 2 } p08_0F,
71
+ {} p10
72
+ >;
73
+
74
+ unicode[] = <
75
+ ascii[] ascii,
76
+ { bmp_hi_common[] hi, byte[] lo } bmp_common,
77
+ { bmp_hi_private_use[] hi, byte[] lo } bmp_private_use,
78
+ plane0[] plane0,
79
+ { byte[] mid, byte[] lo } supplementary_plane1,
80
+ { plane_02_10[] plane, byte[] mid, byte[] lo } supplementary_planes2_16
81
+ >;
82
+
83
+ string[] = < {} nil, { unicode[] car, S cdr } cons > = S;
84
+
85
+ bool[] = < {} true, {} false >;
86
+
87
+ list[X] = < {} nil, { X car, L cdr } cons > = L;
88
+
89
+ pair[K, V] = { K key, V val };
90
+
91
+ object[V] = list[pair[string[], V]];
92
+
93
+ djson[] = <
94
+ number[] number,
95
+ string[] string,
96
+ bool[] bool,
97
+ {} null,
98
+ list[J] list,
99
+ object[J] object
100
+ > = J;
101
+
102
+ json? = ? djson[];
103
+
104
+ bit? = ? bit[];
105
+ string? = ? string[];
106
+ float64? = ? number[];
107
+ bool? = ? bool[];
108
+ null? = ? {};
109
+ list? = ? list[X];
110
+ object? = ? list[pair[K, V]];
111
+
112
+ ---------------------------------------------------------------
113
+ -- §2. Constructors and Projections
114
+ ---------------------------------------------------------------
115
+
116
+ nil = {} | nil list?;
117
+ cons = {.car car, .cdr cdr} | cons list?;
118
+ car = list? /cons .car;
119
+ cdr = list? /cons .cdr;
120
+
121
+ null = {} | null json?;
122
+ true = {} | true | bool json?;
123
+ false = {} | false | bool json?;
124
+ number = float64? | number json?;
125
+ string = string? | string json?;
126
+ bool = bool? | bool json?;
127
+ list = list? | list json?;
128
+ object = object? | object json?;
129
+
130
+ ---------------------------------------------------------------
131
+ -- §3. String Equality (eq_string?)
132
+ ---------------------------------------------------------------
133
+
134
+ eq_bit? = ?{ <{} 0, {} 1>=B x, B y }
135
+ < {.x /0 x, .y /0 y}, {.x /1 x, .y /1 y} > {};
136
+
137
+ eq_bits1? = { {.x .0 x, .y .0 y} eq_bit? 0 } {};
138
+ eq_bits2? = { {.x x, .y y} eq_bits1? a, {.x .1 x, .y .1 y} eq_bit? 1 } {};
139
+ eq_bits3? = { {.x x, .y y} eq_bits2? a, {.x .2 x, .y .2 y} eq_bit? 2 } {};
140
+ eq_bits4? = { {.x x, .y y} eq_bits3? a, {.x .3 x, .y .3 y} eq_bit? 3 } {};
141
+ eq_bits7? = {
142
+ {.x x, .y y} eq_bits4? a,
143
+ {.x .4 x, .y .4 y} eq_bit? 4,
144
+ {.x .5 x, .y .5 y} eq_bit? 5,
145
+ {.x .6 x, .y .6 y} eq_bit? 6
146
+ } {};
147
+ eq_bits8? = { {.x x, .y y} eq_bits7? a, {.x .7 x, .y .7 y} eq_bit? 7 } {};
148
+ eq_bits11? = {
149
+ {.x x, .y y} eq_bits8? a,
150
+ {.x .8 x, .y .8 y} eq_bit? 8,
151
+ {.x .9 x, .y .9 y} eq_bit? 9,
152
+ {.x .10 x, .y .10 y} eq_bit? 10
153
+ } {};
154
+
155
+ eq_bmp_common_hi? = <
156
+ {.x /h08_0F x, .y /h08_0F y} eq_bits3?,
157
+ {.x /h10_7F x, .y /h10_7F y} eq_bits7?,
158
+ {.x /h80_CF x, .y /h80_CF y} eq_bits7?,
159
+ {.x /hD0_D7 x, .y /hD0_D7 y} eq_bits3?,
160
+ {.x /hF9 x, .y /hF9 y} {},
161
+ {.x /hFA_FB x, .y /hFA_FB y} eq_bits1?,
162
+ {.x /hFC_FD x, .y /hFC_FD y} eq_bits1?,
163
+ {.x /hFE_FF x, .y /hFE_FF y} eq_bits1?
164
+ >;
165
+
166
+ eq_bmp_private_use_hi? = <
167
+ {.x /hE0_EF x, .y /hE0_EF y} eq_bits4?,
168
+ {.x /hF0_F7 x, .y /hF0_F7 y} eq_bits3?,
169
+ {.x /hF8 x, .y /hF8 y} {}
170
+ >;
171
+
172
+ eq_plane2_16? = <
173
+ {.x /p02_03 x, .y /p02_03 y} eq_bits1?,
174
+ {.x /p04_07 x, .y /p04_07 y} eq_bits2?,
175
+ {.x /p08_0F x, .y /p08_0F y} eq_bits3?,
176
+ {.x /p10 x, .y /p10 y} {}
177
+ >;
178
+
179
+ eq_char? = <
180
+ {.x /ascii x, .y /ascii y} eq_bits7?,
181
+ {
182
+ {.x /bmp_common .hi x, .y /bmp_common .hi y} eq_bmp_common_hi? hi,
183
+ {.x /bmp_common .lo x, .y /bmp_common .lo y} eq_bits8? lo
184
+ } {},
185
+ {
186
+ {
187
+ .x /bmp_private_use .hi x,
188
+ .y /bmp_private_use .hi y
189
+ } eq_bmp_private_use_hi? hi,
190
+ {.x /bmp_private_use .lo x, .y /bmp_private_use .lo y} eq_bits8? lo
191
+ } {},
192
+ {.x /plane0 x, .y /plane0 y} eq_bits11?,
193
+ {
194
+ {
195
+ .x /supplementary_plane1 .mid x,
196
+ .y /supplementary_plane1 .mid y
197
+ } eq_bits8? mid,
198
+ {
199
+ .x /supplementary_plane1 .lo x,
200
+ .y /supplementary_plane1 .lo y
201
+ } eq_bits8? lo
202
+ } {},
203
+ {
204
+ {
205
+ .x /supplementary_planes2_16 .plane x,
206
+ .y /supplementary_planes2_16 .plane y
207
+ } eq_plane2_16? plane,
208
+ {
209
+ .x /supplementary_planes2_16 .mid x,
210
+ .y /supplementary_planes2_16 .mid y
211
+ } eq_bits8? mid,
212
+ {
213
+ .x /supplementary_planes2_16 .lo x,
214
+ .y /supplementary_planes2_16 .lo y
215
+ } eq_bits8? lo
216
+ } {}
217
+ >;
218
+
219
+ _eq_string? = {.x string? x, .y string? y} <
220
+ {.x /nil x, .y /nil y} {},
221
+ {
222
+ {.x /cons .car x, .y /cons .car y} eq_char? if,
223
+ {.x /cons .cdr x, .y /cons .cdr y} then
224
+ } .then _eq_string?
225
+ >;
226
+
227
+ -- Identity filter on {x, y} when strings x and y are equal
228
+ eq_string? = ?{ S x, S y } {_eq_string? if, () then} .then;
229
+
230
+ ---------------------------------------------------------------
231
+ -- §4. JSON Object Helpers (dot, has_key?, keys, values, remove, put)
232
+ ---------------------------------------------------------------
233
+
234
+ -- Lookup key in object entry list: {key, object} -> val
235
+ dot = ?{ K key, O object } {.key string? key, .object object? object} <
236
+ {
237
+ {.key x, .object /cons .car .key y} eq_string? if,
238
+ .object /cons .car .val then
239
+ } .then,
240
+ {.key key, .object /cons .cdr object} dot
241
+ >;
242
+
243
+ -- Identity filter on {key, object} when key exists in object
244
+ has_key? = ?{ K key, O object } {dot if, () then} .then;
245
+
246
+ -- Extract list of keys from an object entry list: object -> list
247
+ keys = object? <
248
+ /nil nil,
249
+ /cons {.car .key car, .cdr keys cdr} cons
250
+ >;
251
+
252
+ -- Extract list of values from an object entry list: object -> list
253
+ values = object? <
254
+ /nil nil,
255
+ /cons {.car .val car, .cdr values cdr} cons
256
+ >;
257
+
258
+ -- Remove all entries matching key from object: {key, object} -> object
259
+ remove = ?{ K key, O object } {.key string? key, .object object? object} <
260
+ {.object /nil if, nil then} .then,
261
+ {
262
+ {.key x, .object /cons .car .key y} eq_string? if,
263
+ {.key key, .object /cons .cdr object} remove then
264
+ } .then,
265
+ {
266
+ .object /cons .car car,
267
+ {.key key, .object /cons .cdr object} remove cdr
268
+ } cons
269
+ >;
270
+
271
+ -- Insert or replace {key, val} in object: {key, val, object} -> object
272
+ put = ?{ K key, V val, O object } {
273
+ {.key string? key, .val val} car,
274
+ {.key key, .object object} remove cdr
275
+ } cons;
276
+
277
+ -- Lookup bits? index in cons-list: {index, list} -> value
278
+ bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
279
+ 0b = {} | _;
280
+ 0 = 0b | 0;
281
+ 1 = 0b | 1;
282
+
283
+ _inv = ?{ < {} _, B 0, B 1 >=B x, B r } <
284
+ { .x /_ if, .r then } .then,
285
+ { .x /0 x, .r |0 r } _inv,
286
+ { .x /1 x, .r |1 r } _inv
287
+ > bits?;
288
+ _dec = ?{ < {} _, B 0, B 1 >=B x, B y } <
289
+ { .x /1 x, .y |0 r } _inv,
290
+ { .x /0 x, .y |1 y } _dec
291
+ > bits?;
292
+ _inc = ?{ < {} _, B 0, B 1 >=B x, B y } <
293
+ { .x /_ if, .y |1 then } .then,
294
+ { .x /0 x, .y |1 r } _inv,
295
+ { .x /1 x, .y |0 y } _inc
296
+ > bits?;
297
+ _trim0 = bits? < /0 _trim0, /_ 0, () >;
298
+ dec_nat = { { () x, 0b r } _inv x, 0b y } _dec _trim0;
299
+ inc_nat = { { () x, 0b r } _inv x, 0b y } _inc;
300
+
301
+ nth = ?{ I index, L list } { .index bits? index, .list list? list } <
302
+ { .index /0 /_ if, .list /cons .car then } .then,
303
+ { .index dec_nat index, .list /cons .cdr list } nth
304
+ >;
305
+
306
+ -- Count elements in list or object: list -> bits?, object -> bits?
307
+ _list_size = ?{
308
+ < {} nil, { X car, L cdr } cons >=L list,
309
+ < {} _, B 0, B 1 >=B acc
310
+ } <
311
+ { .list /nil if, .acc then } .then,
312
+ { .list /cons .cdr list, .acc inc_nat acc } _list_size
313
+ > bits?;
314
+ list_size = { list? list, 0 acc } _list_size;
315
+
316
+ _obj_size = ?{
317
+ < {} nil, { { K key, V val } car, O cdr } cons >=O object,
318
+ < {} _, B 0, B 1 >=B acc
319
+ } <
320
+ { .object /nil if, .acc then } .then,
321
+ { .object /cons .cdr object, .acc inc_nat acc } _obj_size
322
+ > bits?;
323
+ obj_size = { object? object, 0 acc } _obj_size;
package/Examples/esc.k CHANGED
@@ -1,4 +1,4 @@
1
- $ utf8 = <{} '
1
+ utf8[] = <{} '
2
2
  \u2601\u2600\u2602
3
3
  ',
4
4
  {} '✅',
@@ -5,19 +5,21 @@
5
5
  yes = {} | yes;
6
6
  no = {} | no;
7
7
 
8
- bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
8
+ bits[] = < {} _, B 0, B 1 > = B;
9
+ bits? = ? bits[];
9
10
  0b = {} | _;
10
11
  0 = 0b |0;
11
12
  1 = 0b |1;
12
13
 
13
- unat? = ?< {} _, unat? 1 > = unat?;
14
+ unat[] = < {} _, U 1 > = U;
15
+ unat? = ? unat[];
14
16
  0u = {} | _;
15
17
 
16
18
  empty = < /_ yes, no >;
17
19
  empty? = {empty /yes if, () then} .then;
18
20
 
19
21
  inv = {()x, 0b r} _inv;
20
- _inv = ?{ <X 0, X 1, {} _>=X x, ... }
22
+ _inv = ?{ bits[] = X x, ... }
21
23
  <
22
24
  {.x empty? if, .r then} .then,
23
25
  <
@@ -27,7 +29,7 @@ _inv = ?{ <X 0, X 1, {} _>=X x, ... }
27
29
  >;
28
30
 
29
31
  concat = {.x inv x, .y y} concat_;
30
- concat_ = ?{ <X 0, X 1, {} _>=X x, ... }
32
+ concat_ = ?{ bits[] = X x, ... }
31
33
  <
32
34
  {.x empty? if, .y then} .then,
33
35
  <
@@ -50,7 +52,7 @@ c0 = {} | 0;
50
52
  c1 = {} | 1;
51
53
 
52
54
  _plus = {.x x, .y y, .c c, 0b r} _plus_;
53
- _plus_ = ?{ <X 0, X 1, {} _>=X x, ... }
55
+ _plus_ = ?{ bits[] = X x, ... }
54
56
  <
55
57
  {.x empty? if, .y empty? and, .c/0 c, .r inv then} .then,
56
58
  {.x empty? if, .y empty? and, {.r x, 1 r} _inv then} .then,
@@ -70,7 +72,7 @@ _plus_ = ?{ <X 0, X 1, {} _>=X x, ... }
70
72
  >;
71
73
 
72
74
  _minus = {.x x, .y y, .c c, 0b r} _minus_;
73
- _minus_ = ?{ <X 0, X 1, {} _>=X x, ... }
75
+ _minus_ = ?{ bits[] = X x, ... }
74
76
  <
75
77
  {.y empty? if, .c/0 and, {.r x, .x r} _inv then} .then,
76
78
  <
@@ -90,7 +92,7 @@ _minus_ = ?{ <X 0, X 1, {} _>=X x, ... }
90
92
  plus_bits = {.x inv x, .y inv y, c0 c} _plus inv nat;
91
93
  minus_bits = {.x inv x, .y inv y, c0 c} _minus inv nat;
92
94
 
93
- _times = ?{ <Y 0, Y 1, {} _>=Y y, ... }
95
+ _times = ?{ bits[] = Y y, ... }
94
96
  <
95
97
  {.y empty? if, .result then} .then,
96
98
  <
@@ -100,19 +102,20 @@ _times = ?{ <Y 0, Y 1, {} _>=Y y, ... }
100
102
  >;
101
103
  times_bits = {0 result, .x inv _x, .y y} _times inv nat;
102
104
 
103
- unat_to_zeros = ?< {} _, X 1 >=X < /_ 0b, /1 unat_to_zeros |0 > ?< {} _, Z 0, Z 1 >=Z;
104
- unat_to_double_zeros = ?< {} _, X 1 >=X
105
- < /_ 0b, /1 unat_to_double_zeros |0 |0 > ?< {} _, Z 0, Z 1 >=Z;
105
+ unat_to_zeros =
106
+ ? unat[] < /_ 0b, /1 unat_to_zeros |0 > ? bits[];
107
+ unat_to_double_zeros =
108
+ ? unat[] < /_ 0b, /1 unat_to_double_zeros |0 |0 > ? bits[];
106
109
 
107
110
  _peel2 = < </0,/1> </0,/1>, </0,/1>, () >;
108
- _half_unat = ?{ <X 0, X 1, {} _>=X x, ... }
111
+ _half_unat = ?{ bits[] = X x, ... }
109
112
  <
110
113
  {.x empty? if, .y empty? and, .m then} .then,
111
114
  {.x _peel2 x, .y _peel2 y, .m |1 m} _half_unat
112
115
  >;
113
116
  half_unat = {.x x, .y y, 0u m} _half_unat;
114
117
 
115
- _split_rev_u = ?{ <X 0, X 1, {} _>=X x_rev, <M 1, {} _>=M m, ... }
118
+ _split_rev_u = ?{ bits[] = X x_rev, unat[] = M m, ... }
116
119
  <
117
120
  {.m /_ if, {.low nat low, .x_rev inv nat high} then} .then,
118
121
  {.x_rev empty? if, {.low nat low, 0 high} then} .then,
@@ -155,7 +158,7 @@ shift2_bits_u =
155
158
  {.val x, .m unat_to_double_zeros y} concat
156
159
  >;
157
160
 
158
- _karatsuba = ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y }
161
+ _karatsuba = ?{ bits[] = X x, bits[] = Y y }
159
162
  <
160
163
  -- Base case: if m < 256 (< 512 bits), fall back to times_bits
161
164
  {{.x x, .y y} half_unat m, .x x, .y y}
package/Examples/list.k CHANGED
@@ -1,7 +1,11 @@
1
- list? = ?< {} nil, {X car, Y cdr} cons > = Y;
2
- nil = {} |nil list?;
3
- singleton = {() car, nil cdr} | cons list?;
4
- cons = {.car car, .cdr cdr} | cons list?;
1
+ -- Examples/list.k: Generic linked list patterns and relations
2
+
3
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
4
+ list? = ? list[X];
5
+
6
+ nil = {} | nil list?;
7
+ singleton = { () car, nil cdr } | cons list?;
8
+ cons = { .car car, .cdr cdr } | cons list?;
5
9
  nil? = list? /nil nil;
6
10
  car = list? /cons .car;
7
11
  cdr = list? /cons .cdr;
package/Examples/nat.k CHANGED
@@ -1,11 +1,17 @@
1
- 0 = {} | 0 ;
2
- 0? = { / 0 if, () then} .then;
3
- succ = | +1 ;
4
- pred = / +1 ;
5
- add = ?{ < {} 0, N +1 > = N x, ... } = X <{.x pred x, .y succ y} ?X add, .y> ;
6
- mult = ?{ < {} 0, M +1 > = M x, ... } <
7
- {{.x pred x, .y y} mult x, .y y} add,
8
- 0
9
- > ;
10
-
11
- succ {()x,()y} add
1
+ -- Examples/nat.k: Peano natural numbers arithmetic
2
+
3
+ 0 = {} | 0;
4
+ 0? = { /0 if, () then } .then;
5
+ succ = | +1;
6
+ pred = / +1;
7
+
8
+ nat[] = < {} 0, N +1 > = N;
9
+ nat? = ? nat[];
10
+
11
+ add = ?{ nat[] = N x, ... } = X <{.x pred x, .y succ y} ?X add, .y>;
12
+ mult = ?{ nat[] = M x, ... } <
13
+ {{.x pred x, .y y} mult x, .y y} add,
14
+ 0
15
+ >;
16
+
17
+ succ {()x, ()y} add
package/Examples/poly.k CHANGED
@@ -2,7 +2,8 @@
2
2
  -- Uses arbitrary-precision integers from Examples/arithmetics.k.
3
3
 
4
4
  -- List constructors and destructors
5
- list? = ?< {} nil, {X car, Y cdr} cons > = Y;
5
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
6
+ list? = ? list[X];
6
7
  nil = {} | nil list?;
7
8
  singleton = {() car, nil cdr} | cons list?;
8
9
  cons = {.car car, .cdr cdr} | cons list?;
@@ -95,8 +96,15 @@ gt? =
95
96
  split = {() xs, nil first, nil second} _split;
96
97
  _split = <
97
98
  {.xs /nil if, {.first first, .second second} then} .then,
98
- {.xs cdr /nil if, {{.xs car car, .first cdr} cons first, .second second} then} .then,
99
- {.xs cdr cdr xs, {.xs car car, .first cdr} cons first, {.xs cdr car car, .second cdr} cons second} _split
99
+ {
100
+ .xs cdr /nil if,
101
+ {{.xs car car, .first cdr} cons first, .second second} then
102
+ } .then,
103
+ {
104
+ .xs cdr cdr xs,
105
+ {.xs car car, .first cdr} cons first,
106
+ {.xs cdr car car, .second cdr} cons second
107
+ } _split
100
108
  >;
101
109
 
102
110
  -- Merge two sorted lists: {xs, ys} -> list
@@ -1,50 +1,62 @@
1
1
  -- VHDL to K Translation Patterns
2
2
 
3
3
  -- VHDL: signal a : std_logic;
4
- -- K: $ bit = <{} 0, {} 1>;
4
+ -- K: bit[] = < {} 0, {} 1 >;
5
+ bit[] = < {} 0, {} 1 >;
5
6
 
6
7
  -- VHDL: signal bus : std_logic_vector(7 downto 0);
7
- -- K: $ byte = {bit 0, bit 1, bit 2, bit 3, bit 4, bit 5, bit 6, bit 7};
8
+ -- K: byte[] = {
9
+ -- bit[] 0, bit[] 1, bit[] 2, bit[] 3,
10
+ -- bit[] 4, bit[] 5, bit[] 6, bit[] 7
11
+ -- };
12
+ byte[] = {
13
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
14
+ bit[] 4, bit[] 5, bit[] 6, bit[] 7
15
+ };
16
+
17
+ nibble[] = { bit[] 0, bit[] 1, bit[] 2, bit[] 3 };
8
18
 
9
- -- VHDL: entity adder is port(a,b: in std_logic; sum: out std_logic); end;
10
- -- K: adder = ${bit a, bit b} {.a a_out, .b b_out, xor_gate sum_out};
19
+ 0 = {} | 0;
20
+ 1 = {} | 1;
11
21
 
12
- -- VHDL: process(clk) begin if rising_edge(clk) then q <= d; end if; end;
13
- -- K: dff = $bit .; -- Identity (register holds value)
22
+ -- VHDL: y <= not a;
23
+ not_bit = < /0 1, /1 0 >;
14
24
 
15
25
  -- VHDL: y <= a and b;
16
- -- K: and_gate = ${bit a, bit b} <{.a.1 1, .b.1 1, 1}, 0>;
26
+ and_bit = < .x/0 0, .y/0 0, 1 >;
17
27
 
18
- -- VHDL: y <= a or b;
19
- -- K: or_gate = ${bit a, bit b} <{.a.0 0, .b.0 0, 0}, 1>;
28
+ -- VHDL: y <= a or b;
29
+ or_bit = < .x/1 1, .y/1 1, 0 >;
20
30
 
21
- -- VHDL: y <= not a;
22
- -- K: not_gate = $bit <{.0 0, 1}, {.1 1, 0}>;
31
+ -- VHDL: y <= a xor b;
32
+ xor_bit = < {.x/0 if, .y then} .then, .y not_bit >;
33
+ xor_abc = {{.a x, .b y} xor_bit x, .c y} xor_bit;
23
34
 
24
- -- VHDL: with sel select y <= a when "00", b when "01", c when others;
25
- -- K: mux = ${bit sel0, bit sel1, bit a, bit b, bit c} <
26
- -- {.sel0.0 0, .sel1.0 0, .a},
27
- -- {.sel0.1 1, .sel1.0 0, .b},
28
- -- .c>;
35
+ -- VHDL: Full adder component
36
+ full_adder = ?{ bit[] a, bit[] b, bit[] c_in } {
37
+ {.a a, .b b, .c_in c} xor_abc sum,
38
+ {
39
+ {.a x, .b y} and_bit x,
40
+ {{.a x, .b y} xor_bit x, .c_in y} and_bit y
41
+ } or_bit carry
42
+ };
29
43
 
30
44
  -- VHDL: architecture of 4-bit adder
31
- four_bit_adder = ${
32
- {bit 0, bit 1, bit 2, bit 3} a,
33
- {bit 0, bit 1, bit 2, bit 3} b
45
+ four_bit_adder = ?{ nibble[] a, nibble[] b } {
46
+ .a a, .b b,
47
+ {.a.0 a, .b.0 b, 0 c_in} full_adder fa0
48
+ } {
49
+ .a a, .b b, .fa0 fa0,
50
+ {.a.1 a, .b.1 b, .fa0.carry c_in} full_adder fa1
51
+ } {
52
+ .a a, .b b, .fa0 fa0, .fa1 fa1,
53
+ {.a.2 a, .b.2 b, .fa1.carry c_in} full_adder fa2
54
+ } {
55
+ .fa0 fa0, .fa1 fa1, .fa2 fa2,
56
+ {.a.3 a, .b.3 b, .fa2.carry c_in} full_adder fa3
34
57
  } {
35
- {.a.0 a0, .b.0 b0} full_adder fa0,
36
- {.a.1 a1, .b.1 b1, .fa0.carry c_in} full_adder fa1,
37
- {.a.2 a2, .b.2 b2, .fa1.carry c_in} full_adder fa2,
38
- {.a.3 a3, .b.3 b3, .fa2.carry c_in} full_adder fa3,
39
58
  {.fa0.sum 0, .fa1.sum 1, .fa2.sum 2, .fa3.sum 3} sum,
40
59
  .fa3.carry overflow
41
60
  };
42
61
 
43
- -- VHDL: Full adder component
44
- full_adder = ${bit a, bit b, bit c_in} {
45
- {.a a_val, .b b_val} xor_gate ab_xor,
46
- {.ab_xor xor_val, .c_in c_val} xor_gate sum,
47
- {.a a_val, .b b_val} and_gate ab_and,
48
- {.ab_xor xor_val, .c_in c_val} and_gate xor_cin_and,
49
- {.ab_and and1, .xor_cin_and and2} or_gate carry
50
- };
62
+ ()
package/README.md CHANGED
@@ -45,18 +45,19 @@ k can define recursive data and transformations in the same file. Peano
45
45
  natural numbers are either `0` or one more than another natural number:
46
46
 
47
47
  ```k
48
+ nat[] = < {} 0, N +1 > = N;
48
49
  0 = {} | 0;
49
50
  inc = | +1;
50
51
  dec = / +1; # undefined for '0'
51
- add = ?{ < {} 0, N +1 > = N x, ... } <
52
- { . x dec x, . y inc y } add, # defined if 'x > 0'
53
- . y # else, return 'y'
52
+ add = ?{ nat[] = N x, ... } <
53
+ { .x dec x, .y inc y } add, # defined if 'x > 0'
54
+ .y # else, return 'y'
54
55
  >;
55
56
  ```
56
57
 
57
58
  `add` takes a product `{ x, y }`. If `x` has a `+1`, it moves that
58
59
  successor from `x` to `y` and recurses. When that no longer applies, it
59
- returns `y`. The inductive filter `?{ < {} 0, N +1 > = N x, ... }`
60
+ returns `y`. The inductive filter `?{ nat[] = N x, ... }`
60
61
  explicitly witnesses that recursive calls shrink `x`.
61
62
 
62
63
  In the REPL:
@@ -122,19 +123,41 @@ Every installed command supports `-h` and `--help`.
122
123
 
123
124
  ## What k Gives You
124
125
 
125
- **Algebraic data shapes**
126
+ **Algebraic data shapes and named patterns**
126
127
 
127
- All data structures in k are built from products and tagged unions (variants).
128
- Relations and pattern filters describe their domains:
128
+ All data structures in k are built from products and tagged unions
129
+ (variants). Reusable named patterns describe structural type schemas
130
+ using square brackets `name[...]`:
129
131
 
130
132
  ```k
131
- bit? = ?< {} 0, {} 1 >;
132
- byte? = ?{ Bit 0, Bit 1, Bit 2, Bit 3, Bit 4, Bit 5, Bit 6, Bit 7 };
133
- bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
133
+ bit[] = < {} 0, {} 1 >;
134
+ bits[] = < {} _, B 0, B 1 > = B;
135
+ byte[] = {
136
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
137
+ bit[] 4, bit[] 5, bit[] 6, bit[] 7
138
+ };
139
+
140
+ -- Parameterized type templates:
141
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
142
+ pair[A, B] = { A first, B second };
134
143
  ```
135
144
 
136
- There are no built-in primitive values. The empty product `{}` is the
137
- only leaf in a non-recursive definition.
145
+ Callers instantiate patterns using `? name[...]` as standalone filters
146
+ or inside relation parameter guards (`?{ nat[] = N x, ... }`). There are
147
+ no built-in primitive values: the empty product `{}` is the only leaf
148
+ in a non-recursive definition.
149
+
150
+ **The four-bracket architecture**
151
+
152
+ k uses an orthogonal four-bracket convention with non-overlapping
153
+ semantic domains:
154
+
155
+ | Brackets | Domain | Purpose & Concrete Example |
156
+ | :--- | :--- | :--- |
157
+ | `{ ... }` | Products | Record construction: `{ f a, g b }`, `{}` |
158
+ | `< ... >` | Unions | Variant choice: `< f, g >`, `<>` |
159
+ | `( ... )` | Relations | Composition & identity: `(f g)`, `()` |
160
+ | `[ ... ]` | Patterns | Reusable templates: `list[X]`, `bit[]` |
138
161
 
139
162
  **Composable partial functions**
140
163
 
@@ -149,6 +172,7 @@ Core expressions are deliberately small:
149
172
  | `<f, g>` | try `f`, then `g` if `f` is undefined |
150
173
  | `{f a, g b}` | build a product from parallel transformations |
151
174
  | `?filter` | schema filter / inductive termination witness |
175
+ | `name[...]` | instantiate named pattern template |
152
176
  | `()` | identity |
153
177
  | `<>` | always undefined |
154
178
  | `{}` | constant empty product |
@@ -223,9 +247,12 @@ For a detailed guide to all four formats, commands, and workflows, see
223
247
 
224
248
  | Command | Purpose |
225
249
  | --- | --- |
226
- | `k-json` | Convert JSON to/from the binary stream |
227
- | `k-int` | Convert decimal integers to/from the binary stream |
228
- | `k-ieee` | Convert float literals to/from the binary stream |
250
+ | `k-json` | Convert JSON to/from binary stream (specializing) |
251
+ | `k-djson` | Convert JSON to/from dynamic JSON (cons-list) |
252
+ | `k-djson-btrie` | Convert JSON to/from binary bit-trie dynamic JSON |
253
+ | `k-djson-ptrie` | Convert JSON to/from radix trie dynamic JSON |
254
+ | `k-int` | Convert decimal integers to/from binary stream |
255
+ | `k-ieee` | Convert float literals to/from binary stream |
229
256
  | `k-unit` | Produce or validate the unit value |
230
257
  | `k-utf8` / `k-utf16` | Convert text to/from k string streams |
231
258