File: Mathlib/Algebra/Ring/SumsOfSquares.lean

full_name: isSumSq.sq_add
code: /--
In a type `R` with an addition, a zero element and a multiplication, the property of being a sum of
squares is defined by an inductive predicate: `0 : R` is a sum of squares and if `S` is a sum of
squares, then for all `a : R`, `a * a + S` is a sum of squares in `R`.
-/
@[mk_iff]
inductive isSumSq [Add R] [Zero R] : R → Prop
  | zero                              : isSumSq 0
  | sq_add (a S : R) (pS : isSumSq S) : isSumSq (a * a + S)
goal: isSumSq (a * a + S)

full_name: isSumSq
code: /--
In a type `R` with an addition, a zero element and a multiplication, the property of being a sum of
squares is defined by an inductive predicate: `0 : R` is a sum of squares and if `S` is a sum of
squares, then for all `a : R`, `a * a + S` is a sum of squares in `R`.
-/
@[mk_iff]
inductive isSumSq [Add R] [Zero R] : R → Prop
  | zero                              : isSumSq 0
  | sq_add (a S : R) (pS : isSumSq S) : isSumSq (a * a + S)
goal: R → Prop

full_name: isSumSq.zero
code: /--
In a type `R` with an addition, a zero element and a multiplication, the property of being a sum of
squares is defined by an inductive predicate: `0 : R` is a sum of squares and if `S` is a sum of
squares, then for all `a : R`, `a * a + S` is a sum of squares in `R`.
-/
@[mk_iff]
inductive isSumSq [Add R] [Zero R] : R → Prop
  | zero                              : isSumSq 0
  | sq_add (a S : R) (pS : isSumSq S) : isSumSq (a * a + S)
goal: isSumSq 0

full_name: isSumSq_iff
code: /--
In a type `R` with an addition, a zero element and a multiplication, the property of being a sum of
squares is defined by an inductive predicate: `0 : R` is a sum of squares and if `S` is a sum of
squares, then for all `a : R`, `a * a + S` is a sum of squares in `R`.
-/
@[mk_iff]
inductive isSumSq [Add R] [Zero R] : R → Prop
  | zero                              : isSumSq 0
  | sq_add (a S : R) (pS : isSumSq S) : isSumSq (a * a + S)
goal: ∀ (a : R), isSumSq a ↔ a = 0 ∨ ∃ a_1 S, isSumSq S ∧ a = a_1 * a_1 + S

full_name: isSumSq.add
code: /--
If `S1` and `S2` are sums of squares in a semiring `R`, then `S1 + S2` is a sum of squares in `R`.
-/
theorem isSumSq.add [AddMonoid R] {S1 S2 : R} (p1 : isSumSq S1)
    (p2 : isSumSq S2) : isSumSq (S1 + S2) 
goal: isSumSq (S1 + S2)

full_name: SumSqIn
code: /--
In an additive monoid with multiplication `R`, the type `SumSqIn R` is the submonoid of sums of
squares in `R`.
-/
def SumSqIn [AddMonoid R] : AddSubmonoid R 
goal: AddSubmonoid R

full_name: SquaresInSumSq
code: /--
In an additive monoid with multiplication, every square is a sum of squares. By definition, a square
in `R` is a term `x : R` such that `x = y * y` for some `y : R` and in Mathlib this is known as
`IsSquare R` (see Mathlib.Algebra.Group.Even).
-/
theorem SquaresInSumSq [AddMonoid R] {x : R} (px : IsSquare x) : x ∈ SumSqIn R 
goal: x ∈ SumSqIn R

full_name: SquaresAddClosure
code: /--
In an additive monoid with multiplication `R`, the submonoid generated by the squares is the set of
sums of squares.
-/
theorem SquaresAddClosure [AddMonoid R] : closure IsSquare = SumSqIn R 
goal: AddSubmonoid.closure IsSquare = SumSqIn R

full_name: isSumSq.nonneg
code: /--
Let `R` be a linearly ordered semiring in which the property `a ≤ b → ∃ c, a + c = b` holds
(e.g. `R = ℕ`). If `S : R` is a sum of squares in `R`, then `0 ≤ S`. This is used in
`Mathlib.Algebra.Ring.Semireal.Defs` to show that linearly ordered fields are semireal.
-/
theorem isSumSq.nonneg {R : Type*} [LinearOrderedSemiring R] [ExistsAddOfLE R] {S : R}
    (pS : isSumSq S) : 0 ≤ S 
goal: 0 ≤ S