Grace/Cumulus/NumberTheory/GCDMore.g17

Open in Workbench Download source

Imports

CoprimeCancel · DivisibilityMore

Declarations

Source

1-- Further laws of the greatest common divisor: units and self, order bounds,2-- shifting by multiples, subtraction, distributivity over a common factor,3-- associativity, consecutive numbers, and coprimality under products and4-- powers5-- Part of Cumulus, the Grace17 mathematics library.6-- Copyright (c) 2026 Grant Passmore.7-- Released under the Apache License 2.0. See LICENSE in the repository root.8-- Authors: Grant Passmore910module Grace.Cumulus.NumberTheory.GCDMore11import CoprimeCancel12import DivisibilityMore1314theorem gcd.self (a : Nat)15  shows gcd(a, a) = a16proof17  have reflexive := divides.reflexive at a18  exact gcd.of_divides with reflexive1920theorem gcd.one_left (a : Nat)21  shows gcd(1, a) = 122proof23  have one := one.divides at a24  exact gcd.of_divides with one2526theorem gcd.one_right (a : Nat)27  shows gcd(a, 1) = 128proof29  have commute := gcd.commutative at a, 130  rw commute31  exact gcd.one_left at a3233theorem gcd.divides_iff (a b d : Nat)34  shows d ∣ gcd(a, b) ↔ d ∣ a ∧ d ∣ b35proof36  constructor37  . intro h38    have left := gcd.divides_left at a, b39    have right := gcd.divides_right at a, b40    constructor41    . exact divides.transitive at d, gcd(a, b), a with h, left42    . exact divides.transitive at d, gcd(a, b), b with h, right43  . intro both44    rcases both with ⟨left, right⟩45    exact gcd.greatest with left, right4647theorem gcd.le_left (a b : Nat)48  requires nonzero : a ≠ 049  shows gcd(a, b) ≤ a50proof51  have left := gcd.divides_left at a, b52  exact divides.le at gcd(a, b), a with left, nonzero5354theorem gcd.le_right (a b : Nat)55  requires nonzero : b ≠ 056  shows gcd(a, b) ≤ b57proof58  have right := gcd.divides_right at a, b59  exact divides.le at gcd(a, b), b with right, nonzero6061theorem gcd.nonzero (a b : Nat)62  requires nonzero : a ≠ 063  shows gcd(a, b) ≠ 064proof65  intro zero66  have both := gcd.zero_iff at a, b67  have zeros := both.forward with zero68  exact nonzero with zeros.left6970theorem gcd.nonzero_right (a b : Nat)71  requires nonzero : b ≠ 072  shows gcd(a, b) ≠ 073proof74  intro zero75  have both := gcd.zero_iff at a, b76  have zeros := both.forward with zero77  exact nonzero with zeros.right7879theorem gcd.positive (a b : Nat)80  requires nonzero : a ≠ 081  shows 0 < gcd(a, b)82proof83  have distinct := gcd.nonzero at a, b with nonzero84  exact Less.positive_of_ne_zero with distinct8586theorem gcd.greatest_le (a b d : Nat)87  requires nonzero : a ≠ 088  requires left : d ∣ a89  requires right : d ∣ b90  shows d ≤ gcd(a, b)91proof92  have common := gcd.greatest with left, right93  have distinct := gcd.nonzero at a, b with nonzero94  exact divides.le at d, gcd(a, b) with common, distinct9596theorem gcd.divides_add (a b : Nat)97  shows gcd(a, b) ∣ a + b98proof99  have left := gcd.divides_left at a, b100  have right := gcd.divides_right at a, b101  exact divides.add at gcd(a, b), a, b with left, right102103theorem gcd.divides_mul (a b c : Nat)104  shows gcd(a, b) ∣ a * c105proof106  have left := gcd.divides_left at a, b107  exact divides.multiply_right at gcd(a, b), a, c with left108109theorem gcd.add_left (a b : Nat)110  shows gcd(a + b, b) = gcd(a, b)111proof112  have correct := gcd.correct at a, b113  have certificate := IsGCD.add_right_iff at a, b, gcd(a, b)114  have shifted := certificate.backward with correct115  exact gcd.unique with shifted116117theorem gcd.add_left_swap (a b : Nat)118  shows gcd(b + a, b) = gcd(a, b)119proof120  have commute : b + a = a + b by ring121  rw commute122  exact gcd.add_left at a, b123124theorem gcd.add_right (a b : Nat)125  shows gcd(a, a + b) = gcd(a, b)126proof127  have first := gcd.commutative at a, a + b128  have second := gcd.add_left_swap at b, a129  have third := gcd.commutative at b, a130  rw [first, second, third]131  rfl132133theorem gcd.add_right_swap (a b : Nat)134  shows gcd(a, b + a) = gcd(a, b)135proof136  have commute : b + a = a + b by ring137  rw commute138  exact gcd.add_right at a, b139140theorem gcd.add_mul_left (a b k : Nat)141  shows gcd(a + k * b, b) = gcd(a, b)142proof143  have correct := gcd.correct at a, b144  have swapped := IsGCD.symmetric with correct145  have equation : a + k * b = b * k + a by ring146  have certificate := IsGCD.euclidean_iff at a + k * b, b, k, a, gcd(a, b)147    with equation148  have shifted := certificate.backward with swapped149  exact gcd.unique with shifted150151theorem gcd.add_mul_right (a b k : Nat)152  shows gcd(a, b + k * a) = gcd(a, b)153proof154  have first := gcd.commutative at a, b + k * a155  have second := gcd.add_mul_left at b, a, k156  have third := gcd.commutative at b, a157  rw [first, second, third]158  rfl159160theorem gcd.sub_left (a b : Nat)161  requires below : b ≤ a162  shows gcd(a - b, b) = gcd(a, b)163proof164  have split := sub.add_cancel at a, b with below165  have shifted := gcd.add_left at a - b, b166  rw split at shifted167  symm168  exact shifted169170theorem gcd.sub_right (a b : Nat)171  requires below : b ≤ a172  shows gcd(b, a - b) = gcd(a, b)173proof174  have first := gcd.commutative at b, a - b175  have second := gcd.sub_left at a, b with below176  rw [first, second]177  rfl178179theorem gcd.eq_left_iff (a b : Nat)180  shows gcd(a, b) = a ↔ a ∣ b181proof182  constructor183  . intro same184    have right := gcd.divides_right at a, b185    rw same at right186    exact right187  . intro hab188    exact gcd.of_divides with hab189190theorem gcd.eq_right_iff (a b : Nat)191  shows gcd(a, b) = b ↔ b ∣ a192proof193  have commute := gcd.commutative at a, b194  rw commute195  exact gcd.eq_left_iff at b, a196197theorem gcd.mul_left_self (a b : Nat)198  shows gcd(a, a * b) = a199proof200  have factor := divides.mul_left_self at a, b201  exact gcd.of_divides with factor202203theorem gcd.mul_right_self (a b : Nat)204  shows gcd(a, b * a) = a205proof206  have factor := divides.mul_right_self at a, b207  exact gcd.of_divides with factor208209theorem gcd.mul_self_left (a b : Nat)210  shows gcd(a * b, a) = a211proof212  have commute := gcd.commutative at a * b, a213  rw commute214  exact gcd.mul_left_self at a, b215216theorem gcd.idempotent_left (a b : Nat)217  shows gcd(gcd(a, b), b) = gcd(a, b)218proof219  have right := gcd.divides_right at a, b220  exact gcd.of_divides with right221222theorem gcd.idempotent_right (a b : Nat)223  shows gcd(a, gcd(a, b)) = gcd(a, b)224proof225  have commute := gcd.commutative at a, gcd(a, b)226  rw commute227  have left := gcd.divides_left at a, b228  exact gcd.of_divides with left229230theorem gcd.consecutive (n : Nat)231  shows gcd(n, n + 1) = 1232proof233  have shifted := gcd.add_right at n, 1234  rw shifted235  exact gcd.one_right at n236237theorem gcd.consecutive_left (n : Nat)238  shows gcd(n + 1, n) = 1239proof240  have commute := gcd.commutative at n + 1, n241  rw commute242  exact gcd.consecutive at n243244theorem gcd.associative (a b c : Nat)245  shows gcd(gcd(a, b), c) = gcd(a, gcd(b, c))246proof247  have innerLeft := gcd.divides_left at a, b248  have innerRight := gcd.divides_right at a, b249  have outerLeft := gcd.divides_left at gcd(a, b), c250  have outerRight := gcd.divides_right at gcd(a, b), c251  have dividesA := divides.transitive at gcd(gcd(a, b), c), gcd(a, b), a252    with outerLeft, innerLeft253  have dividesB := divides.transitive at gcd(gcd(a, b), c), gcd(a, b), b254    with outerLeft, innerRight255  have dividesBC := gcd.greatest at b, c, gcd(gcd(a, b), c)256    with dividesB, outerRight257  have certificate : IsGCD(a, gcd(b, c), gcd(gcd(a, b), c))258    apply IsGCD.intro259    . exact dividesA260    . exact dividesBC261    . intros d dNat dA dBC262      have left := gcd.divides_left at b, c263      have right := gcd.divides_right at b, c264      have dB := divides.transitive at d, gcd(b, c), b with dBC, left265      have dC := divides.transitive at d, gcd(b, c), c with dBC, right266      have dAB := gcd.greatest at a, b, d with dA, dB267      exact gcd.greatest at gcd(a, b), c, d with dAB, dC268  symm269  exact gcd.unique with certificate270271-- A common factor comes out of the greatest common divisor; the greatest272-- property passes through Bézout's identity over the integers.273theorem gcd.mul_right_distribute (a b c : Nat)274  shows gcd(a * c, b * c) = gcd(a, b) * c275proof276  have left := gcd.divides_left at a, b277  have right := gcd.divides_right at a, b278  have reflexive := divides.reflexive at c279  have scaledLeft := divides.mul_mono at gcd(a, b), a, c, c with left, reflexive280  have scaledRight := divides.mul_mono at gcd(a, b), b, c, c281    with right, reflexive282  have certificate : IsGCD(a * c, b * c, gcd(a, b) * c)283    apply IsGCD.intro284    . exact scaledLeft285    . exact scaledRight286    . intros d dNat dA dB287      obtain ⟨u, uInteger, v, vInteger, identity⟩ := gcd.bezout at a, b288      have bridgeA := IntegerDivides.natural_left at d, integerOfNat(a * c)289      have bridgeB := IntegerDivides.natural_left at d, integerOfNat(b * c)290      have bridgeG := IntegerDivides.natural_left at d, integerOfNat(gcd(a, b) * c)291      have magnitudeA := integerNatAbs.ofNat at a * c292      have magnitudeB := integerNatAbs.ofNat at b * c293      have magnitudeG := integerNatAbs.ofNat at gcd(a, b) * c294      rw magnitudeA at bridgeA295      rw magnitudeB at bridgeB296      rw magnitudeG at bridgeG297      have integerA := bridgeA.backward with dA298      have integerB := bridgeB.backward with dB299      have combination : IntegerDivides(integerOfNat(d),300          u * integerOfNat(a * c) + v * integerOfNat(b * c))301        exact IntegerDivides.linear_combination with integerA, integerB302      have value : u * integerOfNat(a * c) + v * integerOfNat(b * c) =303          integerOfNat(gcd(a, b) * c)304        have productA := integerOfNat.mul at a, c305        have productB := integerOfNat.mul at b, c306        have productG := integerOfNat.mul at gcd(a, b), c307        unfold integerLinearCombination at identity308        rw [productA, productB, productG, ← identity]309        ring310      rw value at combination311      exact bridgeG.forward with combination312  exact gcd.unique with certificate313314theorem gcd.mul_left_distribute (a b c : Nat)315  shows gcd(c * a, c * b) = c * gcd(a, b)316proof317  have left : c * a = a * c by ring318  have right : c * b = b * c by ring319  have product : gcd(a, b) * c = c * gcd(a, b) by ring320  rw [left, right, ← product]321  exact gcd.mul_right_distribute at a, b, c322323theorem gcd.coprime_mul (a b c : Nat)324  requires coprimeAB : gcd(a, b) = 1325  shows gcd(a, b * c) = gcd(a, c)326proof327  have left := gcd.divides_left at a, c328  have right := gcd.divides_right at a, c329  have scaled := divides.multiply_left at gcd(a, c), c, b with *330  have certificate : IsGCD(a, b * c, gcd(a, c))331    apply IsGCD.intro332    . exact left333    . exact scaled334    . intros d dNat dA dBC335      have dividesB := gcd.divides_left at b, d336      have dividesD := gcd.divides_right at b, d337      have dividesA := divides.transitive at gcd(b, d), d, a with dividesD, dA338      have common := gcd.greatest at a, b, gcd(b, d) with dividesA, dividesB339      rw coprimeAB at common340      have one := divides.one_only at gcd(b, d) with *341      have cancelled := coprime.cancel at b, d, c with one, dBC342      exact gcd.greatest at a, c, d with dA, cancelled343  exact gcd.unique with certificate344345theorem gcd.coprime_mul_left (a b c : Nat)346  requires coprimeAB : gcd(a, b) = 1347  shows gcd(a * c, b) = gcd(c, b)348proof349  have first := gcd.commutative at a * c, b350  have swapped := gcd.commutative at a, b351  rw swapped at coprimeAB352  have second := gcd.coprime_mul at b, a, c with coprimeAB353  have third := gcd.commutative at b, c354  rw [first, second, third]355  rfl356357theorem gcd.eq_one_iff (a b : Nat)358  shows gcd(a, b) = 1 ↔ ∀ d, Nat(d) → d ∣ a → d ∣ b → d = 1359proof360  constructor361  . intros one d dNat left right362    have common := gcd.greatest at a, b, d with left, right363    rw one at common364    exact divides.one_only at d with *365  . intro every366    have left := gcd.divides_left at a, b367    have right := gcd.divides_right at a, b368    exact every with gcd(a, b), left, right369370theorem coprime.symmetric (a b : Nat)371  requires coprimeAB : gcd(a, b) = 1372  shows gcd(b, a) = 1373proof374  have commute := gcd.commutative at b, a375  rw commute376  exact coprimeAB377378theorem coprime.divisor_one (a b d : Nat)379  requires coprimeAB : gcd(a, b) = 1380  requires left : d ∣ a381  requires right : d ∣ b382  shows d = 1383proof384  have every := gcd.eq_one_iff at a, b385  exact every.forward with coprimeAB, d, left, right386387theorem coprime.cancel_right (a n t : Nat)388  requires coprimeAN : gcd(a, n) = 1389  requires product : n ∣ t * a390  shows n ∣ t391proof392  have commute : t * a = a * t by ring393  rw commute at product394  exact coprime.cancel at a, n, t with coprimeAN, product395396theorem coprime.mul_of_coprime (a b n : Nat)397  requires first : gcd(a, n) = 1398  requires second : gcd(b, n) = 1399  shows gcd(a * b, n) = 1400proof401  have swapped := coprime.symmetric at a, n with first402  have reduced := gcd.coprime_mul at n, a, b with swapped403  have commute := gcd.commutative at a * b, n404  rw [commute, reduced]405  exact coprime.symmetric at b, n with second406407theorem coprime.of_mul_left (a b n : Nat)408  requires product : gcd(a * b, n) = 1409  shows gcd(a, n) = 1410proof411  have left := gcd.divides_left at a, n412  have right := gcd.divides_right at a, n413  have scaled := divides.multiply_right at gcd(a, n), a, b with left414  have common := gcd.greatest at a * b, n, gcd(a, n) with scaled, right415  rw product at common416  exact divides.one_only at gcd(a, n) with *417418theorem coprime.of_mul_right (a b n : Nat)419  requires product : gcd(a * b, n) = 1420  shows gcd(b, n) = 1421proof422  have commute : a * b = b * a by ring423  rw commute at product424  exact coprime.of_mul_left at b, a, n with product425426theorem coprime.mul_iff (a b n : Nat)427  shows gcd(a * b, n) = 1 ↔ gcd(a, n) = 1 ∧ gcd(b, n) = 1428proof429  constructor430  . intro product431    constructor432    . exact coprime.of_mul_left at a, b, n with product433    . exact coprime.of_mul_right at a, b, n with product434  . intro both435    rcases both with ⟨first, second⟩436    exact coprime.mul_of_coprime at a, b, n with first, second437438theorem coprime.pow_left (a b n : Nat)439  requires coprimeAB : gcd(a, b) = 1440  shows gcd(a ^ n, b) = 1441proof442  induction n443  | zero =>444    have zero := pow.zero at a445    rw zero446    exact gcd.one_left at b447  | k + 1 using ih =>448    have expand := pow.add_one at a, k449    rw expand450    exact coprime.mul_of_coprime at a, a ^ k, b with coprimeAB, ih451452theorem coprime.pow_right (a b n : Nat)453  requires coprimeAB : gcd(a, b) = 1454  shows gcd(a, b ^ n) = 1455proof456  have swapped := coprime.symmetric at a, b with coprimeAB457  have power := coprime.pow_left at b, a, n with swapped458  exact coprime.symmetric at b ^ n, a with power459460theorem coprime.pow (a b m n : Nat)461  requires coprimeAB : gcd(a, b) = 1462  shows gcd(a ^ m, b ^ n) = 1463proof464  have left := coprime.pow_left at a, b, m with coprimeAB465  exact coprime.pow_right at a ^ m, b, n with left466467theorem coprime.mul_divides (a b n : Nat)468  requires coprimeAB : gcd(a, b) = 1469  requires left : a ∣ n470  requires right : b ∣ n471  shows a * b ∣ n472proof473  obtain ⟨k, kNat, equation⟩ := left474  have scaled : b ∣ a * k475    rw equation476    exact right477  have cancelled := coprime.cancel at a, b, k with coprimeAB, scaled478  obtain ⟨m, mNat, kEquation⟩ := cancelled479  witness m480  rw [← equation, ← kEquation]481  ring482483theorem Prime.gcd_of_not_divides (p a : Nat)484  requires prime : Prime(p)485  requires notDivides : ¬(p ∣ a)486  shows gcd(p, a) = 1487proof488  have certificate := Prime.coprime_of_not_divides with prime, notDivides489  exact gcd.unique with certificate490491theorem Prime.coprime_or_divides (p a : Nat)492  requires prime : Prime(p)493  shows gcd(p, a) = 1 ∨ p ∣ a494proof495  have split : p ∣ a ∨ ¬(p ∣ a) by tauto496  cases split with yes | no497  . right498    exact yes499  . left500    exact Prime.gcd_of_not_divides with prime, no501502theorem Prime.divides_pow (p a n : Nat)503  requires prime : Prime(p)504  requires power : p ∣ a ^ n505  shows p ∣ a506proof507  induction n508  | zero =>509    intro power510    exfalso511    have zero := pow.zero at a512    rw zero at power513    have one := divides.one_only at p with *514    have above := Prime.greater_than_one with prime515    rw one at above516    exact Less.irreflexive at 1 with above517  | k + 1 using ih =>518    intro power519    have expand := pow.add_one at a, k520    rw expand at power521    have split := Prime.divides_mul at p, a, a ^ k with prime, power522    cases split with base | rest523    . exact base524    . exact ih with rest525