kumi 0.0.17 → 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 +28 -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
@@ -13,37 +13,37 @@ module Kumi
13
13
  class << self
14
14
  def enabled? = ENV["KUMI_PROFILE"] == "1"
15
15
  def ops_enabled? = ENV.fetch("KUMI_PROFILE_OPS", "1") == "1"
16
- def sample_rate = (ENV["KUMI_PROFILE_SAMPLE"]&.to_i || 1)
16
+ def sample_rate = ENV["KUMI_PROFILE_SAMPLE"]&.to_i || 1
17
17
  def persistent? = ENV["KUMI_PROFILE_PERSISTENT"] == "1"
18
-
18
+
19
19
  def set_schema_name(name)
20
20
  @schema_name = name
21
-
21
+
22
22
  # Ensure profiler is initialized in persistent mode
23
- unless @initialized
24
- @events = []
25
- @meta = {}
26
- @file = ENV["KUMI_PROFILE_FILE"] || "tmp/profile.jsonl"
27
- @run_id ||= 1
28
- @op_seq ||= 0
29
- @aggregated_stats ||= Hash.new { |h, k| h[k] = { count: 0, total_ms: 0.0, total_cpu_ms: 0.0, rows: 0, runs: Set.new } }
30
-
31
- # Truncate file if needed
32
- if ENV["KUMI_PROFILE_TRUNCATE"] == "1" && !@persistent_initialized
33
- FileUtils.mkdir_p(File.dirname(@file))
34
- File.write(@file, "")
35
- @aggregated_stats.clear
36
- @persistent_initialized = true
37
- end
38
-
39
- @initialized = true
23
+ return if @initialized
24
+
25
+ @events = []
26
+ @meta = {}
27
+ @file = ENV["KUMI_PROFILE_FILE"] || "tmp/profile.jsonl"
28
+ @run_id ||= 1
29
+ @op_seq ||= 0
30
+ @aggregated_stats ||= Hash.new { |h, k| h[k] = { count: 0, total_ms: 0.0, total_cpu_ms: 0.0, rows: 0, runs: Set.new } }
31
+
32
+ # Truncate file if needed
33
+ if ENV["KUMI_PROFILE_TRUNCATE"] == "1" && !@persistent_initialized
34
+ FileUtils.mkdir_p(File.dirname(@file))
35
+ File.write(@file, "")
36
+ @aggregated_stats.clear
37
+ @persistent_initialized = true
40
38
  end
39
+
40
+ @initialized = true
41
41
  end
42
42
 
43
43
  def reset!(meta: {})
44
44
  set_schema_name(meta[:schema_name]) if meta[:schema_name]
45
45
  return unless enabled?
46
-
46
+
47
47
  # In persistent mode, don't reset aggregated stats or increment run_id
48
48
  # This allows profiling across multiple schema creations
49
49
  if persistent?
@@ -54,7 +54,7 @@ module Kumi
54
54
  @run_id ||= 1
55
55
  @op_seq ||= 0
56
56
  @aggregated_stats ||= Hash.new { |h, k| h[k] = { count: 0, total_ms: 0.0, total_cpu_ms: 0.0, rows: 0, runs: Set.new } }
57
-
57
+
58
58
  # Only truncate on very first reset in persistent mode
59
59
  if ENV["KUMI_PROFILE_TRUNCATE"] == "1" && !@persistent_initialized
60
60
  FileUtils.mkdir_p(File.dirname(@file))
@@ -70,8 +70,10 @@ module Kumi
70
70
  @file = ENV["KUMI_PROFILE_FILE"] || "tmp/profile.jsonl"
71
71
  @run_id = (@run_id || 0) + 1
72
72
  @op_seq = 0
73
- @aggregated_stats = (@aggregated_stats || Hash.new { |h, k| h[k] = { count: 0, total_ms: 0.0, total_cpu_ms: 0.0, rows: 0, runs: Set.new } })
74
-
73
+ @aggregated_stats ||= Hash.new do |h, k|
74
+ h[k] = { count: 0, total_ms: 0.0, total_cpu_ms: 0.0, rows: 0, runs: Set.new }
75
+ end
76
+
75
77
  if ENV["KUMI_PROFILE_TRUNCATE"] == "1"
76
78
  FileUtils.mkdir_p(File.dirname(@file))
77
79
  File.write(@file, "")
@@ -84,7 +86,7 @@ module Kumi
84
86
  def t0
85
87
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
86
88
  end
87
-
89
+
88
90
  # CPU time start (process + thread)
89
91
  def cpu_t0
90
92
  Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID)
@@ -93,83 +95,87 @@ module Kumi
93
95
  # Phase timing for coarse-grained operations
94
96
  def phase(name, tags = {})
95
97
  return yield unless enabled?
96
- p0 = t0; c0 = cpu_t0
98
+
99
+ p0 = t0
100
+ c0 = cpu_t0
97
101
  result = yield
98
102
  wall_ms = (t0 - p0) * 1000.0
99
103
  cpu_ms = (cpu_t0 - c0) * 1000.0
100
104
  stream({
101
- ts: Time.now.utc.iso8601(3),
102
- kind: "phase",
103
- name: name,
104
- wall_ms: wall_ms.round(3),
105
- cpu_ms: cpu_ms.round(3),
106
- tags: tags,
107
- run: @run_id
108
- })
105
+ ts: Time.now.utc.iso8601(3),
106
+ kind: "phase",
107
+ name: name,
108
+ wall_ms: wall_ms.round(3),
109
+ cpu_ms: cpu_ms.round(3),
110
+ tags: tags,
111
+ run: @run_id
112
+ })
109
113
  result
110
114
  end
111
115
 
112
116
  # Memory snapshot with GC statistics
113
117
  def memory_snapshot(label, extra: {})
114
118
  return unless enabled?
119
+
115
120
  s = GC.stat
116
121
  stream({
117
- ts: Time.now.utc.iso8601(3),
118
- kind: "mem",
119
- label: label,
120
- heap_live: s[:heap_live_slots],
121
- old_objects: s[:old_objects],
122
- minor_gc: s[:minor_gc_count],
123
- major_gc: s[:major_gc_count],
124
- rss_mb: read_rss_mb,
125
- run: @run_id,
126
- **extra
127
- })
122
+ ts: Time.now.utc.iso8601(3),
123
+ kind: "mem",
124
+ label: label,
125
+ heap_live: s[:heap_live_slots],
126
+ old_objects: s[:old_objects],
127
+ minor_gc: s[:minor_gc_count],
128
+ major_gc: s[:major_gc_count],
129
+ rss_mb: read_rss_mb,
130
+ run: @run_id,
131
+ **extra
132
+ })
128
133
  end
129
134
 
130
135
  def read_rss_mb
131
- ((File.read("/proc/#{$$}/status")[/VmRSS:\s+(\d+)\skB/, 1].to_i) / 1024.0).round(2)
132
- rescue
136
+ (File.read("/proc/#{$$}/status")[/VmRSS:\s+(\d+)\skB/, 1].to_i / 1024.0).round(2)
137
+ rescue StandardError
133
138
  nil
134
139
  end
135
140
 
136
141
  # Per-op record with both wall time and CPU time (with sampling support)
137
142
  def record!(decl:, idx:, tag:, op:, t0:, cpu_t0: nil, rows: nil, note: nil)
138
143
  return unless enabled? && ops_enabled?
144
+
139
145
  @op_seq += 1
140
146
  return unless sample_rate <= 1 || (@op_seq % sample_rate).zero?
141
-
147
+
142
148
  wall_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0) * 1000.0)
143
149
  cpu_ms = cpu_t0 ? ((Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID) - cpu_t0) * 1000.0) : wall_ms
144
-
150
+
145
151
  ev = {
146
- ts: Time.now.utc.iso8601(3),
147
- run: @run_id,
148
- schema: @schema_name, # schema identifier for multi-schema differentiation
149
- decl: decl, # decl name (string/symbol)
150
- i: idx, # op index
151
- tag: tag, # op tag (symbol)
152
+ ts: Time.now.utc.iso8601(3),
153
+ run: @run_id,
154
+ schema: @schema_name, # schema identifier for multi-schema differentiation
155
+ decl: decl, # decl name (string/symbol)
156
+ i: idx, # op index
157
+ tag: tag, # op tag (symbol)
152
158
  wall_ms: wall_ms.round(4),
153
- cpu_ms: cpu_ms.round(4),
154
- rows: rows,
155
- note: note,
156
- key: op_key(decl, idx, tag, op), # stable key for grep/diff
157
- attrs: compact_attrs(op.attrs)
159
+ cpu_ms: cpu_ms.round(4),
160
+ rows: rows,
161
+ note: note,
162
+ key: op_key(decl, idx, tag, op), # stable key for grep/diff
163
+ attrs: compact_attrs(op.attrs)
158
164
  }
159
-
165
+
160
166
  # Aggregate stats for multi-run averaging
161
167
  op_key = "#{decl}@#{idx}:#{tag}"
162
168
  agg = @aggregated_stats[op_key]
163
169
  agg[:count] += 1
164
170
  agg[:total_ms] += wall_ms
165
171
  agg[:total_cpu_ms] += cpu_ms
166
- agg[:rows] += (rows || 0)
172
+ agg[:rows] += rows || 0
167
173
  agg[:runs] << @run_id
168
174
  agg[:decl] = decl
169
175
  agg[:tag] = tag
170
176
  agg[:idx] = idx
171
177
  agg[:note] = note if note
172
-
178
+
173
179
  (@events ||= []) << ev
174
180
  stream(ev) if ENV["KUMI_PROFILE_STREAM"] == "1"
175
181
  ev
@@ -177,43 +183,43 @@ module Kumi
177
183
 
178
184
  def summary(top: 20)
179
185
  return {} unless enabled?
180
-
186
+
181
187
  # Current run summary (legacy format)
182
188
  current_agg = Hash.new { |h, k| h[k] = { count: 0, ms: 0.0, rows: 0 } }
183
189
  (@events || []).each do |e|
184
190
  k = [e[:decl], e[:tag]]
185
191
  a = current_agg[k]
186
192
  a[:count] += 1
187
- a[:ms] += (e[:wall_ms] || e[:ms] || 0)
188
- a[:rows] += (e[:rows] || 0)
193
+ a[:ms] += e[:wall_ms] || e[:ms] || 0
194
+ a[:rows] += e[:rows] || 0
189
195
  end
190
- current_ranked = current_agg.map { |(decl, tag), v|
196
+ current_ranked = current_agg.map do |(decl, tag), v|
191
197
  { decl: decl, tag: tag, count: v[:count], ms: v[:ms].round(3), rows: v[:rows],
192
198
  rps: v[:rows] > 0 ? (v[:rows] / v[:ms]).round(1) : nil }
193
- }.sort_by { |h| -h[:ms] }.first(top)
199
+ end.sort_by { |h| -h[:ms] }.first(top)
194
200
 
195
201
  { meta: @meta || {}, top: current_ranked,
196
- total_ms: ((@events || []).sum { |e| e[:wall_ms] || e[:ms] || 0 }).round(3),
202
+ total_ms: (@events || []).sum { |e| e[:wall_ms] || e[:ms] || 0 }.round(3),
197
203
  op_count: (@events || []).size,
198
204
  run_id: @run_id }
199
205
  end
200
-
206
+
201
207
  # Multi-run averaged analysis
202
208
  def averaged_analysis(top: 20)
203
209
  return {} unless enabled? && @aggregated_stats&.any?
204
-
210
+
205
211
  # Convert aggregated stats to averaged metrics
206
212
  averaged = @aggregated_stats.map do |op_key, stats|
207
213
  num_runs = stats[:runs].size
208
214
  avg_wall_ms = stats[:total_ms] / stats[:count]
209
- avg_cpu_ms = stats[:total_cpu_ms] / stats[:count]
215
+ avg_cpu_ms = stats[:total_cpu_ms] / stats[:count]
210
216
  total_wall_ms = stats[:total_ms]
211
217
  total_cpu_ms = stats[:total_cpu_ms]
212
-
218
+
213
219
  {
214
220
  op_key: op_key,
215
221
  decl: stats[:decl],
216
- idx: stats[:idx],
222
+ idx: stats[:idx],
217
223
  tag: stats[:tag],
218
224
  runs: num_runs,
219
225
  total_calls: stats[:count],
@@ -227,28 +233,28 @@ module Kumi
227
233
  note: stats[:note]
228
234
  }
229
235
  end.sort_by { |s| -s[:total_wall_ms] }.first(top)
230
-
236
+
231
237
  {
232
238
  meta: @meta || {},
233
- total_runs: (@aggregated_stats.values.map { |s| s[:runs].size }.max || 0),
239
+ total_runs: @aggregated_stats.values.map { |s| s[:runs].size }.max || 0,
234
240
  averaged_ops: averaged,
235
241
  total_operations: @aggregated_stats.size
236
242
  }
237
243
  end
238
-
244
+
239
245
  # Identify potential cache overhead operations
240
246
  def cache_overhead_analysis
241
247
  return {} unless enabled? && @aggregated_stats&.any?
242
-
248
+
243
249
  # Look for operations that might be cache-related
244
250
  cache_ops = @aggregated_stats.select do |op_key, stats|
245
251
  op_key.include?("ref") || op_key.include?("load_input") || stats[:note]&.include?("cache")
246
252
  end
247
-
253
+
248
254
  cache_analysis = cache_ops.map do |op_key, stats|
249
- num_runs = stats[:runs].size
255
+ stats[:runs].size
250
256
  avg_wall_ms = stats[:total_ms] / stats[:count]
251
-
257
+
252
258
  {
253
259
  op_key: op_key,
254
260
  decl: stats[:decl],
@@ -259,7 +265,7 @@ module Kumi
259
265
  overhead_per_call: avg_wall_ms.round(6)
260
266
  }
261
267
  end.sort_by { |s| -s[:total_time_ms] }
262
-
268
+
263
269
  {
264
270
  cache_operations: cache_analysis,
265
271
  total_cache_time: cache_analysis.sum { |op| op[:total_time_ms] }.round(3)
@@ -268,47 +274,50 @@ module Kumi
268
274
 
269
275
  def emit_summary!
270
276
  return unless enabled?
277
+
271
278
  stream({ ts: Time.now.utc.iso8601(3), kind: "summary", data: summary })
272
279
  end
273
280
 
274
281
  def init_persistent!
275
282
  return unless enabled? && persistent?
283
+
276
284
  @persistent_initialized = false
277
285
  reset!
278
286
  end
279
287
 
280
288
  def finalize!
281
289
  return unless enabled?
282
-
290
+
283
291
  # Emit final aggregated summary
284
292
  if @aggregated_stats&.any?
285
293
  stream({
286
- ts: Time.now.utc.iso8601(3),
287
- kind: "final_summary",
288
- data: averaged_analysis
289
- })
294
+ ts: Time.now.utc.iso8601(3),
295
+ kind: "final_summary",
296
+ data: averaged_analysis
297
+ })
290
298
  end
291
-
299
+
292
300
  # Emit cache analysis if available
293
301
  cache_analysis = cache_overhead_analysis
294
- if cache_analysis[:cache_operations]&.any?
295
- stream({
296
- ts: Time.now.utc.iso8601(3),
297
- kind: "cache_analysis",
298
- data: cache_analysis
299
- })
300
- end
302
+ return unless cache_analysis[:cache_operations]&.any?
303
+
304
+ stream({
305
+ ts: Time.now.utc.iso8601(3),
306
+ kind: "cache_analysis",
307
+ data: cache_analysis
308
+ })
301
309
  end
302
310
 
303
311
  # Stable textual key for "match ops one by one"
304
312
  def op_key(decl, idx, tag, op)
305
313
  attrs = compact_attrs(op.attrs)
306
314
  args = op.args
307
- "#{decl}@#{idx}:#{tag}|#{attrs.keys.sort_by(&:to_s).map { |k| "#{k}=#{attrs[k].inspect}" }.join(",")}|args=#{args.inspect}"
315
+ "#{decl}@#{idx}:#{tag}|#{attrs.keys.sort_by(&:to_s).map { |k| "#{k}=#{attrs[k].inspect}" }.join(',')}|args=#{args.inspect}"
308
316
  end
309
317
 
310
318
  def compact_attrs(h)
311
319
  return {} unless h
320
+
312
321
  h.transform_values do |v|
313
322
  case v
314
323
  when Array, Hash, Symbol, String, Numeric, TrueClass, FalseClass, NilClass then v
@@ -319,6 +328,7 @@ module Kumi
319
328
 
320
329
  def stream(obj)
321
330
  return unless @file
331
+
322
332
  FileUtils.mkdir_p(File.dirname(@file))
323
333
  File.open(@file, "a") { |f| f.puts(obj.to_json) }
324
334
  end
@@ -327,4 +337,4 @@ module Kumi
327
337
  end
328
338
  end
329
339
  end
330
- end
340
+ end
data/lib/kumi/core/ir.rb CHANGED
@@ -27,7 +27,11 @@ module Kumi
27
27
 
28
28
  module IR::Ops
29
29
  def self.Const(v) = IR::Op.new(tag: :const, attrs: { value: v }, args: [])
30
- def self.LoadInput(plan_id, scope: [], is_scalar: false, has_idx: false) = IR::Op.new(tag: :load_input, attrs: { plan_id: plan_id, scope: scope, is_scalar: is_scalar, has_idx: has_idx }, args: [])
30
+
31
+ def self.LoadInput(plan_id, scope: [], is_scalar: false,
32
+ has_idx: false) = IR::Op.new(tag: :load_input,
33
+ attrs: { plan_id: plan_id, scope: scope, is_scalar: is_scalar, has_idx: has_idx }, args: [])
34
+
31
35
  def self.Ref(name) = IR::Op.new(tag: :ref, attrs: { name: name }, args: [])
32
36
  def self.Map(fn, argc, *slots) = IR::Op.new(tag: :map, attrs: { fn: fn, argc: argc }, args: slots)
33
37
  def self.Array(count, *slots) = IR::Op.new(tag: :array, attrs: { count: count }, args: slots)
@@ -38,7 +42,7 @@ module Kumi
38
42
  def self.Store(name, slot) = IR::Op.new(tag: :store, attrs: { name: name }, args: [slot])
39
43
  def self.Lift(to_scope, slot) = IR::Op.new(tag: :lift, attrs: { to_scope: to_scope }, args: [slot])
40
44
  def self.Join(*slots) = IR::Op.new(tag: :join, attrs: {}, args: slots)
41
-
45
+
42
46
  # Up-sample `source` to the scope (and order) of `target` by index-prefix.
43
47
  # Policies: :error | :nil for missing; require_unique: true enforces 1:1 on prefix.
44
48
  def self.AlignTo(target_slot, source_slot, to_scope:, on_missing: :error, require_unique: true)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Kumi
6
+ module Core
7
+ module IRV2
8
+ class Builder
9
+ attr_reader :values, :exports
10
+
11
+ def initialize
12
+ @next_id = 0
13
+ @values = []
14
+ @exports = []
15
+ end
16
+
17
+ def load_input(path, stamp: nil) = emit(:LoadInput, [path], {}, stamp: stamp)
18
+ def load_declaration(name, stamp: nil) = emit(:LoadDeclaration, [name], {}, stamp: stamp)
19
+ def load_decl(name, stamp: nil) = emit(:LoadDecl, [name], {}, stamp: stamp)
20
+ def const(lit, stamp: nil) = emit(:Const, [lit], {}, stamp: stamp)
21
+ def align_to(v, target_axes, stamp: nil) = emit(:AlignTo, [v], { target_axes: Array(target_axes).map(&:to_s) }, stamp: stamp)
22
+ def select(cond, then_v, else_v, stamp: nil) = emit(:Select, [cond, then_v, else_v], {}, stamp: stamp)
23
+ def map(func, *values, stamp: nil) = emit(:Map, values, { fn: func }, stamp: stamp)
24
+ def reduce(func, val, axis, stamp: nil) = emit(:Reduce, [val], { fn: func, axis: axis.to_s }, stamp: stamp)
25
+ def construct_tuple(*vs, stamp: nil) = emit(:ConstructTuple, vs, {}, stamp: stamp)
26
+ def tuple_get(v, index, stamp: nil) = emit(:TupleGet, [v], { index: index }, stamp: stamp)
27
+
28
+ def store(name, v)
29
+ (@exports << [name, v]
30
+ nil)
31
+ end
32
+
33
+ def dump
34
+ [*values.map(&:to_s), *exports.map { |(n, v)| "Store #{n}, %#{v.id}" }].join("\n")
35
+ end
36
+
37
+ private
38
+
39
+ def emit(op, args, attrs, stamp: nil, elem_stamps: nil)
40
+ v = Value.new(@next_id, op, args, attrs, stamp: stamp, elem_stamps: elem_stamps)
41
+ @values << v
42
+ @next_id += 1
43
+ v
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Kumi
6
+ module Core
7
+ module IRV2
8
+ class Declaration
9
+ attr_reader :name, :operations, :result, :parameters
10
+
11
+ def initialize(name, operations, result, parameters = [])
12
+ @name = name
13
+ @operations = operations
14
+ @result = result
15
+ @parameters = parameters
16
+ end
17
+
18
+ def inputs
19
+ @parameters.select { |p| p[:type] == :input }
20
+ end
21
+
22
+ def dependencies
23
+ @parameters.select { |p| p[:type] == :dependency }.map { |p| p[:source] }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Kumi
6
+ module Core
7
+ module IRV2
8
+ class Module
9
+ attr_reader :declarations, :metadata
10
+
11
+ def initialize(declarations, metadata = {})
12
+ @declarations = declarations
13
+ @metadata = metadata
14
+ end
15
+
16
+ def to_s
17
+ format_declaration_based
18
+ end
19
+
20
+ private
21
+
22
+ def format_declaration_based
23
+ output = []
24
+ output << "; — Module: Declaration-Based IR"
25
+ output << ""
26
+
27
+ @declarations.each do |name, decl|
28
+ output << "Declaration #{name} {"
29
+
30
+ unless decl.parameters.empty?
31
+ output << " params:"
32
+ decl.parameters.each do |param|
33
+ case param[:type]
34
+ when :input
35
+ output << " #{param[:name]} : View(#{param[:dtype]}, axes=#{param[:axes]})"
36
+ when :dependency
37
+ output << " #{param[:name]} : View(#{param[:dtype]}, axes=#{param[:axes]}) ; #{param[:source]}"
38
+ end
39
+ end
40
+ end
41
+
42
+ output << " operations: ["
43
+ decl.operations.each do |op|
44
+ comment = format_operation_comment(op)
45
+ op_str = format_operation(op)
46
+ padding = [50 - op_str.length, 1].max
47
+ output << " #{op_str}#{' ' * padding}; #{comment}"
48
+ end
49
+ output << " ]"
50
+ output << " result: %#{decl.result.id}"
51
+ output << "}"
52
+ output << ""
53
+ end
54
+
55
+ # Add canonical inputs if available
56
+ if @metadata.dig("analysis", "inputs")
57
+ output << "; — Canonical Inputs"
58
+ output << ""
59
+ @metadata["analysis"]["inputs"].each do |input|
60
+ path_str = input["path"].join(".")
61
+ scope_str = input["scope"].empty? ? "[]" : "[#{input['scope'].join(', ')}]"
62
+ output << "#{path_str}: #{input['dtype']} (scope=#{scope_str})"
63
+ end
64
+ output << ""
65
+ end
66
+
67
+ output.join("\n")
68
+ end
69
+
70
+ def format_operation(val)
71
+ case val.op
72
+ when :LoadInput
73
+ "%#{val.id} = LoadInput #{val.args.first.inspect}"
74
+ when :LoadDeclaration
75
+ "%#{val.id} = LoadDeclaration #{val.args.first.inspect}"
76
+ when :LoadDecl
77
+ "%#{val.id} = LoadDecl #{val.args.first.inspect}"
78
+ when :Map
79
+ args_str = val.args.map { |a| "%#{a.id}" }.join(", ")
80
+ op_name = val.attrs[:fn] || "unknown"
81
+ "%#{val.id} = Map(#{op_name}, #{args_str})"
82
+ when :Reduce
83
+ op_name = val.attrs[:fn] || "unknown"
84
+ last_axis = val.attrs[:axis]
85
+ "%#{val.id} = Reduce(#{op_name}, %#{val.args.first.id}, #{last_axis.inspect})"
86
+ when :AlignTo
87
+ axes_str = val.attrs[:target_axes].map(&:inspect).join(",")
88
+ "%#{val.id} = AlignTo(%#{val.args.first.id}, [#{axes_str}])"
89
+ when :ConstructTuple
90
+ args_str = val.args.map { |a| "%#{a.id}" }.join(", ")
91
+ "%#{val.id} = ConstructTuple(#{args_str})"
92
+ else
93
+ val.to_s
94
+ end
95
+ end
96
+
97
+ def format_operation_comment(val)
98
+ # Extract dimensional information from metadata if available
99
+ scope = metadata.dig(:operation_scopes, val.id) || []
100
+ dtype = metadata.dig(:operation_types, val.id) || :unknown
101
+
102
+ scope_str = scope.empty? ? "[]" : "[#{scope.map(&:inspect).join(',')}]"
103
+ "#{scope_str}, #{dtype}"
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
5
+ module Kumi
6
+ module Core
7
+ module IRV2
8
+ class Value
9
+ attr_reader :id, :op, :args, :attrs, :stamp, :elem_stamps
10
+
11
+ def initialize(id, op, args, attrs, stamp: nil, elem_stamps: nil)
12
+ @id = id
13
+ @op = op
14
+ @args = args
15
+ @attrs = attrs
16
+ @stamp = stamp
17
+ @elem_stamps = elem_stamps
18
+ end
19
+
20
+ def to_s
21
+ a = args.map { |x| x.is_a?(Value) ? "%#{x.id}" : x.inspect }.join(", ")
22
+ attrs_s = attrs.empty? ? "" : " " + attrs.map { |k, v| "#{k}: #{v.inspect}" }.join(", ")
23
+ format("%%%d = %s(%s)%s", id, op, a, attrs_s)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end