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.
- checksums.yaml +4 -4
- data/CLAUDE.md +160 -8
- data/README.md +278 -200
- data/{documents → docs}/AST.md +29 -29
- data/{documents → docs}/DSL.md +3 -3
- data/{documents → docs}/SYNTAX.md +107 -24
- data/docs/features/README.md +45 -0
- data/docs/features/analysis-cascade-mutual-exclusion.md +89 -0
- data/docs/features/analysis-type-inference.md +42 -0
- data/docs/features/analysis-unsat-detection.md +71 -0
- data/docs/features/array-broadcasting.md +170 -0
- data/docs/features/input-declaration-system.md +42 -0
- data/docs/features/performance.md +16 -0
- data/examples/federal_tax_calculator_2024.rb +43 -40
- data/examples/game_of_life.rb +97 -0
- data/examples/simple_rpg_game.rb +1000 -0
- data/examples/static_analysis_errors.rb +178 -0
- data/examples/wide_schema_compilation_and_evaluation_benchmark.rb +1 -1
- data/lib/kumi/analyzer/analysis_state.rb +37 -0
- data/lib/kumi/analyzer/constant_evaluator.rb +22 -16
- data/lib/kumi/analyzer/passes/broadcast_detector.rb +251 -0
- data/lib/kumi/analyzer/passes/{definition_validator.rb → declaration_validator.rb} +8 -7
- data/lib/kumi/analyzer/passes/dependency_resolver.rb +106 -26
- data/lib/kumi/analyzer/passes/input_collector.rb +105 -23
- data/lib/kumi/analyzer/passes/name_indexer.rb +2 -2
- data/lib/kumi/analyzer/passes/pass_base.rb +11 -28
- data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +110 -0
- data/lib/kumi/analyzer/passes/toposorter.rb +45 -9
- data/lib/kumi/analyzer/passes/type_checker.rb +34 -11
- data/lib/kumi/analyzer/passes/type_consistency_checker.rb +2 -1
- data/lib/kumi/analyzer/passes/type_inferencer.rb +128 -21
- data/lib/kumi/analyzer/passes/unsat_detector.rb +312 -13
- data/lib/kumi/analyzer/passes/visitor_pass.rb +4 -3
- data/lib/kumi/analyzer.rb +41 -24
- data/lib/kumi/atom_unsat_solver.rb +45 -0
- data/lib/kumi/cli.rb +449 -0
- data/lib/kumi/compiler.rb +194 -16
- data/lib/kumi/constraint_relationship_solver.rb +638 -0
- data/lib/kumi/domain/validator.rb +0 -4
- data/lib/kumi/error_reporter.rb +6 -6
- data/lib/kumi/evaluation_wrapper.rb +20 -4
- data/lib/kumi/explain.rb +28 -28
- data/lib/kumi/export/node_registry.rb +26 -12
- data/lib/kumi/export/node_serializers.rb +1 -1
- data/lib/kumi/function_registry/collection_functions.rb +117 -9
- data/lib/kumi/function_registry/function_builder.rb +4 -3
- data/lib/kumi/function_registry.rb +8 -2
- data/lib/kumi/input/type_matcher.rb +3 -0
- data/lib/kumi/input/validator.rb +0 -3
- data/lib/kumi/parser/declaration_reference_proxy.rb +36 -0
- data/lib/kumi/parser/dsl_cascade_builder.rb +19 -8
- data/lib/kumi/parser/expression_converter.rb +80 -12
- data/lib/kumi/parser/input_builder.rb +40 -9
- data/lib/kumi/parser/input_field_proxy.rb +46 -0
- data/lib/kumi/parser/input_proxy.rb +3 -3
- data/lib/kumi/parser/nested_input.rb +15 -0
- data/lib/kumi/parser/parser.rb +2 -0
- data/lib/kumi/parser/schema_builder.rb +10 -9
- data/lib/kumi/parser/sugar.rb +171 -18
- data/lib/kumi/schema.rb +3 -1
- data/lib/kumi/schema_instance.rb +69 -3
- data/lib/kumi/syntax/array_expression.rb +15 -0
- data/lib/kumi/syntax/call_expression.rb +11 -0
- data/lib/kumi/syntax/cascade_expression.rb +11 -0
- data/lib/kumi/syntax/case_expression.rb +11 -0
- data/lib/kumi/syntax/declaration_reference.rb +11 -0
- data/lib/kumi/syntax/hash_expression.rb +11 -0
- data/lib/kumi/syntax/input_declaration.rb +12 -0
- data/lib/kumi/syntax/input_element_reference.rb +12 -0
- data/lib/kumi/syntax/input_reference.rb +12 -0
- data/lib/kumi/syntax/literal.rb +11 -0
- data/lib/kumi/syntax/root.rb +1 -0
- data/lib/kumi/syntax/trait_declaration.rb +11 -0
- data/lib/kumi/syntax/value_declaration.rb +11 -0
- data/lib/kumi/types/compatibility.rb +8 -0
- data/lib/kumi/types/validator.rb +1 -1
- data/lib/kumi/vectorization_metadata.rb +108 -0
- data/lib/kumi/version.rb +1 -1
- data/scripts/generate_function_docs.rb +22 -10
- metadata +38 -17
- data/CHANGELOG.md +0 -25
- data/lib/kumi/domain.rb +0 -8
- data/lib/kumi/input.rb +0 -8
- data/lib/kumi/syntax/declarations.rb +0 -23
- data/lib/kumi/syntax/expressions.rb +0 -30
- data/lib/kumi/syntax/terminal_expressions.rb +0 -27
- data/lib/kumi/syntax.rb +0 -9
- data/test_impossible_cascade.rb +0 -51
- /data/{documents → docs}/FUNCTIONS.md +0 -0
data/lib/kumi/schema_instance.rb
CHANGED
@@ -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
|
-
|
40
|
-
|
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,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
|
data/lib/kumi/syntax/root.rb
CHANGED
@@ -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
|
data/lib/kumi/types/validator.rb
CHANGED
@@ -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
@@ -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
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
+
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
|
-
-
|
42
|
-
-
|
43
|
-
-
|
44
|
-
-
|
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/
|
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/
|
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/
|
110
|
-
- lib/kumi/syntax/
|
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/
|
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
|
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
data/lib/kumi/input.rb
DELETED
@@ -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
|