Imports
/- Copyright (c) 2026 Nicolas Rouquette. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Nicolas Rouquette -/ module public import Physlib.Units.LTMCTDimensionBase public import Physlib.Units.ISQDimensionBase

Bridging PhysLib's default basis and the ISQ basis

LTMCTDimensionBase (length, time, mass, charge, temperature) and ISQDimensionBase (the seven ISO/IEC 80000-1 base quantities) make different base/derived choices. This module relates them by the two truth-preserving directions of Dimension.Embedding and Dimension.Projection:

    ltmctToISQ : Dimension.Embedding LTMCTDimensionBase ISQDimensionBase β€” the dimension-preserving inclusion of PhysLib dimensions into ISQ dimensions. It sends the charge generator to the derived ISQ charge I Β· T (toISQHom_C𝓭), so it is faithful (toISQHom_injective) and physically correct, not a bare relabelling.

    isqToLTMCT : Dimension.Projection ISQDimensionBase LTMCTDimensionBase β€” the truth-preserving reduction of ISQ dimensions onto PhysLib's. It reads electric current as charge/time and forgets amount of substance and luminous intensity (the base quantities PhysLib does not track).

The two fit together as a retraction, isqToLTMCT ∘ ltmctToISQ = id (isqToLTMCT_comp_ltmctToISQ): PhysLib's basis embeds faithfully into ISQ and is recovered exactly by the projection β€” but the reverse composite is not the identity, because amount of substance and luminous intensity cannot be recovered once dropped. That is the asymmetry: one can reduce ISQ to LTMCT, but not conjure the extra base quantities back without adding them.

@[expose] public section

The function underlying toISQHom: fix length, mass, time and temperature, and send PhysLib's charge generator to the derived ISQ charge I Β· T (the current exponent is the charge exponent, and the time exponent absorbs it).

The dimension-preserving embedding of PhysLib dimensions into the ISQ dimensions.

def toISQHom : Dimension LTMCTDimensionBase β†’* Dimension ISQDimensionBase where toFun := toISQFun map_one' := ⊒ toISQFun 1 = 1 b:ISQDimensionBase⊒ (toISQFun 1).exponent b = exponent 1 b; ⊒ (toISQFun 1).exponent ISQDimensionBase.length = exponent 1 ISQDimensionBase.length⊒ (toISQFun 1).exponent ISQDimensionBase.mass = exponent 1 ISQDimensionBase.mass⊒ (toISQFun 1).exponent ISQDimensionBase.time = exponent 1 ISQDimensionBase.time⊒ (toISQFun 1).exponent ISQDimensionBase.current = exponent 1 ISQDimensionBase.current⊒ (toISQFun 1).exponent ISQDimensionBase.temperature = exponent 1 ISQDimensionBase.temperature⊒ (toISQFun 1).exponent ISQDimensionBase.amount = exponent 1 ISQDimensionBase.amount⊒ (toISQFun 1).exponent ISQDimensionBase.luminousIntensity = exponent 1 ISQDimensionBase.luminousIntensity ⊒ (toISQFun 1).exponent ISQDimensionBase.length = exponent 1 ISQDimensionBase.length⊒ (toISQFun 1).exponent ISQDimensionBase.mass = exponent 1 ISQDimensionBase.mass⊒ (toISQFun 1).exponent ISQDimensionBase.time = exponent 1 ISQDimensionBase.time⊒ (toISQFun 1).exponent ISQDimensionBase.current = exponent 1 ISQDimensionBase.current⊒ (toISQFun 1).exponent ISQDimensionBase.temperature = exponent 1 ISQDimensionBase.temperature⊒ (toISQFun 1).exponent ISQDimensionBase.amount = exponent 1 ISQDimensionBase.amount⊒ (toISQFun 1).exponent ISQDimensionBase.luminousIntensity = exponent 1 ISQDimensionBase.luminousIntensity All goals completed! πŸ™ map_mul' d1 d2 := d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun = d1.toISQFun * d2.toISQFun d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseb:ISQDimensionBase⊒ (d1 * d2).toISQFun.exponent b = (d1.toISQFun * d2.toISQFun).exponent b d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.length = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.lengthd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.mass = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.massd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.time = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.timed1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.current = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.currentd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.temperature = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.temperatured1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.amount = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.amountd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.luminousIntensity = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.luminousIntensity d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.length = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.lengthd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.mass = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.massd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.time = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.timed1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.current = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.currentd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.temperature = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.temperatured1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.amount = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.amountd1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ (d1 * d2).toISQFun.exponent ISQDimensionBase.luminousIntensity = (d1.toISQFun * d2.toISQFun).exponent ISQDimensionBase.luminousIntensity d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBase⊒ 0 = 0 + 0 all_goals All goals completed! πŸ™

toISQHom applied to a dimension is toISQFun.

lemma toISQHom_apply (d : Dimension LTMCTDimensionBase) : toISQHom d = toISQFun d := rfl

The function underlying fromISQHom: fix length, mass and temperature, read electric current as charge/time (the charge exponent is the current exponent, and the time exponent subtracts it), and drop amount of substance and luminous intensity.

The truth-preserving reduction of ISQ dimensions onto PhysLib's.

def fromISQHom : Dimension ISQDimensionBase β†’* Dimension LTMCTDimensionBase where toFun := fromISQFun map_one' := ⊒ fromISQFun 1 = 1 b:LTMCTDimensionBase⊒ (fromISQFun 1).exponent b = exponent 1 b; ⊒ (fromISQFun 1).exponent LTMCTDimensionBase.length = exponent 1 LTMCTDimensionBase.length⊒ (fromISQFun 1).exponent LTMCTDimensionBase.time = exponent 1 LTMCTDimensionBase.time⊒ (fromISQFun 1).exponent LTMCTDimensionBase.mass = exponent 1 LTMCTDimensionBase.mass⊒ (fromISQFun 1).exponent LTMCTDimensionBase.charge = exponent 1 LTMCTDimensionBase.charge⊒ (fromISQFun 1).exponent LTMCTDimensionBase.temperature = exponent 1 LTMCTDimensionBase.temperature ⊒ (fromISQFun 1).exponent LTMCTDimensionBase.length = exponent 1 LTMCTDimensionBase.length⊒ (fromISQFun 1).exponent LTMCTDimensionBase.time = exponent 1 LTMCTDimensionBase.time⊒ (fromISQFun 1).exponent LTMCTDimensionBase.mass = exponent 1 LTMCTDimensionBase.mass⊒ (fromISQFun 1).exponent LTMCTDimensionBase.charge = exponent 1 LTMCTDimensionBase.charge⊒ (fromISQFun 1).exponent LTMCTDimensionBase.temperature = exponent 1 LTMCTDimensionBase.temperature All goals completed! πŸ™ map_mul' d1 d2 := d1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun = d1.fromISQFun * d2.fromISQFun d1:Dimension ISQDimensionBased2:Dimension ISQDimensionBaseb:LTMCTDimensionBase⊒ (d1 * d2).fromISQFun.exponent b = (d1.fromISQFun * d2.fromISQFun).exponent b d1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.length = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.lengthd1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.time = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.timed1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.mass = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.massd1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.charge = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.charged1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.temperature = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.temperature d1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.length = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.lengthd1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.time = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.timed1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.mass = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.massd1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.charge = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.charged1:Dimension ISQDimensionBased2:Dimension ISQDimensionBase⊒ (d1 * d2).fromISQFun.exponent LTMCTDimensionBase.temperature = (d1.fromISQFun * d2.fromISQFun).exponent LTMCTDimensionBase.temperature All goals completed! πŸ™ all_goals All goals completed! πŸ™

fromISQHom applied to a dimension is fromISQFun.

lemma fromISQHom_apply (d : Dimension ISQDimensionBase) : fromISQHom d = fromISQFun d := rfl

The projection recovers PhysLib's basis from its image under the embedding: fromISQHom ∘ toISQHom = id.

lemma fromISQHom_comp_toISQHom : fromISQHom.comp toISQHom = MonoidHom.id (Dimension LTMCTDimensionBase) := ⊒ fromISQHom.comp toISQHom = MonoidHom.id (Dimension LTMCTDimensionBase) d:Dimension LTMCTDimensionBaseb:LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent b = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent b d:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.length = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.lengthd:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.time = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.timed:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.mass = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.massd:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.charge = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.charged:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.temperature = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.temperature d:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.length = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.lengthd:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.time = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.timed:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.mass = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.massd:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.charge = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.charged:Dimension LTMCTDimensionBase⊒ ((fromISQHom.comp toISQHom) d).exponent LTMCTDimensionBase.temperature = ((MonoidHom.id (Dimension LTMCTDimensionBase)) d).exponent LTMCTDimensionBase.temperature All goals completed! πŸ™ all_goals All goals completed! πŸ™

toISQHom is injective: PhysLib dimensions include faithfully into ISQ.

d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent b⊒ d1 = d2 d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent bb:LTMCTDimensionBase⊒ d1.exponent b = d2.exponent b cases b with d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent b⊒ d1.exponent LTMCTDimensionBase.length = d2.exponent LTMCTDimensionBase.length All goals completed! πŸ™ d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent b⊒ d1.exponent LTMCTDimensionBase.time = d2.exponent LTMCTDimensionBase.time d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent bht:d1.toISQFun.exponent ISQDimensionBase.time = d2.toISQFun.exponent ISQDimensionBase.time⊒ d1.exponent LTMCTDimensionBase.time = d2.exponent LTMCTDimensionBase.time d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent bht:d1.toISQFun.exponent ISQDimensionBase.time = d2.toISQFun.exponent ISQDimensionBase.timehc:d1.toISQFun.exponent ISQDimensionBase.current = d2.toISQFun.exponent ISQDimensionBase.current⊒ d1.exponent LTMCTDimensionBase.time = d2.exponent LTMCTDimensionBase.time d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent bht:d1.exponent LTMCTDimensionBase.time + d1.exponent LTMCTDimensionBase.charge = d2.exponent LTMCTDimensionBase.time + d2.exponent LTMCTDimensionBase.chargehc:d1.exponent LTMCTDimensionBase.charge = d2.exponent LTMCTDimensionBase.charge⊒ d1.exponent LTMCTDimensionBase.time = d2.exponent LTMCTDimensionBase.time All goals completed! πŸ™ d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent b⊒ d1.exponent LTMCTDimensionBase.mass = d2.exponent LTMCTDimensionBase.mass All goals completed! πŸ™ d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent b⊒ d1.exponent LTMCTDimensionBase.charge = d2.exponent LTMCTDimensionBase.charge All goals completed! πŸ™ d1:Dimension LTMCTDimensionBased2:Dimension LTMCTDimensionBaseh:toISQHom d1 = toISQHom d2key:βˆ€ (b : ISQDimensionBase), d1.toISQFun.exponent b = d2.toISQFun.exponent b⊒ d1.exponent LTMCTDimensionBase.temperature = d2.exponent LTMCTDimensionBase.temperature All goals completed! πŸ™

fromISQHom is surjective: every PhysLib dimension is the reduction of some ISQ dimension (namely its own embedding).

All goals completed! πŸ™βŸ©

PhysLib's dimensions embed into the ISQ dimensions (charge ↦ I Β· T).

The ISQ dimensions project onto PhysLib's, reading current as charge/time and forgetting amount of substance and luminous intensity.

The projection is a retraction of the embedding: isqToLTMCT ∘ ltmctToISQ = id. So PhysLib's basis embeds faithfully into ISQ and is recovered by the projection, but not conversely β€” amount of substance and luminous intensity cannot be recovered.

lemma isqToLTMCT_comp_ltmctToISQ : isqToLTMCT.toHom.comp ltmctToISQ.toHom = MonoidHom.id (Dimension LTMCTDimensionBase) := fromISQHom_comp_toISQHom

The embedding is physically faithful on charge: PhysLib's charge generator C𝓭 maps to the derived ISQ charge I Β· T.

lemma toISQHom_C𝓭 : toISQHom C𝓭 = ISQDimensionBase.charge := ⊒ toISQHom C𝓭 = ISQDimensionBase.charge b:ISQDimensionBase⊒ (toISQHom C𝓭).exponent b = ISQDimensionBase.charge.exponent b ⊒ (toISQHom C𝓭).exponent ISQDimensionBase.length = ISQDimensionBase.charge.exponent ISQDimensionBase.length⊒ (toISQHom C𝓭).exponent ISQDimensionBase.mass = ISQDimensionBase.charge.exponent ISQDimensionBase.mass⊒ (toISQHom C𝓭).exponent ISQDimensionBase.time = ISQDimensionBase.charge.exponent ISQDimensionBase.time⊒ (toISQHom C𝓭).exponent ISQDimensionBase.current = ISQDimensionBase.charge.exponent ISQDimensionBase.current⊒ (toISQHom C𝓭).exponent ISQDimensionBase.temperature = ISQDimensionBase.charge.exponent ISQDimensionBase.temperature⊒ (toISQHom C𝓭).exponent ISQDimensionBase.amount = ISQDimensionBase.charge.exponent ISQDimensionBase.amount⊒ (toISQHom C𝓭).exponent ISQDimensionBase.luminousIntensity = ISQDimensionBase.charge.exponent ISQDimensionBase.luminousIntensity ⊒ (toISQHom C𝓭).exponent ISQDimensionBase.length = ISQDimensionBase.charge.exponent ISQDimensionBase.length⊒ (toISQHom C𝓭).exponent ISQDimensionBase.mass = ISQDimensionBase.charge.exponent ISQDimensionBase.mass⊒ (toISQHom C𝓭).exponent ISQDimensionBase.time = ISQDimensionBase.charge.exponent ISQDimensionBase.time⊒ (toISQHom C𝓭).exponent ISQDimensionBase.current = ISQDimensionBase.charge.exponent ISQDimensionBase.current⊒ (toISQHom C𝓭).exponent ISQDimensionBase.temperature = ISQDimensionBase.charge.exponent ISQDimensionBase.temperature⊒ (toISQHom C𝓭).exponent ISQDimensionBase.amount = ISQDimensionBase.charge.exponent ISQDimensionBase.amount⊒ (toISQHom C𝓭).exponent ISQDimensionBase.luminousIntensity = ISQDimensionBase.charge.exponent ISQDimensionBase.luminousIntensity All goals completed! πŸ™