Theorem: Subsemiring.mem_closure_iff_exists_list
File: Mathlib/RingTheory/Subsemiring/Basic.lean

tactic: constructor
state_before: R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x : R
⊢ x ∈ closure s ↔ ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x

tactic: intro hx
state_before: case mp
R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x : R
⊢ x ∈ closure s → ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x

tactic: let p : R → Prop := fun x =>
  ∃ (L : List (List R)),
    (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ (List.map List.prod L).sum = x
state_before: case mp
R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x : R
hx : x ∈ closure s
⊢ ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x

tactic: exact AddSubmonoid.closure_induction (p := p) (mem_closure_iff.1 hx)
  (fun x hx =>
    suffices ∃ t : List R, (∀ y ∈ t, y ∈ s) ∧ t.prod = x from
      let ⟨t, ht1, ht2⟩ := this
      ⟨[t], List.forall_mem_singleton.2 ht1, by
        rw [List.map_singleton, List.sum_singleton, ht2]⟩
    Submonoid.closure_induction hx
      (fun x hx => ⟨[x], List.forall_mem_singleton.2 hx, one_mul x⟩)
      ⟨[], List.forall_mem_nil _, rfl⟩ fun x y ⟨t, ht1, ht2⟩ ⟨u, hu1, hu2⟩ =>
      ⟨t ++ u, List.forall_mem_append.2 ⟨ht1, hu1⟩, by rw [List.prod_append, ht2, hu2]⟩)
  ⟨[], List.forall_mem_nil _, rfl⟩ fun x y ⟨L, HL1, HL2⟩ ⟨M, HM1, HM2⟩ =>
  ⟨L ++ M, List.forall_mem_append.2 ⟨HL1, HM1⟩, by
    rw [List.map_append, List.sum_append, HL2, HM2]⟩
state_before: case mp
R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x : R
hx : x ∈ closure s
p : R → Prop := fun x => ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x
⊢ ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x

tactic: rw [List.map_singleton, List.sum_singleton, ht2]
state_before: R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x✝ : R
hx✝ : x✝ ∈ closure s
p : R → Prop := fun x => ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x
x : R
hx : x ∈ ↑(Submonoid.closure s)
this : ∃ t, (∀ (y : R), y ∈ t → y ∈ s) ∧ List.prod t = x
t : List R
ht1 : ∀ (y : R), y ∈ t → y ∈ s
ht2 : List.prod t = x
⊢ List.sum (List.map List.prod [t]) = x

tactic: rw [List.prod_append, ht2, hu2]
state_before: R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x✝³ : R
hx✝ : x✝³ ∈ closure s
p : R → Prop := fun x => ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x
x✝² : R
hx : x✝² ∈ ↑(Submonoid.closure s)
x y : R
x✝¹ : ∃ t, (∀ (y : R), y ∈ t → y ∈ s) ∧ List.prod t = x
x✝ : ∃ t, (∀ (y : R), y ∈ t → y ∈ s) ∧ List.prod t = y
t : List R
ht1 : ∀ (y : R), y ∈ t → y ∈ s
ht2 : List.prod t = x
u : List R
hu1 : ∀ (y : R), y ∈ u → y ∈ s
hu2 : List.prod u = y
⊢ List.prod (t ++ u) = x * y

tactic: rw [List.map_append, List.sum_append, HL2, HM2]
state_before: R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M✝ : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x✝² : R
hx : x✝² ∈ closure s
p : R → Prop := fun x => ∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x
x y : R
x✝¹ : p x
x✝ : p y
L : List (List R)
HL1 : ∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s
HL2 : List.sum (List.map List.prod L) = x
M : List (List R)
HM1 : ∀ (t : List R), t ∈ M → ∀ (y : R), y ∈ t → y ∈ s
HM2 : List.sum (List.map List.prod M) = y
⊢ List.sum (List.map List.prod (L ++ M)) = x + y

tactic: rintro ⟨L, HL1, HL2⟩
state_before: case mpr
R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x : R
⊢ (∃ L, (∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s) ∧ List.sum (List.map List.prod L) = x) → x ∈ closure s

tactic: exact HL2 ▸
  list_sum_mem fun r hr =>
    let ⟨t, ht1, ht2⟩ := List.mem_map.1 hr
    ht2 ▸ list_prod_mem _ fun y hy => subset_closure <| HL1 t ht1 y hy
state_before: case mpr.intro.intro
R✝ : Type u
S : Type v
T : Type w
inst✝³ : NonAssocSemiring R✝
M : Submonoid R✝
inst✝² : NonAssocSemiring S
inst✝¹ : NonAssocSemiring T
R : Type u_1
inst✝ : Semiring R
s : Set R
x : R
L : List (List R)
HL1 : ∀ (t : List R), t ∈ L → ∀ (y : R), y ∈ t → y ∈ s
HL2 : List.sum (List.map List.prod L) = x
⊢ x ∈ closure s