1-- Adjoining an element to an ideal in a commutative ring (ZF).2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Algebra.Ring.IdealAdjoin8import IdealCore910-- I + (x): finite algebra, with no choice of generators or representatives.11def idealAdjoin (A add mul I x : Set) : Set:=12 {z ∈ A |∃ i ∈ I, ∃ a ∈ A, z = call2(add, i, call2(mul, a, x))}1314theorem idealAdjoin.contains (A add zero neg mul one I x : Set)15requiresring : IsCommRing(A, add, zero, neg, mul, one)16requires ideal : IsIdeal(A, add, zero, neg, mul, I)17requires hx : x ∈ A18shows I ⊆ idealAdjoin(A, add, mul, I, x)19proof20have ordinary := IsCommRing.ring withring21have zeroInA := IsRing.zero_in_carrier with ordinary22have bounded := IsIdeal.subset_carrier with ideal23intros i hi24have iInA := bounded with i, hi25have equation : i = call2(add, i, call2(mul, zero, x)) byring26exact idealAdjoin.membership.backward with⟨iInA, i, hi, zero, zeroInA, equation⟩2728theorem idealAdjoin.generator (A add zero neg mul one I x : Set)29requiresring : IsCommRing(A, add, zero, neg, mul, one)30requires ideal : IsIdeal(A, add, zero, neg, mul, I)31requires hx : x ∈ A32shows x ∈ idealAdjoin(A, add, mul, I, x)33proof34have ordinary := IsCommRing.ring withring35have monoid := IsRing.multiplicative with ordinary36have oneInA := IsMonoid.unit_in_carrier with monoid37have zeroIn := IsIdeal.zero_closed with ideal38have equation : x = call2(add, zero, call2(mul, one, x)) byring39exact idealAdjoin.membership.backward with⟨hx, zero, zeroIn, one, oneInA, equation⟩4041theorem idealAdjoin.ideal (A add zero neg mul one I x : Set)42requiresring : IsCommRing(A, add, zero, neg, mul, one)43requires ideal : IsIdeal(A, add, zero, neg, mul, I)44requires hx : x ∈ A45shows IsIdeal(A, add, zero, neg, mul, idealAdjoin(A, add, mul, I, x))46proof47have ordinary := IsCommRing.ring withring48have boundedI := IsIdeal.subset_carrier with ideal49have contains := idealAdjoin.contains with*50have zeroInI := IsIdeal.zero_closed with ideal51have zeroIn := contains with zero, zeroInI52unfold IsIdeal53refine⟨?_, ⟨zeroIn, ⟨?_, ⟨?_, ?_⟩⟩⟩⟩54intros z hz55have data := idealAdjoin.membership.forward with hz56exact data.left57 . intros z hz w hw58obtain⟨zInA, i, hi, a, ha, zValue⟩:= idealAdjoin.membership.forward with hz59obtain⟨wInA, j, hj, b, hb, wValue⟩:= idealAdjoin.membership.forward with hw60have iInA := boundedI with i, hi61have jInA := boundedI with j, hj62have sumInA := IsRing.add_closed at A, add, zero, neg, mul, one, z, w with*63have sumInI := IsIdeal.add_closed with hi, hj64have coefficientInA := IsRing.add_closed with ha, hb65have equation : call2(add, z, w) = call2(add, call2(add, i, j), call2(mul, call2(add, a, b), x))66rw [zValue, wValue]67ring68exact idealAdjoin.membership.backward with⟨sumInA, call2(add, i, j), sumInI, call2(add, a, b), coefficientInA, equation⟩69 . intros z hz70obtain⟨zInA, n, hn, d, hd, value⟩:= idealAdjoin.membership.forward with hz71have jInA := boundedI with n, hn72have negInA := IsRing.neg_closed at A, add, zero, neg, mul, one, z with*73have negInI := IsIdeal.neg_closed with hn74have coefficientInA := IsRing.neg_closed with hd75have equation : neg(z) = call2(add, neg(n), call2(mul, neg(d), x))76rw value77ring78exact idealAdjoin.membership.backward with⟨negInA, neg(n), negInI, neg(d), coefficientInA, equation⟩79 . intros t ht z hz80obtain⟨zInA, k, hk, c, hc, value⟩:= idealAdjoin.membership.forward with hz81have kInA := boundedI with k, hk82have leftInA := IsRing.mul_closed at A, add, zero, neg, mul, one, t,83 z with*84have rightInA := IsRing.mul_closed at A, add, zero, neg, mul, one, z,85 t with*86have productInI := IsIdeal.mul_left_closed with ht, hk87have coefficientInA := IsRing.mul_closed with ht, hc88have equation : call2(mul, t, z) = call2(add, call2(mul, t, k), call2(mul, call2(mul, t, c), x))89rw value90ring91have reverse := IsCommRing.mul_comm at A, add, zero, neg, mul, one, z, t with*92constructor93 . apply idealAdjoin.membership.backward at94 A, add, mul, I, x, call2(mul, t, z)95refine⟨leftInA, call2(mul, t, k), productInI, call2(mul, t, c), coefficientInA, equation⟩96 . rw reverse97exact idealAdjoin.membership.backward with⟨leftInA, call2(mul, t, k), productInI, call2(mul, t, c), coefficientInA, equation⟩9899theorem idealAdjoin.least (A add zero neg mul I x J : Set)100requires idealJ : IsIdeal(A, add, zero, neg, mul, J)101requires contains : I ⊆ J102requires generator : x ∈ J103shows idealAdjoin(A, add, mul, I, x) ⊆ J104proof105intros z hz106obtain⟨zInA, i, hi, a, ha, value⟩:= idealAdjoin.membership.forward with hz107have iInJ := contains with i, hi108have product := IsIdeal.mul_left_closed at A, add, zero, neg, mul, J, a, x with*109have sum := IsIdeal.add_closed at A, add, zero, neg, mul, J, i, call2(mul, a, x) with*110 rwa value111112theorem IsMaximalIdeal.bezout (A add zero neg mul one I x : Set)113requiresring : IsCommRing(A, add, zero, neg, mul, one)114requires maximal : IsMaximalIdeal(A, add, zero, neg, mul, one, I)115requires hx : x ∈ A116requires outside : ¬(x ∈ I)117shows∃ i ∈ I, ∃ a ∈ A, one = call2(add, i, call2(mul, a, x))118proof119have ideal : IsIdeal(A, add, zero, neg, mul, I) bysimp [IsMaximalIdeal, IsProperIdeal]120have ordinary := IsCommRing.ring withring121have monoid := IsRing.multiplicative with ordinary122have oneInA := IsMonoid.unit_in_carrier with monoid123have adjoinIdeal := idealAdjoin.ideal at A, add, zero, neg, mul, one, I, x with*124have contains := idealAdjoin.contains at A, add, zero, neg, mul, one, I, x with*125have generator := idealAdjoin.generator at A, add, zero, neg, mul, one, I, x with*126have alternatives := IsMaximalIdeal.eq_or_whole with*127cases alternatives with same | whole128 . rw same at generator129exfalso130exact outside with generator131 . have oneIn : one ∈ idealAdjoin(A, add, mul, I, x)132 rwa whole133have data := idealAdjoin.membership.forward with oneIn134exact data.right135