kumi 0.0.18 → 0.0.19

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 (676) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +25 -0
  5. data/CLAUDE.md +26 -139
  6. data/README.md +143 -372
  7. data/data/functions/agg/boolean.yaml +14 -0
  8. data/data/functions/agg/numeric.yaml +80 -0
  9. data/data/functions/agg/string.yaml +8 -0
  10. data/data/functions/core/arithmetic.yaml +50 -0
  11. data/data/functions/core/boolean.yaml +18 -0
  12. data/data/functions/core/comparison.yaml +42 -0
  13. data/data/functions/core/constructor.yaml +32 -0
  14. data/data/functions/core/select.yaml +7 -0
  15. data/data/functions/core/stencil.yaml +21 -0
  16. data/data/functions/core/string.yaml +19 -0
  17. data/data/kernels/javascript/agg/boolean.yaml +12 -0
  18. data/data/kernels/javascript/agg/numeric.yaml +27 -0
  19. data/data/kernels/javascript/agg/string.yaml +5 -0
  20. data/data/kernels/javascript/core/arithmetic.yaml +32 -0
  21. data/data/kernels/javascript/core/boolean.yaml +12 -0
  22. data/data/kernels/javascript/core/comparison.yaml +24 -0
  23. data/data/kernels/javascript/core/constructor.yaml +15 -0
  24. data/data/kernels/javascript/core/select.yaml +7 -0
  25. data/data/kernels/javascript/core/string.yaml +12 -0
  26. data/data/kernels/ruby/agg/boolean.yaml +18 -0
  27. data/data/kernels/ruby/agg/numeric.yaml +29 -0
  28. data/data/kernels/ruby/agg/string.yaml +5 -0
  29. data/data/kernels/ruby/core/arithmetic.yaml +38 -0
  30. data/data/kernels/ruby/core/boolean.yaml +15 -0
  31. data/data/kernels/ruby/core/comparison.yaml +30 -0
  32. data/data/kernels/ruby/core/constructor.yaml +17 -0
  33. data/data/kernels/ruby/core/select.yaml +4 -0
  34. data/data/kernels/ruby/core/string.yaml +15 -0
  35. data/debug_ordering.rb +52 -0
  36. data/docs/FORM_SCHEMA.md +85 -0
  37. data/docs/OUTPUT_SCHEMA.md +69 -0
  38. data/docs/SYNTAX.md +626 -373
  39. data/golden/array_element/expected/ast.txt +21 -0
  40. data/golden/array_element/expected/input_plan.txt +5 -0
  41. data/golden/array_element/expected/lir_00_unoptimized.txt +13 -0
  42. data/golden/array_element/expected/lir_01_hoist_scalar_references.txt +13 -0
  43. data/golden/array_element/expected/lir_02_inlined.txt +13 -0
  44. data/golden/array_element/expected/lir_03_cse.txt +13 -0
  45. data/golden/array_element/expected/lir_04_1_loop_fusion.txt +13 -0
  46. data/golden/array_element/expected/lir_04_loop_invcm.txt +13 -0
  47. data/golden/array_element/expected/lir_06_const_prop.txt +13 -0
  48. data/golden/array_element/expected/nast.txt +7 -0
  49. data/golden/array_element/expected/schema_javascript.mjs +13 -0
  50. data/golden/array_element/expected/schema_ruby.rb +41 -0
  51. data/golden/array_element/expected/snast.txt +7 -0
  52. data/golden/array_element/expected.json +5 -0
  53. data/golden/array_element/input.json +9 -0
  54. data/golden/array_element/schema.kumi +11 -0
  55. data/golden/array_index/expected/ast.txt +59 -0
  56. data/golden/array_index/expected/input_plan.txt +5 -0
  57. data/golden/array_index/expected/lir_00_unoptimized.txt +41 -0
  58. data/golden/array_index/expected/lir_01_hoist_scalar_references.txt +41 -0
  59. data/golden/array_index/expected/lir_02_inlined.txt +42 -0
  60. data/golden/array_index/expected/lir_03_cse.txt +40 -0
  61. data/golden/array_index/expected/lir_04_1_loop_fusion.txt +40 -0
  62. data/golden/array_index/expected/lir_04_loop_invcm.txt +40 -0
  63. data/golden/array_index/expected/lir_06_const_prop.txt +40 -0
  64. data/golden/array_index/expected/nast.txt +33 -0
  65. data/golden/array_index/expected/schema_javascript.mjs +46 -0
  66. data/golden/array_index/expected/schema_ruby.rb +75 -0
  67. data/golden/array_index/expected/snast.txt +33 -0
  68. data/golden/array_index/expected.json +5 -0
  69. data/golden/array_index/input.json +1 -0
  70. data/golden/array_index/schema.kumi +19 -0
  71. data/golden/array_operations/expected/ast.txt +50 -0
  72. data/golden/array_operations/expected/input_plan.txt +10 -0
  73. data/golden/array_operations/expected/lir_00_unoptimized.txt +47 -0
  74. data/golden/array_operations/expected/lir_01_hoist_scalar_references.txt +47 -0
  75. data/golden/array_operations/expected/lir_02_inlined.txt +47 -0
  76. data/golden/array_operations/expected/lir_03_cse.txt +47 -0
  77. data/golden/array_operations/expected/lir_04_1_loop_fusion.txt +47 -0
  78. data/golden/array_operations/expected/lir_04_loop_invcm.txt +47 -0
  79. data/golden/array_operations/expected/lir_06_const_prop.txt +47 -0
  80. data/golden/array_operations/expected/nast.txt +32 -0
  81. data/golden/array_operations/expected/schema_javascript.mjs +60 -0
  82. data/golden/array_operations/expected/schema_ruby.rb +91 -0
  83. data/golden/array_operations/expected/snast.txt +32 -0
  84. data/golden/array_operations/expected.json +27 -0
  85. data/golden/array_operations/input.json +8 -0
  86. data/golden/array_operations/schema.kumi +12 -10
  87. data/golden/cascade_logic/expected/ast.txt +37 -0
  88. data/golden/cascade_logic/expected/input_plan.txt +2 -0
  89. data/golden/cascade_logic/expected/lir_00_unoptimized.txt +29 -0
  90. data/golden/cascade_logic/expected/lir_01_hoist_scalar_references.txt +29 -0
  91. data/golden/cascade_logic/expected/lir_02_inlined.txt +37 -0
  92. data/golden/cascade_logic/expected/lir_03_cse.txt +30 -0
  93. data/golden/cascade_logic/expected/lir_04_1_loop_fusion.txt +30 -0
  94. data/golden/cascade_logic/expected/lir_04_loop_invcm.txt +30 -0
  95. data/golden/cascade_logic/expected/lir_06_const_prop.txt +30 -0
  96. data/golden/cascade_logic/expected/nast.txt +32 -0
  97. data/golden/cascade_logic/expected/schema_javascript.mjs +31 -0
  98. data/golden/cascade_logic/expected/schema_ruby.rb +57 -0
  99. data/golden/cascade_logic/expected/snast.txt +32 -0
  100. data/golden/cascade_logic/expected.json +5 -0
  101. data/golden/cascade_logic/input.json +4 -0
  102. data/golden/cascade_logic/schema.kumi +1 -3
  103. data/golden/chained_fusion/expected/ast.txt +57 -0
  104. data/golden/chained_fusion/expected/input_plan.txt +13 -0
  105. data/golden/chained_fusion/expected/lir_00_unoptimized.txt +76 -0
  106. data/golden/chained_fusion/expected/lir_01_hoist_scalar_references.txt +76 -0
  107. data/golden/chained_fusion/expected/lir_02_inlined.txt +114 -0
  108. data/golden/chained_fusion/expected/lir_03_cse.txt +97 -0
  109. data/golden/chained_fusion/expected/lir_04_1_loop_fusion.txt +99 -0
  110. data/golden/chained_fusion/expected/lir_04_loop_invcm.txt +97 -0
  111. data/golden/chained_fusion/expected/lir_06_const_prop.txt +97 -0
  112. data/golden/chained_fusion/expected/nast.txt +55 -0
  113. data/golden/chained_fusion/expected/schema_javascript.mjs +116 -0
  114. data/golden/chained_fusion/expected/schema_ruby.rb +149 -0
  115. data/golden/chained_fusion/expected/snast.txt +55 -0
  116. data/golden/chained_fusion/expected.json +45 -0
  117. data/golden/chained_fusion/input.json +51 -0
  118. data/golden/chained_fusion/schema.kumi +52 -0
  119. data/golden/element_arrays/expected/ast.txt +55 -0
  120. data/golden/element_arrays/expected/input_plan.txt +7 -0
  121. data/golden/element_arrays/expected/lir_00_unoptimized.txt +81 -0
  122. data/golden/element_arrays/expected/lir_01_hoist_scalar_references.txt +81 -0
  123. data/golden/element_arrays/expected/lir_02_inlined.txt +85 -0
  124. data/golden/element_arrays/expected/lir_03_cse.txt +83 -0
  125. data/golden/element_arrays/expected/lir_04_1_loop_fusion.txt +83 -0
  126. data/golden/element_arrays/expected/lir_04_loop_invcm.txt +83 -0
  127. data/golden/element_arrays/expected/lir_06_const_prop.txt +83 -0
  128. data/golden/element_arrays/expected/nast.txt +42 -0
  129. data/golden/element_arrays/expected/schema_javascript.mjs +106 -0
  130. data/golden/element_arrays/expected/schema_ruby.rb +141 -0
  131. data/golden/element_arrays/expected/snast.txt +42 -0
  132. data/golden/element_arrays/expected.json +55 -0
  133. data/golden/element_arrays/input.json +12 -0
  134. data/golden/element_arrays/schema.kumi +21 -0
  135. data/golden/empty_and_null_inputs/expected/ast.txt +42 -0
  136. data/golden/empty_and_null_inputs/expected/input_plan.txt +12 -0
  137. data/golden/empty_and_null_inputs/expected/lir_00_unoptimized.txt +31 -0
  138. data/golden/empty_and_null_inputs/expected/lir_01_hoist_scalar_references.txt +31 -0
  139. data/golden/empty_and_null_inputs/expected/lir_02_inlined.txt +51 -0
  140. data/golden/empty_and_null_inputs/expected/lir_03_cse.txt +49 -0
  141. data/golden/empty_and_null_inputs/expected/lir_04_1_loop_fusion.txt +49 -0
  142. data/golden/empty_and_null_inputs/expected/lir_04_loop_invcm.txt +49 -0
  143. data/golden/empty_and_null_inputs/expected/lir_06_const_prop.txt +49 -0
  144. data/golden/empty_and_null_inputs/expected/nast.txt +18 -0
  145. data/golden/empty_and_null_inputs/expected/schema_javascript.mjs +47 -0
  146. data/golden/empty_and_null_inputs/expected/schema_ruby.rb +79 -0
  147. data/golden/empty_and_null_inputs/expected/snast.txt +18 -0
  148. data/golden/empty_and_null_inputs/expected.json +8 -0
  149. data/golden/empty_and_null_inputs/input.json +16 -0
  150. data/golden/empty_and_null_inputs/schema.kumi +30 -0
  151. data/golden/game_of_life/expected/ast.txt +118 -0
  152. data/golden/game_of_life/expected/input_plan.txt +5 -0
  153. data/golden/game_of_life/expected/lir_00_unoptimized.txt +343 -0
  154. data/golden/game_of_life/expected/lir_01_hoist_scalar_references.txt +343 -0
  155. data/golden/game_of_life/expected/lir_02_inlined.txt +1918 -0
  156. data/golden/game_of_life/expected/lir_03_cse.txt +766 -0
  157. data/golden/game_of_life/expected/lir_04_1_loop_fusion.txt +766 -0
  158. data/golden/game_of_life/expected/lir_04_loop_invcm.txt +766 -0
  159. data/golden/game_of_life/expected/lir_06_const_prop.txt +766 -0
  160. data/golden/game_of_life/expected/nast.txt +104 -0
  161. data/golden/game_of_life/expected/schema_javascript.mjs +98 -0
  162. data/golden/game_of_life/expected/schema_ruby.rb +125 -0
  163. data/golden/game_of_life/expected/snast.txt +104 -0
  164. data/golden/game_of_life/expected.json +3 -0
  165. data/golden/game_of_life/input.json +8 -0
  166. data/golden/game_of_life/schema.kumi +33 -0
  167. data/golden/hash_keys/expected/ast.txt +29 -0
  168. data/golden/hash_keys/expected/input_plan.txt +2 -0
  169. data/golden/hash_keys/expected/lir_00_unoptimized.txt +18 -0
  170. data/golden/hash_keys/expected/lir_01_hoist_scalar_references.txt +18 -0
  171. data/golden/hash_keys/expected/lir_02_inlined.txt +18 -0
  172. data/golden/hash_keys/expected/lir_03_cse.txt +18 -0
  173. data/golden/hash_keys/expected/lir_04_1_loop_fusion.txt +18 -0
  174. data/golden/hash_keys/expected/lir_04_loop_invcm.txt +18 -0
  175. data/golden/hash_keys/expected/lir_06_const_prop.txt +18 -0
  176. data/golden/hash_keys/expected/nast.txt +46 -0
  177. data/golden/hash_keys/expected/schema_javascript.mjs +34 -0
  178. data/golden/hash_keys/expected/schema_ruby.rb +61 -0
  179. data/golden/hash_keys/expected/snast.txt +46 -0
  180. data/golden/hash_keys/expected.json +20 -0
  181. data/golden/hash_keys/input.json +4 -0
  182. data/golden/hash_keys/schema.kumi +14 -0
  183. data/golden/hash_value/expected/ast.txt +37 -0
  184. data/golden/hash_value/expected/input_plan.txt +7 -0
  185. data/golden/hash_value/expected/lir_00_unoptimized.txt +30 -0
  186. data/golden/hash_value/expected/lir_01_hoist_scalar_references.txt +30 -0
  187. data/golden/hash_value/expected/lir_02_inlined.txt +36 -0
  188. data/golden/hash_value/expected/lir_03_cse.txt +33 -0
  189. data/golden/hash_value/expected/lir_04_1_loop_fusion.txt +33 -0
  190. data/golden/hash_value/expected/lir_04_loop_invcm.txt +33 -0
  191. data/golden/hash_value/expected/lir_06_const_prop.txt +33 -0
  192. data/golden/hash_value/expected/nast.txt +25 -0
  193. data/golden/hash_value/expected/schema_javascript.mjs +46 -0
  194. data/golden/hash_value/expected/schema_ruby.rb +75 -0
  195. data/golden/hash_value/expected/snast.txt +25 -0
  196. data/golden/hash_value/expected.json +19 -0
  197. data/golden/hash_value/input.json +12 -0
  198. data/golden/hash_value/schema.kumi +19 -0
  199. data/golden/hierarchical_complex/expected/ast.txt +85 -0
  200. data/golden/hierarchical_complex/expected/input_plan.txt +23 -0
  201. data/golden/hierarchical_complex/expected/lir_00_unoptimized.txt +87 -0
  202. data/golden/hierarchical_complex/expected/lir_01_hoist_scalar_references.txt +87 -0
  203. data/golden/hierarchical_complex/expected/lir_02_inlined.txt +115 -0
  204. data/golden/hierarchical_complex/expected/lir_03_cse.txt +89 -0
  205. data/golden/hierarchical_complex/expected/lir_04_1_loop_fusion.txt +89 -0
  206. data/golden/hierarchical_complex/expected/lir_04_loop_invcm.txt +89 -0
  207. data/golden/hierarchical_complex/expected/lir_06_const_prop.txt +89 -0
  208. data/golden/hierarchical_complex/expected/nast.txt +49 -0
  209. data/golden/hierarchical_complex/expected/schema_javascript.mjs +121 -0
  210. data/golden/hierarchical_complex/expected/schema_ruby.rb +151 -0
  211. data/golden/hierarchical_complex/expected/snast.txt +49 -0
  212. data/golden/hierarchical_complex/expected.json +34 -0
  213. data/golden/hierarchical_complex/input.json +26 -0
  214. data/golden/hierarchical_complex/schema.kumi +38 -0
  215. data/golden/input_reference/expected/ast.txt +46 -0
  216. data/golden/input_reference/expected/input_plan.txt +15 -0
  217. data/golden/input_reference/expected/lir_00_unoptimized.txt +39 -0
  218. data/golden/input_reference/expected/lir_01_hoist_scalar_references.txt +39 -0
  219. data/golden/input_reference/expected/lir_02_inlined.txt +39 -0
  220. data/golden/input_reference/expected/lir_03_cse.txt +39 -0
  221. data/golden/input_reference/expected/lir_04_1_loop_fusion.txt +39 -0
  222. data/golden/input_reference/expected/lir_04_loop_invcm.txt +39 -0
  223. data/golden/input_reference/expected/lir_06_const_prop.txt +39 -0
  224. data/golden/input_reference/expected/nast.txt +21 -0
  225. data/golden/input_reference/expected/schema_javascript.mjs +45 -0
  226. data/golden/input_reference/expected/schema_ruby.rb +74 -0
  227. data/golden/input_reference/expected/snast.txt +21 -0
  228. data/golden/input_reference/expected.json +7 -0
  229. data/golden/input_reference/input.json +11 -0
  230. data/golden/input_reference/schema.kumi +22 -0
  231. data/golden/interleaved_fusion/expected/ast.txt +51 -0
  232. data/golden/interleaved_fusion/expected/input_plan.txt +13 -0
  233. data/golden/interleaved_fusion/expected/lir_00_unoptimized.txt +53 -0
  234. data/golden/interleaved_fusion/expected/lir_01_hoist_scalar_references.txt +53 -0
  235. data/golden/interleaved_fusion/expected/lir_02_inlined.txt +89 -0
  236. data/golden/interleaved_fusion/expected/lir_03_cse.txt +77 -0
  237. data/golden/interleaved_fusion/expected/lir_04_1_loop_fusion.txt +77 -0
  238. data/golden/interleaved_fusion/expected/lir_04_loop_invcm.txt +77 -0
  239. data/golden/interleaved_fusion/expected/lir_06_const_prop.txt +77 -0
  240. data/golden/interleaved_fusion/expected/nast.txt +41 -0
  241. data/golden/interleaved_fusion/expected/schema_javascript.mjs +86 -0
  242. data/golden/interleaved_fusion/expected/schema_ruby.rb +122 -0
  243. data/golden/interleaved_fusion/expected/snast.txt +41 -0
  244. data/golden/interleaved_fusion/expected.json +37 -0
  245. data/golden/interleaved_fusion/input.json +26 -0
  246. data/golden/interleaved_fusion/schema.kumi +57 -0
  247. data/golden/let_inline/expected/ast.txt +33 -0
  248. data/golden/let_inline/expected/input_plan.txt +2 -0
  249. data/golden/let_inline/expected/lir_00_unoptimized.txt +26 -0
  250. data/golden/let_inline/expected/lir_01_hoist_scalar_references.txt +26 -0
  251. data/golden/let_inline/expected/lir_02_inlined.txt +36 -0
  252. data/golden/let_inline/expected/lir_03_cse.txt +30 -0
  253. data/golden/let_inline/expected/lir_04_1_loop_fusion.txt +30 -0
  254. data/golden/let_inline/expected/lir_04_loop_invcm.txt +30 -0
  255. data/golden/let_inline/expected/lir_06_const_prop.txt +30 -0
  256. data/golden/let_inline/expected/nast.txt +26 -0
  257. data/golden/let_inline/expected/schema_javascript.mjs +11 -0
  258. data/golden/let_inline/expected/schema_ruby.rb +37 -0
  259. data/golden/let_inline/expected/snast.txt +26 -0
  260. data/golden/let_inline/expected.json +1 -0
  261. data/golden/let_inline/input.json +1 -0
  262. data/golden/let_inline/schema.kumi +11 -0
  263. data/golden/loop_fusion/expected/ast.txt +44 -0
  264. data/golden/loop_fusion/expected/input_plan.txt +13 -0
  265. data/golden/loop_fusion/expected/lir_00_unoptimized.txt +43 -0
  266. data/golden/loop_fusion/expected/lir_01_hoist_scalar_references.txt +43 -0
  267. data/golden/loop_fusion/expected/lir_02_inlined.txt +62 -0
  268. data/golden/loop_fusion/expected/lir_03_cse.txt +57 -0
  269. data/golden/loop_fusion/expected/lir_04_1_loop_fusion.txt +57 -0
  270. data/golden/loop_fusion/expected/lir_04_loop_invcm.txt +57 -0
  271. data/golden/loop_fusion/expected/lir_06_const_prop.txt +57 -0
  272. data/golden/loop_fusion/expected/nast.txt +32 -0
  273. data/golden/loop_fusion/expected/schema_javascript.mjs +64 -0
  274. data/golden/loop_fusion/expected/schema_ruby.rb +97 -0
  275. data/golden/loop_fusion/expected/snast.txt +32 -0
  276. data/golden/loop_fusion/expected.json +30 -0
  277. data/golden/loop_fusion/input.json +28 -0
  278. data/golden/loop_fusion/schema.kumi +32 -0
  279. data/golden/min_reduce_scope/expected/ast.txt +49 -0
  280. data/golden/min_reduce_scope/expected/input_plan.txt +9 -0
  281. data/golden/min_reduce_scope/expected/lir_00_unoptimized.txt +59 -0
  282. data/golden/min_reduce_scope/expected/lir_01_hoist_scalar_references.txt +59 -0
  283. data/golden/min_reduce_scope/expected/lir_02_inlined.txt +63 -0
  284. data/golden/min_reduce_scope/expected/lir_03_cse.txt +60 -0
  285. data/golden/min_reduce_scope/expected/lir_04_1_loop_fusion.txt +60 -0
  286. data/golden/min_reduce_scope/expected/lir_04_loop_invcm.txt +60 -0
  287. data/golden/min_reduce_scope/expected/lir_06_const_prop.txt +60 -0
  288. data/golden/min_reduce_scope/expected/nast.txt +29 -0
  289. data/golden/min_reduce_scope/expected/schema_javascript.mjs +66 -0
  290. data/golden/min_reduce_scope/expected/schema_ruby.rb +99 -0
  291. data/golden/min_reduce_scope/expected/snast.txt +29 -0
  292. data/golden/min_reduce_scope/expected.json +9 -0
  293. data/golden/min_reduce_scope/input.json +18 -0
  294. data/golden/min_reduce_scope/schema.kumi +25 -0
  295. data/golden/mixed_dimensions/expected/ast.txt +54 -0
  296. data/golden/mixed_dimensions/expected/input_plan.txt +15 -0
  297. data/golden/mixed_dimensions/expected/lir_00_unoptimized.txt +42 -0
  298. data/golden/mixed_dimensions/expected/lir_01_hoist_scalar_references.txt +42 -0
  299. data/golden/mixed_dimensions/expected/lir_02_inlined.txt +48 -0
  300. data/golden/mixed_dimensions/expected/lir_03_cse.txt +48 -0
  301. data/golden/mixed_dimensions/expected/lir_04_1_loop_fusion.txt +48 -0
  302. data/golden/mixed_dimensions/expected/lir_04_loop_invcm.txt +48 -0
  303. data/golden/mixed_dimensions/expected/lir_06_const_prop.txt +48 -0
  304. data/golden/mixed_dimensions/expected/nast.txt +22 -0
  305. data/golden/mixed_dimensions/expected/schema_javascript.mjs +53 -0
  306. data/golden/mixed_dimensions/expected/schema_ruby.rb +84 -0
  307. data/golden/mixed_dimensions/expected/snast.txt +22 -0
  308. data/golden/mixed_dimensions/expected.json +6 -0
  309. data/golden/mixed_dimensions/input.json +22 -0
  310. data/golden/mixed_dimensions/schema.kumi +35 -0
  311. data/golden/multirank_hoisting/expected/ast.txt +72 -0
  312. data/golden/multirank_hoisting/expected/input_plan.txt +18 -0
  313. data/golden/multirank_hoisting/expected/lir_00_unoptimized.txt +75 -0
  314. data/golden/multirank_hoisting/expected/lir_01_hoist_scalar_references.txt +75 -0
  315. data/golden/multirank_hoisting/expected/lir_02_inlined.txt +126 -0
  316. data/golden/multirank_hoisting/expected/lir_03_cse.txt +109 -0
  317. data/golden/multirank_hoisting/expected/lir_04_1_loop_fusion.txt +109 -0
  318. data/golden/multirank_hoisting/expected/lir_04_loop_invcm.txt +109 -0
  319. data/golden/multirank_hoisting/expected/lir_06_const_prop.txt +109 -0
  320. data/golden/multirank_hoisting/expected/nast.txt +39 -0
  321. data/golden/multirank_hoisting/expected/schema_javascript.mjs +128 -0
  322. data/golden/multirank_hoisting/expected/schema_ruby.rb +162 -0
  323. data/golden/multirank_hoisting/expected/snast.txt +39 -0
  324. data/golden/multirank_hoisting/expected.json +15 -0
  325. data/golden/multirank_hoisting/input.json +19 -0
  326. data/golden/multirank_hoisting/schema.kumi +38 -0
  327. data/golden/nested_hash/expected/ast.txt +22 -0
  328. data/golden/nested_hash/expected/input_plan.txt +5 -0
  329. data/golden/nested_hash/expected/lir_00_unoptimized.txt +10 -0
  330. data/golden/nested_hash/expected/lir_01_hoist_scalar_references.txt +10 -0
  331. data/golden/nested_hash/expected/lir_02_inlined.txt +10 -0
  332. data/golden/nested_hash/expected/lir_03_cse.txt +10 -0
  333. data/golden/nested_hash/expected/lir_04_1_loop_fusion.txt +10 -0
  334. data/golden/nested_hash/expected/lir_04_loop_invcm.txt +10 -0
  335. data/golden/nested_hash/expected/lir_06_const_prop.txt +10 -0
  336. data/golden/nested_hash/expected/nast.txt +8 -0
  337. data/golden/nested_hash/expected/schema_javascript.mjs +9 -0
  338. data/golden/nested_hash/expected/schema_ruby.rb +35 -0
  339. data/golden/nested_hash/expected/snast.txt +8 -0
  340. data/golden/nested_hash/expected.json +3 -0
  341. data/golden/nested_hash/input.json +7 -0
  342. data/golden/nested_hash/schema.kumi +11 -0
  343. data/golden/reduction_broadcast/expected/ast.txt +49 -0
  344. data/golden/reduction_broadcast/expected/input_plan.txt +13 -0
  345. data/golden/reduction_broadcast/expected/lir_00_unoptimized.txt +49 -0
  346. data/golden/reduction_broadcast/expected/lir_01_hoist_scalar_references.txt +49 -0
  347. data/golden/reduction_broadcast/expected/lir_02_inlined.txt +80 -0
  348. data/golden/reduction_broadcast/expected/lir_03_cse.txt +68 -0
  349. data/golden/reduction_broadcast/expected/lir_04_1_loop_fusion.txt +68 -0
  350. data/golden/reduction_broadcast/expected/lir_04_loop_invcm.txt +68 -0
  351. data/golden/reduction_broadcast/expected/lir_06_const_prop.txt +68 -0
  352. data/golden/reduction_broadcast/expected/nast.txt +24 -0
  353. data/golden/reduction_broadcast/expected/schema_javascript.mjs +74 -0
  354. data/golden/reduction_broadcast/expected/schema_ruby.rb +110 -0
  355. data/golden/reduction_broadcast/expected/snast.txt +24 -0
  356. data/golden/reduction_broadcast/expected.json +25 -0
  357. data/golden/reduction_broadcast/input.json +19 -0
  358. data/golden/reduction_broadcast/schema.kumi +34 -0
  359. data/golden/roll/expected/ast.txt +36 -0
  360. data/golden/roll/expected/input_plan.txt +3 -0
  361. data/golden/roll/expected/lir_00_unoptimized.txt +56 -0
  362. data/golden/roll/expected/lir_01_hoist_scalar_references.txt +56 -0
  363. data/golden/roll/expected/lir_02_inlined.txt +56 -0
  364. data/golden/roll/expected/lir_03_cse.txt +55 -0
  365. data/golden/roll/expected/lir_04_1_loop_fusion.txt +55 -0
  366. data/golden/roll/expected/lir_04_loop_invcm.txt +55 -0
  367. data/golden/roll/expected/lir_06_const_prop.txt +55 -0
  368. data/golden/roll/expected/nast.txt +26 -0
  369. data/golden/roll/expected/schema_javascript.mjs +65 -0
  370. data/golden/roll/expected/schema_ruby.rb +95 -0
  371. data/golden/roll/expected/snast.txt +26 -0
  372. data/golden/roll/expected.json +6 -0
  373. data/golden/roll/input.json +1 -0
  374. data/golden/roll/schema.kumi +13 -0
  375. data/golden/shift/expected/ast.txt +48 -0
  376. data/golden/shift/expected/input_plan.txt +3 -0
  377. data/golden/shift/expected/lir_00_unoptimized.txt +96 -0
  378. data/golden/shift/expected/lir_01_hoist_scalar_references.txt +96 -0
  379. data/golden/shift/expected/lir_02_inlined.txt +96 -0
  380. data/golden/shift/expected/lir_03_cse.txt +90 -0
  381. data/golden/shift/expected/lir_04_1_loop_fusion.txt +90 -0
  382. data/golden/shift/expected/lir_04_loop_invcm.txt +90 -0
  383. data/golden/shift/expected/lir_06_const_prop.txt +90 -0
  384. data/golden/shift/expected/nast.txt +38 -0
  385. data/golden/shift/expected/schema_javascript.mjs +106 -0
  386. data/golden/shift/expected/schema_ruby.rb +138 -0
  387. data/golden/shift/expected/snast.txt +38 -0
  388. data/golden/shift/expected.json +8 -0
  389. data/golden/shift/input.json +1 -0
  390. data/golden/shift/schema.kumi +15 -0
  391. data/golden/shift_2d/expected/ast.txt +88 -0
  392. data/golden/shift_2d/expected/input_plan.txt +5 -0
  393. data/golden/shift_2d/expected/lir_00_unoptimized.txt +274 -0
  394. data/golden/shift_2d/expected/lir_01_hoist_scalar_references.txt +274 -0
  395. data/golden/shift_2d/expected/lir_02_inlined.txt +274 -0
  396. data/golden/shift_2d/expected/lir_03_cse.txt +262 -0
  397. data/golden/shift_2d/expected/lir_04_1_loop_fusion.txt +262 -0
  398. data/golden/shift_2d/expected/lir_04_loop_invcm.txt +262 -0
  399. data/golden/shift_2d/expected/lir_06_const_prop.txt +262 -0
  400. data/golden/shift_2d/expected/nast.txt +74 -0
  401. data/golden/shift_2d/expected/schema_javascript.mjs +320 -0
  402. data/golden/shift_2d/expected/schema_ruby.rb +358 -0
  403. data/golden/shift_2d/expected/snast.txt +74 -0
  404. data/golden/shift_2d/expected.json +15 -0
  405. data/golden/shift_2d/input.json +14 -0
  406. data/golden/shift_2d/schema.kumi +25 -0
  407. data/golden/simple_math/expected/ast.txt +40 -0
  408. data/golden/simple_math/expected/input_plan.txt +2 -0
  409. data/golden/simple_math/expected/lir_00_unoptimized.txt +31 -0
  410. data/golden/simple_math/expected/lir_01_hoist_scalar_references.txt +31 -0
  411. data/golden/simple_math/expected/lir_02_inlined.txt +31 -0
  412. data/golden/simple_math/expected/lir_03_cse.txt +31 -0
  413. data/golden/simple_math/expected/lir_04_1_loop_fusion.txt +31 -0
  414. data/golden/simple_math/expected/lir_04_loop_invcm.txt +31 -0
  415. data/golden/simple_math/expected/lir_06_const_prop.txt +31 -0
  416. data/golden/simple_math/expected/nast.txt +33 -0
  417. data/golden/simple_math/expected/schema_javascript.mjs +33 -0
  418. data/golden/simple_math/expected/schema_ruby.rb +59 -0
  419. data/golden/simple_math/expected/snast.txt +33 -0
  420. data/golden/simple_math/expected.json +1 -0
  421. data/golden/simple_math/input.json +4 -0
  422. data/golden/simple_math/schema.kumi +2 -1
  423. data/golden/streaming_basics/expected/ast.txt +64 -0
  424. data/golden/streaming_basics/expected/input_plan.txt +8 -0
  425. data/golden/streaming_basics/expected/lir_00_unoptimized.txt +73 -0
  426. data/golden/streaming_basics/expected/lir_01_hoist_scalar_references.txt +73 -0
  427. data/golden/streaming_basics/expected/lir_02_inlined.txt +100 -0
  428. data/golden/streaming_basics/expected/lir_03_cse.txt +84 -0
  429. data/golden/streaming_basics/expected/lir_04_1_loop_fusion.txt +84 -0
  430. data/golden/streaming_basics/expected/lir_04_loop_invcm.txt +84 -0
  431. data/golden/streaming_basics/expected/lir_06_const_prop.txt +84 -0
  432. data/golden/streaming_basics/expected/nast.txt +48 -0
  433. data/golden/streaming_basics/expected/schema_javascript.mjs +94 -0
  434. data/golden/streaming_basics/expected/schema_ruby.rb +127 -0
  435. data/golden/streaming_basics/expected/snast.txt +48 -0
  436. data/golden/streaming_basics/expected.json +10 -0
  437. data/golden/streaming_basics/input.json +8 -0
  438. data/golden/streaming_basics/schema.kumi +24 -0
  439. data/golden/tuples/expected/ast.txt +48 -0
  440. data/golden/tuples/expected/input_plan.txt +1 -0
  441. data/golden/tuples/expected/lir_00_unoptimized.txt +40 -0
  442. data/golden/tuples/expected/lir_01_hoist_scalar_references.txt +40 -0
  443. data/golden/tuples/expected/lir_02_inlined.txt +48 -0
  444. data/golden/tuples/expected/lir_03_cse.txt +48 -0
  445. data/golden/tuples/expected/lir_04_1_loop_fusion.txt +48 -0
  446. data/golden/tuples/expected/lir_04_loop_invcm.txt +48 -0
  447. data/golden/tuples/expected/lir_06_const_prop.txt +48 -0
  448. data/golden/tuples/expected/nast.txt +42 -0
  449. data/golden/tuples/expected/schema_javascript.mjs +51 -0
  450. data/golden/tuples/expected/schema_ruby.rb +77 -0
  451. data/golden/tuples/expected/snast.txt +42 -0
  452. data/golden/tuples/expected.json +7 -0
  453. data/golden/tuples/input.json +3 -0
  454. data/golden/tuples/schema.kumi +11 -0
  455. data/golden/tuples_and_arrays/expected/ast.txt +44 -0
  456. data/golden/tuples_and_arrays/expected/input_plan.txt +7 -0
  457. data/golden/tuples_and_arrays/expected/lir_00_unoptimized.txt +41 -0
  458. data/golden/tuples_and_arrays/expected/lir_01_hoist_scalar_references.txt +41 -0
  459. data/golden/tuples_and_arrays/expected/lir_02_inlined.txt +62 -0
  460. data/golden/tuples_and_arrays/expected/lir_03_cse.txt +51 -0
  461. data/golden/tuples_and_arrays/expected/lir_04_1_loop_fusion.txt +51 -0
  462. data/golden/tuples_and_arrays/expected/lir_04_loop_invcm.txt +51 -0
  463. data/golden/tuples_and_arrays/expected/lir_06_const_prop.txt +51 -0
  464. data/golden/tuples_and_arrays/expected/nast.txt +28 -0
  465. data/golden/tuples_and_arrays/expected/schema_javascript.mjs +58 -0
  466. data/golden/tuples_and_arrays/expected/schema_ruby.rb +88 -0
  467. data/golden/tuples_and_arrays/expected/snast.txt +28 -0
  468. data/golden/tuples_and_arrays/expected.json +18 -0
  469. data/golden/tuples_and_arrays/input.json +7 -0
  470. data/golden/tuples_and_arrays/schema.kumi +38 -0
  471. data/golden/with_constants/expected/ast.txt +28 -0
  472. data/golden/with_constants/expected/input_plan.txt +2 -0
  473. data/golden/with_constants/expected/lir_00_unoptimized.txt +17 -0
  474. data/golden/with_constants/expected/lir_01_hoist_scalar_references.txt +17 -0
  475. data/golden/with_constants/expected/lir_02_inlined.txt +17 -0
  476. data/golden/with_constants/expected/lir_03_cse.txt +17 -0
  477. data/golden/with_constants/expected/lir_04_1_loop_fusion.txt +17 -0
  478. data/golden/with_constants/expected/lir_04_loop_invcm.txt +17 -0
  479. data/golden/with_constants/expected/lir_06_const_prop.txt +17 -0
  480. data/golden/with_constants/expected/nast.txt +21 -0
  481. data/golden/with_constants/expected/schema_javascript.mjs +18 -0
  482. data/golden/with_constants/expected/schema_ruby.rb +44 -0
  483. data/golden/with_constants/expected/snast.txt +15 -0
  484. data/golden/with_constants/schema.kumi +10 -0
  485. data/lib/kumi/analyzer.rb +76 -24
  486. data/lib/kumi/configuration.rb +60 -0
  487. data/lib/kumi/core/analyzer/binder.rb +121 -0
  488. data/lib/kumi/core/analyzer/checkpoint.rb +15 -9
  489. data/lib/kumi/core/analyzer/constant_evaluator.rb +32 -37
  490. data/lib/kumi/core/analyzer/constant_folding_helpers.rb +55 -0
  491. data/lib/kumi/core/analyzer/debug.rb +14 -16
  492. data/lib/kumi/core/analyzer/fn_aliases.rb +46 -0
  493. data/lib/kumi/core/analyzer/folder.rb +94 -0
  494. data/lib/kumi/core/analyzer/macro_expander.rb +69 -0
  495. data/lib/kumi/core/analyzer/passes/assemble_irv2_pass.rb +130 -0
  496. data/lib/kumi/core/analyzer/passes/attach_anchors_pass.rb +71 -0
  497. data/lib/kumi/core/analyzer/passes/attach_terminal_info_pass.rb +181 -0
  498. data/lib/kumi/core/analyzer/passes/codegen/js/declaration_emitter.rb +317 -0
  499. data/lib/kumi/core/analyzer/passes/codegen/js/emitter.rb +75 -0
  500. data/lib/kumi/core/analyzer/passes/codegen/js/output_buffer.rb +103 -0
  501. data/lib/kumi/core/analyzer/passes/codegen/js_pass.rb +27 -0
  502. data/lib/kumi/core/analyzer/passes/codegen/ruby/declaration_emitter.rb +321 -0
  503. data/lib/kumi/core/analyzer/passes/codegen/ruby/emitter.rb +85 -0
  504. data/lib/kumi/core/analyzer/passes/codegen/ruby/output_buffer.rb +111 -0
  505. data/lib/kumi/core/analyzer/passes/codegen/ruby_pass.rb +32 -0
  506. data/lib/kumi/core/analyzer/passes/constant_folding_pass.rb +33 -0
  507. data/lib/kumi/core/analyzer/passes/contract_checker_pass.rb +220 -0
  508. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +5 -6
  509. data/lib/kumi/core/analyzer/passes/input_access_planner_pass.rb +7 -3
  510. data/lib/kumi/core/analyzer/passes/input_collector.rb +74 -122
  511. data/lib/kumi/core/analyzer/passes/input_form_schema_pass.rb +43 -0
  512. data/lib/kumi/core/analyzer/passes/ir_dependency_pass.rb +1 -1
  513. data/lib/kumi/core/analyzer/passes/ir_execution_schedule_pass.rb +1 -1
  514. data/lib/kumi/core/analyzer/passes/join_reduce_planning_pass.rb +21 -23
  515. data/lib/kumi/core/analyzer/passes/lir/constant_propagation_pass.rb +84 -0
  516. data/lib/kumi/core/analyzer/passes/lir/dead_code_elimination_pass.rb +93 -0
  517. data/lib/kumi/core/analyzer/passes/lir/hoist_scalar_references_pass.rb +115 -0
  518. data/lib/kumi/core/analyzer/passes/lir/inline_declarations_pass.rb +274 -0
  519. data/lib/kumi/core/analyzer/passes/lir/instruction_scheduling_pass.rb +198 -0
  520. data/lib/kumi/core/analyzer/passes/lir/kernel_binding_pass.rb +30 -0
  521. data/lib/kumi/core/analyzer/passes/lir/local_cse_pass.rb +121 -0
  522. data/lib/kumi/core/analyzer/passes/lir/loop_fusion_pass.rb +156 -0
  523. data/lib/kumi/core/analyzer/passes/lir/loop_invariant_code_motion_pass.rb +148 -0
  524. data/lib/kumi/core/analyzer/passes/lir/lower_pass.rb +407 -0
  525. data/lib/kumi/core/analyzer/passes/lir/stencil_emitter.rb +243 -0
  526. data/lib/kumi/core/analyzer/passes/lir/validation_pass.rb +83 -0
  527. data/lib/kumi/core/analyzer/passes/load_input_cse.rb +17 -16
  528. data/lib/kumi/core/analyzer/passes/lower_to_ir_pass.rb +4 -2
  529. data/lib/kumi/core/analyzer/passes/lower_to_irv2_pass.rb +197 -0
  530. data/lib/kumi/core/analyzer/passes/name_indexer.rb +4 -1
  531. data/lib/kumi/core/analyzer/passes/nast_dimensional_analyzer_pass.rb +237 -0
  532. data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +156 -0
  533. data/lib/kumi/core/analyzer/passes/output_schema_pass.rb +38 -0
  534. data/lib/kumi/core/analyzer/passes/pass_base.rb +30 -4
  535. data/lib/kumi/core/analyzer/passes/precompute_access_paths_pass.rb +93 -0
  536. data/lib/kumi/core/analyzer/passes/scope_resolution_pass.rb +33 -30
  537. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +5 -26
  538. data/lib/kumi/core/analyzer/passes/snast_pass.rb +229 -0
  539. data/lib/kumi/core/analyzer/passes/toposorter.rb +1 -0
  540. data/lib/kumi/core/analyzer/passes/type_checker.rb +13 -0
  541. data/lib/kumi/core/analyzer/passes/type_inferencer_pass.rb +14 -16
  542. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +2 -1
  543. data/lib/kumi/core/analyzer/plans.rb +12 -0
  544. data/lib/kumi/core/analyzer/state_serde.rb +4 -4
  545. data/lib/kumi/core/analyzer/structs/access_plan.rb +2 -2
  546. data/lib/kumi/core/analyzer/unsat_constant_evaluator.rb +59 -0
  547. data/lib/kumi/core/compiler/access_codegen.rb +1 -1
  548. data/lib/kumi/core/compiler/access_emit/base.rb +9 -5
  549. data/lib/kumi/core/compiler/access_emit/each_indexed.rb +10 -3
  550. data/lib/kumi/core/compiler/access_emit/materialize.rb +12 -5
  551. data/lib/kumi/core/compiler/access_emit/ravel.rb +10 -3
  552. data/lib/kumi/core/compiler/access_emit/read.rb +4 -1
  553. data/lib/kumi/core/compiler/access_planner.rb +42 -4
  554. data/lib/kumi/core/compiler/access_planner_v2.rb +164 -0
  555. data/lib/kumi/core/explain.rb +18 -11
  556. data/lib/kumi/core/functions/loader.rb +47 -0
  557. data/lib/kumi/core/functions/model.rb +10 -0
  558. data/lib/kumi/core/functions/type_rules.rb +108 -0
  559. data/lib/kumi/core/ir/execution_engine/interpreter.rb +1 -1
  560. data/lib/kumi/core/ir/execution_engine/profiler.rb +107 -97
  561. data/lib/kumi/core/ir.rb +6 -2
  562. data/lib/kumi/core/irv2/builder.rb +48 -0
  563. data/lib/kumi/core/irv2/declaration.rb +28 -0
  564. data/lib/kumi/core/irv2/module.rb +108 -0
  565. data/lib/kumi/core/irv2/value.rb +28 -0
  566. data/lib/kumi/core/lir/analyze.rb +64 -0
  567. data/lib/kumi/core/lir/build.rb +363 -0
  568. data/lib/kumi/core/lir/emit.rb +62 -0
  569. data/lib/kumi/core/lir/structs/instruction.rb +44 -0
  570. data/lib/kumi/core/lir/structs/literal.rb +14 -0
  571. data/lib/kumi/core/lir/structs/stamp.rb +13 -0
  572. data/lib/kumi/core/lir/support/error.rb +9 -0
  573. data/lib/kumi/core/lir/support/ids.rb +34 -0
  574. data/lib/kumi/core/lir/validate.rb +74 -0
  575. data/lib/kumi/core/lir.rb +34 -0
  576. data/lib/kumi/core/nast.rb +216 -0
  577. data/lib/kumi/core/ruby_parser/dsl.rb +2 -2
  578. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +1 -1
  579. data/lib/kumi/core/ruby_parser/expression_converter.rb +10 -0
  580. data/lib/kumi/core/ruby_parser/input_builder.rb +16 -17
  581. data/lib/kumi/core/ruby_parser/schema_builder.rb +36 -10
  582. data/lib/kumi/core/ruby_parser/sugar.rb +64 -0
  583. data/lib/kumi/core/types/builder.rb +2 -2
  584. data/lib/kumi/core/types/normalizer.rb +2 -0
  585. data/lib/kumi/core/types/validator.rb +10 -3
  586. data/lib/kumi/core/types.rb +7 -0
  587. data/lib/kumi/dev/codegen.rb +194 -0
  588. data/lib/kumi/dev/golden/generator.rb +105 -0
  589. data/lib/kumi/dev/golden/reporter.rb +160 -0
  590. data/lib/kumi/dev/golden/representation.rb +45 -0
  591. data/lib/kumi/dev/golden/result.rb +98 -0
  592. data/lib/kumi/dev/golden/runtime_test.rb +93 -0
  593. data/lib/kumi/dev/golden/suite.rb +131 -0
  594. data/lib/kumi/dev/golden/verifier.rb +76 -0
  595. data/lib/kumi/dev/golden.rb +75 -0
  596. data/lib/kumi/dev/ir.rb +4 -4
  597. data/lib/kumi/dev/parse.rb +1 -1
  598. data/lib/kumi/dev/pretty_printer.rb +229 -0
  599. data/lib/kumi/dev/printer/irv2_formatter.rb +163 -0
  600. data/lib/kumi/dev/printer/width_aware_json.rb +44 -0
  601. data/lib/kumi/dev/profile_aggregator.rb +36 -38
  602. data/lib/kumi/dev/profile_runner.rb +19 -23
  603. data/lib/kumi/dev/runner.rb +12 -22
  604. data/lib/kumi/dev/support/kumi_runner.mjs +39 -0
  605. data/lib/kumi/dev.rb +3 -3
  606. data/lib/kumi/frontends/ruby.rb +12 -12
  607. data/lib/kumi/frontends/text.rb +26 -21
  608. data/lib/kumi/frontends.rb +6 -8
  609. data/lib/kumi/kernel_registry.rb +59 -0
  610. data/lib/kumi/pack/builder.rb +229 -0
  611. data/lib/kumi/pack.rb +15 -0
  612. data/lib/kumi/registry_v2/loader.rb +81 -0
  613. data/lib/kumi/registry_v2.rb +118 -0
  614. data/lib/kumi/schema.rb +83 -43
  615. data/lib/kumi/support/diff.rb +3 -2
  616. data/lib/kumi/support/ir_render.rb +1 -1
  617. data/lib/kumi/support/lir_printer.rb +143 -0
  618. data/lib/kumi/support/nast_printer.rb +93 -0
  619. data/lib/kumi/support/s_expression_printer.rb +5 -4
  620. data/lib/kumi/support/snast_printer.rb +111 -0
  621. data/lib/kumi/syntax/call_expression.rb +1 -1
  622. data/lib/kumi/syntax/input_declaration.rb +2 -2
  623. data/lib/kumi/syntax/node.rb +4 -12
  624. data/lib/kumi/syntax/root.rb +10 -0
  625. data/lib/kumi/syntax/trait_declaration.rb +1 -0
  626. data/lib/kumi/syntax/value_declaration.rb +1 -0
  627. data/lib/kumi/version.rb +1 -1
  628. data/lib/kumi.rb +47 -5
  629. metadata +571 -54
  630. data/docs/AST.md +0 -133
  631. data/docs/DSL.md +0 -154
  632. data/docs/FUNCTIONS.md +0 -176
  633. data/docs/VECTOR_SEMANTICS.md +0 -286
  634. data/docs/compiler_design_principles.md +0 -86
  635. data/docs/dev/analyzer-debug.md +0 -52
  636. data/docs/dev/parse-command.md +0 -64
  637. data/docs/dev/vm-profiling.md +0 -95
  638. data/docs/development/README.md +0 -120
  639. data/docs/development/error-reporting.md +0 -361
  640. data/docs/features/README.md +0 -58
  641. data/docs/features/analysis-type-inference.md +0 -42
  642. data/docs/features/analysis-unsat-detection.md +0 -71
  643. data/docs/features/hierarchical-broadcasting.md +0 -415
  644. data/docs/features/input-declaration-system.md +0 -58
  645. data/docs/features/performance.md +0 -14
  646. data/docs/features/s-expression-printer.md +0 -77
  647. data/docs/schema_metadata/broadcasts.md +0 -53
  648. data/docs/schema_metadata/cascades.md +0 -45
  649. data/docs/schema_metadata/declarations.md +0 -54
  650. data/docs/schema_metadata/dependencies.md +0 -57
  651. data/docs/schema_metadata/evaluation_order.md +0 -29
  652. data/docs/schema_metadata/examples.md +0 -95
  653. data/docs/schema_metadata/inferred_types.md +0 -46
  654. data/docs/schema_metadata/inputs.md +0 -86
  655. data/docs/schema_metadata.md +0 -108
  656. data/golden/mixed_nesting/schema.kumi +0 -42
  657. data/lib/kumi/core/function_registry/collection_functions.rb +0 -298
  658. data/lib/kumi/core/function_registry/comparison_functions.rb +0 -33
  659. data/lib/kumi/core/function_registry/conditional_functions.rb +0 -48
  660. data/lib/kumi/core/function_registry/function_builder.rb +0 -184
  661. data/lib/kumi/core/function_registry/logical_functions.rb +0 -214
  662. data/lib/kumi/core/function_registry/math_functions.rb +0 -74
  663. data/lib/kumi/core/function_registry/stat_functions.rb +0 -156
  664. data/lib/kumi/core/function_registry/string_functions.rb +0 -57
  665. data/lib/kumi/core/function_registry/type_functions.rb +0 -53
  666. data/lib/kumi/core/function_registry.rb +0 -176
  667. data/lib/kumi/registry.rb +0 -32
  668. data/lib/kumi/runtime/executable.rb +0 -135
  669. data/lib/kumi/runtime/run.rb +0 -105
  670. data/performance_results.txt +0 -63
  671. data/scripts/analyze_broadcast_methods.rb +0 -68
  672. data/scripts/analyze_cascade_methods.rb +0 -74
  673. data/scripts/check_broadcasting_coverage.rb +0 -51
  674. data/scripts/find_dead_code.rb +0 -114
  675. data/scripts/generate_function_docs.rb +0 -71
  676. data/scripts/test_mixed_nesting_performance.rb +0 -206
data/README.md CHANGED
@@ -1,436 +1,207 @@
1
- # Kumi
1
+ # Kumi
2
2
 
3
3
  [![CI](https://github.com/amuta/kumi/workflows/CI/badge.svg)](https://github.com/amuta/kumi/actions)
4
4
  [![Gem Version](https://badge.fury.io/rb/kumi.svg)](https://badge.fury.io/rb/kumi)
5
5
 
6
- **Kumi** is a declarative rules-and-calculation DSL for Ruby. It compiles business logic into a **typed, analyzable dependency graph** with **vector semantics** over nested data, performs **static checks** at definition time, **lowers to a compact IR**, and executes **deterministically**.
7
6
 
8
- It handles complex, interdependent calculations with validation and consistency checking.
7
+ ---
9
8
 
9
+ **Status**: experimental. Public API may change. Typing and some static checks are still evolving.
10
10
 
11
- ## What can you build?
11
+ **Feedback**: have a use case or a paper cut? Open an issue or reach out.
12
12
 
13
- Calculate U.S. federal taxes:
13
+ ---
14
14
 
15
- ```ruby
16
- module FederalTax2024
17
- extend Kumi::Schema
18
-
19
- schema do
20
- input do
21
- float :income
22
- string :filing_status, domain: %w[single married_joint]
23
- end
24
-
25
- # Standard deduction by filing status
26
- trait :single, input.filing_status == "single"
27
- trait :married, input.filing_status == "married_joint"
28
-
29
- value :std_deduction do
30
- on single, 14_600
31
- on married, 29_200
32
- base 21_900 # head_of_household
33
- end
34
-
35
- value :taxable_income, fn(:max, [input.income - std_deduction, 0])
36
-
37
- # Federal tax brackets
38
- value :fed_breaks do
39
- on single, [11_600, 47_150, 100_525, 191_950, 243_725, 609_350, Float::INFINITY]
40
- on married, [23_200, 94_300, 201_050, 383_900, 487_450, 731_200, Float::INFINITY]
41
- end
42
-
43
- value :fed_rates, [0.10, 0.12, 0.22, 0.24, 0.32, 0.35, 0.37]
44
- value :fed_calc, fn(:piecewise_sum, taxable_income, fed_breaks, fed_rates)
45
- value :fed_tax, fed_calc[0]
46
-
47
- # FICA taxes
48
- value :ss_tax, fn(:min, [input.income, 168_600]) * 0.062
49
- value :medicare_tax, input.income * 0.0145
50
-
51
- value :total_tax, fed_tax + ss_tax + medicare_tax
52
- value :after_tax, input.income - total_tax
53
- end
54
- end
55
15
 
56
- # Use it
57
- result = FederalTax2024.from(income: 100_000, filing_status: "single")
58
- result[:total_tax] # => 21,491.00
59
- result[:after_tax] # => 78,509.00
60
- ```
16
+ Kumi is a **declarative calculation DSL for Ruby**. You write business rules once; Kumi:
61
17
 
62
- Real tax calculation with brackets, deductions, and FICA caps.
18
+ - Builds a **typed dependency graph** with vector semantics.
19
+ - Performs **static validation** at definition time.
20
+ - Lowers to a **portable Low-level IR (LIR)**.
21
+ - Code-generates standalone **Ruby** and **JavaScript**.
63
22
 
64
- Validation happens during schema definition.
23
+ Targets: finance, tax, pricing, insurance, payroll, analytics—domains where **correctness, transparency, and reproducibility** matter.
65
24
 
66
- ## Installation
25
+ ---
67
26
 
68
- ```bash
69
- # Requires Ruby 3.1+
70
- # No external dependencies
71
- gem install kumi
72
- ```
73
-
74
- ## Core Features
75
-
76
- <details>
77
- <summary><strong>Schema Primitives</strong> - Four building blocks for business logic</summary>
78
-
79
- ### Schema Primitives
80
-
81
- Kumi schemas are built from four primitives:
82
-
83
- **Inputs** define the data flowing into your schema with built-in validation:
84
- ```ruby
85
- input do
86
- float :price, domain: 0..1000.0 # Validates range
87
- integer :quantity, domain: 1..10000 # Validates range
88
- string :tier, domain: %w[standard premium] # Validates inclusion
89
- end
90
- ```
91
-
92
- **Values** are computed attributes that automatically memoize their results
93
- ```ruby
94
- value :subtotal, input.price * input.quantity
95
- value :tax_rate, 0.08
96
- value :tax_amount, subtotal * tax_rate
97
- ```
27
+ ## Codegen: Currently Ruby and JavaScript
98
28
 
99
- **Traits** are boolean conditions for branching logic:
100
- ```ruby
101
- trait :bulk_order, input.quantity >= 100
102
- trait :premium_customer, input.tier == "premium"
103
-
104
- value :discount do
105
- on bulk_order, premium_customer, 0.25 # 25% for bulk premium orders
106
- on bulk_order, 0.15 # 15% for bulk orders
107
- on premium_customer, 0.10 # 10% for premium customers
108
- base 0.0 # No discount otherwise
109
- end
110
- ```
29
+ *Note: this is not available on the last published gem version (0.0.18), but if you clone this repository you can just copy a ./golden/$schema_name and modify schema.kumi as you and run bin/kumi golden test $schema_name*
111
30
 
112
- **Functions** are computational building blocks:
113
31
 
114
- ```ruby
115
- value :final_price, [subtotal - discount_amount, 0].max
116
- value :monthly_payment, fn(:pmt, rate: 0.05/12, nper: 36, pv: -loan_amount)
117
- ```
118
- Note: You can find a list all core functions in [docs/FUNCTIONS.md](docs/FUNCTIONS.md)
32
+ Kumi emits the kernel for your schema with no runtime in the target language. You can use it within your ruby application backend and/or export to the client.
119
33
 
120
- </details>
121
34
 
122
35
  <details>
123
- <summary><strong>Analysis & Introspection</strong> - Static verification, runtime inspection, and metadata extraction</summary>
124
-
125
- ### Analysis & Introspection
126
-
127
- Kumi provides comprehensive analysis capabilities - catching errors at definition time and exposing schema structure for tooling and debugging.
128
-
129
- #### **Static Analysis: Catch Errors Early**
130
-
131
- Kumi catches many types of business logic errors that cause runtime failures or silent bugs:
36
+ <summary><strong>Schema</strong></summary>
132
37
 
133
38
  ```ruby
134
- module InsurancePolicyPricer
39
+ module GameOfLife
135
40
  extend Kumi::Schema
136
-
41
+
137
42
  schema do
138
43
  input do
139
- integer :age, domain: 18..80
140
- string :risk_category, domain: %w[low medium high]
141
- float :coverage_amount, domain: 50_000..2_000_000
142
- integer :years_experience, domain: 0..50
143
- boolean :has_claims
144
- end
145
-
146
- # Risk assessment with subtle interdependencies
147
- trait :young_driver, input.age < 25
148
- trait :experienced, input.years_experience >= 5
149
- trait :high_risk, input.risk_category == "high"
150
- trait :senior_driver, input.age >= 65
151
-
152
- # Base premium calculation
153
- value :base_premium, input.coverage_amount * 0.02
154
-
155
- # Experience adjustment with subtle circular reference
156
- value :experience_factor do
157
- on experienced & young_driver, experience_discount * 0.8 # ❌ Uses experience_discount before it's defined
158
- on experienced, 0.85
159
- on young_driver, 1.25
160
- base 1.0
161
- end
162
-
163
- # Risk multipliers that create impossible combinations
164
- value :risk_multiplier do
165
- on high_risk & experienced, 1.5 # High risk but experienced
166
- on high_risk, 2.0 # Just high risk
167
- on low_risk & young_driver, 0.9 # ❌ low_risk is undefined (typo for input.risk_category)
168
- base 1.0
169
- end
170
-
171
- # Claims history impact
172
- trait :claims_free, fn(:not, input.has_claims)
173
- trait :perfect_record, claims_free & experienced & fn(:not, young_driver)
174
-
175
- # Discount calculation with type error
176
- value :experience_discount do
177
- on perfect_record, input.years_experience + "%" # ❌ String concatenation with integer
178
- on claims_free, 0.95
179
- base 1.0
180
- end
181
-
182
- # Premium calculation chain
183
- value :adjusted_premium, base_premium * experience_factor * risk_multiplier
184
-
185
- # Age-based impossible logic
186
- trait :mature_professional, senior_driver & experienced & young_driver # ❌ Can't be senior AND young
187
-
188
- # Final premium with self-referencing cascade
189
- value :final_premium do
190
- on mature_professional, adjusted_premium * 0.8
191
- on senior_driver, adjusted_premium * senior_adjustment # ❌ senior_adjustment undefined
192
- base final_premium * 1.1 # ❌ Self-reference in base case
44
+ array :rows do
45
+ array :col do
46
+ integer :alive # 0 or 1
47
+ end
48
+ end
193
49
  end
194
-
195
- # Monthly payment calculation with function arity error
196
- value :monthly_payment, fn(:divide, final_premium) # ❌ divide needs 2 arguments, got 1
197
- end
198
- end
199
-
200
- # Static analysis catches these errors:
201
- # ❌ Circular reference: experience_factor → experience_discount → experience_factor
202
- # ❌ Undefined reference: low_risk (should be input.risk_category == "low")
203
- # ❌ Type mismatch: integer + string in experience_discount
204
- # ❌ Impossible conjunction: senior_driver & young_driver
205
- # ❌ Undefined reference: senior_adjustment
206
- # ❌ Self-reference cycle: final_premium references itself in base case
207
- # ❌ Function arity error: divide expects 2 arguments, got 1
208
- ```
209
-
210
- #### **Runtime Introspection: Debug and Understand**
211
-
212
- **Explainability**: Trace exactly how any value is computed, step-by-step. This is invaluable for debugging complex logic and auditing results.
213
50
 
214
- ```ruby
215
- Kumi::Explain.call(FederalTax2024, :fed_tax, inputs: {income: 100_000, filing_status: "single"})
216
- # => fed_tax = fed_calc[0]
217
- # = (fed_calc = piecewise_sum(taxable_income, fed_breaks, fed_rates)
218
- # = piecewise_sum(85_400, [11_600, 47_150, ...], [0.10, 0.12, ...])
219
- # = [15_099.50, 0.22])
220
- # = 15_099.50
221
- ```
51
+ let :a, input.rows.col.alive
222
52
 
223
- #### **Schema Metadata API: Build Tooling**
53
+ # axis_offset: 0 = x, 1 = y
54
+ let :n, shift(a, -1, axis_offset: 1)
55
+ let :s, shift(a, 1, axis_offset: 1)
56
+ let :w, shift(a, -1)
57
+ let :e, shift(a, 1)
58
+ let :nw, shift(n, -1)
59
+ let :ne, shift(n, 1)
60
+ let :sw, shift(s, -1)
61
+ let :se, shift(s, 1)
224
62
 
225
- Programmatically access the analyzed structure of your schema to build tools like form generators, documentation sites, or custom validators.
63
+ let :neighbors, fn(:sum, [n, s, w, e, nw, ne, sw, se])
226
64
 
227
- ```ruby
228
- metadata = FederalTax2024.schema_metadata
65
+ # Conway rules
66
+ let :alive, a > 0
67
+ let :n3_alive, neighbors == 3
68
+ let :n2_alive, neighbors == 2
69
+ let :keep_alive, n2_alive & alive
229
70
 
230
- # Processed, tool-friendly metadata
231
- metadata.inputs # => { name: { type: :string, domain: ... } }
232
- metadata.values # => { name: { dependencies: [...], expression: "..." } }
233
- metadata.traits # => { name: { condition: "...", dependencies: [...] } }
71
+ let :next_alive, n3_alive | keep_alive
234
72
 
235
- # Raw analyzer state for deep analysis
236
- metadata.dependencies # Dependency graph between all declarations
237
- metadata.evaluation_order # Topologically sorted computation order
73
+ value :next_state, select(next_alive, 1, 0)
74
+ end
238
75
 
239
- # Export to standard formats
240
- metadata.to_h # => Serializable hash for JSON/APIs
241
- metadata.to_json_schema # => JSON Schema for input validation
242
- ```
76
+ end
77
+ ````
243
78
 
244
- #### **AST Visualization: See the Structure**
79
+ </details>
245
80
 
246
- For deep debugging, you can print the raw Abstract Syntax Tree (AST) of a schema.
81
+ <details>
82
+ <summary><strong>Optimized LIR (lowered IR)</strong></summary>
247
83
 
248
- ```ruby
249
- puts Kumi::Support::SExpressionPrinter.print(FederalTax2024.__syntax_tree__)
250
- # => (Root
251
- # inputs: [
252
- # (InputDeclaration :income :float)
253
- # (InputDeclaration :filing_status :string domain: ["single", "married_joint"])
254
- # ]
255
- # traits: [...]
256
- # attributes: [...])
84
+ ```bash
85
+ # ...
86
+ (Declaration next_state
87
+ %t285 = load_input "rows" :: array
88
+ %t1539 = Length %t285 :: integer
89
+ %t1540 = const -1 :: integer
90
+ %t1542 = const 0 :: integer
91
+ %t1546 = const 1 :: integer
92
+ %t1334 = const 3 :: integer
93
+ %t1339 = const 2 :: integer
94
+ %t1547 = call core.sub(%t1539, %t1546) :: integer
95
+ loop rows id=L31 in %t285 as el=%rows_el_286, idx=%rows_i_287
96
+ %t1541 = call core.sub(%rows_i_287, %t1540) :: integer
97
+ %t1561 = call core.sub(%rows_i_287, %t1546) :: integer
98
+ %t1580 = call core.mod(%rows_i_287, %t1539) :: integer
99
+ # ...
257
100
  ```
258
101
 
259
102
  </details>
260
103
 
261
104
  <details>
262
- <summary><strong>Hierarchical Broadcasting</strong> - Vectorization over nested data structures</summary>
105
+ <summary><strong>Generated Ruby (excerpt)</strong></summary>
263
106
 
264
- ### Hierarchical Broadcasting
265
-
266
- Kumi broadcasts operations over hierarchical data structures with two complementary access modes for maximum flexibility.
267
-
268
- See [docs/features/hierarchical-broadcasting.md](docs/features/hierarchical-broadcasting.md) for detailed documentation.
269
-
270
- **Business Scenario**: E-commerce checkout with dynamic pricing rules
271
-
272
- > **"As an e-commerce platform, I need to calculate order totals with complex discount rules:**
273
- > - Premium members get 15% off electronics
274
- > - Bulk orders (5+ items) get 10% off that item
275
- > - Free shipping on orders over $100
276
- > - Calculate: item subtotals, total discounts, shipping, final total
277
- >
278
- > **The challenge:** Each order has different items, quantities, categories, and customer tiers. The discount logic involves multiple conditions - some items qualify for multiple discounts, others for none. Traditional pricing code requires nested if-statements and manual calculations."
279
-
280
- **Kumi Solution** (16 lines of declarative pricing logic):
281
107
  ```ruby
282
- module OrderPricing
283
- extend Kumi::Schema
284
-
285
- schema do
286
- input do
287
- array :items do
288
- float :price
289
- integer :quantity
290
- string :category
291
- end
292
- string :customer_tier
293
- float :shipping_threshold
294
- end
295
-
296
- # Calculate item subtotals and discount eligibility
297
- value :subtotals, input.items.price * input.items.quantity
298
- trait :electronics, input.items.category == "electronics"
299
- trait :bulk_item, input.items.quantity >= 5
300
- trait :premium_customer, input.customer_tier == "premium"
301
-
302
- # Apply layered discounts (premium + bulk can stack)
303
- trait :premium_electronics, premium_customer & electronics
304
- trait :stacked_discount, premium_electronics & bulk_item
305
-
306
- value :discounted_prices do
307
- on stacked_discount, input.items.price * 0.75 # 15% + 10% = 25% off
308
- on premium_electronics, input.items.price * 0.85 # 15% off
309
- on bulk_item, input.items.price * 0.90 # 10% off
310
- base input.items.price # No discount
311
- end
312
-
313
- value :final_subtotals, discounted_prices * input.items.quantity
314
-
315
- # Order totals and conditional shipping
316
- value :subtotal, fn(:sum, final_subtotals)
317
- value :total_savings, fn(:sum, subtotals) - subtotal
318
- value :shipping, subtotal > input.shipping_threshold ? 0.0 : 9.99
319
- value :total, subtotal + shipping
108
+ # Autogenerated by Kumi Codegen
109
+ module Kumi::Compiled::KUMI_bd17a3ebee1bec4e58b72118d43e8c1c93bf773f257fc93d9c32a783d212ea4f
110
+ def self.from(input_data = nil)
111
+ instance = Object.new
112
+ instance.extend(self)
113
+ instance.instance_variable_set(:@input, input_data)
114
+ instance
320
115
  end
321
- end
322
- ```
323
-
324
- **Mixed Access Modes**: Both object and element access can be used together in the same schema:
325
116
 
326
- ```ruby
327
- module UserAnalytics
328
- extend Kumi::Schema
329
-
330
- schema do
331
- input do
332
- # Object access mode - structured business data
333
- array :users do
334
- string :name
335
- integer :age
336
- end
337
-
338
- # Element access mode - multi-dimensional raw arrays
339
- array :recent_purchases do
340
- element :integer, :days_ago
341
- end
342
- end
117
+ def self.__kumi_executable__
118
+ instance = Object.new
119
+ instance.extend(self)
120
+ instance
121
+ end
343
122
 
344
- # Object access works normally
345
- value :user_names, input.users.name
346
- value :avg_age, fn(:avg, input.users.age)
347
-
348
- # Element access handles nested arrays with progressive path traversal
349
- value :all_purchase_days, fn(:flatten, input.recent_purchases.days_ago)
350
- value :recent_flags, input.recent_purchases.days_ago < 5
351
- trait :has_recent_purchase, fn(:any?, fn(:flatten, recent_flags))
352
-
353
- # Progressive dimensional analysis - each path level goes deeper
354
- value :purchase_dimensions, [
355
- fn(:size, input.recent_purchases), # Number of purchase groups
356
- fn(:size, input.recent_purchases.days_ago) # Total individual purchase days
357
- ]
358
-
359
- # Mixed usage in conditions
360
- trait :adult_users, input.users.age >= 18
361
- value :adult_count, fn(:count_if, adult_users)
123
+ def update(input_data)
124
+ @input = @input.merge(input_data)
125
+ self
362
126
  end
363
- end
364
127
 
365
- # Works with mixed data structures
366
- result = UserAnalytics.from({
367
- users: [{ name: "Alice", age: 25 }, { name: "Bob", age: 17 }],
368
- recent_purchases: [[1, 3, 7], [2, 4], [10, 15]] # Nested arrays
369
- })
128
+ def [](name)
129
+ case name
130
+ when :next_state then _next_state
131
+ else raise KeyError, "Unknown declaration"
132
+ end
133
+ end
370
134
 
371
- result[:user_names] # => ["Alice", "Bob"]
372
- result[:has_recent_purchase] # => true (some purchases < 5 days ago)
373
- result[:adult_count] # => 1
374
- result[:purchase_dimensions] # => [3, 8] (3 groups, 8 total days)
135
+ def _next_state(input = @input)
136
+ out = []
137
+ t285 = input["rows"] || input[:rows]
138
+ t1539 = t285.length
139
+ t1540 = -1
140
+ t1542 = 0
141
+ t1546 = 1
142
+ t1334 = 3
143
+ t1339 = 2
144
+ t1547 = t1539 - t1546
145
+ t285.each_with_index do |rows_el_286, rows_i_287|
146
+ out_1 = []
147
+ t1541 = rows_i_287 - t1540
148
+ t1561 = rows_i_287 - t1546
149
+ t1580 = rows_i_287 % t1539
150
+ t1543 = t1541 >= t1542
151
+ t1544 = t1541 < t1539
152
+ t1549 = [[ t1541, t1542 ].max, t1547 ].min
153
+ t1563 = t1561 >= t1542
154
+ # ...
375
155
  ```
376
156
 
377
157
  </details>
378
158
 
379
159
  <details>
380
- <summary><strong>Memoization</strong> - Each value computed exactly once</summary>
381
-
382
- ### Memoization
383
-
384
- Each value is computed exactly once:
385
-
386
- ```ruby
387
- runner = FederalTax2024.from(income: 250_000, filing_status: "married_joint")
388
-
389
- # First access computes full dependency chain
390
- runner[:total_tax] # => 53,155.20
391
-
392
- # Subsequent access uses cached values
393
- runner[:fed_tax] # => 39,077.00 (cached)
394
- runner[:after_tax] # => 196,844.80 (cached)
160
+ <summary><strong>Generated JavaScript (excerpt)</strong></summary>
161
+
162
+ ```js
163
+ export class KumiCompiledModule {
164
+ _next_state(input) {
165
+ let out = [];
166
+ let t285 = input["rows"];
167
+ let t1539 = t285.length
168
+ const t1540 = -1;
169
+ const t1542 = 0;
170
+ const t1546 = 1;
171
+ const t1334 = 3;
172
+ const t1339 = 2;
173
+ let t1547 = t1539 - t1546;
174
+ t285.forEach((rows_el_286, rows_i_287) => {
175
+ let out_1 = [];
176
+ let t1541 = rows_i_287 - t1540;
177
+ let t1561 = rows_i_287 - t1546;
178
+ let t1580 = ((rows_i_287 % t1539) + t1539) % t1539;
179
+ let t1543 = t1541 >= t1542;
180
+ let t1544 = t1541 < t1539;
181
+ let t1549 = Math.min(Math.max(t1541, t1542), t1547);
182
+ let t1563 = t1561 >= t1542;
183
+ let t1564 = t1561 < t1539;
184
+ let t1569 = Math.min(Math.max(t1561, t1542), t1547);
185
+ let t1581 = t1580 + t1539;
186
+ let t1545 = t1543 && t1544;
187
+ let t1550 = t285[t1549]
188
+ // ...
395
189
  ```
396
- </details>
397
-
398
- ## Usage
399
-
400
- **Suitable for:**
401
- - Complex interdependent business rules
402
- - Tax calculation engines
403
- - Insurance premium calculators
404
- - Commission structures with complex tiers
405
- - Pricing engines with multiple discount rules
406
-
407
- **Not suitable for:**
408
- - Basic conditional statements
409
- - Sequential procedural workflows
410
- - High-frequency processing
411
-
412
- ## Performance
413
190
 
414
- Benchmarks on Linux with Ruby 3.3.8 on a Dell Latitude 7450:
415
- - 50-deep dependency chain: **740,000/sec** (analysis <50ms)
416
- - 1,000 attributes: **131,000/sec** (analysis <50ms)
417
- - 10,000 attributes: **14,200/sec** (analysis ~300ms)
418
-
419
- See [docs/features/performance.md](docs/features/performance.md) for detailed benchmarks.
420
-
421
- ## What Kumi does not guarantee
191
+ </details>
422
192
 
423
- Lambdas (e.g. -> inside the schema), external IO, floating-point vs bignum, time-zone math differences, etc.
193
+ ---
424
194
 
425
- ## Learn More
195
+ ## Install
426
196
 
427
- - [DSL Syntax Reference](docs/SYNTAX.md)
428
- - [Examples](examples/)/
197
+ ```bash
198
+ gem install kumi
199
+ ```
429
200
 
430
- ## Contributing
201
+ Requires Ruby 3.1+. No external dependencies.
431
202
 
432
- Bug reports and pull requests are welcome on GitHub at https://github.com/amuta/kumi.
203
+ ---
433
204
 
434
205
  ## License
435
206
 
436
- MIT License. See [LICENSE](LICENSE).
207
+ MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,14 @@
1
+ functions:
2
+ - id: agg.any
3
+ kind: reduce
4
+ params: [{ name: source_value }]
5
+ dtype: "boolean"
6
+ aliases: ["any", "any?"]
7
+ folding_class_method: any?
8
+
9
+ - id: agg.all
10
+ kind: reduce
11
+ params: [{ name: source_value }]
12
+ dtype: "boolean"
13
+ aliases: ["all", "all?"]
14
+ folding_class_method: all?
@@ -0,0 +1,80 @@
1
+ functions:
2
+ - id: agg.sum
3
+ kind: reduce
4
+ params: [{ name: source_value }]
5
+ dtype: "same_as(source_value)"
6
+ reduction_strategy: identity # This function has a true identity value.
7
+ aliases: ["sum"]
8
+
9
+ - id: agg.count
10
+ kind: reduce
11
+ params: [{ name: source_value }]
12
+ dtype: "integer"
13
+ reduction_strategy: identity # This function has a true identity value.
14
+ aliases: ["count"]
15
+
16
+ - id: agg.min
17
+ kind: reduce
18
+ params: [{ name: source_value }]
19
+ dtype: "element_of(source_value)"
20
+ reduction_strategy: first_element
21
+ aliases: ["min"]
22
+
23
+ - id: agg.max
24
+ kind: reduce
25
+ params: [{ name: source_value }]
26
+ dtype: "element_of(source_value)"
27
+ reduction_strategy: first_element
28
+ aliases: ["max"]
29
+
30
+ - id: agg.mean
31
+ kind: reduce
32
+ params: [{ name: source_value }]
33
+ dtype: "float"
34
+ aliases: ["mean", "avg"]
35
+ expand:
36
+ fn: div
37
+ args:
38
+ - fn: sum
39
+ args: [ "$1" ] # $1 is source_value
40
+ - fn: count
41
+ args: [ "$1" ]
42
+
43
+ - id: agg.sum_if
44
+ kind: reduce
45
+ params: [{ name: source_value }, { name: condition }]
46
+ dtype: "same_as(source_value)"
47
+ aliases: ["sum_if"]
48
+ expand:
49
+ fn: sum
50
+ args:
51
+ - fn: __select__
52
+ args: [ "$2", "$1", { const: 0 } ] # $1=source_value, $2=condition
53
+
54
+ - id: agg.count_if
55
+ kind: reduce
56
+ params: [{ name: condition }, { name: source_value }]
57
+ dtype: "integer"
58
+ aliases: ["count_if"]
59
+ expand:
60
+ fn: sum # Summing 1s and 0s is equivalent to a conditional count
61
+ args:
62
+ - fn: __select__
63
+ args:
64
+ - fn: eq
65
+ args: ["$1", "$2"]
66
+ - { const: 1 }
67
+ - { const: 0 }
68
+
69
+ - id: agg.mean_if
70
+ kind: reduce
71
+ params: [{ name: source_value }, { name: condition }]
72
+ dtype: "float"
73
+ aliases: ["avg_if", "mean_if"]
74
+ expand:
75
+ fn: div
76
+ args:
77
+ - fn: sum_if
78
+ args: [ "$1", "$2" ] # Sum the values where the condition is true
79
+ - fn: count_if
80
+ args: [ "$1", "$2" ] # Count the values where the condition is true
@@ -0,0 +1,8 @@
1
+ functions:
2
+ - id: agg.join
3
+ kind: reduce
4
+ params: [{ name: source_value, dtype: string }]
5
+ dtype: "string"
6
+ reduction_strategy: first_element
7
+ aliases: ["join"]
8
+