[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : R_hat R K
⊢ ZeroHom.toFun { toFun := fun x v => ↑(x v), map_zero' := (_ : (fun x v => ↑(x v)) 0 = (fun x v => ↑(x v)) 0) }
      (x + y) =
    ZeroHom.toFun { toFun := fun x v => ↑(x v), map_zero' := (_ : (fun x v => ↑(x v)) 0 = (fun x v => ↑(x v)) 0) } x +
      ZeroHom.toFun { toFun := fun x v => ↑(x v), map_zero' := (_ : (fun x v => ↑(x v)) 0 = (fun x v => ↑(x v)) 0) } y
[PROOFSTEP]
refine funext fun v => ?_
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : R_hat R K
v : HeightOneSpectrum R
⊢ ZeroHom.toFun { toFun := fun x v => ↑(x v), map_zero' := (_ : (fun x v => ↑(x v)) 0 = (fun x v => ↑(x v)) 0) } (x + y)
      v =
    (ZeroHom.toFun { toFun := fun x v => ↑(x v), map_zero' := (_ : (fun x v => ↑(x v)) 0 = (fun x v => ↑(x v)) 0) } x +
        ZeroHom.toFun { toFun := fun x v => ↑(x v), map_zero' := (_ : (fun x v => ↑(x v)) 0 = (fun x v => ↑(x v)) 0) }
          y)
      v
[PROOFSTEP]
simp only [coe_apply, Pi.add_apply, Subring.coe_add]
  -- Porting note: added
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : R_hat R K
v : HeightOneSpectrum R
⊢ ↑((x + y) v) = ((fun v => ↑(x v)) + fun v => ↑(y v)) v
[PROOFSTEP]
erw [Pi.add_apply, Pi.add_apply, Subring.coe_add]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
src✝ : R_hat R K →+ K_hat R K := addMonoidHom R K
x y : R_hat R K
⊢ OneHom.toFun { toFun := fun x v => ↑(x v), map_one' := (_ : (fun x v => ↑(x v)) 1 = (fun x v => ↑(x v)) 1) } (x * y) =
    OneHom.toFun { toFun := fun x v => ↑(x v), map_one' := (_ : (fun x v => ↑(x v)) 1 = (fun x v => ↑(x v)) 1) } x *
      OneHom.toFun { toFun := fun x v => ↑(x v), map_one' := (_ : (fun x v => ↑(x v)) 1 = (fun x v => ↑(x v)) 1) } y
[PROOFSTEP]
refine funext fun p => ?_
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
src✝ : R_hat R K →+ K_hat R K := addMonoidHom R K
x y : R_hat R K
p : HeightOneSpectrum R
⊢ OneHom.toFun { toFun := fun x v => ↑(x v), map_one' := (_ : (fun x v => ↑(x v)) 1 = (fun x v => ↑(x v)) 1) } (x * y)
      p =
    (OneHom.toFun { toFun := fun x v => ↑(x v), map_one' := (_ : (fun x v => ↑(x v)) 1 = (fun x v => ↑(x v)) 1) } x *
        OneHom.toFun { toFun := fun x v => ↑(x v), map_one' := (_ : (fun x v => ↑(x v)) 1 = (fun x v => ↑(x v)) 1) } y)
      p
[PROOFSTEP]
simp only [Pi.mul_apply, Subring.coe_mul]
  -- Porting note: added
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
src✝ : R_hat R K →+ K_hat R K := addMonoidHom R K
x y : R_hat R K
p : HeightOneSpectrum R
⊢ ↑((x * y) p) = ((fun v => ↑(x v)) * fun v => ↑(y v)) p
[PROOFSTEP]
erw [Pi.mul_apply, Pi.mul_apply, Subring.coe_mul]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ Algebra K ((v : HeightOneSpectrum R) → HeightOneSpectrum.adicCompletion K v)
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ Algebra R ((v : HeightOneSpectrum R) → HeightOneSpectrum.adicCompletion K v)
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ IsScalarTower R K ((v : HeightOneSpectrum R) → HeightOneSpectrum.adicCompletion K v)
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ Algebra R ((v : HeightOneSpectrum R) → { x // x ∈ adicCompletionIntegers K v })
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ IsScalarTower R ((v : HeightOneSpectrum R) → { x // x ∈ adicCompletionIntegers K v })
    ((v : HeightOneSpectrum R) → HeightOneSpectrum.adicCompletion K v)
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : IsFiniteAdele x
hy : IsFiniteAdele y
⊢ IsFiniteAdele (x + y)
[PROOFSTEP]
rw [IsFiniteAdele, Filter.eventually_cofinite] at hx hy ⊢
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
⊢ Set.Finite {x_1 | ¬(x + y) x_1 ∈ adicCompletionIntegers K x_1}
[PROOFSTEP]
have h_subset :
  {v : HeightOneSpectrum R | ¬(x + y) v ∈ v.adicCompletionIntegers K} ⊆
    {v : HeightOneSpectrum R | ¬x v ∈ v.adicCompletionIntegers K} ∪
      {v : HeightOneSpectrum R | ¬y v ∈ v.adicCompletionIntegers K} :=
  by
  intro v hv
  rw [mem_union, mem_setOf, mem_setOf]
  rw [mem_setOf] at hv
  contrapose! hv
  rw [mem_adicCompletionIntegers, mem_adicCompletionIntegers, ← max_le_iff] at hv
  rw [mem_adicCompletionIntegers, Pi.add_apply]
  exact le_trans (Valued.v.map_add_le_max' (x v) (y v)) hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
⊢ {v | ¬(x + y) v ∈ adicCompletionIntegers K v} ⊆
    {v | ¬x v ∈ adicCompletionIntegers K v} ∪ {v | ¬y v ∈ adicCompletionIntegers K v}
[PROOFSTEP]
intro v hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : v ∈ {v | ¬(x + y) v ∈ adicCompletionIntegers K v}
⊢ v ∈ {v | ¬x v ∈ adicCompletionIntegers K v} ∪ {v | ¬y v ∈ adicCompletionIntegers K v}
[PROOFSTEP]
rw [mem_union, mem_setOf, mem_setOf]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : v ∈ {v | ¬(x + y) v ∈ adicCompletionIntegers K v}
⊢ ¬x v ∈ adicCompletionIntegers K v ∨ ¬y v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_setOf] at hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : ¬(x + y) v ∈ adicCompletionIntegers K v
⊢ ¬x v ∈ adicCompletionIntegers K v ∨ ¬y v ∈ adicCompletionIntegers K v
[PROOFSTEP]
contrapose! hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : x v ∈ adicCompletionIntegers K v ∧ y v ∈ adicCompletionIntegers K v
⊢ (x + y) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers, mem_adicCompletionIntegers, ← max_le_iff] at hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : max (↑Valued.v (x v)) (↑Valued.v (y v)) ≤ 1
⊢ (x + y) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers, Pi.add_apply]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : max (↑Valued.v (x v)) (↑Valued.v (y v)) ≤ 1
⊢ ↑Valued.v (x v + y v) ≤ 1
[PROOFSTEP]
exact le_trans (Valued.v.map_add_le_max' (x v) (y v)) hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
h_subset :
  {v | ¬(x + y) v ∈ adicCompletionIntegers K v} ⊆
    {v | ¬x v ∈ adicCompletionIntegers K v} ∪ {v | ¬y v ∈ adicCompletionIntegers K v}
⊢ Set.Finite {x_1 | ¬(x + y) x_1 ∈ adicCompletionIntegers K x_1}
[PROOFSTEP]
exact (hx.union hy).subset h_subset
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ IsFiniteAdele 0
[PROOFSTEP]
rw [IsFiniteAdele, Filter.eventually_cofinite]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ Set.Finite {x | ¬OfNat.ofNat 0 x ∈ adicCompletionIntegers K x}
[PROOFSTEP]
have h_empty : {v : HeightOneSpectrum R | ¬(0 : v.adicCompletion K) ∈ v.adicCompletionIntegers K} = ∅ :=
  by
  ext v; rw [mem_empty_iff_false, iff_false_iff]; intro hv
  rw [mem_setOf] at hv ; apply hv; rw [mem_adicCompletionIntegers]
  have h_zero : (Valued.v (0 : v.adicCompletion K) : WithZero (Multiplicative ℤ)) = 0 := Valued.v.map_zero'
  rw [h_zero];
  exact
    zero_le_one'
      _
        -- Porting note: was `exact`, but `OfNat` got in the way.
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ {v | ¬0 ∈ adicCompletionIntegers K v} = ∅
[PROOFSTEP]
ext v
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
⊢ v ∈ {v | ¬0 ∈ adicCompletionIntegers K v} ↔ v ∈ ∅
[PROOFSTEP]
rw [mem_empty_iff_false, iff_false_iff]
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
⊢ ¬v ∈ {v | ¬0 ∈ adicCompletionIntegers K v}
[PROOFSTEP]
intro hv
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : v ∈ {v | ¬0 ∈ adicCompletionIntegers K v}
⊢ False
[PROOFSTEP]
rw [mem_setOf] at hv
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬0 ∈ adicCompletionIntegers K v
⊢ False
[PROOFSTEP]
apply hv
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬0 ∈ adicCompletionIntegers K v
⊢ 0 ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers]
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬0 ∈ adicCompletionIntegers K v
⊢ ↑Valued.v 0 ≤ 1
[PROOFSTEP]
have h_zero : (Valued.v (0 : v.adicCompletion K) : WithZero (Multiplicative ℤ)) = 0 := Valued.v.map_zero'
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬0 ∈ adicCompletionIntegers K v
h_zero : ↑Valued.v 0 = 0
⊢ ↑Valued.v 0 ≤ 1
[PROOFSTEP]
rw [h_zero]
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬0 ∈ adicCompletionIntegers K v
h_zero : ↑Valued.v 0 = 0
⊢ 0 ≤ 1
[PROOFSTEP]
exact
  zero_le_one'
    _
      -- Porting note: was `exact`, but `OfNat` got in the way.
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
h_empty : {v | ¬0 ∈ adicCompletionIntegers K v} = ∅
⊢ Set.Finite {x | ¬OfNat.ofNat 0 x ∈ adicCompletionIntegers K x}
[PROOFSTEP]
convert finite_empty
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x : K_hat R K
hx : IsFiniteAdele x
⊢ IsFiniteAdele (-x)
[PROOFSTEP]
rw [IsFiniteAdele] at hx ⊢
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x : K_hat R K
hx : ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, x v ∈ adicCompletionIntegers K v
⊢ ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, (-x) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
have h : ∀ v : HeightOneSpectrum R, -x v ∈ v.adicCompletionIntegers K ↔ x v ∈ v.adicCompletionIntegers K :=
  by
  intro v
  rw [mem_adicCompletionIntegers, mem_adicCompletionIntegers, Valuation.map_neg]
    -- Porting note: was `simpa only [Pi.neg_apply, h] using hx` but `Pi.neg_apply` no longer works
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x : K_hat R K
hx : ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, x v ∈ adicCompletionIntegers K v
⊢ ∀ (v : HeightOneSpectrum R), -x v ∈ adicCompletionIntegers K v ↔ x v ∈ adicCompletionIntegers K v
[PROOFSTEP]
intro v
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x : K_hat R K
hx : ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, x v ∈ adicCompletionIntegers K v
v : HeightOneSpectrum R
⊢ -x v ∈ adicCompletionIntegers K v ↔ x v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers, mem_adicCompletionIntegers, Valuation.map_neg]
  -- Porting note: was `simpa only [Pi.neg_apply, h] using hx` but `Pi.neg_apply` no longer works
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x : K_hat R K
hx : ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, x v ∈ adicCompletionIntegers K v
h : ∀ (v : HeightOneSpectrum R), -x v ∈ adicCompletionIntegers K v ↔ x v ∈ adicCompletionIntegers K v
⊢ ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, (-x) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
convert hx using 2 with v
[GOAL]
case h.e'_2.h.a
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x : K_hat R K
hx : ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, x v ∈ adicCompletionIntegers K v
h : ∀ (v : HeightOneSpectrum R), -x v ∈ adicCompletionIntegers K v ↔ x v ∈ adicCompletionIntegers K v
v : HeightOneSpectrum R
⊢ (-x) v ∈ adicCompletionIntegers K v ↔ x v ∈ adicCompletionIntegers K v
[PROOFSTEP]
convert h v
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : IsFiniteAdele x
hy : IsFiniteAdele y
⊢ IsFiniteAdele (x * y)
[PROOFSTEP]
rw [IsFiniteAdele, Filter.eventually_cofinite] at hx hy ⊢
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
⊢ Set.Finite {x_1 | ¬(x * y) x_1 ∈ adicCompletionIntegers K x_1}
[PROOFSTEP]
have h_subset :
  {v : HeightOneSpectrum R | ¬(x * y) v ∈ v.adicCompletionIntegers K} ⊆
    {v : HeightOneSpectrum R | ¬x v ∈ v.adicCompletionIntegers K} ∪
      {v : HeightOneSpectrum R | ¬y v ∈ v.adicCompletionIntegers K} :=
  by
  intro v hv
  rw [mem_union, mem_setOf, mem_setOf]
  rw [mem_setOf] at hv
  contrapose! hv
  rw [mem_adicCompletionIntegers, mem_adicCompletionIntegers] at hv
  have h_mul : Valued.v (x v * y v) = Valued.v (x v) * Valued.v (y v) := Valued.v.map_mul' (x v) (y v)
  rw [mem_adicCompletionIntegers, Pi.mul_apply, h_mul]
  exact @mul_le_one' (WithZero (Multiplicative ℤ)) _ _ (OrderedCommMonoid.to_covariantClass_left _) _ _ hv.left hv.right
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
⊢ {v | ¬(x * y) v ∈ adicCompletionIntegers K v} ⊆
    {v | ¬x v ∈ adicCompletionIntegers K v} ∪ {v | ¬y v ∈ adicCompletionIntegers K v}
[PROOFSTEP]
intro v hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : v ∈ {v | ¬(x * y) v ∈ adicCompletionIntegers K v}
⊢ v ∈ {v | ¬x v ∈ adicCompletionIntegers K v} ∪ {v | ¬y v ∈ adicCompletionIntegers K v}
[PROOFSTEP]
rw [mem_union, mem_setOf, mem_setOf]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : v ∈ {v | ¬(x * y) v ∈ adicCompletionIntegers K v}
⊢ ¬x v ∈ adicCompletionIntegers K v ∨ ¬y v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_setOf] at hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : ¬(x * y) v ∈ adicCompletionIntegers K v
⊢ ¬x v ∈ adicCompletionIntegers K v ∨ ¬y v ∈ adicCompletionIntegers K v
[PROOFSTEP]
contrapose! hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : x v ∈ adicCompletionIntegers K v ∧ y v ∈ adicCompletionIntegers K v
⊢ (x * y) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers, mem_adicCompletionIntegers] at hv
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : ↑Valued.v (x v) ≤ 1 ∧ ↑Valued.v (y v) ≤ 1
⊢ (x * y) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
have h_mul : Valued.v (x v * y v) = Valued.v (x v) * Valued.v (y v) := Valued.v.map_mul' (x v) (y v)
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : ↑Valued.v (x v) ≤ 1 ∧ ↑Valued.v (y v) ≤ 1
h_mul : ↑Valued.v (x v * y v) = ↑Valued.v (x v) * ↑Valued.v (y v)
⊢ (x * y) v ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers, Pi.mul_apply, h_mul]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
v : HeightOneSpectrum R
hv : ↑Valued.v (x v) ≤ 1 ∧ ↑Valued.v (y v) ≤ 1
h_mul : ↑Valued.v (x v * y v) = ↑Valued.v (x v) * ↑Valued.v (y v)
⊢ ↑Valued.v (x v) * ↑Valued.v (y v) ≤ 1
[PROOFSTEP]
exact @mul_le_one' (WithZero (Multiplicative ℤ)) _ _ (OrderedCommMonoid.to_covariantClass_left _) _ _ hv.left hv.right
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
x y : K_hat R K
hx : Set.Finite {x_1 | ¬x x_1 ∈ adicCompletionIntegers K x_1}
hy : Set.Finite {x | ¬y x ∈ adicCompletionIntegers K x}
h_subset :
  {v | ¬(x * y) v ∈ adicCompletionIntegers K v} ⊆
    {v | ¬x v ∈ adicCompletionIntegers K v} ∪ {v | ¬y v ∈ adicCompletionIntegers K v}
⊢ Set.Finite {x_1 | ¬(x * y) x_1 ∈ adicCompletionIntegers K x_1}
[PROOFSTEP]
exact (hx.union hy).subset h_subset
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ IsFiniteAdele 1
[PROOFSTEP]
rw [IsFiniteAdele, Filter.eventually_cofinite]
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ Set.Finite {x | ¬OfNat.ofNat 1 x ∈ adicCompletionIntegers K x}
[PROOFSTEP]
have h_empty : {v : HeightOneSpectrum R | ¬(1 : v.adicCompletion K) ∈ v.adicCompletionIntegers K} = ∅ :=
  by
  ext v; rw [mem_empty_iff_false, iff_false_iff]; intro hv
  rw [mem_setOf] at hv ; apply hv; rw [mem_adicCompletionIntegers]
  exact le_of_eq Valued.v.map_one'
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
⊢ {v | ¬1 ∈ adicCompletionIntegers K v} = ∅
[PROOFSTEP]
ext v
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
⊢ v ∈ {v | ¬1 ∈ adicCompletionIntegers K v} ↔ v ∈ ∅
[PROOFSTEP]
rw [mem_empty_iff_false, iff_false_iff]
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
⊢ ¬v ∈ {v | ¬1 ∈ adicCompletionIntegers K v}
[PROOFSTEP]
intro hv
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : v ∈ {v | ¬1 ∈ adicCompletionIntegers K v}
⊢ False
[PROOFSTEP]
rw [mem_setOf] at hv
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬1 ∈ adicCompletionIntegers K v
⊢ False
[PROOFSTEP]
apply hv
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬1 ∈ adicCompletionIntegers K v
⊢ 1 ∈ adicCompletionIntegers K v
[PROOFSTEP]
rw [mem_adicCompletionIntegers]
[GOAL]
case h
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ v : HeightOneSpectrum R
hv : ¬1 ∈ adicCompletionIntegers K v
⊢ ↑Valued.v 1 ≤ 1
[PROOFSTEP]
exact le_of_eq Valued.v.map_one'
[GOAL]
R : Type u_1
K : Type u_2
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
h_empty : {v | ¬1 ∈ adicCompletionIntegers K v} = ∅
⊢ Set.Finite {x | ¬OfNat.ofNat 1 x ∈ adicCompletionIntegers K x}
[PROOFSTEP]
convert finite_empty


[GOAL]
α : Type u_1
β : Type u_2
s : Set (Setoid α)
⊢ Rel (sInf s) = sInf (Rel '' s)
[PROOFSTEP]
ext
[GOAL]
case h.h.a
α : Type u_1
β : Type u_2
s : Set (Setoid α)
x✝¹ x✝ : α
⊢ Rel (sInf s) x✝¹ x✝ ↔ sInf (Rel '' s) x✝¹ x✝
[PROOFSTEP]
simp only [sInf_image, iInf_apply, iInf_Prop_eq]
[GOAL]
case h.h.a
α : Type u_1
β : Type u_2
s : Set (Setoid α)
x✝¹ x✝ : α
⊢ Rel (sInf s) x✝¹ x✝ ↔ ∀ (i : Setoid α), i ∈ s → Rel i x✝¹ x✝
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
⊢ s = ⊤ ↔ ∀ (x y : α), Rel s x y
[PROOFSTEP]
rw [_root_.eq_top_iff, Setoid.le_def, Setoid.top_def]
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
⊢ (∀ {x y : α}, ⊤ x y → Rel s x y) ↔ ∀ (x y : α), Rel s x y
[PROOFSTEP]
simp only [Pi.top_apply, Prop.top_eq_true, forall_true_left]
[GOAL]
α : Type u_1
β : Type u_2
r s : Setoid α
⊢ r ⊔ s = EqvGen.Setoid fun x y => Rel r x y ∨ Rel s x y
[PROOFSTEP]
rw [eqvGen_eq]
[GOAL]
α : Type u_1
β : Type u_2
r s : Setoid α
⊢ r ⊔ s = sInf {s_1 | ∀ ⦃x y : α⦄, Rel r x y ∨ Rel s x y → Rel s_1 x y}
[PROOFSTEP]
apply congr_arg sInf
[GOAL]
α : Type u_1
β : Type u_2
r s : Setoid α
⊢ {x | r ≤ x ∧ s ≤ x} = {s_1 | ∀ ⦃x y : α⦄, Rel r x y ∨ Rel s x y → Rel s_1 x y}
[PROOFSTEP]
simp only [le_def, or_imp, ← forall_and]
[GOAL]
α : Type u_1
β : Type u_2
r s : Setoid α
⊢ r ⊔ s = EqvGen.Setoid (Rel r ⊔ Rel s)
[PROOFSTEP]
rw [sup_eq_eqvGen]
[GOAL]
α : Type u_1
β : Type u_2
r s : Setoid α
⊢ (EqvGen.Setoid fun x y => Rel r x y ∨ Rel s x y) = EqvGen.Setoid (Rel r ⊔ Rel s)
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
S : Set (Setoid α)
⊢ sSup S = EqvGen.Setoid fun x y => ∃ r, r ∈ S ∧ Rel r x y
[PROOFSTEP]
rw [eqvGen_eq]
[GOAL]
α : Type u_1
β : Type u_2
S : Set (Setoid α)
⊢ sSup S = sInf {s | ∀ ⦃x y : α⦄, (∃ r, r ∈ S ∧ Rel r x y) → Rel s x y}
[PROOFSTEP]
apply congr_arg sInf
[GOAL]
α : Type u_1
β : Type u_2
S : Set (Setoid α)
⊢ upperBounds S = {s | ∀ ⦃x y : α⦄, (∃ r, r ∈ S ∧ Rel r x y) → Rel s x y}
[PROOFSTEP]
simp only [upperBounds, le_def, and_imp, exists_imp]
[GOAL]
α : Type u_1
β : Type u_2
S : Set (Setoid α)
⊢ {x | ∀ ⦃a : Setoid α⦄, a ∈ S → ∀ {x_1 y : α}, Rel a x_1 y → Rel x x_1 y} =
    {s | ∀ ⦃x y : α⦄ (x_1 : Setoid α), x_1 ∈ S → Rel x_1 x y → Rel s x y}
[PROOFSTEP]
ext
[GOAL]
case h
α : Type u_1
β : Type u_2
S : Set (Setoid α)
x✝ : Setoid α
⊢ x✝ ∈ {x | ∀ ⦃a : Setoid α⦄, a ∈ S → ∀ {x_1 y : α}, Rel a x_1 y → Rel x x_1 y} ↔
    x✝ ∈ {s | ∀ ⦃x y : α⦄ (x_1 : Setoid α), x_1 ∈ S → Rel x_1 x y → Rel s x y}
[PROOFSTEP]
exact ⟨fun H x y r hr => H hr, fun H r hr x y => H r hr⟩
[GOAL]
α : Type u_1
β : Type u_2
s : Set (Setoid α)
⊢ sSup s = EqvGen.Setoid (sSup (Rel '' s))
[PROOFSTEP]
rw [sSup_eq_eqvGen, sSup_image]
[GOAL]
α : Type u_1
β : Type u_2
s : Set (Setoid α)
⊢ (EqvGen.Setoid fun x y => ∃ r, r ∈ s ∧ Rel r x y) = EqvGen.Setoid (⨆ (a : Setoid α) (_ : a ∈ s), Rel a)
[PROOFSTEP]
congr with (x y)
[GOAL]
case e_r.h.h.a
α : Type u_1
β : Type u_2
s : Set (Setoid α)
x y : α
⊢ (∃ r, r ∈ s ∧ Rel r x y) ↔ iSup (fun a => ⨆ (_ : a ∈ s), Rel a) x y
[PROOFSTEP]
simp only [iSup_apply, iSup_Prop_eq, exists_prop]
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
⊢ EqvGen.Setoid Setoid.r ≤ r
[PROOFSTEP]
rw [eqvGen_eq]
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
⊢ sInf {s | ∀ ⦃x y : α⦄, Setoid.r x y → Rel s x y} ≤ r
[PROOFSTEP]
exact sInf_le fun _ _ => id
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
s : Setoid α
h : ∀ (x y : α), r x y → Rel s x y
⊢ EqvGen.Setoid r ≤ s
[PROOFSTEP]
rw [eqvGen_eq]
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
s : Setoid α
h : ∀ (x y : α), r x y → Rel s x y
⊢ sInf {s | ∀ ⦃x y : α⦄, r x y → Rel s x y} ≤ s
[PROOFSTEP]
exact sInf_le h
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : Quotient r → β
x y : α
h : Rel r x y
⊢ Rel (ker (f ∘ Quotient.mk'')) x y
[PROOFSTEP]
simp [ker_def, Quotient.sound' h]
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
H : r ≤ ker f
g : Quotient r → β
Hg : f = g ∘ Quotient.mk''
⊢ Quotient.lift f H = g
[PROOFSTEP]
ext ⟨x⟩
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
H : r ≤ ker f
g : Quotient r → β
Hg : f = g ∘ Quotient.mk''
x✝ : Quotient r
x : α
⊢ Quotient.lift f H (Quot.mk Setoid.r x) = g (Quot.mk Setoid.r x)
[PROOFSTEP]
erw [Quotient.lift_mk f H, Hg]
[GOAL]
case h.mk
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
H : r ≤ ker f
g : Quotient r → β
Hg : f = g ∘ Quotient.mk''
x✝ : Quotient r
x : α
⊢ (g ∘ Quotient.mk'') x = g (Quot.mk Setoid.r x)
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
x y : Quotient (ker f)
h :
  Quotient.lift (fun x => { val := f x, property := (_ : f x ∈ Set.range f) })
      (_ :
        ∀ (x x_1 : α),
          x ≈ x_1 →
            { val := f x, property := (_ : f x ∈ Set.range f) } =
              { val := f x_1, property := (_ : f x_1 ∈ Set.range f) })
      x =
    Quotient.lift (fun x => { val := f x, property := (_ : f x ∈ Set.range f) })
      (_ :
        ∀ (x x_1 : α),
          x ≈ x_1 →
            { val := f x, property := (_ : f x ∈ Set.range f) } =
              { val := f x_1, property := (_ : f x_1 ∈ Set.range f) })
      y
⊢ Quotient.lift f (_ : ∀ (x x_1 : α), x ≈ x_1 → x ≈ x_1) x = Quotient.lift f (_ : ∀ (x x_1 : α), x ≈ x_1 → x ≈ x_1) y
[PROOFSTEP]
rcases x with ⟨⟩
[GOAL]
case mk
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
x y : Quotient (ker f)
a✝ : α
h :
  Quotient.lift (fun x => { val := f x, property := (_ : f x ∈ Set.range f) })
      (_ :
        ∀ (x x_1 : α),
          x ≈ x_1 →
            { val := f x, property := (_ : f x ∈ Set.range f) } =
              { val := f x_1, property := (_ : f x_1 ∈ Set.range f) })
      (Quot.mk Setoid.r a✝) =
    Quotient.lift (fun x => { val := f x, property := (_ : f x ∈ Set.range f) })
      (_ :
        ∀ (x x_1 : α),
          x ≈ x_1 →
            { val := f x, property := (_ : f x ∈ Set.range f) } =
              { val := f x_1, property := (_ : f x_1 ∈ Set.range f) })
      y
⊢ Quotient.lift f (_ : ∀ (x x_1 : α), x ≈ x_1 → x ≈ x_1) (Quot.mk Setoid.r a✝) =
    Quotient.lift f (_ : ∀ (x x_1 : α), x ≈ x_1 → x ≈ x_1) y
[PROOFSTEP]
rcases y with ⟨⟩
[GOAL]
case mk.mk
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
x y : Quotient (ker f)
a✝¹ a✝ : α
h :
  Quotient.lift (fun x => { val := f x, property := (_ : f x ∈ Set.range f) })
      (_ :
        ∀ (x x_1 : α),
          x ≈ x_1 →
            { val := f x, property := (_ : f x ∈ Set.range f) } =
              { val := f x_1, property := (_ : f x_1 ∈ Set.range f) })
      (Quot.mk Setoid.r a✝¹) =
    Quotient.lift (fun x => { val := f x, property := (_ : f x ∈ Set.range f) })
      (_ :
        ∀ (x x_1 : α),
          x ≈ x_1 →
            { val := f x, property := (_ : f x ∈ Set.range f) } =
              { val := f x_1, property := (_ : f x_1 ∈ Set.range f) })
      (Quot.mk Setoid.r a✝)
⊢ Quotient.lift f (_ : ∀ (x x_1 : α), x ≈ x_1 → x ≈ x_1) (Quot.mk Setoid.r a✝¹) =
    Quotient.lift f (_ : ∀ (x x_1 : α), x ≈ x_1 → x ≈ x_1) (Quot.mk Setoid.r a✝)
[PROOFSTEP]
injections
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f✝ : α → β
r : Setoid α
f : α → β
h : ker f ≤ r
hf : Surjective f
x✝² y✝ z✝ : β
x✝¹ : ∃ a b, f a = x✝² ∧ f b = y✝ ∧ Rel r a b
x✝ : ∃ a b, f a = y✝ ∧ f b = z✝ ∧ Rel r a b
x y : α
hx : f x = x✝²
hy : f y = y✝
h₁ : Rel r x y
y' z : α
hy' : f y' = y✝
hz : f z = z✝
h₂ : Rel r y' z
⊢ Rel (ker f) y y'
[PROOFSTEP]
rwa [← hy'] at hy
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
h : ker f ≤ r
hf : Surjective f
⊢ map r f = mapOfSurjective r f h hf
[PROOFSTEP]
rw [← eqvGen_of_setoid (mapOfSurjective r f h hf)]
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
h : ker f ≤ r
hf : Surjective f
⊢ map r f = EqvGen.Setoid Setoid.r
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f✝ f : α → β
r : Setoid β
x y : α
⊢ Setoid.r x y ↔ Quotient.mk r (f x) = Quotient.mk r (f y)
[PROOFSTEP]
rw [Quotient.eq]
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f✝ f : α → β
r : Setoid β
x y : α
⊢ Setoid.r x y ↔ f x ≈ f y
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
s : Setoid α
h : r ≤ s
x : Quotient (ker (Quot.mapRight h))
y : Quot fun a₁ a₂ => Rel r a₁ a₂
w : α
⊢ (fun x =>
        Quotient.liftOn' x (fun w => Quotient.mk'' (Quotient.mk'' w))
          (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk'' (Quotient.mk'' x) = Quotient.mk'' (Quotient.mk'' y)))
      ((fun x =>
          Quotient.liftOn' x
            (fun w =>
              Quotient.liftOn' w Quotient.mk'' (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk s x = Quotient.mk s y))
            (_ :
              ∀ (x y : Quot fun a₁ a₂ => Rel r a₁ a₂),
                Setoid.r x y →
                  Quotient.liftOn' x Quotient.mk'' (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk s x = Quotient.mk s y) =
                    Quotient.liftOn' y Quotient.mk''
                      (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk s x = Quotient.mk s y)))
        (Quotient.mk'' (Quotient.mk'' w))) =
    Quotient.mk'' (Quotient.mk'' w)
[PROOFSTEP]
show ⟦_⟧ = _
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
s : Setoid α
h : r ≤ s
x : Quotient (ker (Quot.mapRight h))
y : Quot fun a₁ a₂ => Rel r a₁ a₂
w : α
⊢ Quotient.mk (ker (Quot.mapRight h)) (Quotient.mk'' w) = Quotient.mk'' (Quotient.mk'' w)
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
s : Setoid α
h : r ≤ s
x : Quotient s
y : α
⊢ (fun x =>
        Quotient.liftOn' x
          (fun w =>
            Quotient.liftOn' w Quotient.mk'' (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk s x = Quotient.mk s y))
          (_ :
            ∀ (x y : Quot fun a₁ a₂ => Rel r a₁ a₂),
              Setoid.r x y →
                Quotient.liftOn' x Quotient.mk'' (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk s x = Quotient.mk s y) =
                  Quotient.liftOn' y Quotient.mk'' (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk s x = Quotient.mk s y)))
      ((fun x =>
          Quotient.liftOn' x (fun w => Quotient.mk'' (Quotient.mk'' w))
            (_ : ∀ (x y : α), Setoid.r x y → Quotient.mk'' (Quotient.mk'' x) = Quotient.mk'' (Quotient.mk'' y)))
        (Quotient.mk'' y)) =
    Quotient.mk'' y
[PROOFSTEP]
show ⟦_⟧ = _
[GOAL]
α : Type u_1
β : Type u_2
r : Setoid α
f : α → β
s : Setoid α
h : r ≤ s
x : Quotient s
y : α
⊢ Quotient.mk s y = Quotient.mk'' y
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s : Setoid (Quotient r)
x y : α
h : Rel r x y
⊢ Rel (comap Quotient.mk' s) x y
[PROOFSTEP]
rw [comap_rel, eq_rel.2 h]
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s : { s // r ≤ s }
⊢ (fun s => { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
      ((fun s =>
          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
        s) =
    s
[PROOFSTEP]
ext
[GOAL]
case a.H
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s : { s // r ≤ s }
a✝ b✝ : α
⊢ Rel
      (↑((fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
          ((fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
            s)))
      a✝ b✝ ↔
    Rel (↑s) a✝ b✝
[PROOFSTEP]
refine ⟨?_, fun h => ⟨_, _, rfl, rfl, h⟩⟩
[GOAL]
case a.H
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s : { s // r ≤ s }
a✝ b✝ : α
⊢ Rel
      (↑((fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
          ((fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
            s)))
      a✝ b✝ →
    Rel (↑s) a✝ b✝
[PROOFSTEP]
intro ⟨a, b, hx, hy, H⟩
[GOAL]
case a.H
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s : { s // r ≤ s }
a✝ b✝ a b : α
hx : Quotient.mk'' a = Quotient.mk' a✝
hy : Quotient.mk'' b = Quotient.mk' b✝
H : Rel (↑s) a b
⊢ Rel (↑s) a✝ b✝
[PROOFSTEP]
refine s.1.trans' (s.1.symm' <| s.2 <| eq_rel.1 hx) (s.1.trans' H <| s.2 <| (eq_rel.1 hy))
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
⊢ ∀ {a b : { s // r ≤ s }},
    ↑{
              toFun := fun s =>
                mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                  (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
              invFun := fun s =>
                { val := comap Quotient.mk' s,
                  property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
              left_inv :=
                (_ :
                  ∀ (s : { s // r ≤ s }),
                    (fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        ((fun s =>
                            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                          s) =
                      s),
              right_inv :=
                (_ :
                  ∀ (s : Setoid (Quotient r)),
                    (fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        ((fun s =>
                            { val := comap Quotient.mk' s,
                              property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                          s) =
                      s) }
          a ≤
        ↑{
              toFun := fun s =>
                mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                  (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
              invFun := fun s =>
                { val := comap Quotient.mk' s,
                  property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
              left_inv :=
                (_ :
                  ∀ (s : { s // r ≤ s }),
                    (fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        ((fun s =>
                            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                          s) =
                      s),
              right_inv :=
                (_ :
                  ∀ (s : Setoid (Quotient r)),
                    (fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        ((fun s =>
                            { val := comap Quotient.mk' s,
                              property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                          s) =
                      s) }
          b ↔
      a ≤ b
[PROOFSTEP]
intro s t
[GOAL]
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
⊢ ↑{
            toFun := fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
            invFun := fun s =>
              { val := comap Quotient.mk' s,
                property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
            left_inv :=
              (_ :
                ∀ (s : { s // r ≤ s }),
                  (fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      ((fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        s) =
                    s),
            right_inv :=
              (_ :
                ∀ (s : Setoid (Quotient r)),
                  (fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      ((fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        s) =
                    s) }
        s ≤
      ↑{
            toFun := fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
            invFun := fun s =>
              { val := comap Quotient.mk' s,
                property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
            left_inv :=
              (_ :
                ∀ (s : { s // r ≤ s }),
                  (fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      ((fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        s) =
                    s),
            right_inv :=
              (_ :
                ∀ (s : Setoid (Quotient r)),
                  (fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      ((fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        s) =
                    s) }
        t ↔
    s ≤ t
[PROOFSTEP]
refine ⟨?_, ?_⟩
[GOAL]
case refine_1
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
⊢ ↑{
            toFun := fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
            invFun := fun s =>
              { val := comap Quotient.mk' s,
                property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
            left_inv :=
              (_ :
                ∀ (s : { s // r ≤ s }),
                  (fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      ((fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        s) =
                    s),
            right_inv :=
              (_ :
                ∀ (s : Setoid (Quotient r)),
                  (fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      ((fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        s) =
                    s) }
        s ≤
      ↑{
            toFun := fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
            invFun := fun s =>
              { val := comap Quotient.mk' s,
                property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
            left_inv :=
              (_ :
                ∀ (s : { s // r ≤ s }),
                  (fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      ((fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        s) =
                    s),
            right_inv :=
              (_ :
                ∀ (s : Setoid (Quotient r)),
                  (fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      ((fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        s) =
                    s) }
        t →
    s ≤ t
[PROOFSTEP]
intro h x y hs
[GOAL]
case refine_1
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
h :
  ↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      s ≤
    ↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      t
x y : α
hs : Rel (↑s) x y
⊢ Rel (↑t) x y
[PROOFSTEP]
let ⟨a, b, hx, hy, ht⟩ := h ⟨x, y, rfl, rfl, hs⟩
[GOAL]
case refine_1
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
h :
  ↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      s ≤
    ↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      t
x y : α
hs : Rel (↑s) x y
a b : α
hx : Quotient.mk'' a = Quotient.mk'' x
hy : Quotient.mk'' b = Quotient.mk'' y
ht : Rel (↑t) a b
⊢ Rel (↑t) x y
[PROOFSTEP]
exact t.1.trans' (t.1.symm' <| t.2 <| eq_rel.1 hx) <| t.1.trans' ht <| t.2 <| eq_rel.1 hy
[GOAL]
case refine_2
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
⊢ s ≤ t →
    ↑{
            toFun := fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
            invFun := fun s =>
              { val := comap Quotient.mk' s,
                property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
            left_inv :=
              (_ :
                ∀ (s : { s // r ≤ s }),
                  (fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      ((fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        s) =
                    s),
            right_inv :=
              (_ :
                ∀ (s : Setoid (Quotient r)),
                  (fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      ((fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        s) =
                    s) }
        s ≤
      ↑{
            toFun := fun s =>
              mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
            invFun := fun s =>
              { val := comap Quotient.mk' s,
                property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
            left_inv :=
              (_ :
                ∀ (s : { s // r ≤ s }),
                  (fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      ((fun s =>
                          mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                            (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                        s) =
                    s),
            right_inv :=
              (_ :
                ∀ (s : Setoid (Quotient r)),
                  (fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      ((fun s =>
                          { val := comap Quotient.mk' s,
                            property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                        s) =
                    s) }
        t
[PROOFSTEP]
intro h x y hs
[GOAL]
case refine_2
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
h : s ≤ t
x y : Quotient r
hs :
  Rel
    (↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      s)
    x y
⊢ Rel
    (↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      t)
    x y
[PROOFSTEP]
let ⟨a, b, hx, hy, Hs⟩ := hs
[GOAL]
case refine_2
α : Type u_1
β : Type u_2
r✝ : Setoid α
f : α → β
r : Setoid α
s t : { s // r ≤ s }
h : s ≤ t
x y : Quotient r
hs :
  Rel
    (↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      s)
    x y
a b : α
hx : Quotient.mk'' a = x
hy : Quotient.mk'' b = y
Hs : Rel (↑s) a b
⊢ Rel
    (↑{
          toFun := fun s =>
            mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
              (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q),
          invFun := fun s =>
            { val := comap Quotient.mk' s, property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) },
          left_inv :=
            (_ :
              ∀ (s : { s // r ≤ s }),
                (fun s =>
                      { val := comap Quotient.mk' s,
                        property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                    ((fun s =>
                        mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                          (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                      s) =
                  s),
          right_inv :=
            (_ :
              ∀ (s : Setoid (Quotient r)),
                (fun s =>
                      mapOfSurjective (↑s) Quotient.mk'' (_ : ker Quotient.mk'' ≤ ↑s)
                        (_ : ∀ (q : Quotient r), ∃ a, Quotient.mk r a = q))
                    ((fun s =>
                        { val := comap Quotient.mk' s,
                          property := (_ : ∀ (x y : α), Rel r x y → Rel (comap Quotient.mk' s) x y) })
                      s) =
                  s) }
      t)
    x y
[PROOFSTEP]
exact ⟨a, b, hx, hy, h Hs⟩
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
⊢ Subsingleton (Quotient s) ↔ s = ⊤
[PROOFSTEP]
simp only [_root_.subsingleton_iff, eq_top_iff, Setoid.le_def, Setoid.top_def, Pi.top_apply, forall_const]
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
⊢ (∀ (x y : Quotient s), x = y) ↔ ∀ {x y : α}, ⊤ → Setoid.Rel s x y
[PROOFSTEP]
refine' (surjective_quotient_mk _).forall.trans (forall_congr' fun a => _)
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
a : α
⊢ (∀ (y : Quotient s), Quotient.mk s a = y) ↔ ∀ {y : α}, ⊤ → Setoid.Rel s a y
[PROOFSTEP]
refine' (surjective_quotient_mk _).forall.trans (forall_congr' fun b => _)
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
a b : α
⊢ Quotient.mk s a = Quotient.mk s b ↔ ⊤ → Setoid.Rel s a b
[PROOFSTEP]
simp_rw [← Quotient.mk''_eq_mk, Prop.top_eq_true, true_implies, Quotient.eq'']
[GOAL]
α : Type u_1
β : Type u_2
s : Setoid α
a b : α
⊢ Setoid.r a b ↔ Setoid.Rel s a b
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
⊢ Subsingleton (Quot r) ↔ EqvGen r = ⊤
[PROOFSTEP]
simp only [_root_.subsingleton_iff, _root_.eq_top_iff, Pi.le_def, Pi.top_apply, forall_const]
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
⊢ (∀ (x y : Quot r), x = y) ↔ ∀ (i i_1 : α), ⊤ ≤ EqvGen r i i_1
[PROOFSTEP]
refine' (surjective_quot_mk _).forall.trans (forall_congr' fun a => _)
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
a : α
⊢ (∀ (y : Quot r), mk r a = y) ↔ ∀ (i : α), ⊤ ≤ EqvGen r a i
[PROOFSTEP]
refine' (surjective_quot_mk _).forall.trans (forall_congr' fun b => _)
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
a b : α
⊢ mk r a = mk r b ↔ ⊤ ≤ EqvGen r a b
[PROOFSTEP]
rw [Quot.eq]
[GOAL]
α : Type u_1
β : Type u_2
r : α → α → Prop
a b : α
⊢ EqvGen r a b ↔ ⊤ ≤ EqvGen r a b
[PROOFSTEP]
simp only [forall_const, le_Prop_eq, OrderTop.toTop, Pi.orderTop, Pi.top_apply, Prop.top_eq_true, true_implies]


[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s t u : Set M
S : Submonoid M
hs : s ⊆ ↑S
ht : t ⊆ ↑S
⊢ s * t ⊆ ↑S
[PROOFSTEP]
rintro _ ⟨p, q, hp, hq, rfl⟩
[GOAL]
case intro.intro.intro.intro
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s t u : Set M
S : Submonoid M
hs : s ⊆ ↑S
ht : t ⊆ ↑S
p q : M
hp : p ∈ s
hq : q ∈ t
⊢ (fun x x_1 => x * x_1) p q ∈ ↑S
[PROOFSTEP]
exact Submonoid.mul_mem _ (hs hp) (ht hq)
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s✝ t u : Set M
s : Submonoid M
⊢ ↑s * ↑s = ↑s
[PROOFSTEP]
ext x
[GOAL]
case h
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s✝ t u : Set M
s : Submonoid M
x : M
⊢ x ∈ ↑s * ↑s ↔ x ∈ ↑s
[PROOFSTEP]
refine' ⟨_, fun h => ⟨x, 1, h, s.one_mem, mul_one x⟩⟩
[GOAL]
case h
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s✝ t u : Set M
s : Submonoid M
x : M
⊢ x ∈ ↑s * ↑s → x ∈ ↑s
[PROOFSTEP]
rintro ⟨a, b, ha, hb, rfl⟩
[GOAL]
case h.intro.intro.intro.intro
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s✝ t u : Set M
s : Submonoid M
a b : M
ha : a ∈ ↑s
hb : b ∈ ↑s
⊢ (fun x x_1 => x * x_1) a b ∈ ↑s
[PROOFSTEP]
exact s.mul_mem ha hb
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝¹ : Monoid M
inst✝ : AddMonoid A
s t u : Set M
H K : Submonoid M
⊢ closure ↑H ⊔ closure ↑K ≤ H ⊔ K
[PROOFSTEP]
rw [closure_eq, closure_eq]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x : N
hx : x ∈ closure s
⊢ ∃ n, r ^ n • x ∈ closure (r • s)
[PROOFSTEP]
refine' @closure_induction N _ s (fun x : N => ∃ n : ℕ, r ^ n • x ∈ closure (r • s)) _ hx _ _ _
[GOAL]
case refine'_1
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x : N
hx : x ∈ closure s
⊢ ∀ (x : N), x ∈ s → (fun x => ∃ n, r ^ n • x ∈ closure (r • s)) x
[PROOFSTEP]
intro x hx
[GOAL]
case refine'_1
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x✝ : N
hx✝ : x✝ ∈ closure s
x : N
hx : x ∈ s
⊢ ∃ n, r ^ n • x ∈ closure (r • s)
[PROOFSTEP]
exact ⟨1, subset_closure ⟨_, hx, by rw [pow_one]⟩⟩
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x✝ : N
hx✝ : x✝ ∈ closure s
x : N
hx : x ∈ s
⊢ (fun x => r • x) x = r ^ 1 • x
[PROOFSTEP]
rw [pow_one]
[GOAL]
case refine'_2
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x : N
hx : x ∈ closure s
⊢ (fun x => ∃ n, r ^ n • x ∈ closure (r • s)) 1
[PROOFSTEP]
exact ⟨0, by simpa using one_mem _⟩
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x : N
hx : x ∈ closure s
⊢ r ^ 0 • 1 ∈ closure (r • s)
[PROOFSTEP]
simpa using one_mem _
[GOAL]
case refine'_3
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x : N
hx : x ∈ closure s
⊢ ∀ (x y : N),
    (fun x => ∃ n, r ^ n • x ∈ closure (r • s)) x →
      (fun x => ∃ n, r ^ n • x ∈ closure (r • s)) y → (fun x => ∃ n, r ^ n • x ∈ closure (r • s)) (x * y)
[PROOFSTEP]
rintro x y ⟨nx, hx⟩ ⟨ny, hy⟩
[GOAL]
case refine'_3.intro.intro
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x✝ : N
hx✝ : x✝ ∈ closure s
x y : N
nx : ℕ
hx : r ^ nx • x ∈ closure (r • s)
ny : ℕ
hy : r ^ ny • y ∈ closure (r • s)
⊢ ∃ n, r ^ n • (x * y) ∈ closure (r • s)
[PROOFSTEP]
use ny + nx
[GOAL]
case h
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x✝ : N
hx✝ : x✝ ∈ closure s
x y : N
nx : ℕ
hx : r ^ nx • x ∈ closure (r • s)
ny : ℕ
hy : r ^ ny • y ∈ closure (r • s)
⊢ r ^ (ny + nx) • (x * y) ∈ closure (r • s)
[PROOFSTEP]
rw [pow_add, mul_smul, ← smul_mul_assoc, mul_comm, ← smul_mul_assoc]
[GOAL]
case h
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝⁴ : Monoid M
inst✝³ : AddMonoid A
s✝ t u : Set M
N : Type u_6
inst✝² : CommMonoid N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
r : M
s : Set N
x✝ : N
hx✝ : x✝ ∈ closure s
x y : N
nx : ℕ
hx : r ^ nx • x ∈ closure (r • s)
ny : ℕ
hy : r ^ ny • y ∈ closure (r • s)
⊢ r ^ ny • y * r ^ nx • x ∈ closure (r • s)
[PROOFSTEP]
exact mul_mem hy hx
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s t u : Set M
inst✝ : Group G
S : Submonoid G
a✝ b✝ : G
ha : a✝ ∈ (↑S)⁻¹
hb : b✝ ∈ (↑S)⁻¹
⊢ a✝ * b✝ ∈ (↑S)⁻¹
[PROOFSTEP]
rw [mem_inv, mul_inv_rev]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s t u : Set M
inst✝ : Group G
S : Submonoid G
a✝ b✝ : G
ha : a✝ ∈ (↑S)⁻¹
hb : b✝ ∈ (↑S)⁻¹
⊢ b✝⁻¹ * a✝⁻¹ ∈ ↑S
[PROOFSTEP]
exact mul_mem hb ha
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s t u : Set M
inst✝ : Group G
S : Submonoid G
⊢ 1⁻¹ ∈ ↑S
[PROOFSTEP]
rw [inv_one]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s t u : Set M
inst✝ : Group G
S : Submonoid G
⊢ 1 ∈ ↑S
[PROOFSTEP]
exact S.one_mem'
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s✝ t u : Set M
inst✝ : Group G
s : Set G
⊢ closure s⁻¹ = (closure s)⁻¹
[PROOFSTEP]
apply le_antisymm
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s✝ t u : Set M
inst✝ : Group G
s : Set G
⊢ closure s⁻¹ ≤ (closure s)⁻¹
[PROOFSTEP]
rw [closure_le, coe_inv, ← Set.inv_subset, inv_inv]
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s✝ t u : Set M
inst✝ : Group G
s : Set G
⊢ s ⊆ ↑(closure s)
[PROOFSTEP]
exact subset_closure
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s✝ t u : Set M
inst✝ : Group G
s : Set G
⊢ (closure s)⁻¹ ≤ closure s⁻¹
[PROOFSTEP]
rw [inv_le, closure_le, coe_inv, ← Set.inv_subset]
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
s✝ t u : Set M
inst✝ : Group G
s : Set G
⊢ s⁻¹ ⊆ ↑(closure s⁻¹)
[PROOFSTEP]
exact subset_closure
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝³ : Monoid M
inst✝² : AddMonoid A
inst✝¹ : Monoid α
inst✝ : MulDistribMulAction α M
S : Submonoid M
⊢ 1 • S = S
[PROOFSTEP]
change S.map _ = S
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝³ : Monoid M
inst✝² : AddMonoid A
inst✝¹ : Monoid α
inst✝ : MulDistribMulAction α M
S : Submonoid M
⊢ map (↑(MulDistribMulAction.toMonoidEnd α M) 1) S = S
[PROOFSTEP]
simpa only [map_one] using S.map_id
[GOAL]
α : Type u_1
G✝ : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
G : Type u_6
inst✝ : Group G
S : Set G
x : G
⊢ x ∈ closure S⁻¹ ↔ x⁻¹ ∈ closure S
[PROOFSTEP]
rw [closure_inv, mem_inv]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : AddMonoidWithOne R
⊢ 1 = closure {1}
[PROOFSTEP]
rw [closure_singleton_eq, one_eq_mrange]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : AddMonoidWithOne R
⊢ AddMonoidHom.mrange (Nat.castAddMonoidHom R) = AddMonoidHom.mrange (↑(multiplesHom R) 1)
[PROOFSTEP]
congr 1
[GOAL]
case e_f
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : AddMonoidWithOne R
⊢ Nat.castAddMonoidHom R = ↑(multiplesHom R) 1
[PROOFSTEP]
ext
[GOAL]
case e_f.a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : AddMonoidWithOne R
⊢ ↑(Nat.castAddMonoidHom R) 1 = ↑(↑(multiplesHom R) 1) 1
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
M N : AddSubmonoid R
m n : R
hm : m ∈ M
hn : n ∈ N
⊢ ↑(↑AddMonoidHom.mul ↑{ val := m, property := hm }) n = m * n
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
M N : AddSubmonoid R
C : R → Prop
r : R
hr : r ∈ M * N
hm : ∀ (m : R), m ∈ M → ∀ (n : R), n ∈ N → C (m * n)
ha : ∀ (x y : R), C x → C y → C (x + y)
⊢ 0 ∈ { carrier := setOf C, add_mem' := (_ : ∀ {a b : R}, C a → C b → C (a + b)) }.carrier
[PROOFSTEP]
simpa only [zero_mul] using hm _ (zero_mem _) _ (zero_mem _)
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ closure S * closure T = closure (S * T)
[PROOFSTEP]
apply le_antisymm
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ closure S * closure T ≤ closure (S * T)
[PROOFSTEP]
refine mul_le.2 fun a ha b hb => ?_
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
⊢ a * b ∈ closure (S * T)
[PROOFSTEP]
rw [← AddMonoidHom.mulRight_apply, ← AddSubmonoid.mem_comap]
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
⊢ a ∈ comap (AddMonoidHom.mulRight b) (closure (S * T))
[PROOFSTEP]
refine (closure_le.2 fun a' ha' => ?_) ha
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
⊢ a' ∈ ↑(comap (AddMonoidHom.mulRight b) (closure (S * T)))
[PROOFSTEP]
change b ∈ (closure (S * T)).comap (AddMonoidHom.mulLeft a')
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
⊢ b ∈ comap (AddMonoidHom.mulLeft a') (closure (S * T))
[PROOFSTEP]
refine (closure_le.2 fun b' hb' => ?_) hb
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
b' : R
hb' : b' ∈ T
⊢ b' ∈ ↑(comap (AddMonoidHom.mulLeft a') (closure (S * T)))
[PROOFSTEP]
change a' * b' ∈ closure (S * T)
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a : R
ha : a ∈ closure S
b : R
hb : b ∈ closure T
a' : R
ha' : a' ∈ S
b' : R
hb' : b' ∈ T
⊢ a' * b' ∈ closure (S * T)
[PROOFSTEP]
exact subset_closure (Set.mul_mem_mul ha' hb')
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ closure (S * T) ≤ closure S * closure T
[PROOFSTEP]
rw [closure_le]
[GOAL]
case a
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
⊢ S * T ⊆ ↑(closure S * closure T)
[PROOFSTEP]
rintro _ ⟨a, b, ha, hb, rfl⟩
[GOAL]
case a.intro.intro.intro.intro
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S T : Set R
a b : R
ha : a ∈ S
hb : b ∈ T
⊢ (fun x x_1 => x * x_1) a b ∈ ↑(closure S * closure T)
[PROOFSTEP]
exact mul_mem_mul (subset_closure ha) (subset_closure hb)
[GOAL]
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
M N : AddSubmonoid R
⊢ M * N = closure (↑M * ↑N)
[PROOFSTEP]
rw [← closure_mul_closure, closure_eq, closure_eq]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S : AddSubmonoid R
m : R
x✝ : m ∈ S
n : R
hn : n ∈ ⊥
⊢ m * n ∈ ⊥
[PROOFSTEP]
rw [AddSubmonoid.mem_bot] at hn ⊢
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S : AddSubmonoid R
m : R
x✝ : m ∈ S
n : R
hn : n = 0
⊢ m * n = 0
[PROOFSTEP]
rw [hn, mul_zero]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S : AddSubmonoid R
m : R
hm : m ∈ ⊥
n : R
hn : n ∈ S
⊢ m * n ∈ ⊥
[PROOFSTEP]
rw [AddSubmonoid.mem_bot] at hm ⊢
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
S : AddSubmonoid R
m : R
hm : m = 0
n : R
hn : n ∈ S
⊢ m * n = 0
[PROOFSTEP]
rw [hm, zero_mul]
[GOAL]
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
M N : AddSubmonoid R
⊢ ↑M * ↑N ⊆ ↑(M * N)
[PROOFSTEP]
rintro _ ⟨i, j, hi, hj, rfl⟩
[GOAL]
case intro.intro.intro.intro
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocSemiring R
M N : AddSubmonoid R
i j : R
hi : i ∈ ↑M
hj : j ∈ ↑N
⊢ (fun x x_1 => x * x_1) i j ∈ ↑(M * N)
[PROOFSTEP]
exact mul_mem_mul hi hj
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
⊢ -x * y = -(x * y)
[PROOFSTEP]
refine' le_antisymm (mul_le.2 fun m hm n hn => _) ((AddSubmonoid.neg_le _ _).2 <| mul_le.2 fun m hm n hn => _)
[GOAL]
case refine'_1
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ -x
n : R
hn : n ∈ y
⊢ m * n ∈ -(x * y)
[PROOFSTEP]
simp only [AddSubmonoid.mem_neg, ← neg_mul] at *
[GOAL]
case refine'_2
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ x
n : R
hn : n ∈ y
⊢ m * n ∈ -(-x * y)
[PROOFSTEP]
simp only [AddSubmonoid.mem_neg, ← neg_mul] at *
[GOAL]
case refine'_1
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m n : R
hn : n ∈ y
hm : -m ∈ x
⊢ -m * n ∈ x * y
[PROOFSTEP]
exact mul_mem_mul hm hn
[GOAL]
case refine'_2
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ x
n : R
hn : n ∈ y
⊢ -m * n ∈ -x * y
[PROOFSTEP]
exact mul_mem_mul (neg_mem_neg.2 hm) hn
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
⊢ x * -y = -(x * y)
[PROOFSTEP]
refine' le_antisymm (mul_le.2 fun m hm n hn => _) ((AddSubmonoid.neg_le _ _).2 <| mul_le.2 fun m hm n hn => _)
[GOAL]
case refine'_1
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ x
n : R
hn : n ∈ -y
⊢ m * n ∈ -(x * y)
[PROOFSTEP]
simp only [AddSubmonoid.mem_neg, ← mul_neg] at *
[GOAL]
case refine'_2
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ x
n : R
hn : n ∈ y
⊢ m * n ∈ -(x * -y)
[PROOFSTEP]
simp only [AddSubmonoid.mem_neg, ← mul_neg] at *
[GOAL]
case refine'_1
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ x
n : R
hn : -n ∈ y
⊢ m * -n ∈ x * y
[PROOFSTEP]
exact mul_mem_mul hm hn
[GOAL]
case refine'_2
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : NonUnitalNonAssocRing R
src✝ : InvolutiveNeg (AddSubmonoid R) := involutiveNeg
x y : AddSubmonoid R
m : R
hm : m ∈ x
n : R
hn : n ∈ y
⊢ m * -n ∈ x * -y
[PROOFSTEP]
exact mul_mem_mul hm (neg_mem_neg.2 hn)
[GOAL]
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonAssocSemiring R
M : AddSubmonoid R
⊢ 1 * M = M
[PROOFSTEP]
rw [one_eq_closure_one_set, ← closure_eq M, closure_mul_closure, one_mul]
[GOAL]
α : Type u_1
G : Type u_2
M✝ : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M✝
inst✝¹ : AddMonoid A
inst✝ : NonAssocSemiring R
M : AddSubmonoid R
⊢ M * 1 = M
[PROOFSTEP]
rw [one_eq_closure_one_set, ← closure_eq M, closure_mul_closure, mul_one]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : Semiring R
s : Set R
⊢ closure s ^ 0 = closure (s ^ 0)
[PROOFSTEP]
rw [pow_zero, pow_zero, one_eq_closure_one_set]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : Semiring R
s : Set R
n : ℕ
⊢ closure s ^ (n + 1) = closure (s ^ (n + 1))
[PROOFSTEP]
rw [pow_succ, pow_succ, closure_pow s n, closure_mul_closure]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : Semiring R
s : AddSubmonoid R
n : ℕ
⊢ s ^ n = closure (↑s ^ n)
[PROOFSTEP]
rw [← closure_pow, closure_eq]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : OrderedCancelCommMonoid α
s : Set α
hpos : ∀ (x : α), x ∈ s → 1 ≤ x
h : IsPwo s
⊢ IsPwo ↑(Submonoid.closure s)
[PROOFSTEP]
rw [Submonoid.closure_eq_image_prod]
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : OrderedCancelCommMonoid α
s : Set α
hpos : ∀ (x : α), x ∈ s → 1 ≤ x
h : IsPwo s
⊢ IsPwo (List.prod '' {l | ∀ (x : α), x ∈ l → x ∈ s})
[PROOFSTEP]
refine' (h.partiallyWellOrderedOn_sublistForall₂ (· ≤ ·)).image_of_monotone_on _
[GOAL]
α : Type u_1
G : Type u_2
M : Type u_3
R : Type u_4
A : Type u_5
inst✝² : Monoid M
inst✝¹ : AddMonoid A
inst✝ : OrderedCancelCommMonoid α
s : Set α
hpos : ∀ (x : α), x ∈ s → 1 ≤ x
h : IsPwo s
⊢ ∀ (a₁ : List α),
    a₁ ∈ {l | ∀ (x : α), x ∈ l → x ∈ s} →
      ∀ (a₂ : List α),
        a₂ ∈ {l | ∀ (x : α), x ∈ l → x ∈ s} →
          List.SublistForall₂ (fun x x_1 => x ≤ x_1) a₁ a₂ → List.prod a₁ ≤ List.prod a₂
[PROOFSTEP]
exact fun l1 _ l2 hl2 h12 => h12.prod_le_prod' fun x hx => hpos x <| hl2 x hx