universal-physics-tensor 10.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/bin/upt.mjs +13 -1
- package/data/atlas/atlas.json +25 -25
- package/data/atlas/atlas.jsonld +1 -1
- package/data/atlas/diffusion.json +6 -6
- package/data/atlas/oscillators.json +7 -7
- package/data/atlas/waves.json +14 -14
- package/data/atlas/witness-results.json +11 -11
- package/data/bridge-catalog.json +371 -228
- package/data/bridge-catalog.schema.json +45 -7
- package/dist/atlas/applicability.d.ts.map +1 -1
- package/dist/atlas/applicability.js +21 -15
- package/dist/atlas/applicability.js.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts +9 -1
- package/dist/atlas/benchmark/hybrid-retrieval.d.ts.map +1 -1
- package/dist/atlas/benchmark/hybrid-retrieval.js +15 -13
- package/dist/atlas/benchmark/hybrid-retrieval.js.map +1 -1
- package/dist/atlas/benchmark/loader.js +2 -2
- package/dist/atlas/benchmark/loader.js.map +1 -1
- package/dist/atlas/benchmark/stats.d.ts +2 -2
- package/dist/atlas/benchmark/stats.d.ts.map +1 -1
- package/dist/atlas/benchmark/stats.js +15 -7
- package/dist/atlas/benchmark/stats.js.map +1 -1
- package/dist/atlas/catalog-formal-ref.d.ts +26 -3
- package/dist/atlas/catalog-formal-ref.d.ts.map +1 -1
- package/dist/atlas/catalog-formal-ref.js +52 -5
- package/dist/atlas/catalog-formal-ref.js.map +1 -1
- package/dist/atlas/chain-pipeline.d.ts.map +1 -1
- package/dist/atlas/chain-pipeline.js +7 -8
- package/dist/atlas/chain-pipeline.js.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.d.ts +0 -4
- package/dist/atlas/diffusion/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges-closure.js +8 -12
- package/dist/atlas/diffusion/bridges-closure.js.map +1 -1
- package/dist/atlas/diffusion/bridges.d.ts.map +1 -1
- package/dist/atlas/diffusion/bridges.js +27 -39
- package/dist/atlas/diffusion/bridges.js.map +1 -1
- package/dist/atlas/diffusion/dimensions.d.ts +6 -14
- package/dist/atlas/diffusion/dimensions.d.ts.map +1 -1
- package/dist/atlas/diffusion/dimensions.js +8 -16
- package/dist/atlas/diffusion/dimensions.js.map +1 -1
- package/dist/atlas/diffusion/models.d.ts +3 -3
- package/dist/atlas/diffusion/models.d.ts.map +1 -1
- package/dist/atlas/diffusion/models.js +5 -10
- package/dist/atlas/diffusion/models.js.map +1 -1
- package/dist/atlas/diffusion/numerics.d.ts +16 -4
- package/dist/atlas/diffusion/numerics.d.ts.map +1 -1
- package/dist/atlas/diffusion/numerics.js +38 -24
- package/dist/atlas/diffusion/numerics.js.map +1 -1
- package/dist/atlas/link-prediction.d.ts +106 -3
- package/dist/atlas/link-prediction.d.ts.map +1 -1
- package/dist/atlas/link-prediction.js +212 -66
- package/dist/atlas/link-prediction.js.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-coarse.js +7 -11
- package/dist/atlas/oscillators/bridges-coarse.js.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-exact.js +6 -7
- package/dist/atlas/oscillators/bridges-exact.js.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.d.ts +3 -16
- package/dist/atlas/oscillators/bridges-limits.d.ts.map +1 -1
- package/dist/atlas/oscillators/bridges-limits.js +23 -34
- package/dist/atlas/oscillators/bridges-limits.js.map +1 -1
- package/dist/atlas/oscillators/dimensions.d.ts +9 -21
- package/dist/atlas/oscillators/dimensions.d.ts.map +1 -1
- package/dist/atlas/oscillators/dimensions.js +9 -21
- package/dist/atlas/oscillators/dimensions.js.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.d.ts +2 -2
- package/dist/atlas/oscillators/limit-witnesses.d.ts.map +1 -1
- package/dist/atlas/oscillators/limit-witnesses.js +17 -15
- package/dist/atlas/oscillators/limit-witnesses.js.map +1 -1
- package/dist/atlas/oscillators/models.d.ts.map +1 -1
- package/dist/atlas/oscillators/models.js +2 -6
- package/dist/atlas/oscillators/models.js.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.d.ts +29 -6
- package/dist/atlas/oscillators/pendulum-motion.d.ts.map +1 -1
- package/dist/atlas/oscillators/pendulum-motion.js +60 -40
- package/dist/atlas/oscillators/pendulum-motion.js.map +1 -1
- package/dist/atlas/oscillators/phase-translation.d.ts +0 -11
- package/dist/atlas/oscillators/phase-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/phase-translation.js +3 -4
- package/dist/atlas/oscillators/phase-translation.js.map +1 -1
- package/dist/atlas/oscillators/position-translation.d.ts +68 -7
- package/dist/atlas/oscillators/position-translation.d.ts.map +1 -1
- package/dist/atlas/oscillators/position-translation.js +123 -12
- package/dist/atlas/oscillators/position-translation.js.map +1 -1
- package/dist/atlas/oscillators/rejections.d.ts +0 -2
- package/dist/atlas/oscillators/rejections.d.ts.map +1 -1
- package/dist/atlas/oscillators/rejections.js +0 -7
- package/dist/atlas/oscillators/rejections.js.map +1 -1
- package/dist/atlas/physjs-entries.generated.d.ts +25 -24
- package/dist/atlas/physjs-entries.generated.d.ts.map +1 -1
- package/dist/atlas/physjs-entries.generated.js +25 -24
- package/dist/atlas/physjs-entries.generated.js.map +1 -1
- package/dist/atlas/physjs-ref.d.ts +34 -31
- package/dist/atlas/physjs-ref.d.ts.map +1 -1
- package/dist/atlas/physjs-ref.js +55 -53
- package/dist/atlas/physjs-ref.js.map +1 -1
- package/dist/atlas/physjs-reviewed.d.ts +1 -1
- package/dist/atlas/physjs-reviewed.js +15 -15
- package/dist/atlas/physjs-reviewed.js.map +1 -1
- package/dist/atlas/poster/statements.d.ts +0 -19
- package/dist/atlas/poster/statements.d.ts.map +1 -1
- package/dist/atlas/poster/statements.js +1 -1
- package/dist/atlas/poster/statements.js.map +1 -1
- package/dist/atlas/proof-target.d.ts +1 -1
- package/dist/atlas/proof-target.js +1 -1
- package/dist/atlas/proof-target.js.map +1 -1
- package/dist/atlas/regime.d.ts +1 -1
- package/dist/atlas/regime.d.ts.map +1 -1
- package/dist/atlas/regime.js +1 -1
- package/dist/atlas/regime.js.map +1 -1
- package/dist/atlas/text-overlap.d.ts +23 -0
- package/dist/atlas/text-overlap.d.ts.map +1 -0
- package/dist/atlas/text-overlap.js +41 -0
- package/dist/atlas/text-overlap.js.map +1 -0
- package/dist/atlas/waves/bridges-closure.d.ts.map +1 -1
- package/dist/atlas/waves/bridges-closure.js +2 -6
- package/dist/atlas/waves/bridges-closure.js.map +1 -1
- package/dist/atlas/waves/bridges.d.ts.map +1 -1
- package/dist/atlas/waves/bridges.js +32 -48
- package/dist/atlas/waves/bridges.js.map +1 -1
- package/dist/atlas/waves/models.d.ts +5 -6
- package/dist/atlas/waves/models.d.ts.map +1 -1
- package/dist/atlas/waves/models.js +7 -13
- package/dist/atlas/waves/models.js.map +1 -1
- package/dist/atlas/waves/numerics.d.ts.map +1 -1
- package/dist/atlas/waves/numerics.js +10 -3
- package/dist/atlas/waves/numerics.js.map +1 -1
- package/dist/atlas/witness-numeric.d.ts +30 -0
- package/dist/atlas/witness-numeric.d.ts.map +1 -1
- package/dist/atlas/witness-numeric.js +53 -0
- package/dist/atlas/witness-numeric.js.map +1 -1
- package/dist/atlas/witness-specs.d.ts.map +1 -1
- package/dist/atlas/witness-specs.js +19 -0
- package/dist/atlas/witness-specs.js.map +1 -1
- package/dist/atlas/witness-symbolic.d.ts +75 -3
- package/dist/atlas/witness-symbolic.d.ts.map +1 -1
- package/dist/atlas/witness-symbolic.js +116 -10
- package/dist/atlas/witness-symbolic.js.map +1 -1
- package/dist/bridges/catalog-load.d.ts.map +1 -1
- package/dist/bridges/catalog-load.js +13 -8
- package/dist/bridges/catalog-load.js.map +1 -1
- package/dist/bridges/catalog-types.d.ts +26 -2
- package/dist/bridges/catalog-types.d.ts.map +1 -1
- package/dist/bridges/catalog-types.js +11 -1
- package/dist/bridges/catalog-types.js.map +1 -1
- package/dist/bridges/evaluation-errors.d.ts +31 -1
- package/dist/bridges/evaluation-errors.d.ts.map +1 -1
- package/dist/bridges/evaluation-errors.js +20 -2
- package/dist/bridges/evaluation-errors.js.map +1 -1
- package/dist/bridges/evaluator-inputs.d.ts.map +1 -1
- package/dist/bridges/evaluator-inputs.js +7 -5
- package/dist/bridges/evaluator-inputs.js.map +1 -1
- package/dist/bridges/evaluators.d.ts.map +1 -1
- package/dist/bridges/evaluators.js +27 -12
- package/dist/bridges/evaluators.js.map +1 -1
- package/dist/bridges/expr-parse.d.ts +11 -0
- package/dist/bridges/expr-parse.d.ts.map +1 -1
- package/dist/bridges/expr-parse.js +14 -5
- package/dist/bridges/expr-parse.js.map +1 -1
- package/dist/bridges/holds.d.ts +35 -3
- package/dist/bridges/holds.d.ts.map +1 -1
- package/dist/bridges/holds.js +117 -23
- package/dist/bridges/holds.js.map +1 -1
- package/dist/bridges/notices.d.ts.map +1 -1
- package/dist/bridges/notices.js +5 -5
- package/dist/bridges/notices.js.map +1 -1
- package/dist/bridges/relation-eval.d.ts +4 -4
- package/dist/bridges/relation-eval.d.ts.map +1 -1
- package/dist/bridges/relation-eval.js +15 -16
- package/dist/bridges/relation-eval.js.map +1 -1
- package/dist/bridges/sensitivity.d.ts.map +1 -1
- package/dist/bridges/sensitivity.js +3 -3
- package/dist/bridges/sensitivity.js.map +1 -1
- package/dist/bridges/validity.d.ts +33 -0
- package/dist/bridges/validity.d.ts.map +1 -0
- package/dist/bridges/validity.js +67 -0
- package/dist/bridges/validity.js.map +1 -0
- package/dist/canonical/entries/atomic.js +1 -3
- package/dist/canonical/entries/atomic.js.map +1 -1
- package/dist/canonical/entries/condensed-matter.d.ts.map +1 -1
- package/dist/canonical/entries/condensed-matter.js +4 -5
- package/dist/canonical/entries/condensed-matter.js.map +1 -1
- package/dist/canonical/entries/dimensional-classics.d.ts.map +1 -1
- package/dist/canonical/entries/dimensional-classics.js +3 -4
- package/dist/canonical/entries/dimensional-classics.js.map +1 -1
- package/dist/canonical/entries/electromagnetism.d.ts.map +1 -1
- package/dist/canonical/entries/electromagnetism.js +4 -10
- package/dist/canonical/entries/electromagnetism.js.map +1 -1
- package/dist/canonical/entries/fluids-waves.d.ts.map +1 -1
- package/dist/canonical/entries/fluids-waves.js +3 -7
- package/dist/canonical/entries/fluids-waves.js.map +1 -1
- package/dist/canonical/entries/mechanics.d.ts.map +1 -1
- package/dist/canonical/entries/mechanics.js +4 -6
- package/dist/canonical/entries/mechanics.js.map +1 -1
- package/dist/canonical/entries/nonmonomial.d.ts.map +1 -1
- package/dist/canonical/entries/nonmonomial.js +9 -17
- package/dist/canonical/entries/nonmonomial.js.map +1 -1
- package/dist/canonical/entries/relativity.d.ts.map +1 -1
- package/dist/canonical/entries/relativity.js +6 -6
- package/dist/canonical/entries/relativity.js.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.d.ts.map +1 -1
- package/dist/canonical/entries/thermo-nuclear-cosmo.js +6 -10
- package/dist/canonical/entries/thermo-nuclear-cosmo.js.map +1 -1
- package/dist/canonical/fixed-points.d.ts +94 -0
- package/dist/canonical/fixed-points.d.ts.map +1 -0
- package/dist/canonical/fixed-points.js +81 -0
- package/dist/canonical/fixed-points.js.map +1 -0
- package/dist/canonical/linkage.d.ts.map +1 -1
- package/dist/canonical/linkage.js +25 -44
- package/dist/canonical/linkage.js.map +1 -1
- package/dist/canonical/normal-form.d.ts.map +1 -1
- package/dist/canonical/normal-form.js +5 -11
- package/dist/canonical/normal-form.js.map +1 -1
- package/dist/canonical/structural.d.ts +21 -21
- package/dist/canonical/structural.d.ts.map +1 -1
- package/dist/canonical/structural.js +40 -19
- package/dist/canonical/structural.js.map +1 -1
- package/dist/cases/brownian-sphere.d.ts +3 -3
- package/dist/cases/brownian-sphere.d.ts.map +1 -1
- package/dist/cases/brownian-sphere.js +6 -5
- package/dist/cases/brownian-sphere.js.map +1 -1
- package/dist/cases/damped-resonator.d.ts.map +1 -1
- package/dist/cases/damped-resonator.js +6 -9
- package/dist/cases/damped-resonator.js.map +1 -1
- package/dist/cases/kepler-rv.d.ts +1 -1
- package/dist/cases/kepler-rv.d.ts.map +1 -1
- package/dist/cases/kepler-rv.js +3 -2
- package/dist/cases/kepler-rv.js.map +1 -1
- package/dist/cases/lumped-cooling.d.ts +8 -3
- package/dist/cases/lumped-cooling.d.ts.map +1 -1
- package/dist/cases/lumped-cooling.js +21 -23
- package/dist/cases/lumped-cooling.js.map +1 -1
- package/dist/cases/quadrature.d.ts +7 -9
- package/dist/cases/quadrature.d.ts.map +1 -1
- package/dist/cases/quadrature.js +28 -32
- package/dist/cases/quadrature.js.map +1 -1
- package/dist/cases/resistor-noise.js +4 -4
- package/dist/cases/resistor-noise.js.map +1 -1
- package/dist/cases/skin-depth.d.ts +0 -4
- package/dist/cases/skin-depth.d.ts.map +1 -1
- package/dist/cases/skin-depth.js +3 -7
- package/dist/cases/skin-depth.js.map +1 -1
- package/dist/cli/args.d.ts +23 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +30 -8
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/bindings.d.ts.map +1 -1
- package/dist/cli/bindings.js +5 -4
- package/dist/cli/bindings.js.map +1 -1
- package/dist/cli/command.d.ts +8 -1
- package/dist/cli/command.d.ts.map +1 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/commands/_atlas-map.d.ts +0 -9
- package/dist/cli/commands/_atlas-map.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-map.js +8 -18
- package/dist/cli/commands/_atlas-map.js.map +1 -1
- package/dist/cli/commands/_atlas-route.d.ts.map +1 -1
- package/dist/cli/commands/_atlas-route.js +6 -2
- package/dist/cli/commands/_atlas-route.js.map +1 -1
- package/dist/cli/commands/_discovery-opts.d.ts.map +1 -1
- package/dist/cli/commands/_discovery-opts.js +8 -9
- package/dist/cli/commands/_discovery-opts.js.map +1 -1
- package/dist/cli/commands/atlas.d.ts.map +1 -1
- package/dist/cli/commands/atlas.js +8 -5
- package/dist/cli/commands/atlas.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +8 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/axes.d.ts.map +1 -1
- package/dist/cli/commands/axes.js +20 -1
- package/dist/cli/commands/axes.js.map +1 -1
- package/dist/cli/commands/confront.d.ts.map +1 -1
- package/dist/cli/commands/confront.js +8 -14
- package/dist/cli/commands/confront.js.map +1 -1
- package/dist/cli/commands/derive.d.ts.map +1 -1
- package/dist/cli/commands/derive.js +22 -22
- package/dist/cli/commands/derive.js.map +1 -1
- package/dist/cli/commands/discover.d.ts.map +1 -1
- package/dist/cli/commands/discover.js +6 -2
- package/dist/cli/commands/discover.js.map +1 -1
- package/dist/cli/commands/eval.d.ts.map +1 -1
- package/dist/cli/commands/eval.js +1 -0
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/evaluate.d.ts.map +1 -1
- package/dist/cli/commands/evaluate.js +65 -37
- package/dist/cli/commands/evaluate.js.map +1 -1
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/explain.js +2 -1
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/ground.d.ts.map +1 -1
- package/dist/cli/commands/ground.js +1 -0
- package/dist/cli/commands/ground.js.map +1 -1
- package/dist/cli/commands/map.d.ts.map +1 -1
- package/dist/cli/commands/map.js +75 -5
- package/dist/cli/commands/map.js.map +1 -1
- package/dist/cli/commands/metric.d.ts.map +1 -1
- package/dist/cli/commands/metric.js +12 -9
- package/dist/cli/commands/metric.js.map +1 -1
- package/dist/cli/commands/path.d.ts +10 -0
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +25 -3
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/probe.d.ts.map +1 -1
- package/dist/cli/commands/probe.js +59 -16
- package/dist/cli/commands/probe.js.map +1 -1
- package/dist/cli/commands/regime.d.ts.map +1 -1
- package/dist/cli/commands/regime.js +1 -0
- package/dist/cli/commands/regime.js.map +1 -1
- package/dist/cli/commands/retrieve.d.ts.map +1 -1
- package/dist/cli/commands/retrieve.js +1 -0
- package/dist/cli/commands/retrieve.js.map +1 -1
- package/dist/cli/commands/search.d.ts.map +1 -1
- package/dist/cli/commands/search.js +1 -0
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/symbolic.d.ts.map +1 -1
- package/dist/cli/commands/symbolic.js +19 -28
- package/dist/cli/commands/symbolic.js.map +1 -1
- package/dist/cli/commands/testplan.d.ts.map +1 -1
- package/dist/cli/commands/testplan.js +4 -2
- package/dist/cli/commands/testplan.js.map +1 -1
- package/dist/cli/expr-print.d.ts +0 -2
- package/dist/cli/expr-print.d.ts.map +1 -1
- package/dist/cli/expr-print.js +7 -31
- package/dist/cli/expr-print.js.map +1 -1
- package/dist/cli/main.d.ts +7 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +18 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/numeric-flag.d.ts +12 -0
- package/dist/cli/numeric-flag.d.ts.map +1 -0
- package/dist/cli/numeric-flag.js +44 -0
- package/dist/cli/numeric-flag.js.map +1 -0
- package/dist/cli/output.d.ts +20 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +15 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/record-reach.js +2 -2
- package/dist/cli/record-reach.js.map +1 -1
- package/dist/cli/record-tables.d.ts.map +1 -1
- package/dist/cli/record-tables.js +6 -5
- package/dist/cli/record-tables.js.map +1 -1
- package/dist/cli/record.d.ts +1 -5
- package/dist/cli/record.d.ts.map +1 -1
- package/dist/cli/record.js +9 -8
- package/dist/cli/record.js.map +1 -1
- package/dist/cli/search-index.d.ts.map +1 -1
- package/dist/cli/search-index.js +7 -6
- package/dist/cli/search-index.js.map +1 -1
- package/dist/cli/statuses.d.ts +0 -2
- package/dist/cli/statuses.d.ts.map +1 -1
- package/dist/cli/statuses.js +0 -7
- package/dist/cli/statuses.js.map +1 -1
- package/dist/cli/stored-results.d.ts +7 -0
- package/dist/cli/stored-results.d.ts.map +1 -0
- package/dist/cli/stored-results.js +23 -0
- package/dist/cli/stored-results.js.map +1 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +7 -5
- package/dist/cli/version.js.map +1 -1
- package/dist/cli-api.d.ts +34 -5
- package/dist/cli-api.d.ts.map +1 -1
- package/dist/cli-api.js +28 -4
- package/dist/cli-api.js.map +1 -1
- package/dist/composition/algebraic-equivalence.d.ts +43 -0
- package/dist/composition/algebraic-equivalence.d.ts.map +1 -0
- package/dist/composition/algebraic-equivalence.js +115 -0
- package/dist/composition/algebraic-equivalence.js.map +1 -0
- package/dist/composition/axes.d.ts +0 -6
- package/dist/composition/axes.d.ts.map +1 -1
- package/dist/composition/axes.js +6 -6
- package/dist/composition/axes.js.map +1 -1
- package/dist/composition/axis-audit.d.ts +47 -20
- package/dist/composition/axis-audit.d.ts.map +1 -1
- package/dist/composition/axis-audit.js +82 -9
- package/dist/composition/axis-audit.js.map +1 -1
- package/dist/composition/bridge-analysis.d.ts +17 -0
- package/dist/composition/bridge-analysis.d.ts.map +1 -1
- package/dist/composition/bridge-analysis.js +102 -55
- package/dist/composition/bridge-analysis.js.map +1 -1
- package/dist/composition/canonical-compare.d.ts +40 -0
- package/dist/composition/canonical-compare.d.ts.map +1 -1
- package/dist/composition/canonical-compare.js +122 -24
- package/dist/composition/canonical-compare.js.map +1 -1
- package/dist/composition/canonical-graph.d.ts +1 -1
- package/dist/composition/canonical-graph.d.ts.map +1 -1
- package/dist/composition/canonical-graph.js +9 -36
- package/dist/composition/canonical-graph.js.map +1 -1
- package/dist/composition/canonical-json.js +2 -2
- package/dist/composition/canonical-json.js.map +1 -1
- package/dist/composition/catalog-graph.d.ts.map +1 -1
- package/dist/composition/catalog-graph.js +2 -5
- package/dist/composition/catalog-graph.js.map +1 -1
- package/dist/composition/chain-candidate.d.ts +8 -0
- package/dist/composition/chain-candidate.d.ts.map +1 -1
- package/dist/composition/chain-candidate.js +9 -2
- package/dist/composition/chain-candidate.js.map +1 -1
- package/dist/composition/chain-match.d.ts +6 -3
- package/dist/composition/chain-match.d.ts.map +1 -1
- package/dist/composition/chain-match.js +4 -1
- package/dist/composition/chain-match.js.map +1 -1
- package/dist/composition/chain-result.d.ts.map +1 -1
- package/dist/composition/chain-result.js +2 -14
- package/dist/composition/chain-result.js.map +1 -1
- package/dist/composition/compose-symbolic.d.ts.map +1 -1
- package/dist/composition/compose-symbolic.js +3 -2
- package/dist/composition/compose-symbolic.js.map +1 -1
- package/dist/composition/compose.d.ts.map +1 -1
- package/dist/composition/compose.js +13 -5
- package/dist/composition/compose.js.map +1 -1
- package/dist/composition/composition-recovery.d.ts.map +1 -1
- package/dist/composition/composition-recovery.js +4 -7
- package/dist/composition/composition-recovery.js.map +1 -1
- package/dist/composition/discovery.d.ts +56 -0
- package/dist/composition/discovery.d.ts.map +1 -1
- package/dist/composition/discovery.js +114 -60
- package/dist/composition/discovery.js.map +1 -1
- package/dist/composition/edge.d.ts +21 -2
- package/dist/composition/edge.d.ts.map +1 -1
- package/dist/composition/edge.js +23 -1
- package/dist/composition/edge.js.map +1 -1
- package/dist/composition/enumerate.d.ts.map +1 -1
- package/dist/composition/enumerate.js +18 -3
- package/dist/composition/enumerate.js.map +1 -1
- package/dist/composition/evaluate-relation.d.ts +35 -11
- package/dist/composition/evaluate-relation.d.ts.map +1 -1
- package/dist/composition/evaluate-relation.js +60 -39
- package/dist/composition/evaluate-relation.js.map +1 -1
- package/dist/composition/explain.d.ts +3 -12
- package/dist/composition/explain.d.ts.map +1 -1
- package/dist/composition/explain.js +7 -20
- package/dist/composition/explain.js.map +1 -1
- package/dist/composition/expr-eval.d.ts.map +1 -1
- package/dist/composition/expr-eval.js +2 -11
- package/dist/composition/expr-eval.js.map +1 -1
- package/dist/composition/expr-simplify.d.ts +16 -0
- package/dist/composition/expr-simplify.d.ts.map +1 -1
- package/dist/composition/expr-simplify.js +15 -20
- package/dist/composition/expr-simplify.js.map +1 -1
- package/dist/composition/formula-shape.d.ts +23 -4
- package/dist/composition/formula-shape.d.ts.map +1 -1
- package/dist/composition/formula-shape.js +57 -17
- package/dist/composition/formula-shape.js.map +1 -1
- package/dist/composition/graph-structure.d.ts +98 -0
- package/dist/composition/graph-structure.d.ts.map +1 -0
- package/dist/composition/graph-structure.js +167 -0
- package/dist/composition/graph-structure.js.map +1 -0
- package/dist/composition/graph-viz-svg.d.ts.map +1 -1
- package/dist/composition/graph-viz-svg.js +1 -1
- package/dist/composition/graph-viz-svg.js.map +1 -1
- package/dist/composition/graph-viz.d.ts.map +1 -1
- package/dist/composition/graph-viz.js +8 -37
- package/dist/composition/graph-viz.js.map +1 -1
- package/dist/composition/identifiability.d.ts +91 -4
- package/dist/composition/identifiability.d.ts.map +1 -1
- package/dist/composition/identifiability.js +363 -6
- package/dist/composition/identifiability.js.map +1 -1
- package/dist/composition/index.d.ts +8 -4
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +3 -2
- package/dist/composition/index.js.map +1 -1
- package/dist/composition/mathts-quiet.d.ts +4 -3
- package/dist/composition/mathts-quiet.d.ts.map +1 -1
- package/dist/composition/mathts-quiet.js +4 -3
- package/dist/composition/mathts-quiet.js.map +1 -1
- package/dist/composition/mathts-scalar-symbols.d.ts.map +1 -1
- package/dist/composition/mathts-scalar-symbols.js +2 -1
- package/dist/composition/mathts-scalar-symbols.js.map +1 -1
- package/dist/composition/probe/corpus.d.ts +4 -2
- package/dist/composition/probe/corpus.d.ts.map +1 -1
- package/dist/composition/probe/corpus.js +20 -9
- package/dist/composition/probe/corpus.js.map +1 -1
- package/dist/composition/probe/dataset.d.ts +17 -0
- package/dist/composition/probe/dataset.d.ts.map +1 -1
- package/dist/composition/probe/dataset.js +95 -50
- package/dist/composition/probe/dataset.js.map +1 -1
- package/dist/composition/probe/experiment-design.d.ts +5 -1
- package/dist/composition/probe/experiment-design.d.ts.map +1 -1
- package/dist/composition/probe/experiment-design.js +44 -24
- package/dist/composition/probe/experiment-design.js.map +1 -1
- package/dist/composition/probe/falsify.d.ts.map +1 -1
- package/dist/composition/probe/falsify.js +2 -0
- package/dist/composition/probe/falsify.js.map +1 -1
- package/dist/composition/probe/fit.d.ts +6 -0
- package/dist/composition/probe/fit.d.ts.map +1 -1
- package/dist/composition/probe/fit.js +46 -22
- package/dist/composition/probe/fit.js.map +1 -1
- package/dist/composition/probe/frontier.d.ts.map +1 -1
- package/dist/composition/probe/frontier.js +33 -15
- package/dist/composition/probe/frontier.js.map +1 -1
- package/dist/composition/probe/generator.d.ts +27 -1
- package/dist/composition/probe/generator.d.ts.map +1 -1
- package/dist/composition/probe/generator.js +53 -30
- package/dist/composition/probe/generator.js.map +1 -1
- package/dist/composition/probe/index.d.ts +14 -0
- package/dist/composition/probe/index.d.ts.map +1 -1
- package/dist/composition/probe/index.js +6 -0
- package/dist/composition/probe/index.js.map +1 -1
- package/dist/composition/probe/limits.d.ts +24 -1
- package/dist/composition/probe/limits.d.ts.map +1 -1
- package/dist/composition/probe/limits.js +53 -11
- package/dist/composition/probe/limits.js.map +1 -1
- package/dist/composition/probe/pipeline.d.ts.map +1 -1
- package/dist/composition/probe/pipeline.js +10 -4
- package/dist/composition/probe/pipeline.js.map +1 -1
- package/dist/composition/probe/power-law.d.ts +121 -0
- package/dist/composition/probe/power-law.d.ts.map +1 -0
- package/dist/composition/probe/power-law.js +255 -0
- package/dist/composition/probe/power-law.js.map +1 -0
- package/dist/composition/probe/problem.d.ts +7 -4
- package/dist/composition/probe/problem.d.ts.map +1 -1
- package/dist/composition/probe/problem.js +177 -49
- package/dist/composition/probe/problem.js.map +1 -1
- package/dist/composition/probe/report.js +1 -1
- package/dist/composition/probe/report.js.map +1 -1
- package/dist/composition/probe/residual.d.ts +6 -1
- package/dist/composition/probe/residual.d.ts.map +1 -1
- package/dist/composition/probe/residual.js +9 -7
- package/dist/composition/probe/residual.js.map +1 -1
- package/dist/composition/probe/structure.d.ts +82 -17
- package/dist/composition/probe/structure.d.ts.map +1 -1
- package/dist/composition/probe/structure.js +129 -55
- package/dist/composition/probe/structure.js.map +1 -1
- package/dist/composition/probe/study.d.ts +31 -9
- package/dist/composition/probe/study.d.ts.map +1 -1
- package/dist/composition/probe/study.js +236 -181
- package/dist/composition/probe/study.js.map +1 -1
- package/dist/composition/probe/t-tail.d.ts +17 -0
- package/dist/composition/probe/t-tail.d.ts.map +1 -0
- package/dist/composition/probe/t-tail.js +32 -0
- package/dist/composition/probe/t-tail.js.map +1 -0
- package/dist/composition/probe/types.d.ts +3 -0
- package/dist/composition/probe/types.d.ts.map +1 -1
- package/dist/composition/probe/types.js.map +1 -1
- package/dist/composition/proposed-bridges.d.ts +41 -10
- package/dist/composition/proposed-bridges.d.ts.map +1 -1
- package/dist/composition/proposed-bridges.js +100 -55
- package/dist/composition/proposed-bridges.js.map +1 -1
- package/dist/composition/quantity-clusters.d.ts +48 -0
- package/dist/composition/quantity-clusters.d.ts.map +1 -0
- package/dist/composition/quantity-clusters.js +98 -0
- package/dist/composition/quantity-clusters.js.map +1 -0
- package/dist/composition/rational-exponent.d.ts +40 -0
- package/dist/composition/rational-exponent.d.ts.map +1 -0
- package/dist/composition/rational-exponent.js +65 -0
- package/dist/composition/rational-exponent.js.map +1 -0
- package/dist/composition/representative-values.d.ts +22 -0
- package/dist/composition/representative-values.d.ts.map +1 -1
- package/dist/composition/representative-values.js +23 -0
- package/dist/composition/representative-values.js.map +1 -1
- package/dist/composition/retrodiction.d.ts.map +1 -1
- package/dist/composition/retrodiction.js +2 -1
- package/dist/composition/retrodiction.js.map +1 -1
- package/dist/composition/user-equation.d.ts.map +1 -1
- package/dist/composition/user-equation.js +2 -2
- package/dist/composition/user-equation.js.map +1 -1
- package/dist/core/assignment.d.ts +19 -0
- package/dist/core/assignment.d.ts.map +1 -0
- package/dist/core/assignment.js +19 -0
- package/dist/core/assignment.js.map +1 -0
- package/dist/core/compare.d.ts +32 -0
- package/dist/core/compare.d.ts.map +1 -0
- package/dist/core/compare.js +46 -0
- package/dist/core/compare.js.map +1 -0
- package/dist/core/constants.d.ts +30 -30
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +47 -30
- package/dist/core/constants.js.map +1 -1
- package/dist/core/data-file.d.ts +7 -0
- package/dist/core/data-file.d.ts.map +1 -1
- package/dist/core/data-file.js +17 -0
- package/dist/core/data-file.js.map +1 -1
- package/dist/core/format.d.ts +36 -0
- package/dist/core/format.d.ts.map +1 -0
- package/dist/core/format.js +39 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/hash.d.ts +14 -0
- package/dist/core/hash.d.ts.map +1 -0
- package/dist/core/hash.js +17 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/json-schema.d.ts +2 -0
- package/dist/core/json-schema.d.ts.map +1 -1
- package/dist/core/json-schema.js +14 -13
- package/dist/core/json-schema.js.map +1 -1
- package/dist/core/labeled-tensor.d.ts.map +1 -1
- package/dist/core/labeled-tensor.js +0 -8
- package/dist/core/labeled-tensor.js.map +1 -1
- package/dist/core/mathts-read.d.ts +25 -0
- package/dist/core/mathts-read.d.ts.map +1 -0
- package/dist/core/mathts-read.js +51 -0
- package/dist/core/mathts-read.js.map +1 -0
- package/dist/core/tensor.d.ts.map +1 -1
- package/dist/core/tensor.js +24 -0
- package/dist/core/tensor.js.map +1 -1
- package/dist/core/types.d.ts +5 -5
- package/dist/diff/bridge-gradient.d.ts +19 -6
- package/dist/diff/bridge-gradient.d.ts.map +1 -1
- package/dist/diff/bridge-gradient.js +19 -11
- package/dist/diff/bridge-gradient.js.map +1 -1
- package/dist/diff/bridge-specs.d.ts.map +1 -1
- package/dist/diff/bridge-specs.js +3 -0
- package/dist/diff/bridge-specs.js.map +1 -1
- package/dist/dimensional/algebra.d.ts +18 -0
- package/dist/dimensional/algebra.d.ts.map +1 -1
- package/dist/dimensional/algebra.js +41 -1
- package/dist/dimensional/algebra.js.map +1 -1
- package/dist/dimensional/ast-builders.d.ts +7 -0
- package/dist/dimensional/ast-builders.d.ts.map +1 -1
- package/dist/dimensional/ast-builders.js +11 -0
- package/dist/dimensional/ast-builders.js.map +1 -1
- package/dist/dimensional/ast-leaves.d.ts +81 -0
- package/dist/dimensional/ast-leaves.d.ts.map +1 -0
- package/dist/dimensional/ast-leaves.js +146 -0
- package/dist/dimensional/ast-leaves.js.map +1 -0
- package/dist/dimensional/buckingham.d.ts.map +1 -1
- package/dist/dimensional/buckingham.js +15 -27
- package/dist/dimensional/buckingham.js.map +1 -1
- package/dist/dimensional/constant-rows.js +9 -9
- package/dist/dimensional/constant-rows.js.map +1 -1
- package/dist/dimensional/dimension-inference.d.ts.map +1 -1
- package/dist/dimensional/dimension-inference.js +1 -2
- package/dist/dimensional/dimension-inference.js.map +1 -1
- package/dist/dimensional/errors.d.ts +1 -1
- package/dist/dimensional/errors.d.ts.map +1 -1
- package/dist/dimensional/errors.js +1 -15
- package/dist/dimensional/errors.js.map +1 -1
- package/dist/dimensional/exact-scale.d.ts +0 -17
- package/dist/dimensional/exact-scale.d.ts.map +1 -1
- package/dist/dimensional/exact-scale.js +8 -8
- package/dist/dimensional/exact-scale.js.map +1 -1
- package/dist/dimensional/gauge-field.d.ts.map +1 -1
- package/dist/dimensional/gauge-field.js +2 -2
- package/dist/dimensional/gauge-field.js.map +1 -1
- package/dist/dimensional/hyphen-names.d.ts +12 -2
- package/dist/dimensional/hyphen-names.d.ts.map +1 -1
- package/dist/dimensional/hyphen-names.js +44 -19
- package/dist/dimensional/hyphen-names.js.map +1 -1
- package/dist/dimensional/metric.d.ts.map +1 -1
- package/dist/dimensional/metric.js +0 -1
- package/dist/dimensional/metric.js.map +1 -1
- package/dist/dimensional/symbolic-constants.d.ts +9 -0
- package/dist/dimensional/symbolic-constants.d.ts.map +1 -1
- package/dist/dimensional/symbolic-constants.js +13 -1
- package/dist/dimensional/symbolic-constants.js.map +1 -1
- package/dist/dimensional/types.d.ts +36 -0
- package/dist/dimensional/types.d.ts.map +1 -1
- package/dist/dimensional/types.js +45 -7
- package/dist/dimensional/types.js.map +1 -1
- package/dist/dimensional/unit-data.js +2 -2
- package/dist/dimensional/unit-data.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/numerical/christoffel-flat.d.ts.map +1 -1
- package/dist/numerical/christoffel-flat.js +3 -2
- package/dist/numerical/christoffel-flat.js.map +1 -1
- package/dist/numerical/covariant-eikonal.d.ts.map +1 -1
- package/dist/numerical/covariant-eikonal.js +34 -11
- package/dist/numerical/covariant-eikonal.js.map +1 -1
- package/dist/numerical/curvature-lowering-helpers.js +3 -2
- package/dist/numerical/curvature-lowering-helpers.js.map +1 -1
- package/dist/numerical/errors.d.ts.map +1 -1
- package/dist/numerical/errors.js +0 -3
- package/dist/numerical/errors.js.map +1 -1
- package/dist/numerical/finite-difference.d.ts +22 -0
- package/dist/numerical/finite-difference.d.ts.map +1 -0
- package/dist/numerical/finite-difference.js +27 -0
- package/dist/numerical/finite-difference.js.map +1 -0
- package/dist/numerical/geodesic-integrator.d.ts.map +1 -1
- package/dist/numerical/geodesic-integrator.js +22 -14
- package/dist/numerical/geodesic-integrator.js.map +1 -1
- package/dist/numerical/geometrized.d.ts.map +1 -1
- package/dist/numerical/geometrized.js +0 -1
- package/dist/numerical/geometrized.js.map +1 -1
- package/dist/numerical/mathts-engine.d.ts.map +1 -1
- package/dist/numerical/mathts-engine.js +10 -24
- package/dist/numerical/mathts-engine.js.map +1 -1
- package/dist/numerical/metric-inverse.d.ts.map +1 -1
- package/dist/numerical/metric-inverse.js +83 -46
- package/dist/numerical/metric-inverse.js.map +1 -1
- package/dist/numerical/null-ray-integrator.d.ts +2 -1
- package/dist/numerical/null-ray-integrator.d.ts.map +1 -1
- package/dist/numerical/null-ray-integrator.js +12 -12
- package/dist/numerical/null-ray-integrator.js.map +1 -1
- package/dist/numerical/painleve-gullstrand-metric.js +2 -2
- package/dist/numerical/painleve-gullstrand-metric.js.map +1 -1
- package/dist/numerical/perihelion-finder.d.ts +0 -36
- package/dist/numerical/perihelion-finder.d.ts.map +1 -1
- package/dist/numerical/perihelion-finder.js +41 -87
- package/dist/numerical/perihelion-finder.js.map +1 -1
- package/dist/numerical/quadrature.d.ts.map +1 -1
- package/dist/numerical/quadrature.js +8 -10
- package/dist/numerical/quadrature.js.map +1 -1
- package/dist/numerical/rk4-trajectory.d.ts +10 -0
- package/dist/numerical/rk4-trajectory.d.ts.map +1 -0
- package/dist/numerical/rk4-trajectory.js +37 -0
- package/dist/numerical/rk4-trajectory.js.map +1 -0
- package/dist/numerical/schwarzschild.d.ts +14 -0
- package/dist/numerical/schwarzschild.d.ts.map +1 -0
- package/dist/numerical/schwarzschild.js +17 -0
- package/dist/numerical/schwarzschild.js.map +1 -0
- package/dist/numerical/spacetime-metrics.d.ts +12 -0
- package/dist/numerical/spacetime-metrics.d.ts.map +1 -1
- package/dist/numerical/spacetime-metrics.js +72 -56
- package/dist/numerical/spacetime-metrics.js.map +1 -1
- package/dist/numerical/statistics.d.ts +24 -0
- package/dist/numerical/statistics.d.ts.map +1 -0
- package/dist/numerical/statistics.js +52 -0
- package/dist/numerical/statistics.js.map +1 -0
- package/dist/numerical/tensor-engine.d.ts +21 -0
- package/dist/numerical/tensor-engine.d.ts.map +1 -1
- package/dist/numerical/tensor-engine.js +12 -0
- package/dist/numerical/tensor-engine.js.map +1 -1
- package/dist/relations/regime.d.ts +10 -0
- package/dist/relations/regime.d.ts.map +1 -1
- package/dist/relations/regime.js +18 -1
- package/dist/relations/regime.js.map +1 -1
- package/package.json +7 -7
package/dist/bridges/holds.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { parse as parseMathTs } from '@danielsimonjr/mathts-functions';
|
|
17
17
|
import { rewriteCatalogHyphens } from '../dimensional/hyphen-names.js';
|
|
18
18
|
import { ConstantInputError } from './evaluation-errors.js';
|
|
19
|
+
import { expressionNames } from './expr-parse.js';
|
|
19
20
|
/** A condition could not be evaluated: it names an unbound symbol, or its text does not parse. @internal */
|
|
20
21
|
export class HoldsError extends Error {
|
|
21
22
|
constructor(message) {
|
|
@@ -112,35 +113,116 @@ function compile(node, source) {
|
|
|
112
113
|
return arithmetic(node, source);
|
|
113
114
|
}
|
|
114
115
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
/**
|
|
117
|
+
* The conjuncts of `node`: an `and` splits, `not (not X)` is X, `not (A or B)` is
|
|
118
|
+
* `not A` and `not B`, and `not (x == y)` is `x != y`. Each rewrite is exact, so
|
|
119
|
+
* the conjunction of the parts is the condition. Anything else is one conjunct.
|
|
120
|
+
*/
|
|
121
|
+
function conjuncts(node) {
|
|
122
|
+
if (node.type === 'ParenthesisNode')
|
|
123
|
+
return conjuncts(node.content);
|
|
124
|
+
if (node.type === 'OperatorNode' && node.op === 'and')
|
|
125
|
+
return (node.args ?? []).flatMap(conjuncts);
|
|
126
|
+
if (node.type === 'OperatorNode' && node.op === 'not') {
|
|
127
|
+
let inner = node.args[0];
|
|
128
|
+
while (inner.type === 'ParenthesisNode')
|
|
129
|
+
inner = inner.content;
|
|
130
|
+
if (inner.type === 'OperatorNode' && inner.op === 'not')
|
|
131
|
+
return conjuncts(inner.args[0]);
|
|
132
|
+
if (inner.type === 'OperatorNode' && inner.op === 'or')
|
|
133
|
+
return (inner.args ?? []).flatMap((arg) => conjuncts(negation(arg)));
|
|
134
|
+
if (inner.type === 'OperatorNode' && inner.op === '==')
|
|
135
|
+
return [withOperator(inner, '!=')];
|
|
136
|
+
}
|
|
137
|
+
return [node];
|
|
138
|
+
}
|
|
139
|
+
/** `not X` as a node, so the rewrite above can recurse into it. */
|
|
140
|
+
function negation(node) {
|
|
141
|
+
return parseMathTs(`not (${node.toString()})`);
|
|
142
|
+
}
|
|
143
|
+
/** `a op b` with the same operands. */
|
|
144
|
+
function withOperator(node, op) {
|
|
145
|
+
const [a, b] = node.args;
|
|
146
|
+
return parseMathTs(`${a.toString()} ${op} ${b.toString()}`);
|
|
147
|
+
}
|
|
148
|
+
/** The symbol names a node reads, in order, without functions. */
|
|
149
|
+
function symbolNames(node) {
|
|
150
|
+
const out = [];
|
|
151
|
+
const visit = (n) => {
|
|
152
|
+
if (n.type === 'SymbolNode' && n.name !== undefined) {
|
|
153
|
+
if (!out.includes(n.name))
|
|
154
|
+
out.push(n.name);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (n.type === 'ParenthesisNode')
|
|
158
|
+
visit(n.content);
|
|
159
|
+
for (const arg of n.args ?? [])
|
|
160
|
+
visit(arg);
|
|
161
|
+
};
|
|
162
|
+
visit(node);
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Replace each identifier `text` mentions through `rename`, whole-word, in one
|
|
167
|
+
* pass (a renamed word is never renamed again). The identifiers are the ones
|
|
168
|
+
* `expressionNames` reads (the text is a printed conjunct, already written
|
|
169
|
+
* with underscores, so the rewrite it applies is the identity on it).
|
|
170
|
+
*/
|
|
171
|
+
function renameIdentifiers(text, rename) {
|
|
172
|
+
const names = expressionNames(text);
|
|
173
|
+
return text.replace(/[A-Za-z_][A-Za-z0-9_]*/g, (word) => (names.has(word) ? rename(word) : word));
|
|
174
|
+
}
|
|
175
|
+
const CONDITIONS = new Map();
|
|
176
|
+
/**
|
|
177
|
+
* The conjuncts of the condition `source`, each testable alone. Their
|
|
178
|
+
* conjunction is the condition, so a caller that tests them all decides
|
|
179
|
+
* exactly what {@link holds} decides, and can say which part failed.
|
|
180
|
+
* Hyphenated names are rewritten with `names` before parsing and restored in
|
|
181
|
+
* each conjunct's `text` and `names`.
|
|
182
|
+
* @internal
|
|
183
|
+
*/
|
|
184
|
+
export function holdsConditions(source, names) {
|
|
185
|
+
const rewritten = rewriteCatalogHyphens(source, names);
|
|
186
|
+
const hit = CONDITIONS.get(rewritten);
|
|
118
187
|
if (hit !== undefined)
|
|
119
188
|
return hit;
|
|
120
|
-
let
|
|
189
|
+
let root;
|
|
121
190
|
try {
|
|
122
|
-
|
|
191
|
+
root = parseMathTs(rewritten);
|
|
123
192
|
}
|
|
124
193
|
catch (error) {
|
|
125
194
|
throw new HoldsError(`${error instanceof Error ? error.message : String(error)} in ${source}`);
|
|
126
195
|
}
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
196
|
+
const spelled = new Map(names.map((name) => [name.replace(/-/g, '_'), name]));
|
|
197
|
+
const restore = (name) => spelled.get(name) ?? name;
|
|
198
|
+
const parts = conjuncts(root).map((node) => {
|
|
199
|
+
const text = renameIdentifiers(node.toString(), restore);
|
|
200
|
+
const fn = compile(node, text);
|
|
201
|
+
return {
|
|
202
|
+
text,
|
|
203
|
+
names: symbolNames(node).map(restore),
|
|
204
|
+
test: (scope) => {
|
|
205
|
+
const result = fn({ ...scope });
|
|
206
|
+
if (typeof result !== 'boolean')
|
|
207
|
+
throw new HoldsError(`condition is not boolean: ${text}`);
|
|
208
|
+
return result;
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
});
|
|
212
|
+
CONDITIONS.set(rewritten, parts);
|
|
213
|
+
return parts;
|
|
214
|
+
}
|
|
215
|
+
/** The names (hyphens written as underscores) the conditions read. @internal */
|
|
216
|
+
export function conditionReads(conditions) {
|
|
217
|
+
return new Set(conditions.flatMap((condition) => condition.names.map((name) => name.replace(/-/g, '_'))));
|
|
130
218
|
}
|
|
131
|
-
const IDENTIFIER = /[A-Za-z_][A-Za-z0-9_]*/g;
|
|
132
219
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* a {@link ConstantInputError}, a caller error and not a false condition,
|
|
138
|
-
* unless `declared` names it; one the condition does not read is dropped, as
|
|
139
|
-
* any other extra key is.
|
|
220
|
+
* A scope for a condition: the constants, then `values` with hyphens written as
|
|
221
|
+
* underscores. A value whose name is a constant that `declared` does not name
|
|
222
|
+
* is a {@link ConstantInputError} when `reads` holds it, and is dropped otherwise.
|
|
223
|
+
* @internal
|
|
140
224
|
*/
|
|
141
|
-
export function
|
|
142
|
-
const rewritten = rewriteCatalogHyphens(source, names);
|
|
143
|
-
const reads = new Set(rewritten.match(IDENTIFIER) ?? []);
|
|
225
|
+
export function holdsScope(values, constants, reads, declared = []) {
|
|
144
226
|
const scope = { ...constants };
|
|
145
227
|
const allowed = new Set(declared.map((name) => name.replace(/-/g, '_')));
|
|
146
228
|
for (const [key, value] of Object.entries(values)) {
|
|
@@ -152,9 +234,21 @@ export function holds(source, values, constants, names, declared = []) {
|
|
|
152
234
|
}
|
|
153
235
|
scope[name] = value;
|
|
154
236
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
237
|
+
return scope;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Whether `holds` is true for `values`: every conjunct of
|
|
241
|
+
* {@link holdsConditions} holds. Hyphenated quantity names are rewritten with
|
|
242
|
+
* `names` before parsing; an unbound name, a non-boolean result, and a syntax
|
|
243
|
+
* error are a {@link HoldsError}.
|
|
244
|
+
* A value whose name is one of `constants` and which the condition reads is
|
|
245
|
+
* a {@link ConstantInputError}, a caller error and not a false condition,
|
|
246
|
+
* unless `declared` names it; one the condition does not read is dropped, as
|
|
247
|
+
* any other extra key is.
|
|
248
|
+
*/
|
|
249
|
+
export function holds(source, values, constants, names, declared = []) {
|
|
250
|
+
const conditions = holdsConditions(source, names);
|
|
251
|
+
const scope = holdsScope(values, constants, conditionReads(conditions), declared);
|
|
252
|
+
return conditions.every((condition) => condition.test(scope));
|
|
159
253
|
}
|
|
160
254
|
//# sourceMappingURL=holds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"holds.js","sourceRoot":"","sources":["../../src/bridges/holds.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Interpreter for a catalog validity condition.\n *\n * A condition is a boolean expression over quantity names, the registered\n * constants, `isFinite` and `isInteger`, written in MathTS's grammar\n * (`and`, `or`, `not`, `<`, `<=`, `>`, `>=`, `==`, `!=`). MathTS parses it,\n * and MathTS evaluates every arithmetic sub-expression. The comparisons and\n * the logical operators are evaluated here, exactly: MathTS's own comparison\n * operators are tolerance-based (`absTol` 1e-15), so under them `1e-18 > 0`\n * is false, which no condition over SI magnitudes can accept.\n *\n * It is not JavaScript `eval`.\n *\n * @module bridges/holds\n */\n\nimport { parse as parseMathTs } from '@danielsimonjr/mathts-functions';\nimport { rewriteCatalogHyphens } from '../dimensional/hyphen-names.js';\nimport { ConstantInputError } from './evaluation-errors.js';\n\n/** A condition could not be evaluated: it names an unbound symbol, or its text does not parse. @internal */\nexport class HoldsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'HoldsError';\n }\n}\n\n/** The MathTS node shape this interpreter reads. */\ninterface MathNode {\n readonly type: string;\n readonly op?: string;\n readonly fn?: string | { readonly name?: string };\n readonly name?: string;\n readonly value?: unknown;\n readonly args?: readonly MathNode[];\n readonly content?: MathNode;\n evaluate(scope: Record<string, unknown>): unknown;\n}\n\ntype Scope = Record<string, number>;\ntype Compiled = (scope: Scope) => boolean | number;\n\nconst COMPARISONS: Readonly<Record<string, (a: number, b: number) => boolean>> = {\n '<': (a, b) => a < b,\n '<=': (a, b) => a <= b,\n '>': (a, b) => a > b,\n '>=': (a, b) => a >= b,\n '==': (a, b) => a === b,\n '!=': (a, b) => a !== b,\n};\n\nconst PREDICATES: Readonly<Record<string, (x: number) => boolean>> = {\n isFinite: (x) => Number.isFinite(x),\n isInteger: (x) => Number.isInteger(x),\n};\n\nfunction functionName(node: MathNode): string {\n return typeof node.fn === 'string' ? node.fn : (node.fn?.name ?? node.name ?? '');\n}\n\n/** Evaluate an arithmetic sub-tree through MathTS; the result must be a number. */\nfunction arithmetic(node: MathNode, source: string): Compiled {\n return (scope) => {\n let v: unknown;\n try {\n v = node.evaluate(scope);\n } catch (error) {\n throw new HoldsError(`${error instanceof Error ? error.message : String(error)} in ${source}`);\n }\n if (typeof v !== 'number') throw new HoldsError(`operand is not a number: ${node.toString()} in ${source}`);\n return v;\n };\n}\n\nfunction compile(node: MathNode, source: string): Compiled {\n switch (node.type) {\n case 'ParenthesisNode':\n return compile(node.content!, source);\n case 'ConstantNode':\n if (typeof node.value === 'boolean') return () => node.value as boolean;\n return arithmetic(node, source);\n case 'OperatorNode': {\n const op = node.op ?? '';\n const args = node.args ?? [];\n if (op === 'and' || op === 'or') {\n const parts = args.map((a) => compile(a, source));\n return (scope) => {\n const values = parts.map((p) => p(scope));\n if (values.some((v) => typeof v !== 'boolean')) throw new HoldsError(`'${op}' of a number in ${source}`);\n return op === 'and' ? values.every(Boolean) : values.some(Boolean);\n };\n }\n if (op === 'not') {\n const inner = compile(args[0]!, source);\n return (scope) => {\n const v = inner(scope);\n if (typeof v !== 'boolean') throw new HoldsError(`'not' of a number in ${source}`);\n return !v;\n };\n }\n const compare = COMPARISONS[op];\n if (compare !== undefined) {\n const [left, right] = args.map((a) => compile(a, source));\n return (scope) => {\n const a = left!(scope);\n const b = right!(scope);\n if (typeof a !== 'number' || typeof b !== 'number') throw new HoldsError(`'${op}' of a boolean in ${source}`);\n return compare(a, b);\n };\n }\n return arithmetic(node, source);\n }\n case 'FunctionNode': {\n const predicate = PREDICATES[functionName(node)];\n if (predicate !== undefined) {\n const arg = compile(node.args![0]!, source);\n return (scope) => {\n const v = arg(scope);\n if (typeof v !== 'number') throw new HoldsError(`${functionName(node)} of a boolean in ${source}`);\n return predicate(v);\n };\n }\n return arithmetic(node, source);\n }\n default:\n return arithmetic(node, source);\n }\n}\n\nconst COMPILED = new Map<string, Compiled>();\n\nfunction compiled(rewritten: string, source: string): Compiled {\n const hit = COMPILED.get(rewritten);\n if (hit !== undefined) return hit;\n let node: MathNode;\n try {\n node = parseMathTs(rewritten) as unknown as MathNode;\n } catch (error) {\n throw new HoldsError(`${error instanceof Error ? error.message : String(error)} in ${source}`);\n }\n const fn = compile(node, source);\n COMPILED.set(rewritten, fn);\n return fn;\n}\n\nconst IDENTIFIER = /[A-Za-z_][A-Za-z0-9_]*/g;\n\n/**\n * Whether `holds` is true for `values`.\n * Hyphenated quantity names are rewritten with `names` before parsing; an\n * unbound name, a non-boolean result, and a syntax error are a {@link HoldsError}.\n * A value whose name is one of `constants` and which the condition reads is\n * a {@link ConstantInputError}, a caller error and not a false condition,\n * unless `declared` names it; one the condition does not read is dropped, as\n * any other extra key is.\n */\nexport function holds(\n source: string,\n values: Readonly<Record<string, number>>,\n constants: Readonly<Record<string, number>>,\n names: readonly string[],\n declared: readonly string[] = [],\n): boolean {\n const rewritten = rewriteCatalogHyphens(source, names);\n const reads = new Set(rewritten.match(IDENTIFIER) ?? []);\n const scope: Scope = { ...constants };\n const allowed = new Set(declared.map((name) => name.replace(/-/g, '_')));\n for (const [key, value] of Object.entries(values)) {\n const name = key.replace(/-/g, '_');\n if (name in constants && !allowed.has(name)) {\n if (reads.has(name)) throw new ConstantInputError(key);\n continue;\n }\n scope[name] = value;\n }\n const result = compiled(rewritten, source)(scope);\n if (typeof result !== 'boolean') throw new HoldsError(`condition is not boolean: ${source}`);\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"holds.js","sourceRoot":"","sources":["../../src/bridges/holds.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Interpreter for a catalog validity condition.\n *\n * A condition is a boolean expression over quantity names, the registered\n * constants, `isFinite` and `isInteger`, written in MathTS's grammar\n * (`and`, `or`, `not`, `<`, `<=`, `>`, `>=`, `==`, `!=`). MathTS parses it,\n * and MathTS evaluates every arithmetic sub-expression. The comparisons and\n * the logical operators are evaluated here, exactly: MathTS's own comparison\n * operators are tolerance-based (`absTol` 1e-15), so under them `1e-18 > 0`\n * is false, which no condition over SI magnitudes can accept.\n *\n * It is not JavaScript `eval`.\n *\n * @module bridges/holds\n */\n\nimport { parse as parseMathTs } from '@danielsimonjr/mathts-functions';\nimport { rewriteCatalogHyphens } from '../dimensional/hyphen-names.js';\nimport { ConstantInputError } from './evaluation-errors.js';\nimport { expressionNames } from './expr-parse.js';\n\n/** A condition could not be evaluated: it names an unbound symbol, or its text does not parse. @internal */\nexport class HoldsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'HoldsError';\n }\n}\n\n/** The MathTS node shape this interpreter reads. */\ninterface MathNode {\n readonly type: string;\n readonly op?: string;\n readonly fn?: string | { readonly name?: string };\n readonly name?: string;\n readonly value?: unknown;\n readonly args?: readonly MathNode[];\n readonly content?: MathNode;\n evaluate(scope: Record<string, unknown>): unknown;\n}\n\ntype Scope = Record<string, number>;\ntype Compiled = (scope: Scope) => boolean | number;\n\nconst COMPARISONS: Readonly<Record<string, (a: number, b: number) => boolean>> = {\n '<': (a, b) => a < b,\n '<=': (a, b) => a <= b,\n '>': (a, b) => a > b,\n '>=': (a, b) => a >= b,\n '==': (a, b) => a === b,\n '!=': (a, b) => a !== b,\n};\n\nconst PREDICATES: Readonly<Record<string, (x: number) => boolean>> = {\n isFinite: (x) => Number.isFinite(x),\n isInteger: (x) => Number.isInteger(x),\n};\n\nfunction functionName(node: MathNode): string {\n return typeof node.fn === 'string' ? node.fn : (node.fn?.name ?? node.name ?? '');\n}\n\n/** Evaluate an arithmetic sub-tree through MathTS; the result must be a number. */\nfunction arithmetic(node: MathNode, source: string): Compiled {\n return (scope) => {\n let v: unknown;\n try {\n v = node.evaluate(scope);\n } catch (error) {\n throw new HoldsError(`${error instanceof Error ? error.message : String(error)} in ${source}`);\n }\n if (typeof v !== 'number') throw new HoldsError(`operand is not a number: ${node.toString()} in ${source}`);\n return v;\n };\n}\n\nfunction compile(node: MathNode, source: string): Compiled {\n switch (node.type) {\n case 'ParenthesisNode':\n return compile(node.content!, source);\n case 'ConstantNode':\n if (typeof node.value === 'boolean') return () => node.value as boolean;\n return arithmetic(node, source);\n case 'OperatorNode': {\n const op = node.op ?? '';\n const args = node.args ?? [];\n if (op === 'and' || op === 'or') {\n const parts = args.map((a) => compile(a, source));\n return (scope) => {\n const values = parts.map((p) => p(scope));\n if (values.some((v) => typeof v !== 'boolean')) throw new HoldsError(`'${op}' of a number in ${source}`);\n return op === 'and' ? values.every(Boolean) : values.some(Boolean);\n };\n }\n if (op === 'not') {\n const inner = compile(args[0]!, source);\n return (scope) => {\n const v = inner(scope);\n if (typeof v !== 'boolean') throw new HoldsError(`'not' of a number in ${source}`);\n return !v;\n };\n }\n const compare = COMPARISONS[op];\n if (compare !== undefined) {\n const [left, right] = args.map((a) => compile(a, source));\n return (scope) => {\n const a = left!(scope);\n const b = right!(scope);\n if (typeof a !== 'number' || typeof b !== 'number') throw new HoldsError(`'${op}' of a boolean in ${source}`);\n return compare(a, b);\n };\n }\n return arithmetic(node, source);\n }\n case 'FunctionNode': {\n const predicate = PREDICATES[functionName(node)];\n if (predicate !== undefined) {\n const arg = compile(node.args![0]!, source);\n return (scope) => {\n const v = arg(scope);\n if (typeof v !== 'number') throw new HoldsError(`${functionName(node)} of a boolean in ${source}`);\n return predicate(v);\n };\n }\n return arithmetic(node, source);\n }\n default:\n return arithmetic(node, source);\n }\n}\n\n/**\n * One conjunct of a validity condition: the text it is written in (the\n * relation's own names), the names it reads, and its test.\n * @internal\n */\nexport interface HoldsCondition {\n /** The conjunct as the condition states it, in the relation's names (`swing-kelvin >= 0`). */\n readonly text: string;\n /** The names it reads, in order of first use, as the relation spells them. */\n readonly names: readonly string[];\n /** True when the conjunct holds; a name it cannot bind, or a non-boolean result, throws {@link HoldsError}. */\n test(scope: Readonly<Record<string, number>>): boolean;\n}\n\n\n/**\n * The conjuncts of `node`: an `and` splits, `not (not X)` is X, `not (A or B)` is\n * `not A` and `not B`, and `not (x == y)` is `x != y`. Each rewrite is exact, so\n * the conjunction of the parts is the condition. Anything else is one conjunct.\n */\nfunction conjuncts(node: MathNode): MathNode[] {\n if (node.type === 'ParenthesisNode') return conjuncts(node.content!);\n if (node.type === 'OperatorNode' && node.op === 'and') return (node.args ?? []).flatMap(conjuncts);\n if (node.type === 'OperatorNode' && node.op === 'not') {\n let inner = node.args![0]!;\n while (inner.type === 'ParenthesisNode') inner = inner.content!;\n if (inner.type === 'OperatorNode' && inner.op === 'not') return conjuncts(inner.args![0]!);\n if (inner.type === 'OperatorNode' && inner.op === 'or') return (inner.args ?? []).flatMap((arg) => conjuncts(negation(arg)));\n if (inner.type === 'OperatorNode' && inner.op === '==') return [withOperator(inner, '!=')];\n }\n return [node];\n}\n\n/** `not X` as a node, so the rewrite above can recurse into it. */\nfunction negation(node: MathNode): MathNode {\n return parseMathTs(`not (${node.toString()})`) as unknown as MathNode;\n}\n\n/** `a op b` with the same operands. */\nfunction withOperator(node: MathNode, op: string): MathNode {\n const [a, b] = node.args!;\n return parseMathTs(`${a!.toString()} ${op} ${b!.toString()}`) as unknown as MathNode;\n}\n\n/** The symbol names a node reads, in order, without functions. */\nfunction symbolNames(node: MathNode): string[] {\n const out: string[] = [];\n const visit = (n: MathNode): void => {\n if (n.type === 'SymbolNode' && n.name !== undefined) {\n if (!out.includes(n.name)) out.push(n.name);\n return;\n }\n if (n.type === 'ParenthesisNode') visit(n.content!);\n for (const arg of n.args ?? []) visit(arg);\n };\n visit(node);\n return out;\n}\n\n/**\n * Replace each identifier `text` mentions through `rename`, whole-word, in one\n * pass (a renamed word is never renamed again). The identifiers are the ones\n * `expressionNames` reads (the text is a printed conjunct, already written\n * with underscores, so the rewrite it applies is the identity on it).\n */\nfunction renameIdentifiers(text: string, rename: (name: string) => string): string {\n const names = expressionNames(text);\n return text.replace(/[A-Za-z_][A-Za-z0-9_]*/g, (word) => (names.has(word) ? rename(word) : word));\n}\n\nconst CONDITIONS = new Map<string, readonly HoldsCondition[]>();\n\n/**\n * The conjuncts of the condition `source`, each testable alone. Their\n * conjunction is the condition, so a caller that tests them all decides\n * exactly what {@link holds} decides, and can say which part failed.\n * Hyphenated names are rewritten with `names` before parsing and restored in\n * each conjunct's `text` and `names`.\n * @internal\n */\nexport function holdsConditions(source: string, names: readonly string[]): readonly HoldsCondition[] {\n const rewritten = rewriteCatalogHyphens(source, names);\n const hit = CONDITIONS.get(rewritten);\n if (hit !== undefined) return hit;\n let root: MathNode;\n try {\n root = parseMathTs(rewritten) as unknown as MathNode;\n } catch (error) {\n throw new HoldsError(`${error instanceof Error ? error.message : String(error)} in ${source}`);\n }\n const spelled = new Map(names.map((name) => [name.replace(/-/g, '_'), name]));\n const restore = (name: string): string => spelled.get(name) ?? name;\n const parts = conjuncts(root).map((node): HoldsCondition => {\n const text = renameIdentifiers(node.toString(), restore);\n const fn = compile(node, text);\n return {\n text,\n names: symbolNames(node).map(restore),\n test: (scope) => {\n const result = fn({ ...scope });\n if (typeof result !== 'boolean') throw new HoldsError(`condition is not boolean: ${text}`);\n return result;\n },\n };\n });\n CONDITIONS.set(rewritten, parts);\n return parts;\n}\n\n/** The names (hyphens written as underscores) the conditions read. @internal */\nexport function conditionReads(conditions: readonly HoldsCondition[]): ReadonlySet<string> {\n return new Set(conditions.flatMap((condition) => condition.names.map((name) => name.replace(/-/g, '_'))));\n}\n\n/**\n * A scope for a condition: the constants, then `values` with hyphens written as\n * underscores. A value whose name is a constant that `declared` does not name\n * is a {@link ConstantInputError} when `reads` holds it, and is dropped otherwise.\n * @internal\n */\nexport function holdsScope(\n values: Readonly<Record<string, number>>,\n constants: Readonly<Record<string, number>>,\n reads: ReadonlySet<string>,\n declared: readonly string[] = [],\n): Record<string, number> {\n const scope: Record<string, number> = { ...constants };\n const allowed = new Set(declared.map((name) => name.replace(/-/g, '_')));\n for (const [key, value] of Object.entries(values)) {\n const name = key.replace(/-/g, '_');\n if (name in constants && !allowed.has(name)) {\n if (reads.has(name)) throw new ConstantInputError(key);\n continue;\n }\n scope[name] = value;\n }\n return scope;\n}\n\n/**\n * Whether `holds` is true for `values`: every conjunct of\n * {@link holdsConditions} holds. Hyphenated quantity names are rewritten with\n * `names` before parsing; an unbound name, a non-boolean result, and a syntax\n * error are a {@link HoldsError}.\n * A value whose name is one of `constants` and which the condition reads is\n * a {@link ConstantInputError}, a caller error and not a false condition,\n * unless `declared` names it; one the condition does not read is dropped, as\n * any other extra key is.\n */\nexport function holds(\n source: string,\n values: Readonly<Record<string, number>>,\n constants: Readonly<Record<string, number>>,\n names: readonly string[],\n declared: readonly string[] = [],\n): boolean {\n const conditions = holdsConditions(source, names);\n const scope = holdsScope(values, constants, conditionReads(conditions), declared);\n return conditions.every((condition) => condition.test(scope));\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notices.d.ts","sourceRoot":"","sources":["../../src/bridges/notices.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"notices.d.ts","sourceRoot":"","sources":["../../src/bridges/notices.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,EAAE,CAQnE"}
|
package/dist/bridges/notices.js
CHANGED
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
* @module bridges/notices
|
|
7
7
|
*/
|
|
8
8
|
import { constantNotes } from '../dimensional/symbolic-constants.js';
|
|
9
|
-
|
|
10
|
-
function identifiers(expression) {
|
|
11
|
-
return [...new Set(expression.match(/[A-Za-z_][A-Za-z0-9_]*/g) ?? [])];
|
|
12
|
-
}
|
|
9
|
+
import { expressionNames } from './expr-parse.js';
|
|
13
10
|
/** The caveats to print beside `relation`'s value. @internal */
|
|
14
11
|
export function relationNotices(relation) {
|
|
15
12
|
const notes = [];
|
|
16
13
|
if (relation.notice !== undefined)
|
|
17
14
|
notes.push(relation.notice.text);
|
|
18
|
-
|
|
15
|
+
// The names are read after the kebab rewrite: a bare identifier regex read be-39's
|
|
16
|
+
// `truncation-coefficient-b` as the constant `b`. A `reduced-planck-constant` spelling is
|
|
17
|
+
// `hbar` (tests/bridges/expression-names.test.ts).
|
|
18
|
+
for (const note of constantNotes(expressionNames(relation.expression)))
|
|
19
19
|
notes.push(`note: ${note}`);
|
|
20
20
|
return notes;
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notices.js","sourceRoot":"","sources":["../../src/bridges/notices.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"notices.js","sourceRoot":"","sources":["../../src/bridges/notices.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,gEAAgE;AAChE,MAAM,UAAU,eAAe,CAAC,QAAyB;IACvD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpE,mFAAmF;IACnF,0FAA0F;IAC1F,mDAAmD;IACnD,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACpG,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["/**\n * The caveats printed beside a relation's value: the record's own notice, and\n * the note of every registered constant its expression names. No caller\n * switches on a notice; the text is the record's or the constant's.\n *\n * @module bridges/notices\n */\n\nimport { constantNotes } from '../dimensional/symbolic-constants.js';\nimport type { CatalogRelation } from './catalog-types.js';\nimport { expressionNames } from './expr-parse.js';\n\n/** The caveats to print beside `relation`'s value. @internal */\nexport function relationNotices(relation: CatalogRelation): string[] {\n const notes: string[] = [];\n if (relation.notice !== undefined) notes.push(relation.notice.text);\n // The names are read after the kebab rewrite: a bare identifier regex read be-39's\n // `truncation-coefficient-b` as the constant `b`. A `reduced-planck-constant` spelling is\n // `hbar` (tests/bridges/expression-names.test.ts).\n for (const note of constantNotes(expressionNames(relation.expression))) notes.push(`note: ${note}`);\n return notes;\n}\n"]}
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { CarrierSignError } from './carrier-sign.js';
|
|
8
8
|
import type { CatalogRelation } from './catalog-types.js';
|
|
9
|
+
import { type ConditionDomain } from './validity.js';
|
|
9
10
|
/** Thrown when two carrier roles have opposite signs. */
|
|
10
11
|
export { CarrierSignError };
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* does not declare as a source throws `ConstantInputError`.
|
|
13
|
+
* The relation's validity domain, read from its `holds`: the predicate, the
|
|
14
|
+
* description and the violated conditions all come from that one text.
|
|
15
15
|
*/
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function relationDomain(rel: CatalogRelation): ConditionDomain;
|
|
17
17
|
/**
|
|
18
18
|
* The relation's number at `inputs`. The caller has already checked the
|
|
19
19
|
* validity condition. Opposite carrier signs throw {@link CarrierSignError}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relation-eval.d.ts","sourceRoot":"","sources":["../../src/bridges/relation-eval.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"relation-eval.d.ts","sourceRoot":"","sources":["../../src/bridges/relation-eval.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAA0B,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEtE,yDAAyD;AACzD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AA8D5B;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,eAAe,CAMpE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACvC,MAAM,CAiBR"}
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* @module bridges/relation-eval
|
|
6
6
|
*/
|
|
7
7
|
import { quantityRecord } from '../dimensional/quantity-registry.js';
|
|
8
|
+
import { withinSymmetric } from '../core/compare.js';
|
|
8
9
|
import { applyCarrierSignPolicy, CarrierSignError } from './carrier-sign.js';
|
|
9
10
|
import { evaluateFormula, formulaNames, formulaScope } from './expr-parse.js';
|
|
10
|
-
import {
|
|
11
|
+
import { conditionDomain } from './validity.js';
|
|
11
12
|
/** Thrown when two carrier roles have opposite signs. */
|
|
12
13
|
export { CarrierSignError };
|
|
13
14
|
const parityCache = new Map();
|
|
@@ -49,9 +50,9 @@ function classify(rel) {
|
|
|
49
50
|
}
|
|
50
51
|
if (!Number.isFinite(pos) || !Number.isFinite(neg))
|
|
51
52
|
continue;
|
|
52
|
-
|
|
53
|
-
const isEven =
|
|
54
|
-
const isOdd =
|
|
53
|
+
// The scale is max(|pos|, |neg|, 1): relative far from one, absolute near zero.
|
|
54
|
+
const isEven = withinSymmetric(pos, neg, 1e-8, 1);
|
|
55
|
+
const isOdd = withinSymmetric(pos, -neg, 1e-8, 1);
|
|
55
56
|
if (isEven && !isOdd)
|
|
56
57
|
even.push(name);
|
|
57
58
|
if (isOdd && !isEven) {
|
|
@@ -72,20 +73,18 @@ function classify(rel) {
|
|
|
72
73
|
parityCache.set(rel.id, found);
|
|
73
74
|
return found;
|
|
74
75
|
}
|
|
76
|
+
const domainCache = new Map();
|
|
75
77
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* does not declare as a source throws `ConstantInputError`.
|
|
78
|
+
* The relation's validity domain, read from its `holds`: the predicate, the
|
|
79
|
+
* description and the violated conditions all come from that one text.
|
|
79
80
|
*/
|
|
80
|
-
export function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
81
|
+
export function relationDomain(rel) {
|
|
82
|
+
const hit = domainCache.get(rel.id);
|
|
83
|
+
if (hit !== undefined)
|
|
84
|
+
return hit;
|
|
85
|
+
const domain = conditionDomain(rel.holds, formulaNames, formulaScope, rel.sources);
|
|
86
|
+
domainCache.set(rel.id, domain);
|
|
87
|
+
return domain;
|
|
89
88
|
}
|
|
90
89
|
/**
|
|
91
90
|
* The relation's number at `inputs`. The caller has already checked the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relation-eval.js","sourceRoot":"","sources":["../../src/bridges/relation-eval.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"relation-eval.js","sourceRoot":"","sources":["../../src/bridges/relation-eval.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Evaluate one catalog relation: validity condition, carrier-sign policy,\n * and the parsed expression. No per-equation branch.\n *\n * @module bridges/relation-eval\n */\n\nimport { quantityRecord } from '../dimensional/quantity-registry.js';\nimport { withinSymmetric } from '../core/compare.js';\nimport { applyCarrierSignPolicy, CarrierSignError } from './carrier-sign.js';\nimport type { CatalogRelation } from './catalog-types.js';\nimport { evaluateFormula, formulaNames, formulaScope } from './expr-parse.js';\nimport { conditionDomain, type ConditionDomain } from './validity.js';\n\n/** Thrown when two carrier roles have opposite signs. */\nexport { CarrierSignError };\n\nconst parityCache = new Map<string, { readonly even: readonly string[]; readonly pair?: { readonly charge: string; readonly mobility: string } }>();\n\nfunction named(rel: CatalogRelation, name: string): string {\n const alias = rel.aliases[name]?.[0];\n return alias === undefined ? name : `${name} (${alias})`;\n}\n\nfunction signRole(name: string): 'charge' | 'mobility' | undefined {\n return quantityRecord(name)?.signRole;\n}\n\nfunction sampleInputs(rel: CatalogRelation): Record<string, number> | null {\n if (rel.reference !== undefined) return { ...rel.reference.inputs };\n if (rel.sources.length === 0) return {};\n return null;\n}\n\nfunction classify(rel: CatalogRelation): { even: readonly string[]; pair?: { charge: string; mobility: string } } {\n const cached = parityCache.get(rel.id);\n if (cached !== undefined) return cached;\n const base = sampleInputs(rel);\n const even: string[] = [];\n const odd: { charge: string[]; mobility: string[] } = { charge: [], mobility: [] };\n if (base !== null) {\n for (const name of rel.sources) {\n const x = base[name];\n if (x === undefined || x === 0 || !Number.isFinite(x)) continue;\n const magnitude = Math.abs(x);\n let pos: number;\n let neg: number;\n try {\n pos = evaluateFormula(rel.expression, { ...base, [name]: magnitude }, rel.sources);\n neg = evaluateFormula(rel.expression, { ...base, [name]: -magnitude }, rel.sources);\n } catch {\n continue;\n }\n if (!Number.isFinite(pos) || !Number.isFinite(neg)) continue;\n // The scale is max(|pos|, |neg|, 1): relative far from one, absolute near zero.\n const isEven = withinSymmetric(pos, neg, 1e-8, 1);\n const isOdd = withinSymmetric(pos, -neg, 1e-8, 1);\n if (isEven && !isOdd) even.push(name);\n if (isOdd && !isEven) {\n const role = signRole(name);\n if (role === 'charge') odd.charge.push(name);\n if (role === 'mobility') odd.mobility.push(name);\n }\n }\n }\n const charge = odd.charge[0];\n const mobility = odd.mobility[0];\n const found = {\n even,\n ...(charge !== undefined && mobility !== undefined ? { pair: { charge, mobility } } : {}),\n };\n parityCache.set(rel.id, found);\n return found;\n}\n\nconst domainCache = new Map<string, ConditionDomain>();\n\n/**\n * The relation's validity domain, read from its `holds`: the predicate, the\n * description and the violated conditions all come from that one text.\n */\nexport function relationDomain(rel: CatalogRelation): ConditionDomain {\n const hit = domainCache.get(rel.id);\n if (hit !== undefined) return hit;\n const domain = conditionDomain(rel.holds, formulaNames, formulaScope, rel.sources);\n domainCache.set(rel.id, domain);\n return domain;\n}\n\n/**\n * The relation's number at `inputs`. The caller has already checked the\n * validity condition. Opposite carrier signs throw {@link CarrierSignError}.\n */\nexport function evaluateCatalogRelation(\n rel: CatalogRelation,\n inputs: Readonly<Record<string, number>>,\n): number {\n const policy = classify(rel);\n const pair = policy.pair;\n const adjusted = applyCarrierSignPolicy(\n null,\n inputs,\n new Set(policy.even),\n pair === undefined\n ? undefined\n : {\n a: inputs[pair.charge] ?? Number.NaN,\n b: inputs[pair.mobility] ?? Number.NaN,\n left: named(rel, pair.charge),\n right: named(rel, pair.mobility),\n },\n );\n return evaluateFormula(rel.expression, adjusted, rel.sources);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensitivity.d.ts","sourceRoot":"","sources":["../../src/bridges/sensitivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"sensitivity.d.ts","sourceRoot":"","sources":["../../src/bridges/sensitivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG5D,sCAAsC;AACtC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAgBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAQpH;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE,CASnE"}
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module bridges/sensitivity
|
|
9
9
|
*/
|
|
10
|
+
import { centralPartial } from '../numerical/finite-difference.js';
|
|
10
11
|
import { catalogConfrontations } from './catalog-load.js';
|
|
11
12
|
import { BRIDGE_EVALUATORS } from './evaluators.js';
|
|
12
13
|
function elasticityOf(predict, point, key) {
|
|
13
14
|
const x = point[key];
|
|
15
|
+
// Relative step 1e-6, absolute 1e-12 at x = 0: this reader's rule; the derivative is the shared one.
|
|
14
16
|
const h = Math.abs(x) * 1e-6 || 1e-12;
|
|
15
|
-
const up = { ...point, [key]: x + h };
|
|
16
|
-
const dn = { ...point, [key]: x - h };
|
|
17
17
|
const P = predict(point);
|
|
18
|
-
const dP = (predict
|
|
18
|
+
const dP = centralPartial(predict, point, key, h);
|
|
19
19
|
if (!(Number.isFinite(P) && P !== 0))
|
|
20
20
|
return 0;
|
|
21
21
|
return (Math.abs(dP) * Math.abs(x)) / Math.abs(P);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensitivity.js","sourceRoot":"","sources":["../../src/bridges/sensitivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAQpD,SAAS,YAAY,CACnB,OAAkD,EAClD,KAA6B,EAC7B,GAAW;IAEX,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAE,CAAC;IACtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;IACtC,MAAM,
|
|
1
|
+
{"version":3,"file":"sensitivity.js","sourceRoot":"","sources":["../../src/bridges/sensitivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAQpD,SAAS,YAAY,CACnB,OAAkD,EAClD,KAA6B,EAC7B,GAAW;IAEX,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAE,CAAC;IACtB,qGAAqG;IACrG,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;IACtC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IAClD,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,UAA6B,EAAE,MAA8B;IAC1G,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,4BAA4B,CAAC,CAAC;IAChG,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnF,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,+BAA+B,GAAG,2BAA2B,CAAC,CAAC;IAClI,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,MAAM,GAAG,GAAG,qBAAqB,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;IACjF,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACzF,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;IAClC,MAAM,KAAK,GAAG,EAAE,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,CAAC,MAA8B,EAAU,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACvG,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SACtB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;SAC7E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;AACjD,CAAC","sourcesContent":["/**\n * Deciding-measurement elasticity for value-kind confrontations. For each\n * input of a stored prediction point, report the dimensionless\n * log-sensitivity E_i = |∂P/∂x_i|·x_i/P of the number the record predicts.\n * This ranks which input the prediction depends on most strongly. It is not\n * an uncertainty budget.\n *\n * @module bridges/sensitivity\n */\n\nimport { centralPartial } from '../numerical/finite-difference.js';\nimport { catalogConfrontations } from './catalog-load.js';\nimport type { CatalogPrediction } from './catalog-types.js';\nimport { BRIDGE_EVALUATORS } from './evaluators.js';\n\n/** One input's elasticity. @public */\nexport interface Elasticity {\n readonly input: string;\n readonly elasticity: number;\n}\n\nfunction elasticityOf(\n predict: (point: Record<string, number>) => number,\n point: Record<string, number>,\n key: string,\n): number {\n const x = point[key]!;\n // Relative step 1e-6, absolute 1e-12 at x = 0: this reader's rule; the derivative is the shared one.\n const h = Math.abs(x) * 1e-6 || 1e-12;\n const P = predict(point);\n const dP = centralPartial(predict, point, key, h);\n if (!(Number.isFinite(P) && P !== 0)) return 0;\n return (Math.abs(dP) * Math.abs(x)) / Math.abs(P);\n}\n\n/**\n * The number a confrontation's prediction point yields: the evaluator's value\n * at the point, or the extra output the prediction names.\n * @internal\n */\nexport function predictedAt(catalogId: number, prediction: CatalogPrediction, inputs: Record<string, number>): number {\n const spec = BRIDGE_EVALUATORS.get(catalogId);\n if (spec === undefined) throw new Error(`confrontation ${catalogId}: no evaluator predicts it`);\n const result = spec.run(inputs, prediction.output === undefined ? 'value' : 'all');\n const key = prediction.output ?? 'value';\n const value = result[key];\n if (value === undefined) throw new Error(`confrontation ${catalogId}: the evaluator returns no '${key}' at the prediction point`);\n return value;\n}\n\n/**\n * Elasticity ranking for a value-kind confrontation that stores a prediction\n * point. `[]` when the record is not value-kind, has no point, or is absent.\n *\n * @public\n */\nexport function decidingMeasurement(catalogId: number): Elasticity[] {\n const row = catalogConfrontations().find((item) => item.catalogId === catalogId);\n if (row === undefined || row.kind !== 'value' || row.prediction === undefined) return [];\n const prediction = row.prediction;\n const point = { ...prediction.inputs };\n const predict = (inputs: Record<string, number>): number => predictedAt(catalogId, prediction, inputs);\n return Object.keys(point)\n .map((key) => ({ input: key, elasticity: elasticityOf(predict, point, key) }))\n .sort((a, b) => b.elasticity - a.elasticity);\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A validity domain read from one condition text, the record's `holds`.
|
|
3
|
+
*
|
|
4
|
+
* The condition is the single source: the predicate is the conjunction of its
|
|
5
|
+
* conjuncts, the description is those conjuncts written out, and a refusal
|
|
6
|
+
* lists only the conjuncts that failed, each rendered with the key the caller
|
|
7
|
+
* gave the input under. No record carries a second, prose statement of the
|
|
8
|
+
* same domain, so the message cannot contradict the check.
|
|
9
|
+
*
|
|
10
|
+
* @module bridges/validity
|
|
11
|
+
*/
|
|
12
|
+
import type { DomainViolation } from './evaluation-errors.js';
|
|
13
|
+
/** A domain built from a condition text. Structurally a `ValidityDomain`. @internal */
|
|
14
|
+
export interface ConditionDomain {
|
|
15
|
+
/** The conjuncts, in the relation's names, joined by `and`. */
|
|
16
|
+
readonly description: string;
|
|
17
|
+
readonly predicate: (inputs: Record<string, number>) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* The conjuncts `inputs` violate. `keyOf` names the caller's key for a name
|
|
20
|
+
* the relation reads (a parameter key for an evaluator source); a name it
|
|
21
|
+
* does not map is its own key.
|
|
22
|
+
*/
|
|
23
|
+
readonly violations: (inputs: Record<string, number>, keyOf?: (name: string) => string) => readonly DomainViolation[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The domain `text` states over `names` (the hyphenated quantity names it may
|
|
27
|
+
* read), with `constants()` bound. `'true'` is the domain with no condition.
|
|
28
|
+
* An input named for a constant that `declared` does not list, and that the
|
|
29
|
+
* condition reads, is a `ConstantInputError` (a caller error, not a false condition).
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export declare function conditionDomain(text: string, names: () => Iterable<string>, constants: () => Readonly<Record<string, number>>, declared?: readonly string[]): ConditionDomain;
|
|
33
|
+
//# sourceMappingURL=validity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validity.d.ts","sourceRoot":"","sources":["../../src/bridges/validity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,uFAAuF;AACvF,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC;IAChE;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,KAAK,SAAS,eAAe,EAAE,CAAC;CACvH;AAkBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,EAC7B,SAAS,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACjD,QAAQ,GAAE,SAAS,MAAM,EAAO,GAC/B,eAAe,CA8BjB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A validity domain read from one condition text, the record's `holds`.
|
|
3
|
+
*
|
|
4
|
+
* The condition is the single source: the predicate is the conjunction of its
|
|
5
|
+
* conjuncts, the description is those conjuncts written out, and a refusal
|
|
6
|
+
* lists only the conjuncts that failed, each rendered with the key the caller
|
|
7
|
+
* gave the input under. No record carries a second, prose statement of the
|
|
8
|
+
* same domain, so the message cannot contradict the check.
|
|
9
|
+
*
|
|
10
|
+
* @module bridges/validity
|
|
11
|
+
*/
|
|
12
|
+
import { conditionReads, holdsConditions, holdsScope, HoldsError } from './holds.js';
|
|
13
|
+
/** A conjunct fails when it is false or cannot be evaluated (an unbound name, a non-number). */
|
|
14
|
+
function fails(condition, scope) {
|
|
15
|
+
try {
|
|
16
|
+
return !condition.test(scope);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
if (error instanceof HoldsError)
|
|
20
|
+
return true;
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** `text` with each whole-word name it reads replaced by the caller's key. */
|
|
25
|
+
function rendered(condition, keyOf) {
|
|
26
|
+
const keys = new Map(condition.names.map((name) => [name, keyOf(name)]));
|
|
27
|
+
return condition.text.replace(/[A-Za-z_][A-Za-z0-9_-]*/g, (word) => keys.get(word) ?? word);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The domain `text` states over `names` (the hyphenated quantity names it may
|
|
31
|
+
* read), with `constants()` bound. `'true'` is the domain with no condition.
|
|
32
|
+
* An input named for a constant that `declared` does not list, and that the
|
|
33
|
+
* condition reads, is a `ConstantInputError` (a caller error, not a false condition).
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export function conditionDomain(text, names, constants, declared = []) {
|
|
37
|
+
let parts;
|
|
38
|
+
const conditions = () => (parts ??= holdsConditions(text, [...names()]));
|
|
39
|
+
const own = (name) => name;
|
|
40
|
+
return {
|
|
41
|
+
get description() {
|
|
42
|
+
return conditions().map((condition) => condition.text).join(' and ');
|
|
43
|
+
},
|
|
44
|
+
predicate: (inputs) => {
|
|
45
|
+
const scope = holdsScope(inputs, constants(), conditionReads(conditions()), declared);
|
|
46
|
+
return conditions().every((condition) => !fails(condition, scope));
|
|
47
|
+
},
|
|
48
|
+
violations: (inputs, keyOf = own) => {
|
|
49
|
+
const scope = holdsScope(inputs, constants(), conditionReads(conditions()), declared);
|
|
50
|
+
const constantNames = constants();
|
|
51
|
+
return conditions()
|
|
52
|
+
.filter((condition) => fails(condition, scope))
|
|
53
|
+
.map((condition) => {
|
|
54
|
+
const read = condition.names
|
|
55
|
+
.filter((name) => !Object.hasOwn(constantNames, name.replace(/-/g, '_')) || Object.hasOwn(inputs, name))
|
|
56
|
+
.map((name) => ({ key: keyOf(name), quantity: name, value: inputs[name] ?? Number.NaN }));
|
|
57
|
+
return {
|
|
58
|
+
condition: rendered(condition, keyOf),
|
|
59
|
+
key: read[0]?.key ?? '',
|
|
60
|
+
value: read[0]?.value ?? Number.NaN,
|
|
61
|
+
inputs: read,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=validity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validity.js","sourceRoot":"","sources":["../../src/bridges/validity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAuB,MAAM,YAAY,CAAC;AAe1G,gGAAgG;AAChG,SAAS,KAAK,CAAC,SAAyB,EAAE,KAAuC;IAC/E,IAAI,CAAC;QACH,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,UAAU;YAAE,OAAO,IAAI,CAAC;QAC7C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAS,QAAQ,CAAC,SAAyB,EAAE,KAA+B;IAC1E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AAC9F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,KAA6B,EAC7B,SAAiD,EACjD,QAAQ,GAAsB,EAAE;IAEhC,IAAI,KAA4C,CAAC;IACjD,MAAM,UAAU,GAAG,GAA8B,EAAE,CAAC,CAAC,KAAK,KAAK,eAAe,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACpG,MAAM,GAAG,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC;IAC3C,OAAO;QACL,IAAI,WAAW;YACb,OAAO,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvE,CAAC;QACD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YACpB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACtF,OAAO,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,UAAU,EAAE,CAAC,MAAM,EAAE,KAAK,GAAG,GAAG,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACtF,MAAM,aAAa,GAAG,SAAS,EAAE,CAAC;YAClC,OAAO,UAAU,EAAE;iBAChB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;iBAC9C,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;gBACjB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK;qBACzB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;qBACvG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC5F,OAAO;oBACL,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;oBACrC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE;oBACvB,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG;oBACnC,MAAM,EAAE,IAAI;iBACb,CAAC;YACJ,CAAC,CAAC,CAAC;QACP,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * A validity domain read from one condition text, the record's `holds`.\n *\n * The condition is the single source: the predicate is the conjunction of its\n * conjuncts, the description is those conjuncts written out, and a refusal\n * lists only the conjuncts that failed, each rendered with the key the caller\n * gave the input under. No record carries a second, prose statement of the\n * same domain, so the message cannot contradict the check.\n *\n * @module bridges/validity\n */\n\nimport type { DomainViolation } from './evaluation-errors.js';\nimport { conditionReads, holdsConditions, holdsScope, HoldsError, type HoldsCondition } from './holds.js';\n\n/** A domain built from a condition text. Structurally a `ValidityDomain`. @internal */\nexport interface ConditionDomain {\n /** The conjuncts, in the relation's names, joined by `and`. */\n readonly description: string;\n readonly predicate: (inputs: Record<string, number>) => boolean;\n /**\n * The conjuncts `inputs` violate. `keyOf` names the caller's key for a name\n * the relation reads (a parameter key for an evaluator source); a name it\n * does not map is its own key.\n */\n readonly violations: (inputs: Record<string, number>, keyOf?: (name: string) => string) => readonly DomainViolation[];\n}\n\n/** A conjunct fails when it is false or cannot be evaluated (an unbound name, a non-number). */\nfunction fails(condition: HoldsCondition, scope: Readonly<Record<string, number>>): boolean {\n try {\n return !condition.test(scope);\n } catch (error) {\n if (error instanceof HoldsError) return true;\n throw error;\n }\n}\n\n/** `text` with each whole-word name it reads replaced by the caller's key. */\nfunction rendered(condition: HoldsCondition, keyOf: (name: string) => string): string {\n const keys = new Map(condition.names.map((name) => [name, keyOf(name)]));\n return condition.text.replace(/[A-Za-z_][A-Za-z0-9_-]*/g, (word) => keys.get(word) ?? word);\n}\n\n/**\n * The domain `text` states over `names` (the hyphenated quantity names it may\n * read), with `constants()` bound. `'true'` is the domain with no condition.\n * An input named for a constant that `declared` does not list, and that the\n * condition reads, is a `ConstantInputError` (a caller error, not a false condition).\n * @internal\n */\nexport function conditionDomain(\n text: string,\n names: () => Iterable<string>,\n constants: () => Readonly<Record<string, number>>,\n declared: readonly string[] = [],\n): ConditionDomain {\n let parts: readonly HoldsCondition[] | undefined;\n const conditions = (): readonly HoldsCondition[] => (parts ??= holdsConditions(text, [...names()]));\n const own = (name: string): string => name;\n return {\n get description() {\n return conditions().map((condition) => condition.text).join(' and ');\n },\n predicate: (inputs) => {\n const scope = holdsScope(inputs, constants(), conditionReads(conditions()), declared);\n return conditions().every((condition) => !fails(condition, scope));\n },\n violations: (inputs, keyOf = own) => {\n const scope = holdsScope(inputs, constants(), conditionReads(conditions()), declared);\n const constantNames = constants();\n return conditions()\n .filter((condition) => fails(condition, scope))\n .map((condition) => {\n const read = condition.names\n .filter((name) => !Object.hasOwn(constantNames, name.replace(/-/g, '_')) || Object.hasOwn(inputs, name))\n .map((name) => ({ key: keyOf(name), quantity: name, value: inputs[name] ?? Number.NaN }));\n return {\n condition: rendered(condition, keyOf),\n key: read[0]?.key ?? '',\n value: read[0]?.value ?? Number.NaN,\n inputs: read,\n };\n });\n },\n };\n}\n"]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { sym } from '../../dimensional/ast-builders.js';
|
|
2
|
-
import { MASS, VELOCITY, ENERGY, LENGTH, AREA, ACTION, CHARGE, FREQUENCY, DIMENSIONLESS, } from '../../dimensional/types.js';
|
|
2
|
+
import { MASS, VELOCITY, ENERGY, LENGTH, AREA, ACTION, CHARGE, FREQUENCY, DIMENSIONLESS, PERMITTIVITY, MOMENTUM, } from '../../dimensional/types.js';
|
|
3
3
|
import { dim, op, pow, l1 } from './_l1-build.js';
|
|
4
|
-
const PERMITTIVITY = dim(-3, -1, 4, 2); // ε₀ [L⁻³ M⁻¹ T⁴ I²]
|
|
5
4
|
const MAGNETIC_MOMENT = dim(2, 0, 0, 1); // [L² I] (A·m²)
|
|
6
|
-
const MOMENTUM = dim(1, 1, -1); // [L M T⁻¹]
|
|
7
5
|
export const ATOMIC = [
|
|
8
6
|
l1({ name: 'rydberg-energy', dim: ENERGY }, [
|
|
9
7
|
{ name: 'm_e', dim: MASS },
|