feat(Units): parameterise Dimension and its unit twin over a basis (Stacked on #1445)#1447
Conversation
|
Thank you for this PR, which will now be reviewed. If submitting to ./Physlib or ./QuantumInfo, please see our review guidelines if you are not familiar with the process. You should expect a back and forth with a reviewer before your PR is merged. See also that link for how to add appropriate labels to your PR. The PR will also go through a number of automated checks. You can learn more about these here, including how to run them locally. If you are submitting to ./PhyslibAlpha there will be a lighter review process, though your PR must still pass the automated checks. If you want to bring attention to this PR, please write a message on this thread of the Lean Zulip. Important: If a reviewer adds an |
|
Note on dependencies and review order. This PR is stacked on #1445 (the v4.32.0 toolchain bump). Since it targets master, the first two commits — 48fad30 and 978ce09 — belong to #1445 and will drop out of this diff automatically once #1445 merges. The substantive change here is the final commit, 97c70b5 (feat(Units): parameterise Dimension and its unit twin over a basis); that's the one to review. Because of that dependency:
Since the original issue arose in the context of my metrology work which depends on Caltech's TorchLean that already migrated to 4.32.0, I chose to stack this PR on top of #1445. |
b07d0f0 to
8d8ab24
Compare
|
-awaiting-author Separate from the toolchain fix — a naming question raised in review. It came to me by email and I couldn't find it in the PR comments, so I'm recording it here for visibility:
For context: this is I named it after its provenance rather than generically because this basis is a specific, deliberate choice, not a neutral or canonical one. It is charge-based with five generators, so it is not the SI/ISQ base-quantity set (which takes electric current as base and adds amount of substance and luminous intensity); ISQ, Gaussian–CGS, natural units, and the angle-augmented system are other instantiations of The previous unparameterised That said, I'm very open to renaming it. My one constraint is that the name should still signal "a specific, non-ISQ choice of base quantities" rather than implying a canonical basis. If there's a preferred convention — or a good descriptive name for this charge-based, five-generator set — I'll gladly adopt it. Suggestions welcome. |
|
Thanks @nateabr for the retitle (and the Stacked on #1445 note — that's the right base). Want to confirm scope before I build anything further, since "and its unit twin" could mean two things. What's in the PR today is additive: The existing five-field The open question is whether you also want to parameterise A — Keep the bridge (status quo).
B — Consolidate the proofs, keep the API.Leave the
C — Make
|
|
Hey @NicolasRouquette, please give me a bit to go through the details of your PR and your comment and I will get back to you. Many apologies for the delay |
|
The core abstraction you have done with parametric Dimension B, PhyslibBase, and backward compat layer looks clean and I'm happy with the math and the proofs. However, the three new files (BasisExamples, ParametricDimensionExamples, ParametricUnits) and the extend/single API have no current use at the moment and seem to be illustrative. My first thought would be to focus the PR to the core parts. However, even with regards to the core abstraction you have provided; I see the utility in having a parametric type that we could possibly instantiate with a different basis in the future. But purely from a maintenance perspective, this does add complexity to the core dimension type. Furthermore, if the motivation for this PR does lie in a downstream repo, would it make sense for this machinery to live in that repo and not Physlib? That being said, I do believe I am unable to provide you with a constructive review at the moment, the above is more of my thoughts out loud. So I would say hold off on any changes and wait for a better look from a maintainer. |
|
Thanks @nateabr for the feedback. There were already several examples in the public import Physlib.QuantumMechanics.HarmonicOscillator.OneDimension.Examples
public import Physlib.QuantumMechanics.Operators.Examples
public import Physlib.Units.BasisExamples
public import Physlib.Units.Examples
public import Physlib.Units.ParametricDimensionExamplesIf someone can provide guidance where to move the unit-related examples, e.g., a |
|
I think for the units examples we could put them in .Units/Examples for now. Will hopefully get chance to look at this tomorrow. But generally I think the concept of this is good, and should be included. |
|
Would it be possible to rebase this so only the relevant changes are shown? Also I think a PhyslibBase could have a better more physical name if still called that |
Address the parametric-basis API requested in leanprover-community#1441. `Dimension` gains a basis parameter `B`; PhysLib's current charge-based five-generator basis is recovered as `Dimension PhyslibBase`, whose named projections and `@[simp]` lemmas are preserved so all existing results build unchanged. Dimension core (generic in `B`): - `structure Dimension (B)`, with `CommGroup` and `ℚ`-power for every `B`; - `DecidableEq (Dimension B)` for finite `B`; - generic base vectors `Dimension.single b` (with `L𝓭 = single .length`, …); - change of basis `Dimension.extend` along an embedding `B ↪ B'`. Unit twin (generic in `B`) — the second hardwired copy leanprover-community#1441 flags: - `UnitScale B` (a positive-real magnitude per base) and `UnitScale.dimScale : UnitScale B → UnitScale B → Dimension B →* ℝ≥0`, the fold `d ↦ ∏ b, (u₁ b / u₂ b) ^ d.exponent b`; - `UnitChoices.toScale` exhibits the current five-field `UnitChoices` as the `PhyslibBase` instance. Worked instantiations (`Physlib/Units/BasisExamples.lean`): the ISQ seven base quantities (current-based, with amount of substance and luminous intensity), Gaussian–CGS (charge derived `M^(1/2)·L^(3/2)·T^(-1)`), natural units (`c = ħ = 1`), and an angle-augmented basis (`sr = rad²`). `WithDim` is parametric over the basis, and `WithDim.cast` resolves the comparison of propositionally-equal dimensions (see `Physlib/Units/ParametricDimensionExamples.lean`). Co-authored-by: Claude Opus 4.8 <no-reply+claude-opus-4-8@anthropic.com>
8d8ab24 to
de9d6a2
Compare
|
Thanks @jstoobysmith. Done on the first point, and a pointer on the second. Rebased to reduce the scope. #1445 landed on master (squashed as c217bdd), so I rebased this branch onto current master. The four v4.32.0 bump-chain commits dropped out — they're already in master — leaving a single feature commit. The PR now shows only the parametric change: 9 files under Physlib/Units/ (Dimension, Basic, UnitDependent, WithDim/Basic, Integral, the new ParametricUnits/BasisExamples/ParametricDimensionExamples, and the Physlib.lean imports), with no toolchain collateral. The feature patch itself is unchanged — only the base moved. On the name. Agreed that |
|
awaiting-author |
…dimension-preserving base maps Responds to review on leanprover-community#1447: - Rename PhyslibBase -> LTMCTDimensionBase (after its five base dimensions length/time/mass/charge/temperature); move it, its projections and named generators into Physlib/Units/LTMCTDimensionBase.lean. Dimension.lean keeps only the generic parametric algebra. - Replace the illustrative example modules with one reference module, Physlib/Units/ISQDimensionBase.lean: the seven ISO/IEC 80000-1 (VIM 3) base quantities, with cardinality/derived-charge/independence lemmas. - Add Dimension.Embedding (injective MonoidHom) and Dimension.Projection (surjective MonoidHom) as truth-preserving requirements for maps between dimension bases, so dimension-preservation holds by construction. - Add Physlib/Units/ISQBridge.lean: ltmctToISQ embedding (charge |-> I*T), isqToLTMCT projection (current |-> charge/time; drop amount & luminous), and the retraction isqToLTMCT . ltmctToISQ = id. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thank you @jstoobysmith for the careful, constructive review — it genuinely sharpened both the scope and the design. Two of your observations reshaped the PR: 1. Two concrete bases instead of illustrative examples. You were right that the example modules carried no weight. I removed them and kept exactly two instantiations:
2. Truth-preserving maps between bases, enforced by construction. This is where I'd argue from metrology. Relating two systems of quantities is not a relabelling of base symbols: base-vs-derived is a choice the system makes, not a property of the quantity. Electric charge is a base dimension in the LTMCT system but the derived So I made the admissible maps first-class, as bundled requirements on
Requiring a Green across the full build and the style/meta linters. Happy to iterate. |
|
-awaiting-author |
jstoobysmith
left a comment
There was a problem hiding this comment.
Approved - many thanks. Will merge shortly.
Closes #1441 — makes
Dimension's base-dimension set parametric, and moves the unit-side twin (UnitChoices/dimScale) with it, as the issue requires.Thanks to Daniel Morrison for a very useful and constructive design discussion on the Physlib Zulip that shaped this.
This builds on #1445 (the v4.32.0 bump); the substantive change is the final commit,
feat(Units): parameterise Dimension and its unit twin over a basis.Requirements coverage (from the issue)
Already satisfied — preserved by the generic API
exponent : B → ℚ,Pow (Dimension B) ℚinstance : CommGroup (Dimension B)for everyB@[ext] Dimension.extCore — parametrise the generating set
Dimensionparametric in a basisB—structure Dimension (B)CommGroup/ℚ-power derived generically for everyBDecidableEq (Dimension B)for finiteB—instance [Fintype B] : DecidableEq (Dimension B)b : B—Dimension.single b, withL𝓭 = single .length, … (*_eq_single)dimScalefolds overB—UnitScale BandUnitScale.dimScale : UnitScale B → UnitScale B → Dimension B →* ℝ≥0(d ↦ ∏ b, (u₁ b / u₂ b) ^ d.exponent b);UnitChoices.toScaleexhibits the current five-fieldUnitChoicesas thePhyslibBaseinstanceBackward compatibility
Dimension PhyslibBaseoverPhyslibBase = {length, time, mass, charge, temperature}(neutrally named; charge-based, i.e. not the SI/ISQ set).length, …) and@[simp]lemmas preserved — every existingUnits/result builds unchanged (full build: 9238 jobs)Coverage — the motivating quantity systems (
Physlib/Units/BasisExamples.lean)M^(1/2)·L^(3/2)·T^(-1)c = ħ = 1, a single generator (length = time =mass⁻¹)sr = rad²)Optional / stretch
B ↪ B'—Dimension.extend(exponent-preserving on an embedding), with aPhyslibBase ↪angle-augmented demoDesign decisions on the issue's open questions
B → ℚvsB →₀ ℚ— total function (structure Dimension (B) where exponent : B → ℚ);Fintype Bis required only where a fold is taken (dimScale,DecidableEq). This keeps the dimension-comparison cast (below) ergonomic.Dimension; the current type is recovered asDimension PhyslibBasewith the projections re-exposed (the issue's "thin wrapper" path), so nothing downstream changes.PhyslibBase) for theHasDim/CarriesDimensioncarrier layer, with parametricity available to separate developments and to the other bases above. (So the unit-scaling carrier still shares one basis; per-type mixed bases are not introduced.)c = ħ = 1) — modelled by choosing a smaller basis and deriving the rest (seeNatural), the first option the issue lists.Dimension comparison
WithDimis parametric over the basis. A quantity of dimensionlengthand a product of quantities of dimensionlength/timeandtimehave propositionally but not definitionally equal dimensions (rflanddecideboth fail — the equality is group cancellation over ℚ exponents).WithDim.castbridges the two types, discharging the equality automatically; seePhyslib/Units/ParametricDimensionExamples.lean.Checks
lake build(Physlib + QuantumInfo): 9238 jobs, 0 errors / 0 warnings / 0sorry.lint-style.pyandlake exe lint_allclean on all changed files. No new axioms beyondpropext/Classical.choice/Quot.sound; nosorryAx.AI-assisted per the repository's AI policy; commits carry the
Co-authored-bytrailer.