1-- The Möbius function: squarefree numbers, the set and number of prime2-- divisors, μ(n) = (−1)^k at a squarefree n with k prime divisors and 03-- elsewhere, its values at 1, primes, prime squares, and products of two4-- distinct primes, the step μ(p · d) = −μ(d) for a prime p not dividing d,5-- and the key identity ∑_{d ∣ n} μ(d) = 0 for n > 1, proved by pairing each6-- squarefree divisor d with d / p or p · d for a fixed prime p dividing n7-- Part of Cumulus, the Grace17 mathematics library.8-- Copyright (c) 2026 Grant Passmore.9-- Released under the Apache License 2.0. See LICENSE in the repository root.10-- Authors: Grant Passmore1112module Grace.Cumulus.Combinatorics.Moebius13import DivisorSums14import Basics1516-- A natural number is squarefree when no prime square divides it.17predicate Squarefree (n : Nat) :=∀ p ∈ ℕ, Prime(p) →¬(p * p ∣ n)1819theorem Squarefree.not_divides (n p : Nat)20requires squarefree : Squarefree(n)21requires prime : Prime(p)22shows¬(p * p ∣ n)23proof24have pNat : Nat(p) bytypecheck25have pMember := nat.omega.forward with pNat26exact squarefree with p, pMember, prime2728theorem Squarefree.of_divides (m n : Nat)29requires squarefree : Squarefree(n)30requires factor : m ∣ n31shows Squarefree(m)32proof33intros p pMember prime square34have pNat := nat.omega.backward with pMember35have chained := divides.transitive with square, factor36have absent := Squarefree.not_divides with squarefree, prime37exact absent with chained3839theorem Squarefree.nonzero (n : Nat)40requires squarefree : Squarefree(n)41shows n ≠042proof43intro zero44have two := Prime.two45have four := divides.zero at2*246rw zero at squarefree47have absent := Squarefree.not_divides with squarefree, two48exact absent with four4950theorem Squarefree.one51shows Squarefree(1)52proof53intros p pMember prime square54have pNat := nat.omega.backward with pMember55have pDivides := divides.of_mul_left with square56have pOne := divides.one_only at p with pNat, pDivides57exact Prime.ne_one with prime, pOne5859theorem Squarefree.prime (p : Nat)60requires prime : Prime(p)61shows Squarefree(p)62proof63intros q qMember qPrime square64have qNat := nat.omega.backward with qMember65have qDivides := divides.of_mul_left with square66have same := Prime.divides_prime with qPrime, prime, qDivides67rw same at square68have nonzero := Prime.nonzero with prime69have unit : p * p ∣ p *170have shape : p *1= p byring71rw shape72exact square73have cancel := divides.mul_cancel_left at p, p, 1with nonzero74have pDividesOne := cancel.forward with unit75have pOne := divides.one_only at p with*76exact Prime.ne_one with prime, pOne7778theorem Squarefree.not_prime_square (p : Nat)79requires prime : Prime(p)80shows¬Squarefree(p * p)81proof82intro squarefree83haveself:= divides.reflexive at p * p84have absent := Squarefree.not_divides with squarefree, prime85exact absent withself8687-- A prime not dividing a squarefree number keeps the product squarefree.88theorem Squarefree.mul_prime (d p : Nat)89requires squarefree : Squarefree(d)90requires prime : Prime(p)91requires notDivides : ¬(p ∣ d)92shows Squarefree(p * d)93proof94intros q qMember qPrime square95have qNat := nat.omega.backward with qMember96have alternatives : q = p ∨ q ≠ p bytauto97cases alternatives with same | different98 . rw same at square99have nonzero := Prime.nonzero with prime100have cancel := divides.mul_cancel_left at p, p, d with nonzero101have pDivides := cancel.forward with square102exact notDivides with pDivides103 . have qNotDividesP : ¬(q ∣ p)104intro qDivides105have equal := Prime.divides_prime with qPrime, prime, qDivides106exact different with equal107have coprimeQP := Prime.gcd_of_not_divides with qPrime, qNotDividesP108have characterization := coprime.mul_iff at q, q, p109have coprimeSquare := characterization.backward with⟨coprimeQP, coprimeQP⟩110have coprimeSym := coprime.symmetric with coprimeSquare111have commuted : p * d = d * p byring112rw commuted at square113have dividesD := coprime.cancel_right with coprimeSym, square114have absent := Squarefree.not_divides with squarefree, qPrime115exact absent with dividesD116117-- Dividing a squarefree number by a prime factor removes that prime.118theorem Squarefree.quotient_not_divides (d p : Nat)119requires squarefree : Squarefree(d)120requires prime : Prime(p)121requires factor : p ∣ d122shows¬(p ∣ quotientNat(d, p))123proof124intro again125have pNonzero := Prime.nonzero with prime126have equation := divides.quotient_equation with pNonzero, factor127haveself:= divides.reflexive at p128have square := divides.mul_mono withself, again129rw← equation at square130have absent := Squarefree.not_divides with squarefree, prime131exact absent with square132133-- The prime divisors of n and their number.134def primeDivisors (n : Nat) : Set:= { p ∈ divisors(n) | Prime(p) }135136theorem primeDivisors.subset (n : Nat)137shows primeDivisors(n) ⊆ divisors(n)138proof139intros p member140have both := primeDivisors.membership.forward with member141exact both.left142143theorem primeDivisors.finite (n : Nat)144shows Finite(primeDivisors(n))145proof146have finite := divisors.finite at n147have subset := primeDivisors.subset at n148exact Finite.subset with finite, subset149150theorem primeDivisors.one151shows primeDivisors(1) =∅152proof153ext x154constructor155 . intro member156have both := primeDivisors.membership.forward with member157have inOne := both.left158have prime := both.right159rw divisors.one at inOne160have xOne := singleton.membership.forward with inOne161rw xOne at prime162have distinct := Prime.ne_one at1with prime163exfalso164apply distinct165rfl166 . intro member167exfalso168have absent :=set.empty at x169exact absent with member170171theorem primeDivisors.prime (p : Nat)172requires prime : Prime(p)173shows primeDivisors(p) = {p}174proof175have same := divisors.prime with prime176ext x177constructor178 . intro member179have both := primeDivisors.membership.forward with member180have inDivisors := both.left181have xPrime := both.right182rw same at inDivisors183have alternatives := pair.membership.forward with inDivisors184cases alternatives with one |self185 . exfalso186rw one at xPrime187have distinct := Prime.ne_one at1with xPrime188apply distinct189rfl190 . rwself191simp192 . intro member193have xP := singleton.membership.forward with member194rw xP195haveself:= divisors.self_member at p196exact primeDivisors.membership.backward with⟨self, prime⟩197198theorem primeDivisors.mul_prime (d p : Nat)199requires nonzero : d ≠0200requires prime : Prime(p)201shows primeDivisors(p * d) = insert(p, primeDivisors(d))202proof203have pNonzero := Prime.nonzero with prime204have productNonzero : p * d ≠0205intro zero206have characterization := mul.eq_zero_iff at p, d207have alternatives := characterization.forward with zero208cases alternatives with pZero | dZero209 . exact pNonzero with pZero210 . exact nonzero with dZero211ext q212constructor213 . intro member214have both := primeDivisors.membership.forward with member215have inDivisors := both.left216have qPrime := both.right217have qNat := divisors.natural with inDivisors218have factor := divisors.divides with inDivisors219have alternatives := Prime.divides_mul with qPrime, factor220cases alternatives with dividesP | dividesD221 . have same := Prime.divides_prime with qPrime, prime, dividesP222rw same223simp224 . have below := divides.le with dividesD, nonzero225have characterization := divisors.membership_le at d, q226have inD := characterization.backward with⟨below, dividesD⟩227have characterizationD := primeDivisors.membership at d, q228have inPrime := characterizationD.backward with⟨inD, qPrime⟩229simp230 . intro member231have alternatives := insert.membership.forward with member232cases alternatives with same | inD233 . rw same234haveself:= divides.mul_left_self at p, d235have below := divides.le withself, productNonzero236have characterization := divisors.membership_le at p * d, p237have inDivisors := characterization.backward with⟨below, self⟩238exact primeDivisors.membership.backward with⟨inDivisors, prime⟩239 . have both := primeDivisors.membership.forward with inD240have inDivisorsD := both.left241have qPrime := both.right242have qNat := divisors.natural with inDivisorsD243have factor := divisors.divides with inDivisorsD244have multiple := divides.mul_right_self at d, p245have chained := divides.transitive with factor, multiple246have below := divides.le with chained, productNonzero247have characterization := divisors.membership_le at p * d, q248have inDivisors := characterization.backward with⟨below, chained⟩249exact primeDivisors.membership.backward with⟨inDivisors, qPrime⟩250251def primeDivisorCount (n : Nat) : Set:= cardinality(primeDivisors(n))252253theorem primeDivisorCount.natural (n : Nat)254showsNat(primeDivisorCount(n))255proof256have finite := primeDivisors.finite at n257have natural := cardinality.nat with finite258unfold primeDivisorCount259exact natural260261theorem primeDivisorCount.one262shows primeDivisorCount(1) =0263proof264have same := primeDivisors.one265have empty := cardinality.empty266unfold primeDivisorCount267cc268269theorem primeDivisorCount.prime (p : Nat)270requires prime : Prime(p)271shows primeDivisorCount(p) =1272proof273have same := primeDivisors.prime with prime274have single := cardinality.singleton at p275unfold primeDivisorCount276cc277278theorem primeDivisorCount.mul_prime (d p : Nat)279requires nonzero : d ≠0280requires prime : Prime(p)281requires notDivides : ¬(p ∣ d)282shows primeDivisorCount(p * d) = primeDivisorCount(d) +1283proof284have same := primeDivisors.mul_prime with nonzero, prime285have finite := primeDivisors.finite at d286have fresh : ¬(p ∈ primeDivisors(d))287intro member288have both := primeDivisors.membership.forward with member289have factor := divisors.divides with both.left290exact notDivides with factor291have count := cardinality.insert_add_one with finite, fresh292unfold primeDivisorCount293cc294295-- The squarefree numbers, so that the Möbius function has an indicator.296def squarefreeNumbers : Set:= { n ∈ ℕ | Squarefree(n) }297298-- The Möbius function: (−1)^k at a squarefree number with k prime299-- divisors, and 0 at every number with a repeated prime factor.300def moebiusValue (n : Nat) : Set:=301 integerOfNat(indicator(squarefreeNumbers, n)) *302 integerPow(-integerOne, primeDivisorCount(n))303304theorem moebiusValue.integer (n : Nat)305shows Integer(moebiusValue(n))306proof307have countNat := primeDivisorCount.natural at n308have indicatorNat := indicator.natural at squarefreeNumbers, n309have mask := integerOfNat.integer at indicator(squarefreeNumbers, n)310have sign := integerPow.integer at -integerOne, primeDivisorCount(n)311unfold moebiusValue312exact integerMulValue.integer at integerOfNat(indicator(squarefreeNumbers,313 n)), integerPow(-integerOne, primeDivisorCount(n)) with*314315defgraph moebius (n ∈ ℕ) : ℤ := moebiusValue(n)316proof317have nNat := nat.omega.backward with member318exact moebiusValue.integer at n319320theorem moebius.integer (n : Nat)321shows Integer(moebius(n))322proof323have nNat : Nat(n) bytypecheck324have nMember := nat.omega.forward with nNat325have function := moebius.function326exact FunctionBetween.apply_closed with function, nMember327328theorem moebius.of_squarefree (n : Nat)329requires squarefree : Squarefree(n)330shows moebius(n) = integerPow(-integerOne, primeDivisorCount(n))331proof332have nNat : Nat(n) bytypecheck333have nMember := nat.omega.forward with nNat334have countNat := primeDivisorCount.natural at n335have sign := integerPow.integer at -integerOne, primeDivisorCount(n)336have characterization := squarefreeNumbers.membership at n337have inSet := characterization.backward with⟨nMember, squarefree⟩338have one := indicator.member with inSet339have value := moebius.value at n340rw value341simp [moebiusValue]342rw integerOfNat.one343ring344345theorem moebius.of_not_squarefree (n : Nat)346requires notSquarefree : ¬Squarefree(n)347shows moebius(n) = integerZero348proof349have nNat : Nat(n) bytypecheck350have countNat := primeDivisorCount.natural at n351have sign := integerPow.integer at -integerOne, primeDivisorCount(n)352have absent : ¬(n ∈ squarefreeNumbers)353intro inSet354have both := squarefreeNumbers.membership.forward with inSet355exact notSquarefree with both.right356have zero := indicator.absent with absent357have value := moebius.value at n358rw value359simp [moebiusValue]360rw integerOfNat.zero361ring362363theorem moebius.one364shows moebius(1) = integerOne365proof366have squarefree := Squarefree.one367have value := moebius.of_squarefree with squarefree368have count := primeDivisorCount.one369rw [value, count, integerPow.zero]370rfl371372theorem moebius.prime (p : Nat)373requires prime : Prime(p)374shows moebius(p) = -integerOne375proof376have squarefree := Squarefree.prime with prime377have value := moebius.of_squarefree with squarefree378have count := primeDivisorCount.prime with prime379rw [value, count, integerPow.one_right]380rfl381382theorem moebius.prime_square (p : Nat)383requires prime : Prime(p)384shows moebius(p * p) = integerZero385proof386have notSquarefree := Squarefree.not_prime_square with prime387exact moebius.of_not_squarefree with notSquarefree388389-- Multiplying by a new prime flips the sign of the Möbius function.390theorem moebius.mul_prime (d p : Nat)391requires prime : Prime(p)392requires notDivides : ¬(p ∣ d)393shows moebius(p * d) = -moebius(d)394proof395have dInteger := moebius.integer at d396have alternatives : Squarefree(d) ∨¬Squarefree(d) bytauto397cases alternatives with squarefree | notSquarefree398 . have nonzero := Squarefree.nonzero with squarefree399have productSquarefree := Squarefree.mul_prime with squarefree, prime,400 notDivides401have valueD := moebius.of_squarefree with squarefree402have valueProduct := moebius.of_squarefree with productSquarefree403have count := primeDivisorCount.mul_prime with nonzero, prime, notDivides404have countNat := primeDivisorCount.natural at d405have sign := integerPow.integer at -integerOne, primeDivisorCount(d)406rw [valueProduct, count, integerPow.add_one, valueD]407ring408 . have productNotSquarefree : ¬Squarefree(p * d)409intro productSquarefree410have multiple := divides.mul_right_self at d, p411have squarefree := Squarefree.of_divides with productSquarefree, multiple412exact notSquarefree with squarefree413have valueD := moebius.of_not_squarefree with notSquarefree414have valueProduct := moebius.of_not_squarefree with productNotSquarefree415rw [valueProduct, valueD]416ring417418theorem moebius.prime_product (p q : Nat)419requires primeP : Prime(p)420requires primeQ : Prime(q)421requires distinct : p ≠ q422shows moebius(p * q) = integerOne423proof424have notDivides : ¬(p ∣ q)425intro factor426have same := Prime.divides_prime with primeP, primeQ, factor427exact distinct with same428have flipped := moebius.mul_prime with primeP, notDivides429have valueQ := moebius.prime with primeQ430have oneInteger := integerOne.integer431rw [flipped, valueQ]432ring433434-- The squarefree divisors of n, the support of μ on divisors(n).435def squarefreeDivisors (n : Nat) : Set:= { d ∈ divisors(n) | Squarefree(d) }436437theorem squarefreeDivisors.subset (n : Nat)438shows squarefreeDivisors(n) ⊆ divisors(n)439proof440intros d member441have both := squarefreeDivisors.membership.forward with member442exact both.left443444theorem squarefreeDivisors.quotient_member (n p d : Nat)445requires nonzero : n ≠0446requires member : d ∈ squarefreeDivisors(n)447requires factor : p ∣ d448shows quotientNat(d, p) ∈ squarefreeDivisors(n)449proof450have both := squarefreeDivisors.membership.forward with member451have inDivisors := both.left452have squarefree := both.right453have dDivides := divisors.divides with inDivisors454have dNonzero := divides.nonzero with dDivides, nonzero455have pNonzero := divides.nonzero with factor, dNonzero456have quotientDivides := divides.quotient with pNonzero, factor457have chained := divides.transitive with quotientDivides, dDivides458have below := divides.le with chained, nonzero459have characterization := divisors.membership_le at n, quotientNat(d, p)460have inN := characterization.backward with⟨below, chained⟩461have quotientSquarefree := Squarefree.of_divides with squarefree,462 quotientDivides463exact squarefreeDivisors.membership.backward with⟨inN, quotientSquarefree⟩464465theorem squarefreeDivisors.mul_member (n p d : Nat)466requires nonzero : n ≠0467requires prime : Prime(p)468requires pDivides : p ∣ n469requires member : d ∈ squarefreeDivisors(n)470requires notDivides : ¬(p ∣ d)471shows d * p ∈ squarefreeDivisors(n)472proof473have both := squarefreeDivisors.membership.forward with member474have inDivisors := both.left475have squarefree := both.right476have dDivides := divisors.divides with inDivisors477have coprimePD := Prime.gcd_of_not_divides with prime, notDivides478have coprimeDP := coprime.symmetric with coprimePD479have productDivides := coprime.mul_divides with coprimeDP, dDivides, pDivides480have below := divides.le with productDivides, nonzero481have characterization := divisors.membership_le at n, d * p482have inN := characterization.backward with⟨below, productDivides⟩483have productSquarefree := Squarefree.mul_prime with squarefree, prime,484 notDivides485have commuted : d * p = p * d byring486rw commuted487rw commuted at inN488exact squarefreeDivisors.membership.backward with⟨inN, productSquarefree⟩489490-- The partner of d under p: d / p when p divides d, and d · p otherwise.491def moebiusPartnerValue (p d : Nat) : Nat:=492 chooseNat(equalNat(d % p, 0), quotientNat(d, p), d * p)493494theorem moebiusPartnerValue.of_divides (p d : Nat)495requires factor : p ∣ d496shows moebiusPartnerValue(p, d) = quotientNat(d, p)497proof498have characterization := divides.iff_mod_zero at p, d499have modZero := characterization.forward with factor500have flag := equalNat.true_iff.backward with modZero501clear modZero502unfold moebiusPartnerValue503simp [chooseNat, flag]504505theorem moebiusPartnerValue.of_not_divides (p d : Nat)506requires notDivides : ¬(p ∣ d)507shows moebiusPartnerValue(p, d) = d * p508proof509have characterization := divides.iff_mod_zero at p, d510have modNonzero : d % p ≠0511intro modZero512apply notDivides513exact characterization.backward with modZero514have flag := equalNat.false_iff.backward with modNonzero515unfold moebiusPartnerValue516simp [chooseNat, flag]517518-- Pairing the squarefree divisors of n through a prime p dividing n.519defgraph moebiusPartner (n p : Nat) (d ∈ squarefreeDivisors(n)) :520 squarefreeDivisors(n) := moebiusPartnerValue(p, d)521requires nonzero : n ≠0522requires prime : Prime(p)523requires factor : p ∣ n524proof525have both := squarefreeDivisors.membership.forward with member526have dNat := divisors.natural with both.left527have alternatives : p ∣ d ∨¬(p ∣ d) bytauto528cases alternatives with divides | notDivides529 . have value := moebiusPartnerValue.of_divides with divides530rw value531exact squarefreeDivisors.quotient_member with nonzero, member, divides532 . have value := moebiusPartnerValue.of_not_divides with notDivides533rw value534exact squarefreeDivisors.mul_member with nonzero, prime, factor, member,535 notDivides536537theorem moebiusPartner.involution (n p : Nat)538requires nonzero : n ≠0539requires prime : Prime(p)540requires factor : p ∣ n541shows InvolutionOn(moebiusPartner(n, p), squarefreeDivisors(n))542proof543have function := moebiusPartner.function at n, p with nonzero, prime, factor544refine⟨function, _⟩545intros d hd546have both := squarefreeDivisors.membership.forward with hd547have dNat := divisors.natural with both.left548have squarefree := both.right549have pNonzero := Prime.nonzero with prime550have first := moebiusPartner.value at n, p, d with nonzero, prime, factor, hd551have alternatives : p ∣ d ∨¬(p ∣ d) bytauto552cases alternatives with divides | notDivides553 . have quotientValue := moebiusPartnerValue.of_divides with divides554have quotientMember := squarefreeDivisors.quotient_member with nonzero,555 hd, divides556have second := moebiusPartner.value at n, p, quotientNat(d, p) with557 nonzero, prime, factor, quotientMember558have notAgain := Squarefree.quotient_not_divides with squarefree, prime,559 divides560have productValue := moebiusPartnerValue.of_not_divides with notAgain561have equation := divides.quotient_equation with pNonzero, divides562have quotientNatural := quotientNat.natural at p, d563have commuted := mul.commutative at p, quotientNat(d, p)564rw [first, quotientValue, second, productValue]565cc566 . have productValue := moebiusPartnerValue.of_not_divides with notDivides567have productMember := squarefreeDivisors.mul_member with nonzero, prime,568 factor, hd, notDivides569have second := moebiusPartner.value at n, p, d * p with nonzero, prime,570 factor, productMember571have pDividesProduct := divides.mul_right_self at p, d572have quotientValue := moebiusPartnerValue.of_divides with pDividesProduct573have reduced : quotientNat(d * p, p) = d574have commuted := mul.commutative at p, d575rw commuted576exact quotientNat.mul_left with pNonzero577rw [first, productValue, second, quotientValue, reduced]578rfl579580theorem moebius.partner (n p : Nat) (d : Set)581requires nonzero : n ≠0582requires prime : Prime(p)583requires factor : p ∣ n584requires member : d ∈ squarefreeDivisors(n)585shows moebius(moebiusPartner(n, p)(d)) = -moebius(d)586proof587have both := squarefreeDivisors.membership.forward with member588have dNat := divisors.natural with both.left589have squarefree := both.right590have pNonzero := Prime.nonzero with prime591have value := moebiusPartner.value at n, p, d with nonzero, prime, factor,592 member593have alternatives : p ∣ d ∨¬(p ∣ d) bytauto594cases alternatives with divides | notDivides595 . have quotientValue := moebiusPartnerValue.of_divides with divides596have notAgain := Squarefree.quotient_not_divides with squarefree, prime,597 divides598have equation := divides.quotient_equation with pNonzero, divides599have flipped := moebius.mul_prime at quotientNat(d, p), p with prime,600 notAgain601rw← equation at flipped602have quotientInteger := moebius.integer at quotientNat(d, p)603rw [value, quotientValue, flipped, integerNegValue.involutive]604rfl605 . have productValue := moebiusPartnerValue.of_not_divides with notDivides606have flipped := moebius.mul_prime with prime, notDivides607have commuted := mul.commutative at p, d608rw [value, productValue, commuted, flipped]609rfl610611-- The negated weight d ↦ −w(d).612defgraph negatedWeights (w : Set) (d ∈ ℕ) : ℤ := integerNegValue(w(d))613requires weights : w : ℕ → ℤ614proof615have value := FunctionBetween.apply_closed with weights, member616exact integerNegValue.integer at w(d) with*617618theorem integerAddValue.self_eq_zero (x : Integer)619requires doubled : x + x = integerZero620shows x = integerZero621proof622have zeroInteger := integerZero.integer623have collapse : integerZero + integerZero = integerZero byring624have alternatives := integerLess.trichotomy at x, integerZero625rcases alternatives with negative | zero | positive626 . exfalso627have sum := integerLess.add with negative, negative628rw [doubled, collapse] at sum629exact integerLess.irreflexive at integerZero with sum630 . exact zero631 . exfalso632have sum := integerLess.add with positive, positive633rw [doubled, collapse] at sum634exact integerLess.irreflexive at integerZero with sum635636theorem moebius.sum_one637shows divisorSum(1, moebius) = integerOne638proof639have function := moebius.function640have one := divisorSum.one with function641rw [one, moebius.one]642rfl643644-- The key identity: the Möbius function sums to zero over the divisors of645-- any n > 1.646theorem moebius.sum_divisors (n : Nat)647requires aboveOne : 1 < n648shows divisorSum(n, moebius) = integerZero649proof650have nonzero : n ≠0651intro zero652rw zero at aboveOne653arith654obtain⟨p, prime, factor⟩:= natural.exists_prime_divisor with aboveOne655have pNat := Prime.natural with prime656have function := moebius.function657have negatedFunction := negatedWeights.function at moebius with function658have inner := squarefreeDivisors.subset at n659have finiteDivisors := divisors.finite at n660have finite := Finite.subset with finiteDivisors, inner661have naturals := divisors.subset_naturals at n662have subset := Subset.transitive with inner, naturals663have vanishes : ∀ d ∈ divisors(n), ¬(d ∈ squarefreeDivisors(n)) →664 moebius(d) = integerZero665intros d hd absent666have dNat := divisors.natural with hd667have notSquarefree : ¬Squarefree(d)668intro squarefree669apply absent670exact squarefreeDivisors.membership.backward with⟨hd, squarefree⟩671exact moebius.of_not_squarefree with notSquarefree672have restricted := divisorSum.support with function, inner, vanishes673have involution := moebiusPartner.involution with nonzero, prime, factor674have bijective := InvolutionOn.bijective with involution675have partnerFunction := InvolutionOn.function with involution676have values : ∀ d ∈ squarefreeDivisors(n),677 moebius(d) = negatedWeights(moebius)(moebiusPartner(n, p)(d))678intros d hd679have image := FunctionBetween.apply_closed with partnerFunction, hd680have imageMember := subset with moebiusPartner(n, p)(d), image681have negValue := negatedWeights.value at moebius, moebiusPartner(n, p)(d)682with function683have flipped := moebius.partner with nonzero, prime, factor, hd684have dMember := subset with d, hd685have dInteger := FunctionBetween.apply_closed with function, dMember686rw [negValue, flipped, integerNegValue.involutive]687rfl688have reindexed := integerSetSum.reindex at squarefreeDivisors(n),689 squarefreeDivisors(n), ℕ, ℕ, moebius, negatedWeights(moebius),690 moebiusPartner(n, p) with finite, function, negatedFunction, subset,691 subset, bijective, values692have scaledValues : ∀ d ∈ squarefreeDivisors(n),693 negatedWeights(moebius)(d) = integerMulValue(-integerOne, moebius(d))694intros d hd695have dMember := subset with d, hd696have dInteger := FunctionBetween.apply_closed with function, dMember697have negValue := negatedWeights.value at moebius, d with function698rw negValue699ring700have scaled := integerSetSum.scale at squarefreeDivisors(n), ℕ, moebius,701 negatedWeights(moebius), -integerOne with finite, function,702 negatedFunction, subset, scaledValues703have total := integerSetSum.integer with finite, function, subset704have fixed : integerSetSum(squarefreeDivisors(n), moebius) =705 integerMulValue(-integerOne, integerSetSum(squarefreeDivisors(n),706 moebius)) bycc707have cancel : integerSetSum(squarefreeDivisors(n), moebius) +708 integerMulValue(-integerOne, integerSetSum(squarefreeDivisors(n),709 moebius)) = integerZero byring710have doubled : integerSetSum(squarefreeDivisors(n), moebius) +711 integerSetSum(squarefreeDivisors(n), moebius) = integerZero712rw← fixed at cancel713exact cancel714have zero := integerAddValue.self_eq_zero with doubled715rw restricted716exact zero717