kumi 0.0.6 → 0.0.8

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +34 -177
  3. data/README.md +41 -7
  4. data/docs/SYNTAX.md +2 -7
  5. data/docs/features/array-broadcasting.md +1 -1
  6. data/docs/schema_metadata/broadcasts.md +53 -0
  7. data/docs/schema_metadata/cascades.md +45 -0
  8. data/docs/schema_metadata/declarations.md +54 -0
  9. data/docs/schema_metadata/dependencies.md +57 -0
  10. data/docs/schema_metadata/evaluation_order.md +29 -0
  11. data/docs/schema_metadata/examples.md +95 -0
  12. data/docs/schema_metadata/inferred_types.md +46 -0
  13. data/docs/schema_metadata/inputs.md +86 -0
  14. data/docs/schema_metadata.md +108 -0
  15. data/examples/game_of_life.rb +1 -1
  16. data/examples/static_analysis_errors.rb +7 -7
  17. data/lib/kumi/analyzer.rb +20 -20
  18. data/lib/kumi/compiler.rb +44 -50
  19. data/lib/kumi/core/analyzer/analysis_state.rb +39 -0
  20. data/lib/kumi/core/analyzer/constant_evaluator.rb +59 -0
  21. data/lib/kumi/core/analyzer/passes/broadcast_detector.rb +248 -0
  22. data/lib/kumi/core/analyzer/passes/declaration_validator.rb +45 -0
  23. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +153 -0
  24. data/lib/kumi/core/analyzer/passes/input_collector.rb +139 -0
  25. data/lib/kumi/core/analyzer/passes/name_indexer.rb +26 -0
  26. data/lib/kumi/core/analyzer/passes/pass_base.rb +52 -0
  27. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +111 -0
  28. data/lib/kumi/core/analyzer/passes/toposorter.rb +110 -0
  29. data/lib/kumi/core/analyzer/passes/type_checker.rb +162 -0
  30. data/lib/kumi/core/analyzer/passes/type_consistency_checker.rb +48 -0
  31. data/lib/kumi/core/analyzer/passes/type_inferencer.rb +236 -0
  32. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +406 -0
  33. data/lib/kumi/core/analyzer/passes/visitor_pass.rb +44 -0
  34. data/lib/kumi/core/atom_unsat_solver.rb +396 -0
  35. data/lib/kumi/core/compiled_schema.rb +43 -0
  36. data/lib/kumi/core/constraint_relationship_solver.rb +641 -0
  37. data/lib/kumi/core/domain/enum_analyzer.rb +55 -0
  38. data/lib/kumi/core/domain/range_analyzer.rb +85 -0
  39. data/lib/kumi/core/domain/validator.rb +82 -0
  40. data/lib/kumi/core/domain/violation_formatter.rb +42 -0
  41. data/lib/kumi/core/error_reporter.rb +166 -0
  42. data/lib/kumi/core/error_reporting.rb +97 -0
  43. data/lib/kumi/core/errors.rb +120 -0
  44. data/lib/kumi/core/evaluation_wrapper.rb +40 -0
  45. data/lib/kumi/core/explain.rb +295 -0
  46. data/lib/kumi/core/export/deserializer.rb +41 -0
  47. data/lib/kumi/core/export/errors.rb +14 -0
  48. data/lib/kumi/core/export/node_builders.rb +142 -0
  49. data/lib/kumi/core/export/node_registry.rb +54 -0
  50. data/lib/kumi/core/export/node_serializers.rb +158 -0
  51. data/lib/kumi/core/export/serializer.rb +25 -0
  52. data/lib/kumi/core/export.rb +35 -0
  53. data/lib/kumi/core/function_registry/collection_functions.rb +202 -0
  54. data/lib/kumi/core/function_registry/comparison_functions.rb +33 -0
  55. data/lib/kumi/core/function_registry/conditional_functions.rb +38 -0
  56. data/lib/kumi/core/function_registry/function_builder.rb +95 -0
  57. data/lib/kumi/core/function_registry/logical_functions.rb +44 -0
  58. data/lib/kumi/core/function_registry/math_functions.rb +74 -0
  59. data/lib/kumi/core/function_registry/string_functions.rb +57 -0
  60. data/lib/kumi/core/function_registry/type_functions.rb +53 -0
  61. data/lib/kumi/{function_registry.rb → core/function_registry.rb} +28 -36
  62. data/lib/kumi/core/input/type_matcher.rb +97 -0
  63. data/lib/kumi/core/input/validator.rb +51 -0
  64. data/lib/kumi/core/input/violation_creator.rb +52 -0
  65. data/lib/kumi/core/json_schema/generator.rb +65 -0
  66. data/lib/kumi/core/json_schema/validator.rb +27 -0
  67. data/lib/kumi/core/json_schema.rb +16 -0
  68. data/lib/kumi/core/ruby_parser/build_context.rb +27 -0
  69. data/lib/kumi/core/ruby_parser/declaration_reference_proxy.rb +38 -0
  70. data/lib/kumi/core/ruby_parser/dsl.rb +14 -0
  71. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +138 -0
  72. data/lib/kumi/core/ruby_parser/expression_converter.rb +128 -0
  73. data/lib/kumi/core/ruby_parser/guard_rails.rb +45 -0
  74. data/lib/kumi/core/ruby_parser/input_builder.rb +127 -0
  75. data/lib/kumi/core/ruby_parser/input_field_proxy.rb +48 -0
  76. data/lib/kumi/core/ruby_parser/input_proxy.rb +31 -0
  77. data/lib/kumi/core/ruby_parser/nested_input.rb +17 -0
  78. data/lib/kumi/core/ruby_parser/parser.rb +71 -0
  79. data/lib/kumi/core/ruby_parser/schema_builder.rb +175 -0
  80. data/lib/kumi/core/ruby_parser/sugar.rb +263 -0
  81. data/lib/kumi/core/ruby_parser.rb +12 -0
  82. data/lib/kumi/core/schema_instance.rb +111 -0
  83. data/lib/kumi/core/types/builder.rb +23 -0
  84. data/lib/kumi/core/types/compatibility.rb +96 -0
  85. data/lib/kumi/core/types/formatter.rb +26 -0
  86. data/lib/kumi/core/types/inference.rb +42 -0
  87. data/lib/kumi/core/types/normalizer.rb +72 -0
  88. data/lib/kumi/core/types/validator.rb +37 -0
  89. data/lib/kumi/core/types.rb +66 -0
  90. data/lib/kumi/core/vectorization_metadata.rb +110 -0
  91. data/lib/kumi/errors.rb +1 -112
  92. data/lib/kumi/registry.rb +37 -0
  93. data/lib/kumi/schema.rb +13 -7
  94. data/lib/kumi/schema_metadata.rb +524 -0
  95. data/lib/kumi/syntax/array_expression.rb +6 -6
  96. data/lib/kumi/syntax/call_expression.rb +4 -4
  97. data/lib/kumi/syntax/cascade_expression.rb +4 -4
  98. data/lib/kumi/syntax/case_expression.rb +4 -4
  99. data/lib/kumi/syntax/declaration_reference.rb +4 -4
  100. data/lib/kumi/syntax/hash_expression.rb +4 -4
  101. data/lib/kumi/syntax/input_declaration.rb +5 -5
  102. data/lib/kumi/syntax/input_element_reference.rb +5 -5
  103. data/lib/kumi/syntax/input_reference.rb +5 -5
  104. data/lib/kumi/syntax/literal.rb +4 -4
  105. data/lib/kumi/syntax/node.rb +34 -34
  106. data/lib/kumi/syntax/root.rb +6 -6
  107. data/lib/kumi/syntax/trait_declaration.rb +4 -4
  108. data/lib/kumi/syntax/value_declaration.rb +4 -4
  109. data/lib/kumi/version.rb +1 -1
  110. data/lib/kumi.rb +14 -0
  111. data/migrate_to_core_iterative.rb +938 -0
  112. data/scripts/generate_function_docs.rb +9 -9
  113. metadata +85 -69
  114. data/lib/generators/trait_engine/templates/schema_spec.rb.erb +0 -27
  115. data/lib/kumi/analyzer/analysis_state.rb +0 -37
  116. data/lib/kumi/analyzer/constant_evaluator.rb +0 -57
  117. data/lib/kumi/analyzer/passes/broadcast_detector.rb +0 -251
  118. data/lib/kumi/analyzer/passes/declaration_validator.rb +0 -43
  119. data/lib/kumi/analyzer/passes/dependency_resolver.rb +0 -151
  120. data/lib/kumi/analyzer/passes/input_collector.rb +0 -137
  121. data/lib/kumi/analyzer/passes/name_indexer.rb +0 -24
  122. data/lib/kumi/analyzer/passes/pass_base.rb +0 -50
  123. data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +0 -110
  124. data/lib/kumi/analyzer/passes/toposorter.rb +0 -108
  125. data/lib/kumi/analyzer/passes/type_checker.rb +0 -162
  126. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +0 -46
  127. data/lib/kumi/analyzer/passes/type_inferencer.rb +0 -232
  128. data/lib/kumi/analyzer/passes/unsat_detector.rb +0 -406
  129. data/lib/kumi/analyzer/passes/visitor_pass.rb +0 -42
  130. data/lib/kumi/atom_unsat_solver.rb +0 -394
  131. data/lib/kumi/compiled_schema.rb +0 -41
  132. data/lib/kumi/constraint_relationship_solver.rb +0 -638
  133. data/lib/kumi/domain/enum_analyzer.rb +0 -53
  134. data/lib/kumi/domain/range_analyzer.rb +0 -83
  135. data/lib/kumi/domain/validator.rb +0 -80
  136. data/lib/kumi/domain/violation_formatter.rb +0 -40
  137. data/lib/kumi/error_reporter.rb +0 -164
  138. data/lib/kumi/error_reporting.rb +0 -95
  139. data/lib/kumi/evaluation_wrapper.rb +0 -38
  140. data/lib/kumi/explain.rb +0 -281
  141. data/lib/kumi/export/deserializer.rb +0 -39
  142. data/lib/kumi/export/errors.rb +0 -12
  143. data/lib/kumi/export/node_builders.rb +0 -140
  144. data/lib/kumi/export/node_registry.rb +0 -52
  145. data/lib/kumi/export/node_serializers.rb +0 -156
  146. data/lib/kumi/export/serializer.rb +0 -23
  147. data/lib/kumi/export.rb +0 -33
  148. data/lib/kumi/function_registry/collection_functions.rb +0 -200
  149. data/lib/kumi/function_registry/comparison_functions.rb +0 -31
  150. data/lib/kumi/function_registry/conditional_functions.rb +0 -36
  151. data/lib/kumi/function_registry/function_builder.rb +0 -93
  152. data/lib/kumi/function_registry/logical_functions.rb +0 -42
  153. data/lib/kumi/function_registry/math_functions.rb +0 -72
  154. data/lib/kumi/function_registry/string_functions.rb +0 -54
  155. data/lib/kumi/function_registry/type_functions.rb +0 -51
  156. data/lib/kumi/input/type_matcher.rb +0 -95
  157. data/lib/kumi/input/validator.rb +0 -49
  158. data/lib/kumi/input/violation_creator.rb +0 -50
  159. data/lib/kumi/parser/build_context.rb +0 -25
  160. data/lib/kumi/parser/declaration_reference_proxy.rb +0 -36
  161. data/lib/kumi/parser/dsl.rb +0 -12
  162. data/lib/kumi/parser/dsl_cascade_builder.rb +0 -136
  163. data/lib/kumi/parser/expression_converter.rb +0 -126
  164. data/lib/kumi/parser/guard_rails.rb +0 -43
  165. data/lib/kumi/parser/input_builder.rb +0 -125
  166. data/lib/kumi/parser/input_field_proxy.rb +0 -46
  167. data/lib/kumi/parser/input_proxy.rb +0 -29
  168. data/lib/kumi/parser/nested_input.rb +0 -15
  169. data/lib/kumi/parser/parser.rb +0 -68
  170. data/lib/kumi/parser/schema_builder.rb +0 -173
  171. data/lib/kumi/parser/sugar.rb +0 -261
  172. data/lib/kumi/schema_instance.rb +0 -109
  173. data/lib/kumi/types/builder.rb +0 -21
  174. data/lib/kumi/types/compatibility.rb +0 -94
  175. data/lib/kumi/types/formatter.rb +0 -24
  176. data/lib/kumi/types/inference.rb +0 -40
  177. data/lib/kumi/types/normalizer.rb +0 -70
  178. data/lib/kumi/types/validator.rb +0 -35
  179. data/lib/kumi/types.rb +0 -64
  180. data/lib/kumi/vectorization_metadata.rb +0 -108
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Export
5
- class Serializer
6
- include NodeSerializers
7
-
8
- def initialize(pretty: false, include_locations: false)
9
- @pretty = pretty
10
- @include_locations = include_locations
11
- end
12
-
13
- def serialize(syntax_root)
14
- json_data = {
15
- kumi_version: VERSION,
16
- ast: serialize_root(syntax_root)
17
- }
18
-
19
- @pretty ? JSON.pretty_generate(json_data) : JSON.generate(json_data)
20
- end
21
- end
22
- end
23
- end
data/lib/kumi/export.rb DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
-
5
- module Kumi
6
- module Export
7
- # Core interface - only depends on Syntax::Root
8
- def self.to_json(syntax_root, **options)
9
- Serializer.new(**options).serialize(syntax_root)
10
- end
11
-
12
- def self.from_json(json_string, **options)
13
- Deserializer.new(**options).deserialize(json_string)
14
- end
15
-
16
- # Convenience methods
17
- def self.to_file(syntax_root, filepath, **options)
18
- File.write(filepath, to_json(syntax_root, **options))
19
- end
20
-
21
- def self.from_file(filepath, **options)
22
- from_json(File.read(filepath), **options)
23
- end
24
-
25
- # Validation without import
26
- def self.valid?(json_string)
27
- from_json(json_string)
28
- true
29
- rescue StandardError
30
- false
31
- end
32
- end
33
- end
@@ -1,200 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Collection manipulation and query functions
6
- module CollectionFunctions
7
- def self.definitions
8
- {
9
- # Collection queries (these are reducers - they reduce arrays to scalars)
10
- empty?: FunctionBuilder.collection_unary(:empty?, "Check if collection is empty", :empty?, reducer: true),
11
- size: FunctionBuilder.collection_unary(:size, "Get collection size", :size, return_type: :integer, reducer: true),
12
- length: FunctionBuilder.collection_unary(:length, "Get collection length", :length, return_type: :integer, reducer: true),
13
-
14
- # Element access
15
- first: FunctionBuilder::Entry.new(
16
- fn: lambda(&:first),
17
- arity: 1,
18
- param_types: [Kumi::Types.array(:any)],
19
- return_type: :any,
20
- description: "Get first element of collection",
21
- reducer: true
22
- ),
23
-
24
- last: FunctionBuilder::Entry.new(
25
- fn: lambda(&:last),
26
- arity: 1,
27
- param_types: [Kumi::Types.array(:any)],
28
- return_type: :any,
29
- description: "Get last element of collection",
30
- reducer: true
31
- ),
32
-
33
- # Mathematical operations on collections
34
- sum: FunctionBuilder::Entry.new(
35
- fn: lambda(&:sum),
36
- arity: 1,
37
- param_types: [Kumi::Types.array(:float)],
38
- return_type: :float,
39
- description: "Sum all numeric elements in collection",
40
- reducer: true
41
- ),
42
-
43
- min: FunctionBuilder::Entry.new(
44
- fn: lambda(&:min),
45
- arity: 1,
46
- param_types: [Kumi::Types.array(:float)],
47
- return_type: :float,
48
- description: "Find minimum value in numeric collection",
49
- reducer: true
50
- ),
51
-
52
- max: FunctionBuilder::Entry.new(
53
- fn: lambda(&:max),
54
- arity: 1,
55
- param_types: [Kumi::Types.array(:float)],
56
- return_type: :float,
57
- description: "Find maximum value in numeric collection",
58
- reducer: true
59
- ),
60
-
61
- # Collection operations
62
- include?: FunctionBuilder::Entry.new(
63
- fn: ->(collection, element) { collection.include?(element) },
64
- arity: 2,
65
- param_types: [Kumi::Types.array(:any), :any],
66
- return_type: :boolean,
67
- description: "Check if collection includes element"
68
- ),
69
-
70
- reverse: FunctionBuilder::Entry.new(
71
- fn: lambda(&:reverse),
72
- arity: 1,
73
- param_types: [Kumi::Types.array(:any)],
74
- return_type: Kumi::Types.array(:any),
75
- description: "Reverse collection order"
76
- ),
77
-
78
- sort: FunctionBuilder::Entry.new(
79
- fn: lambda(&:sort),
80
- arity: 1,
81
- param_types: [Kumi::Types.array(:any)],
82
- return_type: Kumi::Types.array(:any),
83
- description: "Sort collection"
84
- ),
85
-
86
- unique: FunctionBuilder::Entry.new(
87
- fn: lambda(&:uniq),
88
- arity: 1,
89
- param_types: [Kumi::Types.array(:any)],
90
- return_type: Kumi::Types.array(:any),
91
- description: "Remove duplicate elements from collection"
92
- ),
93
-
94
- # Array transformation functions
95
- flatten: FunctionBuilder::Entry.new(
96
- fn: lambda(&:flatten),
97
- arity: 1,
98
- param_types: [Kumi::Types.array(:any)],
99
- return_type: Kumi::Types.array(:any),
100
- description: "Flatten nested arrays into a single array"
101
- ),
102
-
103
- # Mathematical transformation functions
104
- map_multiply: FunctionBuilder::Entry.new(
105
- fn: ->(collection, factor) { collection.map { |x| x * factor } },
106
- arity: 2,
107
- param_types: [Kumi::Types.array(:float), :float],
108
- return_type: Kumi::Types.array(:float),
109
- description: "Multiply each element by factor"
110
- ),
111
-
112
- map_add: FunctionBuilder::Entry.new(
113
- fn: ->(collection, value) { collection.map { |x| x + value } },
114
- arity: 2,
115
- param_types: [Kumi::Types.array(:float), :float],
116
- return_type: Kumi::Types.array(:float),
117
- description: "Add value to each element"
118
- ),
119
-
120
- # Conditional transformation functions
121
- map_conditional: FunctionBuilder::Entry.new(
122
- fn: lambda { |collection, condition_value, true_value, false_value|
123
- collection.map { |x| x == condition_value ? true_value : false_value }
124
- },
125
- arity: 4,
126
- param_types: %i[array any any any],
127
- return_type: :array,
128
- description: "Transform elements based on condition: if element == condition_value then true_value else false_value"
129
- ),
130
-
131
- # Range/index functions for grid operations
132
- build_array: FunctionBuilder::Entry.new(
133
- fn: lambda { |size, &generator|
134
- (0...size).map { |i| generator ? generator.call(i) : i }
135
- },
136
- arity: 1,
137
- param_types: [:integer],
138
- return_type: Kumi::Types.array(:any),
139
- description: "Build array of given size with index values"
140
- ),
141
-
142
- range: FunctionBuilder::Entry.new(
143
- fn: ->(start, finish) { (start...finish).to_a },
144
- arity: 2,
145
- param_types: %i[integer integer],
146
- return_type: Kumi::Types.array(:integer),
147
- description: "Generate range of integers from start to finish (exclusive)"
148
- ),
149
-
150
- # Array slicing and grouping for rendering
151
- each_slice: FunctionBuilder::Entry.new(
152
- fn: ->(array, size) { array.each_slice(size).to_a },
153
- arity: 2,
154
- param_types: %i[array integer],
155
- return_type: Kumi::Types.array(:array),
156
- description: "Group array elements into subarrays of given size"
157
- ),
158
-
159
- join: FunctionBuilder::Entry.new(
160
- fn: lambda { |array, separator = ""|
161
- array.map(&:to_s).join(separator.to_s)
162
- },
163
- arity: 2,
164
- param_types: %i[array string],
165
- return_type: :string,
166
- description: "Join array elements into string with separator"
167
- ),
168
-
169
- # Transform each subarray to string and join the results
170
- map_join_rows: FunctionBuilder::Entry.new(
171
- fn: lambda { |array_of_arrays, row_separator = "", column_separator = "\n"|
172
- array_of_arrays.map { |row| row.join(row_separator.to_s) }.join(column_separator.to_s)
173
- },
174
- arity: 3,
175
- param_types: [Kumi::Types.array(:array), :string, :string],
176
- return_type: :string,
177
- description: "Join 2D array into string with row and column separators"
178
- ),
179
-
180
- # Higher-order collection functions (limited to common patterns)
181
- map_with_index: FunctionBuilder::Entry.new(
182
- fn: ->(collection) { collection.map.with_index.to_a },
183
- arity: 1,
184
- param_types: [Kumi::Types.array(:any)],
185
- return_type: Kumi::Types.array(:any),
186
- description: "Map collection elements to [element, index] pairs"
187
- ),
188
-
189
- indices: FunctionBuilder::Entry.new(
190
- fn: ->(collection) { (0...collection.size).to_a },
191
- arity: 1,
192
- param_types: [Kumi::Types.array(:any)],
193
- return_type: Kumi::Types.array(:integer),
194
- description: "Generate array of indices for the collection"
195
- )
196
- }
197
- end
198
- end
199
- end
200
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Comparison and equality functions
6
- module ComparisonFunctions
7
- def self.definitions
8
- {
9
- # Equality operators
10
- :== => FunctionBuilder.equality(:==, "Equality comparison", :==),
11
- :!= => FunctionBuilder.equality(:!=, "Inequality comparison", :!=),
12
-
13
- # Comparison operators
14
- :> => FunctionBuilder.comparison(:>, "Greater than comparison", :>),
15
- :< => FunctionBuilder.comparison(:<, "Less than comparison", :<),
16
- :>= => FunctionBuilder.comparison(:>=, "Greater than or equal comparison", :>=),
17
- :<= => FunctionBuilder.comparison(:<=, "Less than or equal comparison", :<=),
18
-
19
- # Range comparison
20
- :between? => FunctionBuilder::Entry.new(
21
- fn: ->(value, min, max) { value.between?(min, max) },
22
- arity: 3,
23
- param_types: %i[float float float],
24
- return_type: :boolean,
25
- description: "Check if value is between min and max"
26
- )
27
- }
28
- end
29
- end
30
- end
31
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Conditional and control flow functions
6
- module ConditionalFunctions
7
- def self.definitions
8
- {
9
- conditional: FunctionBuilder::Entry.new(
10
- fn: ->(condition, true_value, false_value) { condition ? true_value : false_value },
11
- arity: 3,
12
- param_types: %i[boolean any any],
13
- return_type: :any,
14
- description: "Ternary conditional operator"
15
- ),
16
-
17
- if: FunctionBuilder::Entry.new(
18
- fn: ->(condition, true_value, false_value = nil) { condition ? true_value : false_value },
19
- arity: -1, # Variable arity (2 or 3)
20
- param_types: %i[boolean any any],
21
- return_type: :any,
22
- description: "If-then-else conditional"
23
- ),
24
-
25
- coalesce: FunctionBuilder::Entry.new(
26
- fn: ->(*values) { values.find { |v| !v.nil? } },
27
- arity: -1, # Variable arity
28
- param_types: [:any],
29
- return_type: :any,
30
- description: "Return first non-nil value"
31
- )
32
- }
33
- end
34
- end
35
- end
36
- end
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Utility class to reduce repetition in function definitions
6
- class FunctionBuilder
7
- Entry = Struct.new(:fn, :arity, :param_types, :return_type, :description, :inverse, :reducer, keyword_init: true)
8
-
9
- def self.comparison(_name, description, operation)
10
- Entry.new(
11
- fn: ->(a, b) { a.public_send(operation, b) },
12
- arity: 2,
13
- param_types: %i[float float],
14
- return_type: :boolean,
15
- description: description
16
- )
17
- end
18
-
19
- def self.equality(_name, description, operation)
20
- Entry.new(
21
- fn: ->(a, b) { a.public_send(operation, b) },
22
- arity: 2,
23
- param_types: %i[any any],
24
- return_type: :boolean,
25
- description: description
26
- )
27
- end
28
-
29
- def self.math_binary(_name, description, operation, return_type: :float)
30
- Entry.new(
31
- fn: lambda { |a, b|
32
- a.public_send(operation, b)
33
- },
34
- arity: 2,
35
- param_types: %i[float float],
36
- return_type: return_type,
37
- description: description
38
- )
39
- end
40
-
41
- def self.math_unary(_name, description, operation, return_type: :float)
42
- Entry.new(
43
- fn: proc(&operation),
44
- arity: 1,
45
- param_types: [:float],
46
- return_type: return_type,
47
- description: description
48
- )
49
- end
50
-
51
- def self.string_unary(_name, description, operation)
52
- Entry.new(
53
- fn: ->(str) { str.to_s.public_send(operation) },
54
- arity: 1,
55
- param_types: [:string],
56
- return_type: :string,
57
- description: description
58
- )
59
- end
60
-
61
- def self.string_binary(_name, description, operation, return_type: :string)
62
- Entry.new(
63
- fn: ->(str, arg) { str.to_s.public_send(operation, arg.to_s) },
64
- arity: 2,
65
- param_types: %i[string string],
66
- return_type: return_type,
67
- description: description
68
- )
69
- end
70
-
71
- def self.logical_variadic(_name, description, operation)
72
- Entry.new(
73
- fn: ->(conditions) { conditions.public_send(operation) },
74
- arity: -1,
75
- param_types: [:boolean],
76
- return_type: :boolean,
77
- description: description
78
- )
79
- end
80
-
81
- def self.collection_unary(_name, description, operation, return_type: :boolean, reducer: false)
82
- Entry.new(
83
- fn: proc(&operation),
84
- arity: 1,
85
- param_types: [Kumi::Types.array(:any)],
86
- return_type: return_type,
87
- description: description,
88
- reducer: reducer
89
- )
90
- end
91
- end
92
- end
93
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Logical operations and boolean functions
6
- module LogicalFunctions
7
- def self.definitions
8
- {
9
- # Basic logical operations
10
- and: FunctionBuilder::Entry.new(
11
- fn: ->(*conditions) { conditions.all? },
12
- arity: -1,
13
- param_types: [:boolean],
14
- return_type: :boolean,
15
- description: "Logical AND of multiple conditions"
16
- ),
17
-
18
- or: FunctionBuilder::Entry.new(
19
- fn: ->(*conditions) { conditions.any? },
20
- arity: -1,
21
- param_types: [:boolean],
22
- return_type: :boolean,
23
- description: "Logical OR of multiple conditions"
24
- ),
25
-
26
- not: FunctionBuilder::Entry.new(
27
- fn: lambda(&:!),
28
- arity: 1,
29
- param_types: [:boolean],
30
- return_type: :boolean,
31
- description: "Logical NOT"
32
- ),
33
-
34
- # Collection logical operations
35
- all?: FunctionBuilder.collection_unary(:all?, "Check if all elements in collection are truthy", :all?),
36
- any?: FunctionBuilder.collection_unary(:any?, "Check if any element in collection is truthy", :any?),
37
- none?: FunctionBuilder.collection_unary(:none?, "Check if no elements in collection are truthy", :none?)
38
- }
39
- end
40
- end
41
- end
42
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Mathematical operations
6
- module MathFunctions
7
- def self.definitions
8
- {
9
- # Basic arithmetic
10
- add: FunctionBuilder.math_binary(:add, "Add two numbers", :+),
11
- subtract: FunctionBuilder.math_binary(:subtract, "Subtract second number from first", :-),
12
- multiply: FunctionBuilder.math_binary(:multiply, "Multiply two numbers", :*),
13
- divide: FunctionBuilder.math_binary(:divide, "Divide first number by second", :/),
14
- modulo: FunctionBuilder.math_binary(:modulo, "Modulo operation", :%),
15
- power: FunctionBuilder.math_binary(:power, "Raise first number to power of second", :**),
16
-
17
- # Unary operations
18
- abs: FunctionBuilder.math_unary(:abs, "Absolute value", :abs),
19
- floor: FunctionBuilder.math_unary(:floor, "Floor of number", :floor, return_type: :integer),
20
- ceil: FunctionBuilder.math_unary(:ceil, "Ceiling of number", :ceil, return_type: :integer),
21
-
22
- # Special operations
23
- round: FunctionBuilder::Entry.new(
24
- fn: ->(a, precision = 0) { a.round(precision) },
25
- arity: -1,
26
- param_types: [:float],
27
- return_type: :float,
28
- description: "Round number to specified precision"
29
- ),
30
-
31
- clamp: FunctionBuilder::Entry.new(
32
- fn: ->(value, min, max) { value.clamp(min, max) },
33
- arity: 3,
34
- param_types: %i[float float float],
35
- return_type: :float,
36
- description: "Clamp value between min and max"
37
- ),
38
- piecewise_sum: FunctionBuilder::Entry.new(
39
- # Tiered / piece‑wise accumulator ­­­­­­­­­­­­­­­­­­­­­­­­­
40
- fn: lambda do |value, breaks, rates|
41
- raise ArgumentError, "breaks & rates size mismatch" unless breaks.size == rates.size
42
-
43
- acc = 0.0
44
- previous = 0.0
45
- marginal = rates.last
46
-
47
- breaks.zip(rates).each do |upper, rate|
48
- if value <= upper
49
- marginal = rate
50
- acc += (value - previous) * rate
51
- break
52
- else
53
- acc += (upper - previous) * rate
54
- previous = upper
55
- end
56
- end
57
- [acc, marginal] # => [sum, marginal_rate]
58
- end,
59
- arity: 3,
60
- param_types: [
61
- :float,
62
- Kumi::Types.array(:float), # breaks
63
- Kumi::Types.array(:float) # rates
64
- ],
65
- return_type: Kumi::Types.array(:float), # 2‑element [sum, marginal]
66
- description: "Accumulate over tiered ranges; returns [sum, marginal_rate]"
67
- )
68
- }
69
- end
70
- end
71
- end
72
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # String manipulation functions
6
- module StringFunctions
7
- def self.definitions
8
- {
9
- # String transformations
10
- upcase: FunctionBuilder.string_unary(:upcase, "Convert string to uppercase", :upcase),
11
- downcase: FunctionBuilder.string_unary(:downcase, "Convert string to lowercase", :downcase),
12
- capitalize: FunctionBuilder.string_unary(:capitalize, "Capitalize first letter of string", :capitalize),
13
- strip: FunctionBuilder.string_unary(:strip, "Remove leading and trailing whitespace", :strip),
14
-
15
- # String queries
16
- string_length: FunctionBuilder::Entry.new(
17
- fn: ->(str) { str.to_s.length },
18
- arity: 1,
19
- param_types: [:string],
20
- return_type: :integer,
21
- description: "Get string length"
22
- ),
23
-
24
- # Keep the original length for backward compatibility, but it will be overridden
25
- length: FunctionBuilder::Entry.new(
26
- fn: ->(str) { str.to_s.length },
27
- arity: 1,
28
- param_types: [:string],
29
- return_type: :integer,
30
- description: "Get string length"
31
- ),
32
-
33
- # String inclusion using different name to avoid conflict with collection include?
34
- string_include?: FunctionBuilder.string_binary(:include?, "Check if string contains substring", :include?, return_type: :boolean),
35
- includes?: FunctionBuilder.string_binary(:include?, "Check if string contains substring", :include?, return_type: :boolean),
36
- contains?: FunctionBuilder.string_binary(:include?, "Check if string contains substring", :include?, return_type: :boolean),
37
-
38
- start_with?: FunctionBuilder.string_binary(:start_with?, "Check if string starts with prefix", :start_with?,
39
- return_type: :boolean),
40
- end_with?: FunctionBuilder.string_binary(:end_with?, "Check if string ends with suffix", :end_with?, return_type: :boolean),
41
-
42
- # String building
43
- concat: FunctionBuilder::Entry.new(
44
- fn: ->(*strings) { strings.join },
45
- arity: -1,
46
- param_types: [:string],
47
- return_type: :string,
48
- description: "Concatenate multiple strings"
49
- )
50
- }
51
- end
52
- end
53
- end
54
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module FunctionRegistry
5
- # Type checking and conversion functions
6
- module TypeFunctions
7
- def self.definitions
8
- {
9
- fetch: FunctionBuilder::Entry.new(
10
- fn: ->(hash, key, default = nil) { hash.fetch(key, default) },
11
- arity: -1, # Variable arity (2 or 3)
12
- param_types: [Kumi::Types.hash(:any, :any), :any, :any],
13
- return_type: :any,
14
- description: "Fetch value from hash with optional default"
15
- ),
16
-
17
- has_key?: FunctionBuilder::Entry.new(
18
- fn: ->(hash, key) { hash.key?(key) },
19
- arity: 2,
20
- param_types: [Kumi::Types.hash(:any, :any), :any],
21
- return_type: :boolean,
22
- description: "Check if hash has the given key"
23
- ),
24
-
25
- keys: FunctionBuilder::Entry.new(
26
- fn: lambda(&:keys),
27
- arity: 1,
28
- param_types: [Kumi::Types.hash(:any, :any)],
29
- return_type: Kumi::Types.array(:any),
30
- description: "Get all keys from hash"
31
- ),
32
-
33
- values: FunctionBuilder::Entry.new(
34
- fn: lambda(&:values),
35
- arity: 1,
36
- param_types: [Kumi::Types.hash(:any, :any)],
37
- return_type: Kumi::Types.array(:any),
38
- description: "Get all values from hash"
39
- ),
40
- at: FunctionBuilder::Entry.new(
41
- fn: ->(array, index) { array[index] },
42
- arity: 2,
43
- param_types: [Kumi::Types.array(:any), :integer],
44
- return_type: :any,
45
- description: "Get element at index from array"
46
- )
47
- }
48
- end
49
- end
50
- end
51
- end