universal-physics-tensor 0.47.0 → 1.0.1
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/LICENSE +21 -21
- package/README.md +396 -383
- package/bin/upt.mjs +28 -22
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts +108 -0
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -0
- package/dist/atlas/benchmark/hybrid-retrieval.js +241 -0
- package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -0
- package/dist/atlas/catalog-formal-ref.d.ts +24 -0
- package/dist/atlas/catalog-formal-ref.d.ts.map +1 -0
- package/dist/atlas/catalog-formal-ref.js +36 -0
- package/dist/atlas/catalog-formal-ref.js.map +1 -0
- package/dist/atlas/composition-table.d.ts +11 -46
- package/dist/atlas/composition-table.d.ts.map +1 -1
- package/dist/atlas/composition-table.js +7 -124
- package/dist/atlas/composition-table.js.map +1 -1
- package/dist/atlas/conventions.d.ts +4 -58
- package/dist/atlas/conventions.d.ts.map +1 -1
- package/dist/atlas/conventions.js +3 -88
- package/dist/atlas/conventions.js.map +1 -1
- package/dist/atlas/derive-evidence.d.ts +50 -3
- package/dist/atlas/derive-evidence.d.ts.map +1 -1
- package/dist/atlas/derive-evidence.js +73 -4
- package/dist/atlas/derive-evidence.js.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.js +5 -1
- package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
- package/dist/atlas/index.d.ts +9 -7
- package/dist/atlas/index.d.ts.map +1 -1
- package/dist/atlas/index.js +6 -5
- package/dist/atlas/index.js.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.js +6 -0
- package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.d.ts +2 -0
- package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.js +20 -19
- package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.d.ts +93 -0
- package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -0
- package/dist/atlas/oscillators/limit-witnesses.js +152 -0
- package/dist/atlas/oscillators/limit-witnesses.js.map +1 -0
- package/dist/atlas/oscillators/models.d.ts +2 -1
- package/dist/atlas/oscillators/models.d.ts.map +1 -1
- package/dist/atlas/oscillators/models.js +4 -3
- package/dist/atlas/oscillators/models.js.map +1 -1
- package/dist/atlas/oscillators/norm-transport-witness.d.ts +37 -0
- package/dist/atlas/oscillators/norm-transport-witness.d.ts.map +1 -0
- package/dist/atlas/oscillators/norm-transport-witness.js +58 -0
- package/dist/atlas/oscillators/norm-transport-witness.js.map +1 -0
- package/dist/atlas/oscillators/norm-transport.d.ts +44 -0
- package/dist/atlas/oscillators/norm-transport.d.ts.map +1 -0
- package/dist/atlas/oscillators/norm-transport.js +66 -0
- package/dist/atlas/oscillators/norm-transport.js.map +1 -0
- package/dist/atlas/oscillators/norms.d.ts +11 -0
- package/dist/atlas/oscillators/norms.d.ts.map +1 -0
- package/dist/atlas/oscillators/norms.js +11 -0
- package/dist/atlas/oscillators/norms.js.map +1 -0
- package/dist/atlas/oscillators/pendulum-motion.d.ts +38 -0
- package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -0
- package/dist/atlas/oscillators/pendulum-motion.js +122 -0
- package/dist/atlas/oscillators/pendulum-motion.js.map +1 -0
- package/dist/atlas/oscillators/phase-carriage.d.ts +38 -0
- package/dist/atlas/oscillators/phase-carriage.d.ts.map +1 -0
- package/dist/atlas/oscillators/phase-carriage.js +96 -0
- package/dist/atlas/oscillators/phase-carriage.js.map +1 -0
- package/dist/atlas/oscillators/phase-translation.d.ts +46 -0
- package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -0
- package/dist/atlas/oscillators/phase-translation.js +178 -0
- package/dist/atlas/oscillators/phase-translation.js.map +1 -0
- package/dist/atlas/oscillators/position-translation.d.ts +59 -0
- package/dist/atlas/oscillators/position-translation.d.ts.map +1 -0
- package/dist/atlas/oscillators/position-translation.js +254 -0
- package/dist/atlas/oscillators/position-translation.js.map +1 -0
- package/dist/atlas/path-bound.d.ts +126 -9
- package/dist/atlas/path-bound.d.ts.map +1 -1
- package/dist/atlas/path-bound.js +372 -23
- package/dist/atlas/path-bound.js.map +1 -1
- package/dist/atlas/physjs-ref.d.ts +112 -0
- package/dist/atlas/physjs-ref.d.ts.map +1 -0
- package/dist/atlas/physjs-ref.js +842 -0
- package/dist/atlas/physjs-ref.js.map +1 -0
- package/dist/atlas/regime.d.ts +12 -136
- package/dist/atlas/regime.d.ts.map +1 -1
- package/dist/atlas/regime.js +8 -254
- package/dist/atlas/regime.js.map +1 -1
- package/dist/atlas/serialize.d.ts.map +1 -1
- package/dist/atlas/serialize.js +25 -0
- package/dist/atlas/serialize.js.map +1 -1
- package/dist/atlas/translation-registry.d.ts +22 -0
- package/dist/atlas/translation-registry.d.ts.map +1 -0
- package/dist/atlas/translation-registry.js +31 -0
- package/dist/atlas/translation-registry.js.map +1 -0
- package/dist/atlas/translation.d.ts +116 -0
- package/dist/atlas/translation.d.ts.map +1 -0
- package/dist/atlas/translation.js +34 -0
- package/dist/atlas/translation.js.map +1 -0
- package/dist/atlas/types.d.ts +74 -240
- package/dist/atlas/types.d.ts.map +1 -1
- package/dist/atlas/types.js +5 -37
- package/dist/atlas/types.js.map +1 -1
- package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/waves/bridges-closure.js +4 -0
- package/dist/atlas/waves/bridges-closure.js.map +1 -1
- package/dist/atlas/waves/bridges.d.ts.map +1 -1
- package/dist/atlas/waves/bridges.js +3 -0
- package/dist/atlas/waves/bridges.js.map +1 -1
- package/dist/atlas/waves/models.js +1 -1
- package/dist/atlas/waves/models.js.map +1 -1
- package/dist/atlas/witness-dominance.d.ts +50 -0
- package/dist/atlas/witness-dominance.d.ts.map +1 -0
- package/dist/atlas/witness-dominance.js +86 -0
- package/dist/atlas/witness-dominance.js.map +1 -0
- package/dist/atlas/witness-specs.d.ts +30 -0
- package/dist/atlas/witness-specs.d.ts.map +1 -1
- package/dist/atlas/witness-specs.js +107 -0
- package/dist/atlas/witness-specs.js.map +1 -1
- package/dist/bridges/be53-yang-mills-confrontation.d.ts +81 -0
- package/dist/bridges/be53-yang-mills-confrontation.d.ts.map +1 -0
- package/dist/bridges/be53-yang-mills-confrontation.js +110 -0
- package/dist/bridges/be53-yang-mills-confrontation.js.map +1 -0
- package/dist/bridges/confrontations.d.ts +1 -1
- package/dist/bridges/confrontations.d.ts.map +1 -1
- package/dist/bridges/confrontations.js +291 -3
- package/dist/bridges/confrontations.js.map +1 -1
- package/dist/bridges/equations/be-13-einstein-trace.d.ts +2 -3
- package/dist/bridges/equations/be-13-einstein-trace.d.ts.map +1 -1
- package/dist/bridges/equations/be-13-einstein-trace.js +2 -3
- package/dist/bridges/equations/be-13-einstein-trace.js.map +1 -1
- package/dist/bridges/equations/be-38-mond.d.ts +7 -5
- package/dist/bridges/equations/be-38-mond.d.ts.map +1 -1
- package/dist/bridges/equations/be-38-mond.js +7 -5
- package/dist/bridges/equations/be-38-mond.js.map +1 -1
- package/dist/bridges/equations/be-53-yang-mills-beta.d.ts +21 -0
- package/dist/bridges/equations/be-53-yang-mills-beta.d.ts.map +1 -1
- package/dist/bridges/equations/be-53-yang-mills-beta.js +12 -0
- package/dist/bridges/equations/be-53-yang-mills-beta.js.map +1 -1
- package/dist/bridges/evaluator-inputs.d.ts +21 -0
- package/dist/bridges/evaluator-inputs.d.ts.map +1 -0
- package/dist/bridges/evaluator-inputs.js +75 -0
- package/dist/bridges/evaluator-inputs.js.map +1 -0
- package/dist/bridges/evaluators.d.ts +38 -0
- package/dist/bridges/evaluators.d.ts.map +1 -1
- package/dist/bridges/evaluators.js +41 -15
- package/dist/bridges/evaluators.js.map +1 -1
- package/dist/bridges/gravitational-lensing.d.ts +1 -1
- package/dist/bridges/gravitational-lensing.js +1 -1
- package/dist/bridges/index.d.ts +1 -1
- package/dist/bridges/index.d.ts.map +1 -1
- package/dist/bridges/index.js +13 -13
- package/dist/bridges/index.js.map +1 -1
- package/dist/bridges/observations/types.d.ts +110 -2
- package/dist/bridges/observations/types.d.ts.map +1 -1
- package/dist/bridges/observations/types.js +29 -0
- package/dist/bridges/observations/types.js.map +1 -1
- package/dist/bridges/perihelion-precession.d.ts +1 -1
- package/dist/bridges/perihelion-precession.js +1 -1
- package/dist/canonical/canonical-equation.d.ts +1 -1
- package/dist/canonical/canonical-equation.d.ts.map +1 -1
- package/dist/canonical/entries/atomic.d.ts.map +1 -1
- package/dist/canonical/entries/atomic.js +32 -10
- package/dist/canonical/entries/atomic.js.map +1 -1
- package/dist/canonical/entries/dimensional-classics.js +2 -2
- package/dist/canonical/entries/dimensional-classics.js.map +1 -1
- package/dist/canonical/entries/mechanics.d.ts.map +1 -1
- package/dist/canonical/entries/mechanics.js +10 -6
- package/dist/canonical/entries/mechanics.js.map +1 -1
- package/dist/canonical/entries/relativity.d.ts.map +1 -1
- package/dist/canonical/entries/relativity.js +41 -8
- package/dist/canonical/entries/relativity.js.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.js +5 -5
- package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
- package/dist/canonical/linkage.d.ts.map +1 -1
- package/dist/canonical/linkage.js +14 -8
- package/dist/canonical/linkage.js.map +1 -1
- package/dist/canonical/normal-form.d.ts +17 -0
- package/dist/canonical/normal-form.d.ts.map +1 -1
- package/dist/canonical/normal-form.js +21 -4
- package/dist/canonical/normal-form.js.map +1 -1
- package/dist/cases/brownian-sphere.d.ts +68 -0
- package/dist/cases/brownian-sphere.d.ts.map +1 -0
- package/dist/cases/brownian-sphere.js +353 -0
- package/dist/cases/brownian-sphere.js.map +1 -0
- package/dist/cases/damped-resonator.d.ts +23 -0
- package/dist/cases/damped-resonator.d.ts.map +1 -0
- package/dist/cases/damped-resonator.js +224 -0
- package/dist/cases/damped-resonator.js.map +1 -0
- package/dist/cases/index.d.ts +11 -0
- package/dist/cases/index.d.ts.map +1 -0
- package/dist/cases/index.js +29 -0
- package/dist/cases/index.js.map +1 -0
- package/dist/cases/kepler-rv.d.ts +13 -0
- package/dist/cases/kepler-rv.d.ts.map +1 -0
- package/dist/cases/kepler-rv.js +168 -0
- package/dist/cases/kepler-rv.js.map +1 -0
- package/dist/cases/lumped-cooling.d.ts +46 -0
- package/dist/cases/lumped-cooling.d.ts.map +1 -0
- package/dist/cases/lumped-cooling.js +261 -0
- package/dist/cases/lumped-cooling.js.map +1 -0
- package/dist/cases/quadrature.d.ts +14 -0
- package/dist/cases/quadrature.d.ts.map +1 -0
- package/dist/cases/quadrature.js +41 -0
- package/dist/cases/quadrature.js.map +1 -0
- package/dist/cases/resistor-noise.d.ts +14 -0
- package/dist/cases/resistor-noise.d.ts.map +1 -0
- package/dist/cases/resistor-noise.js +210 -0
- package/dist/cases/resistor-noise.js.map +1 -0
- package/dist/cases/skin-depth.d.ts +21 -0
- package/dist/cases/skin-depth.d.ts.map +1 -0
- package/dist/cases/skin-depth.js +174 -0
- package/dist/cases/skin-depth.js.map +1 -0
- package/dist/cases/types.d.ts +115 -0
- package/dist/cases/types.d.ts.map +1 -0
- package/dist/cases/types.js +20 -0
- package/dist/cases/types.js.map +1 -0
- package/dist/cli/commands/_atlas-map.d.ts +409 -0
- package/dist/cli/commands/_atlas-map.d.ts.map +1 -0
- package/dist/cli/commands/_atlas-map.js +1014 -0
- package/dist/cli/commands/_atlas-map.js.map +1 -0
- package/dist/cli/commands/_atlas-route.d.ts +111 -0
- package/dist/cli/commands/_atlas-route.d.ts.map +1 -0
- package/dist/cli/commands/_atlas-route.js +140 -0
- package/dist/cli/commands/_atlas-route.js.map +1 -0
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +10 -1
- package/dist/cli/commands/_discovery-opts.js.map +1 -1
- package/dist/cli/commands/atlas.d.ts +20 -0
- package/dist/cli/commands/atlas.d.ts.map +1 -1
- package/dist/cli/commands/atlas.js +333 -19
- package/dist/cli/commands/atlas.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +14 -5
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/axes.js +4 -4
- package/dist/cli/commands/candidates.d.ts.map +1 -1
- package/dist/cli/commands/candidates.js +6 -5
- package/dist/cli/commands/candidates.js.map +1 -1
- package/dist/cli/commands/canonical.d.ts.map +1 -1
- package/dist/cli/commands/canonical.js +41 -12
- package/dist/cli/commands/canonical.js.map +1 -1
- package/dist/cli/commands/confront.d.ts.map +1 -1
- package/dist/cli/commands/confront.js +210 -28
- package/dist/cli/commands/confront.js.map +1 -1
- package/dist/cli/commands/connectors.d.ts.map +1 -1
- package/dist/cli/commands/connectors.js +11 -10
- package/dist/cli/commands/connectors.js.map +1 -1
- package/dist/cli/commands/coverage.js +3 -3
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +22 -10
- package/dist/cli/commands/derive.js.map +1 -1
- package/dist/cli/commands/discover.d.ts.map +1 -1
- package/dist/cli/commands/discover.js +149 -32
- package/dist/cli/commands/discover.js.map +1 -1
- package/dist/cli/commands/eval.d.ts.map +1 -1
- package/dist/cli/commands/eval.js +76 -17
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/evaluate.d.ts +30 -0
- package/dist/cli/commands/evaluate.d.ts.map +1 -1
- package/dist/cli/commands/evaluate.js +440 -25
- 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 +38 -11
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/frontier.d.ts +3 -0
- package/dist/cli/commands/frontier.d.ts.map +1 -0
- package/dist/cli/commands/frontier.js +28 -0
- package/dist/cli/commands/frontier.js.map +1 -0
- package/dist/cli/commands/ground.d.ts.map +1 -1
- package/dist/cli/commands/ground.js +37 -12
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/index.d.ts +5 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +5 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/map.d.ts +8 -0
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +401 -64
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/commands/metric.d.ts +3 -0
- package/dist/cli/commands/metric.d.ts.map +1 -0
- package/dist/cli/commands/metric.js +136 -0
- package/dist/cli/commands/metric.js.map +1 -0
- package/dist/cli/commands/path.d.ts +109 -1
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +1019 -109
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/predict.d.ts.map +1 -1
- package/dist/cli/commands/predict.js +6 -5
- package/dist/cli/commands/predict.js.map +1 -1
- package/dist/cli/commands/priority.d.ts.map +1 -1
- package/dist/cli/commands/priority.js +4 -3
- package/dist/cli/commands/priority.js.map +1 -1
- package/dist/cli/commands/probe.d.ts +7 -0
- package/dist/cli/commands/probe.d.ts.map +1 -1
- package/dist/cli/commands/probe.js +234 -52
- package/dist/cli/commands/probe.js.map +1 -1
- package/dist/cli/commands/recover.d.ts.map +1 -1
- package/dist/cli/commands/recover.js +17 -6
- package/dist/cli/commands/recover.js.map +1 -1
- package/dist/cli/commands/regime.d.ts +1 -1
- package/dist/cli/commands/regime.d.ts.map +1 -1
- package/dist/cli/commands/regime.js +134 -33
- package/dist/cli/commands/regime.js.map +1 -1
- package/dist/cli/commands/retrieve.d.ts +3 -0
- package/dist/cli/commands/retrieve.d.ts.map +1 -0
- package/dist/cli/commands/retrieve.js +65 -0
- package/dist/cli/commands/retrieve.js.map +1 -0
- package/dist/cli/commands/search.d.ts +3 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +70 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/symbolic.d.ts.map +1 -1
- package/dist/cli/commands/symbolic.js +112 -21
- package/dist/cli/commands/symbolic.js.map +1 -1
- package/dist/cli/commands/testplan.d.ts +3 -0
- package/dist/cli/commands/testplan.d.ts.map +1 -0
- package/dist/cli/commands/testplan.js +131 -0
- package/dist/cli/commands/testplan.js.map +1 -0
- package/dist/cli/conventions.d.ts +22 -0
- package/dist/cli/conventions.d.ts.map +1 -0
- package/dist/cli/conventions.js +48 -0
- package/dist/cli/conventions.js.map +1 -0
- package/dist/cli/euler-guard.d.ts +9 -0
- package/dist/cli/euler-guard.d.ts.map +1 -0
- package/dist/cli/euler-guard.js +11 -0
- package/dist/cli/euler-guard.js.map +1 -0
- package/dist/cli/eval-numbers.d.ts +26 -0
- package/dist/cli/eval-numbers.d.ts.map +1 -0
- package/dist/cli/eval-numbers.js +49 -0
- package/dist/cli/eval-numbers.js.map +1 -0
- package/dist/cli/expr-print.d.ts +25 -0
- package/dist/cli/expr-print.d.ts.map +1 -0
- package/dist/cli/expr-print.js +123 -0
- package/dist/cli/expr-print.js.map +1 -0
- package/dist/cli/graphs.d.ts +26 -0
- package/dist/cli/graphs.d.ts.map +1 -1
- package/dist/cli/graphs.js +19 -0
- package/dist/cli/graphs.js.map +1 -1
- package/dist/cli/main.d.ts +4 -10
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +370 -167
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/map-evidence.d.ts +47 -0
- package/dist/cli/map-evidence.d.ts.map +1 -0
- package/dist/cli/map-evidence.js +53 -0
- package/dist/cli/map-evidence.js.map +1 -0
- package/dist/cli/output.d.ts +21 -1
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +5 -1
- package/dist/cli/output.js.map +1 -1
- package/dist/{composition → cli}/poster-source.d.ts +3 -2
- package/dist/cli/poster-source.d.ts.map +1 -0
- package/dist/{composition → cli}/poster-source.js +2 -1
- package/dist/cli/poster-source.js.map +1 -0
- package/dist/cli/record-reach.d.ts +44 -0
- package/dist/cli/record-reach.d.ts.map +1 -0
- package/dist/cli/record-reach.js +228 -0
- package/dist/cli/record-reach.js.map +1 -0
- package/dist/cli/record-tables.d.ts +38 -0
- package/dist/cli/record-tables.d.ts.map +1 -0
- package/dist/cli/record-tables.js +110 -0
- package/dist/cli/record-tables.js.map +1 -0
- package/dist/cli/record.d.ts +141 -0
- package/dist/cli/record.d.ts.map +1 -0
- package/dist/cli/record.js +612 -0
- package/dist/cli/record.js.map +1 -0
- package/dist/cli/search-index.d.ts +56 -0
- package/dist/cli/search-index.d.ts.map +1 -0
- package/dist/cli/search-index.js +190 -0
- package/dist/cli/search-index.js.map +1 -0
- package/dist/cli/statuses.d.ts +25 -0
- package/dist/cli/statuses.d.ts.map +1 -0
- package/dist/cli/statuses.js +276 -0
- package/dist/cli/statuses.js.map +1 -0
- package/dist/cli/version.d.ts +8 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +32 -1
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +33 -15
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +31 -11
- package/dist/cli-api.js.map +1 -1
- package/dist/composition/bridge-analysis.d.ts.map +1 -1
- package/dist/composition/bridge-analysis.js +2 -1
- package/dist/composition/bridge-analysis.js.map +1 -1
- package/dist/composition/canonical-compare.d.ts +36 -11
- package/dist/composition/canonical-compare.d.ts.map +1 -1
- package/dist/composition/canonical-compare.js +424 -56
- package/dist/composition/canonical-compare.js.map +1 -1
- package/dist/composition/canonical-graph.d.ts +2 -2
- package/dist/composition/canonical-graph.js +3 -3
- package/dist/composition/canonical-graph.js.map +1 -1
- package/dist/composition/canonical-prefactors.d.ts +24 -1
- package/dist/composition/canonical-prefactors.d.ts.map +1 -1
- package/dist/composition/canonical-prefactors.js +97 -1
- package/dist/composition/canonical-prefactors.js.map +1 -1
- package/dist/composition/compose-symbolic.js +1 -1
- package/dist/composition/compose-symbolic.js.map +1 -1
- package/dist/composition/compose.d.ts.map +1 -1
- package/dist/composition/compose.js +17 -9
- package/dist/composition/compose.js.map +1 -1
- package/dist/composition/composition-recovery.d.ts +47 -0
- package/dist/composition/composition-recovery.d.ts.map +1 -0
- package/dist/composition/composition-recovery.js +77 -0
- package/dist/composition/composition-recovery.js.map +1 -0
- package/dist/composition/consequence.d.ts +39 -0
- package/dist/composition/consequence.d.ts.map +1 -1
- package/dist/composition/consequence.js +37 -0
- package/dist/composition/consequence.js.map +1 -1
- package/dist/composition/discovery.d.ts +20 -0
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +27 -5
- package/dist/composition/discovery.js.map +1 -1
- package/dist/composition/edge.d.ts +1 -1
- package/dist/composition/edge.d.ts.map +1 -1
- package/dist/composition/edge.js.map +1 -1
- package/dist/composition/edges/_catalog-helpers.d.ts +4 -0
- package/dist/composition/edges/_catalog-helpers.d.ts.map +1 -1
- package/dist/composition/edges/_catalog-helpers.js +15 -0
- package/dist/composition/edges/_catalog-helpers.js.map +1 -1
- package/dist/composition/edges/calibration.d.ts.map +1 -1
- package/dist/composition/edges/calibration.js +57 -0
- package/dist/composition/edges/calibration.js.map +1 -1
- package/dist/composition/edges/catalog-fields.d.ts.map +1 -1
- package/dist/composition/edges/catalog-fields.js +2 -1
- package/dist/composition/edges/catalog-fields.js.map +1 -1
- package/dist/composition/edges/catalog-gravitation-cosmology.d.ts.map +1 -1
- package/dist/composition/edges/catalog-gravitation-cosmology.js +2 -1
- package/dist/composition/edges/catalog-gravitation-cosmology.js.map +1 -1
- package/dist/composition/edges/catalog-quantum.d.ts.map +1 -1
- package/dist/composition/edges/catalog-quantum.js +26 -0
- package/dist/composition/edges/catalog-quantum.js.map +1 -1
- package/dist/composition/edges/catalog-tranche.d.ts.map +1 -1
- package/dist/composition/edges/catalog-tranche.js +2 -1
- package/dist/composition/edges/catalog-tranche.js.map +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +4 -1
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.js +1 -1
- package/dist/composition/expr-simplify.js.map +1 -1
- package/dist/composition/frontier-account.d.ts +78 -0
- package/dist/composition/frontier-account.d.ts.map +1 -0
- package/dist/composition/frontier-account.js +127 -0
- package/dist/composition/frontier-account.js.map +1 -0
- package/dist/composition/graph-viz.d.ts +7 -22
- package/dist/composition/graph-viz.d.ts.map +1 -1
- package/dist/composition/graph-viz.js +4 -27
- package/dist/composition/graph-viz.js.map +1 -1
- package/dist/composition/grounding.d.ts +49 -0
- package/dist/composition/grounding.d.ts.map +1 -1
- package/dist/composition/grounding.js +38 -0
- package/dist/composition/grounding.js.map +1 -1
- package/dist/composition/index.d.ts +0 -2
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +1 -1
- package/dist/composition/index.js.map +1 -1
- package/dist/composition/probe/expression-gaps.d.ts +27 -0
- package/dist/composition/probe/expression-gaps.d.ts.map +1 -0
- package/dist/composition/probe/expression-gaps.js +47 -0
- package/dist/composition/probe/expression-gaps.js.map +1 -0
- package/dist/composition/probe/frontier.d.ts +2 -1
- package/dist/composition/probe/frontier.d.ts.map +1 -1
- package/dist/composition/probe/frontier.js +3 -2
- package/dist/composition/probe/frontier.js.map +1 -1
- package/dist/composition/probe/index.d.ts +4 -1
- package/dist/composition/probe/index.d.ts.map +1 -1
- package/dist/composition/probe/index.js +3 -1
- package/dist/composition/probe/index.js.map +1 -1
- package/dist/composition/probe/pipeline.d.ts +2 -0
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +6 -2
- package/dist/composition/probe/pipeline.js.map +1 -1
- package/dist/composition/probe/problem.d.ts +7 -0
- package/dist/composition/probe/problem.d.ts.map +1 -1
- package/dist/composition/probe/problem.js +15 -5
- package/dist/composition/probe/problem.js.map +1 -1
- package/dist/composition/probe/search-budget.d.ts.map +1 -1
- package/dist/composition/probe/search-budget.js +6 -2
- package/dist/composition/probe/search-budget.js.map +1 -1
- package/dist/composition/probe/study.d.ts +340 -0
- package/dist/composition/probe/study.d.ts.map +1 -0
- package/dist/composition/probe/study.js +1519 -0
- package/dist/composition/probe/study.js.map +1 -0
- package/dist/composition/proposed-bridges.js +1 -1
- package/dist/composition/proposed-bridges.js.map +1 -1
- package/dist/composition/quantities.d.ts +4 -16
- package/dist/composition/quantities.d.ts.map +1 -1
- package/dist/composition/quantities.js +4 -16
- package/dist/composition/quantities.js.map +1 -1
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +6 -2
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/uncertainty.d.ts +1 -1
- package/dist/composition/uncertainty.d.ts.map +1 -1
- package/dist/composition/user-equation.d.ts +87 -14
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +266 -59
- package/dist/composition/user-equation.js.map +1 -1
- package/dist/core/constants.d.ts +9 -4
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +9 -4
- package/dist/core/constants.js.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +2 -1
- package/dist/core/types.js.map +1 -1
- package/dist/dimensional/curvature.d.ts +7 -56
- package/dist/dimensional/curvature.d.ts.map +1 -1
- package/dist/dimensional/curvature.js +7 -76
- package/dist/dimensional/curvature.js.map +1 -1
- package/dist/dimensional/dimension-spec.d.ts +7 -1
- package/dist/dimensional/dimension-spec.d.ts.map +1 -1
- package/dist/dimensional/dimension-spec.js +131 -3
- package/dist/dimensional/dimension-spec.js.map +1 -1
- package/dist/dimensional/formula-names.d.ts +30 -0
- package/dist/dimensional/formula-names.d.ts.map +1 -0
- package/dist/dimensional/formula-names.js +37 -0
- package/dist/dimensional/formula-names.js.map +1 -0
- package/dist/dimensional/natural-units.d.ts +33 -0
- package/dist/dimensional/natural-units.d.ts.map +1 -0
- package/dist/dimensional/natural-units.js +58 -0
- package/dist/dimensional/natural-units.js.map +1 -0
- package/dist/{composition → dimensional}/symbolic-constants.d.ts +21 -2
- package/dist/dimensional/symbolic-constants.d.ts.map +1 -0
- package/dist/dimensional/symbolic-constants.js +116 -0
- package/dist/dimensional/symbolic-constants.js.map +1 -0
- package/dist/dimensional/unit-convention.d.ts +30 -0
- package/dist/dimensional/unit-convention.d.ts.map +1 -0
- package/dist/dimensional/unit-convention.js +60 -0
- package/dist/dimensional/unit-convention.js.map +1 -0
- package/dist/dimensional/units.d.ts +43 -0
- package/dist/dimensional/units.d.ts.map +1 -0
- package/dist/dimensional/units.js +197 -0
- package/dist/dimensional/units.js.map +1 -0
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/numerical/bianchi-residual.d.ts +55 -0
- package/dist/numerical/bianchi-residual.d.ts.map +1 -0
- package/dist/numerical/bianchi-residual.js +79 -0
- package/dist/numerical/bianchi-residual.js.map +1 -0
- package/dist/numerical/binding-value.d.ts +67 -0
- package/dist/numerical/binding-value.d.ts.map +1 -0
- package/dist/numerical/binding-value.js +347 -0
- package/dist/numerical/binding-value.js.map +1 -0
- package/dist/numerical/connection-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/connection-lowering-helpers.js +13 -26
- package/dist/numerical/connection-lowering-helpers.js.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +9 -0
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/float64-engine.d.ts.map +1 -1
- package/dist/numerical/float64-engine.js +23 -16
- package/dist/numerical/float64-engine.js.map +1 -1
- package/dist/numerical/formula-dimension.d.ts +7 -0
- package/dist/numerical/formula-dimension.d.ts.map +1 -1
- package/dist/numerical/formula-dimension.js +23 -6
- package/dist/numerical/formula-dimension.js.map +1 -1
- package/dist/numerical/formula-mathts.d.ts.map +1 -1
- package/dist/numerical/formula-mathts.js +68 -6
- package/dist/numerical/formula-mathts.js.map +1 -1
- package/dist/numerical/formula.d.ts +27 -0
- package/dist/numerical/formula.d.ts.map +1 -1
- package/dist/numerical/formula.js +68 -6
- package/dist/numerical/formula.js.map +1 -1
- package/dist/numerical/spacetime-metrics.d.ts +243 -0
- package/dist/numerical/spacetime-metrics.d.ts.map +1 -0
- package/dist/numerical/spacetime-metrics.js +1056 -0
- package/dist/numerical/spacetime-metrics.js.map +1 -0
- package/dist/relations/composition-table.d.ts +61 -0
- package/dist/relations/composition-table.d.ts.map +1 -0
- package/dist/relations/composition-table.js +140 -0
- package/dist/relations/composition-table.js.map +1 -0
- package/dist/relations/conventions.d.ts +63 -0
- package/dist/relations/conventions.d.ts.map +1 -0
- package/dist/relations/conventions.js +93 -0
- package/dist/relations/conventions.js.map +1 -0
- package/dist/relations/regime.d.ts +159 -0
- package/dist/relations/regime.d.ts.map +1 -0
- package/dist/relations/regime.js +304 -0
- package/dist/relations/regime.js.map +1 -0
- package/dist/relations/types.d.ts +259 -0
- package/dist/relations/types.d.ts.map +1 -0
- package/dist/relations/types.js +37 -0
- package/dist/relations/types.js.map +1 -0
- package/package.json +166 -163
- package/dist/composition/poster-source.d.ts.map +0 -1
- package/dist/composition/poster-source.js.map +0 -1
- package/dist/composition/symbolic-constants.d.ts.map +0 -1
- package/dist/composition/symbolic-constants.js +0 -65
- package/dist/composition/symbolic-constants.js.map +0 -1
|
@@ -24,11 +24,14 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { equals } from '../dimensional/algebra.js';
|
|
26
26
|
import { CANONICAL_EQUATIONS } from '../canonical/registry.js';
|
|
27
|
-
import { CONSTANTS } from '
|
|
27
|
+
import { CONSTANTS, piMultipleValue } from '../dimensional/symbolic-constants.js';
|
|
28
28
|
import { evalExpr } from './expr-eval.js';
|
|
29
|
-
import { canonicalPrefactor } from './canonical-prefactors.js';
|
|
29
|
+
import { CANONICAL_GROUP_PREFACTORS, canonicalPrefactor } from './canonical-prefactors.js';
|
|
30
|
+
import { formulaNameDimensions } from '../dimensional/formula-names.js';
|
|
30
31
|
import { parseUserEquation, resolveToCatalogName } from './user-equation.js';
|
|
31
|
-
import { parsePhysics } from '../numerical/formula-registry.js';
|
|
32
|
+
import { getFormulaParser, parsePhysics } from '../numerical/formula-registry.js';
|
|
33
|
+
import { formulaSymbolDimension } from '../numerical/formula-dimension.js';
|
|
34
|
+
import { CATALOG_GRAPH } from './catalog-graph.js';
|
|
32
35
|
import { DIMENSIONLESS } from '../dimensional/types.js';
|
|
33
36
|
/**
|
|
34
37
|
* The comparison points: variable `i` (in sorted name order) takes the value
|
|
@@ -42,18 +45,133 @@ import { DIMENSIONLESS } from '../dimensional/types.js';
|
|
|
42
45
|
const FIXED_POINT_EXPONENTS = [1, 1.3, 1.6];
|
|
43
46
|
/** Relative tolerance for "the ratio is constant" and "the ratio is 1". @internal */
|
|
44
47
|
const RATIO_TOLERANCE = 1e-9;
|
|
48
|
+
/**
|
|
49
|
+
* Catalog names for an entry whose frozen target name is a different word.
|
|
50
|
+
* CE-schwarzschild-radius's L0 record calls the target `radius`; the catalog
|
|
51
|
+
* quantity, and the name a student writes, is `schwarzschild-radius`.
|
|
52
|
+
*/
|
|
53
|
+
const ENTRY_TARGET_ALIASES = {
|
|
54
|
+
'CE-schwarzschild-radius': ['schwarzschild-radius'],
|
|
55
|
+
// The L0 id keeps the catalog name. The reduced name is the same entry.
|
|
56
|
+
// The non-reduced entry also answers to that catalog name when the formula uses h.
|
|
57
|
+
'CE-compton-wavelength': ['reduced-compton-wavelength'],
|
|
58
|
+
'CE-compton-wavelength-full': ['compton-wavelength'],
|
|
59
|
+
};
|
|
60
|
+
/** What a dimensionless registry stub stands for, when the symbol is not the latex. */
|
|
61
|
+
const STUB_GLOSS = {
|
|
62
|
+
one_minus_e_sq: '1-e²',
|
|
63
|
+
};
|
|
45
64
|
const normalize = (name) => name.replace(/_/g, '-');
|
|
65
|
+
/**
|
|
66
|
+
* Pair each user source with one canonical variable: by name first, then by a dimension that
|
|
67
|
+
* exactly one remaining canonical variable carries, repeated until nothing changes. `null` when the
|
|
68
|
+
* sources cannot be this entry's variables (a count, a name without a dimension, or a dimension no
|
|
69
|
+
* variable left carries); `'ambiguous'` when every source has a same-dimension partner but the
|
|
70
|
+
* pairing is not unique. Returns user name → canonical name, both normalized.
|
|
71
|
+
*/
|
|
72
|
+
function pairSources(sources, variables) {
|
|
73
|
+
if (sources.length !== variables.length)
|
|
74
|
+
return null;
|
|
75
|
+
const pairs = new Map();
|
|
76
|
+
const freeVars = new Map(variables.map((v) => [normalize(v.name), v.dim]));
|
|
77
|
+
let open = sources.filter((s) => {
|
|
78
|
+
if (!freeVars.has(s.name))
|
|
79
|
+
return true;
|
|
80
|
+
pairs.set(s.name, s.name);
|
|
81
|
+
freeVars.delete(s.name);
|
|
82
|
+
return false;
|
|
83
|
+
});
|
|
84
|
+
let progress = true;
|
|
85
|
+
while (open.length > 0 && progress) {
|
|
86
|
+
progress = false;
|
|
87
|
+
for (const s of open) {
|
|
88
|
+
if (s.dim === undefined)
|
|
89
|
+
return null;
|
|
90
|
+
const partners = [...freeVars].filter(([, dim]) => equals(dim, s.dim));
|
|
91
|
+
if (partners.length === 0)
|
|
92
|
+
return null;
|
|
93
|
+
if (partners.length === 1) {
|
|
94
|
+
pairs.set(s.name, partners[0][0]);
|
|
95
|
+
freeVars.delete(partners[0][0]);
|
|
96
|
+
progress = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
open = open.filter((s) => !pairs.has(s.name));
|
|
100
|
+
}
|
|
101
|
+
return open.length === 0 ? pairs : 'ambiguous';
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Peel user sources that restate a CE governing *constant* (persona finding W1).
|
|
105
|
+
*
|
|
106
|
+
* CE-mass-energy lists `c` as governing, but `c` is in {@link CONSTANTS}, so it is not a free
|
|
107
|
+
* variable of the comparison. Writing the catalog quantity `speed-of-light` (same dimension) must
|
|
108
|
+
* not make the source set look larger than `{mass}` and skip the prefactor check. A source pairs
|
|
109
|
+
* with a constant by name, or by a dimension that exactly one remaining constant carries and that
|
|
110
|
+
* no free variable carries (variables win — `velocity` still pairs with CE-kinetic-energy's
|
|
111
|
+
* `speed`). Returns the sources left for {@link pairSources}, plus user→constant name pairs.
|
|
112
|
+
* Leftover sources that match no variable and no unique constant make the entry a non-match
|
|
113
|
+
* (`null` from the caller when `forVariables` then fails to pair).
|
|
114
|
+
*/
|
|
115
|
+
function peelConstantAliases(sources, variables, constants) {
|
|
116
|
+
const constPairs = new Map();
|
|
117
|
+
const freeConsts = new Map(constants.map((c) => [normalize(c.name), c.dim]));
|
|
118
|
+
const forVariables = [];
|
|
119
|
+
for (const s of sources) {
|
|
120
|
+
if (variables.some((v) => normalize(v.name) === s.name)) {
|
|
121
|
+
forVariables.push(s);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (freeConsts.has(s.name)) {
|
|
125
|
+
constPairs.set(s.name, s.name);
|
|
126
|
+
freeConsts.delete(s.name);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (s.dim !== undefined) {
|
|
130
|
+
const varHits = variables.filter((v) => equals(v.dim, s.dim));
|
|
131
|
+
if (varHits.length > 0) {
|
|
132
|
+
forVariables.push(s);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
// h and ħ are both action. A formula that writes one is not the other.
|
|
136
|
+
if (Object.prototype.hasOwnProperty.call(CONSTANTS, s.name)) {
|
|
137
|
+
forVariables.push(s);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const constHits = [...freeConsts].filter(([, dim]) => equals(dim, s.dim));
|
|
141
|
+
if (constHits.length === 1) {
|
|
142
|
+
constPairs.set(s.name, constHits[0][0]);
|
|
143
|
+
freeConsts.delete(constHits[0][0]);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
forVariables.push(s);
|
|
148
|
+
}
|
|
149
|
+
return { forVariables, constPairs };
|
|
150
|
+
}
|
|
46
151
|
/** A governing variable that is a registered physical constant of the same dimension. */
|
|
47
152
|
function isConstant(v) {
|
|
48
153
|
const c = CONSTANTS[v.name];
|
|
49
154
|
return c !== undefined && equals(c.dim, v.dim);
|
|
50
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* The catalog bridge through which `wantTarget` names this entry's target: the entry records that
|
|
158
|
+
* it restates that bridge (`restatesBridge`), and the bridge's graph edge has `wantTarget` as its
|
|
159
|
+
* target (persona finding W7: `landauer-erasure-energy` is BE-16's target, and CE-landauer, which
|
|
160
|
+
* restates BE-16, names it `erasure-energy`). A recorded restatement, never a shared dimension.
|
|
161
|
+
*/
|
|
162
|
+
function targetThroughRestatedBridge(entry, wantTarget) {
|
|
163
|
+
if (entry.restatesBridge === undefined)
|
|
164
|
+
return undefined;
|
|
165
|
+
const beId = Number(entry.restatesBridge);
|
|
166
|
+
return CATALOG_GRAPH.find((e) => e.beId === beId && normalize(e.target.name) === wantTarget)?.id;
|
|
167
|
+
}
|
|
51
168
|
/** The free (non-constant, non-literal) symbols of an AST, with their dimensions. */
|
|
52
169
|
function freeSymbols(node, out) {
|
|
53
170
|
if (node.kind === 'symbol') {
|
|
54
171
|
const literal = Number.isFinite(Number(node.name));
|
|
55
|
-
if (!literal && CONSTANTS[node.name] === undefined)
|
|
172
|
+
if (!literal && CONSTANTS[node.name] === undefined && piMultipleValue(node.name) === undefined) {
|
|
56
173
|
out.set(node.name, node.dim);
|
|
174
|
+
}
|
|
57
175
|
return out;
|
|
58
176
|
}
|
|
59
177
|
const args = node.args ?? [];
|
|
@@ -62,12 +180,31 @@ function freeSymbols(node, out) {
|
|
|
62
180
|
return out;
|
|
63
181
|
}
|
|
64
182
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
183
|
+
* Dimensionless symbols the entry's AST holds that its governing set does not, and that the user
|
|
184
|
+
* names too: CE-ideal-gas writes `P = N k_B T/V` with the count `N` in its AST only (persona finding
|
|
185
|
+
* L6). They join the comparison variables BY NAME only; pairing a dimensionless stub such as
|
|
186
|
+
* `one_minus_e_sq` with any dimensionless user quantity by dimension would compare different laws.
|
|
187
|
+
*/
|
|
188
|
+
function astOnlyCounts(entry, userNames) {
|
|
189
|
+
if (entry.scalarAst === undefined)
|
|
190
|
+
return [];
|
|
191
|
+
const governing = new Set(entry.dimensional.governing.map((g) => normalize(g.name)));
|
|
192
|
+
return [...freeSymbols(entry.scalarAst, new Map())]
|
|
193
|
+
.filter(([name, dim]) => /^[A-Za-z][A-Za-z0-9_]*$/.test(name) && equals(dim, DIMENSIONLESS))
|
|
194
|
+
.filter(([name]) => !governing.has(normalize(name)) && userNames.has(normalize(name)))
|
|
195
|
+
.map(([name, dim]) => ({ name, dim }));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Every way to map free AST symbols onto governing variables: by name first,
|
|
199
|
+
* then any bijection that respects dimension. One map when each remaining
|
|
200
|
+
* symbol has a unique dimension; several when a product such as m₁ m₂ can be
|
|
201
|
+
* assigned either way. Empty when the counts differ or a symbol has no
|
|
202
|
+
* variable of its dimension. More than 24 bijections is treated as empty —
|
|
203
|
+
* that pairing is not checked, rather than searched.
|
|
67
204
|
*/
|
|
68
|
-
function
|
|
205
|
+
function symbolAlignments(symbols, governing) {
|
|
69
206
|
if (symbols.size !== governing.length)
|
|
70
|
-
return
|
|
207
|
+
return [];
|
|
71
208
|
const assignment = new Map();
|
|
72
209
|
const free = new Set(governing.map((g) => g.name));
|
|
73
210
|
for (const s of [...symbols.keys()].sort()) {
|
|
@@ -76,16 +213,58 @@ function alignSymbols(symbols, governing) {
|
|
|
76
213
|
free.delete(s);
|
|
77
214
|
}
|
|
78
215
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
216
|
+
const rest = [...symbols.entries()]
|
|
217
|
+
.filter(([s]) => !assignment.has(s))
|
|
218
|
+
.sort(([a], [b]) => a.localeCompare(b));
|
|
219
|
+
const out = [];
|
|
220
|
+
const CAP = 24;
|
|
221
|
+
const rec = (i) => {
|
|
222
|
+
if (out.length > CAP)
|
|
223
|
+
return;
|
|
224
|
+
if (i === rest.length) {
|
|
225
|
+
out.push(new Map(assignment));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const [s, dim] = rest[i];
|
|
229
|
+
const candidates = governing
|
|
230
|
+
.filter((g) => free.has(g.name) && equals(g.dim, dim))
|
|
231
|
+
.map((g) => g.name)
|
|
232
|
+
.sort();
|
|
233
|
+
for (const c of candidates) {
|
|
234
|
+
assignment.set(s, c);
|
|
235
|
+
free.delete(c);
|
|
236
|
+
rec(i + 1);
|
|
237
|
+
free.add(c);
|
|
238
|
+
assignment.delete(s);
|
|
239
|
+
if (out.length > CAP)
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
rec(0);
|
|
244
|
+
return out.length > CAP ? [] : out;
|
|
245
|
+
}
|
|
246
|
+
/** Why an AST could not be aligned, naming a dimensionless stub the user did not. */
|
|
247
|
+
function alignmentDetail(symbols, variables) {
|
|
248
|
+
const named = new Set(variables.map((v) => v.name));
|
|
249
|
+
const stubs = [...symbols.entries()]
|
|
250
|
+
.filter(([name, dim]) => !named.has(name) && equals(dim, DIMENSIONLESS))
|
|
251
|
+
.map(([name]) => name)
|
|
252
|
+
.sort();
|
|
253
|
+
if (symbols.size !== variables.length && stubs.length > 0) {
|
|
254
|
+
const shown = stubs.map((s) => (STUB_GLOSS[s] === undefined ? s : `${s} (${STUB_GLOSS[s]})`));
|
|
255
|
+
return `its formula depends on ${shown.join(', ')}, which your formula does not name`;
|
|
87
256
|
}
|
|
88
|
-
return
|
|
257
|
+
return 'its variables could not be aligned by name or by a unique dimension';
|
|
258
|
+
}
|
|
259
|
+
/** True when every alignment produced the same ratio at each fixed point. */
|
|
260
|
+
function sameRatios(series) {
|
|
261
|
+
const first = series[0];
|
|
262
|
+
if (first === undefined)
|
|
263
|
+
return false;
|
|
264
|
+
return series.every((s) => s.every((r, i) => {
|
|
265
|
+
const r0 = first[i];
|
|
266
|
+
return Number.isFinite(r) && Number.isFinite(r0) && r0 !== 0 && Math.abs(r / r0 - 1) <= RATIO_TOLERANCE;
|
|
267
|
+
}));
|
|
89
268
|
}
|
|
90
269
|
function classify(entry, ratios, recordsPrefactor) {
|
|
91
270
|
const base = { id: entry.id, name: entry.name };
|
|
@@ -99,7 +278,11 @@ function classify(entry, ratios, recordsPrefactor) {
|
|
|
99
278
|
kind: 'prefactor-unchecked',
|
|
100
279
|
detail: entry.epistemicStatus === 'dimensional'
|
|
101
280
|
? 'the registry records its dimensional form only'
|
|
102
|
-
:
|
|
281
|
+
: entry.epistemicStatus === 'fully-quantitative' && entry.fieldEquation !== undefined
|
|
282
|
+
? 'the registry records its prefactor only in its field equation, and its scalar record is the dimensional monomial'
|
|
283
|
+
: entry.epistemicStatus === 'fully-quantitative'
|
|
284
|
+
? 'its scalar record is the dimensional monomial only'
|
|
285
|
+
: 'the registry records it only up to a constant',
|
|
103
286
|
};
|
|
104
287
|
}
|
|
105
288
|
return Math.abs(r0 - 1) <= RATIO_TOLERANCE
|
|
@@ -108,55 +291,192 @@ function classify(entry, ratios, recordsPrefactor) {
|
|
|
108
291
|
}
|
|
109
292
|
/**
|
|
110
293
|
* Compare a user formula with every canonical equation that has the same
|
|
111
|
-
* target and the same non-constant variables
|
|
112
|
-
* `
|
|
294
|
+
* target and the same non-constant variables. The target must match by name
|
|
295
|
+
* (after `_` → `-`): pairing it by dimension would reach every law of that
|
|
296
|
+
* dimension. Each source matches a variable by name, or, when the source
|
|
297
|
+
* carries a dimension, by a dimension exactly one remaining variable carries
|
|
298
|
+
* (`velocity` → CE-kinetic-energy's `speed`); such pairs are listed in
|
|
299
|
+
* `paired`. A non-unique pairing is reported as `not-compared`, never guessed.
|
|
300
|
+
* `evaluateUser` receives values keyed by the user's (normalized) source names.
|
|
113
301
|
* Returns one comparison per matching entry, in registry order; empty when
|
|
114
302
|
* no entry matches.
|
|
115
303
|
*
|
|
116
304
|
* @internal
|
|
117
305
|
*/
|
|
118
|
-
|
|
306
|
+
function overrideValue(name, si, overrides) {
|
|
307
|
+
if (overrides !== undefined && Object.prototype.hasOwnProperty.call(overrides, name))
|
|
308
|
+
return overrides[name];
|
|
309
|
+
return si;
|
|
310
|
+
}
|
|
311
|
+
/** A short label for a non-SI constant table, or undefined when the table is SI. */
|
|
312
|
+
function overrideLabel(overrides) {
|
|
313
|
+
if (overrides === undefined)
|
|
314
|
+
return undefined;
|
|
315
|
+
const bits = [];
|
|
316
|
+
if (overrides.c === 1)
|
|
317
|
+
bits.push('c = 1');
|
|
318
|
+
if (overrides.hbar === 1)
|
|
319
|
+
bits.push('ħ = 1');
|
|
320
|
+
if (overrides.h === 2 * Math.PI)
|
|
321
|
+
bits.push('h = 2π');
|
|
322
|
+
if (overrides.G === 1)
|
|
323
|
+
bits.push('G = 1');
|
|
324
|
+
return bits.length === 0 ? undefined : bits.join(', ');
|
|
325
|
+
}
|
|
326
|
+
export function compareWithCanonical(target, sources, evaluateUser, entries = CANONICAL_EQUATIONS, constantOverrides) {
|
|
119
327
|
const wantTarget = normalize(target);
|
|
120
|
-
const wantSources =
|
|
328
|
+
const wantSources = new Map();
|
|
329
|
+
for (const s of sources) {
|
|
330
|
+
const name = normalize(typeof s === 'string' ? s : s.name);
|
|
331
|
+
if (!wantSources.has(name))
|
|
332
|
+
wantSources.set(name, typeof s === 'string' ? { name } : { name, dim: s.dim });
|
|
333
|
+
}
|
|
121
334
|
const results = [];
|
|
122
335
|
for (const entry of entries) {
|
|
123
336
|
const d = entry.dimensional;
|
|
124
|
-
|
|
337
|
+
const via = normalize(d.target.name) === wantTarget ? undefined : targetThroughRestatedBridge(entry, wantTarget);
|
|
338
|
+
const alias = (ENTRY_TARGET_ALIASES[entry.id] ?? []).includes(wantTarget);
|
|
339
|
+
if (normalize(d.target.name) !== wantTarget && via === undefined && !alias)
|
|
125
340
|
continue;
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
341
|
+
const targetVia = via === undefined ? {} : { targetVia: { bridge: via, its: d.target.name } };
|
|
342
|
+
let variables = d.governing.filter((g) => !isConstant(g));
|
|
343
|
+
const constants = d.governing.filter(isConstant);
|
|
344
|
+
// W1: sources that restate a governing constant (speed-of-light ↔ c) peel off first so they
|
|
345
|
+
// do not inflate the free-variable count and skip the prefactor check.
|
|
346
|
+
const { forVariables, constPairs } = peelConstantAliases([...wantSources.values()], variables, constants);
|
|
347
|
+
// A dimensionless group the record does not carry (sound-speed γ) is checked only when the
|
|
348
|
+
// user wrote it. Friedmann's curvature term is CE-friedmann-curvature, not an extension of the flat entry.
|
|
349
|
+
const groupSpec = CANONICAL_GROUP_PREFACTORS.find((g) => g.id === entry.id);
|
|
350
|
+
let boundGroup;
|
|
351
|
+
if (groupSpec) {
|
|
352
|
+
const idx = forVariables.findIndex((s) => s.name === groupSpec.group);
|
|
353
|
+
if (idx >= 0) {
|
|
354
|
+
boundGroup = forVariables[idx].name;
|
|
355
|
+
forVariables.splice(idx, 1);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
let pairing = pairSources(forVariables, variables);
|
|
359
|
+
if (pairing === null) {
|
|
360
|
+
// L6: a count the AST holds but the governing set does not (CE-ideal-gas's N), named by the user.
|
|
361
|
+
const counts = astOnlyCounts(entry, new Set(forVariables.map((s) => s.name)));
|
|
362
|
+
if (counts.length > 0) {
|
|
363
|
+
const widened = [...variables, ...counts];
|
|
364
|
+
pairing = pairSources(forVariables, widened);
|
|
365
|
+
if (pairing !== null)
|
|
366
|
+
variables = widened;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (pairing === null)
|
|
129
370
|
continue;
|
|
130
|
-
|
|
371
|
+
if (pairing === 'ambiguous') {
|
|
372
|
+
results.push({
|
|
373
|
+
id: entry.id,
|
|
374
|
+
name: entry.name,
|
|
375
|
+
kind: 'not-compared',
|
|
376
|
+
detail: 'your variable names differ from its names, and they pair with its variables by dimension in more than one way',
|
|
377
|
+
...targetVia,
|
|
378
|
+
});
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
const byDimension = [...pairing, ...constPairs]
|
|
382
|
+
.filter(([u, c]) => u !== c)
|
|
383
|
+
.sort(([a], [b]) => a.localeCompare(b));
|
|
384
|
+
const paired = byDimension.length > 0 ? { paired: byDimension } : {};
|
|
385
|
+
const names = variables.map((g) => normalize(g.name)).sort();
|
|
386
|
+
const points = FIXED_POINT_EXPONENTS.map((p) => {
|
|
387
|
+
const row = Object.fromEntries(names.map((n, i) => [n, Math.pow(1.7 + i, p)]));
|
|
388
|
+
if (boundGroup !== undefined)
|
|
389
|
+
row['__group'] = Math.pow(2.3, p);
|
|
390
|
+
return row;
|
|
391
|
+
});
|
|
392
|
+
// Constant aliases bind to the registered SI value (same as the canonical AST's CONSTANTS
|
|
393
|
+
// lookup), not to a fixed-point sample — otherwise the ratio would wander with the points.
|
|
394
|
+
const constBindings = Object.fromEntries([...constPairs].map(([u, cName]) => {
|
|
395
|
+
const c = CONSTANTS[cName];
|
|
396
|
+
if (c === undefined) {
|
|
397
|
+
throw new Error(`compareWithCanonical: governing constant '${cName}' is not in CONSTANTS`);
|
|
398
|
+
}
|
|
399
|
+
return [u, overrideValue(cName, c.value, constantOverrides)];
|
|
400
|
+
}));
|
|
401
|
+
const userAt = (p) => evaluateUser({
|
|
402
|
+
...Object.fromEntries([...pairing].map(([u, c]) => [u, p[c]])),
|
|
403
|
+
...constBindings,
|
|
404
|
+
...(boundGroup === undefined ? {} : { [boundGroup]: p['__group'] }),
|
|
405
|
+
});
|
|
131
406
|
// A prefactor the entry does not record may come from the sourced table,
|
|
132
407
|
// which lives outside the pinned src/canonical tree.
|
|
133
408
|
const tabled = entry.epistemicStatus === 'fully-quantitative' ? undefined : canonicalPrefactor(entry.id);
|
|
134
|
-
const
|
|
409
|
+
const extraFactor = (p) => boundGroup === undefined || groupSpec === undefined
|
|
410
|
+
? 1
|
|
411
|
+
: groupSpec.coefficient * Math.pow(p['__group'], groupSpec.exponent);
|
|
412
|
+
const scale = (flat, p) => (tabled ?? 1) * extraFactor(p) * flat;
|
|
135
413
|
let canonicalAt;
|
|
136
414
|
if (entry.scalarAst !== undefined) {
|
|
137
|
-
const
|
|
138
|
-
|
|
415
|
+
const ast = entry.scalarAst;
|
|
416
|
+
const symbols = freeSymbols(ast, new Map());
|
|
417
|
+
const alignments = symbolAlignments(symbols, variables);
|
|
418
|
+
const at = (alignment) => (p) => scale(evalExpr(ast, {
|
|
419
|
+
...(constantOverrides ?? {}),
|
|
420
|
+
...Object.fromEntries([...alignment].map(([sym, g]) => [sym, p[normalize(g)]])),
|
|
421
|
+
}), p);
|
|
422
|
+
if (alignments.length === 0) {
|
|
139
423
|
results.push({
|
|
140
424
|
id: entry.id,
|
|
141
425
|
name: entry.name,
|
|
142
426
|
kind: 'not-compared',
|
|
143
|
-
detail:
|
|
427
|
+
detail: alignmentDetail(symbols, variables),
|
|
428
|
+
...paired, ...targetVia,
|
|
144
429
|
});
|
|
145
430
|
continue;
|
|
146
431
|
}
|
|
147
|
-
|
|
148
|
-
|
|
432
|
+
if (alignments.length === 1) {
|
|
433
|
+
const alignment = alignments[0];
|
|
434
|
+
canonicalAt = at(alignment);
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
let series;
|
|
438
|
+
try {
|
|
439
|
+
series = alignments.map((alignment) => points.map((p) => userAt(p) / at(alignment)(p)));
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
results.push({
|
|
443
|
+
id: entry.id,
|
|
444
|
+
name: entry.name,
|
|
445
|
+
kind: 'not-compared',
|
|
446
|
+
detail: `an evaluation failed (${e instanceof Error ? e.message : String(e)})`,
|
|
447
|
+
...paired, ...targetVia,
|
|
448
|
+
});
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
if (!sameRatios(series)) {
|
|
452
|
+
results.push({
|
|
453
|
+
id: entry.id,
|
|
454
|
+
name: entry.name,
|
|
455
|
+
kind: 'not-compared',
|
|
456
|
+
detail: 'swapping its same-dimension symbols changes the ratio, so they were not paired',
|
|
457
|
+
...paired, ...targetVia,
|
|
458
|
+
});
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
// The ratio does not depend on which same-dimension symbol takes which
|
|
462
|
+
// variable (m₁ m₂ = m₂ m₁). One assignment is enough; none is named.
|
|
463
|
+
canonicalAt = at(alignments[0]);
|
|
464
|
+
}
|
|
149
465
|
}
|
|
150
466
|
else if (d.monomial !== null) {
|
|
467
|
+
// W4: a governing constant takes its SI value, as on the user side and in the AST branch. A
|
|
468
|
+
// name that is neither a variable nor a constant has no value, so the ratio is not finite and
|
|
469
|
+
// the entry is reported as not compared; reading it as 1 made Kepler III "factor 122404".
|
|
151
470
|
const monomial = d.monomial;
|
|
152
|
-
|
|
471
|
+
const constValues = new Map(constants.map((g) => [normalize(g.name), overrideValue(g.name, CONSTANTS[g.name].value, constantOverrides)]));
|
|
472
|
+
canonicalAt = (p) => scale(Object.entries(monomial).reduce((acc, [n, e]) => acc * Math.pow(p[normalize(n)] ?? constValues.get(normalize(n)) ?? Number.NaN, e), 1), p);
|
|
153
473
|
}
|
|
154
474
|
else {
|
|
155
475
|
continue;
|
|
156
476
|
}
|
|
157
477
|
let ratios;
|
|
158
478
|
try {
|
|
159
|
-
ratios = points.map((p) =>
|
|
479
|
+
ratios = points.map((p) => userAt(p) / canonicalAt(p));
|
|
160
480
|
}
|
|
161
481
|
catch (e) {
|
|
162
482
|
results.push({
|
|
@@ -164,47 +484,87 @@ export function compareWithCanonical(target, sources, evaluateUser, entries = CA
|
|
|
164
484
|
name: entry.name,
|
|
165
485
|
kind: 'not-compared',
|
|
166
486
|
detail: `an evaluation failed (${e instanceof Error ? e.message : String(e)})`,
|
|
487
|
+
...paired, ...targetVia,
|
|
167
488
|
});
|
|
168
489
|
continue;
|
|
169
490
|
}
|
|
170
491
|
if (!ratios.every((r) => Number.isFinite(r) && r !== 0)) {
|
|
171
|
-
results.push({ id: entry.id, name: entry.name, kind: 'not-compared', detail: 'a ratio was zero or not finite' });
|
|
492
|
+
results.push({ id: entry.id, name: entry.name, kind: 'not-compared', detail: 'a ratio was zero or not finite', ...paired, ...targetVia });
|
|
172
493
|
continue;
|
|
173
494
|
}
|
|
174
|
-
|
|
495
|
+
// A monomial-only record carries no prefactor. A fully-quantitative scalar AST does.
|
|
496
|
+
const recordsPrefactor = tabled !== undefined ||
|
|
497
|
+
boundGroup !== undefined ||
|
|
498
|
+
(entry.epistemicStatus === 'fully-quantitative' && entry.scalarAst !== undefined);
|
|
499
|
+
const extension = boundGroup !== undefined && groupSpec !== undefined
|
|
500
|
+
? `the dimensionless group ${groupSpec.group} is bound, so the prefactor includes ${groupSpec.coefficient}·${groupSpec.group}^${groupSpec.exponent}`
|
|
501
|
+
: undefined;
|
|
502
|
+
const classified = classify(entry, ratios, recordsPrefactor);
|
|
503
|
+
results.push({
|
|
504
|
+
...classified,
|
|
505
|
+
...(extension !== undefined && classified.detail === undefined ? { detail: extension } : {}),
|
|
506
|
+
...(names.length === 0 ? { constantsOnly: true } : {}),
|
|
507
|
+
...paired, ...targetVia,
|
|
508
|
+
});
|
|
175
509
|
}
|
|
176
|
-
|
|
510
|
+
const label = overrideLabel(constantOverrides);
|
|
511
|
+
return label === undefined ? results : results.map((r) => ({ ...r, evaluatedAt: label }));
|
|
177
512
|
}
|
|
178
513
|
/**
|
|
179
514
|
* Compare a `TARGET = EXPR` user equation (the `upt map --equation` input) with
|
|
180
515
|
* the canonical registry. Names resolve onto `catalogDims` the way
|
|
181
516
|
* `analyzeUserEquation` resolves them; `pi` and `tau` are the only named numbers.
|
|
517
|
+
* The right-hand side is dimension-checked through `parsePhysics` and evaluated by
|
|
518
|
+
* the active formula parser, the one `upt eval` uses, so a comparison accepts every
|
|
519
|
+
* function `eval` accepts (`ln(2)`, `asin`, `atan2`; persona finding W7). A registered
|
|
520
|
+
* constant takes its SI value, as in the canonical AST, unless
|
|
521
|
+
* `constantOverrides` replaces c, ħ, h or G (`--natural` / `--geometrized`).
|
|
182
522
|
* Returns `[]` when the equation does not parse or no entry matches.
|
|
183
523
|
*
|
|
184
524
|
* @internal
|
|
185
525
|
*/
|
|
186
|
-
export async function compareUserEquation(equation, catalogDims) {
|
|
187
|
-
const
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
526
|
+
export async function compareUserEquation(equation, catalogDims, options) {
|
|
527
|
+
const dimsIn = new Map(catalogDims);
|
|
528
|
+
for (const [name, dim] of formulaNameDimensions()) {
|
|
529
|
+
if (!dimsIn.has(name))
|
|
530
|
+
dimsIn.set(name, dim);
|
|
531
|
+
}
|
|
532
|
+
const catalogNames = new Set(dimsIn.keys());
|
|
533
|
+
const bindShort = options?.bindShortNames === true;
|
|
534
|
+
const declined = (token) => !bindShort && token.length === 1 && catalogNames.has(token);
|
|
535
|
+
// W2: same kebab→underscore rewrite as analyzeUserEquation, so comparison and
|
|
536
|
+
// dimensional check see one formula.
|
|
537
|
+
const eq = await parseUserEquation(equation, catalogNames);
|
|
538
|
+
const resolved = new Map(eq.sources.map((s) => [s, declined(s) ? s : (resolveToCatalogName(s, catalogNames) ?? s)]));
|
|
539
|
+
const target = declined(eq.target) ? eq.target : (resolveToCatalogName(eq.target, catalogNames) ?? eq.target);
|
|
191
540
|
const dims = {};
|
|
192
541
|
for (const [name, c] of Object.entries(CONSTANTS))
|
|
193
542
|
dims[name] = c.dim;
|
|
194
|
-
for (const [s, r] of resolved)
|
|
195
|
-
dims[s] =
|
|
196
|
-
|
|
543
|
+
for (const [s, r] of resolved) {
|
|
544
|
+
dims[s] = declined(s) ? DIMENSIONLESS : (dimsIn.get(r) ?? formulaSymbolDimension(s) ?? DIMENSIONLESS);
|
|
545
|
+
}
|
|
546
|
+
const rhs = eq.text.slice(eq.text.indexOf('=') + 1);
|
|
547
|
+
let compiled;
|
|
197
548
|
try {
|
|
198
|
-
|
|
549
|
+
await parsePhysics(rhs, dims);
|
|
550
|
+
compiled = (await getFormulaParser()).parse(rhs);
|
|
199
551
|
}
|
|
200
552
|
catch {
|
|
201
553
|
return [];
|
|
202
554
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
555
|
+
const overrides = options?.constantOverrides;
|
|
556
|
+
const constantValues = Object.fromEntries(Object.entries(CONSTANTS).map(([name, c]) => [name, overrideValue(name, c.value, overrides)]));
|
|
557
|
+
// A name the catalog does not know carries no dimension, so it never pairs by dimension.
|
|
558
|
+
const sources = [...resolved.entries()].map(([token, r]) => {
|
|
559
|
+
if (declined(token))
|
|
560
|
+
return r;
|
|
561
|
+
const dim = dimsIn.get(r);
|
|
562
|
+
return dim === undefined ? r : { name: r, dim };
|
|
563
|
+
});
|
|
564
|
+
return compareWithCanonical(target, sources, (values) => compiled.evaluate({
|
|
565
|
+
...constantValues,
|
|
206
566
|
...Object.fromEntries([...resolved].map(([s, r]) => [s, values[normalize(r)]])),
|
|
207
|
-
}));
|
|
567
|
+
}), CANONICAL_EQUATIONS, overrides);
|
|
208
568
|
}
|
|
209
569
|
/**
|
|
210
570
|
* The report lines for a comparison result, shared by `upt map --equation` and
|
|
@@ -219,15 +579,23 @@ export function describeComparisons(cs) {
|
|
|
219
579
|
}
|
|
220
580
|
/** One report line per comparison. @internal */
|
|
221
581
|
export function describeComparison(c) {
|
|
222
|
-
const
|
|
223
|
-
|
|
582
|
+
const pairs = [
|
|
583
|
+
...(c.targetVia === undefined
|
|
584
|
+
? []
|
|
585
|
+
: [`your target as its ${c.targetVia.its}, the target of ${c.targetVia.bridge}, which it restates`]),
|
|
586
|
+
...(c.paired === undefined ? [] : [`${c.paired.map(([yours, its]) => `your ${yours} as its ${its}`).join(', ')}, paired by dimension`]),
|
|
587
|
+
];
|
|
588
|
+
const who = `${c.id} (${c.name}${pairs.length === 0 ? '' : `; ${pairs.join('; ')}`})`;
|
|
589
|
+
const at = c.constantsOnly === true
|
|
590
|
+
? `at the ${c.evaluatedAt ?? 'SI'} constant values (no free variable, so only the value is compared, not the form)`
|
|
591
|
+
: `at ${FIXED_POINT_EXPONENTS.length} fixed points${c.evaluatedAt === undefined ? '' : ` (${c.evaluatedAt})`}`;
|
|
224
592
|
switch (c.kind) {
|
|
225
593
|
case 'agrees':
|
|
226
|
-
return `✓ agrees with ${who}, prefactor included: yours/canonical = 1 at ${
|
|
594
|
+
return `✓ agrees with ${who}, prefactor included: yours/canonical = 1 ${at}${c.detail ? ` (${c.detail})` : ''}`;
|
|
227
595
|
case 'factor':
|
|
228
|
-
return `⚠ differs from ${who} by a constant factor: yours/canonical = ${c.ratio.toPrecision(6)}
|
|
596
|
+
return `⚠ differs from ${who} by a constant factor: yours/canonical = ${c.ratio.toPrecision(6)} ${at}`;
|
|
229
597
|
case 'form':
|
|
230
|
-
return `⚠ differs in FORM from ${who}: yours/canonical is not constant across ${
|
|
598
|
+
return `⚠ differs in FORM from ${who}: yours/canonical is not constant across ${FIXED_POINT_EXPONENTS.length} fixed points`;
|
|
231
599
|
case 'prefactor-unchecked':
|
|
232
600
|
return `· same form as ${who}, but ${c.detail}, so your prefactor is NOT checked`;
|
|
233
601
|
case 'not-compared':
|