universal-physics-tensor 10.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/bin/upt.mjs +13 -1
- package/data/atlas/atlas.json +25 -25
- package/data/atlas/atlas.jsonld +1 -1
- package/data/atlas/diffusion.json +6 -6
- package/data/atlas/oscillators.json +7 -7
- package/data/atlas/waves.json +14 -14
- package/data/atlas/witness-results.json +11 -11
- package/data/bridge-catalog.json +371 -228
- package/data/bridge-catalog.schema.json +45 -7
- package/dist/atlas/applicability.d.ts.map +1 -1
- package/dist/atlas/applicability.js +21 -15
- package/dist/atlas/applicability.js.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts +9 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.js +15 -13
- package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -1
- package/dist/atlas/benchmark/loader.js +2 -2
- package/dist/atlas/benchmark/loader.js.map +1 -1
- package/dist/atlas/benchmark/stats.d.ts +2 -2
- package/dist/atlas/benchmark/stats.d.ts.map +1 -1
- package/dist/atlas/benchmark/stats.js +15 -7
- package/dist/atlas/benchmark/stats.js.map +1 -1
- package/dist/atlas/catalog-formal-ref.d.ts +26 -3
- package/dist/atlas/catalog-formal-ref.d.ts.map +1 -1
- package/dist/atlas/catalog-formal-ref.js +52 -5
- package/dist/atlas/catalog-formal-ref.js.map +1 -1
- package/dist/atlas/chain-pipeline.d.ts.map +1 -1
- package/dist/atlas/chain-pipeline.js +7 -8
- package/dist/atlas/chain-pipeline.js.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.d.ts +0 -4
- package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.js +8 -12
- package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
- package/dist/atlas/diffusion/bridges.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges.js +27 -39
- package/dist/atlas/diffusion/bridges.js.map +1 -1
- package/dist/atlas/diffusion/dimensions.d.ts +6 -14
- package/dist/atlas/diffusion/dimensions.d.ts.map +1 -1
- package/dist/atlas/diffusion/dimensions.js +8 -16
- package/dist/atlas/diffusion/dimensions.js.map +1 -1
- package/dist/atlas/diffusion/models.d.ts +3 -3
- package/dist/atlas/diffusion/models.d.ts.map +1 -1
- package/dist/atlas/diffusion/models.js +5 -10
- package/dist/atlas/diffusion/models.js.map +1 -1
- package/dist/atlas/diffusion/numerics.d.ts +16 -4
- package/dist/atlas/diffusion/numerics.d.ts.map +1 -1
- package/dist/atlas/diffusion/numerics.js +38 -24
- package/dist/atlas/diffusion/numerics.js.map +1 -1
- package/dist/atlas/link-prediction.d.ts +106 -3
- package/dist/atlas/link-prediction.d.ts.map +1 -1
- package/dist/atlas/link-prediction.js +212 -66
- package/dist/atlas/link-prediction.js.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.js +7 -11
- package/dist/atlas/oscillators/bridges-coarse.js.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.js +6 -7
- package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.d.ts +3 -16
- package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.js +23 -34
- package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
- package/dist/atlas/oscillators/dimensions.d.ts +9 -21
- package/dist/atlas/oscillators/dimensions.d.ts.map +1 -1
- package/dist/atlas/oscillators/dimensions.js +9 -21
- package/dist/atlas/oscillators/dimensions.js.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.d.ts +2 -2
- package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.js +17 -15
- package/dist/atlas/oscillators/limit-witnesses.js.map +1 -1
- package/dist/atlas/oscillators/models.d.ts.map +1 -1
- package/dist/atlas/oscillators/models.js +2 -6
- package/dist/atlas/oscillators/models.js.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.d.ts +29 -6
- package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.js +60 -40
- package/dist/atlas/oscillators/pendulum-motion.js.map +1 -1
- package/dist/atlas/oscillators/phase-translation.d.ts +0 -11
- package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/phase-translation.js +3 -4
- package/dist/atlas/oscillators/phase-translation.js.map +1 -1
- package/dist/atlas/oscillators/position-translation.d.ts +68 -7
- package/dist/atlas/oscillators/position-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/position-translation.js +123 -12
- package/dist/atlas/oscillators/position-translation.js.map +1 -1
- package/dist/atlas/oscillators/rejections.d.ts +0 -2
- package/dist/atlas/oscillators/rejections.d.ts.map +1 -1
- package/dist/atlas/oscillators/rejections.js +0 -7
- package/dist/atlas/oscillators/rejections.js.map +1 -1
- package/dist/atlas/physjs-entries.generated.d.ts +25 -24
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +25 -24
- package/dist/atlas/physjs-entries.generated.js.map +1 -1
- package/dist/atlas/physjs-ref.d.ts +34 -31
- package/dist/atlas/physjs-ref.d.ts.map +1 -1
- package/dist/atlas/physjs-ref.js +55 -53
- package/dist/atlas/physjs-ref.js.map +1 -1
- package/dist/atlas/physjs-reviewed.d.ts +1 -1
- package/dist/atlas/physjs-reviewed.js +15 -15
- package/dist/atlas/physjs-reviewed.js.map +1 -1
- package/dist/atlas/poster/statements.d.ts +0 -19
- package/dist/atlas/poster/statements.d.ts.map +1 -1
- package/dist/atlas/poster/statements.js +1 -1
- package/dist/atlas/poster/statements.js.map +1 -1
- package/dist/atlas/proof-target.d.ts +1 -1
- package/dist/atlas/proof-target.js +1 -1
- package/dist/atlas/proof-target.js.map +1 -1
- package/dist/atlas/regime.d.ts +1 -1
- package/dist/atlas/regime.d.ts.map +1 -1
- package/dist/atlas/regime.js +1 -1
- package/dist/atlas/regime.js.map +1 -1
- package/dist/atlas/text-overlap.d.ts +23 -0
- package/dist/atlas/text-overlap.d.ts.map +1 -0
- package/dist/atlas/text-overlap.js +41 -0
- package/dist/atlas/text-overlap.js.map +1 -0
- package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/waves/bridges-closure.js +2 -6
- 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 +32 -48
- package/dist/atlas/waves/bridges.js.map +1 -1
- package/dist/atlas/waves/models.d.ts +5 -6
- package/dist/atlas/waves/models.d.ts.map +1 -1
- package/dist/atlas/waves/models.js +7 -13
- package/dist/atlas/waves/models.js.map +1 -1
- package/dist/atlas/waves/numerics.d.ts.map +1 -1
- package/dist/atlas/waves/numerics.js +10 -3
- package/dist/atlas/waves/numerics.js.map +1 -1
- package/dist/atlas/witness-numeric.d.ts +30 -0
- package/dist/atlas/witness-numeric.d.ts.map +1 -1
- package/dist/atlas/witness-numeric.js +53 -0
- package/dist/atlas/witness-numeric.js.map +1 -1
- package/dist/atlas/witness-specs.d.ts.map +1 -1
- package/dist/atlas/witness-specs.js +19 -0
- package/dist/atlas/witness-specs.js.map +1 -1
- package/dist/atlas/witness-symbolic.d.ts +75 -3
- package/dist/atlas/witness-symbolic.d.ts.map +1 -1
- package/dist/atlas/witness-symbolic.js +116 -10
- package/dist/atlas/witness-symbolic.js.map +1 -1
- package/dist/bridges/catalog-load.d.ts.map +1 -1
- package/dist/bridges/catalog-load.js +13 -8
- package/dist/bridges/catalog-load.js.map +1 -1
- package/dist/bridges/catalog-types.d.ts +26 -2
- package/dist/bridges/catalog-types.d.ts.map +1 -1
- package/dist/bridges/catalog-types.js +11 -1
- package/dist/bridges/catalog-types.js.map +1 -1
- package/dist/bridges/evaluation-errors.d.ts +31 -1
- package/dist/bridges/evaluation-errors.d.ts.map +1 -1
- package/dist/bridges/evaluation-errors.js +20 -2
- package/dist/bridges/evaluation-errors.js.map +1 -1
- package/dist/bridges/evaluator-inputs.d.ts.map +1 -1
- package/dist/bridges/evaluator-inputs.js +7 -5
- package/dist/bridges/evaluator-inputs.js.map +1 -1
- package/dist/bridges/evaluators.d.ts.map +1 -1
- package/dist/bridges/evaluators.js +27 -12
- package/dist/bridges/evaluators.js.map +1 -1
- package/dist/bridges/expr-parse.d.ts +11 -0
- package/dist/bridges/expr-parse.d.ts.map +1 -1
- package/dist/bridges/expr-parse.js +14 -5
- package/dist/bridges/expr-parse.js.map +1 -1
- package/dist/bridges/holds.d.ts +35 -3
- package/dist/bridges/holds.d.ts.map +1 -1
- package/dist/bridges/holds.js +117 -23
- package/dist/bridges/holds.js.map +1 -1
- package/dist/bridges/notices.d.ts.map +1 -1
- package/dist/bridges/notices.js +5 -5
- package/dist/bridges/notices.js.map +1 -1
- package/dist/bridges/relation-eval.d.ts +4 -4
- package/dist/bridges/relation-eval.d.ts.map +1 -1
- package/dist/bridges/relation-eval.js +15 -16
- package/dist/bridges/relation-eval.js.map +1 -1
- package/dist/bridges/sensitivity.d.ts.map +1 -1
- package/dist/bridges/sensitivity.js +3 -3
- package/dist/bridges/sensitivity.js.map +1 -1
- package/dist/bridges/validity.d.ts +33 -0
- package/dist/bridges/validity.d.ts.map +1 -0
- package/dist/bridges/validity.js +67 -0
- package/dist/bridges/validity.js.map +1 -0
- package/dist/canonical/entries/atomic.js +1 -3
- package/dist/canonical/entries/atomic.js.map +1 -1
- package/dist/canonical/entries/condensed-matter.d.ts.map +1 -1
- package/dist/canonical/entries/condensed-matter.js +4 -5
- package/dist/canonical/entries/condensed-matter.js.map +1 -1
- package/dist/canonical/entries/dimensional-classics.d.ts.map +1 -1
- package/dist/canonical/entries/dimensional-classics.js +3 -4
- package/dist/canonical/entries/dimensional-classics.js.map +1 -1
- package/dist/canonical/entries/electromagnetism.d.ts.map +1 -1
- package/dist/canonical/entries/electromagnetism.js +4 -10
- package/dist/canonical/entries/electromagnetism.js.map +1 -1
- package/dist/canonical/entries/fluids-waves.d.ts.map +1 -1
- package/dist/canonical/entries/fluids-waves.js +3 -7
- package/dist/canonical/entries/fluids-waves.js.map +1 -1
- package/dist/canonical/entries/mechanics.d.ts.map +1 -1
- package/dist/canonical/entries/mechanics.js +4 -6
- package/dist/canonical/entries/mechanics.js.map +1 -1
- package/dist/canonical/entries/nonmonomial.d.ts.map +1 -1
- package/dist/canonical/entries/nonmonomial.js +9 -17
- package/dist/canonical/entries/nonmonomial.js.map +1 -1
- package/dist/canonical/entries/relativity.d.ts.map +1 -1
- package/dist/canonical/entries/relativity.js +6 -6
- package/dist/canonical/entries/relativity.js.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.d.ts.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.js +6 -10
- package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
- package/dist/canonical/fixed-points.d.ts +94 -0
- package/dist/canonical/fixed-points.d.ts.map +1 -0
- package/dist/canonical/fixed-points.js +81 -0
- package/dist/canonical/fixed-points.js.map +1 -0
- package/dist/canonical/linkage.d.ts.map +1 -1
- package/dist/canonical/linkage.js +25 -44
- package/dist/canonical/linkage.js.map +1 -1
- package/dist/canonical/normal-form.d.ts.map +1 -1
- package/dist/canonical/normal-form.js +5 -11
- package/dist/canonical/normal-form.js.map +1 -1
- package/dist/canonical/structural.d.ts +21 -21
- package/dist/canonical/structural.d.ts.map +1 -1
- package/dist/canonical/structural.js +40 -19
- package/dist/canonical/structural.js.map +1 -1
- package/dist/cases/brownian-sphere.d.ts +3 -3
- package/dist/cases/brownian-sphere.d.ts.map +1 -1
- package/dist/cases/brownian-sphere.js +6 -5
- package/dist/cases/brownian-sphere.js.map +1 -1
- package/dist/cases/damped-resonator.d.ts.map +1 -1
- package/dist/cases/damped-resonator.js +6 -9
- package/dist/cases/damped-resonator.js.map +1 -1
- package/dist/cases/kepler-rv.d.ts +1 -1
- package/dist/cases/kepler-rv.d.ts.map +1 -1
- package/dist/cases/kepler-rv.js +3 -2
- package/dist/cases/kepler-rv.js.map +1 -1
- package/dist/cases/lumped-cooling.d.ts +8 -3
- package/dist/cases/lumped-cooling.d.ts.map +1 -1
- package/dist/cases/lumped-cooling.js +21 -23
- package/dist/cases/lumped-cooling.js.map +1 -1
- package/dist/cases/quadrature.d.ts +7 -9
- package/dist/cases/quadrature.d.ts.map +1 -1
- package/dist/cases/quadrature.js +28 -32
- package/dist/cases/quadrature.js.map +1 -1
- package/dist/cases/resistor-noise.js +4 -4
- package/dist/cases/resistor-noise.js.map +1 -1
- package/dist/cases/skin-depth.d.ts +0 -4
- package/dist/cases/skin-depth.d.ts.map +1 -1
- package/dist/cases/skin-depth.js +3 -7
- package/dist/cases/skin-depth.js.map +1 -1
- package/dist/cli/args.d.ts +23 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +30 -8
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/bindings.d.ts.map +1 -1
- package/dist/cli/bindings.js +5 -4
- package/dist/cli/bindings.js.map +1 -1
- package/dist/cli/command.d.ts +8 -1
- package/dist/cli/command.d.ts.map +1 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/commands/_atlas-map.d.ts +0 -9
- package/dist/cli/commands/_atlas-map.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-map.js +8 -18
- package/dist/cli/commands/_atlas-map.js.map +1 -1
- package/dist/cli/commands/_atlas-route.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-route.js +6 -2
- package/dist/cli/commands/_atlas-route.js.map +1 -1
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +8 -9
- package/dist/cli/commands/_discovery-opts.js.map +1 -1
- package/dist/cli/commands/atlas.d.ts.map +1 -1
- package/dist/cli/commands/atlas.js +8 -5
- 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 +8 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/axes.d.ts.map +1 -1
- package/dist/cli/commands/axes.js +20 -1
- package/dist/cli/commands/axes.js.map +1 -1
- package/dist/cli/commands/confront.d.ts.map +1 -1
- package/dist/cli/commands/confront.js +8 -14
- package/dist/cli/commands/confront.js.map +1 -1
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +22 -22
- 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 +6 -2
- 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 +1 -0
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/evaluate.d.ts.map +1 -1
- package/dist/cli/commands/evaluate.js +65 -37
- 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 +2 -1
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/ground.d.ts.map +1 -1
- package/dist/cli/commands/ground.js +1 -0
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +75 -5
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/commands/metric.d.ts.map +1 -1
- package/dist/cli/commands/metric.js +12 -9
- package/dist/cli/commands/metric.js.map +1 -1
- package/dist/cli/commands/path.d.ts +10 -0
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +25 -3
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/probe.d.ts.map +1 -1
- package/dist/cli/commands/probe.js +59 -16
- package/dist/cli/commands/probe.js.map +1 -1
- package/dist/cli/commands/regime.d.ts.map +1 -1
- package/dist/cli/commands/regime.js +1 -0
- package/dist/cli/commands/regime.js.map +1 -1
- package/dist/cli/commands/retrieve.d.ts.map +1 -1
- package/dist/cli/commands/retrieve.js +1 -0
- package/dist/cli/commands/retrieve.js.map +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +1 -0
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/symbolic.d.ts.map +1 -1
- package/dist/cli/commands/symbolic.js +19 -28
- package/dist/cli/commands/symbolic.js.map +1 -1
- package/dist/cli/commands/testplan.d.ts.map +1 -1
- package/dist/cli/commands/testplan.js +4 -2
- package/dist/cli/commands/testplan.js.map +1 -1
- package/dist/cli/expr-print.d.ts +0 -2
- package/dist/cli/expr-print.d.ts.map +1 -1
- package/dist/cli/expr-print.js +7 -31
- package/dist/cli/expr-print.js.map +1 -1
- package/dist/cli/main.d.ts +7 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +18 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/numeric-flag.d.ts +12 -0
- package/dist/cli/numeric-flag.d.ts.map +1 -0
- package/dist/cli/numeric-flag.js +44 -0
- package/dist/cli/numeric-flag.js.map +1 -0
- package/dist/cli/output.d.ts +20 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +15 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/record-reach.js +2 -2
- package/dist/cli/record-reach.js.map +1 -1
- package/dist/cli/record-tables.d.ts.map +1 -1
- package/dist/cli/record-tables.js +6 -5
- package/dist/cli/record-tables.js.map +1 -1
- package/dist/cli/record.d.ts +1 -5
- package/dist/cli/record.d.ts.map +1 -1
- package/dist/cli/record.js +9 -8
- package/dist/cli/record.js.map +1 -1
- package/dist/cli/search-index.d.ts.map +1 -1
- package/dist/cli/search-index.js +7 -6
- package/dist/cli/search-index.js.map +1 -1
- package/dist/cli/statuses.d.ts +0 -2
- package/dist/cli/statuses.d.ts.map +1 -1
- package/dist/cli/statuses.js +0 -7
- package/dist/cli/statuses.js.map +1 -1
- package/dist/cli/stored-results.d.ts +7 -0
- package/dist/cli/stored-results.d.ts.map +1 -0
- package/dist/cli/stored-results.js +23 -0
- package/dist/cli/stored-results.js.map +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +7 -5
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +34 -5
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +28 -4
- package/dist/cli-api.js.map +1 -1
- package/dist/composition/algebraic-equivalence.d.ts +43 -0
- package/dist/composition/algebraic-equivalence.d.ts.map +1 -0
- package/dist/composition/algebraic-equivalence.js +115 -0
- package/dist/composition/algebraic-equivalence.js.map +1 -0
- package/dist/composition/axes.d.ts +0 -6
- package/dist/composition/axes.d.ts.map +1 -1
- package/dist/composition/axes.js +6 -6
- package/dist/composition/axes.js.map +1 -1
- package/dist/composition/axis-audit.d.ts +47 -20
- package/dist/composition/axis-audit.d.ts.map +1 -1
- package/dist/composition/axis-audit.js +82 -9
- package/dist/composition/axis-audit.js.map +1 -1
- package/dist/composition/bridge-analysis.d.ts +17 -0
- package/dist/composition/bridge-analysis.d.ts.map +1 -1
- package/dist/composition/bridge-analysis.js +102 -55
- package/dist/composition/bridge-analysis.js.map +1 -1
- package/dist/composition/canonical-compare.d.ts +40 -0
- package/dist/composition/canonical-compare.d.ts.map +1 -1
- package/dist/composition/canonical-compare.js +122 -24
- package/dist/composition/canonical-compare.js.map +1 -1
- package/dist/composition/canonical-graph.d.ts +1 -1
- package/dist/composition/canonical-graph.d.ts.map +1 -1
- package/dist/composition/canonical-graph.js +9 -36
- package/dist/composition/canonical-graph.js.map +1 -1
- package/dist/composition/canonical-json.js +2 -2
- package/dist/composition/canonical-json.js.map +1 -1
- package/dist/composition/catalog-graph.d.ts.map +1 -1
- package/dist/composition/catalog-graph.js +2 -5
- package/dist/composition/catalog-graph.js.map +1 -1
- package/dist/composition/chain-candidate.d.ts +8 -0
- package/dist/composition/chain-candidate.d.ts.map +1 -1
- package/dist/composition/chain-candidate.js +9 -2
- package/dist/composition/chain-candidate.js.map +1 -1
- package/dist/composition/chain-match.d.ts +6 -3
- package/dist/composition/chain-match.d.ts.map +1 -1
- package/dist/composition/chain-match.js +4 -1
- package/dist/composition/chain-match.js.map +1 -1
- package/dist/composition/chain-result.d.ts.map +1 -1
- package/dist/composition/chain-result.js +2 -14
- package/dist/composition/chain-result.js.map +1 -1
- package/dist/composition/compose-symbolic.d.ts.map +1 -1
- package/dist/composition/compose-symbolic.js +3 -2
- package/dist/composition/compose-symbolic.js.map +1 -1
- package/dist/composition/compose.d.ts.map +1 -1
- package/dist/composition/compose.js +13 -5
- package/dist/composition/compose.js.map +1 -1
- package/dist/composition/composition-recovery.d.ts.map +1 -1
- package/dist/composition/composition-recovery.js +4 -7
- package/dist/composition/composition-recovery.js.map +1 -1
- package/dist/composition/discovery.d.ts +56 -0
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +114 -60
- package/dist/composition/discovery.js.map +1 -1
- package/dist/composition/edge.d.ts +21 -2
- package/dist/composition/edge.d.ts.map +1 -1
- package/dist/composition/edge.js +23 -1
- package/dist/composition/edge.js.map +1 -1
- package/dist/composition/enumerate.d.ts.map +1 -1
- package/dist/composition/enumerate.js +18 -3
- package/dist/composition/enumerate.js.map +1 -1
- package/dist/composition/evaluate-relation.d.ts +35 -11
- package/dist/composition/evaluate-relation.d.ts.map +1 -1
- package/dist/composition/evaluate-relation.js +60 -39
- package/dist/composition/evaluate-relation.js.map +1 -1
- package/dist/composition/explain.d.ts +3 -12
- package/dist/composition/explain.d.ts.map +1 -1
- package/dist/composition/explain.js +7 -20
- package/dist/composition/explain.js.map +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +2 -11
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +16 -0
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +15 -20
- package/dist/composition/expr-simplify.js.map +1 -1
- package/dist/composition/formula-shape.d.ts +23 -4
- package/dist/composition/formula-shape.d.ts.map +1 -1
- package/dist/composition/formula-shape.js +57 -17
- package/dist/composition/formula-shape.js.map +1 -1
- package/dist/composition/graph-structure.d.ts +98 -0
- package/dist/composition/graph-structure.d.ts.map +1 -0
- package/dist/composition/graph-structure.js +167 -0
- package/dist/composition/graph-structure.js.map +1 -0
- package/dist/composition/graph-viz-svg.d.ts.map +1 -1
- package/dist/composition/graph-viz-svg.js +1 -1
- package/dist/composition/graph-viz-svg.js.map +1 -1
- package/dist/composition/graph-viz.d.ts.map +1 -1
- package/dist/composition/graph-viz.js +8 -37
- package/dist/composition/graph-viz.js.map +1 -1
- package/dist/composition/identifiability.d.ts +91 -4
- package/dist/composition/identifiability.d.ts.map +1 -1
- package/dist/composition/identifiability.js +363 -6
- package/dist/composition/identifiability.js.map +1 -1
- package/dist/composition/index.d.ts +8 -4
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +3 -2
- package/dist/composition/index.js.map +1 -1
- package/dist/composition/mathts-quiet.d.ts +4 -3
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +4 -3
- package/dist/composition/mathts-quiet.js.map +1 -1
- package/dist/composition/mathts-scalar-symbols.d.ts.map +1 -1
- package/dist/composition/mathts-scalar-symbols.js +2 -1
- package/dist/composition/mathts-scalar-symbols.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +4 -2
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +20 -9
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +17 -0
- package/dist/composition/probe/dataset.d.ts.map +1 -1
- package/dist/composition/probe/dataset.js +95 -50
- package/dist/composition/probe/dataset.js.map +1 -1
- package/dist/composition/probe/experiment-design.d.ts +5 -1
- package/dist/composition/probe/experiment-design.d.ts.map +1 -1
- package/dist/composition/probe/experiment-design.js +44 -24
- package/dist/composition/probe/experiment-design.js.map +1 -1
- package/dist/composition/probe/falsify.d.ts.map +1 -1
- package/dist/composition/probe/falsify.js +2 -0
- package/dist/composition/probe/falsify.js.map +1 -1
- package/dist/composition/probe/fit.d.ts +6 -0
- package/dist/composition/probe/fit.d.ts.map +1 -1
- package/dist/composition/probe/fit.js +46 -22
- package/dist/composition/probe/fit.js.map +1 -1
- package/dist/composition/probe/frontier.d.ts.map +1 -1
- package/dist/composition/probe/frontier.js +33 -15
- package/dist/composition/probe/frontier.js.map +1 -1
- package/dist/composition/probe/generator.d.ts +27 -1
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +53 -30
- package/dist/composition/probe/generator.js.map +1 -1
- package/dist/composition/probe/index.d.ts +14 -0
- package/dist/composition/probe/index.d.ts.map +1 -1
- package/dist/composition/probe/index.js +6 -0
- package/dist/composition/probe/index.js.map +1 -1
- package/dist/composition/probe/limits.d.ts +24 -1
- package/dist/composition/probe/limits.d.ts.map +1 -1
- package/dist/composition/probe/limits.js +53 -11
- package/dist/composition/probe/limits.js.map +1 -1
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +10 -4
- package/dist/composition/probe/pipeline.js.map +1 -1
- package/dist/composition/probe/power-law.d.ts +121 -0
- package/dist/composition/probe/power-law.d.ts.map +1 -0
- package/dist/composition/probe/power-law.js +255 -0
- package/dist/composition/probe/power-law.js.map +1 -0
- package/dist/composition/probe/problem.d.ts +7 -4
- package/dist/composition/probe/problem.d.ts.map +1 -1
- package/dist/composition/probe/problem.js +177 -49
- package/dist/composition/probe/problem.js.map +1 -1
- package/dist/composition/probe/report.js +1 -1
- package/dist/composition/probe/report.js.map +1 -1
- package/dist/composition/probe/residual.d.ts +6 -1
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +9 -7
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/structure.d.ts +82 -17
- package/dist/composition/probe/structure.d.ts.map +1 -1
- package/dist/composition/probe/structure.js +129 -55
- package/dist/composition/probe/structure.js.map +1 -1
- package/dist/composition/probe/study.d.ts +31 -9
- package/dist/composition/probe/study.d.ts.map +1 -1
- package/dist/composition/probe/study.js +236 -181
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +17 -0
- package/dist/composition/probe/t-tail.d.ts.map +1 -0
- package/dist/composition/probe/t-tail.js +32 -0
- package/dist/composition/probe/t-tail.js.map +1 -0
- package/dist/composition/probe/types.d.ts +3 -0
- package/dist/composition/probe/types.d.ts.map +1 -1
- package/dist/composition/probe/types.js.map +1 -1
- package/dist/composition/proposed-bridges.d.ts +41 -10
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +100 -55
- package/dist/composition/proposed-bridges.js.map +1 -1
- package/dist/composition/quantity-clusters.d.ts +48 -0
- package/dist/composition/quantity-clusters.d.ts.map +1 -0
- package/dist/composition/quantity-clusters.js +98 -0
- package/dist/composition/quantity-clusters.js.map +1 -0
- package/dist/composition/rational-exponent.d.ts +40 -0
- package/dist/composition/rational-exponent.d.ts.map +1 -0
- package/dist/composition/rational-exponent.js +65 -0
- package/dist/composition/rational-exponent.js.map +1 -0
- package/dist/composition/representative-values.d.ts +22 -0
- package/dist/composition/representative-values.d.ts.map +1 -1
- package/dist/composition/representative-values.js +23 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +2 -1
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +2 -2
- package/dist/composition/user-equation.js.map +1 -1
- package/dist/core/assignment.d.ts +19 -0
- package/dist/core/assignment.d.ts.map +1 -0
- package/dist/core/assignment.js +19 -0
- package/dist/core/assignment.js.map +1 -0
- package/dist/core/compare.d.ts +32 -0
- package/dist/core/compare.d.ts.map +1 -0
- package/dist/core/compare.js +46 -0
- package/dist/core/compare.js.map +1 -0
- package/dist/core/constants.d.ts +30 -30
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +47 -30
- package/dist/core/constants.js.map +1 -1
- package/dist/core/data-file.d.ts +7 -0
- package/dist/core/data-file.d.ts.map +1 -1
- package/dist/core/data-file.js +17 -0
- package/dist/core/data-file.js.map +1 -1
- package/dist/core/format.d.ts +36 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +39 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/hash.d.ts +14 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +17 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/json-schema.d.ts +2 -0
- package/dist/core/json-schema.d.ts.map +1 -1
- package/dist/core/json-schema.js +14 -13
- package/dist/core/json-schema.js.map +1 -1
- package/dist/core/labeled-tensor.d.ts.map +1 -1
- package/dist/core/labeled-tensor.js +0 -8
- package/dist/core/labeled-tensor.js.map +1 -1
- package/dist/core/mathts-read.d.ts +25 -0
- package/dist/core/mathts-read.d.ts.map +1 -0
- package/dist/core/mathts-read.js +51 -0
- package/dist/core/mathts-read.js.map +1 -0
- package/dist/core/tensor.d.ts.map +1 -1
- package/dist/core/tensor.js +24 -0
- package/dist/core/tensor.js.map +1 -1
- package/dist/core/types.d.ts +5 -5
- package/dist/diff/bridge-gradient.d.ts +19 -6
- package/dist/diff/bridge-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-gradient.js +19 -11
- package/dist/diff/bridge-gradient.js.map +1 -1
- package/dist/diff/bridge-specs.d.ts.map +1 -1
- package/dist/diff/bridge-specs.js +3 -0
- package/dist/diff/bridge-specs.js.map +1 -1
- package/dist/dimensional/algebra.d.ts +18 -0
- package/dist/dimensional/algebra.d.ts.map +1 -1
- package/dist/dimensional/algebra.js +41 -1
- package/dist/dimensional/algebra.js.map +1 -1
- package/dist/dimensional/ast-builders.d.ts +7 -0
- package/dist/dimensional/ast-builders.d.ts.map +1 -1
- package/dist/dimensional/ast-builders.js +11 -0
- package/dist/dimensional/ast-builders.js.map +1 -1
- package/dist/dimensional/ast-leaves.d.ts +81 -0
- package/dist/dimensional/ast-leaves.d.ts.map +1 -0
- package/dist/dimensional/ast-leaves.js +146 -0
- package/dist/dimensional/ast-leaves.js.map +1 -0
- package/dist/dimensional/buckingham.d.ts.map +1 -1
- package/dist/dimensional/buckingham.js +15 -27
- package/dist/dimensional/buckingham.js.map +1 -1
- package/dist/dimensional/constant-rows.js +9 -9
- package/dist/dimensional/constant-rows.js.map +1 -1
- package/dist/dimensional/dimension-inference.d.ts.map +1 -1
- package/dist/dimensional/dimension-inference.js +1 -2
- package/dist/dimensional/dimension-inference.js.map +1 -1
- package/dist/dimensional/errors.d.ts +1 -1
- package/dist/dimensional/errors.d.ts.map +1 -1
- package/dist/dimensional/errors.js +1 -15
- package/dist/dimensional/errors.js.map +1 -1
- package/dist/dimensional/exact-scale.d.ts +0 -17
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +8 -8
- package/dist/dimensional/exact-scale.js.map +1 -1
- package/dist/dimensional/gauge-field.d.ts.map +1 -1
- package/dist/dimensional/gauge-field.js +2 -2
- package/dist/dimensional/gauge-field.js.map +1 -1
- package/dist/dimensional/hyphen-names.d.ts +12 -2
- package/dist/dimensional/hyphen-names.d.ts.map +1 -1
- package/dist/dimensional/hyphen-names.js +44 -19
- package/dist/dimensional/hyphen-names.js.map +1 -1
- package/dist/dimensional/metric.d.ts.map +1 -1
- package/dist/dimensional/metric.js +0 -1
- package/dist/dimensional/metric.js.map +1 -1
- package/dist/dimensional/symbolic-constants.d.ts +9 -0
- package/dist/dimensional/symbolic-constants.d.ts.map +1 -1
- package/dist/dimensional/symbolic-constants.js +13 -1
- package/dist/dimensional/symbolic-constants.js.map +1 -1
- package/dist/dimensional/types.d.ts +36 -0
- package/dist/dimensional/types.d.ts.map +1 -1
- package/dist/dimensional/types.js +45 -7
- package/dist/dimensional/types.js.map +1 -1
- package/dist/dimensional/unit-data.js +2 -2
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/numerical/christoffel-flat.d.ts.map +1 -1
- package/dist/numerical/christoffel-flat.js +3 -2
- package/dist/numerical/christoffel-flat.js.map +1 -1
- package/dist/numerical/covariant-eikonal.d.ts.map +1 -1
- package/dist/numerical/covariant-eikonal.js +34 -11
- package/dist/numerical/covariant-eikonal.js.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +3 -2
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/errors.d.ts.map +1 -1
- package/dist/numerical/errors.js +0 -3
- package/dist/numerical/errors.js.map +1 -1
- package/dist/numerical/finite-difference.d.ts +22 -0
- package/dist/numerical/finite-difference.d.ts.map +1 -0
- package/dist/numerical/finite-difference.js +27 -0
- package/dist/numerical/finite-difference.js.map +1 -0
- package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
- package/dist/numerical/geodesic-integrator.js +22 -14
- package/dist/numerical/geodesic-integrator.js.map +1 -1
- package/dist/numerical/geometrized.d.ts.map +1 -1
- package/dist/numerical/geometrized.js +0 -1
- package/dist/numerical/geometrized.js.map +1 -1
- package/dist/numerical/mathts-engine.d.ts.map +1 -1
- package/dist/numerical/mathts-engine.js +10 -24
- package/dist/numerical/mathts-engine.js.map +1 -1
- package/dist/numerical/metric-inverse.d.ts.map +1 -1
- package/dist/numerical/metric-inverse.js +83 -46
- package/dist/numerical/metric-inverse.js.map +1 -1
- package/dist/numerical/null-ray-integrator.d.ts +2 -1
- package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
- package/dist/numerical/null-ray-integrator.js +12 -12
- package/dist/numerical/null-ray-integrator.js.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.js +2 -2
- package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
- package/dist/numerical/perihelion-finder.d.ts +0 -36
- package/dist/numerical/perihelion-finder.d.ts.map +1 -1
- package/dist/numerical/perihelion-finder.js +41 -87
- package/dist/numerical/perihelion-finder.js.map +1 -1
- package/dist/numerical/quadrature.d.ts.map +1 -1
- package/dist/numerical/quadrature.js +8 -10
- package/dist/numerical/quadrature.js.map +1 -1
- package/dist/numerical/rk4-trajectory.d.ts +10 -0
- package/dist/numerical/rk4-trajectory.d.ts.map +1 -0
- package/dist/numerical/rk4-trajectory.js +37 -0
- package/dist/numerical/rk4-trajectory.js.map +1 -0
- package/dist/numerical/schwarzschild.d.ts +14 -0
- package/dist/numerical/schwarzschild.d.ts.map +1 -0
- package/dist/numerical/schwarzschild.js +17 -0
- package/dist/numerical/schwarzschild.js.map +1 -0
- package/dist/numerical/spacetime-metrics.d.ts +12 -0
- package/dist/numerical/spacetime-metrics.d.ts.map +1 -1
- package/dist/numerical/spacetime-metrics.js +72 -56
- package/dist/numerical/spacetime-metrics.js.map +1 -1
- package/dist/numerical/statistics.d.ts +24 -0
- package/dist/numerical/statistics.d.ts.map +1 -0
- package/dist/numerical/statistics.js +52 -0
- package/dist/numerical/statistics.js.map +1 -0
- package/dist/numerical/tensor-engine.d.ts +21 -0
- package/dist/numerical/tensor-engine.d.ts.map +1 -1
- package/dist/numerical/tensor-engine.js +12 -0
- package/dist/numerical/tensor-engine.js.map +1 -1
- package/dist/relations/regime.d.ts +10 -0
- package/dist/relations/regime.d.ts.map +1 -1
- package/dist/relations/regime.js +18 -1
- package/dist/relations/regime.js.map +1 -1
- package/package.json +7 -7
|
@@ -38,8 +38,10 @@ import { GATE_AXES } from './axes.js';
|
|
|
38
38
|
import { classifyIdentifiability, forwardClosure } from './identifiability.js';
|
|
39
39
|
import { retrodict, retrodictNode, forwardEvaluate } from './retrodiction.js';
|
|
40
40
|
import { proposeLinkCandidates } from './bridge-analysis.js';
|
|
41
|
+
import { clusterBySharedKeys } from './quantity-clusters.js';
|
|
42
|
+
import { normalCDF } from '@danielsimonjr/mathts-functions';
|
|
41
43
|
import { M_SUN_KG } from '../core/constants.js';
|
|
42
|
-
import { REPRESENTATIVE_VALUES } from './representative-values.js';
|
|
44
|
+
import { DEFAULT_SIGMA_DECADES, REPRESENTATIVE_VALUES, sigmaDecadesOf } from './representative-values.js';
|
|
43
45
|
import { conventionScaleToSI } from '../dimensional/unit-convention.js';
|
|
44
46
|
import { allQuantities } from './quantities.js';
|
|
45
47
|
import { CANONICAL_EQUATIONS } from '../canonical/registry.js';
|
|
@@ -80,37 +82,47 @@ const CANONICAL_QUANTITY_NAMES = (() => {
|
|
|
80
82
|
}
|
|
81
83
|
return s;
|
|
82
84
|
})();
|
|
83
|
-
/**
|
|
84
|
-
*
|
|
85
|
+
/**
|
|
86
|
+
* The component partition of quantity names: names in one equation are one component, and so
|
|
87
|
+
* are the two sides of every identification. The shared partition of `quantity-clusters.ts`
|
|
88
|
+
* (a name is an item; its keys are the equations and identifications it appears in). Returns
|
|
89
|
+
* name → a representative of its component (its first name), read only for equality.
|
|
90
|
+
*
|
|
91
|
+
* RECORDED BEHAVIOUR, kept on purpose: an equation with no source (an all-constant right-hand
|
|
92
|
+
* side, `CE-bohr-radius`) registers no name at all, so its target is absent from the map and
|
|
93
|
+
* an identification touching it never counts as merging components. The union-find this
|
|
94
|
+
* replaced only registered a name when it took part in a union, and the census, the canonical
|
|
95
|
+
* funnel counts and the `map --proposed` golden pin that reading. Registering such a target
|
|
96
|
+
* makes `bohr-radius ≟ hubble-distance` promising; whether it should is a catalog decision,
|
|
97
|
+
* not this module's (`tests/composition/quantity-clusters.test.ts` pins the recorded reading
|
|
98
|
+
* by name).
|
|
99
|
+
*/
|
|
85
100
|
function quantityComponents(edges, idents) {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
let cur = x;
|
|
94
|
-
while (parent.get(cur) !== r) {
|
|
95
|
-
const next = parent.get(cur);
|
|
96
|
-
parent.set(cur, r);
|
|
97
|
-
cur = next;
|
|
98
|
-
}
|
|
99
|
-
return r;
|
|
100
|
-
};
|
|
101
|
-
const union = (a, b) => {
|
|
102
|
-
parent.set(find(a), find(b));
|
|
101
|
+
const keysByName = new Map();
|
|
102
|
+
const tag = (name, key) => {
|
|
103
|
+
const keys = keysByName.get(name);
|
|
104
|
+
if (keys === undefined)
|
|
105
|
+
keysByName.set(name, [key]);
|
|
106
|
+
else
|
|
107
|
+
keys.push(key);
|
|
103
108
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
edges.forEach((e, i) => {
|
|
110
|
+
if (e.sources.length === 0)
|
|
111
|
+
return; // recorded behaviour: a source-less target is not registered
|
|
112
|
+
for (const s of e.sources)
|
|
113
|
+
tag(s.name, `edge:${i}`);
|
|
114
|
+
tag(e.target.name, `edge:${i}`);
|
|
115
|
+
});
|
|
116
|
+
idents.forEach((id, i) => {
|
|
117
|
+
tag(id.from, `ident:${i}`);
|
|
118
|
+
tag(id.to, `ident:${i}`);
|
|
119
|
+
});
|
|
120
|
+
const names = [...keysByName.keys()];
|
|
111
121
|
const roots = new Map();
|
|
112
|
-
for (const
|
|
113
|
-
|
|
122
|
+
for (const cluster of clusterBySharedKeys(names, (name) => keysByName.get(name) ?? [], (name) => name)) {
|
|
123
|
+
for (const name of cluster)
|
|
124
|
+
roots.set(name, cluster[0]);
|
|
125
|
+
}
|
|
114
126
|
return roots;
|
|
115
127
|
}
|
|
116
128
|
/**
|
|
@@ -231,54 +243,95 @@ function newInconsistencies(edges, groundTruth, anchor, candidate, withHyp, base
|
|
|
231
243
|
}
|
|
232
244
|
return nodes;
|
|
233
245
|
}
|
|
246
|
+
/** MathTS `normalCDF`, read back as the number it is. */
|
|
247
|
+
function phi(z) {
|
|
248
|
+
const v = normalCDF(z);
|
|
249
|
+
if (typeof v !== 'number')
|
|
250
|
+
throw new TypeError('normalCDF did not return a number for a number argument');
|
|
251
|
+
return v;
|
|
252
|
+
}
|
|
234
253
|
/**
|
|
235
|
-
*
|
|
236
|
-
*
|
|
254
|
+
* The two-sided tail of a gap of `orders` decades between two values whose log10 carry
|
|
255
|
+
* standard deviations `sigmaA` and `sigmaB` decades: `2·Φ(−orders/√(σ_a² + σ_b²))`, through the
|
|
256
|
+
* NEGATIVE argument (`1 − Φ` rounds a far tail to 0; the lower tail is accurate). A strength of
|
|
257
|
+
* the falsifier, not a credibility score.
|
|
237
258
|
*
|
|
238
259
|
* @internal
|
|
239
260
|
*/
|
|
240
|
-
export function
|
|
241
|
-
return
|
|
261
|
+
export function magnitudeStrength(orders, sigmaA, sigmaB) {
|
|
262
|
+
return 2 * phi(-orders / Math.sqrt(sigmaA * sigmaA + sigmaB * sigmaB));
|
|
242
263
|
}
|
|
243
264
|
/**
|
|
244
|
-
* The
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
265
|
+
* The magnitude gate: an INDEPENDENT falsifier the single-anchor graph cannot make. It runs only
|
|
266
|
+
* when both endpoints have a representative value and abstains (never false-rejects) otherwise.
|
|
267
|
+
* A value comes from the sourced static table first, else — for graph-derived quantities the
|
|
268
|
+
* table omits by design (schwarzschild-radius, thermal-de-broglie-wavelength) — from the
|
|
269
|
+
* quantity's value AT THE REGISTERED ANCHOR, a definite magnitude for this run, with the default
|
|
270
|
+
* σ of one decade. The verdict is `ordersApart > ctx.maxOrders`; `p` is reported beside it.
|
|
248
271
|
*
|
|
249
272
|
* @internal
|
|
250
273
|
*/
|
|
251
|
-
export function
|
|
252
|
-
const { baseIdents, groundTruth, anchor, repVals, maxOrders, anchorValues, anchorValuesProbe, comps, closureBase, attributesByName, baseInconsistentNodes, } = ctx;
|
|
253
|
-
// Magnitude gate: an INDEPENDENT falsifier the single-anchor graph can't make.
|
|
254
|
-
// Only fires when both endpoints have a representative value; abstains (and
|
|
255
|
-
// never false-rejects) otherwise. A value comes from the sourced static table
|
|
256
|
-
// first, else — for graph-derived quantities the table omits by design
|
|
257
|
-
// (schwarzschild-radius, thermal-de-broglie-wavelength) — from the quantity's
|
|
258
|
-
// value AT THE REGISTERED ANCHOR, which is a definite magnitude for this run.
|
|
274
|
+
export function magnitudeGate(candidate, ctx) {
|
|
259
275
|
const magnitudeOf = (name) => {
|
|
260
|
-
const rv = repVals[name];
|
|
276
|
+
const rv = ctx.repVals[name];
|
|
261
277
|
// Both paths apply the same finite-and-nonzero gate: a 0/∞/NaN magnitude
|
|
262
278
|
// would make log10 blow up (log10(0) = -∞), spoofing or silently disabling
|
|
263
279
|
// the falsifier. Symmetric validation across the table and anchor sources.
|
|
264
|
-
if (rv !== undefined && Number.isFinite(rv.value) && rv.value !== 0)
|
|
265
|
-
return { value: rv.value, fromAnchor: false };
|
|
266
|
-
|
|
280
|
+
if (rv !== undefined && Number.isFinite(rv.value) && rv.value !== 0) {
|
|
281
|
+
return { value: rv.value, fromAnchor: false, sigmaDecades: sigmaDecadesOf(rv) };
|
|
282
|
+
}
|
|
283
|
+
const av = ctx.anchorValues.get(name);
|
|
267
284
|
if (av !== undefined) {
|
|
268
285
|
const value = av * conventionScaleToSI(name);
|
|
269
|
-
if (Number.isFinite(value) && value !== 0)
|
|
270
|
-
return { value, fromAnchor: true };
|
|
286
|
+
if (Number.isFinite(value) && value !== 0) {
|
|
287
|
+
return { value, fromAnchor: true, sigmaDecades: DEFAULT_SIGMA_DECADES };
|
|
288
|
+
}
|
|
271
289
|
}
|
|
272
290
|
return undefined;
|
|
273
291
|
};
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
292
|
+
const a = magnitudeOf(candidate.a);
|
|
293
|
+
const b = magnitudeOf(candidate.b);
|
|
294
|
+
const checked = a !== undefined && b !== undefined;
|
|
295
|
+
const ordersApart = checked ? Math.abs(Math.log10(Math.abs(a.value)) - Math.log10(Math.abs(b.value))) : null;
|
|
296
|
+
return {
|
|
297
|
+
a,
|
|
298
|
+
b,
|
|
299
|
+
checked,
|
|
300
|
+
usedAnchor: checked && (a.fromAnchor || b.fromAnchor),
|
|
301
|
+
ordersApart,
|
|
302
|
+
clash: ordersApart !== null && ordersApart > ctx.maxOrders,
|
|
303
|
+
p: checked && ordersApart !== null ? magnitudeStrength(ordersApart, a.sigmaDecades, b.sigmaDecades) : null,
|
|
304
|
+
missing: [a === undefined ? candidate.a : null, b === undefined ? candidate.b : null].filter((e) => e !== null),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Vet one link candidate by hypothesizing the identification a≡b and
|
|
309
|
+
* measuring its structural and numerical consequences. See module docs.
|
|
310
|
+
*
|
|
311
|
+
* @internal
|
|
312
|
+
*/
|
|
313
|
+
export function vetLinkCandidate(edges, candidate, opts = {}) {
|
|
314
|
+
return vetInContext(edges, candidate, buildDiscoveryContext(edges, opts));
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* The per-candidate vetting body, given pre-computed candidate-invariant
|
|
318
|
+
* `ctx`. The hypothesis-augmented closure is per-candidate. Retrodiction is
|
|
319
|
+
* per-candidate only when an endpoint is already in the anchor closure;
|
|
320
|
+
* otherwise the identification cannot fire and the base report stands.
|
|
321
|
+
*
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
324
|
+
export function vetInContext(edges, candidate, ctx) {
|
|
325
|
+
const { baseIdents, groundTruth, anchor, anchorValuesProbe, comps, closureBase, attributesByName, baseInconsistentNodes, } = ctx;
|
|
326
|
+
// Magnitude gate: an INDEPENDENT falsifier the single-anchor graph can't make
|
|
327
|
+
// (`magnitudeGate`): the verdict is the hard threshold, `p` its calibrated strength.
|
|
328
|
+
const gate = magnitudeGate(candidate, ctx);
|
|
329
|
+
const va = gate.a;
|
|
330
|
+
const vb = gate.b;
|
|
331
|
+
const magnitudeChecked = gate.checked;
|
|
332
|
+
const magnitudeUsedAnchor = gate.usedAnchor;
|
|
333
|
+
const ordersApart = gate.ordersApart;
|
|
334
|
+
const magnitudeClash = gate.clash;
|
|
282
335
|
// Anchor-invariance probe: re-read each anchor-derived magnitude at the
|
|
283
336
|
// rescaled anchor. A table value is a constant and does not move.
|
|
284
337
|
const probeOf = (name, m) => {
|
|
@@ -413,10 +466,11 @@ export function vetInContext(edges, candidate, ctx) {
|
|
|
413
466
|
numericallyConsistent,
|
|
414
467
|
inconsistentNodes,
|
|
415
468
|
ordersApart,
|
|
469
|
+
magnitudeP: gate.p,
|
|
416
470
|
magnitudeChecked,
|
|
417
471
|
magnitudeUsedAnchor,
|
|
418
472
|
magnitudeAnchorInvariant,
|
|
419
|
-
magnitudeMissing:
|
|
473
|
+
magnitudeMissing: gate.missing,
|
|
420
474
|
axisUnstated,
|
|
421
475
|
subsuming,
|
|
422
476
|
verdict,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/composition/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Discovery loop — vet link candidates through the verification primitives\n * (Direction 2).\n *\n * `proposeLinkCandidates` surfaces cross-cluster quantity pairs that share a\n * dimension and hands the raw coincidences to a human (the counts at a given\n * catalog are measured by the tests and recorded in NOTES.md). This\n * module closes the loop: it HYPOTHESIZES each candidate identification\n * `a ≡ b` and tests it with the machinery that already exists —\n *\n * - mergesComponents — does identifying a≡b connect two previously\n * disconnected parts of the graph? (structural\n * significance)\n * - unlocksFromAnchor — what becomes determinable from an anchor input\n * set WITH the identification that was not before?\n * (`forwardClosure`)\n * - numericallyConsistent — does retrodiction over the graph stay\n * all-consistent once the identification is\n * added, or does it introduce a contradiction?\n * (`retrodict` — the STRONG filter)\n *\n * so the physicist adjudicates a handful of VETTED, provenance-traced\n * candidates instead of dimensional noise.\n *\n * ⚠ Still a REVIEW SURFACE, never automated discovery (Part-VI §XXVII-B). A\n * shared dimension is a weak prior; the weight is on the numeric and\n * structural signals, and the numeric check only exercises the part of the\n * graph reachable from the anchor. `promising` means \"worth a physicist's\n * minute\", not \"true\".\n *\n * INTERNAL — not on the public surface (mirrors bridge-analysis.ts);\n * surfaced via `upt discover`.\n *\n * @module composition/discovery\n */\n\nimport type { BridgeEdge } from './edge.js';\nimport type { QuantityIdentification } from './compose.js';\nimport { QUANTITY_IDENTIFICATIONS, effectiveAttributes } from './compose.js';\nimport { GATE_AXES } from './axes.js';\nimport type { RegimeAttributes } from './quantity.js';\nimport { classifyIdentifiability, forwardClosure } from './identifiability.js';\nimport { retrodict, retrodictNode, forwardEvaluate } from './retrodiction.js';\nimport { proposeLinkCandidates } from './bridge-analysis.js';\nimport type { LinkCandidate } from './bridge-analysis.js';\nimport { M_SUN_KG } from '../core/constants.js';\nimport { REPRESENTATIVE_VALUES } from './representative-values.js';\nimport type { RepresentativeValue } from './representative-values.js';\nimport { conventionScaleToSI } from '../dimensional/unit-convention.js';\nimport { allQuantities } from './quantities.js';\nimport { CANONICAL_EQUATIONS } from '../canonical/registry.js';\nimport { format } from '../dimensional/algebra.js';\n\n// ── registry-only attribute lookup (D1 axis gate; Option-A resolution) ─────\n// Built from the centralized `Quantity` nodes ONLY (never canonical\n// per-equation stamps — audit adjudication F1). Names that aren't a\n// registry node (most bare canonical-equation variables) are simply absent,\n// so they always abstain — the canonical-only axis-clash=0 invariant holds\n// by construction, not by a special case.\n/** The canonical quantity→attributes map (registry nodes + per-equation stamps).\n * Exported for the axis-discrimination audit. @internal */\nexport const REGISTRY_ATTRIBUTES_BY_NAME: ReadonlyMap<string, RegimeAttributes> = new Map(\n allQuantities().map((quantity) => [quantity.name, quantity.attributes]),\n);\n\n// The axes the D1 regime-label gate compares are `GATE_AXES`, imported from the\n// `axes.ts` registry (`AXES.filter(gated)`) at the top of this module. Currently\n// scale + force; the 2026-07-05 extensible-axis expansion added\n// symmetry/topology/statistics as UNGATED attributes (they only abstain until the\n// discrimination audit earns them a gate — flip `gated: true` in axes.ts).\n\n// ── canonical-kind indexes (Sub-project C) ──────────────────────────────────\n// Discovery quantity names and canonical variable names are different\n// namespaces; the alignable axis is the DIMENSION. These are informational\n// annotations on each candidate (no verdict/score effect): they give the\n// physicist standard-physics context, not a hard filter (the registry is small).\nconst CANONICAL_KINDS_BY_DIM: ReadonlyMap<string, readonly string[]> = (() => {\n const m = new Map<string, Set<string>>();\n for (const ce of CANONICAL_EQUATIONS) {\n const key = format(ce.dimensional.target.dim);\n (m.get(key) ?? m.set(key, new Set()).get(key)!).add(ce.domain);\n }\n return new Map([...m].map(([k, v]) => [k, [...v].sort()]));\n})();\n\nconst CANONICAL_QUANTITY_NAMES: ReadonlySet<string> = (() => {\n const s = new Set<string>();\n for (const ce of CANONICAL_EQUATIONS) {\n s.add(ce.dimensional.target.name);\n for (const g of ce.dimensional.governing) s.add(g.name);\n }\n return s;\n})();\n\n/** A candidate after vetting against the inference suite. @hypothesis @public */\nexport interface VettedCandidate {\n readonly a: string;\n readonly b: string;\n /** Shared SI dimension (from the proposer). */\n readonly dim: string;\n /** One endpoint is in the anchored (established) cluster. */\n readonly touchesCore: boolean;\n /** The names share a word token (same physical KIND). */\n readonly sameKind: boolean;\n /**\n * Identifying a≡b merges two distinct connected components of the\n * quantity graph — it connects physics the catalog keeps separate.\n */\n readonly mergesComponents: boolean;\n /**\n * Quantities newly determinable from the anchor known-set once the\n * identification is added (structural unlock). Sorted.\n */\n readonly unlocksFromAnchor: readonly string[];\n /**\n * Retrodiction over the graph WITH the hypothesized identification creates\n * no numerical contradiction in the anchor-reachable subgraph. The strong\n * filter. A node whose routes already disagree in the base graph is the\n * graph's finding (`retrodict` reports it) and does not make a candidate\n * inconsistent; only a disagreement the hypothesis CREATES does.\n */\n readonly numericallyConsistent: boolean;\n /** Nodes that became inconsistent under the identification and were not\n * inconsistent in the base graph (the falsification, when\n * `numericallyConsistent` is false). Sorted. */\n readonly inconsistentNodes: readonly string[];\n /**\n * Orders of magnitude between the representative values of a and b\n * (`|log10|va| − log10|vb||`), or `null` when either has no representative\n * value (the gate abstained — see `magnitudeChecked`).\n */\n readonly ordersApart: number | null;\n /** Both endpoints had a representative value, so the magnitude gate ran. */\n readonly magnitudeChecked: boolean;\n /** The magnitude gate read at least one endpoint value from the graph at\n * the anchor (no static table entry) rather than the sourced table. */\n readonly magnitudeUsedAnchor: boolean;\n /**\n * The magnitude comparison used an anchor-derived value, and the ratio of the\n * two magnitudes does NOT move when every anchor input is rescaled by\n * {@link ANCHOR_PROBE_FACTOR}. The graph then fixes the ratio at every\n * anchor, so agreement in magnitude is an identity of the graph and not\n * evidence for the identification. The case that exposed it: the anchor sets\n * the temperature to the Hawking temperature of the anchor mass M, and then\n * the thermal wavelength is exactly 4π ℓ_P for EVERY M. Its anchor-derived\n * magnitude is not a representative magnitude of the quantity at all.\n * A quantity whose value really is a constant belongs in the\n * representative-value table, where it is not anchor-derived.\n * A clash stays a clash (the graph itself fixes the two apart); only a pass is\n * withheld, in `describeGrounding`. Optional on the type so hand-built\n * candidates need not state it; the funnel always sets it.\n */\n readonly magnitudeAnchorInvariant?: boolean;\n /**\n * The endpoints with no representative magnitude (neither in the sourced\n * table nor valued at the anchor) — why the magnitude gate abstained. Empty\n * when it ran. Optional on the type; the funnel always sets it.\n */\n readonly magnitudeMissing?: readonly string[];\n /**\n * Per gate axis that abstained, the endpoints that state no value on it —\n * why the axis gate had nothing to compare. Optional; the funnel always sets it.\n */\n readonly axisUnstated?: readonly { readonly axis: string; readonly endpoints: readonly string[] }[];\n /**\n * One endpoint name's hyphen-token set is a strict subset of the other's\n * (`mass` ⊂ `reference-mass`) — a generic↔specific identification of the\n * same KIND. Near-tautological (identifying a generic quantity with one of\n * its own specializations), so it is barred from `promising`.\n */\n readonly subsuming: boolean;\n /**\n * - `magnitude-clash` — representative values differ by more than the\n * threshold N orders (an independent falsification the\n * single-anchor graph cannot make). Checked first.\n * - `contradictory` — breaks numerical consistency (a graph falsification).\n * - `axis-clash` — the identification's stated `scale`/`force` regime\n * attributes disagree. A regime-LABEL prior against a\n * literal identity (D1), not a physical test: it\n * compares catalog labels and runs no computation, so\n * it is never counted or described as a falsification.\n * - `promising` — consistent AND connects disconnected physics AND\n * unlocks ≥1 quantity. Worth physicist review.\n * - `inert` — consistent but structurally/numerically idle (a\n * dimensional coincidence with no consequence).\n */\n readonly verdict: 'promising' | 'inert' | 'contradictory' | 'magnitude-clash' | 'axis-clash';\n /** Composite ranking score (higher = more worth review). */\n readonly score: number;\n /**\n * At least one of the `scale`/`force` axes had a resolved (non-conflicting)\n * value on BOTH endpoints, so the axis-compatibility gate produced a real\n * comparison (whether or not it clashed). `false` means every gate axis\n * abstained (silent on one/both sides, or a fold conflict) — the gate had\n * nothing to check. Populated on EVERY candidate, independent of verdict.\n */\n readonly axisChecked: boolean;\n /**\n * Per-axis clash descriptions (`'scale: quantum ≠ cosmological'`), sorted.\n * Empty when no gate axis clashed — including when `axisChecked` is\n * `false`, and even when a stronger falsifier (magnitude/contradictory)\n * won the verdict (no falsifier shadows another's annotation).\n */\n readonly axisClashes: readonly string[];\n /**\n * Standard-physics domains whose canonical equation has a TARGET of this\n * candidate's dimension (Sub-project C). Informational context — an empty\n * list means no canonical equation targets this dimension.\n */\n readonly canonicalKinds: readonly string[];\n /** At least one endpoint name is a quantity a canonical equation uses\n * (weak name-based prior; informational). */\n readonly touchesCanonical: boolean;\n}\n\n/** Options for the discovery loop. @internal */\nexport interface DiscoveryOptions {\n /**\n * Numeric anchor for the consistency check (and the closure unlock).\n * Default `{ mass: M_sun }` — the pre-registered retrodiction anchor.\n */\n readonly groundTruth?: Readonly<Record<string, number>>;\n /** Extra identifications honored as the baseline (default registered). */\n readonly identifications?: readonly QuantityIdentification[];\n /**\n * Max orders of magnitude two identified quantities may differ before the\n * identification is falsified as a `magnitude-clash`. Default {@link DEFAULT_MAX_ORDERS_OF_MAGNITUDE} — generous\n * enough for O(1) dimensionless prefactors and unit-convention slack, strict\n * enough to kill the scale-clash decoys.\n */\n readonly maxOrdersOfMagnitude?: number;\n /**\n * Sourced order-of-magnitude values for the gate (default\n * `REPRESENTATIVE_VALUES`). Injectable for testing and so the future\n * canonical-equation registry can supply them centrally.\n */\n readonly representativeValues?: Readonly<Record<string, RepresentativeValue>>;\n /**\n * Registry-only `scale`/`force`/`information` attributes by quantity name,\n * for the D1 axis-compatibility gate (default: every centralized\n * `Quantity.attributes`). Injectable for testing — never canonical\n * per-equation stamps (Option-A resolution).\n */\n readonly quantityAttributes?: ReadonlyMap<string, RegimeAttributes>;\n}\n\n/** Union-find over quantity names; merges each edge's endpoints and every\n * identification's from↔to. Returns name → component-root. */\nfunction quantityComponents(\n edges: readonly BridgeEdge[],\n idents: readonly QuantityIdentification[],\n): Map<string, string> {\n const parent = new Map<string, string>();\n const find = (x: string): string => {\n if (!parent.has(x)) parent.set(x, x);\n let r = x;\n while (parent.get(r) !== r) r = parent.get(r)!;\n let cur = x;\n while (parent.get(cur) !== r) {\n const next = parent.get(cur)!;\n parent.set(cur, r);\n cur = next;\n }\n return r;\n };\n const union = (a: string, b: string) => {\n parent.set(find(a), find(b));\n };\n for (const e of edges) {\n const names = [...e.sources.map((s) => s.name), e.target.name];\n for (let i = 1; i < names.length; i++) union(names[0], names[i]);\n }\n for (const id of idents) union(id.from, id.to);\n const roots = new Map<string, string>();\n for (const name of parent.keys()) roots.set(name, find(name));\n return roots;\n}\n\n/**\n * The ground truth the funnel anchors magnitudes to when the caller gives none: one solar mass.\n * Exported so the CLI can print the anchor a result is relative to (audit I3).\n * @internal\n */\nexport const ANCHOR_DEFAULT: Readonly<Record<string, number>> = { mass: M_SUN_KG };\n\n/**\n * The magnitude-clash threshold when the caller gives none: how many orders of magnitude two\n * identified quantities may differ. Exported so the CLI states the default it runs with.\n * @internal\n */\nexport const DEFAULT_MAX_ORDERS_OF_MAGNITUDE = 3;\n\n/**\n * Factor every anchor input is multiplied by to probe whether a magnitude ratio\n * depends on the anchor at all (persona finding L3). Three decades moves any\n * log-ratio that depends on the anchor far beyond {@link ANCHOR_INVARIANCE_TOL}.\n * @internal\n */\nconst ANCHOR_PROBE_FACTOR = 1e3;\n\n/** Decades within which a log-ratio counts as unchanged by the probe. @internal */\nconst ANCHOR_INVARIANCE_TOL = 1e-9;\n\n/**\n * One name's hyphen-token set is a STRICT subset of the other's\n * (`mass` ⊂ `reference-mass`, `mass` ⊂ `planck-mass`) — i.e. identifying a\n * generic quantity with one of its own specializations of the same kind.\n * Such an identification is near-tautological (it asserts the specialization\n * IS its genus), not a discovered cross-cluster link, so it is barred from\n * `promising`. Returns false for equal token sets and for pairs sharing only\n * a partial token (`schwarzschild-radius` ⊄ `foerster-radius`).\n */\nfunction nameSubsumes(a: string, b: string): boolean {\n const ta = new Set(a.split('-'));\n const tb = new Set(b.split('-'));\n if (ta.size === tb.size) return false;\n const [small, big] = ta.size < tb.size ? [ta, tb] : [tb, ta];\n for (const t of small) if (!big.has(t)) return false;\n return true;\n}\n\n/**\n * Candidate-invariant state for the discovery funnel — everything in\n * `vetLinkCandidate` that depends only on `(edges, opts)`, not on the specific\n * candidate. Computed once by `buildDiscoveryContext` and shared across every\n * candidate so `rankDiscoveries` does loop-invariant work once instead of N\n * times. Holds read-only structures — `vetInContext` never mutates them, so\n * sharing is safe. `tests/composition/discovery.test.ts` pins that directly:\n * two builds are equal, and vetting every candidate leaves the context equal\n * to a snapshot taken before.\n *\n * @internal\n */\nexport interface DiscoveryContext {\n readonly baseIdents: readonly QuantityIdentification[];\n readonly groundTruth: Readonly<Record<string, number>>;\n /** `Object.keys(groundTruth)` — the anchor known-set names. */\n readonly anchor: readonly string[];\n readonly repVals: Readonly<Record<string, RepresentativeValue>>;\n readonly maxOrders: number;\n /** Registry-only attribute lookup for the D1 axis gate (opts override or\n * `REGISTRY_ATTRIBUTES_BY_NAME`). */\n readonly attributesByName: ReadonlyMap<string, RegimeAttributes>;\n /** `forwardEvaluate(edges, groundTruth, baseIdents)` — anchor magnitudes. */\n readonly anchorValues: ReadonlyMap<string, number>;\n /** The same evaluation with every anchor input times {@link ANCHOR_PROBE_FACTOR}. */\n readonly anchorValuesProbe: ReadonlyMap<string, number>;\n /** `quantityComponents(edges, baseIdents)` — base component roots. */\n readonly comps: ReadonlyMap<string, string>;\n /** `forwardClosure(edges, anchor, baseIdents)` — base determinable set. */\n readonly closureBase: ReadonlySet<string>;\n /**\n * The targets the retrodiction of the anchor finds inconsistent with no\n * hypothesized identification (empty when the base is consistent). An\n * identification of two quantities outside {@link closureBase} cannot fire,\n * so that candidate's numeric report is this one.\n */\n readonly baseInconsistentNodes: readonly string[];\n}\n\n/** Resolve options and compute the candidate-invariant discovery state once.\n * @internal */\nexport function buildDiscoveryContext(\n edges: readonly BridgeEdge[],\n opts: DiscoveryOptions,\n): DiscoveryContext {\n const baseIdents = opts.identifications ?? QUANTITY_IDENTIFICATIONS;\n const groundTruth = opts.groundTruth ?? ANCHOR_DEFAULT;\n const anchor = Object.keys(groundTruth);\n const baseReport = retrodict(edges, groundTruth, { identifications: baseIdents });\n return {\n baseIdents,\n groundTruth,\n anchor,\n repVals: opts.representativeValues ?? REPRESENTATIVE_VALUES,\n maxOrders: opts.maxOrdersOfMagnitude ?? DEFAULT_MAX_ORDERS_OF_MAGNITUDE,\n attributesByName: opts.quantityAttributes ?? REGISTRY_ATTRIBUTES_BY_NAME,\n // Candidate-invariant: the anchor's forward evaluation, the base component\n // partition, and the base forward closure all depend only on (edges, opts).\n anchorValues: forwardEvaluate(edges, groundTruth, baseIdents),\n anchorValuesProbe: forwardEvaluate(\n edges,\n Object.fromEntries(\n Object.entries(groundTruth).map(([k, v]) => [k, v * ANCHOR_PROBE_FACTOR]),\n ),\n baseIdents,\n ),\n comps: quantityComponents(edges, baseIdents),\n closureBase: forwardClosure(edges, anchor, baseIdents),\n baseInconsistentNodes: baseReport.results\n .filter((r) => r.outcome === 'inconsistent')\n .map((r) => r.target)\n .sort(),\n };\n}\n\n/**\n * The quantities whose value can depend on one of `seeds`: the seeds, every\n * `to` of an identification from the set, and every target of an edge with a\n * source in the set, to a fixed point. An over-approximation (an edge that\n * does not fire still lists its target), which is the safe side: a target\n * left out would keep its base retrodiction unexamined.\n */\nfunction dependents(\n edges: readonly BridgeEdge[],\n seeds: readonly string[],\n idents: readonly QuantityIdentification[],\n): Set<string> {\n const set = new Set<string>(seeds);\n let changed = true;\n while (changed) {\n changed = false;\n for (const id of idents) {\n if (set.has(id.from) && !set.has(id.to)) {\n set.add(id.to);\n changed = true;\n }\n }\n for (const e of edges) {\n if (set.has(e.target.name)) continue;\n if (e.sources.some((s) => set.has(s.name))) {\n set.add(e.target.name);\n changed = true;\n }\n }\n }\n return set;\n}\n\n/**\n * The nodes the hypothesis `a ≡ b` makes inconsistent that the base graph did\n * not already have: inconsistent(hypothesis) minus inconsistent(base). Only a\n * node downstream of `a` or `b` can change, so only those nodes are\n * classified and retrodicted, with the same over-determined rule and the\n * same tolerance `retrodict` applies to the whole graph. Sorted.\n */\nfunction newInconsistencies(\n edges: readonly BridgeEdge[],\n groundTruth: Readonly<Record<string, number>>,\n anchor: readonly string[],\n candidate: LinkCandidate,\n withHyp: readonly QuantityIdentification[],\n baseInconsistentNodes: readonly string[],\n): string[] {\n const base = new Set(baseInconsistentNodes);\n const nodes: string[] = [];\n for (const target of [...dependents(edges, [candidate.a, candidate.b], withHyp)].sort()) {\n if (base.has(target)) continue;\n const classified = classifyIdentifiability(edges, anchor, target, { identifications: withHyp });\n if (classified.verdict !== 'over-determined') continue;\n const result = retrodictNode(edges, groundTruth, target, { identifications: withHyp });\n if (result.outcome === 'inconsistent') nodes.push(target);\n }\n return nodes;\n}\n\n/**\n * Vet one link candidate by hypothesizing the identification a≡b and\n * measuring its structural and numerical consequences. See module docs.\n *\n * @internal\n */\nexport function vetLinkCandidate(\n edges: readonly BridgeEdge[],\n candidate: LinkCandidate,\n opts: DiscoveryOptions = {},\n): VettedCandidate {\n return vetInContext(edges, candidate, buildDiscoveryContext(edges, opts));\n}\n\n/**\n * The per-candidate vetting body, given pre-computed candidate-invariant\n * `ctx`. The hypothesis-augmented closure is per-candidate. Retrodiction is\n * per-candidate only when an endpoint is already in the anchor closure;\n * otherwise the identification cannot fire and the base report stands.\n *\n * @internal\n */\nexport function vetInContext(\n edges: readonly BridgeEdge[],\n candidate: LinkCandidate,\n ctx: DiscoveryContext,\n): VettedCandidate {\n const {\n baseIdents,\n groundTruth,\n anchor,\n repVals,\n maxOrders,\n anchorValues,\n anchorValuesProbe,\n comps,\n closureBase,\n attributesByName,\n baseInconsistentNodes,\n } = ctx;\n\n // Magnitude gate: an INDEPENDENT falsifier the single-anchor graph can't make.\n // Only fires when both endpoints have a representative value; abstains (and\n // never false-rejects) otherwise. A value comes from the sourced static table\n // first, else — for graph-derived quantities the table omits by design\n // (schwarzschild-radius, thermal-de-broglie-wavelength) — from the quantity's\n // value AT THE REGISTERED ANCHOR, which is a definite magnitude for this run.\n const magnitudeOf = (\n name: string,\n ): { value: number; fromAnchor: boolean } | undefined => {\n const rv = repVals[name];\n // Both paths apply the same finite-and-nonzero gate: a 0/∞/NaN magnitude\n // would make log10 blow up (log10(0) = -∞), spoofing or silently disabling\n // the falsifier. Symmetric validation across the table and anchor sources.\n if (rv !== undefined && Number.isFinite(rv.value) && rv.value !== 0)\n return { value: rv.value, fromAnchor: false };\n const av = anchorValues.get(name);\n if (av !== undefined) {\n const value = av * conventionScaleToSI(name);\n if (Number.isFinite(value) && value !== 0)\n return { value, fromAnchor: true };\n }\n return undefined;\n };\n const va = magnitudeOf(candidate.a);\n const vb = magnitudeOf(candidate.b);\n const magnitudeChecked = va !== undefined && vb !== undefined;\n const magnitudeUsedAnchor =\n magnitudeChecked && (va!.fromAnchor || vb!.fromAnchor);\n const ordersApart = magnitudeChecked\n ? Math.abs(Math.log10(Math.abs(va!.value)) - Math.log10(Math.abs(vb!.value)))\n : null;\n const magnitudeClash = ordersApart !== null && ordersApart > maxOrders;\n\n // Anchor-invariance probe: re-read each anchor-derived magnitude at the\n // rescaled anchor. A table value is a constant and does not move.\n const probeOf = (\n name: string,\n m: { value: number; fromAnchor: boolean },\n ): number | undefined => {\n if (!m.fromAnchor) return m.value;\n const probe = anchorValuesProbe.get(name);\n return probe === undefined ? undefined : probe * conventionScaleToSI(name);\n };\n let magnitudeAnchorInvariant = false;\n if (magnitudeUsedAnchor) {\n const pa = probeOf(candidate.a, va!);\n const pb = probeOf(candidate.b, vb!);\n if (pa !== undefined && pb !== undefined && pa !== 0 && pb !== 0 && Number.isFinite(pa) && Number.isFinite(pb)) {\n const la = Math.log10(Math.abs(va!.value));\n const lb = Math.log10(Math.abs(vb!.value));\n const lpa = Math.log10(Math.abs(pa));\n const lpb = Math.log10(Math.abs(pb));\n magnitudeAnchorInvariant = Math.abs((lpa - lpb) - (la - lb)) <= ANCHOR_INVARIANCE_TOL;\n }\n }\n\n // A generic↔specialization identification (mass ≟ reference-mass) is\n // near-tautological — barred from `promising` regardless of structure.\n const subsuming = nameSubsumes(candidate.a, candidate.b);\n\n // Axis-compatibility gate (D1): a literal identity cannot have endpoints\n // whose STATED scale/force regimes disagree. Either side silent on an\n // axis (including a fold-conflict, resolved as unstated by\n // `effectiveAttributes`) abstains that axis rather than clashing.\n // Populated on every candidate, independent of which verdict wins.\n const attrsA = effectiveAttributes(candidate.a, attributesByName, baseIdents);\n const attrsB = effectiveAttributes(candidate.b, attributesByName, baseIdents);\n const checkedAxes: string[] = [];\n const axisClashes: string[] = [];\n const axisUnstated: { axis: string; endpoints: string[] }[] = [];\n // GATE_AXES is registry-derived (string[]); every registry axis name is a\n // RegimeAttributes key whose value is a string union — read via a string record.\n const recA = attrsA as Record<string, string | undefined>;\n const recB = attrsB as Record<string, string | undefined>;\n for (const axis of GATE_AXES) {\n const av = recA[axis];\n const bv = recB[axis];\n if (av === undefined || bv === undefined) {\n axisUnstated.push({\n axis,\n endpoints: [av === undefined ? candidate.a : null, bv === undefined ? candidate.b : null].filter(\n (e): e is string => e !== null,\n ),\n });\n continue; // abstain\n }\n checkedAxes.push(axis);\n if (av !== bv) axisClashes.push(`${axis}: ${av} ≠ ${bv}`);\n }\n axisClashes.sort();\n const axisChecked = checkedAxes.length > 0;\n const axisClash = axisClashes.length > 0;\n\n // The hypothesized identification, added in both directions so a≡b is a\n // full merge (identifications are directional in the engine).\n const rationale = `HYPOTHESIS (unadjudicated): ${candidate.a} ≡ ${candidate.b} — same dimension ${candidate.dim}`;\n const hypothesis: QuantityIdentification[] = [\n { from: candidate.a, to: candidate.b, rationale },\n { from: candidate.b, to: candidate.a, rationale },\n ];\n const withHyp = [...baseIdents, ...hypothesis];\n\n // Structural: does a≡b merge two components? (base partition from ctx)\n const mergesComponents =\n comps.has(candidate.a) &&\n comps.has(candidate.b) &&\n comps.get(candidate.a) !== comps.get(candidate.b);\n\n // Neither endpoint in the anchor closure means the identification cannot\n // fire: `forwardClosure` copies a value across `a ≡ b` only from a\n // determinable side. The hypothesis closure is then the base closure, and no\n // value in the graph moves, so neither closure nor retrodiction is recomputed\n // (9.0.0 audit §4 C9: 4004 of 4196 catalog candidates are this case).\n const touchesClosure = closureBase.has(candidate.a) || closureBase.has(candidate.b);\n\n // Closure unlock: forward closure from the anchor, with vs without. The base\n // closure is candidate-invariant (ctx); only the hypothesis closure is fresh.\n const closureHyp = touchesClosure ? forwardClosure(edges, anchor, withHyp) : closureBase;\n const unlocksFromAnchor = [...closureHyp]\n .filter((q) => !closureBase.has(q))\n .sort();\n\n // Numeric: the hypothesis must not CREATE a disagreement. A node whose\n // routes already disagree in the base graph is the graph's finding\n // (`retrodict` reports it), not this candidate's, so the attribution is\n // inconsistent(hypothesis) minus inconsistent(base) (9.0.0 audit §4 C4).\n // Only a target downstream of `a` or `b` can change under the hypothesis;\n // every other target's retrodiction is the base one, so only those targets\n // are retrodicted (§4 C9).\n const inconsistentNodes = touchesClosure\n ? newInconsistencies(edges, groundTruth, anchor, candidate, withHyp, baseInconsistentNodes)\n : [];\n const numericallyConsistent = inconsistentNodes.length === 0;\n\n // Verdict precedence: a magnitude clash is the most decisive, most\n // interpretable falsification, checked before the graph contradiction;\n // the regime-label prior (axis-clash) is weaker than both numeric\n // falsifiers and is not one itself, but still outranks promising/inert (D1).\n let verdict: VettedCandidate['verdict'];\n if (magnitudeClash) verdict = 'magnitude-clash';\n else if (!numericallyConsistent) verdict = 'contradictory';\n else if (axisClash) verdict = 'axis-clash';\n else if (mergesComponents && unlocksFromAnchor.length > 0 && !subsuming)\n verdict = 'promising';\n else verdict = 'inert';\n\n // Score: all falsifications sink to the bottom; a subsuming (tautological)\n // identification sinks within `inert`; otherwise reward structural merges,\n // unlocks, and the proposer's weak priors.\n let score = 0;\n if (magnitudeClash || !numericallyConsistent || axisClash) {\n score = -1;\n } else if (subsuming) {\n score = 0;\n } else {\n score += mergesComponents ? 4 : 0;\n score += Math.min(unlocksFromAnchor.length, 4);\n score += candidate.touchesCore ? 1 : 0;\n score += candidate.sameKind ? 1 : 0;\n }\n\n const canonicalKinds = CANONICAL_KINDS_BY_DIM.get(candidate.dim) ?? [];\n const touchesCanonical =\n CANONICAL_QUANTITY_NAMES.has(candidate.a) ||\n CANONICAL_QUANTITY_NAMES.has(candidate.b);\n\n return {\n a: candidate.a,\n b: candidate.b,\n dim: candidate.dim,\n touchesCore: candidate.touchesCore,\n sameKind: candidate.sameKind,\n mergesComponents,\n unlocksFromAnchor,\n numericallyConsistent,\n inconsistentNodes,\n ordersApart,\n magnitudeChecked,\n magnitudeUsedAnchor,\n magnitudeAnchorInvariant,\n magnitudeMissing: [va === undefined ? candidate.a : null, vb === undefined ? candidate.b : null].filter(\n (e): e is string => e !== null,\n ),\n axisUnstated,\n subsuming,\n verdict,\n score,\n axisChecked,\n axisClashes,\n canonicalKinds,\n touchesCanonical,\n };\n}\n\n/**\n * Run the full discovery funnel: propose cross-cluster candidates, vet each\n * against the inference suite, and rank — `promising` first, then by score.\n * The output is the physicist's worklist (vetted, provenance-traced), not a\n * list of discoveries.\n *\n * @public\n */\nexport function rankDiscoveries(\n edges: readonly BridgeEdge[],\n opts: DiscoveryOptions = {},\n): VettedCandidate[] {\n const VERDICT_RANK: Record<VettedCandidate['verdict'], number> = {\n promising: 0,\n inert: 1,\n 'magnitude-clash': 2,\n contradictory: 3,\n 'axis-clash': 4,\n };\n const ctx = buildDiscoveryContext(edges, opts);\n const candidates = proposeLinkCandidates(edges);\n const vetted = candidates.map((c) => vetInContext(edges, c, ctx));\n vetted.sort(\n (x, y) =>\n VERDICT_RANK[x.verdict] - VERDICT_RANK[y.verdict] ||\n y.score - x.score ||\n x.a.localeCompare(y.a) ||\n x.b.localeCompare(y.b),\n );\n return vetted;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/composition/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Discovery loop — vet link candidates through the verification primitives\n * (Direction 2).\n *\n * `proposeLinkCandidates` surfaces cross-cluster quantity pairs that share a\n * dimension and hands the raw coincidences to a human (the counts at a given\n * catalog are measured by the tests and recorded in NOTES.md). This\n * module closes the loop: it HYPOTHESIZES each candidate identification\n * `a ≡ b` and tests it with the machinery that already exists —\n *\n * - mergesComponents — does identifying a≡b connect two previously\n * disconnected parts of the graph? (structural\n * significance)\n * - unlocksFromAnchor — what becomes determinable from an anchor input\n * set WITH the identification that was not before?\n * (`forwardClosure`)\n * - numericallyConsistent — does retrodiction over the graph stay\n * all-consistent once the identification is\n * added, or does it introduce a contradiction?\n * (`retrodict` — the STRONG filter)\n *\n * so the physicist adjudicates a handful of VETTED, provenance-traced\n * candidates instead of dimensional noise.\n *\n * ⚠ Still a REVIEW SURFACE, never automated discovery (Part-VI §XXVII-B). A\n * shared dimension is a weak prior; the weight is on the numeric and\n * structural signals, and the numeric check only exercises the part of the\n * graph reachable from the anchor. `promising` means \"worth a physicist's\n * minute\", not \"true\".\n *\n * INTERNAL — not on the public surface (mirrors bridge-analysis.ts);\n * surfaced via `upt discover`.\n *\n * @module composition/discovery\n */\n\nimport type { BridgeEdge } from './edge.js';\nimport type { QuantityIdentification } from './compose.js';\nimport { QUANTITY_IDENTIFICATIONS, effectiveAttributes } from './compose.js';\nimport { GATE_AXES } from './axes.js';\nimport type { RegimeAttributes } from './quantity.js';\nimport { classifyIdentifiability, forwardClosure } from './identifiability.js';\nimport { retrodict, retrodictNode, forwardEvaluate } from './retrodiction.js';\nimport { proposeLinkCandidates } from './bridge-analysis.js';\nimport type { LinkCandidate } from './bridge-analysis.js';\nimport { clusterBySharedKeys } from './quantity-clusters.js';\nimport { normalCDF } from '@danielsimonjr/mathts-functions';\nimport { M_SUN_KG } from '../core/constants.js';\nimport { DEFAULT_SIGMA_DECADES, REPRESENTATIVE_VALUES, sigmaDecadesOf } from './representative-values.js';\nimport type { RepresentativeValue } from './representative-values.js';\nimport { conventionScaleToSI } from '../dimensional/unit-convention.js';\nimport { allQuantities } from './quantities.js';\nimport { CANONICAL_EQUATIONS } from '../canonical/registry.js';\nimport { format } from '../dimensional/algebra.js';\n\n// ── registry-only attribute lookup (D1 axis gate; Option-A resolution) ─────\n// Built from the centralized `Quantity` nodes ONLY (never canonical\n// per-equation stamps — audit adjudication F1). Names that aren't a\n// registry node (most bare canonical-equation variables) are simply absent,\n// so they always abstain — the canonical-only axis-clash=0 invariant holds\n// by construction, not by a special case.\n/** The canonical quantity→attributes map (registry nodes + per-equation stamps).\n * Exported for the axis-discrimination audit. @internal */\nexport const REGISTRY_ATTRIBUTES_BY_NAME: ReadonlyMap<string, RegimeAttributes> = new Map(\n allQuantities().map((quantity) => [quantity.name, quantity.attributes]),\n);\n\n// The axes the D1 regime-label gate compares are `GATE_AXES`, imported from the\n// `axes.ts` registry (`AXES.filter(gated)`) at the top of this module. Currently\n// scale + force; the 2026-07-05 extensible-axis expansion added\n// symmetry/topology/statistics as UNGATED attributes (they only abstain until the\n// discrimination audit earns them a gate — flip `gated: true` in axes.ts).\n\n// ── canonical-kind indexes (Sub-project C) ──────────────────────────────────\n// Discovery quantity names and canonical variable names are different\n// namespaces; the alignable axis is the DIMENSION. These are informational\n// annotations on each candidate (no verdict/score effect): they give the\n// physicist standard-physics context, not a hard filter (the registry is small).\nconst CANONICAL_KINDS_BY_DIM: ReadonlyMap<string, readonly string[]> = (() => {\n const m = new Map<string, Set<string>>();\n for (const ce of CANONICAL_EQUATIONS) {\n const key = format(ce.dimensional.target.dim);\n (m.get(key) ?? m.set(key, new Set()).get(key)!).add(ce.domain);\n }\n return new Map([...m].map(([k, v]) => [k, [...v].sort()]));\n})();\n\nconst CANONICAL_QUANTITY_NAMES: ReadonlySet<string> = (() => {\n const s = new Set<string>();\n for (const ce of CANONICAL_EQUATIONS) {\n s.add(ce.dimensional.target.name);\n for (const g of ce.dimensional.governing) s.add(g.name);\n }\n return s;\n})();\n\n/** A candidate after vetting against the inference suite. @hypothesis @public */\nexport interface VettedCandidate {\n readonly a: string;\n readonly b: string;\n /** Shared SI dimension (from the proposer). */\n readonly dim: string;\n /** One endpoint is in the anchored (established) cluster. */\n readonly touchesCore: boolean;\n /** The names share a word token (same physical KIND). */\n readonly sameKind: boolean;\n /**\n * Identifying a≡b merges two distinct connected components of the\n * quantity graph — it connects physics the catalog keeps separate.\n */\n readonly mergesComponents: boolean;\n /**\n * Quantities newly determinable from the anchor known-set once the\n * identification is added (structural unlock). Sorted.\n */\n readonly unlocksFromAnchor: readonly string[];\n /**\n * Retrodiction over the graph WITH the hypothesized identification creates\n * no numerical contradiction in the anchor-reachable subgraph. The strong\n * filter. A node whose routes already disagree in the base graph is the\n * graph's finding (`retrodict` reports it) and does not make a candidate\n * inconsistent; only a disagreement the hypothesis CREATES does.\n */\n readonly numericallyConsistent: boolean;\n /** Nodes that became inconsistent under the identification and were not\n * inconsistent in the base graph (the falsification, when\n * `numericallyConsistent` is false). Sorted. */\n readonly inconsistentNodes: readonly string[];\n /**\n * Orders of magnitude between the representative values of a and b\n * (`|log10|va| − log10|vb||`), or `null` when either has no representative\n * value (the gate abstained — see `magnitudeChecked`).\n */\n readonly ordersApart: number | null;\n /**\n * The calibrated STRENGTH of the magnitude falsifier against the two values' stated\n * uncertainties: `2·Φ(−ordersApart / √(σ_a² + σ_b²))`, with σ in decades per representative\n * value (`sigmaDecades`, default one decade: the table's \"good to about one order\"; an\n * anchor-derived value takes the default), through MathTS `normalCDF` of the negative\n * argument so a far tail is not rounded to 0 by `1 − cdf`. It is reported BESIDE the verdict\n * and changes no verdict: the clash threshold stays `ordersApart > maxOrders`. A small p says\n * the two magnitudes are hard to reconcile at their stated precision; 2.9 decades at σ = 1\n * is p ≈ 0.040, no longer a clean pass, while 3.1 decades stays a clash. NOT a credibility\n * score: it says nothing about whether the identification is true. `null` when the gate\n * abstained. Optional on the type; the funnel always sets it.\n */\n readonly magnitudeP?: number | null;\n /** Both endpoints had a representative value, so the magnitude gate ran. */\n readonly magnitudeChecked: boolean;\n /** The magnitude gate read at least one endpoint value from the graph at\n * the anchor (no static table entry) rather than the sourced table. */\n readonly magnitudeUsedAnchor: boolean;\n /**\n * The magnitude comparison used an anchor-derived value, and the ratio of the\n * two magnitudes does NOT move when every anchor input is rescaled by\n * {@link ANCHOR_PROBE_FACTOR}. The graph then fixes the ratio at every\n * anchor, so agreement in magnitude is an identity of the graph and not\n * evidence for the identification. The case that exposed it: the anchor sets\n * the temperature to the Hawking temperature of the anchor mass M, and then\n * the thermal wavelength is exactly 4π ℓ_P for EVERY M. Its anchor-derived\n * magnitude is not a representative magnitude of the quantity at all.\n * A quantity whose value really is a constant belongs in the\n * representative-value table, where it is not anchor-derived.\n * A clash stays a clash (the graph itself fixes the two apart); only a pass is\n * withheld, in `describeGrounding`. Optional on the type so hand-built\n * candidates need not state it; the funnel always sets it.\n */\n readonly magnitudeAnchorInvariant?: boolean;\n /**\n * The endpoints with no representative magnitude (neither in the sourced\n * table nor valued at the anchor) — why the magnitude gate abstained. Empty\n * when it ran. Optional on the type; the funnel always sets it.\n */\n readonly magnitudeMissing?: readonly string[];\n /**\n * Per gate axis that abstained, the endpoints that state no value on it —\n * why the axis gate had nothing to compare. Optional; the funnel always sets it.\n */\n readonly axisUnstated?: readonly { readonly axis: string; readonly endpoints: readonly string[] }[];\n /**\n * One endpoint name's hyphen-token set is a strict subset of the other's\n * (`mass` ⊂ `reference-mass`) — a generic↔specific identification of the\n * same KIND. Near-tautological (identifying a generic quantity with one of\n * its own specializations), so it is barred from `promising`.\n */\n readonly subsuming: boolean;\n /**\n * - `magnitude-clash` — representative values differ by more than the\n * threshold N orders (an independent falsification the\n * single-anchor graph cannot make). Checked first.\n * - `contradictory` — breaks numerical consistency (a graph falsification).\n * - `axis-clash` — the identification's stated `scale`/`force` regime\n * attributes disagree. A regime-LABEL prior against a\n * literal identity (D1), not a physical test: it\n * compares catalog labels and runs no computation, so\n * it is never counted or described as a falsification.\n * - `promising` — consistent AND connects disconnected physics AND\n * unlocks ≥1 quantity. Worth physicist review.\n * - `inert` — consistent but structurally/numerically idle (a\n * dimensional coincidence with no consequence).\n */\n readonly verdict: 'promising' | 'inert' | 'contradictory' | 'magnitude-clash' | 'axis-clash';\n /** Composite ranking score (higher = more worth review). */\n readonly score: number;\n /**\n * At least one of the `scale`/`force` axes had a resolved (non-conflicting)\n * value on BOTH endpoints, so the axis-compatibility gate produced a real\n * comparison (whether or not it clashed). `false` means every gate axis\n * abstained (silent on one/both sides, or a fold conflict) — the gate had\n * nothing to check. Populated on EVERY candidate, independent of verdict.\n */\n readonly axisChecked: boolean;\n /**\n * Per-axis clash descriptions (`'scale: quantum ≠ cosmological'`), sorted.\n * Empty when no gate axis clashed — including when `axisChecked` is\n * `false`, and even when a stronger falsifier (magnitude/contradictory)\n * won the verdict (no falsifier shadows another's annotation).\n */\n readonly axisClashes: readonly string[];\n /**\n * Standard-physics domains whose canonical equation has a TARGET of this\n * candidate's dimension (Sub-project C). Informational context — an empty\n * list means no canonical equation targets this dimension.\n */\n readonly canonicalKinds: readonly string[];\n /** At least one endpoint name is a quantity a canonical equation uses\n * (weak name-based prior; informational). */\n readonly touchesCanonical: boolean;\n}\n\n/** Options for the discovery loop. @internal */\nexport interface DiscoveryOptions {\n /**\n * Numeric anchor for the consistency check (and the closure unlock).\n * Default `{ mass: M_sun }` — the pre-registered retrodiction anchor.\n */\n readonly groundTruth?: Readonly<Record<string, number>>;\n /** Extra identifications honored as the baseline (default registered). */\n readonly identifications?: readonly QuantityIdentification[];\n /**\n * Max orders of magnitude two identified quantities may differ before the\n * identification is falsified as a `magnitude-clash`. Default {@link DEFAULT_MAX_ORDERS_OF_MAGNITUDE} — generous\n * enough for O(1) dimensionless prefactors and unit-convention slack, strict\n * enough to kill the scale-clash decoys.\n */\n readonly maxOrdersOfMagnitude?: number;\n /**\n * Sourced order-of-magnitude values for the gate (default\n * `REPRESENTATIVE_VALUES`). Injectable for testing and so the future\n * canonical-equation registry can supply them centrally.\n */\n readonly representativeValues?: Readonly<Record<string, RepresentativeValue>>;\n /**\n * Registry-only `scale`/`force`/`information` attributes by quantity name,\n * for the D1 axis-compatibility gate (default: every centralized\n * `Quantity.attributes`). Injectable for testing — never canonical\n * per-equation stamps (Option-A resolution).\n */\n readonly quantityAttributes?: ReadonlyMap<string, RegimeAttributes>;\n}\n\n/**\n * The component partition of quantity names: names in one equation are one component, and so\n * are the two sides of every identification. The shared partition of `quantity-clusters.ts`\n * (a name is an item; its keys are the equations and identifications it appears in). Returns\n * name → a representative of its component (its first name), read only for equality.\n *\n * RECORDED BEHAVIOUR, kept on purpose: an equation with no source (an all-constant right-hand\n * side, `CE-bohr-radius`) registers no name at all, so its target is absent from the map and\n * an identification touching it never counts as merging components. The union-find this\n * replaced only registered a name when it took part in a union, and the census, the canonical\n * funnel counts and the `map --proposed` golden pin that reading. Registering such a target\n * makes `bohr-radius ≟ hubble-distance` promising; whether it should is a catalog decision,\n * not this module's (`tests/composition/quantity-clusters.test.ts` pins the recorded reading\n * by name).\n */\nfunction quantityComponents(\n edges: readonly BridgeEdge[],\n idents: readonly QuantityIdentification[],\n): Map<string, string> {\n const keysByName = new Map<string, string[]>();\n const tag = (name: string, key: string): void => {\n const keys = keysByName.get(name);\n if (keys === undefined) keysByName.set(name, [key]);\n else keys.push(key);\n };\n edges.forEach((e, i) => {\n if (e.sources.length === 0) return; // recorded behaviour: a source-less target is not registered\n for (const s of e.sources) tag(s.name, `edge:${i}`);\n tag(e.target.name, `edge:${i}`);\n });\n idents.forEach((id, i) => {\n tag(id.from, `ident:${i}`);\n tag(id.to, `ident:${i}`);\n });\n const names = [...keysByName.keys()];\n const roots = new Map<string, string>();\n for (const cluster of clusterBySharedKeys(names, (name) => keysByName.get(name) ?? [], (name) => name)) {\n for (const name of cluster) roots.set(name, cluster[0]);\n }\n return roots;\n}\n\n/**\n * The ground truth the funnel anchors magnitudes to when the caller gives none: one solar mass.\n * Exported so the CLI can print the anchor a result is relative to (audit I3).\n * @internal\n */\nexport const ANCHOR_DEFAULT: Readonly<Record<string, number>> = { mass: M_SUN_KG };\n\n/**\n * The magnitude-clash threshold when the caller gives none: how many orders of magnitude two\n * identified quantities may differ. Exported so the CLI states the default it runs with.\n * @internal\n */\nexport const DEFAULT_MAX_ORDERS_OF_MAGNITUDE = 3;\n\n/**\n * Factor every anchor input is multiplied by to probe whether a magnitude ratio\n * depends on the anchor at all (persona finding L3). Three decades moves any\n * log-ratio that depends on the anchor far beyond {@link ANCHOR_INVARIANCE_TOL}.\n * @internal\n */\nconst ANCHOR_PROBE_FACTOR = 1e3;\n\n/** Decades within which a log-ratio counts as unchanged by the probe. @internal */\nconst ANCHOR_INVARIANCE_TOL = 1e-9;\n\n/**\n * One name's hyphen-token set is a STRICT subset of the other's\n * (`mass` ⊂ `reference-mass`, `mass` ⊂ `planck-mass`) — i.e. identifying a\n * generic quantity with one of its own specializations of the same kind.\n * Such an identification is near-tautological (it asserts the specialization\n * IS its genus), not a discovered cross-cluster link, so it is barred from\n * `promising`. Returns false for equal token sets and for pairs sharing only\n * a partial token (`schwarzschild-radius` ⊄ `foerster-radius`).\n */\nfunction nameSubsumes(a: string, b: string): boolean {\n const ta = new Set(a.split('-'));\n const tb = new Set(b.split('-'));\n if (ta.size === tb.size) return false;\n const [small, big] = ta.size < tb.size ? [ta, tb] : [tb, ta];\n for (const t of small) if (!big.has(t)) return false;\n return true;\n}\n\n/**\n * Candidate-invariant state for the discovery funnel — everything in\n * `vetLinkCandidate` that depends only on `(edges, opts)`, not on the specific\n * candidate. Computed once by `buildDiscoveryContext` and shared across every\n * candidate so `rankDiscoveries` does loop-invariant work once instead of N\n * times. Holds read-only structures — `vetInContext` never mutates them, so\n * sharing is safe. `tests/composition/discovery.test.ts` pins that directly:\n * two builds are equal, and vetting every candidate leaves the context equal\n * to a snapshot taken before.\n *\n * @internal\n */\nexport interface DiscoveryContext {\n readonly baseIdents: readonly QuantityIdentification[];\n readonly groundTruth: Readonly<Record<string, number>>;\n /** `Object.keys(groundTruth)` — the anchor known-set names. */\n readonly anchor: readonly string[];\n readonly repVals: Readonly<Record<string, RepresentativeValue>>;\n readonly maxOrders: number;\n /** Registry-only attribute lookup for the D1 axis gate (opts override or\n * `REGISTRY_ATTRIBUTES_BY_NAME`). */\n readonly attributesByName: ReadonlyMap<string, RegimeAttributes>;\n /** `forwardEvaluate(edges, groundTruth, baseIdents)` — anchor magnitudes. */\n readonly anchorValues: ReadonlyMap<string, number>;\n /** The same evaluation with every anchor input times {@link ANCHOR_PROBE_FACTOR}. */\n readonly anchorValuesProbe: ReadonlyMap<string, number>;\n /** `quantityComponents(edges, baseIdents)` — base component roots. */\n readonly comps: ReadonlyMap<string, string>;\n /** `forwardClosure(edges, anchor, baseIdents)` — base determinable set. */\n readonly closureBase: ReadonlySet<string>;\n /**\n * The targets the retrodiction of the anchor finds inconsistent with no\n * hypothesized identification (empty when the base is consistent). An\n * identification of two quantities outside {@link closureBase} cannot fire,\n * so that candidate's numeric report is this one.\n */\n readonly baseInconsistentNodes: readonly string[];\n}\n\n/** Resolve options and compute the candidate-invariant discovery state once.\n * @internal */\nexport function buildDiscoveryContext(\n edges: readonly BridgeEdge[],\n opts: DiscoveryOptions,\n): DiscoveryContext {\n const baseIdents = opts.identifications ?? QUANTITY_IDENTIFICATIONS;\n const groundTruth = opts.groundTruth ?? ANCHOR_DEFAULT;\n const anchor = Object.keys(groundTruth);\n const baseReport = retrodict(edges, groundTruth, { identifications: baseIdents });\n return {\n baseIdents,\n groundTruth,\n anchor,\n repVals: opts.representativeValues ?? REPRESENTATIVE_VALUES,\n maxOrders: opts.maxOrdersOfMagnitude ?? DEFAULT_MAX_ORDERS_OF_MAGNITUDE,\n attributesByName: opts.quantityAttributes ?? REGISTRY_ATTRIBUTES_BY_NAME,\n // Candidate-invariant: the anchor's forward evaluation, the base component\n // partition, and the base forward closure all depend only on (edges, opts).\n anchorValues: forwardEvaluate(edges, groundTruth, baseIdents),\n anchorValuesProbe: forwardEvaluate(\n edges,\n Object.fromEntries(\n Object.entries(groundTruth).map(([k, v]) => [k, v * ANCHOR_PROBE_FACTOR]),\n ),\n baseIdents,\n ),\n comps: quantityComponents(edges, baseIdents),\n closureBase: forwardClosure(edges, anchor, baseIdents),\n baseInconsistentNodes: baseReport.results\n .filter((r) => r.outcome === 'inconsistent')\n .map((r) => r.target)\n .sort(),\n };\n}\n\n/**\n * The quantities whose value can depend on one of `seeds`: the seeds, every\n * `to` of an identification from the set, and every target of an edge with a\n * source in the set, to a fixed point. An over-approximation (an edge that\n * does not fire still lists its target), which is the safe side: a target\n * left out would keep its base retrodiction unexamined.\n */\nfunction dependents(\n edges: readonly BridgeEdge[],\n seeds: readonly string[],\n idents: readonly QuantityIdentification[],\n): Set<string> {\n const set = new Set<string>(seeds);\n let changed = true;\n while (changed) {\n changed = false;\n for (const id of idents) {\n if (set.has(id.from) && !set.has(id.to)) {\n set.add(id.to);\n changed = true;\n }\n }\n for (const e of edges) {\n if (set.has(e.target.name)) continue;\n if (e.sources.some((s) => set.has(s.name))) {\n set.add(e.target.name);\n changed = true;\n }\n }\n }\n return set;\n}\n\n/**\n * The nodes the hypothesis `a ≡ b` makes inconsistent that the base graph did\n * not already have: inconsistent(hypothesis) minus inconsistent(base). Only a\n * node downstream of `a` or `b` can change, so only those nodes are\n * classified and retrodicted, with the same over-determined rule and the\n * same tolerance `retrodict` applies to the whole graph. Sorted.\n */\nfunction newInconsistencies(\n edges: readonly BridgeEdge[],\n groundTruth: Readonly<Record<string, number>>,\n anchor: readonly string[],\n candidate: LinkCandidate,\n withHyp: readonly QuantityIdentification[],\n baseInconsistentNodes: readonly string[],\n): string[] {\n const base = new Set(baseInconsistentNodes);\n const nodes: string[] = [];\n for (const target of [...dependents(edges, [candidate.a, candidate.b], withHyp)].sort()) {\n if (base.has(target)) continue;\n const classified = classifyIdentifiability(edges, anchor, target, { identifications: withHyp });\n if (classified.verdict !== 'over-determined') continue;\n const result = retrodictNode(edges, groundTruth, target, { identifications: withHyp });\n if (result.outcome === 'inconsistent') nodes.push(target);\n }\n return nodes;\n}\n\n/** One endpoint's magnitude for the gate: its value, where it came from, and its σ in decades. */\ninterface GateMagnitude {\n readonly value: number;\n readonly fromAnchor: boolean;\n readonly sigmaDecades: number;\n}\n\n/** What the magnitude gate found for one candidate. @internal */\nexport interface MagnitudeGate {\n /** The two magnitudes, when both were found (the gate ran). */\n readonly a: GateMagnitude | undefined;\n readonly b: GateMagnitude | undefined;\n readonly checked: boolean;\n readonly usedAnchor: boolean;\n /** `|log10|a| − log10|b||`, or null when the gate abstained. */\n readonly ordersApart: number | null;\n /** The verdict: `ordersApart > maxOrders`. */\n readonly clash: boolean;\n /** The calibrated strength `2·Φ(−orders/√(σ_a² + σ_b²))`, or null when the gate abstained. */\n readonly p: number | null;\n /** The endpoints with no magnitude (why the gate abstained); empty when it ran. */\n readonly missing: readonly string[];\n}\n\n/** MathTS `normalCDF`, read back as the number it is. */\nfunction phi(z: number): number {\n const v: unknown = normalCDF(z);\n if (typeof v !== 'number') throw new TypeError('normalCDF did not return a number for a number argument');\n return v;\n}\n\n/**\n * The two-sided tail of a gap of `orders` decades between two values whose log10 carry\n * standard deviations `sigmaA` and `sigmaB` decades: `2·Φ(−orders/√(σ_a² + σ_b²))`, through the\n * NEGATIVE argument (`1 − Φ` rounds a far tail to 0; the lower tail is accurate). A strength of\n * the falsifier, not a credibility score.\n *\n * @internal\n */\nexport function magnitudeStrength(orders: number, sigmaA: number, sigmaB: number): number {\n return 2 * phi(-orders / Math.sqrt(sigmaA * sigmaA + sigmaB * sigmaB));\n}\n\n/**\n * The magnitude gate: an INDEPENDENT falsifier the single-anchor graph cannot make. It runs only\n * when both endpoints have a representative value and abstains (never false-rejects) otherwise.\n * A value comes from the sourced static table first, else — for graph-derived quantities the\n * table omits by design (schwarzschild-radius, thermal-de-broglie-wavelength) — from the\n * quantity's value AT THE REGISTERED ANCHOR, a definite magnitude for this run, with the default\n * σ of one decade. The verdict is `ordersApart > ctx.maxOrders`; `p` is reported beside it.\n *\n * @internal\n */\nexport function magnitudeGate(candidate: LinkCandidate, ctx: DiscoveryContext): MagnitudeGate {\n const magnitudeOf = (name: string): GateMagnitude | undefined => {\n const rv = ctx.repVals[name];\n // Both paths apply the same finite-and-nonzero gate: a 0/∞/NaN magnitude\n // would make log10 blow up (log10(0) = -∞), spoofing or silently disabling\n // the falsifier. Symmetric validation across the table and anchor sources.\n if (rv !== undefined && Number.isFinite(rv.value) && rv.value !== 0) {\n return { value: rv.value, fromAnchor: false, sigmaDecades: sigmaDecadesOf(rv) };\n }\n const av = ctx.anchorValues.get(name);\n if (av !== undefined) {\n const value = av * conventionScaleToSI(name);\n if (Number.isFinite(value) && value !== 0) {\n return { value, fromAnchor: true, sigmaDecades: DEFAULT_SIGMA_DECADES };\n }\n }\n return undefined;\n };\n const a = magnitudeOf(candidate.a);\n const b = magnitudeOf(candidate.b);\n const checked = a !== undefined && b !== undefined;\n const ordersApart = checked ? Math.abs(Math.log10(Math.abs(a.value)) - Math.log10(Math.abs(b.value))) : null;\n return {\n a,\n b,\n checked,\n usedAnchor: checked && (a.fromAnchor || b.fromAnchor),\n ordersApart,\n clash: ordersApart !== null && ordersApart > ctx.maxOrders,\n p: checked && ordersApart !== null ? magnitudeStrength(ordersApart, a.sigmaDecades, b.sigmaDecades) : null,\n missing: [a === undefined ? candidate.a : null, b === undefined ? candidate.b : null].filter(\n (e): e is string => e !== null,\n ),\n };\n}\n\n/**\n * Vet one link candidate by hypothesizing the identification a≡b and\n * measuring its structural and numerical consequences. See module docs.\n *\n * @internal\n */\nexport function vetLinkCandidate(\n edges: readonly BridgeEdge[],\n candidate: LinkCandidate,\n opts: DiscoveryOptions = {},\n): VettedCandidate {\n return vetInContext(edges, candidate, buildDiscoveryContext(edges, opts));\n}\n\n/**\n * The per-candidate vetting body, given pre-computed candidate-invariant\n * `ctx`. The hypothesis-augmented closure is per-candidate. Retrodiction is\n * per-candidate only when an endpoint is already in the anchor closure;\n * otherwise the identification cannot fire and the base report stands.\n *\n * @internal\n */\nexport function vetInContext(\n edges: readonly BridgeEdge[],\n candidate: LinkCandidate,\n ctx: DiscoveryContext,\n): VettedCandidate {\n const {\n baseIdents,\n groundTruth,\n anchor,\n anchorValuesProbe,\n comps,\n closureBase,\n attributesByName,\n baseInconsistentNodes,\n } = ctx;\n\n // Magnitude gate: an INDEPENDENT falsifier the single-anchor graph can't make\n // (`magnitudeGate`): the verdict is the hard threshold, `p` its calibrated strength.\n const gate = magnitudeGate(candidate, ctx);\n const va = gate.a;\n const vb = gate.b;\n const magnitudeChecked = gate.checked;\n const magnitudeUsedAnchor = gate.usedAnchor;\n const ordersApart = gate.ordersApart;\n const magnitudeClash = gate.clash;\n\n // Anchor-invariance probe: re-read each anchor-derived magnitude at the\n // rescaled anchor. A table value is a constant and does not move.\n const probeOf = (\n name: string,\n m: { value: number; fromAnchor: boolean },\n ): number | undefined => {\n if (!m.fromAnchor) return m.value;\n const probe = anchorValuesProbe.get(name);\n return probe === undefined ? undefined : probe * conventionScaleToSI(name);\n };\n let magnitudeAnchorInvariant = false;\n if (magnitudeUsedAnchor) {\n const pa = probeOf(candidate.a, va!);\n const pb = probeOf(candidate.b, vb!);\n if (pa !== undefined && pb !== undefined && pa !== 0 && pb !== 0 && Number.isFinite(pa) && Number.isFinite(pb)) {\n const la = Math.log10(Math.abs(va!.value));\n const lb = Math.log10(Math.abs(vb!.value));\n const lpa = Math.log10(Math.abs(pa));\n const lpb = Math.log10(Math.abs(pb));\n magnitudeAnchorInvariant = Math.abs((lpa - lpb) - (la - lb)) <= ANCHOR_INVARIANCE_TOL;\n }\n }\n\n // A generic↔specialization identification (mass ≟ reference-mass) is\n // near-tautological — barred from `promising` regardless of structure.\n const subsuming = nameSubsumes(candidate.a, candidate.b);\n\n // Axis-compatibility gate (D1): a literal identity cannot have endpoints\n // whose STATED scale/force regimes disagree. Either side silent on an\n // axis (including a fold-conflict, resolved as unstated by\n // `effectiveAttributes`) abstains that axis rather than clashing.\n // Populated on every candidate, independent of which verdict wins.\n const attrsA = effectiveAttributes(candidate.a, attributesByName, baseIdents);\n const attrsB = effectiveAttributes(candidate.b, attributesByName, baseIdents);\n const checkedAxes: string[] = [];\n const axisClashes: string[] = [];\n const axisUnstated: { axis: string; endpoints: string[] }[] = [];\n // GATE_AXES is registry-derived (string[]); every registry axis name is a\n // RegimeAttributes key whose value is a string union — read via a string record.\n const recA = attrsA as Record<string, string | undefined>;\n const recB = attrsB as Record<string, string | undefined>;\n for (const axis of GATE_AXES) {\n const av = recA[axis];\n const bv = recB[axis];\n if (av === undefined || bv === undefined) {\n axisUnstated.push({\n axis,\n endpoints: [av === undefined ? candidate.a : null, bv === undefined ? candidate.b : null].filter(\n (e): e is string => e !== null,\n ),\n });\n continue; // abstain\n }\n checkedAxes.push(axis);\n if (av !== bv) axisClashes.push(`${axis}: ${av} ≠ ${bv}`);\n }\n axisClashes.sort();\n const axisChecked = checkedAxes.length > 0;\n const axisClash = axisClashes.length > 0;\n\n // The hypothesized identification, added in both directions so a≡b is a\n // full merge (identifications are directional in the engine).\n const rationale = `HYPOTHESIS (unadjudicated): ${candidate.a} ≡ ${candidate.b} — same dimension ${candidate.dim}`;\n const hypothesis: QuantityIdentification[] = [\n { from: candidate.a, to: candidate.b, rationale },\n { from: candidate.b, to: candidate.a, rationale },\n ];\n const withHyp = [...baseIdents, ...hypothesis];\n\n // Structural: does a≡b merge two components? (base partition from ctx)\n const mergesComponents =\n comps.has(candidate.a) &&\n comps.has(candidate.b) &&\n comps.get(candidate.a) !== comps.get(candidate.b);\n\n // Neither endpoint in the anchor closure means the identification cannot\n // fire: `forwardClosure` copies a value across `a ≡ b` only from a\n // determinable side. The hypothesis closure is then the base closure, and no\n // value in the graph moves, so neither closure nor retrodiction is recomputed\n // (9.0.0 audit §4 C9: 4004 of 4196 catalog candidates are this case).\n const touchesClosure = closureBase.has(candidate.a) || closureBase.has(candidate.b);\n\n // Closure unlock: forward closure from the anchor, with vs without. The base\n // closure is candidate-invariant (ctx); only the hypothesis closure is fresh.\n const closureHyp = touchesClosure ? forwardClosure(edges, anchor, withHyp) : closureBase;\n const unlocksFromAnchor = [...closureHyp]\n .filter((q) => !closureBase.has(q))\n .sort();\n\n // Numeric: the hypothesis must not CREATE a disagreement. A node whose\n // routes already disagree in the base graph is the graph's finding\n // (`retrodict` reports it), not this candidate's, so the attribution is\n // inconsistent(hypothesis) minus inconsistent(base) (9.0.0 audit §4 C4).\n // Only a target downstream of `a` or `b` can change under the hypothesis;\n // every other target's retrodiction is the base one, so only those targets\n // are retrodicted (§4 C9).\n const inconsistentNodes = touchesClosure\n ? newInconsistencies(edges, groundTruth, anchor, candidate, withHyp, baseInconsistentNodes)\n : [];\n const numericallyConsistent = inconsistentNodes.length === 0;\n\n // Verdict precedence: a magnitude clash is the most decisive, most\n // interpretable falsification, checked before the graph contradiction;\n // the regime-label prior (axis-clash) is weaker than both numeric\n // falsifiers and is not one itself, but still outranks promising/inert (D1).\n let verdict: VettedCandidate['verdict'];\n if (magnitudeClash) verdict = 'magnitude-clash';\n else if (!numericallyConsistent) verdict = 'contradictory';\n else if (axisClash) verdict = 'axis-clash';\n else if (mergesComponents && unlocksFromAnchor.length > 0 && !subsuming)\n verdict = 'promising';\n else verdict = 'inert';\n\n // Score: all falsifications sink to the bottom; a subsuming (tautological)\n // identification sinks within `inert`; otherwise reward structural merges,\n // unlocks, and the proposer's weak priors.\n let score = 0;\n if (magnitudeClash || !numericallyConsistent || axisClash) {\n score = -1;\n } else if (subsuming) {\n score = 0;\n } else {\n score += mergesComponents ? 4 : 0;\n score += Math.min(unlocksFromAnchor.length, 4);\n score += candidate.touchesCore ? 1 : 0;\n score += candidate.sameKind ? 1 : 0;\n }\n\n const canonicalKinds = CANONICAL_KINDS_BY_DIM.get(candidate.dim) ?? [];\n const touchesCanonical =\n CANONICAL_QUANTITY_NAMES.has(candidate.a) ||\n CANONICAL_QUANTITY_NAMES.has(candidate.b);\n\n return {\n a: candidate.a,\n b: candidate.b,\n dim: candidate.dim,\n touchesCore: candidate.touchesCore,\n sameKind: candidate.sameKind,\n mergesComponents,\n unlocksFromAnchor,\n numericallyConsistent,\n inconsistentNodes,\n ordersApart,\n magnitudeP: gate.p,\n magnitudeChecked,\n magnitudeUsedAnchor,\n magnitudeAnchorInvariant,\n magnitudeMissing: gate.missing,\n axisUnstated,\n subsuming,\n verdict,\n score,\n axisChecked,\n axisClashes,\n canonicalKinds,\n touchesCanonical,\n };\n}\n\n/**\n * Run the full discovery funnel: propose cross-cluster candidates, vet each\n * against the inference suite, and rank — `promising` first, then by score.\n * The output is the physicist's worklist (vetted, provenance-traced), not a\n * list of discoveries.\n *\n * @public\n */\nexport function rankDiscoveries(\n edges: readonly BridgeEdge[],\n opts: DiscoveryOptions = {},\n): VettedCandidate[] {\n const VERDICT_RANK: Record<VettedCandidate['verdict'], number> = {\n promising: 0,\n inert: 1,\n 'magnitude-clash': 2,\n contradictory: 3,\n 'axis-clash': 4,\n };\n const ctx = buildDiscoveryContext(edges, opts);\n const candidates = proposeLinkCandidates(edges);\n const vetted = candidates.map((c) => vetInContext(edges, c, ctx));\n vetted.sort(\n (x, y) =>\n VERDICT_RANK[x.verdict] - VERDICT_RANK[y.verdict] ||\n y.score - x.score ||\n x.a.localeCompare(y.a) ||\n x.b.localeCompare(y.b),\n );\n return vetted;\n}\n"]}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { Quantity } from './quantity.js';
|
|
15
15
|
import type { ExprNode } from '../dimensional/validator.js';
|
|
16
16
|
import type { Conventions, Counterexample, Regime, RelationContract } from '../relations/types.js';
|
|
17
|
+
import { type DomainViolation } from '../bridges/evaluation-errors.js';
|
|
17
18
|
/**
|
|
18
19
|
* First-class validity domain (v0.8.0 G-8). The predicate receives the
|
|
19
20
|
* same keyed inputs as `evaluate` and returns whether the edge's
|
|
@@ -22,11 +23,29 @@ import type { Conventions, Counterexample, Regime, RelationContract } from '../r
|
|
|
22
23
|
* @public
|
|
23
24
|
*/
|
|
24
25
|
export interface ValidityDomain {
|
|
25
|
-
/**
|
|
26
|
+
/** The conditions written out, read from the same text the predicate runs (a catalog relation's `holds`). */
|
|
26
27
|
readonly description: string;
|
|
27
|
-
/**
|
|
28
|
+
/** Whether every condition holds. */
|
|
28
29
|
readonly predicate: (inputs: Record<string, number>) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The conditions `inputs` violate, each written with the caller's keys and
|
|
32
|
+
* naming the inputs it reads; empty exactly when `predicate` holds.
|
|
33
|
+
* `keyOf` maps a name the domain reads to the key the caller gave; a name it
|
|
34
|
+
* does not map is its own key.
|
|
35
|
+
*/
|
|
36
|
+
readonly violations: (inputs: Record<string, number>, keyOf?: (name: string) => string) => readonly DomainViolation[];
|
|
29
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* The validity domain a condition states, in the catalog's condition grammar
|
|
40
|
+
* (`v > 0 and abs(x) < 1`; `true` for none). The predicate, the description
|
|
41
|
+
* and the violations are all read from that one text. `names` lists the
|
|
42
|
+
* hyphenated quantity names the condition reads beyond the registered ones;
|
|
43
|
+
* registered constants are bound. `declared` lists the constant names the
|
|
44
|
+
* condition may take as inputs (a relation's own sources).
|
|
45
|
+
*
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
export declare function validityDomain(condition: string, names?: readonly string[], declared?: readonly string[]): ValidityDomain;
|
|
30
49
|
/**
|
|
31
50
|
* Confidence grade — mirrors the catalog's status taxonomy. Composition
|
|
32
51
|
* demotes via {@link minConfidence}; it never promotes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge.d.ts","sourceRoot":"","sources":["../../src/composition/edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,MAAM,EACN,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"edge.d.ts","sourceRoot":"","sources":["../../src/composition/edge.ts"],"names":[],"mappings":"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"}
|
package/dist/composition/edge.js
CHANGED
|
@@ -13,6 +13,21 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { CANONICAL_GROUP_PREFACTORS } from './canonical-prefactors.js';
|
|
15
15
|
import { DomainViolationError } from '../bridges/evaluation-errors.js';
|
|
16
|
+
import { formulaNames, formulaScope } from '../bridges/expr-parse.js';
|
|
17
|
+
import { conditionDomain } from '../bridges/validity.js';
|
|
18
|
+
/**
|
|
19
|
+
* The validity domain a condition states, in the catalog's condition grammar
|
|
20
|
+
* (`v > 0 and abs(x) < 1`; `true` for none). The predicate, the description
|
|
21
|
+
* and the violations are all read from that one text. `names` lists the
|
|
22
|
+
* hyphenated quantity names the condition reads beyond the registered ones;
|
|
23
|
+
* registered constants are bound. `declared` lists the constant names the
|
|
24
|
+
* condition may take as inputs (a relation's own sources).
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export function validityDomain(condition, names = [], declared = []) {
|
|
29
|
+
return conditionDomain(condition, () => [...formulaNames(), ...names], formulaScope, declared);
|
|
30
|
+
}
|
|
16
31
|
/** Composition failed: no junction quantity matched. @public */
|
|
17
32
|
export class CompositionJunctionError extends Error {
|
|
18
33
|
constructor(message) {
|
|
@@ -153,6 +168,12 @@ function bindAliasInputs(edge, inputs) {
|
|
|
153
168
|
}
|
|
154
169
|
return out ?? inputs;
|
|
155
170
|
}
|
|
171
|
+
/** The key the caller gave `name` under: the name itself, else the first alias present. */
|
|
172
|
+
function givenKey(edge, inputs, name) {
|
|
173
|
+
if (Object.hasOwn(inputs, name))
|
|
174
|
+
return name;
|
|
175
|
+
return (edge.aliases?.[name] ?? []).find((alias) => Object.hasOwn(inputs, alias)) ?? name;
|
|
176
|
+
}
|
|
156
177
|
/**
|
|
157
178
|
* The domain predicate and `evaluate` read source names. This copy reads
|
|
158
179
|
* aliases first, so a CLI key reaches the same formula.
|
|
@@ -166,6 +187,7 @@ export function withBoundAliases(edge) {
|
|
|
166
187
|
domain: {
|
|
167
188
|
description: edge.domain.description,
|
|
168
189
|
predicate: (inputs) => edge.domain.predicate(bindAliasInputs(edge, inputs)),
|
|
190
|
+
violations: (inputs, keyOf = (name) => name) => edge.domain.violations(bindAliasInputs(edge, inputs), (name) => keyOf(givenKey(edge, inputs, name))),
|
|
169
191
|
},
|
|
170
192
|
evaluate: (inputs) => edge.evaluate(bindAliasInputs(edge, inputs)),
|
|
171
193
|
};
|
|
@@ -181,7 +203,7 @@ export function withBoundAliases(edge) {
|
|
|
181
203
|
export function evaluateEdge(edge, inputs) {
|
|
182
204
|
const bound = bindAliasInputs(edge, inputs);
|
|
183
205
|
if (!edge.domain.predicate(bound)) {
|
|
184
|
-
throw new DomainViolationError(
|
|
206
|
+
throw new DomainViolationError(edge.id, edge.domain.violations(bound, (name) => givenKey(edge, inputs, name)));
|
|
185
207
|
}
|
|
186
208
|
assertCoefficientSet(edge, bound);
|
|
187
209
|
return edge.evaluate(bound);
|