kumi 0.0.24 → 0.0.26
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/CHANGELOG.md +14 -0
- data/README.md +70 -71
- data/data/functions/agg/boolean.yaml +6 -2
- data/data/functions/agg/numeric.yaml +32 -16
- data/data/functions/agg/string.yaml +4 -3
- data/data/functions/core/arithmetic.yaml +62 -14
- data/data/functions/core/boolean.yaml +12 -6
- data/data/functions/core/comparison.yaml +25 -13
- data/data/functions/core/constructor.yaml +16 -8
- data/data/functions/core/select.yaml +3 -1
- data/data/functions/core/stencil.yaml +14 -5
- data/data/functions/core/string.yaml +9 -4
- data/data/kernels/ruby/agg/numeric.yaml +1 -1
- data/docs/UNSAT_DETECTION.md +83 -0
- data/golden/array_element/expected/nast.txt +1 -1
- data/golden/array_element/expected/schema_ruby.rb +1 -1
- data/golden/array_index/expected/nast.txt +7 -7
- data/golden/array_index/expected/schema_ruby.rb +1 -1
- data/golden/array_operations/expected/nast.txt +2 -2
- data/golden/array_operations/expected/schema_ruby.rb +1 -1
- data/golden/array_operations/expected/snast.txt +3 -3
- data/golden/cascade_logic/expected/lir_02_inlined.txt +8 -8
- data/golden/cascade_logic/expected/schema_ruby.rb +1 -1
- data/golden/cascade_logic/expected/snast.txt +2 -2
- data/golden/chained_fusion/expected/lir_02_inlined.txt +36 -36
- data/golden/chained_fusion/expected/lir_03_cse.txt +23 -23
- data/golden/chained_fusion/expected/lir_04_1_loop_fusion.txt +25 -25
- data/golden/chained_fusion/expected/lir_04_loop_invcm.txt +23 -23
- data/golden/chained_fusion/expected/lir_06_const_prop.txt +23 -23
- data/golden/chained_fusion/expected/nast.txt +2 -2
- data/golden/chained_fusion/expected/schema_javascript.mjs +23 -23
- data/golden/chained_fusion/expected/schema_ruby.rb +28 -28
- data/golden/element_arrays/expected/nast.txt +2 -2
- data/golden/element_arrays/expected/schema_ruby.rb +1 -1
- data/golden/element_arrays/expected/snast.txt +1 -1
- data/golden/empty_and_null_inputs/expected/lir_02_inlined.txt +18 -18
- data/golden/empty_and_null_inputs/expected/lir_03_cse.txt +17 -17
- data/golden/empty_and_null_inputs/expected/lir_04_1_loop_fusion.txt +17 -17
- data/golden/empty_and_null_inputs/expected/lir_04_loop_invcm.txt +17 -17
- data/golden/empty_and_null_inputs/expected/lir_06_const_prop.txt +17 -17
- data/golden/empty_and_null_inputs/expected/nast.txt +3 -3
- data/golden/empty_and_null_inputs/expected/schema_javascript.mjs +13 -13
- data/golden/empty_and_null_inputs/expected/schema_ruby.rb +18 -18
- data/golden/function_overload/expected/ast.txt +29 -0
- data/golden/function_overload/expected/input_plan.txt +4 -0
- data/golden/function_overload/expected/lir_00_unoptimized.txt +18 -0
- data/golden/function_overload/expected/lir_01_hoist_scalar_references.txt +18 -0
- data/golden/function_overload/expected/lir_02_inlined.txt +20 -0
- data/golden/function_overload/expected/lir_03_cse.txt +20 -0
- data/golden/function_overload/expected/lir_04_1_loop_fusion.txt +20 -0
- data/golden/function_overload/expected/lir_04_loop_invcm.txt +20 -0
- data/golden/function_overload/expected/lir_06_const_prop.txt +20 -0
- data/golden/function_overload/expected/nast.txt +22 -0
- data/golden/function_overload/expected/schema_javascript.mjs +12 -0
- data/golden/function_overload/expected/schema_ruby.rb +39 -0
- data/golden/function_overload/expected/snast.txt +22 -0
- data/golden/function_overload/input.json +8 -0
- data/golden/function_overload/schema.kumi +19 -0
- data/golden/game_of_life/expected/lir_00_unoptimized.txt +4 -4
- data/golden/game_of_life/expected/lir_01_hoist_scalar_references.txt +4 -4
- data/golden/game_of_life/expected/lir_02_inlined.txt +1294 -1294
- data/golden/game_of_life/expected/lir_03_cse.txt +403 -399
- data/golden/game_of_life/expected/lir_04_1_loop_fusion.txt +403 -399
- data/golden/game_of_life/expected/lir_04_loop_invcm.txt +403 -399
- data/golden/game_of_life/expected/lir_06_const_prop.txt +403 -399
- data/golden/game_of_life/expected/nast.txt +4 -4
- data/golden/game_of_life/expected/schema_javascript.mjs +87 -85
- data/golden/game_of_life/expected/schema_ruby.rb +88 -86
- data/golden/game_of_life/expected/snast.txt +10 -10
- data/golden/hash_keys/expected/schema_ruby.rb +1 -1
- data/golden/hash_value/expected/nast.txt +1 -1
- data/golden/hash_value/expected/schema_ruby.rb +1 -1
- data/golden/hash_value/expected/snast.txt +1 -1
- data/golden/hierarchical_complex/expected/lir_02_inlined.txt +15 -15
- data/golden/hierarchical_complex/expected/lir_03_cse.txt +1 -1
- data/golden/hierarchical_complex/expected/lir_04_1_loop_fusion.txt +1 -1
- data/golden/hierarchical_complex/expected/lir_04_loop_invcm.txt +1 -1
- data/golden/hierarchical_complex/expected/lir_06_const_prop.txt +1 -1
- data/golden/hierarchical_complex/expected/nast.txt +3 -3
- data/golden/hierarchical_complex/expected/schema_javascript.mjs +1 -1
- data/golden/hierarchical_complex/expected/schema_ruby.rb +2 -2
- data/golden/hierarchical_complex/expected/snast.txt +3 -3
- data/golden/inline_rename_scope_leak/expected/nast.txt +3 -3
- data/golden/inline_rename_scope_leak/expected/schema_ruby.rb +1 -1
- data/golden/input_reference/expected/nast.txt +2 -2
- data/golden/input_reference/expected/schema_ruby.rb +1 -1
- data/golden/interleaved_fusion/expected/lir_02_inlined.txt +35 -35
- data/golden/interleaved_fusion/expected/lir_03_cse.txt +26 -26
- data/golden/interleaved_fusion/expected/lir_04_1_loop_fusion.txt +27 -26
- data/golden/interleaved_fusion/expected/lir_04_loop_invcm.txt +26 -26
- data/golden/interleaved_fusion/expected/lir_06_const_prop.txt +26 -26
- data/golden/interleaved_fusion/expected/nast.txt +2 -2
- data/golden/interleaved_fusion/expected/schema_javascript.mjs +23 -23
- data/golden/interleaved_fusion/expected/schema_ruby.rb +29 -29
- data/golden/let_inline/expected/nast.txt +4 -4
- data/golden/let_inline/expected/schema_ruby.rb +1 -1
- data/golden/loop_fusion/expected/lir_02_inlined.txt +17 -17
- data/golden/loop_fusion/expected/lir_03_cse.txt +14 -14
- data/golden/loop_fusion/expected/lir_04_1_loop_fusion.txt +14 -14
- data/golden/loop_fusion/expected/lir_04_loop_invcm.txt +14 -14
- data/golden/loop_fusion/expected/lir_06_const_prop.txt +14 -14
- data/golden/loop_fusion/expected/nast.txt +1 -1
- data/golden/loop_fusion/expected/schema_javascript.mjs +12 -12
- data/golden/loop_fusion/expected/schema_ruby.rb +16 -16
- data/golden/min_reduce_scope/expected/nast.txt +3 -3
- data/golden/min_reduce_scope/expected/schema_ruby.rb +1 -1
- data/golden/min_reduce_scope/expected/snast.txt +1 -1
- data/golden/mixed_dimensions/expected/lir_02_inlined.txt +5 -5
- data/golden/mixed_dimensions/expected/lir_03_cse.txt +5 -5
- data/golden/mixed_dimensions/expected/lir_04_1_loop_fusion.txt +5 -5
- data/golden/mixed_dimensions/expected/lir_04_loop_invcm.txt +5 -5
- data/golden/mixed_dimensions/expected/lir_06_const_prop.txt +5 -5
- data/golden/mixed_dimensions/expected/nast.txt +2 -2
- data/golden/mixed_dimensions/expected/schema_javascript.mjs +3 -3
- data/golden/mixed_dimensions/expected/schema_ruby.rb +6 -6
- data/golden/multirank_hoisting/expected/lir_02_inlined.txt +48 -48
- data/golden/multirank_hoisting/expected/lir_03_cse.txt +35 -35
- data/golden/multirank_hoisting/expected/lir_04_1_loop_fusion.txt +35 -35
- data/golden/multirank_hoisting/expected/lir_04_loop_invcm.txt +35 -35
- data/golden/multirank_hoisting/expected/lir_06_const_prop.txt +35 -35
- data/golden/multirank_hoisting/expected/nast.txt +7 -7
- data/golden/multirank_hoisting/expected/schema_javascript.mjs +34 -34
- data/golden/multirank_hoisting/expected/schema_ruby.rb +36 -36
- data/golden/nested_hash/expected/nast.txt +1 -1
- data/golden/nested_hash/expected/schema_ruby.rb +1 -1
- data/golden/reduction_broadcast/expected/lir_02_inlined.txt +30 -30
- data/golden/reduction_broadcast/expected/lir_03_cse.txt +22 -22
- data/golden/reduction_broadcast/expected/lir_04_1_loop_fusion.txt +22 -22
- data/golden/reduction_broadcast/expected/lir_04_loop_invcm.txt +22 -22
- data/golden/reduction_broadcast/expected/lir_06_const_prop.txt +22 -22
- data/golden/reduction_broadcast/expected/nast.txt +3 -3
- data/golden/reduction_broadcast/expected/schema_javascript.mjs +18 -18
- data/golden/reduction_broadcast/expected/schema_ruby.rb +23 -23
- data/golden/reduction_broadcast/expected/snast.txt +1 -1
- data/golden/roll/expected/schema_ruby.rb +1 -1
- data/golden/shift/expected/schema_ruby.rb +1 -1
- data/golden/shift_2d/expected/schema_ruby.rb +1 -1
- data/golden/simple_math/expected/lir_00_unoptimized.txt +1 -1
- data/golden/simple_math/expected/lir_01_hoist_scalar_references.txt +1 -1
- data/golden/simple_math/expected/lir_02_inlined.txt +1 -1
- data/golden/simple_math/expected/lir_03_cse.txt +1 -1
- data/golden/simple_math/expected/lir_04_1_loop_fusion.txt +1 -1
- data/golden/simple_math/expected/lir_04_loop_invcm.txt +1 -1
- data/golden/simple_math/expected/lir_06_const_prop.txt +1 -1
- data/golden/simple_math/expected/nast.txt +5 -5
- data/golden/simple_math/expected/schema_ruby.rb +1 -1
- data/golden/simple_math/expected/snast.txt +2 -2
- data/golden/streaming_basics/expected/lir_02_inlined.txt +25 -25
- data/golden/streaming_basics/expected/lir_03_cse.txt +13 -13
- data/golden/streaming_basics/expected/lir_04_1_loop_fusion.txt +13 -13
- data/golden/streaming_basics/expected/lir_04_loop_invcm.txt +13 -13
- data/golden/streaming_basics/expected/lir_06_const_prop.txt +13 -13
- data/golden/streaming_basics/expected/nast.txt +8 -8
- data/golden/streaming_basics/expected/schema_javascript.mjs +13 -13
- data/golden/streaming_basics/expected/schema_ruby.rb +14 -14
- data/golden/streaming_basics/expected/snast.txt +1 -1
- data/golden/tuples/expected/lir_00_unoptimized.txt +5 -5
- data/golden/tuples/expected/lir_01_hoist_scalar_references.txt +5 -5
- data/golden/tuples/expected/lir_02_inlined.txt +5 -5
- data/golden/tuples/expected/lir_03_cse.txt +5 -5
- data/golden/tuples/expected/lir_04_1_loop_fusion.txt +5 -5
- data/golden/tuples/expected/lir_04_loop_invcm.txt +5 -5
- data/golden/tuples/expected/lir_06_const_prop.txt +5 -5
- data/golden/tuples/expected/nast.txt +4 -4
- data/golden/tuples/expected/schema_ruby.rb +1 -1
- data/golden/tuples/expected/snast.txt +6 -6
- data/golden/tuples_and_arrays/expected/lir_00_unoptimized.txt +1 -1
- data/golden/tuples_and_arrays/expected/lir_01_hoist_scalar_references.txt +1 -1
- data/golden/tuples_and_arrays/expected/lir_02_inlined.txt +17 -17
- data/golden/tuples_and_arrays/expected/lir_03_cse.txt +13 -13
- data/golden/tuples_and_arrays/expected/lir_04_1_loop_fusion.txt +13 -13
- data/golden/tuples_and_arrays/expected/lir_04_loop_invcm.txt +13 -13
- data/golden/tuples_and_arrays/expected/lir_06_const_prop.txt +13 -13
- data/golden/tuples_and_arrays/expected/nast.txt +3 -3
- data/golden/tuples_and_arrays/expected/schema_javascript.mjs +13 -13
- data/golden/tuples_and_arrays/expected/schema_ruby.rb +14 -14
- data/golden/tuples_and_arrays/expected/snast.txt +2 -2
- data/golden/us_tax_2024/expected/ast.txt +63 -670
- data/golden/us_tax_2024/expected/input_plan.txt +8 -45
- data/golden/us_tax_2024/expected/lir_00_unoptimized.txt +253 -863
- data/golden/us_tax_2024/expected/lir_01_hoist_scalar_references.txt +253 -863
- data/golden/us_tax_2024/expected/lir_02_inlined.txt +1215 -5139
- data/golden/us_tax_2024/expected/lir_03_cse.txt +587 -2460
- data/golden/us_tax_2024/expected/lir_04_1_loop_fusion.txt +632 -2480
- data/golden/us_tax_2024/expected/lir_04_loop_invcm.txt +587 -2400
- data/golden/us_tax_2024/expected/lir_06_const_prop.txt +587 -2400
- data/golden/us_tax_2024/expected/nast.txt +123 -826
- data/golden/us_tax_2024/expected/schema_javascript.mjs +127 -581
- data/golden/us_tax_2024/expected/schema_ruby.rb +135 -610
- data/golden/us_tax_2024/expected/snast.txt +155 -858
- data/golden/us_tax_2024/expected.json +120 -1
- data/golden/us_tax_2024/input.json +18 -9
- data/golden/us_tax_2024/schema.kumi +48 -178
- data/golden/with_constants/expected/lir_00_unoptimized.txt +1 -1
- data/golden/with_constants/expected/lir_01_hoist_scalar_references.txt +1 -1
- data/golden/with_constants/expected/lir_02_inlined.txt +1 -1
- data/golden/with_constants/expected/lir_03_cse.txt +1 -1
- data/golden/with_constants/expected/lir_04_1_loop_fusion.txt +1 -1
- data/golden/with_constants/expected/lir_04_loop_invcm.txt +1 -1
- data/golden/with_constants/expected/lir_06_const_prop.txt +1 -1
- data/golden/with_constants/expected/nast.txt +2 -2
- data/golden/with_constants/expected/schema_ruby.rb +1 -1
- data/golden/with_constants/expected/snast.txt +2 -2
- data/lib/kumi/analyzer.rb +12 -12
- data/lib/kumi/core/analyzer/passes/formal_constraint_propagator.rb +236 -0
- data/lib/kumi/core/analyzer/passes/input_collector.rb +22 -4
- data/lib/kumi/core/analyzer/passes/lir/inline_declarations_pass.rb +118 -74
- data/lib/kumi/core/analyzer/passes/nast_dimensional_analyzer_pass.rb +64 -18
- data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +9 -4
- data/lib/kumi/core/analyzer/passes/snast_pass.rb +3 -1
- data/lib/kumi/core/analyzer/passes/unsat_detector.rb +172 -198
- data/lib/kumi/core/error_reporter.rb +36 -1
- data/lib/kumi/core/errors.rb +33 -1
- data/lib/kumi/core/functions/function_spec.rb +5 -4
- data/lib/kumi/core/functions/loader.rb +17 -1
- data/lib/kumi/core/functions/overload_resolver.rb +164 -0
- data/lib/kumi/core/functions/type_error_reporter.rb +118 -0
- data/lib/kumi/core/functions/type_rules.rb +155 -35
- data/lib/kumi/core/types/inference.rb +29 -22
- data/lib/kumi/core/types/normalizer.rb +29 -45
- data/lib/kumi/core/types/validator.rb +16 -27
- data/lib/kumi/core/types/value_objects.rb +116 -0
- data/lib/kumi/core/types.rb +45 -37
- data/lib/kumi/registry_v2/loader.rb +90 -0
- data/lib/kumi/registry_v2.rb +18 -1
- data/lib/kumi/version.rb +1 -1
- metadata +21 -7
- data/lib/kumi/core/analyzer/unsat_constant_evaluator.rb +0 -59
- data/lib/kumi/core/atom_unsat_solver.rb +0 -396
- data/lib/kumi/core/constraint_relationship_solver.rb +0 -641
- data/lib/kumi/core/types/builder.rb +0 -23
- data/lib/kumi/core/types/compatibility.rb +0 -96
- data/lib/kumi/core/types/formatter.rb +0 -26
@@ -0,0 +1,83 @@
|
|
1
|
+
# UNSAT Detection & Constraint Analysis
|
2
|
+
|
3
|
+
Kumi includes static analysis to detect **unsatisfiable constraints**—impossible conditions that can never be true given input domains.
|
4
|
+
|
5
|
+
## How It Works
|
6
|
+
|
7
|
+
### Direct Contradictions
|
8
|
+
Kumi detects when the same variable is constrained to multiple different values:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
schema do
|
12
|
+
input { integer :x }
|
13
|
+
|
14
|
+
# ✓ Detected as UNSAT: x cannot be both 5 and 10
|
15
|
+
trait :impossible, fn(:and, input.x == 5, input.x == 10)
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
### Domain Violations
|
20
|
+
Kumi checks when constraints violate input domains:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
schema do
|
24
|
+
input { integer :age, domain: 0..150 }
|
25
|
+
|
26
|
+
# ✓ Detected as UNSAT: age can never be 200
|
27
|
+
trait :impossible_age, input.age == 200
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
### Constraint Propagation (Phase 2)
|
32
|
+
Kumi propagates constraints through operations to detect derived impossibilities:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
schema do
|
36
|
+
input { integer :x, domain: 0..10 }
|
37
|
+
|
38
|
+
value :doubled, fn(:mul, input.x, 2) # doubled ∈ [0, 20]
|
39
|
+
|
40
|
+
# ✓ Detected as UNSAT: doubled can never be 50
|
41
|
+
trait :impossible_doubled, doubled == 50
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
**Reverse propagation** derives input constraints from output constraints:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
schema do
|
49
|
+
input { integer :x, domain: 0..10 }
|
50
|
+
|
51
|
+
value :result, fn(:add, input.x, 100) # result ∈ [100, 110]
|
52
|
+
|
53
|
+
# ✓ Detected as UNSAT: result == 50 would require x == -50 (outside domain)
|
54
|
+
trait :impossible_result, result == 50
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Error Messages
|
59
|
+
|
60
|
+
Impossible constraints raise `Kumi::Core::Errors::SemanticError`:
|
61
|
+
|
62
|
+
```
|
63
|
+
conjunction `impossible_doubled` is impossible
|
64
|
+
```
|
65
|
+
|
66
|
+
This message appears at schema compilation time, catching bugs before execution.
|
67
|
+
|
68
|
+
## When UNSAT Detection Runs
|
69
|
+
|
70
|
+
UNSAT detection is performed during the **HIR-to-LIR compilation phase**, after:
|
71
|
+
- Function IDs are resolved
|
72
|
+
- Type information is inferred
|
73
|
+
- Dimensional metadata is computed
|
74
|
+
|
75
|
+
This ensures detection has access to complete operation semantics.
|
76
|
+
|
77
|
+
## Future Enhancements
|
78
|
+
|
79
|
+
- **Multi-level propagation**: Chain constraints through multiple operations
|
80
|
+
- **Inequality constraints**: Handle `<`, `>`, `<=`, `>=` constraints
|
81
|
+
- **Combined constraints**: Detect contradictions across multiple traits
|
82
|
+
|
83
|
+
See `spec/integration/unsat_with_propagation_spec.rb` for examples and pending tests.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
2
|
-
module Kumi::Compiled::
|
2
|
+
module Kumi::Compiled::KUMI_1cd98cf56c50f763cab5055e1275d07ac58aaee708cbd081d7773ac43c8d9d33
|
3
3
|
def self.from(input_data = nil)
|
4
4
|
instance = Object.new
|
5
5
|
instance.extend(self)
|
@@ -1,12 +1,12 @@
|
|
1
1
|
(NAST
|
2
2
|
(VALUE W
|
3
|
-
(Call :
|
3
|
+
(Call :array_size
|
4
4
|
(InputRef [:x, :y])
|
5
5
|
)
|
6
6
|
)
|
7
7
|
(VALUE box
|
8
|
-
(Call :
|
9
|
-
(Call :
|
8
|
+
(Call :add
|
9
|
+
(Call :multiply
|
10
10
|
#<struct Kumi::Core::NAST::IndexRef id=83, loc=nil, meta={}>
|
11
11
|
(Ref W)
|
12
12
|
)
|
@@ -14,10 +14,10 @@
|
|
14
14
|
)
|
15
15
|
)
|
16
16
|
(VALUE col_major
|
17
|
-
(Call :
|
18
|
-
(Call :
|
17
|
+
(Call :add
|
18
|
+
(Call :multiply
|
19
19
|
#<struct Kumi::Core::NAST::IndexRef id=91, loc=nil, meta={}>
|
20
|
-
(Call :
|
20
|
+
(Call :array_size
|
21
21
|
(InputRef [:x])
|
22
22
|
)
|
23
23
|
)
|
@@ -25,7 +25,7 @@
|
|
25
25
|
)
|
26
26
|
)
|
27
27
|
(VALUE sum_ij
|
28
|
-
(Call :
|
28
|
+
(Call :add
|
29
29
|
#<struct Kumi::Core::NAST::IndexRef id=100, loc=nil, meta={}>
|
30
30
|
#<struct Kumi::Core::NAST::IndexRef id=102, loc=nil, meta={}>
|
31
31
|
)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
2
|
-
module Kumi::Compiled::
|
2
|
+
module Kumi::Compiled::KUMI_f0ed06608ce6a4d5050abd38d6642055bd22c10f7ed1ba5c5b32a1c61c78736d
|
3
3
|
def self.from(input_data = nil)
|
4
4
|
instance = Object.new
|
5
5
|
instance.extend(self)
|
@@ -1,12 +1,12 @@
|
|
1
1
|
(NAST
|
2
2
|
(VALUE subtotals
|
3
|
-
(Call :
|
3
|
+
(Call :multiply
|
4
4
|
(InputRef [:items, :item, :price])
|
5
5
|
(InputRef [:items, :item, :quantity])
|
6
6
|
)
|
7
7
|
)
|
8
8
|
(VALUE discounted_price
|
9
|
-
(Call :
|
9
|
+
(Call :multiply
|
10
10
|
(InputRef [:items, :item, :price])
|
11
11
|
(Const 0.9)
|
12
12
|
)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
2
|
-
module Kumi::Compiled::
|
2
|
+
module Kumi::Compiled::KUMI_98624b0772f11031b22df384c3c7f33db6dd17485e3f9cf2f69c17ad1d79a9d9
|
3
3
|
def self.from(input_data = nil)
|
4
4
|
instance = Object.new
|
5
5
|
instance.extend(self)
|
@@ -11,19 +11,19 @@
|
|
11
11
|
(Const 0.9) :: [] -> float
|
12
12
|
) :: [items] -> float
|
13
13
|
) :: [items] -> float
|
14
|
-
(
|
14
|
+
(VALUE is_valid_quantity
|
15
15
|
(Call :core.gt
|
16
16
|
(InputRef items.item.quantity key_chain=[]) :: [items] -> integer
|
17
17
|
(Const 0) :: [] -> integer
|
18
18
|
) :: [items] -> boolean
|
19
19
|
) :: [items] -> boolean
|
20
|
-
(
|
20
|
+
(VALUE expensive_items
|
21
21
|
(Call :core.gt
|
22
22
|
(InputRef items.item.price key_chain=[]) :: [items] -> float
|
23
23
|
(Const 100.0) :: [] -> float
|
24
24
|
) :: [items] -> boolean
|
25
25
|
) :: [items] -> boolean
|
26
|
-
(
|
26
|
+
(VALUE electronics
|
27
27
|
(Call :core.eq
|
28
28
|
(InputRef items.item.category key_chain=[]) :: [items] -> string
|
29
29
|
(Const "electronics") :: [] -> string
|
@@ -20,17 +20,17 @@
|
|
20
20
|
%t24 = call core.gt(%t22, %t23) :: boolean
|
21
21
|
%t9 = call core.and(%t21, %t24) :: boolean
|
22
22
|
%t10 = const "both positive" :: string
|
23
|
-
%
|
24
|
-
%
|
25
|
-
%
|
23
|
+
%t25 = load_input "x" :: integer
|
24
|
+
%t26 = const 0 :: integer
|
25
|
+
%t27 = call core.gt(%t25, %t26) :: boolean
|
26
26
|
%t12 = const "x positive" :: string
|
27
|
-
%
|
28
|
-
%
|
29
|
-
%
|
27
|
+
%t28 = load_input "y" :: integer
|
28
|
+
%t29 = const 0 :: integer
|
29
|
+
%t30 = call core.gt(%t28, %t29) :: boolean
|
30
30
|
%t14 = const "y positive" :: string
|
31
31
|
%t15 = const "neither positive" :: string
|
32
|
-
%t16 = select %
|
33
|
-
%t17 = select %
|
32
|
+
%t16 = select %t30, %t14, %t15 :: string
|
33
|
+
%t17 = select %t27, %t12, %t16 :: string
|
34
34
|
%t18 = select %t9, %t10, %t17 :: string
|
35
35
|
yield %t18
|
36
36
|
)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Autogenerated by Kumi Codegen
|
2
|
-
module Kumi::Compiled::
|
2
|
+
module Kumi::Compiled::KUMI_a359b484890e040a5fdd419b92800fddad006edffc49f277f28525eef4e3d9bd
|
3
3
|
def self.from(input_data = nil)
|
4
4
|
instance = Object.new
|
5
5
|
instance.extend(self)
|
@@ -1,11 +1,11 @@
|
|
1
1
|
(SNAST
|
2
|
-
(
|
2
|
+
(VALUE y_positive
|
3
3
|
(Call :core.gt
|
4
4
|
(InputRef y key_chain=[]) :: [] -> integer
|
5
5
|
(Const 0) :: [] -> integer
|
6
6
|
) :: [] -> boolean
|
7
7
|
) :: [] -> boolean
|
8
|
-
(
|
8
|
+
(VALUE x_positive
|
9
9
|
(Call :core.gt
|
10
10
|
(InputRef x key_chain=[]) :: [] -> integer
|
11
11
|
(Const 0) :: [] -> integer
|
@@ -68,46 +68,46 @@
|
|
68
68
|
%t56 = load_input "departments" :: array
|
69
69
|
%acc58 = decl_acc :: integer
|
70
70
|
%t59 = load_field departments_el_48["employees"] :: any
|
71
|
-
loop employees id=L10 in %t59 as el=%
|
72
|
-
%
|
73
|
-
%acc58 = acc_add agg.sum(%acc58, %
|
71
|
+
loop employees id=L10 in %t59 as el=%t60, idx=%t61
|
72
|
+
%t62 = load_field t60["salary"] :: integer
|
73
|
+
%acc58 = acc_add agg.sum(%acc58, %t62) :: integer
|
74
74
|
end_loop
|
75
|
-
%
|
76
|
-
%
|
77
|
-
%
|
78
|
-
%
|
79
|
-
loop employees id=L11 in %
|
80
|
-
%
|
81
|
-
%
|
82
|
-
%
|
83
|
-
%
|
84
|
-
%
|
85
|
-
%
|
86
|
-
%
|
75
|
+
%t63 = acc_load %acc58 :: integer
|
76
|
+
%t64 = load_input "departments" :: array
|
77
|
+
%acc66 = decl_acc :: integer
|
78
|
+
%t67 = load_field departments_el_48["employees"] :: any
|
79
|
+
loop employees id=L11 in %t67 as el=%t68, idx=%t69
|
80
|
+
%t70 = load_field t68["role"] :: string
|
81
|
+
%t71 = const "manager" :: string
|
82
|
+
%t72 = call core.eq(%t70, %t71) :: boolean
|
83
|
+
%t73 = const 1 :: integer
|
84
|
+
%t74 = const 0 :: integer
|
85
|
+
%t75 = select %t72, %t73, %t74 :: integer
|
86
|
+
%acc66 = acc_add agg.sum(%acc66, %t75) :: integer
|
87
87
|
end_loop
|
88
|
-
%
|
89
|
-
%
|
90
|
-
%
|
91
|
-
%
|
92
|
-
loop employees id=L12 in %
|
93
|
-
%
|
94
|
-
%
|
95
|
-
%
|
96
|
-
%
|
97
|
-
%
|
98
|
-
%
|
99
|
-
%
|
88
|
+
%t76 = acc_load %acc66 :: integer
|
89
|
+
%t77 = load_input "departments" :: array
|
90
|
+
%acc79 = decl_acc :: integer
|
91
|
+
%t80 = load_field departments_el_48["employees"] :: any
|
92
|
+
loop employees id=L12 in %t80 as el=%t81, idx=%t82
|
93
|
+
%t83 = load_field t81["role"] :: string
|
94
|
+
%t84 = const "senior" :: string
|
95
|
+
%t85 = call core.eq(%t83, %t84) :: boolean
|
96
|
+
%t86 = const 1 :: integer
|
97
|
+
%t87 = const 0 :: integer
|
98
|
+
%t88 = select %t85, %t86, %t87 :: integer
|
99
|
+
%acc79 = acc_add agg.sum(%acc79, %t88) :: integer
|
100
100
|
end_loop
|
101
|
-
%
|
102
|
-
%
|
103
|
-
%
|
104
|
-
%
|
105
|
-
loop employees id=L13 in %
|
106
|
-
%
|
107
|
-
%
|
101
|
+
%t89 = acc_load %acc79 :: integer
|
102
|
+
%t90 = load_input "departments" :: array
|
103
|
+
%acc92 = decl_acc :: integer
|
104
|
+
%t93 = load_field departments_el_48["employees"] :: any
|
105
|
+
loop employees id=L13 in %t93 as el=%t94, idx=%t95
|
106
|
+
%t96 = load_field t94["salary"] :: integer
|
107
|
+
%acc92 = acc_add agg.max(%acc92, %t96) :: integer
|
108
108
|
end_loop
|
109
|
-
%
|
110
|
-
%t55 = make_object{name: %t50, total_payroll: %
|
109
|
+
%t97 = acc_load %acc92 :: integer
|
110
|
+
%t55 = make_object{name: %t50, total_payroll: %t63, manager_count: %t76, senior_count: %t89, top_salary: %t97} :: object
|
111
111
|
yield %t55
|
112
112
|
end_loop
|
113
113
|
)
|
@@ -67,30 +67,30 @@
|
|
67
67
|
%t50 = load_field departments_el_48["name"] :: string
|
68
68
|
%acc58 = decl_acc :: integer
|
69
69
|
%t59 = load_field departments_el_48["employees"] :: any
|
70
|
-
%
|
71
|
-
%
|
72
|
-
%
|
73
|
-
loop employees id=L10 in %t59 as el=%
|
74
|
-
%
|
75
|
-
%acc58 = acc_add agg.sum(%acc58, %
|
76
|
-
%
|
77
|
-
%
|
78
|
-
%
|
79
|
-
%
|
80
|
-
%
|
81
|
-
%
|
82
|
-
%
|
83
|
-
%
|
84
|
-
%
|
85
|
-
%
|
86
|
-
%
|
87
|
-
%
|
70
|
+
%acc66 = decl_acc :: integer
|
71
|
+
%acc79 = decl_acc :: integer
|
72
|
+
%acc92 = decl_acc :: integer
|
73
|
+
loop employees id=L10 in %t59 as el=%t60, idx=%t61
|
74
|
+
%t62 = load_field t60["salary"] :: integer
|
75
|
+
%acc58 = acc_add agg.sum(%acc58, %t62) :: integer
|
76
|
+
%t70 = load_field t60["role"] :: string
|
77
|
+
%t71 = const "manager" :: string
|
78
|
+
%t72 = call core.eq(%t70, %t71) :: boolean
|
79
|
+
%t73 = const 1 :: integer
|
80
|
+
%t74 = const 0 :: integer
|
81
|
+
%t75 = select %t72, %t73, %t74 :: integer
|
82
|
+
%acc66 = acc_add agg.sum(%acc66, %t75) :: integer
|
83
|
+
%acc92 = acc_add agg.max(%acc92, %t62) :: integer
|
84
|
+
%t84 = const "senior" :: string
|
85
|
+
%t85 = call core.eq(%t70, %t84) :: boolean
|
86
|
+
%t88 = select %t85, %t73, %t74 :: integer
|
87
|
+
%acc79 = acc_add agg.sum(%acc79, %t88) :: integer
|
88
88
|
end_loop
|
89
|
-
%
|
90
|
-
%
|
91
|
-
%
|
92
|
-
%
|
93
|
-
%t55 = make_object{name: %t50, total_payroll: %
|
89
|
+
%t63 = acc_load %acc58 :: integer
|
90
|
+
%t76 = acc_load %acc66 :: integer
|
91
|
+
%t97 = acc_load %acc92 :: integer
|
92
|
+
%t89 = acc_load %acc79 :: integer
|
93
|
+
%t55 = make_object{name: %t50, total_payroll: %t63, manager_count: %t76, senior_count: %t89, top_salary: %t97} :: object
|
94
94
|
yield %t55
|
95
95
|
end_loop
|
96
96
|
)
|
@@ -67,32 +67,32 @@
|
|
67
67
|
%t50 = load_field departments_el_48["name"] :: string
|
68
68
|
%acc58 = decl_acc :: integer
|
69
69
|
%t59 = load_field departments_el_48["employees"] :: any
|
70
|
-
%
|
71
|
-
%
|
72
|
-
%
|
73
|
-
loop employees id=L10 in %t59 as el=%
|
74
|
-
%
|
75
|
-
%acc58 = acc_add agg.sum(%acc58, %
|
76
|
-
%
|
77
|
-
%
|
78
|
-
%
|
79
|
-
%
|
80
|
-
%
|
81
|
-
%
|
82
|
-
%
|
83
|
-
%
|
84
|
-
%
|
85
|
-
%
|
86
|
-
%
|
87
|
-
%
|
88
|
-
%
|
89
|
-
%
|
70
|
+
%acc66 = decl_acc :: integer
|
71
|
+
%acc79 = decl_acc :: integer
|
72
|
+
%acc92 = decl_acc :: integer
|
73
|
+
loop employees id=L10 in %t59 as el=%t60, idx=%t61
|
74
|
+
%t62 = load_field t60["salary"] :: integer
|
75
|
+
%acc58 = acc_add agg.sum(%acc58, %t62) :: integer
|
76
|
+
%t70 = load_field t60["role"] :: string
|
77
|
+
%t71 = const "manager" :: string
|
78
|
+
%t72 = call core.eq(%t70, %t71) :: boolean
|
79
|
+
%t73 = const 1 :: integer
|
80
|
+
%t74 = const 0 :: integer
|
81
|
+
%t75 = select %t72, %t73, %t74 :: integer
|
82
|
+
%acc66 = acc_add agg.sum(%acc66, %t75) :: integer
|
83
|
+
%t96 = load_field t60["salary"] :: integer
|
84
|
+
%acc92 = acc_add agg.max(%acc92, %t96) :: integer
|
85
|
+
%t83 = load_field t60["role"] :: string
|
86
|
+
%t84 = const "senior" :: string
|
87
|
+
%t85 = call core.eq(%t83, %t84) :: boolean
|
88
|
+
%t88 = select %t85, %t73, %t74 :: integer
|
89
|
+
%acc79 = acc_add agg.sum(%acc79, %t88) :: integer
|
90
90
|
end_loop
|
91
|
-
%
|
92
|
-
%
|
93
|
-
%
|
94
|
-
%
|
95
|
-
%t55 = make_object{name: %t50, total_payroll: %
|
91
|
+
%t63 = acc_load %acc58 :: integer
|
92
|
+
%t76 = acc_load %acc66 :: integer
|
93
|
+
%t97 = acc_load %acc92 :: integer
|
94
|
+
%t89 = acc_load %acc79 :: integer
|
95
|
+
%t55 = make_object{name: %t50, total_payroll: %t63, manager_count: %t76, senior_count: %t89, top_salary: %t97} :: object
|
96
96
|
yield %t55
|
97
97
|
end_loop
|
98
98
|
)
|
@@ -63,34 +63,34 @@
|
|
63
63
|
)
|
64
64
|
(Declaration department_summary
|
65
65
|
%t47 = load_input "departments" :: array
|
66
|
-
%
|
67
|
-
%
|
68
|
-
%
|
69
|
-
%
|
66
|
+
%t71 = const "manager" :: string
|
67
|
+
%t73 = const 1 :: integer
|
68
|
+
%t74 = const 0 :: integer
|
69
|
+
%t84 = const "senior" :: string
|
70
70
|
loop departments id=L9 in %t47 as el=%departments_el_48, idx=%departments_i_49
|
71
71
|
%t50 = load_field departments_el_48["name"] :: string
|
72
72
|
%acc58 = decl_acc :: integer
|
73
73
|
%t59 = load_field departments_el_48["employees"] :: any
|
74
|
-
%
|
75
|
-
%
|
76
|
-
%
|
77
|
-
loop employees id=L10 in %t59 as el=%
|
78
|
-
%
|
79
|
-
%acc58 = acc_add agg.sum(%acc58, %
|
80
|
-
%
|
81
|
-
%
|
82
|
-
%
|
83
|
-
%
|
84
|
-
%
|
85
|
-
%
|
86
|
-
%
|
87
|
-
%
|
74
|
+
%acc66 = decl_acc :: integer
|
75
|
+
%acc79 = decl_acc :: integer
|
76
|
+
%acc92 = decl_acc :: integer
|
77
|
+
loop employees id=L10 in %t59 as el=%t60, idx=%t61
|
78
|
+
%t62 = load_field t60["salary"] :: integer
|
79
|
+
%acc58 = acc_add agg.sum(%acc58, %t62) :: integer
|
80
|
+
%t70 = load_field t60["role"] :: string
|
81
|
+
%t72 = call core.eq(%t70, %t71) :: boolean
|
82
|
+
%t75 = select %t72, %t73, %t74 :: integer
|
83
|
+
%acc66 = acc_add agg.sum(%acc66, %t75) :: integer
|
84
|
+
%acc92 = acc_add agg.max(%acc92, %t62) :: integer
|
85
|
+
%t85 = call core.eq(%t70, %t84) :: boolean
|
86
|
+
%t88 = select %t85, %t73, %t74 :: integer
|
87
|
+
%acc79 = acc_add agg.sum(%acc79, %t88) :: integer
|
88
88
|
end_loop
|
89
|
-
%
|
90
|
-
%
|
91
|
-
%
|
92
|
-
%
|
93
|
-
%t55 = make_object{name: %t50, total_payroll: %
|
89
|
+
%t63 = acc_load %acc58 :: integer
|
90
|
+
%t76 = acc_load %acc66 :: integer
|
91
|
+
%t97 = acc_load %acc92 :: integer
|
92
|
+
%t89 = acc_load %acc79 :: integer
|
93
|
+
%t55 = make_object{name: %t50, total_payroll: %t63, manager_count: %t76, senior_count: %t89, top_salary: %t97} :: object
|
94
94
|
yield %t55
|
95
95
|
end_loop
|
96
96
|
)
|
@@ -63,34 +63,34 @@
|
|
63
63
|
)
|
64
64
|
(Declaration department_summary
|
65
65
|
%t47 = load_input "departments" :: array
|
66
|
-
%
|
67
|
-
%
|
68
|
-
%
|
69
|
-
%
|
66
|
+
%t71 = const "manager" :: string
|
67
|
+
%t73 = const 1 :: integer
|
68
|
+
%t74 = const 0 :: integer
|
69
|
+
%t84 = const "senior" :: string
|
70
70
|
loop departments id=L9 in %t47 as el=%departments_el_48, idx=%departments_i_49
|
71
71
|
%t50 = load_field departments_el_48["name"] :: string
|
72
72
|
%acc58 = decl_acc :: integer
|
73
73
|
%t59 = load_field departments_el_48["employees"] :: any
|
74
|
-
%
|
75
|
-
%
|
76
|
-
%
|
77
|
-
loop employees id=L10 in %t59 as el=%
|
78
|
-
%
|
79
|
-
%acc58 = acc_add agg.sum(%acc58, %
|
80
|
-
%
|
81
|
-
%
|
82
|
-
%
|
83
|
-
%
|
84
|
-
%
|
85
|
-
%
|
86
|
-
%
|
87
|
-
%
|
74
|
+
%acc66 = decl_acc :: integer
|
75
|
+
%acc79 = decl_acc :: integer
|
76
|
+
%acc92 = decl_acc :: integer
|
77
|
+
loop employees id=L10 in %t59 as el=%t60, idx=%t61
|
78
|
+
%t62 = load_field t60["salary"] :: integer
|
79
|
+
%acc58 = acc_add agg.sum(%acc58, %t62) :: integer
|
80
|
+
%t70 = load_field t60["role"] :: string
|
81
|
+
%t72 = call core.eq(%t70, %t71) :: boolean
|
82
|
+
%t75 = select %t72, %t73, %t74 :: integer
|
83
|
+
%acc66 = acc_add agg.sum(%acc66, %t75) :: integer
|
84
|
+
%acc92 = acc_add agg.max(%acc92, %t62) :: integer
|
85
|
+
%t85 = call core.eq(%t70, %t84) :: boolean
|
86
|
+
%t88 = select %t85, %t73, %t74 :: integer
|
87
|
+
%acc79 = acc_add agg.sum(%acc79, %t88) :: integer
|
88
88
|
end_loop
|
89
|
-
%
|
90
|
-
%
|
91
|
-
%
|
92
|
-
%
|
93
|
-
%t55 = make_object{name: %t50, total_payroll: %
|
89
|
+
%t63 = acc_load %acc58 :: integer
|
90
|
+
%t76 = acc_load %acc66 :: integer
|
91
|
+
%t97 = acc_load %acc92 :: integer
|
92
|
+
%t89 = acc_load %acc79 :: integer
|
93
|
+
%t55 = make_object{name: %t50, total_payroll: %t63, manager_count: %t76, senior_count: %t89, top_salary: %t97} :: object
|
94
94
|
yield %t55
|
95
95
|
end_loop
|
96
96
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
(NAST
|
2
2
|
(VALUE total_payroll
|
3
|
-
(Call :
|
3
|
+
(Call :sum
|
4
4
|
(InputRef [:departments, :dept, :employees, :emp, :salary])
|
5
5
|
)
|
6
6
|
)
|
@@ -29,7 +29,7 @@
|
|
29
29
|
)
|
30
30
|
)
|
31
31
|
(VALUE max_salary
|
32
|
-
(Call :
|
32
|
+
(Call :max
|
33
33
|
(InputRef [:departments, :dept, :employees, :emp, :salary])
|
34
34
|
)
|
35
35
|
)
|
@@ -75,39 +75,39 @@ export function _max_salary(input) {
|
|
75
75
|
export function _department_summary(input) {
|
76
76
|
let out = [];
|
77
77
|
let t47 = input["departments"];
|
78
|
-
const
|
79
|
-
const
|
80
|
-
const
|
81
|
-
const
|
78
|
+
const t71 = "manager";
|
79
|
+
const t73 = 1;
|
80
|
+
const t74 = 0;
|
81
|
+
const t84 = "senior";
|
82
82
|
t47.forEach((departments_el_48, departments_i_49) => {
|
83
83
|
let t50 = departments_el_48["name"];
|
84
84
|
let acc58 = 0;
|
85
85
|
let t59 = departments_el_48["employees"];
|
86
|
-
let
|
87
|
-
let
|
88
|
-
let
|
89
|
-
t59.forEach((
|
90
|
-
let
|
91
|
-
acc58 +=
|
92
|
-
let
|
93
|
-
let
|
94
|
-
let
|
95
|
-
|
96
|
-
if (
|
97
|
-
|
86
|
+
let acc66 = 0;
|
87
|
+
let acc79 = 0;
|
88
|
+
let acc92 = null;
|
89
|
+
t59.forEach((t60, t61) => {
|
90
|
+
let t62 = t60["salary"];
|
91
|
+
acc58 += t62;
|
92
|
+
let t70 = t60["role"];
|
93
|
+
let t72 = t70 == t71;
|
94
|
+
let t75 = t72 ? t73 : t74;
|
95
|
+
acc66 += t75;
|
96
|
+
if (acc92 === null || acc92 === undefined) {
|
97
|
+
acc92 = t62;
|
98
98
|
} else {
|
99
|
-
|
99
|
+
acc92 = (acc92 === null || t62 > acc92) ? t62 : acc92;
|
100
100
|
}
|
101
|
-
let
|
102
|
-
let
|
103
|
-
|
101
|
+
let t85 = t70 == t84;
|
102
|
+
let t88 = t85 ? t73 : t74;
|
103
|
+
acc79 += t88;
|
104
104
|
});
|
105
105
|
let t55 = {
|
106
106
|
"name": t50,
|
107
107
|
"total_payroll": acc58,
|
108
|
-
"manager_count":
|
109
|
-
"senior_count":
|
110
|
-
"top_salary":
|
108
|
+
"manager_count": acc66,
|
109
|
+
"senior_count": acc79,
|
110
|
+
"top_salary": acc92
|
111
111
|
};
|
112
112
|
out.push(t55);
|
113
113
|
});
|