l3lab/ntp-mathlib huggingface dataset:
/-- If `x` is an `I`-multiple of the submodule spanned by `f '' s`,
then we can write `x` as an `I`-linear combination of the elements of `f '' s`. -/
theorem mem_ideal_smul_span_iff_exists_sum {ι : Type*} (f : ι → M) (x : M) :
    x ∈ I • span R (Set.range f) ↔
      ∃ (a : ι →₀ R) (_ : ∀ i, a i ∈ I), (a.sum fun i c => c • f i) = x := by
  constructor; swap
  · rintro ⟨a, ha, rfl⟩
    exact Submodule.sum_mem _ fun c _ => smul_mem_smul (ha c) <| subset_span <| Set.mem_range_self _
  refine' fun hx => span_induction (mem_smul_span.mp hx) _ _ _ _
  · simp only [Set.mem_iUnion, Set.mem_range, Set.mem_singleton_iff]
    rintro x ⟨y, hy, x, ⟨i, rfl⟩, rfl⟩
    refine' ⟨Finsupp.single i y, fun j => _, _⟩
    · letI := Classical.decEq ι
      rw [Finsupp.single_apply]
      split_ifs
      · assumption
      · exact I.zero_mem
    refine' @Finsupp.sum_single_index ι R M _ _ i _ (fun i y => y • f i) _
    simp
  · exact ⟨0, fun _ => I.zero_mem, Finsupp.sum_zero_index⟩
  · rintro x y ⟨ax, hax, rfl⟩ ⟨ay, hay, rfl⟩
    refine' ⟨ax + ay, fun i => I.add_mem (hax i) (hay i), Finsupp.sum_add_index' _ _⟩ <;> intros <;>
      simp only [zero_smul, add_smul]
  · rintro c x ⟨a, ha, rfl⟩
    refine' ⟨c • a, fun i => I.mul_mem_left c (ha i), _⟩
    rw [Finsupp.sum_smul_index, Finsupp.smul_sum] <;> intros <;> 

Proof state:
case mp.refine'_4.intro.intro
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
ι : Type u_3
f : ι → M
x : M
hx : x ∈ I • span R (Set.range f)
c : R
a : ι →₀ R
ha : ∀ (i : ι), a i ∈ I
⊢ (Finsupp.sum a fun i a => (c * a) • f i) = Finsupp.sum a fun a b => c • b • f a

Next tactic:
simp only [zero_smul, mul_smul]
/-- If `x` is an `I`-multiple of the submodule spanned by `f '' s`,
then we can write `x` as an `I`-linear combination of the elements of `f '' s`. -/
theorem mem_ideal_smul_span_iff_exists_sum {ι : Type*} (f : ι → M) (x : M) :
    x ∈ I • span R (Set.range f) ↔
      ∃ (a : ι →₀ R) (_ : ∀ i, a i ∈ I), (a.sum fun i c => c • f i) = x := by
  constructor; swap
  · rintro ⟨a, ha, rfl⟩
    exact Submodule.sum_mem _ fun c _ => smul_mem_smul (ha c) <| subset_span <| Set.mem_range_self _
  refine' fun hx => span_induction (mem_smul_span.mp hx) _ _ _ _
  · simp only [Set.mem_iUnion, Set.mem_range, Set.mem_singleton_iff]
    rintro x ⟨y, hy, x, ⟨i, rfl⟩, rfl⟩
    refine' ⟨Finsupp.single i y, fun j => _, _⟩
    · letI := Classical.decEq ι
      rw [Finsupp.single_apply]
      split_ifs
      · assumption
      · exact I.zero_mem
    refine' @Finsupp.sum_single_index ι R M _ _ i _ (fun i y => y • f i) _
    simp
  · exact ⟨0, fun _ => I.zero_mem, Finsupp.sum_zero_index⟩
  · rintro x y ⟨ax, hax, rfl⟩ ⟨ay, hay, rfl⟩
    refine' ⟨ax + ay, fun i => I.add_mem (hax i) (hay i), Finsupp.sum_add_index' _ _⟩ <;> intros <;>
      simp only [zero_smul, add_smul]
  · rintro c x ⟨a, ha, rfl⟩
    refine' ⟨c • a, fun i => I.mul_mem_left c (ha i), _⟩
    rw [Finsupp.sum_smul_index, Finsupp.smul_sum] <;> intros <;> 

Proof state:
case mp.refine'_4.intro.intro
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
ι : Type u_3
f : ι → M
x : M
hx : x ∈ I • span R (Set.range f)
c : R
a : ι →₀ R
ha : ∀ (i : ι), a i ∈ I
i✝ : ι
⊢ 0 • f i✝ = 0

Next tactic:
simp only [zero_smul, mul_smul]
theorem mem_ideal_smul_span_iff_exists_sum' {ι : Type*} (s : Set ι) (f : ι → M) (x : M) :
    x ∈ I • span R (f '' s) ↔ ∃ (a : s →₀ R) (_ : ∀ i, a i ∈ I), (a.sum fun i c => c • f i) = x :=
  by 

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
ι : Type u_3
s : Set ι
f : ι → M
x : M
⊢ x ∈ I • span R (f '' s) ↔ ∃ a, ∃ (_ : ∀ (i : ↑s), a i ∈ I), (Finsupp.sum a fun i c => c • f ↑i) = x

Next tactic:
rw [← Submodule.mem_ideal_smul_span_iff_exists_sum, ← Set.image_eq_range]
theorem mem_smul_top_iff (N : Submodule R M) (x : N) :
    x ∈ I • (⊤ : Submodule R N) ↔ (x : M) ∈ I • N := by
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N✝ P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
N : Submodule R M
x : ↥N
⊢ x ∈ I • ⊤ ↔ ↑x ∈ I • N

Next tactic:
change _ ↔ N.subtype x ∈ I • N
theorem mem_smul_top_iff (N : Submodule R M) (x : N) :
    x ∈ I • (⊤ : Submodule R N) ↔ (x : M) ∈ I • N := by
  change _ ↔ N.subtype x ∈ I • N
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N✝ P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
N : Submodule R M
x : ↥N
⊢ x ∈ I • ⊤ ↔ (Submodule.subtype N) x ∈ I • N

Next tactic:
have : Submodule.map N.subtype (I • ⊤) = I • N := by
    rw [Submodule.map_smul'', Submodule.map_top, Submodule.range_subtype]
theorem mem_smul_top_iff (N : Submodule R M) (x : N) :
    x ∈ I • (⊤ : Submodule R N) ↔ (x : M) ∈ I • N := by
  change _ ↔ N.subtype x ∈ I • N
  have : Submodule.map N.subtype (I • ⊤) = I • N := by
    

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N✝ P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
N : Submodule R M
x : ↥N
⊢ map (Submodule.subtype N) (I • ⊤) = I • N

Next tactic:
rw [Submodule.map_smul'', Submodule.map_top, Submodule.range_subtype]
theorem mem_smul_top_iff (N : Submodule R M) (x : N) :
    x ∈ I • (⊤ : Submodule R N) ↔ (x : M) ∈ I • N := by
  change _ ↔ N.subtype x ∈ I • N
  have : Submodule.map N.subtype (I • ⊤) = I • N := by
    rw [Submodule.map_smul'', Submodule.map_top, Submodule.range_subtype]
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N✝ P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
N : Submodule R M
x : ↥N
this : map (Submodule.subtype N) (I • ⊤) = I • N
⊢ x ∈ I • ⊤ ↔ (Submodule.subtype N) x ∈ I • N

Next tactic:
rw [← this]
theorem mem_smul_top_iff (N : Submodule R M) (x : N) :
    x ∈ I • (⊤ : Submodule R N) ↔ (x : M) ∈ I • N := by
  change _ ↔ N.subtype x ∈ I • N
  have : Submodule.map N.subtype (I • ⊤) = I • N := by
    rw [Submodule.map_smul'', Submodule.map_top, Submodule.range_subtype]
  rw [← this]
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I J : Ideal R
N✝ P : Submodule R M
S : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
N : Submodule R M
x : ↥N
this : map (Submodule.subtype N) (I • ⊤) = I • N
⊢ x ∈ I • ⊤ ↔ (Submodule.subtype N) x ∈ map (Submodule.subtype N) (I • ⊤)

Next tactic:
exact (Function.Injective.mem_set_image N.injective_subtype).symm
@[simp]
theorem smul_comap_le_comap_smul (f : M →ₗ[R] M') (S : Submodule R M') (I : Ideal R) :
    I • S.comap f ≤ (I • S).comap f := by
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I✝ J : Ideal R
N P : Submodule R M
S✝ : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
f : M →ₗ[R] M'
S : Submodule R M'
I : Ideal R
⊢ I • comap f S ≤ comap f (I • S)

Next tactic:
refine' Submodule.smul_le.mpr fun r hr x hx => _
@[simp]
theorem smul_comap_le_comap_smul (f : M →ₗ[R] M') (S : Submodule R M') (I : Ideal R) :
    I • S.comap f ≤ (I • S).comap f := by
  refine' Submodule.smul_le.mpr fun r hr x hx => _
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I✝ J : Ideal R
N P : Submodule R M
S✝ : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
f : M →ₗ[R] M'
S : Submodule R M'
I : Ideal R
r : R
hr : r ∈ I
x : M
hx : x ∈ comap f S
⊢ r • x ∈ comap f (I • S)

Next tactic:
rw [Submodule.mem_comap] at hx ⊢
@[simp]
theorem smul_comap_le_comap_smul (f : M →ₗ[R] M') (S : Submodule R M') (I : Ideal R) :
    I • S.comap f ≤ (I • S).comap f := by
  refine' Submodule.smul_le.mpr fun r hr x hx => _
  rw [Submodule.mem_comap] at hx ⊢
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I✝ J : Ideal R
N P : Submodule R M
S✝ : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
f : M →ₗ[R] M'
S : Submodule R M'
I : Ideal R
r : R
hr : r ∈ I
x : M
hx : f x ∈ S
⊢ f (r • x) ∈ I • S

Next tactic:
rw [f.map_smul]
@[simp]
theorem smul_comap_le_comap_smul (f : M →ₗ[R] M') (S : Submodule R M') (I : Ideal R) :
    I • S.comap f ≤ (I • S).comap f := by
  refine' Submodule.smul_le.mpr fun r hr x hx => _
  rw [Submodule.mem_comap] at hx ⊢
  rw [f.map_smul]
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝⁴ : CommSemiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
I✝ J : Ideal R
N P : Submodule R M
S✝ : Set R
T : Set M
M' : Type w
inst✝¹ : AddCommMonoid M'
inst✝ : Module R M'
f : M →ₗ[R] M'
S : Submodule R M'
I : Ideal R
r : R
hr : r ∈ I
x : M
hx : f x ∈ S
⊢ r • f x ∈ I • S

Next tactic:
exact Submodule.smul_mem_smul hr hx
@[simp]
theorem mem_colon_singleton {N : Submodule R M} {x : M} {r : R} :
    r ∈ N.colon (Submodule.span R {x}) ↔ r • x ∈ N :=
  calc
    r ∈ N.colon (Submodule.span R {x}) ↔ ∀ a : R, r • a • x ∈ N := by
      

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
N✝ N₁ N₂ P P₁ P₂ N : Submodule R M
x : M
r : R
⊢ r ∈ colon N (span R {x}) ↔ ∀ (a : R), r • a • x ∈ N

Next tactic:
simp [Submodule.mem_colon, Submodule.mem_span_singleton]
@[simp]
theorem mem_colon_singleton {N : Submodule R M} {x : M} {r : R} :
    r ∈ N.colon (Submodule.span R {x}) ↔ r • x ∈ N :=
  calc
    r ∈ N.colon (Submodule.span R {x}) ↔ ∀ a : R, r • a • x ∈ N := by
      simp [Submodule.mem_colon, Submodule.mem_span_singleton]
    _ ↔ r • x ∈ N := by 

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
N✝ N₁ N₂ P P₁ P₂ N : Submodule R M
x : M
r : R
⊢ (∀ (a : R), r • a • x ∈ N) ↔ r • x ∈ N

Next tactic:
simp_rw [fun (a : R) ↦ smul_comm r a x]
@[simp]
theorem mem_colon_singleton {N : Submodule R M} {x : M} {r : R} :
    r ∈ N.colon (Submodule.span R {x}) ↔ r • x ∈ N :=
  calc
    r ∈ N.colon (Submodule.span R {x}) ↔ ∀ a : R, r • a • x ∈ N := by
      simp [Submodule.mem_colon, Submodule.mem_span_singleton]
    _ ↔ r • x ∈ N := by simp_rw [fun (a : R) ↦ smul_comm r a x]; 

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
N✝ N₁ N₂ P P₁ P₂ N : Submodule R M
x : M
r : R
⊢ (∀ (a : R), a • r • x ∈ N) ↔ r • x ∈ N

Next tactic:
exact SetLike.forall_smul_mem_iff
@[simp]
theorem _root_.Ideal.mem_colon_singleton {I : Ideal R} {x r : R} :
    r ∈ I.colon (Ideal.span {x}) ↔ r * x ∈ I := by
  

Proof state:
R : Type u
M : Type v
F : Type u_1
G : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
N N₁ N₂ P P₁ P₂ : Submodule R M
I : Ideal R
x r : R
⊢ r ∈ colon I (Ideal.span {x}) ↔ r * x ∈ I

Next tactic:
simp only [← Ideal.submodule_span_eq, Submodule.mem_colon_singleton, smul_eq_mul]
@[simp]
theorem one_eq_top : (1 : Ideal R) = ⊤ := by 

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
⊢ 1 = ⊤

Next tactic:
erw [Submodule.one_eq_range, LinearMap.range_id]
theorem add_eq_one_iff : I + J = 1 ↔ ∃ i ∈ I, ∃ j ∈ J, i + j = 1 := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
⊢ I + J = 1 ↔ ∃ i ∈ I, ∃ j ∈ J, i + j = 1

Next tactic:
rw [one_eq_top, eq_top_iff_one, add_eq_sup, Submodule.mem_sup]
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  

Proof state:
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s : Finset ι
I : ι → Ideal R
x : ι → R
⊢ (∀ i ∈ s, x i ∈ I i) → ∏ i in s, x i ∈ ∏ i in s, I i

Next tactic:
classical
    refine Finset.induction_on s ?_ ?_
    · intro
      rw [Finset.prod_empty, Finset.prod_empty, one_eq_top]
      exact Submodule.mem_top
    · intro a s ha IH h
      rw [Finset.prod_insert ha, Finset.prod_insert ha]
      exact
        mul_mem_mul (h a <| Finset.mem_insert_self a s)
          (IH fun i hi => h i <| Finset.mem_insert_of_mem hi)
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    

Proof state:
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s : Finset ι
I : ι → Ideal R
x : ι → R
⊢ (∀ i ∈ s, x i ∈ I i) → ∏ i in s, x i ∈ ∏ i in s, I i

Next tactic:
refine Finset.induction_on s ?_ ?_
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    refine Finset.induction_on s ?_ ?_
    · 

Proof state:
case refine_1
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s : Finset ι
I : ι → Ideal R
x : ι → R
⊢ (∀ i ∈ ∅, x i ∈ I i) → ∏ i in ∅, x i ∈ ∏ i in ∅, I i

Next tactic:
intro
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    refine Finset.induction_on s ?_ ?_
    · intro
      

Proof state:
case refine_1
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s : Finset ι
I : ι → Ideal R
x : ι → R
a✝ : ∀ i ∈ ∅, x i ∈ I i
⊢ ∏ i in ∅, x i ∈ ∏ i in ∅, I i

Next tactic:
rw [Finset.prod_empty, Finset.prod_empty, one_eq_top]
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    refine Finset.induction_on s ?_ ?_
    · intro
      rw [Finset.prod_empty, Finset.prod_empty, one_eq_top]
      

Proof state:
case refine_1
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s : Finset ι
I : ι → Ideal R
x : ι → R
a✝ : ∀ i ∈ ∅, x i ∈ I i
⊢ 1 ∈ ⊤

Next tactic:
exact Submodule.mem_top
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    refine Finset.induction_on s ?_ ?_
    · intro
      rw [Finset.prod_empty, Finset.prod_empty, one_eq_top]
      exact Submodule.mem_top
    · 

Proof state:
case refine_2
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s : Finset ι
I : ι → Ideal R
x : ι → R
⊢ ∀ ⦃a : ι⦄ {s : Finset ι},
    a ∉ s →
      ((∀ i ∈ s, x i ∈ I i) → ∏ i in s, x i ∈ ∏ i in s, I i) →
        (∀ i ∈ insert a s, x i ∈ I i) → ∏ i in insert a s, x i ∈ ∏ i in insert a s, I i

Next tactic:
intro a s ha IH h
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    refine Finset.induction_on s ?_ ?_
    · intro
      rw [Finset.prod_empty, Finset.prod_empty, one_eq_top]
      exact Submodule.mem_top
    · intro a s ha IH h
      

Proof state:
case refine_2
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s✝ : Finset ι
I : ι → Ideal R
x : ι → R
a : ι
s : Finset ι
ha : a ∉ s
IH : (∀ i ∈ s, x i ∈ I i) → ∏ i in s, x i ∈ ∏ i in s, I i
h : ∀ i ∈ insert a s, x i ∈ I i
⊢ ∏ i in insert a s, x i ∈ ∏ i in insert a s, I i

Next tactic:
rw [Finset.prod_insert ha, Finset.prod_insert ha]
theorem prod_mem_prod {ι : Type*} {s : Finset ι} {I : ι → Ideal R} {x : ι → R} :
    (∀ i ∈ s, x i ∈ I i) → (∏ i in s, x i) ∈ ∏ i in s, I i := by
  classical
    refine Finset.induction_on s ?_ ?_
    · intro
      rw [Finset.prod_empty, Finset.prod_empty, one_eq_top]
      exact Submodule.mem_top
    · intro a s ha IH h
      rw [Finset.prod_insert ha, Finset.prod_insert ha]
      

Proof state:
case refine_2
R : Type u
ι✝ : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
ι : Type u_2
s✝ : Finset ι
I : ι → Ideal R
x : ι → R
a : ι
s : Finset ι
ha : a ∉ s
IH : (∀ i ∈ s, x i ∈ I i) → ∏ i in s, x i ∈ ∏ i in s, I i
h : ∀ i ∈ insert a s, x i ∈ I i
⊢ x a * ∏ x_1 in s, x x_1 ∈ I a * ∏ x in s, I x

Next tactic:
exact
        mul_mem_mul (h a <| Finset.mem_insert_self a s)
          (IH fun i hi => h i <| Finset.mem_insert_of_mem hi)
theorem span_mul_span' (S T : Set R) : span S * span T = span (S * T) := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
S T : Set R
⊢ span S * span T = span (S * T)

Next tactic:
unfold span
theorem span_mul_span' (S T : Set R) : span S * span T = span (S * T) := by
  unfold span
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
S T : Set R
⊢ Submodule.span R S * Submodule.span R T = Submodule.span R (S * T)

Next tactic:
rw [Submodule.span_mul_span]
theorem span_singleton_mul_span_singleton (r s : R) :
    span {r} * span {s} = (span {r * s} : Ideal R) := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
r s : R
⊢ span {r} * span {s} = span {r * s}

Next tactic:
unfold span
theorem span_singleton_mul_span_singleton (r s : R) :
    span {r} * span {s} = (span {r * s} : Ideal R) := by
  unfold span
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
r s : R
⊢ Submodule.span R {r} * Submodule.span R {s} = Submodule.span R {r * s}

Next tactic:
rw [Submodule.span_mul_span, Set.singleton_mul_singleton]
theorem span_singleton_pow (s : R) (n : ℕ) : span {s} ^ n = (span {s ^ n} : Ideal R) := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
s : R
n : ℕ
⊢ span {s} ^ n = span {s ^ n}

Next tactic:
induction' n with n ih
theorem span_singleton_pow (s : R) (n : ℕ) : span {s} ^ n = (span {s ^ n} : Ideal R) := by
  induction' n with n ih; · 

Proof state:
case zero
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
s : R
⊢ span {s} ^ Nat.zero = span {s ^ Nat.zero}

Next tactic:
simp [Set.singleton_one]
theorem span_singleton_pow (s : R) (n : ℕ) : span {s} ^ n = (span {s ^ n} : Ideal R) := by
  induction' n with n ih; · simp [Set.singleton_one]
  

Proof state:
case succ
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I J K L : Ideal R
s : R
n : ℕ
ih : span {s} ^ n = span {s ^ n}
⊢ span {s} ^ Nat.succ n = span {s ^ Nat.succ n}

Next tactic:
simp only [pow_succ, ih, span_singleton_mul_span_singleton]
theorem mem_span_singleton_mul {x y : R} {I : Ideal R} : x ∈ span {y} * I ↔ ∃ z ∈ I, y * z = x := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J K L : Ideal R
x y : R
I : Ideal R
⊢ x ∈ span {y} * I ↔ ∃ z ∈ I, y * z = x

Next tactic:
simp only [mul_comm, mem_mul_span_singleton]
theorem le_span_singleton_mul_iff {x : R} {I J : Ideal R} :
    I ≤ span {x} * J ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zJ = zI :=
  show (∀ {zI} (_ : zI ∈ I), zI ∈ span {x} * J) ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zJ = zI by
    

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
⊢ (∀ {zI : R}, zI ∈ I → zI ∈ span {x} * J) ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zJ = zI

Next tactic:
simp only [mem_span_singleton_mul]
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
⊢ span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J

Next tactic:
simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
⊢ (∀ (r : R), x ∣ r → ∀ s ∈ I, r * s ∈ J) ↔ ∀ z ∈ I, x * z ∈ J

Next tactic:
constructor
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
  constructor
  · 

Proof state:
case mp
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
⊢ (∀ (r : R), x ∣ r → ∀ s ∈ I, r * s ∈ J) → ∀ z ∈ I, x * z ∈ J

Next tactic:
intro h zI hzI
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
  constructor
  · intro h zI hzI
    

Proof state:
case mp
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
h : ∀ (r : R), x ∣ r → ∀ s ∈ I, r * s ∈ J
zI : R
hzI : zI ∈ I
⊢ x * zI ∈ J

Next tactic:
exact h x (dvd_refl x) zI hzI
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
  constructor
  · intro h zI hzI
    exact h x (dvd_refl x) zI hzI
  · 

Proof state:
case mpr
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
⊢ (∀ z ∈ I, x * z ∈ J) → ∀ (r : R), x ∣ r → ∀ s ∈ I, r * s ∈ J

Next tactic:
rintro h _ ⟨z, rfl⟩ zI hzI
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
  constructor
  · intro h zI hzI
    exact h x (dvd_refl x) zI hzI
  · rintro h _ ⟨z, rfl⟩ zI hzI
    

Proof state:
case mpr.intro
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
h : ∀ z ∈ I, x * z ∈ J
z zI : R
hzI : zI ∈ I
⊢ x * z * zI ∈ J

Next tactic:
rw [mul_comm x z, mul_assoc]
theorem span_singleton_mul_le_iff {x : R} {I J : Ideal R} :
    span {x} * I ≤ J ↔ ∀ z ∈ I, x * z ∈ J := by
  simp only [mul_le, mem_span_singleton_mul, mem_span_singleton]
  constructor
  · intro h zI hzI
    exact h x (dvd_refl x) zI hzI
  · rintro h _ ⟨z, rfl⟩ zI hzI
    rw [mul_comm x z, mul_assoc]
    

Proof state:
case mpr.intro
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x : R
I J : Ideal R
h : ∀ z ∈ I, x * z ∈ J
z zI : R
hzI : zI ∈ I
⊢ z * (x * zI) ∈ J

Next tactic:
exact J.mul_mem_left _ (h zI hzI)
theorem span_singleton_mul_le_span_singleton_mul {x y : R} {I J : Ideal R} :
    span {x} * I ≤ span {y} * J ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zI = y * zJ := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝ : CommSemiring R
I✝ J✝ K L : Ideal R
x y : R
I J : Ideal R
⊢ span {x} * I ≤ span {y} * J ↔ ∀ zI ∈ I, ∃ zJ ∈ J, x * zI = y * zJ

Next tactic:
simp only [span_singleton_mul_le_iff, mem_span_singleton_mul, eq_comm]
theorem span_singleton_mul_right_mono [IsDomain R] {x : R} (hx : x ≠ 0) :
    span {x} * I ≤ span {x} * J ↔ I ≤ J := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝¹ : CommSemiring R
I J K L : Ideal R
inst✝ : IsDomain R
x : R
hx : x ≠ 0
⊢ span {x} * I ≤ span {x} * J ↔ I ≤ J

Next tactic:
simp_rw [span_singleton_mul_le_span_singleton_mul, mul_right_inj' hx,
    exists_eq_right', SetLike.le_def]
theorem span_singleton_mul_left_mono [IsDomain R] {x : R} (hx : x ≠ 0) :
    I * span {x} ≤ J * span {x} ↔ I ≤ J := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝¹ : CommSemiring R
I J K L : Ideal R
inst✝ : IsDomain R
x : R
hx : x ≠ 0
⊢ I * span {x} ≤ J * span {x} ↔ I ≤ J

Next tactic:
simpa only [mul_comm I, mul_comm J] using span_singleton_mul_right_mono hx
theorem span_singleton_mul_right_inj [IsDomain R] {x : R} (hx : x ≠ 0) :
    span {x} * I = span {x} * J ↔ I = J := by
  

Proof state:
R : Type u
ι : Type u_1
inst✝¹ : CommSemiring R
I J K L : Ideal R
inst✝ : IsDomain R
x : R
hx : x ≠ 0
⊢ span {x} * I = span {x} * J ↔ I = J

Next tactic:
simp only [le_antisymm_iff, span_singleton_mul_right_mono hx]