1-- Laws of truncated subtraction 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.SubtractionLemmas8import Subtraction9import OrderLemmas1011theorem predecessor.le (n : Nat)12shows predecessor(n) ≤ n13proof14have shape := natural.zero_or_successor at n15cases shape with zero | successor16 . rw [zero, predecessor.zero]17exact LessEqual.reflexive with*18 . obtain⟨k, kNat, equation⟩:= successor19rw [equation, predecessor.succ]20exact LessEqual.successor with*2122theorem predecessor.add_one (n : Nat)23shows predecessor(n +1) = n24proof25have shape := add.right_one at n26rw shape27exact predecessor.succ with*2829theorem predecessor.add_one_of_positive (n : Nat)30requires positive : 0 < n31shows predecessor(n) +1= n32proof33have shape := natural.zero_or_successor at n34cases shape with zero | successor35 . rw zero at positive36exfalso37exact Less.irreflexive with positive38 . obtain⟨k, kNat, equation⟩:= successor39rw [equation, predecessor.succ]40exact add.right_one with*4142theorem predecessor.Less_of_positive (n : Nat)43requires positive : 0 < n44shows predecessor(n) < n45proof46have predNat := predecessor.closed at n47have shape := predecessor.add_one_of_positive with positive48have bound : predecessor(n) < predecessor(n) +1bylinarith49rw shape at bound50exact bound5152theorem predecessor.monotone (m n : Nat)53requires below : m ≤ n54shows predecessor(m) ≤ predecessor(n)55proof56have shape := natural.zero_or_successor at m57cases shape with zero | successor58 . rw [zero, predecessor.zero]59have predNat := predecessor.closed at n60linarith61 . obtain⟨k, kNat, equation⟩:= successor62rw equation at below63have nShape := natural.zero_or_successor at n64cases nShape with nZero | nSuccessor65 . rw nZero at below66exfalso67have impossible : succ(k) ≤0:= below68have positive : 0 < succ(k) bylinarith69exact Less.not_LessEqual with positive, impossible70 . obtain⟨j, jNat, nEquation⟩:= nSuccessor71rw nEquation at below72rw [equation, nEquation, predecessor.succ, predecessor.succ]73have stepK : succ(k) = k +1byring74have stepJ : succ(j) = j +1byring75rw [stepK, stepJ] at below76linarith7778theorem sub.add_left (m n : Nat)79shows (n + m) - n = m80proof81have swap := add.commutative at m, n with*82rw swap83exact sub.add_right with*8485theorem sub.self (n : Nat)86shows n - n =087proof88have shape := sub.add_right at0, n89have unit := add.left_unit at n90rw unit at shape91exact shape9293theorem sub.of_add_eq (a b c : Nat)94requires sum : a + b = c95shows c - b = a96proof97rw← sum98exact sub.add_right with*99100theorem sub.of_add_eq_left (a b c : Nat)101requires sum : a + b = c102shows c - a = b103proof104rw← sum105exact sub.add_left with*106107theorem sub.add_cancel (a b : Nat)108requires below : b ≤ a109shows a - b + b = a110proof111obtain⟨k, kNat, equation⟩:= below112have value := sub.of_add_eq_left with equation113rw value114have swap := add.commutative at b, k with*115rw swap116exact equation117118theorem sub.add_cancel_left (a b : Nat)119requires below : b ≤ a120shows b + (a - b) = a121proof122have subNat := sub.closed at a, b123have cancel := sub.add_cancel with below124have swap := add.commutative at a - b, b with*125rw swap126exact cancel127128theorem sub.sub (a b c : Nat)129shows a - (b + c) = (a - b) - c130proof131induction c132| zero =>133have unit := add.right_unit at b134rw unit135have subNat := sub.closed at a, b136rw sub.zero_right137rfl138| succ(k) using ih =>139have shape := add.succ_right at k, b140rw shape141have subNat := sub.closed at a, b142have innerNat := sub.closed at a, b + k143rw [sub.succ_right, ih, sub.succ_right]144rfl145146theorem sub.swap (a b c : Nat)147shows (a - b) - c = (a - c) - b148proof149have first := sub.sub at a, b, c150have second := sub.sub at a, c, b151have swap := add.commutative at c, b with*152rw [← first, ← second, swap]153rfl154155theorem sub.eq_zero_of_le (a b : Nat)156requires below : a ≤ b157shows a - b =0158proof159obtain⟨k, kNat, equation⟩:= below160rw [← equation, sub.sub, sub.self]161exact sub.zero_left with*162163theorem sub.positive_of_Less (a b : Nat)164requires below : a < b165shows0 < b - a166proof167have peeled := sub.succ_of_Less at a with b, below168have innerNat := sub.closed at b, succ(a)169rw peeled170have step : succ(b - succ(a)) = (b - succ(a)) +1byring171rw step172linarith173174theorem sub.eq_zero_iff (a b : Nat)175shows a - b =0↔ a ≤ b176proof177constructor178 . intro zero179havesplit:= Less.or_LessEqual at b, a180casessplitwith above | below181 . have positive := sub.positive_of_Less with above182rw zero at positive183exfalso184exact Less.irreflexive with positive185 . exact below186 . intro below187exact sub.eq_zero_of_le with below188189theorem sub.positive_iff (a b : Nat)190shows0 < b - a ↔ a < b191proof192have subNat := sub.closed at b, a193constructor194 . intro positive195havesplit:= Less.or_LessEqual at a, b196casessplitwith below | above197 . exact below198 . have zero := sub.eq_zero_of_le with above199rw zero at positive200exfalso201exact Less.irreflexive with positive202 . intro below203exact sub.positive_of_Less with below204205theorem sub.le_self (a b : Nat)206shows a - b ≤ a207proof208induction b209| zero =>210rw sub.zero_right211exact LessEqual.reflexive with*212| succ(k) using ih =>213have subNat := sub.closed at a, k214have pred := predecessor.le at a - k215rw sub.succ_right216exact LessEqual.transitive with pred, ih217218theorem sub.monotone_left (a b c : Nat)219requires below : a ≤ b220shows a - c ≤ b - c221proof222induction c223| zero =>224rw [sub.zero_right, sub.zero_right]225exact below226| succ(k) using ih =>227have leftNat := sub.closed at a, k228have rightNat := sub.closed at b, k229rw [sub.succ_right, sub.succ_right]230exact predecessor.monotone with ih231232theorem sub.antitone_right (a b c : Nat)233requires below : b ≤ c234shows a - c ≤ a - b235proof236obtain⟨k, kNat, equation⟩:= below237have subNat := sub.closed at a, b238rw [← equation, sub.sub]239exact sub.le_self with*240241theorem sub.Less_self (a b : Nat)242requires aPositive : 0 < a243requires bPositive : 0 < b244shows a - b < a245proof246have one : 1≤ b bylinarith247have bound := sub.antitone_right at a, 1, b with one248have oneShape := sub.one at a249rw oneShape at bound250have pred := predecessor.Less_of_positive with aPositive251exact LessEqual.transitive_Less with bound, pred252253theorem sub.add_one_of_le (a b : Nat)254requires below : b ≤ a255shows (a +1) - b = (a - b) +1256proof257obtain⟨k, kNat, equation⟩:= below258have value := sub.of_add_eq_left with equation259rw [value, ← equation]260have shape : b + k +1= (k +1) + b byring261rw shape262exact sub.add_right with*263264theorem sub.add_sub_assoc (a b c : Nat)265requires below : c ≤ b266shows a + (b - c) = (a + b) - c267proof268obtain⟨k, kNat, equation⟩:= below269have value := sub.of_add_eq_left with equation270rw [value, ← equation]271have shape : a + (c + k) = (a + k) + c byring272rw shape273 symm274exact sub.add_right with*275276theorem sub.sub_cancel (a b : Nat)277requires below : b ≤ a278shows a - (a - b) = b279proof280obtain⟨k, kNat, equation⟩:= below281have value := sub.of_add_eq_left with equation282rw [value, ← equation]283exact sub.add_right with*284285theorem sub.add_add (a b c : Nat)286shows (a + c) - (b + c) = a - b287proof288have swap := add.commutative at c, b with*289rw [swap, sub.sub]290have cancel := sub.add_right at a, c291rw cancel292rfl293294theorem sub.add_one_both (a b : Nat)295shows (a +1) - (b +1) = a - b296proof297exact sub.add_add at a, b, 1298299theorem sub.add_one_right (n : Nat)300shows (n +1) - 1= n301proof302exact sub.add_right at n, 1303304theorem sub.le_iff (a b c : Nat)305shows a - b ≤ c ↔ a ≤ b + c306proof307have subNat := sub.closed at a, b308constructor309 . intro below310havesplit:= LessEqual.total at b, a311casessplitwith first | second312 . have cancel := sub.add_cancel_left with first313rw← cancel314linarith315 . linarith316 . intro below317have shifted := sub.monotone_left at a, b + c, b with below318have cancel := sub.add_left at c, b319rw cancel at shifted320exact shifted321322theorem sub.Less_iff (a b c : Nat)323requires below : b ≤ a324shows a - b < c ↔ a < b + c325proof326have subNat := sub.closed at a, b327have cancel := sub.add_cancel_left with below328constructor329 . intro strict330rw← cancel331linarith332 . intro strict333rw← cancel at strict334linarith335336theorem sub.eq_iff_of_le (a b c : Nat)337requires below : b ≤ a338shows a - b = c ↔ a = b + c339proof340have subNat := sub.closed at a, b341have cancel := sub.add_cancel_left with below342constructor343 . intro same344rw← same345 symm346exact cancel347 . intro same348rw same349exact sub.add_left with*350351theorem sub.Less_monotone_left (a b c : Nat)352requires below : c ≤ a353requires strict : a < b354shows a - c < b - c355proof356have leftNat := sub.closed at a, c357have rightNat := sub.closed at b, c358have weak : c ≤ b bylinarith359have leftCancel := sub.add_cancel_left with below360have rightCancel := sub.add_cancel_left at b, c with weak361rw [← leftCancel, ← rightCancel] at strict362linarith363364theorem sub.mul_right (a b c : Nat)365shows (a - b) * c = a * c - b * c366proof367havesplit:= LessEqual.total at b, a368casessplitwith below | above369 . obtain⟨k, kNat, equation⟩:= below370have value := sub.of_add_eq_left with equation371rw [value, ← equation]372have shape : (b + k) * c = b * c + k * c byring373rw shape374 symm375exact sub.add_left with*376 . have zero := sub.eq_zero_of_le with above377have scaled := LessEqual.mul_right at a, b, c with above378have productZero := sub.eq_zero_of_le with scaled379rw [zero, productZero]380exact mul.left_zero with*381382theorem sub.mul_left (a b c : Nat)383shows c * (a - b) = c * a - c * b384proof385have subNat := sub.closed at a, b386have swap := mul.commutative at a - b, c with*387have swapA := mul.commutative at a, c with*388have swapB := mul.commutative at b, c with*389rw [swap, swapA, swapB]390exact sub.mul_right with*391392theorem sub.le_of_le_add (a b c : Nat)393requires below : a ≤ b + c394shows a - c ≤ b395proof396have shifted := sub.monotone_left at a, b + c, c with below397have cancel := sub.add_right at b, c398rw cancel at shifted399exact shifted400401theorem sub.injective_of_le (a b c : Nat)402requires first : c ≤ a403requires second : c ≤ b404requires same : a - c = b - c405shows a = b406proof407have leftCancel := sub.add_cancel_left with first408have rightCancel := sub.add_cancel_left at b, c with second409rw [← leftCancel, ← rightCancel, same]410rfl411412-- A product splits along a subtraction of the first factor.413theorem mul.split_sub (p q C : Nat)414requires le : q ≤ p415shows p * C = (p - q) * C + q * C416proof417have pieces := sub.add_cancel with le418have difference := sub.closed at p, q419have expanded : (p - q + q) * C = (p - q) * C + q * C byring420rw pieces at expanded421exact expanded422