1-- Laws of natural-number exponentiation: exponent arithmetic, positivity,2-- and monotonicity in the base and in the exponent3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.Nat.PowLemmas9import Pow10import OrderLemmas1112theorem pow.add_one (a n : Nat)13shows a ^ (n +1) = a * a ^ n14proof15have shape := add.right_one at n16rw shape17exact pow.succ with*1819theorem pow.succ_right (a n : Nat)20shows a ^ (n +1) = a ^ n * a21proof22have powNat := pow.closed at a, n23rw pow.add_one24exact mul.commutative at a ^ n, a with*2526theorem pow.one_right (a : Nat)27shows a ^ 1= a28proof29simp [pow, mul.right_unit]3031theorem pow.two (a : Nat)32shows a ^ 2= a * a33proof34simp [pow, mul.right_unit]3536theorem pow.one_left (n : Nat)37shows1 ^ n =138proof39induction n40| zero =>simp [pow]41| succ(k) using ih =>simp [pow, ih, mul.left_unit]4243theorem pow.zero_left (n : Nat)44shows0 ^ (n +1) =045proof46rw pow.add_one47have powNat := pow.closed at0, n48exact mul.left_zero with*4950theorem pow.mul_base (a b n : Nat)51shows (a * b) ^ n = a ^ n * b ^ n52proof53induction n54| zero =>simp [pow, mul.right_unit]55| succ(k) using ih =>56have productNat : Nat(a * b) bytypecheck57have aPow := pow.closed at a, k58have bPow := pow.closed at b, k59rw [pow.succ, pow.succ, pow.succ, ih]60ring6162theorem pow.mul_exponent (a m n : Nat)63shows (a ^ m) ^ n = a ^ (m * n)64proof65induction n66| zero =>67have vanish := mul.right_zero at m68rw vanish69have basePow := pow.closed at a, m70rw [pow.zero, pow.zero]71rfl72| succ(k) using ih =>73have basePow := pow.closed at a, m74have productNat : Nat(m * k) bytypecheck75have shape : m * succ(k) = m + m * k byring76rw [pow.succ, ih, shape]77havesplit:= pow.add at a, m * k, m78rwsplit79rfl8081theorem pow.double_exponent (a k : Nat)82shows a ^ (2* k) = (a ^ k) ^ 283proof84have inner := pow.mul_exponent at a, k, 285have shape : k *2=2* k byring86rw [inner, shape]87rfl8889theorem pow.positive (a n : Nat)90requires positive : 0 < a91shows0 < a ^ n92proof93induction n94| zero =>95rw pow.zero96linarith97| succ(k) using ih =>98have powNat := pow.closed at a, k99rw pow.succ100exact Less.mul_positive with positive, ih101102theorem pow.ne_zero (a n : Nat)103requires nonzero : a ≠0104shows a ^ n ≠0105proof106have positive := Less.positive_of_ne_zero with nonzero107have powPositive := pow.positive at a, n with positive108exact Less.ne_zero_of_positive with powPositive109110theorem pow.eq_zero (a n : Nat)111requires zero : a ^ n =0112shows a =0113proof114by_contra nonzero115have excluded := pow.ne_zero at a, n with nonzero116exact excluded with zero117118theorem pow.eq_zero_iff (a n : Nat)119shows a ^ (n +1) =0↔ a =0120proof121constructor122 . intro zero123exact pow.eq_zero with zero124 . intro zero125rw zero126exact pow.zero_left with*127128theorem pow.ge_one (a n : Nat)129requires one : 1≤ a130shows1≤ a ^ n131proof132induction n133| zero =>134rw pow.zero135linarith136| succ(k) using ih =>137have powNat := pow.closed at a, k138rw pow.succ139exact LessEqual.one_le_mul with one, ih140141theorem pow.one_lt (a n : Nat)142requires above : 1 < a143shows1 < a ^ (n +1)144proof145have powNat := pow.closed at a, n146have one : 1≤ a bylinarith147have tail := pow.ge_one at a, n with one148have bound := LessEqual.mul at1, a, 1, a ^ n with one, tail149rw pow.add_one150have unit := mul.left_unit at1151rw unit at bound152have strict : 1 < a *1153have unit2 := mul.right_unit at a154rw unit2155exact above156have scaled := LessEqual.mul_left at1, a ^ n, a with tail157exact Less.transitive_LessEqual with strict, scaled158159theorem pow.base_monotone (a b n : Nat)160requires below : a ≤ b161shows a ^ n ≤ b ^ n162proof163induction n164| zero =>165rw [pow.zero, pow.zero]166exact LessEqual.reflexive with*167| succ(k) using ih =>168have aPow := pow.closed at a, k169have bPow := pow.closed at b, k170rw [pow.succ, pow.succ]171exact LessEqual.mul with below, ih172173theorem pow.base_strict (a b n : Nat)174requires below : a < b175shows a ^ (n +1) < b ^ (n +1)176proof177induction n178| zero =>179have shape : 0+1=1byring180rw [shape, pow.one_right, pow.one_right]181exact below182| succ(k) using ih =>183have aPow := pow.closed at a, k +1184have bPow := pow.closed at b, k +1185have leftShape : a ^ (succ(k) +1) = a * a ^ (k +1)186have step : succ(k) +1= (k +1) +1byring187rw step188exact pow.add_one with*189have rightShape : b ^ (succ(k) +1) = b * b ^ (k +1)190have step : succ(k) +1= (k +1) +1byring191rw step192exact pow.add_one with*193rw [leftShape, rightShape]194exact Less.mul with below, ih195196theorem pow.two_monotone (a b : Nat)197requires below : a ≤ b198shows a ^ 2≤ b ^ 2199proof200exact pow.base_monotone at a, b, 2with below201202theorem pow.two_strict (a b : Nat)203requires below : a < b204shows a ^ 2 < b ^ 2205proof206have strict := pow.base_strict at a, b, 1with below207have shape : 1+1=2byring208rw shape at strict209exact strict210211theorem pow.injective_base (a b n : Nat)212requires same : a ^ (n +1) = b ^ (n +1)213shows a = b214proof215have comparison := Less.trichotomy at a, b with*216rcases comparison with less | equal | greater217 . have strict := pow.base_strict at a, b, n with less218rw same at strict219exfalso220exact Less.irreflexive with strict221 . exact equal222 . have strict := pow.base_strict at b, a, n with greater223rw same at strict224exfalso225exact Less.irreflexive with strict226227theorem pow.exponent_monotone (a m n : Nat)228requires one : 1≤ a229requires below : m ≤ n230shows a ^ m ≤ a ^ n231proof232obtain⟨k, kNat, equation⟩:= below233have aPow := pow.closed at a, m234have tailNonzero : a ^ k ≠0235have nonzero := LessEqual.one_iff_ne_zero.forward with one236exact pow.ne_zero at a, k with nonzero237havesplit:= pow.add at a, k, m238rw← equation239rwsplit240exact LessEqual.le_mul_right at a ^ m, a ^ k with tailNonzero241242theorem pow.exponent_strict (a m n : Nat)243requires above : 1 < a244requires below : m < n245shows a ^ m < a ^ n246proof247obtain⟨k, kNat, equation⟩:= Less.exists_add_one with below248have aPow := pow.closed at a, m249have tail := pow.one_lt at a, k with above250have headNonzero : a ^ m ≠0251have one : 1≤ a bylinarith252have nonzero := LessEqual.one_iff_ne_zero.forward with one253exact pow.ne_zero at a, m with nonzero254havesplit:= pow.add at a, k +1, m255have shape : m + k +1= m + (k +1) byring256rw [equation, shape, split]257have scaled := Less.mul_left at1, a ^ (k +1), a ^ m with headNonzero, tail258have unit := mul.right_unit at a ^ m259rw unit at scaled260exact scaled261262theorem pow.injective_exponent (a m n : Nat)263requires above : 1 < a264requires same : a ^ m = a ^ n265shows m = n266proof267have comparison := Less.trichotomy at m, n with*268rcases comparison with less | equal | greater269 . have strict := pow.exponent_strict at a, m, n with above, less270rw same at strict271exfalso272exact Less.irreflexive with strict273 . exact equal274 . have strict := pow.exponent_strict at a, n, m with above, greater275rw same at strict276exfalso277exact Less.irreflexive with strict278279theorem pow.le_self (a n : Nat)280requires one : 1≤ a281shows a ≤ a ^ (n +1)282proof283have bound : 1≤ n +1bylinarith284have monotone := pow.exponent_monotone at a, 1, n +1with one, bound285rw pow.one_right at monotone286exact monotone287288theorem pow.eq_one (a n : Nat)289requires one : a ^ (n +1) =1290shows a =1291proof292have powNat := pow.closed at a, n293rw pow.add_one at one294have both := mul.eq_one with one295exact both.left296297theorem pow.two_succ (n : Nat)298shows2 ^ (n +1) =2 ^ n +2 ^ n299proof300have powNat := pow.closed at2, n301rw pow.add_one302ring303304theorem pow.two_gt (n : Nat)305shows n < 2 ^ n306proof307induction n308| zero =>309rw pow.zero310linarith311| succ(k) using ih =>312have powNat := pow.closed at2, k313have positive : 0 < 2 ^ k314have two : 0 < 2bylinarith315exact pow.positive at2, k with two316have doubled := pow.two_succ at k317have shape : succ(k) = k +1byring318rw [shape, doubled]319linarith320321theorem pow.add_one_le_two (n : Nat)322shows n +1≤2 ^ n323proof324have powNat := pow.closed at2, n325have strict := pow.two_gt at n326linarith327328theorem pow.two_add (a b : Nat)329shows (a + b) ^ 2= a ^ 2+2* a * b + b ^ 2330proof331rw [pow.two, pow.two, pow.two]332ring333