1-- The additive fragment of an ordered ring used by linear arithmetic2-- 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.OrderedAdditive8import Group.Core9import Ring.Core1011-- An ordered ring supplies this interface through its additive group and12-- translation-invariant weak order. No multiplication law is needed by13-- affine arithmetic, so other ordered additive groups can use it as well.14predicate OrderedAdditiveGroup (A add zero neg le : Set) :=15 IsAbelianGroup(A, add, zero, neg) ∧16 (ReflexiveOn(A, le) ∧17 (TransitiveOn(A, le) ∧18 ((∀ x ∈ A, ∀ y ∈ A, ∀ z ∈ A, ∀ w ∈ A,19 relates(le, x, y) → relates(le, z, w) →20 relates(le, call2(add, x, z), call2(add, y, w))) ∧21 ((∀ x ∈ A, ∀ y ∈ A,22 relates(le, x, y) → relates(le, neg(y), neg(x))) ∧23 (∀ x ∈ A, ∀ y ∈ A,24 relates(le, x, y) →25 relates(le, zero, call2(add, y, neg(x))))))))2627predicate OrderedRing (A add zero neg mul one le : Set) :=28 IsCommRing(A, add, zero, neg, mul, one) ∧29 (OrderedAdditiveGroup(A, add, zero, neg, le) ∧30 (AntisymmetricOn(A, le) ∧31 (∀ x ∈ A, ∀ y ∈ A,32 relates(le, zero, x) → relates(le, zero, y) →33 relates(le, zero, call2(mul, x, y)))))3435theorem OrderedRing.comm_ring (A add zero neg mul one le : Set)36requiresordered : OrderedRing(A, add, zero, neg, mul, one, le)37shows IsCommRing(A, add, zero, neg, mul, one)38proof39rcasesorderedwith⟨ring, additive, antisymmetric, positive⟩40exactring4142theorem OrderedRing.additive (A add zero neg mul one le : Set)43requiresordered : OrderedRing(A, add, zero, neg, mul, one, le)44shows OrderedAdditiveGroup(A, add, zero, neg, le)45proof46rcasesorderedwith⟨ring, additive, antisymmetric, positive⟩47exact additive4849theorem OrderedAdditiveGroup.neg_closed (A add zero neg le x : Set)50requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)51requires member : x ∈ A52shows neg(x) ∈ A53proof54rcasesstructurewith⟨group, rest⟩55have ordinary := IsAbelianGroup.group with group56exact IsGroup.inverse_closed with ordinary, member5758theorem OrderedAdditiveGroup.add_closed (A add zero neg le x y : Set)59requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)60requires members : x ∈ A ∧ y ∈ A61shows call2(add, x, y) ∈ A62proof63rcasesstructurewith⟨group, rest⟩64rcases members with⟨hx, hy⟩65have ordinary := IsAbelianGroup.group with group66have monoid := IsGroup.monoid with ordinary67exact IsMonoid.closed with monoid, hx, hy6869theorem OrderedAdditiveGroup.add_comm (A add zero neg le x y : Set)70requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)71requires members : x ∈ A ∧ y ∈ A72shows call2(add, x, y) = call2(add, y, x)73proof74rcasesstructurewith⟨group, rest⟩75rcases members with⟨hx, hy⟩76have commutes := IsAbelianGroup.commutative with group77exact commutes with x, hx, y, hy7879theorem OrderedAdditiveGroup.add_assoc (A add zero neg le x y z : Set)80requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)81requires members : x ∈ A ∧ y ∈ A ∧ z ∈ A82shows call2(add, call2(add, x, y), z) = call2(add, x, call2(add, y, z))83proof84rcasesstructurewith⟨group, rest⟩85rcases members with⟨hx, hy, hz⟩86have ordinary := IsAbelianGroup.group with group87have monoid := IsGroup.monoid with ordinary88have associative := IsMonoid.associative with monoid89exact Associative.law with associative, hx, hy, hz9091theorem OrderedAdditiveGroup.zero_left (A add zero neg le x : Set)92requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)93requires member : x ∈ A94shows call2(add, zero, x) = x95proof96rcasesstructurewith⟨group, rest⟩97have ordinary := IsAbelianGroup.group with group98have monoid := IsGroup.monoid with ordinary99exact IsMonoid.left_identity with monoid, member100101theorem OrderedAdditiveGroup.zero_right (A add zero neg le x : Set)102requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)103requires member : x ∈ A104shows call2(add, x, zero) = x105proof106rcasesstructurewith⟨group, rest⟩107have ordinary := IsAbelianGroup.group with group108have monoid := IsGroup.monoid with ordinary109exact IsMonoid.right_identity with monoid, member110111theorem OrderedAdditiveGroup.add_neg (A add zero neg le x : Set)112requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)113requires member : x ∈ A114shows call2(add, x, neg(x)) = zero115proof116rcasesstructurewith⟨group, rest⟩117have ordinary := IsAbelianGroup.group with group118exact IsGroup.inverse_right with ordinary, member119120theorem OrderedAdditiveGroup.neg_add (A add zero neg le x : Set)121requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)122requires member : x ∈ A123shows call2(add, neg(x), x) = zero124proof125rcasesstructurewith⟨group, rest⟩126have ordinary := IsAbelianGroup.group with group127exact IsGroup.inverse_left with ordinary, member128129theorem OrderedAdditiveGroup.neg_neg (A add zero neg le x : Set)130requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)131requires member : x ∈ A132shows neg(neg(x)) = x133proof134rcasesstructurewith⟨group, rest⟩135have ordinary := IsAbelianGroup.group with group136exact IsGroup.inverse_involutive with ordinary, member137138theorem OrderedAdditiveGroup.add_swap (A add zero neg le x y z : Set)139requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)140requires members : x ∈ A ∧ y ∈ A ∧ z ∈ A141shows call2(add, x, call2(add, y, z)) =142 call2(add, y, call2(add, x, z))143proof144rcases members with⟨hx, hy, hz⟩145have xyMembers : x ∈ A ∧ y ∈ A byrefine⟨hx, hy⟩146have yxMembers : y ∈ A ∧ x ∈ A byrefine⟨hy, hx⟩147have xyzMembers : x ∈ A ∧ y ∈ A ∧ z ∈ A byrefine⟨hx, hy, hz⟩148have yxzMembers : y ∈ A ∧ x ∈ A ∧ z ∈ A byrefine⟨hy, hx, hz⟩149have xy := OrderedAdditiveGroup.add_closed withstructure, xyMembers150have yx := OrderedAdditiveGroup.add_closed withstructure, yxMembers151have first := OrderedAdditiveGroup.add_assoc withstructure, xyzMembers152have swapped := OrderedAdditiveGroup.add_comm withstructure, xyMembers153have second := OrderedAdditiveGroup.add_assoc withstructure, yxzMembers154have step1 : call2(add, x, call2(add, y, z)) =155 call2(add, call2(add, x, y), z)156rw first157rfl158have step2 : call2(add, call2(add, x, y), z) =159 call2(add, call2(add, y, x), z)160rw swapped161rfl162calc163 call2(add, x, call2(add, y, z)) = call2(add, call2(add, x, y), z) := step1164 _ = call2(add, call2(add, y, x), z) := step2165 _ = call2(add, y, call2(add, x, z)) := second166167theorem OrderedAdditiveGroup.add_cancel_left (A add zero neg le x y : Set)168requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)169requires members : x ∈ A ∧ y ∈ A170shows call2(add, call2(add, x, y), neg(x)) = y171proof172rcases members with⟨hx, hy⟩173have xyMembers : x ∈ A ∧ y ∈ A byrefine⟨hx, hy⟩174have negative := OrderedAdditiveGroup.neg_closed withstructure, hx175have xynMembers : x ∈ A ∧ y ∈ A ∧ neg(x) ∈ A byrefine⟨hx, hy, negative⟩176have ynMembers : y ∈ A ∧ neg(x) ∈ A byrefine⟨hy, negative⟩177have xnyMembers : x ∈ A ∧ neg(x) ∈ A ∧ y ∈ A byrefine⟨hx, negative, hy⟩178have regroup := OrderedAdditiveGroup.add_assoc withstructure, xynMembers179have swapped := OrderedAdditiveGroup.add_comm withstructure, ynMembers180have regroupBack := OrderedAdditiveGroup.add_assoc withstructure, xnyMembers181have cancel := OrderedAdditiveGroup.add_neg withstructure, hx182have identity := OrderedAdditiveGroup.zero_left withstructure, hy183have step2 : call2(add, x, call2(add, y, neg(x))) =184 call2(add, x, call2(add, neg(x), y))185rw swapped186rfl187have step3 : call2(add, x, call2(add, neg(x), y)) =188 call2(add, call2(add, x, neg(x)), y)189rw regroupBack190rfl191have step4 : call2(add, call2(add, x, neg(x)), y) =192 call2(add, zero, y)193rw cancel194rfl195calc196 call2(add, call2(add, x, y), neg(x)) =197 call2(add, x, call2(add, y, neg(x))) := regroup198 _ = call2(add, x, call2(add, neg(x), y)) := step2199 _ = call2(add, call2(add, x, neg(x)), y) :=200 step3201 _ = call2(add, zero, y) := step4202 _ = y := identity203204theorem OrderedAdditiveGroup.reflexive (A add zero neg le x : Set)205requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)206requires member : x ∈ A207shows relates(le, x, x)208proof209rcasesstructurewith⟨group, reflexive, rest⟩210exact reflexive with x, member211212theorem OrderedAdditiveGroup.transitive (A add zero neg le x y z : Set)213requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)214requires members : x ∈ A ∧ y ∈ A ∧ z ∈ A215requires xy : relates(le, x, y)216requires yz : relates(le, y, z)217shows relates(le, x, z)218proof219rcasesstructurewith⟨group, reflexive, transitive, rest⟩220rcases members with⟨hx, hy, hz⟩221exact transitive with x, hx, y, hy, z, hz, xy, yz222223theorem OrderedAdditiveGroup.add (A add zero neg le x y z w : Set)224requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)225requires members : x ∈ A ∧ y ∈ A ∧ z ∈ A ∧ w ∈ A226requires xy : relates(le, x, y)227requires zw : relates(le, z, w)228shows relates(le, call2(add, x, z), call2(add, y, w))229proof230rcasesstructurewith⟨group, reflexive, transitive, monotone, rest⟩231rcases members with⟨hx, hy, hz, hw⟩232exact monotone with x, hx, y, hy, z, hz, w, hw, xy, zw233234theorem OrderedAdditiveGroup.neg_reverse (A add zero neg le x y : Set)235requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)236requires members : x ∈ A ∧ y ∈ A237requires xy : relates(le, x, y)238shows relates(le, neg(y), neg(x))239proof240rcasesstructurewith⟨group, reflexive, transitive, monotone, reverse, rest⟩241rcases members with⟨hx, hy⟩242exact reverse with x, hx, y, hy, xy243244theorem OrderedAdditiveGroup.nonnegative_sub (A add zero neg le x y : Set)245requiresstructure : OrderedAdditiveGroup(A, add, zero, neg, le)246requires members : x ∈ A ∧ y ∈ A247requires xy : relates(le, x, y)248shows relates(le, zero, call2(add, y, neg(x)))249proof250rcasesstructurewith⟨group, reflexive, transitive, monotone, reverse, positive⟩251rcases members with⟨hx, hy⟩252exact positive with x, hx, y, hy, xy253