universal-physics-tensor 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/README.md +36 -34
  2. package/data/applied-cases.json +1892 -0
  3. package/data/applied-cases.schema.json +194 -0
  4. package/data/atlas/atlas.json +21 -21
  5. package/data/atlas/atlas.jsonld +1 -1
  6. package/data/atlas/diffusion.json +5 -5
  7. package/data/atlas/oscillators.json +7 -7
  8. package/data/atlas/waves.json +11 -11
  9. package/data/bridge-catalog.json +20 -4
  10. package/data/units.json +6 -25
  11. package/dist/atlas/benchmark/stats.d.ts.map +1 -1
  12. package/dist/atlas/benchmark/stats.js +6 -20
  13. package/dist/atlas/benchmark/stats.js.map +1 -1
  14. package/dist/atlas/physjs-entries.generated.d.ts +13 -4
  15. package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
  16. package/dist/atlas/physjs-entries.generated.js +15 -4
  17. package/dist/atlas/physjs-entries.generated.js.map +1 -1
  18. package/dist/atlas/physjs-reviewed.js +2 -2
  19. package/dist/atlas/physjs-reviewed.js.map +1 -1
  20. package/dist/cases/catalog-checks.d.ts +10 -0
  21. package/dist/cases/catalog-checks.d.ts.map +1 -0
  22. package/dist/cases/catalog-checks.js +241 -0
  23. package/dist/cases/catalog-checks.js.map +1 -0
  24. package/dist/cases/catalog.d.ts +83 -0
  25. package/dist/cases/catalog.d.ts.map +1 -0
  26. package/dist/cases/catalog.js +118 -0
  27. package/dist/cases/catalog.js.map +1 -0
  28. package/dist/cases/engine.d.ts +13 -0
  29. package/dist/cases/engine.d.ts.map +1 -0
  30. package/dist/cases/engine.js +179 -0
  31. package/dist/cases/engine.js.map +1 -0
  32. package/dist/cases/index.d.ts.map +1 -1
  33. package/dist/cases/index.js +5 -7
  34. package/dist/cases/index.js.map +1 -1
  35. package/dist/cases/methods.d.ts +215 -0
  36. package/dist/cases/methods.d.ts.map +1 -0
  37. package/dist/cases/methods.js +743 -0
  38. package/dist/cases/methods.js.map +1 -0
  39. package/dist/cases/types.d.ts +12 -0
  40. package/dist/cases/types.d.ts.map +1 -1
  41. package/dist/cases/types.js.map +1 -1
  42. package/dist/cli/args.d.ts +2 -0
  43. package/dist/cli/args.d.ts.map +1 -1
  44. package/dist/cli/args.js.map +1 -1
  45. package/dist/cli/command.d.ts +3 -0
  46. package/dist/cli/command.d.ts.map +1 -1
  47. package/dist/cli/command.js.map +1 -1
  48. package/dist/cli/commands/_discovery-opts.d.ts +1 -0
  49. package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
  50. package/dist/cli/commands/_discovery-opts.js +1 -0
  51. package/dist/cli/commands/_discovery-opts.js.map +1 -1
  52. package/dist/cli/commands/discover.d.ts.map +1 -1
  53. package/dist/cli/commands/discover.js +116 -71
  54. package/dist/cli/commands/discover.js.map +1 -1
  55. package/dist/cli/commands/evaluate.js +2 -2
  56. package/dist/cli/commands/evaluate.js.map +1 -1
  57. package/dist/cli/commands/explain.d.ts.map +1 -1
  58. package/dist/cli/commands/explain.js +22 -2
  59. package/dist/cli/commands/explain.js.map +1 -1
  60. package/dist/cli/commands/ground.d.ts.map +1 -1
  61. package/dist/cli/commands/ground.js +6 -1
  62. package/dist/cli/commands/ground.js.map +1 -1
  63. package/dist/cli/commands/map.d.ts.map +1 -1
  64. package/dist/cli/commands/map.js +9 -6
  65. package/dist/cli/commands/map.js.map +1 -1
  66. package/dist/cli/determination.d.ts +1 -0
  67. package/dist/cli/determination.d.ts.map +1 -1
  68. package/dist/cli/determination.js.map +1 -1
  69. package/dist/cli/flag-help.d.ts +1 -0
  70. package/dist/cli/flag-help.d.ts.map +1 -1
  71. package/dist/cli/flag-help.js +1 -0
  72. package/dist/cli/flag-help.js.map +1 -1
  73. package/dist/cli/graphs.d.ts +2 -0
  74. package/dist/cli/graphs.d.ts.map +1 -1
  75. package/dist/cli/graphs.js +1 -0
  76. package/dist/cli/graphs.js.map +1 -1
  77. package/dist/cli/main.d.ts +1 -0
  78. package/dist/cli/main.d.ts.map +1 -1
  79. package/dist/cli/main.js +1 -0
  80. package/dist/cli/main.js.map +1 -1
  81. package/dist/cli/output.d.ts +8 -0
  82. package/dist/cli/output.d.ts.map +1 -1
  83. package/dist/cli/output.js +8 -0
  84. package/dist/cli/output.js.map +1 -1
  85. package/dist/cli/statuses.d.ts.map +1 -1
  86. package/dist/cli/statuses.js +12 -2
  87. package/dist/cli/statuses.js.map +1 -1
  88. package/dist/cli/version.d.ts +1 -0
  89. package/dist/cli/version.d.ts.map +1 -1
  90. package/dist/cli/version.js +1 -0
  91. package/dist/cli/version.js.map +1 -1
  92. package/dist/cli-api.d.ts +2 -0
  93. package/dist/cli-api.d.ts.map +1 -1
  94. package/dist/cli-api.js +2 -0
  95. package/dist/cli-api.js.map +1 -1
  96. package/dist/composition/canonical-graph.d.ts +2 -2
  97. package/dist/composition/canonical-graph.js +2 -2
  98. package/dist/composition/canonical-graph.js.map +1 -1
  99. package/dist/composition/consequence.d.ts +15 -5
  100. package/dist/composition/consequence.d.ts.map +1 -1
  101. package/dist/composition/consequence.js +6 -4
  102. package/dist/composition/consequence.js.map +1 -1
  103. package/dist/composition/discovery.d.ts +78 -14
  104. package/dist/composition/discovery.d.ts.map +1 -1
  105. package/dist/composition/discovery.js +73 -23
  106. package/dist/composition/discovery.js.map +1 -1
  107. package/dist/composition/expr-eval.d.ts +1 -1
  108. package/dist/composition/expr-eval.d.ts.map +1 -1
  109. package/dist/composition/expr-eval.js +4 -4
  110. package/dist/composition/expr-eval.js.map +1 -1
  111. package/dist/composition/expr-simplify.d.ts +10 -14
  112. package/dist/composition/expr-simplify.d.ts.map +1 -1
  113. package/dist/composition/expr-simplify.js +49 -52
  114. package/dist/composition/expr-simplify.js.map +1 -1
  115. package/dist/composition/grounding.d.ts.map +1 -1
  116. package/dist/composition/grounding.js +19 -7
  117. package/dist/composition/grounding.js.map +1 -1
  118. package/dist/composition/mathts-quiet.d.ts +4 -6
  119. package/dist/composition/mathts-quiet.d.ts.map +1 -1
  120. package/dist/composition/mathts-quiet.js +4 -14
  121. package/dist/composition/mathts-quiet.js.map +1 -1
  122. package/dist/composition/own-equation-magnitude.d.ts +95 -0
  123. package/dist/composition/own-equation-magnitude.d.ts.map +1 -0
  124. package/dist/composition/own-equation-magnitude.js +270 -0
  125. package/dist/composition/own-equation-magnitude.js.map +1 -0
  126. package/dist/composition/probe/backend-protocol.d.ts +3 -0
  127. package/dist/composition/probe/backend-protocol.d.ts.map +1 -1
  128. package/dist/composition/probe/backend-protocol.js.map +1 -1
  129. package/dist/composition/probe/candidate-store.d.ts +1 -0
  130. package/dist/composition/probe/candidate-store.d.ts.map +1 -1
  131. package/dist/composition/probe/candidate-store.js +1 -0
  132. package/dist/composition/probe/candidate-store.js.map +1 -1
  133. package/dist/composition/probe/corpus.d.ts +4 -2
  134. package/dist/composition/probe/corpus.d.ts.map +1 -1
  135. package/dist/composition/probe/corpus.js +3 -3
  136. package/dist/composition/probe/corpus.js.map +1 -1
  137. package/dist/composition/probe/dataset.d.ts +1 -0
  138. package/dist/composition/probe/dataset.d.ts.map +1 -1
  139. package/dist/composition/probe/dataset.js.map +1 -1
  140. package/dist/composition/probe/experiment-design.d.ts +2 -0
  141. package/dist/composition/probe/experiment-design.d.ts.map +1 -1
  142. package/dist/composition/probe/experiment-design.js.map +1 -1
  143. package/dist/composition/probe/falsify.d.ts +2 -0
  144. package/dist/composition/probe/falsify.d.ts.map +1 -1
  145. package/dist/composition/probe/falsify.js.map +1 -1
  146. package/dist/composition/probe/fit.d.ts +1 -0
  147. package/dist/composition/probe/fit.d.ts.map +1 -1
  148. package/dist/composition/probe/fit.js.map +1 -1
  149. package/dist/composition/probe/generator.d.ts +3 -0
  150. package/dist/composition/probe/generator.d.ts.map +1 -1
  151. package/dist/composition/probe/generator.js +5 -6
  152. package/dist/composition/probe/generator.js.map +1 -1
  153. package/dist/composition/probe/limits.d.ts +1 -0
  154. package/dist/composition/probe/limits.d.ts.map +1 -1
  155. package/dist/composition/probe/limits.js.map +1 -1
  156. package/dist/composition/probe/pipeline.d.ts +5 -0
  157. package/dist/composition/probe/pipeline.d.ts.map +1 -1
  158. package/dist/composition/probe/pipeline.js +64 -21
  159. package/dist/composition/probe/pipeline.js.map +1 -1
  160. package/dist/composition/probe/power-law.d.ts.map +1 -1
  161. package/dist/composition/probe/power-law.js +3 -7
  162. package/dist/composition/probe/power-law.js.map +1 -1
  163. package/dist/composition/probe/problem.d.ts +1 -0
  164. package/dist/composition/probe/problem.d.ts.map +1 -1
  165. package/dist/composition/probe/problem.js.map +1 -1
  166. package/dist/composition/probe/residual.d.ts +1 -0
  167. package/dist/composition/probe/residual.d.ts.map +1 -1
  168. package/dist/composition/probe/residual.js +1 -0
  169. package/dist/composition/probe/residual.js.map +1 -1
  170. package/dist/composition/probe/run-manifest.d.ts +1 -0
  171. package/dist/composition/probe/run-manifest.d.ts.map +1 -1
  172. package/dist/composition/probe/run-manifest.js.map +1 -1
  173. package/dist/composition/probe/scalar-search.d.ts +50 -0
  174. package/dist/composition/probe/scalar-search.d.ts.map +1 -0
  175. package/dist/composition/probe/scalar-search.js +169 -0
  176. package/dist/composition/probe/scalar-search.js.map +1 -0
  177. package/dist/composition/probe/scoring.d.ts +1 -0
  178. package/dist/composition/probe/scoring.d.ts.map +1 -1
  179. package/dist/composition/probe/scoring.js.map +1 -1
  180. package/dist/composition/probe/study.d.ts +2 -2
  181. package/dist/composition/probe/study.d.ts.map +1 -1
  182. package/dist/composition/probe/study.js +6 -10
  183. package/dist/composition/probe/study.js.map +1 -1
  184. package/dist/composition/probe/t-tail.d.ts +3 -4
  185. package/dist/composition/probe/t-tail.d.ts.map +1 -1
  186. package/dist/composition/probe/t-tail.js +7 -10
  187. package/dist/composition/probe/t-tail.js.map +1 -1
  188. package/dist/composition/proposed-bridges.d.ts +11 -2
  189. package/dist/composition/proposed-bridges.d.ts.map +1 -1
  190. package/dist/composition/proposed-bridges.js +7 -5
  191. package/dist/composition/proposed-bridges.js.map +1 -1
  192. package/dist/composition/rational-exponent.d.ts +2 -2
  193. package/dist/composition/rational-exponent.d.ts.map +1 -1
  194. package/dist/composition/rational-exponent.js +4 -4
  195. package/dist/composition/rational-exponent.js.map +1 -1
  196. package/dist/composition/representative-values.d.ts.map +1 -1
  197. package/dist/composition/representative-values.js +6 -0
  198. package/dist/composition/representative-values.js.map +1 -1
  199. package/dist/composition/retrodiction.d.ts +15 -0
  200. package/dist/composition/retrodiction.d.ts.map +1 -1
  201. package/dist/composition/retrodiction.js +10 -3
  202. package/dist/composition/retrodiction.js.map +1 -1
  203. package/dist/composition/user-equation.d.ts +1 -0
  204. package/dist/composition/user-equation.d.ts.map +1 -1
  205. package/dist/composition/user-equation.js +1 -0
  206. package/dist/composition/user-equation.js.map +1 -1
  207. package/dist/core/constants.d.ts +12 -11
  208. package/dist/core/constants.d.ts.map +1 -1
  209. package/dist/core/constants.js +24 -21
  210. package/dist/core/constants.js.map +1 -1
  211. package/dist/diff/bridge-ast-gradient.d.ts +27 -23
  212. package/dist/diff/bridge-ast-gradient.d.ts.map +1 -1
  213. package/dist/diff/bridge-ast-gradient.js +75 -173
  214. package/dist/diff/bridge-ast-gradient.js.map +1 -1
  215. package/dist/dimensional/ast-types.d.ts +15 -0
  216. package/dist/dimensional/ast-types.d.ts.map +1 -1
  217. package/dist/dimensional/ast-types.js.map +1 -1
  218. package/dist/dimensional/curvature-composite.d.ts +1 -1
  219. package/dist/dimensional/curvature-composite.js.map +1 -1
  220. package/dist/dimensional/exact-scale.d.ts +41 -11
  221. package/dist/dimensional/exact-scale.d.ts.map +1 -1
  222. package/dist/dimensional/exact-scale.js +115 -123
  223. package/dist/dimensional/exact-scale.js.map +1 -1
  224. package/dist/dimensional/mathts-unit-delegation.d.ts +29 -0
  225. package/dist/dimensional/mathts-unit-delegation.d.ts.map +1 -0
  226. package/dist/dimensional/mathts-unit-delegation.js +187 -0
  227. package/dist/dimensional/mathts-unit-delegation.js.map +1 -0
  228. package/dist/dimensional/mathts-unit-wrapper.d.ts +33 -0
  229. package/dist/dimensional/mathts-unit-wrapper.d.ts.map +1 -0
  230. package/dist/dimensional/mathts-unit-wrapper.js +190 -0
  231. package/dist/dimensional/mathts-unit-wrapper.js.map +1 -0
  232. package/dist/dimensional/scalar-lowering.d.ts +21 -0
  233. package/dist/dimensional/scalar-lowering.d.ts.map +1 -0
  234. package/dist/dimensional/scalar-lowering.js +45 -0
  235. package/dist/dimensional/scalar-lowering.js.map +1 -0
  236. package/dist/dimensional/unit-data.d.ts +5 -1
  237. package/dist/dimensional/unit-data.d.ts.map +1 -1
  238. package/dist/dimensional/unit-data.js +28 -4
  239. package/dist/dimensional/unit-data.js.map +1 -1
  240. package/dist/dimensional/units.d.ts +2 -0
  241. package/dist/dimensional/units.d.ts.map +1 -1
  242. package/dist/dimensional/units.js +59 -3
  243. package/dist/dimensional/units.js.map +1 -1
  244. package/dist/dimensional/validator.d.ts +2 -0
  245. package/dist/dimensional/validator.d.ts.map +1 -1
  246. package/dist/dimensional/validator.js.map +1 -1
  247. package/dist/index.js.map +1 -1
  248. package/dist/numerical/connection-lowering-helpers.d.ts +3 -1
  249. package/dist/numerical/connection-lowering-helpers.d.ts.map +1 -1
  250. package/dist/numerical/connection-lowering-helpers.js +11 -15
  251. package/dist/numerical/connection-lowering-helpers.js.map +1 -1
  252. package/dist/numerical/pderiv.d.ts.map +1 -1
  253. package/dist/numerical/pderiv.js +2 -6
  254. package/dist/numerical/pderiv.js.map +1 -1
  255. package/dist/numerical/quadrature.js +3 -3
  256. package/dist/numerical/quadrature.js.map +1 -1
  257. package/dist/numerical/statistics.js +1 -1
  258. package/dist/numerical/statistics.js.map +1 -1
  259. package/dist/numerical/strides.d.ts +3 -2
  260. package/dist/numerical/strides.d.ts.map +1 -1
  261. package/dist/numerical/strides.js +3 -10
  262. package/dist/numerical/strides.js.map +1 -1
  263. package/package.json +9 -12
  264. package/dist/cases/brownian-sphere.d.ts +0 -68
  265. package/dist/cases/brownian-sphere.d.ts.map +0 -1
  266. package/dist/cases/brownian-sphere.js +0 -355
  267. package/dist/cases/brownian-sphere.js.map +0 -1
  268. package/dist/cases/damped-resonator.d.ts +0 -23
  269. package/dist/cases/damped-resonator.d.ts.map +0 -1
  270. package/dist/cases/damped-resonator.js +0 -221
  271. package/dist/cases/damped-resonator.js.map +0 -1
  272. package/dist/cases/kepler-rv.d.ts +0 -13
  273. package/dist/cases/kepler-rv.d.ts.map +0 -1
  274. package/dist/cases/kepler-rv.js +0 -173
  275. package/dist/cases/kepler-rv.js.map +0 -1
  276. package/dist/cases/lumped-cooling.d.ts +0 -51
  277. package/dist/cases/lumped-cooling.d.ts.map +0 -1
  278. package/dist/cases/lumped-cooling.js +0 -259
  279. package/dist/cases/lumped-cooling.js.map +0 -1
  280. package/dist/cases/resistor-noise.d.ts +0 -14
  281. package/dist/cases/resistor-noise.d.ts.map +0 -1
  282. package/dist/cases/resistor-noise.js +0 -215
  283. package/dist/cases/resistor-noise.js.map +0 -1
  284. package/dist/cases/skin-depth.d.ts +0 -17
  285. package/dist/cases/skin-depth.d.ts.map +0 -1
  286. package/dist/cases/skin-depth.js +0 -170
  287. package/dist/cases/skin-depth.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ast-types.d.ts","sourceRoot":"","sources":["../../src/dimensional/ast-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast-types.d.ts","sourceRoot":"","sources":["../../src/dimensional/ast-types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ast-types.js","sourceRoot":"","sources":["../../src/dimensional/ast-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG","sourcesContent":["/**\n * The dimensional AST type system — `ExprNode` and every node/index interface\n * it unions, in ONE leaf module.\n *\n * Previously `ExprNode` lived in `validator.ts` and pulled its member node types\n * from ~9 sibling modules (`tensor`, `metric-validators`, `connection-\n * validators`, `curvature`, …). Two of those (`tensor`, `curvature`) imported\n * `ExprNode` back, forming type-only cycles, and several node interfaces used\n * `of: unknown` casts to dodge importing `ExprNode`. Consolidating the *types*\n * here (this module imports only `types.ts` + the leaf `curvature-composite.ts`,\n * so it has no back-edges) breaks both cycles and lets the derivative nodes type\n * `of`/`wrt` as real `ExprNode`.\n *\n * Each origin module now re-exports its types from here (so existing importers\n * are unchanged) and keeps only its validation FUNCTIONS.\n *\n * @module dimensional/ast-types\n */\n\nimport type { Dimension } from './types.js';\nimport type { CurvatureCompositeNode } from './curvature-composite.js';\n\n// ── index types ─────────────────────────────────────────────────────────────\n\nexport type Variance = 'upper' | 'lower';\nexport type Role = 'coordinate' | 'field' | 'constant';\n\nexport interface TensorIndex {\n readonly label: string;\n readonly variance: Variance;\n}\n\n/** A strictly-lower tensor index. */\nexport interface CovariantIndex {\n readonly label: string;\n readonly variance: 'lower';\n}\n\n/** A strictly-upper tensor index. */\nexport interface UpperIndex {\n readonly label: string;\n readonly variance: 'upper';\n}\n\n// ── transcendental functions ────────────────────────────────────────────────\n\n/**\n * Elementwise transcendental functions usable in a `transcendental` node. All\n * take a DIMENSIONLESS argument and return a DIMENSIONLESS result. (`sqrt`/`cbrt`\n * are excluded — they produce fractional dimensions.)\n */\nexport type TranscendentalFn =\n | 'exp'\n | 'ln'\n | 'log2'\n | 'log10'\n | 'sin'\n | 'cos'\n | 'tan'\n | 'sinh'\n | 'cosh'\n | 'tanh';\n\n// ── tensor nodes ────────────────────────────────────────────────────────────\n\nexport interface TensorSymbolNode {\n readonly kind: 'tensor-symbol';\n readonly name: string;\n readonly indices: ReadonlyArray<TensorIndex>;\n readonly dim: Dimension;\n /** Semantic classification (default 'field'). Structural metadata only. */\n readonly role?: Role;\n /** v0.3.5 numerical pderiv strategy when this is a partial-derivative `of`\n * operand (default 'symbolic'). */\n readonly numericalForm?: 'symbolic' | 'numerical-fn' | 'grid';\n}\n\nexport interface TensorProductNode {\n readonly kind: 'tensor-product';\n readonly args: ReadonlyArray<ExprNode>;\n}\n\n// ── metric nodes ────────────────────────────────────────────────────────────\n\nexport interface MetricTensorNode {\n readonly kind: 'metric-tensor';\n readonly name: string;\n readonly indices: ReadonlyArray<TensorIndex>;\n readonly signature: string;\n readonly dim: Dimension;\n /** v0.4.0 numerical-lowering hint for ∂g (default 'computed'). */\n readonly derivativeStrategy?: 'computed' | 'zero' | 'supplied';\n}\n\nexport interface KroneckerDeltaNode {\n readonly kind: 'kronecker-delta';\n readonly indices: ReadonlyArray<TensorIndex>;\n readonly dim: Dimension;\n}\n\nexport interface TensorPartialDerivativeNode {\n readonly kind: 'tensor-partial-derivative';\n readonly of: ExprNode;\n readonly wrt: ExprNode;\n readonly wrtIndex: CovariantIndex;\n}\n\n// ── connection / curvature nodes ────────────────────────────────────────────\n\n/**\n * AST node for the covariant derivative ∇_μ of a tensor expression.\n *\n * @public\n */\nexport interface CovariantDerivativeNode {\n readonly kind: 'covariant-derivative';\n readonly of: ExprNode;\n readonly wrt: ExprNode;\n readonly wrtIndex: CovariantIndex;\n readonly gLower: MetricTensorNode;\n readonly gInverse: MetricTensorNode;\n}\n\nexport type RiemannTensorNode = CurvatureCompositeNode<'riemann-tensor', {\n readonly upperIndex: UpperIndex;\n readonly lowerIndices: readonly [CovariantIndex, CovariantIndex, CovariantIndex];\n readonly gLower: MetricTensorNode;\n readonly gInverse: MetricTensorNode;\n readonly xCoord: TensorSymbolNode;\n}>;\n\n/**\n * AST node for the Ricci tensor R_μν, built by `ricci`.\n *\n * @public\n */\nexport type RicciTensorNode = CurvatureCompositeNode<'ricci-tensor', {\n /** The Riemann tensor, contracted on its upper index and its second lower index: R_μν = R^λ_{μλν}. */\n readonly riemann: RiemannTensorNode;\n}>;\n\n/**\n * AST node for the Einstein tensor G_μν, built by `einstein`.\n *\n * @public\n */\nexport type EinsteinTensorNode = CurvatureCompositeNode<'einstein-tensor', {\n /** The Riemann tensor whose contraction yields the inner Ricci R_μν. */\n readonly riemann: RiemannTensorNode;\n /** Lower metric g_μν — supplies the `½ R g_μν` subtraction tensor. */\n readonly gLower: MetricTensorNode;\n /** Upper metric g^μν — supplies the scalar trace `R = g^μν R_μν`. */\n readonly gInverse: MetricTensorNode;\n}>;\n\n/**\n * AST node for the cyclic second-Bianchi-identity residual, built by `bianchiResidual`.\n *\n * @public\n */\nexport type BianchiResidualNode = CurvatureCompositeNode<'bianchi-residual', {\n /** The Riemann tensor whose cyclic-derivative identity is checked. */\n readonly riemann: RiemannTensorNode;\n}>;\n\nexport type WeylTensorNode = CurvatureCompositeNode<'weyl-tensor', {\n /** Metric g_{μν} (both-lower). Present for numerical lowering consumers. */\n readonly metric: MetricTensorNode;\n /** Contravariant (upper) index ρ. */\n readonly upperIndex: UpperIndex;\n /** Three covariant (lower) indices [σ, μ, ν]. */\n readonly lowerIndices: readonly [CovariantIndex, CovariantIndex, CovariantIndex];\n /** Dimensional signature of each component: [L⁻²], same as Riemann. */\n readonly componentDim: Dimension;\n}>;\n\n/**\n * AST node for the Kretschmann scalar K = R_{ρσμν} R^{ρσμν}.\n *\n * @public\n */\nexport type KretschmannScalarNode = CurvatureCompositeNode<'kretschmann-scalar', {\n /** Riemann tensor R^ρ_{σμν}. */\n readonly riemann: RiemannTensorNode;\n /** Metric (both-lower preferred). */\n readonly metric: MetricTensorNode;\n}>;\n\n// ── Killing / stress-energy / field-equation nodes ──────────────────────────\n\nexport interface KillingVectorNode {\n readonly kind: 'killing-vector';\n readonly vector: TensorSymbolNode;\n readonly metric: MetricTensorNode;\n}\n\nexport interface ConservedChargeNode {\n readonly kind: 'conserved-charge';\n /** The Killing vector ξ^μ (rank-1, upper variance). */\n readonly killing: KillingVectorNode;\n /** The covariant momentum p_μ (rank-1, lower variance), sharing the Killing\n * vector's index label so ξ^μ p_μ is well-formed. */\n readonly momentum: TensorSymbolNode;\n}\n\nexport interface StressEnergyTensorNode {\n readonly kind: 'stress-energy';\n readonly symbol: 'T';\n readonly indices: readonly [CovariantIndex, CovariantIndex];\n readonly symmetry: 'symmetric';\n readonly componentDim: Dimension;\n}\n\nexport interface CosmologicalConstantNode {\n readonly kind: 'cosmological-constant';\n readonly symbol: 'Λ';\n readonly dim: Dimension; // [L⁻²]\n readonly value?: number; // optional numeric value (e.g., 1.1056e-52 m⁻²)\n}\n\n/**\n * AST node for the Einstein field equation G_μν + Λ g_μν = (8πG/c⁴) T_μν.\n *\n * @public\n */\nexport interface EinsteinFieldEquationNode {\n readonly kind: 'einstein-equation';\n readonly lhs: EinsteinTensorNode;\n readonly cosmological: CosmologicalConstantNode | null;\n readonly metric: MetricTensorNode;\n readonly rhs: StressEnergyTensorNode;\n readonly coupling: 'einstein';\n}\n\n// ── the ExprNode union ──────────────────────────────────────────────────────\n\nexport type ExprNode =\n | { kind: 'symbol'; name: string; dim: Dimension }\n | { kind: 'op'; op: '+' | '-' | '*' | '/' | '^'; args: ExprNode[] }\n // ∫ integrand d(over); optional lower/upper bounds make it a DEFINITE integral.\n | { kind: 'integral'; over: ExprNode; integrand: ExprNode; lower?: ExprNode; upper?: ExprNode }\n | { kind: 'derivative'; of: ExprNode; wrt: ExprNode }\n // Dirac-δ correlator: ∫δ(x)dx=1 ⟹ [δ(x)]=[x]⁻¹.\n | { kind: 'dirac-delta'; arg: ExprNode }\n // Functional derivative δF/δφ \"over\" the measure dμ: [δF/δφ]=[F]/([φ]·[μ]).\n | { kind: 'variational-derivative'; functional: ExprNode; field: ExprNode; over: ExprNode }\n // Elementwise transcendental of a DIMENSIONLESS arg → DIMENSIONLESS result.\n | { kind: 'transcendental'; fn: TranscendentalFn; arg: ExprNode }\n // Absolute value |x| — dimension-PRESERVING (unlike the transcendentals).\n | { kind: 'abs'; arg: ExprNode }\n | TensorSymbolNode\n | TensorProductNode\n | MetricTensorNode\n | KroneckerDeltaNode\n | TensorPartialDerivativeNode\n | CovariantDerivativeNode\n | RiemannTensorNode\n | RicciTensorNode\n | EinsteinTensorNode\n | BianchiResidualNode\n | KillingVectorNode\n | ConservedChargeNode\n | StressEnergyTensorNode\n | CosmologicalConstantNode\n | EinsteinFieldEquationNode\n | WeylTensorNode\n | KretschmannScalarNode;\n"]}
1
+ {"version":3,"file":"ast-types.js","sourceRoot":"","sources":["../../src/dimensional/ast-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG","sourcesContent":["/**\n * The dimensional AST type system — `ExprNode` and every node/index interface\n * it unions, in ONE leaf module.\n *\n * Previously `ExprNode` lived in `validator.ts` and pulled its member node types\n * from ~9 sibling modules (`tensor`, `metric-validators`, `connection-\n * validators`, `curvature`, …). Two of those (`tensor`, `curvature`) imported\n * `ExprNode` back, forming type-only cycles, and several node interfaces used\n * `of: unknown` casts to dodge importing `ExprNode`. Consolidating the *types*\n * here (this module imports only `types.ts` + the leaf `curvature-composite.ts`,\n * so it has no back-edges) breaks both cycles and lets the derivative nodes type\n * `of`/`wrt` as real `ExprNode`.\n *\n * Each origin module now re-exports its types from here (so existing importers\n * are unchanged) and keeps only its validation FUNCTIONS.\n *\n * @module dimensional/ast-types\n */\n\nimport type { Dimension } from './types.js';\nimport type { CurvatureCompositeNode } from './curvature-composite.js';\n\n// ── index types ─────────────────────────────────────────────────────────────\n\n/** The position of a tensor index: upper (contravariant) or lower (covariant). */\nexport type Variance = 'upper' | 'lower';\n/** The semantic class of a tensor symbol: coordinate, field or constant. */\nexport type Role = 'coordinate' | 'field' | 'constant';\n\n/** One index of a tensor: its label and whether it is upper or lower. */\nexport interface TensorIndex {\n readonly label: string;\n readonly variance: Variance;\n}\n\n/** A strictly-lower tensor index. */\nexport interface CovariantIndex {\n readonly label: string;\n readonly variance: 'lower';\n}\n\n/** A strictly-upper tensor index. */\nexport interface UpperIndex {\n readonly label: string;\n readonly variance: 'upper';\n}\n\n// ── transcendental functions ────────────────────────────────────────────────\n\n/**\n * Elementwise transcendental functions usable in a `transcendental` node. All\n * take a DIMENSIONLESS argument and return a DIMENSIONLESS result. (`sqrt`/`cbrt`\n * are excluded — they produce fractional dimensions.)\n */\nexport type TranscendentalFn =\n | 'exp'\n | 'ln'\n | 'log2'\n | 'log10'\n | 'sin'\n | 'cos'\n | 'tan'\n | 'sinh'\n | 'cosh'\n | 'tanh';\n\n// ── tensor nodes ────────────────────────────────────────────────────────────\n\n/** A named tensor, with its indices, dimension and optional role. */\nexport interface TensorSymbolNode {\n readonly kind: 'tensor-symbol';\n readonly name: string;\n readonly indices: ReadonlyArray<TensorIndex>;\n readonly dim: Dimension;\n /** Semantic classification (default 'field'). Structural metadata only. */\n readonly role?: Role;\n /** v0.3.5 numerical pderiv strategy when this is a partial-derivative `of`\n * operand (default 'symbolic'). */\n readonly numericalForm?: 'symbolic' | 'numerical-fn' | 'grid';\n}\n\n/** An Einstein-summation product of tensor and scalar operands. */\nexport interface TensorProductNode {\n readonly kind: 'tensor-product';\n readonly args: ReadonlyArray<ExprNode>;\n}\n\n// ── metric nodes ────────────────────────────────────────────────────────────\n\n/** A metric tensor, with its name, indices, signature and dimension. */\nexport interface MetricTensorNode {\n readonly kind: 'metric-tensor';\n readonly name: string;\n readonly indices: ReadonlyArray<TensorIndex>;\n readonly signature: string;\n readonly dim: Dimension;\n /** v0.4.0 numerical-lowering hint for ∂g (default 'computed'). */\n readonly derivativeStrategy?: 'computed' | 'zero' | 'supplied';\n}\n\n/** The Kronecker delta, with its tensor indices and dimension. */\nexport interface KroneckerDeltaNode {\n readonly kind: 'kronecker-delta';\n readonly indices: ReadonlyArray<TensorIndex>;\n readonly dim: Dimension;\n}\n\n/** The partial derivative of an expression, taken on a covariant index. */\nexport interface TensorPartialDerivativeNode {\n readonly kind: 'tensor-partial-derivative';\n readonly of: ExprNode;\n readonly wrt: ExprNode;\n readonly wrtIndex: CovariantIndex;\n}\n\n// ── connection / curvature nodes ────────────────────────────────────────────\n\n/**\n * AST node for the covariant derivative ∇_μ of a tensor expression.\n *\n * @public\n */\nexport interface CovariantDerivativeNode {\n readonly kind: 'covariant-derivative';\n readonly of: ExprNode;\n readonly wrt: ExprNode;\n readonly wrtIndex: CovariantIndex;\n readonly gLower: MetricTensorNode;\n readonly gInverse: MetricTensorNode;\n}\n\n/** The Riemann curvature tensor, with one upper and three lower indices. */\nexport type RiemannTensorNode = CurvatureCompositeNode<'riemann-tensor', {\n readonly upperIndex: UpperIndex;\n readonly lowerIndices: readonly [CovariantIndex, CovariantIndex, CovariantIndex];\n readonly gLower: MetricTensorNode;\n readonly gInverse: MetricTensorNode;\n readonly xCoord: TensorSymbolNode;\n}>;\n\n/**\n * AST node for the Ricci tensor R_μν, built by `ricci`.\n *\n * @public\n */\nexport type RicciTensorNode = CurvatureCompositeNode<'ricci-tensor', {\n /** The Riemann tensor, contracted on its upper index and its second lower index: R_μν = R^λ_{μλν}. */\n readonly riemann: RiemannTensorNode;\n}>;\n\n/**\n * AST node for the Einstein tensor G_μν, built by `einstein`.\n *\n * @public\n */\nexport type EinsteinTensorNode = CurvatureCompositeNode<'einstein-tensor', {\n /** The Riemann tensor whose contraction yields the inner Ricci R_μν. */\n readonly riemann: RiemannTensorNode;\n /** Lower metric g_μν — supplies the `½ R g_μν` subtraction tensor. */\n readonly gLower: MetricTensorNode;\n /** Upper metric g^μν — supplies the scalar trace `R = g^μν R_μν`. */\n readonly gInverse: MetricTensorNode;\n}>;\n\n/**\n * AST node for the cyclic second-Bianchi-identity residual, built by `bianchiResidual`.\n *\n * @public\n */\nexport type BianchiResidualNode = CurvatureCompositeNode<'bianchi-residual', {\n /** The Riemann tensor whose cyclic-derivative identity is checked. */\n readonly riemann: RiemannTensorNode;\n}>;\n\n/** The Weyl curvature tensor, the trace-free part of the Riemann tensor. */\nexport type WeylTensorNode = CurvatureCompositeNode<'weyl-tensor', {\n /** Metric g_{μν} (both-lower). Present for numerical lowering consumers. */\n readonly metric: MetricTensorNode;\n /** Contravariant (upper) index ρ. */\n readonly upperIndex: UpperIndex;\n /** Three covariant (lower) indices [σ, μ, ν]. */\n readonly lowerIndices: readonly [CovariantIndex, CovariantIndex, CovariantIndex];\n /** Dimensional signature of each component: [L⁻²], same as Riemann. */\n readonly componentDim: Dimension;\n}>;\n\n/**\n * AST node for the Kretschmann scalar K = R_{ρσμν} R^{ρσμν}.\n *\n * @public\n */\nexport type KretschmannScalarNode = CurvatureCompositeNode<'kretschmann-scalar', {\n /** Riemann tensor R^ρ_{σμν}. */\n readonly riemann: RiemannTensorNode;\n /** Metric (both-lower preferred). */\n readonly metric: MetricTensorNode;\n}>;\n\n// ── Killing / stress-energy / field-equation nodes ──────────────────────────\n\n/** A Killing vector field, with its vector and the metric it preserves. */\nexport interface KillingVectorNode {\n readonly kind: 'killing-vector';\n readonly vector: TensorSymbolNode;\n readonly metric: MetricTensorNode;\n}\n\n/** A conserved charge: a Killing vector contracted with a momentum. */\nexport interface ConservedChargeNode {\n readonly kind: 'conserved-charge';\n /** The Killing vector ξ^μ (rank-1, upper variance). */\n readonly killing: KillingVectorNode;\n /** The covariant momentum p_μ (rank-1, lower variance), sharing the Killing\n * vector's index label so ξ^μ p_μ is well-formed. */\n readonly momentum: TensorSymbolNode;\n}\n\n/** The symmetric stress-energy tensor T, with its indices and component dimension. */\nexport interface StressEnergyTensorNode {\n readonly kind: 'stress-energy';\n readonly symbol: 'T';\n readonly indices: readonly [CovariantIndex, CovariantIndex];\n readonly symmetry: 'symmetric';\n readonly componentDim: Dimension;\n}\n\n/** The cosmological constant Λ, with its dimension and optional numeric value. */\nexport interface CosmologicalConstantNode {\n readonly kind: 'cosmological-constant';\n readonly symbol: 'Λ';\n readonly dim: Dimension; // [L⁻²]\n readonly value?: number; // optional numeric value (e.g., 1.1056e-52 m⁻²)\n}\n\n/**\n * AST node for the Einstein field equation G_μν + Λ g_μν = (8πG/c⁴) T_μν.\n *\n * @public\n */\nexport interface EinsteinFieldEquationNode {\n readonly kind: 'einstein-equation';\n readonly lhs: EinsteinTensorNode;\n readonly cosmological: CosmologicalConstantNode | null;\n readonly metric: MetricTensorNode;\n readonly rhs: StressEnergyTensorNode;\n readonly coupling: 'einstein';\n}\n\n// ── the ExprNode union ──────────────────────────────────────────────────────\n\n/** Any node of a dimensional expression: scalar, calculus, tensor, curvature or field-equation. */\nexport type ExprNode =\n | { kind: 'symbol'; name: string; dim: Dimension }\n | { kind: 'op'; op: '+' | '-' | '*' | '/' | '^'; args: ExprNode[] }\n // ∫ integrand d(over); optional lower/upper bounds make it a DEFINITE integral.\n | { kind: 'integral'; over: ExprNode; integrand: ExprNode; lower?: ExprNode; upper?: ExprNode }\n | { kind: 'derivative'; of: ExprNode; wrt: ExprNode }\n // Dirac-δ correlator: ∫δ(x)dx=1 ⟹ [δ(x)]=[x]⁻¹.\n | { kind: 'dirac-delta'; arg: ExprNode }\n // Functional derivative δF/δφ \"over\" the measure dμ: [δF/δφ]=[F]/([φ]·[μ]).\n | { kind: 'variational-derivative'; functional: ExprNode; field: ExprNode; over: ExprNode }\n // Elementwise transcendental of a DIMENSIONLESS arg → DIMENSIONLESS result.\n | { kind: 'transcendental'; fn: TranscendentalFn; arg: ExprNode }\n // Absolute value |x| — dimension-PRESERVING (unlike the transcendentals).\n | { kind: 'abs'; arg: ExprNode }\n | TensorSymbolNode\n | TensorProductNode\n | MetricTensorNode\n | KroneckerDeltaNode\n | TensorPartialDerivativeNode\n | CovariantDerivativeNode\n | RiemannTensorNode\n | RicciTensorNode\n | EinsteinTensorNode\n | BianchiResidualNode\n | KillingVectorNode\n | ConservedChargeNode\n | StressEnergyTensorNode\n | CosmologicalConstantNode\n | EinsteinFieldEquationNode\n | WeylTensorNode\n | KretschmannScalarNode;\n"]}
@@ -45,7 +45,7 @@ export type CurvatureKind = 'riemann-tensor' | 'ricci-tensor' | 'einstein-tensor
45
45
  * `componentDim` is the SI dimension of each component in the F8/I3 convention
46
46
  * (metric is dimensionless, coordinates carry [L]).
47
47
  *
48
- * @public
48
+ * @internal
49
49
  */
50
50
  interface CurvatureKindSpec {
51
51
  readonly freeIndicesShape: 'rank-4-1upper-3lower' | 'rank-2-lower-lower' | 'rank-3-lower' | 'scalar';
@@ -1 +1 @@
1
- {"version":3,"file":"curvature-composite.js","sourceRoot":"","sources":["../../src/dimensional/curvature-composite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAwDH,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA6C;IAC/E,gBAAgB,EAAE;QAChB,gBAAgB,EAAE,sBAAsB;QACxC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,cAAc,EAAE;QACd,gBAAgB,EAAE,oBAAoB;QACtC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,iBAAiB,EAAE;QACjB,gBAAgB,EAAE,oBAAoB;QACtC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,kBAAkB,EAAE;QAClB,yFAAyF;QACzF,gBAAgB,EAAE,cAAc;QAChC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,aAAa,EAAE;QACb,gBAAgB,EAAE,sBAAsB;QACxC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,oBAAoB,EAAE;QACpB,gBAAgB,EAAE,QAAQ;QAC1B,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;CACF,CAAC","sourcesContent":["/**\n * Curvature composite-AST factory (v0.6.0 Phase 3, Task 3.9).\n *\n * PD-6 trigger fires: Weyl is the 5th curvature primitive (after\n * Riemann/Ricci/Einstein/Bianchi from v0.5.0). The 4-kind parallel\n * duplication is now extracted into a shared factory.\n *\n * Net LOC change: −180 (per design Decision #5).\n *\n * P-1 fix: `CurvatureCompositeNode<K, S>` is an intersection type, not an\n * interface with an unused S. Without the intersection, the per-kind\n * slot type-safety would silently drop (the S parameter would be\n * decorative and TypeScript would not compose it into the result).\n *\n * @module dimensional/curvature-composite\n */\n\nimport type { Dimension } from './types.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CurvatureKind discriminant union\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Discriminant union of all curvature-composite AST node kinds in UPT v0.6.0.\n *\n * Six curvature primitives:\n * - `riemann-tensor` — R^ρ_{σμν} (rank-4, 1-up 3-down, [L⁻²])\n * - `ricci-tensor` — R_{μν} (rank-2 lower-lower, [L⁻²])\n * - `einstein-tensor` — G_{μν} (rank-2 lower-lower, [L⁻²])\n * - `bianchi-residual` — B_{λμνρσ} (rank-5 lower, [L⁻³])\n * - `weyl-tensor` — C^ρ_{σμν} (rank-4, 1-up 3-down, [L⁻²])\n * - `kretschmann-scalar` — K (scalar, [L⁻⁴])\n *\n * @public\n */\nexport type CurvatureKind =\n | 'riemann-tensor'\n | 'ricci-tensor'\n | 'einstein-tensor'\n | 'bianchi-residual'\n | 'weyl-tensor'\n | 'kretschmann-scalar';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CurvatureKindSpec — per-kind shape + dim descriptor\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Per-kind specification record used by the registry.\n *\n * `freeIndicesShape` is a human-readable summary of the free-index structure:\n * - `'rank-4-1upper-3lower'` — 1 upper + 3 lower (Riemann, Weyl)\n * - `'rank-2-lower-lower'` — 2 lower (Ricci, Einstein)\n * - `'rank-3-lower'` — the Bianchi residual B_{λμνρσ}, which has FIVE lower\n * indices. The \"3\" is not the rank: it counts the three\n * cyclic terms over (λ, μ, ν) in\n * B_{λμνρσ} = ∇_λ R_{μνρσ} + ∇_μ R_{νλρσ} + ∇_ν R_{λμρσ}.\n * The name stays because the registry is public.\n * - `'scalar'` — 0 free indices (Kretschmann)\n *\n * `componentDim` is the SI dimension of each component in the F8/I3 convention\n * (metric is dimensionless, coordinates carry [L]).\n *\n * @public\n */\ninterface CurvatureKindSpec {\n readonly freeIndicesShape: 'rank-4-1upper-3lower' | 'rank-2-lower-lower' | 'rank-3-lower' | 'scalar';\n readonly componentDim: Dimension;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CURVATURE_KIND_REGISTRY\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Registry mapping each `CurvatureKind` to its shape + dimensional spec.\n *\n * Used by:\n * - Tests: to assert all 6 kinds are registered and that Riemann + Weyl\n * share the rank-4 shape (refactor-only invariant).\n * - Future lowering consolidation: `CURVATURE_KIND_REGISTRY[node.kind]`\n * can supply common validation data without per-kind duplication.\n *\n * @public\n */\nexport const CURVATURE_KIND_REGISTRY: Record<CurvatureKind, CurvatureKindSpec> = {\n 'riemann-tensor': {\n freeIndicesShape: 'rank-4-1upper-3lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'ricci-tensor': {\n freeIndicesShape: 'rank-2-lower-lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'einstein-tensor': {\n freeIndicesShape: 'rank-2-lower-lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'bianchi-residual': {\n // Five lower indices; '3' counts the cyclic terms, not the rank (see CurvatureKindSpec).\n freeIndicesShape: 'rank-3-lower',\n componentDim: { L: -3, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'weyl-tensor': {\n freeIndicesShape: 'rank-4-1upper-3lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'kretschmann-scalar': {\n freeIndicesShape: 'scalar',\n componentDim: { L: -4, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CurvatureCompositeNode<K, S> — shared factory type\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Generic factory type for all curvature-composite AST nodes.\n *\n * **P-1 fix (v0.6.0 plan-vet):** Must be an intersection type, not an\n * interface with an unused type parameter. The intersection `{ kind: K } & S`\n * ensures TypeScript actually composes the kind-specific slot type `S` into\n * the resulting type, giving real discriminant + kind-specific type safety.\n *\n * Usage (type alias):\n * ```typescript\n * type RicciTensorNode = CurvatureCompositeNode<'ricci-tensor', {\n * readonly riemann: RiemannTensorNode;\n * }>;\n * ```\n *\n * The intersection produces:\n * ```typescript\n * { readonly kind: 'ricci-tensor' } & { readonly riemann: RiemannTensorNode }\n * // ≡ { readonly kind: 'ricci-tensor'; readonly riemann: RiemannTensorNode }\n * ```\n *\n * @public\n */\nexport type CurvatureCompositeNode<K extends CurvatureKind, S extends object> = {\n readonly kind: K;\n} & S;\n"]}
1
+ {"version":3,"file":"curvature-composite.js","sourceRoot":"","sources":["../../src/dimensional/curvature-composite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAwDH,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA6C;IAC/E,gBAAgB,EAAE;QAChB,gBAAgB,EAAE,sBAAsB;QACxC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,cAAc,EAAE;QACd,gBAAgB,EAAE,oBAAoB;QACtC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,iBAAiB,EAAE;QACjB,gBAAgB,EAAE,oBAAoB;QACtC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,kBAAkB,EAAE;QAClB,yFAAyF;QACzF,gBAAgB,EAAE,cAAc;QAChC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,aAAa,EAAE;QACb,gBAAgB,EAAE,sBAAsB;QACxC,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;IACD,oBAAoB,EAAE;QACpB,gBAAgB,EAAE,QAAQ;QAC1B,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KAChE;CACF,CAAC","sourcesContent":["/**\n * Curvature composite-AST factory (v0.6.0 Phase 3, Task 3.9).\n *\n * PD-6 trigger fires: Weyl is the 5th curvature primitive (after\n * Riemann/Ricci/Einstein/Bianchi from v0.5.0). The 4-kind parallel\n * duplication is now extracted into a shared factory.\n *\n * Net LOC change: −180 (per design Decision #5).\n *\n * P-1 fix: `CurvatureCompositeNode<K, S>` is an intersection type, not an\n * interface with an unused S. Without the intersection, the per-kind\n * slot type-safety would silently drop (the S parameter would be\n * decorative and TypeScript would not compose it into the result).\n *\n * @module dimensional/curvature-composite\n */\n\nimport type { Dimension } from './types.js';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CurvatureKind discriminant union\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Discriminant union of all curvature-composite AST node kinds in UPT v0.6.0.\n *\n * Six curvature primitives:\n * - `riemann-tensor` — R^ρ_{σμν} (rank-4, 1-up 3-down, [L⁻²])\n * - `ricci-tensor` — R_{μν} (rank-2 lower-lower, [L⁻²])\n * - `einstein-tensor` — G_{μν} (rank-2 lower-lower, [L⁻²])\n * - `bianchi-residual` — B_{λμνρσ} (rank-5 lower, [L⁻³])\n * - `weyl-tensor` — C^ρ_{σμν} (rank-4, 1-up 3-down, [L⁻²])\n * - `kretschmann-scalar` — K (scalar, [L⁻⁴])\n *\n * @public\n */\nexport type CurvatureKind =\n | 'riemann-tensor'\n | 'ricci-tensor'\n | 'einstein-tensor'\n | 'bianchi-residual'\n | 'weyl-tensor'\n | 'kretschmann-scalar';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CurvatureKindSpec — per-kind shape + dim descriptor\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Per-kind specification record used by the registry.\n *\n * `freeIndicesShape` is a human-readable summary of the free-index structure:\n * - `'rank-4-1upper-3lower'` — 1 upper + 3 lower (Riemann, Weyl)\n * - `'rank-2-lower-lower'` — 2 lower (Ricci, Einstein)\n * - `'rank-3-lower'` — the Bianchi residual B_{λμνρσ}, which has FIVE lower\n * indices. The \"3\" is not the rank: it counts the three\n * cyclic terms over (λ, μ, ν) in\n * B_{λμνρσ} = ∇_λ R_{μνρσ} + ∇_μ R_{νλρσ} + ∇_ν R_{λμρσ}.\n * The name stays because the registry is public.\n * - `'scalar'` — 0 free indices (Kretschmann)\n *\n * `componentDim` is the SI dimension of each component in the F8/I3 convention\n * (metric is dimensionless, coordinates carry [L]).\n *\n * @internal\n */\ninterface CurvatureKindSpec {\n readonly freeIndicesShape: 'rank-4-1upper-3lower' | 'rank-2-lower-lower' | 'rank-3-lower' | 'scalar';\n readonly componentDim: Dimension;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CURVATURE_KIND_REGISTRY\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Registry mapping each `CurvatureKind` to its shape + dimensional spec.\n *\n * Used by:\n * - Tests: to assert all 6 kinds are registered and that Riemann + Weyl\n * share the rank-4 shape (refactor-only invariant).\n * - Future lowering consolidation: `CURVATURE_KIND_REGISTRY[node.kind]`\n * can supply common validation data without per-kind duplication.\n *\n * @public\n */\nexport const CURVATURE_KIND_REGISTRY: Record<CurvatureKind, CurvatureKindSpec> = {\n 'riemann-tensor': {\n freeIndicesShape: 'rank-4-1upper-3lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'ricci-tensor': {\n freeIndicesShape: 'rank-2-lower-lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'einstein-tensor': {\n freeIndicesShape: 'rank-2-lower-lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'bianchi-residual': {\n // Five lower indices; '3' counts the cyclic terms, not the rank (see CurvatureKindSpec).\n freeIndicesShape: 'rank-3-lower',\n componentDim: { L: -3, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'weyl-tensor': {\n freeIndicesShape: 'rank-4-1upper-3lower',\n componentDim: { L: -2, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n 'kretschmann-scalar': {\n freeIndicesShape: 'scalar',\n componentDim: { L: -4, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 },\n },\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CurvatureCompositeNode<K, S> — shared factory type\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Generic factory type for all curvature-composite AST nodes.\n *\n * **P-1 fix (v0.6.0 plan-vet):** Must be an intersection type, not an\n * interface with an unused type parameter. The intersection `{ kind: K } & S`\n * ensures TypeScript actually composes the kind-specific slot type `S` into\n * the resulting type, giving real discriminant + kind-specific type safety.\n *\n * Usage (type alias):\n * ```typescript\n * type RicciTensorNode = CurvatureCompositeNode<'ricci-tensor', {\n * readonly riemann: RiemannTensorNode;\n * }>;\n * ```\n *\n * The intersection produces:\n * ```typescript\n * { readonly kind: 'ricci-tensor' } & { readonly riemann: RiemannTensorNode }\n * // ≡ { readonly kind: 'ricci-tensor'; readonly riemann: RiemannTensorNode }\n * ```\n *\n * @public\n */\nexport type CurvatureCompositeNode<K extends CurvatureKind, S extends object> = {\n readonly kind: K;\n} & S;\n"]}
@@ -1,3 +1,26 @@
1
+ /**
2
+ * Exact unit scales.
3
+ *
4
+ * A unit's scale to SI is a rational number times one floating factor that
5
+ * holds its irrational part (π for an angle, ln 2 for a bit). Prefixes,
6
+ * products, quotients and integer powers multiply the rationals exactly, so
7
+ * `g/cm^3` is 1000 and `72 mN/m` is 0.072 with no float noise to round away.
8
+ * The one rounding is {@link scaleToNumber}, which rounds the rational
9
+ * correctly and then multiplies by the irrational factor once.
10
+ *
11
+ * A decimal literal is read digit for digit. A JavaScript number is read
12
+ * through its shortest round-trip decimal (`String(x)`), which is the
13
+ * literal a constant was written with.
14
+ *
15
+ * The arithmetic is MathTS's (`@danielsimonjr/mathts-core`); the UPT
16
+ * {@link ExactScale} shape and function names are the thin layer over it, and
17
+ * a scale expression (`data/units.json`) reads through MathTS
18
+ * `readScaleExpression` under this module's UPT-facing signature.
19
+ *
20
+ * @module dimensional/exact-scale
21
+ * @internal
22
+ */
23
+ import { type ExactScale as CoreExactScale } from '@danielsimonjr/mathts-core';
1
24
  /** `num / den × irrational`, with `den > 0` and the fraction in lowest terms. @internal */
2
25
  export interface ExactScale {
3
26
  readonly num: bigint;
@@ -5,6 +28,10 @@ export interface ExactScale {
5
28
  /** The factor no rational states (π, ln 2). 1 for a rational scale. */
6
29
  readonly irrational: number;
7
30
  }
31
+ /** UPT {@link ExactScale} to the MathTS core shape. @internal */
32
+ export declare function coreExactScaleFromUpt(s: ExactScale): CoreExactScale;
33
+ /** MathTS core exact scale to UPT {@link ExactScale}. @internal */
34
+ export declare function uptExactScaleFromCore(s: CoreExactScale): ExactScale;
8
35
  /** The scale 1. @internal */
9
36
  export declare const UNIT_SCALE: ExactScale;
10
37
  /**
@@ -25,7 +52,7 @@ export declare function multiplyScales(...factors: readonly ExactScale[]): Exact
25
52
  export declare function divideScales(a: ExactScale, b: ExactScale): ExactScale;
26
53
  /**
27
54
  * `a ^ n`. An integer power stays exact. A fractional power has no exact
28
- * rational in general, so it becomes one floating factor.
55
+ * rational in general and throws.
29
56
  * @internal
30
57
  */
31
58
  export declare function powerScale(a: ExactScale, n: number): ExactScale;
@@ -34,13 +61,13 @@ export declare function addScales(a: ExactScale, b: ExactScale): ExactScale;
34
61
  /** The scale as a double: the rational rounded once, times the irrational factor. @internal */
35
62
  export declare function scaleToNumber(s: ExactScale): number;
36
63
  /**
37
- * The two sides of a unit text or a scale expression under the single-solidus
38
- * convention of ISO 80000-1: everything after the first `/` is the
39
- * denominator, so a chain is one denominator (`km/s/Mpc` is km/(s·Mpc), and
40
- * `W/m*K` is W/(m·K), not (W/m)·K). The denominator comes back as one
41
- * `*`-joined product, each `/`-part's outer parentheses dropped. `units.ts`
42
- * and {@link readScaleExpression} both split here, so a unit text and a scale
43
- * expression in `data/units.json` read a `/` the same way.
64
+ * The two sides of a unit text under the single-solidus convention of
65
+ * ISO 80000-1: everything after the first `/` is the denominator, so a chain
66
+ * is one denominator (`km/s/Mpc` is km/(s·Mpc), and `W/m*K` is W/(m·K), not
67
+ * (W/m)·K). The denominator comes back as one `*`-joined product, each
68
+ * `/`-part's outer parentheses dropped. `units.ts` splits here, so a unit text
69
+ * reads a `/` the same way a scale expression does. MathTS states the same
70
+ * rule inside its `readScaleExpression` and does not export the split.
44
71
  * @internal
45
72
  */
46
73
  export declare function solidusSides(text: string): {
@@ -53,9 +80,12 @@ export declare function solidusSides(text: string): {
53
80
  * each a decimal literal or a name with an optional integer power
54
81
  * (`4.1868*453.59237/1.8`, `pi/180`, `lbf/inch^2`). A `/` follows the unit
55
82
  * grammar ({@link solidusSides}): `a/b*c` is a/(b·c). `resolve` gives a name
56
- * its scale and returns undefined for a name it does not know, which throws
57
- * here. A decimal literal is read digit for digit, so the result is the
58
- * rational the text states.
83
+ * its scale and returns undefined for a name it does not know, which throws.
84
+ * A decimal literal is read digit for digit, so the result is the rational the
85
+ * text states.
86
+ *
87
+ * MathTS's `readScaleExpression` is the reader; this is the UPT-facing
88
+ * signature over it, the one adapter between its exact scale and UPT's.
59
89
  * @internal
60
90
  */
61
91
  export declare function readScaleExpression(text: string, resolve: (name: string) => ExactScale | undefined): ExactScale;
@@ -1 +1 @@
1
- {"version":3,"file":"exact-scale.d.ts","sourceRoot":"","sources":["../../src/dimensional/exact-scale.ts"],"names":[],"mappings":"AAqBA,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAkBD,6BAA6B;AAC7B,eAAO,MAAM,UAAU,EAAE,UAAgD,CAAC;AAI1E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAW5D;AAED,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAG7C;AAED,sCAAsC;AACtC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAEjF;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAGrD;AAED,6BAA6B;AAC7B,wBAAgB,cAAc,CAAC,GAAG,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAU5E;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAGrE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAO/D;AAED,+FAA+F;AAC/F,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAGlE;AAwDD,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAGnD;AAID;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CASvG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,GAAG,UAAU,CAiB/G"}
1
+ {"version":3,"file":"exact-scale.d.ts","sourceRoot":"","sources":["../../src/dimensional/exact-scale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAYL,KAAK,UAAU,IAAI,cAAc,EAClC,MAAM,4BAA4B,CAAC;AAKpC,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AA+BD,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,UAAU,GAAG,cAAc,CAEnE;AAED,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,cAAc,GAAG,UAAU,CAEnE;AAgDD,6BAA6B;AAC7B,eAAO,MAAM,UAAU,EAAE,UAAgD,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAG5D;AAED,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAG7C;AAED,sCAAsC;AACtC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAEjF;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAGrD;AAED,6BAA6B;AAC7B,wBAAgB,cAAc,CAAC,GAAG,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAG5E;AAED,yBAAyB;AACzB,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAErE;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAG/D;AAED,+FAA+F;AAC/F,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,UAAU,CAIlE;AAED,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAEnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CASvG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,GAAG,UAAU,CAO/G"}
@@ -12,9 +12,15 @@
12
12
  * through its shortest round-trip decimal (`String(x)`), which is the
13
13
  * literal a constant was written with.
14
14
  *
15
+ * The arithmetic is MathTS's (`@danielsimonjr/mathts-core`); the UPT
16
+ * {@link ExactScale} shape and function names are the thin layer over it, and
17
+ * a scale expression (`data/units.json`) reads through MathTS
18
+ * `readScaleExpression` under this module's UPT-facing signature.
19
+ *
15
20
  * @module dimensional/exact-scale
16
21
  * @internal
17
22
  */
23
+ import { addExactScales, decimalExactScale, divideExactScales, exactScaleOf, exactScaleToNumber, LN2_EXACT_SCALE, multiplyExactScales, PI_EXACT_SCALE, powerExactScale, ratioExactScale, readScaleExpression as mathtsReadScaleExpression, } from '@danielsimonjr/mathts-core';
18
24
  import { gcd } from '@danielsimonjr/mathts-functions';
19
25
  import { bigintFrom } from '../core/mathts-read.js';
20
26
  /** The bigint gcd, MathTS `gcd` on its `bigint, bigint` signature, read back as the bigint it is. */
@@ -32,39 +38,101 @@ function make(num, den, irrational) {
32
38
  const g = bigGcd(num, den);
33
39
  return g > 1n ? { num: num / g, den: den / g, irrational } : { num, den, irrational };
34
40
  }
41
+ function irrationalFactor(irrationals) {
42
+ let factor = 1;
43
+ const pi = irrationals.pi ?? 0;
44
+ const ln2 = irrationals.ln2 ?? 0;
45
+ if (pi !== 0)
46
+ factor *= Math.PI ** pi;
47
+ if (ln2 !== 0)
48
+ factor *= Math.LN2 ** ln2;
49
+ return factor;
50
+ }
51
+ function fromCore(s) {
52
+ return make(s.num, s.den, irrationalFactor(s.irrationals));
53
+ }
54
+ /** UPT {@link ExactScale} to the MathTS core shape. @internal */
55
+ export function coreExactScaleFromUpt(s) {
56
+ return toCore(s);
57
+ }
58
+ /** MathTS core exact scale to UPT {@link ExactScale}. @internal */
59
+ export function uptExactScaleFromCore(s) {
60
+ return fromCore(s);
61
+ }
62
+ /** When `x / base` is a nonzero integer, that integer; otherwise null. */
63
+ function integerMultiple(x, base) {
64
+ if (!Number.isFinite(x) || !Number.isFinite(base) || base === 0 || x === 0)
65
+ return null;
66
+ const q = x / base;
67
+ if (!Number.isFinite(q))
68
+ return null;
69
+ const n = Math.trunc(q);
70
+ if (n === 0 || q !== n)
71
+ return null;
72
+ if (Math.abs(n * base - x) > Math.max(1e-12, Math.abs(x) * 1e-14))
73
+ return null;
74
+ return BigInt(n);
75
+ }
76
+ /**
77
+ * When `x` is `base` raised to a small integer power (π⁻¹ for a parsec-scale,
78
+ * ln 2 for a bit), that integer; otherwise null. The factor is compared
79
+ * exactly: `irrationalFactor` built it as `base ** n`, so the same expression
80
+ * reads it back.
81
+ */
82
+ function irrationalExponent(x, base) {
83
+ if (!Number.isFinite(x) || x <= 0 || !Number.isFinite(base) || base <= 0)
84
+ return null;
85
+ for (let n = -8; n <= 8; n++) {
86
+ if (x === base ** n)
87
+ return n;
88
+ }
89
+ return null;
90
+ }
91
+ function toCore(s) {
92
+ let core = ratioExactScale(s.num, s.den);
93
+ const ir = s.irrational;
94
+ if (ir === 1)
95
+ return core;
96
+ const piPower = irrationalExponent(ir, Math.PI);
97
+ if (piPower !== null)
98
+ return multiplyExactScales(core, powerExactScale(PI_EXACT_SCALE, piPower));
99
+ const ln2Power = irrationalExponent(ir, Math.LN2);
100
+ if (ln2Power !== null)
101
+ return multiplyExactScales(core, powerExactScale(LN2_EXACT_SCALE, ln2Power));
102
+ const piMultiple = integerMultiple(ir, Math.PI);
103
+ if (piMultiple !== null) {
104
+ if (piMultiple !== 1n)
105
+ core = multiplyExactScales(core, ratioExactScale(piMultiple, 1n));
106
+ return multiplyExactScales(core, PI_EXACT_SCALE);
107
+ }
108
+ const ln2Multiple = integerMultiple(ir, Math.LN2);
109
+ if (ln2Multiple !== null) {
110
+ if (ln2Multiple !== 1n)
111
+ core = multiplyExactScales(core, ratioExactScale(ln2Multiple, 1n));
112
+ return multiplyExactScales(core, LN2_EXACT_SCALE);
113
+ }
114
+ return multiplyExactScales(core, exactScaleOf(ir));
115
+ }
35
116
  /** The scale 1. @internal */
36
117
  export const UNIT_SCALE = { num: 1n, den: 1n, irrational: 1 };
37
- const DECIMAL = /^([+-]?)(\d*)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$/;
38
118
  /**
39
119
  * The exact value of a decimal literal (`72`, `0.45359237`, `1.602176634e-19`),
40
120
  * or null when `text` is not one.
41
121
  * @internal
42
122
  */
43
123
  export function decimalScale(text) {
44
- const m = DECIMAL.exec(text.trim());
45
- if (m === null)
46
- return null;
47
- const whole = m[2] ?? '';
48
- const fraction = m[3] ?? '';
49
- if (whole === '' && fraction === '')
50
- return null;
51
- const exponent = Number(m[4] ?? '0') - fraction.length;
52
- if (!Number.isSafeInteger(exponent) || Math.abs(exponent) > 10_000)
53
- return null;
54
- let num = BigInt(whole + fraction);
55
- if (m[1] === '-')
56
- num = -num;
57
- return exponent >= 0 ? make(num * 10n ** BigInt(exponent), 1n, 1) : make(num, 10n ** BigInt(-exponent), 1);
124
+ const scaled = decimalExactScale(text.trim());
125
+ return scaled === null ? null : fromCore(scaled);
58
126
  }
59
127
  /** The exact scale a finite JavaScript number was written as. @internal */
60
128
  export function scaleOf(x) {
61
129
  if (!Number.isFinite(x))
62
130
  throw new RangeError(`exact scale: ${x} is not finite`);
63
- return decimalScale(String(x));
131
+ return fromCore(exactScaleOf(x));
64
132
  }
65
133
  /** `num / den`, exactly. @internal */
66
134
  export function ratioScale(num, den) {
67
- return make(BigInt(num), BigInt(den), 1);
135
+ return fromCore(ratioExactScale(num, den));
68
136
  }
69
137
  /** A factor no rational states, such as π or ln 2. @internal */
70
138
  export function irrationalScale(x) {
@@ -74,108 +142,43 @@ export function irrationalScale(x) {
74
142
  }
75
143
  /** `a × b × …`. @internal */
76
144
  export function multiplyScales(...factors) {
77
- let num = 1n;
78
- let den = 1n;
79
- let irrational = 1;
80
- for (const f of factors) {
81
- num *= f.num;
82
- den *= f.den;
83
- irrational *= f.irrational;
84
- }
85
- return make(num, den, irrational);
145
+ if (factors.length === 0)
146
+ return UNIT_SCALE;
147
+ return fromCore(multiplyExactScales(...factors.map(toCore)));
86
148
  }
87
149
  /** `a / b`. @internal */
88
150
  export function divideScales(a, b) {
89
- if (b.num === 0n)
90
- throw new RangeError('exact scale: division by zero');
91
- return make(a.num * b.den, a.den * b.num, a.irrational / b.irrational);
151
+ return fromCore(divideExactScales(toCore(a), toCore(b)));
92
152
  }
93
153
  /**
94
154
  * `a ^ n`. An integer power stays exact. A fractional power has no exact
95
- * rational in general, so it becomes one floating factor.
155
+ * rational in general and throws.
96
156
  * @internal
97
157
  */
98
158
  export function powerScale(a, n) {
99
- if (Number.isInteger(n)) {
100
- const k = BigInt(Math.abs(n));
101
- const up = make(a.num ** k, a.den ** k, a.irrational ** Math.abs(n));
102
- return n >= 0 ? up : divideScales(UNIT_SCALE, up);
103
- }
104
- return irrationalScale(scaleToNumber(a) ** n);
159
+ if (!Number.isInteger(n))
160
+ throw new RangeError(`exact scale: power ${n} is not an integer`);
161
+ return fromCore(powerExactScale(toCore(a), n));
105
162
  }
106
163
  /** `a + b`: exact when both are rational multiples of the same irrational factor. @internal */
107
164
  export function addScales(a, b) {
108
- if (a.irrational === b.irrational)
109
- return make(a.num * b.den + b.num * a.den, a.den * b.den, a.irrational);
110
- return irrationalScale(scaleToNumber(a) + scaleToNumber(b));
111
- }
112
- /** The fewest significant digits kept before the sticky digit; far beyond a double's 17. */
113
- const MIN_DIGITS = 40;
114
- /** Decimal places of `1 / den` when it terminates (`den` = 2^a·5^b): max(a, b). Null otherwise. */
115
- function terminatingPlaces(den) {
116
- let d = den;
117
- let twos = 0;
118
- let fives = 0;
119
- while (d % 2n === 0n) {
120
- d /= 2n;
121
- twos++;
122
- }
123
- while (d % 5n === 0n) {
124
- d /= 5n;
125
- fives++;
126
- }
127
- return d === 1n ? Math.max(twos, fives) : null;
128
- }
129
- /**
130
- * The rational `num / den` (`den > 0`), reduced, rounded once to the nearest double.
131
- *
132
- * A terminating quotient (`den` = 2^a·5^b) is written out exactly, every digit,
133
- * and parsed: a tie between two doubles is a dyadic rational, so it always
134
- * lands here and rounds half to even. Any other quotient is not a tie, and it
135
- * is at least `1 / (den·2^54)` of its magnitude away from every tie; truncating
136
- * it to `max(40, digits(den) + 20)` significant digits stays closer than that,
137
- * and a sticky `1` puts the string strictly inside the truncation interval, so
138
- * the string rounds the way the quotient does for any denominator.
139
- */
140
- function rationalToNumber(num, den) {
141
- if (num === 0n)
142
- return 0;
143
- const negative = num < 0n;
144
- const g = bigGcd(num, den);
145
- const a = (negative ? -num : num) / g;
146
- den /= g;
147
- const places = terminatingPlaces(den);
148
- if (places !== null) {
149
- const value = Number(`${(a * 10n ** BigInt(places)) / den}e-${places}`);
150
- return negative ? -value : value;
151
- }
152
- const digits = Math.max(MIN_DIGITS, den.toString().length + 20);
153
- const shift = digits - (a.toString().length - den.toString().length);
154
- let q;
155
- if (shift >= 0) {
156
- q = (a * 10n ** BigInt(shift)) / den;
157
- }
158
- else {
159
- q = a / (den * 10n ** BigInt(-shift));
160
- }
161
- // Not terminating, so the remainder is never zero: the sticky digit is always due.
162
- const value = Number(`${q.toString()}1e${-(shift + 1)}`);
163
- return negative ? -value : value;
165
+ const sum = addExactScales(toCore(a), toCore(b));
166
+ if (sum === null)
167
+ throw new RangeError('exact scale: unlike irrational factors');
168
+ return fromCore(sum);
164
169
  }
165
170
  /** The scale as a double: the rational rounded once, times the irrational factor. @internal */
166
171
  export function scaleToNumber(s) {
167
- const rational = rationalToNumber(s.num, s.den);
168
- return s.irrational === 1 ? rational : rational * s.irrational;
172
+ return exactScaleToNumber(toCore(s));
169
173
  }
170
- const FACTOR = /^([^*/^\s]+)(?:\^([+-]?\d+))?$/;
171
174
  /**
172
- * The two sides of a unit text or a scale expression under the single-solidus
173
- * convention of ISO 80000-1: everything after the first `/` is the
174
- * denominator, so a chain is one denominator (`km/s/Mpc` is km/(s·Mpc), and
175
- * `W/m*K` is W/(m·K), not (W/m)·K). The denominator comes back as one
176
- * `*`-joined product, each `/`-part's outer parentheses dropped. `units.ts`
177
- * and {@link readScaleExpression} both split here, so a unit text and a scale
178
- * expression in `data/units.json` read a `/` the same way.
175
+ * The two sides of a unit text under the single-solidus convention of
176
+ * ISO 80000-1: everything after the first `/` is the denominator, so a chain
177
+ * is one denominator (`km/s/Mpc` is km/(s·Mpc), and `W/m*K` is W/(m·K), not
178
+ * (W/m)·K). The denominator comes back as one `*`-joined product, each
179
+ * `/`-part's outer parentheses dropped. `units.ts` splits here, so a unit text
180
+ * reads a `/` the same way a scale expression does. MathTS states the same
181
+ * rule inside its `readScaleExpression` and does not export the split.
179
182
  * @internal
180
183
  */
181
184
  export function solidusSides(text) {
@@ -194,29 +197,18 @@ export function solidusSides(text) {
194
197
  * each a decimal literal or a name with an optional integer power
195
198
  * (`4.1868*453.59237/1.8`, `pi/180`, `lbf/inch^2`). A `/` follows the unit
196
199
  * grammar ({@link solidusSides}): `a/b*c` is a/(b·c). `resolve` gives a name
197
- * its scale and returns undefined for a name it does not know, which throws
198
- * here. A decimal literal is read digit for digit, so the result is the
199
- * rational the text states.
200
+ * its scale and returns undefined for a name it does not know, which throws.
201
+ * A decimal literal is read digit for digit, so the result is the rational the
202
+ * text states.
203
+ *
204
+ * MathTS's `readScaleExpression` is the reader; this is the UPT-facing
205
+ * signature over it, the one adapter between its exact scale and UPT's.
200
206
  * @internal
201
207
  */
202
208
  export function readScaleExpression(text, resolve) {
203
- const product = (side) => {
204
- let scale = UNIT_SCALE;
205
- for (const part of side.split('*')) {
206
- const m = FACTOR.exec(part);
207
- if (m === null)
208
- throw new RangeError(`exact scale: '${text}' is not a product of factors`);
209
- const atom = m[1];
210
- const base = decimalScale(atom) ?? resolve(atom);
211
- if (base === undefined)
212
- throw new RangeError(`exact scale: '${text}' names '${atom}', which is not a known scale`);
213
- scale = multiplyScales(scale, m[2] === undefined ? base : powerScale(base, Number(m[2])));
214
- }
215
- return scale;
216
- };
217
- const trimmed = text.trim();
218
- const { numerator, denominator } = solidusSides(trimmed);
219
- const top = product(numerator);
220
- return trimmed.includes('/') ? divideScales(top, product(denominator)) : top;
209
+ return uptExactScaleFromCore(mathtsReadScaleExpression(text.trim(), (name) => {
210
+ const scale = resolve(name);
211
+ return scale === undefined ? undefined : coreExactScaleFromUpt(scale);
212
+ }));
221
213
  }
222
214
  //# sourceMappingURL=exact-scale.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"exact-scale.js","sourceRoot":"","sources":["../../src/dimensional/exact-scale.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Exact unit scales.\n *\n * A unit's scale to SI is a rational number times one floating factor that\n * holds its irrational part (π for an angle, ln 2 for a bit). Prefixes,\n * products, quotients and integer powers multiply the rationals exactly, so\n * `g/cm^3` is 1000 and `72 mN/m` is 0.072 with no float noise to round away.\n * The one rounding is {@link scaleToNumber}, which rounds the rational\n * correctly and then multiplies by the irrational factor once.\n *\n * A decimal literal is read digit for digit. A JavaScript number is read\n * through its shortest round-trip decimal (`String(x)`), which is the\n * literal a constant was written with.\n *\n * @module dimensional/exact-scale\n * @internal\n */\nimport { gcd } from '@danielsimonjr/mathts-functions';\nimport { bigintFrom } from '../core/mathts-read.js';\n\n\n/** `num / den × irrational`, with `den > 0` and the fraction in lowest terms. @internal */\nexport interface ExactScale {\n readonly num: bigint;\n readonly den: bigint;\n /** The factor no rational states (π, ln 2). 1 for a rational scale. */\n readonly irrational: number;\n}\n\n/** The bigint gcd, MathTS `gcd` on its `bigint, bigint` signature, read back as the bigint it is. */\nfunction bigGcd(a: bigint, b: bigint): bigint {\n const g = bigintFrom('gcd', gcd(a, b));\n return g < 0n ? -g : g;\n}\n\nfunction make(num: bigint, den: bigint, irrational: number): ExactScale {\n if (den === 0n) throw new RangeError('exact scale: zero denominator');\n if (den < 0n) {\n num = -num;\n den = -den;\n }\n const g = bigGcd(num, den);\n return g > 1n ? { num: num / g, den: den / g, irrational } : { num, den, irrational };\n}\n\n/** The scale 1. @internal */\nexport const UNIT_SCALE: ExactScale = { num: 1n, den: 1n, irrational: 1 };\n\nconst DECIMAL = /^([+-]?)(\\d*)(?:\\.(\\d*))?(?:[eE]([+-]?\\d+))?$/;\n\n/**\n * The exact value of a decimal literal (`72`, `0.45359237`, `1.602176634e-19`),\n * or null when `text` is not one.\n * @internal\n */\nexport function decimalScale(text: string): ExactScale | null {\n const m = DECIMAL.exec(text.trim());\n if (m === null) return null;\n const whole = m[2] ?? '';\n const fraction = m[3] ?? '';\n if (whole === '' && fraction === '') return null;\n const exponent = Number(m[4] ?? '0') - fraction.length;\n if (!Number.isSafeInteger(exponent) || Math.abs(exponent) > 10_000) return null;\n let num = BigInt(whole + fraction);\n if (m[1] === '-') num = -num;\n return exponent >= 0 ? make(num * 10n ** BigInt(exponent), 1n, 1) : make(num, 10n ** BigInt(-exponent), 1);\n}\n\n/** The exact scale a finite JavaScript number was written as. @internal */\nexport function scaleOf(x: number): ExactScale {\n if (!Number.isFinite(x)) throw new RangeError(`exact scale: ${x} is not finite`);\n return decimalScale(String(x))!;\n}\n\n/** `num / den`, exactly. @internal */\nexport function ratioScale(num: number | bigint, den: number | bigint): ExactScale {\n return make(BigInt(num), BigInt(den), 1);\n}\n\n/** A factor no rational states, such as π or ln 2. @internal */\nexport function irrationalScale(x: number): ExactScale {\n if (!Number.isFinite(x)) throw new RangeError(`exact scale: ${x} is not finite`);\n return { num: 1n, den: 1n, irrational: x };\n}\n\n/** `a × b × …`. @internal */\nexport function multiplyScales(...factors: readonly ExactScale[]): ExactScale {\n let num = 1n;\n let den = 1n;\n let irrational = 1;\n for (const f of factors) {\n num *= f.num;\n den *= f.den;\n irrational *= f.irrational;\n }\n return make(num, den, irrational);\n}\n\n/** `a / b`. @internal */\nexport function divideScales(a: ExactScale, b: ExactScale): ExactScale {\n if (b.num === 0n) throw new RangeError('exact scale: division by zero');\n return make(a.num * b.den, a.den * b.num, a.irrational / b.irrational);\n}\n\n/**\n * `a ^ n`. An integer power stays exact. A fractional power has no exact\n * rational in general, so it becomes one floating factor.\n * @internal\n */\nexport function powerScale(a: ExactScale, n: number): ExactScale {\n if (Number.isInteger(n)) {\n const k = BigInt(Math.abs(n));\n const up = make(a.num ** k, a.den ** k, a.irrational ** Math.abs(n));\n return n >= 0 ? up : divideScales(UNIT_SCALE, up);\n }\n return irrationalScale(scaleToNumber(a) ** n);\n}\n\n/** `a + b`: exact when both are rational multiples of the same irrational factor. @internal */\nexport function addScales(a: ExactScale, b: ExactScale): ExactScale {\n if (a.irrational === b.irrational) return make(a.num * b.den + b.num * a.den, a.den * b.den, a.irrational);\n return irrationalScale(scaleToNumber(a) + scaleToNumber(b));\n}\n\n/** The fewest significant digits kept before the sticky digit; far beyond a double's 17. */\nconst MIN_DIGITS = 40;\n\n/** Decimal places of `1 / den` when it terminates (`den` = 2^a·5^b): max(a, b). Null otherwise. */\nfunction terminatingPlaces(den: bigint): number | null {\n let d = den;\n let twos = 0;\n let fives = 0;\n while (d % 2n === 0n) {\n d /= 2n;\n twos++;\n }\n while (d % 5n === 0n) {\n d /= 5n;\n fives++;\n }\n return d === 1n ? Math.max(twos, fives) : null;\n}\n\n/**\n * The rational `num / den` (`den > 0`), reduced, rounded once to the nearest double.\n *\n * A terminating quotient (`den` = 2^a·5^b) is written out exactly, every digit,\n * and parsed: a tie between two doubles is a dyadic rational, so it always\n * lands here and rounds half to even. Any other quotient is not a tie, and it\n * is at least `1 / (den·2^54)` of its magnitude away from every tie; truncating\n * it to `max(40, digits(den) + 20)` significant digits stays closer than that,\n * and a sticky `1` puts the string strictly inside the truncation interval, so\n * the string rounds the way the quotient does for any denominator.\n */\nfunction rationalToNumber(num: bigint, den: bigint): number {\n if (num === 0n) return 0;\n const negative = num < 0n;\n const g = bigGcd(num, den);\n const a = (negative ? -num : num) / g;\n den /= g;\n const places = terminatingPlaces(den);\n if (places !== null) {\n const value = Number(`${(a * 10n ** BigInt(places)) / den}e-${places}`);\n return negative ? -value : value;\n }\n const digits = Math.max(MIN_DIGITS, den.toString().length + 20);\n const shift = digits - (a.toString().length - den.toString().length);\n let q: bigint;\n if (shift >= 0) {\n q = (a * 10n ** BigInt(shift)) / den;\n } else {\n q = a / (den * 10n ** BigInt(-shift));\n }\n // Not terminating, so the remainder is never zero: the sticky digit is always due.\n const value = Number(`${q.toString()}1e${-(shift + 1)}`);\n return negative ? -value : value;\n}\n\n/** The scale as a double: the rational rounded once, times the irrational factor. @internal */\nexport function scaleToNumber(s: ExactScale): number {\n const rational = rationalToNumber(s.num, s.den);\n return s.irrational === 1 ? rational : rational * s.irrational;\n}\n\nconst FACTOR = /^([^*/^\\s]+)(?:\\^([+-]?\\d+))?$/;\n\n/**\n * The two sides of a unit text or a scale expression under the single-solidus\n * convention of ISO 80000-1: everything after the first `/` is the\n * denominator, so a chain is one denominator (`km/s/Mpc` is km/(s·Mpc), and\n * `W/m*K` is W/(m·K), not (W/m)·K). The denominator comes back as one\n * `*`-joined product, each `/`-part's outer parentheses dropped. `units.ts`\n * and {@link readScaleExpression} both split here, so a unit text and a scale\n * expression in `data/units.json` read a `/` the same way.\n * @internal\n */\nexport function solidusSides(text: string): { readonly numerator: string; readonly denominator: string } {\n const parts = text.split('/');\n return {\n numerator: parts[0]!,\n denominator: parts\n .slice(1)\n .map((part) => part.replace(/^\\((.*)\\)$/, '$1'))\n .join('*'),\n };\n}\n\n/**\n * The exact value of a scale expression, the form `data/units.json` stores:\n * factors joined by `*`, then optionally `/` and the denominator's factors,\n * each a decimal literal or a name with an optional integer power\n * (`4.1868*453.59237/1.8`, `pi/180`, `lbf/inch^2`). A `/` follows the unit\n * grammar ({@link solidusSides}): `a/b*c` is a/(b·c). `resolve` gives a name\n * its scale and returns undefined for a name it does not know, which throws\n * here. A decimal literal is read digit for digit, so the result is the\n * rational the text states.\n * @internal\n */\nexport function readScaleExpression(text: string, resolve: (name: string) => ExactScale | undefined): ExactScale {\n const product = (side: string): ExactScale => {\n let scale = UNIT_SCALE;\n for (const part of side.split('*')) {\n const m = FACTOR.exec(part);\n if (m === null) throw new RangeError(`exact scale: '${text}' is not a product of factors`);\n const atom = m[1]!;\n const base = decimalScale(atom) ?? resolve(atom);\n if (base === undefined) throw new RangeError(`exact scale: '${text}' names '${atom}', which is not a known scale`);\n scale = multiplyScales(scale, m[2] === undefined ? base : powerScale(base, Number(m[2])));\n }\n return scale;\n };\n const trimmed = text.trim();\n const { numerator, denominator } = solidusSides(trimmed);\n const top = product(numerator);\n return trimmed.includes('/') ? divideScales(top, product(denominator)) : top;\n}\n"]}
1
+ {"version":3,"file":"exact-scale.js","sourceRoot":"","sources":["../../src/dimensional/exact-scale.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Exact unit scales.\n *\n * A unit's scale to SI is a rational number times one floating factor that\n * holds its irrational part (π for an angle, ln 2 for a bit). Prefixes,\n * products, quotients and integer powers multiply the rationals exactly, so\n * `g/cm^3` is 1000 and `72 mN/m` is 0.072 with no float noise to round away.\n * The one rounding is {@link scaleToNumber}, which rounds the rational\n * correctly and then multiplies by the irrational factor once.\n *\n * A decimal literal is read digit for digit. A JavaScript number is read\n * through its shortest round-trip decimal (`String(x)`), which is the\n * literal a constant was written with.\n *\n * The arithmetic is MathTS's (`@danielsimonjr/mathts-core`); the UPT\n * {@link ExactScale} shape and function names are the thin layer over it, and\n * a scale expression (`data/units.json`) reads through MathTS\n * `readScaleExpression` under this module's UPT-facing signature.\n *\n * @module dimensional/exact-scale\n * @internal\n */\nimport {\n addExactScales,\n decimalExactScale,\n divideExactScales,\n exactScaleOf,\n exactScaleToNumber,\n LN2_EXACT_SCALE,\n multiplyExactScales,\n PI_EXACT_SCALE,\n powerExactScale,\n ratioExactScale,\n readScaleExpression as mathtsReadScaleExpression,\n type ExactScale as CoreExactScale,\n} from '@danielsimonjr/mathts-core';\nimport { gcd } from '@danielsimonjr/mathts-functions';\nimport { bigintFrom } from '../core/mathts-read.js';\n\n\n/** `num / den × irrational`, with `den > 0` and the fraction in lowest terms. @internal */\nexport interface ExactScale {\n readonly num: bigint;\n readonly den: bigint;\n /** The factor no rational states (π, ln 2). 1 for a rational scale. */\n readonly irrational: number;\n}\n\n/** The bigint gcd, MathTS `gcd` on its `bigint, bigint` signature, read back as the bigint it is. */\nfunction bigGcd(a: bigint, b: bigint): bigint {\n const g = bigintFrom('gcd', gcd(a, b));\n return g < 0n ? -g : g;\n}\n\nfunction make(num: bigint, den: bigint, irrational: number): ExactScale {\n if (den === 0n) throw new RangeError('exact scale: zero denominator');\n if (den < 0n) {\n num = -num;\n den = -den;\n }\n const g = bigGcd(num, den);\n return g > 1n ? { num: num / g, den: den / g, irrational } : { num, den, irrational };\n}\n\nfunction irrationalFactor(irrationals: CoreExactScale['irrationals']): number {\n let factor = 1;\n const pi = irrationals.pi ?? 0;\n const ln2 = irrationals.ln2 ?? 0;\n if (pi !== 0) factor *= Math.PI ** pi;\n if (ln2 !== 0) factor *= Math.LN2 ** ln2;\n return factor;\n}\n\nfunction fromCore(s: CoreExactScale): ExactScale {\n return make(s.num, s.den, irrationalFactor(s.irrationals));\n}\n\n/** UPT {@link ExactScale} to the MathTS core shape. @internal */\nexport function coreExactScaleFromUpt(s: ExactScale): CoreExactScale {\n return toCore(s);\n}\n\n/** MathTS core exact scale to UPT {@link ExactScale}. @internal */\nexport function uptExactScaleFromCore(s: CoreExactScale): ExactScale {\n return fromCore(s);\n}\n\n/** When `x / base` is a nonzero integer, that integer; otherwise null. */\nfunction integerMultiple(x: number, base: number): bigint | null {\n if (!Number.isFinite(x) || !Number.isFinite(base) || base === 0 || x === 0) return null;\n const q = x / base;\n if (!Number.isFinite(q)) return null;\n const n = Math.trunc(q);\n if (n === 0 || q !== n) return null;\n if (Math.abs(n * base - x) > Math.max(1e-12, Math.abs(x) * 1e-14)) return null;\n return BigInt(n);\n}\n\n/**\n * When `x` is `base` raised to a small integer power (π⁻¹ for a parsec-scale,\n * ln 2 for a bit), that integer; otherwise null. The factor is compared\n * exactly: `irrationalFactor` built it as `base ** n`, so the same expression\n * reads it back.\n */\nfunction irrationalExponent(x: number, base: number): number | null {\n if (!Number.isFinite(x) || x <= 0 || !Number.isFinite(base) || base <= 0) return null;\n for (let n = -8; n <= 8; n++) {\n if (x === base ** n) return n;\n }\n return null;\n}\n\nfunction toCore(s: ExactScale): CoreExactScale {\n let core = ratioExactScale(s.num, s.den);\n const ir = s.irrational;\n if (ir === 1) return core;\n const piPower = irrationalExponent(ir, Math.PI);\n if (piPower !== null) return multiplyExactScales(core, powerExactScale(PI_EXACT_SCALE, piPower));\n const ln2Power = irrationalExponent(ir, Math.LN2);\n if (ln2Power !== null) return multiplyExactScales(core, powerExactScale(LN2_EXACT_SCALE, ln2Power));\n const piMultiple = integerMultiple(ir, Math.PI);\n if (piMultiple !== null) {\n if (piMultiple !== 1n) core = multiplyExactScales(core, ratioExactScale(piMultiple, 1n));\n return multiplyExactScales(core, PI_EXACT_SCALE);\n }\n const ln2Multiple = integerMultiple(ir, Math.LN2);\n if (ln2Multiple !== null) {\n if (ln2Multiple !== 1n) core = multiplyExactScales(core, ratioExactScale(ln2Multiple, 1n));\n return multiplyExactScales(core, LN2_EXACT_SCALE);\n }\n return multiplyExactScales(core, exactScaleOf(ir));\n}\n\n/** The scale 1. @internal */\nexport const UNIT_SCALE: ExactScale = { num: 1n, den: 1n, irrational: 1 };\n\n/**\n * The exact value of a decimal literal (`72`, `0.45359237`, `1.602176634e-19`),\n * or null when `text` is not one.\n * @internal\n */\nexport function decimalScale(text: string): ExactScale | null {\n const scaled = decimalExactScale(text.trim());\n return scaled === null ? null : fromCore(scaled);\n}\n\n/** The exact scale a finite JavaScript number was written as. @internal */\nexport function scaleOf(x: number): ExactScale {\n if (!Number.isFinite(x)) throw new RangeError(`exact scale: ${x} is not finite`);\n return fromCore(exactScaleOf(x));\n}\n\n/** `num / den`, exactly. @internal */\nexport function ratioScale(num: number | bigint, den: number | bigint): ExactScale {\n return fromCore(ratioExactScale(num, den));\n}\n\n/** A factor no rational states, such as π or ln 2. @internal */\nexport function irrationalScale(x: number): ExactScale {\n if (!Number.isFinite(x)) throw new RangeError(`exact scale: ${x} is not finite`);\n return { num: 1n, den: 1n, irrational: x };\n}\n\n/** `a × b × …`. @internal */\nexport function multiplyScales(...factors: readonly ExactScale[]): ExactScale {\n if (factors.length === 0) return UNIT_SCALE;\n return fromCore(multiplyExactScales(...factors.map(toCore)));\n}\n\n/** `a / b`. @internal */\nexport function divideScales(a: ExactScale, b: ExactScale): ExactScale {\n return fromCore(divideExactScales(toCore(a), toCore(b)));\n}\n\n/**\n * `a ^ n`. An integer power stays exact. A fractional power has no exact\n * rational in general and throws.\n * @internal\n */\nexport function powerScale(a: ExactScale, n: number): ExactScale {\n if (!Number.isInteger(n)) throw new RangeError(`exact scale: power ${n} is not an integer`);\n return fromCore(powerExactScale(toCore(a), n));\n}\n\n/** `a + b`: exact when both are rational multiples of the same irrational factor. @internal */\nexport function addScales(a: ExactScale, b: ExactScale): ExactScale {\n const sum = addExactScales(toCore(a), toCore(b));\n if (sum === null) throw new RangeError('exact scale: unlike irrational factors');\n return fromCore(sum);\n}\n\n/** The scale as a double: the rational rounded once, times the irrational factor. @internal */\nexport function scaleToNumber(s: ExactScale): number {\n return exactScaleToNumber(toCore(s));\n}\n\n/**\n * The two sides of a unit text under the single-solidus convention of\n * ISO 80000-1: everything after the first `/` is the denominator, so a chain\n * is one denominator (`km/s/Mpc` is km/(s·Mpc), and `W/m*K` is W/(m·K), not\n * (W/m)·K). The denominator comes back as one `*`-joined product, each\n * `/`-part's outer parentheses dropped. `units.ts` splits here, so a unit text\n * reads a `/` the same way a scale expression does. MathTS states the same\n * rule inside its `readScaleExpression` and does not export the split.\n * @internal\n */\nexport function solidusSides(text: string): { readonly numerator: string; readonly denominator: string } {\n const parts = text.split('/');\n return {\n numerator: parts[0]!,\n denominator: parts\n .slice(1)\n .map((part) => part.replace(/^\\((.*)\\)$/, '$1'))\n .join('*'),\n };\n}\n\n/**\n * The exact value of a scale expression, the form `data/units.json` stores:\n * factors joined by `*`, then optionally `/` and the denominator's factors,\n * each a decimal literal or a name with an optional integer power\n * (`4.1868*453.59237/1.8`, `pi/180`, `lbf/inch^2`). A `/` follows the unit\n * grammar ({@link solidusSides}): `a/b*c` is a/(b·c). `resolve` gives a name\n * its scale and returns undefined for a name it does not know, which throws.\n * A decimal literal is read digit for digit, so the result is the rational the\n * text states.\n *\n * MathTS's `readScaleExpression` is the reader; this is the UPT-facing\n * signature over it, the one adapter between its exact scale and UPT's.\n * @internal\n */\nexport function readScaleExpression(text: string, resolve: (name: string) => ExactScale | undefined): ExactScale {\n return uptExactScaleFromCore(\n mathtsReadScaleExpression(text.trim(), (name) => {\n const scale = resolve(name);\n return scale === undefined ? undefined : coreExactScaleFromUpt(scale);\n }),\n );\n}\n"]}