kumi 0.0.4 → 0.0.6

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +160 -8
  3. data/README.md +278 -200
  4. data/{documents → docs}/AST.md +29 -29
  5. data/{documents → docs}/DSL.md +3 -3
  6. data/{documents → docs}/SYNTAX.md +107 -24
  7. data/docs/features/README.md +45 -0
  8. data/docs/features/analysis-cascade-mutual-exclusion.md +89 -0
  9. data/docs/features/analysis-type-inference.md +42 -0
  10. data/docs/features/analysis-unsat-detection.md +71 -0
  11. data/docs/features/array-broadcasting.md +170 -0
  12. data/docs/features/input-declaration-system.md +42 -0
  13. data/docs/features/performance.md +16 -0
  14. data/examples/federal_tax_calculator_2024.rb +43 -40
  15. data/examples/game_of_life.rb +97 -0
  16. data/examples/simple_rpg_game.rb +1000 -0
  17. data/examples/static_analysis_errors.rb +178 -0
  18. data/examples/wide_schema_compilation_and_evaluation_benchmark.rb +1 -1
  19. data/lib/kumi/analyzer/analysis_state.rb +37 -0
  20. data/lib/kumi/analyzer/constant_evaluator.rb +22 -16
  21. data/lib/kumi/analyzer/passes/broadcast_detector.rb +251 -0
  22. data/lib/kumi/analyzer/passes/{definition_validator.rb → declaration_validator.rb} +8 -7
  23. data/lib/kumi/analyzer/passes/dependency_resolver.rb +106 -26
  24. data/lib/kumi/analyzer/passes/input_collector.rb +105 -23
  25. data/lib/kumi/analyzer/passes/name_indexer.rb +2 -2
  26. data/lib/kumi/analyzer/passes/pass_base.rb +11 -28
  27. data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +110 -0
  28. data/lib/kumi/analyzer/passes/toposorter.rb +45 -9
  29. data/lib/kumi/analyzer/passes/type_checker.rb +34 -11
  30. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +2 -1
  31. data/lib/kumi/analyzer/passes/type_inferencer.rb +128 -21
  32. data/lib/kumi/analyzer/passes/unsat_detector.rb +312 -13
  33. data/lib/kumi/analyzer/passes/visitor_pass.rb +4 -3
  34. data/lib/kumi/analyzer.rb +41 -24
  35. data/lib/kumi/atom_unsat_solver.rb +45 -0
  36. data/lib/kumi/cli.rb +449 -0
  37. data/lib/kumi/compiler.rb +194 -16
  38. data/lib/kumi/constraint_relationship_solver.rb +638 -0
  39. data/lib/kumi/domain/validator.rb +0 -4
  40. data/lib/kumi/error_reporter.rb +6 -6
  41. data/lib/kumi/evaluation_wrapper.rb +20 -4
  42. data/lib/kumi/explain.rb +28 -28
  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 +117 -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/parser/declaration_reference_proxy.rb +36 -0
  51. data/lib/kumi/parser/dsl_cascade_builder.rb +19 -8
  52. data/lib/kumi/parser/expression_converter.rb +80 -12
  53. data/lib/kumi/parser/input_builder.rb +40 -9
  54. data/lib/kumi/parser/input_field_proxy.rb +46 -0
  55. data/lib/kumi/parser/input_proxy.rb +3 -3
  56. data/lib/kumi/parser/nested_input.rb +15 -0
  57. data/lib/kumi/parser/parser.rb +2 -0
  58. data/lib/kumi/parser/schema_builder.rb +10 -9
  59. data/lib/kumi/parser/sugar.rb +171 -18
  60. data/lib/kumi/schema.rb +3 -1
  61. data/lib/kumi/schema_instance.rb +69 -3
  62. data/lib/kumi/syntax/array_expression.rb +15 -0
  63. data/lib/kumi/syntax/call_expression.rb +11 -0
  64. data/lib/kumi/syntax/cascade_expression.rb +11 -0
  65. data/lib/kumi/syntax/case_expression.rb +11 -0
  66. data/lib/kumi/syntax/declaration_reference.rb +11 -0
  67. data/lib/kumi/syntax/hash_expression.rb +11 -0
  68. data/lib/kumi/syntax/input_declaration.rb +12 -0
  69. data/lib/kumi/syntax/input_element_reference.rb +12 -0
  70. data/lib/kumi/syntax/input_reference.rb +12 -0
  71. data/lib/kumi/syntax/literal.rb +11 -0
  72. data/lib/kumi/syntax/root.rb +1 -0
  73. data/lib/kumi/syntax/trait_declaration.rb +11 -0
  74. data/lib/kumi/syntax/value_declaration.rb +11 -0
  75. data/lib/kumi/types/compatibility.rb +8 -0
  76. data/lib/kumi/types/validator.rb +1 -1
  77. data/lib/kumi/vectorization_metadata.rb +108 -0
  78. data/lib/kumi/version.rb +1 -1
  79. data/scripts/generate_function_docs.rb +22 -10
  80. metadata +38 -17
  81. data/CHANGELOG.md +0 -25
  82. data/lib/kumi/domain.rb +0 -8
  83. data/lib/kumi/input.rb +0 -8
  84. data/lib/kumi/syntax/declarations.rb +0 -23
  85. data/lib/kumi/syntax/expressions.rb +0 -30
  86. data/lib/kumi/syntax/terminal_expressions.rb +0 -27
  87. data/lib/kumi/syntax.rb +0 -9
  88. data/test_impossible_cascade.rb +0 -51
  89. /data/{documents → docs}/FUNCTIONS.md +0 -0
@@ -9,8 +9,10 @@ module Kumi
9
9
  # instance.slice(:tax_due) # alias for evaluate(*keys)
10
10
  # instance.explain(:tax_due) # pretty trace string
11
11
  # instance.input # original context (read‑only)
12
- #
12
+
13
13
  class SchemaInstance
14
+ attr_reader :compiled_schema, :analysis, :context
15
+
14
16
  def initialize(compiled_schema, analysis, context)
15
17
  @compiled_schema = compiled_schema # Kumi::CompiledSchema
16
18
  @analysis = analysis # Analyzer result (for deps)
@@ -36,8 +38,72 @@ module Kumi
36
38
  evaluate(key_name)[key_name]
37
39
  end
38
40
 
39
- def input
40
- @context
41
+ # Update input values and clear affected cached computations
42
+ def update(**changes)
43
+ changes.each do |field, value|
44
+ # Validate field exists
45
+ raise ArgumentError, "unknown input field: #{field}" unless input_field_exists?(field)
46
+
47
+ # Validate domain constraints
48
+ validate_domain_constraint(field, value)
49
+
50
+ # Update the input data
51
+ @context[field] = value
52
+
53
+ # Clear affected cached values using transitive closure by default
54
+ if ENV["KUMI_SIMPLE_CACHE"] == "true"
55
+ # Simple fallback: clear all cached values
56
+ @context.clear_cache
57
+ else
58
+ # Default: selective cache clearing using precomputed transitive closure
59
+ affected_keys = find_dependent_declarations_optimized(field)
60
+ affected_keys.each { |key| @context.clear_cache(key) }
61
+ end
62
+ end
63
+
64
+ self # Return self for chaining
65
+ end
66
+
67
+ private
68
+
69
+ def input_field_exists?(field)
70
+ # Check if field is declared in input block
71
+ input_meta = @analysis&.state&.dig(:input_meta) || {}
72
+ input_meta.key?(field) || @context.key?(field)
73
+ end
74
+
75
+ def validate_domain_constraint(field, value)
76
+ input_meta = @analysis&.state&.dig(:input_meta) || {}
77
+ field_meta = input_meta[field]
78
+ return unless field_meta&.dig(:domain)
79
+
80
+ domain = field_meta[:domain]
81
+ return unless violates_domain?(value, domain)
82
+
83
+ raise ArgumentError, "value #{value} is not in domain #{domain}"
84
+ end
85
+
86
+ def violates_domain?(value, domain)
87
+ case domain
88
+ when Range
89
+ !domain.include?(value)
90
+ when Array
91
+ !domain.include?(value)
92
+ when Proc
93
+ # For Proc domains, we can't statically analyze
94
+ false
95
+ else
96
+ false
97
+ end
98
+ end
99
+
100
+ def find_dependent_declarations_optimized(field)
101
+ # Use precomputed transitive closure for true O(1) lookup!
102
+ transitive_dependents = @analysis&.state&.dig(:transitive_dependents)
103
+ return [] unless transitive_dependents
104
+
105
+ # This is truly O(1) - just array lookup, no traversal needed
106
+ transitive_dependents[field] || []
41
107
  end
42
108
  end
43
109
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ ArrayExpression = Struct.new(:elements) do
6
+ include Node
7
+
8
+ def children = elements
9
+
10
+ def size
11
+ elements.size
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ CallExpression = Struct.new(:fn_name, :args) do
6
+ include Node
7
+
8
+ def children = args
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ CascadeExpression = Struct.new(:cases) do
6
+ include Node
7
+
8
+ def children = cases
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ CaseExpression = Struct.new(:condition, :result) do
6
+ include Node
7
+
8
+ def children = [condition, result]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ DeclarationReference = Struct.new(:name) do
6
+ include Node
7
+
8
+ def children = []
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ HashExpression = Struct.new(:pairs) do
6
+ include Node
7
+
8
+ def children = pairs.flatten
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ # For field metadata declarations inside input blocks
6
+ InputDeclaration = Struct.new(:name, :domain, :type, :children) do
7
+ include Node
8
+
9
+ def children = self[:children] || []
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ # For field usage/reference in expressions (input.field_name)
6
+ InputElementReference = Struct.new(:path) do
7
+ include Node
8
+
9
+ def children = []
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ # For field usage/reference in expressions (input.field_name)
6
+ InputReference = Struct.new(:name) do
7
+ include Node
8
+
9
+ def children = []
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ Literal = Struct.new(:value) do
6
+ include Node
7
+
8
+ def children = []
9
+ end
10
+ end
11
+ end
@@ -6,6 +6,7 @@ module Kumi
6
6
  # It holds all the top-level declarations parsed from the source.
7
7
  Root = Struct.new(:inputs, :attributes, :traits) do
8
8
  include Node
9
+
9
10
  def children = [inputs, attributes, traits]
10
11
  end
11
12
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ TraitDeclaration = Struct.new(:name, :expression) do
6
+ include Node
7
+
8
+ def children = [expression]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ ValueDeclaration = Struct.new(:name, :expression) do
6
+ include Node
7
+
8
+ def children = [expression]
9
+ end
10
+ end
11
+ end
@@ -12,6 +12,10 @@ module Kumi
12
12
  # Exact match
13
13
  return true if type1 == type2
14
14
 
15
+ # Generic array compatibility: :array is compatible with any structured array
16
+ return true if (type1 == :array && Validator.array_type?(type2)) ||
17
+ (type2 == :array && Validator.array_type?(type1))
18
+
15
19
  # Numeric compatibility
16
20
  return true if numeric_compatible?(type1, type2)
17
21
 
@@ -32,6 +36,10 @@ module Kumi
32
36
  return type2 if type1 == :any
33
37
  return type1 if type2 == :any
34
38
 
39
+ # Generic array unification: structured array is more specific than :array
40
+ return type2 if type1 == :array && Validator.array_type?(type2)
41
+ return type1 if type2 == :array && Validator.array_type?(type1)
42
+
35
43
  # Numeric unification
36
44
  if numeric_compatible?(type1, type2)
37
45
  return :integer if type1 == :integer && type2 == :integer
@@ -4,7 +4,7 @@ module Kumi
4
4
  module Types
5
5
  # Validates type definitions and structures
6
6
  class Validator
7
- VALID_TYPES = %i[string integer float boolean any symbol regexp time date datetime].freeze
7
+ VALID_TYPES = %i[string integer float boolean any symbol regexp time date datetime array].freeze
8
8
 
9
9
  def self.valid_type?(type)
10
10
  return true if VALID_TYPES.include?(type)
@@ -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.4"
4
+ VERSION = "0.0.6"
5
5
  end
@@ -30,10 +30,25 @@ end
30
30
  # Main documentation generation logic.
31
31
  def generate_docs
32
32
  output = []
33
+ add_header(output)
34
+ add_function_categories(output)
35
+ output.join("\n")
36
+ end
37
+
38
+ def add_header(output)
33
39
  output << "# Kumi Standard Function Library Reference"
34
40
  output << "\nKumi provides a rich library of built-in functions for use within `value` and `trait` expressions via `fn(...)`."
41
+ end
42
+
43
+ def add_function_categories(output)
44
+ function_categories.each do |title, functions|
45
+ output << "\n## #{title}\n"
46
+ add_functions_for_category(output, functions)
47
+ end
48
+ end
35
49
 
36
- categories = {
50
+ def function_categories
51
+ {
37
52
  "Logical Functions" => Kumi::FunctionRegistry.logical_operations,
38
53
  "Comparison Functions" => Kumi::FunctionRegistry.comparison_operators,
39
54
  "Math Functions" => Kumi::FunctionRegistry.math_operations,
@@ -42,17 +57,14 @@ def generate_docs
42
57
  "Conditional Functions" => Kumi::FunctionRegistry.conditional_operations,
43
58
  "Type & Hash Functions" => Kumi::FunctionRegistry.type_operations
44
59
  }
60
+ end
45
61
 
46
- categories.each do |title, functions|
47
- output << "\n## #{title}\n"
48
- functions.sort.each do |name|
49
- signature = Kumi::FunctionRegistry.signature(name)
50
- output << "* **`#{name}`**: #{signature[:description]}"
51
- output << " * **Usage**: #{generate_signature(name, signature)}"
52
- end
62
+ def add_functions_for_category(output, functions)
63
+ functions.sort.each do |name|
64
+ signature = Kumi::FunctionRegistry.signature(name)
65
+ output << "* **`#{name}`**: #{signature[:description]}"
66
+ output << " * **Usage**: #{generate_signature(name, signature)}"
53
67
  end
54
-
55
- output.join("\n")
56
68
  end
57
69
 
58
70
  # Execute the script and print the documentation.
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.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Muta
@@ -31,29 +31,41 @@ extra_rdoc_files: []
31
31
  files:
32
32
  - ".rspec"
33
33
  - ".rubocop.yml"
34
- - CHANGELOG.md
35
34
  - CLAUDE.md
36
35
  - LICENSE.txt
37
36
  - README.md
38
37
  - Rakefile
38
+ - docs/AST.md
39
+ - docs/DSL.md
40
+ - docs/FUNCTIONS.md
41
+ - docs/SYNTAX.md
39
42
  - docs/development/README.md
40
43
  - docs/development/error-reporting.md
41
- - documents/AST.md
42
- - documents/DSL.md
43
- - documents/FUNCTIONS.md
44
- - 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
45
51
  - examples/deep_schema_compilation_and_evaluation_benchmark.rb
46
52
  - examples/federal_tax_calculator_2024.rb
53
+ - examples/game_of_life.rb
54
+ - examples/simple_rpg_game.rb
55
+ - examples/static_analysis_errors.rb
47
56
  - examples/wide_schema_compilation_and_evaluation_benchmark.rb
48
57
  - lib/generators/trait_engine/templates/schema_spec.rb.erb
49
58
  - lib/kumi.rb
50
59
  - lib/kumi/analyzer.rb
60
+ - lib/kumi/analyzer/analysis_state.rb
51
61
  - lib/kumi/analyzer/constant_evaluator.rb
52
- - lib/kumi/analyzer/passes/definition_validator.rb
62
+ - lib/kumi/analyzer/passes/broadcast_detector.rb
63
+ - lib/kumi/analyzer/passes/declaration_validator.rb
53
64
  - lib/kumi/analyzer/passes/dependency_resolver.rb
54
65
  - lib/kumi/analyzer/passes/input_collector.rb
55
66
  - lib/kumi/analyzer/passes/name_indexer.rb
56
67
  - lib/kumi/analyzer/passes/pass_base.rb
68
+ - lib/kumi/analyzer/passes/semantic_constraint_validator.rb
57
69
  - lib/kumi/analyzer/passes/toposorter.rb
58
70
  - lib/kumi/analyzer/passes/type_checker.rb
59
71
  - lib/kumi/analyzer/passes/type_consistency_checker.rb
@@ -61,9 +73,10 @@ files:
61
73
  - lib/kumi/analyzer/passes/unsat_detector.rb
62
74
  - lib/kumi/analyzer/passes/visitor_pass.rb
63
75
  - lib/kumi/atom_unsat_solver.rb
76
+ - lib/kumi/cli.rb
64
77
  - lib/kumi/compiled_schema.rb
65
78
  - lib/kumi/compiler.rb
66
- - lib/kumi/domain.rb
79
+ - lib/kumi/constraint_relationship_solver.rb
67
80
  - lib/kumi/domain/enum_analyzer.rb
68
81
  - lib/kumi/domain/range_analyzer.rb
69
82
  - lib/kumi/domain/validator.rb
@@ -89,28 +102,38 @@ files:
89
102
  - lib/kumi/function_registry/math_functions.rb
90
103
  - lib/kumi/function_registry/string_functions.rb
91
104
  - lib/kumi/function_registry/type_functions.rb
92
- - lib/kumi/input.rb
93
105
  - lib/kumi/input/type_matcher.rb
94
106
  - lib/kumi/input/validator.rb
95
107
  - lib/kumi/input/violation_creator.rb
96
108
  - lib/kumi/parser/build_context.rb
109
+ - lib/kumi/parser/declaration_reference_proxy.rb
97
110
  - lib/kumi/parser/dsl.rb
98
111
  - lib/kumi/parser/dsl_cascade_builder.rb
99
112
  - lib/kumi/parser/expression_converter.rb
100
113
  - lib/kumi/parser/guard_rails.rb
101
114
  - lib/kumi/parser/input_builder.rb
115
+ - lib/kumi/parser/input_field_proxy.rb
102
116
  - lib/kumi/parser/input_proxy.rb
117
+ - lib/kumi/parser/nested_input.rb
103
118
  - lib/kumi/parser/parser.rb
104
119
  - lib/kumi/parser/schema_builder.rb
105
120
  - lib/kumi/parser/sugar.rb
106
121
  - lib/kumi/schema.rb
107
122
  - lib/kumi/schema_instance.rb
108
- - lib/kumi/syntax.rb
109
- - lib/kumi/syntax/declarations.rb
110
- - lib/kumi/syntax/expressions.rb
123
+ - lib/kumi/syntax/array_expression.rb
124
+ - lib/kumi/syntax/call_expression.rb
125
+ - lib/kumi/syntax/cascade_expression.rb
126
+ - lib/kumi/syntax/case_expression.rb
127
+ - lib/kumi/syntax/declaration_reference.rb
128
+ - lib/kumi/syntax/hash_expression.rb
129
+ - lib/kumi/syntax/input_declaration.rb
130
+ - lib/kumi/syntax/input_element_reference.rb
131
+ - lib/kumi/syntax/input_reference.rb
132
+ - lib/kumi/syntax/literal.rb
111
133
  - lib/kumi/syntax/node.rb
112
134
  - lib/kumi/syntax/root.rb
113
- - lib/kumi/syntax/terminal_expressions.rb
135
+ - lib/kumi/syntax/trait_declaration.rb
136
+ - lib/kumi/syntax/value_declaration.rb
114
137
  - lib/kumi/types.rb
115
138
  - lib/kumi/types/builder.rb
116
139
  - lib/kumi/types/compatibility.rb
@@ -118,9 +141,9 @@ files:
118
141
  - lib/kumi/types/inference.rb
119
142
  - lib/kumi/types/normalizer.rb
120
143
  - lib/kumi/types/validator.rb
144
+ - lib/kumi/vectorization_metadata.rb
121
145
  - lib/kumi/version.rb
122
146
  - scripts/generate_function_docs.rb
123
- - test_impossible_cascade.rb
124
147
  homepage: https://github.com/amuta/kumi
125
148
  licenses:
126
149
  - MIT
@@ -146,7 +169,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
169
  requirements: []
147
170
  rubygems_version: 3.7.1
148
171
  specification_version: 4
149
- summary: A declarative Ruby DSL for defining business rules and calculations with
150
- static dependency checks, cycle detection, domain validation, and human‑readable
151
- explainability.
172
+ summary: A Declarative logic framework with static analysis for Ruby.
152
173
  test_files: []
data/CHANGELOG.md DELETED
@@ -1,25 +0,0 @@
1
- ## [Unreleased]
2
-
3
- ### Changed
4
- - **BREAKING**: Replaced `StrictCycleChecker` with `AtomUnsatSolver` for stack-safe UNSAT detection
5
- - Refactored cycle detection to use iterative Kahn's topological sort algorithm instead of recursive DFS
6
- - Added support for always-false comparison detection (e.g., `100 < 100`)
7
-
8
- ### Added
9
- - **Evaluation memoization**: `EvaluationWrapper` struct with `@__schema_cache__` provides automatic caching of computed bindings
10
- - **Massive performance improvements**: 369x-1,379x speedup on deep dependency chains through intelligent memoization
11
- - Depth-safe UNSAT detection handles 30k+ node graphs without stack overflow
12
- - Comprehensive test suite for large graph scenarios (acyclic ladders, cycles, mixed constraints)
13
- - Enhanced documentation with YARD comments for `AtomUnsatSolver` module
14
- - Extracted `StrictInequalitySolver` module for clear separation of cycle detection logic
15
-
16
- ### Performance
17
- - **Stack-safe UNSAT detection**: Eliminates `SystemStackError` in constraint analysis for 30k+ node graphs
18
- - **Fixed gather_atoms recursion**: Made AST traversal iterative to handle deep dependency chains
19
- - Sub-millisecond performance on 10k-20k node constraint graphs with cycle detection
20
- - Maintained identical UNSAT detection correctness for all existing scenarios
21
- - **Note**: Deep schemas (2500+ dependencies) may still hit Ruby stack limits in compilation/evaluation phases
22
-
23
- ## [0.1.0] - 2025-07-01
24
-
25
- - Initial release
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,23 +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
- def children = [expression]
9
- end
10
-
11
- Trait = Struct.new(:name, :expression) do
12
- include Node
13
- def children = [expression]
14
- end
15
-
16
- # For field metadata declarations inside input blocks
17
- FieldDecl = Struct.new(:name, :domain, :type) do
18
- include Node
19
- def children = []
20
- end
21
- end
22
- end
23
- end