1-- Two-sided ideals of a bundled ring: Ideal(R, I) under a ring hypothesis,2-- the proper and maximal ideals, the ring notation on the elements of an3-- ideal, the bridges to the forms over separate pieces, and the closure4-- instances; everything here is ZF5-- Part of Cumulus, the Grace17 mathematics library.6-- Copyright (c) 2026 Grant Passmore.7-- Released under the Apache License 2.0. See LICENSE in the repository root.8-- Authors: Grant Passmore910module Grace.Cumulus.Algebra.Ring.Ideal11import Basic12import IdealCore1314-- Under a hypothesis Ring(R), an ideal of R is a subset containing zero and15-- closed under addition, negation, and multiplication by any element of R16-- on either side; a proper ideal omits one, and a maximal ideal is a proper17-- ideal contained in no larger proper ideal. The predicates take the ring18-- first, Ideal(R, I), and their bodies read the operations off the19-- hypothesis, so each is a formula over R.add, R.zero, R.neg, and R.mul20-- alone. IsIdeal(A, add, zero, neg, mul, I), IsProperIdeal(A, …, one, I),21-- and IsMaximalIdeal(A, …, one, M) remain the forms over separate pieces,22-- bridged below.23section Definitions24variable (R : Set)25hypothesisring : Ring(R)2627predicate Ideal (I : Set) :=28 I ⊆ R ∧ R[0] ∈ I ∧ (∀ x y ∈ I, x + y ∈ I) ∧29 (∀ x ∈ I, -x ∈ I) ∧ (∀ a ∈ R, ∀ x ∈ I, a * x ∈ I ∧ x * a ∈ I)30predicate ProperIdeal (I : Set) := Ideal(I) ∧ R[1] ∉ I31predicate MaximalIdeal (M : Set) :=32 ProperIdeal(M) ∧ (∀ J, ProperIdeal(J) → M ⊆ J → J = M)3334end Definitions3536-- On the elements of an ideal the operations are written as in the ring:37-- under Ideal(R, I) a binder (x : I) is x ∈ I, and x + y, x * y, -x, and38-- x - y are the operations of R.39notationinfixl60"+"=> call2(R.add, _, _) viahypothesis Ideal(R, I) for I40notationinfixl70"*"=> call2(R.mul, _, _) viahypothesis Ideal(R, I) for I41notationprefix75"-"=>apply(R.neg, _) viahypothesis Ideal(R, I) for I42notationinfixl60"-"=> Ring.sub(R, _, _) viahypothesis Ideal(R, I) for I43notationinfixl60"+"=> call2(R.add, _, _) viahypothesis ProperIdeal(R, I) for I44notationinfixl70"*"=> call2(R.mul, _, _) viahypothesis ProperIdeal(R, I) for I45notationprefix75"-"=>apply(R.neg, _) viahypothesis ProperIdeal(R, I) for I46notationinfixl60"-"=> Ring.sub(R, _, _) viahypothesis ProperIdeal(R, I) for I47notationinfixl60"+"=> call2(R.add, _, _) viahypothesis MaximalIdeal(R, I) for I48notationinfixl70"*"=> call2(R.mul, _, _) viahypothesis MaximalIdeal(R, I) for I49notationprefix75"-"=>apply(R.neg, _) viahypothesis MaximalIdeal(R, I) for I50notationinfixl60"-"=> Ring.sub(R, _, _) viahypothesis MaximalIdeal(R, I) for I5152-- Bridges between the bundled predicates and the forms over separate53-- pieces. The bundled-to-unbundled directions are instances, so `with *`54-- reads the unbundled form off a bundled hypothesis; of_projections comes55-- back for a ring value, and of_parts for a constructed ring.56instance Ideal.parts (R I : Set)57requires ideal : Ideal(R, I)58shows IsIdeal(R.carrier, R.add, R.zero, R.neg, R.mul, I)59proof60obtain⟨bounded, zeroIn, sums, negatives, products⟩:= ideal61unfold IsIdeal62exact⟨bounded, zeroIn, sums, negatives, products⟩6364theorem Ideal.of_projections (R I : Set)65requires ideal : IsIdeal(R.carrier, R.add, R.zero, R.neg, R.mul, I)66shows Ideal(R, I)67proof68obtain⟨bounded, zeroIn, sums, negatives, products⟩:= ideal69unfold Ideal.Ideal70exact⟨bounded, zeroIn, sums, negatives, products⟩7172theorem Ideal.of_parts (A add zero neg mul one I : Set)73requires ideal : IsIdeal(A, add, zero, neg, mul, I)74shows Ideal(Ring.mk(A, add, zero, neg, mul, one), I)75proof76have shifted : IsIdeal(Ring.carrier(Ring.mk(A, add, zero, neg, mul, one)),77 Ring.add(Ring.mk(A, add, zero, neg, mul, one)),78 Ring.zero(Ring.mk(A, add, zero, neg, mul, one)),79 Ring.neg(Ring.mk(A, add, zero, neg, mul, one)),80 Ring.mul(Ring.mk(A, add, zero, neg, mul, one)), I)81 ring_projections82exact Ideal.of_projections with shifted8384instance ProperIdeal.parts (R I : Set)85requires proper : ProperIdeal(R, I)86shows IsProperIdeal(R.carrier, R.add, R.zero, R.neg, R.mul, R.one, I)87proof88obtain⟨ideal, oneOut⟩:= proper89have parts := Ideal.parts with ideal90unfold IsProperIdeal91exact⟨parts, oneOut⟩9293theorem ProperIdeal.of_projections (R I : Set)94requires proper : IsProperIdeal(R.carrier, R.add, R.zero, R.neg, R.mul, R.one, I)95shows ProperIdeal(R, I)96proof97obtain⟨ideal, oneOut⟩:= proper98have bundled := Ideal.of_projections with ideal99unfold Ideal.ProperIdeal100exact⟨bundled, oneOut⟩101102theorem ProperIdeal.of_parts (A add zero neg mul one I : Set)103requires proper : IsProperIdeal(A, add, zero, neg, mul, one, I)104shows ProperIdeal(Ring.mk(A, add, zero, neg, mul, one), I)105proof106have shifted : IsProperIdeal(Ring.carrier(Ring.mk(A, add, zero, neg, mul, one)),107 Ring.add(Ring.mk(A, add, zero, neg, mul, one)),108 Ring.zero(Ring.mk(A, add, zero, neg, mul, one)),109 Ring.neg(Ring.mk(A, add, zero, neg, mul, one)),110 Ring.mul(Ring.mk(A, add, zero, neg, mul, one)),111 Ring.one(Ring.mk(A, add, zero, neg, mul, one)), I)112 ring_projections113exact ProperIdeal.of_projections with shifted114115instance MaximalIdeal.parts (R M : Set)116requires maximal : MaximalIdeal(R, M)117shows IsMaximalIdeal(R.carrier, R.add, R.zero, R.neg, R.mul, R.one, M)118proof119obtain⟨proper, largest⟩:= maximal120have parts := ProperIdeal.parts with proper121unfold IsMaximalIdeal122refine⟨parts, ?_⟩123intros J properJ contains124have bundledJ := ProperIdeal.of_projections with properJ125exact largest with J, bundledJ, contains126127theorem MaximalIdeal.of_projections (R M : Set)128requires maximal : IsMaximalIdeal(R.carrier, R.add, R.zero, R.neg, R.mul, R.one, M)129shows MaximalIdeal(R, M)130proof131obtain⟨proper, largest⟩:= maximal132have bundled := ProperIdeal.of_projections with proper133unfold Ideal.MaximalIdeal134refine⟨bundled, ?_⟩135intros J properJ contains136have partsJ := ProperIdeal.parts with properJ137exact largest with J, partsJ, contains138139theorem MaximalIdeal.of_parts (A add zero neg mul one M : Set)140requires maximal : IsMaximalIdeal(A, add, zero, neg, mul, one, M)141shows MaximalIdeal(Ring.mk(A, add, zero, neg, mul, one), M)142proof143have shifted : IsMaximalIdeal(Ring.carrier(Ring.mk(A, add, zero, neg, mul, one)),144 Ring.add(Ring.mk(A, add, zero, neg, mul, one)),145 Ring.zero(Ring.mk(A, add, zero, neg, mul, one)),146 Ring.neg(Ring.mk(A, add, zero, neg, mul, one)),147 Ring.mul(Ring.mk(A, add, zero, neg, mul, one)),148 Ring.one(Ring.mk(A, add, zero, neg, mul, one)), M)149 ring_projections150exact MaximalIdeal.of_projections with shifted151152-- The projections down the hierarchy; the instance paths form a chain.153instance ProperIdeal.to_ideal (R I : Set)154requires proper : ProperIdeal(R, I)155shows Ideal(R, I)156proof157obtain⟨ideal, oneOut⟩:= proper158exact ideal159160theorem ProperIdeal.one_not_mem (R I : Set)161requires proper : ProperIdeal(R, I)162shows R[1] ∉ I163proof164obtain⟨ideal, oneOut⟩:= proper165exact oneOut166167instance MaximalIdeal.to_proper (R M : Set)168requires maximal : MaximalIdeal(R, M)169shows ProperIdeal(R, M)170proof171obtain⟨proper, largest⟩:= maximal172exact proper173174theorem MaximalIdeal.to_ideal (R M : Set)175requires maximal : MaximalIdeal(R, M)176shows Ideal(R, M)177proof178have proper := MaximalIdeal.to_proper with maximal179exact ProperIdeal.to_ideal with proper180181section IdealLaws182variable (R I : Set)183hypothesis ideal : Ideal(R, I)184185theorem Ideal.subset186shows I ⊆ R.carrier187proof188obtain⟨bounded, rest⟩:= ideal189exact bounded190191-- Closure: the carrier membership of an element of the ideal is a typing192-- rule, and the membership of zero, a sum, and a negation are instances,193-- so each is synthesized.194theorem Ideal.mem_carrier (x : I)195shows x ∈ R.carrier196proof197have bounded := Ideal.subset with ideal198have xIn : x ∈ I byassumption199exact bounded with x, xIn200201instance Ideal.zero_mem202shows R[0] ∈ I203proof204obtain⟨bounded, zeroIn, rest⟩:= ideal205exact zeroIn206207instance Ideal.add_mem (x y : I)208shows x + y ∈ I209proof210obtain⟨bounded, zeroIn, sums, negatives, products⟩:= ideal211have xIn : x ∈ I byassumption212have yIn : y ∈ I byassumption213exact sums with x, xIn, y, yIn214215instance Ideal.neg_mem (x : I)216shows -x ∈ I217proof218obtain⟨bounded, zeroIn, sums, negatives, products⟩:= ideal219have xIn : x ∈ I byassumption220exact negatives with x, xIn221222theorem Ideal.nonempty223shows Nonempty(I)224proof225have zeroIn : R[0] ∈ I := Ideal.zero_mem with*226exact⟨R[0], zeroIn⟩227228end IdealLaws229230section IdealAbsorption231variable (R I : Set)232hypothesisring : Ring(R)233hypothesis ideal : Ideal(R, I)234235-- Absorption on either side, and closure under subtraction.236instance Ideal.mul_left_mem (a : R) (x : I)237shows a * x ∈ I238proof239obtain⟨bounded, zeroIn, sums, negatives, products⟩:= ideal240have aIn : a ∈ R byassumption241have xIn : x ∈ I byassumption242have both := products with a, aIn, x, xIn243exact both.left244245instance Ideal.mul_right_mem (a : R) (x : I)246shows x * a ∈ I247proof248obtain⟨bounded, zeroIn, sums, negatives, products⟩:= ideal249have aIn : a ∈ R byassumption250have xIn : x ∈ I byassumption251have both := products with a, aIn, x, xIn252exact both.right253254instance Ideal.sub_mem (x y : I)255shows x - y ∈ I256proof257have xIn : x ∈ R := Ideal.mem_carrier with*258have yIn : y ∈ R := Ideal.mem_carrier with*259have negIn : -y ∈ I := Ideal.neg_mem with*260rw Ring.sub.value261exact Ideal.add_mem with*262263end IdealAbsorption264265section IdealConstructions266variable (R : Set)267hypothesisring : Ring(R)268269-- The constructor.270theorem Ideal.mk (I : Set)271requires bounded : I ⊆ R272requires zeroIn : R[0] ∈ I273requires sums : ∀ x y ∈ I, x + y ∈ I274requires negatives : ∀ x ∈ I, -x ∈ I275requires products : ∀ a ∈ R, ∀ x ∈ I, a * x ∈ I ∧ x * a ∈ I276shows Ideal(R, I)277proof278unfold Ideal.Ideal279exact⟨bounded, zeroIn, sums, negatives, products⟩280281theorem ProperIdeal.mk (I : Set)282requires ideal : Ideal(R, I)283requires oneOut : R[1] ∉ I284shows ProperIdeal(R, I)285proof286unfold Ideal.ProperIdeal287exact⟨ideal, oneOut⟩288289-- The ideals every ring has: the whole ring and the zero ideal.290theorem Ideal.whole291shows Ideal(R, R.carrier)292proof293have reflexive := Subset.reflexive at R.carrier294have zeroIn : R[0] ∈ R := Ring.zero_mem with*295apply Ideal.mk withring, reflexive, zeroIn296 . intros x hx y hy297exact Ring.add_mem with*298 . intros x hx299exact Ring.neg_mem with*300 . intros a ha x hx301constructor302 . exact Ring.mul_mem with*303 . exact Ring.mul_mem with*304305theorem Ideal.zero306shows Ideal(R, {R[0]})307proof308have parts := Ring.parts withring309have engine := IsIdeal.zero_ideal with parts310exact Ideal.of_projections with engine311312-- An ideal containing one is the whole ring, so a proper ideal is exactly313-- an ideal different from the ring.314theorem Ideal.contains_one (I : Set)315requires ideal : Ideal(R, I)316requires oneIn : R[1] ∈ I317shows I = R.carrier318proof319have parts := Ring.parts withring320have engine := Ideal.parts with ideal321exact IsIdeal.whole_of_one with parts, engine, oneIn322323theorem ProperIdeal.iff_ne_carrier (I : Set)324requires ideal : Ideal(R, I)325shows ProperIdeal(R, I) ↔ I ≠ R.carrier326proof327have parts := Ring.parts withring328have engine := Ideal.parts with ideal329have criterion := IsProperIdeal.iff_ne_whole with parts, engine330constructor331 . intro proper332exact criterion.forward with (ProperIdeal.parts with proper)333 . intro distinct334exact ProperIdeal.of_projections with (criterion.backward with distinct)335336theorem ProperIdeal.zero337requires nontrivial : R[0] ≠ R[1]338shows ProperIdeal(R, {R[0]})339proof340have parts := Ring.parts withring341have zeroIn : R[0] ∈ R := Ring.zero_mem with*342have oneIn : R[1] ∈ R := Ring.one_mem with*343have distinct : Nontrivial(R.carrier, R.zero, R.one)344unfold Nontrivial345exact⟨zeroIn, oneIn, nontrivial⟩346have engine := IsProperIdeal.zero_ideal with parts, distinct347exact ProperIdeal.of_projections with engine348349-- An ideal above a maximal ideal is the maximal ideal or the whole ring.350theorem MaximalIdeal.overideal (M J : Set)351requires maximal : MaximalIdeal(R, M)352requires ideal : Ideal(R, J)353requires contains : M ⊆ J354shows J = M ∨ J = R.carrier355proof356have parts := Ring.parts withring357have engineM := MaximalIdeal.parts with maximal358have engineJ := Ideal.parts with ideal359exact IsMaximalIdeal.eq_or_whole with parts, engineM, engineJ, contains360361end IdealConstructions362