universal-physics-tensor 10.0.0 → 11.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 (720) hide show
  1. package/README.md +4 -3
  2. package/bin/upt.mjs +13 -1
  3. package/data/atlas/atlas.json +25 -25
  4. package/data/atlas/atlas.jsonld +1 -1
  5. package/data/atlas/diffusion.json +6 -6
  6. package/data/atlas/oscillators.json +7 -7
  7. package/data/atlas/waves.json +14 -14
  8. package/data/atlas/witness-results.json +11 -11
  9. package/data/bridge-catalog.json +371 -228
  10. package/data/bridge-catalog.schema.json +45 -7
  11. package/dist/atlas/applicability.d.ts.map +1 -1
  12. package/dist/atlas/applicability.js +21 -15
  13. package/dist/atlas/applicability.js.map +1 -1
  14. package/dist/atlas/benchmark/hybrid-retrieval.d.ts +9 -1
  15. package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -1
  16. package/dist/atlas/benchmark/hybrid-retrieval.js +15 -13
  17. package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -1
  18. package/dist/atlas/benchmark/loader.js +2 -2
  19. package/dist/atlas/benchmark/loader.js.map +1 -1
  20. package/dist/atlas/benchmark/stats.d.ts +2 -2
  21. package/dist/atlas/benchmark/stats.d.ts.map +1 -1
  22. package/dist/atlas/benchmark/stats.js +15 -7
  23. package/dist/atlas/benchmark/stats.js.map +1 -1
  24. package/dist/atlas/catalog-formal-ref.d.ts +26 -3
  25. package/dist/atlas/catalog-formal-ref.d.ts.map +1 -1
  26. package/dist/atlas/catalog-formal-ref.js +52 -5
  27. package/dist/atlas/catalog-formal-ref.js.map +1 -1
  28. package/dist/atlas/chain-pipeline.d.ts.map +1 -1
  29. package/dist/atlas/chain-pipeline.js +7 -8
  30. package/dist/atlas/chain-pipeline.js.map +1 -1
  31. package/dist/atlas/diffusion/bridges-closure.d.ts +0 -4
  32. package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
  33. package/dist/atlas/diffusion/bridges-closure.js +8 -12
  34. package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
  35. package/dist/atlas/diffusion/bridges.d.ts.map +1 -1
  36. package/dist/atlas/diffusion/bridges.js +27 -39
  37. package/dist/atlas/diffusion/bridges.js.map +1 -1
  38. package/dist/atlas/diffusion/dimensions.d.ts +6 -14
  39. package/dist/atlas/diffusion/dimensions.d.ts.map +1 -1
  40. package/dist/atlas/diffusion/dimensions.js +8 -16
  41. package/dist/atlas/diffusion/dimensions.js.map +1 -1
  42. package/dist/atlas/diffusion/models.d.ts +3 -3
  43. package/dist/atlas/diffusion/models.d.ts.map +1 -1
  44. package/dist/atlas/diffusion/models.js +5 -10
  45. package/dist/atlas/diffusion/models.js.map +1 -1
  46. package/dist/atlas/diffusion/numerics.d.ts +16 -4
  47. package/dist/atlas/diffusion/numerics.d.ts.map +1 -1
  48. package/dist/atlas/diffusion/numerics.js +38 -24
  49. package/dist/atlas/diffusion/numerics.js.map +1 -1
  50. package/dist/atlas/link-prediction.d.ts +106 -3
  51. package/dist/atlas/link-prediction.d.ts.map +1 -1
  52. package/dist/atlas/link-prediction.js +212 -66
  53. package/dist/atlas/link-prediction.js.map +1 -1
  54. package/dist/atlas/oscillators/bridges-coarse.d.ts.map +1 -1
  55. package/dist/atlas/oscillators/bridges-coarse.js +7 -11
  56. package/dist/atlas/oscillators/bridges-coarse.js.map +1 -1
  57. package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
  58. package/dist/atlas/oscillators/bridges-exact.js +6 -7
  59. package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
  60. package/dist/atlas/oscillators/bridges-limits.d.ts +3 -16
  61. package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
  62. package/dist/atlas/oscillators/bridges-limits.js +23 -34
  63. package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
  64. package/dist/atlas/oscillators/dimensions.d.ts +9 -21
  65. package/dist/atlas/oscillators/dimensions.d.ts.map +1 -1
  66. package/dist/atlas/oscillators/dimensions.js +9 -21
  67. package/dist/atlas/oscillators/dimensions.js.map +1 -1
  68. package/dist/atlas/oscillators/limit-witnesses.d.ts +2 -2
  69. package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -1
  70. package/dist/atlas/oscillators/limit-witnesses.js +17 -15
  71. package/dist/atlas/oscillators/limit-witnesses.js.map +1 -1
  72. package/dist/atlas/oscillators/models.d.ts.map +1 -1
  73. package/dist/atlas/oscillators/models.js +2 -6
  74. package/dist/atlas/oscillators/models.js.map +1 -1
  75. package/dist/atlas/oscillators/pendulum-motion.d.ts +29 -6
  76. package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -1
  77. package/dist/atlas/oscillators/pendulum-motion.js +60 -40
  78. package/dist/atlas/oscillators/pendulum-motion.js.map +1 -1
  79. package/dist/atlas/oscillators/phase-translation.d.ts +0 -11
  80. package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -1
  81. package/dist/atlas/oscillators/phase-translation.js +3 -4
  82. package/dist/atlas/oscillators/phase-translation.js.map +1 -1
  83. package/dist/atlas/oscillators/position-translation.d.ts +68 -7
  84. package/dist/atlas/oscillators/position-translation.d.ts.map +1 -1
  85. package/dist/atlas/oscillators/position-translation.js +123 -12
  86. package/dist/atlas/oscillators/position-translation.js.map +1 -1
  87. package/dist/atlas/oscillators/rejections.d.ts +0 -2
  88. package/dist/atlas/oscillators/rejections.d.ts.map +1 -1
  89. package/dist/atlas/oscillators/rejections.js +0 -7
  90. package/dist/atlas/oscillators/rejections.js.map +1 -1
  91. package/dist/atlas/physjs-entries.generated.d.ts +25 -24
  92. package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
  93. package/dist/atlas/physjs-entries.generated.js +25 -24
  94. package/dist/atlas/physjs-entries.generated.js.map +1 -1
  95. package/dist/atlas/physjs-ref.d.ts +34 -31
  96. package/dist/atlas/physjs-ref.d.ts.map +1 -1
  97. package/dist/atlas/physjs-ref.js +55 -53
  98. package/dist/atlas/physjs-ref.js.map +1 -1
  99. package/dist/atlas/physjs-reviewed.d.ts +1 -1
  100. package/dist/atlas/physjs-reviewed.js +15 -15
  101. package/dist/atlas/physjs-reviewed.js.map +1 -1
  102. package/dist/atlas/poster/statements.d.ts +0 -19
  103. package/dist/atlas/poster/statements.d.ts.map +1 -1
  104. package/dist/atlas/poster/statements.js +1 -1
  105. package/dist/atlas/poster/statements.js.map +1 -1
  106. package/dist/atlas/proof-target.d.ts +1 -1
  107. package/dist/atlas/proof-target.js +1 -1
  108. package/dist/atlas/proof-target.js.map +1 -1
  109. package/dist/atlas/regime.d.ts +1 -1
  110. package/dist/atlas/regime.d.ts.map +1 -1
  111. package/dist/atlas/regime.js +1 -1
  112. package/dist/atlas/regime.js.map +1 -1
  113. package/dist/atlas/text-overlap.d.ts +23 -0
  114. package/dist/atlas/text-overlap.d.ts.map +1 -0
  115. package/dist/atlas/text-overlap.js +41 -0
  116. package/dist/atlas/text-overlap.js.map +1 -0
  117. package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
  118. package/dist/atlas/waves/bridges-closure.js +2 -6
  119. package/dist/atlas/waves/bridges-closure.js.map +1 -1
  120. package/dist/atlas/waves/bridges.d.ts.map +1 -1
  121. package/dist/atlas/waves/bridges.js +32 -48
  122. package/dist/atlas/waves/bridges.js.map +1 -1
  123. package/dist/atlas/waves/models.d.ts +5 -6
  124. package/dist/atlas/waves/models.d.ts.map +1 -1
  125. package/dist/atlas/waves/models.js +7 -13
  126. package/dist/atlas/waves/models.js.map +1 -1
  127. package/dist/atlas/waves/numerics.d.ts.map +1 -1
  128. package/dist/atlas/waves/numerics.js +10 -3
  129. package/dist/atlas/waves/numerics.js.map +1 -1
  130. package/dist/atlas/witness-numeric.d.ts +30 -0
  131. package/dist/atlas/witness-numeric.d.ts.map +1 -1
  132. package/dist/atlas/witness-numeric.js +53 -0
  133. package/dist/atlas/witness-numeric.js.map +1 -1
  134. package/dist/atlas/witness-specs.d.ts.map +1 -1
  135. package/dist/atlas/witness-specs.js +19 -0
  136. package/dist/atlas/witness-specs.js.map +1 -1
  137. package/dist/atlas/witness-symbolic.d.ts +75 -3
  138. package/dist/atlas/witness-symbolic.d.ts.map +1 -1
  139. package/dist/atlas/witness-symbolic.js +116 -10
  140. package/dist/atlas/witness-symbolic.js.map +1 -1
  141. package/dist/bridges/catalog-load.d.ts.map +1 -1
  142. package/dist/bridges/catalog-load.js +13 -8
  143. package/dist/bridges/catalog-load.js.map +1 -1
  144. package/dist/bridges/catalog-types.d.ts +26 -2
  145. package/dist/bridges/catalog-types.d.ts.map +1 -1
  146. package/dist/bridges/catalog-types.js +11 -1
  147. package/dist/bridges/catalog-types.js.map +1 -1
  148. package/dist/bridges/evaluation-errors.d.ts +31 -1
  149. package/dist/bridges/evaluation-errors.d.ts.map +1 -1
  150. package/dist/bridges/evaluation-errors.js +20 -2
  151. package/dist/bridges/evaluation-errors.js.map +1 -1
  152. package/dist/bridges/evaluator-inputs.d.ts.map +1 -1
  153. package/dist/bridges/evaluator-inputs.js +7 -5
  154. package/dist/bridges/evaluator-inputs.js.map +1 -1
  155. package/dist/bridges/evaluators.d.ts.map +1 -1
  156. package/dist/bridges/evaluators.js +27 -12
  157. package/dist/bridges/evaluators.js.map +1 -1
  158. package/dist/bridges/expr-parse.d.ts +11 -0
  159. package/dist/bridges/expr-parse.d.ts.map +1 -1
  160. package/dist/bridges/expr-parse.js +14 -5
  161. package/dist/bridges/expr-parse.js.map +1 -1
  162. package/dist/bridges/holds.d.ts +35 -3
  163. package/dist/bridges/holds.d.ts.map +1 -1
  164. package/dist/bridges/holds.js +117 -23
  165. package/dist/bridges/holds.js.map +1 -1
  166. package/dist/bridges/notices.d.ts.map +1 -1
  167. package/dist/bridges/notices.js +5 -5
  168. package/dist/bridges/notices.js.map +1 -1
  169. package/dist/bridges/relation-eval.d.ts +4 -4
  170. package/dist/bridges/relation-eval.d.ts.map +1 -1
  171. package/dist/bridges/relation-eval.js +15 -16
  172. package/dist/bridges/relation-eval.js.map +1 -1
  173. package/dist/bridges/sensitivity.d.ts.map +1 -1
  174. package/dist/bridges/sensitivity.js +3 -3
  175. package/dist/bridges/sensitivity.js.map +1 -1
  176. package/dist/bridges/validity.d.ts +33 -0
  177. package/dist/bridges/validity.d.ts.map +1 -0
  178. package/dist/bridges/validity.js +67 -0
  179. package/dist/bridges/validity.js.map +1 -0
  180. package/dist/canonical/entries/atomic.js +1 -3
  181. package/dist/canonical/entries/atomic.js.map +1 -1
  182. package/dist/canonical/entries/condensed-matter.d.ts.map +1 -1
  183. package/dist/canonical/entries/condensed-matter.js +4 -5
  184. package/dist/canonical/entries/condensed-matter.js.map +1 -1
  185. package/dist/canonical/entries/dimensional-classics.d.ts.map +1 -1
  186. package/dist/canonical/entries/dimensional-classics.js +3 -4
  187. package/dist/canonical/entries/dimensional-classics.js.map +1 -1
  188. package/dist/canonical/entries/electromagnetism.d.ts.map +1 -1
  189. package/dist/canonical/entries/electromagnetism.js +4 -10
  190. package/dist/canonical/entries/electromagnetism.js.map +1 -1
  191. package/dist/canonical/entries/fluids-waves.d.ts.map +1 -1
  192. package/dist/canonical/entries/fluids-waves.js +3 -7
  193. package/dist/canonical/entries/fluids-waves.js.map +1 -1
  194. package/dist/canonical/entries/mechanics.d.ts.map +1 -1
  195. package/dist/canonical/entries/mechanics.js +4 -6
  196. package/dist/canonical/entries/mechanics.js.map +1 -1
  197. package/dist/canonical/entries/nonmonomial.d.ts.map +1 -1
  198. package/dist/canonical/entries/nonmonomial.js +9 -17
  199. package/dist/canonical/entries/nonmonomial.js.map +1 -1
  200. package/dist/canonical/entries/relativity.d.ts.map +1 -1
  201. package/dist/canonical/entries/relativity.js +6 -6
  202. package/dist/canonical/entries/relativity.js.map +1 -1
  203. package/dist/canonical/entries/thermo-nuclear-cosmo.d.ts.map +1 -1
  204. package/dist/canonical/entries/thermo-nuclear-cosmo.js +6 -10
  205. package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
  206. package/dist/canonical/fixed-points.d.ts +94 -0
  207. package/dist/canonical/fixed-points.d.ts.map +1 -0
  208. package/dist/canonical/fixed-points.js +81 -0
  209. package/dist/canonical/fixed-points.js.map +1 -0
  210. package/dist/canonical/linkage.d.ts.map +1 -1
  211. package/dist/canonical/linkage.js +25 -44
  212. package/dist/canonical/linkage.js.map +1 -1
  213. package/dist/canonical/normal-form.d.ts.map +1 -1
  214. package/dist/canonical/normal-form.js +5 -11
  215. package/dist/canonical/normal-form.js.map +1 -1
  216. package/dist/canonical/structural.d.ts +21 -21
  217. package/dist/canonical/structural.d.ts.map +1 -1
  218. package/dist/canonical/structural.js +40 -19
  219. package/dist/canonical/structural.js.map +1 -1
  220. package/dist/cases/brownian-sphere.d.ts +3 -3
  221. package/dist/cases/brownian-sphere.d.ts.map +1 -1
  222. package/dist/cases/brownian-sphere.js +6 -5
  223. package/dist/cases/brownian-sphere.js.map +1 -1
  224. package/dist/cases/damped-resonator.d.ts.map +1 -1
  225. package/dist/cases/damped-resonator.js +6 -9
  226. package/dist/cases/damped-resonator.js.map +1 -1
  227. package/dist/cases/kepler-rv.d.ts +1 -1
  228. package/dist/cases/kepler-rv.d.ts.map +1 -1
  229. package/dist/cases/kepler-rv.js +3 -2
  230. package/dist/cases/kepler-rv.js.map +1 -1
  231. package/dist/cases/lumped-cooling.d.ts +8 -3
  232. package/dist/cases/lumped-cooling.d.ts.map +1 -1
  233. package/dist/cases/lumped-cooling.js +21 -23
  234. package/dist/cases/lumped-cooling.js.map +1 -1
  235. package/dist/cases/quadrature.d.ts +7 -9
  236. package/dist/cases/quadrature.d.ts.map +1 -1
  237. package/dist/cases/quadrature.js +28 -32
  238. package/dist/cases/quadrature.js.map +1 -1
  239. package/dist/cases/resistor-noise.js +4 -4
  240. package/dist/cases/resistor-noise.js.map +1 -1
  241. package/dist/cases/skin-depth.d.ts +0 -4
  242. package/dist/cases/skin-depth.d.ts.map +1 -1
  243. package/dist/cases/skin-depth.js +3 -7
  244. package/dist/cases/skin-depth.js.map +1 -1
  245. package/dist/cli/args.d.ts +23 -1
  246. package/dist/cli/args.d.ts.map +1 -1
  247. package/dist/cli/args.js +30 -8
  248. package/dist/cli/args.js.map +1 -1
  249. package/dist/cli/bindings.d.ts.map +1 -1
  250. package/dist/cli/bindings.js +5 -4
  251. package/dist/cli/bindings.js.map +1 -1
  252. package/dist/cli/command.d.ts +8 -1
  253. package/dist/cli/command.d.ts.map +1 -1
  254. package/dist/cli/command.js.map +1 -1
  255. package/dist/cli/commands/_atlas-map.d.ts +0 -9
  256. package/dist/cli/commands/_atlas-map.d.ts.map +1 -1
  257. package/dist/cli/commands/_atlas-map.js +8 -18
  258. package/dist/cli/commands/_atlas-map.js.map +1 -1
  259. package/dist/cli/commands/_atlas-route.d.ts.map +1 -1
  260. package/dist/cli/commands/_atlas-route.js +6 -2
  261. package/dist/cli/commands/_atlas-route.js.map +1 -1
  262. package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
  263. package/dist/cli/commands/_discovery-opts.js +8 -9
  264. package/dist/cli/commands/_discovery-opts.js.map +1 -1
  265. package/dist/cli/commands/atlas.d.ts.map +1 -1
  266. package/dist/cli/commands/atlas.js +8 -5
  267. package/dist/cli/commands/atlas.js.map +1 -1
  268. package/dist/cli/commands/audit.d.ts.map +1 -1
  269. package/dist/cli/commands/audit.js +8 -1
  270. package/dist/cli/commands/audit.js.map +1 -1
  271. package/dist/cli/commands/axes.d.ts.map +1 -1
  272. package/dist/cli/commands/axes.js +20 -1
  273. package/dist/cli/commands/axes.js.map +1 -1
  274. package/dist/cli/commands/confront.d.ts.map +1 -1
  275. package/dist/cli/commands/confront.js +8 -14
  276. package/dist/cli/commands/confront.js.map +1 -1
  277. package/dist/cli/commands/derive.d.ts.map +1 -1
  278. package/dist/cli/commands/derive.js +22 -22
  279. package/dist/cli/commands/derive.js.map +1 -1
  280. package/dist/cli/commands/discover.d.ts.map +1 -1
  281. package/dist/cli/commands/discover.js +6 -2
  282. package/dist/cli/commands/discover.js.map +1 -1
  283. package/dist/cli/commands/eval.d.ts.map +1 -1
  284. package/dist/cli/commands/eval.js +1 -0
  285. package/dist/cli/commands/eval.js.map +1 -1
  286. package/dist/cli/commands/evaluate.d.ts.map +1 -1
  287. package/dist/cli/commands/evaluate.js +65 -37
  288. package/dist/cli/commands/evaluate.js.map +1 -1
  289. package/dist/cli/commands/explain.d.ts.map +1 -1
  290. package/dist/cli/commands/explain.js +2 -1
  291. package/dist/cli/commands/explain.js.map +1 -1
  292. package/dist/cli/commands/ground.d.ts.map +1 -1
  293. package/dist/cli/commands/ground.js +1 -0
  294. package/dist/cli/commands/ground.js.map +1 -1
  295. package/dist/cli/commands/map.d.ts.map +1 -1
  296. package/dist/cli/commands/map.js +75 -5
  297. package/dist/cli/commands/map.js.map +1 -1
  298. package/dist/cli/commands/metric.d.ts.map +1 -1
  299. package/dist/cli/commands/metric.js +12 -9
  300. package/dist/cli/commands/metric.js.map +1 -1
  301. package/dist/cli/commands/path.d.ts +10 -0
  302. package/dist/cli/commands/path.d.ts.map +1 -1
  303. package/dist/cli/commands/path.js +25 -3
  304. package/dist/cli/commands/path.js.map +1 -1
  305. package/dist/cli/commands/probe.d.ts.map +1 -1
  306. package/dist/cli/commands/probe.js +59 -16
  307. package/dist/cli/commands/probe.js.map +1 -1
  308. package/dist/cli/commands/regime.d.ts.map +1 -1
  309. package/dist/cli/commands/regime.js +1 -0
  310. package/dist/cli/commands/regime.js.map +1 -1
  311. package/dist/cli/commands/retrieve.d.ts.map +1 -1
  312. package/dist/cli/commands/retrieve.js +1 -0
  313. package/dist/cli/commands/retrieve.js.map +1 -1
  314. package/dist/cli/commands/search.d.ts.map +1 -1
  315. package/dist/cli/commands/search.js +1 -0
  316. package/dist/cli/commands/search.js.map +1 -1
  317. package/dist/cli/commands/symbolic.d.ts.map +1 -1
  318. package/dist/cli/commands/symbolic.js +19 -28
  319. package/dist/cli/commands/symbolic.js.map +1 -1
  320. package/dist/cli/commands/testplan.d.ts.map +1 -1
  321. package/dist/cli/commands/testplan.js +4 -2
  322. package/dist/cli/commands/testplan.js.map +1 -1
  323. package/dist/cli/expr-print.d.ts +0 -2
  324. package/dist/cli/expr-print.d.ts.map +1 -1
  325. package/dist/cli/expr-print.js +7 -31
  326. package/dist/cli/expr-print.js.map +1 -1
  327. package/dist/cli/main.d.ts +7 -0
  328. package/dist/cli/main.d.ts.map +1 -1
  329. package/dist/cli/main.js +18 -3
  330. package/dist/cli/main.js.map +1 -1
  331. package/dist/cli/numeric-flag.d.ts +12 -0
  332. package/dist/cli/numeric-flag.d.ts.map +1 -0
  333. package/dist/cli/numeric-flag.js +44 -0
  334. package/dist/cli/numeric-flag.js.map +1 -0
  335. package/dist/cli/output.d.ts +20 -0
  336. package/dist/cli/output.d.ts.map +1 -1
  337. package/dist/cli/output.js +15 -0
  338. package/dist/cli/output.js.map +1 -1
  339. package/dist/cli/record-reach.js +2 -2
  340. package/dist/cli/record-reach.js.map +1 -1
  341. package/dist/cli/record-tables.d.ts.map +1 -1
  342. package/dist/cli/record-tables.js +6 -5
  343. package/dist/cli/record-tables.js.map +1 -1
  344. package/dist/cli/record.d.ts +1 -5
  345. package/dist/cli/record.d.ts.map +1 -1
  346. package/dist/cli/record.js +9 -8
  347. package/dist/cli/record.js.map +1 -1
  348. package/dist/cli/search-index.d.ts.map +1 -1
  349. package/dist/cli/search-index.js +7 -6
  350. package/dist/cli/search-index.js.map +1 -1
  351. package/dist/cli/statuses.d.ts +0 -2
  352. package/dist/cli/statuses.d.ts.map +1 -1
  353. package/dist/cli/statuses.js +0 -7
  354. package/dist/cli/statuses.js.map +1 -1
  355. package/dist/cli/stored-results.d.ts +7 -0
  356. package/dist/cli/stored-results.d.ts.map +1 -0
  357. package/dist/cli/stored-results.js +23 -0
  358. package/dist/cli/stored-results.js.map +1 -0
  359. package/dist/cli/version.d.ts.map +1 -1
  360. package/dist/cli/version.js +7 -5
  361. package/dist/cli/version.js.map +1 -1
  362. package/dist/cli-api.d.ts +34 -5
  363. package/dist/cli-api.d.ts.map +1 -1
  364. package/dist/cli-api.js +28 -4
  365. package/dist/cli-api.js.map +1 -1
  366. package/dist/composition/algebraic-equivalence.d.ts +43 -0
  367. package/dist/composition/algebraic-equivalence.d.ts.map +1 -0
  368. package/dist/composition/algebraic-equivalence.js +115 -0
  369. package/dist/composition/algebraic-equivalence.js.map +1 -0
  370. package/dist/composition/axes.d.ts +0 -6
  371. package/dist/composition/axes.d.ts.map +1 -1
  372. package/dist/composition/axes.js +6 -6
  373. package/dist/composition/axes.js.map +1 -1
  374. package/dist/composition/axis-audit.d.ts +47 -20
  375. package/dist/composition/axis-audit.d.ts.map +1 -1
  376. package/dist/composition/axis-audit.js +82 -9
  377. package/dist/composition/axis-audit.js.map +1 -1
  378. package/dist/composition/bridge-analysis.d.ts +17 -0
  379. package/dist/composition/bridge-analysis.d.ts.map +1 -1
  380. package/dist/composition/bridge-analysis.js +102 -55
  381. package/dist/composition/bridge-analysis.js.map +1 -1
  382. package/dist/composition/canonical-compare.d.ts +40 -0
  383. package/dist/composition/canonical-compare.d.ts.map +1 -1
  384. package/dist/composition/canonical-compare.js +122 -24
  385. package/dist/composition/canonical-compare.js.map +1 -1
  386. package/dist/composition/canonical-graph.d.ts +1 -1
  387. package/dist/composition/canonical-graph.d.ts.map +1 -1
  388. package/dist/composition/canonical-graph.js +9 -36
  389. package/dist/composition/canonical-graph.js.map +1 -1
  390. package/dist/composition/canonical-json.js +2 -2
  391. package/dist/composition/canonical-json.js.map +1 -1
  392. package/dist/composition/catalog-graph.d.ts.map +1 -1
  393. package/dist/composition/catalog-graph.js +2 -5
  394. package/dist/composition/catalog-graph.js.map +1 -1
  395. package/dist/composition/chain-candidate.d.ts +8 -0
  396. package/dist/composition/chain-candidate.d.ts.map +1 -1
  397. package/dist/composition/chain-candidate.js +9 -2
  398. package/dist/composition/chain-candidate.js.map +1 -1
  399. package/dist/composition/chain-match.d.ts +6 -3
  400. package/dist/composition/chain-match.d.ts.map +1 -1
  401. package/dist/composition/chain-match.js +4 -1
  402. package/dist/composition/chain-match.js.map +1 -1
  403. package/dist/composition/chain-result.d.ts.map +1 -1
  404. package/dist/composition/chain-result.js +2 -14
  405. package/dist/composition/chain-result.js.map +1 -1
  406. package/dist/composition/compose-symbolic.d.ts.map +1 -1
  407. package/dist/composition/compose-symbolic.js +3 -2
  408. package/dist/composition/compose-symbolic.js.map +1 -1
  409. package/dist/composition/compose.d.ts.map +1 -1
  410. package/dist/composition/compose.js +13 -5
  411. package/dist/composition/compose.js.map +1 -1
  412. package/dist/composition/composition-recovery.d.ts.map +1 -1
  413. package/dist/composition/composition-recovery.js +4 -7
  414. package/dist/composition/composition-recovery.js.map +1 -1
  415. package/dist/composition/discovery.d.ts +56 -0
  416. package/dist/composition/discovery.d.ts.map +1 -1
  417. package/dist/composition/discovery.js +114 -60
  418. package/dist/composition/discovery.js.map +1 -1
  419. package/dist/composition/edge.d.ts +21 -2
  420. package/dist/composition/edge.d.ts.map +1 -1
  421. package/dist/composition/edge.js +23 -1
  422. package/dist/composition/edge.js.map +1 -1
  423. package/dist/composition/enumerate.d.ts.map +1 -1
  424. package/dist/composition/enumerate.js +18 -3
  425. package/dist/composition/enumerate.js.map +1 -1
  426. package/dist/composition/evaluate-relation.d.ts +35 -11
  427. package/dist/composition/evaluate-relation.d.ts.map +1 -1
  428. package/dist/composition/evaluate-relation.js +60 -39
  429. package/dist/composition/evaluate-relation.js.map +1 -1
  430. package/dist/composition/explain.d.ts +3 -12
  431. package/dist/composition/explain.d.ts.map +1 -1
  432. package/dist/composition/explain.js +7 -20
  433. package/dist/composition/explain.js.map +1 -1
  434. package/dist/composition/expr-eval.d.ts.map +1 -1
  435. package/dist/composition/expr-eval.js +2 -11
  436. package/dist/composition/expr-eval.js.map +1 -1
  437. package/dist/composition/expr-simplify.d.ts +16 -0
  438. package/dist/composition/expr-simplify.d.ts.map +1 -1
  439. package/dist/composition/expr-simplify.js +15 -20
  440. package/dist/composition/expr-simplify.js.map +1 -1
  441. package/dist/composition/formula-shape.d.ts +23 -4
  442. package/dist/composition/formula-shape.d.ts.map +1 -1
  443. package/dist/composition/formula-shape.js +57 -17
  444. package/dist/composition/formula-shape.js.map +1 -1
  445. package/dist/composition/graph-structure.d.ts +98 -0
  446. package/dist/composition/graph-structure.d.ts.map +1 -0
  447. package/dist/composition/graph-structure.js +167 -0
  448. package/dist/composition/graph-structure.js.map +1 -0
  449. package/dist/composition/graph-viz-svg.d.ts.map +1 -1
  450. package/dist/composition/graph-viz-svg.js +1 -1
  451. package/dist/composition/graph-viz-svg.js.map +1 -1
  452. package/dist/composition/graph-viz.d.ts.map +1 -1
  453. package/dist/composition/graph-viz.js +8 -37
  454. package/dist/composition/graph-viz.js.map +1 -1
  455. package/dist/composition/identifiability.d.ts +91 -4
  456. package/dist/composition/identifiability.d.ts.map +1 -1
  457. package/dist/composition/identifiability.js +363 -6
  458. package/dist/composition/identifiability.js.map +1 -1
  459. package/dist/composition/index.d.ts +8 -4
  460. package/dist/composition/index.d.ts.map +1 -1
  461. package/dist/composition/index.js +3 -2
  462. package/dist/composition/index.js.map +1 -1
  463. package/dist/composition/mathts-quiet.d.ts +4 -3
  464. package/dist/composition/mathts-quiet.d.ts.map +1 -1
  465. package/dist/composition/mathts-quiet.js +4 -3
  466. package/dist/composition/mathts-quiet.js.map +1 -1
  467. package/dist/composition/mathts-scalar-symbols.d.ts.map +1 -1
  468. package/dist/composition/mathts-scalar-symbols.js +2 -1
  469. package/dist/composition/mathts-scalar-symbols.js.map +1 -1
  470. package/dist/composition/probe/corpus.d.ts +4 -2
  471. package/dist/composition/probe/corpus.d.ts.map +1 -1
  472. package/dist/composition/probe/corpus.js +20 -9
  473. package/dist/composition/probe/corpus.js.map +1 -1
  474. package/dist/composition/probe/dataset.d.ts +17 -0
  475. package/dist/composition/probe/dataset.d.ts.map +1 -1
  476. package/dist/composition/probe/dataset.js +95 -50
  477. package/dist/composition/probe/dataset.js.map +1 -1
  478. package/dist/composition/probe/experiment-design.d.ts +5 -1
  479. package/dist/composition/probe/experiment-design.d.ts.map +1 -1
  480. package/dist/composition/probe/experiment-design.js +44 -24
  481. package/dist/composition/probe/experiment-design.js.map +1 -1
  482. package/dist/composition/probe/falsify.d.ts.map +1 -1
  483. package/dist/composition/probe/falsify.js +2 -0
  484. package/dist/composition/probe/falsify.js.map +1 -1
  485. package/dist/composition/probe/fit.d.ts +6 -0
  486. package/dist/composition/probe/fit.d.ts.map +1 -1
  487. package/dist/composition/probe/fit.js +46 -22
  488. package/dist/composition/probe/fit.js.map +1 -1
  489. package/dist/composition/probe/frontier.d.ts.map +1 -1
  490. package/dist/composition/probe/frontier.js +33 -15
  491. package/dist/composition/probe/frontier.js.map +1 -1
  492. package/dist/composition/probe/generator.d.ts +27 -1
  493. package/dist/composition/probe/generator.d.ts.map +1 -1
  494. package/dist/composition/probe/generator.js +53 -30
  495. package/dist/composition/probe/generator.js.map +1 -1
  496. package/dist/composition/probe/index.d.ts +14 -0
  497. package/dist/composition/probe/index.d.ts.map +1 -1
  498. package/dist/composition/probe/index.js +6 -0
  499. package/dist/composition/probe/index.js.map +1 -1
  500. package/dist/composition/probe/limits.d.ts +24 -1
  501. package/dist/composition/probe/limits.d.ts.map +1 -1
  502. package/dist/composition/probe/limits.js +53 -11
  503. package/dist/composition/probe/limits.js.map +1 -1
  504. package/dist/composition/probe/pipeline.d.ts.map +1 -1
  505. package/dist/composition/probe/pipeline.js +10 -4
  506. package/dist/composition/probe/pipeline.js.map +1 -1
  507. package/dist/composition/probe/power-law.d.ts +121 -0
  508. package/dist/composition/probe/power-law.d.ts.map +1 -0
  509. package/dist/composition/probe/power-law.js +255 -0
  510. package/dist/composition/probe/power-law.js.map +1 -0
  511. package/dist/composition/probe/problem.d.ts +7 -4
  512. package/dist/composition/probe/problem.d.ts.map +1 -1
  513. package/dist/composition/probe/problem.js +177 -49
  514. package/dist/composition/probe/problem.js.map +1 -1
  515. package/dist/composition/probe/report.js +1 -1
  516. package/dist/composition/probe/report.js.map +1 -1
  517. package/dist/composition/probe/residual.d.ts +6 -1
  518. package/dist/composition/probe/residual.d.ts.map +1 -1
  519. package/dist/composition/probe/residual.js +9 -7
  520. package/dist/composition/probe/residual.js.map +1 -1
  521. package/dist/composition/probe/structure.d.ts +82 -17
  522. package/dist/composition/probe/structure.d.ts.map +1 -1
  523. package/dist/composition/probe/structure.js +129 -55
  524. package/dist/composition/probe/structure.js.map +1 -1
  525. package/dist/composition/probe/study.d.ts +31 -9
  526. package/dist/composition/probe/study.d.ts.map +1 -1
  527. package/dist/composition/probe/study.js +236 -181
  528. package/dist/composition/probe/study.js.map +1 -1
  529. package/dist/composition/probe/t-tail.d.ts +17 -0
  530. package/dist/composition/probe/t-tail.d.ts.map +1 -0
  531. package/dist/composition/probe/t-tail.js +32 -0
  532. package/dist/composition/probe/t-tail.js.map +1 -0
  533. package/dist/composition/probe/types.d.ts +3 -0
  534. package/dist/composition/probe/types.d.ts.map +1 -1
  535. package/dist/composition/probe/types.js.map +1 -1
  536. package/dist/composition/proposed-bridges.d.ts +41 -10
  537. package/dist/composition/proposed-bridges.d.ts.map +1 -1
  538. package/dist/composition/proposed-bridges.js +100 -55
  539. package/dist/composition/proposed-bridges.js.map +1 -1
  540. package/dist/composition/quantity-clusters.d.ts +48 -0
  541. package/dist/composition/quantity-clusters.d.ts.map +1 -0
  542. package/dist/composition/quantity-clusters.js +98 -0
  543. package/dist/composition/quantity-clusters.js.map +1 -0
  544. package/dist/composition/rational-exponent.d.ts +40 -0
  545. package/dist/composition/rational-exponent.d.ts.map +1 -0
  546. package/dist/composition/rational-exponent.js +65 -0
  547. package/dist/composition/rational-exponent.js.map +1 -0
  548. package/dist/composition/representative-values.d.ts +22 -0
  549. package/dist/composition/representative-values.d.ts.map +1 -1
  550. package/dist/composition/representative-values.js +23 -0
  551. package/dist/composition/representative-values.js.map +1 -1
  552. package/dist/composition/retrodiction.d.ts.map +1 -1
  553. package/dist/composition/retrodiction.js +2 -1
  554. package/dist/composition/retrodiction.js.map +1 -1
  555. package/dist/composition/user-equation.d.ts.map +1 -1
  556. package/dist/composition/user-equation.js +2 -2
  557. package/dist/composition/user-equation.js.map +1 -1
  558. package/dist/core/assignment.d.ts +19 -0
  559. package/dist/core/assignment.d.ts.map +1 -0
  560. package/dist/core/assignment.js +19 -0
  561. package/dist/core/assignment.js.map +1 -0
  562. package/dist/core/compare.d.ts +32 -0
  563. package/dist/core/compare.d.ts.map +1 -0
  564. package/dist/core/compare.js +46 -0
  565. package/dist/core/compare.js.map +1 -0
  566. package/dist/core/constants.d.ts +30 -30
  567. package/dist/core/constants.d.ts.map +1 -1
  568. package/dist/core/constants.js +47 -30
  569. package/dist/core/constants.js.map +1 -1
  570. package/dist/core/data-file.d.ts +7 -0
  571. package/dist/core/data-file.d.ts.map +1 -1
  572. package/dist/core/data-file.js +17 -0
  573. package/dist/core/data-file.js.map +1 -1
  574. package/dist/core/format.d.ts +36 -0
  575. package/dist/core/format.d.ts.map +1 -0
  576. package/dist/core/format.js +39 -0
  577. package/dist/core/format.js.map +1 -0
  578. package/dist/core/hash.d.ts +14 -0
  579. package/dist/core/hash.d.ts.map +1 -0
  580. package/dist/core/hash.js +17 -0
  581. package/dist/core/hash.js.map +1 -0
  582. package/dist/core/json-schema.d.ts +2 -0
  583. package/dist/core/json-schema.d.ts.map +1 -1
  584. package/dist/core/json-schema.js +14 -13
  585. package/dist/core/json-schema.js.map +1 -1
  586. package/dist/core/labeled-tensor.d.ts.map +1 -1
  587. package/dist/core/labeled-tensor.js +0 -8
  588. package/dist/core/labeled-tensor.js.map +1 -1
  589. package/dist/core/mathts-read.d.ts +25 -0
  590. package/dist/core/mathts-read.d.ts.map +1 -0
  591. package/dist/core/mathts-read.js +51 -0
  592. package/dist/core/mathts-read.js.map +1 -0
  593. package/dist/core/tensor.d.ts.map +1 -1
  594. package/dist/core/tensor.js +24 -0
  595. package/dist/core/tensor.js.map +1 -1
  596. package/dist/core/types.d.ts +5 -5
  597. package/dist/diff/bridge-gradient.d.ts +19 -6
  598. package/dist/diff/bridge-gradient.d.ts.map +1 -1
  599. package/dist/diff/bridge-gradient.js +19 -11
  600. package/dist/diff/bridge-gradient.js.map +1 -1
  601. package/dist/diff/bridge-specs.d.ts.map +1 -1
  602. package/dist/diff/bridge-specs.js +3 -0
  603. package/dist/diff/bridge-specs.js.map +1 -1
  604. package/dist/dimensional/algebra.d.ts +18 -0
  605. package/dist/dimensional/algebra.d.ts.map +1 -1
  606. package/dist/dimensional/algebra.js +41 -1
  607. package/dist/dimensional/algebra.js.map +1 -1
  608. package/dist/dimensional/ast-builders.d.ts +7 -0
  609. package/dist/dimensional/ast-builders.d.ts.map +1 -1
  610. package/dist/dimensional/ast-builders.js +11 -0
  611. package/dist/dimensional/ast-builders.js.map +1 -1
  612. package/dist/dimensional/ast-leaves.d.ts +81 -0
  613. package/dist/dimensional/ast-leaves.d.ts.map +1 -0
  614. package/dist/dimensional/ast-leaves.js +146 -0
  615. package/dist/dimensional/ast-leaves.js.map +1 -0
  616. package/dist/dimensional/buckingham.d.ts.map +1 -1
  617. package/dist/dimensional/buckingham.js +15 -27
  618. package/dist/dimensional/buckingham.js.map +1 -1
  619. package/dist/dimensional/constant-rows.js +9 -9
  620. package/dist/dimensional/constant-rows.js.map +1 -1
  621. package/dist/dimensional/dimension-inference.d.ts.map +1 -1
  622. package/dist/dimensional/dimension-inference.js +1 -2
  623. package/dist/dimensional/dimension-inference.js.map +1 -1
  624. package/dist/dimensional/errors.d.ts +1 -1
  625. package/dist/dimensional/errors.d.ts.map +1 -1
  626. package/dist/dimensional/errors.js +1 -15
  627. package/dist/dimensional/errors.js.map +1 -1
  628. package/dist/dimensional/exact-scale.d.ts +0 -17
  629. package/dist/dimensional/exact-scale.d.ts.map +1 -1
  630. package/dist/dimensional/exact-scale.js +8 -8
  631. package/dist/dimensional/exact-scale.js.map +1 -1
  632. package/dist/dimensional/gauge-field.d.ts.map +1 -1
  633. package/dist/dimensional/gauge-field.js +2 -2
  634. package/dist/dimensional/gauge-field.js.map +1 -1
  635. package/dist/dimensional/hyphen-names.d.ts +12 -2
  636. package/dist/dimensional/hyphen-names.d.ts.map +1 -1
  637. package/dist/dimensional/hyphen-names.js +44 -19
  638. package/dist/dimensional/hyphen-names.js.map +1 -1
  639. package/dist/dimensional/metric.d.ts.map +1 -1
  640. package/dist/dimensional/metric.js +0 -1
  641. package/dist/dimensional/metric.js.map +1 -1
  642. package/dist/dimensional/symbolic-constants.d.ts +9 -0
  643. package/dist/dimensional/symbolic-constants.d.ts.map +1 -1
  644. package/dist/dimensional/symbolic-constants.js +13 -1
  645. package/dist/dimensional/symbolic-constants.js.map +1 -1
  646. package/dist/dimensional/types.d.ts +36 -0
  647. package/dist/dimensional/types.d.ts.map +1 -1
  648. package/dist/dimensional/types.js +45 -7
  649. package/dist/dimensional/types.js.map +1 -1
  650. package/dist/dimensional/unit-data.js +2 -2
  651. package/dist/dimensional/unit-data.js.map +1 -1
  652. package/dist/index.d.ts +9 -3
  653. package/dist/index.d.ts.map +1 -1
  654. package/dist/index.js +10 -4
  655. package/dist/index.js.map +1 -1
  656. package/dist/numerical/christoffel-flat.d.ts.map +1 -1
  657. package/dist/numerical/christoffel-flat.js +3 -2
  658. package/dist/numerical/christoffel-flat.js.map +1 -1
  659. package/dist/numerical/covariant-eikonal.d.ts.map +1 -1
  660. package/dist/numerical/covariant-eikonal.js +34 -11
  661. package/dist/numerical/covariant-eikonal.js.map +1 -1
  662. package/dist/numerical/curvature-lowering-helpers.js +3 -2
  663. package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
  664. package/dist/numerical/errors.d.ts.map +1 -1
  665. package/dist/numerical/errors.js +0 -3
  666. package/dist/numerical/errors.js.map +1 -1
  667. package/dist/numerical/finite-difference.d.ts +22 -0
  668. package/dist/numerical/finite-difference.d.ts.map +1 -0
  669. package/dist/numerical/finite-difference.js +27 -0
  670. package/dist/numerical/finite-difference.js.map +1 -0
  671. package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
  672. package/dist/numerical/geodesic-integrator.js +22 -14
  673. package/dist/numerical/geodesic-integrator.js.map +1 -1
  674. package/dist/numerical/geometrized.d.ts.map +1 -1
  675. package/dist/numerical/geometrized.js +0 -1
  676. package/dist/numerical/geometrized.js.map +1 -1
  677. package/dist/numerical/mathts-engine.d.ts.map +1 -1
  678. package/dist/numerical/mathts-engine.js +10 -24
  679. package/dist/numerical/mathts-engine.js.map +1 -1
  680. package/dist/numerical/metric-inverse.d.ts.map +1 -1
  681. package/dist/numerical/metric-inverse.js +83 -46
  682. package/dist/numerical/metric-inverse.js.map +1 -1
  683. package/dist/numerical/null-ray-integrator.d.ts +2 -1
  684. package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
  685. package/dist/numerical/null-ray-integrator.js +12 -12
  686. package/dist/numerical/null-ray-integrator.js.map +1 -1
  687. package/dist/numerical/painleve-gullstrand-metric.js +2 -2
  688. package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
  689. package/dist/numerical/perihelion-finder.d.ts +0 -36
  690. package/dist/numerical/perihelion-finder.d.ts.map +1 -1
  691. package/dist/numerical/perihelion-finder.js +41 -87
  692. package/dist/numerical/perihelion-finder.js.map +1 -1
  693. package/dist/numerical/quadrature.d.ts.map +1 -1
  694. package/dist/numerical/quadrature.js +8 -10
  695. package/dist/numerical/quadrature.js.map +1 -1
  696. package/dist/numerical/rk4-trajectory.d.ts +10 -0
  697. package/dist/numerical/rk4-trajectory.d.ts.map +1 -0
  698. package/dist/numerical/rk4-trajectory.js +37 -0
  699. package/dist/numerical/rk4-trajectory.js.map +1 -0
  700. package/dist/numerical/schwarzschild.d.ts +14 -0
  701. package/dist/numerical/schwarzschild.d.ts.map +1 -0
  702. package/dist/numerical/schwarzschild.js +17 -0
  703. package/dist/numerical/schwarzschild.js.map +1 -0
  704. package/dist/numerical/spacetime-metrics.d.ts +12 -0
  705. package/dist/numerical/spacetime-metrics.d.ts.map +1 -1
  706. package/dist/numerical/spacetime-metrics.js +72 -56
  707. package/dist/numerical/spacetime-metrics.js.map +1 -1
  708. package/dist/numerical/statistics.d.ts +24 -0
  709. package/dist/numerical/statistics.d.ts.map +1 -0
  710. package/dist/numerical/statistics.js +52 -0
  711. package/dist/numerical/statistics.js.map +1 -0
  712. package/dist/numerical/tensor-engine.d.ts +21 -0
  713. package/dist/numerical/tensor-engine.d.ts.map +1 -1
  714. package/dist/numerical/tensor-engine.js +12 -0
  715. package/dist/numerical/tensor-engine.js.map +1 -1
  716. package/dist/relations/regime.d.ts +10 -0
  717. package/dist/relations/regime.d.ts.map +1 -1
  718. package/dist/relations/regime.js +18 -1
  719. package/dist/relations/regime.js.map +1 -1
  720. package/package.json +7 -7
@@ -21,13 +21,33 @@
21
21
  * resulting nonlinear system has a unique numeric solution (undecidable
22
22
  * in general for closed-form evaluators). "Independent derivation" means
23
23
  * a structurally distinct edge, NOT a provably-independent formula — two
24
- * edges encoding the same relation are counted as two (an honest
25
- * over-count). The classifier PROPOSES; humans filter (Part-VI §XXVII-B),
26
- * exactly as `enumerateCompositions` does.
24
+ * edges encoding the same relation are counted as two by the forward
25
+ * count (an honest over-count, kept as `surplusConstraints`). The
26
+ * classifier PROPOSES; humans filter (Part-VI §XXVII-B), exactly as
27
+ * `enumerateCompositions` does.
28
+ *
29
+ * TWO INSTRUMENTS, TWO FIELDS. The forward closure fires an edge only when
30
+ * every source is known, so it never reads a law in reverse. The MONOMIAL
31
+ * edges (a `symbolic` product of powers, or a canonical equation with a
32
+ * stated monomial) are also a linear system in log space: `y = C Π xᵢ^aᵢ`
33
+ * is the row `log y − Σ aᵢ log xᵢ = log C`. Stacked with a unit row per
34
+ * known quantity, the exact null space (MathTS `rationalNullspace`) says
35
+ * which quantities are DETERMINED (their column is zero in every basis
36
+ * vector) whichever way the laws are read, and `distinct rows − rank` is
37
+ * the number of independent consistency checks, where a restated monomial
38
+ * is one row, not two. {@link identifiabilityByRank} is that instrument;
39
+ * {@link classifyIdentifiability} reports both, `determinable` being their
40
+ * union, and names every law the rank read in reverse, because a validity
41
+ * domain is stated on the sources and a caller may refuse the inversion.
27
42
  *
28
43
  * @module composition/identifiability
29
44
  */
45
+ import { Fraction } from '@danielsimonjr/mathts-core';
46
+ import { rationalNullspace } from '@danielsimonjr/mathts-functions';
30
47
  import { QUANTITY_IDENTIFICATIONS } from './compose.js';
48
+ import { monomialExponentsExact } from './formula-shape.js';
49
+ import { rationalize } from './rational-exponent.js';
50
+ import { canonicalById } from '../canonical/registry.js';
31
51
  /**
32
52
  * The monotone forward closure: the least set ⊇ `knownNames` closed under
33
53
  * "all of an edge's sources determinable ⟹ its target determinable",
@@ -60,6 +80,317 @@ export function forwardClosure(edges, knownNames, identifications = QUANTITY_IDE
60
80
  }
61
81
  return determinable;
62
82
  }
83
+ /**
84
+ * The exact exponents of `edge`'s target over its source names, read from
85
+ * its `symbolic` form, or, for a canonical edge with no symbolic form, from
86
+ * the equation's stated monomial and `formulaFactors`. A leaf that is not a
87
+ * source (a constant, a literal, a held stub) is part of the prefactor and
88
+ * contributes no column. Undefined when the form is not a monomial, when an
89
+ * exponent is not a small rational, or when the target is among the sources.
90
+ *
91
+ * @internal
92
+ */
93
+ export function edgeMonomial(edge) {
94
+ const sourceNames = new Set(edge.sources.map((s) => s.name));
95
+ if (sourceNames.has(edge.target.name))
96
+ return undefined;
97
+ const out = new Map();
98
+ if (edge.symbolic !== undefined) {
99
+ const exact = monomialExponentsExact(edge.symbolic);
100
+ if (exact === undefined)
101
+ return undefined;
102
+ for (const [name, exp] of exact)
103
+ if (sourceNames.has(name))
104
+ out.set(name, exp);
105
+ return out;
106
+ }
107
+ if (edge.beId !== null)
108
+ return undefined;
109
+ const equation = canonicalById(edge.id);
110
+ const monomial = equation?.dimensional.monomial;
111
+ if (monomial === undefined || monomial === null)
112
+ return undefined;
113
+ const stated = { ...monomial, ...(edge.formulaFactors ?? {}) };
114
+ for (const [name, exp] of Object.entries(stated)) {
115
+ if (!sourceNames.has(name))
116
+ continue;
117
+ const q = rationalize(exp);
118
+ if (q === undefined)
119
+ return undefined;
120
+ out.set(name, q);
121
+ }
122
+ return out;
123
+ }
124
+ /** A row scaled so its first nonzero entry is 1, as a string, so two rows of one relation compare equal. */
125
+ function rowKey(row) {
126
+ const pivot = row.find((f) => !f.isZero());
127
+ if (pivot === undefined)
128
+ return '0';
129
+ return row.map((f) => f.divide(pivot).toString()).join(',');
130
+ }
131
+ const ZERO = new Fraction(0);
132
+ const ONE = new Fraction(1);
133
+ /** Directed identifications: `from` in the set puts `to` in it. */
134
+ function expandByIdentifications(set, identifications) {
135
+ let changed = true;
136
+ while (changed) {
137
+ changed = false;
138
+ for (const ident of identifications) {
139
+ if (set.has(ident.from) && !set.has(ident.to)) {
140
+ set.add(ident.to);
141
+ changed = true;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ const rankIndexCache = new WeakMap();
147
+ /**
148
+ * The monomial rows of `edges` under `reader`, grouped into the connected
149
+ * components of the graph whose vertices are quantity names and whose links
150
+ * are the rows (a row joins its target to each of its sources). The
151
+ * log-space matrix is block-diagonal over these components, so each is
152
+ * solved on its own, once per asserted set, and the answers are exact.
153
+ * Built once per edge array and reader.
154
+ */
155
+ function rankIndex(edges, reader, readerKey) {
156
+ let perEdges = rankIndexCache.get(edges);
157
+ if (perEdges === undefined) {
158
+ perEdges = new Map();
159
+ rankIndexCache.set(edges, perEdges);
160
+ }
161
+ const hit = perEdges.get(readerKey);
162
+ if (hit !== undefined)
163
+ return hit;
164
+ const rows = [];
165
+ for (const edge of edges) {
166
+ const sources = reader(edge);
167
+ if (sources !== undefined)
168
+ rows.push({ id: edge.id, target: edge.target.name, sources });
169
+ }
170
+ const parent = new Map();
171
+ const find = (name) => {
172
+ let root = name;
173
+ while (parent.get(root) !== root)
174
+ root = parent.get(root);
175
+ let cur = name;
176
+ while (cur !== root) {
177
+ const next = parent.get(cur);
178
+ parent.set(cur, root);
179
+ cur = next;
180
+ }
181
+ return root;
182
+ };
183
+ for (const row of rows) {
184
+ if (!parent.has(row.target))
185
+ parent.set(row.target, row.target);
186
+ for (const name of row.sources.keys()) {
187
+ if (!parent.has(name))
188
+ parent.set(name, name);
189
+ const a = find(row.target);
190
+ const b = find(name);
191
+ if (a !== b)
192
+ parent.set(a, b);
193
+ }
194
+ }
195
+ const groups = new Map();
196
+ for (const row of rows) {
197
+ const root = find(row.target);
198
+ let group = groups.get(root);
199
+ if (group === undefined) {
200
+ group = { rows: [], names: new Set() };
201
+ groups.set(root, group);
202
+ }
203
+ group.rows.push(row);
204
+ group.names.add(row.target);
205
+ for (const name of row.sources.keys())
206
+ group.names.add(name);
207
+ }
208
+ const components = [...groups.values()].map((group, index) => ({
209
+ index,
210
+ rows: group.rows,
211
+ names: [...group.names],
212
+ }));
213
+ const componentOf = new Map();
214
+ for (const component of components)
215
+ for (const name of component.names)
216
+ componentOf.set(name, component.index);
217
+ const index = { rows, components, componentOf, solves: new Map() };
218
+ perEdges.set(readerKey, index);
219
+ return index;
220
+ }
221
+ /**
222
+ * Solve one component with the asserted names inside it as unit rows.
223
+ * Memoised per asserted set; a solve whose asserted set extends a cached
224
+ * one by names that solve already determined is that solve with one more
225
+ * dependent row per extra name (an already-determined quantity asserted
226
+ * again is a consistency check, and determines nothing new).
227
+ */
228
+ function solveComponent(index, component, asserted) {
229
+ const inside = component.names.filter((name) => asserted.has(name)).sort();
230
+ let cached = index.solves.get(component.index);
231
+ if (cached === undefined) {
232
+ cached = [];
233
+ index.solves.set(component.index, cached);
234
+ }
235
+ const insideSet = new Set(inside);
236
+ for (const solve of cached) {
237
+ if (solve.inside.length === inside.length && solve.inside.every((name) => insideSet.has(name)))
238
+ return solve;
239
+ }
240
+ for (const solve of cached) {
241
+ if (!solve.inside.every((name) => insideSet.has(name)))
242
+ continue;
243
+ const extra = inside.filter((name) => !solve.inside.includes(name));
244
+ if (extra.every((name) => solve.determined.has(name))) {
245
+ const widened = { inside, determined: solve.determined, surplus: solve.surplus + extra.length };
246
+ cached.push(widened);
247
+ return widened;
248
+ }
249
+ }
250
+ const column = new Map(component.names.map((name, i) => [name, i]));
251
+ const matrix = [];
252
+ const seen = new Set();
253
+ const pushRow = (row) => {
254
+ const k = rowKey(row);
255
+ if (k === '0' || seen.has(k))
256
+ return;
257
+ seen.add(k);
258
+ matrix.push(row);
259
+ };
260
+ for (const row of component.rows) {
261
+ const vector = component.names.map(() => ZERO);
262
+ vector[column.get(row.target)] = ONE;
263
+ for (const [name, exp] of row.sources) {
264
+ const i = column.get(name);
265
+ vector[i] = vector[i].sub(exp);
266
+ }
267
+ pushRow(vector);
268
+ }
269
+ for (const name of inside) {
270
+ const vector = component.names.map(() => ZERO);
271
+ vector[column.get(name)] = ONE;
272
+ pushRow(vector);
273
+ }
274
+ const solved = rationalNullspace(matrix, { columns: component.names.length });
275
+ const determined = new Set(inside);
276
+ component.names.forEach((name, i) => {
277
+ if (solved.basis.every((vector) => vector[i].isZero()))
278
+ determined.add(name);
279
+ });
280
+ const result = { inside, determined, surplus: matrix.length - solved.rank };
281
+ cached.push(result);
282
+ return result;
283
+ }
284
+ /**
285
+ * The asserted set is the known names plus every name a directed
286
+ * identification reaches from a known or a determined one; only these get a
287
+ * unit row, and a name the rank determines is never fed back in as a row
288
+ * (that would count it as a check). Each pass solves the components the
289
+ * asserted set touches (every component when `every`, so the surplus counts
290
+ * the whole system), lets the identifications assert what the determined
291
+ * names reach, and repeats until nothing new is asserted.
292
+ */
293
+ function solveRank(index, knownNames, identifications, every) {
294
+ const asserted = new Set(knownNames);
295
+ expandByIdentifications(asserted, identifications);
296
+ const determined = new Set();
297
+ let surplus = 0;
298
+ for (;;) {
299
+ determined.clear();
300
+ for (const name of asserted)
301
+ determined.add(name);
302
+ surplus = 0;
303
+ for (const component of index.components) {
304
+ if (!every && !component.names.some((name) => asserted.has(name)))
305
+ continue;
306
+ const solve = solveComponent(index, component, asserted);
307
+ for (const name of solve.determined)
308
+ determined.add(name);
309
+ surplus += solve.surplus;
310
+ }
311
+ const before = asserted.size;
312
+ const reach = new Set(determined);
313
+ expandByIdentifications(reach, identifications);
314
+ for (const name of reach)
315
+ if (!determined.has(name))
316
+ asserted.add(name);
317
+ if (asserted.size === before)
318
+ break;
319
+ }
320
+ return { determined, surplus };
321
+ }
322
+ /** The cache of full rank reports per edge array, keyed by the known set and the identifications. */
323
+ const rankCache = new WeakMap();
324
+ function rankCacheKey(known, identifications, custom) {
325
+ return `${[...known].sort().join('\u0001')}|${identifications.map((i) => `${i.from}>${i.to}`).join('\u0001')}|${custom ? 'custom' : 'default'}`;
326
+ }
327
+ /**
328
+ * {@link identifiabilityByRank} with the monomial reader chosen by the
329
+ * caller (the default is {@link edgeMonomial}). A custom reader's index and
330
+ * results are cached beside the default's, never in its place.
331
+ *
332
+ * @internal
333
+ */
334
+ export function identifiabilityByRankWith(edges, knownNames, reader, opts = {}) {
335
+ return rankWithReader(edges, knownNames, reader, reader !== edgeMonomial, opts);
336
+ }
337
+ /**
338
+ * The log-space rank: which quantities the monomial edges determine from
339
+ * `knownNames`, whichever direction each law is read, how many independent
340
+ * consistency checks the system carries, and which laws were read in
341
+ * reverse. Identifications stay directed, as in {@link forwardClosure}: a
342
+ * name they reach joins the known rows, and the system is solved again
343
+ * until nothing new is determined. Non-monomial edges contribute nothing
344
+ * here; the forward closure is their instrument.
345
+ *
346
+ * @public
347
+ */
348
+ export function identifiabilityByRank(edges, knownNames, opts = {}) {
349
+ return rankWithReader(edges, knownNames, edgeMonomial, false, opts);
350
+ }
351
+ function rankWithReader(edges, knownNames, reader, custom, opts) {
352
+ const identifications = opts.identifications ?? QUANTITY_IDENTIFICATIONS;
353
+ const key = rankCacheKey(knownNames, identifications, custom);
354
+ let perEdges = rankCache.get(edges);
355
+ if (perEdges === undefined) {
356
+ perEdges = new Map();
357
+ rankCache.set(edges, perEdges);
358
+ }
359
+ const hit = perEdges.get(key);
360
+ if (hit !== undefined)
361
+ return hit;
362
+ const index = rankIndex(edges, reader, custom ? 'custom' : 'default');
363
+ const { determined, surplus } = solveRank(index, knownNames, identifications, true);
364
+ // A law is read in reverse when one of its sources is determined, and not
365
+ // by the forward closure over the monomial edges alone.
366
+ const monomialIds = new Set(index.rows.map((r) => r.id));
367
+ const forward = forwardClosure(edges.filter((e) => monomialIds.has(e.id)), knownNames, identifications);
368
+ const usedInReverse = index.rows
369
+ .filter((row) => [...row.sources.keys()].some((name) => !forward.has(name) && determined.has(name)))
370
+ .map((row) => row.id);
371
+ const result = {
372
+ determined: [...determined].sort(),
373
+ determinedByRankOnly: [...determined].filter((name) => !forward.has(name)).sort(),
374
+ surplusChecks: surplus,
375
+ usedInReverse,
376
+ monomialEdges: index.rows.map((r) => r.id),
377
+ };
378
+ perEdges.set(key, result);
379
+ return result;
380
+ }
381
+ /**
382
+ * Whether the rank determines `target` from `knownNames`. Only the
383
+ * components the asserted set touches are solved, and each solve is
384
+ * memoised, so the funnel's thousands of calls per anchor cost one solve
385
+ * per touched component, plus one per hypothesis that actually asserts a
386
+ * new name.
387
+ */
388
+ function rankDetermines(edges, knownNames, target, identifications) {
389
+ const index = rankIndex(edges, edgeMonomial, 'default');
390
+ if (!index.componentOf.has(target))
391
+ return false;
392
+ return solveRank(index, knownNames, identifications, false).determined.has(target);
393
+ }
63
394
  /** The quantities from which `targetName` is forward-reachable (its
64
395
  * backward cone, target included). */
65
396
  function backwardCone(edges, targetName) {
@@ -90,7 +421,24 @@ function backwardCone(edges, targetName) {
90
421
  export function classifyIdentifiability(edges, knownNames, targetName, opts = {}) {
91
422
  const identifications = opts.identifications ?? QUANTITY_IDENTIFICATIONS;
92
423
  const known = [...new Set(knownNames)];
93
- const determinable = forwardClosure(edges, known, identifications);
424
+ const closure = forwardClosure(edges, known, identifications);
425
+ // The rank is computed once per result and only when something reads it:
426
+ // the verdict needs it only for a target the closure does not reach, and
427
+ // the funnel classifies thousands of targets whose verdict it does reach.
428
+ let rankMemo;
429
+ const rankOf = () => {
430
+ rankMemo ??= identifiabilityByRank(edges, known, { identifications });
431
+ return rankMemo;
432
+ };
433
+ // The union: the closure (every edge, forward) and the rank (the monomial
434
+ // edges, either way). `determinedByRankOnly` is reported against the whole
435
+ // closure here, so a name the closure reaches through an opaque edge is
436
+ // not counted as rank-only.
437
+ const determinableOf = () => new Set([...closure, ...rankOf().determined]);
438
+ const rankReport = () => {
439
+ const rank = rankOf();
440
+ return { ...rank, determinedByRankOnly: rank.determined.filter((name) => !closure.has(name)) };
441
+ };
94
442
  // Derivations must not depend on the target itself: close over the
95
443
  // graph with every edge INTO the target removed (excludes circular
96
444
  // self-support — see the design note's worked counterexample).
@@ -105,13 +453,16 @@ export function classifyIdentifiability(edges, knownNames, targetName, opts = {}
105
453
  if (isGiven) {
106
454
  verdict = 'given';
107
455
  }
108
- else if (!determinable.has(targetName)) {
456
+ else if (!closure.has(targetName) && !rankDetermines(edges, known, targetName, identifications)) {
109
457
  verdict = 'under-determined';
110
458
  }
111
459
  else if (derivations.length >= 2) {
112
460
  verdict = 'over-determined';
113
461
  }
114
462
  else {
463
+ // One forward derivation, or determined by identity, or determined by
464
+ // the rank alone (then `derivations` is empty and `rank.usedInReverse`
465
+ // names the laws that were read backwards).
115
466
  verdict = 'exactly-determined';
116
467
  }
117
468
  const surplusConstraints = isGiven
@@ -120,6 +471,7 @@ export function classifyIdentifiability(edges, knownNames, targetName, opts = {}
120
471
  let blockingFrontier = [];
121
472
  if (verdict === 'under-determined') {
122
473
  const knownSet = new Set(known);
474
+ const determinable = determinableOf();
123
475
  blockingFrontier = [...backwardCone(edges, targetName)]
124
476
  .filter((q) => q !== targetName && !determinable.has(q) && !knownSet.has(q))
125
477
  .sort();
@@ -131,7 +483,12 @@ export function classifyIdentifiability(edges, knownNames, targetName, opts = {}
131
483
  derivations,
132
484
  surplusConstraints,
133
485
  blockingFrontier,
134
- determinable: [...determinable].sort(),
486
+ get determinable() {
487
+ return [...determinableOf()].sort();
488
+ },
489
+ get rank() {
490
+ return rankReport();
491
+ },
135
492
  };
136
493
  }
137
494
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"identifiability.js","sourceRoot":"","sources":["../../src/composition/identifiability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Identifiability classifier (Consequence 1 of\n * docs/planning/Bridge-Inference-Epistemics-Note.md, designed in\n * docs/planning/Identifiability-Classifier-Design-Note.md).\n *\n * Answers a STRUCTURAL question over the directed hypergraph of\n * `BridgeEdge`s: given a set of known quantities and a target quantity,\n * how many INDEPENDENT ways can the graph compute the target from the\n * knowns? The count drives the epistemics-note trichotomy:\n *\n * - under-determined — unreachable; needs more inputs or more physics.\n * - exactly-determined — one derivation; solvable (up to the\n * dimensionless constant dimensional analysis cannot supply).\n * - over-determined — ≥2 derivations; the surplus are FALSIFIABLE\n * consistency constraints (each predicts the target; they must\n * agree). The headline regime.\n * - given — the target is itself a known (degenerate); derivations\n * become cross-checks on the supplied value.\n *\n * This is STRUCTURAL, not parametric: it does not decide whether the\n * resulting nonlinear system has a unique numeric solution (undecidable\n * in general for closed-form evaluators). \"Independent derivation\" means\n * a structurally distinct edge, NOT a provably-independent formula — two\n * edges encoding the same relation are counted as two (an honest\n * over-count). The classifier PROPOSES; humans filter (Part-VI §XXVII-B),\n * exactly as `enumerateCompositions` does.\n *\n * @module composition/identifiability\n */\n\nimport type { BridgeEdge } from './edge.js';\nimport type { QuantityIdentification } from './compose.js';\nimport { QUANTITY_IDENTIFICATIONS } from './compose.js';\n\n/** The four-way structural-identifiability verdict. @public */\nexport type IdentifiabilityVerdict =\n | 'given'\n | 'under-determined'\n | 'exactly-determined'\n | 'over-determined';\n\n/** Options for the classifier. @public */\nexport interface IdentifiabilityOptions {\n /**\n * Quantity identifications honored when expanding determinability\n * (directed name-equivalences: `from` determinable ⟹ `to` determinable).\n * Defaults to the registered {@link QUANTITY_IDENTIFICATIONS}, mirroring\n * how `composeEdges` connects the graph. Pass `[]` for the pure\n * physical-edge graph.\n */\n readonly identifications?: readonly QuantityIdentification[];\n}\n\n/** The result of classifying one target against one known set. @public */\nexport interface IdentifiabilityResult {\n /** The target quantity name that was classified. */\n readonly target: string;\n /** The known-quantity names (deduplicated). */\n readonly known: readonly string[];\n readonly verdict: IdentifiabilityVerdict;\n /**\n * Ids of the distinct edges that independently derive the target from\n * the known set — sources determinable WITHOUT using any edge into the\n * target (so circular self-support is excluded). Empty ⟺ no physical\n * derivation (under-determined, or determined only by identity).\n */\n readonly derivations: readonly string[];\n /**\n * Redundant derivations = falsifiable consistency constraints. For a\n * non-given target the first derivation pins the value and the rest are\n * checks (`max(0, |derivations| − 1)`); for a given (measured) target\n * every derivation is a check (`|derivations|`).\n */\n readonly surplusConstraints: number;\n /**\n * For under-determined targets: the upstream quantities that block\n * determinability — on some path toward the target, not determinable\n * from the known set, not themselves known. Knowing a sufficient subset\n * moves the target toward determined. Empty when determinable.\n */\n readonly blockingFrontier: readonly string[];\n /** Every quantity determinable from the known set (the forward closure). */\n readonly determinable: readonly string[];\n}\n\n/**\n * The monotone forward closure: the least set ⊇ `knownNames` closed under\n * \"all of an edge's sources determinable ⟹ its target determinable\",\n * with identifications expanding it as directed name-equivalences.\n *\n * A parameter-free edge (empty `sources`) fires unconditionally — its\n * target is in every closure (a constant is always determinable).\n *\n * @public\n */\nexport function forwardClosure(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n identifications: readonly QuantityIdentification[] = QUANTITY_IDENTIFICATIONS,\n): Set<string> {\n const determinable = new Set<string>(knownNames);\n let changed = true;\n while (changed) {\n changed = false;\n for (const ident of identifications) {\n if (determinable.has(ident.from) && !determinable.has(ident.to)) {\n determinable.add(ident.to);\n changed = true;\n }\n }\n for (const e of edges) {\n if (determinable.has(e.target.name)) continue;\n if (e.sources.every((s) => determinable.has(s.name))) {\n determinable.add(e.target.name);\n changed = true;\n }\n }\n }\n return determinable;\n}\n\n/** The quantities from which `targetName` is forward-reachable (its\n * backward cone, target included). */\nfunction backwardCone(\n edges: readonly BridgeEdge[],\n targetName: string,\n): Set<string> {\n const cone = new Set<string>([targetName]);\n let changed = true;\n while (changed) {\n changed = false;\n for (const e of edges) {\n if (!cone.has(e.target.name)) continue;\n for (const s of e.sources) {\n if (!cone.has(s.name)) {\n cone.add(s.name);\n changed = true;\n }\n }\n }\n }\n return cone;\n}\n\n/**\n * Classify the structural identifiability of `targetName` given\n * `knownNames` over `edges`. See the module docs and\n * docs/planning/Identifiability-Classifier-Design-Note.md.\n *\n * @public\n */\nexport function classifyIdentifiability(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n targetName: string,\n opts: IdentifiabilityOptions = {},\n): IdentifiabilityResult {\n const identifications = opts.identifications ?? QUANTITY_IDENTIFICATIONS;\n const known = [...new Set(knownNames)];\n\n const determinable = forwardClosure(edges, known, identifications);\n\n // Derivations must not depend on the target itself: close over the\n // graph with every edge INTO the target removed (excludes circular\n // self-support — see the design note's worked counterexample).\n const edgesMinusIntoTarget = edges.filter(\n (e) => e.target.name !== targetName,\n );\n const dMinusT = forwardClosure(edgesMinusIntoTarget, known, identifications);\n\n const derivations = edges\n .filter(\n (e) =>\n e.target.name === targetName &&\n e.sources.every((s) => dMinusT.has(s.name)),\n )\n .map((e) => e.id);\n\n const isGiven = known.includes(targetName);\n let verdict: IdentifiabilityVerdict;\n if (isGiven) {\n verdict = 'given';\n } else if (!determinable.has(targetName)) {\n verdict = 'under-determined';\n } else if (derivations.length >= 2) {\n verdict = 'over-determined';\n } else {\n verdict = 'exactly-determined';\n }\n\n const surplusConstraints = isGiven\n ? derivations.length\n : Math.max(0, derivations.length - 1);\n\n let blockingFrontier: string[] = [];\n if (verdict === 'under-determined') {\n const knownSet = new Set(known);\n blockingFrontier = [...backwardCone(edges, targetName)]\n .filter(\n (q) => q !== targetName && !determinable.has(q) && !knownSet.has(q),\n )\n .sort();\n }\n\n return {\n target: targetName,\n known,\n verdict,\n derivations,\n surplusConstraints,\n blockingFrontier,\n determinable: [...determinable].sort(),\n };\n}\n\n/**\n * Classify every quantity that is some edge's target, against one known\n * set. The natural feeder for a retrodiction harness (mask a node, ask\n * whether the graph recovers it). Sorted by target name.\n *\n * @public\n */\nexport function classifyAll(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n opts: IdentifiabilityOptions = {},\n): IdentifiabilityResult[] {\n const targets = [...new Set(edges.map((e) => e.target.name))].sort();\n return targets.map((t) =>\n classifyIdentifiability(edges, knownNames, t, opts),\n );\n}\n"]}
1
+ {"version":3,"file":"identifiability.js","sourceRoot":"","sources":["../../src/composition/identifiability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Identifiability classifier (Consequence 1 of\n * docs/planning/Bridge-Inference-Epistemics-Note.md, designed in\n * docs/planning/Identifiability-Classifier-Design-Note.md).\n *\n * Answers a STRUCTURAL question over the directed hypergraph of\n * `BridgeEdge`s: given a set of known quantities and a target quantity,\n * how many INDEPENDENT ways can the graph compute the target from the\n * knowns? The count drives the epistemics-note trichotomy:\n *\n * - under-determined — unreachable; needs more inputs or more physics.\n * - exactly-determined — one derivation; solvable (up to the\n * dimensionless constant dimensional analysis cannot supply).\n * - over-determined — ≥2 derivations; the surplus are FALSIFIABLE\n * consistency constraints (each predicts the target; they must\n * agree). The headline regime.\n * - given — the target is itself a known (degenerate); derivations\n * become cross-checks on the supplied value.\n *\n * This is STRUCTURAL, not parametric: it does not decide whether the\n * resulting nonlinear system has a unique numeric solution (undecidable\n * in general for closed-form evaluators). \"Independent derivation\" means\n * a structurally distinct edge, NOT a provably-independent formula — two\n * edges encoding the same relation are counted as two by the forward\n * count (an honest over-count, kept as `surplusConstraints`). The\n * classifier PROPOSES; humans filter (Part-VI §XXVII-B), exactly as\n * `enumerateCompositions` does.\n *\n * TWO INSTRUMENTS, TWO FIELDS. The forward closure fires an edge only when\n * every source is known, so it never reads a law in reverse. The MONOMIAL\n * edges (a `symbolic` product of powers, or a canonical equation with a\n * stated monomial) are also a linear system in log space: `y = C Π xᵢ^aᵢ`\n * is the row `log y − Σ aᵢ log xᵢ = log C`. Stacked with a unit row per\n * known quantity, the exact null space (MathTS `rationalNullspace`) says\n * which quantities are DETERMINED (their column is zero in every basis\n * vector) whichever way the laws are read, and `distinct rows − rank` is\n * the number of independent consistency checks, where a restated monomial\n * is one row, not two. {@link identifiabilityByRank} is that instrument;\n * {@link classifyIdentifiability} reports both, `determinable` being their\n * union, and names every law the rank read in reverse, because a validity\n * domain is stated on the sources and a caller may refuse the inversion.\n *\n * @module composition/identifiability\n */\n\nimport { Fraction } from '@danielsimonjr/mathts-core';\nimport { rationalNullspace } from '@danielsimonjr/mathts-functions';\nimport type { BridgeEdge } from './edge.js';\nimport type { QuantityIdentification } from './compose.js';\nimport { QUANTITY_IDENTIFICATIONS } from './compose.js';\nimport { monomialExponentsExact } from './formula-shape.js';\nimport { rationalize } from './rational-exponent.js';\nimport { canonicalById } from '../canonical/registry.js';\n\n/** The four-way structural-identifiability verdict. @public */\nexport type IdentifiabilityVerdict =\n | 'given'\n | 'under-determined'\n | 'exactly-determined'\n | 'over-determined';\n\n/** Options for the classifier. @public */\nexport interface IdentifiabilityOptions {\n /**\n * Quantity identifications honored when expanding determinability\n * (directed name-equivalences: `from` determinable ⟹ `to` determinable).\n * Defaults to the registered {@link QUANTITY_IDENTIFICATIONS}, mirroring\n * how `composeEdges` connects the graph. Pass `[]` for the pure\n * physical-edge graph.\n */\n readonly identifications?: readonly QuantityIdentification[];\n}\n\n/**\n * What the log-space rank says about one known set, over the monomial edges\n * of the graph. See the module docs: this is the second instrument beside\n * the forward closure, and its numbers are not the closure's.\n *\n * @public\n */\nexport interface RankIdentifiability {\n /** Every quantity whose column is zero in every null-space basis vector, sorted. */\n readonly determined: readonly string[];\n /** The quantities the rank determines that the forward closure does not, sorted. */\n readonly determinedByRankOnly: readonly string[];\n /**\n * Independent consistency checks the system carries: distinct rows\n * (a restated monomial is one row) minus the rank. Zero when every row\n * is needed to determine what it determines.\n */\n readonly surplusChecks: number;\n /**\n * Ids of the monomial edges the rank read against their direction: a\n * source of the edge is determined, and not by the forward closure over\n * the monomial edges. A caller whose validity domain is stated on the\n * sources may refuse these.\n */\n readonly usedInReverse: readonly string[];\n /** Ids of the edges that contributed a row (a readable monomial, target not among its sources). */\n readonly monomialEdges: readonly string[];\n}\n\n/** The result of classifying one target against one known set. @public */\nexport interface IdentifiabilityResult {\n /** The target quantity name that was classified. */\n readonly target: string;\n /** The known-quantity names (deduplicated). */\n readonly known: readonly string[];\n readonly verdict: IdentifiabilityVerdict;\n /**\n * Ids of the distinct edges that independently derive the target from\n * the known set — sources determinable WITHOUT using any edge into the\n * target (so circular self-support is excluded). Empty ⟺ no physical\n * derivation (under-determined, or determined only by identity).\n */\n readonly derivations: readonly string[];\n /**\n * Redundant derivations = falsifiable consistency constraints. For a\n * non-given target the first derivation pins the value and the rest are\n * checks (`max(0, |derivations| − 1)`); for a given (measured) target\n * every derivation is a check (`|derivations|`).\n */\n readonly surplusConstraints: number;\n /**\n * For under-determined targets: the upstream quantities that block\n * determinability — on some path toward the target, not determinable\n * from the known set, not themselves known. Knowing a sufficient subset\n * moves the target toward determined. Empty when determinable.\n */\n readonly blockingFrontier: readonly string[];\n /**\n * Every quantity determinable from the known set: the forward closure\n * united with what the log-space rank determines through the monomial\n * edges (`rank.determined`), sorted.\n */\n readonly determinable: readonly string[];\n /** The rank instrument's own report for this known set. */\n readonly rank: RankIdentifiability;\n}\n\n/**\n * The monotone forward closure: the least set ⊇ `knownNames` closed under\n * \"all of an edge's sources determinable ⟹ its target determinable\",\n * with identifications expanding it as directed name-equivalences.\n *\n * A parameter-free edge (empty `sources`) fires unconditionally — its\n * target is in every closure (a constant is always determinable).\n *\n * @public\n */\nexport function forwardClosure(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n identifications: readonly QuantityIdentification[] = QUANTITY_IDENTIFICATIONS,\n): Set<string> {\n const determinable = new Set<string>(knownNames);\n let changed = true;\n while (changed) {\n changed = false;\n for (const ident of identifications) {\n if (determinable.has(ident.from) && !determinable.has(ident.to)) {\n determinable.add(ident.to);\n changed = true;\n }\n }\n for (const e of edges) {\n if (determinable.has(e.target.name)) continue;\n if (e.sources.every((s) => determinable.has(s.name))) {\n determinable.add(e.target.name);\n changed = true;\n }\n }\n }\n return determinable;\n}\n\n// ---------------------------------------------------------------------------\n// The log-space rank over the monomial edges.\n// ---------------------------------------------------------------------------\n\n/**\n * The exact exponents of an edge's monomial over its SOURCE names, or\n * undefined when it is not one. Internal: a `Fraction` is not a root type.\n * @internal\n */\nexport type EdgeMonomialReader = (edge: BridgeEdge) => ReadonlyMap<string, Fraction> | undefined;\n\n/**\n * The exact exponents of `edge`'s target over its source names, read from\n * its `symbolic` form, or, for a canonical edge with no symbolic form, from\n * the equation's stated monomial and `formulaFactors`. A leaf that is not a\n * source (a constant, a literal, a held stub) is part of the prefactor and\n * contributes no column. Undefined when the form is not a monomial, when an\n * exponent is not a small rational, or when the target is among the sources.\n *\n * @internal\n */\nexport function edgeMonomial(edge: BridgeEdge): ReadonlyMap<string, Fraction> | undefined {\n const sourceNames = new Set(edge.sources.map((s) => s.name));\n if (sourceNames.has(edge.target.name)) return undefined;\n const out = new Map<string, Fraction>();\n if (edge.symbolic !== undefined) {\n const exact = monomialExponentsExact(edge.symbolic);\n if (exact === undefined) return undefined;\n for (const [name, exp] of exact) if (sourceNames.has(name)) out.set(name, exp);\n return out;\n }\n if (edge.beId !== null) return undefined;\n const equation = canonicalById(edge.id);\n const monomial = equation?.dimensional.monomial;\n if (monomial === undefined || monomial === null) return undefined;\n const stated: Record<string, number> = { ...monomial, ...(edge.formulaFactors ?? {}) };\n for (const [name, exp] of Object.entries(stated)) {\n if (!sourceNames.has(name)) continue;\n const q = rationalize(exp);\n if (q === undefined) return undefined;\n out.set(name, q);\n }\n return out;\n}\n\ninterface MonomialRow {\n readonly id: string;\n readonly target: string;\n readonly sources: ReadonlyMap<string, Fraction>;\n}\n\n/** A row scaled so its first nonzero entry is 1, as a string, so two rows of one relation compare equal. */\nfunction rowKey(row: readonly Fraction[]): string {\n const pivot = row.find((f) => !f.isZero());\n if (pivot === undefined) return '0';\n return row.map((f) => f.divide(pivot).toString()).join(',');\n}\n\nconst ZERO = new Fraction(0);\nconst ONE = new Fraction(1);\n\n/** Directed identifications: `from` in the set puts `to` in it. */\nfunction expandByIdentifications(set: Set<string>, identifications: readonly QuantityIdentification[]): void {\n let changed = true;\n while (changed) {\n changed = false;\n for (const ident of identifications) {\n if (set.has(ident.from) && !set.has(ident.to)) {\n set.add(ident.to);\n changed = true;\n }\n }\n }\n}\n\n/** One connected component of the monomial graph: its rows and its column names. */\ninterface MonomialComponent {\n readonly index: number;\n readonly rows: readonly MonomialRow[];\n readonly names: readonly string[];\n}\n\n/** The solve of one component under one asserted set. */\ninterface ComponentSolve {\n /** The asserted names inside the component, sorted. */\n readonly inside: readonly string[];\n readonly determined: ReadonlySet<string>;\n /** Distinct rows minus rank, for this component. */\n readonly surplus: number;\n}\n\n/** The rows, the components and the memo of component solves, per edge array and reader. */\ninterface RankIndex {\n readonly rows: readonly MonomialRow[];\n readonly components: readonly MonomialComponent[];\n readonly componentOf: ReadonlyMap<string, number>;\n readonly solves: Map<number, ComponentSolve[]>;\n}\n\nconst rankIndexCache = new WeakMap<readonly BridgeEdge[], Map<string, RankIndex>>();\n\n/**\n * The monomial rows of `edges` under `reader`, grouped into the connected\n * components of the graph whose vertices are quantity names and whose links\n * are the rows (a row joins its target to each of its sources). The\n * log-space matrix is block-diagonal over these components, so each is\n * solved on its own, once per asserted set, and the answers are exact.\n * Built once per edge array and reader.\n */\nfunction rankIndex(edges: readonly BridgeEdge[], reader: EdgeMonomialReader, readerKey: string): RankIndex {\n let perEdges = rankIndexCache.get(edges);\n if (perEdges === undefined) {\n perEdges = new Map();\n rankIndexCache.set(edges, perEdges);\n }\n const hit = perEdges.get(readerKey);\n if (hit !== undefined) return hit;\n\n const rows: MonomialRow[] = [];\n for (const edge of edges) {\n const sources = reader(edge);\n if (sources !== undefined) rows.push({ id: edge.id, target: edge.target.name, sources });\n }\n const parent = new Map<string, string>();\n const find = (name: string): string => {\n let root = name;\n while (parent.get(root) !== root) root = parent.get(root)!;\n let cur = name;\n while (cur !== root) {\n const next = parent.get(cur)!;\n parent.set(cur, root);\n cur = next;\n }\n return root;\n };\n for (const row of rows) {\n if (!parent.has(row.target)) parent.set(row.target, row.target);\n for (const name of row.sources.keys()) {\n if (!parent.has(name)) parent.set(name, name);\n const a = find(row.target);\n const b = find(name);\n if (a !== b) parent.set(a, b);\n }\n }\n const groups = new Map<string, { rows: MonomialRow[]; names: Set<string> }>();\n for (const row of rows) {\n const root = find(row.target);\n let group = groups.get(root);\n if (group === undefined) {\n group = { rows: [], names: new Set() };\n groups.set(root, group);\n }\n group.rows.push(row);\n group.names.add(row.target);\n for (const name of row.sources.keys()) group.names.add(name);\n }\n const components: MonomialComponent[] = [...groups.values()].map((group, index) => ({\n index,\n rows: group.rows,\n names: [...group.names],\n }));\n const componentOf = new Map<string, number>();\n for (const component of components) for (const name of component.names) componentOf.set(name, component.index);\n const index: RankIndex = { rows, components, componentOf, solves: new Map() };\n perEdges.set(readerKey, index);\n return index;\n}\n\n/**\n * Solve one component with the asserted names inside it as unit rows.\n * Memoised per asserted set; a solve whose asserted set extends a cached\n * one by names that solve already determined is that solve with one more\n * dependent row per extra name (an already-determined quantity asserted\n * again is a consistency check, and determines nothing new).\n */\nfunction solveComponent(index: RankIndex, component: MonomialComponent, asserted: ReadonlySet<string>): ComponentSolve {\n const inside = component.names.filter((name) => asserted.has(name)).sort();\n let cached = index.solves.get(component.index);\n if (cached === undefined) {\n cached = [];\n index.solves.set(component.index, cached);\n }\n const insideSet = new Set(inside);\n for (const solve of cached) {\n if (solve.inside.length === inside.length && solve.inside.every((name) => insideSet.has(name))) return solve;\n }\n for (const solve of cached) {\n if (!solve.inside.every((name) => insideSet.has(name))) continue;\n const extra = inside.filter((name) => !solve.inside.includes(name));\n if (extra.every((name) => solve.determined.has(name))) {\n const widened: ComponentSolve = { inside, determined: solve.determined, surplus: solve.surplus + extra.length };\n cached.push(widened);\n return widened;\n }\n }\n\n const column = new Map(component.names.map((name, i) => [name, i] as const));\n const matrix: Fraction[][] = [];\n const seen = new Set<string>();\n const pushRow = (row: Fraction[]): void => {\n const k = rowKey(row);\n if (k === '0' || seen.has(k)) return;\n seen.add(k);\n matrix.push(row);\n };\n for (const row of component.rows) {\n const vector = component.names.map(() => ZERO);\n vector[column.get(row.target)!] = ONE;\n for (const [name, exp] of row.sources) {\n const i = column.get(name)!;\n vector[i] = vector[i]!.sub(exp);\n }\n pushRow(vector);\n }\n for (const name of inside) {\n const vector = component.names.map(() => ZERO);\n vector[column.get(name)!] = ONE;\n pushRow(vector);\n }\n const solved = rationalNullspace(matrix, { columns: component.names.length });\n const determined = new Set<string>(inside);\n component.names.forEach((name, i) => {\n if (solved.basis.every((vector) => vector[i]!.isZero())) determined.add(name);\n });\n const result: ComponentSolve = { inside, determined, surplus: matrix.length - solved.rank };\n cached.push(result);\n return result;\n}\n\ninterface RankSolution {\n readonly determined: Set<string>;\n readonly surplus: number;\n}\n\n/**\n * The asserted set is the known names plus every name a directed\n * identification reaches from a known or a determined one; only these get a\n * unit row, and a name the rank determines is never fed back in as a row\n * (that would count it as a check). Each pass solves the components the\n * asserted set touches (every component when `every`, so the surplus counts\n * the whole system), lets the identifications assert what the determined\n * names reach, and repeats until nothing new is asserted.\n */\nfunction solveRank(\n index: RankIndex,\n knownNames: readonly string[],\n identifications: readonly QuantityIdentification[],\n every: boolean,\n): RankSolution {\n const asserted = new Set<string>(knownNames);\n expandByIdentifications(asserted, identifications);\n const determined = new Set<string>();\n let surplus = 0;\n for (;;) {\n determined.clear();\n for (const name of asserted) determined.add(name);\n surplus = 0;\n for (const component of index.components) {\n if (!every && !component.names.some((name) => asserted.has(name))) continue;\n const solve = solveComponent(index, component, asserted);\n for (const name of solve.determined) determined.add(name);\n surplus += solve.surplus;\n }\n const before = asserted.size;\n const reach = new Set(determined);\n expandByIdentifications(reach, identifications);\n for (const name of reach) if (!determined.has(name)) asserted.add(name);\n if (asserted.size === before) break;\n }\n return { determined, surplus };\n}\n\n/** The cache of full rank reports per edge array, keyed by the known set and the identifications. */\nconst rankCache = new WeakMap<readonly BridgeEdge[], Map<string, RankIdentifiability>>();\n\nfunction rankCacheKey(known: readonly string[], identifications: readonly QuantityIdentification[], custom: boolean): string {\n return `${[...known].sort().join('\\u0001')}|${identifications.map((i) => `${i.from}>${i.to}`).join('\\u0001')}|${custom ? 'custom' : 'default'}`;\n}\n\n/**\n * {@link identifiabilityByRank} with the monomial reader chosen by the\n * caller (the default is {@link edgeMonomial}). A custom reader's index and\n * results are cached beside the default's, never in its place.\n *\n * @internal\n */\nexport function identifiabilityByRankWith(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n reader: EdgeMonomialReader,\n opts: IdentifiabilityOptions = {},\n): RankIdentifiability {\n return rankWithReader(edges, knownNames, reader, reader !== edgeMonomial, opts);\n}\n\n/**\n * The log-space rank: which quantities the monomial edges determine from\n * `knownNames`, whichever direction each law is read, how many independent\n * consistency checks the system carries, and which laws were read in\n * reverse. Identifications stay directed, as in {@link forwardClosure}: a\n * name they reach joins the known rows, and the system is solved again\n * until nothing new is determined. Non-monomial edges contribute nothing\n * here; the forward closure is their instrument.\n *\n * @public\n */\nexport function identifiabilityByRank(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n opts: IdentifiabilityOptions = {},\n): RankIdentifiability {\n return rankWithReader(edges, knownNames, edgeMonomial, false, opts);\n}\n\nfunction rankWithReader(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n reader: EdgeMonomialReader,\n custom: boolean,\n opts: IdentifiabilityOptions,\n): RankIdentifiability {\n const identifications = opts.identifications ?? QUANTITY_IDENTIFICATIONS;\n const key = rankCacheKey(knownNames, identifications, custom);\n let perEdges = rankCache.get(edges);\n if (perEdges === undefined) {\n perEdges = new Map();\n rankCache.set(edges, perEdges);\n }\n const hit = perEdges.get(key);\n if (hit !== undefined) return hit;\n\n const index = rankIndex(edges, reader, custom ? 'custom' : 'default');\n const { determined, surplus } = solveRank(index, knownNames, identifications, true);\n\n // A law is read in reverse when one of its sources is determined, and not\n // by the forward closure over the monomial edges alone.\n const monomialIds = new Set(index.rows.map((r) => r.id));\n const forward = forwardClosure(\n edges.filter((e) => monomialIds.has(e.id)),\n knownNames,\n identifications,\n );\n const usedInReverse = index.rows\n .filter((row) => [...row.sources.keys()].some((name) => !forward.has(name) && determined.has(name)))\n .map((row) => row.id);\n\n const result: RankIdentifiability = {\n determined: [...determined].sort(),\n determinedByRankOnly: [...determined].filter((name) => !forward.has(name)).sort(),\n surplusChecks: surplus,\n usedInReverse,\n monomialEdges: index.rows.map((r) => r.id),\n };\n perEdges.set(key, result);\n return result;\n}\n\n/**\n * Whether the rank determines `target` from `knownNames`. Only the\n * components the asserted set touches are solved, and each solve is\n * memoised, so the funnel's thousands of calls per anchor cost one solve\n * per touched component, plus one per hypothesis that actually asserts a\n * new name.\n */\nfunction rankDetermines(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n target: string,\n identifications: readonly QuantityIdentification[],\n): boolean {\n const index = rankIndex(edges, edgeMonomial, 'default');\n if (!index.componentOf.has(target)) return false;\n return solveRank(index, knownNames, identifications, false).determined.has(target);\n}\n\n/** The quantities from which `targetName` is forward-reachable (its\n * backward cone, target included). */\nfunction backwardCone(\n edges: readonly BridgeEdge[],\n targetName: string,\n): Set<string> {\n const cone = new Set<string>([targetName]);\n let changed = true;\n while (changed) {\n changed = false;\n for (const e of edges) {\n if (!cone.has(e.target.name)) continue;\n for (const s of e.sources) {\n if (!cone.has(s.name)) {\n cone.add(s.name);\n changed = true;\n }\n }\n }\n }\n return cone;\n}\n\n/**\n * Classify the structural identifiability of `targetName` given\n * `knownNames` over `edges`. See the module docs and\n * docs/planning/Identifiability-Classifier-Design-Note.md.\n *\n * @public\n */\nexport function classifyIdentifiability(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n targetName: string,\n opts: IdentifiabilityOptions = {},\n): IdentifiabilityResult {\n const identifications = opts.identifications ?? QUANTITY_IDENTIFICATIONS;\n const known = [...new Set(knownNames)];\n\n const closure = forwardClosure(edges, known, identifications);\n // The rank is computed once per result and only when something reads it:\n // the verdict needs it only for a target the closure does not reach, and\n // the funnel classifies thousands of targets whose verdict it does reach.\n let rankMemo: RankIdentifiability | undefined;\n const rankOf = (): RankIdentifiability => {\n rankMemo ??= identifiabilityByRank(edges, known, { identifications });\n return rankMemo;\n };\n // The union: the closure (every edge, forward) and the rank (the monomial\n // edges, either way). `determinedByRankOnly` is reported against the whole\n // closure here, so a name the closure reaches through an opaque edge is\n // not counted as rank-only.\n const determinableOf = (): Set<string> => new Set<string>([...closure, ...rankOf().determined]);\n const rankReport = (): RankIdentifiability => {\n const rank = rankOf();\n return { ...rank, determinedByRankOnly: rank.determined.filter((name) => !closure.has(name)) };\n };\n\n // Derivations must not depend on the target itself: close over the\n // graph with every edge INTO the target removed (excludes circular\n // self-support — see the design note's worked counterexample).\n const edgesMinusIntoTarget = edges.filter(\n (e) => e.target.name !== targetName,\n );\n const dMinusT = forwardClosure(edgesMinusIntoTarget, known, identifications);\n\n const derivations = edges\n .filter(\n (e) =>\n e.target.name === targetName &&\n e.sources.every((s) => dMinusT.has(s.name)),\n )\n .map((e) => e.id);\n\n const isGiven = known.includes(targetName);\n let verdict: IdentifiabilityVerdict;\n if (isGiven) {\n verdict = 'given';\n } else if (!closure.has(targetName) && !rankDetermines(edges, known, targetName, identifications)) {\n verdict = 'under-determined';\n } else if (derivations.length >= 2) {\n verdict = 'over-determined';\n } else {\n // One forward derivation, or determined by identity, or determined by\n // the rank alone (then `derivations` is empty and `rank.usedInReverse`\n // names the laws that were read backwards).\n verdict = 'exactly-determined';\n }\n\n const surplusConstraints = isGiven\n ? derivations.length\n : Math.max(0, derivations.length - 1);\n\n let blockingFrontier: string[] = [];\n if (verdict === 'under-determined') {\n const knownSet = new Set(known);\n const determinable = determinableOf();\n blockingFrontier = [...backwardCone(edges, targetName)]\n .filter(\n (q) => q !== targetName && !determinable.has(q) && !knownSet.has(q),\n )\n .sort();\n }\n\n return {\n target: targetName,\n known,\n verdict,\n derivations,\n surplusConstraints,\n blockingFrontier,\n get determinable(): readonly string[] {\n return [...determinableOf()].sort();\n },\n get rank(): RankIdentifiability {\n return rankReport();\n },\n };\n}\n\n/**\n * Classify every quantity that is some edge's target, against one known\n * set. The natural feeder for a retrodiction harness (mask a node, ask\n * whether the graph recovers it). Sorted by target name.\n *\n * @public\n */\nexport function classifyAll(\n edges: readonly BridgeEdge[],\n knownNames: readonly string[],\n opts: IdentifiabilityOptions = {},\n): IdentifiabilityResult[] {\n const targets = [...new Set(edges.map((e) => e.target.name))].sort();\n return targets.map((t) =>\n classifyIdentifiability(edges, knownNames, t, opts),\n );\n}\n"]}
@@ -14,9 +14,11 @@ export type { Quantity, RegimeAttributes } from './quantity.js';
14
14
  export { regimesDiffer } from './quantity.js';
15
15
  export type { BridgeEdge, EdgeConfidence, ValidityDomain } from './edge.js';
16
16
  /** Edge evaluation and the errors it throws. An unset coefficient is `CoefficientUnsetError`. */
17
- export { CoefficientUnsetError, CompositionAliasError, CompositionDimensionError, CompositionJunctionError, UndefinedCompositionError, evaluateEdge, } from './edge.js';
17
+ export { CoefficientUnsetError, CompositionAliasError, CompositionDimensionError, CompositionJunctionError, UndefinedCompositionError, evaluateEdge, validityDomain, } from './edge.js';
18
18
  /** The errors one evaluation throws: the input checks, then the validity domain. */
19
19
  export { DomainViolationError, DuplicateInputError, InputTypeError, MissingInputError, NonFiniteInputError, UnknownInputError, } from '../bridges/evaluation-errors.js';
20
+ /** A failed validity condition and the inputs it read, as `DomainViolationError.violations` lists them. */
21
+ export type { DomainInput, DomainViolation } from '../bridges/evaluation-errors.js';
20
22
  export type { ComposeOptions, QuantityIdentification } from './compose.js';
21
23
  export { composeEdges, minConfidence, QUANTITY_IDENTIFICATIONS, SOURCE_ALIAS_DISPOSITIONS, } from './compose.js';
22
24
  export type { AliasDisposition } from './compose.js';
@@ -29,15 +31,17 @@ export type { CompositionCandidate, EnumerationReport, } from './enumerate.js';
29
31
  export { enumerateCompositions, REGISTERED_COMPOSITION_IDS, } from './enumerate.js';
30
32
  export type { UncertaintyResult } from './uncertainty.js';
31
33
  export { propagateUncertainty } from './uncertainty.js';
32
- export type { IdentifiabilityVerdict, IdentifiabilityResult, IdentifiabilityOptions, } from './identifiability.js';
33
- export { classifyIdentifiability, classifyAll, forwardClosure, } from './identifiability.js';
34
+ /** The classifier's verdict, result and option types, and the rank instrument's report. */
35
+ export type { IdentifiabilityVerdict, IdentifiabilityResult, IdentifiabilityOptions, RankIdentifiability, } from './identifiability.js';
36
+ /** The forward closure, the per-target classifier, the sweep, and the log-space rank over the monomial edges. */
37
+ export { classifyIdentifiability, classifyAll, forwardClosure, identifiabilityByRank, } from './identifiability.js';
34
38
  /** The retrodiction harness's result, prediction, refusal, report and option types. */
35
39
  export type { RetrodictionOutcome, RetrodictionPrediction, RetrodictionResult, RetrodictionRefusal, RetrodictionReport, RetrodictionOptions, } from './retrodiction.js';
36
40
  export { retrodict, retrodictNode } from './retrodiction.js';
37
41
  export type { DerivationExplanation, ExplainOptions, QuantityExplanation, } from './explain.js';
38
42
  export { explainQuantity } from './explain.js';
39
43
  /** The result of {@link evaluateRelation}. A value carries a dimension. An unset coefficient carries the formula. */
40
- export type { Evaluation } from './evaluate-relation.js';
44
+ export type { Evaluation, ExtraOutput } from './evaluate-relation.js';
41
45
  /** Evaluate a catalog id or a canonical id. A sourced number is `kind: 'value'`. An unset coefficient is `kind: 'unset'`. */
42
46
  export { evaluateRelation } from './evaluate-relation.js';
43
47
  export type { Observable, ComposeSymbolicOptions } from './compose-symbolic.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composition/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composition/index.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@
12
12
  */
13
13
  export { regimesDiffer } from './quantity.js';
14
14
  /** Edge evaluation and the errors it throws. An unset coefficient is `CoefficientUnsetError`. */
15
- export { CoefficientUnsetError, CompositionAliasError, CompositionDimensionError, CompositionJunctionError, UndefinedCompositionError, evaluateEdge, } from './edge.js';
15
+ export { CoefficientUnsetError, CompositionAliasError, CompositionDimensionError, CompositionJunctionError, UndefinedCompositionError, evaluateEdge, validityDomain, } from './edge.js';
16
16
  /** The errors one evaluation throws: the input checks, then the validity domain. */
17
17
  export { DomainViolationError, DuplicateInputError, InputTypeError, MissingInputError, NonFiniteInputError, UnknownInputError, } from '../bridges/evaluation-errors.js';
18
18
  export { composeEdges, minConfidence, QUANTITY_IDENTIFICATIONS, SOURCE_ALIAS_DISPOSITIONS, } from './compose.js';
@@ -23,7 +23,8 @@ export { catalogEdge, CATALOG_GRAPH } from './catalog-graph.js';
23
23
  export { CANONICAL_GRAPH, canonicalToEdges, CANONICAL_CONSTANTS, } from './canonical-graph.js';
24
24
  export { enumerateCompositions, REGISTERED_COMPOSITION_IDS, } from './enumerate.js';
25
25
  export { propagateUncertainty } from './uncertainty.js';
26
- export { classifyIdentifiability, classifyAll, forwardClosure, } from './identifiability.js';
26
+ /** The forward closure, the per-target classifier, the sweep, and the log-space rank over the monomial edges. */
27
+ export { classifyIdentifiability, classifyAll, forwardClosure, identifiabilityByRank, } from './identifiability.js';
27
28
  export { retrodict, retrodictNode } from './retrodiction.js';
28
29
  export { explainQuantity } from './explain.js';
29
30
  /** Evaluate a catalog id or a canonical id. A sourced number is `kind: 'value'`. An unset coefficient is `kind: 'unset'`. */