File: Mathlib/Algebra/MvPolynomial/Monad.lean

full_name: MvPolynomial.bind₁
code: /--
`bind₁` is the "left hand side" bind operation on `MvPolynomial`, operating on the variable type.
Given a polynomial `p : MvPolynomial σ R` and a map `f : σ → MvPolynomial τ R` taking variables
in `p` to polynomials in the variable type `τ`, `bind₁ f p` replaces each variable in `p` with
its value under `f`, producing a new polynomial in `τ`. The coefficient type remains the same.
This operation is an algebra hom.
-/
def bind₁ (f : σ → MvPolynomial τ R) : MvPolynomial σ R →ₐ[R] MvPolynomial τ R 
goal: MvPolynomial σ R →ₐ[R] MvPolynomial τ R

full_name: MvPolynomial.bind₂
code: /-- `bind₂` is the "right hand side" bind operation on `MvPolynomial`,
operating on the coefficient type.
Given a polynomial `p : MvPolynomial σ R` and
a map `f : R → MvPolynomial σ S` taking coefficients in `p` to polynomials over a new ring `S`,
`bind₂ f p` replaces each coefficient in `p` with its value under `f`,
producing a new polynomial over `S`.
The variable type remains the same. This operation is a ring hom.
-/
def bind₂ (f : R →+* MvPolynomial σ S) : MvPolynomial σ R →+* MvPolynomial σ S 
goal: MvPolynomial σ R →+* MvPolynomial σ S

full_name: MvPolynomial.join₁
code: /--
`join₁` is the monadic join operation corresponding to `MvPolynomial.bind₁`. Given a polynomial `p`
with coefficients in `R` whose variables are polynomials in `σ` with coefficients in `R`,
`join₁ p` collapses `p` to a polynomial with variables in `σ` and coefficients in `R`.
This operation is an algebra hom.
-/
def join₁ : MvPolynomial (MvPolynomial σ R) R →ₐ[R] MvPolynomial σ R 
goal: MvPolynomial (MvPolynomial σ R) R →ₐ[R] MvPolynomial σ R

full_name: MvPolynomial.join₂
code: /--
`join₂` is the monadic join operation corresponding to `MvPolynomial.bind₂`. Given a polynomial `p`
with variables in `σ` whose coefficients are polynomials in `σ` with coefficients in `R`,
`join₂ p` collapses `p` to a polynomial with variables in `σ` and coefficients in `R`.
This operation is a ring hom.
-/
def join₂ : MvPolynomial σ (MvPolynomial σ R) →+* MvPolynomial σ R 
goal: MvPolynomial σ (MvPolynomial σ R) →+* MvPolynomial σ R

full_name: MvPolynomial.aeval_eq_bind₁
code: @[simp]
theorem aeval_eq_bind₁ (f : σ → MvPolynomial τ R) : aeval f = bind₁ f 
goal: MvPolynomial.aeval f = MvPolynomial.bind₁ f

full_name: MvPolynomial.eval₂Hom_C_eq_bind₁
code: @[simp]
theorem eval₂Hom_C_eq_bind₁ (f : σ → MvPolynomial τ R) : eval₂Hom C f = bind₁ f 
goal: MvPolynomial.eval₂Hom MvPolynomial.C f = ↑(MvPolynomial.bind₁ f)

full_name: MvPolynomial.eval₂Hom_eq_bind₂
code: @[simp]
theorem eval₂Hom_eq_bind₂ (f : R →+* MvPolynomial σ S) : eval₂Hom f X = bind₂ f 
goal: MvPolynomial.eval₂Hom f MvPolynomial.X = MvPolynomial.bind₂ f

full_name: MvPolynomial.aeval_id_eq_join₁
code: @[simp]
theorem aeval_id_eq_join₁ : aeval id = @join₁ σ R _ 
goal: MvPolynomial.aeval id = MvPolynomial.join₁

full_name: MvPolynomial.eval₂Hom_C_id_eq_join₁
code: theorem eval₂Hom_C_id_eq_join₁ (φ : MvPolynomial (MvPolynomial σ R) R) :
    eval₂Hom C id φ = join₁ φ 
goal: (MvPolynomial.eval₂Hom MvPolynomial.C id) φ = MvPolynomial.join₁ φ

full_name: MvPolynomial.eval₂Hom_id_X_eq_join₂
code: @[simp]
theorem eval₂Hom_id_X_eq_join₂ : eval₂Hom (RingHom.id _) X = @join₂ σ R _ 
goal: MvPolynomial.eval₂Hom (RingHom.id (MvPolynomial σ R)) MvPolynomial.X = MvPolynomial.join₂

full_name: MvPolynomial.bind₁_X_right
code: @[simp]
theorem bind₁_X_right (f : σ → MvPolynomial τ R) (i : σ) : bind₁ f (X i) = f i 
goal: (MvPolynomial.bind₁ f) (MvPolynomial.X i) = f i

full_name: MvPolynomial.bind₂_X_right
code: @[simp]
theorem bind₂_X_right (f : R →+* MvPolynomial σ S) (i : σ) : bind₂ f (X i) = X i 
goal: (MvPolynomial.bind₂ f) (MvPolynomial.X i) = MvPolynomial.X i

full_name: MvPolynomial.bind₁_X_left
code: @[simp]
theorem bind₁_X_left : bind₁ (X : σ → MvPolynomial σ R) = AlgHom.id R _ 
goal: MvPolynomial.bind₁ MvPolynomial.X = AlgHom.id R (MvPolynomial σ R)

full_name: MvPolynomial.bind₁_C_right
code: theorem bind₁_C_right (f : σ → MvPolynomial τ R) (x) : bind₁ f (C x) = C x 
goal: (MvPolynomial.bind₁ f) (MvPolynomial.C x) = MvPolynomial.C x

full_name: MvPolynomial.bind₂_C_right
code: @[simp]
theorem bind₂_C_right (f : R →+* MvPolynomial σ S) (r : R) : bind₂ f (C r) = f r 
goal: (MvPolynomial.bind₂ f) (MvPolynomial.C r) = f r

full_name: MvPolynomial.bind₂_C_left
code: @[simp]
theorem bind₂_C_left : bind₂ (C : R →+* MvPolynomial σ R) = RingHom.id _ 
goal: MvPolynomial.bind₂ MvPolynomial.C = RingHom.id (MvPolynomial σ R)

full_name: MvPolynomial.bind₂_comp_C
code: @[simp]
theorem bind₂_comp_C (f : R →+* MvPolynomial σ S) : (bind₂ f).comp C = f 
goal: (MvPolynomial.bind₂ f).comp MvPolynomial.C = f

full_name: MvPolynomial.join₂_map
code: @[simp]
theorem join₂_map (f : R →+* MvPolynomial σ S) (φ : MvPolynomial σ R) :
    join₂ (map f φ) = bind₂ f φ 
goal: MvPolynomial.join₂ ((MvPolynomial.map f) φ) = (MvPolynomial.bind₂ f) φ

full_name: MvPolynomial.join₂_comp_map
code: @[simp]
theorem join₂_comp_map (f : R →+* MvPolynomial σ S) : join₂.comp (map f) = bind₂ f 
goal: MvPolynomial.join₂.comp (MvPolynomial.map f) = MvPolynomial.bind₂ f

full_name: MvPolynomial.aeval_id_rename
code: theorem aeval_id_rename (f : σ → MvPolynomial τ R) (p : MvPolynomial σ R) :
    aeval id (rename f p) = aeval f p 
goal: (MvPolynomial.aeval id) ((MvPolynomial.rename f) p) = (MvPolynomial.aeval f) p

full_name: MvPolynomial.join₁_rename
code: @[simp]
theorem join₁_rename (f : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) :
    join₁ (rename f φ) = bind₁ f φ 
goal: MvPolynomial.join₁ ((MvPolynomial.rename f) φ) = (MvPolynomial.bind₁ f) φ

full_name: MvPolynomial.bind₁_id
code: @[simp]
theorem bind₁_id : bind₁ (@id (MvPolynomial σ R)) = join₁ 
goal: MvPolynomial.bind₁ id = MvPolynomial.join₁

full_name: MvPolynomial.bind₂_id
code: @[simp]
theorem bind₂_id : bind₂ (RingHom.id (MvPolynomial σ R)) = join₂ 
goal: MvPolynomial.bind₂ (RingHom.id (MvPolynomial σ R)) = MvPolynomial.join₂

full_name: MvPolynomial.bind₁_bind₁
code: theorem bind₁_bind₁ {υ : Type*} (f : σ → MvPolynomial τ R) (g : τ → MvPolynomial υ R)
    (φ : MvPolynomial σ R) : (bind₁ g) (bind₁ f φ) = bind₁ (fun i => bind₁ g (f i)) φ 
goal: (MvPolynomial.bind₁ g) ((MvPolynomial.bind₁ f) φ) = (MvPolynomial.bind₁ fun i => (MvPolynomial.bind₁ g) (f i)) φ

full_name: MvPolynomial.bind₁_comp_bind₁
code: theorem bind₁_comp_bind₁ {υ : Type*} (f : σ → MvPolynomial τ R) (g : τ → MvPolynomial υ R) :
    (bind₁ g).comp (bind₁ f) = bind₁ fun i => bind₁ g (f i) 
goal: (MvPolynomial.bind₁ g).comp (MvPolynomial.bind₁ f) = MvPolynomial.bind₁ fun i => (MvPolynomial.bind₁ g) (f i)

full_name: MvPolynomial.bind₂_comp_bind₂
code: theorem bind₂_comp_bind₂ (f : R →+* MvPolynomial σ S) (g : S →+* MvPolynomial σ T) :
    (bind₂ g).comp (bind₂ f) = bind₂ ((bind₂ g).comp f) 
goal: (MvPolynomial.bind₂ g).comp (MvPolynomial.bind₂ f) = MvPolynomial.bind₂ ((MvPolynomial.bind₂ g).comp f)

full_name: MvPolynomial.bind₂_bind₂
code: theorem bind₂_bind₂ (f : R →+* MvPolynomial σ S) (g : S →+* MvPolynomial σ T)
    (φ : MvPolynomial σ R) : (bind₂ g) (bind₂ f φ) = bind₂ ((bind₂ g).comp f) φ 
goal: (MvPolynomial.bind₂ g) ((MvPolynomial.bind₂ f) φ) = (MvPolynomial.bind₂ ((MvPolynomial.bind₂ g).comp f)) φ

full_name: MvPolynomial.rename_comp_bind₁
code: theorem rename_comp_bind₁ {υ : Type*} (f : σ → MvPolynomial τ R) (g : τ → υ) :
    (rename g).comp (bind₁ f) = bind₁ fun i => rename g <| f i 
goal: (MvPolynomial.rename g).comp (MvPolynomial.bind₁ f) = MvPolynomial.bind₁ fun i => (MvPolynomial.rename g) (f i)

full_name: MvPolynomial.rename_bind₁
code: theorem rename_bind₁ {υ : Type*} (f : σ → MvPolynomial τ R) (g : τ → υ) (φ : MvPolynomial σ R) :
    rename g (bind₁ f φ) = bind₁ (fun i => rename g <| f i) φ 
goal: (MvPolynomial.rename g) ((MvPolynomial.bind₁ f) φ) = (MvPolynomial.bind₁ fun i => (MvPolynomial.rename g) (f i)) φ

full_name: MvPolynomial.map_bind₂
code: theorem map_bind₂ (f : R →+* MvPolynomial σ S) (g : S →+* T) (φ : MvPolynomial σ R) :
    map g (bind₂ f φ) = bind₂ ((map g).comp f) φ 
goal: (MvPolynomial.map g) ((MvPolynomial.bind₂ f) φ) = (MvPolynomial.bind₂ ((MvPolynomial.map g).comp f)) φ

full_name: MvPolynomial.bind₁_comp_rename
code: theorem bind₁_comp_rename {υ : Type*} (f : τ → MvPolynomial υ R) (g : σ → τ) :
    (bind₁ f).comp (rename g) = bind₁ (f ∘ g) 
goal: (MvPolynomial.bind₁ f).comp (MvPolynomial.rename g) = MvPolynomial.bind₁ (f ∘ g)

full_name: MvPolynomial.bind₁_rename
code: theorem bind₁_rename {υ : Type*} (f : τ → MvPolynomial υ R) (g : σ → τ) (φ : MvPolynomial σ R) :
    bind₁ f (rename g φ) = bind₁ (f ∘ g) φ 
goal: (MvPolynomial.bind₁ f) ((MvPolynomial.rename g) φ) = (MvPolynomial.bind₁ (f ∘ g)) φ

full_name: MvPolynomial.bind₂_map
code: theorem bind₂_map (f : S →+* MvPolynomial σ T) (g : R →+* S) (φ : MvPolynomial σ R) :
    bind₂ f (map g φ) = bind₂ (f.comp g) φ 
goal: (MvPolynomial.bind₂ f) ((MvPolynomial.map g) φ) = (MvPolynomial.bind₂ (f.comp g)) φ

full_name: MvPolynomial.map_comp_C
code: @[simp]
theorem map_comp_C (f : R →+* S) : (map f).comp (C : R →+* MvPolynomial σ R) = C.comp f 
goal: (MvPolynomial.map f).comp MvPolynomial.C = MvPolynomial.C.comp f

full_name: MvPolynomial.hom_bind₁
code: theorem hom_bind₁ (f : MvPolynomial τ R →+* S) (g : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) :
    f (bind₁ g φ) = eval₂Hom (f.comp C) (fun i => f (g i)) φ 
goal: f ((MvPolynomial.bind₁ g) φ) = (MvPolynomial.eval₂Hom (f.comp MvPolynomial.C) fun i => f (g i)) φ

full_name: MvPolynomial.map_bind₁
code: theorem map_bind₁ (f : R →+* S) (g : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) :
    map f (bind₁ g φ) = bind₁ (fun i : σ => (map f) (g i)) (map f φ) 
goal: (MvPolynomial.map f) ((MvPolynomial.bind₁ g) φ) =
  (MvPolynomial.bind₁ fun i => (MvPolynomial.map f) (g i)) ((MvPolynomial.map f) φ)

full_name: MvPolynomial.eval₂Hom_comp_C
code: @[simp]
theorem eval₂Hom_comp_C (f : R →+* S) (g : σ → S) : (eval₂Hom f g).comp C = f 
goal: (MvPolynomial.eval₂Hom f g).comp MvPolynomial.C = f

full_name: MvPolynomial.eval₂Hom_bind₁
code: theorem eval₂Hom_bind₁ (f : R →+* S) (g : τ → S) (h : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) :
    eval₂Hom f g (bind₁ h φ) = eval₂Hom f (fun i => eval₂Hom f g (h i)) φ 
goal: (MvPolynomial.eval₂Hom f g) ((MvPolynomial.bind₁ h) φ) =
  (MvPolynomial.eval₂Hom f fun i => (MvPolynomial.eval₂Hom f g) (h i)) φ

full_name: MvPolynomial.aeval_bind₁
code: theorem aeval_bind₁ [Algebra R S] (f : τ → S) (g : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) :
    aeval f (bind₁ g φ) = aeval (fun i => aeval f (g i)) φ 
goal: (MvPolynomial.aeval f) ((MvPolynomial.bind₁ g) φ) = (MvPolynomial.aeval fun i => (MvPolynomial.aeval f) (g i)) φ

full_name: MvPolynomial.aeval_comp_bind₁
code: theorem aeval_comp_bind₁ [Algebra R S] (f : τ → S) (g : σ → MvPolynomial τ R) :
    (aeval f).comp (bind₁ g) = aeval fun i => aeval f (g i) 
goal: (MvPolynomial.aeval f).comp (MvPolynomial.bind₁ g) = MvPolynomial.aeval fun i => (MvPolynomial.aeval f) (g i)

full_name: MvPolynomial.eval₂Hom_comp_bind₂
code: theorem eval₂Hom_comp_bind₂ (f : S →+* T) (g : σ → T) (h : R →+* MvPolynomial σ S) :
    (eval₂Hom f g).comp (bind₂ h) = eval₂Hom ((eval₂Hom f g).comp h) g 
goal: (MvPolynomial.eval₂Hom f g).comp (MvPolynomial.bind₂ h) = MvPolynomial.eval₂Hom ((MvPolynomial.eval₂Hom f g).comp h) g

full_name: MvPolynomial.eval₂Hom_bind₂
code: theorem eval₂Hom_bind₂ (f : S →+* T) (g : σ → T) (h : R →+* MvPolynomial σ S)
    (φ : MvPolynomial σ R) : eval₂Hom f g (bind₂ h φ) = eval₂Hom ((eval₂Hom f g).comp h) g φ 
goal: (MvPolynomial.eval₂Hom f g) ((MvPolynomial.bind₂ h) φ) =
  (MvPolynomial.eval₂Hom ((MvPolynomial.eval₂Hom f g).comp h) g) φ

full_name: MvPolynomial.aeval_bind₂
code: theorem aeval_bind₂ [Algebra S T] (f : σ → T) (g : R →+* MvPolynomial σ S) (φ : MvPolynomial σ R) :
    aeval f (bind₂ g φ) = eval₂Hom ((↑(aeval f : _ →ₐ[S] _) : _ →+* _).comp g) f φ 
goal: (MvPolynomial.aeval f) ((MvPolynomial.bind₂ g) φ) = (MvPolynomial.eval₂Hom ((↑(MvPolynomial.aeval f)).comp g) f) φ

full_name: MvPolynomial.eval₂Hom_C_left
code: theorem eval₂Hom_C_left (f : σ → MvPolynomial τ R) : eval₂Hom C f = bind₁ f 
goal: MvPolynomial.eval₂Hom MvPolynomial.C f = ↑(MvPolynomial.bind₁ f)

full_name: MvPolynomial.bind₁_monomial
code: theorem bind₁_monomial (f : σ → MvPolynomial τ R) (d : σ →₀ ℕ) (r : R) :
    bind₁ f (monomial d r) = C r * ∏ i ∈ d.support, f i ^ d i 
goal: (MvPolynomial.bind₁ f) ((MvPolynomial.monomial d) r) = MvPolynomial.C r * ∏ i ∈ d.support, f i ^ d i

full_name: MvPolynomial.bind₂_monomial
code: theorem bind₂_monomial (f : R →+* MvPolynomial σ S) (d : σ →₀ ℕ) (r : R) :
    bind₂ f (monomial d r) = f r * monomial d 1 
goal: (MvPolynomial.bind₂ f) ((MvPolynomial.monomial d) r) = f r * (MvPolynomial.monomial d) 1

full_name: MvPolynomial.bind₂_monomial_one
code: @[simp]
theorem bind₂_monomial_one (f : R →+* MvPolynomial σ S) (d : σ →₀ ℕ) :
    bind₂ f (monomial d 1) = monomial d 1 
goal: (MvPolynomial.bind₂ f) ((MvPolynomial.monomial d) 1) = (MvPolynomial.monomial d) 1

full_name: MvPolynomial.vars_bind₁
code: theorem vars_bind₁ [DecidableEq τ] (f : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) :
    (bind₁ f φ).vars ⊆ φ.vars.biUnion fun i => (f i).vars 
goal: ((MvPolynomial.bind₁ f) φ).vars ⊆ φ.vars.biUnion fun i => (f i).vars

full_name: MvPolynomial.mem_vars_bind₁
code: theorem mem_vars_bind₁ (f : σ → MvPolynomial τ R) (φ : MvPolynomial σ R) {j : τ}
    (h : j ∈ (bind₁ f φ).vars) : ∃ i : σ, i ∈ φ.vars ∧ j ∈ (f i).vars 
goal: ∃ i ∈ φ.vars, j ∈ (f i).vars

full_name: MvPolynomial.monad
code: instance monad : Monad fun σ => MvPolynomial σ R 
goal: Monad fun σ => MvPolynomial σ R

full_name: MvPolynomial.lawfulFunctor
code: instance lawfulFunctor : LawfulFunctor fun σ => MvPolynomial σ R 
goal: LawfulFunctor fun σ => MvPolynomial σ R

full_name: MvPolynomial.lawfulMonad
code: instance lawfulMonad : LawfulMonad fun σ => MvPolynomial σ R 
goal: LawfulMonad fun σ => MvPolynomial σ R