Imports
/- Copyright (c) 2026 Rob Sneiderman. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Rob Sneiderman -/ module public import Physlib.SpaceAndTime.Space.EuclideanGroup.Basic public import Physlib.SpaceAndTime.Space.Origin public import Physlib.SpaceAndTime.Time.Basic

The Galilean group

This file defines Galilean transformations in d spatial dimensions, together with their group law and their action on Time × Space d.

An element consists of a spatial orthogonal transformation R, a boost velocity v, a spatial translation a, and a time translation b. We use the active convention (t, x) ↦ (t + b, R x + v t + a).

@[expose] public section

A Galilean transformation in d spatial dimensions. The fields are, in order, the spatial orthogonal part, boost velocity, spatial translation, and time translation.

The spatial orthogonal part.

The boost velocity.

The spatial translation.

The time translation.

@[ext] structure GalileanGroup (d : := 3) where rotation : Matrix.orthogonalGroup (Fin d) velocity : EuclideanSpace (Fin d) spaceTranslation : EuclideanSpace (Fin d) timeTranslation : Time

A. Basic support lemmas

All goals completed! 🐙

B. Group operations

The identity Galilean transformation.

instance : One (GalileanGroup d) where one := 1, 0, 0, 0
@[simp] lemma one_rotation : (1 : GalileanGroup d).rotation = 1 := rfl@[simp] lemma one_velocity : (1 : GalileanGroup d).velocity = 0 := rfl@[simp] lemma one_spaceTranslation : (1 : GalileanGroup d).spaceTranslation = 0 := rfl@[simp] lemma one_timeTranslation : (1 : GalileanGroup d).timeTranslation = 0 := rfl

The product whose action is composition: (g * h) • tx = g • h • tx.

instance : Mul (GalileanGroup d) where mul g h := g.rotation * h.rotation, g.rotation h.velocity + g.velocity, g.spaceTranslation + g.rotation h.spaceTranslation + h.timeTranslation.val g.velocity, g.timeTranslation + h.timeTranslation
@[simp] lemma mul_rotation (g h : GalileanGroup d) : (g * h).rotation = g.rotation * h.rotation := rfl@[simp] lemma mul_velocity (g h : GalileanGroup d) : (g * h).velocity = g.rotation h.velocity + g.velocity := rfl@[simp] lemma mul_spaceTranslation (g h : GalileanGroup d) : (g * h).spaceTranslation = g.spaceTranslation + g.rotation h.spaceTranslation + h.timeTranslation.val g.velocity := rfl@[simp] lemma mul_timeTranslation (g h : GalileanGroup d) : (g * h).timeTranslation = g.timeTranslation + h.timeTranslation := rfl

The inverse Galilean transformation.

instance : Inv (GalileanGroup d) where inv g := g.rotation⁻¹, -(g.rotation⁻¹ g.velocity), -(g.rotation⁻¹ g.spaceTranslation) + g.timeTranslation.val (g.rotation⁻¹ g.velocity), -g.timeTranslation
@[simp] lemma inv_rotation (g : GalileanGroup d) : g⁻¹.rotation = g.rotation⁻¹ := rfl

The inverse boost velocity formula.

@[simp] lemma inv_velocity (g : GalileanGroup d) : g⁻¹.velocity = -(g.rotation⁻¹ g.velocity) := rfl
@[simp] lemma inv_spaceTranslation (g : GalileanGroup d) : g⁻¹.spaceTranslation = -(g.rotation⁻¹ g.spaceTranslation) + g.timeTranslation.val (g.rotation⁻¹ g.velocity) := rfl@[simp] lemma inv_timeTranslation (g : GalileanGroup d) : g⁻¹.timeTranslation = -g.timeTranslation := rfl

The Galilean transformations form a group under composition.

d:g:GalileanGroup dh:GalileanGroup dk:GalileanGroup dg.spaceTranslation + g.rotation h.spaceTranslation + h.timeTranslation.val g.velocity + g.rotation h.rotation k.spaceTranslation + (k.timeTranslation.val g.rotation h.velocity + k.timeTranslation.val g.velocity) = g.spaceTranslation + (g.rotation h.spaceTranslation + g.rotation h.rotation k.spaceTranslation + k.timeTranslation.val g.rotation h.velocity) + (h.timeTranslation.val g.velocity + k.timeTranslation.val g.velocity) All goals completed! 🐙 d:g:GalileanGroup dh:GalileanGroup dk:GalileanGroup d(g * h * k).timeTranslation = (g * (h * k)).timeTranslation d:g:GalileanGroup dh:GalileanGroup dk:GalileanGroup d(g * h * k).timeTranslation.val = (g * (h * k)).timeTranslation.val All goals completed! 🐙 one_mul g := d:g:GalileanGroup d1 * g = g d:g:GalileanGroup d(1 * g).rotation = g.rotationd:g:GalileanGroup d(1 * g).velocity = g.velocityd:g:GalileanGroup d(1 * g).spaceTranslation = g.spaceTranslationd:g:GalileanGroup d(1 * g).timeTranslation = g.timeTranslation d:g:GalileanGroup d(1 * g).rotation = g.rotation All goals completed! 🐙 d:g:GalileanGroup d(1 * g).velocity = g.velocity All goals completed! 🐙 d:g:GalileanGroup d(1 * g).spaceTranslation = g.spaceTranslation All goals completed! 🐙 d:g:GalileanGroup d(1 * g).timeTranslation = g.timeTranslation d:g:GalileanGroup d(1 * g).timeTranslation.val = g.timeTranslation.val All goals completed! 🐙 mul_one g := d:g:GalileanGroup dg * 1 = g d:g:GalileanGroup d(g * 1).rotation = g.rotationd:g:GalileanGroup d(g * 1).velocity = g.velocityd:g:GalileanGroup d(g * 1).spaceTranslation = g.spaceTranslationd:g:GalileanGroup d(g * 1).timeTranslation = g.timeTranslation d:g:GalileanGroup d(g * 1).rotation = g.rotation All goals completed! 🐙 d:g:GalileanGroup d(g * 1).velocity = g.velocity All goals completed! 🐙 d:g:GalileanGroup d(g * 1).spaceTranslation = g.spaceTranslation All goals completed! 🐙 d:g:GalileanGroup d(g * 1).timeTranslation = g.timeTranslation d:g:GalileanGroup d(g * 1).timeTranslation.val = g.timeTranslation.val All goals completed! 🐙 inv_mul_cancel g := d:g:GalileanGroup dg⁻¹ * g = 1 d:g:GalileanGroup d(g⁻¹ * g).rotation = rotation 1d:g:GalileanGroup d(g⁻¹ * g).velocity = velocity 1d:g:GalileanGroup d(g⁻¹ * g).spaceTranslation = spaceTranslation 1d:g:GalileanGroup d(g⁻¹ * g).timeTranslation = timeTranslation 1 d:g:GalileanGroup d(g⁻¹ * g).rotation = rotation 1 All goals completed! 🐙 d:g:GalileanGroup d(g⁻¹ * g).velocity = velocity 1 All goals completed! 🐙 d:g:GalileanGroup d(g⁻¹ * g).spaceTranslation = spaceTranslation 1 All goals completed! 🐙 d:g:GalileanGroup d(g⁻¹ * g).timeTranslation = timeTranslation 1 d:g:GalileanGroup d(g⁻¹ * g).timeTranslation.val = (timeTranslation 1).val All goals completed! 🐙
instance : Inhabited (GalileanGroup d) where default := 1

C. Action on time and space

@[simp] lemma smul_fst (g : GalileanGroup d) (tx : Time × Space d) : (g tx).1 = tx.1 + g.timeTranslation := rfl@[simp] lemma smul_snd (g : GalileanGroup d) (tx : Time × Space d) : (g tx).2 = g.actSpace tx.1 tx.2 := rfl@[simp] lemma smul_mk (g : GalileanGroup d) (t : Time) (x : Space d) : g ((t, x) : Time × Space d) = (t + g.timeTranslation, g.actSpace t x) := rfl@[simp] lemma actSpace_apply (g : GalileanGroup d) (t : Time) (x : Space d) (i : Fin d) : g.actSpace t x i = (g.rotation (x -ᵥ (0 : Space d))) i + t.val * g.velocity i + g.spaceTranslation i := d:g:GalileanGroup dt:Timex:Space di:Fin d(g.actSpace t x).val i = (g.rotation (x -ᵥ 0)).ofLp i + t.val * g.velocity.ofLp i + g.spaceTranslation.ofLp i All goals completed! 🐙

D. Subgroup inclusions

A Euclidean spatial transformation as a Galilean transformation with zero boost and no time translation.

def ofEuclidean (g : EuclideanGroup d) : GalileanGroup d := g.linear, 0, g.translation, 0
@[simp] lemma ofEuclidean_rotation (g : EuclideanGroup d) : (ofEuclidean g).rotation = g.linear := rfl@[simp] lemma ofEuclidean_velocity (g : EuclideanGroup d) : (ofEuclidean g).velocity = 0 := rfl@[simp] lemma ofEuclidean_spaceTranslation (g : EuclideanGroup d) : (ofEuclidean g).spaceTranslation = g.translation := rfl@[simp] lemma ofEuclidean_timeTranslation (g : EuclideanGroup d) : (ofEuclidean g).timeTranslation = 0 := rfl

Inclusion of the Euclidean group into the Galilean group.

def euclidean.incl : EuclideanGroup d →* GalileanGroup d where toFun := ofEuclidean map_one' := rfl map_mul' g h := d:g:EuclideanGroup dh:EuclideanGroup dofEuclidean (g * h) = ofEuclidean g * ofEuclidean h d:g:EuclideanGroup dh:EuclideanGroup di:Fin dj✝:Fin d(ofEuclidean (g * h)).rotation i j✝ = (ofEuclidean g * ofEuclidean h).rotation i j✝d:g:EuclideanGroup dh:EuclideanGroup di:Fin d(ofEuclidean (g * h)).velocity.ofLp i = (ofEuclidean g * ofEuclidean h).velocity.ofLp id:g:EuclideanGroup dh:EuclideanGroup di:Fin d(ofEuclidean (g * h)).spaceTranslation.ofLp i = (ofEuclidean g * ofEuclidean h).spaceTranslation.ofLp id:g:EuclideanGroup dh:EuclideanGroup d(ofEuclidean (g * h)).timeTranslation.val = (ofEuclidean g * ofEuclidean h).timeTranslation.val d:g:EuclideanGroup dh:EuclideanGroup di:Fin dj✝:Fin d(ofEuclidean (g * h)).rotation i j✝ = (ofEuclidean g * ofEuclidean h).rotation i j✝d:g:EuclideanGroup dh:EuclideanGroup di:Fin d(ofEuclidean (g * h)).velocity.ofLp i = (ofEuclidean g * ofEuclidean h).velocity.ofLp id:g:EuclideanGroup dh:EuclideanGroup di:Fin d(ofEuclidean (g * h)).spaceTranslation.ofLp i = (ofEuclidean g * ofEuclidean h).spaceTranslation.ofLp id:g:EuclideanGroup dh:EuclideanGroup d(ofEuclidean (g * h)).timeTranslation.val = (ofEuclidean g * ofEuclidean h).timeTranslation.val All goals completed! 🐙

A pure orthogonal spatial transformation as a Galilean transformation.

def ofOrthogonal (R : Matrix.orthogonalGroup (Fin d) ) : GalileanGroup d := R, 0, 0, 0
@[simp] lemma ofOrthogonal_rotation (R : Matrix.orthogonalGroup (Fin d) ) : (ofOrthogonal R).rotation = R := rfl@[simp] lemma ofOrthogonal_velocity (R : Matrix.orthogonalGroup (Fin d) ) : (ofOrthogonal R).velocity = 0 := rfl@[simp] lemma ofOrthogonal_spaceTranslation (R : Matrix.orthogonalGroup (Fin d) ) : (ofOrthogonal R).spaceTranslation = 0 := rfl@[simp] lemma ofOrthogonal_timeTranslation (R : Matrix.orthogonalGroup (Fin d) ) : (ofOrthogonal R).timeTranslation = 0 := rfl

Inclusion of the orthogonal group into the Galilean group.

def orthogonal.incl : Matrix.orthogonalGroup (Fin d) →* GalileanGroup d where toFun := ofOrthogonal map_one' := rfl map_mul' R S := d:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )ofOrthogonal (R * S) = ofOrthogonal R * ofOrthogonal S d:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )i:Fin dj✝:Fin d(ofOrthogonal (R * S)).rotation i j✝ = (ofOrthogonal R * ofOrthogonal S).rotation i j✝d:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )i:Fin d(ofOrthogonal (R * S)).velocity.ofLp i = (ofOrthogonal R * ofOrthogonal S).velocity.ofLp id:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )i:Fin d(ofOrthogonal (R * S)).spaceTranslation.ofLp i = (ofOrthogonal R * ofOrthogonal S).spaceTranslation.ofLp id:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )(ofOrthogonal (R * S)).timeTranslation.val = (ofOrthogonal R * ofOrthogonal S).timeTranslation.val d:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )i:Fin dj✝:Fin d(ofOrthogonal (R * S)).rotation i j✝ = (ofOrthogonal R * ofOrthogonal S).rotation i j✝d:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )i:Fin d(ofOrthogonal (R * S)).velocity.ofLp i = (ofOrthogonal R * ofOrthogonal S).velocity.ofLp id:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )i:Fin d(ofOrthogonal (R * S)).spaceTranslation.ofLp i = (ofOrthogonal R * ofOrthogonal S).spaceTranslation.ofLp id:R:(Matrix.orthogonalGroup (Fin d) )S:(Matrix.orthogonalGroup (Fin d) )(ofOrthogonal (R * S)).timeTranslation.val = (ofOrthogonal R * ofOrthogonal S).timeTranslation.val All goals completed! 🐙

A pure spatial translation as a Galilean transformation.

def ofSpaceTranslation (a : EuclideanSpace (Fin d)) : GalileanGroup d := 1, 0, a, 0
@[simp] lemma ofSpaceTranslation_rotation (a : EuclideanSpace (Fin d)) : (ofSpaceTranslation a).rotation = 1 := rfl@[simp] lemma ofSpaceTranslation_velocity (a : EuclideanSpace (Fin d)) : (ofSpaceTranslation a).velocity = 0 := rfl@[simp] lemma ofSpaceTranslation_spaceTranslation (a : EuclideanSpace (Fin d)) : (ofSpaceTranslation a).spaceTranslation = a := rfl@[simp] lemma ofSpaceTranslation_timeTranslation (a : EuclideanSpace (Fin d)) : (ofSpaceTranslation a).timeTranslation = 0 := rfl

Inclusion of spatial translations into the Galilean group.

def spaceTranslation.incl : Multiplicative (EuclideanSpace (Fin d)) →* GalileanGroup d where toFun a := ofSpaceTranslation a.toAdd map_one' := rfl map_mul' a b := d:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))ofSpaceTranslation (Multiplicative.toAdd (a * b)) = ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b) d:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))i:Fin dj✝:Fin d(ofSpaceTranslation (Multiplicative.toAdd (a * b))).rotation i j✝ = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).rotation i j✝d:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))i:Fin d(ofSpaceTranslation (Multiplicative.toAdd (a * b))).velocity.ofLp i = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).velocity.ofLp id:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))i:Fin d(ofSpaceTranslation (Multiplicative.toAdd (a * b))).spaceTranslation.ofLp i = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).spaceTranslation.ofLp id:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))(ofSpaceTranslation (Multiplicative.toAdd (a * b))).timeTranslation.val = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).timeTranslation.val d:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))i:Fin dj✝:Fin d(ofSpaceTranslation (Multiplicative.toAdd (a * b))).rotation i j✝ = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).rotation i j✝d:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))i:Fin d(ofSpaceTranslation (Multiplicative.toAdd (a * b))).velocity.ofLp i = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).velocity.ofLp id:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))i:Fin d(ofSpaceTranslation (Multiplicative.toAdd (a * b))).spaceTranslation.ofLp i = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).spaceTranslation.ofLp id:a:Multiplicative (EuclideanSpace (Fin d))b:Multiplicative (EuclideanSpace (Fin d))(ofSpaceTranslation (Multiplicative.toAdd (a * b))).timeTranslation.val = (ofSpaceTranslation (Multiplicative.toAdd a) * ofSpaceTranslation (Multiplicative.toAdd b)).timeTranslation.val All goals completed! 🐙

A pure time translation as a Galilean transformation.

def ofTimeTranslation (b : Time) : GalileanGroup d := 1, 0, 0, b
@[simp] lemma ofTimeTranslation_rotation (b : Time) : (ofTimeTranslation (d := d) b).rotation = 1 := rfl@[simp] lemma ofTimeTranslation_velocity (b : Time) : (ofTimeTranslation (d := d) b).velocity = 0 := rfl@[simp] lemma ofTimeTranslation_spaceTranslation (b : Time) : (ofTimeTranslation (d := d) b).spaceTranslation = 0 := rfl@[simp] lemma ofTimeTranslation_timeTranslation (b : Time) : (ofTimeTranslation (d := d) b).timeTranslation = b := rfl

Inclusion of time translations into the Galilean group.

def timeTranslation.incl : Multiplicative Time →* GalileanGroup d where toFun b := ofTimeTranslation b.toAdd map_one' := rfl map_mul' a b := d:a:Multiplicative Timeb:Multiplicative TimeofTimeTranslation (Multiplicative.toAdd (a * b)) = ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b) d:a:Multiplicative Timeb:Multiplicative Timei:Fin dj✝:Fin d(ofTimeTranslation (Multiplicative.toAdd (a * b))).rotation i j✝ = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).rotation i j✝d:a:Multiplicative Timeb:Multiplicative Timei:Fin d(ofTimeTranslation (Multiplicative.toAdd (a * b))).velocity.ofLp i = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).velocity.ofLp id:a:Multiplicative Timeb:Multiplicative Timei:Fin d(ofTimeTranslation (Multiplicative.toAdd (a * b))).spaceTranslation.ofLp i = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).spaceTranslation.ofLp id:a:Multiplicative Timeb:Multiplicative Time(ofTimeTranslation (Multiplicative.toAdd (a * b))).timeTranslation.val = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).timeTranslation.val d:a:Multiplicative Timeb:Multiplicative Timei:Fin dj✝:Fin d(ofTimeTranslation (Multiplicative.toAdd (a * b))).rotation i j✝ = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).rotation i j✝d:a:Multiplicative Timeb:Multiplicative Timei:Fin d(ofTimeTranslation (Multiplicative.toAdd (a * b))).velocity.ofLp i = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).velocity.ofLp id:a:Multiplicative Timeb:Multiplicative Timei:Fin d(ofTimeTranslation (Multiplicative.toAdd (a * b))).spaceTranslation.ofLp i = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).spaceTranslation.ofLp id:a:Multiplicative Timeb:Multiplicative Time(ofTimeTranslation (Multiplicative.toAdd (a * b))).timeTranslation.val = (ofTimeTranslation (Multiplicative.toAdd a) * ofTimeTranslation (Multiplicative.toAdd b)).timeTranslation.val All goals completed! 🐙