1-- The order of the integers: nonnegative integers, ≤, and <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.Int.Order8import Ring9import AbsoluteValue1011predicate IntegerNonnegative (z : Set) :=∃ n ∈ ℕ, z = integerOfNat(n)12predicate IntegerPositive (z : Set) :=∃ n ∈ ℕ, z = integerOfNat(n +1)1314predicate integerLe (x y : Integer) := IntegerNonnegative(y - x)15notationinfix50"≤"=> integerLe for Integer16notationinfix50"≥"=> reverse integerLe for Integer1718predicate integerLess (x y : Integer) := integerLe(x +1, y)19notationinfix50"<"=> integerLess for Integer2021theorem IntegerNonnegative.ofNat (n : Nat)22shows IntegerNonnegative(integerOfNat(n))23proof24witness n25constructor26 . typecheck27 . rfl2829theorem IntegerNonnegative.integer (z : Set)30requires nonnegative : IntegerNonnegative(z)31shows Integer(z)32proof33obtain⟨n, nMember, shape⟩:= nonnegative34have nNat := nat.omega.backward with nMember35rw shape36exact integerOfNat.integer with*3738theorem IntegerNonnegative.zero39shows IntegerNonnegative(integerZero)40proof41have value := IntegerNonnegative.ofNat at042rw integerOfNat.zero at value43exact value4445theorem IntegerNonnegative.one46shows IntegerNonnegative(integerOne)47proof48have value := IntegerNonnegative.ofNat at149unfold integerOne50exact value5152theorem IntegerNonnegative.add (x y : Integer)53requires first : IntegerNonnegative(x)54requires second : IntegerNonnegative(y)55shows IntegerNonnegative(x + y)56proof57obtain⟨n, nMember, xShape⟩:= first58obtain⟨m, mMember, yShape⟩:= second59have nNat := nat.omega.backward with nMember60have mNat := nat.omega.backward with mMember61have sum := integerOfNat.add at n, m62rw [xShape, yShape, ← sum]63exact IntegerNonnegative.ofNat with*6465theorem IntegerNonnegative.mul (x y : Integer)66requires first : IntegerNonnegative(x)67requires second : IntegerNonnegative(y)68shows IntegerNonnegative(x * y)69proof70obtain⟨n, nMember, xShape⟩:= first71obtain⟨m, mMember, yShape⟩:= second72have nNat := nat.omega.backward with nMember73have mNat := nat.omega.backward with mMember74have product := integerMulValue.ofNat at n, m75rw [xShape, yShape, product]76exact IntegerNonnegative.ofNat with*7778theorem IntegerNonnegative.negative_iff (n : Nat)79shows IntegerNonnegative(integerNegativeOfNat(n)) ↔ n =080proof81constructor82 . intro nonnegative83obtain⟨m, mMember, shape⟩:= nonnegative84have mNat := nat.omega.backward with mMember85 symm at shape86have both := integerOfNat.eq_negative with shape87exact both.right88 . intro zero89rw zero90have same : integerNegativeOfNat(0) = integerOfNat(0)91simp [integerNegativeOfNat, integerOfNat]92rw same93exact IntegerNonnegative.ofNat with*9495theorem IntegerNonnegative.cases (z : Integer)96shows IntegerNonnegative(z) ∨ IntegerNonnegative(-z)97proof98obtain⟨n, nNat, sign⟩:= Integer.signed_natural at z with*99cases sign with positive | negative100 . left101rw positive102exact IntegerNonnegative.ofNat with*103 . right104rw negative105have flipped := integerNegativeOfNat.neg at n106rw flipped107exact IntegerNonnegative.ofNat with*108109theorem IntegerNonnegative.exists_natural (z : Integer)110requires nonnegative : IntegerNonnegative(z)111shows∃ n, Nat(n) ∧ z = integerOfNat(n)112proof113obtain⟨n, nMember, shape⟩:= nonnegative114have nNat := nat.omega.backward with nMember115exact⟨n, nNat, shape⟩116117theorem IntegerNonnegative.eq_zero (z : Integer)118requires first : IntegerNonnegative(z)119requires second : IntegerNonnegative(-z)120shows z =0121proof122obtain⟨n, nMember, zShape⟩:= first123obtain⟨m, mMember, negShape⟩:= second124have nNat := nat.omega.backward with nMember125have mNat := nat.omega.backward with mMember126have cancel : z + (-z) =0byring127rw [negShape, zShape] at cancel128have sum := integerOfNat.add at n, m129rw [← sum, ← integerOfNat.zero] at cancel130have sumZero := integerOfNat.injective with cancel131have both := add.eq_zero with sumZero132rw [zShape, both.left]133exact integerOfNat.zero134135theorem IntegerNonnegative.of_positive (z : Integer)136requires positive : IntegerPositive(z)137shows IntegerNonnegative(z)138proof139obtain⟨n, nMember, shape⟩:= positive140have nNat := nat.omega.backward with nMember141rw shape142exact IntegerNonnegative.ofNat with*143144theorem IntegerPositive.ofNat_add_one (n : Nat)145shows IntegerPositive(integerOfNat(n +1))146proof147witness n148constructor149 . typecheck150 . rfl151152theorem IntegerPositive.iff_sub_one (z : Integer)153shows IntegerPositive(z) ↔ IntegerNonnegative(z - 1)154proof155constructor156 . intro positive157obtain⟨n, nMember, shape⟩:= positive158have nNat := nat.omega.backward with nMember159havesplit:= integerOfNat.add at n, 1160have one : integerOfNat(1) =1161unfold integerOne162rfl163rw [shape, split, one]164have cancel : integerOfNat(n) +1 - 1= integerOfNat(n) byring165rw cancel166exact IntegerNonnegative.ofNat with*167 . intro nonnegative168obtain⟨n, nMember, shape⟩:= nonnegative169have nNat := nat.omega.backward with nMember170havesplit:= integerOfNat.add at n, 1171have one : integerOfNat(1) =1172unfold integerOne173rfl174have restore : z = (z - 1) +1byring175rw [restore, shape, ← one, ←split]176exact IntegerPositive.ofNat_add_one with*177178theorem IntegerPositive.mul (x y : Integer)179requires first : IntegerPositive(x)180requires second : IntegerPositive(y)181shows IntegerPositive(x * y)182proof183obtain⟨n, nMember, xShape⟩:= first184obtain⟨m, mMember, yShape⟩:= second185have nNat := nat.omega.backward with nMember186have mNat := nat.omega.backward with mMember187have product := integerMulValue.ofNat at n +1, m +1188have expand : (n +1) * (m +1) = (n * m + n + m) +1byring189rw [xShape, yShape, product, expand]190exact IntegerPositive.ofNat_add_one with*191192theorem IntegerPositive.add (x y : Integer)193requires first : IntegerPositive(x)194requires second : IntegerPositive(y)195shows IntegerPositive(x + y)196proof197obtain⟨n, nMember, xShape⟩:= first198obtain⟨m, mMember, yShape⟩:= second199have nNat := nat.omega.backward with nMember200have mNat := nat.omega.backward with mMember201have sum := integerOfNat.add at n +1, m +1202have expand : (n +1) + (m +1) = (n + m +1) +1byring203rw [xShape, yShape, ← sum, expand]204exact IntegerPositive.ofNat_add_one with*205206theorem IntegerPositive.not_zero207shows¬IntegerPositive(integerZero)208proof209intro positive210obtain⟨n, nMember, shape⟩:= positive211have nNat := nat.omega.backward with nMember212rw← integerOfNat.zero at shape213have same := integerOfNat.injective with shape214have impossible : 0 < 0bylinarith215exact Less.irreflexive with impossible216217theorem integerLe.reflexive (x : Integer)218shows x ≤ x219proof220unfold integerLe221have zero : x - x =0byring222rw zero223exact IntegerNonnegative.zero224225theorem integerLe.of_eq (x y : Integer)226requires same : x = y227shows x ≤ y228proof229rw same230exact integerLe.reflexive with*231232theorem integerLe.transitive (x y z : Integer)233requires first : x ≤ y234requires second : y ≤ z235shows x ≤ z236proof237unfold integerLe at first238unfold integerLe at second239have sum : z - x = (z - y) + (y - x) byring240unfold integerLe241rw sum242exact IntegerNonnegative.add with second, first243244theorem integerLe.antisymmetric (x y : Integer)245requires first : x ≤ y246requires second : y ≤ x247shows x = y248proof249unfold integerLe at first250unfold integerLe at second251have flip : x - y = -(y - x) byring252rw flip at second253have zero := IntegerNonnegative.eq_zero with first, second254have restore : x = y - (y - x) byring255rw [restore, zero]256ring257258theorem integerLe.total (x y : Integer)259shows x ≤ y ∨ y ≤ x260proof261havesplit:= IntegerNonnegative.cases at y - x with*262casessplitwith forward | backward263 . left264exact forward265 . right266have flip : x - y = -(y - x) byring267unfold integerLe268rw flip269exact backward270271theorem integerLe.zero_iff (x : Integer)272shows0≤ x ↔ IntegerNonnegative(x)273proof274have shape : x - 0= x byring275constructor276 . intro below277unfold integerLe at below278rw shape at below279exact below280 . intro nonnegative281unfold integerLe282rw shape283exact nonnegative284285theorem integerLe.sub_nonneg_iff (x y : Integer)286shows x ≤ y ↔0≤ y - x287proof288have difference := integerLe.zero_iff at y - x with*289constructor290 . intro below291unfold integerLe at below292exact difference.backward with below293 . intro below294have nonnegative := difference.forward with below295unfold integerLe296exact nonnegative297298theorem integerLe.ofNat_nonneg (n : Nat)299shows0≤ integerOfNat(n)300proof301apply integerLe.zero_iff.backward302exact IntegerNonnegative.ofNat with*303304theorem integerLe.negative_nonpos (n : Nat)305shows integerNegativeOfNat(n) ≤0306proof307unfold integerLe308have flip : 0 - integerNegativeOfNat(n) = -(integerNegativeOfNat(n)) byring309rw [flip, integerNegativeOfNat.neg]310exact IntegerNonnegative.ofNat with*311312theorem integerLe.zero_one313shows integerZero ≤ integerOne314proof315unfold integerLe316have shape : integerOne - integerZero = integerOne byring317rw shape318exact IntegerNonnegative.one319320theorem integerLe.add_right (x y z : Integer)321requires below : x ≤ y322shows x + z ≤ y + z323proof324have shape : (y + z) - (x + z) = y - x byring325unfold integerLe326rw shape327exact below328329theorem integerLe.add_left (x y z : Integer)330requires below : x ≤ y331shows z + x ≤ z + y332proof333have shape : (z + y) - (z + x) = y - x byring334unfold integerLe335rw shape336exact below337338theorem integerLe.add (a b c d : Integer)339requires first : a ≤ b340requires second : c ≤ d341shows a + c ≤ b + d342proof343haveleft:= integerLe.add_right at a, b, c with first344haveright:= integerLe.add_left at c, d, b with second345exact integerLe.transitive withleft, right346347theorem integerLe.add_right_cancel (x y z : Integer)348requires below : x + z ≤ y + z349shows x ≤ y350proof351have shape : (y + z) - (x + z) = y - x byring352unfold integerLe at below353rw shape at below354exact below355356theorem integerLe.add_left_cancel (x y z : Integer)357requires below : z + x ≤ z + y358shows x ≤ y359proof360have shape : (z + y) - (z + x) = y - x byring361unfold integerLe at below362rw shape at below363exact below364365theorem integerLe.neg (x y : Integer)366shows x ≤ y ↔ -y ≤ -x367proof368have shape : (-x) - (-y) = y - x byring369constructor370 . intro below371unfold integerLe372rw shape373exact below374 . intro below375unfold integerLe at below376rw shape at below377exact below378379theorem integerLe.neg_nonneg_iff (x : Integer)380shows0≤ -x ↔ x ≤0381proof382have shape : (-x) - 0=0 - x byring383constructor384 . intro below385unfold integerLe at below386rw shape at below387exact below388 . intro below389unfold integerLe390rw shape391exact below392393theorem integerLe.sub_right (x y z : Integer)394requires below : x ≤ y395shows x - z ≤ y - z396proof397have shape : (y - z) - (x - z) = y - x byring398unfold integerLe399rw shape400exact below401402theorem integerLe.sub_left (x y z : Integer)403requires below : x ≤ y404shows z - y ≤ z - x405proof406have shape : (z - x) - (z - y) = y - x byring407unfold integerLe408rw shape409exact below410411theorem integerLe.exists_natural (x y : Integer)412requires below : x ≤ y413shows∃ n, Nat(n) ∧ y = x + integerOfNat(n)414proof415unfold integerLe at below416obtain⟨n, nNat, shape⟩:= IntegerNonnegative.exists_natural with below417witness n418have restore : y = x + (y - x) byring419rw [restore, shape]420rfl421422theorem integerLe.of_natural (x y : Integer, n : Nat)423requires shape : y = x + integerOfNat(n)424shows x ≤ y425proof426unfold integerLe427rw shape428have cancel : x + integerOfNat(n) - x = integerOfNat(n) byring429rw cancel430exact IntegerNonnegative.ofNat with*431432theorem integerLe.ofNat_iff (a b : Nat)433shows integerOfNat(a) ≤ integerOfNat(b) ↔ a ≤ b434proof435constructor436 . intro below437obtain⟨n, nNat, shape⟩:= integerLe.exists_natural with below438have sum := integerOfNat.add at a, n439rw← sum at shape440have same := integerOfNat.injective with shape441witness n442 symm443exact same444 . intro below445obtain⟨n, nNat, equation⟩:= below446have sum := integerOfNat.add at a, n447apply integerLe.of_natural at integerOfNat(a), integerOfNat(b), n448rw [← sum, equation]449rfl450451theorem integerLe.cases_sign (x : Integer)452shows0≤ x ∨ x ≤0453proof454havesplit:= IntegerNonnegative.cases at x with*455casessplitwith nonnegative | negative456 . left457exact integerLe.zero_iff.backward with nonnegative458 . right459have lifted := integerLe.zero_iff.backward with negative460exact integerLe.neg_nonneg_iff.forward with lifted461462theorem integerLe.exists_negative (x : Integer)463requires nonpositive : x ≤0464shows∃ n, Nat(n) ∧ x = integerNegativeOfNat(n)465proof466have negated := integerLe.neg_nonneg_iff.backward with nonpositive467have nonnegative := integerLe.zero_iff.forward with negated468obtain⟨n, nNat, shape⟩:=469 IntegerNonnegative.exists_natural with nonnegative470witness n471have restore : x = -(-x) byring472rw [restore, shape]473exact integerOfNat.neg with*474475theorem integerLess.iff_add_one_le (x y : Integer)476shows x < y ↔ x +1≤ y477proof478constructor479 . intro below480unfold integerLess at below481exact below482 . intro below483unfold integerLess484exact below485486theorem integerLess.zero_iff_positive (x : Integer)487shows0 < x ↔ IntegerPositive(x)488proof489have shape : x - (integerZero +1) = x - 1byring490have positive := IntegerPositive.iff_sub_one at x with*491constructor492 . intro below493unfold integerLess at below494unfold integerLe at below495rw shape at below496exact positive.backward with below497 . intro isPositive498have nonnegative := positive.forward with isPositive499unfold integerLess500unfold integerLe501rw shape502exact nonnegative503504theorem integerLess.sub_positive_iff (x y : Integer)505shows x < y ↔0 < y - x506proof507have shape : y - (x +1) = (y - x) - (integerZero +1) byring508constructor509 . intro below510unfold integerLess at below511unfold integerLe at below512rw shape at below513unfold integerLess514unfold integerLe515exact below516 . intro below517unfold integerLess at below518unfold integerLe at below519unfold integerLess520unfold integerLe521rw shape522exact below523524theorem integerLess.add_one (x : Integer)525shows x < x +1526proof527unfold integerLess528exact integerLe.reflexive with*529530theorem integerLe.add_one (x : Integer)531shows x ≤ x +1532proof533apply integerLe.of_natural at x, x +1, 1534unfold integerOne535rfl536537theorem integerLess.implies_le (x y : Integer)538requires below : x < y539shows x ≤ y540proof541unfold integerLess at below542have step := integerLe.add_one at x543exact integerLe.transitive with step, below544545theorem integerLess.irreflexive (x : Integer)546shows¬x < x547proof548intro below549unfold integerLess at below550unfold integerLe at below551have shape : x - (x +1) = integerNegativeOfNat(1)552have flipped := integerOfNat.neg at1553unfold integerOne554rw← flipped555ring556rw shape at below557have zero := IntegerNonnegative.negative_iff.forward with below558have impossible : 0 < 1bylinarith559rw zero at impossible560exact Less.irreflexive with impossible561562theorem integerLess.ne (x y : Integer)563requires below : x < y564shows x ≠ y565proof566intro same567rw same at below568exact integerLess.irreflexive with below569570theorem integerLess.transitive_le (x y z : Integer)571requires first : x < y572requires second : y ≤ z573shows x < z574proof575unfold integerLess at first576unfold integerLess577exact integerLe.transitive with first, second578579theorem integerLe.transitive_less (x y z : Integer)580requires first : x ≤ y581requires second : y < z582shows x < z583proof584unfold integerLess at second585unfold integerLess586have step := integerLe.add_right at x, y, integerOne with first587exact integerLe.transitive with step, second588589theorem integerLess.transitive (x y z : Integer)590requires first : x < y591requires second : y < z592shows x < z593proof594have weak := integerLess.implies_le with second595exact integerLess.transitive_le with first, weak596597theorem integerLess.of_le_ne (x y : Integer)598requires below : x ≤ y599requires distinct : x ≠ y600shows x < y601proof602obtain⟨n, nNat, shape⟩:= integerLe.exists_natural with below603havesplit:= natural.zero_or_successor at n604casessplitwith zero | successor605 . rw [zero, integerOfNat.zero] at shape606have same : x = y607rw shape608ring609exfalso610exact distinct with same611 . obtain⟨k, kNat, equation⟩:= successor612have step : succ(k) = k +1byring613rw [equation, step] at shape614have sum := integerOfNat.add at k, 1615have one : integerOfNat(1) =1616unfold integerOne617rfl618rw [sum, one] at shape619unfold integerLess620apply integerLe.of_natural at x +1, y, k621rw shape622ring623624theorem integerLess.iff_le_ne (x y : Integer)625shows x < y ↔ x ≤ y ∧ x ≠ y626proof627constructor628 . intro below629exact⟨integerLess.implies_le with below, integerLess.ne with below⟩630 . intro both631exact integerLess.of_le_ne with both.left, both.right632633theorem integerLe.cases (x y : Integer)634requires below : x ≤ y635shows x < y ∨ x = y636proof637havesplit : x = y ∨ x ≠ y bytauto638casessplitwith same | distinct639 . right640exact same641 . left642exact integerLess.of_le_ne with below, distinct643644theorem integerLe.not_less (x y : Integer)645requires below : x ≤ y646shows¬y < x647proof648intro above649have cycle := integerLess.transitive_le with above, below650exact integerLess.irreflexive with cycle651652theorem integerLess.not_le (x y : Integer)653requires below : x < y654shows¬y ≤ x655proof656intro above657have cycle := integerLess.transitive_le with below, above658exact integerLess.irreflexive with cycle659660theorem integerLess.asymmetric (x y : Integer)661requires below : x < y662shows¬y < x663proof664have weak := integerLess.implies_le with below665exact integerLe.not_less with weak666667theorem integerLe.of_not_less (x y : Integer)668requires notBelow : ¬x < y669shows y ≤ x670proof671have total := integerLe.total at x, y672cases total with below | above673 . havesplit:= integerLe.cases with below674casessplitwith strict | same675 . exfalso676exact notBelow with strict677 . rw same678exact integerLe.reflexive with*679 . exact above680681theorem integerLess.of_not_le (x y : Integer)682requires notBelow : ¬x ≤ y683shows y < x684proof685have total := integerLe.total at x, y686cases total with below | above687 . exfalso688exact notBelow with below689 . have distinct : y ≠ x690intro same691rw same at notBelow692exact notBelow with (integerLe.reflexive at x)693exact integerLess.of_le_ne with above, distinct694695theorem integerLess.trichotomy (x y : Integer)696shows x < y ∨ x = y ∨ y < x697proof698have total := integerLe.total at x, y699cases total with below | above700 . havesplit:= integerLe.cases with below701casessplitwith strict | same702 . left703exact strict704 . right705left706exact same707 . havesplit:= integerLe.cases with above708casessplitwith strict | same709 . right710right711exact strict712 . right713left714 symm715exact same716717theorem integerLess.add_right (x y z : Integer)718requires below : x < y719shows x + z < y + z720proof721unfold integerLess at below722unfold integerLess723have shape : x + z +1= (x +1) + z byring724rw shape725exact integerLe.add_right with below726727theorem integerLess.add_left (x y z : Integer)728requires below : x < y729shows z + x < z + y730proof731have shifted := integerLess.add_right at x, y, z with below732haveleft : x + z = z + x byring733haveright : y + z = z + y byring734rw [left, right] at shifted735exact shifted736737theorem integerLess.add_le (a b c d : Integer)738requires first : a < b739requires second : c ≤ d740shows a + c < b + d741proof742haveleft:= integerLess.add_right at a, b, c with first743haveright:= integerLe.add_left at c, d, b with second744exact integerLess.transitive_le withleft, right745746theorem integerLe.add_less (a b c d : Integer)747requires first : a ≤ b748requires second : c < d749shows a + c < b + d750proof751haveleft:= integerLe.add_right at a, b, c with first752haveright:= integerLess.add_left at c, d, b with second753exact integerLe.transitive_less withleft, right754755theorem integerLess.add (a b c d : Integer)756requires first : a < b757requires second : c < d758shows a + c < b + d759proof760have weak := integerLess.implies_le with second761exact integerLess.add_le with first, weak762763theorem integerLess.add_right_cancel (x y z : Integer)764requires below : x + z < y + z765shows x < y766proof767have shifted := integerLess.add_right at x + z, y + z, -z with below768haveleft : x + z + (-z) = x byring769haveright : y + z + (-z) = y byring770rw [left, right] at shifted771exact shifted772773theorem integerLess.neg (x y : Integer)774shows x < y ↔ -y < -x775proof776have shape : (-x) - (-y +1) = y - (x +1) byring777constructor778 . intro below779unfold integerLess at below780unfold integerLe at below781unfold integerLess782unfold integerLe783rw shape784exact below785 . intro below786unfold integerLess at below787unfold integerLe at below788rw shape at below789unfold integerLess790unfold integerLe791exact below792793theorem integerLess.zero_one794shows integerZero < integerOne795proof796unfold integerLess797have shape : integerZero +1= integerOne byring798rw shape799exact integerLe.reflexive with*800801theorem integerLess.ofNat_iff (a b : Nat)802shows integerOfNat(a) < integerOfNat(b) ↔ a < b803proof804have sum := integerOfNat.add at a, 1805have one : integerOfNat(1) =1806unfold integerOne807rfl808have gap := Less.gap at a, b809have bridge := integerLe.ofNat_iff at a +1, b810constructor811 . intro below812unfold integerLess at below813rw [← one, ← sum] at below814have weak := bridge.forward with below815exact gap.backward with weak816 . intro below817have weak := gap.forward with below818have lifted := bridge.backward with weak819unfold integerLess820rw [← one, ← sum]821exact lifted822823theorem integerLess.one_le_of_positive (x : Integer)824requires positive : 0 < x825shows1≤ x826proof827unfold integerLess at positive828have shape : integerZero +1= integerOne byring829rw shape at positive830exact positive831832theorem integerLess.not_between (x y : Integer)833requires first : x < y834requires second : y < x +1835shows⊥836proof837unfold integerLess at first838unfold integerLess at second839have cancelled := integerLe.add_right_cancel at y, x, integerOne with second840have cycle := integerLe.transitive with first, cancelled841exact integerLess.irreflexive at x with cycle842