The core module lean/FrcCore/Pigeonhole.lean — the substrate from first principles, no Mathlib, no axioms (the modules in order: Nat, Pigeonhole, Shell, Series, Cycle, Ring, FrameCore, Frame, Parity, Transform, Orbit, Sum, Theme/Projective, Theme/Fourier, Theme/Fractional, Theme/Lifts, Theme/Dichotomy, Theme/Rotations, Theme/Heisenberg, Theme/Spectra, Theme/Exclusivity, Theme/Quadratic, Theme/Extension, Theme/Tally, Theme/Numbers, Theme/Logic, Theme/SecondOrder, Theme/Formation, Theme/Field, Theme/Foundation, Theme/Drive, Theme/Carrier, Theme/Subject, Theme/Pair, Theme/Hopf, Theme/Symbol, Theme/Gravity, Theme/Quantum, Theme/Unitary, Theme/Interactions, Theme/Horizon, Theme/Shift, Theme/Lattice, Theme/Drift, Theme/Observation, Theme/Interference, Theme/Composite, Theme/Ladder, Meridian, Fourier, Algebra, Epi, Dimensions, Poly, Quaternion, Causality, Representation, Reductio, Godel, Finitism, Geometry, Complex, Instances, Rh, Entropy, Dirac, Gravity, S13, Qm, Pnp, Keys/Frame, Keys/Extension, Keys/Projective, Keys/Fourier, Keys/Numbers, Keys/Logic, Keys/Foundation, Keys/Carrier, Keys/Subject, Keys/Gravity, Keys/Quantum, Keys/Interactions, Keys/Horizon): 9 theorems (4 definitions): 9 with no axioms, 0 at tier 1 (propext, Quot.sound), 0 at tier 2 (Classical.choice), 0 red; the mark's colour is the library's (green, the core; red a proof the gate rejects), each declaration's axioms on hover; the small plain glyph marks a definition (no proof, no axioms; on the ledger pages the plain glyph is instead a module cited as a whole). Each declaration is anchored; the ledger predicates cite them by name. ▶ open in Lean Live · axioms.log.
1import FrcCore.Nat23/-!4# FrcCore.Pigeonhole — a list of `n` distinct numbers in `[1, n]` is all of `[1, n]`56The counting fact behind "the drive generates": its `p − 1` powers are distinct nonzero residues, and there7are only `p − 1` of those. Lists of naturals with their own membership, no-duplicates and erase (Lean's8`List` lemmas carry `propext`); everything by induction. No axioms.9-/1011namespace FRC12namespace Pigeonhole1314/-- Membership, by recursion (decidable). -/15def mem (v : Nat) : List Nat → Prop16 | [] => False17 | a :: l => v = a ∨ mem v l1819
def decMem (v : Nat) : (l : List Nat) → Decidable (mem v l)20 | [] => isFalse id21 | a :: l => match Nat.decEq v a, decMem v l with22 | isTrue h, _ => isTrue (Or.inl h)23 | isFalse _, isTrue h' => isTrue (Or.inr h')24 | isFalse h, isFalse h' => isFalse (fun e => match e with | Or.inl e => h e | Or.inr e => h' e)2526instance (v : Nat) (l : List Nat) : Decidable (mem v l) := decMem v l2728/-- No duplicates, by recursion. -/29
def NoDup : List Nat → Prop30 | [] => True31 | a :: l => ¬ mem a l ∧ NoDup l3233/-- Remove the first occurrence of `v`. -/34
def erase (v : Nat) : List Nat → List Nat35 | [] => []36 | a :: l => if a = v then l else a :: erase v l3738
theorem length_erase_of_mem {v : Nat} : ∀ {l : List Nat}, mem v l → (erase v l).length + 1 = l.length39 | [], h => absurd h id40 | a :: l, h => by41 show (if a = v then l else a :: erase v l).length + 1 = l.length + 142 exact match Nat.decEq a v with43 | isTrue e => by rw [ite_eq_left e]44 | isFalse e => by45 rw [ite_eq_right e]46 show (erase v l).length + 1 + 1 = l.length + 147 have hm : mem v l := match h with48 | Or.inl h' => absurd h'.symm e49 | Or.inr h' => h'50 rw [length_erase_of_mem hm]5152
theorem mem_of_mem_erase {w v : Nat} : ∀ {l : List Nat}, mem w (erase v l) → mem w l53 | [], h => absurd h id54 | a :: l, h => by55 show w = a ∨ mem w l56 exact match Nat.decEq a v with57 | isTrue e => by58 rw [show erase v (a :: l) = l from ite_eq_left e] at h59 exact Or.inr h60 | isFalse e => by61 rw [show erase v (a :: l) = a :: erase v l from ite_eq_right e] at h62 exact match h with63 | Or.inl h' => Or.inl h'64 | Or.inr h' => Or.inr (mem_of_mem_erase h')6566
theorem mem_erase_of_ne {w v : Nat} (hwv : w ≠ v) : ∀ {l : List Nat}, mem w l → mem w (erase v l)67 | [], h => absurd h id68 | a :: l, h => by69 exact match Nat.decEq a v with70 | isTrue e => by71 rw [show erase v (a :: l) = l from ite_eq_left e]72 exact match h with73 | Or.inl h' => absurd (h'.trans e) hwv74 | Or.inr h' => h'75 | isFalse e => by76 rw [show erase v (a :: l) = a :: erase v l from ite_eq_right e]77 exact match h with78 | Or.inl h' => Or.inl h'79 | Or.inr h' => Or.inr (mem_erase_of_ne hwv h')8081
theorem nodup_erase (v : Nat) : ∀ {l : List Nat}, NoDup l → NoDup (erase v l)82 | [], _ => trivial83 | a :: l, ⟨ha, hl⟩ => by84 exact match Nat.decEq a v with85 | isTrue e => by rw [show erase v (a :: l) = l from ite_eq_left e]; exact hl86 | isFalse e => by87 rw [show erase v (a :: l) = a :: erase v l from ite_eq_right e]88 exact ⟨fun h => ha (mem_of_mem_erase h), nodup_erase v hl⟩8990
theorem not_mem_erase_self (v : Nat) : ∀ {l : List Nat}, NoDup l → ¬ mem v (erase v l)91 | [], _, h => h92 | a :: l, ⟨ha, hl⟩, h => by93 exact match Nat.decEq a v with94 | isTrue e => by95 rw [show erase v (a :: l) = l from ite_eq_left e] at h96 exact ha (e ▸ h)97 | isFalse e => by98 rw [show erase v (a :: l) = a :: erase v l from ite_eq_right e] at h99 exact match h with100 | Or.inl h' => e h'.symm101 | Or.inr h' => not_mem_erase_self v hl h'102103/-- The bound: a list of distinct numbers in `[1, n]` has at most `n` entries. -/104
theorem length_le_of_nodup : ∀ (n : Nat) (l : List Nat), NoDup l → (∀ e, mem e l → 1 ≤ e ∧ e ≤ n) →105 l.length ≤ n106 | 0, [], _, _ => Nat.le_refl 0107 | 0, a :: l, _, hb => absurd (hb a (Or.inl rfl)) (fun ⟨h1, h0⟩ => Nat.lt_irrefl 0 (Nat.lt_of_lt_of_le h1 h0))108 | n + 1, l, hnd, hb =>109 match (inferInstance : Decidable (mem (n + 1) l)) with110 | isTrue hm =>111 have h1 : (erase (n + 1) l).length ≤ n :=112 length_le_of_nodup n (erase (n + 1) l) (nodup_erase _ hnd) (fun e he =>113 have hb' := hb e (mem_of_mem_erase he)114 ⟨hb'.1, match Nat.lt_or_ge e (n + 1) with115 | Or.inl hlt => Nat.le_of_lt_succ hlt116 | Or.inr hge =>117 have : e = n + 1 := Nat.le_antisymm hb'.2 hge118 absurd (this ▸ he) (not_mem_erase_self (n + 1) hnd)⟩)119 by rw [← length_erase_of_mem hm]; exact Nat.succ_le_succ h1120 | isFalse hm =>121 Nat.le_succ_of_le (length_le_of_nodup n l hnd (fun e he =>122 have hb' := hb e he123 ⟨hb'.1, match Nat.lt_or_ge e (n + 1) with124 | Or.inl hlt => Nat.le_of_lt_succ hlt125 | Or.inr hge => absurd he ((Nat.le_antisymm hb'.2 hge) ▸ hm)⟩))126127/-- The pigeonhole: `n` distinct numbers in `[1, n]` are all of them. -/128
theorem mem_of_nodup_of_length (n : Nat) (l : List Nat) (hnd : NoDup l) (hb : ∀ e, mem e l → 1 ≤ e ∧ e ≤ n)129 (hlen : l.length = n) (v : Nat) (hv1 : 1 ≤ v) (hvn : v ≤ n) : mem v l :=130 match decMem v l with131 | isTrue h => h132 | isFalse h =>133 have hnd' : NoDup (v :: l) := ⟨h, hnd⟩134 have hb' : ∀ e, mem e (v :: l) → 1 ≤ e ∧ e ≤ n := fun e he => match he with135 | Or.inl e' => e' ▸ ⟨hv1, hvn⟩136 | Or.inr e' => hb e e'137 have := length_le_of_nodup n (v :: l) hnd' hb'138 absurd (hlen ▸ this : n + 1 ≤ n) (Nat.not_succ_le_self n)139140/-- The same with the range `[0, n)`: a list of distinct numbers below `n` has at most `n` entries. -/141
theorem length_le_of_nodup_lt : ∀ (n : Nat) (l : List Nat), NoDup l → (∀ e, mem e l → e < n) → l.length ≤ n142 | 0, [], _, _ => Nat.le_refl 0143 | 0, a :: l, _, hb => absurd (hb a (Or.inl rfl)) (Nat.not_lt_zero a)144 | n + 1, l, hnd, hb =>145 match decMem n l with146 | isTrue hm =>147 have h1 : (erase n l).length ≤ n :=148 length_le_of_nodup_lt n (erase n l) (nodup_erase _ hnd) (fun e he =>149 match Nat.lt_or_ge e n with150 | Or.inl hlt => hlt151 | Or.inr hge =>152 have : e = n := Nat.le_antisymm (Nat.le_of_lt_succ (hb e (mem_of_mem_erase he))) hge153 absurd (this ▸ he) (not_mem_erase_self n hnd))154 by rw [← length_erase_of_mem hm]; exact Nat.succ_le_succ h1155 | isFalse hm =>156 Nat.le_succ_of_le (length_le_of_nodup_lt n l hnd (fun e he =>157 match Nat.lt_or_ge e n with158 | Or.inl hlt => hlt159 | Or.inr hge => absurd he ((Nat.le_antisymm (Nat.le_of_lt_succ (hb e he)) hge) ▸ hm)))160161/-- `n` distinct numbers below `n` are all of them. -/162
theorem mem_of_nodup_of_length_lt (n : Nat) (l : List Nat) (hnd : NoDup l) (hb : ∀ e, mem e l → e < n)163 (hlen : l.length = n) (v : Nat) (hv : v < n) : mem v l :=164 match decMem v l with165 | isTrue h => h166 | isFalse h =>167 have hb' : ∀ e, mem e (v :: l) → e < n := fun e he => match he with168 | Or.inl e' => e' ▸ hv169 | Or.inr e' => hb e e'170 have := length_le_of_nodup_lt n (v :: l) ⟨h, hnd⟩ hb'171 absurd (hlen ▸ this : n + 1 ≤ n) (Nat.not_succ_le_self n)172173end Pigeonhole174end FRC175

