[GOAL]
n : ℕ
⊢ LeftMoves (powHalf n) = PUnit
[PROOFSTEP]
cases n
[GOAL]
case zero
⊢ LeftMoves (powHalf Nat.zero) = PUnit
[PROOFSTEP]
rfl
[GOAL]
case succ
n✝ : ℕ
⊢ LeftMoves (powHalf (Nat.succ n✝)) = PUnit
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
i : LeftMoves (powHalf n)
⊢ moveLeft (powHalf n) i = 0
[PROOFSTEP]
cases n
[GOAL]
case zero
i : LeftMoves (powHalf Nat.zero)
⊢ moveLeft (powHalf Nat.zero) i = 0
[PROOFSTEP]
cases i
[GOAL]
case succ
n✝ : ℕ
i : LeftMoves (powHalf (Nat.succ n✝))
⊢ moveLeft (powHalf (Nat.succ n✝)) i = 0
[PROOFSTEP]
cases i
[GOAL]
case zero.unit
⊢ moveLeft (powHalf Nat.zero) PUnit.unit = 0
[PROOFSTEP]
rfl
[GOAL]
case succ.unit
n✝ : ℕ
⊢ moveLeft (powHalf (Nat.succ n✝)) PUnit.unit = 0
[PROOFSTEP]
rfl
[GOAL]
n : ℕ
⊢ Unique (LeftMoves (powHalf n))
[PROOFSTEP]
cases n
[GOAL]
case zero
⊢ Unique (LeftMoves (powHalf Nat.zero))
[PROOFSTEP]
exact PUnit.unique
[GOAL]
case succ
n✝ : ℕ
⊢ Unique (LeftMoves (powHalf (Nat.succ n✝)))
[PROOFSTEP]
exact PUnit.unique
[GOAL]
⊢ birthday (powHalf 1) = 2
[PROOFSTEP]
rw [birthday_def]
[GOAL]
⊢ max (Ordinal.lsub fun i => birthday (moveLeft (powHalf 1) i))
      (Ordinal.lsub fun i => birthday (moveRight (powHalf 1) i)) =
    2
[PROOFSTEP]
dsimp
[GOAL]
⊢ max (Ordinal.lsub fun i => birthday (moveLeft (powHalf 1) i)) (Ordinal.lsub fun i => birthday 1) = 2
[PROOFSTEP]
simpa using Order.le_succ (1 : Ordinal)
[GOAL]
n : ℕ
⊢ Numeric (powHalf n)
[PROOFSTEP]
induction' n with n hn
[GOAL]
case zero
⊢ Numeric (powHalf Nat.zero)
[PROOFSTEP]
exact numeric_one
[GOAL]
case succ
n : ℕ
hn : Numeric (powHalf n)
⊢ Numeric (powHalf (Nat.succ n))
[PROOFSTEP]
constructor
[GOAL]
case succ.left
n : ℕ
hn : Numeric (powHalf n)
⊢ ∀ (i j : PUnit), OfNat.ofNat 0 i < (fun x => powHalf n) j
[PROOFSTEP]
simpa using hn.moveLeft_lt default
[GOAL]
case succ.right
n : ℕ
hn : Numeric (powHalf n)
⊢ (∀ (i : PUnit), Numeric (OfNat.ofNat 0 i)) ∧ ∀ (j : PUnit), Numeric ((fun x => powHalf n) j)
[PROOFSTEP]
exact ⟨fun _ => numeric_zero, fun _ => hn⟩
[GOAL]
n : ℕ
⊢ powHalf n ≤ 1
[PROOFSTEP]
induction' n with n hn
[GOAL]
case zero
⊢ powHalf Nat.zero ≤ 1
[PROOFSTEP]
exact le_rfl
[GOAL]
case succ
n : ℕ
hn : powHalf n ≤ 1
⊢ powHalf (Nat.succ n) ≤ 1
[PROOFSTEP]
exact (powHalf_succ_le_powHalf n).trans hn
[GOAL]
n : ℕ
⊢ 0 < powHalf n
[PROOFSTEP]
rw [← lf_iff_lt numeric_zero (numeric_powHalf n), zero_lf_le]
[GOAL]
n : ℕ
⊢ ∃ i, 0 ≤ moveLeft (powHalf n) i
[PROOFSTEP]
simp
[GOAL]
n : ℕ
⊢ powHalf (n + 1) + powHalf (n + 1) ≈ powHalf n
[PROOFSTEP]
induction' n using Nat.strong_induction_on with n hn
[GOAL]
case h
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf (n + 1) + powHalf (n + 1) ≈ powHalf n
[PROOFSTEP]
constructor
[GOAL]
case h.left
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf (n + 1) + powHalf (n + 1) ≤ powHalf n
[PROOFSTEP]
rw [le_iff_forall_lf]
[GOAL]
case h.right
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf n ≤ powHalf (n + 1) + powHalf (n + 1)
[PROOFSTEP]
rw [le_iff_forall_lf]
[GOAL]
case h.left
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ (∀ (i : LeftMoves (powHalf (n + 1) + powHalf (n + 1))), moveLeft (powHalf (n + 1) + powHalf (n + 1)) i ⧏ powHalf n) ∧
    ∀ (j : RightMoves (powHalf n)), powHalf (n + 1) + powHalf (n + 1) ⧏ moveRight (powHalf n) j
[PROOFSTEP]
constructor
[GOAL]
case h.right
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ (∀ (i : LeftMoves (powHalf n)), moveLeft (powHalf n) i ⧏ powHalf (n + 1) + powHalf (n + 1)) ∧
    ∀ (j : RightMoves (powHalf (n + 1) + powHalf (n + 1))), powHalf n ⧏ moveRight (powHalf (n + 1) + powHalf (n + 1)) j
[PROOFSTEP]
constructor
[GOAL]
case h.left.left
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ ∀ (i : LeftMoves (powHalf (n + 1) + powHalf (n + 1))), moveLeft (powHalf (n + 1) + powHalf (n + 1)) i ⧏ powHalf n
[PROOFSTEP]
rintro (⟨⟨⟩⟩ | ⟨⟨⟩⟩)
[GOAL]
case h.left.left.inl.unit
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveLeft (powHalf (n + 1) + powHalf (n + 1)) (Sum.inl PUnit.unit) ⧏ powHalf n
[PROOFSTEP]
apply lf_of_lt
[GOAL]
case h.left.left.inr.unit
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveLeft (powHalf (n + 1) + powHalf (n + 1)) (Sum.inr PUnit.unit) ⧏ powHalf n
[PROOFSTEP]
apply lf_of_lt
[GOAL]
case h.left.left.inl.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveLeft (powHalf (n + 1) + powHalf (n + 1)) (Sum.inl PUnit.unit) < powHalf n
[PROOFSTEP]
calc
  0 + powHalf n.succ ≈ powHalf n.succ := zero_add_equiv _
  _ < powHalf n := powHalf_succ_lt_powHalf n
[GOAL]
case h.left.left.inr.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveLeft (powHalf (n + 1) + powHalf (n + 1)) (Sum.inr PUnit.unit) < powHalf n
[PROOFSTEP]
calc
  powHalf n.succ + 0 ≈ powHalf n.succ := add_zero_equiv _
  _ < powHalf n := powHalf_succ_lt_powHalf n
[GOAL]
case h.left.right
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ ∀ (j : RightMoves (powHalf n)), powHalf (n + 1) + powHalf (n + 1) ⧏ moveRight (powHalf n) j
[PROOFSTEP]
cases' n with n
[GOAL]
case h.left.right.zero
hn : ∀ (m : ℕ), m < Nat.zero → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ ∀ (j : RightMoves (powHalf Nat.zero)),
    powHalf (Nat.zero + 1) + powHalf (Nat.zero + 1) ⧏ moveRight (powHalf Nat.zero) j
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case h.left.right.succ
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ ∀ (j : RightMoves (powHalf (Nat.succ n))),
    powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1) ⧏ moveRight (powHalf (Nat.succ n)) j
[PROOFSTEP]
rintro ⟨⟩
[GOAL]
case h.left.right.succ.unit
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1) ⧏ moveRight (powHalf (Nat.succ n)) PUnit.unit
[PROOFSTEP]
apply lf_of_moveRight_le
[GOAL]
case h.left.right.succ.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveRight (powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1)) ?h.left.right.succ.unit.j ≤
    moveRight (powHalf (Nat.succ n)) PUnit.unit
case h.left.right.succ.unit.j
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ RightMoves (powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1))
[PROOFSTEP]
swap
[GOAL]
case h.left.right.succ.unit.j
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ RightMoves (powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1))
case h.left.right.succ.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveRight (powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1)) ?h.left.right.succ.unit.j ≤
    moveRight (powHalf (Nat.succ n)) PUnit.unit
[PROOFSTEP]
exact Sum.inl default
[GOAL]
case h.left.right.succ.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < Nat.succ n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ moveRight (powHalf (Nat.succ n + 1) + powHalf (Nat.succ n + 1)) (Sum.inl default) ≤
    moveRight (powHalf (Nat.succ n)) PUnit.unit
[PROOFSTEP]
calc
  powHalf n.succ + powHalf (n.succ + 1) ≤ powHalf n.succ + powHalf n.succ :=
    add_le_add_left (powHalf_succ_le_powHalf _) _
  _ ≈ powHalf n := hn _ (Nat.lt_succ_self n)
[GOAL]
case h.right.left
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ ∀ (i : LeftMoves (powHalf n)), moveLeft (powHalf n) i ⧏ powHalf (n + 1) + powHalf (n + 1)
[PROOFSTEP]
simp only [powHalf_moveLeft, forall_const]
[GOAL]
case h.right.left
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ 0 ⧏ powHalf (n + 1) + powHalf (n + 1)
[PROOFSTEP]
apply lf_of_lt
[GOAL]
case h.right.left.h
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ 0 < powHalf (n + 1) + powHalf (n + 1)
[PROOFSTEP]
calc
  0 ≈ 0 + 0 := (Equiv.symm (add_zero_equiv 0))
  _ ≤ powHalf n.succ + 0 := (add_le_add_right (zero_le_powHalf _) _)
  _ < powHalf n.succ + powHalf n.succ := add_lt_add_left (powHalf_pos _) _
[GOAL]
case h.right.right
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ ∀ (j : RightMoves (powHalf (n + 1) + powHalf (n + 1))), powHalf n ⧏ moveRight (powHalf (n + 1) + powHalf (n + 1)) j
[PROOFSTEP]
rintro (⟨⟨⟩⟩ | ⟨⟨⟩⟩)
[GOAL]
case h.right.right.inl.unit
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf n ⧏ moveRight (powHalf (n + 1) + powHalf (n + 1)) (Sum.inl PUnit.unit)
[PROOFSTEP]
apply lf_of_lt
[GOAL]
case h.right.right.inr.unit
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf n ⧏ moveRight (powHalf (n + 1) + powHalf (n + 1)) (Sum.inr PUnit.unit)
[PROOFSTEP]
apply lf_of_lt
[GOAL]
case h.right.right.inl.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf n < moveRight (powHalf (n + 1) + powHalf (n + 1)) (Sum.inl PUnit.unit)
[PROOFSTEP]
calc
  powHalf n ≈ powHalf n + 0 := (Equiv.symm (add_zero_equiv _))
  _ < powHalf n + powHalf n.succ := add_lt_add_left (powHalf_pos _) _
[GOAL]
case h.right.right.inr.unit.h
n : ℕ
hn : ∀ (m : ℕ), m < n → powHalf (m + 1) + powHalf (m + 1) ≈ powHalf m
⊢ powHalf n < moveRight (powHalf (n + 1) + powHalf (n + 1)) (Sum.inr PUnit.unit)
[PROOFSTEP]
calc
  powHalf n ≈ 0 + powHalf n := (Equiv.symm (zero_add_equiv _))
  _ < powHalf n.succ + powHalf n := add_lt_add_right (powHalf_pos _) _
[GOAL]
n : ℕ
⊢ 2 • powHalf (Nat.succ n) = powHalf n
[PROOFSTEP]
rw [two_nsmul]
[GOAL]
n : ℕ
⊢ powHalf (Nat.succ n) + powHalf (Nat.succ n) = powHalf n
[PROOFSTEP]
exact Quotient.sound (PGame.add_powHalf_succ_self_eq_powHalf n)
[GOAL]
n : ℕ
⊢ 2 ^ n • powHalf n = 1
[PROOFSTEP]
induction' n with n hn
[GOAL]
case zero
⊢ 2 ^ Nat.zero • powHalf Nat.zero = 1
[PROOFSTEP]
simp only [Nat.zero_eq, pow_zero, powHalf_zero, one_smul]
[GOAL]
case succ
n : ℕ
hn : 2 ^ n • powHalf n = 1
⊢ 2 ^ Nat.succ n • powHalf (Nat.succ n) = 1
[PROOFSTEP]
rw [← hn, ← double_powHalf_succ_eq_powHalf n, smul_smul (2 ^ n) 2 (powHalf n.succ), mul_comm, pow_succ]
[GOAL]
n k : ℕ
⊢ 2 ^ n • powHalf (n + k) = powHalf k
[PROOFSTEP]
induction' k with k hk
[GOAL]
case zero
n : ℕ
⊢ 2 ^ n • powHalf (n + Nat.zero) = powHalf Nat.zero
[PROOFSTEP]
simp only [add_zero, Surreal.nsmul_pow_two_powHalf, Nat.zero_eq, eq_self_iff_true, Surreal.powHalf_zero]
[GOAL]
case succ
n k : ℕ
hk : 2 ^ n • powHalf (n + k) = powHalf k
⊢ 2 ^ n • powHalf (n + Nat.succ k) = powHalf (Nat.succ k)
[PROOFSTEP]
rw [← double_powHalf_succ_eq_powHalf (n + k), ← double_powHalf_succ_eq_powHalf k, smul_algebra_smul_comm] at hk
[GOAL]
case succ
n k : ℕ
hk : 2 • 2 ^ n • powHalf (Nat.succ (n + k)) = 2 • powHalf (Nat.succ k)
⊢ 2 ^ n • powHalf (n + Nat.succ k) = powHalf (Nat.succ k)
[PROOFSTEP]
rwa [← zsmul_eq_zsmul_iff' two_ne_zero]
[GOAL]
m : ℤ
n k : ℕ
⊢ (m * 2 ^ n) • powHalf (n + k) = m • powHalf k
[PROOFSTEP]
rw [mul_zsmul]
[GOAL]
m : ℤ
n k : ℕ
⊢ m • 2 ^ n • powHalf (n + k) = m • powHalf k
[PROOFSTEP]
congr
[GOAL]
case e_a
m : ℤ
n k : ℕ
⊢ 2 ^ n • powHalf (n + k) = powHalf k
[PROOFSTEP]
norm_cast
[GOAL]
case e_a
m : ℤ
n k : ℕ
⊢ 2 ^ n • powHalf (n + k) = powHalf k
[PROOFSTEP]
exact nsmul_pow_two_powHalf' n k
[GOAL]
m₁ m₂ : ℤ
y₁ y₂ : ℕ
h₂ : m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂
⊢ m₁ • powHalf y₂ = m₂ • powHalf y₁
[PROOFSTEP]
revert m₁ m₂
[GOAL]
y₁ y₂ : ℕ
⊢ ∀ {m₁ m₂ : ℤ}, m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂ → m₁ • powHalf y₂ = m₂ • powHalf y₁
[PROOFSTEP]
wlog h : y₁ ≤ y₂
[GOAL]
case inr
y₁ y₂ : ℕ
this : ∀ {y₁ y₂ : ℕ}, y₁ ≤ y₂ → ∀ {m₁ m₂ : ℤ}, m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂ → m₁ • powHalf y₂ = m₂ • powHalf y₁
h : ¬y₁ ≤ y₂
⊢ ∀ {m₁ m₂ : ℤ}, m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂ → m₁ • powHalf y₂ = m₂ • powHalf y₁
[PROOFSTEP]
intro m₁ m₂ aux
[GOAL]
case inr
y₁ y₂ : ℕ
this : ∀ {y₁ y₂ : ℕ}, y₁ ≤ y₂ → ∀ {m₁ m₂ : ℤ}, m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂ → m₁ • powHalf y₂ = m₂ • powHalf y₁
h : ¬y₁ ≤ y₂
m₁ m₂ : ℤ
aux : m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂
⊢ m₁ • powHalf y₂ = m₂ • powHalf y₁
[PROOFSTEP]
exact (this (le_of_not_le h) aux.symm).symm
[GOAL]
y₁ y₂ : ℕ
h : y₁ ≤ y₂
⊢ ∀ {m₁ m₂ : ℤ}, m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂ → m₁ • powHalf y₂ = m₂ • powHalf y₁
[PROOFSTEP]
intro m₁ m₂ h₂
[GOAL]
y₁ y₂ : ℕ
h : y₁ ≤ y₂
m₁ m₂ : ℤ
h₂ : m₁ * 2 ^ y₁ = m₂ * 2 ^ y₂
⊢ m₁ • powHalf y₂ = m₂ • powHalf y₁
[PROOFSTEP]
obtain ⟨c, rfl⟩ := le_iff_exists_add.mp h
[GOAL]
case intro
y₁ : ℕ
m₁ m₂ : ℤ
c : ℕ
h : y₁ ≤ y₁ + c
h₂ : m₁ * 2 ^ y₁ = m₂ * 2 ^ (y₁ + c)
⊢ m₁ • powHalf (y₁ + c) = m₂ • powHalf y₁
[PROOFSTEP]
rw [add_comm, pow_add, ← mul_assoc, mul_eq_mul_right_iff] at h₂
[GOAL]
case intro
y₁ : ℕ
m₁ m₂ : ℤ
c : ℕ
h : y₁ ≤ y₁ + c
h₂ : m₁ = m₂ * 2 ^ c ∨ 2 ^ y₁ = 0
⊢ m₁ • powHalf (y₁ + c) = m₂ • powHalf y₁
[PROOFSTEP]
cases' h₂ with h₂ h₂
[GOAL]
case intro.inl
y₁ : ℕ
m₁ m₂ : ℤ
c : ℕ
h : y₁ ≤ y₁ + c
h₂ : m₁ = m₂ * 2 ^ c
⊢ m₁ • powHalf (y₁ + c) = m₂ • powHalf y₁
[PROOFSTEP]
rw [h₂, add_comm, zsmul_pow_two_powHalf m₂ c y₁]
[GOAL]
case intro.inr
y₁ : ℕ
m₁ m₂ : ℤ
c : ℕ
h : y₁ ≤ y₁ + c
h₂ : 2 ^ y₁ = 0
⊢ m₁ • powHalf (y₁ + c) = m₂ • powHalf y₁
[PROOFSTEP]
have := Nat.one_le_pow y₁ 2 Nat.succ_pos'
[GOAL]
case intro.inr
y₁ : ℕ
m₁ m₂ : ℤ
c : ℕ
h : y₁ ≤ y₁ + c
h₂ : 2 ^ y₁ = 0
this : 1 ≤ 2 ^ y₁
⊢ m₁ • powHalf (y₁ + c) = m₂ • powHalf y₁
[PROOFSTEP]
norm_cast at h₂
[GOAL]
case intro.inr
y₁ : ℕ
m₁ m₂ : ℤ
c : ℕ
h : y₁ ≤ y₁ + c
this : 1 ≤ 2 ^ y₁
h₂ : 2 ^ y₁ = 0
⊢ m₁ • powHalf (y₁ + c) = m₂ • powHalf y₁
[PROOFSTEP]
linarith
[GOAL]
x : Localization.Away 2
⊢ ∀ {a c : ℤ} {b d : { x // x ∈ Submonoid.powers 2 }},
    ↑(Localization.r (Submonoid.powers 2)) (a, b) (c, d) → a • powHalf (Submonoid.log b) = c • powHalf (Submonoid.log d)
[PROOFSTEP]
intro m₁ m₂ n₁ n₂ h₁
[GOAL]
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
obtain ⟨⟨n₃, y₃, hn₃⟩, h₂⟩ := Localization.r_iff_exists.mp h₁
[GOAL]
case intro.mk.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h₂ :
  ↑{ val := n₃, property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = n₃) } * (↑(m₂, n₂).snd * (m₁, n₁).fst) =
    ↑{ val := n₃, property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = n₃) } * (↑(m₁, n₁).snd * (m₂, n₂).fst)
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
simp only [Subtype.coe_mk, mul_eq_mul_left_iff] at h₂
[GOAL]
case intro.mk.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h₂ : ↑n₂ * m₁ = ↑n₁ * m₂ ∨ n₃ = 0
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
cases h₂
[GOAL]
case intro.mk.intro.inl
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
obtain ⟨a₁, ha₁⟩ := n₁.prop
[GOAL]
case intro.mk.intro.inl.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : (fun x x_1 => x ^ x_1) 2 a₁ = ↑n₁
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
obtain ⟨a₂, ha₂⟩ := n₂.prop
[GOAL]
case intro.mk.intro.inl.intro.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : (fun x x_1 => x ^ x_1) 2 a₁ = ↑n₁
a₂ : ℕ
ha₂ : (fun x x_1 => x ^ x_1) 2 a₂ = ↑n₂
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
simp only at ha₁ ha₂ ⊢
[GOAL]
case intro.mk.intro.inl.intro.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : 2 ^ a₁ = ↑n₁
a₂ : ℕ
ha₂ : 2 ^ a₂ = ↑n₂
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
have hn₁ : n₁ = Submonoid.pow 2 a₁ := Subtype.ext ha₁.symm
[GOAL]
case intro.mk.intro.inl.intro.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : 2 ^ a₁ = ↑n₁
a₂ : ℕ
ha₂ : 2 ^ a₂ = ↑n₂
hn₁ : n₁ = Submonoid.pow 2 a₁
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
have hn₂ : n₂ = Submonoid.pow 2 a₂ := Subtype.ext ha₂.symm
[GOAL]
case intro.mk.intro.inl.intro.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : 2 ^ a₁ = ↑n₁
a₂ : ℕ
ha₂ : 2 ^ a₂ = ↑n₂
hn₁ : n₁ = Submonoid.pow 2 a₁
hn₂ : n₂ = Submonoid.pow 2 a₂
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
have h₂ : 1 < (2 : ℤ).natAbs := one_lt_two
[GOAL]
case intro.mk.intro.inl.intro.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : 2 ^ a₁ = ↑n₁
a₂ : ℕ
ha₂ : 2 ^ a₂ = ↑n₂
hn₁ : n₁ = Submonoid.pow 2 a₁
hn₂ : n₂ = Submonoid.pow 2 a₂
h₂ : 1 < Int.natAbs 2
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
rw [hn₁, hn₂, Submonoid.log_pow_int_eq_self h₂, Submonoid.log_pow_int_eq_self h₂]
[GOAL]
case intro.mk.intro.inl.intro.intro
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : 2 ^ a₁ = ↑n₁
a₂ : ℕ
ha₂ : 2 ^ a₂ = ↑n₂
hn₁ : n₁ = Submonoid.pow 2 a₁
hn₂ : n₂ = Submonoid.pow 2 a₂
h₂ : 1 < Int.natAbs 2
⊢ m₁ • powHalf a₁ = m₂ • powHalf a₂
[PROOFSTEP]
apply dyadic_aux
[GOAL]
case intro.mk.intro.inl.intro.intro.h₂
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : ↑n₂ * m₁ = ↑n₁ * m₂
a₁ : ℕ
ha₁ : 2 ^ a₁ = ↑n₁
a₂ : ℕ
ha₂ : 2 ^ a₂ = ↑n₂
hn₁ : n₁ = Submonoid.pow 2 a₁
hn₂ : n₂ = Submonoid.pow 2 a₂
h₂ : 1 < Int.natAbs 2
⊢ m₁ * 2 ^ a₂ = m₂ * 2 ^ a₁
[PROOFSTEP]
rwa [ha₁, ha₂, mul_comm, mul_comm m₂]
[GOAL]
case intro.mk.intro.inr
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : n₃ = 0
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
have : (1 : ℤ) ≤ 2 ^ y₃ := by exact_mod_cast Nat.one_le_pow y₃ 2 Nat.succ_pos'
[GOAL]
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : n₃ = 0
⊢ 1 ≤ 2 ^ y₃
[PROOFSTEP]
exact_mod_cast Nat.one_le_pow y₃ 2 Nat.succ_pos'
[GOAL]
case intro.mk.intro.inr
x : Localization.Away 2
m₁ m₂ : ℤ
n₁ n₂ : { x // x ∈ Submonoid.powers 2 }
h₁ : ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂)
n₃ : ℤ
y₃ : ℕ
hn₃ : (fun x x_1 => x ^ x_1) 2 y₃ = n₃
h✝ : n₃ = 0
this : 1 ≤ 2 ^ y₃
⊢ m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)
[PROOFSTEP]
linarith
[GOAL]
x y : Localization.Away 2
⊢ ∀ (x y : ℤ × { x // x ∈ Submonoid.powers 2 }),
    ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk x.fst x.snd + Localization.mk y.fst y.snd) =
      ZeroHom.toFun
          {
            toFun := fun x =>
              Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
                (_ :
                  ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                    ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                      m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
            map_zero' :=
              (_ :
                Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                    (_ :
                      ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                        ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                          m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                  0 • powHalf (Submonoid.log 1)) }
          (Localization.mk x.fst x.snd) +
        ZeroHom.toFun
          {
            toFun := fun x =>
              Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
                (_ :
                  ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                    ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                      m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
            map_zero' :=
              (_ :
                Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                    (_ :
                      ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                        ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                          m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                  0 • powHalf (Submonoid.log 1)) }
          (Localization.mk y.fst y.snd)
[PROOFSTEP]
rintro ⟨a, ⟨b, ⟨b', rfl⟩⟩⟩ ⟨c, ⟨d, ⟨d', rfl⟩⟩⟩
[GOAL]
case mk.mk.intro.mk.mk.intro
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
⊢ ZeroHom.toFun
      {
        toFun := fun x =>
          Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
            (_ :
              ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                  m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
        map_zero' :=
          (_ :
            Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                (_ :
                  ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                    ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                      m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
              0 • powHalf (Submonoid.log 1)) }
      (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd +
        Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd) =
    ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd) +
      ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd)
[PROOFSTEP]
have h₂ : 1 < (2 : ℤ).natAbs := one_lt_two
[GOAL]
case mk.mk.intro.mk.mk.intro
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
h₂ : 1 < Int.natAbs 2
⊢ ZeroHom.toFun
      {
        toFun := fun x =>
          Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
            (_ :
              ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                  m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
        map_zero' :=
          (_ :
            Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                (_ :
                  ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                    ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                      m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
              0 • powHalf (Submonoid.log 1)) }
      (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd +
        Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd) =
    ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd) +
      ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd)
[PROOFSTEP]
have hpow₂ := Submonoid.log_pow_int_eq_self h₂
[GOAL]
case mk.mk.intro.mk.mk.intro
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
h₂ : 1 < Int.natAbs 2
hpow₂ : ∀ (m : ℕ), Submonoid.log (Submonoid.pow 2 m) = m
⊢ ZeroHom.toFun
      {
        toFun := fun x =>
          Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
            (_ :
              ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                  m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
        map_zero' :=
          (_ :
            Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                (_ :
                  ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                    ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                      m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
              0 • powHalf (Submonoid.log 1)) }
      (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd +
        Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd) =
    ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd) +
      ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd)
[PROOFSTEP]
simp_rw [Submonoid.pow_apply] at hpow₂
[GOAL]
case mk.mk.intro.mk.mk.intro
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
h₂ : 1 < Int.natAbs 2
hpow₂ : ∀ (m : ℕ), Submonoid.log { val := 2 ^ m, property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = 2 ^ m) } = m
⊢ ZeroHom.toFun
      {
        toFun := fun x =>
          Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
            (_ :
              ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                  m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
        map_zero' :=
          (_ :
            Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                (_ :
                  ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                    ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                      m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
              0 • powHalf (Submonoid.log 1)) }
      (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd +
        Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd) =
    ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).fst
          (a,
              { val := (fun x x_1 => x ^ x_1) 2 b',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 b') }).snd) +
      ZeroHom.toFun
        {
          toFun := fun x =>
            Localization.liftOn x (fun x y => x • powHalf (Submonoid.log y))
              (_ :
                ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                  ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                    m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)),
          map_zero' :=
            (_ :
              Localization.liftOn 0 (fun x y => x • powHalf (Submonoid.log y))
                  (_ :
                    ∀ {m₁ m₂ : ℤ} {n₁ n₂ : { x // x ∈ Submonoid.powers 2 }},
                      ↑(Localization.r (Submonoid.powers 2)) (m₁, n₁) (m₂, n₂) →
                        m₁ • powHalf (Submonoid.log n₁) = m₂ • powHalf (Submonoid.log n₂)) =
                0 • powHalf (Submonoid.log 1)) }
        (Localization.mk
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).fst
          (c,
              { val := (fun x x_1 => x ^ x_1) 2 d',
                property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = (fun x x_1 => x ^ x_1) 2 d') }).snd)
[PROOFSTEP]
simp_rw [Localization.add_mk, Localization.liftOn_mk, Submonoid.log_mul (Int.pow_right_injective h₂), hpow₂]
[GOAL]
case mk.mk.intro.mk.mk.intro
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
h₂ : 1 < Int.natAbs 2
hpow₂ : ∀ (m : ℕ), Submonoid.log { val := 2 ^ m, property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = 2 ^ m) } = m
⊢ (2 ^ b' * c + 2 ^ d' * a) • powHalf (b' + d') = a • powHalf b' + c • powHalf d'
[PROOFSTEP]
calc
  (2 ^ b' * c + 2 ^ d' * a) • powHalf (b' + d') = (c * 2 ^ b') • powHalf (b' + d') + (a * 2 ^ d') • powHalf (d' + b') :=
    by simp only [add_smul, mul_comm, add_comm]
  _ = c • powHalf d' + a • powHalf b' := by simp only [zsmul_pow_two_powHalf]
  _ = a • powHalf b' + c • powHalf d' := add_comm _ _
[GOAL]
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
h₂ : 1 < Int.natAbs 2
hpow₂ : ∀ (m : ℕ), Submonoid.log { val := 2 ^ m, property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = 2 ^ m) } = m
⊢ (2 ^ b' * c + 2 ^ d' * a) • powHalf (b' + d') = (c * 2 ^ b') • powHalf (b' + d') + (a * 2 ^ d') • powHalf (d' + b')
[PROOFSTEP]
simp only [add_smul, mul_comm, add_comm]
[GOAL]
x y : Localization.Away 2
a : ℤ
b' : ℕ
c : ℤ
d' : ℕ
h₂ : 1 < Int.natAbs 2
hpow₂ : ∀ (m : ℕ), Submonoid.log { val := 2 ^ m, property := (_ : ∃ y, (fun x x_1 => x ^ x_1) 2 y = 2 ^ m) } = m
⊢ (c * 2 ^ b') • powHalf (b' + d') + (a * 2 ^ d') • powHalf (d' + b') = c • powHalf d' + a • powHalf b'
[PROOFSTEP]
simp only [zsmul_pow_two_powHalf]
[GOAL]
m : ℤ
p : { x // x ∈ Submonoid.powers 2 }
⊢ ↑dyadicMap (IsLocalization.mk' (Localization (Submonoid.powers 2)) m p) = m • powHalf (Submonoid.log p)
[PROOFSTEP]
rw [← Localization.mk_eq_mk']
[GOAL]
m : ℤ
p : { x // x ∈ Submonoid.powers 2 }
⊢ ↑dyadicMap (Localization.mk m p) = m • powHalf (Submonoid.log p)
[PROOFSTEP]
rfl
[GOAL]
m : ℤ
n : ℕ
⊢ ↑dyadicMap (IsLocalization.mk' (Localization (Submonoid.powers 2)) m (Submonoid.pow 2 n)) = m • powHalf n
[PROOFSTEP]
rw [dyadicMap_apply, @Submonoid.log_pow_int_eq_self 2 one_lt_two]
[GOAL]
m : ℤ
n : ℕ
⊢ m • powHalf (Submonoid.log (Submonoid.pow 2 n)) = m • powHalf n
[PROOFSTEP]
rw [@Submonoid.log_pow_int_eq_self 2 one_lt_two]


[GOAL]
⊢ ∀ {X' X : Type u} {Y : AddCommGroupCat} (f : X' ⟶ X) (g : X ⟶ (forget AddCommGroupCat).obj Y),
    ↑((fun X G => FreeAbelianGroup.lift.symm) X' Y).symm (f ≫ g) =
      free.map f ≫ ↑((fun X G => FreeAbelianGroup.lift.symm) X Y).symm g
[PROOFSTEP]
intros
[GOAL]
X'✝ X✝ : Type u
Y✝ : AddCommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget AddCommGroupCat).obj Y✝
⊢ ↑((fun X G => FreeAbelianGroup.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝) =
    free.map f✝ ≫ ↑((fun X G => FreeAbelianGroup.lift.symm) X✝ Y✝).symm g✝
[PROOFSTEP]
ext
[GOAL]
case w
X'✝ X✝ : Type u
Y✝ : AddCommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget AddCommGroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ↑(↑((fun X G => FreeAbelianGroup.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝)) x✝ =
    ↑(free.map f✝ ≫ ↑((fun X G => FreeAbelianGroup.lift.symm) X✝ Y✝).symm g✝) x✝
[PROOFSTEP]
simp only [Equiv.symm_symm]
[GOAL]
case w
X'✝ X✝ : Type u
Y✝ : AddCommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget AddCommGroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ↑(↑FreeAbelianGroup.lift (f✝ ≫ g✝)) x✝ = ↑(free.map f✝ ≫ ↑FreeAbelianGroup.lift g✝) x✝
[PROOFSTEP]
apply FreeAbelianGroup.lift_comp
[GOAL]
⊢ ∀ (X : Type u),
    { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map (𝟙 X) =
      𝟙 ({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X)
[PROOFSTEP]
intros
[GOAL]
X✝ : Type u
⊢ { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map (𝟙 X✝) =
    𝟙 ({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
[PROOFSTEP]
ext1
[GOAL]
case w
X✝ : Type u
x✝ : ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
⊢ ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map (𝟙 X✝)) x✝ =
    ↑(𝟙 ({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)) x✝
[PROOFSTEP]
rw [← FreeGroup.map.unique]
[GOAL]
case w.hg
X✝ : Type u
x✝ : ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
⊢ ∀ (x : X✝),
    ↑(𝟙 ({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)) (FreeGroup.of x) =
      FreeGroup.of (𝟙 X✝ x)
[PROOFSTEP]
intros
[GOAL]
case w.hg
X✝ : Type u
x✝¹ : ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
x✝ : X✝
⊢ ↑(𝟙 ({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)) (FreeGroup.of x✝) =
    FreeGroup.of (𝟙 X✝ x✝)
[PROOFSTEP]
rfl
[GOAL]
⊢ ∀ {X Y Z : Type u} (f : X ⟶ Y) (g : Y ⟶ Z),
    { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map (f ≫ g) =
      { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map f ≫
        { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map g
[PROOFSTEP]
intros
[GOAL]
X✝ Y✝ Z✝ : Type u
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map (f✝ ≫ g✝) =
    { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map f✝ ≫
      { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map g✝
[PROOFSTEP]
ext1
[GOAL]
case w
X✝ Y✝ Z✝ : Type u
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
x✝ : ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
⊢ ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map (f✝ ≫ g✝)) x✝ =
    ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map f✝ ≫
          { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map g✝)
      x✝
[PROOFSTEP]
rw [← FreeGroup.map.unique]
[GOAL]
case w.hg
X✝ Y✝ Z✝ : Type u
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
x✝ : ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
⊢ ∀ (x : X✝),
    ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map f✝ ≫
            { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map g✝)
        (FreeGroup.of x) =
      FreeGroup.of ((f✝ ≫ g✝) x)
[PROOFSTEP]
intros
[GOAL]
case w.hg
X✝ Y✝ Z✝ : Type u
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
x✝¹ : ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.obj X✝)
x✝ : X✝
⊢ ↑({ obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map f✝ ≫
          { obj := fun α => of (FreeGroup α), map := fun {X Y} => FreeGroup.map }.map g✝)
      (FreeGroup.of x✝) =
    FreeGroup.of ((f✝ ≫ g✝) x✝)
[PROOFSTEP]
rfl
[GOAL]
⊢ ∀ {X' X : Type u} {Y : GroupCat} (f : X' ⟶ X) (g : X ⟶ (forget GroupCat).obj Y),
    ↑((fun X G => FreeGroup.lift.symm) X' Y).symm (f ≫ g) = free.map f ≫ ↑((fun X G => FreeGroup.lift.symm) X Y).symm g
[PROOFSTEP]
intros
[GOAL]
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
⊢ ↑((fun X G => FreeGroup.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝) =
    free.map f✝ ≫ ↑((fun X G => FreeGroup.lift.symm) X✝ Y✝).symm g✝
[PROOFSTEP]
ext1
[GOAL]
case w
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ↑(↑((fun X G => FreeGroup.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝)) x✝ =
    ↑(free.map f✝ ≫ ↑((fun X G => FreeGroup.lift.symm) X✝ Y✝).symm g✝) x✝
[PROOFSTEP]
simp only [Equiv.symm_symm]
[GOAL]
case w
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ↑(↑FreeGroup.lift (f✝ ≫ g✝)) x✝ = ↑(free.map f✝ ≫ ↑FreeGroup.lift g✝) x✝
[PROOFSTEP]
apply Eq.symm
[GOAL]
case w.h
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ↑(free.map f✝ ≫ ↑FreeGroup.lift g✝) x✝ = ↑(↑FreeGroup.lift (f✝ ≫ g✝)) x✝
[PROOFSTEP]
apply FreeGroup.lift.unique
[GOAL]
case w.h.hg
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝ : ↑(free.obj X'✝)
⊢ ∀ (x : X'✝), ↑(free.map f✝ ≫ ↑FreeGroup.lift g✝) (FreeGroup.of x) = (f✝ ≫ g✝) x
[PROOFSTEP]
intros
[GOAL]
case w.h.hg
X'✝ X✝ : Type u
Y✝ : GroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget GroupCat).obj Y✝
x✝¹ : ↑(free.obj X'✝)
x✝ : X'✝
⊢ ↑(free.map f✝ ≫ ↑FreeGroup.lift g✝) (FreeGroup.of x✝) = (f✝ ≫ g✝) x✝
[PROOFSTEP]
apply FreeGroup.lift.of
[GOAL]
G : GroupCat
⊢ CommGroup (Abelianization ↑G)
[PROOFSTEP]
infer_instance
[GOAL]
X✝ Y✝ : GroupCat
f : X✝ ⟶ Y✝
⊢ (fun x => ↑Abelianization.of (↑f x)) 1 = 1
[PROOFSTEP]
simp
[GOAL]
X✝ Y✝ : GroupCat
f : X✝ ⟶ Y✝
⊢ ∀ (x y : ↑X✝),
    OneHom.toFun { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) }
        (x * y) =
      OneHom.toFun { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) } x *
        OneHom.toFun { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) } y
[PROOFSTEP]
simp
[GOAL]
⊢ ∀ (X : GroupCat),
    { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              ↑Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        ↑Abelianization.of (↑f (a * a_1)) =
                          ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
        (𝟙 X) =
      𝟙
        ({ obj := fun G => Bundled.mk (Abelianization ↑G),
              map := fun {X Y} f =>
                ↑Abelianization.lift
                  {
                    toOneHom :=
                      { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                    map_mul' :=
                      (_ :
                        ∀ (a a_1 : ↑X),
                          ↑Abelianization.of (↑f (a * a_1)) =
                            ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.obj
          X)
[PROOFSTEP]
intros
[GOAL]
X✝ : GroupCat
⊢ { obj := fun G => Bundled.mk (Abelianization ↑G),
          map := fun {X Y} f =>
            ↑Abelianization.lift
              {
                toOneHom :=
                  { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                map_mul' :=
                  (_ :
                    ∀ (a a_1 : ↑X),
                      ↑Abelianization.of (↑f (a * a_1)) =
                        ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
      (𝟙 X✝) =
    𝟙
      ({ obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              ↑Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        ↑Abelianization.of (↑f (a * a_1)) =
                          ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.obj
        X✝)
[PROOFSTEP]
simp only [MonoidHom.mk_coe, coe_id]
[GOAL]
X✝ : GroupCat
⊢ ↑Abelianization.lift
      {
        toOneHom :=
          { toFun := fun x => ↑Abelianization.of (↑(𝟙 X✝) x), map_one' := (_ : ↑Abelianization.of (↑(𝟙 X✝) 1) = 1) },
        map_mul' :=
          (_ :
            ∀ (a a_1 : ↑X✝),
              ↑Abelianization.of (↑(𝟙 X✝) (a * a_1)) =
                ↑Abelianization.of (↑(𝟙 X✝) a) * ↑Abelianization.of (↑(𝟙 X✝) a_1)) } =
    𝟙 (Bundled.mk (Abelianization ↑X✝))
[PROOFSTEP]
apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr
[GOAL]
X✝ : GroupCat
⊢ {
      toOneHom :=
        { toFun := fun x => ↑Abelianization.of (↑(𝟙 X✝) x), map_one' := (_ : ↑Abelianization.of (↑(𝟙 X✝) 1) = 1) },
      map_mul' :=
        (_ :
          ∀ (a a_1 : ↑X✝),
            ↑Abelianization.of (↑(𝟙 X✝) (a * a_1)) =
              ↑Abelianization.of (↑(𝟙 X✝) a) * ↑Abelianization.of (↑(𝟙 X✝) a_1)) } =
    ↑Abelianization.lift.symm (𝟙 (Bundled.mk (Abelianization ↑X✝)))
[PROOFSTEP]
rfl
[GOAL]
⊢ ∀ {X Y Z : GroupCat} (f : X ⟶ Y) (g : Y ⟶ Z),
    { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              ↑Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        ↑Abelianization.of (↑f (a * a_1)) =
                          ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
        (f ≫ g) =
      { obj := fun G => Bundled.mk (Abelianization ↑G),
              map := fun {X Y} f =>
                ↑Abelianization.lift
                  {
                    toOneHom :=
                      { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                    map_mul' :=
                      (_ :
                        ∀ (a a_1 : ↑X),
                          ↑Abelianization.of (↑f (a * a_1)) =
                            ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
          f ≫
        { obj := fun G => Bundled.mk (Abelianization ↑G),
              map := fun {X Y} f =>
                ↑Abelianization.lift
                  {
                    toOneHom :=
                      { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                    map_mul' :=
                      (_ :
                        ∀ (a a_1 : ↑X),
                          ↑Abelianization.of (↑f (a * a_1)) =
                            ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
          g
[PROOFSTEP]
intros
[GOAL]
X✝ Y✝ Z✝ : GroupCat
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ { obj := fun G => Bundled.mk (Abelianization ↑G),
          map := fun {X Y} f =>
            ↑Abelianization.lift
              {
                toOneHom :=
                  { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                map_mul' :=
                  (_ :
                    ∀ (a a_1 : ↑X),
                      ↑Abelianization.of (↑f (a * a_1)) =
                        ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
      (f✝ ≫ g✝) =
    { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              ↑Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        ↑Abelianization.of (↑f (a * a_1)) =
                          ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
        f✝ ≫
      { obj := fun G => Bundled.mk (Abelianization ↑G),
            map := fun {X Y} f =>
              ↑Abelianization.lift
                {
                  toOneHom :=
                    { toFun := fun x => ↑Abelianization.of (↑f x), map_one' := (_ : ↑Abelianization.of (↑f 1) = 1) },
                  map_mul' :=
                    (_ :
                      ∀ (a a_1 : ↑X),
                        ↑Abelianization.of (↑f (a * a_1)) =
                          ↑Abelianization.of (↑f a) * ↑Abelianization.of (↑f a_1)) } }.map
        g✝
[PROOFSTEP]
simp only [coe_comp]
[GOAL]
X✝ Y✝ Z✝ : GroupCat
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ ↑Abelianization.lift
      {
        toOneHom :=
          { toFun := fun x => ↑Abelianization.of (↑(f✝ ≫ g✝) x),
            map_one' := (_ : ↑Abelianization.of (↑(f✝ ≫ g✝) 1) = 1) },
        map_mul' :=
          (_ :
            ∀ (a a_1 : ↑X✝),
              ↑Abelianization.of (↑(f✝ ≫ g✝) (a * a_1)) =
                ↑Abelianization.of (↑(f✝ ≫ g✝) a) * ↑Abelianization.of (↑(f✝ ≫ g✝) a_1)) } =
    ↑Abelianization.lift
        {
          toOneHom :=
            { toFun := fun x => ↑Abelianization.of (↑f✝ x), map_one' := (_ : ↑Abelianization.of (↑f✝ 1) = 1) },
          map_mul' :=
            (_ :
              ∀ (a a_1 : ↑X✝),
                ↑Abelianization.of (↑f✝ (a * a_1)) = ↑Abelianization.of (↑f✝ a) * ↑Abelianization.of (↑f✝ a_1)) } ≫
      ↑Abelianization.lift
        {
          toOneHom :=
            { toFun := fun x => ↑Abelianization.of (↑g✝ x), map_one' := (_ : ↑Abelianization.of (↑g✝ 1) = 1) },
          map_mul' :=
            (_ :
              ∀ (a a_1 : ↑Y✝),
                ↑Abelianization.of (↑g✝ (a * a_1)) = ↑Abelianization.of (↑g✝ a) * ↑Abelianization.of (↑g✝ a_1)) }
[PROOFSTEP]
apply (Equiv.apply_eq_iff_eq_symm_apply Abelianization.lift).mpr
[GOAL]
X✝ Y✝ Z✝ : GroupCat
f✝ : X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Z✝
⊢ {
      toOneHom :=
        { toFun := fun x => ↑Abelianization.of (↑(f✝ ≫ g✝) x),
          map_one' := (_ : ↑Abelianization.of (↑(f✝ ≫ g✝) 1) = 1) },
      map_mul' :=
        (_ :
          ∀ (a a_1 : ↑X✝),
            ↑Abelianization.of (↑(f✝ ≫ g✝) (a * a_1)) =
              ↑Abelianization.of (↑(f✝ ≫ g✝) a) * ↑Abelianization.of (↑(f✝ ≫ g✝) a_1)) } =
    ↑Abelianization.lift.symm
      (↑Abelianization.lift
          {
            toOneHom :=
              { toFun := fun x => ↑Abelianization.of (↑f✝ x), map_one' := (_ : ↑Abelianization.of (↑f✝ 1) = 1) },
            map_mul' :=
              (_ :
                ∀ (a a_1 : ↑X✝),
                  ↑Abelianization.of (↑f✝ (a * a_1)) = ↑Abelianization.of (↑f✝ a) * ↑Abelianization.of (↑f✝ a_1)) } ≫
        ↑Abelianization.lift
          {
            toOneHom :=
              { toFun := fun x => ↑Abelianization.of (↑g✝ x), map_one' := (_ : ↑Abelianization.of (↑g✝ 1) = 1) },
            map_mul' :=
              (_ :
                ∀ (a a_1 : ↑Y✝),
                  ↑Abelianization.of (↑g✝ (a * a_1)) = ↑Abelianization.of (↑g✝ a) * ↑Abelianization.of (↑g✝ a_1)) })
[PROOFSTEP]
rfl
[GOAL]
⊢ ∀ {X' X : GroupCat} {Y : CommGroupCat} (f : X' ⟶ X) (g : X ⟶ (forget₂ CommGroupCat GroupCat).obj Y),
    ↑((fun G A => Abelianization.lift.symm) X' Y).symm (f ≫ g) =
      abelianize.map f ≫ ↑((fun G A => Abelianization.lift.symm) X Y).symm g
[PROOFSTEP]
intros
[GOAL]
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
⊢ ↑((fun G A => Abelianization.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝) =
    abelianize.map f✝ ≫ ↑((fun G A => Abelianization.lift.symm) X✝ Y✝).symm g✝
[PROOFSTEP]
ext1
[GOAL]
case w
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ ↑(↑((fun G A => Abelianization.lift.symm) X'✝ Y✝).symm (f✝ ≫ g✝)) x✝ =
    ↑(abelianize.map f✝ ≫ ↑((fun G A => Abelianization.lift.symm) X✝ Y✝).symm g✝) x✝
[PROOFSTEP]
simp only [Equiv.symm_symm]
[GOAL]
case w
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ ↑(↑Abelianization.lift (f✝ ≫ g✝)) x✝ = ↑(abelianize.map f✝ ≫ ↑Abelianization.lift g✝) x✝
[PROOFSTEP]
apply Eq.symm
[GOAL]
case w.h
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ ↑(abelianize.map f✝ ≫ ↑Abelianization.lift g✝) x✝ = ↑(↑Abelianization.lift (f✝ ≫ g✝)) x✝
[PROOFSTEP]
apply Abelianization.lift.unique
[GOAL]
case w.h.hφ
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝ : ↑(abelianize.obj X'✝)
⊢ ∀ (x : ↑X'✝), ↑(abelianize.map f✝ ≫ ↑Abelianization.lift g✝) (↑Abelianization.of x) = ↑(f✝ ≫ g✝) x
[PROOFSTEP]
intros
[GOAL]
case w.h.hφ
X'✝ X✝ : GroupCat
Y✝ : CommGroupCat
f✝ : X'✝ ⟶ X✝
g✝ : X✝ ⟶ (forget₂ CommGroupCat GroupCat).obj Y✝
x✝¹ : ↑(abelianize.obj X'✝)
x✝ : ↑X'✝
⊢ ↑(abelianize.map f✝ ≫ ↑Abelianization.lift g✝) (↑Abelianization.of x✝) = ↑(f✝ ≫ g✝) x✝
[PROOFSTEP]
apply Abelianization.lift.of
[GOAL]
⊢ ∀ ⦃X Y : MonCat⦄ (f : X ⟶ Y),
    (MonCat.units ⋙ forget₂ GroupCat MonCat).map f ≫ (fun X => Units.coeHom ↑X) Y =
      (fun X => Units.coeHom ↑X) X ≫ (𝟭 MonCat).map f
[PROOFSTEP]
intros
[GOAL]
X✝ Y✝ : MonCat
f✝ : X✝ ⟶ Y✝
⊢ (MonCat.units ⋙ forget₂ GroupCat MonCat).map f✝ ≫ (fun X => Units.coeHom ↑X) Y✝ =
    (fun X => Units.coeHom ↑X) X✝ ≫ (𝟭 MonCat).map f✝
[PROOFSTEP]
exact MonoidHom.ext fun x => rfl
[GOAL]
⊢ ∀ ⦃X Y : CommMonCat⦄ (f : X ⟶ Y),
    (CommMonCat.units ⋙ forget₂ CommGroupCat CommMonCat).map f ≫ (fun X => Units.coeHom ↑X) Y =
      (fun X => Units.coeHom ↑X) X ≫ (𝟭 CommMonCat).map f
[PROOFSTEP]
intros
[GOAL]
X✝ Y✝ : CommMonCat
f✝ : X✝ ⟶ Y✝
⊢ (CommMonCat.units ⋙ forget₂ CommGroupCat CommMonCat).map f✝ ≫ (fun X => Units.coeHom ↑X) Y✝ =
    (fun X => Units.coeHom ↑X) X✝ ≫ (𝟭 CommMonCat).map f✝
[PROOFSTEP]
exact MonoidHom.ext fun x => rfl


[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
⊢ Injective toAffineMap
[PROOFSTEP]
rintro ⟨e, el, h⟩ ⟨e', el', h'⟩ H
[GOAL]
case mk.mk
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), ↑e (v +ᵥ p) = ↑el v +ᵥ ↑e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), ↑e' (v +ᵥ p) = ↑el' v +ᵥ ↑e' p
H : ↑{ toEquiv := e, linear := el, map_vadd' := h } = ↑{ toEquiv := e', linear := el', map_vadd' := h' }
⊢ { toEquiv := e, linear := el, map_vadd' := h } = { toEquiv := e', linear := el', map_vadd' := h' }
[PROOFSTEP]
simp only [(toAffineMap_mk), (AffineMap.mk.injEq), Equiv.coe_inj, LinearEquiv.toLinearMap_inj] at H
[GOAL]
case mk.mk
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), ↑e (v +ᵥ p) = ↑el v +ᵥ ↑e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), ↑e' (v +ᵥ p) = ↑el' v +ᵥ ↑e' p
H : e = e' ∧ el = el'
⊢ { toEquiv := e, linear := el, map_vadd' := h } = { toEquiv := e', linear := el', map_vadd' := h' }
[PROOFSTEP]
congr
[GOAL]
case mk.mk.e_toEquiv
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), ↑e (v +ᵥ p) = ↑el v +ᵥ ↑e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), ↑e' (v +ᵥ p) = ↑el' v +ᵥ ↑e' p
H : e = e' ∧ el = el'
⊢ e = e'
case mk.mk.e_linear
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ P₂
el : V₁ ≃ₗ[k] V₂
h : ∀ (p : P₁) (v : V₁), ↑e (v +ᵥ p) = ↑el v +ᵥ ↑e p
e' : P₁ ≃ P₂
el' : V₁ ≃ₗ[k] V₂
h' : ∀ (p : P₁) (v : V₁), ↑e' (v +ᵥ p) = ↑el' v +ᵥ ↑e' p
H : e = e' ∧ el = el'
⊢ el = el'
[PROOFSTEP]
exacts [H.1, H.2]
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ → P₂
e' : V₁ ≃ₗ[k] V₂
p : P₁
h : ∀ (p' : P₁), e p' = ↑e' (p' -ᵥ p) +ᵥ e p
p' : P₁
⊢ (fun q' => ↑(LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p) (e p') = p'
[PROOFSTEP]
simp [h p', (vadd_vsub), (vsub_vadd)]
  -- Porting note: `simp` needs `()`
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ → P₂
e' : V₁ ≃ₗ[k] V₂
p : P₁
h : ∀ (p' : P₁), e p' = ↑e' (p' -ᵥ p) +ᵥ e p
q' : P₂
⊢ e ((fun q' => ↑(LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p) q') = q'
[PROOFSTEP]
simp [h (e'.symm (q' -ᵥ e p) +ᵥ p), (vadd_vsub), (vsub_vadd)]
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ → P₂
e' : V₁ ≃ₗ[k] V₂
p : P₁
h : ∀ (p' : P₁), e p' = ↑e' (p' -ᵥ p) +ᵥ e p
p' : P₁
v : V₁
⊢ ↑{ toFun := e, invFun := fun q' => ↑(LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p,
          left_inv := (_ : ∀ (p' : P₁), ↑(LinearEquiv.symm e') (e p' -ᵥ e p) +ᵥ p = p'),
          right_inv := (_ : ∀ (q' : P₂), e (↑(LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p) = q') }
      (v +ᵥ p') =
    ↑e' v +ᵥ
      ↑{ toFun := e, invFun := fun q' => ↑(LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p,
            left_inv := (_ : ∀ (p' : P₁), ↑(LinearEquiv.symm e') (e p' -ᵥ e p) +ᵥ p = p'),
            right_inv := (_ : ∀ (q' : P₂), e (↑(LinearEquiv.symm e') (q' -ᵥ e p) +ᵥ p) = q') }
        p'
[PROOFSTEP]
simp [h p', h (v +ᵥ p'), (vadd_vsub_assoc), (vadd_vadd)]
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ᵃ[k] P₂
p : P₂
v : V₂
⊢ v +ᵥ p = ↑e.symm.symm (↑(LinearEquiv.symm e.linear) v +ᵥ ↑e.symm p)
[PROOFSTEP]
rw [Equiv.symm_symm, e.map_vadd' ((Equiv.symm e.toEquiv) p) ((LinearEquiv.symm e.linear) v),
  LinearEquiv.apply_symm_apply, Equiv.apply_symm_apply]
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
e : P₁ ≃ᵃ[k] P₂
e' : P₂ ≃ᵃ[k] P₃
p : P₁
v : V₁
⊢ ↑(e.trans e'.toEquiv) (v +ᵥ p) = ↑(LinearEquiv.trans e.linear e'.linear) v +ᵥ ↑(e.trans e'.toEquiv) p
[PROOFSTEP]
simp only [LinearEquiv.trans_apply, (coe_toEquiv), (· ∘ ·), Equiv.coe_trans, (map_vadd)]
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹² : Ring k
inst✝¹¹ : AddCommGroup V₁
inst✝¹⁰ : Module k V₁
inst✝⁹ : AffineSpace V₁ P₁
inst✝⁸ : AddCommGroup V₂
inst✝⁷ : Module k V₂
inst✝⁶ : AffineSpace V₂ P₂
inst✝⁵ : AddCommGroup V₃
inst✝⁴ : Module k V₃
inst✝³ : AffineSpace V₃ P₃
inst✝² : AddCommGroup V₄
inst✝¹ : Module k V₄
inst✝ : AffineSpace V₄ P₄
p p' : P₁
v : V₁
⊢ ↑(Equiv.constVSub p) (v +ᵥ p') = ↑(LinearEquiv.neg k) v +ᵥ ↑(Equiv.constVSub p) p'
[PROOFSTEP]
simp [(Equiv.coe_constVSub), (vsub_vadd_eq_vsub_sub), neg_add_eq_sub]
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹³ : Ring k
inst✝¹² : AddCommGroup V₁
inst✝¹¹ : Module k V₁
inst✝¹⁰ : AffineSpace V₁ P₁
inst✝⁹ : AddCommGroup V₂
inst✝⁸ : Module k V₂
inst✝⁷ : AffineSpace V₂ P₂
inst✝⁶ : AddCommGroup V₃
inst✝⁵ : Module k V₃
inst✝⁴ : AffineSpace V₃ P₃
inst✝³ : AddCommGroup V₄
inst✝² : Module k V₄
inst✝¹ : AffineSpace V₄ P₄
inst✝ : Invertible 2
x y : V₁
h : bit0 x = bit0 y
⊢ x = y
[PROOFSTEP]
rwa [bit0, bit0, ← two_smul k x, ← two_smul k y, (isUnit_of_invertible (2 : k)).smul_left_cancel] at h
[GOAL]
k : Type u_1
P₁ : Type u_2
P₂ : Type u_3
P₃ : Type u_4
P₄ : Type u_5
V₁ : Type u_6
V₂ : Type u_7
V₃ : Type u_8
V₄ : Type u_9
inst✝¹⁴ : Ring k
inst✝¹³ : AddCommGroup V₁
inst✝¹² : Module k V₁
inst✝¹¹ : AffineSpace V₁ P₁
inst✝¹⁰ : AddCommGroup V₂
inst✝⁹ : Module k V₂
inst✝⁸ : AffineSpace V₂ P₂
inst✝⁷ : AddCommGroup V₃
inst✝⁶ : Module k V₃
inst✝⁵ : AffineSpace V₃ P₃
inst✝⁴ : AddCommGroup V₄
inst✝³ : Module k V₄
inst✝² : AffineSpace V₄ P₄
R' : Type u_10
inst✝¹ : CommRing R'
inst✝ : Module R' V₁
c p : P₁
⊢ ↑(homothety c (-1)) p = ↑(pointReflection R' c) p
[PROOFSTEP]
simp [(homothety_apply), pointReflection_apply _, (neg_vsub_eq_vsub_rev)]


[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
⊢ Finset.Nonempty (Finset.sigma s t) ↔ ∃ i, i ∈ s ∧ Finset.Nonempty (t i)
[PROOFSTEP]
simp [Finset.Nonempty]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
⊢ Finset.sigma s t = ∅ ↔ ∀ (i : ι), i ∈ s → t i = ∅
[PROOFSTEP]
simp only [← not_nonempty_iff_eq_empty, sigma_nonempty, not_exists, not_and]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
⊢ Set.PairwiseDisjoint ↑s fun i => map (Embedding.sigmaMk i) (t i)
[PROOFSTEP]
intro i _ j _ hij
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
⊢ (_root_.Disjoint on fun i => map (Embedding.sigmaMk i) (t i)) i j
[PROOFSTEP]
rw [Function.onFun, disjoint_left]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
⊢ ∀ ⦃a : (x : ι) × α x⦄, a ∈ map (Embedding.sigmaMk i) (t i) → ¬a ∈ map (Embedding.sigmaMk j) (t j)
[PROOFSTEP]
simp_rw [mem_map, Function.Embedding.sigmaMk_apply]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
⊢ ∀ ⦃a : (x : ι) × α x⦄,
    (∃ a_1, a_1 ∈ t i ∧ { fst := i, snd := a_1 } = a) → ¬∃ a_2, a_2 ∈ t j ∧ { fst := j, snd := a_2 } = a
[PROOFSTEP]
rintro _ ⟨y, _, rfl⟩ ⟨z, _, hz'⟩
[GOAL]
case intro.intro.intro.intro
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
i : ι
a✝¹ : i ∈ ↑s
j : ι
a✝ : j ∈ ↑s
hij : i ≠ j
y : α i
left✝¹ : y ∈ t i
z : α j
left✝ : z ∈ t j
hz' : { fst := j, snd := z } = { fst := i, snd := y }
⊢ False
[PROOFSTEP]
exact hij (congr_arg Sigma.fst hz'.symm)
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s✝ s₁ s₂ : Finset ι
t✝ t₁ t₂ : (i : ι) → Finset (α i)
inst✝ : DecidableEq ((i : ι) × α i)
s : Finset ι
t : (i : ι) → Finset (α i)
⊢ Finset.sigma s t = Finset.biUnion s fun i => map (Embedding.sigmaMk i) (t i)
[PROOFSTEP]
ext ⟨x, y⟩
[GOAL]
case a.mk
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s✝ s₁ s₂ : Finset ι
t✝ t₁ t₂ : (i : ι) → Finset (α i)
inst✝ : DecidableEq ((i : ι) × α i)
s : Finset ι
t : (i : ι) → Finset (α i)
x : ι
y : α x
⊢ { fst := x, snd := y } ∈ Finset.sigma s t ↔
    { fst := x, snd := y } ∈ Finset.biUnion s fun i => map (Embedding.sigmaMk i) (t i)
[PROOFSTEP]
simp [and_left_comm]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
f : (i : ι) × α i → β
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
⊢ sup (Finset.sigma s t) f = sup s fun i => sup (t i) fun b => f { fst := i, snd := b }
[PROOFSTEP]
simp only [le_antisymm_iff, Finset.sup_le_iff, mem_sigma, and_imp, Sigma.forall]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : Type u_3
s s₁ s₂ : Finset ι
t t₁ t₂ : (i : ι) → Finset (α i)
f : (i : ι) × α i → β
inst✝¹ : SemilatticeSup β
inst✝ : OrderBot β
⊢ (∀ (a : ι) (b : α a),
      a ∈ s → b ∈ t a → f { fst := a, snd := b } ≤ sup s fun i => sup (t i) fun b => f { fst := i, snd := b }) ∧
    ∀ (b : ι), b ∈ s → ∀ (b_1 : α b), b_1 ∈ t b → f { fst := b, snd := b_1 } ≤ sup (Finset.sigma s t) f
[PROOFSTEP]
exact
  ⟨fun i a hi ha => (le_sup hi).trans' <| le_sup (f := fun a => f ⟨i, a⟩) ha, fun i hi a ha =>
    le_sup <| mem_sigma.2 ⟨hi, ha⟩⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : Sigma α
b : Sigma β
x : Sigma γ
⊢ x ∈ sigmaLift f a b ↔ ∃ ha hb, x.snd ∈ f (ha ▸ a.snd) (hb ▸ b.snd)
[PROOFSTEP]
obtain ⟨⟨i, a⟩, j, b⟩ := a, b
[GOAL]
case mk.mk
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := j, snd := b } ↔
    ∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)
[PROOFSTEP]
obtain rfl | h := Decidable.eq_or_ne i j
[GOAL]
case mk.mk.inl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b } ↔
    ∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := i, snd := b }.snd)
[PROOFSTEP]
constructor
[GOAL]
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b } →
    ∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := i, snd := b }.snd)
[PROOFSTEP]
simp_rw [sigmaLift]
[GOAL]
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ (x ∈ if h : True then map (Embedding.sigmaMk i) (f a b) else ∅) →
    ∃ h h_1, x.snd ∈ f ((_ : { fst := i, snd := a }.fst = x.fst) ▸ a) ((_ : { fst := i, snd := b }.fst = x.fst) ▸ b)
[PROOFSTEP]
simp only [dite_eq_ite, ite_true, mem_map, Embedding.sigmaMk_apply, forall_exists_index, and_imp]
[GOAL]
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ ∀ (x_1 : γ i),
    x_1 ∈ f a b →
      { fst := i, snd := x_1 } = x →
        ∃ h h_1, x.snd ∈ f ((_ : { fst := i, snd := a }.fst = x.fst) ▸ a) ((_ : { fst := i, snd := b }.fst = x.fst) ▸ b)
[PROOFSTEP]
rintro x hx rfl
[GOAL]
case mk.mk.inl.mp
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
i : ι
a : α i
b : β i
x : γ i
hx : x ∈ f a b
⊢ ∃ h h_1,
    { fst := i, snd := x }.snd ∈
      f ((_ : { fst := i, snd := a }.fst = { fst := i, snd := x }.fst) ▸ a)
        ((_ : { fst := i, snd := b }.fst = { fst := i, snd := x }.fst) ▸ b)
[PROOFSTEP]
exact ⟨rfl, rfl, hx⟩
[GOAL]
case mk.mk.inl.mpr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
b : β i
⊢ (∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := i, snd := b }.snd)) →
    x ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b }
[PROOFSTEP]
rintro ⟨⟨⟩, ⟨⟩, hx⟩
[GOAL]
case mk.mk.inl.mpr.intro.refl.intro.refl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
hx :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ x ∈ sigmaLift f { fst := x.1, snd := a } { fst := x.1, snd := b }
[PROOFSTEP]
rw [sigmaLift, dif_pos rfl, mem_map]
[GOAL]
case mk.mk.inl.mpr.intro.refl.intro.refl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
hx :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ ∃ a_1,
    a_1 ∈
        f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
          { fst := x.1, snd := b }.snd ∧
      ↑(Embedding.sigmaMk { fst := x.1, snd := b }.fst) a_1 = x
[PROOFSTEP]
exact ⟨_, hx, by simp [Sigma.ext_iff]⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
hx :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ ↑(Embedding.sigmaMk { fst := x.1, snd := b }.fst) x.snd = x
[PROOFSTEP]
simp [Sigma.ext_iff]
[GOAL]
case mk.mk.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
h : i ≠ j
⊢ x ∈ sigmaLift f { fst := i, snd := a } { fst := j, snd := b } ↔
    ∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)
[PROOFSTEP]
rw [sigmaLift, dif_neg h]
[GOAL]
case mk.mk.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
h : i ≠ j
⊢ x ∈ ∅ ↔ ∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)
[PROOFSTEP]
refine' iff_of_false (not_mem_empty _) _
[GOAL]
case mk.mk.inr
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
i : ι
a : α i
j : ι
b : β j
h : i ≠ j
⊢ ¬∃ ha hb, x.snd ∈ f (ha ▸ { fst := i, snd := a }.snd) (hb ▸ { fst := j, snd := b }.snd)
[PROOFSTEP]
rintro ⟨⟨⟩, ⟨⟩, _⟩
[GOAL]
case mk.mk.inr.intro.refl.intro.refl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
x : Sigma γ
a : α x.1
b : β x.1
h : x.1 ≠ x.1
h✝ :
  x.snd ∈
    f ((_ : { fst := x.1, snd := a }.fst = { fst := x.1, snd := a }.fst) ▸ { fst := x.1, snd := a }.snd)
      ((_ : { fst := x.1, snd := b }.fst = { fst := x.1, snd := b }.fst) ▸ { fst := x.1, snd := b }.snd)
⊢ False
[PROOFSTEP]
exact h rfl
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
i : ι
a : α i
b : β i
x : γ i
⊢ { fst := i, snd := x } ∈ sigmaLift f { fst := i, snd := a } { fst := i, snd := b } ↔ x ∈ f a b
[PROOFSTEP]
rw [sigmaLift, dif_pos rfl, mem_map]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
i : ι
a : α i
b : β i
x : γ i
⊢ (∃ a_1,
      a_1 ∈
          f ((_ : { fst := i, snd := a }.fst = { fst := i, snd := a }.fst) ▸ { fst := i, snd := a }.snd)
            { fst := i, snd := b }.snd ∧
        ↑(Embedding.sigmaMk { fst := i, snd := b }.fst) a_1 = { fst := i, snd := x }) ↔
    x ∈ f a b
[PROOFSTEP]
refine' ⟨_, fun hx => ⟨_, hx, rfl⟩⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
i : ι
a : α i
b : β i
x : γ i
⊢ (∃ a_1,
      a_1 ∈
          f ((_ : { fst := i, snd := a }.fst = { fst := i, snd := a }.fst) ▸ { fst := i, snd := a }.snd)
            { fst := i, snd := b }.snd ∧
        ↑(Embedding.sigmaMk { fst := i, snd := b }.fst) a_1 = { fst := i, snd := x }) →
    x ∈ f a b
[PROOFSTEP]
rintro ⟨x, hx, _, rfl⟩
[GOAL]
case intro.intro.refl
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
i : ι
a : α i
b : β i
x : γ i
hx :
  x ∈
    f ((_ : { fst := i, snd := a }.fst = { fst := i, snd := a }.fst) ▸ { fst := i, snd := a }.snd)
      { fst := i, snd := b }.snd
⊢ x ∈ f a b
[PROOFSTEP]
exact hx
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : Sigma α
b : Sigma β
x : Sigma γ
h : a.fst ≠ x.fst
⊢ ¬x ∈ sigmaLift f a b
[PROOFSTEP]
rw [mem_sigmaLift]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : Sigma α
b : Sigma β
x : Sigma γ
h : a.fst ≠ x.fst
⊢ ¬∃ ha hb, x.snd ∈ f (ha ▸ a.snd) (hb ▸ b.snd)
[PROOFSTEP]
exact fun H => h H.fst
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : Sigma α
b : Sigma β
x : Sigma γ
h : b.fst ≠ x.fst
⊢ ¬x ∈ sigmaLift f a b
[PROOFSTEP]
rw [mem_sigmaLift]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : Sigma α
b : Sigma β
x : Sigma γ
h : b.fst ≠ x.fst
⊢ ¬∃ ha hb, x.snd ∈ f (ha ▸ a.snd) (hb ▸ b.snd)
[PROOFSTEP]
exact fun H => h H.snd.fst
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
⊢ Finset.Nonempty (sigmaLift f a b) ↔ ∃ h, Finset.Nonempty (f (h ▸ a.snd) b.snd)
[PROOFSTEP]
simp_rw [nonempty_iff_ne_empty, sigmaLift]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
⊢ (if h : a.fst = b.fst then map (Embedding.sigmaMk b.fst) (f (h ▸ a.snd) b.snd) else ∅) ≠ ∅ ↔
    ∃ h, f ((_ : a.fst = b.fst) ▸ a.snd) b.snd ≠ ∅
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
h : a.fst = b.fst
⊢ map (Embedding.sigmaMk b.fst) (f (h ▸ a.snd) b.snd) ≠ ∅ ↔ ∃ h, f ((_ : a.fst = b.fst) ▸ a.snd) b.snd ≠ ∅
[PROOFSTEP]
simp [h]
[GOAL]
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
h : ¬a.fst = b.fst
⊢ ∅ ≠ ∅ ↔ ∃ h, f ((_ : a.fst = b.fst) ▸ a.snd) b.snd ≠ ∅
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
⊢ sigmaLift f a b = ∅ ↔ ∀ (h : a.fst = b.fst), f (h ▸ a.snd) b.snd = ∅
[PROOFSTEP]
simp_rw [sigmaLift]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
⊢ (if h : a.fst = b.fst then map (Embedding.sigmaMk b.fst) (f (h ▸ a.snd) b.snd) else ∅) = ∅ ↔
    ∀ (h : a.fst = b.fst), f (h ▸ a.snd) b.snd = ∅
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
h : a.fst = b.fst
⊢ map (Embedding.sigmaMk b.fst) (f (h ▸ a.snd) b.snd) = ∅ ↔ ∀ (h : a.fst = b.fst), f (h ▸ a.snd) b.snd = ∅
[PROOFSTEP]
simp [h, forall_prop_of_true h]
[GOAL]
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
h : ¬a.fst = b.fst
⊢ ∅ = ∅ ↔ ∀ (h : a.fst = b.fst), f (h ▸ a.snd) b.snd = ∅
[PROOFSTEP]
simp [h, forall_prop_of_false h]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a✝ : (i : ι) × α i
b✝ : (i : ι) × β i
h : ∀ ⦃i : ι⦄ ⦃a : α i⦄ ⦃b : β i⦄, f a b ⊆ g a b
a : (i : ι) × α i
b : (i : ι) × β i
⊢ sigmaLift f a b ⊆ sigmaLift g a b
[PROOFSTEP]
rintro x hx
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a✝ : (i : ι) × α i
b✝ : (i : ι) × β i
h : ∀ ⦃i : ι⦄ ⦃a : α i⦄ ⦃b : β i⦄, f a b ⊆ g a b
a : (i : ι) × α i
b : (i : ι) × β i
x : (i : ι) × γ i
hx : x ∈ sigmaLift f a b
⊢ x ∈ sigmaLift g a b
[PROOFSTEP]
rw [mem_sigmaLift] at hx ⊢
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a✝ : (i : ι) × α i
b✝ : (i : ι) × β i
h : ∀ ⦃i : ι⦄ ⦃a : α i⦄ ⦃b : β i⦄, f a b ⊆ g a b
a : (i : ι) × α i
b : (i : ι) × β i
x : (i : ι) × γ i
hx : ∃ ha hb, x.snd ∈ f (ha ▸ a.snd) (hb ▸ b.snd)
⊢ ∃ ha hb, x.snd ∈ g (ha ▸ a.snd) (hb ▸ b.snd)
[PROOFSTEP]
obtain ⟨ha, hb, hx⟩ := hx
[GOAL]
case intro.intro
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a✝ : (i : ι) × α i
b✝ : (i : ι) × β i
h : ∀ ⦃i : ι⦄ ⦃a : α i⦄ ⦃b : β i⦄, f a b ⊆ g a b
a : (i : ι) × α i
b : (i : ι) × β i
x : (i : ι) × γ i
ha : a.fst = x.fst
hb : b.fst = x.fst
hx : x.snd ∈ f (ha ▸ a.snd) (hb ▸ b.snd)
⊢ ∃ ha hb, x.snd ∈ g (ha ▸ a.snd) (hb ▸ b.snd)
[PROOFSTEP]
exact ⟨ha, hb, h hx⟩
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
⊢ card (sigmaLift f a b) = if h : a.fst = b.fst then card (f (h ▸ a.snd) b.snd) else 0
[PROOFSTEP]
simp_rw [sigmaLift]
[GOAL]
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
⊢ card (if h : a.fst = b.fst then map (Embedding.sigmaMk b.fst) (f (h ▸ a.snd) b.snd) else ∅) =
    if h : a.fst = b.fst then card (f (h ▸ a.snd) b.snd) else 0
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
h : a.fst = b.fst
⊢ card (map (Embedding.sigmaMk b.fst) (f (h ▸ a.snd) b.snd)) = card (f (h ▸ a.snd) b.snd)
[PROOFSTEP]
simp [h]
[GOAL]
case neg
ι : Type u_1
α : ι → Type u_2
β : ι → Type u_3
γ : ι → Type u_4
inst✝ : DecidableEq ι
f g : ⦃i : ι⦄ → α i → β i → Finset (γ i)
a : (i : ι) × α i
b : (i : ι) × β i
h : ¬a.fst = b.fst
⊢ card ∅ = 0
[PROOFSTEP]
simp [h]


[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
g1 g2 : G
p : P
h : g1 +ᵥ p = g2 +ᵥ p
⊢ g1 = g2
[PROOFSTEP]
rw [← vadd_vsub g1 p, h, vadd_vsub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
g : G
p1 p2 : P
⊢ g +ᵥ p1 -ᵥ p2 = g + (p1 -ᵥ p2)
[PROOFSTEP]
apply vadd_right_cancel p2
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
g : G
p1 p2 : P
⊢ g +ᵥ p1 -ᵥ p2 +ᵥ p2 = g + (p1 -ᵥ p2) +ᵥ p2
[PROOFSTEP]
rw [vsub_vadd, add_vadd, vsub_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p : P
⊢ p -ᵥ p = 0
[PROOFSTEP]
rw [← zero_add (p -ᵥ p), ← vadd_vsub_assoc, vadd_vsub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 : P
h : p1 -ᵥ p2 = 0
⊢ p1 = p2
[PROOFSTEP]
rw [← vsub_vadd p1 p2, h, zero_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 p3 : P
⊢ p1 -ᵥ p2 + (p2 -ᵥ p3) = p1 -ᵥ p3
[PROOFSTEP]
apply vadd_right_cancel p3
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 p3 : P
⊢ p1 -ᵥ p2 + (p2 -ᵥ p3) +ᵥ p3 = p1 -ᵥ p3 +ᵥ p3
[PROOFSTEP]
rw [add_vadd, vsub_vadd, vsub_vadd, vsub_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 : P
⊢ -(p1 -ᵥ p2) = p2 -ᵥ p1
[PROOFSTEP]
refine' neg_eq_of_add_eq_zero_right (vadd_right_cancel p1 _)
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 : P
⊢ p1 -ᵥ p2 + (p2 -ᵥ p1) +ᵥ p1 = 0 +ᵥ p1
[PROOFSTEP]
rw [vsub_add_vsub_cancel, vsub_self]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
g : G
p q : P
⊢ g +ᵥ p -ᵥ q = g - (q -ᵥ p)
[PROOFSTEP]
rw [vadd_vsub_assoc, sub_eq_add_neg, neg_vsub_eq_vsub_rev]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 : P
g : G
⊢ p1 -ᵥ (g +ᵥ p2) = p1 -ᵥ p2 - g
[PROOFSTEP]
rw [← add_right_inj (p2 -ᵥ p1 : G), vsub_add_vsub_cancel, ← neg_vsub_eq_vsub_rev, vadd_vsub, ← add_sub_assoc, ←
  neg_vsub_eq_vsub_rev, neg_add_self, zero_sub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 p3 : P
⊢ p1 -ᵥ p3 - (p2 -ᵥ p3) = p1 -ᵥ p2
[PROOFSTEP]
rw [← vsub_vadd_eq_vsub_sub, vsub_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
v₁ v₂ : G
p₁ p₂ : P
⊢ v₁ +ᵥ p₁ = v₂ +ᵥ p₂ ↔ -v₁ + v₂ = p₁ -ᵥ p₂
[PROOFSTEP]
rw [eq_vadd_iff_vsub_eq, vadd_vsub_assoc, ← add_right_inj (-v₁), neg_add_cancel_left, eq_comm]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p : P
⊢ {p} -ᵥ {p} = {0}
[PROOFSTEP]
rw [Set.singleton_vsub_singleton, vsub_self]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
v₁ v₂ : G
p : P
⊢ v₁ +ᵥ p -ᵥ (v₂ +ᵥ p) = v₁ - v₂
[PROOFSTEP]
rw [vsub_vadd_eq_vsub_sub, vadd_vsub_assoc, vsub_self, add_zero]
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 p : P
h : p1 -ᵥ p = p2 -ᵥ p
⊢ p1 = p2
[PROOFSTEP]
rwa [← sub_eq_zero, vsub_sub_vsub_cancel_right, vsub_eq_zero_iff_eq] at h
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 p : P
h : p -ᵥ p1 = p -ᵥ p2
⊢ p1 = p2
[PROOFSTEP]
refine' vadd_left_cancel (p -ᵥ p2) _
[GOAL]
G : Type u_1
P : Type u_2
inst✝ : AddGroup G
T : AddTorsor G P
p1 p2 p : P
h : p -ᵥ p1 = p -ᵥ p2
⊢ p -ᵥ p2 +ᵥ p1 = p -ᵥ p2 +ᵥ p2
[PROOFSTEP]
rw [vsub_vadd, ← h, vsub_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
p1 p2 p3 : P
⊢ p3 -ᵥ p2 - (p3 -ᵥ p1) = p1 -ᵥ p2
[PROOFSTEP]
rw [sub_eq_add_neg, neg_vsub_eq_vsub_rev, add_comm, vsub_add_vsub_cancel]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
v : G
p1 p2 : P
⊢ v +ᵥ p1 -ᵥ (v +ᵥ p2) = p1 -ᵥ p2
[PROOFSTEP]
rw [vsub_vadd_eq_vsub_sub, vadd_vsub_assoc, add_sub_cancel']
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
p1 p2 p3 : P
⊢ p1 -ᵥ p2 +ᵥ p3 = p3 -ᵥ p2 +ᵥ p1
[PROOFSTEP]
rw [← @vsub_eq_zero_iff_eq G, vadd_vsub_assoc, vsub_vadd_eq_vsub_sub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
p1 p2 p3 : P
⊢ p1 -ᵥ p2 + (p3 -ᵥ p1 - (p3 -ᵥ p2)) = 0
[PROOFSTEP]
simp
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
v₁ v₂ : G
p₁ p₂ : P
⊢ v₁ +ᵥ p₁ = v₂ +ᵥ p₂ ↔ v₂ - v₁ = p₁ -ᵥ p₂
[PROOFSTEP]
rw [vadd_eq_vadd_iff_neg_add_eq_vsub, neg_add_eq_sub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
p₁ p₂ p₃ p₄ : P
⊢ p₁ -ᵥ p₂ - (p₃ -ᵥ p₄) = p₁ -ᵥ p₃ - (p₂ -ᵥ p₄)
[PROOFSTEP]
rw [← vsub_vadd_eq_vsub_sub, vsub_vadd_comm, vsub_vadd_eq_vsub_sub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
p p' : P
⊢ (fun v => -v +ᵥ p) ((fun x x_1 => x -ᵥ x_1) p p') = p'
[PROOFSTEP]
simp
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
p : P
v : G
⊢ (fun x x_1 => x -ᵥ x_1) p ((fun v => -v +ᵥ p) v) = v
[PROOFSTEP]
simp [vsub_vadd_eq_vsub_sub]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
v : G
p : P
⊢ (fun x x_1 => x +ᵥ x_1) (-v) ((fun x x_1 => x +ᵥ x_1) v p) = p
[PROOFSTEP]
simp [vadd_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
v : G
p : P
⊢ (fun x x_1 => x +ᵥ x_1) v ((fun x x_1 => x +ᵥ x_1) (-v) p) = p
[PROOFSTEP]
simp [vadd_vadd]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
x y : P
⊢ -(x -ᵥ ↑(pointReflection x) y) = -(y -ᵥ x)
[PROOFSTEP]
simp
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
x y : P
⊢ ↑(pointReflection x) y -ᵥ y = 2 • (x -ᵥ y)
[PROOFSTEP]
simp [pointReflection, two_nsmul, vadd_vsub_assoc]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
x y : P
⊢ -(y -ᵥ ↑(pointReflection x) y) = -(2 • (y -ᵥ x))
[PROOFSTEP]
simp [← neg_nsmul]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
x : P
⊢ ∀ (x_1 : P), ↑(pointReflection x).symm x_1 = ↑(pointReflection x) x_1
[PROOFSTEP]
simp [pointReflection]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
x y : P
⊢ ↑(pointReflection x) y = ↑(pointReflection x).symm y
[PROOFSTEP]
rw [pointReflection_symm]
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
x y : P
h : Injective bit0
⊢ ↑(pointReflection x) y = y ↔ y = x
[PROOFSTEP]
rw [pointReflection_apply, eq_comm, eq_vadd_iff_vsub_eq, ← neg_vsub_eq_vsub_rev, neg_eq_iff_add_eq_zero, ← bit0, ←
  bit0_zero, h.eq_iff, vsub_eq_zero_iff_eq, eq_comm]
[GOAL]
G✝ : Type u_1
P✝ : Type u_2
inst✝³ : AddGroup G✝
inst✝² : AddTorsor G✝ P✝
G : Type u_3
P : Type u_4
inst✝¹ : AddCommGroup G
inst✝ : AddTorsor G P
h : Injective bit0
y x₁ x₂ : P
hy : ↑(pointReflection x₁) y = ↑(pointReflection x₂) y
⊢ x₁ = x₂
[PROOFSTEP]
rwa [pointReflection_apply, pointReflection_apply, vadd_eq_vadd_iff_sub_eq_vsub, vsub_sub_vsub_cancel_right, ←
  neg_vsub_eq_vsub_rev, neg_eq_iff_add_eq_zero, ← bit0, ← bit0_zero, h.eq_iff, vsub_eq_zero_iff_eq] at hy
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
⊢ Subsingleton G ↔ Subsingleton P
[PROOFSTEP]
inhabit P
[GOAL]
G : Type u_1
P : Type u_2
inst✝¹ : AddGroup G
inst✝ : AddTorsor G P
inhabited_h : Inhabited P
⊢ Subsingleton G ↔ Subsingleton P
[PROOFSTEP]
exact (Equiv.vaddConst default).subsingleton_congr