1-- Core ring theory2-- 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.Core8import Group.Basic9import Defs1011theorem IsSemiring.distributive (A add zero mul one : Set)12requires h : IsSemiring(A, add, zero, mul, one)13shows Distributive(A, add, mul)14proof15simp [IsSemiring]1617theorem IsRing.additive (A add zero neg mul one : Set)18requires h : IsRing(A, add, zero, neg, mul, one)19shows IsAbelianGroup(A, add, zero, neg)20proof21simp [IsRing]2223theorem IsRing.multiplicative (A add zero neg mul one : Set)24requires h : IsRing(A, add, zero, neg, mul, one)25shows IsMonoid(A, mul, one)26proof27simp [IsRing]2829theorem IsRing.distributive (A add zero neg mul one : Set)30requires h : IsRing(A, add, zero, neg, mul, one)31shows Distributive(A, add, mul)32proof33simp [IsRing]3435theorem IsRing.add_closed (A add zero neg mul one x y : Set)36requiresring : IsRing(A, add, zero, neg, mul, one)37requires xInA : x ∈ A38requires yInA : y ∈ A39shows call2(add, x, y) ∈ A40proof41have additive := IsRing.additive withring42have group := IsAbelianGroup.group with additive43have monoid := IsGroup.monoid with group44exact IsMonoid.closed with monoid, xInA, yInA4546theorem IsRing.neg_closed (A add zero neg mul one x : Set)47requiresring : IsRing(A, add, zero, neg, mul, one)48requires xInA : x ∈ A49shows neg(x) ∈ A50proof51have additive := IsRing.additive withring52have group := IsAbelianGroup.group with additive53exact IsGroup.inverse_closed with group, xInA5455theorem IsRing.zero_in_carrier (A add zero neg mul one : Set)56requiresring : IsRing(A, add, zero, neg, mul, one)57shows zero ∈ A58proof59have additive := IsRing.additive withring60have group := IsAbelianGroup.group with additive61have monoid := IsGroup.monoid with group62exact IsMonoid.unit_in_carrier with monoid6364theorem IsRing.add_associative (A add zero neg mul one : Set)65requiresring : IsRing(A, add, zero, neg, mul, one)66shows Associative(A, add)67proof68have additive := IsRing.additive withring69have group := IsAbelianGroup.group with additive70have monoid := IsGroup.monoid with group71exact IsMonoid.associative with monoid7273theorem IsRing.add_left_identity (A add zero neg mul one x : Set)74requiresring : IsRing(A, add, zero, neg, mul, one)75requires xInA : x ∈ A76shows call2(add, zero, x) = x77proof78have additive := IsRing.additive withring79have group := IsAbelianGroup.group with additive80have monoid := IsGroup.monoid with group81exact IsMonoid.left_identity with monoid, xInA8283theorem IsRing.add_right_identity (A add zero neg mul one x : Set)84requiresring : IsRing(A, add, zero, neg, mul, one)85requires xInA : x ∈ A86shows call2(add, x, zero) = x87proof88have additive := IsRing.additive withring89have group := IsAbelianGroup.group with additive90have monoid := IsGroup.monoid with group91exact IsMonoid.right_identity with monoid, xInA9293theorem IsRing.add_inverse_left (A add zero neg mul one x : Set)94requiresring : IsRing(A, add, zero, neg, mul, one)95requires xInA : x ∈ A96shows call2(add, neg(x), x) = zero97proof98have additive := IsRing.additive withring99have group := IsAbelianGroup.group with additive100exact IsGroup.inverse_left with group, xInA101102theorem IsRing.add_inverse_right (A add zero neg mul one x : Set)103requiresring : IsRing(A, add, zero, neg, mul, one)104requires xInA : x ∈ A105shows call2(add, x, neg(x)) = zero106proof107have additive := IsRing.additive withring108have group := IsAbelianGroup.group with additive109exact IsGroup.inverse_right with group, xInA110111theorem IsRing.mul_closed (A add zero neg mul one x y : Set)112requiresring : IsRing(A, add, zero, neg, mul, one)113requires xInA : x ∈ A114requires yInA : y ∈ A115shows call2(mul, x, y) ∈ A116proof117have multiplicative := IsRing.multiplicative withring118exact IsMonoid.closed with multiplicative, xInA, yInA119120theorem IsRing.zero_mul (A add zero neg mul one x : Set)121requiresring : IsRing(A, add, zero, neg, mul, one)122requires xInA : x ∈ A123shows call2(mul, zero, x) = zero124proof125have zeroInA := IsRing.zero_in_carrier withring126have productInA := IsRing.mul_closed withring, zeroInA, xInA127have distributive := IsRing.distributive withring128obtain⟨leftLaw, rightLaw⟩:= distributive with zero, zeroInA, zero, zeroInA, x, xInA129have zeroPlusZero := IsRing.add_left_identity withring, zeroInA130rw zeroPlusZero at rightLaw131have negProductInA := IsRing.neg_closed withring, productInA132have associative := IsRing.add_associative withring133have reassociate := Associative.law with associative, negProductInA, productInA, productInA134have inverse := IsRing.add_inverse_left withring, productInA135have identity := IsRing.add_left_identity withring, productInA136cc137138theorem IsRing.mul_zero (A add zero neg mul one x : Set)139requiresring : IsRing(A, add, zero, neg, mul, one)140requires xInA : x ∈ A141shows call2(mul, x, zero) = zero142proof143have zeroInA := IsRing.zero_in_carrier withring144have productInA := IsRing.mul_closed withring, xInA, zeroInA145have distributive := IsRing.distributive withring146obtain⟨leftLaw, rightLaw⟩:= distributive with x, xInA, zero, zeroInA, zero, zeroInA147have zeroPlusZero := IsRing.add_left_identity withring, zeroInA148rw zeroPlusZero at leftLaw149have negProductInA := IsRing.neg_closed withring, productInA150have associative := IsRing.add_associative withring151have reassociate := Associative.law with associative, negProductInA, productInA, productInA152have inverse := IsRing.add_inverse_left withring, productInA153have identity := IsRing.add_left_identity withring, productInA154cc155156theorem IsRing.neg_mul (A add zero neg mul one x y : Set)157requiresring : IsRing(A, add, zero, neg, mul, one)158requires xInA : x ∈ A159requires yInA : y ∈ A160shows call2(mul, neg(x), y) = neg(call2(mul, x, y))161proof162have additive := IsRing.additive withring163have group := IsAbelianGroup.group with additive164have monoid := IsGroup.monoid with group165have negXInA := IsRing.neg_closed withring, xInA166have productInA := IsRing.mul_closed withring, xInA, yInA167have negProductInA := IsRing.neg_closed withring, productInA168have candidateInA := IsRing.mul_closed withring, negXInA, yInA169have distributive := IsRing.distributive withring170obtain⟨leftLaw, rightLaw⟩:= distributive with neg(x), negXInA, x, xInA, y, yInA171have inverseX := IsRing.add_inverse_left withring, xInA172have zeroProduct := IsRing.zero_mul withring, yInA173rw [inverseX, zeroProduct] at rightLaw174have commutative := IsAbelianGroup.commutative with additive175have candidateSwap := commutative with176 call2(mul, neg(x), y), candidateInA,177 call2(mul, x, y), productInA178have candidateLeft : call2(add,179 call2(mul, neg(x), y), call2(mul, x, y)) = zero180cc181have candidateRight : call2(add,182 call2(mul, x, y), call2(mul, neg(x), y)) = zero183cc184have canonical : IsInverse(A, add, zero,185 call2(mul, x, y), neg(call2(mul, x, y)))186unfold IsInverse187refine⟨productInA, negProductInA, _, _⟩188 . exact IsRing.add_inverse_left at189 A, add, zero, neg, mul, one, call2(mul, x, y) withring, productInA190 . exact IsRing.add_inverse_right at191 A, add, zero, neg, mul, one, call2(mul, x, y) withring, productInA192have candidate : IsInverse(A, add, zero,193 call2(mul, x, y), call2(mul, neg(x), y))194unfold IsInverse195refine⟨productInA, candidateInA, candidateLeft, candidateRight⟩196have unique := IsInverse.unique with monoid, canonical, candidate197cc198199theorem CommSemiring.semiring (A add zero mul one : Set)200requires h : CommSemiring(A, add, zero, mul, one)201shows IsSemiring(A, add, zero, mul, one)202proof203simp [CommSemiring]204205theorem CommSemiring.commutative (A add zero mul one : Set)206requires h : CommSemiring(A, add, zero, mul, one)207shows Commutative(A, mul)208proof209simp [CommSemiring]210211theorem IsCommRing.ring (A add zero neg mul one : Set)212requires h : IsCommRing(A, add, zero, neg, mul, one)213shows IsRing(A, add, zero, neg, mul, one)214proof215simp [IsCommRing]216217theorem IsCommRing.commutative (A add zero neg mul one : Set)218requires h : IsCommRing(A, add, zero, neg, mul, one)219shows Commutative(A, mul)220proof221simp [IsCommRing]222223theorem IsCommRing.add_commutative (A add zero neg mul one : Set)224requiresring : IsCommRing(A, add, zero, neg, mul, one)225shows Commutative(A, add)226proof227have ordinary := IsCommRing.ring withring228have additive := IsRing.additive with ordinary229exact IsAbelianGroup.commutative with additive230231-- Direct equational laws used by checked polynomial normalization.232theorem IsCommRing.add_comm (A add zero neg mul one x y : Set)233requiresring : IsCommRing(A, add, zero, neg, mul, one)234requires hx : x ∈ A235requires hy : y ∈ A236shows call2(add, x, y) = call2(add, y, x)237proof238have comm := IsCommRing.add_commutative withring239exact comm with x, hx, y, hy240241theorem IsCommRing.add_assoc (A add zero neg mul one x y z : Set)242requiresring : IsCommRing(A, add, zero, neg, mul, one)243requires hx : x ∈ A244requires hy : y ∈ A245requires hz : z ∈ A246shows call2(add, call2(add, x, y), z) = call2(add, x, call2(add, y, z))247proof248have ordinary := IsCommRing.ring withring249have associative := IsRing.add_associative with ordinary250exact Associative.law with associative, hx, hy, hz251252theorem IsCommRing.add_swap (A add zero neg mul one x y z : Set)253requiresring : IsCommRing(A, add, zero, neg, mul, one)254requires hx : x ∈ A255requires hy : y ∈ A256requires hz : z ∈ A257shows call2(add, x, call2(add, y, z)) = call2(add, y, call2(add, x, z))258proof259have xy := IsCommRing.add_comm withring, hx, hy260have lhs := IsCommRing.add_assoc withring, hx, hy, hz261have rhs := IsCommRing.add_assoc withring, hy, hx, hz262cc263264theorem IsCommRing.neg_add (A add zero neg mul one x y : Set)265requiresring : IsCommRing(A, add, zero, neg, mul, one)266requires hx : x ∈ A267requires hy : y ∈ A268shows neg(call2(add, x, y)) = call2(add, neg(x), neg(y))269proof270have ordinary := IsCommRing.ring withring271have group := IsRing.additive with ordinary272exact IsAbelianGroup.inverse_op with group, hx, hy273274theorem IsCommRing.neg_neg (A add zero neg mul one x : Set)275requiresring : IsCommRing(A, add, zero, neg, mul, one)276requires hx : x ∈ A277shows neg(neg(x)) = x278proof279have ordinary := IsCommRing.ring withring280have additive := IsRing.additive with ordinary281have group := IsAbelianGroup.group with additive282exact IsGroup.inverse_involutive with group, hx283284theorem IsCommRing.neg_zero (A add zero neg mul one : Set)285requiresring : IsCommRing(A, add, zero, neg, mul, one)286shows neg(zero) = zero287proof288have ordinary := IsCommRing.ring withring289have additive := IsRing.additive with ordinary290have group := IsAbelianGroup.group with additive291exact IsGroup.inverse_unit with group292293theorem IsCommRing.mul_comm (A add zero neg mul one x y : Set)294requiresring : IsCommRing(A, add, zero, neg, mul, one)295requires hx : x ∈ A296requires hy : y ∈ A297shows call2(mul, x, y) = call2(mul, y, x)298proof299have comm := IsCommRing.commutative withring300exact comm with x, hx, y, hy301302theorem IsCommRing.mul_assoc (A add zero neg mul one x y z : Set)303requiresring : IsCommRing(A, add, zero, neg, mul, one)304requires hx : x ∈ A305requires hy : y ∈ A306requires hz : z ∈ A307shows call2(mul, call2(mul, x, y), z) = call2(mul, x, call2(mul, y, z))308proof309have ordinary := IsCommRing.ring withring310have multiplicative := IsRing.multiplicative with ordinary311have associative := IsMonoid.associative with multiplicative312exact Associative.law with associative, hx, hy, hz313314theorem IsCommRing.mul_swap (A add zero neg mul one x y z : Set)315requiresring : IsCommRing(A, add, zero, neg, mul, one)316requires hx : x ∈ A317requires hy : y ∈ A318requires hz : z ∈ A319shows call2(mul, x, call2(mul, y, z)) = call2(mul, y, call2(mul, x, z))320proof321have xy := IsCommRing.mul_comm withring, hx, hy322have lhs := IsCommRing.mul_assoc withring, hx, hy, hz323have rhs := IsCommRing.mul_assoc withring, hy, hx, hz324cc325326theorem IsCommRing.one_left (A add zero neg mul one x : Set)327requiresring : IsCommRing(A, add, zero, neg, mul, one)328requires hx : x ∈ A329shows call2(mul, one, x) = x330proof331have ordinary := IsCommRing.ring withring332have monoid := IsRing.multiplicative with ordinary333exact IsMonoid.left_identity with monoid, hx334335theorem IsCommRing.one_right (A add zero neg mul one x : Set)336requiresring : IsCommRing(A, add, zero, neg, mul, one)337requires hx : x ∈ A338shows call2(mul, x, one) = x339proof340have ordinary := IsCommRing.ring withring341have monoid := IsRing.multiplicative with ordinary342exact IsMonoid.right_identity with monoid, hx343344theorem IsCommRing.mul_add (A add zero neg mul one x y z : Set)345requiresring : IsCommRing(A, add, zero, neg, mul, one)346requires hx : x ∈ A347requires hy : y ∈ A348requires hz : z ∈ A349shows call2(mul, x, call2(add, y, z)) =350 call2(add, call2(mul, x, y), call2(mul, x, z))351proof352have ordinary := IsCommRing.ring withring353have distributive := IsRing.distributive with ordinary354obtain⟨left, right⟩:= distributive with x, hx, y, hy, z, hz355exactleft356357theorem IsCommRing.add_mul (A add zero neg mul one x y z : Set)358requiresring : IsCommRing(A, add, zero, neg, mul, one)359requires hx : x ∈ A360requires hy : y ∈ A361requires hz : z ∈ A362shows call2(mul, call2(add, x, y), z) =363 call2(add, call2(mul, x, z), call2(mul, y, z))364proof365have ordinary := IsCommRing.ring withring366have distributive := IsRing.distributive with ordinary367obtain⟨left, right⟩:= distributive with x, hx, y, hy, z, hz368exactright369370theorem IsCommRing.mul_neg (A add zero neg mul one x y : Set)371requires commRing : IsCommRing(A, add, zero, neg, mul, one)372requires xInA : x ∈ A373requires yInA : y ∈ A374shows call2(mul, x, neg(y)) = neg(call2(mul, x, y))375proof376havering:= IsCommRing.ring with commRing377have negYInA := IsRing.neg_closed withring, yInA378have commutative := IsCommRing.commutative with commRing379have leftSwap := commutative with x, xInA, neg(y), negYInA380have rightSwap := commutative with x, xInA, y, yInA381have negated := IsRing.neg_mul withring, yInA, xInA382cc383384theorem IsCommRing.neg_mul_neg (A add zero neg mul one x y : Set)385requires commRing : IsCommRing(A, add, zero, neg, mul, one)386requires xInA : x ∈ A387requires yInA : y ∈ A388shows call2(mul, neg(x), neg(y)) = call2(mul, x, y)389proof390havering:= IsCommRing.ring with commRing391have additive := IsRing.additive withring392have group := IsAbelianGroup.group with additive393have negYInA := IsRing.neg_closed withring, yInA394have outerNeg := IsRing.neg_mul withring, xInA, negYInA395have innerNeg := IsCommRing.mul_neg with commRing, xInA, yInA396have productInA := IsRing.mul_closed withring, xInA, yInA397have involutive := IsGroup.inverse_involutive with group, productInA398cc399400theorem Nontrivial.distinct (A zero one : Set)401requires h : Nontrivial(A, zero, one)402shows zero ≠ one403proof404simp [Nontrivial]405406theorem IsIntegralDomain.comm_ring (A add zero neg mul one : Set)407requires h : IsIntegralDomain(A, add, zero, neg, mul, one)408shows IsCommRing(A, add, zero, neg, mul, one)409proof410simp [IsIntegralDomain]411412theorem IsIntegralDomain.nontrivial (A add zero neg mul one : Set)413requires h : IsIntegralDomain(A, add, zero, neg, mul, one)414shows Nontrivial(A, zero, one)415proof416simp [IsIntegralDomain]417418theorem IsIntegralDomain.no_zero_divisors (A add zero neg mul one : Set)419requires h : IsIntegralDomain(A, add, zero, neg, mul, one)420shows NoZeroDivisors(A, mul, zero)421proof422simp [IsIntegralDomain]423