Imports
/- Copyright (c) 2025 Joseph Tooby-Smith. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joseph Tooby-Smith -/ module public import Mathlib.Geometry.Manifold.Diffeomorph public import Physlib.SpaceAndTime.Time.Basic public import Physlib.SpaceAndTime.Time.TimeUnit

The time manifold with a transitive action of

In this module we define the type TimeTransMan. This type physically corresponds to the manifold of time (diffeomorphic to ) with the following additional structure:

    a transitive action of ,

    a choice of orientation.

The manifold TimeTransMan is not equipped with a translationally-invariant metric. Such metrics are in one-to-one correspondence (to be shown) with positive reals, and as such we define the type TimeUnit (equivalent to the positive reals) to represent the choice of metric on TimeTransMan. This is defined in a different module.

From the point of view of physics, this choice of metric corresponds to a choice of units, hence the name, and we will use the phrase 'units of time' interchangeably 'choice of metric'.

Given a x : TimeUnit, and the structure above, we can define the following operations on TimeTransMan:

    diff x t1 t2, for t1 t2 : TimeTransMan gives the signed difference between two points in time in the units x.

    addTime x r t, for r : ℝ and t : TimeTransMan, gives the point in TimeTransMan that separated from t, by r in the unit x. For example, if x is the unit of seconds, then addTime x 1 t gives the point in TimeTransMan that is one second after t.

    neg zero t, for a given zero : TimeTransMan, gives the point in TimeTransMan that is the same distance away from zero as t but in the opposite direction. This is defined using a choice of units, but is independent of the choice.

Recall that the type Time corresponds to the manifold of time with a given (but arbitrary) choice of units and origin (and therefore has a structure of a module over ). Here we define the homeomorphism:

    toTime zero x from TimeTransMan to Time where zero : TimeTransMan is the choice of origin and x : TimeUnit is the choice of units. This map is a diffeomorphism (to be shown).

@[expose] public section

The type TimeTransMan represents the time manifold with an orientation and a transitive action of the reals.

The choice of a map from TimeTransMan to .

structure TimeTransMan where val :
@[ext] lemma ext_of {t1 t2 : TimeTransMan} (h : t1.val = t2.val) : t1 = t2 := t1:TimeTransMant2:TimeTransManh:t1.val = t2.valt1 = t2 t2:TimeTransManval✝:h:{ val := val✝ }.val = t2.val{ val := val✝ } = t2; val✝¹:val✝:h:{ val := val✝¹ }.val = { val := val✝ }.val{ val := val✝¹ } = { val := val✝ }; All goals completed! 🐙

The topology on TimeTransMan.

The topology on TimeTransMan is induced from the topology on , via the choice of map TimeTransMan.val.

The instance of a topological space on TimeTransMan induced by the map TimeTransMan.val.

instance : TopologicalSpace TimeTransMan := TopologicalSpace.induced TimeTransMan.val PseudoMetricSpace.toUniformSpace.toTopologicalSpace
lemma val_surjective : Function.Surjective TimeTransMan.val := Function.Surjective val t: a, a.val = t All goals completed! 🐙@[simp] lemma val_range : Set.range val = Set.univ := Set.range val = Set.univ All goals completed! 🐙lemma val_inducing : Topology.IsInducing TimeTransMan.val where eq_induced := rfllemma val_injective : Function.Injective TimeTransMan.val := Function.Injective val t1:TimeTransMant2:TimeTransManh:t1.val = t2.valt1 = t2 t2:TimeTransManval✝:h:{ val := val✝ }.val = t2.val{ val := val✝ } = t2 val✝¹:val✝:h:{ val := val✝¹ }.val = { val := val✝ }.val{ val := val✝¹ } = { val := val✝ } All goals completed! 🐙lemma val_isOpenEmbedding : Topology.IsOpenEmbedding TimeTransMan.val where eq_induced := rfl isOpen_range := IsOpen (Set.range val) All goals completed! 🐙 injective := val_injectivelemma isOpen_iff {s : Set TimeTransMan} : IsOpen s IsOpen (TimeTransMan.val '' s) := Topology.IsOpenEmbedding.isOpen_iff_image_isOpen val_isOpenEmbedding

The choice of map Time.val from TimeTransMan to as a homeomorphism.

s:Set TimeTransManhs:IsOpen (val '' s)IsOpen (?m.66 '' s)s:Set TimeTransManhs:IsOpen (val '' s)Function.LeftInverse (fun t => { val := t }) ?m.66s:Set TimeTransManhs:IsOpen (val '' s)Function.RightInverse (fun t => { val := t }) ?m.66s:Set TimeTransManhs:IsOpen (val '' s)TimeTransMan s:Set TimeTransManhs:IsOpen (val '' s)IsOpen (?m.66 '' s) All goals completed! 🐙 s:Set TimeTransManhs:IsOpen (val '' s)Function.LeftInverse (fun t => { val := t }) val s:Set TimeTransManhs:IsOpen (val '' s)t:TimeTransMan(fun t => { val := t }) t.val = t All goals completed! 🐙 s:Set TimeTransManhs:IsOpen (val '' s)Function.RightInverse (fun t => { val := t }) val s:Set TimeTransManhs:IsOpen (val '' s)x:((fun t => { val := t }) x).val = x All goals completed! 🐙

The manifold structure on TimeTransMan

The structure of a charted space on TimeTransMan

instance : ChartedSpace TimeTransMan where atlas := { valHomeomorphism.toOpenPartialHomeomorph } chartAt _ := valHomeomorphism.toOpenPartialHomeomorph mem_chart_source := (x : TimeTransMan), x valHomeomorphism.toOpenPartialHomeomorph.source All goals completed! 🐙 chart_mem_atlas := (x : TimeTransMan), valHomeomorphism.toOpenPartialHomeomorph {valHomeomorphism.toOpenPartialHomeomorph} x:TimeTransManvalHomeomorphism.toOpenPartialHomeomorph {valHomeomorphism.toOpenPartialHomeomorph} All goals completed! 🐙

The structure of a manifold on TimeTransMan induced by the choice of map Time.val.

instance : IsManifold 𝓘(, ) ω TimeTransMan where compatible := {e e' : OpenPartialHomeomorph TimeTransMan }, e atlas TimeTransMan e' atlas TimeTransMan e.symm ≫ₕ e' contDiffGroupoid ω 𝓘(, ) e1:OpenPartialHomeomorph TimeTransMan e2:OpenPartialHomeomorph TimeTransMan h1:e1 atlas TimeTransManh2:e2 atlas TimeTransMane1.symm ≫ₕ e2 contDiffGroupoid ω 𝓘(, ) e1:OpenPartialHomeomorph TimeTransMan e2:OpenPartialHomeomorph TimeTransMan h1:e1 = valHomeomorphism.toOpenPartialHomeomorphh2:e2 = valHomeomorphism.toOpenPartialHomeomorphe1.symm ≫ₕ e2 contDiffGroupoid ω 𝓘(, ) valHomeomorphism.toOpenPartialHomeomorph.symm ≫ₕ valHomeomorphism.toOpenPartialHomeomorph contDiffGroupoid ω 𝓘(, ) All goals completed! 🐙
lemma val_contDiff : ContMDiff 𝓘(, ) 𝓘(, ) ω TimeTransMan.val := ContMDiff 𝓘(, ) 𝓘(, ) ω val ContMDiffOn 𝓘(, ) 𝓘(, ) ω val Set.univ All goals completed! 🐙

The transitive group action on TimeTransMan

instance : VAdd TimeTransMan where vadd p t := { val := p + t.val }@[simp] lemma vadd_val (p : ) (t : TimeTransMan) : (p +ᵥ t).val = p + t.val := rflinstance : AddAction TimeTransMan where zero_vadd t := t:TimeTransMan0 +ᵥ t = t val✝:0 +ᵥ { val := val✝ } = { val := val✝ } val✝:(0 +ᵥ { val := val✝ }).val = { val := val✝ }.val All goals completed! 🐙 add_vadd p1 p2 t := p1:p2:t:TimeTransMan(p1 + p2) +ᵥ t = p1 +ᵥ p2 +ᵥ t p1:p2:t:TimeTransMan((p1 + p2) +ᵥ t).val = (p1 +ᵥ p2 +ᵥ t).val p1:p2:t:TimeTransManp1 + p2 + t.val = p1 + (p2 + t.val) All goals completed! 🐙

A choice of orientation on TimeTransMan

instance : LE TimeTransMan where le x y := x.val y.vallemma le_def (t1 t2 : TimeTransMan) : t1 t2 t1.val t2.val := Iff.rflinstance : Nonempty TimeTransMan := Nonempty.intro 0

Functions based on a choice of unit

Signed difference

x:TimeUnitt1:TimeTransMant2:TimeTransManh:t1.val < t2.val-(x.val⁻¹ * -(t1.val - t2.val)) = x.val⁻¹ * (t1.val - t2.val)x:TimeUnitt1:TimeTransMant2:TimeTransManh:t1.val < t2.valt1.val - t2.val < 0 x:TimeUnitt1:TimeTransMant2:TimeTransManh:t1.val < t2.valhx:x.val 0-(x.val⁻¹ * -(t1.val - t2.val)) = x.val⁻¹ * (t1.val - t2.val)x:TimeUnitt1:TimeTransMant2:TimeTransManh:t1.val < t2.valt1.val - t2.val < 0 x:TimeUnitt1:TimeTransMant2:TimeTransManh:t1.val < t2.valt1.val - t2.val < 0 All goals completed! 🐙@[simp] lemma diff_self (x : TimeUnit) (t : TimeTransMan) : diff x t t = 0 := x:TimeUnitt:TimeTransMandiff x t t = 0 All goals completed! 🐙x:TimeUnitt:TimeTransMant1:TimeTransMant2:TimeTransManh:-(t1.val - t.val) = -(t2.val - t.val)h1:t1.val < t.valh2:t2.val < t.valt1 = t2 x:TimeUnitt:TimeTransMant1:TimeTransMant2:TimeTransManh1:t1.val < t.valh2:t2.val < t.valh:t1.val = t2.valt1 = t2 x:TimeUnitt:TimeTransMant1:TimeTransMant2:TimeTransManh1:t1.val < t.valh2:t2.val < t.valh:t1.val = t2.valt1.val = t2.val All goals completed! 🐙x:TimeUnitt:TimeTransManr:h:¬0 r- -r = rx:TimeUnitt:TimeTransManr:h:¬0 r¬t x.val * r +ᵥ t x:TimeUnitt:TimeTransManr:h:¬0 r¬t x.val * r +ᵥ t x:TimeUnitt:TimeTransManr:h:¬0 rx.val * r < 0 refine mul_neg_of_pos_of_neg x.val_pos (x:TimeUnitt:TimeTransManr:h:¬0 rr < 0 All goals completed! 🐙)lemma diff_fst_bijective (x : TimeUnit) (t : TimeTransMan) : Function.Bijective (diff x · t) := diff_fst_injective x t, diff_fst_surjective x t

Adding time

x:TimeUnitr:t:TimeTransManr = (fun x_1 => diff x x_1 t) { val := x.val * r + t.val } All goals completed! 🐙All goals completed! 🐙

Negation of time around a zero

lemma neg_eq_negMetric (zero : TimeTransMan) (x : TimeUnit) (t : TimeTransMan) : neg zero t = negMetric zero x t := zero:TimeTransManx:TimeUnitt:TimeTransManzero.neg t = zero.negMetric x t zero:TimeTransManx:TimeUnitt:TimeTransManaddTime default (diff default zero t) zero = addTime x (diff x zero t) zero zero:TimeTransManx:TimeUnitt:TimeTransMan(addTime default (diff default zero t) zero).val = (addTime x (diff x zero t) zero).val All goals completed! 🐙

The map from TimeTransMan to Time

@[simp] lemma toTime_zero (zero : TimeTransMan) (x : TimeUnit) : toTime zero x zero = 0 := zero:TimeTransManx:TimeUnit(zero.toTime x) zero = 0 zero:TimeTransManx:TimeUnit((zero.toTime x) zero).val = Time.val 0 All goals completed! 🐙@[simp] lemma toTime_symm_zero_add (zero : TimeTransMan) (x : TimeUnit) : (toTime zero x).symm 0 = zero := zero:TimeTransManx:TimeUnit(zero.toTime x).symm 0 = zero zero:TimeTransManx:TimeUnit((zero.toTime x).symm 0).val = zero.val All goals completed! 🐙lemma toTime_val (zero : TimeTransMan) (x : TimeUnit) (t : TimeTransMan) : (toTime zero x t).val = diff x t zero := zero:TimeTransManx:TimeUnitt:TimeTransMan((zero.toTime x) t).val = diff x t zero All goals completed! 🐙lemma toTime_symm_val (zero : TimeTransMan) (x : TimeUnit) (r : Time) : (toTime zero x).symm r = addTime x r zero := zero:TimeTransManx:TimeUnitr:Time(zero.toTime x).symm r = addTime x r.val zero zero:TimeTransManx:TimeUnitr:Time((zero.toTime x).symm r).val = (addTime x r.val zero).val All goals completed! 🐙@[simp] lemma toTime_addTime (zero : TimeTransMan) (x : TimeUnit) (r : ) (τ : TimeTransMan) : toTime zero x (addTime x r τ) = r + toTime zero x τ:= zero:TimeTransManx:TimeUnitr:τ:TimeTransMan(zero.toTime x) (addTime x r τ) = { val := r } + (zero.toTime x) τ zero:TimeTransManx:TimeUnitr:τ:TimeTransMan((zero.toTime x) (addTime x r τ)).val = ({ val := r } + (zero.toTime x) τ).val zero:TimeTransManx:TimeUnitr:τ:TimeTransManx.val⁻¹ * (x.val * r + τ.val - zero.val) = r + x.val⁻¹ * (τ.val - zero.val) zero:TimeTransManx:TimeUnitr:τ:TimeTransManx.val * r + τ.val - zero.val = x.val * r + (τ.val - zero.val) All goals completed! 🐙lemma toTime_symm_add (zero : TimeTransMan) (x : TimeUnit) (t1 t2 : Time) : (toTime zero x).symm (t1 + t2) = addTime x (diff x ((toTime zero x).symm t1) zero) ((toTime zero x).symm t2) := zero:TimeTransManx:TimeUnitt1:Timet2:Time(zero.toTime x).symm (t1 + t2) = addTime x (diff x ((zero.toTime x).symm t1) zero) ((zero.toTime x).symm t2) zero:TimeTransManx:TimeUnitt1:Timet2:Time((zero.toTime x).symm (t1 + t2)).val = (addTime x (diff x ((zero.toTime x).symm t1) zero) ((zero.toTime x).symm t2)).val zero:TimeTransManx:TimeUnitt1:Timet2:Timex.val * (t1.val + t2.val) + zero.val = x.val * t1.val + (x.val * t2.val + zero.val) All goals completed! 🐙lemma toTime_symm_add' (zero : TimeTransMan) (x : TimeUnit) (t1 t2 : Time) : (toTime zero x).symm (t1 + t2) = addTime x (diff x ((toTime zero x).symm t2) zero) ((toTime zero x).symm t1) := zero:TimeTransManx:TimeUnitt1:Timet2:Time(zero.toTime x).symm (t1 + t2) = addTime x (diff x ((zero.toTime x).symm t2) zero) ((zero.toTime x).symm t1) zero:TimeTransManx:TimeUnitt1:Timet2:Time((zero.toTime x).symm (t1 + t2)).val = (addTime x (diff x ((zero.toTime x).symm t2) zero) ((zero.toTime x).symm t1)).val zero:TimeTransManx:TimeUnitt1:Timet2:Timex.val * (t1.val + t2.val) + zero.val = x.val * t2.val + (x.val * t1.val + zero.val) All goals completed! 🐙lemma diff_eq_toTime_sub (zero : TimeTransMan) (x : TimeUnit) (t1 t2 : TimeTransMan) : diff x t2 t1 = toTime zero x t2 - toTime zero x t1 := zero:TimeTransManx:TimeUnitt1:TimeTransMant2:TimeTransMandiff x t2 t1 = ((zero.toTime x) t2).val - ((zero.toTime x) t1).val zero:TimeTransManx:TimeUnitt1:TimeTransMant2:TimeTransManx.val⁻¹ * (t2.val - t1.val) = x.val⁻¹ * (t2.val - zero.val) - x.val⁻¹ * (t1.val - zero.val) zero:TimeTransManx:TimeUnitt1:TimeTransMant2:TimeTransMant2.val - t1.val = t2.val - zero.val - (t1.val - zero.val) All goals completed! 🐙zero:TimeTransManx:TimeUnitt:TimeTransMan(zero.toTime x) (zero.negMetric x t) = -(zero.toTime x) t zero:TimeTransManx:TimeUnitt:TimeTransMan((zero.toTime x) (zero.negMetric x t)).val = (-(zero.toTime x) t).val zero:TimeTransManx:TimeUnitt:TimeTransManx.val⁻¹ * (zero.val - t.val) = -(x.val⁻¹ * (t.val - zero.val)) All goals completed! 🐙lemma toTime_symm_neg (zero : TimeTransMan) (x : TimeUnit) (t : Time) : (toTime zero x).symm (- t) = neg zero ((toTime zero x).symm t) := zero:TimeTransManx:TimeUnitt:Time(zero.toTime x).symm (-t) = zero.neg ((zero.toTime x).symm t) zero:TimeTransManx:TimeUnitt:Time((zero.toTime x).symm (-t)).val = (zero.neg ((zero.toTime x).symm t)).val All goals completed! 🐙lemma toTime_symm_sub (zero : TimeTransMan) (x : TimeUnit) (t1 t2 : Time) : (toTime zero x).symm (t1 - t2) = addTime x (diff x zero ((toTime zero x).symm t2)) ((toTime zero x).symm t1) := zero:TimeTransManx:TimeUnitt1:Timet2:Time(zero.toTime x).symm (t1 - t2) = addTime x (diff x zero ((zero.toTime x).symm t2)) ((zero.toTime x).symm t1) zero:TimeTransManx:TimeUnitt1:Timet2:Time((zero.toTime x).symm (t1 - t2)).val = (addTime x (diff x zero ((zero.toTime x).symm t2)) ((zero.toTime x).symm t1)).val zero:TimeTransManx:TimeUnitt1:Timet2:Timex.val * (t1.val - t2.val) + zero.val = -(x.val * t2.val) + (x.val * t1.val + zero.val) All goals completed! 🐙