fix(StrandCapacityBound): repair proofs + register in lakefile

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>
This commit is contained in:
allaun 2026-07-03 15:19:47 -05:00
parent 3362d554d1
commit b65ef756ca
2 changed files with 20 additions and 15 deletions

View file

@ -43,33 +43,33 @@ 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 ) :
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, Finset.card_Ico, Nat.cast_inj]
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₁ : ) := emod_nonneg a (by norm_num : 0 < (L₁ : ))
have hlt : a % (L₁ : ) < (L₁ : ) := emod_lt a (by norm_num : 0 < (L₁ : ))
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₂ : ) :=
emod_nonneg _ (by norm_num : 0 < (L₂ : ))
Int.emod_nonneg _ (ne_of_gt hL₂')
have hlt' : ((S : ) - a) % (L₂ : ) < (L₂ : ) :=
emod_lt _ (by norm_num : 0 < (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_of_subset (Finset.image_subset _ (by
intro a ha
exact hmem a))
Finset.card_le_card (Finset.image_subset_iff.mpr (fun a _ => hmem a))
_ = (L₁ : ) * L₂ := hgrid
/--
@ -78,20 +78,24 @@ 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 ) :
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
· 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 ) :
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]
nlinarith [capacity_bound L₁ L₂ S A hL₁ hL₂]
#eval ((Finset.Ico 1 7).image (strandPair 3 4 7)).card
-- Expected: 4 (Sidon example A={1,2,5,6} with moduli 3,4, S=7)
-- 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

View file

@ -44,6 +44,7 @@ lean_lib «SilverSightFormal» where
`CoreFormalism.HachimojiManifoldAxiom,
`CoreFormalism.ChentsovFinite,
`CoreFormalism.HopfFibration,
`CoreFormalism.StrandCapacityBound,
`SilverSight.AngrySphinx,
`SilverSight.CollatzBraid,
`SilverSight.GoldenSpiral,