πŸ›οΈ Atlasβœ’οΈFormalizations.Physics.QuantumMechanics.SpeedLimit.TwoQubitEntangling view on GitHub β†—28 theorems
/-Copyright (c) 2026 Carles MarΓ­n. All rights reserved.Released under Apache 2.0 license as described in the file LICENSE.Authors: Carles MarΓ­n, Claude (AI assistant)-/module public import Mathlib.Analysis.CStarAlgebra.Matrixpublic import Mathlib.LinearAlgebra.Matrix.Kroneckerpublic import Mathlib.Analysis.Normed.Algebra.MatrixExponentialpublic import Mathlib.Analysis.SpecialFunctions.Exponentialpublic import Mathlib.Analysis.Calculus.MeanValuepublic import Mathlib.Analysis.Calculus.Deriv.Comppublic import Mathlib.Analysis.Calculus.Deriv.Mulpublic import Mathlib.Analysis.CStarAlgebra.Exponentialpublic import Mathlib.Analysis.InnerProductSpace.PiL2public import Mathlib.Analysis.SpecialFunctions.Pow.Real /-!# A lower bound on the duration of an entangling two-qubit gate Two qubits, `β„‚Β² βŠ— β„‚Β²` with basis indexed by `Fin 2 Γ— Fin 2`, evolve under a Hamiltonian`L + H`, where `L = A βŠ— 1 + 1 βŠ— B` is an arbitrary local (piecewise constant) control and `H` isa Hermitian interaction of operator norm at most `J` (Δ§ = 1). The Bell vector`Ξ¦ = (eβ‚€β‚€ + e₁₁)/√2` is at L2-distance at least `√(2 βˆ’ √2)` from every product vector, since`|⟨Φ, a βŠ— b⟩| ≀ 1/√2`. Local unitaries preserve product vectors, so a gate that sends a productvector to `Ξ¦` is at operator distance at least `√(2 βˆ’ √2)` from every local unitary `A βŠ— B`.A Duhamel estimate `β€–exp (X + Y) βˆ’ exp Xβ€– ≀ β€–Yβ€–` for skew-Hermitian `X, Y` shows that each step`exp (βˆ’i Ο„ (L + H))` is within `Ο„ β€–Hβ€–` of the local unitary `exp (βˆ’i Ο„ L)`, and telescoping overthe steps gives `√(2 βˆ’ √2) ≀ J Β· βˆ‘ Ο„β‚–`: the total time `βˆ‘ Ο„β‚–` is at least `√(2 βˆ’ √2) / J`. Matrices are over `β„‚` with the L2 operator norm (`Matrix.Norms.L2Operator`); vectors live in`EuclideanSpace β„‚ (Fin 2 Γ— Fin 2)`. ## Main results * `QSL.TwoQubit.norm_inner_bell_prodVec_le`: `β€–βŸͺΞ¦, a βŠ— bβŸ«β€– ≀ 1/√2` for unit `a, b`* `QSL.TwoQubit.sqrt_two_sub_sqrt_two_le_norm_bell_sub_prodVec`:  `√(2 βˆ’ √2) ≀ β€–Ξ¦ βˆ’ a βŠ— bβ€–` for unit `a, b`* `QSL.TwoQubit.sqrt_two_sub_sqrt_two_le_norm_sub_kronecker`: if `G` maps a unit product vector  to `Ξ¦`, then `√(2 βˆ’ √2) ≀ β€–G βˆ’ A βŠ—β‚– Bβ€–` for all unitary `A, B`* `QSL.TwoQubit.norm_exp_add_sub_exp_le`: `β€–exp (X + Y) βˆ’ exp Xβ€– ≀ β€–Yβ€–` for skew-Hermitian `X, Y`* `QSL.TwoQubit.entangling_time_lower_bound`: a controlled evolution  `∏ exp (βˆ’i Ο„β‚– (Lβ‚– + H))` with `β€–Hβ€– ≀ J` that sends a unit product vector to `Ξ¦` satisfies  `√(2 βˆ’ √2) ≀ J Β· βˆ‘ Ο„β‚–` ## References * C. MarΓ­n, *The Clock That Never Ticks: a machine-checked path from the dilogarithm to quantum  speed limits in Lean 4*, Zenodo (2026), doi:10.5281/zenodo.20675271.-/ @[expose] public section noncomputable section open scoped Matrix Kroneckeropen scoped Matrix.Norms.L2Operatoropen NormedSpace namespace QSL.TwoQubit /-- Qubit vectors. -/abbrev Vec2 := EuclideanSpace β„‚ (Fin 2)/-- Two-qubit vectors. -/abbrev Vec4 := EuclideanSpace β„‚ (Fin 2 Γ— Fin 2)/-- Single-qubit operators. -/abbrev Mat2 := Matrix (Fin 2) (Fin 2) β„‚/-- Two-qubit operators. -/abbrev Mat4 := Matrix (Fin 2 Γ— Fin 2) (Fin 2 Γ— Fin 2) β„‚ /-- The product vector `(a βŠ— b) (i, j) = a i * b j`. -/def prodVec (a b : Vec2) : Vec4 := WithLp.toLp 2 fun p => a p.1 * b p.2 /-- The Bell vector `Ξ¦ = (eβ‚€β‚€ + e₁₁)/√2`. -/def bell : Vec4 := WithLp.toLp 2 fun p => if p.1 = p.2 then (((Real.sqrt 2)⁻¹ : ℝ) : β„‚) else 0 /-- Action of a matrix on a Euclidean vector. -/def act {n : Type*} [Fintype n] (M : Matrix n n β„‚) (v : EuclideanSpace β„‚ n) :    EuclideanSpace β„‚ n := WithLp.toLp 2 (M *α΅₯ v.ofLp) private lemma norm_act_le {n : Type*} [Fintype n] [DecidableEq n] (M : Matrix n n β„‚)    (v : EuclideanSpace β„‚ n) : β€–act M vβ€– ≀ β€–Mβ€– * β€–vβ€– :=  M.l2_opNorm_mulVec v private lemma norm_prodVec (a b : Vec2) : β€–prodVec a bβ€– = β€–aβ€– * β€–bβ€– := by  have h : β€–prodVec a bβ€– ^ 2 = (β€–aβ€– * β€–bβ€–) ^ 2 := by    rw [mul_pow, EuclideanSpace.norm_sq_eq, EuclideanSpace.norm_sq_eq,      EuclideanSpace.norm_sq_eq, Finset.sum_mul_sum, Fintype.sum_prod_type]    simp [prodVec, mul_pow]  exact (sq_eq_sqβ‚€ (norm_nonneg _) (mul_nonneg (norm_nonneg _) (norm_nonneg _))).1 h private lemma act_kronecker_prodVec (A B : Mat2) (a b : Vec2) :    act (A βŠ—β‚– B) (prodVec a b) = prodVec (act A a) (act B b) := by  ext ⟨i, j⟩  simp [act, prodVec, Matrix.mulVec, dotProduct, Fintype.sum_prod_type, Matrix.kroneckerMap_apply]  ring private lemma norm_bell : β€–bellβ€– = 1 := by  have h : β€–bellβ€– ^ 2 = 1 ^ 2 := by    rw [EuclideanSpace.norm_sq_eq, Fintype.sum_prod_type]    simp [bell, Fin.sum_univ_two, inv_pow, Real.sq_sqrt]    norm_num  exact (sq_eq_sqβ‚€ (norm_nonneg _) zero_le_one).1 h private lemma sq_norm_two (a : Vec2) : β€–a 0β€– ^ 2 + β€–a 1β€– ^ 2 = β€–aβ€– ^ 2 := by  rw [EuclideanSpace.norm_sq_eq, Fin.sum_univ_two] /-- (1) Bell overlap: `β€–βŸͺΞ¦, a βŠ— bβŸ«β€– ≀ 1/√2` for unit vectors `a, b ∈ β„‚Β²`. -/theorem norm_inner_bell_prodVec_le (a b : Vec2) (ha : β€–aβ€– = 1) (hb : β€–bβ€– = 1) :    β€–inner β„‚ bell (prodVec a b)β€– ≀ (Real.sqrt 2)⁻¹ := by  have e : inner β„‚ bell (prodVec a b) =      (((Real.sqrt 2)⁻¹ : ℝ) : β„‚) * (a 0 * b 0 + a 1 * b 1) := by    simp [PiLp.inner_apply, Fintype.sum_prod_type, Fin.sum_univ_two, bell, prodVec]    ring  rw [e, norm_mul, Complex.norm_real, Real.norm_of_nonneg (by positivity)]  have h1 := sq_norm_two a  have h2 := sq_norm_two b  rw [ha] at h1  rw [hb] at h2  have : β€–a 0 * b 0 + a 1 * b 1β€– ≀ 1 := by    calc β€–a 0 * b 0 + a 1 * b 1β€– ≀ β€–a 0 * b 0β€– + β€–a 1 * b 1β€– := norm_add_le _ _      _ = β€–a 0β€– * β€–b 0β€– + β€–a 1β€– * β€–b 1β€– := by rw [norm_mul, norm_mul]      _ ≀ 1 := by        nlinarith [sq_nonneg (β€–a 0β€– - β€–b 0β€–), sq_nonneg (β€–a 1β€– - β€–b 1β€–)]  have hpos : 0 ≀ (Real.sqrt 2)⁻¹ := by positivity  nlinarith /-- (2) Distance: `√(2 βˆ’ √2) ≀ β€–Ξ¦ βˆ’ a βŠ— bβ€–` for unit vectors `a, b ∈ β„‚Β²`. -/theorem sqrt_two_sub_sqrt_two_le_norm_bell_sub_prodVec (a b : Vec2) (ha : β€–aβ€– = 1)    (hb : β€–bβ€– = 1) : Real.sqrt (2 - Real.sqrt 2) ≀ β€–bell - prodVec a bβ€– := by  have hv : β€–prodVec a bβ€– = 1 := by rw [norm_prodVec, ha, hb, one_mul]  have hre : RCLike.re (inner β„‚ bell (prodVec a b)) ≀ (Real.sqrt 2)⁻¹ :=    (RCLike.re_le_norm _).trans (norm_inner_bell_prodVec_le a b ha hb)  have hs : (Real.sqrt 2)⁻¹ * 2 = Real.sqrt 2 := by    have h2 : Real.sqrt 2 * Real.sqrt 2 = 2 := Real.mul_self_sqrt (by norm_num)    have h0 : Real.sqrt 2 β‰  0 := by positivity    field_simp    linarith  have key : 2 - Real.sqrt 2 ≀ β€–bell - prodVec a bβ€– ^ 2 := by    rw [norm_sub_sq (π•œ := β„‚), norm_bell, hv]    linarith  exact Real.sqrt_le_iff.2 ⟨norm_nonneg _, key⟩ private lemma act_act {n : Type*} [Fintype n] (M N : Matrix n n β„‚) (v : EuclideanSpace β„‚ n) :    act M (act N v) = act (M * N) v := by  ext i  simp [act, Matrix.mulVec_mulVec] private lemma act_sub {n : Type*} [Fintype n] (M N : Matrix n n β„‚) (v : EuclideanSpace β„‚ n) :    act (M - N) v = act M v - act N v := by  ext i  simp [act, Matrix.sub_mulVec] private lemma norm_act_unitary (A : Mat2) (hA : A ∈ Matrix.unitaryGroup (Fin 2) β„‚) (a : Vec2) :    β€–act A aβ€– = β€–aβ€– := by  have hn : β€–Aβ€– = 1 := CStarRing.norm_of_mem_unitary hA  have h1 : β€–act A aβ€– ≀ β€–aβ€– := by    simpa [hn] using norm_act_le A a  have h2 : a = act Aα΄΄ (act A a) := by    rw [act_act]    have : Aα΄΄ * A = 1 := Matrix.mem_unitaryGroup_iff'.1 hA    rw [this]    ext i    simp [act]  have h3 : β€–aβ€– ≀ β€–act A aβ€– := by    calc β€–aβ€– = β€–act Aα΄΄ (act A a)β€– := by rw [← h2]      _ ≀ β€–Aα΄΄β€– * β€–act A aβ€– := norm_act_le _ _      _ = β€–act A aβ€– := by rw [Matrix.l2_opNorm_conjTranspose, hn, one_mul]  exact le_antisymm h1 h3 /-- (3) Entangling gates are far from local gates: if `G` maps a unit product vector to `Ξ¦`,then `√(2 βˆ’ √2) ≀ β€–G βˆ’ A βŠ—β‚– Bβ€–` for all unitary `2 Γ— 2` matrices `A, B`. -/theorem sqrt_two_sub_sqrt_two_le_norm_sub_kronecker (G : Mat4) (a b : Vec2) (ha : β€–aβ€– = 1)    (hb : β€–bβ€– = 1) (hG : act G (prodVec a b) = bell) (A B : Mat2)    (hA : A ∈ Matrix.unitaryGroup (Fin 2) β„‚) (hB : B ∈ Matrix.unitaryGroup (Fin 2) β„‚) :    Real.sqrt (2 - Real.sqrt 2) ≀ β€–G - A βŠ—β‚– Bβ€– := by  have h1 := sqrt_two_sub_sqrt_two_le_norm_bell_sub_prodVec (act A a) (act B b)    ((norm_act_unitary A hA a).trans ha) ((norm_act_unitary B hB b).trans hb)  have e : act (G - A βŠ—β‚– B) (prodVec a b) = bell - prodVec (act A a) (act B b) := by    rw [act_sub, hG, act_kronecker_prodVec]  have h2 := norm_act_le (G - A βŠ—β‚– B) (prodVec a b)  rw [e, norm_prodVec, ha, hb, mul_one, mul_one] at h2  exact h1.trans h2 /-! ### Exponentials of skew-Hermitian matrices and the Duhamel estimate -/ private lemma exp_mem_unitary {n : Type*} [Fintype n] [DecidableEq n] (Z : Matrix n n β„‚)    (hZ : Zα΄΄ = -Z) : exp Z ∈ Matrix.unitaryGroup n β„‚ := by  let +nondep : NormedAlgebra β„š (Matrix n n β„‚) := .restrictScalars β„š β„‚ _  exact exp_mem_unitary_of_mem_skewAdjoint    (by simpa [skewAdjoint.mem_iff, Matrix.star_eq_conjTranspose] using hZ) private lemma norm_exp_skew {n : Type*} [Fintype n] [DecidableEq n] [Nonempty n]    (Z : Matrix n n β„‚) (hZ : Zα΄΄ = -Z) : β€–exp Zβ€– = 1 :=  CStarRing.norm_of_mem_unitary (exp_mem_unitary Z hZ) /-- (4) Duhamel step: for skew-Hermitian `X, Y`, `β€–exp (X + Y) βˆ’ exp Xβ€– ≀ β€–Yβ€–`. -/theorem norm_exp_add_sub_exp_le {n : Type*} [Fintype n] [DecidableEq n] [Nonempty n]    (X Y : Matrix n n β„‚) (hX : Xα΄΄ = -X) (hY : Yα΄΄ = -Y) :    β€–exp (X + Y) - exp Xβ€– ≀ β€–Yβ€– := by  have hXY : (X + Y)α΄΄ = -(X + Y) := by rw [Matrix.conjTranspose_add, hX, hY, neg_add]  have hs : βˆ€ (Z : Matrix n n β„‚), Zα΄΄ = -Z β†’ βˆ€ t : ℝ, β€–exp (t β€’ Z)β€– = 1 := by    intro Z hZ t    apply norm_exp_skew    rw [Matrix.conjTranspose_smul, hZ]    simp  let f : ℝ β†’ Matrix n n β„‚ := fun t => exp (t β€’ (X + Y)) * exp ((1 - t) β€’ X)  have hd : βˆ€ t : ℝ, HasDerivAt f (exp (t β€’ (X + Y)) * Y * exp ((1 - t) β€’ X)) t := by    intro t    have h1 : HasDerivAt (fun u : ℝ => exp (u β€’ (X + Y))) (exp (t β€’ (X + Y)) * (X + Y)) t :=      hasDerivAt_exp_smul_const (X + Y) t    have h2 : HasDerivAt (fun u : ℝ => exp (u β€’ X)) (X * exp ((1 - t) β€’ X)) (1 - t) :=      hasDerivAt_exp_smul_const' X (1 - t)    have h3 : HasDerivAt (fun u : ℝ => 1 - u) (-1) t := by      simpa using (hasDerivAt_id t).const_sub 1    have h4 := HasDerivAt.scomp t h2 h3    have h5 := h1.mul h4    have h6 : HasDerivAt f (exp (t β€’ (X + Y)) * (X + Y) * exp ((1 - t) β€’ X) +        exp (t β€’ (X + Y)) * ((-1 : ℝ) β€’ (X * exp ((1 - t) β€’ X)))) t := h5    refine h6.congr_deriv ?_    simp only [neg_smul, one_smul, mul_neg]    noncomm_ring  have hb : βˆ€ t ∈ Set.Ico (0 : ℝ) 1, β€–exp (t β€’ (X + Y)) * Y * exp ((1 - t) β€’ X)β€– ≀ β€–Yβ€– := by    intro t _    calc β€–exp (t β€’ (X + Y)) * Y * exp ((1 - t) β€’ X)β€–        ≀ β€–exp (t β€’ (X + Y)) * Yβ€– * β€–exp ((1 - t) β€’ X)β€– := norm_mul_le _ _      _ ≀ (β€–exp (t β€’ (X + Y))β€– * β€–Yβ€–) * β€–exp ((1 - t) β€’ X)β€– := by          gcongr; exact norm_mul_le _ _      _ = β€–Yβ€– := by rw [hs _ hXY, hs _ hX]; ring  have := norm_image_sub_le_of_norm_deriv_le_segment_01' (f := f)    (fun t _ => (hd t).hasDerivWithinAt) hb  simpa [f] using this /-! ### Local evolutions and the main theorem -/ /-- `A ↦ A βŠ—β‚– 1` as a ring homomorphism. -/private def kronLeft : Mat2 β†’+* Mat4 where  toFun A := A βŠ—β‚– (1 : Mat2)  map_one' := Matrix.one_kronecker_one  map_mul' A B := by rw [← Matrix.mul_kronecker_mul, mul_one]  map_zero' := Matrix.zero_kronecker _  map_add' A B := Matrix.add_kronecker _ _ _ /-- `B ↦ 1 βŠ—β‚– B` as a ring homomorphism. -/private def kronRight : Mat2 β†’+* Mat4 where  toFun B := (1 : Mat2) βŠ—β‚– B  map_one' := Matrix.one_kronecker_one  map_mul' A B := by rw [← Matrix.mul_kronecker_mul, mul_one]  map_zero' := Matrix.kronecker_zero _  map_add' A B := Matrix.kronecker_add _ _ _ private lemma continuous_kronLeft : Continuous kronLeft := by  refine continuous_matrix fun ⟨i, j⟩ ⟨k, l⟩ => ?_  simp only [kronLeft, RingHom.coe_mk, MonoidHom.coe_mk, OneHom.coe_mk,    Matrix.kroneckerMap_apply]  fun_prop private lemma continuous_kronRight : Continuous kronRight := by  refine continuous_matrix fun ⟨i, j⟩ ⟨k, l⟩ => ?_  simp only [kronRight, RingHom.coe_mk, MonoidHom.coe_mk, OneHom.coe_mk,    Matrix.kroneckerMap_apply]  fun_prop private lemma exp_kronLeft (A : Mat2) : exp (A βŠ—β‚– (1 : Mat2)) = exp A βŠ—β‚– (1 : Mat2) := by  let +nondep : NormedAlgebra β„š Mat2 := .restrictScalars β„š β„‚ _  exact (map_exp kronLeft continuous_kronLeft A).symm private lemma exp_kronRight (B : Mat2) : exp ((1 : Mat2) βŠ—β‚– B) = (1 : Mat2) βŠ—β‚– exp B := by  let +nondep : NormedAlgebra β„š Mat2 := .restrictScalars β„š β„‚ _  exact (map_exp kronRight continuous_kronRight B).symm private lemma exp_local (A B : Mat2) :    exp (A βŠ—β‚– (1 : Mat2) + (1 : Mat2) βŠ—β‚– B) = exp A βŠ—β‚– exp B := by  let +nondep : NormedAlgebra β„š Mat4 := .restrictScalars β„š β„‚ _  have hc : Commute (A βŠ—β‚– (1 : Mat2)) ((1 : Mat2) βŠ—β‚– B) := by    show _ * _ = _ * _    rw [← Matrix.mul_kronecker_mul, ← Matrix.mul_kronecker_mul]    simp  rw [exp_add_of_commute hc, exp_kronLeft, exp_kronRight, ← Matrix.mul_kronecker_mul]  simp private lemma skew_smul {n : Type*} [Fintype n] (Ο„ : ℝ) {M : Matrix n n β„‚} (hM : Mα΄΄ = M) :    ((-(Ο„ : β„‚) * Complex.I) β€’ M)α΄΄ = -((-(Ο„ : β„‚) * Complex.I) β€’ M) := by  rw [Matrix.conjTranspose_smul, hM, ← neg_smul]  congr 1  apply Complex.ext <;> simp private lemma hermitian_local (A B : Mat2) (hA : Aα΄΄ = A) (hB : Bα΄΄ = B) :    (A βŠ—β‚– (1 : Mat2) + (1 : Mat2) βŠ—β‚– B)α΄΄ = A βŠ—β‚– (1 : Mat2) + (1 : Mat2) βŠ—β‚– B := by  rw [Matrix.conjTranspose_add, Matrix.conjTranspose_kronecker, Matrix.conjTranspose_kronecker,    hA, hB, Matrix.conjTranspose_one] /-- One step of the controlled evolution: `exp (βˆ’i Ο„ (A βŠ— 1 + 1 βŠ— B + H))`. -/private def Ustep (H : Mat4) (s : ℝ Γ— Mat2 Γ— Mat2) : Mat4 :=  exp ((-(s.1 : β„‚) * Complex.I) β€’ (s.2.1 βŠ—β‚– (1 : Mat2) + (1 : Mat2) βŠ—β‚– s.2.2 + H)) /-- The local part of a step: `exp (βˆ’i Ο„ A) βŠ— exp (βˆ’i Ο„ B)`. -/private def Vstep (s : ℝ Γ— Mat2 Γ— Mat2) : Mat4 :=  exp ((-(s.1 : β„‚) * Complex.I) β€’ s.2.1) βŠ—β‚– exp ((-(s.1 : β„‚) * Complex.I) β€’ s.2.2) private lemma Vstep_eq (s : ℝ Γ— Mat2 Γ— Mat2) :    Vstep s = exp ((-(s.1 : β„‚) * Complex.I) β€’ (s.2.1 βŠ—β‚– (1 : Mat2) + (1 : Mat2) βŠ—β‚– s.2.2)) := by  unfold Vstep  rw [smul_add, ← Matrix.smul_kronecker, ← Matrix.kronecker_smul, exp_local] private lemma step_core (L H : Mat4) (Ο„ : ℝ) (hΟ„ : 0 ≀ Ο„) (hL : Lα΄΄ = L) (hH : Hα΄΄ = H) :    β€–exp ((-(Ο„ : β„‚) * Complex.I) β€’ (L + H))β€– ≀ 1 ∧ β€–exp ((-(Ο„ : β„‚) * Complex.I) β€’ L)β€– ≀ 1 ∧      β€–exp ((-(Ο„ : β„‚) * Complex.I) β€’ (L + H)) - exp ((-(Ο„ : β„‚) * Complex.I) β€’ L)β€– ≀        Ο„ * β€–Hβ€– := by  have hsL := skew_smul Ο„ hL  have hsH := skew_smul Ο„ hH  have hsum := skew_smul Ο„ (show (L + H)α΄΄ = L + H by rw [Matrix.conjTranspose_add, hL, hH])  refine ⟨(norm_exp_skew _ hsum).le, (norm_exp_skew _ hsL).le, ?_⟩  have key := norm_exp_add_sub_exp_le _ _ hsL hsH  rw [smul_add]  refine key.trans (le_of_eq ?_)  rw [norm_smul]  have : β€–(-(Ο„ : β„‚) * Complex.I)β€– = Ο„ := by    simp [abs_of_nonneg hΟ„]  rw [this] private lemma step_facts (H : Mat4) (hH : Hα΄΄ = H) (J : ℝ) (hJ : β€–Hβ€– ≀ J)    (s : ℝ Γ— Mat2 Γ— Mat2) (hΟ„ : 0 ≀ s.1) (hA : s.2.1α΄΄ = s.2.1) (hB : s.2.2α΄΄ = s.2.2) :    β€–Ustep H sβ€– ≀ 1 ∧ β€–Vstep sβ€– ≀ 1 ∧ β€–Ustep H s - Vstep sβ€– ≀ J * s.1 := by  obtain ⟨h1, h2, h3⟩ := step_core _ H s.1 hΟ„ (hermitian_local _ _ hA hB) hH  rw [Vstep_eq]  refine ⟨h1, h2, h3.trans ?_⟩  nlinarith private lemma norm_list_prod_le (f : ℝ Γ— Mat2 Γ— Mat2 β†’ Mat4) (l : List (ℝ Γ— Mat2 Γ— Mat2))    (hf : βˆ€ s ∈ l, β€–f sβ€– ≀ 1) : β€–(l.map f).prodβ€– ≀ 1 := by  induction l with  | nil => simp  | cons s l ih =>    rw [List.map_cons, List.prod_cons]    have h1 := hf s (by simp)    have h2 := ih fun t ht => hf t (by simp [ht])    calc β€–f s * (l.map f).prodβ€– ≀ β€–f sβ€– * β€–(l.map f).prodβ€– := norm_mul_le _ _      _ ≀ 1 := by nlinarith [norm_nonneg (f s), norm_nonneg (l.map f).prod] private lemma norm_list_prod_sub_le (f g : ℝ Γ— Mat2 Γ— Mat2 β†’ Mat4) (w : ℝ Γ— Mat2 Γ— Mat2 β†’ ℝ)    (l : List (ℝ Γ— Mat2 Γ— Mat2)) (hf : βˆ€ s ∈ l, β€–f sβ€– ≀ 1) (hg : βˆ€ s ∈ l, β€–g sβ€– ≀ 1)    (hw : βˆ€ s ∈ l, β€–f s - g sβ€– ≀ w s) :    β€–(l.map f).prod - (l.map g).prodβ€– ≀ (l.map w).sum := by  induction l with  | nil => simp  | cons s l ih =>    rw [List.map_cons, List.prod_cons, List.map_cons, List.prod_cons, List.map_cons,      List.sum_cons]    have ih' := ih (fun t ht => hf t (by simp [ht])) (fun t ht => hg t (by simp [ht]))      (fun t ht => hw t (by simp [ht]))    have hP := norm_list_prod_le f l (fun t ht => hf t (by simp [ht]))    have hgs := hg s (by simp)    have hws := hw s (by simp)    have e : f s * (l.map f).prod - g s * (l.map g).prod =        (f s - g s) * (l.map f).prod + g s * ((l.map f).prod - (l.map g).prod) := by      noncomm_ring    rw [e]    calc _ ≀ β€–(f s - g s) * (l.map f).prodβ€– + β€–g s * ((l.map f).prod - (l.map g).prod)β€– :=          norm_add_le _ _      _ ≀ β€–f s - g sβ€– * β€–(l.map f).prodβ€– +          β€–g sβ€– * β€–(l.map f).prod - (l.map g).prodβ€– := add_le_add (norm_mul_le _ _) (norm_mul_le _ _)      _ ≀ w s + (l.map w).sum := by          have := norm_nonneg (f s - g s)          have := norm_nonneg (g s)          have := norm_nonneg ((l.map f).prod - (l.map g).prod)          nlinarith [norm_nonneg ((l.map f).prod)] private lemma local_prod (l : List (ℝ Γ— Mat2 Γ— Mat2)) (hA : βˆ€ s ∈ l, s.2.1α΄΄ = s.2.1)    (hB : βˆ€ s ∈ l, s.2.2α΄΄ = s.2.2) :    βˆƒ P Q : Mat2, P ∈ Matrix.unitaryGroup (Fin 2) β„‚ ∧ Q ∈ Matrix.unitaryGroup (Fin 2) β„‚ ∧      (l.map Vstep).prod = P βŠ—β‚– Q := by  induction l with  | nil => exact ⟨1, 1, one_mem _, one_mem _, by simp⟩  | cons s l ih =>    obtain ⟨P, Q, hP, hQ, h⟩ :=      ih (fun t ht => hA t (by simp [ht])) (fun t ht => hB t (by simp [ht]))    refine ⟨exp ((-(s.1 : β„‚) * Complex.I) β€’ s.2.1) * P,      exp ((-(s.1 : β„‚) * Complex.I) β€’ s.2.2) * Q, mul_mem (exp_mem_unitary _ ?_) hP,      mul_mem (exp_mem_unitary _ ?_) hQ, ?_⟩    Β· exact skew_smul s.1 (hA s (by simp))    Β· exact skew_smul s.1 (hB s (by simp))    Β· rw [List.map_cons, List.prod_cons, h, Vstep, ← Matrix.mul_kronecker_mul] /-- (5) Main theorem. Let `H` be a Hermitian interaction with `β€–Hβ€– ≀ J` and let`U = βˆβ‚– exp (βˆ’i Ο„β‚– (Aβ‚– βŠ— 1 + 1 βŠ— Bβ‚– + H))` (an ordered product over the list `steps` oftriples `(Ο„β‚–, Aβ‚–, Bβ‚–)`, `Ο„β‚– β‰₯ 0`, `Aβ‚–, Bβ‚–` Hermitian) be a controlled evolution with arbitrarylocal controls. If `U` maps a unit product vector `a βŠ— b` to the Bell vector `Ξ¦`, then`√(2 βˆ’ √2) ≀ J Β· βˆ‘ Ο„β‚–`. -/theorem entangling_time_lower_bound (H : Mat4) (hH : H.IsHermitian) (J : ℝ) (hJ : β€–Hβ€– ≀ J)    (steps : List (ℝ Γ— Mat2 Γ— Mat2)) (hΟ„ : βˆ€ s ∈ steps, 0 ≀ s.1)    (hA : βˆ€ s ∈ steps, s.2.1.IsHermitian) (hB : βˆ€ s ∈ steps, s.2.2.IsHermitian)    (a b : Vec2) (ha : β€–aβ€– = 1) (hb : β€–bβ€– = 1)    (hU : act (steps.map fun s => exp ((-(s.1 : β„‚) * Complex.I) β€’        (s.2.1 βŠ—β‚– (1 : Mat2) + (1 : Mat2) βŠ—β‚– s.2.2 + H))).prod (prodVec a b) = bell) :    Real.sqrt (2 - Real.sqrt 2) ≀ J * (steps.map Prod.fst).sum := by  obtain ⟨P, Q, hP, hQ, hV⟩ := local_prod steps (fun s hs => (hA s hs).eq) (fun s hs => (hB s hs).eq)  have h3 := sqrt_two_sub_sqrt_two_le_norm_sub_kronecker _ a b ha hb hU P Q hP hQ  rw [← hV] at h3  have facts := fun s (hs : s ∈ steps) =>    step_facts H hH.eq J hJ s (hΟ„ s hs) (hA s hs).eq (hB s hs).eq  have h4 := norm_list_prod_sub_le (Ustep H) Vstep (fun s => J * s.1) steps    (fun s hs => (facts s hs).1) (fun s hs => (facts s hs).2.1) (fun s hs => (facts s hs).2.2)  have e : (steps.map fun s => J * s.1).sum = J * (steps.map Prod.fst).sum := by    rw [List.sum_map_mul_left]  rw [e] at h4  exact h3.trans h4 end QSL.TwoQubit