universal-physics-tensor 10.0.0 → 12.0.0

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 (835) hide show
  1. package/README.md +39 -36
  2. package/bin/upt.mjs +13 -1
  3. package/data/applied-cases.json +1892 -0
  4. package/data/applied-cases.schema.json +194 -0
  5. package/data/atlas/atlas.json +25 -25
  6. package/data/atlas/atlas.jsonld +1 -1
  7. package/data/atlas/diffusion.json +6 -6
  8. package/data/atlas/oscillators.json +7 -7
  9. package/data/atlas/waves.json +14 -14
  10. package/data/atlas/witness-results.json +11 -11
  11. package/data/bridge-catalog.json +389 -230
  12. package/data/bridge-catalog.schema.json +45 -7
  13. package/data/units.json +6 -25
  14. package/dist/atlas/applicability.d.ts.map +1 -1
  15. package/dist/atlas/applicability.js +21 -15
  16. package/dist/atlas/applicability.js.map +1 -1
  17. package/dist/atlas/benchmark/hybrid-retrieval.d.ts +9 -1
  18. package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -1
  19. package/dist/atlas/benchmark/hybrid-retrieval.js +15 -13
  20. package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -1
  21. package/dist/atlas/benchmark/loader.js +2 -2
  22. package/dist/atlas/benchmark/loader.js.map +1 -1
  23. package/dist/atlas/benchmark/stats.d.ts +2 -2
  24. package/dist/atlas/benchmark/stats.d.ts.map +1 -1
  25. package/dist/atlas/benchmark/stats.js +9 -15
  26. package/dist/atlas/benchmark/stats.js.map +1 -1
  27. package/dist/atlas/catalog-formal-ref.d.ts +26 -3
  28. package/dist/atlas/catalog-formal-ref.d.ts.map +1 -1
  29. package/dist/atlas/catalog-formal-ref.js +52 -5
  30. package/dist/atlas/catalog-formal-ref.js.map +1 -1
  31. package/dist/atlas/chain-pipeline.d.ts.map +1 -1
  32. package/dist/atlas/chain-pipeline.js +7 -8
  33. package/dist/atlas/chain-pipeline.js.map +1 -1
  34. package/dist/atlas/diffusion/bridges-closure.d.ts +0 -4
  35. package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
  36. package/dist/atlas/diffusion/bridges-closure.js +8 -12
  37. package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
  38. package/dist/atlas/diffusion/bridges.d.ts.map +1 -1
  39. package/dist/atlas/diffusion/bridges.js +27 -39
  40. package/dist/atlas/diffusion/bridges.js.map +1 -1
  41. package/dist/atlas/diffusion/dimensions.d.ts +6 -14
  42. package/dist/atlas/diffusion/dimensions.d.ts.map +1 -1
  43. package/dist/atlas/diffusion/dimensions.js +8 -16
  44. package/dist/atlas/diffusion/dimensions.js.map +1 -1
  45. package/dist/atlas/diffusion/models.d.ts +3 -3
  46. package/dist/atlas/diffusion/models.d.ts.map +1 -1
  47. package/dist/atlas/diffusion/models.js +5 -10
  48. package/dist/atlas/diffusion/models.js.map +1 -1
  49. package/dist/atlas/diffusion/numerics.d.ts +16 -4
  50. package/dist/atlas/diffusion/numerics.d.ts.map +1 -1
  51. package/dist/atlas/diffusion/numerics.js +38 -24
  52. package/dist/atlas/diffusion/numerics.js.map +1 -1
  53. package/dist/atlas/link-prediction.d.ts +106 -3
  54. package/dist/atlas/link-prediction.d.ts.map +1 -1
  55. package/dist/atlas/link-prediction.js +212 -66
  56. package/dist/atlas/link-prediction.js.map +1 -1
  57. package/dist/atlas/oscillators/bridges-coarse.d.ts.map +1 -1
  58. package/dist/atlas/oscillators/bridges-coarse.js +7 -11
  59. package/dist/atlas/oscillators/bridges-coarse.js.map +1 -1
  60. package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
  61. package/dist/atlas/oscillators/bridges-exact.js +6 -7
  62. package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
  63. package/dist/atlas/oscillators/bridges-limits.d.ts +3 -16
  64. package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
  65. package/dist/atlas/oscillators/bridges-limits.js +23 -34
  66. package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
  67. package/dist/atlas/oscillators/dimensions.d.ts +9 -21
  68. package/dist/atlas/oscillators/dimensions.d.ts.map +1 -1
  69. package/dist/atlas/oscillators/dimensions.js +9 -21
  70. package/dist/atlas/oscillators/dimensions.js.map +1 -1
  71. package/dist/atlas/oscillators/limit-witnesses.d.ts +2 -2
  72. package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -1
  73. package/dist/atlas/oscillators/limit-witnesses.js +17 -15
  74. package/dist/atlas/oscillators/limit-witnesses.js.map +1 -1
  75. package/dist/atlas/oscillators/models.d.ts.map +1 -1
  76. package/dist/atlas/oscillators/models.js +2 -6
  77. package/dist/atlas/oscillators/models.js.map +1 -1
  78. package/dist/atlas/oscillators/pendulum-motion.d.ts +29 -6
  79. package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -1
  80. package/dist/atlas/oscillators/pendulum-motion.js +60 -40
  81. package/dist/atlas/oscillators/pendulum-motion.js.map +1 -1
  82. package/dist/atlas/oscillators/phase-translation.d.ts +0 -11
  83. package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -1
  84. package/dist/atlas/oscillators/phase-translation.js +3 -4
  85. package/dist/atlas/oscillators/phase-translation.js.map +1 -1
  86. package/dist/atlas/oscillators/position-translation.d.ts +68 -7
  87. package/dist/atlas/oscillators/position-translation.d.ts.map +1 -1
  88. package/dist/atlas/oscillators/position-translation.js +123 -12
  89. package/dist/atlas/oscillators/position-translation.js.map +1 -1
  90. package/dist/atlas/oscillators/rejections.d.ts +0 -2
  91. package/dist/atlas/oscillators/rejections.d.ts.map +1 -1
  92. package/dist/atlas/oscillators/rejections.js +0 -7
  93. package/dist/atlas/oscillators/rejections.js.map +1 -1
  94. package/dist/atlas/physjs-entries.generated.d.ts +35 -25
  95. package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
  96. package/dist/atlas/physjs-entries.generated.js +37 -25
  97. package/dist/atlas/physjs-entries.generated.js.map +1 -1
  98. package/dist/atlas/physjs-ref.d.ts +34 -31
  99. package/dist/atlas/physjs-ref.d.ts.map +1 -1
  100. package/dist/atlas/physjs-ref.js +55 -53
  101. package/dist/atlas/physjs-ref.js.map +1 -1
  102. package/dist/atlas/physjs-reviewed.d.ts +1 -1
  103. package/dist/atlas/physjs-reviewed.js +15 -15
  104. package/dist/atlas/physjs-reviewed.js.map +1 -1
  105. package/dist/atlas/poster/statements.d.ts +0 -19
  106. package/dist/atlas/poster/statements.d.ts.map +1 -1
  107. package/dist/atlas/poster/statements.js +1 -1
  108. package/dist/atlas/poster/statements.js.map +1 -1
  109. package/dist/atlas/proof-target.d.ts +1 -1
  110. package/dist/atlas/proof-target.js +1 -1
  111. package/dist/atlas/proof-target.js.map +1 -1
  112. package/dist/atlas/regime.d.ts +1 -1
  113. package/dist/atlas/regime.d.ts.map +1 -1
  114. package/dist/atlas/regime.js +1 -1
  115. package/dist/atlas/regime.js.map +1 -1
  116. package/dist/atlas/text-overlap.d.ts +23 -0
  117. package/dist/atlas/text-overlap.d.ts.map +1 -0
  118. package/dist/atlas/text-overlap.js +41 -0
  119. package/dist/atlas/text-overlap.js.map +1 -0
  120. package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
  121. package/dist/atlas/waves/bridges-closure.js +2 -6
  122. package/dist/atlas/waves/bridges-closure.js.map +1 -1
  123. package/dist/atlas/waves/bridges.d.ts.map +1 -1
  124. package/dist/atlas/waves/bridges.js +32 -48
  125. package/dist/atlas/waves/bridges.js.map +1 -1
  126. package/dist/atlas/waves/models.d.ts +5 -6
  127. package/dist/atlas/waves/models.d.ts.map +1 -1
  128. package/dist/atlas/waves/models.js +7 -13
  129. package/dist/atlas/waves/models.js.map +1 -1
  130. package/dist/atlas/waves/numerics.d.ts.map +1 -1
  131. package/dist/atlas/waves/numerics.js +10 -3
  132. package/dist/atlas/waves/numerics.js.map +1 -1
  133. package/dist/atlas/witness-numeric.d.ts +30 -0
  134. package/dist/atlas/witness-numeric.d.ts.map +1 -1
  135. package/dist/atlas/witness-numeric.js +53 -0
  136. package/dist/atlas/witness-numeric.js.map +1 -1
  137. package/dist/atlas/witness-specs.d.ts.map +1 -1
  138. package/dist/atlas/witness-specs.js +19 -0
  139. package/dist/atlas/witness-specs.js.map +1 -1
  140. package/dist/atlas/witness-symbolic.d.ts +75 -3
  141. package/dist/atlas/witness-symbolic.d.ts.map +1 -1
  142. package/dist/atlas/witness-symbolic.js +116 -10
  143. package/dist/atlas/witness-symbolic.js.map +1 -1
  144. package/dist/bridges/catalog-load.d.ts.map +1 -1
  145. package/dist/bridges/catalog-load.js +13 -8
  146. package/dist/bridges/catalog-load.js.map +1 -1
  147. package/dist/bridges/catalog-types.d.ts +26 -2
  148. package/dist/bridges/catalog-types.d.ts.map +1 -1
  149. package/dist/bridges/catalog-types.js +11 -1
  150. package/dist/bridges/catalog-types.js.map +1 -1
  151. package/dist/bridges/evaluation-errors.d.ts +31 -1
  152. package/dist/bridges/evaluation-errors.d.ts.map +1 -1
  153. package/dist/bridges/evaluation-errors.js +20 -2
  154. package/dist/bridges/evaluation-errors.js.map +1 -1
  155. package/dist/bridges/evaluator-inputs.d.ts.map +1 -1
  156. package/dist/bridges/evaluator-inputs.js +7 -5
  157. package/dist/bridges/evaluator-inputs.js.map +1 -1
  158. package/dist/bridges/evaluators.d.ts.map +1 -1
  159. package/dist/bridges/evaluators.js +27 -12
  160. package/dist/bridges/evaluators.js.map +1 -1
  161. package/dist/bridges/expr-parse.d.ts +11 -0
  162. package/dist/bridges/expr-parse.d.ts.map +1 -1
  163. package/dist/bridges/expr-parse.js +14 -5
  164. package/dist/bridges/expr-parse.js.map +1 -1
  165. package/dist/bridges/holds.d.ts +35 -3
  166. package/dist/bridges/holds.d.ts.map +1 -1
  167. package/dist/bridges/holds.js +117 -23
  168. package/dist/bridges/holds.js.map +1 -1
  169. package/dist/bridges/notices.d.ts.map +1 -1
  170. package/dist/bridges/notices.js +5 -5
  171. package/dist/bridges/notices.js.map +1 -1
  172. package/dist/bridges/relation-eval.d.ts +4 -4
  173. package/dist/bridges/relation-eval.d.ts.map +1 -1
  174. package/dist/bridges/relation-eval.js +15 -16
  175. package/dist/bridges/relation-eval.js.map +1 -1
  176. package/dist/bridges/sensitivity.d.ts.map +1 -1
  177. package/dist/bridges/sensitivity.js +3 -3
  178. package/dist/bridges/sensitivity.js.map +1 -1
  179. package/dist/bridges/validity.d.ts +33 -0
  180. package/dist/bridges/validity.d.ts.map +1 -0
  181. package/dist/bridges/validity.js +67 -0
  182. package/dist/bridges/validity.js.map +1 -0
  183. package/dist/canonical/entries/atomic.js +1 -3
  184. package/dist/canonical/entries/atomic.js.map +1 -1
  185. package/dist/canonical/entries/condensed-matter.d.ts.map +1 -1
  186. package/dist/canonical/entries/condensed-matter.js +4 -5
  187. package/dist/canonical/entries/condensed-matter.js.map +1 -1
  188. package/dist/canonical/entries/dimensional-classics.d.ts.map +1 -1
  189. package/dist/canonical/entries/dimensional-classics.js +3 -4
  190. package/dist/canonical/entries/dimensional-classics.js.map +1 -1
  191. package/dist/canonical/entries/electromagnetism.d.ts.map +1 -1
  192. package/dist/canonical/entries/electromagnetism.js +4 -10
  193. package/dist/canonical/entries/electromagnetism.js.map +1 -1
  194. package/dist/canonical/entries/fluids-waves.d.ts.map +1 -1
  195. package/dist/canonical/entries/fluids-waves.js +3 -7
  196. package/dist/canonical/entries/fluids-waves.js.map +1 -1
  197. package/dist/canonical/entries/mechanics.d.ts.map +1 -1
  198. package/dist/canonical/entries/mechanics.js +4 -6
  199. package/dist/canonical/entries/mechanics.js.map +1 -1
  200. package/dist/canonical/entries/nonmonomial.d.ts.map +1 -1
  201. package/dist/canonical/entries/nonmonomial.js +9 -17
  202. package/dist/canonical/entries/nonmonomial.js.map +1 -1
  203. package/dist/canonical/entries/relativity.d.ts.map +1 -1
  204. package/dist/canonical/entries/relativity.js +6 -6
  205. package/dist/canonical/entries/relativity.js.map +1 -1
  206. package/dist/canonical/entries/thermo-nuclear-cosmo.d.ts.map +1 -1
  207. package/dist/canonical/entries/thermo-nuclear-cosmo.js +6 -10
  208. package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
  209. package/dist/canonical/fixed-points.d.ts +94 -0
  210. package/dist/canonical/fixed-points.d.ts.map +1 -0
  211. package/dist/canonical/fixed-points.js +81 -0
  212. package/dist/canonical/fixed-points.js.map +1 -0
  213. package/dist/canonical/linkage.d.ts.map +1 -1
  214. package/dist/canonical/linkage.js +25 -44
  215. package/dist/canonical/linkage.js.map +1 -1
  216. package/dist/canonical/normal-form.d.ts.map +1 -1
  217. package/dist/canonical/normal-form.js +5 -11
  218. package/dist/canonical/normal-form.js.map +1 -1
  219. package/dist/canonical/structural.d.ts +21 -21
  220. package/dist/canonical/structural.d.ts.map +1 -1
  221. package/dist/canonical/structural.js +40 -19
  222. package/dist/canonical/structural.js.map +1 -1
  223. package/dist/cases/catalog-checks.d.ts +10 -0
  224. package/dist/cases/catalog-checks.d.ts.map +1 -0
  225. package/dist/cases/catalog-checks.js +241 -0
  226. package/dist/cases/catalog-checks.js.map +1 -0
  227. package/dist/cases/catalog.d.ts +83 -0
  228. package/dist/cases/catalog.d.ts.map +1 -0
  229. package/dist/cases/catalog.js +118 -0
  230. package/dist/cases/catalog.js.map +1 -0
  231. package/dist/cases/engine.d.ts +13 -0
  232. package/dist/cases/engine.d.ts.map +1 -0
  233. package/dist/cases/engine.js +179 -0
  234. package/dist/cases/engine.js.map +1 -0
  235. package/dist/cases/index.d.ts.map +1 -1
  236. package/dist/cases/index.js +5 -7
  237. package/dist/cases/index.js.map +1 -1
  238. package/dist/cases/methods.d.ts +215 -0
  239. package/dist/cases/methods.d.ts.map +1 -0
  240. package/dist/cases/methods.js +743 -0
  241. package/dist/cases/methods.js.map +1 -0
  242. package/dist/cases/quadrature.d.ts +7 -9
  243. package/dist/cases/quadrature.d.ts.map +1 -1
  244. package/dist/cases/quadrature.js +28 -32
  245. package/dist/cases/quadrature.js.map +1 -1
  246. package/dist/cases/types.d.ts +12 -0
  247. package/dist/cases/types.d.ts.map +1 -1
  248. package/dist/cases/types.js.map +1 -1
  249. package/dist/cli/args.d.ts +25 -1
  250. package/dist/cli/args.d.ts.map +1 -1
  251. package/dist/cli/args.js +30 -8
  252. package/dist/cli/args.js.map +1 -1
  253. package/dist/cli/bindings.d.ts.map +1 -1
  254. package/dist/cli/bindings.js +5 -4
  255. package/dist/cli/bindings.js.map +1 -1
  256. package/dist/cli/command.d.ts +11 -1
  257. package/dist/cli/command.d.ts.map +1 -1
  258. package/dist/cli/command.js.map +1 -1
  259. package/dist/cli/commands/_atlas-map.d.ts +0 -9
  260. package/dist/cli/commands/_atlas-map.d.ts.map +1 -1
  261. package/dist/cli/commands/_atlas-map.js +8 -18
  262. package/dist/cli/commands/_atlas-map.js.map +1 -1
  263. package/dist/cli/commands/_atlas-route.d.ts.map +1 -1
  264. package/dist/cli/commands/_atlas-route.js +6 -2
  265. package/dist/cli/commands/_atlas-route.js.map +1 -1
  266. package/dist/cli/commands/_discovery-opts.d.ts +1 -0
  267. package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
  268. package/dist/cli/commands/_discovery-opts.js +9 -9
  269. package/dist/cli/commands/_discovery-opts.js.map +1 -1
  270. package/dist/cli/commands/atlas.d.ts.map +1 -1
  271. package/dist/cli/commands/atlas.js +8 -5
  272. package/dist/cli/commands/atlas.js.map +1 -1
  273. package/dist/cli/commands/audit.d.ts.map +1 -1
  274. package/dist/cli/commands/audit.js +8 -1
  275. package/dist/cli/commands/audit.js.map +1 -1
  276. package/dist/cli/commands/axes.d.ts.map +1 -1
  277. package/dist/cli/commands/axes.js +20 -1
  278. package/dist/cli/commands/axes.js.map +1 -1
  279. package/dist/cli/commands/confront.d.ts.map +1 -1
  280. package/dist/cli/commands/confront.js +8 -14
  281. package/dist/cli/commands/confront.js.map +1 -1
  282. package/dist/cli/commands/derive.d.ts.map +1 -1
  283. package/dist/cli/commands/derive.js +22 -22
  284. package/dist/cli/commands/derive.js.map +1 -1
  285. package/dist/cli/commands/discover.d.ts.map +1 -1
  286. package/dist/cli/commands/discover.js +122 -73
  287. package/dist/cli/commands/discover.js.map +1 -1
  288. package/dist/cli/commands/eval.d.ts.map +1 -1
  289. package/dist/cli/commands/eval.js +1 -0
  290. package/dist/cli/commands/eval.js.map +1 -1
  291. package/dist/cli/commands/evaluate.d.ts.map +1 -1
  292. package/dist/cli/commands/evaluate.js +67 -39
  293. package/dist/cli/commands/evaluate.js.map +1 -1
  294. package/dist/cli/commands/explain.d.ts.map +1 -1
  295. package/dist/cli/commands/explain.js +24 -3
  296. package/dist/cli/commands/explain.js.map +1 -1
  297. package/dist/cli/commands/ground.d.ts.map +1 -1
  298. package/dist/cli/commands/ground.js +7 -1
  299. package/dist/cli/commands/ground.js.map +1 -1
  300. package/dist/cli/commands/map.d.ts.map +1 -1
  301. package/dist/cli/commands/map.js +84 -11
  302. package/dist/cli/commands/map.js.map +1 -1
  303. package/dist/cli/commands/metric.d.ts.map +1 -1
  304. package/dist/cli/commands/metric.js +12 -9
  305. package/dist/cli/commands/metric.js.map +1 -1
  306. package/dist/cli/commands/path.d.ts +10 -0
  307. package/dist/cli/commands/path.d.ts.map +1 -1
  308. package/dist/cli/commands/path.js +25 -3
  309. package/dist/cli/commands/path.js.map +1 -1
  310. package/dist/cli/commands/probe.d.ts.map +1 -1
  311. package/dist/cli/commands/probe.js +59 -16
  312. package/dist/cli/commands/probe.js.map +1 -1
  313. package/dist/cli/commands/regime.d.ts.map +1 -1
  314. package/dist/cli/commands/regime.js +1 -0
  315. package/dist/cli/commands/regime.js.map +1 -1
  316. package/dist/cli/commands/retrieve.d.ts.map +1 -1
  317. package/dist/cli/commands/retrieve.js +1 -0
  318. package/dist/cli/commands/retrieve.js.map +1 -1
  319. package/dist/cli/commands/search.d.ts.map +1 -1
  320. package/dist/cli/commands/search.js +1 -0
  321. package/dist/cli/commands/search.js.map +1 -1
  322. package/dist/cli/commands/symbolic.d.ts.map +1 -1
  323. package/dist/cli/commands/symbolic.js +19 -28
  324. package/dist/cli/commands/symbolic.js.map +1 -1
  325. package/dist/cli/commands/testplan.d.ts.map +1 -1
  326. package/dist/cli/commands/testplan.js +4 -2
  327. package/dist/cli/commands/testplan.js.map +1 -1
  328. package/dist/cli/determination.d.ts +1 -0
  329. package/dist/cli/determination.d.ts.map +1 -1
  330. package/dist/cli/determination.js.map +1 -1
  331. package/dist/cli/expr-print.d.ts +0 -2
  332. package/dist/cli/expr-print.d.ts.map +1 -1
  333. package/dist/cli/expr-print.js +7 -31
  334. package/dist/cli/expr-print.js.map +1 -1
  335. package/dist/cli/flag-help.d.ts +1 -0
  336. package/dist/cli/flag-help.d.ts.map +1 -1
  337. package/dist/cli/flag-help.js +1 -0
  338. package/dist/cli/flag-help.js.map +1 -1
  339. package/dist/cli/graphs.d.ts +2 -0
  340. package/dist/cli/graphs.d.ts.map +1 -1
  341. package/dist/cli/graphs.js +1 -0
  342. package/dist/cli/graphs.js.map +1 -1
  343. package/dist/cli/main.d.ts +8 -0
  344. package/dist/cli/main.d.ts.map +1 -1
  345. package/dist/cli/main.js +19 -3
  346. package/dist/cli/main.js.map +1 -1
  347. package/dist/cli/numeric-flag.d.ts +12 -0
  348. package/dist/cli/numeric-flag.d.ts.map +1 -0
  349. package/dist/cli/numeric-flag.js +44 -0
  350. package/dist/cli/numeric-flag.js.map +1 -0
  351. package/dist/cli/output.d.ts +28 -0
  352. package/dist/cli/output.d.ts.map +1 -1
  353. package/dist/cli/output.js +23 -0
  354. package/dist/cli/output.js.map +1 -1
  355. package/dist/cli/record-reach.js +2 -2
  356. package/dist/cli/record-reach.js.map +1 -1
  357. package/dist/cli/record-tables.d.ts.map +1 -1
  358. package/dist/cli/record-tables.js +6 -5
  359. package/dist/cli/record-tables.js.map +1 -1
  360. package/dist/cli/record.d.ts +1 -5
  361. package/dist/cli/record.d.ts.map +1 -1
  362. package/dist/cli/record.js +9 -8
  363. package/dist/cli/record.js.map +1 -1
  364. package/dist/cli/search-index.d.ts.map +1 -1
  365. package/dist/cli/search-index.js +7 -6
  366. package/dist/cli/search-index.js.map +1 -1
  367. package/dist/cli/statuses.d.ts +0 -2
  368. package/dist/cli/statuses.d.ts.map +1 -1
  369. package/dist/cli/statuses.js +12 -9
  370. package/dist/cli/statuses.js.map +1 -1
  371. package/dist/cli/stored-results.d.ts +7 -0
  372. package/dist/cli/stored-results.d.ts.map +1 -0
  373. package/dist/cli/stored-results.js +23 -0
  374. package/dist/cli/stored-results.js.map +1 -0
  375. package/dist/cli/version.d.ts +1 -0
  376. package/dist/cli/version.d.ts.map +1 -1
  377. package/dist/cli/version.js +8 -5
  378. package/dist/cli/version.js.map +1 -1
  379. package/dist/cli-api.d.ts +36 -5
  380. package/dist/cli-api.d.ts.map +1 -1
  381. package/dist/cli-api.js +30 -4
  382. package/dist/cli-api.js.map +1 -1
  383. package/dist/composition/algebraic-equivalence.d.ts +43 -0
  384. package/dist/composition/algebraic-equivalence.d.ts.map +1 -0
  385. package/dist/composition/algebraic-equivalence.js +115 -0
  386. package/dist/composition/algebraic-equivalence.js.map +1 -0
  387. package/dist/composition/axes.d.ts +0 -6
  388. package/dist/composition/axes.d.ts.map +1 -1
  389. package/dist/composition/axes.js +6 -6
  390. package/dist/composition/axes.js.map +1 -1
  391. package/dist/composition/axis-audit.d.ts +47 -20
  392. package/dist/composition/axis-audit.d.ts.map +1 -1
  393. package/dist/composition/axis-audit.js +82 -9
  394. package/dist/composition/axis-audit.js.map +1 -1
  395. package/dist/composition/bridge-analysis.d.ts +17 -0
  396. package/dist/composition/bridge-analysis.d.ts.map +1 -1
  397. package/dist/composition/bridge-analysis.js +102 -55
  398. package/dist/composition/bridge-analysis.js.map +1 -1
  399. package/dist/composition/canonical-compare.d.ts +40 -0
  400. package/dist/composition/canonical-compare.d.ts.map +1 -1
  401. package/dist/composition/canonical-compare.js +122 -24
  402. package/dist/composition/canonical-compare.js.map +1 -1
  403. package/dist/composition/canonical-graph.d.ts +3 -3
  404. package/dist/composition/canonical-graph.d.ts.map +1 -1
  405. package/dist/composition/canonical-graph.js +11 -38
  406. package/dist/composition/canonical-graph.js.map +1 -1
  407. package/dist/composition/canonical-json.js +2 -2
  408. package/dist/composition/canonical-json.js.map +1 -1
  409. package/dist/composition/catalog-graph.d.ts.map +1 -1
  410. package/dist/composition/catalog-graph.js +2 -5
  411. package/dist/composition/catalog-graph.js.map +1 -1
  412. package/dist/composition/chain-candidate.d.ts +8 -0
  413. package/dist/composition/chain-candidate.d.ts.map +1 -1
  414. package/dist/composition/chain-candidate.js +9 -2
  415. package/dist/composition/chain-candidate.js.map +1 -1
  416. package/dist/composition/chain-match.d.ts +6 -3
  417. package/dist/composition/chain-match.d.ts.map +1 -1
  418. package/dist/composition/chain-match.js +4 -1
  419. package/dist/composition/chain-match.js.map +1 -1
  420. package/dist/composition/chain-result.d.ts.map +1 -1
  421. package/dist/composition/chain-result.js +2 -14
  422. package/dist/composition/chain-result.js.map +1 -1
  423. package/dist/composition/compose-symbolic.d.ts.map +1 -1
  424. package/dist/composition/compose-symbolic.js +3 -2
  425. package/dist/composition/compose-symbolic.js.map +1 -1
  426. package/dist/composition/compose.d.ts.map +1 -1
  427. package/dist/composition/compose.js +13 -5
  428. package/dist/composition/compose.js.map +1 -1
  429. package/dist/composition/composition-recovery.d.ts.map +1 -1
  430. package/dist/composition/composition-recovery.js +4 -7
  431. package/dist/composition/composition-recovery.js.map +1 -1
  432. package/dist/composition/consequence.d.ts +15 -5
  433. package/dist/composition/consequence.d.ts.map +1 -1
  434. package/dist/composition/consequence.js +6 -4
  435. package/dist/composition/consequence.js.map +1 -1
  436. package/dist/composition/discovery.d.ts +129 -9
  437. package/dist/composition/discovery.d.ts.map +1 -1
  438. package/dist/composition/discovery.js +171 -67
  439. package/dist/composition/discovery.js.map +1 -1
  440. package/dist/composition/edge.d.ts +21 -2
  441. package/dist/composition/edge.d.ts.map +1 -1
  442. package/dist/composition/edge.js +23 -1
  443. package/dist/composition/edge.js.map +1 -1
  444. package/dist/composition/enumerate.d.ts.map +1 -1
  445. package/dist/composition/enumerate.js +18 -3
  446. package/dist/composition/enumerate.js.map +1 -1
  447. package/dist/composition/evaluate-relation.d.ts +35 -11
  448. package/dist/composition/evaluate-relation.d.ts.map +1 -1
  449. package/dist/composition/evaluate-relation.js +60 -39
  450. package/dist/composition/evaluate-relation.js.map +1 -1
  451. package/dist/composition/explain.d.ts +3 -12
  452. package/dist/composition/explain.d.ts.map +1 -1
  453. package/dist/composition/explain.js +7 -20
  454. package/dist/composition/explain.js.map +1 -1
  455. package/dist/composition/expr-eval.d.ts +1 -1
  456. package/dist/composition/expr-eval.d.ts.map +1 -1
  457. package/dist/composition/expr-eval.js +6 -15
  458. package/dist/composition/expr-eval.js.map +1 -1
  459. package/dist/composition/expr-simplify.d.ts +26 -14
  460. package/dist/composition/expr-simplify.d.ts.map +1 -1
  461. package/dist/composition/expr-simplify.js +64 -72
  462. package/dist/composition/expr-simplify.js.map +1 -1
  463. package/dist/composition/formula-shape.d.ts +23 -4
  464. package/dist/composition/formula-shape.d.ts.map +1 -1
  465. package/dist/composition/formula-shape.js +57 -17
  466. package/dist/composition/formula-shape.js.map +1 -1
  467. package/dist/composition/graph-structure.d.ts +98 -0
  468. package/dist/composition/graph-structure.d.ts.map +1 -0
  469. package/dist/composition/graph-structure.js +167 -0
  470. package/dist/composition/graph-structure.js.map +1 -0
  471. package/dist/composition/graph-viz-svg.d.ts.map +1 -1
  472. package/dist/composition/graph-viz-svg.js +1 -1
  473. package/dist/composition/graph-viz-svg.js.map +1 -1
  474. package/dist/composition/graph-viz.d.ts.map +1 -1
  475. package/dist/composition/graph-viz.js +8 -37
  476. package/dist/composition/graph-viz.js.map +1 -1
  477. package/dist/composition/grounding.d.ts.map +1 -1
  478. package/dist/composition/grounding.js +19 -7
  479. package/dist/composition/grounding.js.map +1 -1
  480. package/dist/composition/identifiability.d.ts +91 -4
  481. package/dist/composition/identifiability.d.ts.map +1 -1
  482. package/dist/composition/identifiability.js +363 -6
  483. package/dist/composition/identifiability.js.map +1 -1
  484. package/dist/composition/index.d.ts +8 -4
  485. package/dist/composition/index.d.ts.map +1 -1
  486. package/dist/composition/index.js +3 -2
  487. package/dist/composition/index.js.map +1 -1
  488. package/dist/composition/mathts-quiet.d.ts +7 -8
  489. package/dist/composition/mathts-quiet.d.ts.map +1 -1
  490. package/dist/composition/mathts-quiet.js +7 -16
  491. package/dist/composition/mathts-quiet.js.map +1 -1
  492. package/dist/composition/mathts-scalar-symbols.d.ts.map +1 -1
  493. package/dist/composition/mathts-scalar-symbols.js +2 -1
  494. package/dist/composition/mathts-scalar-symbols.js.map +1 -1
  495. package/dist/composition/own-equation-magnitude.d.ts +95 -0
  496. package/dist/composition/own-equation-magnitude.d.ts.map +1 -0
  497. package/dist/composition/own-equation-magnitude.js +270 -0
  498. package/dist/composition/own-equation-magnitude.js.map +1 -0
  499. package/dist/composition/probe/backend-protocol.d.ts +3 -0
  500. package/dist/composition/probe/backend-protocol.d.ts.map +1 -1
  501. package/dist/composition/probe/backend-protocol.js.map +1 -1
  502. package/dist/composition/probe/candidate-store.d.ts +1 -0
  503. package/dist/composition/probe/candidate-store.d.ts.map +1 -1
  504. package/dist/composition/probe/candidate-store.js +1 -0
  505. package/dist/composition/probe/candidate-store.js.map +1 -1
  506. package/dist/composition/probe/corpus.d.ts +8 -4
  507. package/dist/composition/probe/corpus.d.ts.map +1 -1
  508. package/dist/composition/probe/corpus.js +23 -12
  509. package/dist/composition/probe/corpus.js.map +1 -1
  510. package/dist/composition/probe/dataset.d.ts +18 -0
  511. package/dist/composition/probe/dataset.d.ts.map +1 -1
  512. package/dist/composition/probe/dataset.js +95 -50
  513. package/dist/composition/probe/dataset.js.map +1 -1
  514. package/dist/composition/probe/experiment-design.d.ts +7 -1
  515. package/dist/composition/probe/experiment-design.d.ts.map +1 -1
  516. package/dist/composition/probe/experiment-design.js +44 -24
  517. package/dist/composition/probe/experiment-design.js.map +1 -1
  518. package/dist/composition/probe/falsify.d.ts +2 -0
  519. package/dist/composition/probe/falsify.d.ts.map +1 -1
  520. package/dist/composition/probe/falsify.js +2 -0
  521. package/dist/composition/probe/falsify.js.map +1 -1
  522. package/dist/composition/probe/fit.d.ts +7 -0
  523. package/dist/composition/probe/fit.d.ts.map +1 -1
  524. package/dist/composition/probe/fit.js +46 -22
  525. package/dist/composition/probe/fit.js.map +1 -1
  526. package/dist/composition/probe/frontier.d.ts.map +1 -1
  527. package/dist/composition/probe/frontier.js +33 -15
  528. package/dist/composition/probe/frontier.js.map +1 -1
  529. package/dist/composition/probe/generator.d.ts +30 -1
  530. package/dist/composition/probe/generator.d.ts.map +1 -1
  531. package/dist/composition/probe/generator.js +58 -36
  532. package/dist/composition/probe/generator.js.map +1 -1
  533. package/dist/composition/probe/index.d.ts +14 -0
  534. package/dist/composition/probe/index.d.ts.map +1 -1
  535. package/dist/composition/probe/index.js +6 -0
  536. package/dist/composition/probe/index.js.map +1 -1
  537. package/dist/composition/probe/limits.d.ts +25 -1
  538. package/dist/composition/probe/limits.d.ts.map +1 -1
  539. package/dist/composition/probe/limits.js +53 -11
  540. package/dist/composition/probe/limits.js.map +1 -1
  541. package/dist/composition/probe/pipeline.d.ts +5 -0
  542. package/dist/composition/probe/pipeline.d.ts.map +1 -1
  543. package/dist/composition/probe/pipeline.js +73 -24
  544. package/dist/composition/probe/pipeline.js.map +1 -1
  545. package/dist/composition/probe/power-law.d.ts +121 -0
  546. package/dist/composition/probe/power-law.d.ts.map +1 -0
  547. package/dist/composition/probe/power-law.js +251 -0
  548. package/dist/composition/probe/power-law.js.map +1 -0
  549. package/dist/composition/probe/problem.d.ts +8 -4
  550. package/dist/composition/probe/problem.d.ts.map +1 -1
  551. package/dist/composition/probe/problem.js +177 -49
  552. package/dist/composition/probe/problem.js.map +1 -1
  553. package/dist/composition/probe/report.js +1 -1
  554. package/dist/composition/probe/report.js.map +1 -1
  555. package/dist/composition/probe/residual.d.ts +7 -1
  556. package/dist/composition/probe/residual.d.ts.map +1 -1
  557. package/dist/composition/probe/residual.js +10 -7
  558. package/dist/composition/probe/residual.js.map +1 -1
  559. package/dist/composition/probe/run-manifest.d.ts +1 -0
  560. package/dist/composition/probe/run-manifest.d.ts.map +1 -1
  561. package/dist/composition/probe/run-manifest.js.map +1 -1
  562. package/dist/composition/probe/scalar-search.d.ts +50 -0
  563. package/dist/composition/probe/scalar-search.d.ts.map +1 -0
  564. package/dist/composition/probe/scalar-search.js +169 -0
  565. package/dist/composition/probe/scalar-search.js.map +1 -0
  566. package/dist/composition/probe/scoring.d.ts +1 -0
  567. package/dist/composition/probe/scoring.d.ts.map +1 -1
  568. package/dist/composition/probe/scoring.js.map +1 -1
  569. package/dist/composition/probe/structure.d.ts +82 -17
  570. package/dist/composition/probe/structure.d.ts.map +1 -1
  571. package/dist/composition/probe/structure.js +129 -55
  572. package/dist/composition/probe/structure.js.map +1 -1
  573. package/dist/composition/probe/study.d.ts +31 -9
  574. package/dist/composition/probe/study.d.ts.map +1 -1
  575. package/dist/composition/probe/study.js +235 -184
  576. package/dist/composition/probe/study.js.map +1 -1
  577. package/dist/composition/probe/t-tail.d.ts +16 -0
  578. package/dist/composition/probe/t-tail.d.ts.map +1 -0
  579. package/dist/composition/probe/t-tail.js +29 -0
  580. package/dist/composition/probe/t-tail.js.map +1 -0
  581. package/dist/composition/probe/types.d.ts +3 -0
  582. package/dist/composition/probe/types.d.ts.map +1 -1
  583. package/dist/composition/probe/types.js.map +1 -1
  584. package/dist/composition/proposed-bridges.d.ts +52 -12
  585. package/dist/composition/proposed-bridges.d.ts.map +1 -1
  586. package/dist/composition/proposed-bridges.js +107 -60
  587. package/dist/composition/proposed-bridges.js.map +1 -1
  588. package/dist/composition/quantity-clusters.d.ts +48 -0
  589. package/dist/composition/quantity-clusters.d.ts.map +1 -0
  590. package/dist/composition/quantity-clusters.js +98 -0
  591. package/dist/composition/quantity-clusters.js.map +1 -0
  592. package/dist/composition/rational-exponent.d.ts +40 -0
  593. package/dist/composition/rational-exponent.d.ts.map +1 -0
  594. package/dist/composition/rational-exponent.js +65 -0
  595. package/dist/composition/rational-exponent.js.map +1 -0
  596. package/dist/composition/representative-values.d.ts +22 -0
  597. package/dist/composition/representative-values.d.ts.map +1 -1
  598. package/dist/composition/representative-values.js +29 -0
  599. package/dist/composition/representative-values.js.map +1 -1
  600. package/dist/composition/retrodiction.d.ts +15 -0
  601. package/dist/composition/retrodiction.d.ts.map +1 -1
  602. package/dist/composition/retrodiction.js +12 -4
  603. package/dist/composition/retrodiction.js.map +1 -1
  604. package/dist/composition/user-equation.d.ts +1 -0
  605. package/dist/composition/user-equation.d.ts.map +1 -1
  606. package/dist/composition/user-equation.js +3 -2
  607. package/dist/composition/user-equation.js.map +1 -1
  608. package/dist/core/assignment.d.ts +19 -0
  609. package/dist/core/assignment.d.ts.map +1 -0
  610. package/dist/core/assignment.js +19 -0
  611. package/dist/core/assignment.js.map +1 -0
  612. package/dist/core/compare.d.ts +32 -0
  613. package/dist/core/compare.d.ts.map +1 -0
  614. package/dist/core/compare.js +46 -0
  615. package/dist/core/compare.js.map +1 -0
  616. package/dist/core/constants.d.ts +42 -41
  617. package/dist/core/constants.d.ts.map +1 -1
  618. package/dist/core/constants.js +71 -51
  619. package/dist/core/constants.js.map +1 -1
  620. package/dist/core/data-file.d.ts +7 -0
  621. package/dist/core/data-file.d.ts.map +1 -1
  622. package/dist/core/data-file.js +17 -0
  623. package/dist/core/data-file.js.map +1 -1
  624. package/dist/core/format.d.ts +36 -0
  625. package/dist/core/format.d.ts.map +1 -0
  626. package/dist/core/format.js +39 -0
  627. package/dist/core/format.js.map +1 -0
  628. package/dist/core/hash.d.ts +14 -0
  629. package/dist/core/hash.d.ts.map +1 -0
  630. package/dist/core/hash.js +17 -0
  631. package/dist/core/hash.js.map +1 -0
  632. package/dist/core/json-schema.d.ts +2 -0
  633. package/dist/core/json-schema.d.ts.map +1 -1
  634. package/dist/core/json-schema.js +14 -13
  635. package/dist/core/json-schema.js.map +1 -1
  636. package/dist/core/labeled-tensor.d.ts.map +1 -1
  637. package/dist/core/labeled-tensor.js +0 -8
  638. package/dist/core/labeled-tensor.js.map +1 -1
  639. package/dist/core/mathts-read.d.ts +25 -0
  640. package/dist/core/mathts-read.d.ts.map +1 -0
  641. package/dist/core/mathts-read.js +51 -0
  642. package/dist/core/mathts-read.js.map +1 -0
  643. package/dist/core/tensor.d.ts.map +1 -1
  644. package/dist/core/tensor.js +24 -0
  645. package/dist/core/tensor.js.map +1 -1
  646. package/dist/core/types.d.ts +5 -5
  647. package/dist/diff/bridge-ast-gradient.d.ts +27 -23
  648. package/dist/diff/bridge-ast-gradient.d.ts.map +1 -1
  649. package/dist/diff/bridge-ast-gradient.js +75 -173
  650. package/dist/diff/bridge-ast-gradient.js.map +1 -1
  651. package/dist/diff/bridge-gradient.d.ts +19 -6
  652. package/dist/diff/bridge-gradient.d.ts.map +1 -1
  653. package/dist/diff/bridge-gradient.js +19 -11
  654. package/dist/diff/bridge-gradient.js.map +1 -1
  655. package/dist/diff/bridge-specs.d.ts.map +1 -1
  656. package/dist/diff/bridge-specs.js +3 -0
  657. package/dist/diff/bridge-specs.js.map +1 -1
  658. package/dist/dimensional/algebra.d.ts +18 -0
  659. package/dist/dimensional/algebra.d.ts.map +1 -1
  660. package/dist/dimensional/algebra.js +41 -1
  661. package/dist/dimensional/algebra.js.map +1 -1
  662. package/dist/dimensional/ast-builders.d.ts +7 -0
  663. package/dist/dimensional/ast-builders.d.ts.map +1 -1
  664. package/dist/dimensional/ast-builders.js +11 -0
  665. package/dist/dimensional/ast-builders.js.map +1 -1
  666. package/dist/dimensional/ast-leaves.d.ts +81 -0
  667. package/dist/dimensional/ast-leaves.d.ts.map +1 -0
  668. package/dist/dimensional/ast-leaves.js +146 -0
  669. package/dist/dimensional/ast-leaves.js.map +1 -0
  670. package/dist/dimensional/ast-types.d.ts +15 -0
  671. package/dist/dimensional/ast-types.d.ts.map +1 -1
  672. package/dist/dimensional/ast-types.js.map +1 -1
  673. package/dist/dimensional/buckingham.d.ts.map +1 -1
  674. package/dist/dimensional/buckingham.js +15 -27
  675. package/dist/dimensional/buckingham.js.map +1 -1
  676. package/dist/dimensional/constant-rows.js +9 -9
  677. package/dist/dimensional/constant-rows.js.map +1 -1
  678. package/dist/dimensional/curvature-composite.d.ts +1 -1
  679. package/dist/dimensional/curvature-composite.js.map +1 -1
  680. package/dist/dimensional/dimension-inference.d.ts.map +1 -1
  681. package/dist/dimensional/dimension-inference.js +1 -2
  682. package/dist/dimensional/dimension-inference.js.map +1 -1
  683. package/dist/dimensional/errors.d.ts +1 -1
  684. package/dist/dimensional/errors.d.ts.map +1 -1
  685. package/dist/dimensional/errors.js +1 -15
  686. package/dist/dimensional/errors.js.map +1 -1
  687. package/dist/dimensional/exact-scale.d.ts +24 -11
  688. package/dist/dimensional/exact-scale.d.ts.map +1 -1
  689. package/dist/dimensional/exact-scale.js +122 -130
  690. package/dist/dimensional/exact-scale.js.map +1 -1
  691. package/dist/dimensional/gauge-field.d.ts.map +1 -1
  692. package/dist/dimensional/gauge-field.js +2 -2
  693. package/dist/dimensional/gauge-field.js.map +1 -1
  694. package/dist/dimensional/hyphen-names.d.ts +12 -2
  695. package/dist/dimensional/hyphen-names.d.ts.map +1 -1
  696. package/dist/dimensional/hyphen-names.js +44 -19
  697. package/dist/dimensional/hyphen-names.js.map +1 -1
  698. package/dist/dimensional/mathts-unit-delegation.d.ts +29 -0
  699. package/dist/dimensional/mathts-unit-delegation.d.ts.map +1 -0
  700. package/dist/dimensional/mathts-unit-delegation.js +187 -0
  701. package/dist/dimensional/mathts-unit-delegation.js.map +1 -0
  702. package/dist/dimensional/mathts-unit-wrapper.d.ts +33 -0
  703. package/dist/dimensional/mathts-unit-wrapper.d.ts.map +1 -0
  704. package/dist/dimensional/mathts-unit-wrapper.js +190 -0
  705. package/dist/dimensional/mathts-unit-wrapper.js.map +1 -0
  706. package/dist/dimensional/metric.d.ts.map +1 -1
  707. package/dist/dimensional/metric.js +0 -1
  708. package/dist/dimensional/metric.js.map +1 -1
  709. package/dist/dimensional/scalar-lowering.d.ts +21 -0
  710. package/dist/dimensional/scalar-lowering.d.ts.map +1 -0
  711. package/dist/dimensional/scalar-lowering.js +45 -0
  712. package/dist/dimensional/scalar-lowering.js.map +1 -0
  713. package/dist/dimensional/symbolic-constants.d.ts +9 -0
  714. package/dist/dimensional/symbolic-constants.d.ts.map +1 -1
  715. package/dist/dimensional/symbolic-constants.js +13 -1
  716. package/dist/dimensional/symbolic-constants.js.map +1 -1
  717. package/dist/dimensional/types.d.ts +36 -0
  718. package/dist/dimensional/types.d.ts.map +1 -1
  719. package/dist/dimensional/types.js +45 -7
  720. package/dist/dimensional/types.js.map +1 -1
  721. package/dist/dimensional/unit-data.d.ts +5 -1
  722. package/dist/dimensional/unit-data.d.ts.map +1 -1
  723. package/dist/dimensional/unit-data.js +30 -6
  724. package/dist/dimensional/unit-data.js.map +1 -1
  725. package/dist/dimensional/units.d.ts +2 -0
  726. package/dist/dimensional/units.d.ts.map +1 -1
  727. package/dist/dimensional/units.js +59 -3
  728. package/dist/dimensional/units.js.map +1 -1
  729. package/dist/dimensional/validator.d.ts +2 -0
  730. package/dist/dimensional/validator.d.ts.map +1 -1
  731. package/dist/dimensional/validator.js.map +1 -1
  732. package/dist/index.d.ts +9 -3
  733. package/dist/index.d.ts.map +1 -1
  734. package/dist/index.js +10 -4
  735. package/dist/index.js.map +1 -1
  736. package/dist/numerical/christoffel-flat.d.ts.map +1 -1
  737. package/dist/numerical/christoffel-flat.js +3 -2
  738. package/dist/numerical/christoffel-flat.js.map +1 -1
  739. package/dist/numerical/connection-lowering-helpers.d.ts +3 -1
  740. package/dist/numerical/connection-lowering-helpers.d.ts.map +1 -1
  741. package/dist/numerical/connection-lowering-helpers.js +11 -15
  742. package/dist/numerical/connection-lowering-helpers.js.map +1 -1
  743. package/dist/numerical/covariant-eikonal.d.ts.map +1 -1
  744. package/dist/numerical/covariant-eikonal.js +34 -11
  745. package/dist/numerical/covariant-eikonal.js.map +1 -1
  746. package/dist/numerical/curvature-lowering-helpers.js +3 -2
  747. package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
  748. package/dist/numerical/errors.d.ts.map +1 -1
  749. package/dist/numerical/errors.js +0 -3
  750. package/dist/numerical/errors.js.map +1 -1
  751. package/dist/numerical/finite-difference.d.ts +22 -0
  752. package/dist/numerical/finite-difference.d.ts.map +1 -0
  753. package/dist/numerical/finite-difference.js +27 -0
  754. package/dist/numerical/finite-difference.js.map +1 -0
  755. package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
  756. package/dist/numerical/geodesic-integrator.js +22 -14
  757. package/dist/numerical/geodesic-integrator.js.map +1 -1
  758. package/dist/numerical/geometrized.d.ts.map +1 -1
  759. package/dist/numerical/geometrized.js +0 -1
  760. package/dist/numerical/geometrized.js.map +1 -1
  761. package/dist/numerical/mathts-engine.d.ts.map +1 -1
  762. package/dist/numerical/mathts-engine.js +10 -24
  763. package/dist/numerical/mathts-engine.js.map +1 -1
  764. package/dist/numerical/metric-inverse.d.ts.map +1 -1
  765. package/dist/numerical/metric-inverse.js +83 -46
  766. package/dist/numerical/metric-inverse.js.map +1 -1
  767. package/dist/numerical/null-ray-integrator.d.ts +2 -1
  768. package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
  769. package/dist/numerical/null-ray-integrator.js +12 -12
  770. package/dist/numerical/null-ray-integrator.js.map +1 -1
  771. package/dist/numerical/painleve-gullstrand-metric.js +2 -2
  772. package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
  773. package/dist/numerical/pderiv.d.ts.map +1 -1
  774. package/dist/numerical/pderiv.js +2 -6
  775. package/dist/numerical/pderiv.js.map +1 -1
  776. package/dist/numerical/perihelion-finder.d.ts +0 -36
  777. package/dist/numerical/perihelion-finder.d.ts.map +1 -1
  778. package/dist/numerical/perihelion-finder.js +41 -87
  779. package/dist/numerical/perihelion-finder.js.map +1 -1
  780. package/dist/numerical/quadrature.d.ts.map +1 -1
  781. package/dist/numerical/quadrature.js +11 -13
  782. package/dist/numerical/quadrature.js.map +1 -1
  783. package/dist/numerical/rk4-trajectory.d.ts +10 -0
  784. package/dist/numerical/rk4-trajectory.d.ts.map +1 -0
  785. package/dist/numerical/rk4-trajectory.js +37 -0
  786. package/dist/numerical/rk4-trajectory.js.map +1 -0
  787. package/dist/numerical/schwarzschild.d.ts +14 -0
  788. package/dist/numerical/schwarzschild.d.ts.map +1 -0
  789. package/dist/numerical/schwarzschild.js +17 -0
  790. package/dist/numerical/schwarzschild.js.map +1 -0
  791. package/dist/numerical/spacetime-metrics.d.ts +12 -0
  792. package/dist/numerical/spacetime-metrics.d.ts.map +1 -1
  793. package/dist/numerical/spacetime-metrics.js +72 -56
  794. package/dist/numerical/spacetime-metrics.js.map +1 -1
  795. package/dist/numerical/statistics.d.ts +24 -0
  796. package/dist/numerical/statistics.d.ts.map +1 -0
  797. package/dist/numerical/statistics.js +52 -0
  798. package/dist/numerical/statistics.js.map +1 -0
  799. package/dist/numerical/strides.d.ts +3 -2
  800. package/dist/numerical/strides.d.ts.map +1 -1
  801. package/dist/numerical/strides.js +3 -10
  802. package/dist/numerical/strides.js.map +1 -1
  803. package/dist/numerical/tensor-engine.d.ts +21 -0
  804. package/dist/numerical/tensor-engine.d.ts.map +1 -1
  805. package/dist/numerical/tensor-engine.js +12 -0
  806. package/dist/numerical/tensor-engine.js.map +1 -1
  807. package/dist/relations/regime.d.ts +10 -0
  808. package/dist/relations/regime.d.ts.map +1 -1
  809. package/dist/relations/regime.js +18 -1
  810. package/dist/relations/regime.js.map +1 -1
  811. package/package.json +9 -12
  812. package/dist/cases/brownian-sphere.d.ts +0 -68
  813. package/dist/cases/brownian-sphere.d.ts.map +0 -1
  814. package/dist/cases/brownian-sphere.js +0 -354
  815. package/dist/cases/brownian-sphere.js.map +0 -1
  816. package/dist/cases/damped-resonator.d.ts +0 -23
  817. package/dist/cases/damped-resonator.d.ts.map +0 -1
  818. package/dist/cases/damped-resonator.js +0 -224
  819. package/dist/cases/damped-resonator.js.map +0 -1
  820. package/dist/cases/kepler-rv.d.ts +0 -13
  821. package/dist/cases/kepler-rv.d.ts.map +0 -1
  822. package/dist/cases/kepler-rv.js +0 -172
  823. package/dist/cases/kepler-rv.js.map +0 -1
  824. package/dist/cases/lumped-cooling.d.ts +0 -46
  825. package/dist/cases/lumped-cooling.d.ts.map +0 -1
  826. package/dist/cases/lumped-cooling.js +0 -261
  827. package/dist/cases/lumped-cooling.js.map +0 -1
  828. package/dist/cases/resistor-noise.d.ts +0 -14
  829. package/dist/cases/resistor-noise.d.ts.map +0 -1
  830. package/dist/cases/resistor-noise.js +0 -215
  831. package/dist/cases/resistor-noise.js.map +0 -1
  832. package/dist/cases/skin-depth.d.ts +0 -21
  833. package/dist/cases/skin-depth.d.ts.map +0 -1
  834. package/dist/cases/skin-depth.js +0 -174
  835. package/dist/cases/skin-depth.js.map +0 -1
@@ -5,10 +5,60 @@
5
5
  * that tree is Product A's confrontation ledger and must stay cycle-free
6
6
  * from probe.
7
7
  *
8
+ * A cell is a finite number or a non-empty string in the strict decimal
9
+ * grammar (`1`, `-0.5`, `.5`, `2.`, `1e-3`). Nothing is coerced: an empty
10
+ * cell, `null`, `true`, `false`, a list and `"0x10"` are refused by column
11
+ * and row, with {@link DatasetError}. `Number(v)` once read all of those as
12
+ * 0, 1 or 16, which also defeated the missing-observation guard of the
13
+ * declared-limit check (a missing observation scored as 0).
14
+ *
8
15
  * @internal
9
16
  */
10
17
  import { readFileSync } from 'node:fs';
18
+ import { readJsonFile } from '../../core/data-file.js';
11
19
  import { SCHEMA_VERSION } from './types.js';
20
+ /** A dataset file or object that is not a dataset: the message names the row and the column. @internal */
21
+ export class DatasetError extends Error {
22
+ constructor(message) {
23
+ super(message);
24
+ this.name = 'DatasetError';
25
+ }
26
+ }
27
+ /** The strict decimal grammar a string cell must match: sign, digits with an optional fraction, an optional exponent. */
28
+ const DECIMAL = /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;
29
+ /** What a JSON value is, in the words a file author would use. */
30
+ function kindOf(v) {
31
+ if (v === null)
32
+ return 'null';
33
+ if (Array.isArray(v))
34
+ return 'a list';
35
+ if (typeof v === 'boolean')
36
+ return String(v);
37
+ if (typeof v === 'string')
38
+ return `'${v}'`;
39
+ return typeof v === 'object' ? 'an object' : typeof v;
40
+ }
41
+ /**
42
+ * A cell as a number: a finite number, or a non-empty string in the strict
43
+ * decimal grammar. Anything else is refused at `where` (the dataset, row and
44
+ * column). @internal
45
+ */
46
+ export function readDatasetNumber(v, where) {
47
+ if (typeof v === 'number') {
48
+ if (!Number.isFinite(v))
49
+ throw new DatasetError(`${where}: ${v} is not a finite number`);
50
+ return v;
51
+ }
52
+ if (typeof v === 'string') {
53
+ if (v.trim() === '')
54
+ throw new DatasetError(`${where}: an empty cell is not a number`);
55
+ const n = DECIMAL.test(v.trim()) ? Number(v.trim()) : NaN;
56
+ if (!Number.isFinite(n))
57
+ throw new DatasetError(`${where}: ${kindOf(v)} is not a finite decimal number`);
58
+ return n;
59
+ }
60
+ throw new DatasetError(`${where}: ${kindOf(v)} is not a number`);
61
+ }
12
62
  /** Build an in-memory dataset. @internal */
13
63
  export function datasetFromRows(rows, observable, role, id = 'inline', sigma) {
14
64
  return { id, role, rows, observable, ...(sigma !== undefined ? { sigma } : {}), schemaVersion: SCHEMA_VERSION };
@@ -16,33 +66,29 @@ export function datasetFromRows(rows, observable, role, id = 'inline', sigma) {
16
66
  /** Coerce unknown JSON into a ProbeDataset. @internal */
17
67
  export function asDatasetSafe(raw, fallbackId, fallbackRole) {
18
68
  if (!raw || typeof raw !== 'object') {
19
- throw new Error(`dataset JSON is not an object (${fallbackId})`);
69
+ throw new DatasetError(`dataset JSON is not an object (${fallbackId})`);
20
70
  }
21
71
  const obj = raw;
22
72
  if (!Array.isArray(obj.rows)) {
23
- throw new Error(`dataset at ${fallbackId} is missing rows[]`);
73
+ throw new DatasetError(`dataset at ${fallbackId} is missing rows[]`);
24
74
  }
25
75
  if (typeof obj.observable !== 'string' || obj.observable.length === 0) {
26
- throw new Error(`dataset at ${fallbackId} is missing observable`);
76
+ throw new DatasetError(`dataset at ${fallbackId} is missing observable`);
27
77
  }
28
78
  const role = (typeof obj.role === 'string' ? obj.role : fallbackRole);
29
79
  if (role !== 'exploratory-fit' &&
30
80
  role !== 'validation-holdout' &&
31
81
  role !== 'external-replication' &&
32
82
  role !== 'falsification-only') {
33
- throw new Error(`dataset at ${fallbackId} has invalid role '${String(obj.role)}'`);
83
+ throw new DatasetError(`dataset at ${fallbackId} has invalid role '${String(obj.role)}'`);
34
84
  }
35
85
  const rows = obj.rows.map((row, i) => {
36
86
  if (!row || typeof row !== 'object' || Array.isArray(row)) {
37
- throw new Error(`dataset ${fallbackId} row ${i} is not an object`);
87
+ throw new DatasetError(`dataset ${fallbackId} row ${i} is not an object`);
38
88
  }
39
89
  const out = {};
40
90
  for (const [k, v] of Object.entries(row)) {
41
- const n = typeof v === 'number' ? v : Number(v);
42
- if (!Number.isFinite(n)) {
43
- throw new Error(`dataset ${fallbackId} row ${i} column ${k}: not a finite number`);
44
- }
45
- out[k] = n;
91
+ out[k] = readDatasetNumber(v, `dataset ${fallbackId} row ${i} column ${k}`);
46
92
  }
47
93
  return out;
48
94
  });
@@ -57,12 +103,12 @@ export function asDatasetSafe(raw, fallbackId, fallbackRole) {
57
103
  }
58
104
  /** Load a single ProbeDataset JSON object. @internal */
59
105
  export function loadDatasetFromJson(path, fallbackRole) {
60
- const raw = JSON.parse(readFileSync(path, 'utf8'));
106
+ const raw = readJsonFile(path);
61
107
  return asDatasetSafe(raw, path, fallbackRole);
62
108
  }
63
109
  /** Load `{ exploratory, holdout }` JSON. @internal */
64
110
  export function loadSplitDatasetsFromJson(path) {
65
- const raw = JSON.parse(readFileSync(path, 'utf8'));
111
+ const raw = readJsonFile(path);
66
112
  if (raw.exploratory || raw.holdout) {
67
113
  return {
68
114
  exploratory: raw.exploratory
@@ -78,7 +124,35 @@ export function loadSplitDatasetsFromJson(path) {
78
124
  exploratory: asDatasetSafe({ ...raw.observations, role: 'exploratory-fit' }, `${path}#observations`, 'exploratory-fit'),
79
125
  };
80
126
  }
81
- throw new Error(`JSON at ${path} needs exploratory/holdout or observations`);
127
+ throw new DatasetError(`JSON at ${path} needs exploratory/holdout or observations`);
128
+ }
129
+ /** The header and the data lines of a CSV file; the file needs both. */
130
+ function csvLines(path) {
131
+ const text = readFileSync(path, 'utf8').trim();
132
+ const lines = text.split(/\r?\n/).filter((l) => l.length > 0);
133
+ if (lines.length < 2) {
134
+ throw new DatasetError(`CSV dataset at ${path} needs a header and at least one row`);
135
+ }
136
+ const headers = lines[0].split(',').map((h) => h.trim());
137
+ return { headers, lines };
138
+ }
139
+ /**
140
+ * One CSV data line as a row of numbers. A line with fewer cells than the
141
+ * header is refused by the first column it lacks; `skip` names the header
142
+ * column (if any) that is not a number column. `line` is the 1-based line
143
+ * number of the file, so a message points at the file.
144
+ */
145
+ function csvRow(cells, headers, line, path, skip) {
146
+ if (cells.length < headers.length) {
147
+ throw new DatasetError(`CSV ${path} row ${line} has ${cells.length} cell(s); the header has ${headers.length} (column ${headers[cells.length]} is missing)`);
148
+ }
149
+ const row = {};
150
+ for (let c = 0; c < headers.length; c++) {
151
+ if (c === skip)
152
+ continue;
153
+ row[headers[c]] = readDatasetNumber(cells[c], `CSV ${path} row ${line} column ${headers[c]}`);
154
+ }
155
+ return row;
82
156
  }
83
157
  /**
84
158
  * Minimal CSV: first row headers, remaining rows numeric values.
@@ -88,66 +162,37 @@ export function loadSplitDatasetsFromJson(path) {
88
162
  * @internal
89
163
  */
90
164
  export function loadDatasetFromCsv(path, observable, role, id = path) {
91
- const text = readFileSync(path, 'utf8').trim();
92
- const lines = text.split(/\r?\n/).filter((l) => l.length > 0);
93
- if (lines.length < 2) {
94
- throw new Error(`CSV dataset at ${path} needs a header and at least one row`);
95
- }
96
- const headers = lines[0].split(',').map((h) => h.trim());
165
+ const { headers, lines } = csvLines(path);
166
+ const splitIdx = headers.indexOf('split');
97
167
  const rows = [];
98
168
  for (let i = 1; i < lines.length; i++) {
99
169
  const cells = lines[i].split(',').map((c) => c.trim());
100
- const row = {};
101
- for (let c = 0; c < headers.length; c++) {
102
- const h = headers[c];
103
- if (h === 'split')
104
- continue;
105
- const n = Number(cells[c] ?? '');
106
- if (!Number.isFinite(n)) {
107
- throw new Error(`CSV ${path} row ${i + 1} column ${h}: not a finite number`);
108
- }
109
- row[h] = n;
110
- }
111
- rows.push(row);
170
+ rows.push(csvRow(cells, headers, i + 1, path, splitIdx));
112
171
  }
113
172
  if (!(observable in (rows[0] ?? {}))) {
114
- throw new Error(`CSV ${path} is missing observable column '${observable}'`);
173
+ throw new DatasetError(`CSV ${path} is missing observable column '${observable}'`);
115
174
  }
116
175
  return datasetFromRows(rows, observable, role, id);
117
176
  }
118
177
  /** Partition a mixed-split CSV (uses a `split` column). @internal */
119
178
  export function loadSplitCsv(path, observable) {
120
- const text = readFileSync(path, 'utf8').trim();
121
- const lines = text.split(/\r?\n/).filter((l) => l.length > 0);
122
- if (lines.length < 2) {
123
- throw new Error(`CSV dataset at ${path} needs a header and at least one row`);
124
- }
125
- const headers = lines[0].split(',').map((h) => h.trim());
179
+ const { headers, lines } = csvLines(path);
126
180
  const splitIdx = headers.indexOf('split');
127
181
  if (splitIdx < 0) {
128
- throw new Error(`CSV ${path} has no split column`);
182
+ throw new DatasetError(`CSV ${path} has no split column`);
129
183
  }
130
184
  const exploratoryRows = [];
131
185
  const holdoutRows = [];
132
186
  for (let i = 1; i < lines.length; i++) {
133
187
  const cells = lines[i].split(',').map((c) => c.trim());
134
- const row = {};
135
- for (let c = 0; c < headers.length; c++) {
136
- if (c === splitIdx)
137
- continue;
138
- const n = Number(cells[c] ?? '');
139
- if (!Number.isFinite(n)) {
140
- throw new Error(`CSV ${path} row ${i + 1} column ${headers[c]}: not a finite number`);
141
- }
142
- row[headers[c]] = n;
143
- }
188
+ const row = csvRow(cells, headers, i + 1, path, splitIdx);
144
189
  const split = cells[splitIdx];
145
190
  if (split === 'holdout' || split === 'blind')
146
191
  holdoutRows.push(row);
147
192
  else if (split === 'exploratory')
148
193
  exploratoryRows.push(row);
149
194
  else
150
- throw new Error(`CSV ${path} row ${i + 1} has invalid split '${split}'`);
195
+ throw new DatasetError(`CSV ${path} row ${i + 1} has invalid split '${split}'`);
151
196
  }
152
197
  return {
153
198
  exploratory: datasetFromRows(exploratoryRows, observable, 'exploratory-fit', `${path}#exploratory`),
@@ -1 +1 @@
1
- {"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../../src/composition/probe/dataset.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Observation adapters for Product B.\n *\n * In-memory / JSON / CSV. Does not live in `src/bridges/observations/` —\n * that tree is Product A's confrontation ledger and must stay cycle-free\n * from probe.\n *\n * @internal\n */\n\nimport { readFileSync } from 'node:fs';\nimport type { DatasetRole, ObservationRow, ProbeDataset } from './types.js';\nimport { SCHEMA_VERSION } from './types.js';\n\n/** Build an in-memory dataset. @internal */\nexport function datasetFromRows(\n rows: readonly ObservationRow[],\n observable: string,\n role: DatasetRole,\n id = 'inline',\n sigma?: number,\n): ProbeDataset {\n return { id, role, rows, observable, ...(sigma !== undefined ? { sigma } : {}), schemaVersion: SCHEMA_VERSION };\n}\n\n/** Coerce unknown JSON into a ProbeDataset. @internal */\nexport function asDatasetSafe(raw: unknown, fallbackId: string, fallbackRole?: DatasetRole): ProbeDataset {\n if (!raw || typeof raw !== 'object') {\n throw new Error(`dataset JSON is not an object (${fallbackId})`);\n }\n const obj = raw as {\n id?: unknown;\n role?: unknown;\n rows?: unknown;\n observable?: unknown;\n sigma?: unknown;\n schemaVersion?: unknown;\n };\n if (!Array.isArray(obj.rows)) {\n throw new Error(`dataset at ${fallbackId} is missing rows[]`);\n }\n if (typeof obj.observable !== 'string' || obj.observable.length === 0) {\n throw new Error(`dataset at ${fallbackId} is missing observable`);\n }\n const role = (typeof obj.role === 'string' ? obj.role : fallbackRole) as DatasetRole | undefined;\n if (\n role !== 'exploratory-fit' &&\n role !== 'validation-holdout' &&\n role !== 'external-replication' &&\n role !== 'falsification-only'\n ) {\n throw new Error(`dataset at ${fallbackId} has invalid role '${String(obj.role)}'`);\n }\n const rows: ObservationRow[] = obj.rows.map((row, i) => {\n if (!row || typeof row !== 'object' || Array.isArray(row)) {\n throw new Error(`dataset ${fallbackId} row ${i} is not an object`);\n }\n const out: Record<string, number> = {};\n for (const [k, v] of Object.entries(row as Record<string, unknown>)) {\n const n = typeof v === 'number' ? v : Number(v);\n if (!Number.isFinite(n)) {\n throw new Error(`dataset ${fallbackId} row ${i} column ${k}: not a finite number`);\n }\n out[k] = n;\n }\n return out;\n });\n return {\n id: typeof obj.id === 'string' ? obj.id : fallbackId,\n role,\n rows,\n observable: obj.observable,\n ...(typeof obj.sigma === 'number' && Number.isFinite(obj.sigma) ? { sigma: obj.sigma } : {}),\n schemaVersion: typeof obj.schemaVersion === 'string' ? obj.schemaVersion : SCHEMA_VERSION,\n };\n}\n\n/** Load a single ProbeDataset JSON object. @internal */\nexport function loadDatasetFromJson(path: string, fallbackRole?: DatasetRole): ProbeDataset {\n const raw = JSON.parse(readFileSync(path, 'utf8')) as unknown;\n return asDatasetSafe(raw, path, fallbackRole);\n}\n\nexport interface SplitFileDatasets {\n readonly exploratory?: ProbeDataset;\n readonly holdout?: ProbeDataset;\n}\n\n/** Load `{ exploratory, holdout }` JSON. @internal */\nexport function loadSplitDatasetsFromJson(path: string): SplitFileDatasets {\n const raw = JSON.parse(readFileSync(path, 'utf8')) as {\n exploratory?: unknown;\n holdout?: unknown;\n observations?: unknown;\n };\n if (raw.exploratory || raw.holdout) {\n return {\n exploratory: raw.exploratory\n ? asDatasetSafe(raw.exploratory, `${path}#exploratory`, 'exploratory-fit')\n : undefined,\n holdout: raw.holdout\n ? asDatasetSafe(raw.holdout, `${path}#holdout`, 'validation-holdout')\n : undefined,\n };\n }\n if (raw.observations) {\n return {\n exploratory: asDatasetSafe(\n { ...(raw.observations as object), role: 'exploratory-fit' },\n `${path}#observations`,\n 'exploratory-fit',\n ),\n };\n }\n throw new Error(`JSON at ${path} needs exploratory/holdout or observations`);\n}\n\n/**\n * Minimal CSV: first row headers, remaining rows numeric values.\n * Optional `split` column (`exploratory`/`holdout`/`blind`).\n * `blind` rows are withheld with holdout data, never fit.\n *\n * @internal\n */\nexport function loadDatasetFromCsv(\n path: string,\n observable: string,\n role: DatasetRole,\n id = path,\n): ProbeDataset {\n const text = readFileSync(path, 'utf8').trim();\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length < 2) {\n throw new Error(`CSV dataset at ${path} needs a header and at least one row`);\n }\n const headers = lines[0]!.split(',').map((h) => h.trim());\n const rows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n const row: Record<string, number> = {};\n for (let c = 0; c < headers.length; c++) {\n const h = headers[c]!;\n if (h === 'split') continue;\n const n = Number(cells[c] ?? '');\n if (!Number.isFinite(n)) {\n throw new Error(`CSV ${path} row ${i + 1} column ${h}: not a finite number`);\n }\n row[h] = n;\n }\n rows.push(row);\n }\n if (!(observable in (rows[0] ?? {}))) {\n throw new Error(`CSV ${path} is missing observable column '${observable}'`);\n }\n return datasetFromRows(rows, observable, role, id);\n}\n\n/** Partition a mixed-split CSV (uses a `split` column). @internal */\nexport function loadSplitCsv(\n path: string,\n observable: string,\n): { exploratory: ProbeDataset; holdout: ProbeDataset } {\n const text = readFileSync(path, 'utf8').trim();\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length < 2) {\n throw new Error(`CSV dataset at ${path} needs a header and at least one row`);\n }\n const headers = lines[0]!.split(',').map((h) => h.trim());\n const splitIdx = headers.indexOf('split');\n if (splitIdx < 0) {\n throw new Error(`CSV ${path} has no split column`);\n }\n const exploratoryRows: ObservationRow[] = [];\n const holdoutRows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n const row: Record<string, number> = {};\n for (let c = 0; c < headers.length; c++) {\n if (c === splitIdx) continue;\n const n = Number(cells[c] ?? '');\n if (!Number.isFinite(n)) {\n throw new Error(`CSV ${path} row ${i + 1} column ${headers[c]}: not a finite number`);\n }\n row[headers[c]!] = n;\n }\n const split = cells[splitIdx];\n if (split === 'holdout' || split === 'blind') holdoutRows.push(row);\n else if (split === 'exploratory') exploratoryRows.push(row);\n else throw new Error(`CSV ${path} row ${i + 1} has invalid split '${split}'`);\n }\n return {\n exploratory: datasetFromRows(exploratoryRows, observable, 'exploratory-fit', `${path}#exploratory`),\n holdout: datasetFromRows(holdoutRows, observable, 'validation-holdout', `${path}#holdout`),\n };\n}\n"]}
1
+ {"version":3,"file":"dataset.js","sourceRoot":"","sources":["../../../src/composition/probe/dataset.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Observation adapters for Product B.\n *\n * In-memory / JSON / CSV. Does not live in `src/bridges/observations/` —\n * that tree is Product A's confrontation ledger and must stay cycle-free\n * from probe.\n *\n * A cell is a finite number or a non-empty string in the strict decimal\n * grammar (`1`, `-0.5`, `.5`, `2.`, `1e-3`). Nothing is coerced: an empty\n * cell, `null`, `true`, `false`, a list and `\"0x10\"` are refused by column\n * and row, with {@link DatasetError}. `Number(v)` once read all of those as\n * 0, 1 or 16, which also defeated the missing-observation guard of the\n * declared-limit check (a missing observation scored as 0).\n *\n * @internal\n */\n\nimport { readFileSync } from 'node:fs';\nimport { readJsonFile } from '../../core/data-file.js';\nimport type { DatasetRole, ObservationRow, ProbeDataset } from './types.js';\nimport { SCHEMA_VERSION } from './types.js';\n\n/** A dataset file or object that is not a dataset: the message names the row and the column. @internal */\nexport class DatasetError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DatasetError';\n }\n}\n\n/** The strict decimal grammar a string cell must match: sign, digits with an optional fraction, an optional exponent. */\nconst DECIMAL = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/;\n\n/** What a JSON value is, in the words a file author would use. */\nfunction kindOf(v: unknown): string {\n if (v === null) return 'null';\n if (Array.isArray(v)) return 'a list';\n if (typeof v === 'boolean') return String(v);\n if (typeof v === 'string') return `'${v}'`;\n return typeof v === 'object' ? 'an object' : typeof v;\n}\n\n/**\n * A cell as a number: a finite number, or a non-empty string in the strict\n * decimal grammar. Anything else is refused at `where` (the dataset, row and\n * column). @internal\n */\nexport function readDatasetNumber(v: unknown, where: string): number {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) throw new DatasetError(`${where}: ${v} is not a finite number`);\n return v;\n }\n if (typeof v === 'string') {\n if (v.trim() === '') throw new DatasetError(`${where}: an empty cell is not a number`);\n const n = DECIMAL.test(v.trim()) ? Number(v.trim()) : NaN;\n if (!Number.isFinite(n)) throw new DatasetError(`${where}: ${kindOf(v)} is not a finite decimal number`);\n return n;\n }\n throw new DatasetError(`${where}: ${kindOf(v)} is not a number`);\n}\n\n/** Build an in-memory dataset. @internal */\nexport function datasetFromRows(\n rows: readonly ObservationRow[],\n observable: string,\n role: DatasetRole,\n id = 'inline',\n sigma?: number,\n): ProbeDataset {\n return { id, role, rows, observable, ...(sigma !== undefined ? { sigma } : {}), schemaVersion: SCHEMA_VERSION };\n}\n\n/** Coerce unknown JSON into a ProbeDataset. @internal */\nexport function asDatasetSafe(raw: unknown, fallbackId: string, fallbackRole?: DatasetRole): ProbeDataset {\n if (!raw || typeof raw !== 'object') {\n throw new DatasetError(`dataset JSON is not an object (${fallbackId})`);\n }\n const obj = raw as {\n id?: unknown;\n role?: unknown;\n rows?: unknown;\n observable?: unknown;\n sigma?: unknown;\n schemaVersion?: unknown;\n };\n if (!Array.isArray(obj.rows)) {\n throw new DatasetError(`dataset at ${fallbackId} is missing rows[]`);\n }\n if (typeof obj.observable !== 'string' || obj.observable.length === 0) {\n throw new DatasetError(`dataset at ${fallbackId} is missing observable`);\n }\n const role = (typeof obj.role === 'string' ? obj.role : fallbackRole) as DatasetRole | undefined;\n if (\n role !== 'exploratory-fit' &&\n role !== 'validation-holdout' &&\n role !== 'external-replication' &&\n role !== 'falsification-only'\n ) {\n throw new DatasetError(`dataset at ${fallbackId} has invalid role '${String(obj.role)}'`);\n }\n const rows: ObservationRow[] = obj.rows.map((row, i) => {\n if (!row || typeof row !== 'object' || Array.isArray(row)) {\n throw new DatasetError(`dataset ${fallbackId} row ${i} is not an object`);\n }\n const out: Record<string, number> = {};\n for (const [k, v] of Object.entries(row as Record<string, unknown>)) {\n out[k] = readDatasetNumber(v, `dataset ${fallbackId} row ${i} column ${k}`);\n }\n return out;\n });\n return {\n id: typeof obj.id === 'string' ? obj.id : fallbackId,\n role,\n rows,\n observable: obj.observable,\n ...(typeof obj.sigma === 'number' && Number.isFinite(obj.sigma) ? { sigma: obj.sigma } : {}),\n schemaVersion: typeof obj.schemaVersion === 'string' ? obj.schemaVersion : SCHEMA_VERSION,\n };\n}\n\n/** Load a single ProbeDataset JSON object. @internal */\nexport function loadDatasetFromJson(path: string, fallbackRole?: DatasetRole): ProbeDataset {\n const raw = readJsonFile(path);\n return asDatasetSafe(raw, path, fallbackRole);\n}\n\n/** The exploratory and holdout datasets that one split JSON file holds. */\nexport interface SplitFileDatasets {\n readonly exploratory?: ProbeDataset;\n readonly holdout?: ProbeDataset;\n}\n\n/** Load `{ exploratory, holdout }` JSON. @internal */\nexport function loadSplitDatasetsFromJson(path: string): SplitFileDatasets {\n const raw = readJsonFile(path) as {\n exploratory?: unknown;\n holdout?: unknown;\n observations?: unknown;\n };\n if (raw.exploratory || raw.holdout) {\n return {\n exploratory: raw.exploratory\n ? asDatasetSafe(raw.exploratory, `${path}#exploratory`, 'exploratory-fit')\n : undefined,\n holdout: raw.holdout\n ? asDatasetSafe(raw.holdout, `${path}#holdout`, 'validation-holdout')\n : undefined,\n };\n }\n if (raw.observations) {\n return {\n exploratory: asDatasetSafe(\n { ...(raw.observations as object), role: 'exploratory-fit' },\n `${path}#observations`,\n 'exploratory-fit',\n ),\n };\n }\n throw new DatasetError(`JSON at ${path} needs exploratory/holdout or observations`);\n}\n\n/** The header and the data lines of a CSV file; the file needs both. */\nfunction csvLines(path: string): { headers: string[]; lines: string[] } {\n const text = readFileSync(path, 'utf8').trim();\n const lines = text.split(/\\r?\\n/).filter((l) => l.length > 0);\n if (lines.length < 2) {\n throw new DatasetError(`CSV dataset at ${path} needs a header and at least one row`);\n }\n const headers = lines[0]!.split(',').map((h) => h.trim());\n return { headers, lines };\n}\n\n/**\n * One CSV data line as a row of numbers. A line with fewer cells than the\n * header is refused by the first column it lacks; `skip` names the header\n * column (if any) that is not a number column. `line` is the 1-based line\n * number of the file, so a message points at the file.\n */\nfunction csvRow(cells: readonly string[], headers: readonly string[], line: number, path: string, skip: number): Record<string, number> {\n if (cells.length < headers.length) {\n throw new DatasetError(\n `CSV ${path} row ${line} has ${cells.length} cell(s); the header has ${headers.length} (column ${headers[cells.length]} is missing)`,\n );\n }\n const row: Record<string, number> = {};\n for (let c = 0; c < headers.length; c++) {\n if (c === skip) continue;\n row[headers[c]!] = readDatasetNumber(cells[c], `CSV ${path} row ${line} column ${headers[c]}`);\n }\n return row;\n}\n\n/**\n * Minimal CSV: first row headers, remaining rows numeric values.\n * Optional `split` column (`exploratory`/`holdout`/`blind`).\n * `blind` rows are withheld with holdout data, never fit.\n *\n * @internal\n */\nexport function loadDatasetFromCsv(\n path: string,\n observable: string,\n role: DatasetRole,\n id = path,\n): ProbeDataset {\n const { headers, lines } = csvLines(path);\n const splitIdx = headers.indexOf('split');\n const rows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n rows.push(csvRow(cells, headers, i + 1, path, splitIdx));\n }\n if (!(observable in (rows[0] ?? {}))) {\n throw new DatasetError(`CSV ${path} is missing observable column '${observable}'`);\n }\n return datasetFromRows(rows, observable, role, id);\n}\n\n/** Partition a mixed-split CSV (uses a `split` column). @internal */\nexport function loadSplitCsv(\n path: string,\n observable: string,\n): { exploratory: ProbeDataset; holdout: ProbeDataset } {\n const { headers, lines } = csvLines(path);\n const splitIdx = headers.indexOf('split');\n if (splitIdx < 0) {\n throw new DatasetError(`CSV ${path} has no split column`);\n }\n const exploratoryRows: ObservationRow[] = [];\n const holdoutRows: ObservationRow[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cells = lines[i]!.split(',').map((c) => c.trim());\n const row = csvRow(cells, headers, i + 1, path, splitIdx);\n const split = cells[splitIdx];\n if (split === 'holdout' || split === 'blind') holdoutRows.push(row);\n else if (split === 'exploratory') exploratoryRows.push(row);\n else throw new DatasetError(`CSV ${path} row ${i + 1} has invalid split '${split}'`);\n }\n return {\n exploratory: datasetFromRows(exploratoryRows, observable, 'exploratory-fit', `${path}#exploratory`),\n holdout: datasetFromRows(holdoutRows, observable, 'validation-holdout', `${path}#holdout`),\n };\n}\n"]}
@@ -7,6 +7,7 @@
7
7
  * @internal
8
8
  */
9
9
  import type { ExprNode } from '../../dimensional/ast-types.js';
10
+ /** The variable ranges, forbidden regions and sigma that bound an experiment design. */
10
11
  export interface DesignBounds {
11
12
  readonly variables: Readonly<Record<string, {
12
13
  min: number;
@@ -19,8 +20,13 @@ export interface DesignBounds {
19
20
  }>>[];
20
21
  readonly sigma?: number;
21
22
  }
22
- /** Coerce unknown JSON into {@link DesignBounds}. @internal */
23
+ /**
24
+ * Coerce unknown JSON into {@link DesignBounds}. Every bound is a finite
25
+ * number and `steps` a positive integer; a value of another kind is refused,
26
+ * naming the field and what was found. @internal
27
+ */
23
28
  export declare function parseDesignBounds(raw: unknown, source: string): DesignBounds;
29
+ /** One suggested experiment point, and how well it separates two hypotheses. */
24
30
  export interface DesignSuggestion {
25
31
  readonly point: Readonly<Record<string, number>>;
26
32
  readonly discrimination: number;
@@ -1 +1 @@
1
- {"version":3,"file":"experiment-design.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3F,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,EAAE,CAAC;IACvF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAqE5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAeD,6FAA6F;AAC7F,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,YAAY,GACnB,gBAAgB,CAkElB"}
1
+ {"version":3,"file":"experiment-design.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG/D,wFAAwF;AACxF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC3F,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,EAAE,CAAC;IACvF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAyBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CA4D5E;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAeD,6FAA6F;AAC7F,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,QAAQ,EACZ,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,YAAY,GACnB,gBAAgB,CAkElB"}
@@ -7,7 +7,36 @@
7
7
  * @internal
8
8
  */
9
9
  import { evalExpr } from '../expr-eval.js';
10
- /** Coerce unknown JSON into {@link DesignBounds}. @internal */
10
+ /** What a JSON value is, in the words a file author would use. */
11
+ function kindOf(v) {
12
+ if (v === null)
13
+ return 'null';
14
+ if (Array.isArray(v))
15
+ return 'a list';
16
+ if (typeof v === 'string')
17
+ return 'text';
18
+ if (typeof v === 'number')
19
+ return Number.isFinite(v) ? 'a number' : String(v);
20
+ if (typeof v === 'boolean')
21
+ return 'true or false';
22
+ return typeof v === 'object' ? 'an object' : typeof v;
23
+ }
24
+ /** A finite number, or null: nothing is coerced (`null`, `""` and `"0"` once read as 0). */
25
+ const finite = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : null);
26
+ /** `{min, max}` as two finite numbers, located by `where` in any refusal. */
27
+ function readRange(spec, where) {
28
+ const min = finite(spec.min);
29
+ const max = finite(spec.max);
30
+ if (min === null || max === null) {
31
+ throw new Error(`${where} needs finite min/max numbers (found ${kindOf(spec.min)} and ${kindOf(spec.max)})`);
32
+ }
33
+ return { min, max };
34
+ }
35
+ /**
36
+ * Coerce unknown JSON into {@link DesignBounds}. Every bound is a finite
37
+ * number and `steps` a positive integer; a value of another kind is refused,
38
+ * naming the field and what was found. @internal
39
+ */
11
40
  export function parseDesignBounds(raw, source) {
12
41
  if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
13
42
  throw new Error(`design bounds at ${source} is not an object`);
@@ -21,22 +50,18 @@ export function parseDesignBounds(raw, source) {
21
50
  if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {
22
51
  throw new Error(`design bounds at ${source}: variables.${name} is not an object`);
23
52
  }
24
- const { min, max, steps } = spec;
25
- const minN = typeof min === 'number' ? min : Number(min);
26
- const maxN = typeof max === 'number' ? max : Number(max);
27
- if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {
28
- throw new Error(`design bounds at ${source}: variables.${name} needs finite min/max`);
29
- }
30
- if (minN > maxN) {
31
- throw new Error(`design bounds at ${source}: variables.${name} has min > max`);
53
+ const where = `design bounds at ${source}: variables.${name}`;
54
+ const { min, max } = readRange(spec, where);
55
+ if (min > max) {
56
+ throw new Error(`${where} has min > max`);
32
57
  }
33
- const entry = { min: minN, max: maxN };
58
+ const entry = { min, max };
59
+ const { steps } = spec;
34
60
  if (steps !== undefined) {
35
- const stepsN = typeof steps === 'number' ? steps : Number(steps);
36
- if (!Number.isFinite(stepsN) || stepsN <= 0) {
37
- throw new Error(`design bounds at ${source}: variables.${name}.steps must be positive`);
61
+ if (typeof steps !== 'number' || !Number.isInteger(steps) || steps < 1) {
62
+ throw new Error(`${where}.steps must be a positive integer (found ${typeof steps === 'number' ? steps : kindOf(steps)})`);
38
63
  }
39
- entry.steps = stepsN;
64
+ entry.steps = steps;
40
65
  }
41
66
  variables[name] = entry;
42
67
  }
@@ -54,23 +79,18 @@ export function parseDesignBounds(raw, source) {
54
79
  if (!r || typeof r !== 'object' || Array.isArray(r)) {
55
80
  throw new Error(`design bounds at ${source}: forbidden[${i}].${k} is not an object`);
56
81
  }
57
- const { min, max } = r;
58
- const minN = typeof min === 'number' ? min : Number(min);
59
- const maxN = typeof max === 'number' ? max : Number(max);
60
- if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {
61
- throw new Error(`design bounds at ${source}: forbidden[${i}].${k} needs finite min/max`);
62
- }
63
- out[k] = { min: minN, max: maxN };
82
+ out[k] = readRange(r, `design bounds at ${source}: forbidden[${i}].${k}`);
64
83
  }
65
84
  return out;
66
85
  });
67
86
  }
68
87
  let sigma;
69
88
  if (obj.sigma !== undefined) {
70
- sigma = typeof obj.sigma === 'number' ? obj.sigma : Number(obj.sigma);
71
- if (!Number.isFinite(sigma) || sigma <= 0) {
72
- throw new Error(`design bounds at ${source}: sigma must be a positive number`);
89
+ const s = finite(obj.sigma);
90
+ if (s === null || s <= 0) {
91
+ throw new Error(`design bounds at ${source}: sigma must be a positive number (found ${s === null ? kindOf(obj.sigma) : s})`);
73
92
  }
93
+ sigma = s;
74
94
  }
75
95
  return { variables, ...(forbidden ? { forbidden } : {}), ...(sigma !== undefined ? { sigma } : {}) };
76
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"experiment-design.js","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cheap experiment-design suggestions for two competing hypotheses.\n *\n * Grid-search max |H1−H2|/σ under declared bounds. Never recommend a\n * forbidden region.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { evalExpr } from '../expr-eval.js';\n\nexport interface DesignBounds {\n readonly variables: Readonly<Record<string, { min: number; max: number; steps?: number }>>;\n readonly forbidden?: readonly Readonly<Record<string, { min: number; max: number }>>[];\n readonly sigma?: number;\n}\n\n/** Coerce unknown JSON into {@link DesignBounds}. @internal */\nexport function parseDesignBounds(raw: unknown, source: string): DesignBounds {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new Error(`design bounds at ${source} is not an object`);\n }\n const obj = raw as {\n variables?: unknown;\n forbidden?: unknown;\n sigma?: unknown;\n };\n if (!obj.variables || typeof obj.variables !== 'object' || Array.isArray(obj.variables)) {\n throw new Error(`design bounds at ${source} is missing variables`);\n }\n const variables: Record<string, { min: number; max: number; steps?: number }> = {};\n for (const [name, spec] of Object.entries(obj.variables as Record<string, unknown>)) {\n if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {\n throw new Error(`design bounds at ${source}: variables.${name} is not an object`);\n }\n const { min, max, steps } = spec as { min?: unknown; max?: unknown; steps?: unknown };\n const minN = typeof min === 'number' ? min : Number(min);\n const maxN = typeof max === 'number' ? max : Number(max);\n if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {\n throw new Error(`design bounds at ${source}: variables.${name} needs finite min/max`);\n }\n if (minN > maxN) {\n throw new Error(`design bounds at ${source}: variables.${name} has min > max`);\n }\n const entry: { min: number; max: number; steps?: number } = { min: minN, max: maxN };\n if (steps !== undefined) {\n const stepsN = typeof steps === 'number' ? steps : Number(steps);\n if (!Number.isFinite(stepsN) || stepsN <= 0) {\n throw new Error(`design bounds at ${source}: variables.${name}.steps must be positive`);\n }\n entry.steps = stepsN;\n }\n variables[name] = entry;\n }\n let forbidden: DesignBounds['forbidden'];\n if (obj.forbidden !== undefined) {\n if (!Array.isArray(obj.forbidden)) {\n throw new Error(`design bounds at ${source}: forbidden must be an array`);\n }\n forbidden = obj.forbidden.map((region, i) => {\n if (!region || typeof region !== 'object' || Array.isArray(region)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}] is not an object`);\n }\n const out: Record<string, { min: number; max: number }> = {};\n for (const [k, r] of Object.entries(region as Record<string, unknown>)) {\n if (!r || typeof r !== 'object' || Array.isArray(r)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}].${k} is not an object`);\n }\n const { min, max } = r as { min?: unknown; max?: unknown };\n const minN = typeof min === 'number' ? min : Number(min);\n const maxN = typeof max === 'number' ? max : Number(max);\n if (!Number.isFinite(minN) || !Number.isFinite(maxN)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}].${k} needs finite min/max`);\n }\n out[k] = { min: minN, max: maxN };\n }\n return out;\n });\n }\n let sigma: number | undefined;\n if (obj.sigma !== undefined) {\n sigma = typeof obj.sigma === 'number' ? obj.sigma : Number(obj.sigma);\n if (!Number.isFinite(sigma) || sigma <= 0) {\n throw new Error(`design bounds at ${source}: sigma must be a positive number`);\n }\n }\n return { variables, ...(forbidden ? { forbidden } : {}), ...(sigma !== undefined ? { sigma } : {}) };\n}\n\nexport interface DesignSuggestion {\n readonly point: Readonly<Record<string, number>>;\n readonly discrimination: number;\n readonly h1: number;\n readonly h2: number;\n readonly abstained?: boolean;\n readonly reason?: string;\n}\n\nfunction inForbidden(\n point: Record<string, number>,\n forbidden: readonly Readonly<Record<string, { min: number; max: number }>>[] | undefined,\n): boolean {\n if (!forbidden) return false;\n return forbidden.some((region) =>\n Object.entries(region).every(([k, r]) => {\n const v = point[k];\n return v !== undefined && v >= r.min && v <= r.max;\n }),\n );\n}\n\n/** Suggest the grid point that maximises |H1−H2|/σ, skipping forbidden regions. @internal */\nexport function suggestDiscriminatingPoint(\n h1: ExprNode,\n h2: ExprNode,\n bounds: DesignBounds,\n): DesignSuggestion {\n const names = Object.keys(bounds.variables);\n if (names.length === 0) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'no free variables in bounds',\n };\n }\n\n const sigma = bounds.sigma ?? 1;\n let best: DesignSuggestion | null = null;\n\n const grids = names.map((n) => {\n const b = bounds.variables[n]!;\n const steps = Math.max(2, b.steps ?? 8);\n const out: number[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n out.push(b.min + t * (b.max - b.min));\n }\n return out;\n });\n\n const idx = new Array(names.length).fill(0);\n const rec = (d: number): void => {\n if (d === names.length) {\n const point: Record<string, number> = {};\n for (let i = 0; i < names.length; i++) point[names[i]!] = grids[i]![idx[i]!]!;\n if (inForbidden(point, bounds.forbidden)) return;\n let y1: number;\n let y2: number;\n try {\n y1 = evalExpr(h1, point);\n y2 = evalExpr(h2, point);\n } catch {\n return;\n }\n if (!Number.isFinite(y1) || !Number.isFinite(y2)) return;\n const disc = Math.abs(y1 - y2) / sigma;\n if (!best || disc > best.discrimination) {\n best = { point, discrimination: disc, h1: y1, h2: y2 };\n }\n return;\n }\n for (let i = 0; i < grids[d]!.length; i++) {\n idx[d] = i;\n rec(d + 1);\n }\n };\n rec(0);\n\n if (!best) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'every grid point was forbidden or non-finite',\n };\n }\n return best;\n}\n"]}
1
+ {"version":3,"file":"experiment-design.js","sourceRoot":"","sources":["../../../src/composition/probe/experiment-design.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cheap experiment-design suggestions for two competing hypotheses.\n *\n * Grid-search max |H1−H2|/σ under declared bounds. Never recommend a\n * forbidden region.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { evalExpr } from '../expr-eval.js';\n\n/** The variable ranges, forbidden regions and sigma that bound an experiment design. */\nexport interface DesignBounds {\n readonly variables: Readonly<Record<string, { min: number; max: number; steps?: number }>>;\n readonly forbidden?: readonly Readonly<Record<string, { min: number; max: number }>>[];\n readonly sigma?: number;\n}\n\n/** What a JSON value is, in the words a file author would use. */\nfunction kindOf(v: unknown): string {\n if (v === null) return 'null';\n if (Array.isArray(v)) return 'a list';\n if (typeof v === 'string') return 'text';\n if (typeof v === 'number') return Number.isFinite(v) ? 'a number' : String(v);\n if (typeof v === 'boolean') return 'true or false';\n return typeof v === 'object' ? 'an object' : typeof v;\n}\n\n/** A finite number, or null: nothing is coerced (`null`, `\"\"` and `\"0\"` once read as 0). */\nconst finite = (v: unknown): number | null => (typeof v === 'number' && Number.isFinite(v) ? v : null);\n\n/** `{min, max}` as two finite numbers, located by `where` in any refusal. */\nfunction readRange(spec: Record<string, unknown>, where: string): { min: number; max: number } {\n const min = finite(spec.min);\n const max = finite(spec.max);\n if (min === null || max === null) {\n throw new Error(`${where} needs finite min/max numbers (found ${kindOf(spec.min)} and ${kindOf(spec.max)})`);\n }\n return { min, max };\n}\n\n/**\n * Coerce unknown JSON into {@link DesignBounds}. Every bound is a finite\n * number and `steps` a positive integer; a value of another kind is refused,\n * naming the field and what was found. @internal\n */\nexport function parseDesignBounds(raw: unknown, source: string): DesignBounds {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new Error(`design bounds at ${source} is not an object`);\n }\n const obj = raw as {\n variables?: unknown;\n forbidden?: unknown;\n sigma?: unknown;\n };\n if (!obj.variables || typeof obj.variables !== 'object' || Array.isArray(obj.variables)) {\n throw new Error(`design bounds at ${source} is missing variables`);\n }\n const variables: Record<string, { min: number; max: number; steps?: number }> = {};\n for (const [name, spec] of Object.entries(obj.variables as Record<string, unknown>)) {\n if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {\n throw new Error(`design bounds at ${source}: variables.${name} is not an object`);\n }\n const where = `design bounds at ${source}: variables.${name}`;\n const { min, max } = readRange(spec as Record<string, unknown>, where);\n if (min > max) {\n throw new Error(`${where} has min > max`);\n }\n const entry: { min: number; max: number; steps?: number } = { min, max };\n const { steps } = spec as { steps?: unknown };\n if (steps !== undefined) {\n if (typeof steps !== 'number' || !Number.isInteger(steps) || steps < 1) {\n throw new Error(`${where}.steps must be a positive integer (found ${typeof steps === 'number' ? steps : kindOf(steps)})`);\n }\n entry.steps = steps;\n }\n variables[name] = entry;\n }\n let forbidden: DesignBounds['forbidden'];\n if (obj.forbidden !== undefined) {\n if (!Array.isArray(obj.forbidden)) {\n throw new Error(`design bounds at ${source}: forbidden must be an array`);\n }\n forbidden = obj.forbidden.map((region, i) => {\n if (!region || typeof region !== 'object' || Array.isArray(region)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}] is not an object`);\n }\n const out: Record<string, { min: number; max: number }> = {};\n for (const [k, r] of Object.entries(region as Record<string, unknown>)) {\n if (!r || typeof r !== 'object' || Array.isArray(r)) {\n throw new Error(`design bounds at ${source}: forbidden[${i}].${k} is not an object`);\n }\n out[k] = readRange(r as Record<string, unknown>, `design bounds at ${source}: forbidden[${i}].${k}`);\n }\n return out;\n });\n }\n let sigma: number | undefined;\n if (obj.sigma !== undefined) {\n const s = finite(obj.sigma);\n if (s === null || s <= 0) {\n throw new Error(`design bounds at ${source}: sigma must be a positive number (found ${s === null ? kindOf(obj.sigma) : s})`);\n }\n sigma = s;\n }\n return { variables, ...(forbidden ? { forbidden } : {}), ...(sigma !== undefined ? { sigma } : {}) };\n}\n\n/** One suggested experiment point, and how well it separates two hypotheses. */\nexport interface DesignSuggestion {\n readonly point: Readonly<Record<string, number>>;\n readonly discrimination: number;\n readonly h1: number;\n readonly h2: number;\n readonly abstained?: boolean;\n readonly reason?: string;\n}\n\nfunction inForbidden(\n point: Record<string, number>,\n forbidden: readonly Readonly<Record<string, { min: number; max: number }>>[] | undefined,\n): boolean {\n if (!forbidden) return false;\n return forbidden.some((region) =>\n Object.entries(region).every(([k, r]) => {\n const v = point[k];\n return v !== undefined && v >= r.min && v <= r.max;\n }),\n );\n}\n\n/** Suggest the grid point that maximises |H1−H2|/σ, skipping forbidden regions. @internal */\nexport function suggestDiscriminatingPoint(\n h1: ExprNode,\n h2: ExprNode,\n bounds: DesignBounds,\n): DesignSuggestion {\n const names = Object.keys(bounds.variables);\n if (names.length === 0) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'no free variables in bounds',\n };\n }\n\n const sigma = bounds.sigma ?? 1;\n let best: DesignSuggestion | null = null;\n\n const grids = names.map((n) => {\n const b = bounds.variables[n]!;\n const steps = Math.max(2, b.steps ?? 8);\n const out: number[] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n out.push(b.min + t * (b.max - b.min));\n }\n return out;\n });\n\n const idx = new Array(names.length).fill(0);\n const rec = (d: number): void => {\n if (d === names.length) {\n const point: Record<string, number> = {};\n for (let i = 0; i < names.length; i++) point[names[i]!] = grids[i]![idx[i]!]!;\n if (inForbidden(point, bounds.forbidden)) return;\n let y1: number;\n let y2: number;\n try {\n y1 = evalExpr(h1, point);\n y2 = evalExpr(h2, point);\n } catch {\n return;\n }\n if (!Number.isFinite(y1) || !Number.isFinite(y2)) return;\n const disc = Math.abs(y1 - y2) / sigma;\n if (!best || disc > best.discrimination) {\n best = { point, discrimination: disc, h1: y1, h2: y2 };\n }\n return;\n }\n for (let i = 0; i < grids[d]!.length; i++) {\n idx[d] = i;\n rec(d + 1);\n }\n };\n rec(0);\n\n if (!best) {\n return {\n point: {},\n discrimination: 0,\n h1: NaN,\n h2: NaN,\n abstained: true,\n reason: 'every grid point was forbidden or non-finite',\n };\n }\n return best;\n}\n"]}
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import type { ExprNode } from '../../dimensional/ast-types.js';
11
11
  import type { DeclaredLimit, FalsificationBattery, FalsificationRecord, ProbeDataset } from './types.js';
12
+ /** The candidate, data and declared limits that one falsification battery tests. */
12
13
  export interface FalsifyInput {
13
14
  readonly expr: ExprNode;
14
15
  readonly dataset?: ProbeDataset;
@@ -17,6 +18,7 @@ export interface FalsifyInput {
17
18
  readonly limits?: readonly DeclaredLimit[];
18
19
  readonly skipDimensional?: boolean;
19
20
  }
21
+ /** The records, survival flag and counterexamples of one falsification battery. */
20
22
  export interface FalsifyResult {
21
23
  readonly records: readonly FalsificationRecord[];
22
24
  readonly survived: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"falsify.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAI/D,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;CACvE;AA2FD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAwBnE;AAED,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,SAAS,oBAAoB,EAI5D,CAAC"}
1
+ {"version":3,"file":"falsify.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAI/D,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,mFAAmF;AACnF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;CACvE;AA6FD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAwBnE;AAED,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,SAAS,oBAAoB,EAI5D,CAAC"}
@@ -77,6 +77,8 @@ function limitsBattery(checks) {
77
77
  detail: fatal.map((c) => c.detail).join('; '),
78
78
  };
79
79
  }
80
+ // A non-fatal failure (domain not claimed) and an undecided limit (too few evaluable rows)
81
+ // both leave the battery inconclusive; neither is a pass.
80
82
  const failedNonFatal = checks.filter((c) => !c.passed && !c.fatal);
81
83
  if (failedNonFatal.length > 0) {
82
84
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"falsify.js","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAyB,MAAM,aAAa,CAAC;AAuBzE,SAAS,UAAU,CAAC,IAAc;IAChC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO;YACL,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,0CAA0C;SACnD,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,wCAAwC;KACjD,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,IAAc,EACd,OAAiC,EACjC,SAAiB;IAEjB,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,OAAO;YACL,MAAM,EAAE;gBACN,OAAO,EAAE,YAAY;gBACrB,OAAO,EAAE,MAAM;gBACf,MAAM,EAAE,qBAAqB;aAC9B;YACD,eAAe,EAAE,EAAE;SACpB,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAA6B,EAAE,CAAC;IACrD,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAS,CAAC;QACd,IAAI,CAAC;YACH,CAAC,GAAG,SAAS,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,eAAe,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YACjC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,eAAe,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,MAAM,EAAE;gBACN,OAAO,EAAE,YAAY;gBACrB,OAAO,EAAE,MAAM;gBACf,MAAM,EAAE,GAAG,eAAe,CAAC,MAAM,iDAAiD;aACnF;YACD,eAAe;SAChB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE;YACN,OAAO,EAAE,YAAY;YACrB,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,wBAAwB;SACjC;QACD,eAAe,EAAE,EAAE;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAmC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;SAC9C,CAAC;IACJ,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,cAAc;YACvB,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;SACvD,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,MAAM;QACf,MAAM,EACJ,MAAM,CAAC,MAAM,KAAK,CAAC;YACjB,CAAC,CAAC,oBAAoB;YACtB,CAAC,CAAC,oDAAoD;KAC3D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;IACvC,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,MAAM,eAAe,GAA6B,EAAE,CAAC;IAErD,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACpE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,eAAe,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAG,mBAAmB,CACrC,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,OAAO,EACb,SAAS,EACT,KAAK,CAAC,MAAM,IAAI,EAAE,EAClB,KAAK,CAAC,cAAc,IAAI,EAAE,CAC3B,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC;IAC5D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;AAChD,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAAoC;IAChE,aAAa;IACb,YAAY;IACZ,QAAQ;CACT,CAAC","sourcesContent":["/**\n * Falsification batteries for probe candidates.\n *\n * Persist counterexamples. Failed limits are fatal only when the candidate\n * claims that domain (see limits.ts). Catalog retrodiction is Product A and\n * is not a battery here.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { validate } from '../../dimensional/validator.js';\nimport { evalExpr } from '../expr-eval.js';\nimport { checkDeclaredLimits, type LimitCheckResult } from './limits.js';\nimport type {\n DeclaredLimit,\n FalsificationBattery,\n FalsificationRecord,\n ProbeDataset,\n} from './types.js';\n\nexport interface FalsifyInput {\n readonly expr: ExprNode;\n readonly dataset?: ProbeDataset;\n readonly prefactor?: number;\n readonly claimedRegimes?: Readonly<Record<string, string>>;\n readonly limits?: readonly DeclaredLimit[];\n readonly skipDimensional?: boolean;\n}\n\nexport interface FalsifyResult {\n readonly records: readonly FalsificationRecord[];\n readonly survived: boolean;\n readonly counterexamples: readonly Readonly<Record<string, number>>[];\n}\n\nfunction dimBattery(expr: ExprNode): FalsificationRecord {\n const v = validate(expr);\n if (!v.ok || v.inferredDimension === null) {\n return {\n battery: 'dimensional',\n outcome: 'fail',\n detail: 'expression is dimensionally inconsistent',\n };\n }\n return {\n battery: 'dimensional',\n outcome: 'pass',\n detail: 'expression is dimensionally consistent',\n };\n}\n\nfunction finitenessBattery(\n expr: ExprNode,\n dataset: ProbeDataset | undefined,\n prefactor: number,\n): { record: FalsificationRecord; counterexamples: Record<string, number>[] } {\n if (!dataset || dataset.rows.length === 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'no rows to evaluate',\n },\n counterexamples: [],\n };\n }\n const counterexamples: Record<string, number>[] = [];\n for (const row of dataset.rows) {\n let y: number;\n try {\n y = prefactor * evalExpr(expr, row);\n } catch {\n counterexamples.push({ ...row });\n continue;\n }\n if (!Number.isFinite(y)) counterexamples.push({ ...row });\n }\n if (counterexamples.length > 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'fail',\n detail: `${counterexamples.length} observation(s) produced non-finite predictions`,\n },\n counterexamples,\n };\n }\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'all predictions finite',\n },\n counterexamples: [],\n };\n}\n\nfunction limitsBattery(checks: readonly LimitCheckResult[]): FalsificationRecord {\n const fatal = checks.filter((c) => c.fatal);\n if (fatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'fail',\n detail: fatal.map((c) => c.detail).join('; '),\n };\n }\n const failedNonFatal = checks.filter((c) => !c.passed && !c.fatal);\n if (failedNonFatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'inconclusive',\n detail: failedNonFatal.map((c) => c.detail).join('; '),\n };\n }\n return {\n battery: 'limits',\n outcome: 'pass',\n detail:\n checks.length === 0\n ? 'no declared limits'\n : 'declared limits held or were out of claimed domain',\n };\n}\n\n/**\n * Run the Product B falsification batteries: dimensional, finiteness, limits.\n *\n * Every listed battery can fail. Two batteries once listed here, `retrodiction`\n * and `observational-bounds`, returned `inconclusive` by construction (catalog\n * retrodiction is Product A, and no bound was ever evaluated), so \"survived\n * five batteries\" overstated what was checked; they are not listed until they\n * are real (9.0.0 audit §4 Low). A problem's `observationalBoundIds` stay\n * recorded on the problem and are not a battery.\n *\n * @internal\n */\nexport function runFalsification(input: FalsifyInput): FalsifyResult {\n const prefactor = input.prefactor ?? 1;\n const records: FalsificationRecord[] = [];\n const counterexamples: Record<string, number>[] = [];\n\n if (!input.skipDimensional) {\n records.push(dimBattery(input.expr));\n }\n\n const fin = finitenessBattery(input.expr, input.dataset, prefactor);\n records.push(fin.record);\n counterexamples.push(...fin.counterexamples);\n\n const limitChecks = checkDeclaredLimits(\n input.expr,\n input.dataset,\n prefactor,\n input.limits ?? [],\n input.claimedRegimes ?? {},\n );\n records.push(limitsBattery(limitChecks));\n\n const survived = records.every((r) => r.outcome !== 'fail');\n return { records, survived, counterexamples };\n}\n\n/** The batteries `runFalsification` runs, in order; each one can fail. @internal */\nexport const DEFAULT_BATTERIES: readonly FalsificationBattery[] = [\n 'dimensional',\n 'finiteness',\n 'limits',\n];\n"]}
1
+ {"version":3,"file":"falsify.js","sourceRoot":"","sources":["../../../src/composition/probe/falsify.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Falsification batteries for probe candidates.\n *\n * Persist counterexamples. Failed limits are fatal only when the candidate\n * claims that domain (see limits.ts). Catalog retrodiction is Product A and\n * is not a battery here.\n *\n * @internal\n */\n\nimport type { ExprNode } from '../../dimensional/ast-types.js';\nimport { validate } from '../../dimensional/validator.js';\nimport { evalExpr } from '../expr-eval.js';\nimport { checkDeclaredLimits, type LimitCheckResult } from './limits.js';\nimport type {\n DeclaredLimit,\n FalsificationBattery,\n FalsificationRecord,\n ProbeDataset,\n} from './types.js';\n\n/** The candidate, data and declared limits that one falsification battery tests. */\nexport interface FalsifyInput {\n readonly expr: ExprNode;\n readonly dataset?: ProbeDataset;\n readonly prefactor?: number;\n readonly claimedRegimes?: Readonly<Record<string, string>>;\n readonly limits?: readonly DeclaredLimit[];\n readonly skipDimensional?: boolean;\n}\n\n/** The records, survival flag and counterexamples of one falsification battery. */\nexport interface FalsifyResult {\n readonly records: readonly FalsificationRecord[];\n readonly survived: boolean;\n readonly counterexamples: readonly Readonly<Record<string, number>>[];\n}\n\nfunction dimBattery(expr: ExprNode): FalsificationRecord {\n const v = validate(expr);\n if (!v.ok || v.inferredDimension === null) {\n return {\n battery: 'dimensional',\n outcome: 'fail',\n detail: 'expression is dimensionally inconsistent',\n };\n }\n return {\n battery: 'dimensional',\n outcome: 'pass',\n detail: 'expression is dimensionally consistent',\n };\n}\n\nfunction finitenessBattery(\n expr: ExprNode,\n dataset: ProbeDataset | undefined,\n prefactor: number,\n): { record: FalsificationRecord; counterexamples: Record<string, number>[] } {\n if (!dataset || dataset.rows.length === 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'no rows to evaluate',\n },\n counterexamples: [],\n };\n }\n const counterexamples: Record<string, number>[] = [];\n for (const row of dataset.rows) {\n let y: number;\n try {\n y = prefactor * evalExpr(expr, row);\n } catch {\n counterexamples.push({ ...row });\n continue;\n }\n if (!Number.isFinite(y)) counterexamples.push({ ...row });\n }\n if (counterexamples.length > 0) {\n return {\n record: {\n battery: 'finiteness',\n outcome: 'fail',\n detail: `${counterexamples.length} observation(s) produced non-finite predictions`,\n },\n counterexamples,\n };\n }\n return {\n record: {\n battery: 'finiteness',\n outcome: 'pass',\n detail: 'all predictions finite',\n },\n counterexamples: [],\n };\n}\n\nfunction limitsBattery(checks: readonly LimitCheckResult[]): FalsificationRecord {\n const fatal = checks.filter((c) => c.fatal);\n if (fatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'fail',\n detail: fatal.map((c) => c.detail).join('; '),\n };\n }\n // A non-fatal failure (domain not claimed) and an undecided limit (too few evaluable rows)\n // both leave the battery inconclusive; neither is a pass.\n const failedNonFatal = checks.filter((c) => !c.passed && !c.fatal);\n if (failedNonFatal.length > 0) {\n return {\n battery: 'limits',\n outcome: 'inconclusive',\n detail: failedNonFatal.map((c) => c.detail).join('; '),\n };\n }\n return {\n battery: 'limits',\n outcome: 'pass',\n detail:\n checks.length === 0\n ? 'no declared limits'\n : 'declared limits held or were out of claimed domain',\n };\n}\n\n/**\n * Run the Product B falsification batteries: dimensional, finiteness, limits.\n *\n * Every listed battery can fail. Two batteries once listed here, `retrodiction`\n * and `observational-bounds`, returned `inconclusive` by construction (catalog\n * retrodiction is Product A, and no bound was ever evaluated), so \"survived\n * five batteries\" overstated what was checked; they are not listed until they\n * are real (9.0.0 audit §4 Low). A problem's `observationalBoundIds` stay\n * recorded on the problem and are not a battery.\n *\n * @internal\n */\nexport function runFalsification(input: FalsifyInput): FalsifyResult {\n const prefactor = input.prefactor ?? 1;\n const records: FalsificationRecord[] = [];\n const counterexamples: Record<string, number>[] = [];\n\n if (!input.skipDimensional) {\n records.push(dimBattery(input.expr));\n }\n\n const fin = finitenessBattery(input.expr, input.dataset, prefactor);\n records.push(fin.record);\n counterexamples.push(...fin.counterexamples);\n\n const limitChecks = checkDeclaredLimits(\n input.expr,\n input.dataset,\n prefactor,\n input.limits ?? [],\n input.claimedRegimes ?? {},\n );\n records.push(limitsBattery(limitChecks));\n\n const survived = records.every((r) => r.outcome !== 'fail');\n return { records, survived, counterexamples };\n}\n\n/** The batteries `runFalsification` runs, in order; each one can fail. @internal */\nexport const DEFAULT_BATTERIES: readonly FalsificationBattery[] = [\n 'dimensional',\n 'finiteness',\n 'limits',\n];\n"]}
@@ -5,8 +5,15 @@
5
5
  */
6
6
  import type { ExprNode } from '../../dimensional/ast-types.js';
7
7
  import { type ProbeDataset } from './types.js';
8
+ /** The prefactor fit of one candidate, with its exploratory and holdout errors. */
8
9
  export interface FitResult {
9
10
  readonly prefactor: number;
11
+ /**
12
+ * Standard error of the prefactor from the residual scatter of the exploratory rows
13
+ * (MathTS `ols`, one column, no intercept); null below two finite rows or when the
14
+ * form is zero on every row.
15
+ */
16
+ readonly prefactorStderr: number | null;
10
17
  readonly exploratoryRmse: number;
11
18
  readonly nExploratory: number;
12
19
  readonly holdoutRmse: number | null;
@@ -1 +1 @@
1
- {"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/fit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAIpE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AA2BD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,YAAY,EACzB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,UAAU,SAAsB,GAC/B,SAAS,CA8DX"}
1
+ {"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../../src/composition/probe/fit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAIpE,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAuDD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,QAAQ,EACd,WAAW,EAAE,YAAY,EACzB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,UAAU,SAAsB,GAC/B,SAAS,CAuDX"}