Class: Kumi::SchemaMetadata
- Inherits:
-
Object
- Object
- Kumi::SchemaMetadata
- Defined in:
- lib/kumi/schema_metadata.rb,
lib/kumi/schema_metadata/printer.rb
Overview
The algebra of a compiled schema, as read-only data.
A Kumi schema is, formally: a set of typed, domain-constrained inputs (free variables), a set of definitions (values and traits) each given by an expression over inputs and earlier definitions, and the **dependency relation** between them. ‘SchemaMetadata` exposes exactly that — precise, named, and total — sourced from the analyzer rather than re-derived.
Returned by ‘MySchema.schema_metadata`. It is the surface every tool over Kumi builds on (form generation, simulation harnesses, fuzzers, docs) and the self-describing contract an LLM reads to reason about a schema it cannot see the source of. See #to_h for the serializable form and #to_s/Printer for the human/LLM-readable rendering.
Defined Under Namespace
Classes: Definition, InputField, Printer
Instance Method Summary collapse
- #array_outputs ⇒ Array<Symbol>
- #axes_for(name) ⇒ Array<Symbol>
- #definition(name) ⇒ Definition?
-
#definition_names ⇒ Array<Symbol>
All definition names (values and traits).
-
#definitions ⇒ Hash{Symbol => Definition}
Every definition (value or trait) as a Definition: kind, dtype, axes, the rendered expression, the names it reads, and the names that read it.
-
#evaluation_order ⇒ Array<Symbol>
Order in which definitions are evaluated (a topological sort of the dependency relation).
-
#hints ⇒ Hash{Symbol => Hash}
Per-declaration hints (the configurable-codegen seam).
-
#imported_names ⇒ Array<Symbol>
Names imported from other schemas (inlined at compile time).
-
#initialize(state, syntax_tree) ⇒ SchemaMetadata
constructor
A new instance of SchemaMetadata.
-
#input_field(path) ⇒ InputField?
Look up one input leaf by path (array of symbols or dotted string).
-
#input_fields ⇒ Array<InputField>
Flat list of every input leaf, each an InputField: its addressable path, dtype, declared domain, the array axes it sits under, and the key path into one array element.
-
#input_names ⇒ Array<Symbol>
Top-level input names.
-
#input_plan ⇒ Hash{String => Hash}
The raw per-path input navigation plan keyed by dotted path.
-
#input_tree ⇒ Hash
Nested tree mirroring the declared structure with domains attached.
-
#inputs ⇒ Hash{Symbol => Hash}
Recursive description of the declared inputs.
- #output_names ⇒ Array<Symbol>
-
#outputs ⇒ Hash{Symbol => Hash}
Backwards-compatible alias: the output declarations keyed by name with ‘{ kind:, type:, axes: }`.
-
#read_by(name) ⇒ Array<Symbol>
Names that read this input or definition directly.
-
#reads(name) ⇒ Array<Symbol>
Names this definition reads directly (inputs and other definitions).
-
#scalar_definitions ⇒ Array<Symbol>
Definitions that reduce to a scalar (no axes).
- #scalar_outputs ⇒ Array<Symbol>
-
#to_h ⇒ Hash
Total, JSON-safe snapshot of the whole algebra.
-
#to_s ⇒ String
(also: #to_str, #inspect)
Human/LLM-readable rendering of the algebra.
-
#trait_names ⇒ Array<Symbol>
Names of ‘trait` definitions.
-
#value_names ⇒ Array<Symbol>
Names of ‘value` definitions.
-
#vector_definitions ⇒ Array<Symbol>
Definitions that broadcast over one or more axes.
Constructor Details
#initialize(state, syntax_tree) ⇒ SchemaMetadata
Returns a new instance of SchemaMetadata.
47 48 49 50 |
# File 'lib/kumi/schema_metadata.rb', line 47 def initialize(state, syntax_tree) @state = state @syntax_tree = syntax_tree end |
Instance Method Details
#array_outputs ⇒ Array<Symbol>
192 |
# File 'lib/kumi/schema_metadata.rb', line 192 def array_outputs = vector_definitions |
#axes_for(name) ⇒ Array<Symbol>
198 199 200 201 202 203 |
# File 'lib/kumi/schema_metadata.rb', line 198 def axes_for(name) d = definition(name) raise KeyError, "Unknown definition: #{name}" unless d d.axes end |
#definition(name) ⇒ Definition?
118 119 120 |
# File 'lib/kumi/schema_metadata.rb', line 118 def definition(name) definitions[name.to_sym] end |
#definition_names ⇒ Array<Symbol>
Returns all definition names (values and traits).
123 124 125 |
# File 'lib/kumi/schema_metadata.rb', line 123 def definition_names definitions.keys end |
#definitions ⇒ Hash{Symbol => Definition}
Every definition (value or trait) as a Definition: kind, dtype, axes, the rendered expression, the names it reads, and the names that read it.
113 114 115 |
# File 'lib/kumi/schema_metadata.rb', line 113 def definitions @definitions ||= build_definitions end |
#evaluation_order ⇒ Array<Symbol>
Order in which definitions are evaluated (a topological sort of the dependency relation).
151 152 153 |
# File 'lib/kumi/schema_metadata.rb', line 151 def evaluation_order Array(@state[:evaluation_order]) end |
#hints ⇒ Hash{Symbol => Hash}
Per-declaration hints (the configurable-codegen seam).
208 209 210 |
# File 'lib/kumi/schema_metadata.rb', line 208 def hints @state[:hints] || {} end |
#imported_names ⇒ Array<Symbol>
Names imported from other schemas (inlined at compile time).
174 175 176 |
# File 'lib/kumi/schema_metadata.rb', line 174 def imported_names Array(@state[:imported_declarations]&.keys) end |
#input_field(path) ⇒ InputField?
Look up one input leaf by path (array of symbols or dotted string).
87 88 89 90 |
# File 'lib/kumi/schema_metadata.rb', line 87 def input_field(path) key = path.is_a?(String) ? path.split(".").map(&:to_sym) : Array(path) input_fields.find { |f| f.path == key } end |
#input_fields ⇒ Array<InputField>
Flat list of every input leaf, each an InputField: its addressable path, dtype, declared domain, the array axes it sits under, and the key path into one array element. Navigation (‘axes`, `element_path`) is taken from the analyzer’s ‘precomputed_plan_by_fqn`, not re-derived, so it is correct through arbitrary nesting and multiple arrays.
75 76 77 78 79 80 81 82 |
# File 'lib/kumi/schema_metadata.rb', line 75 def input_fields @input_fields ||= begin leaves = [] walk_input_nodes(@state[:input_metadata] || {}, [], leaves) plans = @state[:precomputed_plan_by_fqn] || {} leaves.map { |leaf| build_input_field(leaf, plans) } end end |
#input_names ⇒ Array<Symbol>
Returns top-level input names.
64 65 66 |
# File 'lib/kumi/schema_metadata.rb', line 64 def input_names inputs.keys end |
#input_plan ⇒ Hash{String => Hash}
The raw per-path input navigation plan keyed by dotted path. Authoritative source for axis/element information; most callers want #input_fields.
103 104 105 |
# File 'lib/kumi/schema_metadata.rb', line 103 def input_plan @state[:precomputed_plan_by_fqn] || {} end |
#input_tree ⇒ Hash
Nested tree mirroring the declared structure with domains attached.
95 96 97 |
# File 'lib/kumi/schema_metadata.rb', line 95 def input_tree (@state[:input_metadata] || {}).transform_values { |node| node_to_tree(node) } end |
#inputs ⇒ Hash{Symbol => Hash}
Recursive description of the declared inputs. Shape: ‘{ name => { type:, … } }`; array entries carry an `element`, object entries carry `fields`.
59 60 61 |
# File 'lib/kumi/schema_metadata.rb', line 59 def inputs @state[:input_form_schema] || {} end |
#output_names ⇒ Array<Symbol>
189 |
# File 'lib/kumi/schema_metadata.rb', line 189 def output_names = outputs.keys |
#outputs ⇒ Hash{Symbol => Hash}
Backwards-compatible alias: the output declarations keyed by name with ‘{ kind:, type:, axes: }`. Prefer #definitions.
184 185 186 |
# File 'lib/kumi/schema_metadata.rb', line 184 def outputs @state[:output_schema] || {} end |
#read_by(name) ⇒ Array<Symbol>
Names that read this input or definition directly.
165 166 167 |
# File 'lib/kumi/schema_metadata.rb', line 165 def read_by(name) Array(@state.dig(:dependents, name.to_sym)) end |
#reads(name) ⇒ Array<Symbol>
Names this definition reads directly (inputs and other definitions).
158 159 160 |
# File 'lib/kumi/schema_metadata.rb', line 158 def reads(name) definition(name)&.reads || [] end |
#scalar_definitions ⇒ Array<Symbol>
Returns definitions that reduce to a scalar (no axes).
138 139 140 |
# File 'lib/kumi/schema_metadata.rb', line 138 def scalar_definitions definitions.select { |_, d| d.axes.empty? }.keys end |
#scalar_outputs ⇒ Array<Symbol>
195 |
# File 'lib/kumi/schema_metadata.rb', line 195 def scalar_outputs = scalar_definitions |
#to_h ⇒ Hash
Total, JSON-safe snapshot of the whole algebra. Safe to hand to a frontend, persist, or give to an LLM as a tool-use contract.
216 217 218 219 220 221 222 223 224 |
# File 'lib/kumi/schema_metadata.rb', line 216 def to_h { inputs: input_fields.map(&:to_h), definitions: definitions.values.map(&:to_h), evaluation_order: evaluation_order, imports: imported_names, hints: hints } end |
#to_s ⇒ String Also known as: to_str, inspect
Human/LLM-readable rendering of the algebra.
229 230 231 |
# File 'lib/kumi/schema_metadata.rb', line 229 def to_s Printer.new(self).render end |
#trait_names ⇒ Array<Symbol>
Returns names of ‘trait` definitions.
133 134 135 |
# File 'lib/kumi/schema_metadata.rb', line 133 def trait_names definitions.select { |_, d| d.kind == :trait }.keys end |
#value_names ⇒ Array<Symbol>
Returns names of ‘value` definitions.
128 129 130 |
# File 'lib/kumi/schema_metadata.rb', line 128 def value_names definitions.select { |_, d| d.kind == :value }.keys end |
#vector_definitions ⇒ Array<Symbol>
Returns definitions that broadcast over one or more axes.
143 144 145 |
# File 'lib/kumi/schema_metadata.rb', line 143 def vector_definitions definitions.reject { |_, d| d.axes.empty? }.keys end |