@fraczak/k 6.10.6 → 7.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 (69) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/CLAUDE.md +1 -1
  3. package/DOCS/BIG_PICTURE.md +156 -172
  4. package/DOCS/BINARY_CODEC_STATUS_AND_TODO.md +3 -3
  5. package/DOCS/CODEC_ARCHITECTURE.md +2 -2
  6. package/DOCS/DICTIONARY.md +243 -250
  7. package/DOCS/DIVERGENCE_DETECTION.md +0 -1
  8. package/DOCS/FILE_FORMATS.md +5 -5
  9. package/DOCS/KIR_SPECIALIZATION_DESIGN.md +1 -1
  10. package/DOCS/OBJECT_FILE_AND_PATTERN.md +12 -12
  11. package/DOCS/PATTERNS.md +17 -17
  12. package/DOCS/PATTERNS_AND_TYPED_VALUES.md +1 -1
  13. package/DOCS/REPL.md +9 -19
  14. package/DOCS/TYPE_DERIVATION.md +2 -8
  15. package/DOCS/WEB_REPL_REQUIREMENTS.md +8 -8
  16. package/DOCS/book/01-introduction.md +8 -11
  17. package/DOCS/book/02-syntax-and-values.md +19 -20
  18. package/DOCS/book/03-types-as-finite-automata.md +42 -43
  19. package/DOCS/book/04-partial-functions-and-composition.md +2 -3
  20. package/DOCS/book/05-typing-filters-and-normalization.md +44 -46
  21. package/DOCS/book/06-values-in-memory.md +10 -10
  22. package/DOCS/book/08-operational-semantics-and-execution.md +21 -26
  23. package/DOCS/book/09-compiler-architecture.md +11 -11
  24. package/DOCS/book/10-from-ast-to-intermediate-representation.md +6 -7
  25. package/DOCS/book/14-canonical-serialization.md +2 -2
  26. package/DOCS/book/appendix-b-incorporating-external-predefined-types-and-functions.md +17 -17
  27. package/DOCS/book.md +5 -5
  28. package/Examples/arithmetics.k +49 -153
  29. package/Examples/bnat.k +13 -13
  30. package/Examples/byte.k +2 -50
  31. package/Examples/ieee.k +408 -423
  32. package/Examples/karatsuba-mult.k +30 -34
  33. package/Examples/nat.k +5 -6
  34. package/README.md +54 -49
  35. package/TODO.md +13 -18
  36. package/browser/vfs-data.mjs +11 -11
  37. package/codecs/BINARY_FORMAT.md +4 -4
  38. package/codecs/POLYMORPHIC_BINARY_FORMAT.md +4 -4
  39. package/codecs/README.md +6 -6
  40. package/codecs/ieee.mjs +15 -11
  41. package/codecs/int.mjs +9 -5
  42. package/codecs/string-codec.mjs +46 -47
  43. package/core.k +123 -95
  44. package/object.mjs +0 -7
  45. package/package.json +5 -2
  46. package/parser.jison +2 -41
  47. package/parser.mjs +55 -95
  48. package/pretty.mjs +11 -4
  49. package/repl.mjs +8 -63
  50. package/scripts/build-repl-html.mjs +8 -38
  51. package/tests/code-derivation/blowup.mjs +2 -4
  52. package/tests/code-derivation/bnat.mjs +2 -3
  53. package/tests/code-derivation/dot.mjs +5 -11
  54. package/tests/code-derivation/nat.mjs +2 -2
  55. package/tests/code-derivation/not-not.mjs +6 -6
  56. package/tests/code-derivation/pattern-envelope.mjs +4 -6
  57. package/tests/code-derivation/product.mjs +3 -6
  58. package/tests/code-derivation/rlz.mjs +4 -5
  59. package/tests/test-codecs.mjs +1 -1
  60. package/tests/test-fingerprint.mjs +36 -41
  61. package/tests/test-hash-normalization.mjs +4 -6
  62. package/tests/test-ieee-arithmetic.mjs +6 -7
  63. package/tests/test-k-object.mjs +11 -15
  64. package/tests/test-kir.mjs +0 -1
  65. package/tests/test-kvm-polymorphic.mjs +1 -2
  66. package/tests/test-kvm.mjs +8 -11
  67. package/tests/test-repl-html.mjs +5 -2
  68. package/tests/test-repl.mjs +38 -53
  69. package/tests/test.mjs +2 -3
@@ -1,14 +1,14 @@
1
- # Chapter 3 — Types as Finite Automata
1
+ # Chapter 3 — Schemas as Finite Automata
2
2
 
3
3
  ## **3.1 Motivation**
4
4
 
5
- A type in `k` describes a set of finite labeled trees, which can be recognized by a finite tree automaton (FTA). Equivalently, a type definition can be seen as a context-free grammar (CFG), where the values of the type are the derivation trees of the grammar.
5
+ A schema in `k` describes a set of finite labeled trees, which can be recognized by a finite tree automaton (FTA). Equivalently, a schema definition can be seen as a context-free grammar (CFG), where the payloads of the schema are the derivation trees of the grammar.
6
6
 
7
- For example, the recursive type definition of a `list`:
7
+ For example, the recursive schema of a `list`:
8
8
 
9
9
  ```k-lang
10
- $ bool = < {} true, {} false >;
11
- $ list = < {} nil, { bool head, list tail } cons >;
10
+ bool = ?< {} true, {} false >;
11
+ list = ?< {} nil, { < {} true, {} false > head, L tail } cons > = L;
12
12
  ```
13
13
 
14
14
  corresponds to the following 4-rule grammar:
@@ -20,7 +20,7 @@ corresponds to the following 4-rule grammar:
20
20
  4: <list> ::= { <bool> head, <list> tail } |cons
21
21
  ```
22
22
 
23
- A value of type `list` is a derivation tree of this grammar. For instance, a list containing a single boolean value `true` can be represented by the following derivation:
23
+ A payload of schema `list` is a derivation tree of this grammar. For instance, a list containing a single boolean value `true` can be represented by the following derivation:
24
24
 
25
25
  ```
26
26
  <list>
@@ -31,25 +31,25 @@ A value of type `list` is a derivation tree of this grammar. For instance, a lis
31
31
  -- (rule 1) --> {} |true
32
32
  ```
33
33
 
34
- This derivation tree corresponds to the value generated by the constant function `{ {} |true head, {} |nil tail } |cons`.
34
+ This derivation tree corresponds to the payload generated by the constant relation `{ {} |true head, {} |nil tail } |cons`.
35
35
 
36
- Representing types as automata (or CFGs) provides each type with a well-defined structure, independent of the names used in the source code. This allows for canonical normal forms and for comparing types for equality by structure alone.
36
+ Representing schemas as automata (or CFGs) provides each schema with a well-defined structure, independent of the names used in the source code. This allows for canonical normal forms and for comparing schemas for equality by structure alone.
37
37
 
38
38
  ---
39
39
 
40
40
  ## **3.2 States and Transitions**
41
41
 
42
- Each type definition introduces one or more *states* in the automaton. A union or a product definition corresponds to a state, and the variants or fields correspond to transitions to other states.
42
+ Each schema structure introduces one or more *states* in the automaton. A union or a product schema corresponds to a state, and the variants or fields correspond to transitions to other states.
43
43
 
44
- For example, consider the `$bool` type:
44
+ For example, consider the `bool` schema:
45
45
 
46
46
  ```k-lang
47
- $ bool = < {} true, {} false >;
47
+ bool = ?< {} true, {} false >;
48
48
  ```
49
49
 
50
- This definition translates to an automaton with two states:
50
+ This schema translates to an automaton with two states:
51
51
 
52
- - A root state, let's call it `C0`, representing the `$bool` type itself (a union).
52
+ - A root state, let's call it `C0`, representing the `bool` schema itself (a union).
53
53
  - A state `C1` representing the empty product `{}`.
54
54
 
55
55
  From the root state `C0`, there are two transitions:
@@ -57,46 +57,45 @@ From the root state `C0`, there are two transitions:
57
57
  - A transition labeled `true` to state `C1`.
58
58
  - A transition labeled `false` to state `C1`.
59
59
 
60
- `C0` is the root state of the type, and `C1` is a leaf state, representing an empty value.
60
+ `C0` is the root state of the schema, and `C1` is a leaf state, representing an empty unit value.
61
61
 
62
62
  ---
63
63
 
64
64
  ## **3.3 Canonical Form**
65
65
 
66
- Different type expressions can describe the same automaton. For example:
66
+ Different schema expressions can describe the same automaton. For example:
67
67
 
68
68
  ```k-lang
69
- $ bool = < {} false, {} true >;
70
- $ pair = { bool x, bool y };
71
- $ pair2 = { < {} true, {} false > x, bool y };
69
+ pair = ?{ < {} false, {} true > x, < {} false, {} true > y };
70
+ pair2 = ?{ < {} true, {} false > x, < {} true, {} false > y };
72
71
  ```
73
72
 
74
- The types `pair` and `pair2` are structurally equivalent because `$bool` is defined as `< {} true, {} false >`, making the definition of `x` in `pair2` identical to the standalone `$bool` type used in `pair`. Canonicalization is the process of removing these superficial differences by erasing local names and renumbering states to produce a single stable representation for each unique type structure.
73
+ The schemas `pair` and `pair2` are structurally equivalent because the choice order in a union does not alter the underlying accepted set of trees. Canonicalization is the process of removing these superficial differences by erasing local names and renumbering states to produce a single stable representation for each unique schema structure.
75
74
 
76
- The canonical form is generated by traversing the type's graph structure starting from its root state. The process ensures a unique representation by following a consistent ordering:
75
+ The canonical form is generated by traversing the schema's graph structure starting from its root state. The process ensures a unique representation by following a consistent ordering:
77
76
 
78
- 1. **Start at the Root**: Assign the number `C0` to the root state of the type.
77
+ 1. **Start at the Root**: Assign the number `C0` to the root state of the schema.
79
78
  2. **Explore Neighbors**: Visit all states reachable from `C0`. Sort the transitions alphabetically by their labels (field or variant names) and assign consecutive numbers (`C1`, `C2`, ...) to the destination states in that order.
80
79
  3. **Iterate**: Move to the next state in the numbered sequence (`C1`, then `C2`, etc.) and repeat the process for any of its neighbors that have not yet been numbered.
81
80
  4. **Complete**: Continue until all reachable states have been assigned a unique number.
82
81
 
83
- This traversal produces a unique and deterministic numbering for any finite directed graph, ensuring that any two structurally identical types will have the exact same canonical representation.
82
+ This traversal produces a unique and deterministic numbering for any finite directed graph, ensuring that any two structurally identical schemas will have the exact same canonical representation.
84
83
 
85
84
  ---
86
85
 
87
86
  ## **3.4 Examples**
88
87
 
89
- For a type representing binary natural numbers:
88
+ For a schema representing binary natural numbers:
90
89
 
91
90
  ```k-lang
92
- $ bnat = < bnat 0, bnat 1, {} _ >;
91
+ bnat = ?< Bnat 0, Bnat 1, {} _ > = Bnat;
93
92
  ```
94
93
 
95
- the canonical form is:
94
+ the canonical automaton form is:
96
95
 
97
- ```k-lang
98
- $C0 = < C0 "0", C0 "1", C1 "_" >;
99
- $C1 = {};
96
+ ```text
97
+ C0 = < C0 "0", C0 "1", C1 "_" >;
98
+ C1 = {};
100
99
  ```
101
100
 
102
101
  The automaton has two states. `C0` is a recursive state that recognizes sequences of "0"s and "1"s, while `C1` is the terminal state, marked by the "_" transition.
@@ -105,52 +104,52 @@ The automaton has two states. `C0` is a recursive state that recognizes sequence
105
104
 
106
105
  ## **3.5 Normalization Process**
107
106
 
108
- When compiling a program, the following steps are taken to normalize types:
107
+ When compiling a program, the following steps are taken to normalize schemas:
109
108
 
110
- 1. **Collect**: Gather all type definitions from the program.
111
- 2. **Expand**: Recursively replace all named types with their underlying definitions until only products and unions remain.
112
- 3. **Deduplicate**: Eliminate duplicate type structures by comparing them structurally.
113
- 4. **Canonicalize**: Assign stable state numbers to the unique types to produce their canonical text representation.
109
+ 1. **Collect**: Gather all schema structures and filters from the program.
110
+ 2. **Expand**: Recursively replace named relation references with their underlying schema structures until only products and unions remain.
111
+ 3. **Deduplicate**: Eliminate duplicate schema structures by comparing them structurally.
112
+ 4. **Canonicalize**: Assign stable state numbers to the unique schemas to produce their canonical text representation.
114
113
 
115
- This process is deterministic, ensuring that the same type structure always produces the exact same canonical form.
114
+ This process is deterministic, ensuring that the same schema structure always produces the exact same canonical form.
116
115
 
117
116
  ---
118
117
 
119
118
  ## **3.6 Hash-Based Naming**
120
119
 
121
- To create a globally unique and stable identifier for each type, the compiler computes a hash of its canonical representation. This hash becomes the official, unambiguous name of the type.
120
+ To create a globally unique and stable index for each schema, the compiler computes a digest of its canonical automaton representation. This hash becomes a fixed-width content address for the schema in the registry.
122
121
 
123
122
  For example:
124
123
 
125
124
  ```text
126
- Canonical Form: $C0=<C0"0",C0"1",C1"_">;$C1={}
125
+ Canonical Automaton: C0=<C0"0",C0"1",C1"_">;C1={}
127
126
  ↓
128
127
  Hash
129
128
  ↓
130
129
  Identifier: @VtPHxGf5GNMzzyVFxtv7gegFfJRYapBGtCeyV56bs5Zb
131
130
  ```
132
131
 
133
- Program objects can then refer to types by their hash-based identifiers (prefixed with `@`) without ambiguity.
132
+ Program objects and contracts can refer to schemas by their hash-based identifiers (prefixed with `@`) without ambiguity.
134
133
 
135
134
  ---
136
135
 
137
136
  ## **3.7 Interpretation**
138
137
 
139
- The canonical representation of a type can be interpreted as:
138
+ The canonical representation of a schema can be interpreted as:
140
139
 
141
140
  - A finite set of states, `C0…Cn`.
142
141
  - Each state is either a product (a record with named fields) or a union (a set of variants).
143
142
  - Transitions between states are labeled with strings (field or variant names).
144
143
 
145
- Every value of a given type is a finite tree that is accepted by this automaton.
144
+ Every payload tree of a given schema is a finite tree that is accepted by this automaton.
146
145
 
147
146
  ---
148
147
 
149
148
  ## **3.8 Summary**
150
149
 
151
- - Types in `k` denote sets of finite, labeled trees.
152
- - Every type can be expressed as a finite tree automaton or a context-free grammar.
153
- - The canonical form eliminates naming differences, providing a single representation for structurally identical types.
154
- - Hash-based naming gives each unique type a stable and globally unique identifier.
150
+ - Schemas in `k` denote sets of finite, labeled trees.
151
+ - Every schema can be expressed as a finite tree automaton or a context-free grammar.
152
+ - The canonical form eliminates naming differences, providing a single representation for structurally identical schemas.
153
+ - Hash-based naming gives each unique schema a stable and globally unique content-addressable identifier.
155
154
 
156
155
  ---
@@ -82,9 +82,8 @@ Since `k` lacks a direct syntax for literal values, constants are created using
82
82
  For example, we can define functions that return `true` and `false`:
83
83
 
84
84
  ```k-lang
85
- $ bool = < {} true, {} false >;
86
- true_bool = {} |true $bool ;
87
- false_bool = {} |false $bool ;
85
+ true_bool = {} |true;
86
+ false_bool = {} |false;
88
87
  ```
89
88
 
90
89
  Here, `true_bool` and `false_bool` are constant functions. They are also **total functions**, meaning they are defined for all inputs. Each function ignores its input and produces a fixed boolean value.
@@ -1,54 +1,51 @@
1
- # Chapter 5 — Typing, Filters, and Normalization
1
+ # Chapter 5 — Schemas, Filters, and Contracts
2
2
 
3
- ## **5.1 Types as functions**
3
+ ## **5.1 Filters as partial identity relations**
4
4
 
5
- A type expression in `k` can appear wherever a function is expected.
6
- When used this way, it is prefixed by `$`.
7
- It then behaves as a partial **identity** function that is defined only for values of that type.
8
- For example, `$ bool` is a partial identity: it returns its argument unchanged when the argument is of type `bool`, and it is undefined otherwise.
5
+ Filters in `k` are introduced by `?` and appear wherever an expression is expected.
6
+ A filter behaves as a partial **identity** relation: it returns its payload unchanged when the payload matches the schema described by the filter, and it is undefined otherwise.
7
+ For example, `? < {} true, {} false >` is a partial identity: it returns its payload unchanged when the payload is a boolean variant, and it is undefined otherwise.
9
8
 
10
- This convention eliminates any special syntax for annotating sub-expressions with types.
11
- An expression may be *restricted* to a type simply by composing it with the corresponding type expression.
9
+ Beyond serving as runtime guards, filters serve as **inductive termination witnesses** that allow contract derivation for recursive relations to converge into finite-state automata.
12
10
 
13
11
  ---
14
12
 
15
- ## **5.2 Filters**
13
+ ## **5.2 Filters and Schemas**
16
14
 
17
- A **filter** is a syntactic form that denotes a *class of types* — a set of types that share a common structure.
15
+ A **filter** is a syntactic form that denotes a *schema graph* — a structural specification of payloads that share a common shape.
18
16
 
19
17
  Filter expressions are introduced by `?` and can be:
20
18
 
21
- - **Type expressions** — `? $bool`, `? $< {} x, bool y >`
22
19
  - **Product filters** — `? { Filter1 field1, Filter2 field2 }`
23
20
  - **Union filters** — `? < Filter1 tag1, Filter2 tag2 >`
24
- - **Any-type filter** — `? ( ... )`
25
- - **Filter variables** — `? X` (metavariables representing unknown types)
26
- - **Filter bindings** — `? < X f, (...) = Y g, ... > = X`
21
+ - **Any-schema filter** — `? ( ... )`
22
+ - **Schema variables** — `? X` (local metavariables representing schema graph nodes)
23
+ - **Schema bindings** — `? < X f, (...) = Y g, ... > = X`
27
24
 
28
25
  Filters may contain `...` to indicate that additional fields or tags are allowed:
29
26
  `? { Filter1 field1, ... }` matches any product with at least `field1`.
30
27
 
31
- The filter `? (...)` matches any type.
32
- The filter `? {...}` matches any product type.
33
- The filter `? <...>` matches any union type.
28
+ The filter `? (...)` matches any schema.
29
+ The filter `? {...}` matches any product schema.
30
+ The filter `? <...>` matches any union schema.
34
31
  There is no closed unknown filter: use `?{}` for the empty product or `?<>` for the empty union.
35
32
 
36
33
  ---
37
34
 
38
35
  ## **5.3 Examples of filters**
39
36
 
40
- - `?(...)` — represents any type.
41
- - `?< (...) f, (...) g >` — represents all union types having exactly two variants `f` and `g`.
42
- - `?{ X f, X g }` — represents all product types with two fields `f` and `g`, both of the same type.
37
+ - `?(...)` — represents any schema.
38
+ - `?< (...) f, (...) g >` — represents all union schemas having exactly two variants `f` and `g`.
39
+ - `?{ X f, X g }` — represents all product schemas with two fields `f` and `g`, both of the same schema.
43
40
 
44
- A filter constrains where a partial function is defined; it does not affect the operational behavior of the function once defined.
41
+ A filter constrains where a relation is defined; it does not alter the output payload once defined.
45
42
 
46
43
  ---
47
44
 
48
- ## **5.4 Recursive filters**
45
+ ## **5.4 Recursive schemas and filters**
49
46
 
50
47
  Filters may be recursive.
51
- They can describe families of recursive types by defining a metavariable in terms of a filter that references it.
48
+ They can describe families of recursive schemas by defining a metavariable in terms of a filter that references it.
52
49
 
53
50
  Example (list definition):
54
51
 
@@ -56,19 +53,19 @@ Example (list definition):
56
53
  ?< {} nil, {X car, Y cdr} cons > = Y
57
54
  ```
58
55
 
59
- This filter states that `Y` is a union type with two variants: `nil` and `cons`.
56
+ This filter states that `Y` is a union schema with two variants: `nil` and `cons`.
60
57
 
61
58
  - The `nil` variant holds an empty product `{}`.
62
- - The `cons` variant is a product with two fields: `car` of some type `X`, and `cdr` of type `Y` itself.
59
+ - The `cons` variant is a product with two fields: `car` of some schema `X`, and `cdr` of schema `Y` itself.
63
60
 
64
- This recursive structure defines a linked list where each element has a `car` (the value) and a `cdr` (the rest of the list).
65
- It thus denotes lists of elements of type `X`.
61
+ This recursive structure defines a linked list where each element has a `car` (the payload) and a `cdr` (the rest of the list).
62
+ It thus denotes lists of elements of schema `X`.
66
63
 
67
64
  ---
68
65
 
69
- ## **5.5 Type variables and scope**
66
+ ## **5.5 Schema variables and scope**
70
67
 
71
- A type variable (an identifier, typically starting with an uppercase letter) introduced in a filter is visible within the enclosing function definition.
68
+ A schema variable (an identifier, typically starting with an uppercase letter) introduced in a filter is visible within the enclosing relation definition.
72
69
  For example:
73
70
 
74
71
  ```k-lang
@@ -77,35 +74,36 @@ car = ?< {} nil, {X car, Y cdr} cons > = Y /cons .car ?X;
77
74
 
78
75
  Here:
79
76
 
80
- - `X` and `Y` are type variables.
81
- - The filter `?<{}nil,{X car,Y cdr}cons>=Y` constrains the function `car` to be defined only on types that match the recursive list structure.
82
- - The expression `/cons` selects the `cons` variant of the union.
77
+ - `X` and `Y` are schema variables.
78
+ - The filter `?<{}nil,{X car,Y cdr}cons>=Y` constrains the relation `car` to be defined only on inputs that match the recursive list structure.
79
+ - The expression `/cons` asserts the `cons` variant of the union.
83
80
  - The expression `.car` accesses the `car` field of a `cons` variant.
84
- - The final filter `?X` asserts that the result of the field access is of type `X`, the type of the list's elements.
81
+ - The final filter `?X` asserts that the result of the field access is of schema `X`, the schema of the list's elements.
85
82
 
86
83
  ---
87
84
 
88
- ## **5.6 Type inference and normalization**
85
+ ## **5.6 Contract derivation and normalization**
89
86
 
90
- Every `k` program can be analyzed to assign an input and an output filter to every sub-expression. This process is called type inference and normalization.
87
+ Every `k` relation is analyzed by the compiler to derive its **contract**: a connected $(input, output)$ schema graph with shared vertices ($=X$) proving that input substructures are preserved through to the output.
91
88
 
92
- Type inference and normalization proceed as follows:
89
+ Contract derivation and normalization proceed as follows:
93
90
 
94
- 1. Build a graph of all type references appearing explicitly and implicitly in the program.
95
- 2. Annotate each expression node with a pair of (input filter, output filter).
96
- 3. Replace filters that match a single, concrete type with that type expression, adding any newly discovered types to the graph.
97
- 4. Repeat until a fixed point is reached and no more changes occur.
98
- 5. Compute canonical forms for all newly introduced types.
91
+ 1. Build a schema graph from explicit filters and primitive operations (projections, constructors, products).
92
+ 2. Propagate schemas forward and backward through compositions, products, and choices.
93
+ 3. Validate inductive convergence for recursive relations using filter witnesses.
94
+ 4. Replace filters that match a single, concrete schema with that closed schema, adding any newly discovered schemas to the registry.
95
+ 5. Repeat until a fixed point is reached.
96
+ 6. Compute canonical forms and content-addressed hashes for all discovered schemas.
99
97
 
100
98
  ---
101
99
 
102
100
  ## **5.7 Summary**
103
101
 
104
- - Type expressions act as identity functions defined on values of that type.
105
- - Filters describe sets of types and can constrain where a function is defined.
106
- - Filters may be products, unions, or the unconstrained any-type form, and can be recursive.
102
+ - Filter expressions act as partial identity relations defined on payloads conforming to a schema.
103
+ - Filters describe schema constraints and inductive termination witnesses for recursive relations.
104
+ - Filters may be products, unions, or the unconstrained any-schema form, and can be recursive.
107
105
  - Variables in filters have definition-level scope.
108
- - Normalization computes explicit input/output filters for every expression.
109
- - Filters are used in the normalization and type checking process. They are ignored at runtime.
106
+ - Contract derivation computes an interconnected $(input, output)$ schema graph for every relation.
107
+ - The canonical form of a schema provides a universal content-addressable identity in the schema registry.
110
108
 
111
109
  ---
@@ -11,7 +11,7 @@ Every `k` value exists in one of three forms during execution:
11
11
  This unified approach enables programs to operate on serialized inputs without unnecessary deserialization, optimizing performance for identity operations and partial data access patterns.
12
12
 
13
13
  In the current pattern-framed model, every form also has a pattern context. For
14
- serialized values this is the decoded leading `$pattern` value; for materialized
14
+ serialized values this is the decoded leading `pattern` value; for materialized
15
15
  values it is carried on the runtime `Value`. The product/union tree is the
16
16
  payload, while the pattern records the polymorphic type information needed to
17
17
  interpret and re-encode that payload.
@@ -111,11 +111,11 @@ Each node in the value tree is encoded based on its automaton state:
111
111
 
112
112
  #### **Example: Natural numbers**
113
113
 
114
- For type `bnat`, intuitively binary natural numbers defined by `$bnat = < bnat 0, bnat 1, {} _ >`, we get
114
+ For type `bnat`, intuitively binary natural numbers defined by `bnat = ?< Bnat 0, Bnat 1, {} _ > = Bnat;`, we get
115
115
 
116
116
  ```text
117
- > :C bnat
118
- $ bnat = < @... 0, @... 1, {} _ >; -- @...
117
+ > :rel bnat
118
+ bnat = ?< Bnat 0, Bnat 1, {} _ > = Bnat; -- @...
119
119
  ```
120
120
 
121
121
  The corresponding Context-Free grammar is:
@@ -191,7 +191,7 @@ Subtrees that happen to produce the same local payload bits under different type
191
191
  Consider a binary tree with repeated leaf patterns:
192
192
 
193
193
  ```k-lang
194
- $tree = < { tree left, tree right } branch, int leaf >;
194
+ tree = ?< { T left, T right } branch, int leaf > = T;
195
195
  ```
196
196
 
197
197
  Value: A tree corresponding to the structure:
@@ -293,8 +293,8 @@ These are encoder-side construction choices for reaching the same canonical resu
293
293
  Consider a list of similar records:
294
294
 
295
295
  ```k-lang
296
- $record = { string name, int age, string department };
297
- $company = < { record head, company tail } cons, {} nil >;
296
+ record = ?{ string name, int age, string department };
297
+ company = ?< { record head, C tail } cons, {} nil > = C;
298
298
  ```
299
299
 
300
300
  Value representing 1000 employees where 80% work in "Engineering":
@@ -712,9 +712,9 @@ const Arena = struct {
712
712
  Consider processing a large JSON-like structure where we only need one field:
713
713
 
714
714
  ```k-lang
715
- $record = { string name, list data, metadata meta };
716
- $list = < {nat value, list next} cons, {} nil >;
717
- $metadata = { timestamp created, string author };
715
+ metadata = ?{ timestamp created, string author };
716
+ list = ?< { nat value, L next } cons, {} nil > = L;
717
+ record = ?{ string name, list data, metadata meta };
718
718
  ```
719
719
 
720
720
  For the input program `\x.x.name` (extract name field):
@@ -54,16 +54,16 @@ If `v` carries a pattern, the result carries the subpattern reached by `label`.
54
54
  For a union projection `/label`, the same rule applies to the selected tag's
55
55
  payload.
56
56
 
57
- ### **Type expression**
57
+ ### **Filter expression**
58
58
 
59
- For a type `T`,
59
+ For a pattern filter `?F`,
60
60
 
61
61
  ```text
62
- ⟨ $T , v ⟩ ⇓ v if v ∈ T
62
+ ⟨ ?F , v ⟩ ⇓ v if v ∈ L(F)
63
63
  ```
64
64
 
65
65
  and undefined otherwise.
66
- Type expressions thus act as identity functions restricted to their type.
66
+ Filter expressions thus act as partial identity functions restricted to their pattern language.
67
67
 
68
68
  ---
69
69
 
@@ -121,22 +121,19 @@ If no subfunction is defined, the union composition is undefined.
121
121
 
122
122
  ## **8.7 Rules for filters**
123
123
 
124
- If a filter `F` matches a single type `T`
124
+ A filter `?F` validates that the input value conforms to the pattern:
125
125
 
126
126
  ```text
127
- ⟨ ?F , v ⟩ ⇓ ⟨ $T , v ⟩
127
+ ⟨ ?F , v ⟩ ⇓ v if v matches pattern F
128
128
  ```
129
129
 
130
- otherwise it is an identity
130
+ otherwise undefined.
131
131
 
132
- ```text
133
- ⟨ ?F , v ⟩ ⇓ v
134
- ```
135
-
136
- Filters therefore act as compile-time annotations for type checking only.
137
- As operations they are identities at run time, unless they lead to fully typed
138
- expressions (i.e., can be replaced by a type). Their pattern information may
139
- still be present on the runtime value because values can carry codec patterns.
132
+ Filters act as partial identity relations. At compile time, they guide type
133
+ derivation and provide inductive termination witnesses for recursive relations.
134
+ At runtime, filters succeed and preserve the input value when it conforms to
135
+ the pattern, or fail if the value does not match. Their pattern information is
136
+ carried by the runtime value's pattern envelope.
140
137
 
141
138
  ---
142
139
 
@@ -156,19 +153,17 @@ for any given input, at most one result tree can be produced.
156
153
  Given:
157
154
 
158
155
  ```k-lang
159
- $bool = < {} true, {} false >;
160
- neg = $bool < .true {{ } false}, .false {{ } true} > $bool;
156
+ bool = ?< {} true, {} false >;
157
+ neg = ?< {} true, {} false > < /true | false, /false | true >;
161
158
  ```
162
159
 
163
- and input value `{ {} true }` of type `bool`,
164
- evaluation steps are:
160
+ and input value `{} |true`, evaluation steps are:
165
161
 
166
- 1. `⟨ $bool , { {} true } ⟩ ⇓ { {} true }`
167
- 2. `⟨ < .true {{ } false}, .false {{ } true} > , { {} true } ⟩ ⇓ {{ } false}`
168
- 3. `⟨ $bool , {{ } false} ⟩ ⇓ {{ } false}`
162
+ 1. `⟨ ?< {} true, {} false > , {} |true ⟩ ⇓ {} |true`
163
+ 2. `⟨ < /true | false, /false | true > , {} |true ⟩ ⇓ {} |false`
169
164
 
170
- Final result: `{{ } false}`.
171
- If the input were of another type, step 1 would be undefined.
165
+ Final result: `{} |false`.
166
+ If the input were of another shape, step 1 would be undefined.
172
167
 
173
168
  ---
174
169
 
@@ -181,7 +176,7 @@ The evaluation rules map directly onto the runtime ABI:
181
176
  | Projection | `k_project` |
182
177
  | Product composition | multiple subcalls + `k_make_product` |
183
178
  | Union composition | sequential subcalls with early return |
184
- | Type | runtime check of `state` |
179
+ | Filter | runtime check or identity |
185
180
  | Composition | function call chain |
186
181
 
187
182
  In compiled form, the `ok` flag of `KOpt` represents whether a rule applies;
@@ -194,7 +189,7 @@ the node pointer represents the result value.
194
189
  * Execution follows deterministic, left-to-right rules.
195
190
  * All expressions denote partial functions on runtime values.
196
191
  * Runtime values may carry patterns, and structural operations propagate them.
197
- * Type expressions act as restricted identities.
192
+ * Filter expressions act as restricted identities.
198
193
  * Composition is associative; undefined propagates automatically.
199
194
  * Runtime semantics match the formal evaluation relation exactly.
200
195
 
@@ -73,15 +73,15 @@ These tables ensure that generated code can find fields and variants by number r
73
73
  Consider a simple k program:
74
74
 
75
75
  ```k-lang
76
- $bool = < {} true, {} false >;
77
- neg = $bool < /true | false, /false | true > $bool;
76
+ bool = ?< {} true, {} false >;
77
+ neg = bool < /true | false, /false | true > bool;
78
78
  ```
79
79
 
80
80
  1. **Parsing:**
81
- The compiler recognizes a type definition `$bool` and a function `neg`.
81
+ The compiler recognizes the relation definitions `bool` and `neg`.
82
82
 
83
83
  2. **Type analysis:**
84
- Both the input and output of `neg` are of type `bool`.
84
+ The compiler derives that both the input and output of `neg` conform to boolean variants.
85
85
 
86
86
  3. **Internal representation:**
87
87
  The compiler constructs an internal tree describing that
@@ -105,13 +105,13 @@ Before producing final code, many compilers use an *intermediate representation*
105
105
  It is a language designed to be easy to generate and easy to translate further into real machine code.
106
106
  For `k`, the IR mirrors the structure of partial functions:
107
107
 
108
- | Concept in k | IR operation |
109
- | --------------------- | -------------------------------- |
110
- | Projection `.x` `/x` | `PROJECT label_id` |
111
- | Composition `(f g)` | `CALL f; CALL g` |
112
- | Union `<f,g>` | `TRY f; IF undefined THEN TRY g` |
113
- | Product `{.x f, .y g}` | `PRODUCT_CALL (f, g); COMBINE` |
114
- | Type restriction `$T` | `CHECK_TYPE state_id` |
108
+ | Concept in k | IR operation |
109
+ | ----------------------- | -------------------------------- |
110
+ | Projection `.x` `/x` | `PROJECT label_id` |
111
+ | Composition `(f g)` | `CALL f; CALL g` |
112
+ | Union `<f,g>` | `TRY f; IF undefined THEN TRY g` |
113
+ | Product `{.x f, .y g}` | `PRODUCT_CALL (f, g); COMBINE` |
114
+ | Filter restriction `?F` | `CHECK_FILTER pattern_id` |
115
115
 
116
116
  The compiler converts each AST node into one or more IR instructions.
117
117
  The `PRODUCT_CALL(f, g)` instruction is a higher-level concept that implies applying both `f` and `g` to the same input value.
@@ -42,24 +42,23 @@ Each function in the program becomes a small list or tree of such IR instruction
42
42
  Source program:
43
43
 
44
44
  ```k-lang
45
- $bool = < {} true, {} false >;
46
- neg = $bool < .true {{ } false}, .false {{ } true} > $bool;
45
+ bool = ?< {} true, {} false >;
46
+ neg = ?< {} true, {} false > < /true | false, /false | true >;
47
47
  ```
48
48
 
49
49
  The IR for `neg` can be written informally as:
50
50
 
51
51
  ```text
52
52
  neg:
53
- TYPECHECK bool
53
+ CHECK_FILTER bool
54
54
  UNION [
55
55
  SEQ [ PROJECT true, CONST false ],
56
56
  SEQ [ PROJECT false, CONST true ]
57
57
  ]
58
- TYPECHECK bool
59
58
  ```
60
59
 
61
60
  This IR expresses the same logic as the source:
62
- check the type, then try the first projection `.true`, otherwise the second, and finally ensure the result is again of type `$bool`.
61
+ check that the value matches the pattern, then try the first projection `/true`, otherwise the second.
63
62
 
64
63
  ---
65
64
 
@@ -89,8 +88,8 @@ The process of converting the AST to IR follows a recursive pattern:
89
88
  2. **Compositions** `(f g h)` become a `SEQ` list of their components.
90
89
  3. **Unions** `<f,g>` become a `UNION` list.
91
90
  4. **Products** `{f l₁, g l₂}` become a `PRODUCT` list with labeled entries.
92
- 5. **Type expressions** `$T` become `TYPECHECK` instructions.
93
- 6. **Filters** disappear; their meaning is already captured by typechecks.
91
+ 5. **Filter expressions** `?F` become `CHECK_FILTER` or `TYPECHECK` instructions.
92
+ 6. Inductive filters that match derived shapes can be elided or turned into no-op identity during execution.
94
93
 
95
94
  Each transformation step produces IR nodes with fixed behavior and explicit order.
96
95
 
@@ -67,8 +67,8 @@ This rule allows the decoder to know, from the type alone, how many bits to read
67
67
 
68
68
  For the type
69
69
 
70
- ```
71
- $bnat = < bnat 0, bnat 1, {} _ >;
70
+ ```k-lang
71
+ bnat = ?< Bnat 0, Bnat 1, {} _ > = Bnat;
72
72
  ```
73
73
 
74
74
  the canonical form has three transitions from state C0.