[GOAL]
n : ℕ
⊢ ∀ (a b c : QuaternionGroup n), a * b * c = a * (b * c)
[PROOFSTEP]
rintro (i | i) (j | j) (k | k)
[GOAL]
case a.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * a j * a k = a i * (a j * a k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case a.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * a j * xa k = a i * (a j * xa k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case a.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * xa j * a k = a i * (xa j * a k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case a.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a i * xa j * xa k = a i * (xa j * xa k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case xa.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * a j * a k = xa i * (a j * a k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case xa.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * a j * xa k = xa i * (a j * xa k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case xa.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * xa j * a k = xa i * (xa j * a k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case xa.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa i * xa j * xa k = xa i * (xa j * xa k)
[PROOFSTEP]
simp only [(· * ·), mul]
[GOAL]
case a.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a (i + j + k) = a (i + (j + k))
[PROOFSTEP]
ring_nf
[GOAL]
case a.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (k - (i + j)) = xa (k - j - i)
[PROOFSTEP]
ring_nf
[GOAL]
case a.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (j - i + k) = xa (j + k - i)
[PROOFSTEP]
ring_nf
[GOAL]
case a.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a (↑n + k - (j - i)) = a (i + (↑n + k - j))
[PROOFSTEP]
ring_nf
[GOAL]
case xa.a.a
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (i + j + k) = xa (i + (j + k))
[PROOFSTEP]
ring_nf
[GOAL]
case xa.a.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ a (↑n + k - (i + j)) = a (↑n + (k - j) - i)
[PROOFSTEP]
ring_nf
[GOAL]
case xa.xa.a
n : ℕ
i j k : ZMod (2 * n)
⊢ a (↑n + j - i + k) = a (↑n + (j + k) - i)
[PROOFSTEP]
ring_nf
[GOAL]
case xa.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (k - (↑n + j - i)) = xa (i + (↑n + k - j))
[PROOFSTEP]
ring_nf
[GOAL]
case xa.xa.xa
n : ℕ
i j k : ZMod (2 * n)
⊢ xa (k + (-↑n - j) + i) = xa (k + (↑n - j) + i)
[PROOFSTEP]
congr
[GOAL]
case xa.xa.xa.e_a.e_a.e_a.e_a
n : ℕ
i j k : ZMod (2 * n)
⊢ -↑n = ↑n
[PROOFSTEP]
calc
  -(n : ZMod (2 * n)) = 0 - n := by rw [zero_sub]
  _ = 2 * n - n := by norm_cast; simp
  _ = n := by ring
[GOAL]
n : ℕ
i j k : ZMod (2 * n)
⊢ -↑n = 0 - ↑n
[PROOFSTEP]
rw [zero_sub]
[GOAL]
n : ℕ
i j k : ZMod (2 * n)
⊢ 0 - ↑n = 2 * ↑n - ↑n
[PROOFSTEP]
norm_cast
[GOAL]
n : ℕ
i j k : ZMod (2 * n)
⊢ ↑(Int.subNatNat 0 n) = ↑(Int.subNatNat (2 * n) n)
[PROOFSTEP]
simp
[GOAL]
n : ℕ
i j k : ZMod (2 * n)
⊢ 2 * ↑n - ↑n = ↑n
[PROOFSTEP]
ring
[GOAL]
n : ℕ
⊢ ∀ (a : QuaternionGroup n), 1 * a = a
[PROOFSTEP]
rintro (i | i)
[GOAL]
case a
n : ℕ
i : ZMod (2 * n)
⊢ 1 * a i = a i
[PROOFSTEP]
exact congr_arg a (zero_add i)
[GOAL]
case xa
n : ℕ
i : ZMod (2 * n)
⊢ 1 * xa i = xa i
[PROOFSTEP]
exact congr_arg xa (sub_zero i)
[GOAL]
n : ℕ
⊢ ∀ (a : QuaternionGroup n), a * 1 = a
[PROOFSTEP]
rintro (i | i)
[GOAL]
case a
n : ℕ
i : ZMod (2 * n)
⊢ a i * 1 = a i
[PROOFSTEP]
exact congr_arg a (add_zero i)
[GOAL]
case xa
n : ℕ
i : ZMod (2 * n)
⊢ xa i * 1 = xa i
[PROOFSTEP]
exact congr_arg xa (add_zero i)
[GOAL]
n : ℕ
⊢ ∀ (a : QuaternionGroup n), a⁻¹ * a = 1
[PROOFSTEP]
rintro (i | i)
[GOAL]
case a
n : ℕ
i : ZMod (2 * n)
⊢ (a i)⁻¹ * a i = 1
[PROOFSTEP]
exact congr_arg a (neg_add_self i)
[GOAL]
case xa
n : ℕ
i : ZMod (2 * n)
⊢ (xa i)⁻¹ * xa i = 1
[PROOFSTEP]
exact congr_arg a (sub_self (n + i))
[GOAL]
n : ℕ
⊢ Function.LeftInverse
    (fun i =>
      match i with
      | a j => Sum.inl j
      | xa j => Sum.inr j)
    fun i =>
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
[PROOFSTEP]
rintro (x | x)
[GOAL]
case inl
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | a j => Sum.inl j
        | xa j => Sum.inr j)
      ((fun i =>
          match i with
          | Sum.inl j => a j
          | Sum.inr j => xa j)
        (Sum.inl x)) =
    Sum.inl x
[PROOFSTEP]
rfl
[GOAL]
case inr
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | a j => Sum.inl j
        | xa j => Sum.inr j)
      ((fun i =>
          match i with
          | Sum.inl j => a j
          | Sum.inr j => xa j)
        (Sum.inr x)) =
    Sum.inr x
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
⊢ Function.RightInverse
    (fun i =>
      match i with
      | a j => Sum.inl j
      | xa j => Sum.inr j)
    fun i =>
    match i with
    | Sum.inl j => a j
    | Sum.inr j => xa j
[PROOFSTEP]
rintro (x | x)
[GOAL]
case a
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | Sum.inl j => a j
        | Sum.inr j => xa j)
      ((fun i =>
          match i with
          | a j => Sum.inl j
          | xa j => Sum.inr j)
        (a x)) =
    a x
[PROOFSTEP]
rfl
[GOAL]
case xa
n : ℕ
x : ZMod (2 * n)
⊢ (fun i =>
        match i with
        | Sum.inl j => a j
        | Sum.inr j => xa j)
      ((fun i =>
          match i with
          | a j => Sum.inl j
          | xa j => Sum.inr j)
        (xa x)) =
    xa x
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
⊢ Function.LeftInverse
    (fun i =>
      match i with
      | DihedralGroup.r j => a j
      | DihedralGroup.sr j => xa j)
    fun i =>
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j
[PROOFSTEP]
rintro (k | k)
[GOAL]
case a
n : ℕ
k : ZMod (2 * 0)
⊢ (fun i =>
        match i with
        | DihedralGroup.r j => a j
        | DihedralGroup.sr j => xa j)
      ((fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j)
        (a k)) =
    a k
[PROOFSTEP]
rfl
[GOAL]
case xa
n : ℕ
k : ZMod (2 * 0)
⊢ (fun i =>
        match i with
        | DihedralGroup.r j => a j
        | DihedralGroup.sr j => xa j)
      ((fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j)
        (xa k)) =
    xa k
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
⊢ Function.RightInverse
    (fun i =>
      match i with
      | DihedralGroup.r j => a j
      | DihedralGroup.sr j => xa j)
    fun i =>
    match i with
    | a j => DihedralGroup.r j
    | xa j => DihedralGroup.sr j
[PROOFSTEP]
rintro (k | k)
[GOAL]
case r
n : ℕ
k : ZMod 0
⊢ (fun i =>
        match i with
        | a j => DihedralGroup.r j
        | xa j => DihedralGroup.sr j)
      ((fun i =>
          match i with
          | DihedralGroup.r j => a j
          | DihedralGroup.sr j => xa j)
        (DihedralGroup.r k)) =
    DihedralGroup.r k
[PROOFSTEP]
rfl
[GOAL]
case sr
n : ℕ
k : ZMod 0
⊢ (fun i =>
        match i with
        | a j => DihedralGroup.r j
        | xa j => DihedralGroup.sr j)
      ((fun i =>
          match i with
          | DihedralGroup.r j => a j
          | DihedralGroup.sr j => xa j)
        (DihedralGroup.sr k)) =
    DihedralGroup.sr k
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
⊢ ∀ (x y : QuaternionGroup 0),
    Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (x * y) =
      Equiv.toFun
          {
            toFun := fun i =>
              match i with
              | a j => DihedralGroup.r j
              | xa j => DihedralGroup.sr j,
            invFun := fun i =>
              match i with
              | DihedralGroup.r j => a j
              | DihedralGroup.sr j => xa j,
            left_inv :=
              (_ :
                ∀ (x : QuaternionGroup 0),
                  (fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      ((fun i =>
                          match i with
                          | a j => DihedralGroup.r j
                          | xa j => DihedralGroup.sr j)
                        x) =
                    x),
            right_inv :=
              (_ :
                ∀ (x : DihedralGroup 0),
                  (fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      ((fun i =>
                          match i with
                          | DihedralGroup.r j => a j
                          | DihedralGroup.sr j => xa j)
                        x) =
                    x) }
          x *
        Equiv.toFun
          {
            toFun := fun i =>
              match i with
              | a j => DihedralGroup.r j
              | xa j => DihedralGroup.sr j,
            invFun := fun i =>
              match i with
              | DihedralGroup.r j => a j
              | DihedralGroup.sr j => xa j,
            left_inv :=
              (_ :
                ∀ (x : QuaternionGroup 0),
                  (fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      ((fun i =>
                          match i with
                          | a j => DihedralGroup.r j
                          | xa j => DihedralGroup.sr j)
                        x) =
                    x),
            right_inv :=
              (_ :
                ∀ (x : DihedralGroup 0),
                  (fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      ((fun i =>
                          match i with
                          | DihedralGroup.r j => a j
                          | DihedralGroup.sr j => xa j)
                        x) =
                    x) }
          y
[PROOFSTEP]
rintro (k | k) (l | l)
[GOAL]
case a.a
n : ℕ
k l : ZMod (2 * 0)
⊢ Equiv.toFun
      {
        toFun := fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j,
        invFun := fun i =>
          match i with
          | DihedralGroup.r j => a j
          | DihedralGroup.sr j => xa j,
        left_inv :=
          (_ :
            ∀ (x : QuaternionGroup 0),
              (fun i =>
                    match i with
                    | DihedralGroup.r j => a j
                    | DihedralGroup.sr j => xa j)
                  ((fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    x) =
                x),
        right_inv :=
          (_ :
            ∀ (x : DihedralGroup 0),
              (fun i =>
                    match i with
                    | a j => DihedralGroup.r j
                    | xa j => DihedralGroup.sr j)
                  ((fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    x) =
                x) }
      (a k * a l) =
    Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (a k) *
      Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (a l)
[PROOFSTEP]
simp
[GOAL]
case a.xa
n : ℕ
k l : ZMod (2 * 0)
⊢ Equiv.toFun
      {
        toFun := fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j,
        invFun := fun i =>
          match i with
          | DihedralGroup.r j => a j
          | DihedralGroup.sr j => xa j,
        left_inv :=
          (_ :
            ∀ (x : QuaternionGroup 0),
              (fun i =>
                    match i with
                    | DihedralGroup.r j => a j
                    | DihedralGroup.sr j => xa j)
                  ((fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    x) =
                x),
        right_inv :=
          (_ :
            ∀ (x : DihedralGroup 0),
              (fun i =>
                    match i with
                    | a j => DihedralGroup.r j
                    | xa j => DihedralGroup.sr j)
                  ((fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    x) =
                x) }
      (a k * xa l) =
    Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (a k) *
      Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (xa l)
[PROOFSTEP]
simp
[GOAL]
case xa.a
n : ℕ
k l : ZMod (2 * 0)
⊢ Equiv.toFun
      {
        toFun := fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j,
        invFun := fun i =>
          match i with
          | DihedralGroup.r j => a j
          | DihedralGroup.sr j => xa j,
        left_inv :=
          (_ :
            ∀ (x : QuaternionGroup 0),
              (fun i =>
                    match i with
                    | DihedralGroup.r j => a j
                    | DihedralGroup.sr j => xa j)
                  ((fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    x) =
                x),
        right_inv :=
          (_ :
            ∀ (x : DihedralGroup 0),
              (fun i =>
                    match i with
                    | a j => DihedralGroup.r j
                    | xa j => DihedralGroup.sr j)
                  ((fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    x) =
                x) }
      (xa k * a l) =
    Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (xa k) *
      Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (a l)
[PROOFSTEP]
simp
[GOAL]
case xa.xa
n : ℕ
k l : ZMod (2 * 0)
⊢ Equiv.toFun
      {
        toFun := fun i =>
          match i with
          | a j => DihedralGroup.r j
          | xa j => DihedralGroup.sr j,
        invFun := fun i =>
          match i with
          | DihedralGroup.r j => a j
          | DihedralGroup.sr j => xa j,
        left_inv :=
          (_ :
            ∀ (x : QuaternionGroup 0),
              (fun i =>
                    match i with
                    | DihedralGroup.r j => a j
                    | DihedralGroup.sr j => xa j)
                  ((fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    x) =
                x),
        right_inv :=
          (_ :
            ∀ (x : DihedralGroup 0),
              (fun i =>
                    match i with
                    | a j => DihedralGroup.r j
                    | xa j => DihedralGroup.sr j)
                  ((fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    x) =
                x) }
      (xa k * xa l) =
    Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (xa k) *
      Equiv.toFun
        {
          toFun := fun i =>
            match i with
            | a j => DihedralGroup.r j
            | xa j => DihedralGroup.sr j,
          invFun := fun i =>
            match i with
            | DihedralGroup.r j => a j
            | DihedralGroup.sr j => xa j,
          left_inv :=
            (_ :
              ∀ (x : QuaternionGroup 0),
                (fun i =>
                      match i with
                      | DihedralGroup.r j => a j
                      | DihedralGroup.sr j => xa j)
                    ((fun i =>
                        match i with
                        | a j => DihedralGroup.r j
                        | xa j => DihedralGroup.sr j)
                      x) =
                  x),
          right_inv :=
            (_ :
              ∀ (x : DihedralGroup 0),
                (fun i =>
                      match i with
                      | a j => DihedralGroup.r j
                      | xa j => DihedralGroup.sr j)
                    ((fun i =>
                        match i with
                        | DihedralGroup.r j => a j
                        | DihedralGroup.sr j => xa j)
                      x) =
                  x) }
        (xa l)
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ a 0 ≠ xa 0
[PROOFSTEP]
revert n
[GOAL]
⊢ ∀ {n : ℕ}, a 0 ≠ xa 0
[PROOFSTEP]
simp
[GOAL]
n : ℕ
inst✝ : NeZero n
⊢ Fintype.card (QuaternionGroup n) = 4 * n
[PROOFSTEP]
rw [← Fintype.card_eq.mpr ⟨fintypeHelper⟩, Fintype.card_sum, ZMod.card, two_mul]
[GOAL]
n : ℕ
inst✝ : NeZero n
⊢ n + n + (n + n) = 4 * n
[PROOFSTEP]
ring
[GOAL]
n k : ℕ
⊢ a 1 ^ k = a ↑k
[PROOFSTEP]
induction' k with k IH
[GOAL]
case zero
n : ℕ
⊢ a 1 ^ Nat.zero = a ↑Nat.zero
[PROOFSTEP]
rw [Nat.cast_zero]
[GOAL]
case zero
n : ℕ
⊢ a 1 ^ Nat.zero = a 0
[PROOFSTEP]
rfl
[GOAL]
case succ
n k : ℕ
IH : a 1 ^ k = a ↑k
⊢ a 1 ^ Nat.succ k = a ↑(Nat.succ k)
[PROOFSTEP]
rw [pow_succ, IH, a_mul_a]
[GOAL]
case succ
n k : ℕ
IH : a 1 ^ k = a ↑k
⊢ a (1 + ↑k) = a ↑(Nat.succ k)
[PROOFSTEP]
congr 1
[GOAL]
case succ.e_a
n k : ℕ
IH : a 1 ^ k = a ↑k
⊢ 1 + ↑k = ↑(Nat.succ k)
[PROOFSTEP]
norm_cast
[GOAL]
case succ.e_a
n k : ℕ
IH : a 1 ^ k = a ↑k
⊢ ↑(1 + k) = ↑(Nat.succ k)
[PROOFSTEP]
rw [Nat.one_add]
[GOAL]
n : ℕ
⊢ a 1 ^ (2 * n) = 1
[PROOFSTEP]
rw [a_one_pow, one_def]
[GOAL]
n : ℕ
⊢ a ↑(2 * n) = a 0
[PROOFSTEP]
congr 1
[GOAL]
case e_a
n : ℕ
⊢ ↑(2 * n) = 0
[PROOFSTEP]
exact ZMod.nat_cast_self _
[GOAL]
n : ℕ
i : ZMod (2 * n)
⊢ xa i ^ 2 = a ↑n
[PROOFSTEP]
simp [sq]
[GOAL]
n : ℕ
i : ZMod (2 * n)
⊢ xa i ^ 4 = 1
[PROOFSTEP]
rw [pow_succ, pow_succ, sq, xa_mul_xa, xa_mul_a, xa_mul_xa, add_sub_cancel, add_sub_assoc, add_sub_cancel']
[GOAL]
n : ℕ
i : ZMod (2 * n)
⊢ a (↑n + ↑n) = 1
[PROOFSTEP]
norm_cast
[GOAL]
n : ℕ
i : ZMod (2 * n)
⊢ a ↑(n + n) = 1
[PROOFSTEP]
rw [← two_mul]
[GOAL]
n : ℕ
i : ZMod (2 * n)
⊢ a ↑(2 * n) = 1
[PROOFSTEP]
simp [one_def]
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
⊢ orderOf (xa i) = 4
[PROOFSTEP]
change _ = 2 ^ 2
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
⊢ orderOf (xa i) = 2 ^ 2
[PROOFSTEP]
haveI : Fact (Nat.Prime 2) := Fact.mk Nat.prime_two
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
⊢ orderOf (xa i) = 2 ^ 2
[PROOFSTEP]
apply orderOf_eq_prime_pow
[GOAL]
case hnot
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
⊢ ¬xa i ^ 2 ^ 1 = 1
[PROOFSTEP]
intro h
[GOAL]
case hnot
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
h : xa i ^ 2 ^ 1 = 1
⊢ False
[PROOFSTEP]
simp only [pow_one, xa_sq] at h
[GOAL]
case hnot
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
h : a ↑n = 1
⊢ False
[PROOFSTEP]
injection h with h'
[GOAL]
case hnot
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
h' : ↑n = 0
⊢ False
[PROOFSTEP]
apply_fun ZMod.val at h'
[GOAL]
case hnot
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
h' : ZMod.val ↑n = ZMod.val 0
⊢ False
[PROOFSTEP]
apply_fun (· / n) at h'
[GOAL]
case hnot
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
h' : ZMod.val ↑n / n = ZMod.val 0 / n
⊢ False
[PROOFSTEP]
simp only [ZMod.val_nat_cast, ZMod.val_zero, Nat.zero_div, Nat.mod_mul_left_div_self, Nat.div_self (NeZero.pos n)] at h'
[GOAL]
case hfin
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
this : Fact (Nat.Prime 2)
⊢ xa i ^ 2 ^ (1 + 1) = 1
[PROOFSTEP]
norm_num
[GOAL]
n : ℕ
⊢ IsCyclic (QuaternionGroup 1)
[PROOFSTEP]
apply isCyclic_of_orderOf_eq_card
[GOAL]
case hx
n : ℕ
⊢ orderOf ?x = Fintype.card (QuaternionGroup 1)
case x n : ℕ ⊢ QuaternionGroup 1
[PROOFSTEP]
rw [card, mul_one]
[GOAL]
case hx
n : ℕ
⊢ orderOf ?x = 4
case x
n : ℕ
⊢ QuaternionGroup 1
case x
n : ℕ
⊢ QuaternionGroup 1
case x n : ℕ ⊢ QuaternionGroup 1
[PROOFSTEP]
exact orderOf_xa 0
[GOAL]
n : ℕ
⊢ orderOf (a 1) = 2 * n
[PROOFSTEP]
cases' eq_zero_or_neZero n with hn hn
[GOAL]
case inl
n : ℕ
hn : n = 0
⊢ orderOf (a 1) = 2 * n
[PROOFSTEP]
subst hn
[GOAL]
case inl
⊢ orderOf (a 1) = 2 * 0
[PROOFSTEP]
simp_rw [mul_zero, orderOf_eq_zero_iff']
[GOAL]
case inl
⊢ ∀ (n : ℕ), 0 < n → QuaternionGroup.a 1 ^ n ≠ 1
[PROOFSTEP]
intro n h
[GOAL]
case inl
n : ℕ
h : 0 < n
⊢ a 1 ^ n ≠ 1
[PROOFSTEP]
rw [one_def, a_one_pow]
[GOAL]
case inl
n : ℕ
h : 0 < n
⊢ a ↑n ≠ a 0
[PROOFSTEP]
apply mt a.inj
[GOAL]
case inl
n : ℕ
h : 0 < n
⊢ ¬↑n = 0
[PROOFSTEP]
haveI : CharZero (ZMod (2 * 0)) := ZMod.charZero
[GOAL]
case inl
n : ℕ
h : 0 < n
this : CharZero (ZMod (2 * 0))
⊢ ¬↑n = 0
[PROOFSTEP]
simpa using h.ne'
[GOAL]
case inr
n : ℕ
hn : NeZero n
⊢ orderOf (a 1) = 2 * n
[PROOFSTEP]
apply (Nat.le_of_dvd (NeZero.pos _) (orderOf_dvd_of_pow_eq_one (@a_one_pow_n n))).lt_or_eq.resolve_left
[GOAL]
case inr
n : ℕ
hn : NeZero n
⊢ ¬orderOf (a 1) < 2 * n
[PROOFSTEP]
intro h
[GOAL]
case inr
n : ℕ
hn : NeZero n
h : orderOf (a 1) < 2 * n
⊢ False
[PROOFSTEP]
have h1 : (a 1 : QuaternionGroup n) ^ orderOf (a 1) = 1 := pow_orderOf_eq_one _
[GOAL]
case inr
n : ℕ
hn : NeZero n
h : orderOf (a 1) < 2 * n
h1 : a 1 ^ orderOf (a 1) = 1
⊢ False
[PROOFSTEP]
rw [a_one_pow] at h1
[GOAL]
case inr
n : ℕ
hn : NeZero n
h : orderOf (a 1) < 2 * n
h1 : a ↑(orderOf (a 1)) = 1
⊢ False
[PROOFSTEP]
injection h1 with h2
[GOAL]
case inr
n : ℕ
hn : NeZero n
h : orderOf (a 1) < 2 * n
h2 : ↑(orderOf (a 1)) = 0
⊢ False
[PROOFSTEP]
rw [← ZMod.val_eq_zero, ZMod.val_nat_cast, Nat.mod_eq_of_lt h] at h2
[GOAL]
case inr
n : ℕ
hn : NeZero n
h : orderOf (a 1) < 2 * n
h2 : orderOf (a 1) = 0
⊢ False
[PROOFSTEP]
exact absurd h2.symm (orderOf_pos _).ne
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
⊢ orderOf (a i) = 2 * n / Nat.gcd (2 * n) (ZMod.val i)
[PROOFSTEP]
conv_lhs => rw [← ZMod.nat_cast_zmod_val i]
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
| orderOf (a i)
[PROOFSTEP]
rw [← ZMod.nat_cast_zmod_val i]
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
| orderOf (a i)
[PROOFSTEP]
rw [← ZMod.nat_cast_zmod_val i]
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
| orderOf (a i)
[PROOFSTEP]
rw [← ZMod.nat_cast_zmod_val i]
[GOAL]
n : ℕ
inst✝ : NeZero n
i : ZMod (2 * n)
⊢ orderOf (a ↑(ZMod.val i)) = 2 * n / Nat.gcd (2 * n) (ZMod.val i)
[PROOFSTEP]
rw [← a_one_pow, orderOf_pow, orderOf_a_one]
[GOAL]
n : ℕ
⊢ Monoid.exponent (QuaternionGroup n) = 2 * lcm n 2
[PROOFSTEP]
rw [← normalize_eq 2, ← lcm_mul_left, normalize_eq]
[GOAL]
n : ℕ
⊢ Monoid.exponent (QuaternionGroup n) = lcm (2 * n) (2 * 2)
[PROOFSTEP]
norm_num
[GOAL]
n : ℕ
⊢ Monoid.exponent (QuaternionGroup n) = lcm (2 * n) 4
[PROOFSTEP]
cases' eq_zero_or_neZero n with hn hn
[GOAL]
case inl
n : ℕ
hn : n = 0
⊢ Monoid.exponent (QuaternionGroup n) = lcm (2 * n) 4
[PROOFSTEP]
subst hn
[GOAL]
case inl
⊢ Monoid.exponent (QuaternionGroup 0) = lcm (2 * 0) 4
[PROOFSTEP]
simp only [lcm_zero_left, mul_zero]
[GOAL]
case inl
⊢ Monoid.exponent (QuaternionGroup 0) = 0
[PROOFSTEP]
exact Monoid.exponent_eq_zero_of_order_zero orderOf_a_one
[GOAL]
case inr
n : ℕ
hn : NeZero n
⊢ Monoid.exponent (QuaternionGroup n) = lcm (2 * n) 4
[PROOFSTEP]
apply Nat.dvd_antisymm
[GOAL]
case inr.a
n : ℕ
hn : NeZero n
⊢ Monoid.exponent (QuaternionGroup n) ∣ lcm (2 * n) 4
[PROOFSTEP]
apply Monoid.exponent_dvd_of_forall_pow_eq_one
[GOAL]
case inr.a.hG
n : ℕ
hn : NeZero n
⊢ ∀ (g : QuaternionGroup n), g ^ lcm (2 * n) 4 = 1
[PROOFSTEP]
rintro (m | m)
[GOAL]
case inr.a.hG.a
n : ℕ
hn : NeZero n
m : ZMod (2 * n)
⊢ a m ^ lcm (2 * n) 4 = 1
[PROOFSTEP]
rw [← orderOf_dvd_iff_pow_eq_one, orderOf_a]
[GOAL]
case inr.a.hG.a
n : ℕ
hn : NeZero n
m : ZMod (2 * n)
⊢ 2 * n / Nat.gcd (2 * n) (ZMod.val m) ∣ lcm (2 * n) 4
[PROOFSTEP]
refine' Nat.dvd_trans ⟨gcd (2 * n) m.val, _⟩ (dvd_lcm_left (2 * n) 4)
[GOAL]
case inr.a.hG.a
n : ℕ
hn : NeZero n
m : ZMod (2 * n)
⊢ 2 * n = 2 * n / Nat.gcd (2 * n) (ZMod.val m) * gcd (2 * n) (ZMod.val m)
[PROOFSTEP]
exact (Nat.div_mul_cancel (Nat.gcd_dvd_left (2 * n) m.val)).symm
[GOAL]
case inr.a.hG.xa
n : ℕ
hn : NeZero n
m : ZMod (2 * n)
⊢ xa m ^ lcm (2 * n) 4 = 1
[PROOFSTEP]
rw [← orderOf_dvd_iff_pow_eq_one, orderOf_xa]
[GOAL]
case inr.a.hG.xa
n : ℕ
hn : NeZero n
m : ZMod (2 * n)
⊢ 4 ∣ lcm (2 * n) 4
[PROOFSTEP]
exact dvd_lcm_right (2 * n) 4
[GOAL]
case inr.a
n : ℕ
hn : NeZero n
⊢ lcm (2 * n) 4 ∣ Monoid.exponent (QuaternionGroup n)
[PROOFSTEP]
apply lcm_dvd
[GOAL]
case inr.a.hab
n : ℕ
hn : NeZero n
⊢ 2 * n ∣ Monoid.exponent (QuaternionGroup n)
[PROOFSTEP]
convert Monoid.order_dvd_exponent (a 1)
[GOAL]
case h.e'_3
n : ℕ
hn : NeZero n
⊢ 2 * n = orderOf (a 1)
[PROOFSTEP]
exact orderOf_a_one.symm
[GOAL]
case inr.a.hcb
n : ℕ
hn : NeZero n
⊢ 4 ∣ Monoid.exponent (QuaternionGroup n)
[PROOFSTEP]
convert Monoid.order_dvd_exponent (xa (0 : ZMod (2 * n)))
[GOAL]
case h.e'_3
n : ℕ
hn : NeZero n
⊢ 4 = orderOf (xa 0)
[PROOFSTEP]
exact (orderOf_xa 0).symm


[GOAL]
n : ℕ
E : Type u_1
inst✝ : NormedAddCommGroup E
c : Fin n → ℂ
R θ : Fin n → ℝ
⊢ torusMap c R θ - c = torusMap 0 R θ
[PROOFSTEP]
ext1 i
[GOAL]
case h
n : ℕ
E : Type u_1
inst✝ : NormedAddCommGroup E
c : Fin n → ℂ
R θ : Fin n → ℝ
i : Fin n
⊢ (torusMap c R θ - c) i = torusMap 0 R θ i
[PROOFSTEP]
simp [torusMap]
[GOAL]
n : ℕ
E : Type u_1
inst✝ : NormedAddCommGroup E
c : Fin n → ℂ
R θ : Fin n → ℝ
⊢ torusMap c R θ = c ↔ R = 0
[PROOFSTEP]
simp [funext_iff, torusMap, exp_ne_zero]
[GOAL]
n : ℕ
E : Type u_1
inst✝ : NormedAddCommGroup E
f g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
a : E
c : Fin n → ℂ
R : Fin n → ℝ
⊢ TorusIntegrable (fun x => a) c R
[PROOFSTEP]
simp [TorusIntegrable, measure_Icc_lt_top]
[GOAL]
n : ℕ
E : Type u_1
inst✝ : NormedAddCommGroup E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R : Fin n → ℝ
f : (Fin n → ℂ) → E
c : Fin n → ℂ
⊢ TorusIntegrable f c 0
[PROOFSTEP]
rw [TorusIntegrable, torusMap_zero_radius]
[GOAL]
n : ℕ
E : Type u_1
inst✝ : NormedAddCommGroup E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R : Fin n → ℝ
f : (Fin n → ℂ) → E
c : Fin n → ℂ
⊢ IntegrableOn (fun θ => f (const (Fin n → ℝ) c θ)) (Icc 0 fun x => 2 * π)
[PROOFSTEP]
apply torusIntegrable_const (f c) c 0
[GOAL]
n : ℕ
E : Type u_1
inst✝¹ : NormedAddCommGroup E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
inst✝ : NormedSpace ℂ E
hf : TorusIntegrable f c R
⊢ IntegrableOn (fun θ => (∏ i : Fin n, ↑(R i) * exp (↑(θ i) * I) * I) • f (torusMap c R θ)) (Icc 0 fun x => 2 * π)
[PROOFSTEP]
refine' (hf.norm.const_mul (∏ i, |R i|)).mono' _ _
[GOAL]
case refine'_1
n : ℕ
E : Type u_1
inst✝¹ : NormedAddCommGroup E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
inst✝ : NormedSpace ℂ E
hf : TorusIntegrable f c R
⊢ AEStronglyMeasurable (fun θ => (∏ i : Fin n, ↑(R i) * exp (↑(θ i) * I) * I) • f (torusMap c R θ))
    (Measure.restrict volume (Icc 0 fun x => 2 * π))
[PROOFSTEP]
refine (Continuous.aestronglyMeasurable ?_).smul hf.1
[GOAL]
case refine'_1
n : ℕ
E : Type u_1
inst✝¹ : NormedAddCommGroup E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
inst✝ : NormedSpace ℂ E
hf : TorusIntegrable f c R
⊢ Continuous fun θ => ∏ i : Fin n, ↑(R i) * exp (↑(θ i) * I) * I
[PROOFSTEP]
continuity
[GOAL]
case refine'_2
n : ℕ
E : Type u_1
inst✝¹ : NormedAddCommGroup E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
inst✝ : NormedSpace ℂ E
hf : TorusIntegrable f c R
⊢ ∀ᵐ (a : Fin n → ℝ) ∂Measure.restrict volume (Icc 0 fun x => 2 * π),
    ‖(∏ i : Fin n, ↑(R i) * exp (↑(a i) * I) * I) • f (torusMap c R a)‖ ≤ (∏ i : Fin n, |R i|) * ‖f (torusMap c R a)‖
[PROOFSTEP]
simp [norm_smul, map_prod]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R : Fin n → ℝ
hn : n ≠ 0
f : (Fin n → ℂ) → E
c : Fin n → ℂ
⊢ (∯ (x : Fin n → ℂ) in T(c, 0), f x) = 0
[PROOFSTEP]
simp only [torusIntegral, Pi.zero_apply, ofReal_zero, mul_zero, zero_mul, Fin.prod_const, zero_pow' n hn, zero_smul,
  integral_zero]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
⊢ (∯ (x : Fin n → ℂ) in T(c, R), -f x) = -∯ (x : Fin n → ℂ) in T(c, R), f x
[PROOFSTEP]
simp [torusIntegral, integral_neg]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
hf : TorusIntegrable f c R
hg : TorusIntegrable g c R
⊢ (∯ (x : Fin n → ℂ) in T(c, R), f x + g x) = (∯ (x : Fin n → ℂ) in T(c, R), f x) + ∯ (x : Fin n → ℂ) in T(c, R), g x
[PROOFSTEP]
simpa only [torusIntegral, smul_add, Pi.add_apply] using integral_add hf.function_integrable hg.function_integrable
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
hf : TorusIntegrable f c R
hg : TorusIntegrable g c R
⊢ (∯ (x : Fin n → ℂ) in T(c, R), f x - g x) = (∯ (x : Fin n → ℂ) in T(c, R), f x) - ∯ (x : Fin n → ℂ) in T(c, R), g x
[PROOFSTEP]
simpa only [sub_eq_add_neg, ← torusIntegral_neg] using torusIntegral_add hf hg.neg
[GOAL]
n : ℕ
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : NormedSpace ℂ E
inst✝³ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
𝕜 : Type u_2
inst✝² : IsROrC 𝕜
inst✝¹ : NormedSpace 𝕜 E
inst✝ : SMulCommClass 𝕜 ℂ E
a : 𝕜
f : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
⊢ (∯ (x : Fin n → ℂ) in T(c, R), a • f x) = a • ∯ (x : Fin n → ℂ) in T(c, R), f x
[PROOFSTEP]
simp only [torusIntegral, integral_smul, ← smul_comm a (_ : ℂ) (_ : E)]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
C : ℝ
hf : ∀ (θ : Fin n → ℝ), ‖f (torusMap c R θ)‖ ≤ C
θ : Fin n → ℝ
x✝ : θ ∈ Icc 0 fun x => 2 * π
⊢ ‖(∏ i : Fin n, ↑(R i) * exp (↑(θ i) * I) * I) • f (torusMap c R θ)‖ = (∏ i : Fin n, |R i|) * ‖f (torusMap c R θ)‖
[PROOFSTEP]
simp [norm_smul]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f g : (Fin n → ℂ) → E
c : Fin n → ℂ
R : Fin n → ℝ
C : ℝ
hf : ∀ (θ : Fin n → ℝ), ‖f (torusMap c R θ)‖ ≤ C
⊢ (∏ i : Fin n, |R i|) * C * ENNReal.toReal (↑↑volume (Icc 0 fun x => 2 * π)) = ((2 * π) ^ n * ∏ i : Fin n, |R i|) * C
[PROOFSTEP]
simp only [Pi.zero_def, Real.volume_Icc_pi_toReal fun _ => Real.two_pi_pos.le, sub_zero, Fin.prod_const, mul_assoc,
  mul_comm ((2 * π) ^ (n : ℕ))]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 0 → ℂ) → E
c : Fin 0 → ℂ
R : Fin 0 → ℝ
⊢ (∯ (x : Fin 0 → ℂ) in T(c, R), f x) = f c
[PROOFSTEP]
simp only [torusIntegral, Fin.prod_univ_zero, one_smul, Subsingleton.elim (fun _ : Fin 0 => 2 * π) 0, Icc_self,
  Measure.restrict_singleton, volume_pi, integral_smul_measure, integral_dirac,
  Measure.pi_of_empty (fun _ : Fin 0 ↦ volume) 0, Measure.dirac_apply_of_mem (mem_singleton _),
  Subsingleton.elim (torusMap c R 0) c]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
⊢ (∯ (x : Fin 1 → ℂ) in T(c, R), f x) = ∮ (z : ℂ) in C(c 0, R 0), f fun x => z
[PROOFSTEP]
have H₁ : (((MeasurableEquiv.funUnique _ _).symm) ⁻¹' Icc 0 fun _ => 2 * π) = Icc 0 (2 * π) :=
  (OrderIso.funUnique (Fin 1) ℝ).symm.preimage_Icc _ _
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
H₁ : (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π)
⊢ (∯ (x : Fin 1 → ℂ) in T(c, R), f x) = ∮ (z : ℂ) in C(c 0, R 0), f fun x => z
[PROOFSTEP]
have H₂ : torusMap c R = fun θ _ ↦ circleMap (c 0) (R 0) (θ 0) :=
  by
  ext θ i : 2
  rw [Subsingleton.elim i 0]; rfl
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
H₁ : (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π)
⊢ torusMap c R = fun θ x => circleMap (c 0) (R 0) (θ 0)
[PROOFSTEP]
ext θ i : 2
[GOAL]
case h.h
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
H₁ : (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π)
θ : Fin 1 → ℝ
i : Fin 1
⊢ torusMap c R θ i = circleMap (c 0) (R 0) (θ 0)
[PROOFSTEP]
rw [Subsingleton.elim i 0]
[GOAL]
case h.h
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
H₁ : (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π)
θ : Fin 1 → ℝ
i : Fin 1
⊢ torusMap c R θ 0 = circleMap (c 0) (R 0) (θ 0)
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
H₁ : (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π)
H₂ : torusMap c R = fun θ x => circleMap (c 0) (R 0) (θ 0)
⊢ (∯ (x : Fin 1 → ℂ) in T(c, R), f x) = ∮ (z : ℂ) in C(c 0, R 0), f fun x => z
[PROOFSTEP]
rw [torusIntegral, circleIntegral, intervalIntegral.integral_of_le Real.two_pi_pos.le,
  Measure.restrict_congr_set Ioc_ae_eq_Icc, ←
  ((volume_preserving_funUnique (Fin 1) ℝ).symm _).set_integral_preimage_emb (MeasurableEquiv.measurableEmbedding _),
  H₁, H₂]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin 1 → ℂ) → E
c : Fin 1 → ℂ
R : Fin 1 → ℝ
H₁ : (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π)
H₂ : torusMap c R = fun θ x => circleMap (c 0) (R 0) (θ 0)
⊢ ∫ (x : ℝ) in Icc 0 (2 * π),
      (∏ i : Fin 1, ↑(R i) * exp (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) x i) * I) * I) •
        f ((fun θ x => circleMap (c 0) (R 0) (θ 0)) (↑(MeasurableEquiv.symm (MeasurableEquiv.funUnique (Fin 1) ℝ)) x)) =
    ∫ (x : ℝ) in Icc 0 (2 * π), deriv (circleMap (c 0) (R 0)) x • f fun x_1 => circleMap (c 0) (R 0) x
[PROOFSTEP]
simp [circleMap_zero]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
⊢ (∯ (x : Fin (n + 1) → ℂ) in T(c, R), f x) =
    ∮ (x : ℂ) in C(c i, R i), ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succAbove i, R ∘ Fin.succAbove i), f (Fin.insertNth i x y)
[PROOFSTEP]
set e : ℝ × ℝⁿ ≃ᵐ ℝⁿ⁺¹ := (MeasurableEquiv.piFinSuccAboveEquiv (fun _ => ℝ) i).symm
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
⊢ (∯ (x : Fin (n + 1) → ℂ) in T(c, R), f x) =
    ∮ (x : ℂ) in C(c i, R i), ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succAbove i, R ∘ Fin.succAbove i), f (Fin.insertNth i x y)
[PROOFSTEP]
have hem : MeasurePreserving e := (volume_preserving_piFinSuccAboveEquiv (fun _ : Fin (n + 1) => ℝ) i).symm _
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
⊢ (∯ (x : Fin (n + 1) → ℂ) in T(c, R), f x) =
    ∮ (x : ℂ) in C(c i, R i), ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succAbove i, R ∘ Fin.succAbove i), f (Fin.insertNth i x y)
[PROOFSTEP]
have heπ : (e ⁻¹' Icc 0 fun _ => 2 * π) = Icc 0 (2 * π) ×ˢ Icc (0 : ℝⁿ) fun _ => 2 * π :=
  ((OrderIso.piFinSuccAboveIso (fun _ => ℝ) i).symm.preimage_Icc _ _).trans (Icc_prod_eq _ _)
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
⊢ (∯ (x : Fin (n + 1) → ℂ) in T(c, R), f x) =
    ∮ (x : ℂ) in C(c i, R i), ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succAbove i, R ∘ Fin.succAbove i), f (Fin.insertNth i x y)
[PROOFSTEP]
rw [torusIntegral, ← hem.map_eq, set_integral_map_equiv, heπ, Measure.volume_eq_prod, set_integral_prod,
  circleIntegral_def_Icc]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
⊢ ∫ (x : ℝ) in Icc 0 (2 * π),
      ∫ (y : Fin n → ℝ) in Icc 0 fun x => 2 * π,
        (∏ i : Fin (n + 1), ↑(R i) * exp (↑(↑e (x, y) i) * I) * I) • f (torusMap c R (↑e (x, y))) =
    ∫ (θ : ℝ) in Icc 0 (2 * π),
      deriv (circleMap (c i) (R i)) θ •
        ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succAbove i, R ∘ Fin.succAbove i),
          f (Fin.insertNth i (circleMap (c i) (R i) θ) y)
[PROOFSTEP]
refine' set_integral_congr measurableSet_Icc fun θ _ => _
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
θ : ℝ
x✝ : θ ∈ Icc 0 (2 * π)
⊢ ∫ (y : Fin n → ℝ) in Icc 0 fun x => 2 * π,
      (∏ i : Fin (n + 1), ↑(R i) * exp (↑(↑e (θ, y) i) * I) * I) • f (torusMap c R (↑e (θ, y))) =
    deriv (circleMap (c i) (R i)) θ •
      ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succAbove i, R ∘ Fin.succAbove i), f (Fin.insertNth i (circleMap (c i) (R i) θ) y)
[PROOFSTEP]
simp only [torusIntegral, ← integral_smul, deriv_circleMap, i.prod_univ_succAbove _, smul_smul, torusMap,
  circleMap_zero]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
θ : ℝ
x✝ : θ ∈ Icc 0 (2 * π)
⊢ (∫ (y : Fin n → ℝ) in Icc 0 fun x => 2 * π,
      (↑(R i) * exp (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)) (θ, y) i) * I) * I *
          ∏ i_1 : Fin n,
            ↑(R (Fin.succAbove i i_1)) *
                exp
                  (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)) (θ, y)
                        (Fin.succAbove i i_1)) *
                    I) *
              I) •
        f fun i_1 =>
          c i_1 +
            ↑(R i_1) *
              exp (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)) (θ, y) i_1) * I)) =
    ∫ (a : Fin n → ℝ) in Icc 0 fun x => 2 * π,
      (↑(R i) * exp (↑θ * I) * I * ∏ i_1 : Fin n, ↑((R ∘ Fin.succAbove i) i_1) * exp (↑(a i_1) * I) * I) •
        f
          (Fin.insertNth i (circleMap (c i) (R i) θ) fun i_1 =>
            (c ∘ Fin.succAbove i) i_1 + ↑((R ∘ Fin.succAbove i) i_1) * exp (↑(a i_1) * I))
[PROOFSTEP]
refine' set_integral_congr measurableSet_Icc fun Θ _ => _
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
θ : ℝ
x✝¹ : θ ∈ Icc 0 (2 * π)
Θ : Fin n → ℝ
x✝ : Θ ∈ Icc 0 fun x => 2 * π
⊢ ((↑(R i) * exp (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)) (θ, Θ) i) * I) * I *
        ∏ i_1 : Fin n,
          ↑(R (Fin.succAbove i i_1)) *
              exp
                (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)) (θ, Θ)
                      (Fin.succAbove i i_1)) *
                  I) *
            I) •
      f fun i_1 =>
        c i_1 +
          ↑(R i_1) *
            exp (↑(↑(MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)) (θ, Θ) i_1) * I)) =
    (↑(R i) * exp (↑θ * I) * I * ∏ i_1 : Fin n, ↑((R ∘ Fin.succAbove i) i_1) * exp (↑(Θ i_1) * I) * I) •
      f
        (Fin.insertNth i (circleMap (c i) (R i) θ) fun i_1 =>
          (c ∘ Fin.succAbove i) i_1 + ↑((R ∘ Fin.succAbove i) i_1) * exp (↑(Θ i_1) * I))
[PROOFSTEP]
simp only [MeasurableEquiv.piFinSuccAboveEquiv_symm_apply, i.insertNth_apply_same, i.insertNth_apply_succAbove, (· ∘ ·)]
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
θ : ℝ
x✝¹ : θ ∈ Icc 0 (2 * π)
Θ : Fin n → ℝ
x✝ : Θ ∈ Icc 0 fun x => 2 * π
⊢ ((↑(R i) * exp (↑θ * I) * I * ∏ x : Fin n, ↑(R (Fin.succAbove i x)) * exp (↑(Θ x) * I) * I) •
      f fun i_1 => c i_1 + ↑(R i_1) * exp (↑(Fin.insertNth i θ Θ i_1) * I)) =
    (↑(R i) * exp (↑θ * I) * I * ∏ x : Fin n, ↑(R (Fin.succAbove i x)) * exp (↑(Θ x) * I) * I) •
      f
        (Fin.insertNth i (circleMap (c i) (R i) θ) fun i_1 =>
          c (Fin.succAbove i i_1) + ↑(R (Fin.succAbove i i_1)) * exp (↑(Θ i_1) * I))
[PROOFSTEP]
congr 2
[GOAL]
case e_a.e_a
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
θ : ℝ
x✝¹ : θ ∈ Icc 0 (2 * π)
Θ : Fin n → ℝ
x✝ : Θ ∈ Icc 0 fun x => 2 * π
⊢ (fun i_1 => c i_1 + ↑(R i_1) * exp (↑(Fin.insertNth i θ Θ i_1) * I)) =
    Fin.insertNth i (circleMap (c i) (R i) θ) fun i_1 =>
      c (Fin.succAbove i i_1) + ↑(R (Fin.succAbove i i_1)) * exp (↑(Θ i_1) * I)
[PROOFSTEP]
simp only [funext_iff, i.forall_iff_succAbove, circleMap, Fin.insertNth_apply_same, eq_self_iff_true,
  Fin.insertNth_apply_succAbove, imp_true_iff, and_self_iff]
[GOAL]
case hf
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
⊢ IntegrableOn (fun x => (∏ i : Fin (n + 1), ↑(R i) * exp (↑(↑e x i) * I) * I) • f (torusMap c R (↑e x)))
    (Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π)
[PROOFSTEP]
have := hf.function_integrable
[GOAL]
case hf
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
i : Fin (n + 1)
e : ℝ × (Fin n → ℝ) ≃ᵐ (Fin (n + 1) → ℝ) := MeasurableEquiv.symm (MeasurableEquiv.piFinSuccAboveEquiv (fun x => ℝ) i)
hem : MeasurePreserving ↑e
heπ : (↑e ⁻¹' Icc 0 fun x => 2 * π) = Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π
this :
  IntegrableOn (fun θ => (∏ i : Fin (n + 1), ↑(R i) * exp (↑(θ i) * I) * I) • f (torusMap c R θ)) (Icc 0 fun x => 2 * π)
⊢ IntegrableOn (fun x => (∏ i : Fin (n + 1), ↑(R i) * exp (↑(↑e x i) * I) * I) • f (torusMap c R (↑e x)))
    (Icc 0 (2 * π) ×ˢ Icc 0 fun x => 2 * π)
[PROOFSTEP]
rwa [← hem.integrableOn_comp_preimage e.measurableEmbedding, heπ] at this
[GOAL]
n : ℕ
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : NormedSpace ℂ E
inst✝ : CompleteSpace E
f✝ g : (Fin n → ℂ) → E
c✝ : Fin n → ℂ
R✝ : Fin n → ℝ
f : (Fin (n + 1) → ℂ) → E
c : Fin (n + 1) → ℂ
R : Fin (n + 1) → ℝ
hf : TorusIntegrable f c R
⊢ (∯ (x : Fin (n + 1) → ℂ) in T(c, R), f x) =
    ∮ (x : ℂ) in C(c 0, R 0), ∯ (y : Fin n → ℂ) in T(c ∘ Fin.succ, R ∘ Fin.succ), f (Fin.cons x y)
[PROOFSTEP]
simpa using torusIntegral_succAbove hf 0


[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
⊢ Subgraph.Connected H ↔ Subgraph.Preconnected H ∧ Set.Nonempty H.verts
[PROOFSTEP]
rw [H.connected_iff', connected_iff, H.preconnected_iff, Set.nonempty_coe_sort]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Connected H
⊢ Subgraph.Preconnected H
[PROOFSTEP]
rw [H.connected_iff] at h
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Preconnected H ∧ Set.Nonempty H.verts
⊢ Subgraph.Preconnected H
[PROOFSTEP]
exact h.1
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Connected H
⊢ Set.Nonempty H.verts
[PROOFSTEP]
rw [H.connected_iff] at h
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Preconnected H ∧ Set.Nonempty H.verts
⊢ Set.Nonempty H.verts
[PROOFSTEP]
exact h.2
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v : V
⊢ Subgraph.Connected (SimpleGraph.singletonSubgraph G v)
[PROOFSTEP]
refine ⟨⟨?_⟩⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v : V
⊢ Preconnected (Subgraph.coe (SimpleGraph.singletonSubgraph G v))
[PROOFSTEP]
rintro ⟨a, ha⟩ ⟨b, hb⟩
[GOAL]
case mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v a : V
ha : a ∈ (SimpleGraph.singletonSubgraph G v).verts
b : V
hb : b ∈ (SimpleGraph.singletonSubgraph G v).verts
⊢ Reachable (Subgraph.coe (SimpleGraph.singletonSubgraph G v)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
simp only [singletonSubgraph_verts, Set.mem_singleton_iff] at ha hb
[GOAL]
case mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v a : V
ha✝ : a ∈ (SimpleGraph.singletonSubgraph G v).verts
b : V
hb✝ : b ∈ (SimpleGraph.singletonSubgraph G v).verts
ha : a = v
hb : b = v
⊢ Reachable (Subgraph.coe (SimpleGraph.singletonSubgraph G v)) { val := a, property := ha✝ }
    { val := b, property := hb✝ }
[PROOFSTEP]
subst_vars
[GOAL]
case mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
b : V
ha hb : b = b
⊢ Reachable (Subgraph.coe (SimpleGraph.singletonSubgraph G b)) { val := b, property := (_ : b = b) }
    { val := b, property := (_ : b = b) }
[PROOFSTEP]
rfl
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
hvw : SimpleGraph.Adj G v w
⊢ Subgraph.Connected (subgraphOfAdj G hvw)
[PROOFSTEP]
refine ⟨⟨?_⟩⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
hvw : SimpleGraph.Adj G v w
⊢ Preconnected (Subgraph.coe (subgraphOfAdj G hvw))
[PROOFSTEP]
rintro ⟨a, ha⟩ ⟨b, hb⟩
[GOAL]
case mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
hvw : SimpleGraph.Adj G v w
a : V
ha : a ∈ (subgraphOfAdj G hvw).verts
b : V
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
simp only [subgraphOfAdj_verts, Set.mem_insert_iff, Set.mem_singleton_iff] at ha hb
[GOAL]
case mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
hvw : SimpleGraph.Adj G v w
a : V
ha✝ : a ∈ (subgraphOfAdj G hvw).verts
b : V
hb✝ : b ∈ (subgraphOfAdj G hvw).verts
ha : a = v ∨ a = w
hb : b = v ∨ b = w
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha✝ } { val := b, property := hb✝ }
[PROOFSTEP]
obtain rfl | rfl := ha
[GOAL]
case mk.mk.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
w a b : V
hvw : SimpleGraph.Adj G a w
ha : a ∈ (subgraphOfAdj G hvw).verts
hb✝ : b ∈ (subgraphOfAdj G hvw).verts
hb : b = a ∨ b = w
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb✝ }
[PROOFSTEP]
obtain rfl | rfl := hb
[GOAL]
case mk.mk.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v a b : V
hvw : SimpleGraph.Adj G v a
ha : a ∈ (subgraphOfAdj G hvw).verts
hb✝ : b ∈ (subgraphOfAdj G hvw).verts
hb : b = v ∨ b = a
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb✝ }
[PROOFSTEP]
obtain rfl | rfl := hb
[GOAL]
case mk.mk.inl.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
w b : V
hvw : SimpleGraph.Adj G b w
ha hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := b, property := ha } { val := b, property := hb }
[PROOFSTEP]
first
| rfl
| (apply Adj.reachable; simp)
[GOAL]
case mk.mk.inl.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
w b : V
hvw : SimpleGraph.Adj G b w
ha hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := b, property := ha } { val := b, property := hb }
[PROOFSTEP]
rfl
[GOAL]
case mk.mk.inl.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G a b
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
first
| rfl
| (apply Adj.reachable; simp)
[GOAL]
case mk.mk.inl.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G a b
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
rfl
[GOAL]
case mk.mk.inl.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G a b
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
apply Adj.reachable
[GOAL]
case mk.mk.inl.inr.h
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G a b
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ SimpleGraph.Adj (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
simp
[GOAL]
case mk.mk.inr.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G b a
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
first
| rfl
| (apply Adj.reachable; simp)
[GOAL]
case mk.mk.inr.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G b a
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
rfl
[GOAL]
case mk.mk.inr.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G b a
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
apply Adj.reachable
[GOAL]
case mk.mk.inr.inl.h
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
a b : V
hvw : SimpleGraph.Adj G b a
ha : a ∈ (subgraphOfAdj G hvw).verts
hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ SimpleGraph.Adj (Subgraph.coe (subgraphOfAdj G hvw)) { val := a, property := ha } { val := b, property := hb }
[PROOFSTEP]
simp
[GOAL]
case mk.mk.inr.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v b : V
hvw : SimpleGraph.Adj G v b
ha hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := b, property := ha } { val := b, property := hb }
[PROOFSTEP]
first
| rfl
| (apply Adj.reachable; simp)
[GOAL]
case mk.mk.inr.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v b : V
hvw : SimpleGraph.Adj G v b
ha hb : b ∈ (subgraphOfAdj G hvw).verts
⊢ Reachable (Subgraph.coe (subgraphOfAdj G hvw)) { val := b, property := ha } { val := b, property := hb }
[PROOFSTEP]
rfl
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
huv : SimpleGraph.Adj G u v
⊢ Subgraph.Connected (induce ⊤ {u, v})
[PROOFSTEP]
rw [← subgraphOfAdj_eq_induce huv]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
huv : SimpleGraph.Adj G u v
⊢ Subgraph.Connected (subgraphOfAdj G huv)
[PROOFSTEP]
exact subgraphOfAdj_connected huv
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H H' : Subgraph G
hle : H ≤ H'
hv : H.verts = H'.verts
h : Subgraph.Connected H
⊢ Subgraph.Connected H'
[PROOFSTEP]
rw [← Subgraph.copy_eq H' H.verts hv H'.Adj rfl]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H H' : Subgraph G
hle : H ≤ H'
hv : H.verts = H'.verts
h : Subgraph.Connected H
⊢ Subgraph.Connected (copy H' H.verts hv H'.Adj (_ : H'.Adj = H'.Adj))
[PROOFSTEP]
refine ⟨h.coe.mono ?_⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H H' : Subgraph G
hle : H ≤ H'
hv : H.verts = H'.verts
h : Subgraph.Connected H
⊢ Subgraph.coe H ≤ Subgraph.coe (copy H' H.verts hv H'.Adj (_ : H'.Adj = H'.Adj))
[PROOFSTEP]
rintro ⟨v, hv⟩ ⟨w, hw⟩ hvw
[GOAL]
case mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H H' : Subgraph G
hle : H ≤ H'
hv✝ : H.verts = H'.verts
h : Subgraph.Connected H
v : V
hv : v ∈ H.verts
w : V
hw : w ∈ H.verts
hvw : SimpleGraph.Adj (Subgraph.coe H) { val := v, property := hv } { val := w, property := hw }
⊢ SimpleGraph.Adj (Subgraph.coe (copy H' H.verts hv✝ H'.Adj (_ : H'.Adj = H'.Adj))) { val := v, property := hv }
    { val := w, property := hw }
[PROOFSTEP]
exact hle.2 hvw
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H H' : Subgraph G
hle : ∀ (v w : V), Adj H v w → Adj H' v w
hv : H.verts = H'.verts
h : Subgraph.Connected H
⊢ Subgraph.Connected H'
[PROOFSTEP]
exact h.mono ⟨hv.le, hle⟩ hv
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
hH : Subgraph.Connected H
hK : Subgraph.Connected K
hn : Set.Nonempty (H ⊓ K).verts
⊢ Subgraph.Connected (H ⊔ K)
[PROOFSTEP]
rw [Subgraph.connected_iff', connected_iff_exists_forall_reachable]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
hH : Subgraph.Connected H
hK : Subgraph.Connected K
hn : Set.Nonempty (H ⊓ K).verts
⊢ ∃ v, ∀ (w : ↑(H ⊔ K).verts), Reachable (Subgraph.coe (H ⊔ K)) v w
[PROOFSTEP]
obtain ⟨u, hu, hu'⟩ := hn
[GOAL]
case intro.intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
hH : Subgraph.Connected H
hK : Subgraph.Connected K
u : V
hu : u ∈ H.verts
hu' : u ∈ K.verts
⊢ ∃ v, ∀ (w : ↑(H ⊔ K).verts), Reachable (Subgraph.coe (H ⊔ K)) v w
[PROOFSTEP]
exists ⟨u, Or.inl hu⟩
[GOAL]
case intro.intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
hH : Subgraph.Connected H
hK : Subgraph.Connected K
u : V
hu : u ∈ H.verts
hu' : u ∈ K.verts
⊢ ∀ (w : ↑(H ⊔ K).verts), Reachable (Subgraph.coe (H ⊔ K)) { val := u, property := (_ : u ∈ H.verts ∨ u ∈ K.verts) } w
[PROOFSTEP]
rintro ⟨v, (hv | hv)⟩
[GOAL]
case intro.intro.mk.inl
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
hH : Subgraph.Connected H
hK : Subgraph.Connected K
u : V
hu : u ∈ H.verts
hu' : u ∈ K.verts
v : V
hv : v ∈ H.verts
⊢ Reachable (Subgraph.coe (H ⊔ K)) { val := u, property := (_ : u ∈ H.verts ∨ u ∈ K.verts) }
    { val := v, property := (_ : v ∈ H.verts ∨ v ∈ K.verts) }
[PROOFSTEP]
exact Reachable.map (Subgraph.inclusion (le_sup_left : H ≤ H ⊔ K)) (hH ⟨u, hu⟩ ⟨v, hv⟩)
[GOAL]
case intro.intro.mk.inr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
hH : Subgraph.Connected H
hK : Subgraph.Connected K
u : V
hu : u ∈ H.verts
hu' : u ∈ K.verts
v : V
hv : v ∈ K.verts
⊢ Reachable (Subgraph.coe (H ⊔ K)) { val := u, property := (_ : u ∈ H.verts ∨ u ∈ K.verts) }
    { val := v, property := (_ : v ∈ H.verts ∨ v ∈ K.verts) }
[PROOFSTEP]
exact Reachable.map (Subgraph.inclusion (le_sup_right : K ≤ H ⊔ K)) (hK ⟨u, hu'⟩ ⟨v, hv⟩)
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
p : Walk G u v
⊢ Subgraph.Connected (Walk.toSubgraph p)
[PROOFSTEP]
induction p with
| nil => apply singletonSubgraph_connected
| cons h p ih =>
  apply (subgraphOfAdj_connected h).sup ih
  rename_i w _
  exists w
  simp
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
p : Walk G u v
⊢ Subgraph.Connected (Walk.toSubgraph p)
[PROOFSTEP]
induction p with
| nil => apply singletonSubgraph_connected
| cons h p ih =>
  apply (subgraphOfAdj_connected h).sup ih
  rename_i w _
  exists w
  simp
[GOAL]
case nil
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ : V
⊢ Subgraph.Connected (Walk.toSubgraph Walk.nil)
[PROOFSTEP]

| nil => apply singletonSubgraph_connected
[GOAL]
case nil
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ : V
⊢ Subgraph.Connected (Walk.toSubgraph Walk.nil)
[PROOFSTEP]
apply singletonSubgraph_connected
[GOAL]
case cons
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ v✝ w✝ : V
h : SimpleGraph.Adj G u✝ v✝
p : Walk G v✝ w✝
ih : Subgraph.Connected (Walk.toSubgraph p)
⊢ Subgraph.Connected (Walk.toSubgraph (Walk.cons h p))
[PROOFSTEP]

| cons h p ih =>
  apply (subgraphOfAdj_connected h).sup ih
  rename_i w _
  exists w
  simp
[GOAL]
case cons
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ v✝ w✝ : V
h : SimpleGraph.Adj G u✝ v✝
p : Walk G v✝ w✝
ih : Subgraph.Connected (Walk.toSubgraph p)
⊢ Subgraph.Connected (Walk.toSubgraph (Walk.cons h p))
[PROOFSTEP]
apply (subgraphOfAdj_connected h).sup ih
[GOAL]
case cons
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ v✝ w✝ : V
h : SimpleGraph.Adj G u✝ v✝
p : Walk G v✝ w✝
ih : Subgraph.Connected (Walk.toSubgraph p)
⊢ Set.Nonempty (subgraphOfAdj G h ⊓ Walk.toSubgraph p).verts
[PROOFSTEP]
rename_i w _
[GOAL]
case cons
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ w w✝ : V
h : SimpleGraph.Adj G u✝ w
p : Walk G w w✝
ih : Subgraph.Connected (Walk.toSubgraph p)
⊢ Set.Nonempty (subgraphOfAdj G h ⊓ Walk.toSubgraph p).verts
[PROOFSTEP]
exists w
[GOAL]
case cons
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v u✝ w w✝ : V
h : SimpleGraph.Adj G u✝ w
p : Walk G w w✝
ih : Subgraph.Connected (Walk.toSubgraph p)
⊢ w ∈ (subgraphOfAdj G h ⊓ Walk.toSubgraph p).verts
[PROOFSTEP]
simp
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
s t : Set V
sconn : Subgraph.Connected (induce H s)
tconn : Subgraph.Connected (induce H t)
sintert : Set.Nonempty (s ⊓ t)
⊢ Subgraph.Connected (induce H (s ∪ t))
[PROOFSTEP]
refine (sconn.sup tconn sintert).mono ?_ ?_
[GOAL]
case refine_1
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
s t : Set V
sconn : Subgraph.Connected (induce H s)
tconn : Subgraph.Connected (induce H t)
sintert : Set.Nonempty (s ⊓ t)
⊢ induce H s ⊔ induce H t ≤ induce H (s ∪ t)
[PROOFSTEP]
apply le_induce_union
[GOAL]
case refine_2
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
s t : Set V
sconn : Subgraph.Connected (induce H s)
tconn : Subgraph.Connected (induce H t)
sintert : Set.Nonempty (s ⊓ t)
⊢ (induce H s ⊔ induce H t).verts = (induce H (s ∪ t)).verts
[PROOFSTEP]
simp
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
Hconn : Subgraph.Connected H
Kconn : Subgraph.Connected K
u v : V
uH : u ∈ H.verts
vK : v ∈ K.verts
huv : SimpleGraph.Adj G u v
⊢ Subgraph.Connected (induce ⊤ {u, v} ⊔ H ⊔ K)
[PROOFSTEP]
refine ((top_induce_pair_connected_of_adj huv).sup Hconn ?_).sup Kconn ?_
[GOAL]
case refine_1
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
Hconn : Subgraph.Connected H
Kconn : Subgraph.Connected K
u v : V
uH : u ∈ H.verts
vK : v ∈ K.verts
huv : SimpleGraph.Adj G u v
⊢ Set.Nonempty (induce ⊤ {u, v} ⊓ H).verts
[PROOFSTEP]
exact ⟨u, by simp [uH]⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
Hconn : Subgraph.Connected H
Kconn : Subgraph.Connected K
u v : V
uH : u ∈ H.verts
vK : v ∈ K.verts
huv : SimpleGraph.Adj G u v
⊢ u ∈ (induce ⊤ {u, v} ⊓ H).verts
[PROOFSTEP]
simp [uH]
[GOAL]
case refine_2
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
Hconn : Subgraph.Connected H
Kconn : Subgraph.Connected K
u v : V
uH : u ∈ H.verts
vK : v ∈ K.verts
huv : SimpleGraph.Adj G u v
⊢ Set.Nonempty ((induce ⊤ {u, v} ⊔ H) ⊓ K).verts
[PROOFSTEP]
exact ⟨v, by simp [vK]⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H K : Subgraph G
Hconn : Subgraph.Connected H
Kconn : Subgraph.Connected K
u v : V
uH : u ∈ H.verts
vK : v ∈ K.verts
huv : SimpleGraph.Adj G u v
⊢ v ∈ ((induce ⊤ {u, v} ⊔ H) ⊓ K).verts
[PROOFSTEP]
simp [vK]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
⊢ Subgraph.Preconnected H ↔ ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
[PROOFSTEP]
constructor
[GOAL]
case mp
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
⊢ Subgraph.Preconnected H → ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
[PROOFSTEP]
intro hc u v hu hv
[GOAL]
case mp
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hc : Subgraph.Preconnected H
u v : V
hu : u ∈ H.verts
hv : v ∈ H.verts
⊢ ∃ p, Walk.toSubgraph p ≤ H
[PROOFSTEP]
refine (hc ⟨_, hu⟩ ⟨_, hv⟩).elim fun p => ?_
[GOAL]
case mp
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hc : Subgraph.Preconnected H
u v : V
hu : u ∈ H.verts
hv : v ∈ H.verts
p : Walk (Subgraph.coe H) { val := u, property := hu } { val := v, property := hv }
⊢ ∃ p, Walk.toSubgraph p ≤ H
[PROOFSTEP]
exists p.map (Subgraph.hom _)
[GOAL]
case mp
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hc : Subgraph.Preconnected H
u v : V
hu : u ∈ H.verts
hv : v ∈ H.verts
p : Walk (Subgraph.coe H) { val := u, property := hu } { val := v, property := hv }
⊢ Walk.toSubgraph (Walk.map (Subgraph.hom H) p) ≤ H
[PROOFSTEP]
simp [coeSubgraph_le]
[GOAL]
case mpr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
⊢ (∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H) → Subgraph.Preconnected H
[PROOFSTEP]
intro hw
[GOAL]
case mpr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hw : ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
⊢ Subgraph.Preconnected H
[PROOFSTEP]
rw [Subgraph.preconnected_iff]
[GOAL]
case mpr
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hw : ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
⊢ Preconnected (Subgraph.coe H)
[PROOFSTEP]
rintro ⟨u, hu⟩ ⟨v, hv⟩
[GOAL]
case mpr.mk.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hw : ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
u : V
hu : u ∈ H.verts
v : V
hv : v ∈ H.verts
⊢ Reachable (Subgraph.coe H) { val := u, property := hu } { val := v, property := hv }
[PROOFSTEP]
obtain ⟨p, h⟩ := hw hu hv
[GOAL]
case mpr.mk.mk.intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
hw : ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
u : V
hu : u ∈ H.verts
v : V
hv : v ∈ H.verts
p : Walk G u v
h : Walk.toSubgraph p ≤ H
⊢ Reachable (Subgraph.coe H) { val := u, property := hu } { val := v, property := hv }
[PROOFSTEP]
exact
  Reachable.map (Subgraph.inclusion h)
    (p.toSubgraph_connected ⟨_, p.start_mem_verts_toSubgraph⟩ ⟨_, p.end_mem_verts_toSubgraph⟩)
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
⊢ Subgraph.Connected H ↔ Set.Nonempty H.verts ∧ ∀ {u v : V}, u ∈ H.verts → v ∈ H.verts → ∃ p, Walk.toSubgraph p ≤ H
[PROOFSTEP]
rw [H.connected_iff, preconnected_iff_forall_exists_walk_subgraph, and_comm]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s : Set V
⊢ Connected (induce s G) ↔ Subgraph.Connected (Subgraph.induce ⊤ s)
[PROOFSTEP]
rw [induce_eq_coe_induce_top, ← Subgraph.connected_iff']
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s t : Set V
sconn : Connected (induce s G)
tconn : Connected (induce t G)
sintert : Set.Nonempty (s ∩ t)
⊢ Connected (induce (s ∪ t) G)
[PROOFSTEP]
rw [connected_induce_iff] at sconn tconn ⊢
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
sintert : Set.Nonempty (s ∩ t)
⊢ Subgraph.Connected (Subgraph.induce ⊤ (s ∪ t))
[PROOFSTEP]
exact Subgraph.induce_union_connected sconn tconn sintert
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
huv : Adj G u v
⊢ Connected (induce {u, v} G)
[PROOFSTEP]
rw [connected_induce_iff]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
huv : Adj G u v
⊢ Subgraph.Connected (Subgraph.induce ⊤ {u, v})
[PROOFSTEP]
exact Subgraph.top_induce_pair_connected_of_adj huv
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Connected H
⊢ Connected (SimpleGraph.induce H.verts G)
[PROOFSTEP]
rw [connected_induce_iff]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Connected H
⊢ Subgraph.Connected (induce ⊤ H.verts)
[PROOFSTEP]
exact h.mono le_induce_top_verts (by exact rfl)
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
H : Subgraph G
h : Subgraph.Connected H
⊢ H.verts = (induce ⊤ H.verts).verts
[PROOFSTEP]
exact rfl
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
p : Walk G u v
⊢ Connected (induce {v_1 | v_1 ∈ support p} G)
[PROOFSTEP]
rw [← p.verts_toSubgraph]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
u v : V
p : Walk G u v
⊢ Connected (induce (Walk.toSubgraph p).verts G)
[PROOFSTEP]
exact p.toSubgraph_connected.induce_verts
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Connected (induce s G)
tconn : Connected (induce t G)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ Connected (induce (s ∪ t) G)
[PROOFSTEP]
rw [connected_induce_iff] at sconn tconn ⊢
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ Subgraph.Connected (Subgraph.induce ⊤ (s ∪ t))
[PROOFSTEP]
apply (sconn.adj_union tconn hv hw ha).mono
[GOAL]
case hle
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ Subgraph.induce ⊤ {v, w} ⊔ Subgraph.induce ⊤ s ⊔ Subgraph.induce ⊤ t ≤ Subgraph.induce ⊤ (s ∪ t)
[PROOFSTEP]
simp only [Set.mem_singleton_iff, sup_le_iff, Subgraph.le_induce_union_left, Subgraph.le_induce_union_right, and_true, ←
  Subgraph.subgraphOfAdj_eq_induce ha]
[GOAL]
case hle
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ subgraphOfAdj G ha ≤ Subgraph.induce ⊤ (s ∪ t)
[PROOFSTEP]
apply subgraphOfAdj_le_of_adj
[GOAL]
case hle.h
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ Subgraph.Adj (Subgraph.induce ⊤ (s ∪ t)) v w
[PROOFSTEP]
simp [hv, hw, ha]
[GOAL]
case hv
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ (Subgraph.induce ⊤ {v, w} ⊔ Subgraph.induce ⊤ s ⊔ Subgraph.induce ⊤ t).verts = (Subgraph.induce ⊤ (s ∪ t)).verts
[PROOFSTEP]
simp only [Set.mem_singleton_iff, sup_le_iff, Subgraph.verts_sup, Subgraph.induce_verts]
[GOAL]
case hv
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ {v, w} ∪ s ∪ t = s ∪ t
[PROOFSTEP]
rw [Set.union_assoc]
[GOAL]
case hv
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
v w : V
s t : Set V
sconn : Subgraph.Connected (Subgraph.induce ⊤ s)
tconn : Subgraph.Connected (Subgraph.induce ⊤ t)
hv : v ∈ s
hw : w ∈ t
ha : Adj G v w
⊢ {v, w} ∪ (s ∪ t) = s ∪ t
[PROOFSTEP]
simp [Set.insert_subset_iff, Set.singleton_subset_iff, hv, hw]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s : Set V
u : V
hu : u ∈ s
patches :
  ∀ {v : V}, v ∈ s → ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
⊢ Connected (induce s G)
[PROOFSTEP]
rw [connected_iff_exists_forall_reachable]
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s : Set V
u : V
hu : u ∈ s
patches :
  ∀ {v : V}, v ∈ s → ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
⊢ ∃ v, ∀ (w : ↑s), Reachable (induce s G) v w
[PROOFSTEP]
refine ⟨⟨u, hu⟩, ?_⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s : Set V
u : V
hu : u ∈ s
patches :
  ∀ {v : V}, v ∈ s → ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
⊢ ∀ (w : ↑s), Reachable (induce s G) { val := u, property := hu } w
[PROOFSTEP]
rintro ⟨v, hv⟩
[GOAL]
case mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s : Set V
u : V
hu : u ∈ s
patches :
  ∀ {v : V}, v ∈ s → ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
v : V
hv : v ∈ s
⊢ Reachable (induce s G) { val := u, property := hu } { val := v, property := hv }
[PROOFSTEP]
obtain ⟨sv, svs, hu', hv', uv⟩ := patches hv
[GOAL]
case mk.intro.intro.intro.intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
s : Set V
u : V
hu : u ∈ s
patches :
  ∀ {v : V}, v ∈ s → ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
v : V
hv : v ∈ s
sv : Set V
svs : sv ⊆ s
hu' : u ∈ sv
hv' : v ∈ sv
uv : Reachable (induce sv G) { val := u, property := hu' } { val := v, property := hv' }
⊢ Reachable (induce s G) { val := u, property := hu } { val := v, property := hv }
[PROOFSTEP]
exact uv.map (induceHomOfLE _ svs).toHom
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Sn : Set.Nonempty S
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
⊢ Connected (induce (⋃₀ S) G)
[PROOFSTEP]
obtain ⟨s, sS⟩ := Sn
[GOAL]
case intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
s : Set V
sS : s ∈ S
⊢ Connected (induce (⋃₀ S) G)
[PROOFSTEP]
obtain ⟨v, vs⟩ := (Sc sS).nonempty
[GOAL]
case intro.intro.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
s : Set V
sS : s ∈ S
v : V
vs : v ∈ s
⊢ Connected (induce (⋃₀ S) G)
[PROOFSTEP]
apply G.induce_connected_of_patches _ (Set.subset_sUnion_of_mem sS vs)
[GOAL]
case intro.intro.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
s : Set V
sS : s ∈ S
v : V
vs : v ∈ s
⊢ ∀ {v_1 : V},
    v_1 ∈ ⋃₀ S → ∃ s' x hu' hv', Reachable (induce s' G) { val := v, property := hu' } { val := v_1, property := hv' }
[PROOFSTEP]
rintro w hw
[GOAL]
case intro.intro.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
s : Set V
sS : s ∈ S
v : V
vs : v ∈ s
w : V
hw : w ∈ ⋃₀ S
⊢ ∃ s' x hu' hv', Reachable (induce s' G) { val := v, property := hu' } { val := w, property := hv' }
[PROOFSTEP]
simp only [Set.mem_sUnion, exists_prop] at hw
[GOAL]
case intro.intro.mk
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
s : Set V
sS : s ∈ S
v : V
vs : v ∈ s
w : V
hw : ∃ t, t ∈ S ∧ w ∈ t
⊢ ∃ s' x hu' hv', Reachable (induce s' G) { val := v, property := hu' } { val := w, property := hv' }
[PROOFSTEP]
obtain ⟨t, tS, wt⟩ := hw
[GOAL]
case intro.intro.mk.intro.intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
S : Set (Set V)
Snd : ∀ {s t : Set V}, s ∈ S → t ∈ S → Set.Nonempty (s ∩ t)
Sc : ∀ {s : Set V}, s ∈ S → Connected (induce s G)
s : Set V
sS : s ∈ S
v : V
vs : v ∈ s
w : V
t : Set V
tS : t ∈ S
wt : w ∈ t
⊢ ∃ s' x hu' hv', Reachable (induce s' G) { val := v, property := hu' } { val := w, property := hv' }
[PROOFSTEP]
refine
  ⟨s ∪ t, Set.union_subset (Set.subset_sUnion_of_mem sS) (Set.subset_sUnion_of_mem tS), Or.inl vs, Or.inr wt,
    induce_union_connected (Sc sS) (Sc tS) (Snd sS tS) _ _⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
tn : Finset.Nonempty t
⊢ ∃ t', t ⊆ t' ∧ Connected (induce (↑t') G)
[PROOFSTEP]
classical
obtain ⟨u, ut⟩ := tn
refine ⟨t.biUnion (fun v => (Gpc u v).some.support.toFinset), fun v vt => ?_, ?_⟩
· simp only [Finset.mem_biUnion, List.mem_toFinset, exists_prop]
  refine ⟨v, vt, Walk.end_mem_support _⟩
· apply G.induce_connected_of_patches u
  · simp only [Finset.coe_biUnion, Finset.mem_coe, List.coe_toFinset, Set.mem_iUnion, Set.mem_setOf_eq,
      Walk.start_mem_support, exists_prop, and_true]
    exact ⟨u, ut⟩
  intros v hv
  simp only [Finset.mem_coe, Finset.mem_biUnion, List.mem_toFinset, exists_prop] at hv
  obtain ⟨w, wt, hw⟩ := hv
  refine ⟨{x | x ∈ (Gpc u w).some.support}, ?_, ?_⟩
  · simp only [Finset.coe_biUnion, Finset.mem_coe, List.coe_toFinset]
    exact fun x xw => Set.mem_iUnion₂.mpr ⟨w, wt, xw⟩
  · simp only [Set.mem_setOf_eq, Walk.start_mem_support, exists_true_left]
    refine ⟨hw, Walk.connected_induce_support _ _ _⟩
[GOAL]
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
tn : Finset.Nonempty t
⊢ ∃ t', t ⊆ t' ∧ Connected (induce (↑t') G)
[PROOFSTEP]
obtain ⟨u, ut⟩ := tn
[GOAL]
case intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
⊢ ∃ t', t ⊆ t' ∧ Connected (induce (↑t') G)
[PROOFSTEP]
refine ⟨t.biUnion (fun v => (Gpc u v).some.support.toFinset), fun v vt => ?_, ?_⟩
[GOAL]
case intro.refine_1
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v : V
vt : v ∈ t
⊢ v ∈ Finset.biUnion t fun v => List.toFinset (Walk.support (Nonempty.some (_ : Reachable G u v)))
[PROOFSTEP]
simp only [Finset.mem_biUnion, List.mem_toFinset, exists_prop]
[GOAL]
case intro.refine_1
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v : V
vt : v ∈ t
⊢ ∃ a, a ∈ t ∧ v ∈ Walk.support (Nonempty.some (_ : Reachable G u a))
[PROOFSTEP]
refine ⟨v, vt, Walk.end_mem_support _⟩
[GOAL]
case intro.refine_2
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
⊢ Connected (induce (↑(Finset.biUnion t fun v => List.toFinset (Walk.support (Nonempty.some (_ : Reachable G u v))))) G)
[PROOFSTEP]
apply G.induce_connected_of_patches u
[GOAL]
case intro.refine_2.hu
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
⊢ u ∈ ↑(Finset.biUnion t fun v => List.toFinset (Walk.support (Nonempty.some (_ : Reachable G u v))))
[PROOFSTEP]
simp only [Finset.coe_biUnion, Finset.mem_coe, List.coe_toFinset, Set.mem_iUnion, Set.mem_setOf_eq,
  Walk.start_mem_support, exists_prop, and_true]
[GOAL]
case intro.refine_2.hu
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
⊢ ∃ i, i ∈ t
[PROOFSTEP]
exact ⟨u, ut⟩
[GOAL]
case intro.refine_2.patches
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
⊢ ∀ {v : V},
    v ∈ ↑(Finset.biUnion t fun v => List.toFinset (Walk.support (Nonempty.some (_ : Reachable G u v)))) →
      ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
[PROOFSTEP]
intros v hv
[GOAL]
case intro.refine_2.patches
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v : V
hv : v ∈ ↑(Finset.biUnion t fun v => List.toFinset (Walk.support (Nonempty.some (_ : Reachable G u v))))
⊢ ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
[PROOFSTEP]
simp only [Finset.mem_coe, Finset.mem_biUnion, List.mem_toFinset, exists_prop] at hv
[GOAL]
case intro.refine_2.patches
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v : V
hv : ∃ a, a ∈ t ∧ v ∈ Walk.support (Nonempty.some (_ : Reachable G u a))
⊢ ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
[PROOFSTEP]
obtain ⟨w, wt, hw⟩ := hv
[GOAL]
case intro.refine_2.patches.intro.intro
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v w : V
wt : w ∈ t
hw : v ∈ Walk.support (Nonempty.some (_ : Reachable G u w))
⊢ ∃ s' x hu' hv', Reachable (induce s' G) { val := u, property := hu' } { val := v, property := hv' }
[PROOFSTEP]
refine ⟨{x | x ∈ (Gpc u w).some.support}, ?_, ?_⟩
[GOAL]
case intro.refine_2.patches.intro.intro.refine_1
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v w : V
wt : w ∈ t
hw : v ∈ Walk.support (Nonempty.some (_ : Reachable G u w))
⊢ {x | x ∈ Walk.support (Nonempty.some (_ : Reachable G u w))} ⊆
    ↑(Finset.biUnion t fun v => List.toFinset (Walk.support (Nonempty.some (_ : Reachable G u v))))
[PROOFSTEP]
simp only [Finset.coe_biUnion, Finset.mem_coe, List.coe_toFinset]
[GOAL]
case intro.refine_2.patches.intro.intro.refine_1
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v w : V
wt : w ∈ t
hw : v ∈ Walk.support (Nonempty.some (_ : Reachable G u w))
⊢ {x | x ∈ Walk.support (Nonempty.some (_ : Reachable G u w))} ⊆
    ⋃ (x : V) (_ : x ∈ t), {a | a ∈ Walk.support (Nonempty.some (_ : Reachable G u x))}
[PROOFSTEP]
exact fun x xw => Set.mem_iUnion₂.mpr ⟨w, wt, xw⟩
[GOAL]
case intro.refine_2.patches.intro.intro.refine_2
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v w : V
wt : w ∈ t
hw : v ∈ Walk.support (Nonempty.some (_ : Reachable G u w))
⊢ ∃ hu' hv',
    Reachable (induce {x | x ∈ Walk.support (Nonempty.some (_ : Reachable G u w))} G) { val := u, property := hu' }
      { val := v, property := hv' }
[PROOFSTEP]
simp only [Set.mem_setOf_eq, Walk.start_mem_support, exists_true_left]
[GOAL]
case intro.refine_2.patches.intro.intro.refine_2
V : Type u
V' : Type v
G : SimpleGraph V
G' : SimpleGraph V'
Gpc : Preconnected G
t : Finset V
u : V
ut : u ∈ t
v w : V
wt : w ∈ t
hw : v ∈ Walk.support (Nonempty.some (_ : Reachable G u w))
⊢ ∃ hv',
    Reachable (induce {x | x ∈ Walk.support (Nonempty.some (_ : Reachable G u w))} G)
      { val := u, property := (_ : u ∈ {x | x ∈ Walk.support (Nonempty.some (_ : Reachable G u w))}) }
      { val := v, property := hv' }
[PROOFSTEP]
refine ⟨hw, Walk.connected_induce_support _ _ _⟩


[GOAL]
α : Type u_1
N : Type u_2
inst✝ : Zero N
r : α → α → Prop
s : N → N → Prop
hbot : ∀ ⦃n : N⦄, ¬s n 0
hs : WellFounded s
x : α →₀ N
h : ∀ (a : α), a ∈ x.support → Acc (rᶜ ⊓ fun x x_1 => x ≠ x_1) a
⊢ Acc (Finsupp.Lex r s) x
[PROOFSTEP]
rw [lex_eq_invImage_dfinsupp_lex]
[GOAL]
α : Type u_1
N : Type u_2
inst✝ : Zero N
r : α → α → Prop
s : N → N → Prop
hbot : ∀ ⦃n : N⦄, ¬s n 0
hs : WellFounded s
x : α →₀ N
h : ∀ (a : α), a ∈ x.support → Acc (rᶜ ⊓ fun x x_1 => x ≠ x_1) a
⊢ Acc (InvImage (DFinsupp.Lex r fun x => s) toDFinsupp) x
[PROOFSTEP]
classical
refine' InvImage.accessible toDFinsupp (DFinsupp.Lex.acc (fun _ => hbot) (fun _ => hs) _ _)
simpa only [toDFinsupp_support] using h
[GOAL]
α : Type u_1
N : Type u_2
inst✝ : Zero N
r : α → α → Prop
s : N → N → Prop
hbot : ∀ ⦃n : N⦄, ¬s n 0
hs : WellFounded s
x : α →₀ N
h : ∀ (a : α), a ∈ x.support → Acc (rᶜ ⊓ fun x x_1 => x ≠ x_1) a
⊢ Acc (InvImage (DFinsupp.Lex r fun x => s) toDFinsupp) x
[PROOFSTEP]
refine' InvImage.accessible toDFinsupp (DFinsupp.Lex.acc (fun _ => hbot) (fun _ => hs) _ _)
[GOAL]
α : Type u_1
N : Type u_2
inst✝ : Zero N
r : α → α → Prop
s : N → N → Prop
hbot : ∀ ⦃n : N⦄, ¬s n 0
hs : WellFounded s
x : α →₀ N
h : ∀ (a : α), a ∈ x.support → Acc (rᶜ ⊓ fun x x_1 => x ≠ x_1) a
⊢ ∀ (i : α), i ∈ DFinsupp.support (toDFinsupp x) → Acc (rᶜ ⊓ fun x x_1 => x ≠ x_1) i
[PROOFSTEP]
simpa only [toDFinsupp_support] using h