Physlib.Units.UnitSystem
Unit systems, parametrised in a dimension basis
A **unit system** is the everyday physics object: a rule fixing one concrete unit for each base quantity. SI fixes the metre for length, the second for time, the kilogram for mass, …; CGS fixes the centimetre, second and gram. Choosing a system gives every quantity a numerical value; changing systems rescales those values.
This module makes that notion work for *any* dimension basis `B` (matching the basis-generic `Dimension B`), while keeping units *typed*: the unit in the length slot has type `LengthUnit`, the one in the time slot `TimeUnit`, so the checker rejects a mass unit in a length slot.
* `UnitMagnitudeCatalog B` — the **menu** for basis `B`. For each base dimension `b : B` it gives a *type* `Unit b` of admissible units — so a dimension may offer many (length: metre, kilometre, micrometre, …) — and a *function* `mag` assigning each unit its one positive-real magnitude. The menu lists the options and picks none; many unit systems share one catalog. * `UnitSystem B` — the **pick**: a function choosing *exactly one* unit per base dimension. A single unit system therefore fixes one length unit — metre *or* kilometre, never both — so metre and kilometre are two menu entries selected by two different `UnitSystem`s over the same catalog. SI and CGS are two such picks. * `UnitSystem.toScale : UnitSystem B → UnitScale B` — forget the unit *types*, keep only the magnitudes, landing in the bare magnitude layer `UnitScale B` where the scaling homomorphism `UnitScale.dimScale` is proved once.
**Menu vs. pick.** The catalog is a menu, not a choice: it says which units exist and what each weighs, but selects none — a `UnitSystem` makes the selection. And in PhysLib a base unit *is* a positive real (`{ val : ℝ // 0 < val }`), i.e. its own magnitude, so the magnitude comes fixed with the unit; there is no separate "assign a magnitude" step. Hence metre, micrometre and kilometre are three *different* units on the one length menu, and "SI in metres" versus "the same in micrometres" are two different `UnitSystem`s over the **same** catalog — related by `UnitScale.dimScale`, which computes the 10⁶ factor between them. (The multiplicity one might expect from "many magnitudes" lives here, among the unit systems, not in many catalogs.)
The `LTMCTDimensionBase` catalog recovers PhysLib's five named unit types, and `LTMCTUnitChoices ≃ UnitSystem LTMCTDimensionBase` exhibits the bespoke five-field record as that instance. Scaling laws are **not** re-proved here — they live once on `UnitScale B`, and the typed layer is a thin faithful wrapper projecting onto it via `toScale`.
This is the typed, basis-generic layer discussed as "Option D" in the review of the dimension-parametrisation PR; it is the only design that keeps *both* basis-genericity and typed-unit safety.
The `LTMCTDimensionBase` catalog
The default basis's `UnitMagnitudeCatalog` recovers exactly PhysLib's five named typed unit types, so `UnitSystem LTMCTDimensionBase` is the typed five-slot unit system and `u .length : LengthUnit`, `LengthUnit.meters`, … all still work — and a `MassUnit` cannot be placed in the length slot.
`LTMCTUnitChoices` is `UnitSystem LTMCTDimensionBase`
The bespoke five-field record and the generic unit system over the default basis carry the same data.
The bespoke scaling law is the generic fold
`LTMCTUnitChoices.dimScale` — the five explicit `rpow` factors written out by hand in `Basic.lean` — is exactly the generic `UnitScale.dimScale` fold (a `Finset.prod` over the basis) at the `LTMCTDimensionBase` instance, applied to `toScale`. This is what makes the typed layer a *faithful* wrapper rather than a second, independent statement of the scaling law: there is one source of truth, the generic fold on `UnitScale B`.
9 declarations
Unit system over a dimension basis
Given a dimension basis and a unit magnitude catalog that provides a type of units for each base dimension , a **unit system** is defined as a function that maps each base dimension to a specific unit of type . This structure serves as the formal representation of physical unit systems such as SI or CGS, ensuring that for every base dimension, exactly one unit is chosen from the available options in the catalog.
Extensionality of Unit Systems:
Let be a dimension basis. For any two unit systems and over , if they select the same unit for every base dimension (i.e., for all ), then the unit systems are equal ().
Unit scale of a unit system
The function maps a unit system over a dimension basis to its corresponding `UnitScale B`. For each base dimension , the resulting scale value is the numerical magnitude of the unit chosen by the system. This transformation effectively "forgets" the specific unit types associated with the system and retains only their positive real magnitudes.
The scale value equals the magnitude
Let be a dimension basis and be a unit system over . For any base dimension , the numerical scale value of the unit system at , denoted by , is equal to the magnitude of the unit chosen by the system for that dimension, denoted by .
Unit magnitude catalog for the LTMCT dimension basis
The `UnitMagnitudeCatalog` instance for the basis of physical dimensions consisting of length, time, mass, charge, and temperature (LTMCT). For each dimension in the basis , the catalog specifies the set of available units as the types `LengthUnit`, `TimeUnit`, `MassUnit`, `ChargeUnit`, and `TemperatureUnit`, respectively. The magnitude function maps a unit to its underlying numerical value in .
The equivalence establishes that the bespoke record type containing five fields (length, time, mass, charge, and temperature) and the generic unit system defined over the LTMCT dimension basis represent the same data. The mapping identifies the record fields , , , , and with the values of a function applied to the corresponding elements of the basis .
For any choice of base units represented by the record type `LTMCTUnitChoices`, the `UnitScale` obtained by viewing as a generic unit system (via the equivalence ) and then projecting it to its numerical magnitudes is equal to the scale obtained through the specific `toScale` function defined for `LTMCTUnitChoices`. That is, .
The product over `LTMCTDimensionBase` equals the product of its five components
Let be a commutative monoid and be a function. The product of over all elements in the set of base dimensions is equal to the product of the function values for each specific dimension in their canonical order:
Bespoke LTMCT scaling factor equals generic magnitude-layer scaling
For any two unit systems and represented as `LTMCTUnitChoices` (which define specific units for length, time, mass, charge, and temperature) and for any physical dimension in the basis, the bespoke scaling factor is equal to the generic scaling factor calculated at the magnitude layer. This result establishes that the explicitly defined five-factor scaling law matches the general basis-generic product definition.
