Complete and partial residue blocks used to count finite prime-square conditions.
The k-th complete block of positive integers of length M.
Equations
- LeanPool.DeadEnds.completeBlock M k = Finset.Icc (k * M + 1) ((k + 1) * M)
Instances For
For any x, y in the complete block [kM+1, (k+1)M], we have |y - x| < M.
This follows because:
- The block has width (k+1)M - (kM+1) = M - 1
- So the maximum absolute difference between any two elements is M - 1 < M
In integers: max(y) - min(x) = (k+1)M - (kM+1) = M - 1
and min(y) - max(x) = (kM+1) - (k+1)M = 1 - M
So |y - x| ≤ M - 1 < M.
Mathlib coverage: This uses
abs_sub_lt_iffand basic interval arithmetic.
The function N ↦ N % M is injective on the complete block. Two numbers in [kM+1, (k+1)M] with the same residue mod M must be equal, since they are within distance M of each other. The proof uses the fact that if x, y are in [kM+1, (k+1)M], then |x - y| < M. If x % M = y % M and |x - y| < M, then x = y (since the only multiple of M in (-M, M) is 0).
For N in the k-th complete block, N mod M takes each residue below M exactly once. This is because N ranges from kM+1 through (k+1)M, and:
- (kM+j) mod M = j for 1 ≤ j < M
- (k+1)M mod M = 0
More precisely: the map N ↦ N % M is a bijection from B_k to
Finset.range M.
Filtering a complete block preserves injectivity of the residue map.
Filtering a complete block preserves surjectivity of the residue map onto valid residues.
Each complete block B_k contributes exactly |A| valid integers.
Since the map N ↦ N % M is a bijection from B_k to Finset.range M, and by
condition_mod_invariant validity depends only on N % M, the count of valid N in B_k
equals the count of valid residues in Finset.range M, which is |A|.
Uses: condition_mod_invariant, completeBlock_residues_bijective
The complete blocks indexed by Finset.range q are pairwise disjoint.
Block B_i = [iM+1, (i+1)M] and B_j = [jM+1, (j+1)M] are disjoint for i ≠ j
because their ranges don't overlap.
Uses: For i < j, (i+1)M < jM+1 so the intervals are disjoint.
The sum of valid elements from all complete blocks ≤ count.
Since blocks are disjoint and contained in [1,X], the union of filtered blocks is a subset of the filtered [1,X], so the sum of cardinalities is at most count. Uses: completeBlocks_pairwise_disjoint, completeBlocks_subset_Icc, Finset.card_biUnion
The partial block consists of the remaining integers from q * M + 1 through X,
where q = X / M.
Equations
- LeanPool.DeadEnds.partialBlock M X = Finset.Icc (X / M * M + 1) X
Instances For
The residue map N ↦ N % M is injective on the partial block from q * M + 1 through X.
This is because for any N in the partial block, N = qM + k where 1 ≤ k ≤ r < M
(where r = X % M), so N % M = k. Different elements have different k values.
The key insight is that all elements lie within a single period of M:
they are all in [qM+1, q*M+r] where r < M.
Uses: Set.InjOn : ∀ {α : Type u_1} {β : Type u_2}, (α → β) → Set α → Prop
which states f is injective on s iff ∀ x ∈ s, ∀ y ∈ s, f x = f y → x = y.
The interval [1,X] equals the disjoint union of complete blocks indexed by Finset.range q and
the partial block V from qM + 1 through X.
Every n ∈ [1,X] falls into exactly one of:
- Complete block B_k where k = (n-1)/M for k < q
- Partial block V if (n-1)/M ≥ q Conversely, all elements in the blocks are in [1,X] by completeBlocks_subset_Icc and partialBlock_subset_Icc. Uses the division algorithm: n = (n-1)/M * M + (n-1)%M + 1.
Filtering preserves pairwise disjointness of Finsets: if the original Finsets are
pairwise disjoint, then their filtered versions are too.
Mathlib has Finset.pairwiseDisjoint_filter : ∀ {α β : Type*} {s : Finset α} {f : α → Finset β}, (↑s).PairwiseDisjoint f → ∀ (p : β → Prop), (↑s).PairwiseDisjoint (fun a => Finset.filter p (f a))
but this only works for Finsets s, not arbitrary sets.
This follows from Set.PairwiseDisjoint.mono : ∀ {s : Set ι} {f g : ι → α}, s.PairwiseDisjoint f → g ≤ f → s.PairwiseDisjoint g
combined with Finset.filter_subset : ∀ (p : α → Prop) [DecidablePred p] (s : Finset α), Finset.filter p s ⊆ s to show that filtering decreases each set.
Since (f k).filter P ⊆ f k for all k, and disjointness is preserved under taking subsets,
the filtered family inherits pairwise disjointness from the original family.