Theorem: Real.volume_preserving_transvectionStruct
File: Mathlib/MeasureTheory/Measure/Lebesgue/Basic.lean

tactic: let p : ι → Prop := fun i => i ≠ t.i
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: let α : Type _ := { x // p x }
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: let β : Type _ := { x // ¬p x }
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: let g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun _ => t.c * a ⟨t.j, t.hij.symm⟩) + b
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: let F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.1, g p.1 p.2)
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: let e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun _ : ι => ℝ) p
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: rw [this]
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
⊢ MeasurePreserving ↑(↑toLin' (TransvectionStruct.toMatrix t))

tactic: have A : MeasurePreserving e := by
  convert volume_preserving_piEquivPiSubtypeProd (fun _ : ι => ℝ) p
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
⊢ MeasurePreserving (↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e)

tactic: have B : MeasurePreserving F :=
  haveI g_meas : Measurable (Function.uncurry g) := by
    have : Measurable fun c : α → ℝ => c ⟨t.j, t.hij.symm⟩ :=
      measurable_pi_apply ⟨t.j, t.hij.symm⟩
    refine Measurable.add ?_ measurable_snd
    refine measurable_pi_lambda _ fun _ => Measurable.const_mul ?_ _
    exact this.comp measurable_fst
  (MeasurePreserving.id _).skew_product g_meas
    (eventually_of_forall fun a => map_add_left_eq_self
      (Measure.pi fun _ => (stdOrthonormalBasis ℝ ℝ).toBasis.addHaar) _)
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
A : MeasurePreserving ↑e
⊢ MeasurePreserving (↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e)

tactic: exact ((A.symm e).comp B).comp A
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
A : MeasurePreserving ↑e
B : MeasurePreserving F
⊢ MeasurePreserving (↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e)

tactic: ext (f k)
state_before: case mk
ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t_i t_j : ι
t_hij : t_i ≠ t_j
t_c : ℝ
p : ι → Prop := fun i => i ≠ { i := t_i, j := t_j, hij := t_hij, c := t_c }.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ :=
  fun a b =>
    (fun x =>
        { i := t_i, j := t_j, hij := t_hij, c := t_c }.c *
          a
            { val := { i := t_i, j := t_j, hij := t_hij, c := t_c }.j,
              property :=
                (_ :
                  { i := t_i, j := t_j, hij := t_hij, c := t_c }.j ≠
                    { i := t_i, j := t_j, hij := t_hij, c := t_c }.i) }) +
      b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
⊢ ↑(↑toLin' (TransvectionStruct.toMatrix { i := t_i, j := t_j, hij := t_hij, c := t_c })) =
    ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e

tactic: simp only [LinearEquiv.map_smul, dite_eq_ite, LinearMap.id_coe, ite_not,
  Algebra.id.smul_eq_mul, one_mul, dotProduct, stdBasisMatrix,
  MeasurableEquiv.piEquivPiSubtypeProd_symm_apply, id.def, transvection, Pi.add_apply,
  MulZeroClass.zero_mul, LinearMap.smul_apply, Function.comp_apply,
  MeasurableEquiv.piEquivPiSubtypeProd_apply, Matrix.TransvectionStruct.toMatrix_mk,
  Matrix.mulVec, LinearEquiv.map_add, ite_mul, Matrix.toLin'_apply, Pi.smul_apply,
  Subtype.coe_mk, LinearMap.add_apply, Finset.sum_congr, Matrix.toLin'_one]
state_before: case mk.h.h
ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t_i t_j : ι
t_hij : t_i ≠ t_j
t_c : ℝ
p : ι → Prop := fun i => i ≠ { i := t_i, j := t_j, hij := t_hij, c := t_c }.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ :=
  fun a b =>
    (fun x =>
        { i := t_i, j := t_j, hij := t_hij, c := t_c }.c *
          a
            { val := { i := t_i, j := t_j, hij := t_hij, c := t_c }.j,
              property :=
                (_ :
                  { i := t_i, j := t_j, hij := t_hij, c := t_c }.j ≠
                    { i := t_i, j := t_j, hij := t_hij, c := t_c }.i) }) +
      b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
f : ι → ℝ
k : ι
⊢ ↑(↑toLin' (TransvectionStruct.toMatrix { i := t_i, j := t_j, hij := t_hij, c := t_c })) f k =
    (↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e) f k

tactic: by_cases h : t_i = k
state_before: case mk.h.h
ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t_i t_j : ι
t_hij : t_i ≠ t_j
t_c : ℝ
p : ι → Prop := fun i => i ≠ { i := t_i, j := t_j, hij := t_hij, c := t_c }.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ :=
  fun a b =>
    (fun x =>
        { i := t_i, j := t_j, hij := t_hij, c := t_c }.c *
          a
            { val := { i := t_i, j := t_j, hij := t_hij, c := t_c }.j,
              property :=
                (_ :
                  { i := t_i, j := t_j, hij := t_hij, c := t_c }.j ≠
                    { i := t_i, j := t_j, hij := t_hij, c := t_c }.i) }) +
      b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
f : ι → ℝ
k : ι
⊢ (f k + ∑ x : ι, if t_i = k ∧ t_j = x then t_c * f x else 0) = if k = t_i then t_c * f t_j + f k else f k

tactic: simp only [h, true_and_iff, Finset.mem_univ, if_true, eq_self_iff_true, Finset.sum_ite_eq,
  one_apply, boole_mul, add_comm]
state_before: case pos
ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t_i t_j : ι
t_hij : t_i ≠ t_j
t_c : ℝ
p : ι → Prop := fun i => i ≠ { i := t_i, j := t_j, hij := t_hij, c := t_c }.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ :=
  fun a b =>
    (fun x =>
        { i := t_i, j := t_j, hij := t_hij, c := t_c }.c *
          a
            { val := { i := t_i, j := t_j, hij := t_hij, c := t_c }.j,
              property :=
                (_ :
                  { i := t_i, j := t_j, hij := t_hij, c := t_c }.j ≠
                    { i := t_i, j := t_j, hij := t_hij, c := t_c }.i) }) +
      b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
f : ι → ℝ
k : ι
h : t_i = k
⊢ (f k + ∑ x : ι, if t_i = k ∧ t_j = x then t_c * f x else 0) = if k = t_i then t_c * f t_j + f k else f k

tactic: simp only [h, Ne.symm h, add_zero, if_false, Finset.sum_const_zero, false_and_iff,
  MulZeroClass.mul_zero]
state_before: case neg
ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t_i t_j : ι
t_hij : t_i ≠ t_j
t_c : ℝ
p : ι → Prop := fun i => i ≠ { i := t_i, j := t_j, hij := t_hij, c := t_c }.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ :=
  fun a b =>
    (fun x =>
        { i := t_i, j := t_j, hij := t_hij, c := t_c }.c *
          a
            { val := { i := t_i, j := t_j, hij := t_hij, c := t_c }.j,
              property :=
                (_ :
                  { i := t_i, j := t_j, hij := t_hij, c := t_c }.j ≠
                    { i := t_i, j := t_j, hij := t_hij, c := t_c }.i) }) +
      b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
f : ι → ℝ
k : ι
h : ¬t_i = k
⊢ (f k + ∑ x : ι, if t_i = k ∧ t_j = x then t_c * f x else 0) = if k = t_i then t_c * f t_j + f k else f k

tactic: convert volume_preserving_piEquivPiSubtypeProd (fun _ : ι => ℝ) p
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
⊢ MeasurePreserving ↑e

tactic: have : Measurable fun c : α → ℝ => c ⟨t.j, t.hij.symm⟩ :=
  measurable_pi_apply ⟨t.j, t.hij.symm⟩
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
A : MeasurePreserving ↑e
⊢ Measurable (Function.uncurry g)

tactic: refine Measurable.add ?_ measurable_snd
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this✝ : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
A : MeasurePreserving ↑e
this : Measurable fun c => c { val := t.j, property := (_ : t.j ≠ t.i) }
⊢ Measurable (Function.uncurry g)

tactic: refine measurable_pi_lambda _ fun _ => Measurable.const_mul ?_ _
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this✝ : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
A : MeasurePreserving ↑e
this : Measurable fun c => c { val := t.j, property := (_ : t.j ≠ t.i) }
⊢ Measurable fun a x => t.c * Prod.fst a { val := t.j, property := (_ : t.j ≠ t.i) }

tactic: exact this.comp measurable_fst
state_before: ι : Type u_1
inst✝¹ : Fintype ι
inst✝ : DecidableEq ι
t : TransvectionStruct ι ℝ
p : ι → Prop := fun i => i ≠ t.i
α : Type u_1 := { x // p x }
β : Type u_1 := { x // ¬p x }
g : (α → ℝ) → (β → ℝ) → β → ℝ := fun a b => (fun x => t.c * a { val := t.j, property := (_ : t.j ≠ t.i) }) + b
F : (α → ℝ) × (β → ℝ) → (α → ℝ) × (β → ℝ) := fun p => (id p.fst, g p.fst p.snd)
e : (ι → ℝ) ≃ᵐ (α → ℝ) × (β → ℝ) := MeasurableEquiv.piEquivPiSubtypeProd (fun x => ℝ) p
this✝ : ↑(↑toLin' (TransvectionStruct.toMatrix t)) = ↑(MeasurableEquiv.symm e) ∘ F ∘ ↑e
A : MeasurePreserving ↑e
this : Measurable fun c => c { val := t.j, property := (_ : t.j ≠ t.i) }
x✝ : β
⊢ Measurable fun c => Prod.fst c { val := t.j, property := (_ : t.j ≠ t.i) }