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
|
@@ -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
|
|
@@ -19,10 +23,11 @@
|
|
|
19
23
|
*
|
|
20
24
|
* @module dimensional/unit-data
|
|
21
25
|
*/
|
|
26
|
+
import { REFUSED_UNIT_SPELLINGS, readScaleExpression } from '@danielsimonjr/mathts-core';
|
|
22
27
|
import { sha256Hex } from '../core/hash.js';
|
|
23
28
|
import { dataSchema, dataText, parseDataFile } from '../core/data-file.js';
|
|
24
29
|
import { constantRow } from './constant-rows.js';
|
|
25
|
-
import { decimalScale, irrationalScale,
|
|
30
|
+
import { coreExactScaleFromUpt, decimalScale, irrationalScale, scaleOf, uptExactScaleFromCore, } from './exact-scale.js';
|
|
26
31
|
/** π, which the registry does not spell (a formula scope adds `pi` itself), as the irrational factor. */
|
|
27
32
|
const PI = 'pi';
|
|
28
33
|
const PI_SCALE = irrationalScale(Math.PI);
|
|
@@ -69,7 +74,10 @@ export function readUnitFile(text, schema) {
|
|
|
69
74
|
if (reading.has(name))
|
|
70
75
|
throw new Error(`data/units.json: scale '${name}' is defined in terms of itself`);
|
|
71
76
|
reading.add(name);
|
|
72
|
-
const scale = readScaleExpression(shared,
|
|
77
|
+
const scale = uptExactScaleFromCore(readScaleExpression(shared, (name) => {
|
|
78
|
+
const resolved = resolve(name);
|
|
79
|
+
return resolved === undefined ? undefined : coreExactScaleFromUpt(resolved);
|
|
80
|
+
}));
|
|
73
81
|
reading.delete(name);
|
|
74
82
|
named.set(name, scale);
|
|
75
83
|
return scale;
|
|
@@ -78,7 +86,10 @@ export function readUnitFile(text, schema) {
|
|
|
78
86
|
};
|
|
79
87
|
const read = (text, where) => {
|
|
80
88
|
try {
|
|
81
|
-
return readScaleExpression(text,
|
|
89
|
+
return uptExactScaleFromCore(readScaleExpression(text, (name) => {
|
|
90
|
+
const scale = resolve(name);
|
|
91
|
+
return scale === undefined ? undefined : coreExactScaleFromUpt(scale);
|
|
92
|
+
}));
|
|
82
93
|
}
|
|
83
94
|
catch (error) {
|
|
84
95
|
throw new Error(`data/units.json ${where}: ${error.message}`);
|
|
@@ -101,6 +112,19 @@ export function readUnitFile(text, schema) {
|
|
|
101
112
|
throw new Error(`data/units.json: refused '${symbol}' is also a unit or refused twice`);
|
|
102
113
|
refused.set(symbol, reason);
|
|
103
114
|
}
|
|
115
|
+
// The refusal definitions MathTS ships (`dB` and friends) are delegated, not restated here:
|
|
116
|
+
// a spelling MathTS refuses may not be a unit row, and a local row MathTS also refuses must
|
|
117
|
+
// state the same reason, or the two tables drift.
|
|
118
|
+
for (const symbol of Object.keys(REFUSED_UNIT_SPELLINGS)) {
|
|
119
|
+
if (units.has(symbol))
|
|
120
|
+
throw new Error(`data/units.json: unit '${symbol}' is also refused by MathTS; one table decides`);
|
|
121
|
+
}
|
|
122
|
+
for (const { symbol, reason } of file.refused) {
|
|
123
|
+
const mathtsReason = REFUSED_UNIT_SPELLINGS[symbol];
|
|
124
|
+
if (mathtsReason !== undefined && mathtsReason !== reason) {
|
|
125
|
+
throw new Error(`data/units.json: refused '${symbol}' states a different reason than MathTS does`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
104
128
|
for (const letter of file.prefixLetterUnits.letters) {
|
|
105
129
|
if (!prefixes.has(letter) || !units.has(letter)) {
|
|
106
130
|
throw new Error(`data/units.json: prefix letter '${letter}' is not both a prefix and a unit`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unit-data.js","sourceRoot":"","sources":["../../src/dimensional/unit-data.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The unit table, loaded from `data/units.json` and validated once.\n *\n * The file is checked against `data/units.schema.json` when this module\n * loads (`core/data-file`), then against the rules a schema cannot state:\n * every scale expression reads, a symbol is spelled by one row, a refused\n * spelling and an affine spelling are not also a unit, every prefix letter is\n * both a prefix and a unit, and every `{NAME}` in a note is a constant. A\n * file that breaks one throws here, so `units.ts` never reads a half-valid table.\n *\n * A scale is an exact expression, read by `exact-scale.ts`. A name in it is a\n * shared scale from the file's `scales`, `pi`, or a constant under its registry\n * spelling (`c`, `e`, `m_u`, `M_sun`, `Msun_iau`, `ln2`; `constant-rows.ts`),\n * the same spelling a `{NAME}` note placeholder uses. A constant is read through\n * its shortest decimal (`scaleOf`), or as the irrational factor when its row is\n * `irrational`. A shared scale may not reuse a constant's spelling, so a name\n * has one meaning. The raw rows are strings and integer exponents, so another\n * exact reader (MathTS) replaces this loader without touching the file.\n *\n * @module dimensional/unit-data\n */\n\nimport { sha256Hex } from '../core/hash.js';\nimport { dataSchema, dataText, parseDataFile } from '../core/data-file.js';\nimport type { JsonSchema } from '../core/json-schema.js';\nimport { constantRow } from './constant-rows.js';\nimport type { Dimension } from './types.js';\nimport { decimalScale, irrationalScale, readScaleExpression, scaleOf, type ExactScale } from './exact-scale.js';\n\ntype DimensionFile = Partial<Record<keyof Dimension, number>>;\n\ninterface UnitFileRow {\n readonly symbols: readonly string[];\n readonly scale: string;\n readonly dimension: DimensionFile;\n readonly prefixable: boolean;\n readonly cycles?: true;\n}\n\ninterface AffineFileRow {\n readonly id: string;\n readonly scale: string;\n readonly icePoint: string;\n readonly symbols: readonly string[];\n}\n\ninterface UnitFile {\n readonly scales: Readonly<Record<string, string>>;\n readonly prefixes: Readonly<Record<string, string>>;\n readonly units: readonly UnitFileRow[];\n readonly refused: readonly { readonly symbol: string; readonly reason: string }[];\n readonly prefixLetterUnits: { readonly letters: readonly string[] };\n readonly affine: { readonly iceKelvin: string; readonly scales: readonly AffineFileRow[] };\n readonly spellingNotes: readonly { readonly spelling: string; readonly note: string }[];\n}\n\n/** One unit symbol, read exactly. @internal */\nexport interface UnitRow {\n /** Exact scale to SI base units. */\n readonly scale: ExactScale;\n readonly dim: Dimension;\n /** Takes an SI prefix. */\n readonly prefixable: boolean;\n /**\n * The unit counts cycles (turns), not radians. An angular-frequency input in\n * rad/s takes 2π per cycle; the radian itself does not.\n */\n readonly cycles?: true;\n}\n\n/** One affine temperature scale, read exactly. @internal */\nexport interface AffineRow {\n readonly id: string;\n /** Kelvin per degree, exactly. */\n readonly scale: ExactScale;\n /** The reading at the ice point (0 °C, 273.15 K), exactly. */\n readonly icePoint: ExactScale;\n readonly symbols: readonly string[];\n}\n\n/** The unit table `units.ts` reads. @internal */\nexport interface UnitTableData {\n readonly units: ReadonlyMap<string, UnitRow>;\n readonly prefixes: ReadonlyMap<string, ExactScale>;\n /** Refused spelling → the message it prints. */\n readonly refused: ReadonlyMap<string, string>;\n readonly prefixLetterUnits: ReadonlySet<string>;\n /** Kelvin at 0 °C, exactly. */\n readonly iceKelvin: ExactScale;\n readonly affine: readonly AffineRow[];\n /** Spelling → its note, with every `{NAME}` replaced by that constant. */\n readonly spellingNotes: ReadonlyMap<string, string>;\n /** SHA-256 of `data/units.json` with line endings as LF, for the CLI record fingerprint. */\n readonly sha256: string;\n}\n\n/** π, which the registry does not spell (a formula scope adds `pi` itself), as the irrational factor. */\nconst PI = 'pi';\nconst PI_SCALE = irrationalScale(Math.PI);\n\n/** The registered constant `name` spells, exactly: its irrational factor or its shortest decimal; undefined when no constant has that spelling. */\nfunction constantScale(name: string): ExactScale | undefined {\n const constant = constantRow(name);\n if (constant === undefined) return undefined;\n return constant.irrational === true ? irrationalScale(constant.value) : scaleOf(constant.value);\n}\n\nfunction dimension(d: DimensionFile): Dimension {\n return {\n L: d.L ?? 0,\n M: d.M ?? 0,\n T: d.T ?? 0,\n I: d.I ?? 0,\n Theta: d.Theta ?? 0,\n N: d.N ?? 0,\n J: d.J ?? 0,\n };\n}\n\n/**\n * Validate and read `text`, the contents of `data/units.json`, against `schema`.\n * Throws on a file the schema or the table rules reject. A test passes a broken copy.\n * @internal\n */\nexport function readUnitFile(text: string, schema: JsonSchema): UnitTableData {\n const file = parseDataFile('units.json', text, schema) as UnitFile;\n for (const name of Object.keys(file.scales)) {\n if (name === PI || constantRow(name) !== undefined) {\n throw new Error(`data/units.json: shared scale '${name}' is also ${name === PI ? 'π' : 'a registered constant'}; a name has one meaning`);\n }\n }\n\n const named = new Map<string, ExactScale>();\n const reading = new Set<string>();\n const resolve = (name: string): ExactScale | undefined => {\n if (name === PI) return PI_SCALE;\n const shared = file.scales[name];\n if (shared !== undefined) {\n const done = named.get(name);\n if (done !== undefined) return done;\n if (reading.has(name)) throw new Error(`data/units.json: scale '${name}' is defined in terms of itself`);\n reading.add(name);\n const scale = readScaleExpression(shared, resolve);\n reading.delete(name);\n named.set(name, scale);\n return scale;\n }\n return constantScale(name);\n };\n const read = (text: string, where: string): ExactScale => {\n try {\n return readScaleExpression(text, resolve);\n } catch (error) {\n throw new Error(`data/units.json ${where}: ${(error as Error).message}`);\n }\n };\n\n const prefixes = new Map(Object.entries(file.prefixes).map(([prefix, text]) => [prefix, decimalScale(text)!] as const));\n const units = new Map<string, UnitRow>();\n for (const row of file.units) {\n const scale = read(row.scale, `unit ${row.symbols[0]}`);\n const unit: UnitRow = { scale, dim: dimension(row.dimension), prefixable: row.prefixable, ...(row.cycles ? { cycles: true as const } : {}) };\n for (const symbol of row.symbols) {\n if (units.has(symbol)) throw new Error(`data/units.json: unit '${symbol}' is spelled by two rows`);\n units.set(symbol, unit);\n }\n }\n const refused = new Map<string, string>();\n for (const { symbol, reason } of file.refused) {\n if (units.has(symbol) || refused.has(symbol)) throw new Error(`data/units.json: refused '${symbol}' is also a unit or refused twice`);\n refused.set(symbol, reason);\n }\n for (const letter of file.prefixLetterUnits.letters) {\n if (!prefixes.has(letter) || !units.has(letter)) {\n throw new Error(`data/units.json: prefix letter '${letter}' is not both a prefix and a unit`);\n }\n }\n const affine = file.affine.scales.map((row) => {\n for (const symbol of row.symbols) {\n if (units.has(symbol) || refused.has(symbol)) throw new Error(`data/units.json: affine '${symbol}' is also a unit or refused`);\n }\n return { id: row.id, scale: read(row.scale, `affine ${row.id}`), icePoint: read(row.icePoint, `affine ${row.id}`), symbols: row.symbols };\n });\n const spellingNotes = new Map<string, string>();\n for (const { spelling, note } of file.spellingNotes) {\n const filled = note.replace(/\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, name: string) => {\n const constant = constantRow(name);\n if (constant === undefined) throw new Error(`data/units.json: note for '${spelling}' names '${name}', which is not a registered constant`);\n return String(constant.value);\n });\n spellingNotes.set(spelling, filled);\n }\n return {\n units,\n prefixes,\n refused,\n prefixLetterUnits: new Set(file.prefixLetterUnits.letters),\n iceKelvin: read(file.affine.iceKelvin, 'affine iceKelvin'),\n affine,\n spellingNotes,\n sha256: sha256Hex(text.replace(/\\r\\n/g, '\\n')),\n };\n}\n\n/** The unit table, read once from `data/units.json`. @internal */\nexport const UNIT_DATA: UnitTableData = readUnitFile(dataText('units.json'), dataSchema('units.json'));\n"]}
|
|
1
|
+
{"version":3,"file":"unit-data.js","sourceRoot":"","sources":["../../src/dimensional/unit-data.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The unit table, loaded from `data/units.json` and validated once.\n *\n * The file is checked against `data/units.schema.json` when this module\n * loads (`core/data-file`), then against the rules a schema cannot state:\n * every scale expression reads, a symbol is spelled by one row, a refused\n * spelling and an affine spelling are not also a unit, every prefix letter is\n * both a prefix and a unit, and every `{NAME}` in a note is a constant. A\n * file that breaks one throws here, so `units.ts` never reads a half-valid table.\n * The refusal definitions MathTS ships (`REFUSED_UNIT_SPELLINGS`) are\n * delegated, not restated: a spelling MathTS refuses may not be a unit row,\n * and a local refusal MathTS also refuses must state the same reason.\n *\n * A scale is an exact expression, read by MathTS `readScaleExpression` with\n * this file's resolver. A name in it is a\n * shared scale from the file's `scales`, `pi`, or a constant under its registry\n * spelling (`c`, `e`, `m_u`, `M_sun`, `Msun_iau`, `ln2`; `constant-rows.ts`),\n * the same spelling a `{NAME}` note placeholder uses. A constant is read through\n * its shortest decimal (`scaleOf`), or as the irrational factor when its row is\n * `irrational`. A shared scale may not reuse a constant's spelling, so a name\n * has one meaning. The raw rows are strings and integer exponents, so another\n * exact reader (MathTS) replaces this loader without touching the file.\n *\n * @module dimensional/unit-data\n */\n\nimport { REFUSED_UNIT_SPELLINGS, readScaleExpression } from '@danielsimonjr/mathts-core';\nimport { sha256Hex } from '../core/hash.js';\nimport { dataSchema, dataText, parseDataFile } from '../core/data-file.js';\nimport type { JsonSchema } from '../core/json-schema.js';\nimport { constantRow } from './constant-rows.js';\nimport type { Dimension } from './types.js';\nimport {\n coreExactScaleFromUpt,\n decimalScale,\n irrationalScale,\n scaleOf,\n uptExactScaleFromCore,\n type ExactScale,\n} from './exact-scale.js';\n\ntype DimensionFile = Partial<Record<keyof Dimension, number>>;\n\ninterface UnitFileRow {\n readonly symbols: readonly string[];\n readonly scale: string;\n readonly dimension: DimensionFile;\n readonly prefixable: boolean;\n readonly cycles?: true;\n}\n\ninterface AffineFileRow {\n readonly id: string;\n readonly scale: string;\n readonly icePoint: string;\n readonly symbols: readonly string[];\n}\n\ninterface UnitFile {\n readonly scales: Readonly<Record<string, string>>;\n readonly prefixes: Readonly<Record<string, string>>;\n readonly units: readonly UnitFileRow[];\n readonly refused: readonly { readonly symbol: string; readonly reason: string }[];\n readonly prefixLetterUnits: { readonly letters: readonly string[] };\n readonly affine: { readonly iceKelvin: string; readonly scales: readonly AffineFileRow[] };\n readonly spellingNotes: readonly { readonly spelling: string; readonly note: string }[];\n}\n\n/** One unit symbol, read exactly. @internal */\nexport interface UnitRow {\n /** Exact scale to SI base units. */\n readonly scale: ExactScale;\n readonly dim: Dimension;\n /** Takes an SI prefix. */\n readonly prefixable: boolean;\n /**\n * The unit counts cycles (turns), not radians. An angular-frequency input in\n * rad/s takes 2π per cycle; the radian itself does not.\n */\n readonly cycles?: true;\n}\n\n/** One affine temperature scale, read exactly. @internal */\nexport interface AffineRow {\n readonly id: string;\n /** Kelvin per degree, exactly. */\n readonly scale: ExactScale;\n /** The reading at the ice point (0 °C, 273.15 K), exactly. */\n readonly icePoint: ExactScale;\n readonly symbols: readonly string[];\n}\n\n/** The unit table `units.ts` reads. @internal */\nexport interface UnitTableData {\n readonly units: ReadonlyMap<string, UnitRow>;\n readonly prefixes: ReadonlyMap<string, ExactScale>;\n /** Refused spelling → the message it prints. */\n readonly refused: ReadonlyMap<string, string>;\n readonly prefixLetterUnits: ReadonlySet<string>;\n /** Kelvin at 0 °C, exactly. */\n readonly iceKelvin: ExactScale;\n readonly affine: readonly AffineRow[];\n /** Spelling → its note, with every `{NAME}` replaced by that constant. */\n readonly spellingNotes: ReadonlyMap<string, string>;\n /** SHA-256 of `data/units.json` with line endings as LF, for the CLI record fingerprint. */\n readonly sha256: string;\n}\n\n/** π, which the registry does not spell (a formula scope adds `pi` itself), as the irrational factor. */\nconst PI = 'pi';\nconst PI_SCALE = irrationalScale(Math.PI);\n\n/** The registered constant `name` spells, exactly: its irrational factor or its shortest decimal; undefined when no constant has that spelling. */\nfunction constantScale(name: string): ExactScale | undefined {\n const constant = constantRow(name);\n if (constant === undefined) return undefined;\n return constant.irrational === true ? irrationalScale(constant.value) : scaleOf(constant.value);\n}\n\nfunction dimension(d: DimensionFile): Dimension {\n return {\n L: d.L ?? 0,\n M: d.M ?? 0,\n T: d.T ?? 0,\n I: d.I ?? 0,\n Theta: d.Theta ?? 0,\n N: d.N ?? 0,\n J: d.J ?? 0,\n };\n}\n\n/**\n * Validate and read `text`, the contents of `data/units.json`, against `schema`.\n * Throws on a file the schema or the table rules reject. A test passes a broken copy.\n * @internal\n */\nexport function readUnitFile(text: string, schema: JsonSchema): UnitTableData {\n const file = parseDataFile('units.json', text, schema) as UnitFile;\n for (const name of Object.keys(file.scales)) {\n if (name === PI || constantRow(name) !== undefined) {\n throw new Error(`data/units.json: shared scale '${name}' is also ${name === PI ? 'π' : 'a registered constant'}; a name has one meaning`);\n }\n }\n\n const named = new Map<string, ExactScale>();\n const reading = new Set<string>();\n const resolve = (name: string): ExactScale | undefined => {\n if (name === PI) return PI_SCALE;\n const shared = file.scales[name];\n if (shared !== undefined) {\n const done = named.get(name);\n if (done !== undefined) return done;\n if (reading.has(name)) throw new Error(`data/units.json: scale '${name}' is defined in terms of itself`);\n reading.add(name);\n const scale = uptExactScaleFromCore(\n readScaleExpression(shared, (name) => {\n const resolved = resolve(name);\n return resolved === undefined ? undefined : coreExactScaleFromUpt(resolved);\n }),\n );\n reading.delete(name);\n named.set(name, scale);\n return scale;\n }\n return constantScale(name);\n };\n const read = (text: string, where: string): ExactScale => {\n try {\n return uptExactScaleFromCore(\n readScaleExpression(text, (name) => {\n const scale = resolve(name);\n return scale === undefined ? undefined : coreExactScaleFromUpt(scale);\n }),\n );\n } catch (error) {\n throw new Error(`data/units.json ${where}: ${(error as Error).message}`);\n }\n };\n\n const prefixes = new Map(Object.entries(file.prefixes).map(([prefix, text]) => [prefix, decimalScale(text)!] as const));\n const units = new Map<string, UnitRow>();\n for (const row of file.units) {\n const scale = read(row.scale, `unit ${row.symbols[0]}`);\n const unit: UnitRow = { scale, dim: dimension(row.dimension), prefixable: row.prefixable, ...(row.cycles ? { cycles: true as const } : {}) };\n for (const symbol of row.symbols) {\n if (units.has(symbol)) throw new Error(`data/units.json: unit '${symbol}' is spelled by two rows`);\n units.set(symbol, unit);\n }\n }\n const refused = new Map<string, string>();\n for (const { symbol, reason } of file.refused) {\n if (units.has(symbol) || refused.has(symbol)) throw new Error(`data/units.json: refused '${symbol}' is also a unit or refused twice`);\n refused.set(symbol, reason);\n }\n // The refusal definitions MathTS ships (`dB` and friends) are delegated, not restated here:\n // a spelling MathTS refuses may not be a unit row, and a local row MathTS also refuses must\n // state the same reason, or the two tables drift.\n for (const symbol of Object.keys(REFUSED_UNIT_SPELLINGS)) {\n if (units.has(symbol)) throw new Error(`data/units.json: unit '${symbol}' is also refused by MathTS; one table decides`);\n }\n for (const { symbol, reason } of file.refused) {\n const mathtsReason = REFUSED_UNIT_SPELLINGS[symbol];\n if (mathtsReason !== undefined && mathtsReason !== reason) {\n throw new Error(`data/units.json: refused '${symbol}' states a different reason than MathTS does`);\n }\n }\n for (const letter of file.prefixLetterUnits.letters) {\n if (!prefixes.has(letter) || !units.has(letter)) {\n throw new Error(`data/units.json: prefix letter '${letter}' is not both a prefix and a unit`);\n }\n }\n const affine = file.affine.scales.map((row) => {\n for (const symbol of row.symbols) {\n if (units.has(symbol) || refused.has(symbol)) throw new Error(`data/units.json: affine '${symbol}' is also a unit or refused`);\n }\n return { id: row.id, scale: read(row.scale, `affine ${row.id}`), icePoint: read(row.icePoint, `affine ${row.id}`), symbols: row.symbols };\n });\n const spellingNotes = new Map<string, string>();\n for (const { spelling, note } of file.spellingNotes) {\n const filled = note.replace(/\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, name: string) => {\n const constant = constantRow(name);\n if (constant === undefined) throw new Error(`data/units.json: note for '${spelling}' names '${name}', which is not a registered constant`);\n return String(constant.value);\n });\n spellingNotes.set(spelling, filled);\n }\n return {\n units,\n prefixes,\n refused,\n prefixLetterUnits: new Set(file.prefixLetterUnits.letters),\n iceKelvin: read(file.affine.iceKelvin, 'affine iceKelvin'),\n affine,\n spellingNotes,\n sha256: sha256Hex(text.replace(/\\r\\n/g, '\\n')),\n };\n}\n\n/** The unit table, read once from `data/units.json`. @internal */\nexport const UNIT_DATA: UnitTableData = readUnitFile(dataText('units.json'), dataSchema('units.json'));\n"]}
|
|
@@ -54,6 +54,8 @@ export interface UnitReading extends ParsedUnit {
|
|
|
54
54
|
export declare function unitConventionNotes(given: string): string[];
|
|
55
55
|
/** The one reading of a unit expression; more than one is refused. @internal */
|
|
56
56
|
export declare function readUnit(text: string): UnitReading;
|
|
57
|
+
/** Which reader parsed `text` last: local grammar or MathTS `Unit.parse`. @internal */
|
|
58
|
+
export declare function unitReadingsSource(text: string): 'mathts' | 'local';
|
|
57
59
|
/** Parse a unit expression; the empty string is dimensionless. @public */
|
|
58
60
|
export declare function parseUnit(text: string): ParsedUnit;
|
|
59
61
|
/** How a temperature value is read: as a point on the scale, or as a difference. @public */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../src/dimensional/units.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"units.d.ts","sourceRoot":"","sources":["../../src/dimensional/units.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,8 +44,11 @@
|
|
|
44
44
|
*
|
|
45
45
|
* @module dimensional/units
|
|
46
46
|
*/
|
|
47
|
+
import { Unit, exactScaleToNumber } from '@danielsimonjr/mathts-core';
|
|
47
48
|
import { equals, format, multiply, power } from './algebra.js';
|
|
48
49
|
import { addScales, decimalScale, divideScales, multiplyScales, powerScale, ratioScale, scaleToNumber, solidusSides, UNIT_SCALE, } from './exact-scale.js';
|
|
50
|
+
import { mathtsParsedDimension, unitExactScaleViaMathts, unitParserViaMathts, } from './mathts-unit-delegation.js';
|
|
51
|
+
import { applyBitScaleOverride, tryMathtsA5Reading, uptRefusalReason } from './mathts-unit-wrapper.js';
|
|
49
52
|
import { UNIT_DATA } from './unit-data.js';
|
|
50
53
|
/** Thrown for any input that does not parse as a value with a known unit. @public */
|
|
51
54
|
export class UnitError extends Error {
|
|
@@ -144,6 +147,7 @@ function trySymbol(sym) {
|
|
|
144
147
|
}
|
|
145
148
|
return null;
|
|
146
149
|
}
|
|
150
|
+
const SUPERSCRIPT = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };
|
|
147
151
|
/** One factor, or null when `token` is not exactly one unit with an optional exponent. */
|
|
148
152
|
function tryOneFactor(token) {
|
|
149
153
|
let base = token;
|
|
@@ -308,8 +312,17 @@ function reading(exact, dim, label, cycles, affine) {
|
|
|
308
312
|
...(affine === undefined ? {} : { affine }),
|
|
309
313
|
};
|
|
310
314
|
}
|
|
315
|
+
let lastReadingSource = null;
|
|
316
|
+
function applyMathtsExactScale(text, local) {
|
|
317
|
+
if (!unitExactScaleViaMathts(text, local.scale, local.exact, local.dim))
|
|
318
|
+
return local;
|
|
319
|
+
const core = Unit.exactScale(text.trim());
|
|
320
|
+
if (core === null)
|
|
321
|
+
return local;
|
|
322
|
+
return { ...local, scale: exactScaleToNumber(core) };
|
|
323
|
+
}
|
|
311
324
|
/**
|
|
312
|
-
* Every dimensionally distinct reading of one unit expression.
|
|
325
|
+
* Every dimensionally distinct reading of one unit expression (local grammar).
|
|
313
326
|
*
|
|
314
327
|
* The unit grammar is not the formula grammar, and the difference is
|
|
315
328
|
* deliberate: a unit symbol is not an identifier (a prefix, a glued product
|
|
@@ -319,7 +332,7 @@ function reading(exact, dim, label, cycles, affine) {
|
|
|
319
332
|
* formula grammar would read `(W/m)·K`.
|
|
320
333
|
* @internal
|
|
321
334
|
*/
|
|
322
|
-
function
|
|
335
|
+
function localUnitReadings(text) {
|
|
323
336
|
const t = text.trim();
|
|
324
337
|
if (t === '' || t === '1')
|
|
325
338
|
return [reading(UNIT_SCALE, DIMENSIONLESS, '1', 0)];
|
|
@@ -360,7 +373,44 @@ function unitReadings(text) {
|
|
|
360
373
|
}
|
|
361
374
|
return [...unique.values()];
|
|
362
375
|
}
|
|
363
|
-
|
|
376
|
+
function unitReadings(text) {
|
|
377
|
+
const t = text.trim();
|
|
378
|
+
lastReadingSource = { text: t, kind: 'local' };
|
|
379
|
+
const refusal = uptRefusalReason(t);
|
|
380
|
+
if (refusal !== null)
|
|
381
|
+
throw new UnitRefusedError(refusal);
|
|
382
|
+
const a5 = tryMathtsA5Reading(t);
|
|
383
|
+
if (a5 !== null) {
|
|
384
|
+
// A12 partial: A5 in-set texts skip localUnitReadings when MathTS agrees.
|
|
385
|
+
lastReadingSource = { text: t, kind: 'mathts' };
|
|
386
|
+
const affine = affineRow(t);
|
|
387
|
+
return [
|
|
388
|
+
reading(a5.exact, a5.dim, t, a5.cycles, affine?.id),
|
|
389
|
+
];
|
|
390
|
+
}
|
|
391
|
+
const readings = localUnitReadings(text);
|
|
392
|
+
if (readings.length === 1) {
|
|
393
|
+
const local = readings[0];
|
|
394
|
+
if (unitParserViaMathts(t, local.scale, local.exact, local.dim)) {
|
|
395
|
+
lastReadingSource = { text: t, kind: 'mathts' };
|
|
396
|
+
const core = Unit.exactScale(t);
|
|
397
|
+
const scale = core === null ? local.scale : exactScaleToNumber(core);
|
|
398
|
+
const overridden = applyBitScaleOverride(t, local.exact, scale);
|
|
399
|
+
return [
|
|
400
|
+
{
|
|
401
|
+
...local,
|
|
402
|
+
dim: mathtsParsedDimension(t, local.dim),
|
|
403
|
+
exact: overridden.exact,
|
|
404
|
+
scale: overridden.scale,
|
|
405
|
+
},
|
|
406
|
+
];
|
|
407
|
+
}
|
|
408
|
+
const scaled = applyMathtsExactScale(t, local);
|
|
409
|
+
const overridden = applyBitScaleOverride(t, scaled.exact, scaled.scale);
|
|
410
|
+
return [{ ...scaled, exact: overridden.exact, scale: overridden.scale }];
|
|
411
|
+
}
|
|
412
|
+
return readings;
|
|
413
|
+
}
|
|
364
414
|
/**
|
|
365
415
|
* Spellings that convert correctly and still mean something else to a reader:
|
|
366
416
|
* the `spellingNotes` of `data/units.json` for each symbol in `given`, in file
|
|
@@ -379,6 +429,12 @@ export function readUnit(text) {
|
|
|
379
429
|
throw new AmbiguousUnitError(t, readings.map((r) => r.label));
|
|
380
430
|
return readings[0];
|
|
381
431
|
}
|
|
432
|
+
/** Which reader parsed `text` last: local grammar or MathTS `Unit.parse`. @internal */
|
|
433
|
+
export function unitReadingsSource(text) {
|
|
434
|
+
readUnit(text);
|
|
435
|
+
const t = text.trim();
|
|
436
|
+
return lastReadingSource !== null && lastReadingSource.text === t ? lastReadingSource.kind : 'local';
|
|
437
|
+
}
|
|
382
438
|
/** Parse a unit expression; the empty string is dimensionless. @public */
|
|
383
439
|
export function parseUnit(text) {
|
|
384
440
|
const r = readUnit(text);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/dimensional/units.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unit parsing for numeric inputs: `1um`, `25degC`, `1 kohm`, `3.8e-16 kg/m^3`.\n *\n * A unit is a product of factors, each `symbol[^n]`, joined by `*`, `·` or a\n * space; everything after a single `/` is the denominator (`W/(m*K)` and\n * `W/m*K` both mean W·m⁻¹·K⁻¹). An exact symbol is matched before a prefixed\n * one, so `min` is a minute, `Pa` a pascal and `mm` a millimetre.\n *\n * An affine temperature (`degC`, `°C`, `degF`, `°F`) is accepted only alone.\n * The kelvin value is `value × scale + offset` for an absolute reading and\n * `value × scale` for a difference. Rankine is proportional (`°R × 5/9`), not\n * affine. The caller decides which reading, from the quantity's role.\n *\n * An exact symbol wins over a prefix: `T` is the tesla and `Ts` is a\n * terasecond; `G` is the gauss and `GPa` is a gigapascal; `P` is the poise\n * and `PV` is still a petavolt. A glued positive exponent is that power when\n * the letters are already a unit, so `K2` and `K²` are `K^2`.\n *\n * A token with no separator is one factor when the whole token is an exact\n * unit or a prefix plus a unit, with an optional exponent. That reading\n * wins on a bare token, so `ms` stays a millisecond, `mm` a millimetre,\n * `mK` a millikelvin, and `Ts` a terasecond. Inside a larger expression the\n * prefixed reading competes with a heterogeneous product (`mK` is millikelvin\n * or metre·kelvin; `ms` is millisecond or metre·second). A split that puts\n * a prefix letter's own unit twice in a row is never a reading, because a\n * power is written `m2` or `m^2`: `mm` is a millimetre, not metre·metre,\n * and `mmin` is metre·minute or millimetre·inch, not metre·metre·inch.\n * A unit that is not a prefix letter still juxtaposes with itself (`NN` is\n * N·N). `parseUnit` names\n * every remaining reading and refuses. `convertValue` keeps the one reading\n * whose dimension is the declared unit. A token that is not one factor is a\n * product when exactly one split exists: `m2K` is `m^2·K`, `Vs` is `V·s`,\n * and `cm^2/Vs` is `cm^2/(V·s)`. Zero splits are an unknown unit. Two or more\n * splits name each reading and are refused (`mAs` is milliampere·second or\n * metre·ampere·second). An unknown token that ends in a digit stays unknown\n * when it is not that product. A numerator that is the single token `1` is\n * the dimensionless unit, so `1/s` is a reciprocal second and `1/m^3` a\n * number density; `1` is not a symbol anywhere else.\n * The table is data: `data/units.json`, loaded and validated by\n * `unit-data.ts`. Every row, prefix, refused spelling, prefix letter, affine\n * scale and spelling note is a row there, with the reason as its `comment`;\n * this module holds the grammar. `myr` is a milliyear because `m` is the SI\n * prefix, and `eV` takes one, so `GeV` is 10⁹ eV in joules.\n *\n * @module dimensional/units\n */\nimport { equals, format, multiply, power } from './algebra.js';\nimport type { Dimension } from './types.js';\nimport {\n addScales,\n decimalScale,\n divideScales,\n multiplyScales,\n powerScale,\n ratioScale,\n scaleToNumber,\n solidusSides,\n UNIT_SCALE,\n type ExactScale,\n} from './exact-scale.js';\nimport { UNIT_DATA, type AffineRow as UnitDataAffineRow } from './unit-data.js';\n\n/** An affine temperature scale: a lone `degC` or `degF`. @public */\nexport type AffineTemperature = 'celsius' | 'fahrenheit';\n\n/** A unit, as a scale to SI base units and a dimension. @public */\nexport interface ParsedUnit {\n readonly scale: number;\n readonly dim: Dimension;\n /** Set only for a lone affine temperature, which needs a reading. */\n readonly affine?: AffineTemperature;\n}\n\n/** Thrown for any input that does not parse as a value with a known unit. @public */\nexport class UnitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UnitError';\n }\n}\n\n/** A symbol no table row and no prefix spells. @public */\nexport class UnknownUnitError extends UnitError {\n constructor(readonly symbol: string) {\n super(`unknown unit '${symbol}'`);\n this.name = 'UnknownUnitError';\n }\n}\n\n/**\n * A unit the reader recognizes and refuses: a logarithmic or ratio unit, an\n * ambiguous name such as `ton`, or an affine temperature inside a compound.\n * @public\n */\nexport class UnitRefusedError extends UnitError {\n constructor(message: string) {\n super(message);\n this.name = 'UnitRefusedError';\n }\n}\n\n/** A unit expression with more than one dimensionally distinct reading. @public */\nexport class AmbiguousUnitError extends UnitError {\n constructor(readonly text: string, readonly readings: readonly string[]) {\n super(`'${text}' is ambiguous: ${readings.join(' or ')}`);\n this.name = 'AmbiguousUnitError';\n }\n}\n\nconst D = (p: Partial<Dimension>): Dimension => ({ L: 0, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0, ...p });\nconst DIMENSIONLESS = D({});\n\n/** symbol → exact scale to SI base, dimension, prefixability, cycle count. Rows are `data/units.json`. */\nconst UNITS = UNIT_DATA.units;\n\n/** Units that are a ratio or a log scale, and the reason each is not a plain factor. */\nconst REFUSED_UNITS = UNIT_DATA.refused;\n\n/**\n * Letters that are both an SI prefix and a unit of their own. Such a token\n * reads as the prefix reading and not as the unit times the rest: `Gyr` is a\n * gigayear. The file's `prefixLetterUnits.comment` says why `m` is not one.\n */\nconst PREFIX_LETTER_UNITS = UNIT_DATA.prefixLetterUnits;\n\n/** Kelvin at 0 °C, exactly. */\nconst CELSIUS_OFFSET_K = UNIT_DATA.iceKelvin;\n\ninterface AffineRow extends UnitDataAffineRow {\n readonly id: AffineTemperature;\n}\n\n/**\n * Lone spellings. A compound that contains one is refused. The schema's `id`\n * enum is {@link AffineTemperature}, held equal by a test: the public type\n * promises callers these ids, so a new affine scale is an API change.\n */\nconst AFFINE = UNIT_DATA.affine as readonly AffineRow[];\n\n/** Kelvin at a reading of zero, exactly: 273.15 − icePoint × scale. */\nfunction affineOffset(row: AffineRow): ExactScale {\n return addScales(CELSIUS_OFFSET_K, multiplyScales(ratioScale(-1, 1), row.icePoint, row.scale));\n}\n\nconst fractionText = (s: ExactScale): string => (s.den === 1n ? String(s.num) : `${s.num}/${s.den}`);\n\n/**\n * How a reading on an affine scale becomes kelvin, from the row's scale and\n * ice point: `absolute: (degF − 32) × 5/9 + 273.15`, `a difference: × 5/9, no offset`.\n * @internal\n */\nexport function affineReadingNote(affine: AffineTemperature, reading: TemperatureReading): string {\n const row = AFFINE.find((candidate) => candidate.id === affine)!;\n const unitScale = row.scale.num === row.scale.den;\n if (reading === 'difference') return unitScale ? 'a difference: no offset' : `a difference: × ${fractionText(row.scale)}, no offset`;\n const kelvin = String(scaleToNumber(CELSIUS_OFFSET_K));\n if (unitScale && row.icePoint.num === 0n) return `absolute: + ${kelvin}`;\n const shifted = row.icePoint.num === 0n ? row.symbols[0]! : `(${row.symbols[0]!} − ${fractionText(row.icePoint)})`;\n return `absolute: ${unitScale ? shifted : `${shifted} × ${fractionText(row.scale)}`} + ${kelvin}`;\n}\n\nfunction affineRow(text: string): AffineRow | undefined {\n return AFFINE.find((candidate) => candidate.symbols.includes(text));\n}\n\nconst PREFIXES = UNIT_DATA.prefixes;\n\ninterface SymbolReading {\n readonly scale: ExactScale;\n readonly dim: Dimension;\n readonly cycles: number;\n}\n\nfunction trySymbol(sym: string): SymbolReading | null {\n const exact = UNITS.get(sym);\n if (exact !== undefined) return { scale: exact.scale, dim: exact.dim, cycles: exact.cycles === true ? 1 : 0 };\n for (const [p, f] of PREFIXES) {\n if (!sym.startsWith(p) || sym.length === p.length) continue;\n const base = UNITS.get(sym.slice(p.length));\n if (base !== undefined && base.prefixable) {\n return { scale: multiplyScales(f, base.scale), dim: base.dim, cycles: base.cycles === true ? 1 : 0 };\n }\n }\n return null;\n}\n\ninterface FactorReading {\n readonly base: string;\n readonly exp: number;\n readonly scale: ExactScale;\n readonly dim: Dimension;\n readonly cycles: number;\n}\n\n/** One factor, or null when `token` is not exactly one unit with an optional exponent. */\nfunction tryOneFactor(token: string): FactorReading | null {\n let base = token;\n let exp = 1;\n const caret = /^(.+)\\^([+-]?\\d+)$/.exec(token);\n if (caret !== null) {\n base = caret[1]!;\n exp = Number(caret[2]);\n } else {\n const uni = /^(.*?)(⁻?[¹²³])$/.exec(token);\n const superExp = uni === null ? undefined : SUPERSCRIPT[uni[2]!];\n if (uni !== null && superExp !== undefined && uni[1]!.length > 0) {\n base = uni[1]!;\n exp = superExp;\n } else {\n const glued = /^(.*?)([1-9]\\d*)$/.exec(token);\n if (glued !== null && glued[1]!.length > 0 && trySymbol(glued[1]!) !== null) {\n base = glued[1]!;\n exp = Number(glued[2]);\n }\n }\n }\n const parsed = trySymbol(base);\n if (parsed === null || !Number.isFinite(exp)) return null;\n return { base, exp, scale: parsed.scale, dim: parsed.dim, cycles: parsed.cycles };\n}\n\nfunction formatReading(factors: readonly FactorReading[]): string {\n return factors.map((factor) => (factor.exp === 1 ? factor.base : `${factor.base}^${factor.exp}`)).join('·');\n}\n\n/** The unprefixed unit a prefix spelling attaches to, or null when `symbol` is exact. */\nfunction attachedUnit(symbol: string): string | null {\n if (UNITS.has(symbol)) return null;\n for (const [prefix] of PREFIXES) {\n if (!symbol.startsWith(prefix) || symbol.length === prefix.length) continue;\n const base = symbol.slice(prefix.length);\n const unitRow = UNITS.get(base);\n if (unitRow !== undefined && unitRow.prefixable) return base;\n }\n return null;\n}\n\n/**\n * `X·X` where `XX` is X's own prefix spelling (`m·m` beside `mm`, `d·d`\n * beside `dd`): not a split, because a power is written `X2` or `X^2`. A\n * run of a unit that is not also a prefix letter (`N·N`) stays a product.\n */\nfunction prefixRun(last: FactorReading, next: FactorReading): boolean {\n return last.base === next.base && attachedUnit(last.base + next.base) === last.base;\n}\n\n/**\n * Every way to split `token` into one or more factors. A one-factor token is\n * included. A split that puts a prefix letter's own unit twice in a row\n * (`m·m`, `m·m²`, `m·m·in`) is not a way, inside any split.\n */\nfunction segmentations(token: string): FactorReading[][] {\n const ways: FactorReading[][][] = Array.from({ length: token.length + 1 }, () => []);\n ways[0]!.push([]);\n for (let i = 0; i < token.length; i++) {\n if (ways[i]!.length === 0) continue;\n for (let j = i + 1; j <= token.length; j++) {\n const factor = tryOneFactor(token.slice(i, j));\n if (factor === null) continue;\n for (const prev of ways[i]!) {\n if (prev.length > 0 && prefixRun(prev[prev.length - 1]!, factor)) continue;\n ways[j]!.push([...prev, factor]);\n }\n }\n }\n const unique = new Map<string, FactorReading[]>();\n for (const way of ways[token.length]!) unique.set(formatReading(way), way);\n return [...unique.values()];\n}\n\n/**\n * Ways to read one token. A bare expression keeps a one-factor reading and\n * does not also split it. Inside a compound, a prefixed factor also competes\n * with each heterogeneous product; `segmentations` has already dropped the\n * homogeneous runs.\n */\nfunction tokenWays(token: string, compete: boolean, side: 'numerator' | 'denominator'): FactorReading[][] {\n const refused = REFUSED_UNITS.get(token);\n if (refused !== undefined) throw new UnitRefusedError(refused);\n const single = tryOneFactor(token);\n if (single !== null && !compete) return [[single]];\n // A prefixed numerator token is the prefix reading: `mN/m` is millinewton per metre.\n // A denominator keeps the product readings (`W/mK`), and a target dimension chooses.\n if (single !== null && side === 'numerator') return [[single]];\n const prefixWins = single !== null && PREFIX_LETTER_UNITS.has(token[0]!) && attachedUnit(single.base) !== null;\n const products = segmentations(token)\n .filter((way) => way.length > 1)\n .filter(() => !prefixWins);\n const ways: FactorReading[][] = [];\n if (single !== null) ways.push([single]);\n for (const way of products) ways.push(way);\n const unique = new Map<string, FactorReading[]>();\n for (const way of ways) unique.set(formatReading(way), way);\n const list = [...unique.values()];\n if (list.length === 0) throw new UnknownUnitError(token);\n return list;\n}\n\nfunction cartesian<T>(lists: readonly (readonly T[])[]): T[][] {\n let acc: T[][] = [[]];\n for (const list of lists) {\n const next: T[][] = [];\n for (const prev of acc) for (const item of list) next.push([...prev, item]);\n acc = next;\n }\n return acc;\n}\n\n/** One reading of a unit expression, with its exact scale. @internal */\nexport interface UnitReading extends ParsedUnit {\n readonly label: string;\n readonly exact: ExactScale;\n /** Net power of cycle-counting units (Hz, rpm): 1 for a lone `kHz`, 0 for `1/s`. */\n readonly cycles: number;\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\nfunction formatSide(tokens: readonly (readonly FactorReading[])[]): string {\n return tokens.map((factors) => formatReading(factors)).join('·');\n}\n\nfunction formatExpression(\n num: readonly (readonly FactorReading[])[],\n den: readonly (readonly FactorReading[])[],\n): string {\n // An empty numerator over a denominator is the dimensionless 1: `1/s`.\n const numerator = num.length === 0 ? '1' : formatSide(num);\n if (den.length === 0) return numerator;\n const denominator = formatSide(den);\n return denominator.includes('·') ? `${numerator}/(${denominator})` : `${numerator}/${denominator}`;\n}\n\nfunction accumulate(\n tokens: readonly (readonly FactorReading[])[],\n sign: 1 | -1,\n): { scale: ExactScale; dim: Dimension; cycles: number } {\n let scale = UNIT_SCALE;\n let dim = DIMENSIONLESS;\n let cycles = 0;\n for (const factors of tokens) {\n for (const factor of factors) {\n const n = sign * factor.exp;\n scale = multiplyScales(scale, powerScale(factor.scale, n));\n dim = multiply(dim, power(factor.dim, n));\n cycles += factor.cycles * n;\n }\n }\n return { scale, dim, cycles };\n}\n\nfunction reading(exact: ExactScale, dim: Dimension, label: string, cycles: number, affine?: AffineTemperature): UnitReading {\n return {\n scale: scaleToNumber(exact),\n exact,\n dim,\n label,\n cycles,\n ...(affine === undefined ? {} : { affine }),\n };\n}\n\n/**\n * Every dimensionally distinct reading of one unit expression.\n *\n * The unit grammar is not the formula grammar, and the difference is\n * deliberate: a unit symbol is not an identifier (a prefix, a glued product\n * or a glued power lives inside one token: `mN`, `m2K`, `Vs`, `K²`, `°C`,\n * `%`), and everything after the first `/` is the denominator, the\n * single-solidus convention of ISO 80000-1 (`W/m*K` is W·m⁻¹·K⁻¹), where the\n * formula grammar would read `(W/m)·K`.\n * @internal\n */\nfunction unitReadings(text: string): UnitReading[] {\n const t = text.trim();\n if (t === '' || t === '1') return [reading(UNIT_SCALE, DIMENSIONLESS, '1', 0)];\n const affine = affineRow(t);\n if (affine !== undefined) return [reading(affine.scale, D({ Theta: 1 }), t, 0, affine.id)];\n if (\n AFFINE.some((candidate) => candidate.symbols.some((symbol) => t.includes(symbol))) ||\n /deg\\s+[CFcf]|°\\s*[CFcf]/.test(t)\n ) {\n throw new UnitRefusedError('an affine temperature cannot be part of a compound unit; give K');\n }\n // An operator with nothing on one side (`m/`, `m//s`, `m*`, `*m`, `m/*s`) is not a unit\n // text; it was read as if the empty factor were 1 (Tom's second round). A leading `/`\n // (`/s`) stays the dimensionless numerator.\n if (/[*·/]\\s*$|^\\s*[*·]|[*·/]\\s*[*·/]/.test(t)) throw new UnknownUnitError(t);\n // A chain is one denominator: `km/s/Mpc` is km/(s·Mpc), the way the Hubble constant is written.\n const sides = solidusSides(t);\n const compete = /[*·/\\s]/.test(t);\n const numeratorTokens = sideTokens(sides.numerator);\n // A numerator that is the single token `1` is the dimensionless unit: `1/s`, `1/m^3`.\n const numerator = numeratorTokens.length === 1 && numeratorTokens[0] === '1' ? [] : numeratorTokens;\n const denominator = sides.denominator === '' ? [] : sideTokens(sides.denominator);\n // `/s` is a dimensionless numerator over seconds. A bare `/` is not a unit.\n if (numerator.length === 0 && denominator.length === 0) throw new UnknownUnitError(t);\n const numWays = numerator.map((token) => tokenWays(token, compete, 'numerator'));\n const denWays = denominator.map((token) => tokenWays(token, compete, 'denominator'));\n const numCombos = numerator.length === 0 ? [[]] : cartesian(numWays);\n const denCombos = denominator.length === 0 ? [[]] : cartesian(denWays);\n const unique = new Map<string, UnitReading>();\n for (const num of numCombos) {\n for (const den of denCombos) {\n const n = accumulate(num, 1);\n const d = accumulate(den, -1);\n const label = formatExpression(num, den);\n unique.set(label, reading(multiplyScales(n.scale, d.scale), multiply(n.dim, d.dim), label, n.cycles + d.cycles));\n }\n }\n return [...unique.values()];\n}\n\nconst SUPERSCRIPT: Readonly<Record<string, number>> = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };\n\n/**\n * Spellings that convert correctly and still mean something else to a reader:\n * the `spellingNotes` of `data/units.json` for each symbol in `given`, in file\n * order. `myr` is a milliyear, bare `G` is the gauss, bare `A` the ampere.\n * @internal\n */\nexport function unitConventionNotes(given: string): string[] {\n const symbols = new Set(given.split(/[*·/\\s^0-9()+-]+/).filter((s) => s.length > 0));\n return [...UNIT_DATA.spellingNotes].filter(([spelling]) => symbols.has(spelling)).map(([, note]) => note);\n}\n\n/** The one reading of a unit expression; more than one is refused. @internal */\nexport function readUnit(text: string): UnitReading {\n const t = text.trim();\n const readings = unitReadings(t);\n if (readings.length !== 1) throw new AmbiguousUnitError(t, readings.map((r) => r.label));\n return readings[0]!;\n}\n\n/** Parse a unit expression; the empty string is dimensionless. @public */\nexport function parseUnit(text: string): ParsedUnit {\n const r = readUnit(text);\n return { scale: r.scale, dim: r.dim, ...(r.affine !== undefined ? { affine: r.affine } : {}) };\n}\n\n/** How a temperature value is read: as a point on the scale, or as a difference. @public */\nexport type TemperatureReading = 'absolute' | 'difference';\n\n/** The SI magnitude of `magnitude` in `unit`, exactly. An absolute affine reading adds its offset. */\nfunction siMagnitude(magnitude: ExactScale, unit: UnitReading, temperature: TemperatureReading): ExactScale {\n const scaled = multiplyScales(magnitude, unit.exact);\n const row = unit.affine === undefined ? undefined : AFFINE.find((candidate) => candidate.id === unit.affine);\n return row !== undefined && temperature === 'absolute' ? addScales(scaled, affineOffset(row)) : scaled;\n}\n\nconst FRACTION = /^\\s*([+-]?(?:\\d+\\.?\\d*|\\.\\d+))\\s*\\/\\s*((?:\\d+\\.?\\d*|\\.\\d+))\\s*$/;\nconst NUMBER_THEN_REST = /^\\s*([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)\\s*(.*?)\\s*$/;\n\n/**\n * `raw` split into an exact decimal magnitude and the unit text after it, or\n * null when `raw` is not a number followed by an optional unit. A plain\n * fraction (`1/3`) is a number. Text that begins with an operator (`*h`,\n * `·c`) is an expression, not a unit.\n * @internal\n */\nfunction splitQuantityLiteral(raw: string): { readonly magnitude: ExactScale; readonly unit: string } | null {\n const fraction = FRACTION.exec(raw);\n if (fraction !== null) {\n const den = decimalScale(fraction[2]!)!;\n if (den.num !== 0n) return { magnitude: divideScales(decimalScale(fraction[1]!)!, den), unit: '' };\n }\n const m = NUMBER_THEN_REST.exec(raw);\n if (m === null) return null;\n const unit = m[2]!;\n if (unit.startsWith('*') || unit.startsWith('·')) return null;\n const magnitude = decimalScale(m[1]!);\n return magnitude === null ? null : { magnitude, unit };\n}\n\n/** A number with a unit, read exactly and rounded once. @internal */\nexport interface QuantityLiteral {\n /** SI value; a bare number is unchanged. */\n readonly value: number;\n readonly dim: Dimension;\n /** The unit text as given; `''` for a bare number. */\n readonly unit: string;\n readonly cycles: number;\n readonly affine?: AffineTemperature;\n}\n\nfunction finiteLiteral(raw: string, value: number): number {\n if (!Number.isFinite(value)) throw new UnitError(`'${raw}' is not a finite number`);\n return value;\n}\n\n/**\n * Read `raw` as one number with an optional unit, in SI. Null when `raw` is\n * not that form or names a unit no row spells, so the caller can read it as\n * an expression. A refused unit and an ambiguous one throw. The value may be\n * non-finite (`1e999`); the caller owns that refusal and its error class.\n * @internal\n */\nexport function readQuantityLiteral(raw: string, temperature: TemperatureReading = 'absolute'): QuantityLiteral | null {\n const literal = splitQuantityLiteral(raw);\n if (literal === null) return null;\n if (literal.unit === '') {\n return { value: scaleToNumber(literal.magnitude), dim: DIMENSIONLESS, unit: '', cycles: 0 };\n }\n let unit: UnitReading;\n try {\n unit = readUnit(literal.unit);\n } catch (error) {\n if (error instanceof UnknownUnitError) return null;\n throw error;\n }\n return {\n value: scaleToNumber(siMagnitude(literal.magnitude, unit, temperature)),\n dim: unit.dim,\n unit: literal.unit,\n cycles: unit.cycles,\n ...(unit.affine === undefined ? {} : { affine: unit.affine }),\n };\n}\n\n/** A value converted into a declared unit. @public */\nexport interface ConvertedValue {\n readonly value: number;\n /** The unit the user gave; `''` for a bare number. */\n readonly given: string;\n /** Net power of cycle-counting units in `given` (1 for `Hz` or `rpm`); absent when 0. */\n readonly cycles?: number;\n /** Set when `given` is a lone affine temperature. */\n readonly affine?: AffineTemperature;\n}\n\n/**\n * Convert `raw` (`<number>[unit]`) into `target` (a unit expression). A bare\n * number is taken to be in `target` already. The dimensions must agree.\n *\n * The magnitude, the unit scales and the target scale are multiplied as\n * exact rationals and rounded once, so `1 g/cm^3` in `kg/m^3` is 1000.\n *\n * @returns the value in `target`, and the unit the user gave (`''` for none).\n * @public\n */\nexport function convertValue(raw: string, target: string, temperature: TemperatureReading = 'absolute'): ConvertedValue {\n const literal = splitQuantityLiteral(raw);\n if (literal === null) throw new UnitError(`'${raw}' is not a number with an optional unit`);\n if (literal.unit === '') return { value: finiteLiteral(raw, scaleToNumber(literal.magnitude)), given: '' };\n const given = literal.unit;\n const readings = unitReadings(given);\n const to = readUnit(target);\n if (to.affine !== undefined) throw new UnitError(`a declared unit cannot be affine ('${target}')`);\n const matched = readings.filter((candidate) => equals(candidate.dim, to.dim));\n if (matched.length !== 1) {\n if (readings.length > 1) throw new AmbiguousUnitError(given, readings.map((r) => r.label));\n const from = readings[0];\n if (from === undefined) throw new UnknownUnitError(given);\n throw new UnitError(`'${given}' is ${format(from.dim)}, but this input is ${format(to.dim)} (${target || 'dimensionless'})`);\n }\n const from = matched[0]!;\n const value = scaleToNumber(divideScales(siMagnitude(literal.magnitude, from, temperature), to.exact));\n return {\n value: finiteLiteral(raw, value),\n given,\n ...(from.cycles === 0 ? {} : { cycles: from.cycles }),\n ...(from.affine === undefined ? {} : { affine: from.affine }),\n };\n}\n\n/** The dimension of a declared unit expression. @internal */\nexport function unitDimension(unit: string): Dimension {\n return parseUnit(unit).dim;\n}\n\n/** The symbols the unit table spells, with their exact scales, for the agreement test against MathTS. @internal */\nexport function unitRows(): ReadonlyMap<string, { readonly scale: ExactScale; readonly dim: Dimension; readonly prefixable: boolean }> {\n return UNITS;\n}\n\n/**\n * The tables conversion reads, for the CLI record's fingerprint (`src/cli/record-tables.ts`):\n * each row's scale, dimension, prefixability and `cycles` flag (which multiplies an angular\n * input by 2π), the prefixes, the Celsius offset, and the SHA-256 of `data/units.json`, so a\n * refused spelling, a prefix letter, an affine row or a note that changes changes the fingerprint too.\n * @internal\n */\nexport function unitTables(): {\n units: ReadonlyMap<string, readonly [number, Dimension, boolean, boolean]>;\n prefixes: ReadonlyMap<string, number>;\n celsiusOffsetK: number;\n sourceSha256: string;\n} {\n return {\n units: new Map([...UNITS].map(([symbol, r]) => [symbol, [scaleToNumber(r.scale), r.dim, r.prefixable, r.cycles === true] as const])),\n prefixes: new Map([...PREFIXES].map(([prefix, f]) => [prefix, scaleToNumber(f)] as const)),\n celsiusOffsetK: scaleToNumber(CELSIUS_OFFSET_K),\n sourceSha256: UNIT_DATA.sha256,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"units.js","sourceRoot":"","sources":["../../src/dimensional/units.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Unit parsing for numeric inputs: `1um`, `25degC`, `1 kohm`, `3.8e-16 kg/m^3`.\n *\n * A unit is a product of factors, each `symbol[^n]`, joined by `*`, `·` or a\n * space; everything after a single `/` is the denominator (`W/(m*K)` and\n * `W/m*K` both mean W·m⁻¹·K⁻¹). An exact symbol is matched before a prefixed\n * one, so `min` is a minute, `Pa` a pascal and `mm` a millimetre.\n *\n * An affine temperature (`degC`, `°C`, `degF`, `°F`) is accepted only alone.\n * The kelvin value is `value × scale + offset` for an absolute reading and\n * `value × scale` for a difference. Rankine is proportional (`°R × 5/9`), not\n * affine. The caller decides which reading, from the quantity's role.\n *\n * An exact symbol wins over a prefix: `T` is the tesla and `Ts` is a\n * terasecond; `G` is the gauss and `GPa` is a gigapascal; `P` is the poise\n * and `PV` is still a petavolt. A glued positive exponent is that power when\n * the letters are already a unit, so `K2` and `K²` are `K^2`.\n *\n * A token with no separator is one factor when the whole token is an exact\n * unit or a prefix plus a unit, with an optional exponent. That reading\n * wins on a bare token, so `ms` stays a millisecond, `mm` a millimetre,\n * `mK` a millikelvin, and `Ts` a terasecond. Inside a larger expression the\n * prefixed reading competes with a heterogeneous product (`mK` is millikelvin\n * or metre·kelvin; `ms` is millisecond or metre·second). A split that puts\n * a prefix letter's own unit twice in a row is never a reading, because a\n * power is written `m2` or `m^2`: `mm` is a millimetre, not metre·metre,\n * and `mmin` is metre·minute or millimetre·inch, not metre·metre·inch.\n * A unit that is not a prefix letter still juxtaposes with itself (`NN` is\n * N·N). `parseUnit` names\n * every remaining reading and refuses. `convertValue` keeps the one reading\n * whose dimension is the declared unit. A token that is not one factor is a\n * product when exactly one split exists: `m2K` is `m^2·K`, `Vs` is `V·s`,\n * and `cm^2/Vs` is `cm^2/(V·s)`. Zero splits are an unknown unit. Two or more\n * splits name each reading and are refused (`mAs` is milliampere·second or\n * metre·ampere·second). An unknown token that ends in a digit stays unknown\n * when it is not that product. A numerator that is the single token `1` is\n * the dimensionless unit, so `1/s` is a reciprocal second and `1/m^3` a\n * number density; `1` is not a symbol anywhere else.\n * The table is data: `data/units.json`, loaded and validated by\n * `unit-data.ts`. Every row, prefix, refused spelling, prefix letter, affine\n * scale and spelling note is a row there, with the reason as its `comment`;\n * this module holds the grammar. `myr` is a milliyear because `m` is the SI\n * prefix, and `eV` takes one, so `GeV` is 10⁹ eV in joules.\n *\n * @module dimensional/units\n */\nimport { Unit, exactScaleToNumber } from '@danielsimonjr/mathts-core';\nimport { equals, format, multiply, power } from './algebra.js';\nimport type { Dimension } from './types.js';\nimport {\n addScales,\n decimalScale,\n divideScales,\n multiplyScales,\n powerScale,\n ratioScale,\n scaleToNumber,\n solidusSides,\n UNIT_SCALE,\n type ExactScale,\n} from './exact-scale.js';\nimport {\n mathtsParsedDimension,\n unitExactScaleViaMathts,\n unitParserViaMathts,\n} from './mathts-unit-delegation.js';\nimport { applyBitScaleOverride, tryMathtsA5Reading, uptRefusalReason } from './mathts-unit-wrapper.js';\nimport { UNIT_DATA, type AffineRow as UnitDataAffineRow } from './unit-data.js';\n\n/** An affine temperature scale: a lone `degC` or `degF`. @public */\nexport type AffineTemperature = 'celsius' | 'fahrenheit';\n\n/** A unit, as a scale to SI base units and a dimension. @public */\nexport interface ParsedUnit {\n readonly scale: number;\n readonly dim: Dimension;\n /** Set only for a lone affine temperature, which needs a reading. */\n readonly affine?: AffineTemperature;\n}\n\n/** Thrown for any input that does not parse as a value with a known unit. @public */\nexport class UnitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UnitError';\n }\n}\n\n/** A symbol no table row and no prefix spells. @public */\nexport class UnknownUnitError extends UnitError {\n constructor(readonly symbol: string) {\n super(`unknown unit '${symbol}'`);\n this.name = 'UnknownUnitError';\n }\n}\n\n/**\n * A unit the reader recognizes and refuses: a logarithmic or ratio unit, an\n * ambiguous name such as `ton`, or an affine temperature inside a compound.\n * @public\n */\nexport class UnitRefusedError extends UnitError {\n constructor(message: string) {\n super(message);\n this.name = 'UnitRefusedError';\n }\n}\n\n/** A unit expression with more than one dimensionally distinct reading. @public */\nexport class AmbiguousUnitError extends UnitError {\n constructor(readonly text: string, readonly readings: readonly string[]) {\n super(`'${text}' is ambiguous: ${readings.join(' or ')}`);\n this.name = 'AmbiguousUnitError';\n }\n}\n\nconst D = (p: Partial<Dimension>): Dimension => ({ L: 0, M: 0, T: 0, I: 0, Theta: 0, N: 0, J: 0, ...p });\nconst DIMENSIONLESS = D({});\n\n/** symbol → exact scale to SI base, dimension, prefixability, cycle count. Rows are `data/units.json`. */\nconst UNITS = UNIT_DATA.units;\n\n/** Units that are a ratio or a log scale, and the reason each is not a plain factor. */\nconst REFUSED_UNITS = UNIT_DATA.refused;\n\n/**\n * Letters that are both an SI prefix and a unit of their own. Such a token\n * reads as the prefix reading and not as the unit times the rest: `Gyr` is a\n * gigayear. The file's `prefixLetterUnits.comment` says why `m` is not one.\n */\nconst PREFIX_LETTER_UNITS = UNIT_DATA.prefixLetterUnits;\n\n/** Kelvin at 0 °C, exactly. */\nconst CELSIUS_OFFSET_K = UNIT_DATA.iceKelvin;\n\ninterface AffineRow extends UnitDataAffineRow {\n readonly id: AffineTemperature;\n}\n\n/**\n * Lone spellings. A compound that contains one is refused. The schema's `id`\n * enum is {@link AffineTemperature}, held equal by a test: the public type\n * promises callers these ids, so a new affine scale is an API change.\n */\nconst AFFINE = UNIT_DATA.affine as readonly AffineRow[];\n\n/** Kelvin at a reading of zero, exactly: 273.15 − icePoint × scale. */\nfunction affineOffset(row: AffineRow): ExactScale {\n return addScales(CELSIUS_OFFSET_K, multiplyScales(ratioScale(-1, 1), row.icePoint, row.scale));\n}\n\nconst fractionText = (s: ExactScale): string => (s.den === 1n ? String(s.num) : `${s.num}/${s.den}`);\n\n/**\n * How a reading on an affine scale becomes kelvin, from the row's scale and\n * ice point: `absolute: (degF − 32) × 5/9 + 273.15`, `a difference: × 5/9, no offset`.\n * @internal\n */\nexport function affineReadingNote(affine: AffineTemperature, reading: TemperatureReading): string {\n const row = AFFINE.find((candidate) => candidate.id === affine)!;\n const unitScale = row.scale.num === row.scale.den;\n if (reading === 'difference') return unitScale ? 'a difference: no offset' : `a difference: × ${fractionText(row.scale)}, no offset`;\n const kelvin = String(scaleToNumber(CELSIUS_OFFSET_K));\n if (unitScale && row.icePoint.num === 0n) return `absolute: + ${kelvin}`;\n const shifted = row.icePoint.num === 0n ? row.symbols[0]! : `(${row.symbols[0]!} − ${fractionText(row.icePoint)})`;\n return `absolute: ${unitScale ? shifted : `${shifted} × ${fractionText(row.scale)}`} + ${kelvin}`;\n}\n\nfunction affineRow(text: string): AffineRow | undefined {\n return AFFINE.find((candidate) => candidate.symbols.includes(text));\n}\n\nconst PREFIXES = UNIT_DATA.prefixes;\n\ninterface SymbolReading {\n readonly scale: ExactScale;\n readonly dim: Dimension;\n readonly cycles: number;\n}\n\nfunction trySymbol(sym: string): SymbolReading | null {\n const exact = UNITS.get(sym);\n if (exact !== undefined) return { scale: exact.scale, dim: exact.dim, cycles: exact.cycles === true ? 1 : 0 };\n for (const [p, f] of PREFIXES) {\n if (!sym.startsWith(p) || sym.length === p.length) continue;\n const base = UNITS.get(sym.slice(p.length));\n if (base !== undefined && base.prefixable) {\n return { scale: multiplyScales(f, base.scale), dim: base.dim, cycles: base.cycles === true ? 1 : 0 };\n }\n }\n return null;\n}\n\nconst SUPERSCRIPT: Readonly<Record<string, number>> = { '¹': 1, '²': 2, '³': 3, '⁻¹': -1, '⁻²': -2, '⁻³': -3 };\n\ninterface FactorReading {\n readonly base: string;\n readonly exp: number;\n readonly scale: ExactScale;\n readonly dim: Dimension;\n readonly cycles: number;\n}\n\n/** One factor, or null when `token` is not exactly one unit with an optional exponent. */\nfunction tryOneFactor(token: string): FactorReading | null {\n let base = token;\n let exp = 1;\n const caret = /^(.+)\\^([+-]?\\d+)$/.exec(token);\n if (caret !== null) {\n base = caret[1]!;\n exp = Number(caret[2]);\n } else {\n const uni = /^(.*?)(⁻?[¹²³])$/.exec(token);\n const superExp = uni === null ? undefined : SUPERSCRIPT[uni[2]!];\n if (uni !== null && superExp !== undefined && uni[1]!.length > 0) {\n base = uni[1]!;\n exp = superExp;\n } else {\n const glued = /^(.*?)([1-9]\\d*)$/.exec(token);\n if (glued !== null && glued[1]!.length > 0 && trySymbol(glued[1]!) !== null) {\n base = glued[1]!;\n exp = Number(glued[2]);\n }\n }\n }\n const parsed = trySymbol(base);\n if (parsed === null || !Number.isFinite(exp)) return null;\n return { base, exp, scale: parsed.scale, dim: parsed.dim, cycles: parsed.cycles };\n}\n\nfunction formatReading(factors: readonly FactorReading[]): string {\n return factors.map((factor) => (factor.exp === 1 ? factor.base : `${factor.base}^${factor.exp}`)).join('·');\n}\n\n/** The unprefixed unit a prefix spelling attaches to, or null when `symbol` is exact. */\nfunction attachedUnit(symbol: string): string | null {\n if (UNITS.has(symbol)) return null;\n for (const [prefix] of PREFIXES) {\n if (!symbol.startsWith(prefix) || symbol.length === prefix.length) continue;\n const base = symbol.slice(prefix.length);\n const unitRow = UNITS.get(base);\n if (unitRow !== undefined && unitRow.prefixable) return base;\n }\n return null;\n}\n\n/**\n * `X·X` where `XX` is X's own prefix spelling (`m·m` beside `mm`, `d·d`\n * beside `dd`): not a split, because a power is written `X2` or `X^2`. A\n * run of a unit that is not also a prefix letter (`N·N`) stays a product.\n */\nfunction prefixRun(last: FactorReading, next: FactorReading): boolean {\n return last.base === next.base && attachedUnit(last.base + next.base) === last.base;\n}\n\n/**\n * Every way to split `token` into one or more factors. A one-factor token is\n * included. A split that puts a prefix letter's own unit twice in a row\n * (`m·m`, `m·m²`, `m·m·in`) is not a way, inside any split.\n */\nfunction segmentations(token: string): FactorReading[][] {\n const ways: FactorReading[][][] = Array.from({ length: token.length + 1 }, () => []);\n ways[0]!.push([]);\n for (let i = 0; i < token.length; i++) {\n if (ways[i]!.length === 0) continue;\n for (let j = i + 1; j <= token.length; j++) {\n const factor = tryOneFactor(token.slice(i, j));\n if (factor === null) continue;\n for (const prev of ways[i]!) {\n if (prev.length > 0 && prefixRun(prev[prev.length - 1]!, factor)) continue;\n ways[j]!.push([...prev, factor]);\n }\n }\n }\n const unique = new Map<string, FactorReading[]>();\n for (const way of ways[token.length]!) unique.set(formatReading(way), way);\n return [...unique.values()];\n}\n\n/**\n * Ways to read one token. A bare expression keeps a one-factor reading and\n * does not also split it. Inside a compound, a prefixed factor also competes\n * with each heterogeneous product; `segmentations` has already dropped the\n * homogeneous runs.\n */\nfunction tokenWays(token: string, compete: boolean, side: 'numerator' | 'denominator'): FactorReading[][] {\n const refused = REFUSED_UNITS.get(token);\n if (refused !== undefined) throw new UnitRefusedError(refused);\n const single = tryOneFactor(token);\n if (single !== null && !compete) return [[single]];\n // A prefixed numerator token is the prefix reading: `mN/m` is millinewton per metre.\n // A denominator keeps the product readings (`W/mK`), and a target dimension chooses.\n if (single !== null && side === 'numerator') return [[single]];\n const prefixWins = single !== null && PREFIX_LETTER_UNITS.has(token[0]!) && attachedUnit(single.base) !== null;\n const products = segmentations(token)\n .filter((way) => way.length > 1)\n .filter(() => !prefixWins);\n const ways: FactorReading[][] = [];\n if (single !== null) ways.push([single]);\n for (const way of products) ways.push(way);\n const unique = new Map<string, FactorReading[]>();\n for (const way of ways) unique.set(formatReading(way), way);\n const list = [...unique.values()];\n if (list.length === 0) throw new UnknownUnitError(token);\n return list;\n}\n\nfunction cartesian<T>(lists: readonly (readonly T[])[]): T[][] {\n let acc: T[][] = [[]];\n for (const list of lists) {\n const next: T[][] = [];\n for (const prev of acc) for (const item of list) next.push([...prev, item]);\n acc = next;\n }\n return acc;\n}\n\n/** One reading of a unit expression, with its exact scale. @internal */\nexport interface UnitReading extends ParsedUnit {\n readonly label: string;\n readonly exact: ExactScale;\n /** Net power of cycle-counting units (Hz, rpm): 1 for a lone `kHz`, 0 for `1/s`. */\n readonly cycles: number;\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\nfunction formatSide(tokens: readonly (readonly FactorReading[])[]): string {\n return tokens.map((factors) => formatReading(factors)).join('·');\n}\n\nfunction formatExpression(\n num: readonly (readonly FactorReading[])[],\n den: readonly (readonly FactorReading[])[],\n): string {\n // An empty numerator over a denominator is the dimensionless 1: `1/s`.\n const numerator = num.length === 0 ? '1' : formatSide(num);\n if (den.length === 0) return numerator;\n const denominator = formatSide(den);\n return denominator.includes('·') ? `${numerator}/(${denominator})` : `${numerator}/${denominator}`;\n}\n\nfunction accumulate(\n tokens: readonly (readonly FactorReading[])[],\n sign: 1 | -1,\n): { scale: ExactScale; dim: Dimension; cycles: number } {\n let scale = UNIT_SCALE;\n let dim = DIMENSIONLESS;\n let cycles = 0;\n for (const factors of tokens) {\n for (const factor of factors) {\n const n = sign * factor.exp;\n scale = multiplyScales(scale, powerScale(factor.scale, n));\n dim = multiply(dim, power(factor.dim, n));\n cycles += factor.cycles * n;\n }\n }\n return { scale, dim, cycles };\n}\n\nfunction reading(exact: ExactScale, dim: Dimension, label: string, cycles: number, affine?: AffineTemperature): UnitReading {\n return {\n scale: scaleToNumber(exact),\n exact,\n dim,\n label,\n cycles,\n ...(affine === undefined ? {} : { affine }),\n };\n}\n\nlet lastReadingSource: { readonly text: string; readonly kind: 'mathts' | 'local' } | null = null;\n\nfunction applyMathtsExactScale(text: string, local: UnitReading): UnitReading {\n if (!unitExactScaleViaMathts(text, local.scale, local.exact, local.dim)) return local;\n const core = Unit.exactScale(text.trim());\n if (core === null) return local;\n return { ...local, scale: exactScaleToNumber(core) };\n}\n\n/**\n * Every dimensionally distinct reading of one unit expression (local grammar).\n *\n * The unit grammar is not the formula grammar, and the difference is\n * deliberate: a unit symbol is not an identifier (a prefix, a glued product\n * or a glued power lives inside one token: `mN`, `m2K`, `Vs`, `K²`, `°C`,\n * `%`), and everything after the first `/` is the denominator, the\n * single-solidus convention of ISO 80000-1 (`W/m*K` is W·m⁻¹·K⁻¹), where the\n * formula grammar would read `(W/m)·K`.\n * @internal\n */\nfunction localUnitReadings(text: string): UnitReading[] {\n const t = text.trim();\n if (t === '' || t === '1') return [reading(UNIT_SCALE, DIMENSIONLESS, '1', 0)];\n const affine = affineRow(t);\n if (affine !== undefined) return [reading(affine.scale, D({ Theta: 1 }), t, 0, affine.id)];\n if (\n AFFINE.some((candidate) => candidate.symbols.some((symbol) => t.includes(symbol))) ||\n /deg\\s+[CFcf]|°\\s*[CFcf]/.test(t)\n ) {\n throw new UnitRefusedError('an affine temperature cannot be part of a compound unit; give K');\n }\n // An operator with nothing on one side (`m/`, `m//s`, `m*`, `*m`, `m/*s`) is not a unit\n // text; it was read as if the empty factor were 1 (Tom's second round). A leading `/`\n // (`/s`) stays the dimensionless numerator.\n if (/[*·/]\\s*$|^\\s*[*·]|[*·/]\\s*[*·/]/.test(t)) throw new UnknownUnitError(t);\n // A chain is one denominator: `km/s/Mpc` is km/(s·Mpc), the way the Hubble constant is written.\n const sides = solidusSides(t);\n const compete = /[*·/\\s]/.test(t);\n const numeratorTokens = sideTokens(sides.numerator);\n // A numerator that is the single token `1` is the dimensionless unit: `1/s`, `1/m^3`.\n const numerator = numeratorTokens.length === 1 && numeratorTokens[0] === '1' ? [] : numeratorTokens;\n const denominator = sides.denominator === '' ? [] : sideTokens(sides.denominator);\n // `/s` is a dimensionless numerator over seconds. A bare `/` is not a unit.\n if (numerator.length === 0 && denominator.length === 0) throw new UnknownUnitError(t);\n const numWays = numerator.map((token) => tokenWays(token, compete, 'numerator'));\n const denWays = denominator.map((token) => tokenWays(token, compete, 'denominator'));\n const numCombos = numerator.length === 0 ? [[]] : cartesian(numWays);\n const denCombos = denominator.length === 0 ? [[]] : cartesian(denWays);\n const unique = new Map<string, UnitReading>();\n for (const num of numCombos) {\n for (const den of denCombos) {\n const n = accumulate(num, 1);\n const d = accumulate(den, -1);\n const label = formatExpression(num, den);\n unique.set(label, reading(multiplyScales(n.scale, d.scale), multiply(n.dim, d.dim), label, n.cycles + d.cycles));\n }\n }\n return [...unique.values()];\n}\n\nfunction unitReadings(text: string): UnitReading[] {\n const t = text.trim();\n lastReadingSource = { text: t, kind: 'local' };\n const refusal = uptRefusalReason(t);\n if (refusal !== null) throw new UnitRefusedError(refusal);\n\n const a5 = tryMathtsA5Reading(t);\n if (a5 !== null) {\n // A12 partial: A5 in-set texts skip localUnitReadings when MathTS agrees.\n lastReadingSource = { text: t, kind: 'mathts' };\n const affine = affineRow(t);\n return [\n reading(a5.exact, a5.dim, t, a5.cycles, affine?.id),\n ];\n }\n\n const readings = localUnitReadings(text);\n if (readings.length === 1) {\n const local = readings[0]!;\n if (unitParserViaMathts(t, local.scale, local.exact, local.dim)) {\n lastReadingSource = { text: t, kind: 'mathts' };\n const core = Unit.exactScale(t);\n const scale = core === null ? local.scale : exactScaleToNumber(core);\n const overridden = applyBitScaleOverride(t, local.exact, scale);\n return [\n {\n ...local,\n dim: mathtsParsedDimension(t, local.dim),\n exact: overridden.exact,\n scale: overridden.scale,\n },\n ];\n }\n const scaled = applyMathtsExactScale(t, local);\n const overridden = applyBitScaleOverride(t, scaled.exact, scaled.scale);\n return [{ ...scaled, exact: overridden.exact, scale: overridden.scale }];\n }\n return readings;\n}\n\n/**\n * Spellings that convert correctly and still mean something else to a reader:\n * the `spellingNotes` of `data/units.json` for each symbol in `given`, in file\n * order. `myr` is a milliyear, bare `G` is the gauss, bare `A` the ampere.\n * @internal\n */\nexport function unitConventionNotes(given: string): string[] {\n const symbols = new Set(given.split(/[*·/\\s^0-9()+-]+/).filter((s) => s.length > 0));\n return [...UNIT_DATA.spellingNotes].filter(([spelling]) => symbols.has(spelling)).map(([, note]) => note);\n}\n\n/** The one reading of a unit expression; more than one is refused. @internal */\nexport function readUnit(text: string): UnitReading {\n const t = text.trim();\n const readings = unitReadings(t);\n if (readings.length !== 1) throw new AmbiguousUnitError(t, readings.map((r) => r.label));\n return readings[0]!;\n}\n\n/** Which reader parsed `text` last: local grammar or MathTS `Unit.parse`. @internal */\nexport function unitReadingsSource(text: string): 'mathts' | 'local' {\n readUnit(text);\n const t = text.trim();\n return lastReadingSource !== null && lastReadingSource.text === t ? lastReadingSource.kind : 'local';\n}\n\n/** Parse a unit expression; the empty string is dimensionless. @public */\nexport function parseUnit(text: string): ParsedUnit {\n const r = readUnit(text);\n return { scale: r.scale, dim: r.dim, ...(r.affine !== undefined ? { affine: r.affine } : {}) };\n}\n\n/** How a temperature value is read: as a point on the scale, or as a difference. @public */\nexport type TemperatureReading = 'absolute' | 'difference';\n\n/** The SI magnitude of `magnitude` in `unit`, exactly. An absolute affine reading adds its offset. */\nfunction siMagnitude(magnitude: ExactScale, unit: UnitReading, temperature: TemperatureReading): ExactScale {\n const scaled = multiplyScales(magnitude, unit.exact);\n const row = unit.affine === undefined ? undefined : AFFINE.find((candidate) => candidate.id === unit.affine);\n return row !== undefined && temperature === 'absolute' ? addScales(scaled, affineOffset(row)) : scaled;\n}\n\nconst FRACTION = /^\\s*([+-]?(?:\\d+\\.?\\d*|\\.\\d+))\\s*\\/\\s*((?:\\d+\\.?\\d*|\\.\\d+))\\s*$/;\nconst NUMBER_THEN_REST = /^\\s*([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)\\s*(.*?)\\s*$/;\n\n/**\n * `raw` split into an exact decimal magnitude and the unit text after it, or\n * null when `raw` is not a number followed by an optional unit. A plain\n * fraction (`1/3`) is a number. Text that begins with an operator (`*h`,\n * `·c`) is an expression, not a unit.\n * @internal\n */\nfunction splitQuantityLiteral(raw: string): { readonly magnitude: ExactScale; readonly unit: string } | null {\n const fraction = FRACTION.exec(raw);\n if (fraction !== null) {\n const den = decimalScale(fraction[2]!)!;\n if (den.num !== 0n) return { magnitude: divideScales(decimalScale(fraction[1]!)!, den), unit: '' };\n }\n const m = NUMBER_THEN_REST.exec(raw);\n if (m === null) return null;\n const unit = m[2]!;\n if (unit.startsWith('*') || unit.startsWith('·')) return null;\n const magnitude = decimalScale(m[1]!);\n return magnitude === null ? null : { magnitude, unit };\n}\n\n/** A number with a unit, read exactly and rounded once. @internal */\nexport interface QuantityLiteral {\n /** SI value; a bare number is unchanged. */\n readonly value: number;\n readonly dim: Dimension;\n /** The unit text as given; `''` for a bare number. */\n readonly unit: string;\n readonly cycles: number;\n readonly affine?: AffineTemperature;\n}\n\nfunction finiteLiteral(raw: string, value: number): number {\n if (!Number.isFinite(value)) throw new UnitError(`'${raw}' is not a finite number`);\n return value;\n}\n\n/**\n * Read `raw` as one number with an optional unit, in SI. Null when `raw` is\n * not that form or names a unit no row spells, so the caller can read it as\n * an expression. A refused unit and an ambiguous one throw. The value may be\n * non-finite (`1e999`); the caller owns that refusal and its error class.\n * @internal\n */\nexport function readQuantityLiteral(raw: string, temperature: TemperatureReading = 'absolute'): QuantityLiteral | null {\n const literal = splitQuantityLiteral(raw);\n if (literal === null) return null;\n if (literal.unit === '') {\n return { value: scaleToNumber(literal.magnitude), dim: DIMENSIONLESS, unit: '', cycles: 0 };\n }\n let unit: UnitReading;\n try {\n unit = readUnit(literal.unit);\n } catch (error) {\n if (error instanceof UnknownUnitError) return null;\n throw error;\n }\n return {\n value: scaleToNumber(siMagnitude(literal.magnitude, unit, temperature)),\n dim: unit.dim,\n unit: literal.unit,\n cycles: unit.cycles,\n ...(unit.affine === undefined ? {} : { affine: unit.affine }),\n };\n}\n\n/** A value converted into a declared unit. @public */\nexport interface ConvertedValue {\n readonly value: number;\n /** The unit the user gave; `''` for a bare number. */\n readonly given: string;\n /** Net power of cycle-counting units in `given` (1 for `Hz` or `rpm`); absent when 0. */\n readonly cycles?: number;\n /** Set when `given` is a lone affine temperature. */\n readonly affine?: AffineTemperature;\n}\n\n/**\n * Convert `raw` (`<number>[unit]`) into `target` (a unit expression). A bare\n * number is taken to be in `target` already. The dimensions must agree.\n *\n * The magnitude, the unit scales and the target scale are multiplied as\n * exact rationals and rounded once, so `1 g/cm^3` in `kg/m^3` is 1000.\n *\n * @returns the value in `target`, and the unit the user gave (`''` for none).\n * @public\n */\nexport function convertValue(raw: string, target: string, temperature: TemperatureReading = 'absolute'): ConvertedValue {\n const literal = splitQuantityLiteral(raw);\n if (literal === null) throw new UnitError(`'${raw}' is not a number with an optional unit`);\n if (literal.unit === '') return { value: finiteLiteral(raw, scaleToNumber(literal.magnitude)), given: '' };\n const given = literal.unit;\n const readings = unitReadings(given);\n const to = readUnit(target);\n if (to.affine !== undefined) throw new UnitError(`a declared unit cannot be affine ('${target}')`);\n const matched = readings.filter((candidate) => equals(candidate.dim, to.dim));\n if (matched.length !== 1) {\n if (readings.length > 1) throw new AmbiguousUnitError(given, readings.map((r) => r.label));\n const from = readings[0];\n if (from === undefined) throw new UnknownUnitError(given);\n throw new UnitError(`'${given}' is ${format(from.dim)}, but this input is ${format(to.dim)} (${target || 'dimensionless'})`);\n }\n const from = matched[0]!;\n const value = scaleToNumber(divideScales(siMagnitude(literal.magnitude, from, temperature), to.exact));\n return {\n value: finiteLiteral(raw, value),\n given,\n ...(from.cycles === 0 ? {} : { cycles: from.cycles }),\n ...(from.affine === undefined ? {} : { affine: from.affine }),\n };\n}\n\n/** The dimension of a declared unit expression. @internal */\nexport function unitDimension(unit: string): Dimension {\n return parseUnit(unit).dim;\n}\n\n/** The symbols the unit table spells, with their exact scales, for the agreement test against MathTS. @internal */\nexport function unitRows(): ReadonlyMap<string, { readonly scale: ExactScale; readonly dim: Dimension; readonly prefixable: boolean }> {\n return UNITS;\n}\n\n/**\n * The tables conversion reads, for the CLI record's fingerprint (`src/cli/record-tables.ts`):\n * each row's scale, dimension, prefixability and `cycles` flag (which multiplies an angular\n * input by 2π), the prefixes, the Celsius offset, and the SHA-256 of `data/units.json`, so a\n * refused spelling, a prefix letter, an affine row or a note that changes changes the fingerprint too.\n * @internal\n */\nexport function unitTables(): {\n units: ReadonlyMap<string, readonly [number, Dimension, boolean, boolean]>;\n prefixes: ReadonlyMap<string, number>;\n celsiusOffsetK: number;\n sourceSha256: string;\n} {\n return {\n units: new Map([...UNITS].map(([symbol, r]) => [symbol, [scaleToNumber(r.scale), r.dim, r.prefixable, r.cycles === true] as const])),\n prefixes: new Map([...PREFIXES].map(([prefix, f]) => [prefix, scaleToNumber(f)] as const)),\n celsiusOffsetK: scaleToNumber(CELSIUS_OFFSET_K),\n sourceSha256: UNIT_DATA.sha256,\n };\n}\n"]}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { Dimension } from './types.js';
|
|
17
17
|
import type { ExprNode, MetricTensorNode } from './ast-types.js';
|
|
18
18
|
export type { ExprNode, TranscendentalFn, TensorSymbolNode, TensorProductNode, TensorIndex, Variance, Role, MetricTensorNode, KroneckerDeltaNode, TensorPartialDerivativeNode, CovariantIndex, UpperIndex, CovariantDerivativeNode, RiemannTensorNode, RicciTensorNode, EinsteinTensorNode, BianchiResidualNode, KillingVectorNode, ConservedChargeNode, StressEnergyTensorNode, CosmologicalConstantNode, EinsteinFieldEquationNode, WeylTensorNode, KretschmannScalarNode, } from './ast-types.js';
|
|
19
|
+
/** One dimensional violation that validation found in an expression. */
|
|
19
20
|
export interface Violation {
|
|
20
21
|
/** Tree path, e.g. "args[1].args[0]". Empty string for the root. */
|
|
21
22
|
location: string;
|
|
@@ -26,6 +27,7 @@ export interface Violation {
|
|
|
26
27
|
* validation (ValidationResult.ok stays true) but are still reported. */
|
|
27
28
|
severity?: 'error' | 'warning';
|
|
28
29
|
}
|
|
30
|
+
/** The result of validating one expression: its verdict, dimension, free indices and violations. */
|
|
29
31
|
export interface ValidationResult {
|
|
30
32
|
ok: boolean;
|
|
31
33
|
inferredDimension: Dimension | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/dimensional/validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,SAAS,EAEV,MAAM,YAAY,CAAC;AAqBpB,OAAO,KAAK,EACV,QAAQ,EAIR,gBAAgB,EAejB,MAAM,gBAAgB,CAAC;AAwBxB,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,gBAAgB,EAChB,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,SAAS;IACxB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb;8EAC0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,iBAAiB,EAAE,SAAS,GAAG,IAAI,CAAC;IACpC;;qDAEiD;IACjD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAusBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,gBAAgB,CASzD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,GACvB,SAAS,EAAE,CAUb;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CA8C/E"}
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/dimensional/validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,SAAS,EAEV,MAAM,YAAY,CAAC;AAqBpB,OAAO,KAAK,EACV,QAAQ,EAIR,gBAAgB,EAejB,MAAM,gBAAgB,CAAC;AAwBxB,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,gBAAgB,EAChB,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,UAAU,EACV,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAExB,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb;8EAC0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,oGAAoG;AACpG,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,iBAAiB,EAAE,SAAS,GAAG,IAAI,CAAC;IACpC;;qDAEiD;IACjD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAusBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,gBAAgB,CASzD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,gBAAgB,GACvB,SAAS,EAAE,CAUb;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CA8C/E"}
|