mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
Registering required it to actually compile (it did not). Fixes:
- capacity_bound_grid was FALSE at L₁=0 or L₂=0 (empty grid, nonempty image)
and its `norm_num : 0 < (L₁:ℤ)` could not prove positivity of a variable.
Added `0 < L₁, 0 < L₂` hypotheses; threaded through capacity_bound and
chiral_capacity_bound.
- mathlib name drift: emod_nonneg/emod_lt → Int.emod_nonneg (b ≠ 0) /
Int.emod_lt_of_pos; Finset.card_Ico → Int.card_Ico;
Finset.card_le_card_of_subset → Finset.card_le_card; Finset.image_subset →
Finset.image_subset_iff.mpr.
- replaced a `#eval` (broke on ℤ's noncomputable order instance) and its WRONG
expected value (claimed 4 over {1..6}, actually 6) with two kernel-checked
`decide` witnesses: {1,2,5,6}→4 (the Sidon set) and Ico 1 7→6.
- registered CoreFormalism.StrandCapacityBound in lakefile.
Verified: lake build OK (links into SilverSightFormal), #print axioms =
{propext, Classical.choice, Quot.sound} (no sorryAx, no custom axiom),
anti-smuggle --ci clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
101 lines
4.2 KiB
Text
101 lines
4.2 KiB
Text
import Mathlib.Data.Nat.Basic
|
||
import Mathlib.Data.Int.Basic
|
||
import Mathlib.Data.Finset.Basic
|
||
import Mathlib.Tactic
|
||
|
||
open Finset
|
||
open Nat
|
||
|
||
/-!
|
||
# Strand Capacity Bound
|
||
|
||
A single chiral strand pair (L₁, L₂) maps each a ∈ A to the pair
|
||
(a mod L₁, S−a mod L₂) on the 2-torus Z/L₁Z × Z/L₂Z.
|
||
|
||
## Theorem
|
||
|
||
For a single strand with moduli L₁, L₂ and any finite set A:
|
||
|
||
|F(A)| ≤ min(|A|, L₁·L₂) × 2
|
||
|
||
The bound has two parts:
|
||
1. |F(A)| ≤ |A| (injectivity — F is a function from A)
|
||
2. |F(A)| ≤ L₁·L₂ (codomain has only L₁·L₂ distinct pairs)
|
||
-/
|
||
|
||
variable (L₁ L₂ S : ℕ)
|
||
|
||
/-- The strand pairing: (a mod L₁, S − a mod L₂). -/
|
||
def strandPair (a : ℤ) : ℤ × ℤ :=
|
||
(a % (L₁ : ℤ), ((S : ℤ) - a) % (L₂ : ℤ))
|
||
|
||
/-- Image of A under the strand pairing. -/
|
||
noncomputable def strandImage (A : Set ℤ) : Set (ℤ × ℤ) :=
|
||
strandPair L₁ L₂ S '' A
|
||
|
||
/-- Bound 1: image cardinality ≤ input cardinality (trivial, F is a function). -/
|
||
theorem capacity_bound_input (A : Finset ℤ) :
|
||
(A.image (strandPair L₁ L₂ S)).card ≤ A.card :=
|
||
Finset.card_image_le
|
||
|
||
/--
|
||
Bound 2: the codomain grid has size L₁·L₂.
|
||
Each residue lies in [0, L₁) resp. [0, L₂), so at most
|
||
L₁ × L₂ distinct pairs are reachable regardless of |A|.
|
||
-/
|
||
theorem capacity_bound_grid (A : Finset ℤ) (hL₁ : 0 < L₁) (hL₂ : 0 < L₂) :
|
||
(A.image (strandPair L₁ L₂ S)).card ≤ (L₁ : ℕ) * L₂ := by
|
||
have hL₁' : (0 : ℤ) < (L₁ : ℤ) := by exact_mod_cast hL₁
|
||
have hL₂' : (0 : ℤ) < (L₂ : ℤ) := by exact_mod_cast hL₂
|
||
-- The grid of possible residues
|
||
let grid : Finset (ℤ × ℤ) :=
|
||
(Finset.Ico 0 (L₁ : ℤ)) ×ˢ (Finset.Ico 0 (L₂ : ℤ))
|
||
have hgrid : grid.card = (L₁ : ℕ) * L₂ := by
|
||
simp [grid, Finset.card_product, Int.card_Ico]
|
||
-- Every strand pair lands in the grid
|
||
have hmem : ∀ a : ℤ, strandPair L₁ L₂ S a ∈ grid := by
|
||
intro a
|
||
have hx : a % (L₁ : ℤ) ∈ Finset.Ico 0 (L₁ : ℤ) := by
|
||
have hnonneg : 0 ≤ a % (L₁ : ℤ) := Int.emod_nonneg a (ne_of_gt hL₁')
|
||
have hlt : a % (L₁ : ℤ) < (L₁ : ℤ) := Int.emod_lt_of_pos a hL₁'
|
||
exact Finset.mem_Ico.mpr ⟨hnonneg, hlt⟩
|
||
have hy : ((S : ℤ) - a) % (L₂ : ℤ) ∈ Finset.Ico 0 (L₂ : ℤ) := by
|
||
have hnonneg' : 0 ≤ ((S : ℤ) - a) % (L₂ : ℤ) :=
|
||
Int.emod_nonneg _ (ne_of_gt hL₂')
|
||
have hlt' : ((S : ℤ) - a) % (L₂ : ℤ) < (L₂ : ℤ) :=
|
||
Int.emod_lt_of_pos _ hL₂'
|
||
exact Finset.mem_Ico.mpr ⟨hnonneg', hlt'⟩
|
||
exact Finset.mem_product.mpr ⟨hx, hy⟩
|
||
-- Image is subset of grid, so cardinality bounded by grid cardinality
|
||
calc
|
||
(A.image (strandPair L₁ L₂ S)).card ≤ grid.card :=
|
||
Finset.card_le_card (Finset.image_subset_iff.mpr (fun a _ => hmem a))
|
||
_ = (L₁ : ℕ) * L₂ := hgrid
|
||
|
||
/--
|
||
Combined bound: |F(A)| ≤ min(|A|, L₁·L₂).
|
||
|
||
For a single strand with chirality (2 orientations per pair),
|
||
the full capacity is min(|A|, L₁·L₂) × 2.
|
||
-/
|
||
theorem capacity_bound (A : Finset ℤ) (hL₁ : 0 < L₁) (hL₂ : 0 < L₂) :
|
||
(A.image (strandPair L₁ L₂ S)).card ≤ min A.card ((L₁ : ℕ) * L₂) := by
|
||
apply le_min
|
||
· exact capacity_bound_input L₁ L₂ S A
|
||
· exact capacity_bound_grid L₁ L₂ S A hL₁ hL₂
|
||
|
||
/--
|
||
With chirality: each pair can be read in 2 orders
|
||
(identity, reflection) or (reflection, identity),
|
||
corresponding to σᵢ vs σᵢ⁻¹ in the braid group.
|
||
-/
|
||
theorem chiral_capacity_bound (A : Finset ℤ) (hL₁ : 0 < L₁) (hL₂ : 0 < L₂) :
|
||
(A.image (strandPair L₁ L₂ S)).card * 2 ≤ min A.card ((L₁ : ℕ) * L₂) * 2 := by
|
||
nlinarith [capacity_bound L₁ L₂ S A hL₁ hL₂]
|
||
|
||
-- Sidon example A = {1,2,5,6} with moduli 3,4, S=7 → image has 4 distinct pairs:
|
||
-- 1↦(1,2), 2↦(2,1), 5↦(2,2), 6↦(0,1). Kernel-checked (`decide`, not
|
||
-- `#eval`/`native_decide`), sidestepping ℤ's noncomputable order instance.
|
||
example : (({1, 2, 5, 6} : Finset ℤ).image (strandPair 3 4 7)).card = 4 := by decide
|
||
-- Full range Ico 1 7 = {1,…,6} instead gives 6 distinct pairs (all injective here):
|
||
example : ((Finset.Ico (1 : ℤ) 7).image (strandPair 3 4 7)).card = 6 := by decide
|