universal-physics-tensor 0.7.3 → 0.15.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 +147 -109
- package/bin/upt.mjs +508 -0
- package/dist/bridges/be23-planckian-confrontation.d.ts +162 -0
- package/dist/bridges/be23-planckian-confrontation.d.ts.map +1 -0
- package/dist/bridges/be23-planckian-confrontation.js +196 -0
- package/dist/bridges/be23-planckian-confrontation.js.map +1 -0
- package/dist/bridges/be36-gw170817-confrontation.d.ts +111 -0
- package/dist/bridges/be36-gw170817-confrontation.d.ts.map +1 -0
- package/dist/bridges/be36-gw170817-confrontation.js +100 -0
- package/dist/bridges/be36-gw170817-confrontation.js.map +1 -0
- package/dist/bridges/bridge-equations.d.ts +129 -0
- package/dist/bridges/bridge-equations.d.ts.map +1 -0
- package/dist/bridges/bridge-equations.js +130 -0
- package/dist/bridges/bridge-equations.js.map +1 -0
- package/dist/bridges/catalog-adapter.d.ts +1 -1
- package/dist/bridges/catalog-adapter.js +1 -1
- package/dist/bridges/confrontation-coverage.d.ts +67 -0
- package/dist/bridges/confrontation-coverage.d.ts.map +1 -0
- package/dist/bridges/confrontation-coverage.js +83 -0
- package/dist/bridges/confrontation-coverage.js.map +1 -0
- package/dist/bridges/equations/_be-helpers.d.ts +2 -1
- package/dist/bridges/equations/_be-helpers.d.ts.map +1 -1
- package/dist/bridges/equations/be-12-coherence-length.d.ts +1 -1
- package/dist/bridges/equations/be-13-einstein-trace.d.ts +2 -2
- package/dist/bridges/equations/be-13-einstein-trace.js +1 -1
- package/dist/bridges/equations/be-14-ryu-takayanagi.d.ts +2 -2
- package/dist/bridges/equations/be-15-emergence.d.ts +19 -5
- package/dist/bridges/equations/be-15-emergence.d.ts.map +1 -1
- package/dist/bridges/equations/be-15-emergence.js +18 -4
- package/dist/bridges/equations/be-15-emergence.js.map +1 -1
- package/dist/bridges/equations/be-16-landauer.d.ts +1 -1
- package/dist/bridges/equations/be-17-einstein-cartan.d.ts +1 -1
- package/dist/bridges/equations/be-18-higgs-mass.d.ts +1 -1
- package/dist/bridges/equations/be-19-quantum-bounce.d.ts +1 -1
- package/dist/bridges/equations/be-20-vacuum-energy.d.ts +4 -4
- package/dist/bridges/equations/be-20-vacuum-energy.d.ts.map +1 -1
- package/dist/bridges/equations/be-20-vacuum-energy.js +4 -2
- package/dist/bridges/equations/be-20-vacuum-energy.js.map +1 -1
- package/dist/bridges/equations/be-22-topological-entanglement.d.ts +1 -1
- package/dist/bridges/equations/be-23-syk-planckian.d.ts +1 -1
- package/dist/bridges/equations/be-24-foerster-fret.d.ts +1 -1
- package/dist/bridges/equations/be-25-iit-phi.d.ts +1 -1
- package/dist/bridges/equations/be-25-orch-or.d.ts +13 -1
- package/dist/bridges/equations/be-25-orch-or.d.ts.map +1 -1
- package/dist/bridges/equations/be-25-orch-or.js +12 -0
- package/dist/bridges/equations/be-25-orch-or.js.map +1 -1
- package/dist/bridges/equations/be-26-dna-tunneling.d.ts +2 -2
- package/dist/bridges/equations/be-26-dna-tunneling.js +1 -1
- package/dist/bridges/equations/be-27-effective-temperature.d.ts +1 -1
- package/dist/bridges/equations/be-28-onsager-entropy-production.d.ts +1 -1
- package/dist/bridges/equations/be-29-jarzynski.d.ts +1 -1
- package/dist/bridges/equations/be-30-flm-first-law.d.ts +2 -2
- package/dist/bridges/equations/be-31-causal-set-bd.d.ts +1 -1
- package/dist/bridges/equations/be-32-quantum-reference-frame.d.ts +1 -1
- package/dist/bridges/equations/be-33-hertz-millis.d.ts +1 -1
- package/dist/bridges/equations/be-34-kibble-zurek.d.ts +1 -1
- package/dist/bridges/equations/be-35-conformal-bootstrap.d.ts +1 -1
- package/dist/bridges/equations/be-36-gw-speed-bound.d.ts +12 -5
- package/dist/bridges/equations/be-36-gw-speed-bound.d.ts.map +1 -1
- package/dist/bridges/equations/be-36-gw-speed-bound.js +11 -4
- package/dist/bridges/equations/be-36-gw-speed-bound.js.map +1 -1
- package/dist/bridges/equations/be-38-mond.d.ts +1 -1
- package/dist/bridges/equations/be-39-asymptotic-safety.d.ts +2 -2
- package/dist/bridges/equations/be-40-composite-higgs.d.ts +1 -1
- package/dist/bridges/equations/be-41-swampland.d.ts +1 -1
- package/dist/bridges/equations/be-43-er-epr.d.ts +1 -1
- package/dist/bridges/equations/be-44-soft-hair.d.ts +1 -1
- package/dist/bridges/equations/be-45-tcc.d.ts +1 -1
- package/dist/bridges/equations/be-46-multiverse-measure.d.ts +1 -1
- package/dist/bridges/equations/be-47-bbn-dark-sector.d.ts +1 -1
- package/dist/bridges/equations/be-48-grw-localization.d.ts +1 -1
- package/dist/bridges/equations/be-49-quantum-darwinism.d.ts +1 -1
- package/dist/bridges/equations/be-50-wheeler-feynman.d.ts +1 -1
- package/dist/bridges/index.d.ts +10 -7
- package/dist/bridges/index.d.ts.map +1 -1
- package/dist/bridges/index.js +47 -34
- package/dist/bridges/index.js.map +1 -1
- package/dist/bridges/membership.d.ts +44 -0
- package/dist/bridges/membership.d.ts.map +1 -0
- package/dist/bridges/membership.js +59 -0
- package/dist/bridges/membership.js.map +1 -0
- package/dist/bridges/rejected.d.ts +40 -0
- package/dist/bridges/rejected.d.ts.map +1 -0
- package/dist/bridges/rejected.js +81 -0
- package/dist/bridges/rejected.js.map +1 -0
- package/dist/composition/bridge-analysis.d.ts +189 -0
- package/dist/composition/bridge-analysis.d.ts.map +1 -0
- package/dist/composition/bridge-analysis.js +445 -0
- package/dist/composition/bridge-analysis.js.map +1 -0
- package/dist/composition/bridge-prediction.d.ts +95 -0
- package/dist/composition/bridge-prediction.d.ts.map +1 -0
- package/dist/composition/bridge-prediction.js +0 -0
- package/dist/composition/bridge-prediction.js.map +1 -0
- package/dist/composition/catalog-graph.d.ts +20 -0
- package/dist/composition/catalog-graph.d.ts.map +1 -0
- package/dist/composition/catalog-graph.js +39 -0
- package/dist/composition/catalog-graph.js.map +1 -0
- package/dist/composition/compose-surface.d.ts +12 -0
- package/dist/composition/compose-surface.d.ts.map +1 -0
- package/dist/composition/compose-surface.js +10 -0
- package/dist/composition/compose-surface.js.map +1 -0
- package/dist/composition/compose-symbolic.d.ts +75 -0
- package/dist/composition/compose-symbolic.d.ts.map +1 -0
- package/dist/composition/compose-symbolic.js +157 -0
- package/dist/composition/compose-symbolic.js.map +1 -0
- package/dist/composition/compose.d.ts +110 -0
- package/dist/composition/compose.d.ts.map +1 -0
- package/dist/composition/compose.js +231 -0
- package/dist/composition/compose.js.map +1 -0
- package/dist/composition/consistency.d.ts +24 -0
- package/dist/composition/consistency.d.ts.map +1 -0
- package/dist/composition/consistency.js +26 -0
- package/dist/composition/consistency.js.map +1 -0
- package/dist/composition/discovery.d.ts +104 -0
- package/dist/composition/discovery.d.ts.map +1 -0
- package/dist/composition/discovery.js +165 -0
- package/dist/composition/discovery.js.map +1 -0
- package/dist/composition/edge.d.ts +139 -0
- package/dist/composition/edge.d.ts.map +1 -0
- package/dist/composition/edge.js +72 -0
- package/dist/composition/edge.js.map +1 -0
- package/dist/composition/edges/calibration.d.ts +107 -0
- package/dist/composition/edges/calibration.d.ts.map +1 -0
- package/dist/composition/edges/calibration.js +373 -0
- package/dist/composition/edges/calibration.js.map +1 -0
- package/dist/composition/edges/catalog-full.d.ts +299 -0
- package/dist/composition/edges/catalog-full.d.ts.map +1 -0
- package/dist/composition/edges/catalog-full.js +989 -0
- package/dist/composition/edges/catalog-full.js.map +1 -0
- package/dist/composition/edges/catalog-tranche.d.ts +112 -0
- package/dist/composition/edges/catalog-tranche.d.ts.map +1 -0
- package/dist/composition/edges/catalog-tranche.js +241 -0
- package/dist/composition/edges/catalog-tranche.js.map +1 -0
- package/dist/composition/enumerate.d.ts +67 -0
- package/dist/composition/enumerate.d.ts.map +1 -0
- package/dist/composition/enumerate.js +78 -0
- package/dist/composition/enumerate.js.map +1 -0
- package/dist/composition/explain.d.ts +102 -0
- package/dist/composition/explain.d.ts.map +1 -0
- package/dist/composition/explain.js +244 -0
- package/dist/composition/explain.js.map +1 -0
- package/dist/composition/expr-eval.d.ts +33 -0
- package/dist/composition/expr-eval.d.ts.map +1 -0
- package/dist/composition/expr-eval.js +95 -0
- package/dist/composition/expr-eval.js.map +1 -0
- package/dist/composition/expr-simplify.d.ts +60 -0
- package/dist/composition/expr-simplify.d.ts.map +1 -0
- package/dist/composition/expr-simplify.js +330 -0
- package/dist/composition/expr-simplify.js.map +1 -0
- package/dist/composition/expr-subst.d.ts +29 -0
- package/dist/composition/expr-subst.d.ts.map +1 -0
- package/dist/composition/expr-subst.js +60 -0
- package/dist/composition/expr-subst.js.map +1 -0
- package/dist/composition/identifiability.d.ts +103 -0
- package/dist/composition/identifiability.d.ts.map +1 -0
- package/dist/composition/identifiability.js +148 -0
- package/dist/composition/identifiability.js.map +1 -0
- package/dist/composition/index.d.ts +37 -0
- package/dist/composition/index.d.ts.map +1 -0
- package/dist/composition/index.js +27 -0
- package/dist/composition/index.js.map +1 -0
- package/dist/composition/quantities.d.ts +297 -0
- package/dist/composition/quantities.d.ts.map +1 -0
- package/dist/composition/quantities.js +1017 -0
- package/dist/composition/quantities.js.map +1 -0
- package/dist/composition/quantity.d.ts +59 -0
- package/dist/composition/quantity.d.ts.map +1 -0
- package/dist/composition/quantity.js +36 -0
- package/dist/composition/quantity.js.map +1 -0
- package/dist/composition/retrodiction.d.ts +94 -0
- package/dist/composition/retrodiction.d.ts.map +1 -0
- package/dist/composition/retrodiction.js +171 -0
- package/dist/composition/retrodiction.js.map +1 -0
- package/dist/composition/symbolic-constants.d.ts +33 -0
- package/dist/composition/symbolic-constants.d.ts.map +1 -0
- package/dist/composition/symbolic-constants.js +50 -0
- package/dist/composition/symbolic-constants.js.map +1 -0
- package/dist/composition/uncertainty.d.ts +45 -0
- package/dist/composition/uncertainty.d.ts.map +1 -0
- package/dist/composition/uncertainty.js +59 -0
- package/dist/composition/uncertainty.js.map +1 -0
- package/dist/core/axes-registry.d.ts +1 -1
- package/dist/core/axes-registry.js +1 -1
- package/dist/core/cell.d.ts +0 -8
- package/dist/core/cell.d.ts.map +1 -1
- package/dist/core/cell.js +1 -1
- package/dist/core/cell.js.map +1 -1
- package/dist/core/constants.d.ts +15 -1
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +15 -1
- package/dist/core/constants.js.map +1 -1
- package/dist/core/flux-rules.d.ts +10 -13
- package/dist/core/flux-rules.d.ts.map +1 -1
- package/dist/core/flux-rules.js +19 -10
- package/dist/core/flux-rules.js.map +1 -1
- package/dist/core/labeled-tensor.d.ts +80 -1
- package/dist/core/labeled-tensor.d.ts.map +1 -1
- package/dist/core/labeled-tensor.js +263 -17
- package/dist/core/labeled-tensor.js.map +1 -1
- package/dist/core/universal-index.d.ts +1 -1
- package/dist/core/universal-index.js +1 -1
- package/dist/diff/bridge-gradient.d.ts +51 -8
- package/dist/diff/bridge-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-gradient.js +75 -8
- package/dist/diff/bridge-gradient.js.map +1 -1
- package/dist/dimensional/buckingham.d.ts +103 -0
- package/dist/dimensional/buckingham.d.ts.map +1 -0
- package/dist/dimensional/buckingham.js +284 -0
- package/dist/dimensional/buckingham.js.map +1 -0
- package/dist/dimensional/dimension-spec.d.ts +24 -0
- package/dist/dimensional/dimension-spec.d.ts.map +1 -0
- package/dist/dimensional/dimension-spec.js +110 -0
- package/dist/dimensional/dimension-spec.js.map +1 -0
- package/dist/dimensional/field-equation-helpers.d.ts +1 -1
- package/dist/dimensional/field-equation-helpers.js +1 -1
- package/dist/dimensional/friedmann-equation.d.ts +1 -1
- package/dist/dimensional/friedmann-equation.js +1 -1
- package/dist/dimensional/gauge-field.d.ts +1 -1
- package/dist/dimensional/gauge-field.js +1 -1
- package/dist/dimensional/klein-gordon-equation.d.ts +8 -5
- package/dist/dimensional/klein-gordon-equation.d.ts.map +1 -1
- package/dist/dimensional/klein-gordon-equation.js +8 -5
- package/dist/dimensional/klein-gordon-equation.js.map +1 -1
- package/dist/dimensional/tensor-trace.d.ts +1 -1
- package/dist/dimensional/tensor-trace.js +1 -1
- package/dist/dimensional/validator.d.ts +13 -3
- package/dist/dimensional/validator.d.ts.map +1 -1
- package/dist/dimensional/validator.js +129 -42
- package/dist/dimensional/validator.js.map +1 -1
- package/dist/index.d.ts +34 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +64 -3
- package/dist/index.js.map +1 -1
- package/dist/numerical/be37-covariant-eikonal.d.ts.map +1 -1
- package/dist/numerical/be37-covariant-eikonal.js +15 -18
- package/dist/numerical/be37-covariant-eikonal.js.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.d.ts +7 -13
- package/dist/numerical/curvature-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +1 -1
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/derivative-lowering.d.ts +2 -1
- package/dist/numerical/derivative-lowering.d.ts.map +1 -1
- package/dist/numerical/formula-dimension.d.ts +40 -0
- package/dist/numerical/formula-dimension.d.ts.map +1 -0
- package/dist/numerical/formula-dimension.js +199 -0
- package/dist/numerical/formula-dimension.js.map +1 -0
- package/dist/numerical/formula-mathts.d.ts +27 -0
- package/dist/numerical/formula-mathts.d.ts.map +1 -0
- package/dist/numerical/formula-mathts.js +98 -0
- package/dist/numerical/formula-mathts.js.map +1 -0
- package/dist/numerical/formula-registry.d.ts +30 -0
- package/dist/numerical/formula-registry.d.ts.map +1 -0
- package/dist/numerical/formula-registry.js +88 -0
- package/dist/numerical/formula-registry.js.map +1 -0
- package/dist/numerical/formula.d.ts +75 -0
- package/dist/numerical/formula.d.ts.map +1 -0
- package/dist/numerical/formula.js +275 -0
- package/dist/numerical/formula.js.map +1 -0
- package/dist/numerical/geometrized.d.ts +51 -0
- package/dist/numerical/geometrized.d.ts.map +1 -0
- package/dist/numerical/geometrized.js +66 -0
- package/dist/numerical/geometrized.js.map +1 -0
- package/dist/numerical/gl4-integrator.d.ts +8 -6
- package/dist/numerical/gl4-integrator.d.ts.map +1 -1
- package/dist/numerical/gl4-integrator.js +6 -6
- package/dist/numerical/gl4-integrator.js.map +1 -1
- package/dist/numerical/klein-gordon.d.ts +145 -0
- package/dist/numerical/klein-gordon.d.ts.map +1 -0
- package/dist/numerical/klein-gordon.js +145 -0
- package/dist/numerical/klein-gordon.js.map +1 -0
- package/dist/numerical/kretschmann.d.ts +43 -12
- package/dist/numerical/kretschmann.d.ts.map +1 -1
- package/dist/numerical/kretschmann.js +116 -29
- package/dist/numerical/kretschmann.js.map +1 -1
- package/dist/numerical/lowering.d.ts +18 -0
- package/dist/numerical/lowering.d.ts.map +1 -1
- package/dist/numerical/lowering.js +54 -42
- package/dist/numerical/lowering.js.map +1 -1
- package/dist/numerical/null-ic.d.ts +1 -1
- package/dist/numerical/null-ic.d.ts.map +1 -1
- package/dist/numerical/null-ic.js +3 -2
- package/dist/numerical/null-ic.js.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.d.ts +18 -6
- package/dist/numerical/painleve-gullstrand-metric.d.ts.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.js +31 -16
- package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
- package/dist/numerical/perihelion-finder.d.ts +4 -3
- package/dist/numerical/perihelion-finder.d.ts.map +1 -1
- package/dist/numerical/perihelion-finder.js +5 -4
- package/dist/numerical/perihelion-finder.js.map +1 -1
- package/dist/numerical/types.d.ts +6 -3
- package/dist/numerical/types.d.ts.map +1 -1
- package/dist/numerical/weyl-lowering.d.ts +4 -4
- package/dist/numerical/weyl-lowering.d.ts.map +1 -1
- package/dist/numerical/weyl-lowering.js +14 -1
- package/dist/numerical/weyl-lowering.js.map +1 -1
- package/package.json +19 -8
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbolic simplification of a scalar `ExprNode` via MathTS (v0.12 — optional
|
|
3
|
+
* supplement to symbolic composition).
|
|
4
|
+
*
|
|
5
|
+
* Composing two bridges' symbolic forms leaves an UNSIMPLIFIED AST — CT-1 is
|
|
6
|
+
* `k_B·(ℏc³/8πG·mass·k_B)·ln2`, with `k_B` uncancelled. This folds it to the
|
|
7
|
+
* canonical `ℏc³·ln2/(8πG·mass)` using `@danielsimonjr/mathts-functions`'
|
|
8
|
+
* `simplify` (the same OPTIONAL peer the Path-A formula parser loads).
|
|
9
|
+
*
|
|
10
|
+
* Pipeline (Adam+Eve-vetted — docs/planning/v0.12.0-Symbolic-Simplification-
|
|
11
|
+
* Design.md): GENSYM every non-exponent leaf to a mathjs-safe identifier
|
|
12
|
+
* (shared by name, so repeated leaves cancel), render FULLY-PARENTHESIZED
|
|
13
|
+
* (EVE-A — no precedence ambiguity), `parse`+`simplify`, walk the result back
|
|
14
|
+
* (un-gensym, INTEGER-exponent-strict — EVE/Adam HIGH-1). Three guards make a
|
|
15
|
+
* black-box CAS safe to trust:
|
|
16
|
+
* 1. dimensional — `validate(simplified)` dim `equals` the original's;
|
|
17
|
+
* 2. structural — non-numeric symbols of the result ⊆ those of the original
|
|
18
|
+
* (no leaf invented — Adam HIGH-2 / EVE-B);
|
|
19
|
+
* 3. numeric — `evalExpr` agrees over ≥2 finite synthesized probes at
|
|
20
|
+
* rel tol 1e-9 (Adam CRITICAL-2 / EVE-C).
|
|
21
|
+
* A representable result that DISAGREES dimensionally/numerically THROWS (a
|
|
22
|
+
* bug to surface); anything we cannot represent / verify / load degrades to a
|
|
23
|
+
* graceful no-op (return the original, `simplified:false`).
|
|
24
|
+
*
|
|
25
|
+
* INTERNAL — surfaced via `upt symbolic --simplify`.
|
|
26
|
+
*
|
|
27
|
+
* @module composition/expr-simplify
|
|
28
|
+
*/
|
|
29
|
+
import { validate } from '../dimensional/validator.js';
|
|
30
|
+
import { equals } from '../dimensional/algebra.js';
|
|
31
|
+
import { DIMENSIONLESS } from '../dimensional/types.js';
|
|
32
|
+
import { evalExpr } from './expr-eval.js';
|
|
33
|
+
import { CONSTANTS } from './symbolic-constants.js';
|
|
34
|
+
import { makeObservable } from './compose-symbolic.js';
|
|
35
|
+
/** A simplification completed but produced a dimensionally/numerically wrong
|
|
36
|
+
* result (a real bug — not a graceful no-op). @internal */
|
|
37
|
+
export class SimplificationError extends Error {
|
|
38
|
+
constructor(message) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = 'SimplificationError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Thrown internally when a node cannot be rendered/walked — caught and turned
|
|
44
|
+
* into a graceful no-op (never escapes the module). */
|
|
45
|
+
class Unsupported extends Error {
|
|
46
|
+
}
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Optional-peer load — cache + quietly + simplify-smoke (mirrors
|
|
49
|
+
// formula-registry.ts).
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
let cached;
|
|
52
|
+
/** Run `fn` with MathTS's import-time WASM-fallback chatter suppressed. */
|
|
53
|
+
async function quietly(fn) {
|
|
54
|
+
const origWarn = console.warn;
|
|
55
|
+
const origError = console.error;
|
|
56
|
+
const origWrite = process.stderr.write.bind(process.stderr);
|
|
57
|
+
console.warn = () => { };
|
|
58
|
+
console.error = () => { };
|
|
59
|
+
process.stderr.write = () => true;
|
|
60
|
+
try {
|
|
61
|
+
return await fn();
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
console.warn = origWarn;
|
|
65
|
+
console.error = origError;
|
|
66
|
+
process.stderr.write = origWrite;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Load + smoke-test the peer. A peer with `parse` but a missing/broken
|
|
70
|
+
* `simplify` (it must actually CANCEL) is rejected → null (graceful no-op). */
|
|
71
|
+
async function detect() {
|
|
72
|
+
try {
|
|
73
|
+
// Import AND smoke-test inside one suppression window (the WASM-fallback
|
|
74
|
+
// chatter fires lazily on first parse/simplify, not only at import).
|
|
75
|
+
return await quietly(async () => {
|
|
76
|
+
const mod = (await import('@danielsimonjr/mathts-functions'));
|
|
77
|
+
if (typeof mod.parse !== 'function' || typeof mod.simplify !== 'function') {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
// Smoke: g0 must cancel out of (g0)*((g1)/(g0)) → only g1 remains.
|
|
81
|
+
const s = mod.simplify(mod.parse('(g0)*((g1)/(g0))'));
|
|
82
|
+
const names = new Set();
|
|
83
|
+
collectMathSymbols(s, names);
|
|
84
|
+
return names.size === 1 && names.has('g1') ? mod : null;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function loadSimplifier() {
|
|
92
|
+
cached ??= detect();
|
|
93
|
+
return cached;
|
|
94
|
+
}
|
|
95
|
+
/** Synchronous variant of {@link quietly} for the parse+simplify calls (MathTS
|
|
96
|
+
* emits WASM-fallback chatter lazily on first use, not only at import). */
|
|
97
|
+
function quietlySync(fn) {
|
|
98
|
+
const origWarn = console.warn;
|
|
99
|
+
const origError = console.error;
|
|
100
|
+
const origWrite = process.stderr.write.bind(process.stderr);
|
|
101
|
+
console.warn = () => { };
|
|
102
|
+
console.error = () => { };
|
|
103
|
+
process.stderr.write = () => true;
|
|
104
|
+
try {
|
|
105
|
+
return fn();
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
console.warn = origWarn;
|
|
109
|
+
console.error = origError;
|
|
110
|
+
process.stderr.write = origWrite;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function collectMathSymbols(n, out) {
|
|
114
|
+
if (n.type === 'SymbolNode' && n.name)
|
|
115
|
+
out.add(n.name);
|
|
116
|
+
if (n.content)
|
|
117
|
+
collectMathSymbols(n.content, out);
|
|
118
|
+
for (const a of n.args ?? [])
|
|
119
|
+
collectMathSymbols(a, out);
|
|
120
|
+
}
|
|
121
|
+
const isLiteral = (name) => Number.isFinite(Number(name));
|
|
122
|
+
/** Render a scalar ExprNode to a mathjs-safe, fully-parenthesized string,
|
|
123
|
+
* gensym'ing each non-literal leaf by NAME (so repeats share an identifier
|
|
124
|
+
* and can cancel). Throws `Unsupported` on non-scalar arms. */
|
|
125
|
+
function renderGensym(expr, gensymOf, meta) {
|
|
126
|
+
switch (expr.kind) {
|
|
127
|
+
case 'symbol': {
|
|
128
|
+
if (isLiteral(expr.name))
|
|
129
|
+
return String(Number(expr.name));
|
|
130
|
+
let g = gensymOf.get(expr.name);
|
|
131
|
+
if (g === undefined) {
|
|
132
|
+
g = `g${gensymOf.size}`;
|
|
133
|
+
gensymOf.set(expr.name, g);
|
|
134
|
+
meta.set(g, { name: expr.name, dim: expr.dim });
|
|
135
|
+
}
|
|
136
|
+
return g;
|
|
137
|
+
}
|
|
138
|
+
case 'op': {
|
|
139
|
+
if (expr.op === '^') {
|
|
140
|
+
const exp = expr.args[1];
|
|
141
|
+
if (!exp || exp.kind !== 'symbol' || !isLiteral(exp.name)) {
|
|
142
|
+
throw new Unsupported();
|
|
143
|
+
}
|
|
144
|
+
return `(${renderGensym(expr.args[0], gensymOf, meta)})^${Number(exp.name)}`;
|
|
145
|
+
}
|
|
146
|
+
if (expr.args.length === 0)
|
|
147
|
+
throw new Unsupported();
|
|
148
|
+
const parts = expr.args.map((a) => `(${renderGensym(a, gensymOf, meta)})`);
|
|
149
|
+
return `(${parts.join(expr.op)})`;
|
|
150
|
+
}
|
|
151
|
+
default:
|
|
152
|
+
throw new Unsupported(); // integral / derivative / tensor arms
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const lit = (v) => ({ kind: 'symbol', name: String(v), dim: DIMENSIONLESS });
|
|
156
|
+
/** Walk a simplified MathTS node back to an ExprNode, un-gensym'ing leaves and
|
|
157
|
+
* rejecting anything outside UPT's integer-exponent scalar model (→ throws
|
|
158
|
+
* `Unsupported`, a graceful no-op). */
|
|
159
|
+
function walkBack(node, meta) {
|
|
160
|
+
switch (node.type) {
|
|
161
|
+
case 'ConstantNode': {
|
|
162
|
+
if (typeof node.value !== 'number' || !Number.isFinite(node.value)) {
|
|
163
|
+
throw new Unsupported();
|
|
164
|
+
}
|
|
165
|
+
return lit(node.value);
|
|
166
|
+
}
|
|
167
|
+
case 'SymbolNode': {
|
|
168
|
+
const m = node.name !== undefined ? meta.get(node.name) : undefined;
|
|
169
|
+
if (!m)
|
|
170
|
+
throw new Unsupported(); // a symbol we did not issue
|
|
171
|
+
return { kind: 'symbol', name: m.name, dim: m.dim };
|
|
172
|
+
}
|
|
173
|
+
case 'ParenthesisNode':
|
|
174
|
+
if (!node.content)
|
|
175
|
+
throw new Unsupported();
|
|
176
|
+
return walkBack(node.content, meta);
|
|
177
|
+
case 'OperatorNode': {
|
|
178
|
+
const op = node.op;
|
|
179
|
+
const args = node.args ?? [];
|
|
180
|
+
if (op === '^') {
|
|
181
|
+
if (args.length !== 2)
|
|
182
|
+
throw new Unsupported();
|
|
183
|
+
const exp = args[1];
|
|
184
|
+
if (exp.type !== 'ConstantNode' ||
|
|
185
|
+
typeof exp.value !== 'number' ||
|
|
186
|
+
!Number.isInteger(exp.value)) {
|
|
187
|
+
throw new Unsupported(); // non-integer exponent — not in ℤ⁷ model
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
kind: 'op',
|
|
191
|
+
op: '^',
|
|
192
|
+
args: [walkBack(args[0], meta), lit(exp.value)],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if ((op === '+' || op === '-') && args.length === 1) {
|
|
196
|
+
// unary minus → (-1) * arg
|
|
197
|
+
return { kind: 'op', op: '*', args: [lit(-1), walkBack(args[0], meta)] };
|
|
198
|
+
}
|
|
199
|
+
if (op === '+' || op === '-' || op === '*' || op === '/') {
|
|
200
|
+
if (args.length < 2)
|
|
201
|
+
throw new Unsupported();
|
|
202
|
+
return { kind: 'op', op, args: args.map((a) => walkBack(a, meta)) };
|
|
203
|
+
}
|
|
204
|
+
throw new Unsupported();
|
|
205
|
+
}
|
|
206
|
+
default:
|
|
207
|
+
throw new Unsupported(); // FunctionNode (sqrt/cbrt/…) etc.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Guards.
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
function symbolNames(expr, out = []) {
|
|
214
|
+
if (expr.kind === 'symbol')
|
|
215
|
+
out.push(expr.name);
|
|
216
|
+
else if (expr.kind === 'op')
|
|
217
|
+
for (const a of expr.args)
|
|
218
|
+
symbolNames(a, out);
|
|
219
|
+
else if (expr.kind === 'integral') {
|
|
220
|
+
symbolNames(expr.over, out);
|
|
221
|
+
symbolNames(expr.integrand, out);
|
|
222
|
+
}
|
|
223
|
+
else if (expr.kind === 'derivative') {
|
|
224
|
+
symbolNames(expr.of, out);
|
|
225
|
+
symbolNames(expr.wrt, out);
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
const nonNumericSymbols = (expr) => symbolNames(expr).filter((n) => !isLiteral(n));
|
|
230
|
+
const PROBE_VALUES = [2.3, 3.7, 5.1, 7.9, 11.3, 13.1, 17.9, 19.3];
|
|
231
|
+
const PROBE_MULTIPLIERS = [1, 1.7, 0.41, 2.9];
|
|
232
|
+
/** Numeric agreement of `original` and `candidate` over synthesized probes.
|
|
233
|
+
* Free (non-constant) leaves get distinct, mutually-incommensurate values to
|
|
234
|
+
* avoid accidental cancellation. <2 finite probes ⇒ 'insufficient' (cannot
|
|
235
|
+
* verify — EVE-C). */
|
|
236
|
+
function numericAgreement(original, candidate) {
|
|
237
|
+
const leaves = [...new Set(nonNumericSymbols(original))].filter((n) => !(n in CONSTANTS));
|
|
238
|
+
let finiteProbes = 0;
|
|
239
|
+
for (const mult of PROBE_MULTIPLIERS) {
|
|
240
|
+
const values = {};
|
|
241
|
+
leaves.forEach((leaf, i) => {
|
|
242
|
+
values[leaf] = PROBE_VALUES[i % PROBE_VALUES.length] * mult;
|
|
243
|
+
});
|
|
244
|
+
let a;
|
|
245
|
+
let b;
|
|
246
|
+
try {
|
|
247
|
+
a = evalExpr(original, values);
|
|
248
|
+
b = evalExpr(candidate, values);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
continue; // a probe drove evalExpr non-finite — skip it
|
|
252
|
+
}
|
|
253
|
+
if (!Number.isFinite(a) || !Number.isFinite(b))
|
|
254
|
+
continue;
|
|
255
|
+
finiteProbes++;
|
|
256
|
+
if (Math.abs(a - b) / Math.abs(b || 1) > 1e-9)
|
|
257
|
+
return 'disagree';
|
|
258
|
+
}
|
|
259
|
+
return finiteProbes >= 2 ? 'agree' : 'insufficient';
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Simplify a scalar `ExprNode` via MathTS, guarded. Returns the original
|
|
263
|
+
* unchanged (`simplified:false`) when the peer is absent or the result cannot
|
|
264
|
+
* be represented/verified; THROWS {@link SimplificationError} only when a
|
|
265
|
+
* representable result disagrees dimensionally/numerically. See module docs.
|
|
266
|
+
*
|
|
267
|
+
* @internal
|
|
268
|
+
*/
|
|
269
|
+
export async function simplifyExpr(expr) {
|
|
270
|
+
const mod = await loadSimplifier();
|
|
271
|
+
if (!mod)
|
|
272
|
+
return { expr, simplified: false };
|
|
273
|
+
const gensymOf = new Map();
|
|
274
|
+
const meta = new Map();
|
|
275
|
+
let candidate;
|
|
276
|
+
try {
|
|
277
|
+
const str = renderGensym(expr, gensymOf, meta);
|
|
278
|
+
// The peer can THROW on some forms (e.g. a known mathts `simplify` BigInt
|
|
279
|
+
// bug on nested `a/(b/c²)`); that, like an unsupported node, is a graceful
|
|
280
|
+
// no-op, not an error. WASM chatter is suppressed (the call is lazy).
|
|
281
|
+
const simplifiedNode = quietlySync(() => mod.simplify(mod.parse(str)));
|
|
282
|
+
candidate = walkBack(simplifiedNode, meta);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return { expr, simplified: false }; // unsupported / unrepresentable / peer threw
|
|
286
|
+
}
|
|
287
|
+
// Guard 1 — dimensional. Inability to validate ⇒ no-op; a CHANGED dimension
|
|
288
|
+
// is a representable disagreement ⇒ throw.
|
|
289
|
+
const origDim = validate(expr).inferredDimension;
|
|
290
|
+
const newResult = validate(candidate);
|
|
291
|
+
if (origDim === null || !newResult.ok || newResult.inferredDimension === null) {
|
|
292
|
+
return { expr, simplified: false };
|
|
293
|
+
}
|
|
294
|
+
if (!equals(origDim, newResult.inferredDimension)) {
|
|
295
|
+
throw new SimplificationError(`simplifyExpr: the simplified form changed dimension — a CAS or ` +
|
|
296
|
+
`walk-back error.`);
|
|
297
|
+
}
|
|
298
|
+
// Guard 2 — structural subset (no non-numeric leaf invented).
|
|
299
|
+
const origSyms = new Set(nonNumericSymbols(expr));
|
|
300
|
+
for (const s of nonNumericSymbols(candidate)) {
|
|
301
|
+
if (!origSyms.has(s))
|
|
302
|
+
return { expr, simplified: false }; // suspicious ⇒ no-op
|
|
303
|
+
}
|
|
304
|
+
// Guard 3 — numeric agreement.
|
|
305
|
+
const verdict = numericAgreement(expr, candidate);
|
|
306
|
+
if (verdict === 'disagree') {
|
|
307
|
+
throw new SimplificationError(`simplifyExpr: the simplified form disagrees numerically with the ` +
|
|
308
|
+
`original — a CAS or walk-back error.`);
|
|
309
|
+
}
|
|
310
|
+
if (verdict === 'insufficient')
|
|
311
|
+
return { expr, simplified: false };
|
|
312
|
+
// Identical-structure ⇒ nothing gained; report not simplified.
|
|
313
|
+
const changed = symbolNames(candidate).length !== symbolNames(expr).length;
|
|
314
|
+
return { expr: candidate, simplified: changed };
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Simplify a composed {@link Observable}: returns a freshly-RECONSTRUCTED
|
|
318
|
+
* Observable (new strict `evaluate` closure over the simplified `expr` +
|
|
319
|
+
* recomputed `leaves`) when simplification succeeds, else the original
|
|
320
|
+
* unchanged. See module docs.
|
|
321
|
+
*
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
324
|
+
export async function simplifyObservable(obs) {
|
|
325
|
+
const { expr, simplified } = await simplifyExpr(obs.expr);
|
|
326
|
+
if (!simplified)
|
|
327
|
+
return obs;
|
|
328
|
+
return makeObservable(obs.name, obs.symbol, obs.dim, expr);
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=expr-simplify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr-simplify.js","sourceRoot":"","sources":["../../src/composition/expr-simplify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scalar `ExprNode` substitution (v0.12 symbolic composition).
|
|
3
|
+
*
|
|
4
|
+
* `substitute(expr, name, replacement)` replaces every `{kind:'symbol', name}`
|
|
5
|
+
* leaf with `replacement`, recursing the scalar arms (`op` / `integral` /
|
|
6
|
+
* `derivative`). It returns the new tree AND the occurrence count — the count
|
|
7
|
+
* is load-bearing: `composeSymbolic` rejects a ZERO-occurrence substitution
|
|
8
|
+
* (a silent no-op that would yield a dimensionally-valid but physics-wrong
|
|
9
|
+
* composition ignoring the first operand — Adam A-3). Tensor arms are out of
|
|
10
|
+
* scope and throw (symbolic composition targets scalar closed forms).
|
|
11
|
+
*
|
|
12
|
+
* INTERNAL — not on the public surface.
|
|
13
|
+
*
|
|
14
|
+
* @module composition/expr-subst
|
|
15
|
+
*/
|
|
16
|
+
import type { ExprNode } from '../dimensional/validator.js';
|
|
17
|
+
/** The substituted tree and how many leaves were replaced. */
|
|
18
|
+
export interface SubstitutionResult {
|
|
19
|
+
readonly expr: ExprNode;
|
|
20
|
+
readonly count: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Replace every leaf `symbol` named `name` with `replacement`. See module
|
|
24
|
+
* docs. Returns `{ expr, count }`.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare function substitute(expr: ExprNode, name: string, replacement: ExprNode): SubstitutionResult;
|
|
29
|
+
//# sourceMappingURL=expr-subst.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr-subst.d.ts","sourceRoot":"","sources":["../../src/composition/expr-subst.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAG5D,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,QAAQ,GACpB,kBAAkB,CA0CpB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scalar `ExprNode` substitution (v0.12 symbolic composition).
|
|
3
|
+
*
|
|
4
|
+
* `substitute(expr, name, replacement)` replaces every `{kind:'symbol', name}`
|
|
5
|
+
* leaf with `replacement`, recursing the scalar arms (`op` / `integral` /
|
|
6
|
+
* `derivative`). It returns the new tree AND the occurrence count — the count
|
|
7
|
+
* is load-bearing: `composeSymbolic` rejects a ZERO-occurrence substitution
|
|
8
|
+
* (a silent no-op that would yield a dimensionally-valid but physics-wrong
|
|
9
|
+
* composition ignoring the first operand — Adam A-3). Tensor arms are out of
|
|
10
|
+
* scope and throw (symbolic composition targets scalar closed forms).
|
|
11
|
+
*
|
|
12
|
+
* INTERNAL — not on the public surface.
|
|
13
|
+
*
|
|
14
|
+
* @module composition/expr-subst
|
|
15
|
+
*/
|
|
16
|
+
import { SymbolicEvalError } from './expr-eval.js';
|
|
17
|
+
/**
|
|
18
|
+
* Replace every leaf `symbol` named `name` with `replacement`. See module
|
|
19
|
+
* docs. Returns `{ expr, count }`.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export function substitute(expr, name, replacement) {
|
|
24
|
+
switch (expr.kind) {
|
|
25
|
+
case 'symbol':
|
|
26
|
+
return expr.name === name
|
|
27
|
+
? { expr: replacement, count: 1 }
|
|
28
|
+
: { expr, count: 0 };
|
|
29
|
+
case 'op': {
|
|
30
|
+
let count = 0;
|
|
31
|
+
const args = expr.args.map((a) => {
|
|
32
|
+
const r = substitute(a, name, replacement);
|
|
33
|
+
count += r.count;
|
|
34
|
+
return r.expr;
|
|
35
|
+
});
|
|
36
|
+
return { expr: { ...expr, args }, count };
|
|
37
|
+
}
|
|
38
|
+
case 'integral': {
|
|
39
|
+
const over = substitute(expr.over, name, replacement);
|
|
40
|
+
const integrand = substitute(expr.integrand, name, replacement);
|
|
41
|
+
return {
|
|
42
|
+
expr: { ...expr, over: over.expr, integrand: integrand.expr },
|
|
43
|
+
count: over.count + integrand.count,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
case 'derivative': {
|
|
47
|
+
const of = substitute(expr.of, name, replacement);
|
|
48
|
+
const wrt = substitute(expr.wrt, name, replacement);
|
|
49
|
+
return {
|
|
50
|
+
expr: { ...expr, of: of.expr, wrt: wrt.expr },
|
|
51
|
+
count: of.count + wrt.count,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
default:
|
|
55
|
+
throw new SymbolicEvalError(`substitute: node kind '${expr.kind}' is out of scope (scalar ` +
|
|
56
|
+
`symbol/op/integral/derivative only; tensor nodes are not ` +
|
|
57
|
+
`substitutable here).`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=expr-subst.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expr-subst.js","sourceRoot":"","sources":["../../src/composition/expr-subst.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAQnD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,IAAc,EACd,IAAY,EACZ,WAAqB;IAErB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI;gBACvB,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE;gBACjC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAEzB,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC/B,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;gBAC3C,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC;gBACjB,OAAO,CAAC,CAAC,IAAI,CAAC;YAChB,CAAC,CAAC,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;QAC5C,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YACtD,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YAChE,OAAO;gBACL,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,EAAE;gBAC7D,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK;aACpC,CAAC;QACJ,CAAC;QAED,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;YACpD,OAAO;gBACL,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE;gBAC7C,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK;aAC5B,CAAC;QACJ,CAAC;QAED;YACE,MAAM,IAAI,iBAAiB,CACzB,0BAA0B,IAAI,CAAC,IAAI,4BAA4B;gBAC7D,2DAA2D;gBAC3D,sBAAsB,CACzB,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identifiability classifier (Consequence 1 of
|
|
3
|
+
* docs/planning/Bridge-Inference-Epistemics-Note.md, designed in
|
|
4
|
+
* docs/planning/Identifiability-Classifier-Design-Note.md).
|
|
5
|
+
*
|
|
6
|
+
* Answers a STRUCTURAL question over the directed hypergraph of
|
|
7
|
+
* `BridgeEdge`s: given a set of known quantities and a target quantity,
|
|
8
|
+
* how many INDEPENDENT ways can the graph compute the target from the
|
|
9
|
+
* knowns? The count drives the epistemics-note trichotomy:
|
|
10
|
+
*
|
|
11
|
+
* - under-determined — unreachable; needs more inputs or more physics.
|
|
12
|
+
* - exactly-determined — one derivation; solvable (up to the
|
|
13
|
+
* dimensionless constant dimensional analysis cannot supply).
|
|
14
|
+
* - over-determined — ≥2 derivations; the surplus are FALSIFIABLE
|
|
15
|
+
* consistency constraints (each predicts the target; they must
|
|
16
|
+
* agree). The headline regime.
|
|
17
|
+
* - given — the target is itself a known (degenerate); derivations
|
|
18
|
+
* become cross-checks on the supplied value.
|
|
19
|
+
*
|
|
20
|
+
* This is STRUCTURAL, not parametric: it does not decide whether the
|
|
21
|
+
* resulting nonlinear system has a unique numeric solution (undecidable
|
|
22
|
+
* in general for closed-form evaluators). "Independent derivation" means
|
|
23
|
+
* a structurally distinct edge, NOT a provably-independent formula — two
|
|
24
|
+
* edges encoding the same relation are counted as two (an honest
|
|
25
|
+
* over-count). The classifier PROPOSES; humans filter (Part-VI §XXVII-B),
|
|
26
|
+
* exactly as `enumerateCompositions` does.
|
|
27
|
+
*
|
|
28
|
+
* @module composition/identifiability
|
|
29
|
+
*/
|
|
30
|
+
import type { BridgeEdge } from './edge.js';
|
|
31
|
+
import type { QuantityIdentification } from './compose.js';
|
|
32
|
+
/** The four-way structural-identifiability verdict. @public */
|
|
33
|
+
export type IdentifiabilityVerdict = 'given' | 'under-determined' | 'exactly-determined' | 'over-determined';
|
|
34
|
+
/** Options for the classifier. @public */
|
|
35
|
+
export interface IdentifiabilityOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Quantity identifications honored when expanding determinability
|
|
38
|
+
* (directed name-equivalences: `from` determinable ⟹ `to` determinable).
|
|
39
|
+
* Defaults to the registered {@link QUANTITY_IDENTIFICATIONS}, mirroring
|
|
40
|
+
* how `composeEdges` connects the graph. Pass `[]` for the pure
|
|
41
|
+
* physical-edge graph.
|
|
42
|
+
*/
|
|
43
|
+
readonly identifications?: readonly QuantityIdentification[];
|
|
44
|
+
}
|
|
45
|
+
/** The result of classifying one target against one known set. @public */
|
|
46
|
+
export interface IdentifiabilityResult {
|
|
47
|
+
/** The target quantity name that was classified. */
|
|
48
|
+
readonly target: string;
|
|
49
|
+
/** The known-quantity names (deduplicated). */
|
|
50
|
+
readonly known: readonly string[];
|
|
51
|
+
readonly verdict: IdentifiabilityVerdict;
|
|
52
|
+
/**
|
|
53
|
+
* Ids of the distinct edges that independently derive the target from
|
|
54
|
+
* the known set — sources determinable WITHOUT using any edge into the
|
|
55
|
+
* target (so circular self-support is excluded). Empty ⟺ no physical
|
|
56
|
+
* derivation (under-determined, or determined only by identity).
|
|
57
|
+
*/
|
|
58
|
+
readonly derivations: readonly string[];
|
|
59
|
+
/**
|
|
60
|
+
* Redundant derivations = falsifiable consistency constraints. For a
|
|
61
|
+
* non-given target the first derivation pins the value and the rest are
|
|
62
|
+
* checks (`max(0, |derivations| − 1)`); for a given (measured) target
|
|
63
|
+
* every derivation is a check (`|derivations|`).
|
|
64
|
+
*/
|
|
65
|
+
readonly surplusConstraints: number;
|
|
66
|
+
/**
|
|
67
|
+
* For under-determined targets: the upstream quantities that block
|
|
68
|
+
* determinability — on some path toward the target, not determinable
|
|
69
|
+
* from the known set, not themselves known. Knowing a sufficient subset
|
|
70
|
+
* moves the target toward determined. Empty when determinable.
|
|
71
|
+
*/
|
|
72
|
+
readonly blockingFrontier: readonly string[];
|
|
73
|
+
/** Every quantity determinable from the known set (the forward closure). */
|
|
74
|
+
readonly determinable: readonly string[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The monotone forward closure: the least set ⊇ `knownNames` closed under
|
|
78
|
+
* "all of an edge's sources determinable ⟹ its target determinable",
|
|
79
|
+
* with identifications expanding it as directed name-equivalences.
|
|
80
|
+
*
|
|
81
|
+
* A parameter-free edge (empty `sources`) fires unconditionally — its
|
|
82
|
+
* target is in every closure (a constant is always determinable).
|
|
83
|
+
*
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
export declare function forwardClosure(edges: readonly BridgeEdge[], knownNames: readonly string[], identifications?: readonly QuantityIdentification[]): Set<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Classify the structural identifiability of `targetName` given
|
|
89
|
+
* `knownNames` over `edges`. See the module docs and
|
|
90
|
+
* docs/planning/Identifiability-Classifier-Design-Note.md.
|
|
91
|
+
*
|
|
92
|
+
* @public
|
|
93
|
+
*/
|
|
94
|
+
export declare function classifyIdentifiability(edges: readonly BridgeEdge[], knownNames: readonly string[], targetName: string, opts?: IdentifiabilityOptions): IdentifiabilityResult;
|
|
95
|
+
/**
|
|
96
|
+
* Classify every quantity that is some edge's target, against one known
|
|
97
|
+
* set. The natural feeder for a retrodiction harness (mask a node, ask
|
|
98
|
+
* whether the graph recovers it). Sorted by target name.
|
|
99
|
+
*
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
export declare function classifyAll(edges: readonly BridgeEdge[], knownNames: readonly string[], opts?: IdentifiabilityOptions): IdentifiabilityResult[];
|
|
103
|
+
//# sourceMappingURL=identifiability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifiability.d.ts","sourceRoot":"","sources":["../../src/composition/identifiability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D,+DAA+D;AAC/D,MAAM,MAAM,sBAAsB,GAC9B,OAAO,GACP,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,0CAA0C;AAC1C,MAAM,WAAW,sBAAsB;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;CAC9D;AAED,0EAA0E;AAC1E,MAAM,WAAW,qBAAqB;IACpC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,4EAA4E;IAC5E,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,eAAe,GAAE,SAAS,sBAAsB,EAA6B,GAC5E,GAAG,CAAC,MAAM,CAAC,CAoBb;AAyBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,sBAA2B,GAChC,qBAAqB,CAyDvB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,IAAI,GAAE,sBAA2B,GAChC,qBAAqB,EAAE,CAKzB"}
|