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,89 @@
1
+ # Cascade Mutual Exclusion Detection
2
+
3
+ Analyzes cascade expressions to allow safe recursive patterns when conditions are mutually exclusive.
4
+
5
+ ## Overview
6
+
7
+ The cascade mutual exclusion detector identifies when all conditions in a cascade expression cannot be true simultaneously, enabling safe mutual recursion patterns that would otherwise be rejected as cycles.
8
+
9
+ ## Core Mechanism
10
+
11
+ The system performs three-stage analysis:
12
+
13
+ 1. **Conditional Dependency Tracking** - DependencyResolver marks base case dependencies as conditional
14
+ 2. **Mutual Exclusion Analysis** - UnsatDetector determines if cascade conditions are mutually exclusive
15
+ 3. **Safe Cycle Detection** - Toposorter allows cycles where all edges are conditional and conditions are mutually exclusive
16
+
17
+ ## Example: Processing Workflow
18
+
19
+ ```ruby
20
+ schema do
21
+ input do
22
+ string :operation # "forward", "reverse", "unknown"
23
+ integer :value
24
+ end
25
+
26
+ trait :is_forward, input.operation == "forward"
27
+ trait :is_reverse, input.operation == "reverse"
28
+
29
+ # Safe mutual recursion - conditions are mutually exclusive
30
+ value :forward_processor do
31
+ on is_forward, input.value * 2 # Direct calculation
32
+ on is_reverse, reverse_processor + 10 # Delegates to reverse (safe)
33
+ base "invalid operation" # Fallback for unknown operations
34
+ end
35
+
36
+ value :reverse_processor do
37
+ on is_forward, forward_processor - 5 # Delegates to forward (safe)
38
+ on is_reverse, input.value / 2 # Direct calculation
39
+ base "invalid operation" # Fallback for unknown operations
40
+ end
41
+ end
42
+ ```
43
+
44
+ ## Safety Guarantees
45
+
46
+ **Allowed**: Cycles where conditions are mutually exclusive
47
+ - `is_forward` and `is_reverse` cannot both be true (operation has single value)
48
+ - Each recursion executes exactly one step before hitting direct calculation
49
+ - Bounded recursion with guaranteed termination
50
+
51
+ **Rejected**: Cycles with overlapping conditions
52
+ ```ruby
53
+ # This would be rejected - conditions can overlap
54
+ value :unsafe_cycle do
55
+ on input.n > 0, "positive"
56
+ on input.n > 5, "large" # Both can be true!
57
+ base fn(:not, unsafe_cycle)
58
+ end
59
+ ```
60
+
61
+ ## Implementation Details
62
+
63
+ ### Conditional Dependencies
64
+ Base case dependencies are marked as conditional because they only execute when no explicit conditions match.
65
+
66
+ ### Mutual Exclusion Analysis
67
+ Conditions are analyzed for mutual exclusion:
68
+ - Same field equality comparisons: `field == value1` vs `field == value2`
69
+ - Domain constraints ensuring impossibility
70
+ - All condition pairs must be mutually exclusive
71
+
72
+ ### Metadata Generation
73
+ Analysis results stored in `cascade_metadata` state:
74
+ ```ruby
75
+ {
76
+ condition_traits: [:is_forward, :is_reverse],
77
+ condition_count: 2,
78
+ all_mutually_exclusive: true,
79
+ exclusive_pairs: 1,
80
+ total_pairs: 1
81
+ }
82
+ ```
83
+
84
+ ## Use Cases
85
+
86
+ - Processing workflows with bidirectional logic
87
+ - State machine fallback patterns
88
+ - Recursive decision trees with termination conditions
89
+ - Complex business rules with safe delegation patterns
@@ -0,0 +1,42 @@
1
+ # Type Inference
2
+
3
+ Infers types from expressions and propagates them through dependency chains for compile-time type checking.
4
+
5
+ ## Type Inference Rules
6
+
7
+ **Literals:**
8
+ - `42` → `:integer`
9
+ - `3.14` → `:float`
10
+ - `"hello"` → `:string`
11
+ - `true` → `:boolean`
12
+ - `[1, 2, 3]` → `{ array: :integer }`
13
+
14
+ **Operations:**
15
+ - Integer arithmetic → `:integer`
16
+ - Mixed numeric operations → `:numeric`
17
+ - Comparisons → `:boolean`
18
+
19
+ **Functions:**
20
+ - Return types defined in function registry
21
+ - Arguments validated against parameter types
22
+
23
+ ## Error Detection
24
+
25
+ **Type mismatches:**
26
+ ```
27
+ TypeError: argument 2 of addition expects numeric, got input field `age` of declared type integer,
28
+ but argument 1 is input field `customer_name` of declared type string
29
+ ```
30
+
31
+ **Function validation:**
32
+ - Arity validation (correct number of arguments)
33
+ - Type compatibility validation
34
+ - Unknown function detection
35
+
36
+ ## Inference Process
37
+
38
+ - Processes declarations in topological order to resolve dependencies
39
+ - Literal types determined from values
40
+ - Function return types from function registry
41
+ - Array types unified from element types
42
+ - Cascade types inferred from result expressions
@@ -0,0 +1,71 @@
1
+ # Unsatisfiability Detection
2
+
3
+ Analyzes logical relationships across dependency chains to detect impossible rule combinations at compile time.
4
+
5
+ ## Example: Credit Card Approval System
6
+
7
+ This schema contains impossible rule combinations:
8
+
9
+ ```ruby
10
+ module CreditCardApproval
11
+ extend Kumi::Schema
12
+
13
+ schema do
14
+ input do
15
+ integer :annual_income
16
+ integer :monthly_debt
17
+ integer :credit_score, domain: 300..850
18
+ string :employment_type, domain: %w[full_time part_time contract self_employed]
19
+ end
20
+
21
+ # Financial calculations
22
+ value :monthly_income, input.annual_income / 12
23
+ value :available_monthly, monthly_income - input.monthly_debt
24
+ value :credit_limit_base, input.annual_income * 0.3
25
+ value :score_multiplier, (input.credit_score - 600) * 0.01
26
+ value :final_credit_limit, credit_limit_base * score_multiplier
27
+ value :employment_stability_factor,
28
+ input.employment_type == "full_time" ? 1.0 :
29
+ input.employment_type == "part_time" ? 0.7 :
30
+ input.employment_type == "contract" ? 0.5 : 0.3
31
+
32
+ # Business rules
33
+ trait :stable_income, (input.annual_income >= 60_000)
34
+ trait :good_credit, (input.credit_score >= 700)
35
+ trait :high_available_income, (available_monthly >= 4_000)
36
+ trait :premium_limit_qualified, (final_credit_limit >= 50_000)
37
+ trait :stable_employment, (input.employment_type == "full_time")
38
+ trait :high_stability_factor, (employment_stability_factor >= 0.8)
39
+ trait :excellent_credit, (input.credit_score == 900)
40
+
41
+ # Approval tiers - which combinations are impossible?
42
+ value :approval_tier do
43
+ on stable_income,good_credit,premium_limit_qualified, "platinum_tier"
44
+ on stable_employment,high_stability_factor, "executive_tier"
45
+ on excellent_credit,good_credit, "perfect_score_tier"
46
+ on stable_income,good_credit, "standard_tier"
47
+ base "manual_review"
48
+ end
49
+ end
50
+ end
51
+ ```
52
+
53
+ **Detected errors:**
54
+
55
+ ```
56
+ SemanticError:
57
+ conjunction `excellent_credit AND good_credit` is impossible
58
+ conjunction `excellent_credit` is impossible
59
+ ```
60
+
61
+ **Root cause:**
62
+ - `excellent_credit` requires `credit_score == 900`
63
+ - Input domain constrains `credit_score` to `300..850`
64
+ - Any cascade condition using `excellent_credit` becomes impossible
65
+
66
+ ## Detection Mechanisms
67
+
68
+ - Domain constraint violations: `field == value` where value is outside declared domain
69
+ - Cascade condition analysis: each `on` condition checked independently
70
+ - OR expression handling: impossible only if both sides are impossible
71
+ - Cross-variable mathematical constraint analysis
@@ -0,0 +1,170 @@
1
+ # Array Broadcasting
2
+
3
+ Automatic vectorization of operations over array fields with element-wise computation and aggregation.
4
+
5
+ ## Overview
6
+
7
+ The array broadcasting system enables natural field access syntax on array inputs (`input.items.price`) that automatically applies operations element-wise across the array, with intelligent detection of map vs reduce operations.
8
+
9
+ ## Core Mechanism
10
+
11
+ The system uses a three-stage pipeline:
12
+
13
+ 1. **Parser** - Creates InputElementReference AST nodes for nested field access
14
+ 2. **BroadcastDetector** - Identifies which operations should be vectorized vs scalar
15
+ 3. **Compiler** - Generates appropriate map/reduce functions based on usage context
16
+
17
+ ## Basic Broadcasting
18
+
19
+ ```ruby
20
+ schema do
21
+ input do
22
+ array :line_items do
23
+ float :price
24
+ integer :quantity
25
+ string :category
26
+ end
27
+ float :tax_rate, type: :float
28
+ end
29
+
30
+ # Element-wise computation - broadcasts over each item
31
+ value :subtotals, input.line_items.price * input.line_items.quantity
32
+
33
+ # Element-wise traits - applied to each item
34
+ trait :is_taxable, (input.line_items.category != "digital")
35
+
36
+ # Conditional logic - element-wise evaluation
37
+ value :taxes, fn(:if, is_taxable, subtotals * input.tax_rate, 0.0)
38
+ end
39
+ ```
40
+
41
+ ## Aggregation Operations
42
+
43
+ Operations that consume arrays to produce scalars are automatically detected:
44
+
45
+ ```ruby
46
+ schema do
47
+ # These aggregate the vectorized results
48
+ value :total_subtotal, fn(:sum, subtotals)
49
+ value :total_tax, fn(:sum, taxes)
50
+ value :grand_total, total_subtotal + total_tax
51
+
52
+ # Statistics over arrays
53
+ value :avg_price, fn(:avg, input.line_items.price)
54
+ value :max_quantity, fn(:max, input.line_items.quantity)
55
+ end
56
+ ```
57
+
58
+ ## Field Access Nesting
59
+
60
+ Supports arbitrary depth field access with path building:
61
+
62
+ ```ruby
63
+ schema do
64
+ input do
65
+ array :orders do
66
+ array :items do
67
+ hash :product do
68
+ string :name
69
+ float :base_price
70
+ end
71
+ integer :quantity
72
+ end
73
+ end
74
+ end
75
+
76
+ # Deep field access - automatically broadcasts over nested arrays
77
+ value :all_product_names, input.orders.items.product.name
78
+ value :total_values, input.orders.items.product.base_price * input.orders.items.quantity
79
+ end
80
+ ```
81
+
82
+ ## Type Inference
83
+
84
+ The type system automatically infers appropriate types for broadcasted operations:
85
+
86
+ - `input.items.price` (float array) → inferred as `:float` per element
87
+ - `input.items.price * input.items.quantity` → element-wise `:float` result
88
+ - `fn(:sum, input.items.price)` → scalar `:float` result
89
+
90
+ ## Implementation Details
91
+
92
+ ### Parser Layer
93
+ - **InputFieldProxy** - Handles `input.field.subfield...` with path building
94
+ - **InputElementReference** - AST node representing array field access paths
95
+
96
+ ### Analysis Layer
97
+ - **BroadcastDetector** - Identifies vectorized vs scalar operations
98
+ - **TypeInferencer** - Infers types for array element access patterns
99
+
100
+ ### Compilation Layer
101
+ - **Automatic Dispatch** - Maps element-wise operations to array map functions
102
+ - **Reduction Detection** - Converts aggregation functions to array reduce operations
103
+
104
+ ## Usage Patterns
105
+
106
+ ### Element-wise Operations
107
+ ```ruby
108
+ # All of these broadcast element-wise
109
+ value :discounted_prices, input.items.price * 0.9
110
+ trait :expensive, (input.items.price > 100.0)
111
+ value :categories, input.items.category
112
+ ```
113
+
114
+ ### Aggregation Operations
115
+ ```ruby
116
+ # These consume arrays to produce scalars
117
+ value :item_count, fn(:size, input.items)
118
+ value :total_price, fn(:sum, input.items.price)
119
+ value :has_expensive, fn(:any?, expensive)
120
+ ```
121
+
122
+ ### Mixed Operations
123
+ ```ruby
124
+ # Element-wise computation followed by aggregation
125
+ value :line_totals, input.items.price * input.items.quantity
126
+ value :order_total, fn(:sum, line_totals)
127
+ value :avg_line_total, fn(:avg, line_totals)
128
+ ```
129
+
130
+ ## Error Handling
131
+
132
+ ### Dimension Mismatch Detection
133
+
134
+ Array broadcasting operations are only valid within the same array source. Attempting to broadcast across different arrays generates detailed error messages:
135
+
136
+ ```ruby
137
+ schema do
138
+ input do
139
+ array :items do
140
+ string :name
141
+ end
142
+ array :logs do
143
+ string :user_name
144
+ end
145
+ end
146
+
147
+ # This will generate a dimension mismatch error
148
+ trait :same_name, input.items.name == input.logs.user_name
149
+ end
150
+
151
+ # Error:
152
+ # Cannot broadcast operation across arrays from different sources: items, logs.
153
+ # Problem: Multiple operands are arrays from different sources:
154
+ # - Operand 1 resolves to array(string) from array 'items'
155
+ # - Operand 2 resolves to array(string) from array 'logs'
156
+ # Direct operations on arrays from different sources is ambiguous and not supported.
157
+ # Vectorized operations can only work on fields from the same array input.
158
+ ```
159
+
160
+ The error messages provide:
161
+ - **Quick Summary**: Identifies the conflicting array sources
162
+ - **Type Information**: Shows the resolved types of each operand
163
+ - **Clear Explanation**: Why the operation is ambiguous and not supported
164
+
165
+ ## Performance Characteristics
166
+
167
+ - **Single Pass** - Each array is traversed once per computation chain
168
+ - **Lazy Evaluation** - Operations are composed into efficient pipelines
169
+ - **Memory Efficient** - No intermediate array allocations for simple operations
170
+ - **Type Safe** - Full compile-time type checking for array element operations
@@ -0,0 +1,42 @@
1
+ # Input Declarations
2
+
3
+ Declares expected inputs with types and domain constraints, separating input metadata from business logic.
4
+
5
+ ## Declaration Syntax
6
+
7
+ ```ruby
8
+ schema do
9
+ input do
10
+ string :customer_name
11
+ integer :age, domain: 18..120
12
+ float :balance, domain: 0.0..Float::INFINITY
13
+ boolean :verified
14
+ array :tags, elem: { type: :string }
15
+ hash :metadata, key: { type: :string }, val: { type: :any }
16
+ any :flexible
17
+ end
18
+
19
+ trait :adult, (input.age >= 18)
20
+ value :status, input.verified ? "verified" : "pending"
21
+ end
22
+ ```
23
+
24
+ ## Domain Constraints
25
+
26
+ **Validation occurs at runtime:**
27
+ ```ruby
28
+ schema.from(credit_score: 900) # Domain: 300..850
29
+ # => InputValidationError: Field :credit_score value 900 is outside domain 300..850
30
+ ```
31
+
32
+ **Constraint types:**
33
+ - Range domains: `domain: 18..120`
34
+ - Array domains: `domain: %w[active inactive]`
35
+ - Regex domains: `domain: /^[a-zA-Z]+$/`
36
+
37
+ ## Validation Process
38
+
39
+ - Input data validated against declared field metadata
40
+ - Type validation checks value matches declared type
41
+ - Domain validation checks value satisfies constraints
42
+ - Detailed error messages for violations
@@ -0,0 +1,16 @@
1
+ # Performance
2
+
3
+ TODO: Add benchmark data
4
+
5
+ Processes large schemas with optimized algorithms for analysis, compilation, and execution.
6
+
7
+ ## Execution Model
8
+
9
+ **Compilation:**
10
+ - Each expression compiled to executable lambda
11
+ - Direct function calls for operations
12
+
13
+ **Runtime:**
14
+ - Result caching to avoid recomputation
15
+ - Selective evaluation: only requested keys computed
16
+ - Direct lambda invocation
@@ -0,0 +1,53 @@
1
+ # Broadcasts Metadata
2
+
3
+ Array broadcasting operation analysis for vectorized computations.
4
+
5
+ ## Structure
6
+
7
+ ```ruby
8
+ state[:broadcasts] = {
9
+ array_fields: Hash,
10
+ vectorized_operations: Hash,
11
+ reduction_operations: Hash
12
+ }
13
+ ```
14
+
15
+ ## Array Fields
16
+
17
+ ```ruby
18
+ array_fields: {
19
+ :line_items => {
20
+ element_fields: [:price, :quantity, :name],
21
+ element_types: { price: :float, quantity: :integer, name: :string }
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## Vectorized Operations
27
+
28
+ ```ruby
29
+ vectorized_operations: {
30
+ :item_totals => {
31
+ operation: :multiply,
32
+ vectorized_args: { 0 => true, 1 => true }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ## Reduction Operations
38
+
39
+ ```ruby
40
+ reduction_operations: {
41
+ :total_amount => {
42
+ function: :sum,
43
+ source: :array_field
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## Usage
49
+
50
+ - Compiler optimizations
51
+ - Parallel execution
52
+ - Type inference
53
+ - Performance analysis
@@ -0,0 +1,45 @@
1
+ # Cascades Metadata
2
+
3
+ Cascade mutual exclusion analysis for safe conditional cycles.
4
+
5
+ ## Structure
6
+
7
+ ```ruby
8
+ state[:cascades] = {
9
+ cascade_name => {
10
+ condition_traits: Array,
11
+ condition_count: Integer,
12
+ all_mutually_exclusive: Boolean,
13
+ exclusive_pairs: Integer,
14
+ total_pairs: Integer
15
+ }
16
+ }
17
+ ```
18
+
19
+ ## Example
20
+
21
+ ```ruby
22
+ {
23
+ :tax_rate => {
24
+ condition_traits: [:single, :married],
25
+ condition_count: 2,
26
+ all_mutually_exclusive: true,
27
+ exclusive_pairs: 1,
28
+ total_pairs: 1
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## Fields
34
+
35
+ - `condition_traits`: Trait names used in cascade conditions
36
+ - `all_mutually_exclusive`: Whether all condition pairs are exclusive
37
+ - `exclusive_pairs`: Count of mutually exclusive pairs
38
+ - `total_pairs`: Total possible pairs
39
+
40
+ ## Usage
41
+
42
+ - Cycle safety analysis
43
+ - Topological sorting
44
+ - Optimization detection
45
+ - Dependency validation
@@ -0,0 +1,54 @@
1
+ # Declarations Metadata
2
+
3
+ Processed declaration metadata for all schema declarations (traits and values) with clean, serializable information.
4
+
5
+ ## Access
6
+
7
+ ```ruby
8
+ metadata = MySchema.schema_metadata
9
+ declarations = metadata.declarations
10
+ ```
11
+
12
+ ## Structure
13
+
14
+ ```ruby
15
+ # Returns Hash<Symbol, Hash>
16
+ {
17
+ declaration_name => {
18
+ type: :trait | :value, # Declaration type
19
+ expression: String # Human-readable expression
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## Example
25
+
26
+ ```ruby
27
+ metadata.declarations
28
+ # => {
29
+ # :adult => { type: :trait, expression: ">=(input.age, 18)" },
30
+ # :tax_amount => { type: :value, expression: "multiply(input.income, tax_rate)" },
31
+ # :status => { type: :value, expression: "cascade" }
32
+ # }
33
+ ```
34
+
35
+ ## Raw AST Access
36
+
37
+ For advanced use cases requiring direct AST manipulation:
38
+
39
+ ```ruby
40
+ raw_declarations = metadata.analyzer_state[:declarations]
41
+ # => { :adult => #<TraitDeclaration...>, :tax_amount => #<ValueDeclaration...> }
42
+ ```
43
+
44
+ ## AST Node Types
45
+
46
+ - **TraitDeclaration**: Boolean conditions
47
+ - **ValueDeclaration**: Computed values or cascades
48
+
49
+ ## Usage
50
+
51
+ - Dependency analysis
52
+ - Code generation
53
+ - AST traversal
54
+ - Type inference
@@ -0,0 +1,57 @@
1
+ # Dependencies Metadata
2
+
3
+ Processed dependency information showing relationships between declarations with clean, serializable data.
4
+
5
+ ## Access
6
+
7
+ ```ruby
8
+ metadata = MySchema.schema_metadata
9
+ dependencies = metadata.dependencies
10
+ ```
11
+
12
+ ## Structure
13
+
14
+ ```ruby
15
+ # Returns Hash<Symbol, Array<Hash>>
16
+ {
17
+ declaration_name => [
18
+ {
19
+ to: Symbol, # Target declaration name
20
+ conditional: Boolean, # True if dependency is conditional (cascade branch)
21
+ cascade_owner: Symbol # Optional: cascade that owns this conditional edge
22
+ }
23
+ ]
24
+ }
25
+ ```
26
+
27
+ ## Example
28
+
29
+ ```ruby
30
+ metadata.dependencies
31
+ # => {
32
+ # :tax_amount => [
33
+ # { to: :income, conditional: false },
34
+ # { to: :deductions, conditional: false }
35
+ # ],
36
+ # :status => [
37
+ # { to: :adult, conditional: true, cascade_owner: :status },
38
+ # { to: :verified, conditional: true, cascade_owner: :status }
39
+ # ]
40
+ # }
41
+ ```
42
+
43
+ ## Raw Edge Objects
44
+
45
+ For advanced use cases requiring direct Edge object access:
46
+
47
+ ```ruby
48
+ raw_dependencies = metadata.analyzer_state[:dependencies]
49
+ # => { :tax_amount => [#<Edge to: :income>, #<Edge to: :deductions>] }
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ - Topological sorting
55
+ - Cycle detection
56
+ - Evaluation planning
57
+ - Dependency visualization
@@ -0,0 +1,29 @@
1
+ # Evaluation Order Metadata
2
+
3
+ Topologically sorted order for safe declaration evaluation.
4
+
5
+ ## Structure
6
+
7
+ ```ruby
8
+ state[:evaluation_order] = [:name1, :name2, :name3, ...]
9
+ ```
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ [:income, :deductions, :taxable_income, :tax_rate, :tax_amount, :adult, :status]
15
+ ```
16
+
17
+ ## Properties
18
+
19
+ - Dependencies appear before dependents
20
+ - Handles conditional cycles in cascades
21
+ - Deterministic ordering
22
+ - Leaf nodes typically appear first
23
+
24
+ ## Usage
25
+
26
+ - Compilation order
27
+ - Evaluation sequencing
28
+ - Optimization planning
29
+ - Parallel execution grouping