universal-physics-tensor 10.0.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -36
- package/bin/upt.mjs +13 -1
- package/data/applied-cases.json +1892 -0
- package/data/applied-cases.schema.json +194 -0
- 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 +389 -230
- package/data/bridge-catalog.schema.json +45 -7
- package/data/units.json +6 -25
- 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 +9 -15
- 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 +35 -25
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +37 -25
- 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/catalog-checks.d.ts +10 -0
- package/dist/cases/catalog-checks.d.ts.map +1 -0
- package/dist/cases/catalog-checks.js +241 -0
- package/dist/cases/catalog-checks.js.map +1 -0
- package/dist/cases/catalog.d.ts +83 -0
- package/dist/cases/catalog.d.ts.map +1 -0
- package/dist/cases/catalog.js +118 -0
- package/dist/cases/catalog.js.map +1 -0
- package/dist/cases/engine.d.ts +13 -0
- package/dist/cases/engine.d.ts.map +1 -0
- package/dist/cases/engine.js +179 -0
- package/dist/cases/engine.js.map +1 -0
- package/dist/cases/index.d.ts.map +1 -1
- package/dist/cases/index.js +5 -7
- package/dist/cases/index.js.map +1 -1
- package/dist/cases/methods.d.ts +215 -0
- package/dist/cases/methods.d.ts.map +1 -0
- package/dist/cases/methods.js +743 -0
- package/dist/cases/methods.js.map +1 -0
- package/dist/cases/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/types.d.ts +12 -0
- package/dist/cases/types.d.ts.map +1 -1
- package/dist/cases/types.js.map +1 -1
- package/dist/cli/args.d.ts +25 -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 +11 -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 +1 -0
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +9 -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 +122 -73
- 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 +67 -39
- 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 +24 -3
- 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 +7 -1
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +84 -11
- 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/determination.d.ts +1 -0
- package/dist/cli/determination.d.ts.map +1 -1
- package/dist/cli/determination.js.map +1 -1
- package/dist/cli/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/flag-help.d.ts +1 -0
- package/dist/cli/flag-help.d.ts.map +1 -1
- package/dist/cli/flag-help.js +1 -0
- package/dist/cli/flag-help.js.map +1 -1
- package/dist/cli/graphs.d.ts +2 -0
- package/dist/cli/graphs.d.ts.map +1 -1
- package/dist/cli/graphs.js +1 -0
- package/dist/cli/graphs.js.map +1 -1
- package/dist/cli/main.d.ts +8 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +19 -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 +28 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +23 -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 +12 -9
- 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 +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +8 -5
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +36 -5
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +30 -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 +3 -3
- package/dist/composition/canonical-graph.d.ts.map +1 -1
- package/dist/composition/canonical-graph.js +11 -38
- 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/consequence.d.ts +15 -5
- package/dist/composition/consequence.d.ts.map +1 -1
- package/dist/composition/consequence.js +6 -4
- package/dist/composition/consequence.js.map +1 -1
- package/dist/composition/discovery.d.ts +129 -9
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +171 -67
- 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 +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +6 -15
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +26 -14
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +64 -72
- 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/grounding.d.ts.map +1 -1
- package/dist/composition/grounding.js +19 -7
- package/dist/composition/grounding.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 +7 -8
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +7 -16
- 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/own-equation-magnitude.d.ts +95 -0
- package/dist/composition/own-equation-magnitude.d.ts.map +1 -0
- package/dist/composition/own-equation-magnitude.js +270 -0
- package/dist/composition/own-equation-magnitude.js.map +1 -0
- package/dist/composition/probe/backend-protocol.d.ts +3 -0
- package/dist/composition/probe/backend-protocol.d.ts.map +1 -1
- package/dist/composition/probe/backend-protocol.js.map +1 -1
- package/dist/composition/probe/candidate-store.d.ts +1 -0
- package/dist/composition/probe/candidate-store.d.ts.map +1 -1
- package/dist/composition/probe/candidate-store.js +1 -0
- package/dist/composition/probe/candidate-store.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +8 -4
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +23 -12
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +18 -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 +7 -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 +2 -0
- 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 +7 -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 +30 -1
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +58 -36
- 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 +25 -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 +5 -0
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +73 -24
- 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 +251 -0
- package/dist/composition/probe/power-law.js.map +1 -0
- package/dist/composition/probe/problem.d.ts +8 -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 +7 -1
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +10 -7
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/run-manifest.d.ts +1 -0
- package/dist/composition/probe/run-manifest.d.ts.map +1 -1
- package/dist/composition/probe/run-manifest.js.map +1 -1
- package/dist/composition/probe/scalar-search.d.ts +50 -0
- package/dist/composition/probe/scalar-search.d.ts.map +1 -0
- package/dist/composition/probe/scalar-search.js +169 -0
- package/dist/composition/probe/scalar-search.js.map +1 -0
- package/dist/composition/probe/scoring.d.ts +1 -0
- package/dist/composition/probe/scoring.d.ts.map +1 -1
- package/dist/composition/probe/scoring.js.map +1 -1
- package/dist/composition/probe/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 +235 -184
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +16 -0
- package/dist/composition/probe/t-tail.d.ts.map +1 -0
- package/dist/composition/probe/t-tail.js +29 -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 +52 -12
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +107 -60
- 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 +29 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts +15 -0
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +12 -4
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts +1 -0
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +3 -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 +42 -41
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +71 -51
- 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-ast-gradient.d.ts +27 -23
- package/dist/diff/bridge-ast-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-ast-gradient.js +75 -173
- package/dist/diff/bridge-ast-gradient.js.map +1 -1
- package/dist/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/ast-types.d.ts +15 -0
- package/dist/dimensional/ast-types.d.ts.map +1 -1
- package/dist/dimensional/ast-types.js.map +1 -1
- package/dist/dimensional/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/curvature-composite.d.ts +1 -1
- package/dist/dimensional/curvature-composite.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 +24 -11
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +122 -130
- 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/mathts-unit-delegation.d.ts +29 -0
- package/dist/dimensional/mathts-unit-delegation.d.ts.map +1 -0
- package/dist/dimensional/mathts-unit-delegation.js +187 -0
- package/dist/dimensional/mathts-unit-delegation.js.map +1 -0
- package/dist/dimensional/mathts-unit-wrapper.d.ts +33 -0
- package/dist/dimensional/mathts-unit-wrapper.d.ts.map +1 -0
- package/dist/dimensional/mathts-unit-wrapper.js +190 -0
- package/dist/dimensional/mathts-unit-wrapper.js.map +1 -0
- package/dist/dimensional/metric.d.ts.map +1 -1
- package/dist/dimensional/metric.js +0 -1
- package/dist/dimensional/metric.js.map +1 -1
- package/dist/dimensional/scalar-lowering.d.ts +21 -0
- package/dist/dimensional/scalar-lowering.d.ts.map +1 -0
- package/dist/dimensional/scalar-lowering.js +45 -0
- package/dist/dimensional/scalar-lowering.js.map +1 -0
- package/dist/dimensional/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.d.ts +5 -1
- package/dist/dimensional/unit-data.d.ts.map +1 -1
- package/dist/dimensional/unit-data.js +30 -6
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/dimensional/units.d.ts +2 -0
- package/dist/dimensional/units.d.ts.map +1 -1
- package/dist/dimensional/units.js +59 -3
- package/dist/dimensional/units.js.map +1 -1
- package/dist/dimensional/validator.d.ts +2 -0
- package/dist/dimensional/validator.d.ts.map +1 -1
- package/dist/dimensional/validator.js.map +1 -1
- package/dist/index.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/connection-lowering-helpers.d.ts +3 -1
- package/dist/numerical/connection-lowering-helpers.d.ts.map +1 -1
- package/dist/numerical/connection-lowering-helpers.js +11 -15
- package/dist/numerical/connection-lowering-helpers.js.map +1 -1
- package/dist/numerical/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/pderiv.d.ts.map +1 -1
- package/dist/numerical/pderiv.js +2 -6
- package/dist/numerical/pderiv.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 +11 -13
- 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/strides.d.ts +3 -2
- package/dist/numerical/strides.d.ts.map +1 -1
- package/dist/numerical/strides.js +3 -10
- package/dist/numerical/strides.js.map +1 -1
- package/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 +9 -12
- package/dist/cases/brownian-sphere.d.ts +0 -68
- package/dist/cases/brownian-sphere.d.ts.map +0 -1
- package/dist/cases/brownian-sphere.js +0 -354
- package/dist/cases/brownian-sphere.js.map +0 -1
- package/dist/cases/damped-resonator.d.ts +0 -23
- package/dist/cases/damped-resonator.d.ts.map +0 -1
- package/dist/cases/damped-resonator.js +0 -224
- package/dist/cases/damped-resonator.js.map +0 -1
- package/dist/cases/kepler-rv.d.ts +0 -13
- package/dist/cases/kepler-rv.d.ts.map +0 -1
- package/dist/cases/kepler-rv.js +0 -172
- package/dist/cases/kepler-rv.js.map +0 -1
- package/dist/cases/lumped-cooling.d.ts +0 -46
- package/dist/cases/lumped-cooling.d.ts.map +0 -1
- package/dist/cases/lumped-cooling.js +0 -261
- package/dist/cases/lumped-cooling.js.map +0 -1
- package/dist/cases/resistor-noise.d.ts +0 -14
- package/dist/cases/resistor-noise.d.ts.map +0 -1
- package/dist/cases/resistor-noise.js +0 -215
- package/dist/cases/resistor-noise.js.map +0 -1
- package/dist/cases/skin-depth.d.ts +0 -21
- package/dist/cases/skin-depth.d.ts.map +0 -1
- package/dist/cases/skin-depth.js +0 -174
- package/dist/cases/skin-depth.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linkage.js","sourceRoot":"","sources":["../../src/canonical/linkage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bridge↔canonical linkage (Sub-project B) — the \"validate against standard\n * physics\" engine. For a canonical equation with a scalar-AST and a bridge with\n * an RHS AST, it asks:\n * 1. do they share the same dimension? (necessary)\n * 2. are they the same relation up to dimensionless factors? (`normalForm`)\n * 3. (best-effort) do they agree numerically up to a constant ratio?\n *\n * The structural half — same dimension, `normalForm`, and the F4\n * `restatesBridge` guard — is `classifyStructure` in `structural.ts`. This\n * module calls that function and then runs numerical recovery. A structural\n * match is `restates-canonical` (a trivial X≡X, NOT a discovery) only when\n * the canonical entry's `restatesBridge` actually names that bridge. A\n * structural match the registry did NOT pre-declare is a genuine `recovers`\n * correspondence. Numerical agreement is not a confirmation.\n *\n * @module canonical/linkage\n */\nimport type { ExprNode } from '../dimensional/validator.js';\nimport type { Dimension } from '../dimensional/types.js';\nimport { evalExpr } from '../composition/expr-eval.js';\nimport { CONSTANTS } from '../dimensional/symbolic-constants.js';\nimport type { CanonicalEquation } from './canonical-equation.js';\nimport { CANONICAL_EQUATIONS, canonicalById } from './registry.js';\nimport { canonicalQuantityName, normalForm } from './normal-form.js';\nimport { bridgeShapes, classifyStructure } from './structural.js';\nimport type { BridgeShape } from './structural.js';\n\n/** Best-effort numerical-recovery outcome. */\nexport interface RecoveryOutcome {\n /** Both ASTs evaluated at every sample (no unresolved leaf). */\n readonly tested: boolean;\n /** Spread of the canonical/bridge value ratio across samples (0 ⇒ they agree\n * up to a single constant factor). `NaN` when not tested. */\n readonly maxRelErr: number;\n}\n\n/** One bridge↔canonical comparison. */\nexport interface LinkageResult {\n readonly canonicalId: string;\n readonly bridgeId: number;\n /** Inferred dimensions agree. */\n readonly dimMatch: boolean;\n /** Same relation up to dimensionless factors (`normalForm`). */\n readonly structuralMatch: boolean;\n readonly recovery: RecoveryOutcome | null;\n readonly classification:\n | 'restates-canonical'\n | 'recovers'\n | 'dimensional-only'\n | 'unrelated';\n}\n\nconst isDimensionless = (d: Dimension): boolean =>\n d.L === 0 &&\n d.M === 0 &&\n d.T === 0 &&\n d.I === 0 &&\n d.Theta === 0 &&\n d.N === 0 &&\n d.J === 0;\n\n/**\n * Collect leaves `evalExpr` can't resolve (not a registered constant, not a\n * numeric literal), split into physical `vars` (non-dimensionless — varied\n * across samples) and `dimless` (dimensionless — held fixed: they ARE the\n * constant factor \"up to\" which recovery is measured).\n */\nfunction collectLeaves(\n node: ExprNode,\n vars: Map<string, string>,\n dimless: Set<string>,\n): void {\n switch (node.kind) {\n case 'symbol':\n if (!(node.name in CONSTANTS) && Number.isNaN(Number(node.name))) {\n if (isDimensionless(node.dim)) dimless.add(node.name);\n else vars.set(node.name, canonicalQuantityName(node.name, node.dim));\n }\n return;\n case 'op':\n for (const a of node.args) collectLeaves(a, vars, dimless);\n return;\n case 'transcendental':\n collectLeaves(node.arg, vars, dimless);\n return;\n case 'abs':\n collectLeaves(node.arg, vars, dimless);\n return;\n default:\n return;\n }\n}\n\n/**\n * The sample points: variable `i` (in sorted canonical-name order) takes the\n * value `(1.3 + 0.7·i)^p` at exponent `p`. Each variable has its own base, so\n * the RATIOS between variables change from point to point too. One common\n * scale factor would leave every ratio such as y/x fixed, and two homogeneous\n * expressions of the same degree (`x + 2y` and `x + y`) would then pass as a\n * constant ratio at every point: a recovery that could not fail (9.0.0 audit\n * §4 C3). `canonical-compare.ts` uses the same scheme.\n */\nconst SAMPLE_EXPONENTS = [1, 1.3, 1.6];\n\n/**\n * Best-effort check that two ASTs agree up to a constant ratio.\n *\n * @internal\n */\nexport function numericalRecovery(canon: ExprNode, bridge: ExprNode): RecoveryOutcome {\n const vars = new Map<string, string>();\n const dimless = new Set<string>();\n collectLeaves(canon, vars, dimless);\n collectLeaves(bridge, vars, dimless);\n // `M` and `mass` are one quantity. They share a sample, or the ratio is a\n // float artifact of two independent draws of the same mass.\n const canonicals = [...new Set(vars.values())].sort();\n const index = new Map(canonicals.map((n, i) => [n, i]));\n const ratios: number[] = [];\n for (const p of SAMPLE_EXPONENTS) {\n const values: Record<string, number> = {};\n for (const [raw, canonName] of vars) {\n values[raw] = Math.pow(1.3 + 0.7 * index.get(canonName)!, p);\n }\n // Hold unresolved dimensionless leaves fixed — recovery is \"up to\" them.\n for (const n of dimless) values[n] = 1;\n let cv: number;\n let bv: number;\n try {\n cv = evalExpr(canon, values);\n bv = evalExpr(bridge, values);\n } catch {\n return { tested: false, maxRelErr: NaN };\n }\n // Guard cv===0 too: with cv===0 the ratio is 0 at every sample, so the\n // relative-spread denominator r0===0 ⇒ NaN — a false \"tested\" result.\n if (!Number.isFinite(cv) || !Number.isFinite(bv) || bv === 0 || cv === 0) {\n return { tested: false, maxRelErr: NaN };\n }\n ratios.push(cv / bv);\n }\n const r0 = ratios[0];\n const maxRelErr = Math.max(...ratios.map((r) => Math.abs((r - r0) / r0)));\n return { tested: true, maxRelErr };\n}\n\n/**\n * The comparison core, given a canonical entry (with its pre-computed\n * normal-form) and a bridge's shape from the process-wide `bridgeShapes`\n * table (validated dimension and normal-form hash, computed once). Pure: no\n * AST re-walks except the rare `numericalRecovery` that only fires on a\n * structural match.\n */\nfunction classifyAgainst(\n canon: CanonicalEquation,\n canonAst: ExprNode,\n canonNormal: string,\n bridgeId: number,\n bridge: BridgeShape,\n): LinkageResult {\n const relation = classifyStructure({\n left: canonAst,\n leftDim: canon.dimensional.target.dim,\n leftNormal: canonNormal,\n right: bridge.rhs,\n rightDim: bridge.dim,\n rightNormal: bridge.normal,\n restatesBridge: canon.restatesBridge,\n bridgeId: String(bridgeId),\n });\n const recovery = relation.structuralMatch ? numericalRecovery(canonAst, bridge.rhs) : null;\n\n let classification: LinkageResult['classification'];\n if (relation.structuralMatch) {\n classification = relation.restates ? 'restates-canonical' : 'recovers';\n } else if (relation.dimMatch) {\n classification = 'dimensional-only';\n } else {\n classification = 'unrelated';\n }\n\n return {\n canonicalId: canon.id,\n bridgeId,\n dimMatch: relation.dimMatch,\n structuralMatch: relation.structuralMatch,\n recovery,\n classification,\n };\n}\n\n/** Compare one canonical entry against one bridge. */\nexport function classifyLinkage(\n canonicalId: string,\n bridgeId: number,\n): LinkageResult {\n const canon = canonicalById(canonicalId);\n const bridge = bridgeShapes().get(bridgeId);\n\n if (!canon || !bridge || !canon.scalarAst) {\n return {\n canonicalId,\n bridgeId,\n dimMatch: false,\n structuralMatch: false,\n recovery: null,\n classification: 'unrelated',\n };\n }\n\n return classifyAgainst(\n canon,\n canon.scalarAst,\n normalForm(canon.scalarAst),\n bridgeId,\n bridge,\n );\n}\n\n/**\n * Scan every canonical entry (with a scalar-AST) against every bridge RHS, and\n * return the non-`unrelated` results — the physicist's linkage worklist.\n *\n * Each bridge's shape comes from the process-wide `bridgeShapes` table\n * (validated and normal-formed once), and each canonical's normal-form is\n * computed once per outer iteration (bridge-invariant); the inner loop then\n * only compares pre-computed strings and dimensions.\n */\nexport function scanLinkages(): LinkageResult[] {\n const results: LinkageResult[] = [];\n const bridges = bridgeShapes();\n\n for (const ce of CANONICAL_EQUATIONS) {\n if (!ce.scalarAst) continue;\n const canonNormal = normalForm(ce.scalarAst);\n for (const [bridgeId, bridge] of bridges) {\n const r = classifyAgainst(\n ce,\n ce.scalarAst,\n canonNormal,\n bridgeId,\n bridge,\n );\n if (r.classification !== 'unrelated') results.push(r);\n }\n }\n return results;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"linkage.js","sourceRoot":"","sources":["../../src/canonical/linkage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bridge↔canonical linkage (Sub-project B) — the \"validate against standard\n * physics\" engine. For a canonical equation with a scalar-AST and a bridge with\n * an RHS AST, it asks:\n * 1. do they share the same dimension? (necessary)\n * 2. are they the same relation up to dimensionless factors? (`normalForm`)\n * 3. (best-effort) do they agree numerically up to a constant ratio?\n *\n * The structural half — same dimension, `normalForm`, and the F4\n * `restatesBridge` guard — is `classifyStructure` in `structural.ts`. This\n * module calls that function and then runs numerical recovery. A structural\n * match is `restates-canonical` (a trivial X≡X, NOT a discovery) only when\n * the canonical entry's `restatesBridge` actually names that bridge. A\n * structural match the registry did NOT pre-declare is a genuine `recovers`\n * correspondence. Numerical agreement is not a confirmation.\n *\n * @module canonical/linkage\n */\nimport type { ExprNode } from '../dimensional/validator.js';\nimport { isDimensionless } from '../dimensional/algebra.js';\nimport { evalExpr } from '../composition/expr-eval.js';\nimport { forEachScalarLeaf, isDecimalLiteral } from '../dimensional/ast-leaves.js';\nimport { isRegisteredConstant } from '../dimensional/symbolic-constants.js';\nimport type { CanonicalEquation } from './canonical-equation.js';\nimport { CANONICAL_EQUATIONS, canonicalById } from './registry.js';\nimport { canonicalQuantityName, normalForm } from './normal-form.js';\nimport { bridgeShapes, classifyStructure } from './structural.js';\nimport type { BridgeShape } from './structural.js';\nimport { FIXED_POINT_EXPONENTS, constantRatio, fixedPoint } from './fixed-points.js';\n\n/** Best-effort numerical-recovery outcome. */\nexport interface RecoveryOutcome {\n /** Both ASTs evaluated at every sample (no unresolved leaf). */\n readonly tested: boolean;\n /** Spread of the canonical/bridge value ratio across samples (0 ⇒ they agree\n * up to a single constant factor). `NaN` when not tested. */\n readonly maxRelErr: number;\n}\n\n/** One bridge↔canonical comparison. */\nexport interface LinkageResult {\n readonly canonicalId: string;\n readonly bridgeId: number;\n /** Inferred dimensions agree. */\n readonly dimMatch: boolean;\n /** Same relation up to dimensionless factors (`normalForm`). */\n readonly structuralMatch: boolean;\n readonly recovery: RecoveryOutcome | null;\n readonly classification:\n | 'restates-canonical'\n | 'recovers'\n | 'dimensional-only'\n | 'unrelated';\n}\n\n/**\n * Collect leaves `evalExpr` can't resolve (not a registered constant, not a\n * numeric literal), split into physical `vars` (non-dimensionless — varied\n * across samples) and `dimless` (dimensionless — held fixed: they ARE the\n * constant factor \"up to\" which recovery is measured).\n */\nfunction collectLeaves(\n node: ExprNode,\n vars: Map<string, string>,\n dimless: Set<string>,\n): void {\n forEachScalarLeaf(\n node,\n (leaf) => {\n if (isRegisteredConstant(leaf.name) || isDecimalLiteral(leaf.name)) return;\n if (isDimensionless(leaf.dim)) dimless.add(leaf.name);\n else vars.set(leaf.name, canonicalQuantityName(leaf.name, leaf.dim));\n },\n { transcendental: true, abs: true },\n );\n}\n\n/**\n * The sample points: variable `i` (in sorted canonical-name order) takes the\n * value `(1.3 + 0.7·i)^p` at each exponent of `FIXED_POINT_EXPONENTS`. Each\n * variable has its own base, so the RATIOS between variables change from\n * point to point too. One common scale factor would leave every ratio such\n * as y/x fixed, and two homogeneous expressions of the same degree\n * (`x + 2y` and `x + y`) would then pass as a constant ratio at every point:\n * a recovery that could not fail (9.0.0 audit §4 C3). `canonical-compare.ts`\n * uses the same exponents on its own base.\n */\nconst RECOVERY_SCHEME = { base: 1.3, step: 0.7 } as const;\n\n/**\n * Best-effort check that two ASTs agree up to a constant ratio.\n *\n * @internal\n */\nexport function numericalRecovery(canon: ExprNode, bridge: ExprNode): RecoveryOutcome {\n const vars = new Map<string, string>();\n const dimless = new Set<string>();\n collectLeaves(canon, vars, dimless);\n collectLeaves(bridge, vars, dimless);\n // `M` and `mass` are one quantity. They share a sample, or the ratio is a\n // float artifact of two independent draws of the same mass.\n const canonicals = [...new Set(vars.values())].sort();\n const ratios: number[] = [];\n for (const p of FIXED_POINT_EXPONENTS) {\n const point = fixedPoint(canonicals, p, RECOVERY_SCHEME);\n const values: Record<string, number> = {};\n for (const [raw, canonName] of vars) values[raw] = point[canonName]!;\n // Hold unresolved dimensionless leaves fixed — recovery is \"up to\" them.\n for (const n of dimless) values[n] = 1;\n let cv: number;\n let bv: number;\n try {\n cv = evalExpr(canon, values);\n bv = evalExpr(bridge, values);\n } catch {\n return { tested: false, maxRelErr: NaN };\n }\n // Guard cv===0 too: with cv===0 the ratio is 0 at every sample, so the\n // relative-spread denominator r0===0 ⇒ NaN — a false \"tested\" result.\n if (!Number.isFinite(cv) || !Number.isFinite(bv) || bv === 0 || cv === 0) {\n return { tested: false, maxRelErr: NaN };\n }\n ratios.push(cv / bv);\n }\n // The recovery records the spread; the reader decides. Every ratio is finite and nonzero here.\n return { tested: true, maxRelErr: constantRatio(ratios, 0).maxRelErr };\n}\n\n/**\n * The comparison core, given a canonical entry (with its pre-computed\n * normal-form) and a bridge's shape from the process-wide `bridgeShapes`\n * table (validated dimension and normal-form hash, computed once). Pure: no\n * AST re-walks except the rare `numericalRecovery` that only fires on a\n * structural match.\n */\nfunction classifyAgainst(\n canon: CanonicalEquation,\n canonAst: ExprNode,\n canonNormal: string,\n bridgeId: number,\n bridge: BridgeShape,\n): LinkageResult {\n const relation = classifyStructure({\n left: canonAst,\n leftDim: canon.dimensional.target.dim,\n leftNormal: canonNormal,\n right: bridge.rhs,\n rightDim: bridge.dim,\n rightNormal: bridge.normal,\n restatesBridge: canon.restatesBridge,\n bridgeId: String(bridgeId),\n });\n const recovery = relation.structuralMatch ? numericalRecovery(canonAst, bridge.rhs) : null;\n\n let classification: LinkageResult['classification'];\n if (relation.structuralMatch) {\n classification = relation.restates ? 'restates-canonical' : 'recovers';\n } else if (relation.dimMatch) {\n classification = 'dimensional-only';\n } else {\n classification = 'unrelated';\n }\n\n return {\n canonicalId: canon.id,\n bridgeId,\n dimMatch: relation.dimMatch,\n structuralMatch: relation.structuralMatch,\n recovery,\n classification,\n };\n}\n\n/** Compare one canonical entry against one bridge. */\nexport function classifyLinkage(\n canonicalId: string,\n bridgeId: number,\n): LinkageResult {\n const canon = canonicalById(canonicalId);\n const bridge = bridgeShapes().get(bridgeId);\n\n if (!canon || !bridge || !canon.scalarAst) {\n return {\n canonicalId,\n bridgeId,\n dimMatch: false,\n structuralMatch: false,\n recovery: null,\n classification: 'unrelated',\n };\n }\n\n return classifyAgainst(\n canon,\n canon.scalarAst,\n normalForm(canon.scalarAst),\n bridgeId,\n bridge,\n );\n}\n\n/**\n * Scan every canonical entry (with a scalar-AST) against every bridge RHS, and\n * return the non-`unrelated` results — the physicist's linkage worklist.\n *\n * Each bridge's shape comes from the process-wide `bridgeShapes` table\n * (validated and normal-formed once), and each canonical's normal-form is\n * computed once per outer iteration (bridge-invariant); the inner loop then\n * only compares pre-computed strings and dimensions.\n */\nexport function scanLinkages(): LinkageResult[] {\n const results: LinkageResult[] = [];\n const bridges = bridgeShapes();\n\n for (const ce of CANONICAL_EQUATIONS) {\n if (!ce.scalarAst) continue;\n const canonNormal = normalForm(ce.scalarAst);\n for (const [bridgeId, bridge] of bridges) {\n const r = classifyAgainst(\n ce,\n ce.scalarAst,\n canonNormal,\n bridgeId,\n bridge,\n );\n if (r.classification !== 'unrelated') results.push(r);\n }\n }\n return results;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normal-form.d.ts","sourceRoot":"","sources":["../../src/canonical/normal-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"normal-form.d.ts","sourceRoot":"","sources":["../../src/canonical/normal-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAoBzD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,CAK1E;AAoDD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAiEjD;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAEnE"}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { equals } from '../dimensional/algebra.js';
|
|
1
|
+
import { equals, isDimensionless } from '../dimensional/algebra.js';
|
|
2
2
|
import { DIMENSION_RENAMES, quantityIdForSpelling } from '../dimensional/formula-names.js';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
d.M === 0 &&
|
|
6
|
-
d.T === 0 &&
|
|
7
|
-
d.I === 0 &&
|
|
8
|
-
d.Theta === 0 &&
|
|
9
|
-
d.N === 0 &&
|
|
10
|
-
d.J === 0;
|
|
3
|
+
import { isRegisteredConstant, piMultipleValue } from '../dimensional/symbolic-constants.js';
|
|
4
|
+
import { isDecimalLiteral } from '../dimensional/ast-leaves.js';
|
|
11
5
|
/** Token for a node that carries no structural content (a dimensionless factor). */
|
|
12
6
|
const UNIT = '1';
|
|
13
7
|
/**
|
|
@@ -44,8 +38,8 @@ export function canonicalQuantityName(name, dim) {
|
|
|
44
38
|
* dropping it would conflate distinct interiors.
|
|
45
39
|
*/
|
|
46
40
|
function isDroppableConstant(name) {
|
|
47
|
-
return (name
|
|
48
|
-
|
|
41
|
+
return (isRegisteredConstant(name) ||
|
|
42
|
+
isDecimalLiteral(name) ||
|
|
49
43
|
NAMED_DIMENSIONLESS_CONSTANTS.has(name) ||
|
|
50
44
|
piMultipleValue(name) !== undefined);
|
|
51
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normal-form.js","sourceRoot":"","sources":["../../src/canonical/normal-form.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Normalized structural form of a scalar `ExprNode`, **up to dimensionless\n * multiplicative factors** — the hash the F4 circularity guard uses to decide\n * whether a bridge's RHS and a canonical equation encode the same relation.\n *\n * Two expressions hash equal when they differ only by:\n * - dimensionless multiplicative CONSTANTS (numeric literals + registered\n * named constants: ln2, 4π, …),\n * - product nesting (`(a·b)·c` vs `a·b·c`),\n * - commutative reordering of `*` / `+` operands.\n *\n * They hash DIFFERENT when an exponent differs (T⁴ ≠ T), the non-dimensionless\n * factor set differs, OR a dimensionless **stub** differs. A dimensionless\n * symbol that is NOT a recognized constant is a STUB for an unknown\n * dimensionless quantity (e.g. `ln⟨exp(−βW)⟩` in BE-29) — it is kept as a\n * distinct structural token, so Jarzynski's `ln⟨e^−βW⟩` and Landauer's `ln2`\n * no longer collapse to the same form (\"up to a *constant*\" must not absorb a\n * differing functional). Sums keep every term; `^` keeps its exponent; `/`\n * keeps the numerator/denominator split.\n *\n * @module canonical/normal-form\n */\nimport type { ExprNode } from '../dimensional/validator.js';\nimport type { Dimension } from '../dimensional/types.js';\nimport { equals } from '../dimensional/algebra.js';\nimport { DIMENSION_RENAMES, quantityIdForSpelling } from '../dimensional/formula-names.js';\nimport { CONSTANTS, piMultipleValue } from '../dimensional/symbolic-constants.js';\n\nconst isDimensionless = (d: Dimension): boolean =>\n d.L === 0 &&\n d.M === 0 &&\n d.T === 0 &&\n d.I === 0 &&\n d.Theta === 0 &&\n d.N === 0 &&\n d.J === 0;\n\n/** Token for a node that carries no structural content (a dimensionless factor). */\nconst UNIT = '1';\n\n/**\n * Spelled-out dimensionless numeric constants some encoders write as a named\n * symbol rather than a literal — genuine constants the eval `CONSTANTS`\n * registry does not list under that spelling (its own keys are the canonical\n * rows of the constant registry; `piMultipleValue` reads `pi`/`2pi`/`6pi`/…).\n * `ln_2_constant` is BE-16's spelling of `ln 2`. These stay droppable;\n * everything else dimensionless-and-named is a PARAMETER stub (`alpha`,\n * `lambda`, `g_dark`, `ln⟨e^−βW⟩`, …) and is kept.\n */\nconst NAMED_DIMENSIONLESS_CONSTANTS = new Set(['ln_2_constant']);\n\n/**\n * Bridge ASTs still spell a governing quantity with the short symbol (`T`, `M`,\n * `m_1`, `m_2`). The registry uses one name. The structural hash treats the\n * short spelling as that name when the dimension is the quantity's dimension,\n * so a time coordinate named `T` stays a different symbol.\n *\n * @internal\n */\nexport function canonicalQuantityName(name: string, dim: Dimension): string {\n for (const row of DIMENSION_RENAMES) {\n if (row.symbol === name && equals(dim, row.dimension)) return row.name;\n }\n return quantityIdForSpelling(name) ?? name;\n}\n\n/**\n * A dimensionless symbol is a droppable \"up to a constant\" factor only when it\n * is a numeric literal (`2`, `-1`, `0.5`), a registered named constant\n * (`ln2`, `4pi`, …), or a spelled-out numeric constant (`6pi`, `ln_2_constant`).\n * Any OTHER dimensionless symbol is a stub for an unknown dimensionless quantity\n * (a parameter or a functional like `ln⟨exp(−βW)⟩`) and is structural —\n * dropping it would conflate distinct interiors.\n */\nfunction isDroppableConstant(name: string): boolean {\n return (\n name in CONSTANTS ||\n Number.isFinite(Number(name)) ||\n NAMED_DIMENSIONLESS_CONSTANTS.has(name) ||\n piMultipleValue(name) !== undefined\n );\n}\n\n/**\n * Full structural serialization that NEVER drops dimensionless factors — used\n * for `^` exponents, which are structural (T⁴ ≠ T) and must not be treated\n * \"up to dimensionless factors\". Commutative operands are still sorted so the\n * exponent comparison is robust to reordering.\n */\nfunction rawForm(node: ExprNode): string {\n switch (node.kind) {\n case 'symbol':\n return `s:${node.name}`;\n case 'op': {\n const parts = node.args.map(rawForm);\n if (node.op === '*' || node.op === '+') parts.sort();\n return `${node.op}(${parts.join(',')})`;\n }\n case 'transcendental':\n return `${node.fn}[${rawForm(node.arg)}]`;\n case 'abs':\n return `abs[${rawForm(node.arg)}]`;\n default:\n return `${node.kind}:${JSON.stringify(node)}`;\n }\n}\n\n/** Collect the factors of a (possibly nested) `*` product. */\nfunction flattenProduct(node: ExprNode, out: ExprNode[]): void {\n if (node.kind === 'op' && node.op === '*') {\n for (const a of node.args) flattenProduct(a, out);\n } else {\n out.push(node);\n }\n}\n\n/**\n * The normalized structural form of `node`. Equal strings ⇒ same relation up to\n * dimensionless multiplicative factors.\n */\nexport function normalForm(node: ExprNode): string {\n switch (node.kind) {\n case 'symbol':\n // A non-dimensionless symbol is structural. A dimensionless symbol is a\n // droppable factor ONLY when it is a recognized constant; otherwise it is\n // a stub for an unknown dimensionless quantity and is kept (tagged) so two\n // different stubs do not collapse to the same form.\n if (!isDimensionless(node.dim)) return `sym:${canonicalQuantityName(node.name, node.dim)}`;\n return isDroppableConstant(node.name) ? UNIT : `stub:${node.name}`;\n\n case 'op': {\n switch (node.op) {\n case '*': {\n const factors: ExprNode[] = [];\n flattenProduct(node, factors);\n const kept = factors\n .map(normalForm)\n .filter((f) => f !== UNIT) // drop dimensionless factors\n .sort();\n if (kept.length === 0) return UNIT;\n if (kept.length === 1) return kept[0];\n return `*(${kept.join(',')})`;\n }\n case '/': {\n const num = normalForm(node.args[0]);\n const den = normalForm(node.args[1]);\n if (den === UNIT) return num; // ÷ dimensionless ⇒ the numerator\n return `/(${num},${den})`;\n }\n case '^': {\n // The exponent is structural (T⁴ ≠ T) and must NOT be reduced\n // \"up to dimensionless factors\" — serialize it with rawForm so a\n // dimensionless exponent is never dropped (symmetric for direct\n // symbols and op sub-expressions alike).\n const base = normalForm(node.args[0]);\n // A dimensionless constant to any power is still a dimensionless constant (π², √(2π)),\n // dropped as the constant is; the exponent is structural only on a dimensionful base.\n if (base === UNIT) return UNIT;\n return `^(${base},${rawForm(node.args[1])})`;\n }\n case '+':\n case '-': {\n const parts = node.args.map(normalForm);\n if (node.op === '+') parts.sort();\n return `${node.op}(${parts.join(',')})`;\n }\n default:\n return `op:${JSON.stringify(node)}`;\n }\n }\n\n case 'transcendental': {\n // ln(2) is the same dimensionless constant as the symbol `ln2`.\n const arg = normalForm(node.arg);\n if (arg === UNIT) return UNIT;\n return `${node.fn}(${arg})`;\n }\n\n case 'abs':\n return `abs(${normalForm(node.arg)})`;\n\n default:\n // integral / derivative / tensor arms: compare structurally by kind+shape.\n return `${node.kind}:${JSON.stringify(node)}`;\n }\n}\n\n/** Whether two scalar ASTs are the same relation up to dimensionless factors. */\nexport function structurallyEqual(a: ExprNode, b: ExprNode): boolean {\n return normalForm(a) === normalForm(b);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"normal-form.js","sourceRoot":"","sources":["../../src/canonical/normal-form.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Normalized structural form of a scalar `ExprNode`, **up to dimensionless\n * multiplicative factors** — the hash the F4 circularity guard uses to decide\n * whether a bridge's RHS and a canonical equation encode the same relation.\n *\n * Two expressions hash equal when they differ only by:\n * - dimensionless multiplicative CONSTANTS (numeric literals + registered\n * named constants: ln2, 4π, …),\n * - product nesting (`(a·b)·c` vs `a·b·c`),\n * - commutative reordering of `*` / `+` operands.\n *\n * They hash DIFFERENT when an exponent differs (T⁴ ≠ T), the non-dimensionless\n * factor set differs, OR a dimensionless **stub** differs. A dimensionless\n * symbol that is NOT a recognized constant is a STUB for an unknown\n * dimensionless quantity (e.g. `ln⟨exp(−βW)⟩` in BE-29) — it is kept as a\n * distinct structural token, so Jarzynski's `ln⟨e^−βW⟩` and Landauer's `ln2`\n * no longer collapse to the same form (\"up to a *constant*\" must not absorb a\n * differing functional). Sums keep every term; `^` keeps its exponent; `/`\n * keeps the numerator/denominator split.\n *\n * @module canonical/normal-form\n */\nimport type { ExprNode } from '../dimensional/validator.js';\nimport type { Dimension } from '../dimensional/types.js';\nimport { equals, isDimensionless } from '../dimensional/algebra.js';\nimport { DIMENSION_RENAMES, quantityIdForSpelling } from '../dimensional/formula-names.js';\nimport { isRegisteredConstant, piMultipleValue } from '../dimensional/symbolic-constants.js';\nimport { isDecimalLiteral } from '../dimensional/ast-leaves.js';\n\n/** Token for a node that carries no structural content (a dimensionless factor). */\nconst UNIT = '1';\n\n/**\n * Spelled-out dimensionless numeric constants some encoders write as a named\n * symbol rather than a literal — genuine constants the eval `CONSTANTS`\n * registry does not list under that spelling (its own keys are the canonical\n * rows of the constant registry; `piMultipleValue` reads `pi`/`2pi`/`6pi`/…).\n * `ln_2_constant` is BE-16's spelling of `ln 2`. These stay droppable;\n * everything else dimensionless-and-named is a PARAMETER stub (`alpha`,\n * `lambda`, `g_dark`, `ln⟨e^−βW⟩`, …) and is kept.\n */\nconst NAMED_DIMENSIONLESS_CONSTANTS = new Set(['ln_2_constant']);\n\n/**\n * Bridge ASTs still spell a governing quantity with the short symbol (`T`, `M`,\n * `m_1`, `m_2`). The registry uses one name. The structural hash treats the\n * short spelling as that name when the dimension is the quantity's dimension,\n * so a time coordinate named `T` stays a different symbol.\n *\n * @internal\n */\nexport function canonicalQuantityName(name: string, dim: Dimension): string {\n for (const row of DIMENSION_RENAMES) {\n if (row.symbol === name && equals(dim, row.dimension)) return row.name;\n }\n return quantityIdForSpelling(name) ?? name;\n}\n\n/**\n * A dimensionless symbol is a droppable \"up to a constant\" factor only when it\n * is a numeric literal (`2`, `-1`, `0.5`), a registered named constant\n * (`ln2`, `4pi`, …), or a spelled-out numeric constant (`6pi`, `ln_2_constant`).\n * Any OTHER dimensionless symbol is a stub for an unknown dimensionless quantity\n * (a parameter or a functional like `ln⟨exp(−βW)⟩`) and is structural —\n * dropping it would conflate distinct interiors.\n */\nfunction isDroppableConstant(name: string): boolean {\n return (\n isRegisteredConstant(name) ||\n isDecimalLiteral(name) ||\n NAMED_DIMENSIONLESS_CONSTANTS.has(name) ||\n piMultipleValue(name) !== undefined\n );\n}\n\n/**\n * Full structural serialization that NEVER drops dimensionless factors — used\n * for `^` exponents, which are structural (T⁴ ≠ T) and must not be treated\n * \"up to dimensionless factors\". Commutative operands are still sorted so the\n * exponent comparison is robust to reordering.\n */\nfunction rawForm(node: ExprNode): string {\n switch (node.kind) {\n case 'symbol':\n return `s:${node.name}`;\n case 'op': {\n const parts = node.args.map(rawForm);\n if (node.op === '*' || node.op === '+') parts.sort();\n return `${node.op}(${parts.join(',')})`;\n }\n case 'transcendental':\n return `${node.fn}[${rawForm(node.arg)}]`;\n case 'abs':\n return `abs[${rawForm(node.arg)}]`;\n default:\n return `${node.kind}:${JSON.stringify(node)}`;\n }\n}\n\n/** Collect the factors of a (possibly nested) `*` product. */\nfunction flattenProduct(node: ExprNode, out: ExprNode[]): void {\n if (node.kind === 'op' && node.op === '*') {\n for (const a of node.args) flattenProduct(a, out);\n } else {\n out.push(node);\n }\n}\n\n/**\n * The normalized structural form of `node`. Equal strings ⇒ same relation up to\n * dimensionless multiplicative factors.\n */\nexport function normalForm(node: ExprNode): string {\n switch (node.kind) {\n case 'symbol':\n // A non-dimensionless symbol is structural. A dimensionless symbol is a\n // droppable factor ONLY when it is a recognized constant; otherwise it is\n // a stub for an unknown dimensionless quantity and is kept (tagged) so two\n // different stubs do not collapse to the same form.\n if (!isDimensionless(node.dim)) return `sym:${canonicalQuantityName(node.name, node.dim)}`;\n return isDroppableConstant(node.name) ? UNIT : `stub:${node.name}`;\n\n case 'op': {\n switch (node.op) {\n case '*': {\n const factors: ExprNode[] = [];\n flattenProduct(node, factors);\n const kept = factors\n .map(normalForm)\n .filter((f) => f !== UNIT) // drop dimensionless factors\n .sort();\n if (kept.length === 0) return UNIT;\n if (kept.length === 1) return kept[0];\n return `*(${kept.join(',')})`;\n }\n case '/': {\n const num = normalForm(node.args[0]);\n const den = normalForm(node.args[1]);\n if (den === UNIT) return num; // ÷ dimensionless ⇒ the numerator\n return `/(${num},${den})`;\n }\n case '^': {\n // The exponent is structural (T⁴ ≠ T) and must NOT be reduced\n // \"up to dimensionless factors\" — serialize it with rawForm so a\n // dimensionless exponent is never dropped (symmetric for direct\n // symbols and op sub-expressions alike).\n const base = normalForm(node.args[0]);\n // A dimensionless constant to any power is still a dimensionless constant (π², √(2π)),\n // dropped as the constant is; the exponent is structural only on a dimensionful base.\n if (base === UNIT) return UNIT;\n return `^(${base},${rawForm(node.args[1])})`;\n }\n case '+':\n case '-': {\n const parts = node.args.map(normalForm);\n if (node.op === '+') parts.sort();\n return `${node.op}(${parts.join(',')})`;\n }\n default:\n return `op:${JSON.stringify(node)}`;\n }\n }\n\n case 'transcendental': {\n // ln(2) is the same dimensionless constant as the symbol `ln2`.\n const arg = normalForm(node.arg);\n if (arg === UNIT) return UNIT;\n return `${node.fn}(${arg})`;\n }\n\n case 'abs':\n return `abs(${normalForm(node.arg)})`;\n\n default:\n // integral / derivative / tensor arms: compare structurally by kind+shape.\n return `${node.kind}:${JSON.stringify(node)}`;\n }\n}\n\n/** Whether two scalar ASTs are the same relation up to dimensionless factors. */\nexport function structurallyEqual(a: ExprNode, b: ExprNode): boolean {\n return normalForm(a) === normalForm(b);\n}\n"]}
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Structural half of a bridge↔canonical comparison, shared with the chain
|
|
3
|
-
* pipeline. Same dimension, `normalForm`, and the F4 `restatesBridge` guard.
|
|
4
|
-
*
|
|
5
|
-
* This module does not import `composition/expr-eval.ts`. Numerical agreement
|
|
6
|
-
* is not a result here and is not a confirmation. `linkage.ts` calls
|
|
7
|
-
* {@link classifyStructure} and then runs its own numerical recovery.
|
|
8
|
-
*
|
|
9
|
-
* A chain whose normal form matches a catalog right-hand side the registry
|
|
10
|
-
* did not pre-declare confirms that catalog id. The call writes nothing.
|
|
11
|
-
* A chain that matches a canonical equation the registry pre-declared with
|
|
12
|
-
* `restatesBridge` is a restatement. Any other chain receives a provisional
|
|
13
|
-
* id, `chain-` followed by the ordered edge ids. That id is not a catalog
|
|
14
|
-
* id. It enters `BRIDGE_EQUATIONS` only after a vendored PhysJS proof, which
|
|
15
|
-
* this function does not record.
|
|
16
|
-
*
|
|
17
|
-
* @module canonical/structural
|
|
18
|
-
*/
|
|
19
1
|
import type { ExprNode } from '../dimensional/validator.js';
|
|
20
2
|
import type { Dimension } from '../dimensional/types.js';
|
|
21
3
|
/** One side of a structural comparison, plus the F4 inputs. @internal */
|
|
@@ -34,10 +16,25 @@ export interface StructuralPair {
|
|
|
34
16
|
/** The bridge id this comparison is against, as `restatesBridge` spells it. */
|
|
35
17
|
readonly bridgeId: string;
|
|
36
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* The algebraic-equivalence step a layer above may inject: on a normal-form
|
|
21
|
+
* miss with equal dimension, whether the two expressions are the same
|
|
22
|
+
* relation up to a dimensionless constant (`composition/algebraic-equivalence.ts`
|
|
23
|
+
* answers with MathTS `simplify`). This module stays below `composition/`, so
|
|
24
|
+
* it does not import the step; a caller that has it passes it.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export interface StructuralOptions {
|
|
29
|
+
readonly equivalent?: (left: ExprNode, right: ExprNode) => boolean;
|
|
30
|
+
}
|
|
37
31
|
/** Dimension, normal form, and the F4 guard. No numerical recovery. @internal */
|
|
38
32
|
export interface StructuralRelation {
|
|
39
33
|
readonly dimMatch: boolean;
|
|
34
|
+
/** The normal forms match, or the injected step found them equal up to a constant. */
|
|
40
35
|
readonly structuralMatch: boolean;
|
|
36
|
+
/** True only when the match came from the injected step, not from the hash. */
|
|
37
|
+
readonly algebraic: boolean;
|
|
41
38
|
/**
|
|
42
39
|
* True only when the normal forms match and `restatesBridge` names
|
|
43
40
|
* `bridgeId`. A structural match the registry did not pre-declare is
|
|
@@ -96,10 +93,13 @@ export declare function bridgeShapes(): ReadonlyMap<number, BridgeShape>;
|
|
|
96
93
|
*
|
|
97
94
|
* A {@link StructuralPair} returns the dimension, normal-form, and F4
|
|
98
95
|
* result `classifyLinkage` uses. An expression plus the chain's ordered
|
|
99
|
-
* edge ids returns the chain classification. Both calls are this function
|
|
96
|
+
* edge ids returns the chain classification. Both calls are this function,
|
|
97
|
+
* and both take the optional {@link StructuralOptions} whose `equivalent`
|
|
98
|
+
* runs on a normal-form miss with equal dimension; without it the hash is
|
|
99
|
+
* the whole decision.
|
|
100
100
|
*
|
|
101
101
|
* @internal
|
|
102
102
|
*/
|
|
103
|
-
export declare function classifyStructure(pair: StructuralPair): StructuralRelation;
|
|
104
|
-
export declare function classifyStructure(expr: ExprNode, edgeIds: readonly string[]): ChainClassification;
|
|
103
|
+
export declare function classifyStructure(pair: StructuralPair, opts?: StructuralOptions): StructuralRelation;
|
|
104
|
+
export declare function classifyStructure(expr: ExprNode, edgeIds: readonly string[], opts?: StructuralOptions): ChainClassification;
|
|
105
105
|
//# sourceMappingURL=structural.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../../src/canonical/structural.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../../src/canonical/structural.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAOzD,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC;CACpE;AAED,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,4CAA4C;AAC5C,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AA8B1F;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAID;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAU/D;AA+ED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;AACtG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,mBAAmB,CAAC"}
|
|
@@ -1,24 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural half of a bridge↔canonical comparison, shared with the chain
|
|
3
|
+
* pipeline. Same dimension, `normalForm`, and the F4 `restatesBridge` guard.
|
|
4
|
+
*
|
|
5
|
+
* This module does not import `composition/expr-eval.ts`. Numerical agreement
|
|
6
|
+
* is not a result here and is not a confirmation. `linkage.ts` calls
|
|
7
|
+
* {@link classifyStructure} and then runs its own numerical recovery.
|
|
8
|
+
*
|
|
9
|
+
* A chain whose normal form matches a catalog right-hand side the registry
|
|
10
|
+
* did not pre-declare confirms that catalog id. The call writes nothing.
|
|
11
|
+
* A chain that matches a canonical equation the registry pre-declared with
|
|
12
|
+
* `restatesBridge` is a restatement. Any other chain receives a provisional
|
|
13
|
+
* id, `chain-` followed by the ordered edge ids. That id is not a catalog
|
|
14
|
+
* id. It enters `BRIDGE_EQUATIONS` only after a Lean proof in `lean/`, which
|
|
15
|
+
* this function does not record.
|
|
16
|
+
*
|
|
17
|
+
* @module canonical/structural
|
|
18
|
+
*/
|
|
19
|
+
import { compareCodepoint } from '../core/compare.js';
|
|
20
|
+
import { exactlyEquals } from '../dimensional/algebra.js';
|
|
1
21
|
import { validate } from '../dimensional/validator.js';
|
|
2
22
|
import { BRIDGE_RHS_BY_ID } from '../bridges/rhs-registry.js';
|
|
3
23
|
import { CANONICAL_EQUATIONS } from './registry.js';
|
|
4
24
|
import { normalForm } from './normal-form.js';
|
|
5
|
-
const dimEqual = (a, b) => a.L === b.L &&
|
|
6
|
-
a.M === b.M &&
|
|
7
|
-
a.T === b.T &&
|
|
8
|
-
a.I === b.I &&
|
|
9
|
-
a.Theta === b.Theta &&
|
|
10
|
-
a.N === b.N &&
|
|
11
|
-
a.J === b.J;
|
|
12
25
|
function isStructuralPair(value) {
|
|
13
26
|
return !('kind' in value) && 'bridgeId' in value;
|
|
14
27
|
}
|
|
15
|
-
function comparePair(pair) {
|
|
28
|
+
function comparePair(pair, opts = {}) {
|
|
16
29
|
const leftNormal = pair.leftNormal ?? normalForm(pair.left);
|
|
17
30
|
const rightNormal = pair.rightNormal ?? normalForm(pair.right);
|
|
18
|
-
const
|
|
31
|
+
const dimMatch = pair.rightDim != null && exactlyEquals(pair.rightDim, pair.leftDim);
|
|
32
|
+
const hashMatch = leftNormal === rightNormal;
|
|
33
|
+
// The hash is the cheap key; the step runs only on a miss, and only when the
|
|
34
|
+
// dimensions agree (a different dimension is a different relation).
|
|
35
|
+
const algebraic = !hashMatch && dimMatch && opts.equivalent !== undefined && opts.equivalent(pair.left, pair.right);
|
|
36
|
+
const structuralMatch = hashMatch || algebraic;
|
|
19
37
|
return {
|
|
20
|
-
dimMatch
|
|
38
|
+
dimMatch,
|
|
21
39
|
structuralMatch,
|
|
40
|
+
algebraic,
|
|
22
41
|
restates: structuralMatch &&
|
|
23
42
|
pair.restatesBridge !== undefined &&
|
|
24
43
|
pair.restatesBridge === pair.bridgeId,
|
|
@@ -54,7 +73,7 @@ export function bridgeShapes() {
|
|
|
54
73
|
function provisionalChainId(edgeIds) {
|
|
55
74
|
return `chain-${edgeIds.join('-')}`;
|
|
56
75
|
}
|
|
57
|
-
function classifyChain(expr, edgeIds) {
|
|
76
|
+
function classifyChain(expr, edgeIds, opts) {
|
|
58
77
|
const ordered = [...edgeIds];
|
|
59
78
|
const validated = validate(expr);
|
|
60
79
|
const leftDim = validated.ok ? validated.inferredDimension : null;
|
|
@@ -74,7 +93,7 @@ function classifyChain(expr, edgeIds) {
|
|
|
74
93
|
rightDim: ce.dimensional.target.dim,
|
|
75
94
|
restatesBridge: ce.restatesBridge,
|
|
76
95
|
bridgeId: ce.restatesBridge,
|
|
77
|
-
});
|
|
96
|
+
}, opts);
|
|
78
97
|
if (relation.restates && relation.dimMatch) {
|
|
79
98
|
restatements.push({ canonicalId: ce.id, restatesBridge: ce.restatesBridge });
|
|
80
99
|
}
|
|
@@ -83,7 +102,7 @@ function classifyChain(expr, edgeIds) {
|
|
|
83
102
|
const byBridge = bridgeRank(a.restatesBridge) - bridgeRank(b.restatesBridge);
|
|
84
103
|
if (byBridge !== 0)
|
|
85
104
|
return byBridge;
|
|
86
|
-
return a.canonicalId
|
|
105
|
+
return compareCodepoint(a.canonicalId, b.canonicalId);
|
|
87
106
|
});
|
|
88
107
|
const restatement = restatements[0];
|
|
89
108
|
if (restatement !== undefined) {
|
|
@@ -105,7 +124,7 @@ function classifyChain(expr, edgeIds) {
|
|
|
105
124
|
rightNormal: bridge.normal,
|
|
106
125
|
restatesBridge: undefined,
|
|
107
126
|
bridgeId: String(id),
|
|
108
|
-
});
|
|
127
|
+
}, opts);
|
|
109
128
|
if (relation.structuralMatch && relation.dimMatch)
|
|
110
129
|
confirmations.push(id);
|
|
111
130
|
}
|
|
@@ -116,12 +135,14 @@ function classifyChain(expr, edgeIds) {
|
|
|
116
135
|
}
|
|
117
136
|
return { kind: 'provisional', id: provisionalChainId(ordered), edgeIds: ordered };
|
|
118
137
|
}
|
|
119
|
-
export function classifyStructure(exprOrPair,
|
|
120
|
-
if (isStructuralPair(exprOrPair))
|
|
121
|
-
|
|
122
|
-
|
|
138
|
+
export function classifyStructure(exprOrPair, edgeIdsOrOpts, opts = {}) {
|
|
139
|
+
if (isStructuralPair(exprOrPair)) {
|
|
140
|
+
const pairOpts = edgeIdsOrOpts !== undefined && !Array.isArray(edgeIdsOrOpts) ? edgeIdsOrOpts : {};
|
|
141
|
+
return comparePair(exprOrPair, pairOpts);
|
|
142
|
+
}
|
|
143
|
+
if (edgeIdsOrOpts === undefined || !Array.isArray(edgeIdsOrOpts)) {
|
|
123
144
|
throw new TypeError('classifyStructure: a chain needs its ordered edge ids');
|
|
124
145
|
}
|
|
125
|
-
return classifyChain(exprOrPair,
|
|
146
|
+
return classifyChain(exprOrPair, edgeIdsOrOpts, opts);
|
|
126
147
|
}
|
|
127
148
|
//# sourceMappingURL=structural.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structural.js","sourceRoot":"","sources":["../../src/canonical/structural.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Structural half of a bridge↔canonical comparison, shared with the chain\n * pipeline. Same dimension, `normalForm`, and the F4 `restatesBridge` guard.\n *\n * This module does not import `composition/expr-eval.ts`. Numerical agreement\n * is not a result here and is not a confirmation. `linkage.ts` calls\n * {@link classifyStructure} and then runs its own numerical recovery.\n *\n * A chain whose normal form matches a catalog right-hand side the registry\n * did not pre-declare confirms that catalog id. The call writes nothing.\n * A chain that matches a canonical equation the registry pre-declared with\n * `restatesBridge` is a restatement. Any other chain receives a provisional\n * id, `chain-` followed by the ordered edge ids. That id is not a catalog\n * id. It enters `BRIDGE_EQUATIONS` only after a vendored PhysJS proof, which\n * this function does not record.\n *\n * @module canonical/structural\n */\nimport type { ExprNode } from '../dimensional/validator.js';\nimport type { Dimension } from '../dimensional/types.js';\nimport { validate } from '../dimensional/validator.js';\nimport { BRIDGE_RHS_BY_ID } from '../bridges/rhs-registry.js';\nimport { CANONICAL_EQUATIONS } from './registry.js';\nimport { normalForm } from './normal-form.js';\n\n/** One side of a structural comparison, plus the F4 inputs. @internal */\nexport interface StructuralPair {\n readonly left: ExprNode;\n readonly leftDim: Dimension;\n /** Precomputed `normalForm(left)`. Computed here when omitted. */\n readonly leftNormal?: string;\n readonly right: ExprNode;\n /** Inferred dimension of `right`, or null when validation failed. */\n readonly rightDim: Dimension | null;\n /** Precomputed `normalForm(right)`. Computed here when omitted. */\n readonly rightNormal?: string;\n /** The canonical entry's `restatesBridge`, when it has one. */\n readonly restatesBridge: string | undefined;\n /** The bridge id this comparison is against, as `restatesBridge` spells it. */\n readonly bridgeId: string;\n}\n\n/** Dimension, normal form, and the F4 guard. No numerical recovery. @internal */\nexport interface StructuralRelation {\n readonly dimMatch: boolean;\n readonly structuralMatch: boolean;\n /**\n * True only when the normal forms match and `restatesBridge` names\n * `bridgeId`. A structural match the registry did not pre-declare is\n * not a restatement.\n */\n readonly restates: boolean;\n}\n\n/** A chain matched an existing catalog equation. Nothing was written. @internal */\nexport interface ChainConfirmation {\n readonly kind: 'confirmation';\n readonly catalogId: number;\n readonly edgeIds: readonly string[];\n}\n\n/** A chain matches a canonical equation the registry pre-declared. @internal */\nexport interface ChainRestatement {\n readonly kind: 'restatement';\n readonly canonicalId: string;\n readonly restatesBridge: string;\n readonly edgeIds: readonly string[];\n}\n\n/**\n * A chain that is neither a catalog confirmation nor a pre-declared\n * restatement. `id` is `chain-` plus the edge ids in chain order.\n * @internal\n */\nexport interface ChainProvisional {\n readonly kind: 'provisional';\n readonly id: string;\n readonly edgeIds: readonly string[];\n}\n\n/** Decision (a) for one chain. @internal */\nexport type ChainClassification = ChainConfirmation | ChainRestatement | ChainProvisional;\n\nconst dimEqual = (a: Dimension, b: Dimension): boolean =>\n a.L === b.L &&\n a.M === b.M &&\n a.T === b.T &&\n a.I === b.I &&\n a.Theta === b.Theta &&\n a.N === b.N &&\n a.J === b.J;\n\nfunction isStructuralPair(value: ExprNode | StructuralPair): value is StructuralPair {\n return !('kind' in value) && 'bridgeId' in value;\n}\n\nfunction comparePair(pair: StructuralPair): StructuralRelation {\n const leftNormal = pair.leftNormal ?? normalForm(pair.left);\n const rightNormal = pair.rightNormal ?? normalForm(pair.right);\n const structuralMatch = leftNormal === rightNormal;\n return {\n dimMatch: pair.rightDim != null && dimEqual(pair.rightDim, pair.leftDim),\n structuralMatch,\n restates:\n structuralMatch &&\n pair.restatesBridge !== undefined &&\n pair.restatesBridge === pair.bridgeId,\n };\n}\n\nfunction bridgeRank(id: string): number {\n return /^\\d+$/.test(id) ? Number(id) : Number.POSITIVE_INFINITY;\n}\n\n/**\n * A bridge RHS reduced to its comparison-ready, canonical-invariant form: its\n * validated dimension (`null` when validation failed) and its normal-form\n * hash. Both depend only on the bridge.\n *\n * @internal\n */\nexport interface BridgeShape {\n readonly rhs: ExprNode;\n readonly dim: Dimension | null;\n readonly normal: string;\n}\n\nlet bridgeShapeTable: ReadonlyMap<number, BridgeShape> | undefined;\n\n/**\n * Every bridge RHS, validated and normal-formed ONCE for the process.\n * `BRIDGE_RHS_BY_ID` is static, so the table is computed on first use and\n * kept; a chain classification and a linkage scan both read it instead of\n * re-validating every entry per call (9.0.0 audit §4 Low).\n *\n * @internal\n */\nexport function bridgeShapes(): ReadonlyMap<number, BridgeShape> {\n if (bridgeShapeTable === undefined) {\n const table = new Map<number, BridgeShape>();\n for (const [id, rhs] of BRIDGE_RHS_BY_ID) {\n const v = validate(rhs);\n table.set(id, { rhs, dim: v.ok ? v.inferredDimension : null, normal: normalForm(rhs) });\n }\n bridgeShapeTable = table;\n }\n return bridgeShapeTable;\n}\n\n/**\n * Provisional id for a chain. The edge ids stay in the order the caller\n * passed, which is the chain order. They are not sorted.\n */\nfunction provisionalChainId(edgeIds: readonly string[]): string {\n return `chain-${edgeIds.join('-')}`;\n}\n\nfunction classifyChain(expr: ExprNode, edgeIds: readonly string[]): ChainClassification {\n const ordered = [...edgeIds];\n const validated = validate(expr);\n const leftDim = validated.ok ? validated.inferredDimension : null;\n if (leftDim == null) {\n return { kind: 'provisional', id: provisionalChainId(ordered), edgeIds: ordered };\n }\n const leftNormal = normalForm(expr);\n\n const restatements: { canonicalId: string; restatesBridge: string }[] = [];\n for (const ce of CANONICAL_EQUATIONS) {\n if (ce.scalarAst === undefined || ce.restatesBridge === undefined) continue;\n const relation = comparePair({\n left: expr,\n leftDim,\n leftNormal,\n right: ce.scalarAst,\n rightDim: ce.dimensional.target.dim,\n restatesBridge: ce.restatesBridge,\n bridgeId: ce.restatesBridge,\n });\n if (relation.restates && relation.dimMatch) {\n restatements.push({ canonicalId: ce.id, restatesBridge: ce.restatesBridge });\n }\n }\n restatements.sort((a, b) => {\n const byBridge = bridgeRank(a.restatesBridge) - bridgeRank(b.restatesBridge);\n if (byBridge !== 0) return byBridge;\n return a.canonicalId < b.canonicalId ? -1 : a.canonicalId > b.canonicalId ? 1 : 0;\n });\n const restatement = restatements[0];\n if (restatement !== undefined) {\n return {\n kind: 'restatement',\n canonicalId: restatement.canonicalId,\n restatesBridge: restatement.restatesBridge,\n edgeIds: ordered,\n };\n }\n\n const confirmations: number[] = [];\n for (const [id, bridge] of bridgeShapes()) {\n const relation = comparePair({\n left: expr,\n leftDim,\n leftNormal,\n right: bridge.rhs,\n rightDim: bridge.dim,\n rightNormal: bridge.normal,\n restatesBridge: undefined,\n bridgeId: String(id),\n });\n if (relation.structuralMatch && relation.dimMatch) confirmations.push(id);\n }\n confirmations.sort((a, b) => a - b);\n const catalogId = confirmations[0];\n if (catalogId !== undefined) {\n return { kind: 'confirmation', catalogId, edgeIds: ordered };\n }\n\n return { kind: 'provisional', id: provisionalChainId(ordered), edgeIds: ordered };\n}\n\n/**\n * The structural classifier.\n *\n * A {@link StructuralPair} returns the dimension, normal-form, and F4\n * result `classifyLinkage` uses. An expression plus the chain's ordered\n * edge ids returns the chain classification. Both calls are this function.\n *\n * @internal\n */\nexport function classifyStructure(pair: StructuralPair): StructuralRelation;\nexport function classifyStructure(expr: ExprNode, edgeIds: readonly string[]): ChainClassification;\nexport function classifyStructure(\n exprOrPair: ExprNode | StructuralPair,\n edgeIds?: readonly string[],\n): StructuralRelation | ChainClassification {\n if (isStructuralPair(exprOrPair)) return comparePair(exprOrPair);\n if (edgeIds === undefined) {\n throw new TypeError('classifyStructure: a chain needs its ordered edge ids');\n }\n return classifyChain(exprOrPair, edgeIds);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"structural.js","sourceRoot":"","sources":["../../src/canonical/structural.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Structural half of a bridge↔canonical comparison, shared with the chain\n * pipeline. Same dimension, `normalForm`, and the F4 `restatesBridge` guard.\n *\n * This module does not import `composition/expr-eval.ts`. Numerical agreement\n * is not a result here and is not a confirmation. `linkage.ts` calls\n * {@link classifyStructure} and then runs its own numerical recovery.\n *\n * A chain whose normal form matches a catalog right-hand side the registry\n * did not pre-declare confirms that catalog id. The call writes nothing.\n * A chain that matches a canonical equation the registry pre-declared with\n * `restatesBridge` is a restatement. Any other chain receives a provisional\n * id, `chain-` followed by the ordered edge ids. That id is not a catalog\n * id. It enters `BRIDGE_EQUATIONS` only after a Lean proof in `lean/`, which\n * this function does not record.\n *\n * @module canonical/structural\n */\nimport { compareCodepoint } from '../core/compare.js';\nimport type { ExprNode } from '../dimensional/validator.js';\nimport type { Dimension } from '../dimensional/types.js';\nimport { exactlyEquals } from '../dimensional/algebra.js';\nimport { validate } from '../dimensional/validator.js';\nimport { BRIDGE_RHS_BY_ID } from '../bridges/rhs-registry.js';\nimport { CANONICAL_EQUATIONS } from './registry.js';\nimport { normalForm } from './normal-form.js';\n\n/** One side of a structural comparison, plus the F4 inputs. @internal */\nexport interface StructuralPair {\n readonly left: ExprNode;\n readonly leftDim: Dimension;\n /** Precomputed `normalForm(left)`. Computed here when omitted. */\n readonly leftNormal?: string;\n readonly right: ExprNode;\n /** Inferred dimension of `right`, or null when validation failed. */\n readonly rightDim: Dimension | null;\n /** Precomputed `normalForm(right)`. Computed here when omitted. */\n readonly rightNormal?: string;\n /** The canonical entry's `restatesBridge`, when it has one. */\n readonly restatesBridge: string | undefined;\n /** The bridge id this comparison is against, as `restatesBridge` spells it. */\n readonly bridgeId: string;\n}\n\n/**\n * The algebraic-equivalence step a layer above may inject: on a normal-form\n * miss with equal dimension, whether the two expressions are the same\n * relation up to a dimensionless constant (`composition/algebraic-equivalence.ts`\n * answers with MathTS `simplify`). This module stays below `composition/`, so\n * it does not import the step; a caller that has it passes it.\n *\n * @internal\n */\nexport interface StructuralOptions {\n readonly equivalent?: (left: ExprNode, right: ExprNode) => boolean;\n}\n\n/** Dimension, normal form, and the F4 guard. No numerical recovery. @internal */\nexport interface StructuralRelation {\n readonly dimMatch: boolean;\n /** The normal forms match, or the injected step found them equal up to a constant. */\n readonly structuralMatch: boolean;\n /** True only when the match came from the injected step, not from the hash. */\n readonly algebraic: boolean;\n /**\n * True only when the normal forms match and `restatesBridge` names\n * `bridgeId`. A structural match the registry did not pre-declare is\n * not a restatement.\n */\n readonly restates: boolean;\n}\n\n/** A chain matched an existing catalog equation. Nothing was written. @internal */\nexport interface ChainConfirmation {\n readonly kind: 'confirmation';\n readonly catalogId: number;\n readonly edgeIds: readonly string[];\n}\n\n/** A chain matches a canonical equation the registry pre-declared. @internal */\nexport interface ChainRestatement {\n readonly kind: 'restatement';\n readonly canonicalId: string;\n readonly restatesBridge: string;\n readonly edgeIds: readonly string[];\n}\n\n/**\n * A chain that is neither a catalog confirmation nor a pre-declared\n * restatement. `id` is `chain-` plus the edge ids in chain order.\n * @internal\n */\nexport interface ChainProvisional {\n readonly kind: 'provisional';\n readonly id: string;\n readonly edgeIds: readonly string[];\n}\n\n/** Decision (a) for one chain. @internal */\nexport type ChainClassification = ChainConfirmation | ChainRestatement | ChainProvisional;\n\nfunction isStructuralPair(value: ExprNode | StructuralPair): value is StructuralPair {\n return !('kind' in value) && 'bridgeId' in value;\n}\n\nfunction comparePair(pair: StructuralPair, opts: StructuralOptions = {}): StructuralRelation {\n const leftNormal = pair.leftNormal ?? normalForm(pair.left);\n const rightNormal = pair.rightNormal ?? normalForm(pair.right);\n const dimMatch = pair.rightDim != null && exactlyEquals(pair.rightDim, pair.leftDim);\n const hashMatch = leftNormal === rightNormal;\n // The hash is the cheap key; the step runs only on a miss, and only when the\n // dimensions agree (a different dimension is a different relation).\n const algebraic = !hashMatch && dimMatch && opts.equivalent !== undefined && opts.equivalent(pair.left, pair.right);\n const structuralMatch = hashMatch || algebraic;\n return {\n dimMatch,\n structuralMatch,\n algebraic,\n restates:\n structuralMatch &&\n pair.restatesBridge !== undefined &&\n pair.restatesBridge === pair.bridgeId,\n };\n}\n\nfunction bridgeRank(id: string): number {\n return /^\\d+$/.test(id) ? Number(id) : Number.POSITIVE_INFINITY;\n}\n\n/**\n * A bridge RHS reduced to its comparison-ready, canonical-invariant form: its\n * validated dimension (`null` when validation failed) and its normal-form\n * hash. Both depend only on the bridge.\n *\n * @internal\n */\nexport interface BridgeShape {\n readonly rhs: ExprNode;\n readonly dim: Dimension | null;\n readonly normal: string;\n}\n\nlet bridgeShapeTable: ReadonlyMap<number, BridgeShape> | undefined;\n\n/**\n * Every bridge RHS, validated and normal-formed ONCE for the process.\n * `BRIDGE_RHS_BY_ID` is static, so the table is computed on first use and\n * kept; a chain classification and a linkage scan both read it instead of\n * re-validating every entry per call (9.0.0 audit §4 Low).\n *\n * @internal\n */\nexport function bridgeShapes(): ReadonlyMap<number, BridgeShape> {\n if (bridgeShapeTable === undefined) {\n const table = new Map<number, BridgeShape>();\n for (const [id, rhs] of BRIDGE_RHS_BY_ID) {\n const v = validate(rhs);\n table.set(id, { rhs, dim: v.ok ? v.inferredDimension : null, normal: normalForm(rhs) });\n }\n bridgeShapeTable = table;\n }\n return bridgeShapeTable;\n}\n\n/**\n * Provisional id for a chain. The edge ids stay in the order the caller\n * passed, which is the chain order. They are not sorted.\n */\nfunction provisionalChainId(edgeIds: readonly string[]): string {\n return `chain-${edgeIds.join('-')}`;\n}\n\nfunction classifyChain(expr: ExprNode, edgeIds: readonly string[], opts: StructuralOptions): ChainClassification {\n const ordered = [...edgeIds];\n const validated = validate(expr);\n const leftDim = validated.ok ? validated.inferredDimension : null;\n if (leftDim == null) {\n return { kind: 'provisional', id: provisionalChainId(ordered), edgeIds: ordered };\n }\n const leftNormal = normalForm(expr);\n\n const restatements: { canonicalId: string; restatesBridge: string }[] = [];\n for (const ce of CANONICAL_EQUATIONS) {\n if (ce.scalarAst === undefined || ce.restatesBridge === undefined) continue;\n const relation = comparePair(\n {\n left: expr,\n leftDim,\n leftNormal,\n right: ce.scalarAst,\n rightDim: ce.dimensional.target.dim,\n restatesBridge: ce.restatesBridge,\n bridgeId: ce.restatesBridge,\n },\n opts,\n );\n if (relation.restates && relation.dimMatch) {\n restatements.push({ canonicalId: ce.id, restatesBridge: ce.restatesBridge });\n }\n }\n restatements.sort((a, b) => {\n const byBridge = bridgeRank(a.restatesBridge) - bridgeRank(b.restatesBridge);\n if (byBridge !== 0) return byBridge;\n return compareCodepoint(a.canonicalId, b.canonicalId);\n });\n const restatement = restatements[0];\n if (restatement !== undefined) {\n return {\n kind: 'restatement',\n canonicalId: restatement.canonicalId,\n restatesBridge: restatement.restatesBridge,\n edgeIds: ordered,\n };\n }\n\n const confirmations: number[] = [];\n for (const [id, bridge] of bridgeShapes()) {\n const relation = comparePair(\n {\n left: expr,\n leftDim,\n leftNormal,\n right: bridge.rhs,\n rightDim: bridge.dim,\n rightNormal: bridge.normal,\n restatesBridge: undefined,\n bridgeId: String(id),\n },\n opts,\n );\n if (relation.structuralMatch && relation.dimMatch) confirmations.push(id);\n }\n confirmations.sort((a, b) => a - b);\n const catalogId = confirmations[0];\n if (catalogId !== undefined) {\n return { kind: 'confirmation', catalogId, edgeIds: ordered };\n }\n\n return { kind: 'provisional', id: provisionalChainId(ordered), edgeIds: ordered };\n}\n\n/**\n * The structural classifier.\n *\n * A {@link StructuralPair} returns the dimension, normal-form, and F4\n * result `classifyLinkage` uses. An expression plus the chain's ordered\n * edge ids returns the chain classification. Both calls are this function,\n * and both take the optional {@link StructuralOptions} whose `equivalent`\n * runs on a normal-form miss with equal dimension; without it the hash is\n * the whole decision.\n *\n * @internal\n */\nexport function classifyStructure(pair: StructuralPair, opts?: StructuralOptions): StructuralRelation;\nexport function classifyStructure(expr: ExprNode, edgeIds: readonly string[], opts?: StructuralOptions): ChainClassification;\nexport function classifyStructure(\n exprOrPair: ExprNode | StructuralPair,\n edgeIdsOrOpts?: readonly string[] | StructuralOptions,\n opts: StructuralOptions = {},\n): StructuralRelation | ChainClassification {\n if (isStructuralPair(exprOrPair)) {\n const pairOpts = edgeIdsOrOpts !== undefined && !Array.isArray(edgeIdsOrOpts) ? (edgeIdsOrOpts as StructuralOptions) : {};\n return comparePair(exprOrPair, pairOpts);\n }\n if (edgeIdsOrOpts === undefined || !Array.isArray(edgeIdsOrOpts)) {\n throw new TypeError('classifyStructure: a chain needs its ordered edge ids');\n }\n return classifyChain(exprOrPair, edgeIdsOrOpts as readonly string[], opts);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check records (expr + bound) for the applied-case catalog. Declarative prose lives
|
|
3
|
+
* in `data/applied-cases.json`; thresholds stay here beside the expr the engine reads.
|
|
4
|
+
*
|
|
5
|
+
* @module cases/catalog-checks
|
|
6
|
+
*/
|
|
7
|
+
import type { AppliedCaseCheckRecord } from './catalog.js';
|
|
8
|
+
/** Check records keyed by applied-case id. */
|
|
9
|
+
export declare const CHECKS_BY_CASE_ID: Readonly<Record<string, readonly AppliedCaseCheckRecord[]>>;
|
|
10
|
+
//# sourceMappingURL=catalog-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-checks.d.ts","sourceRoot":"","sources":["../../src/cases/catalog-checks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE3D,8CAA8C;AAC9C,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,sBAAsB,EAAE,CAAC,CAyPzF,CAAC"}
|