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.
- package/README.md +36 -34
- package/data/applied-cases.json +1892 -0
- package/data/applied-cases.schema.json +194 -0
- package/data/atlas/atlas.json +21 -21
- package/data/atlas/atlas.jsonld +1 -1
- package/data/atlas/diffusion.json +5 -5
- package/data/atlas/oscillators.json +7 -7
- package/data/atlas/waves.json +11 -11
- package/data/bridge-catalog.json +20 -4
- package/data/units.json +6 -25
- package/dist/atlas/benchmark/stats.d.ts.map +1 -1
- package/dist/atlas/benchmark/stats.js +6 -20
- package/dist/atlas/benchmark/stats.js.map +1 -1
- package/dist/atlas/physjs-entries.generated.d.ts +13 -4
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +15 -4
- package/dist/atlas/physjs-entries.generated.js.map +1 -1
- package/dist/atlas/physjs-reviewed.js +2 -2
- package/dist/atlas/physjs-reviewed.js.map +1 -1
- package/dist/cases/catalog-checks.d.ts +10 -0
- package/dist/cases/catalog-checks.d.ts.map +1 -0
- package/dist/cases/catalog-checks.js +241 -0
- package/dist/cases/catalog-checks.js.map +1 -0
- package/dist/cases/catalog.d.ts +83 -0
- package/dist/cases/catalog.d.ts.map +1 -0
- package/dist/cases/catalog.js +118 -0
- package/dist/cases/catalog.js.map +1 -0
- package/dist/cases/engine.d.ts +13 -0
- package/dist/cases/engine.d.ts.map +1 -0
- package/dist/cases/engine.js +179 -0
- package/dist/cases/engine.js.map +1 -0
- package/dist/cases/index.d.ts.map +1 -1
- package/dist/cases/index.js +5 -7
- package/dist/cases/index.js.map +1 -1
- package/dist/cases/methods.d.ts +215 -0
- package/dist/cases/methods.d.ts.map +1 -0
- package/dist/cases/methods.js +743 -0
- package/dist/cases/methods.js.map +1 -0
- package/dist/cases/types.d.ts +12 -0
- package/dist/cases/types.d.ts.map +1 -1
- package/dist/cases/types.js.map +1 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/command.d.ts +3 -0
- package/dist/cli/command.d.ts.map +1 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/commands/_discovery-opts.d.ts +1 -0
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +1 -0
- package/dist/cli/commands/_discovery-opts.js.map +1 -1
- package/dist/cli/commands/discover.d.ts.map +1 -1
- package/dist/cli/commands/discover.js +116 -71
- package/dist/cli/commands/discover.js.map +1 -1
- package/dist/cli/commands/evaluate.js +2 -2
- package/dist/cli/commands/evaluate.js.map +1 -1
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/explain.js +22 -2
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/ground.d.ts.map +1 -1
- package/dist/cli/commands/ground.js +6 -1
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +9 -6
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/determination.d.ts +1 -0
- package/dist/cli/determination.d.ts.map +1 -1
- package/dist/cli/determination.js.map +1 -1
- package/dist/cli/flag-help.d.ts +1 -0
- package/dist/cli/flag-help.d.ts.map +1 -1
- package/dist/cli/flag-help.js +1 -0
- package/dist/cli/flag-help.js.map +1 -1
- package/dist/cli/graphs.d.ts +2 -0
- package/dist/cli/graphs.d.ts.map +1 -1
- package/dist/cli/graphs.js +1 -0
- package/dist/cli/graphs.js.map +1 -1
- package/dist/cli/main.d.ts +1 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +1 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output.d.ts +8 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +8 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/statuses.d.ts.map +1 -1
- package/dist/cli/statuses.js +12 -2
- package/dist/cli/statuses.js.map +1 -1
- package/dist/cli/version.d.ts +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +1 -0
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +2 -0
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +2 -0
- package/dist/cli-api.js.map +1 -1
- package/dist/composition/canonical-graph.d.ts +2 -2
- package/dist/composition/canonical-graph.js +2 -2
- package/dist/composition/canonical-graph.js.map +1 -1
- package/dist/composition/consequence.d.ts +15 -5
- package/dist/composition/consequence.d.ts.map +1 -1
- package/dist/composition/consequence.js +6 -4
- package/dist/composition/consequence.js.map +1 -1
- package/dist/composition/discovery.d.ts +78 -14
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +73 -23
- package/dist/composition/discovery.js.map +1 -1
- package/dist/composition/expr-eval.d.ts +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +4 -4
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +10 -14
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +49 -52
- package/dist/composition/expr-simplify.js.map +1 -1
- package/dist/composition/grounding.d.ts.map +1 -1
- package/dist/composition/grounding.js +19 -7
- package/dist/composition/grounding.js.map +1 -1
- package/dist/composition/mathts-quiet.d.ts +4 -6
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +4 -14
- package/dist/composition/mathts-quiet.js.map +1 -1
- package/dist/composition/own-equation-magnitude.d.ts +95 -0
- package/dist/composition/own-equation-magnitude.d.ts.map +1 -0
- package/dist/composition/own-equation-magnitude.js +270 -0
- package/dist/composition/own-equation-magnitude.js.map +1 -0
- package/dist/composition/probe/backend-protocol.d.ts +3 -0
- package/dist/composition/probe/backend-protocol.d.ts.map +1 -1
- package/dist/composition/probe/backend-protocol.js.map +1 -1
- package/dist/composition/probe/candidate-store.d.ts +1 -0
- package/dist/composition/probe/candidate-store.d.ts.map +1 -1
- package/dist/composition/probe/candidate-store.js +1 -0
- package/dist/composition/probe/candidate-store.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +4 -2
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +3 -3
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +1 -0
- package/dist/composition/probe/dataset.d.ts.map +1 -1
- package/dist/composition/probe/dataset.js.map +1 -1
- package/dist/composition/probe/experiment-design.d.ts +2 -0
- package/dist/composition/probe/experiment-design.d.ts.map +1 -1
- package/dist/composition/probe/experiment-design.js.map +1 -1
- package/dist/composition/probe/falsify.d.ts +2 -0
- package/dist/composition/probe/falsify.d.ts.map +1 -1
- package/dist/composition/probe/falsify.js.map +1 -1
- package/dist/composition/probe/fit.d.ts +1 -0
- package/dist/composition/probe/fit.d.ts.map +1 -1
- package/dist/composition/probe/fit.js.map +1 -1
- package/dist/composition/probe/generator.d.ts +3 -0
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +5 -6
- package/dist/composition/probe/generator.js.map +1 -1
- package/dist/composition/probe/limits.d.ts +1 -0
- package/dist/composition/probe/limits.d.ts.map +1 -1
- package/dist/composition/probe/limits.js.map +1 -1
- package/dist/composition/probe/pipeline.d.ts +5 -0
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +64 -21
- package/dist/composition/probe/pipeline.js.map +1 -1
- package/dist/composition/probe/power-law.d.ts.map +1 -1
- package/dist/composition/probe/power-law.js +3 -7
- package/dist/composition/probe/power-law.js.map +1 -1
- package/dist/composition/probe/problem.d.ts +1 -0
- package/dist/composition/probe/problem.d.ts.map +1 -1
- package/dist/composition/probe/problem.js.map +1 -1
- package/dist/composition/probe/residual.d.ts +1 -0
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +1 -0
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/run-manifest.d.ts +1 -0
- package/dist/composition/probe/run-manifest.d.ts.map +1 -1
- package/dist/composition/probe/run-manifest.js.map +1 -1
- package/dist/composition/probe/scalar-search.d.ts +50 -0
- package/dist/composition/probe/scalar-search.d.ts.map +1 -0
- package/dist/composition/probe/scalar-search.js +169 -0
- package/dist/composition/probe/scalar-search.js.map +1 -0
- package/dist/composition/probe/scoring.d.ts +1 -0
- package/dist/composition/probe/scoring.d.ts.map +1 -1
- package/dist/composition/probe/scoring.js.map +1 -1
- package/dist/composition/probe/study.d.ts +2 -2
- package/dist/composition/probe/study.d.ts.map +1 -1
- package/dist/composition/probe/study.js +6 -10
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +3 -4
- package/dist/composition/probe/t-tail.d.ts.map +1 -1
- package/dist/composition/probe/t-tail.js +7 -10
- package/dist/composition/probe/t-tail.js.map +1 -1
- package/dist/composition/proposed-bridges.d.ts +11 -2
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +7 -5
- package/dist/composition/proposed-bridges.js.map +1 -1
- package/dist/composition/rational-exponent.d.ts +2 -2
- package/dist/composition/rational-exponent.d.ts.map +1 -1
- package/dist/composition/rational-exponent.js +4 -4
- package/dist/composition/rational-exponent.js.map +1 -1
- package/dist/composition/representative-values.d.ts.map +1 -1
- package/dist/composition/representative-values.js +6 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts +15 -0
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +10 -3
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts +1 -0
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +1 -0
- package/dist/composition/user-equation.js.map +1 -1
- package/dist/core/constants.d.ts +12 -11
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +24 -21
- package/dist/core/constants.js.map +1 -1
- package/dist/diff/bridge-ast-gradient.d.ts +27 -23
- package/dist/diff/bridge-ast-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-ast-gradient.js +75 -173
- package/dist/diff/bridge-ast-gradient.js.map +1 -1
- package/dist/dimensional/ast-types.d.ts +15 -0
- package/dist/dimensional/ast-types.d.ts.map +1 -1
- package/dist/dimensional/ast-types.js.map +1 -1
- package/dist/dimensional/curvature-composite.d.ts +1 -1
- package/dist/dimensional/curvature-composite.js.map +1 -1
- package/dist/dimensional/exact-scale.d.ts +41 -11
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +115 -123
- package/dist/dimensional/exact-scale.js.map +1 -1
- package/dist/dimensional/mathts-unit-delegation.d.ts +29 -0
- package/dist/dimensional/mathts-unit-delegation.d.ts.map +1 -0
- package/dist/dimensional/mathts-unit-delegation.js +187 -0
- package/dist/dimensional/mathts-unit-delegation.js.map +1 -0
- package/dist/dimensional/mathts-unit-wrapper.d.ts +33 -0
- package/dist/dimensional/mathts-unit-wrapper.d.ts.map +1 -0
- package/dist/dimensional/mathts-unit-wrapper.js +190 -0
- package/dist/dimensional/mathts-unit-wrapper.js.map +1 -0
- package/dist/dimensional/scalar-lowering.d.ts +21 -0
- package/dist/dimensional/scalar-lowering.d.ts.map +1 -0
- package/dist/dimensional/scalar-lowering.js +45 -0
- package/dist/dimensional/scalar-lowering.js.map +1 -0
- package/dist/dimensional/unit-data.d.ts +5 -1
- package/dist/dimensional/unit-data.d.ts.map +1 -1
- package/dist/dimensional/unit-data.js +28 -4
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/dimensional/units.d.ts +2 -0
- package/dist/dimensional/units.d.ts.map +1 -1
- package/dist/dimensional/units.js +59 -3
- package/dist/dimensional/units.js.map +1 -1
- package/dist/dimensional/validator.d.ts +2 -0
- package/dist/dimensional/validator.d.ts.map +1 -1
- package/dist/dimensional/validator.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/numerical/connection-lowering-helpers.d.ts +3 -1
- package/dist/numerical/connection-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/connection-lowering-helpers.js +11 -15
- package/dist/numerical/connection-lowering-helpers.js.map +1 -1
- package/dist/numerical/pderiv.d.ts.map +1 -1
- package/dist/numerical/pderiv.js +2 -6
- package/dist/numerical/pderiv.js.map +1 -1
- package/dist/numerical/quadrature.js +3 -3
- package/dist/numerical/quadrature.js.map +1 -1
- package/dist/numerical/statistics.js +1 -1
- package/dist/numerical/statistics.js.map +1 -1
- package/dist/numerical/strides.d.ts +3 -2
- package/dist/numerical/strides.d.ts.map +1 -1
- package/dist/numerical/strides.js +3 -10
- package/dist/numerical/strides.js.map +1 -1
- package/package.json +9 -12
- package/dist/cases/brownian-sphere.d.ts +0 -68
- package/dist/cases/brownian-sphere.d.ts.map +0 -1
- package/dist/cases/brownian-sphere.js +0 -355
- package/dist/cases/brownian-sphere.js.map +0 -1
- package/dist/cases/damped-resonator.d.ts +0 -23
- package/dist/cases/damped-resonator.d.ts.map +0 -1
- package/dist/cases/damped-resonator.js +0 -221
- package/dist/cases/damped-resonator.js.map +0 -1
- package/dist/cases/kepler-rv.d.ts +0 -13
- package/dist/cases/kepler-rv.d.ts.map +0 -1
- package/dist/cases/kepler-rv.js +0 -173
- package/dist/cases/kepler-rv.js.map +0 -1
- package/dist/cases/lumped-cooling.d.ts +0 -51
- package/dist/cases/lumped-cooling.d.ts.map +0 -1
- package/dist/cases/lumped-cooling.js +0 -259
- package/dist/cases/lumped-cooling.js.map +0 -1
- package/dist/cases/resistor-noise.d.ts +0 -14
- package/dist/cases/resistor-noise.d.ts.map +0 -1
- package/dist/cases/resistor-noise.js +0 -215
- package/dist/cases/resistor-noise.js.map +0 -1
- package/dist/cases/skin-depth.d.ts +0 -17
- package/dist/cases/skin-depth.d.ts.map +0 -1
- package/dist/cases/skin-depth.js +0 -170
- package/dist/cases/skin-depth.js.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ExactScale } from './exact-scale.js';
|
|
2
|
+
import type { Dimension } from './types.js';
|
|
3
|
+
/** Every factor base in `text` is admitted in UPT and present in MathTS. */
|
|
4
|
+
export declare function everySymbolInBothTables(text: string): boolean;
|
|
5
|
+
/** True when `Unit.exactScale` matches the local scale and `bit` is excluded. */
|
|
6
|
+
export declare function mathtsExactScaleAgreed(text: string, localScale: number, _localExact: ExactScale): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The sub-kilo parsec spellings, UPT's by policy: MathTS 0.21.0 admits only the
|
|
9
|
+
* k-and-up prefixes on `pc` (its row is `SHORT_UP_ONLY`), while UPT's prefix table
|
|
10
|
+
* applies to every prefixable row in `data/units.json`. Those readings stay local.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isSubKiloParsec(text: string): boolean;
|
|
13
|
+
/** True when the full unit text may take exact scale and dimension from MathTS (A4). */
|
|
14
|
+
export declare function unitExactScaleViaMathts(text: string, localScale: number, localExact: ExactScale, localDim: Dimension): boolean;
|
|
15
|
+
/** True when `Unit.parse` may replace the local grammar for `text` (A5). */
|
|
16
|
+
export declare function unitParserViaMathts(text: string, localScale: number, localExact: ExactScale, localDim: Dimension): boolean;
|
|
17
|
+
/** Map MathTS unit dimensions to the UPT seven-base record. */
|
|
18
|
+
export declare function mathtsParsedDimension(text: string, localDim: Dimension): Dimension;
|
|
19
|
+
/**
|
|
20
|
+
* Raise a dimension to an integer power (test-only).
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export declare function _powerDim(dim: Dimension, exp: number): Dimension;
|
|
24
|
+
/**
|
|
25
|
+
* Multiply two dimensions (test-only).
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare function _multiplyDim(a: Dimension, b: Dimension): Dimension;
|
|
29
|
+
//# sourceMappingURL=mathts-unit-delegation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mathts-unit-delegation.d.ts","sourceRoot":"","sources":["../../src/dimensional/mathts-unit-delegation.ts"],"names":[],"mappings":"AAiBA,OAAO,EAA+B,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAuC5C,4EAA4E;AAC5E,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgB7D;AAaD,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,GAAG,OAAO,CAIzG;AA+BD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED,wFAAwF;AACxF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAU9H;AAGD,4EAA4E;AAC5E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,SAAS,GAClB,OAAO,CAST;AAED,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS,CAGlF;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAEhE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,SAAS,CAElE"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MathTS unit delegation predicates (Part A steps A4–A5).
|
|
3
|
+
*
|
|
4
|
+
* A text enters the MathTS path only when the predicate is true up front; a
|
|
5
|
+
* MathTS failure is not caught and routed back to the local reader.
|
|
6
|
+
*
|
|
7
|
+
* @module dimensional/mathts-unit-delegation
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
import { Unit, exactScaleToNumber, getUnitRow, toSiDimensionVector, } from '@danielsimonjr/mathts-core';
|
|
11
|
+
import { symmetricRelDiff } from '../core/compare.js';
|
|
12
|
+
import { equals, multiply, power } from './algebra.js';
|
|
13
|
+
import { scaleToNumber, solidusSides } from './exact-scale.js';
|
|
14
|
+
import { UNIT_DATA } from './unit-data.js';
|
|
15
|
+
const DIMENSIONLESS = { L: 0, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 };
|
|
16
|
+
const UNITS = UNIT_DATA.units;
|
|
17
|
+
const PREFIXES = UNIT_DATA.prefixes;
|
|
18
|
+
const REFUSED = UNIT_DATA.refused;
|
|
19
|
+
const SUPERSCRIPT = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };
|
|
20
|
+
function trySymbol(sym) {
|
|
21
|
+
if (UNITS.has(sym))
|
|
22
|
+
return { base: sym };
|
|
23
|
+
for (const [prefix] of PREFIXES) {
|
|
24
|
+
if (!sym.startsWith(prefix) || sym.length === prefix.length)
|
|
25
|
+
continue;
|
|
26
|
+
const base = sym.slice(prefix.length);
|
|
27
|
+
const row = UNITS.get(base);
|
|
28
|
+
if (row !== undefined && row.prefixable)
|
|
29
|
+
return { base };
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
function tryOneFactorBase(token) {
|
|
34
|
+
let base = token;
|
|
35
|
+
const caret = /^(.+)\^([+-]?\d+)$/.exec(token);
|
|
36
|
+
if (caret !== null)
|
|
37
|
+
base = caret[1];
|
|
38
|
+
else {
|
|
39
|
+
const uni = /^(.*?)(⁻?[¹²³])$/.exec(token);
|
|
40
|
+
if (uni !== null && SUPERSCRIPT[uni[2]] !== undefined && uni[1].length > 0)
|
|
41
|
+
base = uni[1];
|
|
42
|
+
else {
|
|
43
|
+
const glued = /^(.*?)([1-9]\d*)$/.exec(token);
|
|
44
|
+
if (glued !== null && glued[1].length > 0 && trySymbol(glued[1]) !== null)
|
|
45
|
+
base = glued[1];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return trySymbol(base)?.base ?? null;
|
|
49
|
+
}
|
|
50
|
+
function sideTokens(text) {
|
|
51
|
+
return text.split(/[*·\s]+|(?<=[A-Za-zµμΩ])\.(?=[A-Za-zµμΩ])/).filter((part) => part.length > 0);
|
|
52
|
+
}
|
|
53
|
+
/** Every factor base in `text` is admitted in UPT and present in MathTS. */
|
|
54
|
+
export function everySymbolInBothTables(text) {
|
|
55
|
+
const t = text.trim();
|
|
56
|
+
if (t === '' || t === '1')
|
|
57
|
+
return true;
|
|
58
|
+
if (REFUSED.has(t))
|
|
59
|
+
return false;
|
|
60
|
+
if (UNIT_DATA.affine.some((row) => row.symbols.includes(t)))
|
|
61
|
+
return getUnitRow(t) !== undefined;
|
|
62
|
+
const { numerator, denominator } = solidusSides(t);
|
|
63
|
+
const tokens = [...sideTokens(numerator), ...sideTokens(denominator)];
|
|
64
|
+
if (tokens.length === 0)
|
|
65
|
+
return false;
|
|
66
|
+
for (const token of tokens) {
|
|
67
|
+
if (token === '1')
|
|
68
|
+
continue;
|
|
69
|
+
const base = tryOneFactorBase(token);
|
|
70
|
+
if (base === null)
|
|
71
|
+
return false;
|
|
72
|
+
if (!UNITS.has(base))
|
|
73
|
+
return false;
|
|
74
|
+
if (getUnitRow(base) === undefined)
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
function mathtsScaleNumber(text) {
|
|
80
|
+
if (!everySymbolInBothTables(text))
|
|
81
|
+
return null;
|
|
82
|
+
if (text.trim() === 'bit')
|
|
83
|
+
return null;
|
|
84
|
+
try {
|
|
85
|
+
const core = Unit.exactScale(text.trim());
|
|
86
|
+
return core === null ? null : exactScaleToNumber(core);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** True when `Unit.exactScale` matches the local scale and `bit` is excluded. */
|
|
93
|
+
export function mathtsExactScaleAgreed(text, localScale, _localExact) {
|
|
94
|
+
if (text.trim() === 'bit')
|
|
95
|
+
return false;
|
|
96
|
+
const mt = mathtsScaleNumber(text);
|
|
97
|
+
return mt !== null && (mt === localScale || symmetricRelDiff(localScale, mt) < 1e-15);
|
|
98
|
+
}
|
|
99
|
+
function siNumber(entry) {
|
|
100
|
+
return typeof entry === 'number' ? entry : entry.toNumber();
|
|
101
|
+
}
|
|
102
|
+
function dimensionFromMathtsVector(dimensions, localDim) {
|
|
103
|
+
try {
|
|
104
|
+
const v = toSiDimensionVector(dimensions);
|
|
105
|
+
return { L: siNumber(v[0]), M: siNumber(v[1]), T: siNumber(v[2]), I: siNumber(v[3]), Theta: siNumber(v[4]), N: siNumber(v[5]), J: siNumber(v[6]) };
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
const ignored = toSiDimensionVector(dimensions, { ignoreExtra: true });
|
|
109
|
+
if (equals(localDim, DIMENSIONLESS)) {
|
|
110
|
+
return DIMENSIONLESS;
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
L: siNumber(ignored[0]),
|
|
114
|
+
M: siNumber(ignored[1]),
|
|
115
|
+
T: siNumber(ignored[2]),
|
|
116
|
+
I: siNumber(ignored[3]),
|
|
117
|
+
Theta: siNumber(ignored[4]),
|
|
118
|
+
N: siNumber(ignored[5]),
|
|
119
|
+
J: siNumber(ignored[6]),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The sub-kilo parsec spellings, UPT's by policy: MathTS 0.21.0 admits only the
|
|
125
|
+
* k-and-up prefixes on `pc` (its row is `SHORT_UP_ONLY`), while UPT's prefix table
|
|
126
|
+
* applies to every prefixable row in `data/units.json`. Those readings stay local.
|
|
127
|
+
*/
|
|
128
|
+
export function isSubKiloParsec(text) {
|
|
129
|
+
const t = text.trim();
|
|
130
|
+
if (!t.endsWith('pc'))
|
|
131
|
+
return false;
|
|
132
|
+
const prefix = t.slice(0, -2);
|
|
133
|
+
if (prefix === '')
|
|
134
|
+
return false;
|
|
135
|
+
const base = UNITS.get('pc');
|
|
136
|
+
const factor = PREFIXES.get(prefix);
|
|
137
|
+
return base !== undefined && base.prefixable && factor !== undefined && scaleToNumber(factor) < 1000;
|
|
138
|
+
}
|
|
139
|
+
/** True when the full unit text may take exact scale and dimension from MathTS (A4). */
|
|
140
|
+
export function unitExactScaleViaMathts(text, localScale, localExact, localDim) {
|
|
141
|
+
if (isSubKiloParsec(text))
|
|
142
|
+
return false;
|
|
143
|
+
if (!mathtsExactScaleAgreed(text, localScale, localExact))
|
|
144
|
+
return false;
|
|
145
|
+
try {
|
|
146
|
+
const u = Unit.parse(text.trim());
|
|
147
|
+
const dim = dimensionFromMathtsVector(u.dimensions, localDim);
|
|
148
|
+
return equals(dim, localDim);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** True when `Unit.parse` may replace the local grammar for `text` (A5). */
|
|
155
|
+
export function unitParserViaMathts(text, localScale, localExact, localDim) {
|
|
156
|
+
if (isSubKiloParsec(text))
|
|
157
|
+
return false;
|
|
158
|
+
if (!unitExactScaleViaMathts(text, localScale, localExact, localDim))
|
|
159
|
+
return false;
|
|
160
|
+
try {
|
|
161
|
+
Unit.parse(text.trim());
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
/** Map MathTS unit dimensions to the UPT seven-base record. */
|
|
169
|
+
export function mathtsParsedDimension(text, localDim) {
|
|
170
|
+
const u = Unit.parse(text.trim());
|
|
171
|
+
return dimensionFromMathtsVector(u.dimensions, localDim);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Raise a dimension to an integer power (test-only).
|
|
175
|
+
* @internal
|
|
176
|
+
*/
|
|
177
|
+
export function _powerDim(dim, exp) {
|
|
178
|
+
return power(dim, exp);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Multiply two dimensions (test-only).
|
|
182
|
+
* @internal
|
|
183
|
+
*/
|
|
184
|
+
export function _multiplyDim(a, b) {
|
|
185
|
+
return multiply(a, b);
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=mathts-unit-delegation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mathts-unit-delegation.js","sourceRoot":"","sources":["../../src/dimensional/mathts-unit-delegation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MathTS unit delegation predicates (Part A steps A4–A5).\n *\n * A text enters the MathTS path only when the predicate is true up front; a\n * MathTS failure is not caught and routed back to the local reader.\n *\n * @module dimensional/mathts-unit-delegation\n * @internal\n */\nimport {\n Unit,\n exactScaleToNumber,\n getUnitRow,\n toSiDimensionVector,\n} from '@danielsimonjr/mathts-core';\nimport { symmetricRelDiff } from '../core/compare.js';\nimport { equals, multiply, power } from './algebra.js';\nimport { scaleToNumber, solidusSides, type ExactScale } from './exact-scale.js';\nimport { UNIT_DATA } from './unit-data.js';\nimport type { Dimension } from './types.js';\n\nconst DIMENSIONLESS: Dimension = { L: 0, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 };\nconst UNITS = UNIT_DATA.units;\nconst PREFIXES = UNIT_DATA.prefixes;\nconst REFUSED = UNIT_DATA.refused;\n\nconst SUPERSCRIPT: Readonly<Record<string, number>> = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };\n\nfunction trySymbol(sym: string): { readonly base: string } | null {\n if (UNITS.has(sym)) return { base: sym };\n for (const [prefix] of PREFIXES) {\n if (!sym.startsWith(prefix) || sym.length === prefix.length) continue;\n const base = sym.slice(prefix.length);\n const row = UNITS.get(base);\n if (row !== undefined && row.prefixable) return { base };\n }\n return null;\n}\n\nfunction tryOneFactorBase(token: string): string | null {\n let base = token;\n const caret = /^(.+)\\^([+-]?\\d+)$/.exec(token);\n if (caret !== null) base = caret[1]!;\n else {\n const uni = /^(.*?)(⁻?[¹²³])$/.exec(token);\n if (uni !== null && SUPERSCRIPT[uni[2]!] !== undefined && uni[1]!.length > 0) base = uni[1]!;\n else {\n const glued = /^(.*?)([1-9]\\d*)$/.exec(token);\n if (glued !== null && glued[1]!.length > 0 && trySymbol(glued[1]!) !== null) base = glued[1]!;\n }\n }\n return trySymbol(base)?.base ?? null;\n}\n\nfunction sideTokens(text: string): string[] {\n return text.split(/[*·\\s]+|(?<=[A-Za-zµμΩ])\\.(?=[A-Za-zµμΩ])/).filter((part) => part.length > 0);\n}\n\n/** Every factor base in `text` is admitted in UPT and present in MathTS. */\nexport function everySymbolInBothTables(text: string): boolean {\n const t = text.trim();\n if (t === '' || t === '1') return true;\n if (REFUSED.has(t)) return false;\n if (UNIT_DATA.affine.some((row) => row.symbols.includes(t))) return getUnitRow(t) !== undefined;\n const { numerator, denominator } = solidusSides(t);\n const tokens = [...sideTokens(numerator), ...sideTokens(denominator)];\n if (tokens.length === 0) return false;\n for (const token of tokens) {\n if (token === '1') continue;\n const base = tryOneFactorBase(token);\n if (base === null) return false;\n if (!UNITS.has(base)) return false;\n if (getUnitRow(base) === undefined) return false;\n }\n return true;\n}\n\nfunction mathtsScaleNumber(text: string): number | null {\n if (!everySymbolInBothTables(text)) return null;\n if (text.trim() === 'bit') return null;\n try {\n const core = Unit.exactScale(text.trim());\n return core === null ? null : exactScaleToNumber(core);\n } catch {\n return null;\n }\n}\n\n/** True when `Unit.exactScale` matches the local scale and `bit` is excluded. */\nexport function mathtsExactScaleAgreed(text: string, localScale: number, _localExact: ExactScale): boolean {\n if (text.trim() === 'bit') return false;\n const mt = mathtsScaleNumber(text);\n return mt !== null && (mt === localScale || symmetricRelDiff(localScale, mt) < 1e-15);\n}\n\n\n/** A MathTS SI-dimension entry: 0.20.0 states exact rational exponents, so a number or a `Fraction`. */\ntype SiEntry = number | { readonly toNumber: () => number };\n\nfunction siNumber(entry: SiEntry): number {\n return typeof entry === 'number' ? entry : entry.toNumber();\n}\n\nfunction dimensionFromMathtsVector(dimensions: readonly number[], localDim: Dimension): Dimension {\n try {\n const v = toSiDimensionVector(dimensions);\n return { L: siNumber(v[0]!), M: siNumber(v[1]!), T: siNumber(v[2]!), I: siNumber(v[3]!), Theta: siNumber(v[4]!), N: siNumber(v[5]!), J: siNumber(v[6]!) };\n } catch {\n const ignored = toSiDimensionVector(dimensions, { ignoreExtra: true });\n if (equals(localDim, DIMENSIONLESS)) {\n return DIMENSIONLESS;\n }\n return {\n L: siNumber(ignored[0]!),\n M: siNumber(ignored[1]!),\n T: siNumber(ignored[2]!),\n I: siNumber(ignored[3]!),\n Theta: siNumber(ignored[4]!),\n N: siNumber(ignored[5]!),\n J: siNumber(ignored[6]!),\n };\n }\n}\n\n/**\n * The sub-kilo parsec spellings, UPT's by policy: MathTS 0.21.0 admits only the\n * k-and-up prefixes on `pc` (its row is `SHORT_UP_ONLY`), while UPT's prefix table\n * applies to every prefixable row in `data/units.json`. Those readings stay local.\n */\nexport function isSubKiloParsec(text: string): boolean {\n const t = text.trim();\n if (!t.endsWith('pc')) return false;\n const prefix = t.slice(0, -2);\n if (prefix === '') return false;\n const base = UNITS.get('pc');\n const factor = PREFIXES.get(prefix);\n return base !== undefined && base.prefixable && factor !== undefined && scaleToNumber(factor) < 1000;\n}\n\n/** True when the full unit text may take exact scale and dimension from MathTS (A4). */\nexport function unitExactScaleViaMathts(text: string, localScale: number, localExact: ExactScale, localDim: Dimension): boolean {\n if (isSubKiloParsec(text)) return false;\n if (!mathtsExactScaleAgreed(text, localScale, localExact)) return false;\n try {\n const u = Unit.parse(text.trim());\n const dim = dimensionFromMathtsVector(u.dimensions, localDim);\n return equals(dim, localDim);\n } catch {\n return false;\n }\n}\n\n\n/** True when `Unit.parse` may replace the local grammar for `text` (A5). */\nexport function unitParserViaMathts(\n text: string,\n localScale: number,\n localExact: ExactScale,\n localDim: Dimension,\n): boolean {\n if (isSubKiloParsec(text)) return false;\n if (!unitExactScaleViaMathts(text, localScale, localExact, localDim)) return false;\n try {\n Unit.parse(text.trim());\n } catch {\n return false;\n }\n return true;\n}\n\n/** Map MathTS unit dimensions to the UPT seven-base record. */\nexport function mathtsParsedDimension(text: string, localDim: Dimension): Dimension {\n const u = Unit.parse(text.trim());\n return dimensionFromMathtsVector(u.dimensions, localDim);\n}\n\n/**\n * Raise a dimension to an integer power (test-only).\n * @internal\n */\nexport function _powerDim(dim: Dimension, exp: number): Dimension {\n return power(dim, exp);\n}\n\n/**\n * Multiply two dimensions (test-only).\n * @internal\n */\nexport function _multiplyDim(a: Dimension, b: Dimension): Dimension {\n return multiply(a, b);\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ExactScale } from './exact-scale.js';
|
|
2
|
+
import type { Dimension } from './types.js';
|
|
3
|
+
/** Agreed spellings that fully parse through MathTS (Part A step A5). The 0.21.0
|
|
4
|
+
* core adds the day symbol, the angstrom spellings, and SI prefixes on `psi` and
|
|
5
|
+
* `torr`; the k-and-up parsec spellings agree with the table double for double.
|
|
6
|
+
* The 0.22.0 core adds the glued products `m2K`, `Vs`, `cm^2/Vs` and `W/m2K`. */
|
|
7
|
+
export declare const A5_DELEGATED_TEXTS: readonly ['km', 'degC', 'g/cm^3', 'mN/m', 'kohm', 'GeV', 'km/s/Mpc', 'd', 'day', 'Angstrom', 'angstrom', 'Å', 'psi', 'torr', 'kpsi', 'Mpsi', 'mtorr', 'utorr', 'kpc', 'Mpc', 'Gpc', 'm2K', 'Vs', 'cm^2/Vs', 'W/m2K'];
|
|
8
|
+
/** Tokens whose spelling carries a refusal reason: UPT policy rows first, then MathTS's registry. */
|
|
9
|
+
export declare function refusedTokensIn(text: string): readonly string[];
|
|
10
|
+
/** Refusal message: UPT policy (`ton`) first, then the MathTS registry (`dB` and friends). Null when the text is not denied. */
|
|
11
|
+
export declare function uptRefusalReason(text: string): string | null;
|
|
12
|
+
/** Whether `text` is on the Part A step A5 delegated spelling list. */
|
|
13
|
+
export declare function isA5DelegatedText(text: string): boolean;
|
|
14
|
+
/** Whether MathTS `Unit.parse` accepts `text`. */
|
|
15
|
+
export declare function mathtsWouldParse(text: string): boolean;
|
|
16
|
+
/** Keep `bit` at ln 2 nat on the 7-vector (A11a). */
|
|
17
|
+
export declare function applyBitScaleOverride(text: string, exact: ExactScale, scale: number): {
|
|
18
|
+
readonly exact: ExactScale;
|
|
19
|
+
readonly scale: number;
|
|
20
|
+
};
|
|
21
|
+
/** Scale, dimension, and cycles for one A5 in-set text read through MathTS. */
|
|
22
|
+
export interface MathtsDelegatedReading {
|
|
23
|
+
readonly exact: ExactScale;
|
|
24
|
+
readonly scale: number;
|
|
25
|
+
readonly dim: Dimension;
|
|
26
|
+
readonly cycles: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Scale and dimension for an A5 in-set text through MathTS only (A12 partial).
|
|
30
|
+
* Returns null when the text is not on the A5 list or MathTS rejects it.
|
|
31
|
+
*/
|
|
32
|
+
export declare function tryMathtsA5Reading(text: string): MathtsDelegatedReading | null;
|
|
33
|
+
//# sourceMappingURL=mathts-unit-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mathts-unit-wrapper.d.ts","sourceRoot":"","sources":["../../src/dimensional/mathts-unit-wrapper.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAsD,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGvG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C;;;iFAGiF;AACjF,eAAO,MAAM,kBAAkB,YAC7B,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,MAAM,EACN,MAAM,EACN,KAAK,EACL,UAAU,EACV,GAAG,EACH,KAAK,EACL,UAAU,EACV,UAAU,EACV,GAAG,EACH,KAAK,EACL,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,KAAK,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,SAAS,EACT,OAAO,CACC,CAAC;AAyCX,qGAAqG;AACrG,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAiB/D;AAED,gIAAgI;AAChI,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK5D;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED,qDAAqD;AACrD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAM5I;AAED,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAOD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAiB9E"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UPT unit wrapper policy on top of MathTS (Part A steps A8, A11, A12 partial).
|
|
3
|
+
*
|
|
4
|
+
* Admission, refusal policy, and cycle counting stay here even when parsing and
|
|
5
|
+
* scales delegate to MathTS. Four deliberate overrides of MathTS defaults are
|
|
6
|
+
* layered here, each pinned by a test that reads both sides:
|
|
7
|
+
*
|
|
8
|
+
* 1. `ton` and `tons` — MathTS names them ambiguous; UPT refuses them with its own
|
|
9
|
+
* message (`data/units.json`, `tests/dimensional/unit-wrapper-refusal.test.ts`).
|
|
10
|
+
* 2. An affine temperature inside a compound — MathTS refuses `degC/s` but parses the
|
|
11
|
+
* spaced `deg C/s`; UPT refuses both (`localUnitReadings`,
|
|
12
|
+
* `tests/dimensional/mathts-unit-gaps.test.ts`).
|
|
13
|
+
* 3. `pc` prefixes — MathTS admits only k and up (`SHORT_UP_ONLY`); UPT's
|
|
14
|
+
* prefix table applies to every prefixable row, so `mpc` stays on the local
|
|
15
|
+
* grammar (`isSubKiloParsec`, `tests/dimensional/unit-override-parsec.test.ts`).
|
|
16
|
+
* 4. `bit` — MathTS reports scale 1 on its bit axis; UPT keeps ln 2 nat
|
|
17
|
+
* (`applyBitScaleOverride`, `tests/dimensional/unit-wrapper-bit.test.ts`).
|
|
18
|
+
*
|
|
19
|
+
* The refusal *definitions* for `dB`, `dBm`, `dBW`, `Np`, `Mach` and `mach` are
|
|
20
|
+
* MathTS's `REFUSED_UNIT_SPELLINGS` (0.21.0); `data/units.json` no longer
|
|
21
|
+
* repeats them. The wrapper turns a MathTS refusal into `UnitRefusedError`
|
|
22
|
+
* before any parse, compounds included.
|
|
23
|
+
*
|
|
24
|
+
* @module dimensional/mathts-unit-wrapper
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
import { REFUSED_UNIT_SPELLINGS, Unit, exactScaleToNumber } from '@danielsimonjr/mathts-core';
|
|
28
|
+
import { scaleToNumber, solidusSides, uptExactScaleFromCore } from './exact-scale.js';
|
|
29
|
+
import { isSubKiloParsec, mathtsParsedDimension } from './mathts-unit-delegation.js';
|
|
30
|
+
import { UNIT_DATA } from './unit-data.js';
|
|
31
|
+
const DIMENSIONLESS = { L: 0, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 };
|
|
32
|
+
const REFUSED = UNIT_DATA.refused;
|
|
33
|
+
const UNITS = UNIT_DATA.units;
|
|
34
|
+
/** Agreed spellings that fully parse through MathTS (Part A step A5). The 0.21.0
|
|
35
|
+
* core adds the day symbol, the angstrom spellings, and SI prefixes on `psi` and
|
|
36
|
+
* `torr`; the k-and-up parsec spellings agree with the table double for double.
|
|
37
|
+
* The 0.22.0 core adds the glued products `m2K`, `Vs`, `cm^2/Vs` and `W/m2K`. */
|
|
38
|
+
export const A5_DELEGATED_TEXTS = [
|
|
39
|
+
'km',
|
|
40
|
+
'degC',
|
|
41
|
+
'g/cm^3',
|
|
42
|
+
'mN/m',
|
|
43
|
+
'kohm',
|
|
44
|
+
'GeV',
|
|
45
|
+
'km/s/Mpc',
|
|
46
|
+
'd',
|
|
47
|
+
'day',
|
|
48
|
+
'Angstrom',
|
|
49
|
+
'angstrom',
|
|
50
|
+
'Å',
|
|
51
|
+
'psi',
|
|
52
|
+
'torr',
|
|
53
|
+
'kpsi',
|
|
54
|
+
'Mpsi',
|
|
55
|
+
'mtorr',
|
|
56
|
+
'utorr',
|
|
57
|
+
'kpc',
|
|
58
|
+
'Mpc',
|
|
59
|
+
'Gpc',
|
|
60
|
+
'm2K',
|
|
61
|
+
'Vs',
|
|
62
|
+
'cm^2/Vs',
|
|
63
|
+
'W/m2K',
|
|
64
|
+
];
|
|
65
|
+
const A5_DELEGATED = new Set(A5_DELEGATED_TEXTS);
|
|
66
|
+
const SUPERSCRIPT = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };
|
|
67
|
+
function sideTokens(text) {
|
|
68
|
+
return text.split(/[*·\s]+|(?<=[A-Za-zµμΩ])\.(?=[A-Za-zµμΩ])/).filter((part) => part.length > 0);
|
|
69
|
+
}
|
|
70
|
+
function trySymbolBase(token) {
|
|
71
|
+
if (UNITS.has(token))
|
|
72
|
+
return token;
|
|
73
|
+
for (const [prefix] of UNIT_DATA.prefixes) {
|
|
74
|
+
if (!token.startsWith(prefix) || token.length === prefix.length)
|
|
75
|
+
continue;
|
|
76
|
+
const base = token.slice(prefix.length);
|
|
77
|
+
const row = UNITS.get(base);
|
|
78
|
+
if (row !== undefined && row.prefixable)
|
|
79
|
+
return base;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function factorBase(token) {
|
|
84
|
+
let base = token;
|
|
85
|
+
const caret = /^(.+)\^([+-]?\d+)$/.exec(token);
|
|
86
|
+
if (caret !== null)
|
|
87
|
+
base = caret[1];
|
|
88
|
+
else {
|
|
89
|
+
const uni = /^(.*?)(⁻?[¹²³])$/.exec(token);
|
|
90
|
+
if (uni !== null && SUPERSCRIPT[uni[2]] !== undefined && uni[1].length > 0)
|
|
91
|
+
base = uni[1];
|
|
92
|
+
else {
|
|
93
|
+
const glued = /^(.*?)([1-9]\d*)$/.exec(token);
|
|
94
|
+
if (glued !== null && glued[1].length > 0 && trySymbolBase(glued[1]) !== null)
|
|
95
|
+
base = glued[1];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return trySymbolBase(base);
|
|
99
|
+
}
|
|
100
|
+
/** A token MathTS refuses by name: UPT policy rows first, then the MathTS registry. */
|
|
101
|
+
function refusalReasonFor(token) {
|
|
102
|
+
return REFUSED.get(token) ?? REFUSED_UNIT_SPELLINGS[token];
|
|
103
|
+
}
|
|
104
|
+
/** Tokens whose spelling carries a refusal reason: UPT policy rows first, then MathTS's registry. */
|
|
105
|
+
export function refusedTokensIn(text) {
|
|
106
|
+
const t = text.trim();
|
|
107
|
+
if (t === '' || t === '1')
|
|
108
|
+
return [];
|
|
109
|
+
const whole = refusalReasonFor(t);
|
|
110
|
+
if (whole !== undefined)
|
|
111
|
+
return [t];
|
|
112
|
+
const { numerator, denominator } = solidusSides(t);
|
|
113
|
+
const tokens = [...sideTokens(numerator), ...sideTokens(denominator)];
|
|
114
|
+
const hits = [];
|
|
115
|
+
for (const token of tokens) {
|
|
116
|
+
if (token === '1')
|
|
117
|
+
continue;
|
|
118
|
+
if (refusalReasonFor(token) !== undefined)
|
|
119
|
+
hits.push(token);
|
|
120
|
+
else {
|
|
121
|
+
const base = factorBase(token);
|
|
122
|
+
if (base !== null && refusalReasonFor(base) !== undefined)
|
|
123
|
+
hits.push(base);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return hits;
|
|
127
|
+
}
|
|
128
|
+
/** Refusal message: UPT policy (`ton`) first, then the MathTS registry (`dB` and friends). Null when the text is not denied. */
|
|
129
|
+
export function uptRefusalReason(text) {
|
|
130
|
+
const hits = refusedTokensIn(text);
|
|
131
|
+
if (hits.length === 0)
|
|
132
|
+
return null;
|
|
133
|
+
const token = hits[0];
|
|
134
|
+
return refusalReasonFor(token) ?? null;
|
|
135
|
+
}
|
|
136
|
+
/** Whether `text` is on the Part A step A5 delegated spelling list. */
|
|
137
|
+
export function isA5DelegatedText(text) {
|
|
138
|
+
return A5_DELEGATED.has(text.trim());
|
|
139
|
+
}
|
|
140
|
+
/** Whether MathTS `Unit.parse` accepts `text`. */
|
|
141
|
+
export function mathtsWouldParse(text) {
|
|
142
|
+
try {
|
|
143
|
+
Unit.parse(text.trim());
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** Keep `bit` at ln 2 nat on the 7-vector (A11a). */
|
|
151
|
+
export function applyBitScaleOverride(text, exact, scale) {
|
|
152
|
+
if (text.trim() !== 'bit')
|
|
153
|
+
return { exact, scale };
|
|
154
|
+
const row = UNITS.get('bit');
|
|
155
|
+
if (row === undefined)
|
|
156
|
+
return { exact, scale };
|
|
157
|
+
const localScale = scaleToNumber(row.scale);
|
|
158
|
+
return { exact: row.scale, scale: localScale };
|
|
159
|
+
}
|
|
160
|
+
function affineDim(text) {
|
|
161
|
+
const row = UNIT_DATA.affine.find((candidate) => candidate.symbols.includes(text));
|
|
162
|
+
return row === undefined ? null : { ...DIMENSIONLESS, Theta: 1 };
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Scale and dimension for an A5 in-set text through MathTS only (A12 partial).
|
|
166
|
+
* Returns null when the text is not on the A5 list or MathTS rejects it.
|
|
167
|
+
*/
|
|
168
|
+
export function tryMathtsA5Reading(text) {
|
|
169
|
+
const t = text.trim();
|
|
170
|
+
if (isSubKiloParsec(t))
|
|
171
|
+
return null;
|
|
172
|
+
if (!isA5DelegatedText(t))
|
|
173
|
+
return null;
|
|
174
|
+
const affineDimHint = affineDim(t);
|
|
175
|
+
try {
|
|
176
|
+
Unit.parse(t);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const core = Unit.exactScale(t);
|
|
182
|
+
if (core === null)
|
|
183
|
+
return null;
|
|
184
|
+
const scale = exactScaleToNumber(core);
|
|
185
|
+
const dim = mathtsParsedDimension(t, affineDimHint ?? DIMENSIONLESS);
|
|
186
|
+
const exact = UNITS.get(t)?.scale ?? uptExactScaleFromCore(core);
|
|
187
|
+
const overridden = applyBitScaleOverride(t, exact, scale);
|
|
188
|
+
return { exact: overridden.exact, scale: overridden.scale, dim, cycles: 0 };
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=mathts-unit-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mathts-unit-wrapper.js","sourceRoot":"","sources":["../../src/dimensional/mathts-unit-wrapper.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * UPT unit wrapper policy on top of MathTS (Part A steps A8, A11, A12 partial).\n *\n * Admission, refusal policy, and cycle counting stay here even when parsing and\n * scales delegate to MathTS. Four deliberate overrides of MathTS defaults are\n * layered here, each pinned by a test that reads both sides:\n *\n * 1. `ton` and `tons` — MathTS names them ambiguous; UPT refuses them with its own\n * message (`data/units.json`, `tests/dimensional/unit-wrapper-refusal.test.ts`).\n * 2. An affine temperature inside a compound — MathTS refuses `degC/s` but parses the\n * spaced `deg C/s`; UPT refuses both (`localUnitReadings`,\n * `tests/dimensional/mathts-unit-gaps.test.ts`).\n * 3. `pc` prefixes — MathTS admits only k and up (`SHORT_UP_ONLY`); UPT's\n * prefix table applies to every prefixable row, so `mpc` stays on the local\n * grammar (`isSubKiloParsec`, `tests/dimensional/unit-override-parsec.test.ts`).\n * 4. `bit` — MathTS reports scale 1 on its bit axis; UPT keeps ln 2 nat\n * (`applyBitScaleOverride`, `tests/dimensional/unit-wrapper-bit.test.ts`).\n *\n * The refusal *definitions* for `dB`, `dBm`, `dBW`, `Np`, `Mach` and `mach` are\n * MathTS's `REFUSED_UNIT_SPELLINGS` (0.21.0); `data/units.json` no longer\n * repeats them. The wrapper turns a MathTS refusal into `UnitRefusedError`\n * before any parse, compounds included.\n *\n * @module dimensional/mathts-unit-wrapper\n * @internal\n */\nimport { REFUSED_UNIT_SPELLINGS, Unit, exactScaleToNumber } from '@danielsimonjr/mathts-core';\nimport { scaleToNumber, solidusSides, uptExactScaleFromCore, type ExactScale } from './exact-scale.js';\nimport { isSubKiloParsec, mathtsParsedDimension } from './mathts-unit-delegation.js';\nimport { UNIT_DATA } from './unit-data.js';\nimport type { Dimension } from './types.js';\n\nconst DIMENSIONLESS: Dimension = { L: 0, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0 };\n\nconst REFUSED = UNIT_DATA.refused;\nconst UNITS = UNIT_DATA.units;\n\n/** Agreed spellings that fully parse through MathTS (Part A step A5). The 0.21.0\n * core adds the day symbol, the angstrom spellings, and SI prefixes on `psi` and\n * `torr`; the k-and-up parsec spellings agree with the table double for double.\n * The 0.22.0 core adds the glued products `m2K`, `Vs`, `cm^2/Vs` and `W/m2K`. */\nexport const A5_DELEGATED_TEXTS = [\n 'km',\n 'degC',\n 'g/cm^3',\n 'mN/m',\n 'kohm',\n 'GeV',\n 'km/s/Mpc',\n 'd',\n 'day',\n 'Angstrom',\n 'angstrom',\n 'Å',\n 'psi',\n 'torr',\n 'kpsi',\n 'Mpsi',\n 'mtorr',\n 'utorr',\n 'kpc',\n 'Mpc',\n 'Gpc',\n 'm2K',\n 'Vs',\n 'cm^2/Vs',\n 'W/m2K',\n] as const;\n\nconst A5_DELEGATED = new Set<string>(A5_DELEGATED_TEXTS);\n\nconst SUPERSCRIPT: Readonly<Record<string, number>> = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };\n\nfunction sideTokens(text: string): string[] {\n return text.split(/[*·\\s]+|(?<=[A-Za-zµμΩ])\\.(?=[A-Za-zµμΩ])/).filter((part) => part.length > 0);\n}\n\nfunction trySymbolBase(token: string): string | null {\n if (UNITS.has(token)) return token;\n for (const [prefix] of UNIT_DATA.prefixes) {\n if (!token.startsWith(prefix) || token.length === prefix.length) continue;\n const base = token.slice(prefix.length);\n const row = UNITS.get(base);\n if (row !== undefined && row.prefixable) return base;\n }\n return null;\n}\n\nfunction factorBase(token: string): string | null {\n let base = token;\n const caret = /^(.+)\\^([+-]?\\d+)$/.exec(token);\n if (caret !== null) base = caret[1]!;\n else {\n const uni = /^(.*?)(⁻?[¹²³])$/.exec(token);\n if (uni !== null && SUPERSCRIPT[uni[2]!] !== undefined && uni[1]!.length > 0) base = uni[1]!;\n else {\n const glued = /^(.*?)([1-9]\\d*)$/.exec(token);\n if (glued !== null && glued[1]!.length > 0 && trySymbolBase(glued[1]!) !== null) base = glued[1]!;\n }\n }\n return trySymbolBase(base);\n}\n\n/** A token MathTS refuses by name: UPT policy rows first, then the MathTS registry. */\nfunction refusalReasonFor(token: string): string | undefined {\n return REFUSED.get(token) ?? REFUSED_UNIT_SPELLINGS[token];\n}\n\n/** Tokens whose spelling carries a refusal reason: UPT policy rows first, then MathTS's registry. */\nexport function refusedTokensIn(text: string): readonly string[] {\n const t = text.trim();\n if (t === '' || t === '1') return [];\n const whole = refusalReasonFor(t);\n if (whole !== undefined) return [t];\n const { numerator, denominator } = solidusSides(t);\n const tokens = [...sideTokens(numerator), ...sideTokens(denominator)];\n const hits: string[] = [];\n for (const token of tokens) {\n if (token === '1') continue;\n if (refusalReasonFor(token) !== undefined) hits.push(token);\n else {\n const base = factorBase(token);\n if (base !== null && refusalReasonFor(base) !== undefined) hits.push(base);\n }\n }\n return hits;\n}\n\n/** Refusal message: UPT policy (`ton`) first, then the MathTS registry (`dB` and friends). Null when the text is not denied. */\nexport function uptRefusalReason(text: string): string | null {\n const hits = refusedTokensIn(text);\n if (hits.length === 0) return null;\n const token = hits[0]!;\n return refusalReasonFor(token) ?? null;\n}\n\n/** Whether `text` is on the Part A step A5 delegated spelling list. */\nexport function isA5DelegatedText(text: string): boolean {\n return A5_DELEGATED.has(text.trim());\n}\n\n/** Whether MathTS `Unit.parse` accepts `text`. */\nexport function mathtsWouldParse(text: string): boolean {\n try {\n Unit.parse(text.trim());\n return true;\n } catch {\n return false;\n }\n}\n\n/** Keep `bit` at ln 2 nat on the 7-vector (A11a). */\nexport function applyBitScaleOverride(text: string, exact: ExactScale, scale: number): { readonly exact: ExactScale; readonly scale: number } {\n if (text.trim() !== 'bit') return { exact, scale };\n const row = UNITS.get('bit');\n if (row === undefined) return { exact, scale };\n const localScale = scaleToNumber(row.scale);\n return { exact: row.scale, scale: localScale };\n}\n\n/** Scale, dimension, and cycles for one A5 in-set text read through MathTS. */\nexport interface MathtsDelegatedReading {\n readonly exact: ExactScale;\n readonly scale: number;\n readonly dim: Dimension;\n readonly cycles: number;\n}\n\nfunction affineDim(text: string): Dimension | null {\n const row = UNIT_DATA.affine.find((candidate) => candidate.symbols.includes(text));\n return row === undefined ? null : { ...DIMENSIONLESS, Theta: 1 };\n}\n\n/**\n * Scale and dimension for an A5 in-set text through MathTS only (A12 partial).\n * Returns null when the text is not on the A5 list or MathTS rejects it.\n */\nexport function tryMathtsA5Reading(text: string): MathtsDelegatedReading | null {\n const t = text.trim();\n if (isSubKiloParsec(t)) return null;\n if (!isA5DelegatedText(t)) return null;\n const affineDimHint = affineDim(t);\n try {\n Unit.parse(t);\n } catch {\n return null;\n }\n const core = Unit.exactScale(t);\n if (core === null) return null;\n const scale = exactScaleToNumber(core);\n const dim = mathtsParsedDimension(t, affineDimHint ?? DIMENSIONLESS);\n const exact = UNITS.get(t)?.scale ?? uptExactScaleFromCore(core);\n const overridden = applyBitScaleOverride(t, exact, scale);\n return { exact: overridden.exact, scale: overridden.scale, dim, cycles: 0 };\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one lowering of a UPT scalar `ExprNode` to a MathTS `ScalarNode`.
|
|
3
|
+
*
|
|
4
|
+
* MathTS `evaluateScalar` and `compileScalarGradient` read a one-argument `-`
|
|
5
|
+
* as the identity: `op('-', [x])` at x = 3 evaluates to 3. This module writes
|
|
6
|
+
* `−x` as `(−1)·x` and `+x` as `x` before the MathTS scalar builder reads the
|
|
7
|
+
* tree. Every other node goes to the builder unchanged. `composition/expr-eval`
|
|
8
|
+
* and `diff/bridge-ast-gradient` both call this function.
|
|
9
|
+
*
|
|
10
|
+
* @module dimensional/scalar-lowering
|
|
11
|
+
*/
|
|
12
|
+
import { type ScalarNode } from '@danielsimonjr/mathts-expression';
|
|
13
|
+
import type { ExprNode } from './validator.js';
|
|
14
|
+
/**
|
|
15
|
+
* A scalar `ExprNode` as a MathTS `ScalarNode`, with each one-argument sign
|
|
16
|
+
* rewritten first.
|
|
17
|
+
* @throws ScalarBuildError (MathTS) on a node kind outside symbol, op, transcendental and abs.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare function toScalarNode(node: ExprNode): ScalarNode;
|
|
21
|
+
//# sourceMappingURL=scalar-lowering.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scalar-lowering.d.ts","sourceRoot":"","sources":["../../src/dimensional/scalar-lowering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AA0B/C;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAEvD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one lowering of a UPT scalar `ExprNode` to a MathTS `ScalarNode`.
|
|
3
|
+
*
|
|
4
|
+
* MathTS `evaluateScalar` and `compileScalarGradient` read a one-argument `-`
|
|
5
|
+
* as the identity: `op('-', [x])` at x = 3 evaluates to 3. This module writes
|
|
6
|
+
* `−x` as `(−1)·x` and `+x` as `x` before the MathTS scalar builder reads the
|
|
7
|
+
* tree. Every other node goes to the builder unchanged. `composition/expr-eval`
|
|
8
|
+
* and `diff/bridge-ast-gradient` both call this function.
|
|
9
|
+
*
|
|
10
|
+
* @module dimensional/scalar-lowering
|
|
11
|
+
*/
|
|
12
|
+
import { createScalarBuilder } from '@danielsimonjr/mathts-expression';
|
|
13
|
+
import { DIMENSIONLESS } from './types.js';
|
|
14
|
+
const builder = createScalarBuilder();
|
|
15
|
+
const MINUS_ONE = { kind: 'symbol', name: '-1', dim: DIMENSIONLESS };
|
|
16
|
+
/** Rewrite every one-argument sign on the scalar arms. Return every other node unchanged. */
|
|
17
|
+
function rewriteSigns(node) {
|
|
18
|
+
switch (node.kind) {
|
|
19
|
+
case 'op': {
|
|
20
|
+
const args = node.args.map(rewriteSigns);
|
|
21
|
+
if (args.length === 1) {
|
|
22
|
+
if (node.op === '-')
|
|
23
|
+
return { kind: 'op', op: '*', args: [MINUS_ONE, args[0]] };
|
|
24
|
+
if (node.op === '+')
|
|
25
|
+
return args[0];
|
|
26
|
+
}
|
|
27
|
+
return { ...node, args };
|
|
28
|
+
}
|
|
29
|
+
case 'transcendental':
|
|
30
|
+
case 'abs':
|
|
31
|
+
return { ...node, arg: rewriteSigns(node.arg) };
|
|
32
|
+
default:
|
|
33
|
+
return node;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A scalar `ExprNode` as a MathTS `ScalarNode`, with each one-argument sign
|
|
38
|
+
* rewritten first.
|
|
39
|
+
* @throws ScalarBuildError (MathTS) on a node kind outside symbol, op, transcendental and abs.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export function toScalarNode(node) {
|
|
43
|
+
return builder.from(rewriteSigns(node));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=scalar-lowering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scalar-lowering.js","sourceRoot":"","sources":["../../src/dimensional/scalar-lowering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,mBAAmB,EAAmB,MAAM,kCAAkC,CAAC;AAExF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;AAEtC,MAAM,SAAS,GAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;AAE/E,6FAA6F;AAC7F,SAAS,YAAY,CAAC,IAAc;IAClC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG;oBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;gBACjF,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG;oBAAE,OAAO,IAAI,CAAC,CAAC,CAAE,CAAC;YACvC,CAAC;YACD,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,KAAK,gBAAgB,CAAC;QACtB,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,OAAO,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["/**\n * The one lowering of a UPT scalar `ExprNode` to a MathTS `ScalarNode`.\n *\n * MathTS `evaluateScalar` and `compileScalarGradient` read a one-argument `-`\n * as the identity: `op('-', [x])` at x = 3 evaluates to 3. This module writes\n * `−x` as `(−1)·x` and `+x` as `x` before the MathTS scalar builder reads the\n * tree. Every other node goes to the builder unchanged. `composition/expr-eval`\n * and `diff/bridge-ast-gradient` both call this function.\n *\n * @module dimensional/scalar-lowering\n */\n\nimport { createScalarBuilder, type ScalarNode } from '@danielsimonjr/mathts-expression';\nimport type { ExprNode } from './validator.js';\nimport { DIMENSIONLESS } from './types.js';\n\nconst builder = createScalarBuilder();\n\nconst MINUS_ONE: ExprNode = { kind: 'symbol', name: '-1', dim: DIMENSIONLESS };\n\n/** Rewrite every one-argument sign on the scalar arms. Return every other node unchanged. */\nfunction rewriteSigns(node: ExprNode): ExprNode {\n switch (node.kind) {\n case 'op': {\n const args = node.args.map(rewriteSigns);\n if (args.length === 1) {\n if (node.op === '-') return { kind: 'op', op: '*', args: [MINUS_ONE, args[0]!] };\n if (node.op === '+') return args[0]!;\n }\n return { ...node, args };\n }\n case 'transcendental':\n case 'abs':\n return { ...node, arg: rewriteSigns(node.arg) };\n default:\n return node;\n }\n}\n\n/**\n * A scalar `ExprNode` as a MathTS `ScalarNode`, with each one-argument sign\n * rewritten first.\n * @throws ScalarBuildError (MathTS) on a node kind outside symbol, op, transcendental and abs.\n * @internal\n */\nexport function toScalarNode(node: ExprNode): ScalarNode {\n return builder.from(rewriteSigns(node));\n}\n"]}
|
|
@@ -7,8 +7,12 @@
|
|
|
7
7
|
* spelling and an affine spelling are not also a unit, every prefix letter is
|
|
8
8
|
* both a prefix and a unit, and every `{NAME}` in a note is a constant. A
|
|
9
9
|
* file that breaks one throws here, so `units.ts` never reads a half-valid table.
|
|
10
|
+
* The refusal definitions MathTS ships (`REFUSED_UNIT_SPELLINGS`) are
|
|
11
|
+
* delegated, not restated: a spelling MathTS refuses may not be a unit row,
|
|
12
|
+
* and a local refusal MathTS also refuses must state the same reason.
|
|
10
13
|
*
|
|
11
|
-
* A scale is an exact expression, read by `
|
|
14
|
+
* A scale is an exact expression, read by MathTS `readScaleExpression` with
|
|
15
|
+
* this file's resolver. A name in it is a
|
|
12
16
|
* shared scale from the file's `scales`, `pi`, or a constant under its registry
|
|
13
17
|
* spelling (`c`, `e`, `m_u`, `M_sun`, `Msun_iau`, `ln2`; `constant-rows.ts`),
|
|
14
18
|
* the same spelling a `{NAME}` note placeholder uses. A constant is read through
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unit-data.d.ts","sourceRoot":"","sources":["../../src/dimensional/unit-data.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"unit-data.d.ts","sourceRoot":"","sources":["../../src/dimensional/unit-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AA6B1B,+CAA+C;AAC/C,MAAM,WAAW,OAAO;IACtB,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,0BAA0B;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;CACxB;AAED,4DAA4D;AAC5D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnD,gDAAgD;IAChD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,+BAA+B;IAC/B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAyBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,aAAa,CAoG5E;AAED,kEAAkE;AAClE,eAAO,MAAM,SAAS,EAAE,aAA8E,CAAC"}
|