1-- Everyday order lemmas on the natural numbers2-- 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.Nat.OrderLemmas8import Order910theorem LessEqual.of_eq (a b : Nat)11requires same : a = b12shows a ≤ b13proof14rw same15exact LessEqual.reflexive with*1617theorem LessEqual.exists_add (a b : Nat)18requires below : a ≤ b19shows∃ k, Nat(k) ∧ b = a + k20proof21obtain⟨k, kNat, equation⟩:= below22witness k23 symm24exact equation2526theorem Less.ne (a b : Nat)27requires below : a < b28shows a ≠ b29proof30intro same31rw same at below32have excluded := Less.irreflexive at b33exact excluded with below3435theorem Less.ne_reverse (a b : Nat)36requires below : a < b37shows b ≠ a38proof39intro same40rw same at below41have excluded := Less.irreflexive at a42exact excluded with below4344theorem Less.of_LessEqual_ne (a b : Nat)45requires below : a ≤ b46requires distinct : a ≠ b47shows a < b48proof49have comparison := Less.trichotomy at a, b with*50rcases comparison with less | equal | greater51 . exact less52 . exfalso53exact distinct with equal54 . have weak := Less.implies_LessEqual with greater55have same := LessEqual.antisymmetric with below, weak56exfalso57exact distinct with same5859theorem Less.iff_LessEqual_ne (a b : Nat)60shows a < b ↔ a ≤ b ∧ a ≠ b61proof62constructor63 . intro below64exact⟨Less.implies_LessEqual with below, Less.ne with below⟩65 . intro both66exact Less.of_LessEqual_ne with both.left, both.right6768theorem LessEqual.cases (a b : Nat)69requires below : a ≤ b70shows a < b ∨ a = b71proof72havesplit : a = b ∨ a ≠ b bytauto73casessplitwith same | distinct74 . right75exact same76 . left77exact Less.of_LessEqual_ne with*7879theorem LessEqual.iff_Less_or_eq (a b : Nat)80shows a ≤ b ↔ a < b ∨ a = b81proof82constructor83 . intro below84exact LessEqual.cases with below85 . introsplit86casessplitwith less | same87 . exact Less.implies_LessEqual with less88 . exact LessEqual.of_eq with same8990theorem LessEqual.not_Less (a b : Nat)91requires below : a ≤ b92shows¬b < a93proof94intro above95have cycle := Less.transitive_LessEqual with above, below96have excluded := Less.irreflexive at b97exact excluded with cycle9899theorem Less.not_LessEqual (a b : Nat)100requires below : a < b101shows¬b ≤ a102proof103intro above104have cycle := Less.transitive_LessEqual with below, above105have excluded := Less.irreflexive at a106exact excluded with cycle107108theorem Less.asymmetric (a b : Nat)109requires below : a < b110shows¬b < a111proof112exact LessEqual.not_Less with (Less.implies_LessEqual with below)113114theorem LessEqual.iff_not_Less (a b : Nat)115shows a ≤ b ↔¬b < a116proof117constructor118 . intro below119exact LessEqual.not_Less with below120 . intro notAbove121exact LessEqual.of_not_Less with notAbove122123theorem Less.iff_not_LessEqual (a b : Nat)124shows a < b ↔¬b ≤ a125proof126constructor127 . intro below128exact Less.not_LessEqual with below129 . intro notAbove130exact Less.of_not_LessEqual with notAbove131132theorem LessEqual.antisymmetric_iff (a b : Nat)133shows a = b ↔ a ≤ b ∧ b ≤ a134proof135constructor136 . intro same137constructor138 . exact LessEqual.of_eq with same139 . symm at same140exact LessEqual.of_eq with same141 . intro both142exact LessEqual.antisymmetric with both.left, both.right143144theorem Less.or_LessEqual (a b : Nat)145shows a < b ∨ b ≤ a146proof147havesplit : a < b ∨¬a < b bytauto148casessplitwith less | notLess149 . left150exact less151 . right152exact LessEqual.of_not_Less with notLess153154theorem Less.not_below_zero (a : Nat)155shows¬a < 0156proof157intro below158have zero : 0≤ a bylinarith159exact Less.not_LessEqual with below, zero160161theorem LessEqual.eq_zero (a : Nat)162requires below : a ≤0163shows a =0164proof165have zero : 0≤ a bylinarith166exact LessEqual.antisymmetric with below, zero167168theorem LessEqual.zero_iff (a : Nat)169shows a ≤0↔ a =0170proof171constructor172 . intro below173exact LessEqual.eq_zero with below174 . intro zero175rw zero176exact LessEqual.reflexive with*177178theorem Less.positive_of_ne_zero (a : Nat)179requires nonzero : a ≠0180shows0 < a181proof182have zero : 0≤ a bylinarith183have distinct : 0≠ a184intro same185 symm at same186exact nonzero with same187exact Less.of_LessEqual_ne with zero, distinct188189theorem Less.ne_zero_of_positive (a : Nat)190requires positive : 0 < a191shows a ≠0192proof193exact Less.ne_reverse with positive194195theorem Less.positive_iff (a : Nat)196shows0 < a ↔ a ≠0197proof198constructor199 . intro positive200exact Less.ne_zero_of_positive with positive201 . intro nonzero202exact Less.positive_of_ne_zero with nonzero203204theorem LessEqual.one_of_positive (a : Nat)205requires positive : 0 < a206shows1≤ a207proof208linarith209210theorem LessEqual.one_iff_positive (a : Nat)211shows1≤ a ↔0 < a212proof213constructor214 . intro one215linarith216 . intro positive217linarith218219theorem LessEqual.one_iff_ne_zero (a : Nat)220shows1≤ a ↔ a ≠0221proof222constructor223 . intro one224have positive : 0 < a bylinarith225exact Less.ne_zero_of_positive with positive226 . intro nonzero227have positive := Less.positive_of_ne_zero with nonzero228linarith229230theorem Less.zero_one231shows0 < 1232proof233linarith234235theorem Less.add_one (a : Nat)236shows a < a +1237proof238linarith239240theorem LessEqual.add_one (a : Nat)241shows a ≤ a +1242proof243linarith244245theorem Less.add_one_iff (a b : Nat)246shows a < b +1↔ a ≤ b247proof248constructor249 . intro below250linarith251 . intro below252linarith253254theorem LessEqual.add_one_iff (a b : Nat)255shows a +1≤ b +1↔ a ≤ b256proof257constructor258 . intro below259linarith260 . intro below261linarith262263theorem Less.add_one_both_iff (a b : Nat)264shows a +1 < b +1↔ a < b265proof266constructor267 . intro below268linarith269 . intro below270linarith271272theorem LessEqual.add_left_self (a k : Nat)273shows a ≤ k + a274proof275linarith276277theorem LessEqual.add_monotone_left (a b c : Nat)278requires below : a ≤ b279shows c + a ≤ c + b280proof281linarith282283theorem LessEqual.add_right_iff (a b c : Nat)284shows a + c ≤ b + c ↔ a ≤ b285proof286constructor287 . intro below288exact LessEqual.add_right_cancel with below289 . intro below290linarith291292theorem LessEqual.add_left_iff (a b c : Nat)293shows c + a ≤ c + b ↔ a ≤ b294proof295constructor296 . intro below297exact LessEqual.add_left_cancel with below298 . intro below299linarith300301theorem Less.add_monotone_right (a b c : Nat)302requires below : a < b303shows a + c < b + c304proof305linarith306307theorem Less.add_monotone_left (a b c : Nat)308requires below : a < b309shows c + a < c + b310proof311linarith312313theorem Less.add_left_cancel (a b c : Nat)314requires below : c + a < c + b315shows a < b316proof317linarith318319theorem Less.add_right_iff (a b c : Nat)320shows a + c < b + c ↔ a < b321proof322constructor323 . intro below324linarith325 . intro below326linarith327328theorem Less.add_left_iff (a b c : Nat)329shows c + a < c + b ↔ a < b330proof331constructor332 . intro below333linarith334 . intro below335linarith336337theorem LessEqual.of_add_left (a b c : Nat)338requires below : a + b ≤ c339shows a ≤ c340proof341linarith342343theorem LessEqual.of_add_right (a b c : Nat)344requires below : a + b ≤ c345shows b ≤ c346proof347linarith348349theorem Less.of_add_left (a b c : Nat)350requires below : a + b < c351shows a < c352proof353linarith354355theorem Less.of_add_right (a b c : Nat)356requires below : a + b < c357shows b < c358proof359linarith360361theorem Less.add_positive_left (a k : Nat)362requires positive : 0 < k363shows a < k + a364proof365linarith366367theorem Less.add_positive_right (a k : Nat)368requires positive : 0 < k369shows a < a + k370proof371linarith372373theorem LessEqual.double (a : Nat)374shows a ≤ a + a375proof376linarith377378theorem Less.double_of_positive (a : Nat)379requires positive : 0 < a380shows a < a + a381proof382linarith383384theorem LessEqual.mul_right (a b k : Nat)385requires below : a ≤ b386shows a * k ≤ b * k387proof388haveleft:= LessEqual.mul_left at a, b, k with below389have swapA := mul.commutative at a, k with*390have swapB := mul.commutative at b, k with*391rw [swapA, swapB] atleft392exactleft393394theorem LessEqual.mul (a b c d : Nat)395requires first : a ≤ b396requires second : c ≤ d397shows a * c ≤ b * d398proof399haveleft:= LessEqual.mul_right at a, b, c with first400haveright:= LessEqual.mul_left at c, d, b with second401exact LessEqual.transitive withleft, right402403theorem Less.mul_right (a b k : Nat)404requires positive : k ≠0405requires below : a < b406shows a * k < b * k407proof408haveleft:= Less.mul_left at a, b, k with positive, below409have swapA := mul.commutative at a, k with*410have swapB := mul.commutative at b, k with*411rw [swapA, swapB] atleft412exactleft413414theorem Less.mul (a b c d : Nat)415requires first : a < b416requires second : c < d417shows a * c < b * d418proof419have bPositive : b ≠0420intro zero421rw zero at first422exact Less.not_below_zero with first423have weak := Less.implies_LessEqual with first424haveleft:= LessEqual.mul_right at a, b, c with weak425haveright:= Less.mul_left at c, d, b with bPositive, second426exact LessEqual.transitive_Less withleft, right427428theorem Less.mul_positive (a b : Nat)429requires first : 0 < a430requires second : 0 < b431shows0 < a * b432proof433have aNonzero := Less.ne_zero_of_positive with first434have bNonzero := Less.ne_zero_of_positive with second435have nonzero := mul.nonzero with aNonzero, bNonzero436exact Less.positive_of_ne_zero with nonzero437438theorem mul.positive_iff (a b : Nat)439shows0 < a * b ↔0 < a ∧0 < b440proof441constructor442 . intro positive443have nonzero := Less.ne_zero_of_positive with positive444constructor445 . apply Less.positive_of_ne_zero446intro zero447rw zero at nonzero448have vanish := mul.left_zero at b449exact nonzero with vanish450 . apply Less.positive_of_ne_zero451intro zero452rw zero at nonzero453have vanish := mul.right_zero at a454exact nonzero with vanish455 . intro both456exact Less.mul_positive with both.left, both.right457458theorem mul.eq_zero_iff (a b : Nat)459shows a * b =0↔ a =0∨ b =0460proof461constructor462 . intro zero463havesplit : a =0∨ a ≠0bytauto464casessplitwith aZero | aNonzero465 . left466exact aZero467 . right468have factor := mul.eq_zero with zero469cases factor with first | second470 . exfalso471exact aNonzero with first472 . exact second473 . introsplit474casessplitwith aZero | bZero475 . rw aZero476exact mul.left_zero with*477 . rw bZero478exact mul.right_zero with*479480theorem LessEqual.mul_left_cancel_positive (a b k : Nat)481requires positive : k ≠0482requires below : k * a ≤ k * b483shows a ≤ b484proof485havesplit:= Less.or_LessEqual at b, a486casessplitwith above | fine487 . have strict := Less.mul_left at b, a, k with positive, above488exfalso489exact LessEqual.not_Less with below, strict490 . exact fine491492theorem LessEqual.mul_right_cancel_positive (a b k : Nat)493requires positive : k ≠0494requires below : a * k ≤ b * k495shows a ≤ b496proof497have swapA := mul.commutative at k, a with*498have swapB := mul.commutative at k, b with*499rw [swapA, swapB] at below500exact LessEqual.mul_left_cancel_positive with positive, below501502theorem Less.mul_right_cancel_positive (a b k : Nat)503requires positive : k ≠0504requires below : a * k < b * k505shows a < b506proof507have swapA := mul.commutative at k, a with*508have swapB := mul.commutative at k, b with*509rw [swapA, swapB] at below510exact Less.mul_left_cancel_positive with positive, below511512theorem LessEqual.le_mul_left (a k : Nat)513requires positive : k ≠0514shows a ≤ k * a515proof516have one := LessEqual.one_iff_ne_zero.backward with positive517have scaled := LessEqual.mul_right at1, k, a with one518have unit := mul.left_unit at a519rw unit at scaled520exact scaled521522theorem LessEqual.le_mul_right (a k : Nat)523requires positive : k ≠0524shows a ≤ a * k525proof526haveleft:= LessEqual.le_mul_left at a, k with positive527have swap := mul.commutative at a, k with*528rw swap atleft529exactleft530531theorem LessEqual.one_le_mul (a b : Nat)532requires first : 1≤ a533requires second : 1≤ b534shows1≤ a * b535proof536have product := LessEqual.mul with first, second537have unit := mul.left_unit at1538rw unit at product539exact product540541theorem LessEqual.mul_self (a : Nat)542shows a ≤ a * a543proof544havesplit : a =0∨ a ≠0bytauto545casessplitwith zero | nonzero546 . rw zero547linarith548 . exact LessEqual.le_mul_left with nonzero549550theorem mul.eq_one (a b : Nat)551requires product : a * b =1552shows a =1∧ b =1553proof554have aNonzero : a ≠0555intro zero556rw zero at product557have vanish := mul.left_zero at b558rw vanish at product559have impossible : 0 < 0bylinarith560exact Less.irreflexive with impossible561have bNonzero : b ≠0562intro zero563rw zero at product564have vanish := mul.right_zero at a565rw vanish at product566have impossible : 0 < 0bylinarith567exact Less.irreflexive with impossible568have aBound := LessEqual.le_mul_right at a, b with bNonzero569have bBound := LessEqual.le_mul_left at b, a with aNonzero570rw product at aBound571rw product at bBound572have aOne := LessEqual.one_iff_ne_zero.backward with aNonzero573have bOne := LessEqual.one_iff_ne_zero.backward with bNonzero574constructor575 . exact LessEqual.antisymmetric with aBound, aOne576 . exact LessEqual.antisymmetric with bBound, bOne577578theorem Less.one_lt_iff (a : Nat)579shows1 < a ↔ a ≠0∧ a ≠1580proof581constructor582 . intro above583constructor584 . intro zero585rw zero at above586exact Less.not_below_zero with above587 . exact Less.ne_reverse with above588 . intro both589have one := LessEqual.one_iff_ne_zero.backward with both.left590have distinct : 1≠ a591intro same592 symm at same593exact both.right with same594exact Less.of_LessEqual_ne with one, distinct595596theorem Less.exists_add_one (a b : Nat)597requires below : a < b598shows∃ k, Nat(k) ∧ b = a + k +1599proof600obtain⟨k, kNat, equation⟩:= below601witness k602have shape : succ(a) + k = a + k +1byring603rw shape at equation604 symm605exact equation606607theorem Less.add_one_le_of_lt (a b : Nat)608requires below : a < b609shows a +1≤ b610proof611linarith612613theorem Less.of_add_one_le (a b : Nat)614requires below : a +1≤ b615shows a < b616proof617linarith618619theorem Less.lt_of_lt_of_eq (a b c : Nat)620requires below : a < b621requires same : b = c622shows a < c623proof624rw← same625exact below626627theorem LessEqual.le_of_le_of_eq (a b c : Nat)628requires below : a ≤ b629requires same : b = c630shows a ≤ c631proof632rw← same633exact below634