1-- Natural-number order and its von Neumann membership interpretation2-- 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.Order8import Core9import Foundation1011theorem LessEqual.zero (a : Nat)12shows0≤ a13proof14witness a15simp [add]1617-- These four addition laws are the small proof-producing certificate basis18-- used by linear arithmetic automation. They are Cumulus19-- theorems: an arithmetic oracle may search for combinations, but the kernel20-- sees only applications of these checked laws.21theorem LessEqual.add (a b c d : Nat)22requires hab : a ≤ b23requires hcd : c ≤ d24shows a + c ≤ b + d25proof26obtain⟨k, hkNat, hkEq⟩:= hab27obtain⟨l, hlNat, hlEq⟩:= hcd28witness k + l29have shuffle := add.four_shuffle at a, c, k, l30rw [shuffle, hkEq, hlEq]31rfl3233theorem Less.add_LessEqual (a b c d : Nat)34requires hab : a < b35requires hcd : c ≤ d36shows a + c < b + d37proof38unfold Less at hab39have haSucc := Naturals.constructor.succ at a40have sum := LessEqual.add with hab, hcd41unfold Less42 simpa [add] using sum4344theorem LessEqual.add_Less (a b c d : Nat)45requires hab : a ≤ b46requires hcd : c < d47shows a + c < b + d48proof49unfold Less at hcd50have sum := LessEqual.add at a, b, succ(c), d with*51unfold Less52 simpa [add.succ_right] using sum5354theorem Less.add (a b c d : Nat)55requires hab : a < b56requires hcd : c < d57shows a + c < b + d58proof59simp [Less.implies_LessEqual, Less.add_LessEqual]6061-- Adding a nonzero natural number moves strictly to the right. This compact62-- certificate is useful when polynomial normalization has isolated a positive63-- remainder.64theorem Less.add_positive (a k : Nat)65requires nonzero : k ≠066shows a < a + k67proof68have shape := natural.zero_or_successor at k69cases shape with zero | successor70 . exfalso71exact nonzero with zero72 . obtain⟨j, jNatural, kShape⟩:= successor73rw kShape74witness j75simp [add.successor_shift]7677theorem LessEqual.mul_left (a b k : Nat)78requires hab : a ≤ b79shows k * a ≤ k * b80proof81induction k82| zero =>83have zeroA := mul.left_zero at a84have zeroB := mul.left_zero at b85rw [zeroA, zeroB]86apply LessEqual.reflexive87| succ(j) using ih =>88have leftStep := mul.succ_left at j, a with h_j89have rightStep := mul.succ_left at j, b with h_j90rw [leftStep, rightStep]91have products := ih92apply LessEqual.add93 . assumption94 . assumption9596theorem Less.mul_left (a b k : Nat)97requires positive : k ≠098requires hab : a < b99shows k * a < k * b100proof101have shape := natural.zero_or_successor at k102cases shape with zero | successor103 . exfalso104apply positive105exact zero106 . obtain⟨j, hj⟩:= successor107rcases hj with⟨hjNat, kShape⟩108rw kShape109have leftStep := mul.succ_left at j, a with hjNat110have rightStep := mul.succ_left at j, b with hjNat111rw [leftStep, rightStep]112have weak := Less.implies_LessEqual with*113have products := LessEqual.mul_left at a, b, j with hjNat, weak114apply Less.add_LessEqual115 . assumption116 . assumption117118theorem LessEqual.add_right_cancel (a b c : Nat)119requires hab : a + c ≤ b + c120shows a ≤ b121proof122obtain⟨k, hkNat, hkEq⟩:= hab123witness k124apply add.right_cancel at a + k, b, c125 . have shuffle := add.swap_last at a, c, k with hkNat126 rwa ← shuffle127128theorem LessEqual.add_left_cancel (a b c : Nat)129requires hab : c + a ≤ c + b130shows a ≤ b131proof132haveleft:= add.commutative at a, c with*133rwleftat hab134haveright:= add.commutative at b, c with*135rwrightat hab136apply LessEqual.add_right_cancel137 . assumption138139theorem Less.add_right_cancel (a b c : Nat)140requires hab : a + c < b + c141shows a < b142proof143have shift : succ(a + c) = succ(a) + c bysimp [add]144unfold Less at hab145unfold Less146apply LessEqual.add_right_cancel at succ(a), b, c147 . settlewith Naturals.constructor.succ148149theorem Less.gap (a b : Nat)150shows a < b ↔ a +1≤ b151proof152simp [Less, add.right_one]153154-- Users reason with `<`; this bridge reveals that it is membership for the155-- von Neumann implementation of Nat only when set-theoretic access is useful.156theorem Less.of_membership (a b : Nat)157shows a ∈ b → a < b158proof159induction b160| zero =>161intro h162exfalso163settlewith nat.zero, set.empty164| succ(k) using ih =>165intro h166have shape := membership.successor_forward{n := k} at a167cases shape with hEarlier | hEqual168 . have earlier := ih with hEarlier169unfold Less at earlier170unfold Less171apply LessEqual.transitive172 . exact earlier173 . apply LessEqual.successor at k174 . rw hEqual175unfold Less176apply LessEqual.reflexive177178-- The converse bridge is kept here, at the explicit boundary between the179-- Nat order API and its von Neumann implementation.180lemma membership.add_right_successor (a : Set, k : Nat)181requires haNat : Nat(a)182shows a ∈ add(k, succ(a))183proof184induction k185| zero =>186settlewith add, membership.self_successor187| succ(j) using ih =>188have haSucc := Naturals.constructor.succ with haNat189have sumNat := add.closed with haSucc, h_j190settlewith add, membership.successor_backward, ih, sumNat191192theorem membership.of_Less (a b : Set)193requires haNat : Nat(a)194requires hbNat : Nat(b)195shows a < b → a ∈ b196proof197intro h198obtain⟨k, hkNat, hSum⟩:= h199rw← hSum200have haSucc := Naturals.constructor.succ with haNat201have commute := add.commutative with hkNat, haSucc202rw commute203apply membership.add_right_successor at a, k204205theorem Less.trichotomy (a b : Set)206requires haNat : Nat(a)207requires hbNat : Nat(b)208shows a < b ∨ a = b ∨ b < a209proof210simp [Ordinal.natural, Ordinal.trichotomy, Less.of_membership]211212theorem Less.irreflexive (a : Nat)213shows¬a < a214proof215intro h216have member := membership.of_Less with*, h217have irreflexive := membership.irreflexive at a218apply irreflexive219exact member220221theorem mul.left_cancel_positive (a b k : Nat)222requires positive : k ≠0223requires products : k * a = k * b224shows a = b225proof226have comparison := Less.trichotomy at a, b with*227cases comparison with hab | rest228 . have strict := Less.mul_left with positive, hab229rw products at strict230have productNat := mul.closed at b, k with*231have impossible := Less.irreflexive with productNat232exfalso233apply impossible234exact strict235 . cases rest with equal | hba236 . exact equal237 . have strict := Less.mul_left with positive, hba238rw products at strict239have productNat := mul.closed at b, k with*240have impossible := Less.irreflexive with productNat241exfalso242apply impossible243exact strict244245theorem Less.mul_left_cancel_positive (a b k : Nat)246requires positive : k ≠0247requires products : k * a < k * b248shows a < b249proof250have comparison := Less.trichotomy at a, b with*251cases comparison with less | rest252 . exact less253 . cases rest with equal | greater254 . rw equal at products255have productNat := mul.closed at b, k with*256have impossible := Less.irreflexive with productNat257exfalso258apply impossible259exact products260 . have reverseProducts := Less.mul_left with positive, greater261have productANat : Nat(k * a) bysimp [mul.closed]262have reverseWeak := Less.implies_LessEqual with reverseProducts263have cycle : k * a < k * a264unfold Less265apply LessEqual.transitive266 . exact products267 . exact reverseWeak268have impossible := Less.irreflexive with productANat269exfalso270apply impossible271exact cycle272273theorem Less.transitive_LessEqual (a b c : Nat)274requires hab : a < b275requires hbc : b ≤ c276shows a < c277proof278unfold Less at hab279unfold Less280apply LessEqual.transitive281 . settlewith Naturals.constructor.succ282 . assumption283284theorem Less.transitive (a b c : Nat)285requires hab : a < b286requires hbc : b < c287shows a < c288proof289have weak := Less.implies_LessEqual at b, c with*290exact Less.transitive_LessEqual with*291292theorem LessEqual.transitive_Less (a b c : Nat)293requires hab : a ≤ b294requires hbc : b < c295shows a < c296proof297have shifted := LessEqual.add_monotone_right at a, b, 1with*298simp [add.succ_right, add.right_unit] at shifted299unfold Less at hbc300unfold Less301apply LessEqual.transitive302 . settlewith Naturals.constructor.succ303 . settlewith Naturals.constructor.succ304305theorem LessEqual.antisymmetric (a b : Nat)306requires hab : a ≤ b307requires hba : b ≤ a308shows a = b309proof310have tri := Less.trichotomy at a, b with*311cases tri with habStrict | rest312 . have cycle := Less.transitive_LessEqual with habStrict, hba313have impossible := Less.irreflexive at a314exfalso315apply impossible316exact cycle317 . cases rest with equal | hbaStrict318 . exact equal319 . have cycle := Less.transitive_LessEqual with hbaStrict, hab320have impossible := Less.irreflexive at b321exfalso322apply impossible323exact cycle324325theorem Less.of_not_LessEqual (a b : Nat)326requires h : ¬a ≤ b327shows b < a328proof329have tri := Less.trichotomy at a, b with*330cases tri with hab | rest331 . exfalso332apply h333apply Less.implies_LessEqual334 . exact hab335 . cases rest with eqab | hba336 . exfalso337apply h338rw eqab339apply LessEqual.reflexive340assumption341342theorem LessEqual.of_not_Less (a b : Nat)343requires h : ¬a < b344shows b ≤ a345proof346have tri := Less.trichotomy at a, b with*347cases tri with hab | rest348 . exfalso349apply h350exact hab351 . cases rest with eqab | hba352 . rw eqab353apply LessEqual.reflexive354 . apply Less.implies_LessEqual at b, a355 . assumption356357-- These replacement laws package the ordered-additive reasoning used358-- after a denominator has been cleared. They keep client proofs focused on359-- the mathematical substitution rather than reassociation and cancellation.360theorem Less.replace_right (a b c d e f : Nat)361requires less : a + d < b + c362requires equal : c + f = d + e363shows a + f < b + e364proof365have reflexive := LessEqual.reflexive at f366have augmented := Less.add_LessEqual with less, reflexive367have leftShape : (a + d) + f = (a + f) + d byring368have rightShape : (b + c) + f = b + (c + f) byring369rw [leftShape, rightShape, equal] at augmented370have finalShape : b + (d + e) = (b + e) + d byring371rw finalShape at augmented372exact Less.add_right_cancel with augmented373374theorem Less.replace_left (a b c d e f : Nat)375requires equal : a + f = b + e376requires less : a + d < b + c377shows d + e < c + f378proof379have reflexive := LessEqual.reflexive at f380have augmented := Less.add_LessEqual with less, reflexive381have leftShape : (a + d) + f = (a + f) + d byring382have rightShape : (b + c) + f = (c + f) + b byring383rw [leftShape, rightShape, equal] at augmented384have finalShape : (b + e) + d = (d + e) + b byring385rw finalShape at augmented386exact Less.add_right_cancel with augmented387388theorem Less.cross_transitive (a b c d e f : Nat)389requiresleft : a + d < b + c390requiresright : c + f < d + e391shows a + f < b + e392proof393have reflexiveF := LessEqual.reflexive at f394have first := Less.add_LessEqual withleft, reflexiveF395have firstLeft : (a + d) + f = (a + f) + d byring396have firstRight : (b + c) + f = (c + f) + b byring397rw [firstLeft, firstRight] at first398have reflexiveB := LessEqual.reflexive at b399have second := Less.add_LessEqual withright, reflexiveB400have secondRight : (d + e) + b = (b + e) + d byring401rw secondRight at second402have secondWeak := Less.implies_LessEqual with second403have composed := Less.transitive_LessEqual with first, secondWeak404exact Less.add_right_cancel with composed405406-- A finite Boolean crossing on the naturals has a last included point. The407-- set S need not itself be finite or downward closed; only the finite interval408-- from zero to the omitted endpoint is inspected.409theorem natural.exists_boundary (S : Set, n : Nat)410shows0∈ S →¬(n ∈ S) →411∃ k, Nat(k) ∧ k ∈ S ∧¬(succ(k) ∈ S)412proof413induction n414| zero =>415intros zeroIn nMissing416exfalso417exact nMissing with zeroIn418| succ(j) using ih =>419intros zeroIn nMissing420havesplit : j ∈ S ∨¬(j ∈ S) bytauto421casessplitwith jIn | jMissing422 . witness j423refine⟨jIn, nMissing⟩424 . exact ih with zeroIn, jMissing425426theorem membership.successor_monotone (a b x : Set)427requires haNat : Nat(a)428requires hbNat : Nat(b)429requires hbInA : b ∈ a430requires hx : x ∈ succ(b)431shows x ∈ succ(a)432proof433have shape := membership.successor_forward{n := b} at x434apply membership.successor_backward{n := a} at x435left436cases shape with hxInB | hxEqB437 . have haOrdinal :=Ordinal.natural at a with haNat438have transitive :=Ordinal.transitive with haOrdinal439have bSubset := transitive with hbInA440exact bSubset with x, hxInB441 . rw hxEqB442exact hbInA443444theorem LessEqual.total (a b : Nat)445shows a ≤ b ∨ b ≤ a446proof447have comparison := Less.trichotomy at a, b with*448rcases comparison with less | equal | greater449 . left450arith451 . left452rw equal453exact LessEqual.reflexive with*454 . right455arith456457theorem Less.successor_upper (a b : Nat)458requires below : a < succ(b)459shows a ≤ b460proof461obtain⟨d, natural, equation⟩:= below462simp [add] at equation463have cancelled := Naturals.injective.succ with equation464unfold LessEqual465refine⟨d, natural, cancelled⟩466467theorem Less.successor_lower_of_ne (a b : Nat)468requires below : a < b469requires separated : b ≠ succ(a)470shows succ(a) < b471proof472havecases:= Less.trichotomy at succ(a), b with*473casescaseswith less | remaining474 . exact less475 . cases remaining with equal | reverse476 . have same : b = succ(a)477cc478exfalso479exact separated with same480 . have bound := Less.successor_upper with*481have impossible : a < a byarith482have excluded := Less.irreflexive at a with*483exfalso484exact excluded with impossible485486theorem Less.of_successor_upper_ne (a b : Nat)487requires below : a < succ(b)488requires separated : a ≠ b489shows a < b490proof491have member := membership.of_Less with*, below492have shape := membership.successor_forward{n := b} with member493cases shape with before | same494 . have bridge := Less.of_membership at a, b with*495exact bridge with before496 . exfalso497exact separated with same498