kumi 0.0.5 → 0.0.7

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +76 -174
  3. data/README.md +205 -52
  4. data/{documents → docs}/AST.md +29 -29
  5. data/{documents → docs}/SYNTAX.md +95 -8
  6. data/docs/features/README.md +45 -0
  7. data/docs/features/analysis-cascade-mutual-exclusion.md +89 -0
  8. data/docs/features/analysis-type-inference.md +42 -0
  9. data/docs/features/analysis-unsat-detection.md +71 -0
  10. data/docs/features/array-broadcasting.md +170 -0
  11. data/docs/features/input-declaration-system.md +42 -0
  12. data/docs/features/performance.md +16 -0
  13. data/docs/schema_metadata/broadcasts.md +53 -0
  14. data/docs/schema_metadata/cascades.md +45 -0
  15. data/docs/schema_metadata/declarations.md +54 -0
  16. data/docs/schema_metadata/dependencies.md +57 -0
  17. data/docs/schema_metadata/evaluation_order.md +29 -0
  18. data/docs/schema_metadata/examples.md +95 -0
  19. data/docs/schema_metadata/inferred_types.md +46 -0
  20. data/docs/schema_metadata/inputs.md +86 -0
  21. data/docs/schema_metadata.md +108 -0
  22. data/examples/federal_tax_calculator_2024.rb +11 -6
  23. data/lib/kumi/analyzer/constant_evaluator.rb +1 -1
  24. data/lib/kumi/analyzer/passes/broadcast_detector.rb +246 -0
  25. data/lib/kumi/analyzer/passes/{definition_validator.rb → declaration_validator.rb} +4 -4
  26. data/lib/kumi/analyzer/passes/dependency_resolver.rb +78 -38
  27. data/lib/kumi/analyzer/passes/input_collector.rb +91 -30
  28. data/lib/kumi/analyzer/passes/name_indexer.rb +2 -2
  29. data/lib/kumi/analyzer/passes/pass_base.rb +1 -1
  30. data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +24 -25
  31. data/lib/kumi/analyzer/passes/toposorter.rb +44 -8
  32. data/lib/kumi/analyzer/passes/type_checker.rb +34 -14
  33. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +2 -2
  34. data/lib/kumi/analyzer/passes/type_inferencer.rb +130 -21
  35. data/lib/kumi/analyzer/passes/unsat_detector.rb +134 -56
  36. data/lib/kumi/analyzer/passes/visitor_pass.rb +2 -2
  37. data/lib/kumi/analyzer.rb +16 -17
  38. data/lib/kumi/compiler.rb +188 -16
  39. data/lib/kumi/constraint_relationship_solver.rb +6 -6
  40. data/lib/kumi/domain/validator.rb +0 -4
  41. data/lib/kumi/error_reporting.rb +1 -1
  42. data/lib/kumi/explain.rb +32 -20
  43. data/lib/kumi/export/node_registry.rb +26 -12
  44. data/lib/kumi/export/node_serializers.rb +1 -1
  45. data/lib/kumi/function_registry/collection_functions.rb +14 -9
  46. data/lib/kumi/function_registry/function_builder.rb +4 -3
  47. data/lib/kumi/function_registry.rb +8 -2
  48. data/lib/kumi/input/type_matcher.rb +3 -0
  49. data/lib/kumi/input/validator.rb +0 -3
  50. data/lib/kumi/json_schema/generator.rb +63 -0
  51. data/lib/kumi/json_schema/validator.rb +25 -0
  52. data/lib/kumi/json_schema.rb +14 -0
  53. data/lib/kumi/{parser → ruby_parser}/build_context.rb +1 -1
  54. data/lib/kumi/ruby_parser/declaration_reference_proxy.rb +36 -0
  55. data/lib/kumi/{parser → ruby_parser}/dsl.rb +1 -1
  56. data/lib/kumi/{parser → ruby_parser}/dsl_cascade_builder.rb +5 -5
  57. data/lib/kumi/{parser → ruby_parser}/expression_converter.rb +20 -20
  58. data/lib/kumi/{parser → ruby_parser}/guard_rails.rb +1 -1
  59. data/lib/kumi/{parser → ruby_parser}/input_builder.rb +41 -10
  60. data/lib/kumi/ruby_parser/input_field_proxy.rb +46 -0
  61. data/lib/kumi/{parser → ruby_parser}/input_proxy.rb +4 -4
  62. data/lib/kumi/ruby_parser/nested_input.rb +15 -0
  63. data/lib/kumi/{parser → ruby_parser}/parser.rb +11 -10
  64. data/lib/kumi/{parser → ruby_parser}/schema_builder.rb +11 -10
  65. data/lib/kumi/{parser → ruby_parser}/sugar.rb +62 -10
  66. data/lib/kumi/ruby_parser.rb +10 -0
  67. data/lib/kumi/schema.rb +10 -4
  68. data/lib/kumi/schema_instance.rb +6 -6
  69. data/lib/kumi/schema_metadata.rb +524 -0
  70. data/lib/kumi/syntax/array_expression.rb +15 -0
  71. data/lib/kumi/syntax/call_expression.rb +11 -0
  72. data/lib/kumi/syntax/cascade_expression.rb +11 -0
  73. data/lib/kumi/syntax/case_expression.rb +11 -0
  74. data/lib/kumi/syntax/declaration_reference.rb +11 -0
  75. data/lib/kumi/syntax/hash_expression.rb +11 -0
  76. data/lib/kumi/syntax/input_declaration.rb +12 -0
  77. data/lib/kumi/syntax/input_element_reference.rb +12 -0
  78. data/lib/kumi/syntax/input_reference.rb +12 -0
  79. data/lib/kumi/syntax/literal.rb +11 -0
  80. data/lib/kumi/syntax/trait_declaration.rb +11 -0
  81. data/lib/kumi/syntax/value_declaration.rb +11 -0
  82. data/lib/kumi/vectorization_metadata.rb +108 -0
  83. data/lib/kumi/version.rb +1 -1
  84. data/lib/kumi.rb +14 -0
  85. metadata +55 -25
  86. data/lib/generators/trait_engine/templates/schema_spec.rb.erb +0 -27
  87. data/lib/kumi/domain.rb +0 -8
  88. data/lib/kumi/input.rb +0 -8
  89. data/lib/kumi/syntax/declarations.rb +0 -26
  90. data/lib/kumi/syntax/expressions.rb +0 -34
  91. data/lib/kumi/syntax/terminal_expressions.rb +0 -30
  92. data/lib/kumi/syntax.rb +0 -9
  93. /data/{documents → docs}/DSL.md +0 -0
  94. /data/{documents → docs}/FUNCTIONS.md +0 -0
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ # Metadata system for vectorization detection and handling
5
+ module VectorizationMetadata
6
+ # Tracks which declarations are arrays with children (vectorizable)
7
+ class ArrayDeclarationTracker
8
+ def initialize
9
+ @array_declarations = {}
10
+ end
11
+
12
+ def register_array(name, children)
13
+ @array_declarations[name] = children.map(&:name)
14
+ end
15
+
16
+ def array_declaration?(name)
17
+ @array_declarations.key?(name)
18
+ end
19
+
20
+ def array_children(name)
21
+ @array_declarations[name] || []
22
+ end
23
+
24
+ def all_arrays
25
+ @array_declarations.keys
26
+ end
27
+ end
28
+
29
+ # Detects vectorized operations in expressions
30
+ class VectorizationDetector
31
+ def initialize(array_tracker)
32
+ @array_tracker = array_tracker
33
+ end
34
+
35
+ # Check if an expression should be vectorized
36
+ def vectorized_expression?(expression)
37
+ case expression
38
+ when Kumi::Syntax::CallExpression
39
+ vectorized_call?(expression)
40
+ when Kumi::Syntax::InputElementReference
41
+ vectorized_element_reference?(expression)
42
+ else
43
+ false
44
+ end
45
+ end
46
+
47
+ # Check if a function call should be treated as a reducer
48
+ def reducer_function?(fn_name, args)
49
+ REDUCER_FUNCTIONS.include?(fn_name) &&
50
+ args.any? { |arg| vectorized_expression?(arg) }
51
+ end
52
+
53
+ private
54
+
55
+ REDUCER_FUNCTIONS = %i[sum min max size length first last].freeze
56
+
57
+ def vectorized_call?(call_expr)
58
+ # Arithmetic operations between array elements are vectorized
59
+ ARITHMETIC_OPERATIONS.include?(call_expr.fn_name) &&
60
+ call_expr.args.any? { |arg| vectorized_expression?(arg) }
61
+ end
62
+
63
+ def vectorized_element_reference?(elem_ref)
64
+ return false unless elem_ref.path.size >= 2
65
+
66
+ array_name, _field_name = elem_ref.path
67
+ @array_tracker.array_declaration?(array_name)
68
+ end
69
+
70
+ ARITHMETIC_OPERATIONS = %i[add subtract multiply divide modulo power].freeze
71
+ end
72
+
73
+ # Metadata about how values should be computed
74
+ class ComputationMetadata
75
+ attr_reader :vectorized_values, :reducer_values, :scalar_values
76
+
77
+ def initialize
78
+ @vectorized_values = Set.new
79
+ @reducer_values = Set.new
80
+ @scalar_values = Set.new
81
+ end
82
+
83
+ def mark_vectorized(name)
84
+ @vectorized_values.add(name)
85
+ end
86
+
87
+ def mark_reducer(name)
88
+ @reducer_values.add(name)
89
+ end
90
+
91
+ def mark_scalar(name)
92
+ @scalar_values.add(name)
93
+ end
94
+
95
+ def vectorized?(name)
96
+ @vectorized_values.include?(name)
97
+ end
98
+
99
+ def reducer?(name)
100
+ @reducer_values.include?(name)
101
+ end
102
+
103
+ def scalar?(name)
104
+ @scalar_values.include?(name)
105
+ end
106
+ end
107
+ end
108
+ end
data/lib/kumi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kumi
4
- VERSION = "0.0.5"
4
+ VERSION = "0.0.7"
5
5
  end
data/lib/kumi.rb CHANGED
@@ -9,4 +9,18 @@ loader.setup
9
9
 
10
10
  module Kumi
11
11
  extend Schema
12
+
13
+ def self.inspector_from_schema
14
+ Inspector.new(@__syntax_tree__, @__analyzer_result__, @__compiled_schema__)
15
+ end
16
+
17
+ def self.reset!
18
+ @__syntax_tree__ = nil
19
+ @__analyzer_result__ = nil
20
+ @__compiled_schema__ = nil
21
+ @__schema_metadata__ = nil
22
+ end
23
+
24
+ # Reset on require to avoid state leakage in tests
25
+ reset!
12
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Muta
@@ -35,24 +35,40 @@ files:
35
35
  - LICENSE.txt
36
36
  - README.md
37
37
  - Rakefile
38
+ - docs/AST.md
39
+ - docs/DSL.md
40
+ - docs/FUNCTIONS.md
41
+ - docs/SYNTAX.md
38
42
  - docs/development/README.md
39
43
  - docs/development/error-reporting.md
40
- - documents/AST.md
41
- - documents/DSL.md
42
- - documents/FUNCTIONS.md
43
- - documents/SYNTAX.md
44
+ - docs/features/README.md
45
+ - docs/features/analysis-cascade-mutual-exclusion.md
46
+ - docs/features/analysis-type-inference.md
47
+ - docs/features/analysis-unsat-detection.md
48
+ - docs/features/array-broadcasting.md
49
+ - docs/features/input-declaration-system.md
50
+ - docs/features/performance.md
51
+ - docs/schema_metadata.md
52
+ - docs/schema_metadata/broadcasts.md
53
+ - docs/schema_metadata/cascades.md
54
+ - docs/schema_metadata/declarations.md
55
+ - docs/schema_metadata/dependencies.md
56
+ - docs/schema_metadata/evaluation_order.md
57
+ - docs/schema_metadata/examples.md
58
+ - docs/schema_metadata/inferred_types.md
59
+ - docs/schema_metadata/inputs.md
44
60
  - examples/deep_schema_compilation_and_evaluation_benchmark.rb
45
61
  - examples/federal_tax_calculator_2024.rb
46
62
  - examples/game_of_life.rb
47
63
  - examples/simple_rpg_game.rb
48
64
  - examples/static_analysis_errors.rb
49
65
  - examples/wide_schema_compilation_and_evaluation_benchmark.rb
50
- - lib/generators/trait_engine/templates/schema_spec.rb.erb
51
66
  - lib/kumi.rb
52
67
  - lib/kumi/analyzer.rb
53
68
  - lib/kumi/analyzer/analysis_state.rb
54
69
  - lib/kumi/analyzer/constant_evaluator.rb
55
- - lib/kumi/analyzer/passes/definition_validator.rb
70
+ - lib/kumi/analyzer/passes/broadcast_detector.rb
71
+ - lib/kumi/analyzer/passes/declaration_validator.rb
56
72
  - lib/kumi/analyzer/passes/dependency_resolver.rb
57
73
  - lib/kumi/analyzer/passes/input_collector.rb
58
74
  - lib/kumi/analyzer/passes/name_indexer.rb
@@ -69,7 +85,6 @@ files:
69
85
  - lib/kumi/compiled_schema.rb
70
86
  - lib/kumi/compiler.rb
71
87
  - lib/kumi/constraint_relationship_solver.rb
72
- - lib/kumi/domain.rb
73
88
  - lib/kumi/domain/enum_analyzer.rb
74
89
  - lib/kumi/domain/range_analyzer.rb
75
90
  - lib/kumi/domain/validator.rb
@@ -95,28 +110,43 @@ files:
95
110
  - lib/kumi/function_registry/math_functions.rb
96
111
  - lib/kumi/function_registry/string_functions.rb
97
112
  - lib/kumi/function_registry/type_functions.rb
98
- - lib/kumi/input.rb
99
113
  - lib/kumi/input/type_matcher.rb
100
114
  - lib/kumi/input/validator.rb
101
115
  - lib/kumi/input/violation_creator.rb
102
- - lib/kumi/parser/build_context.rb
103
- - lib/kumi/parser/dsl.rb
104
- - lib/kumi/parser/dsl_cascade_builder.rb
105
- - lib/kumi/parser/expression_converter.rb
106
- - lib/kumi/parser/guard_rails.rb
107
- - lib/kumi/parser/input_builder.rb
108
- - lib/kumi/parser/input_proxy.rb
109
- - lib/kumi/parser/parser.rb
110
- - lib/kumi/parser/schema_builder.rb
111
- - lib/kumi/parser/sugar.rb
116
+ - lib/kumi/json_schema.rb
117
+ - lib/kumi/json_schema/generator.rb
118
+ - lib/kumi/json_schema/validator.rb
119
+ - lib/kumi/ruby_parser.rb
120
+ - lib/kumi/ruby_parser/build_context.rb
121
+ - lib/kumi/ruby_parser/declaration_reference_proxy.rb
122
+ - lib/kumi/ruby_parser/dsl.rb
123
+ - lib/kumi/ruby_parser/dsl_cascade_builder.rb
124
+ - lib/kumi/ruby_parser/expression_converter.rb
125
+ - lib/kumi/ruby_parser/guard_rails.rb
126
+ - lib/kumi/ruby_parser/input_builder.rb
127
+ - lib/kumi/ruby_parser/input_field_proxy.rb
128
+ - lib/kumi/ruby_parser/input_proxy.rb
129
+ - lib/kumi/ruby_parser/nested_input.rb
130
+ - lib/kumi/ruby_parser/parser.rb
131
+ - lib/kumi/ruby_parser/schema_builder.rb
132
+ - lib/kumi/ruby_parser/sugar.rb
112
133
  - lib/kumi/schema.rb
113
134
  - lib/kumi/schema_instance.rb
114
- - lib/kumi/syntax.rb
115
- - lib/kumi/syntax/declarations.rb
116
- - lib/kumi/syntax/expressions.rb
135
+ - lib/kumi/schema_metadata.rb
136
+ - lib/kumi/syntax/array_expression.rb
137
+ - lib/kumi/syntax/call_expression.rb
138
+ - lib/kumi/syntax/cascade_expression.rb
139
+ - lib/kumi/syntax/case_expression.rb
140
+ - lib/kumi/syntax/declaration_reference.rb
141
+ - lib/kumi/syntax/hash_expression.rb
142
+ - lib/kumi/syntax/input_declaration.rb
143
+ - lib/kumi/syntax/input_element_reference.rb
144
+ - lib/kumi/syntax/input_reference.rb
145
+ - lib/kumi/syntax/literal.rb
117
146
  - lib/kumi/syntax/node.rb
118
147
  - lib/kumi/syntax/root.rb
119
- - lib/kumi/syntax/terminal_expressions.rb
148
+ - lib/kumi/syntax/trait_declaration.rb
149
+ - lib/kumi/syntax/value_declaration.rb
120
150
  - lib/kumi/types.rb
121
151
  - lib/kumi/types/builder.rb
122
152
  - lib/kumi/types/compatibility.rb
@@ -124,6 +154,7 @@ files:
124
154
  - lib/kumi/types/inference.rb
125
155
  - lib/kumi/types/normalizer.rb
126
156
  - lib/kumi/types/validator.rb
157
+ - lib/kumi/vectorization_metadata.rb
127
158
  - lib/kumi/version.rb
128
159
  - scripts/generate_function_docs.rb
129
160
  homepage: https://github.com/amuta/kumi
@@ -151,6 +182,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
182
  requirements: []
152
183
  rubygems_version: 3.7.1
153
184
  specification_version: 4
154
- summary: A declarative DSL that transforms business logic into a statically-checked
155
- dependency graph
185
+ summary: A Declarative logic framework with static analysis for Ruby.
156
186
  test_files: []
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
- require "rails_helper"
3
-
4
- RSpec.describe <%= schema_constant %> do
5
- # Single shared instance for every example
6
- let(:schema) { described_class }
7
-
8
- # Minimal dummy context so every binding can run
9
- let(:ctx) do
10
- {
11
- <% leaf_keys.each do |k| -%>
12
- <%= "#{k}:" %> nil,
13
- <% end -%>
14
- }
15
- end
16
-
17
- <% expose_names.each do |name| -%>
18
- describe "<%= name %>" do
19
- it "evaluates without raising" do
20
- expect {
21
- schema.evaluate_binding(:<%= name %>, ctx)
22
- }.not_to raise_error
23
- end
24
- end
25
-
26
- <% end -%>
27
- end
data/lib/kumi/domain.rb DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Domain
5
- end
6
- end
7
-
8
- require_relative "domain/validator"
data/lib/kumi/input.rb DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Input
5
- end
6
- end
7
-
8
- require_relative "input/validator"
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Syntax
5
- module Declarations
6
- Attribute = Struct.new(:name, :expression) do
7
- include Node
8
-
9
- def children = [expression]
10
- end
11
-
12
- Trait = Struct.new(:name, :expression) do
13
- include Node
14
-
15
- def children = [expression]
16
- end
17
-
18
- # For field metadata declarations inside input blocks
19
- FieldDecl = Struct.new(:name, :domain, :type) do
20
- include Node
21
-
22
- def children = []
23
- end
24
- end
25
- end
26
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Syntax
5
- module Expressions
6
- CallExpression = Struct.new(:fn_name, :args) do
7
- include Node
8
-
9
- def children = args
10
- end
11
- CascadeExpression = Struct.new(:cases) do
12
- include Node
13
-
14
- def children = cases
15
- end
16
-
17
- WhenCaseExpression = Struct.new(:condition, :result) do
18
- include Node
19
-
20
- def children = [condition, result]
21
- end
22
-
23
- ListExpression = Struct.new(:elements) do
24
- include Node
25
-
26
- def children = elements
27
-
28
- def size
29
- elements.size
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "node"
4
-
5
- module Kumi
6
- module Syntax
7
- module TerminalExpressions
8
- # Leaf expressions that represent a value or reference and terminate a branch.
9
-
10
- Literal = Struct.new(:value) do
11
- include Node
12
-
13
- def children = []
14
- end
15
-
16
- # For field usage/reference in expressions (input.field_name)
17
- FieldRef = Struct.new(:name) do
18
- include Node
19
-
20
- def children = []
21
- end
22
-
23
- Binding = Struct.new(:name) do
24
- include Node
25
-
26
- def children = []
27
- end
28
- end
29
- end
30
- end
data/lib/kumi/syntax.rb DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Syntax
5
- include Declarations
6
- include Expressions
7
- include TerminalExpressions
8
- end
9
- end
File without changes
File without changes