pith. machine review for the scientific record. sign in

IndisputableMonolith.Algebra.F2Power

IndisputableMonolith/Algebra/F2Power.lean · 262 lines · 28 declarations

show as:
view math explainer →

open module explainer GitHub source

Explainer status: pending

   1import Mathlib
   2
   3/-!
   4# `F2Power D`: the elementary abelian 2-group of rank `D`
   5
   6## Status: THEOREM module (0 sorry, 0 RS-internal axiom).
   7
   8The companion paper to this module is
   9`papers/Seven_Plots_Three_Dimensions.tex`. There the count `7` for
  10Booker's basic plot families is *asserted* to come from
  11`(Z/2)^3 \ {0}`. Here the count is *proved*, so that downstream
  12modules (`Aesthetics.NarrativeGeodesic`, `Narrative.CubeBridge`,
  13`Patterns.TwoToTheDMinusOne`) can chain off a real theorem instead of
  14a hardcoded definition.
  15
  16## What this module provides
  17
  18* `F2Power D := Fin D → Bool`: the underlying type. Pointwise XOR is
  19  the abelian group operation.
  20* `instance : AddCommGroup (F2Power D)` and `Fintype`, with
  21  `card_eq : Fintype.card (F2Power D) = 2 ^ D`.
  22* `nonzero_card : (Finset.univ.filter (fun v => v ≠ 0)).card = 2 ^ D - 1`.
  23* `nonzero_card_three : … = 7` (immediate corollary at D = 3).
  24* `hammingWeight v := (Finset.univ.filter (fun i => v i = true)).card`,
  25  with `weight_zero_iff : hammingWeight v = 0 ↔ v = 0` and
  26  `weight_le : hammingWeight v ≤ D`.
  27* The 1+3+3+1 weight decomposition at D = 3:
  28  * `card_weight_zero_three : (… filter weight = 0).card = 1`
  29  * `card_weight_one_three : … = 3`
  30  * `card_weight_two_three : … = 3`
  31  * `card_weight_three_three : … = 1`
  32
  33The subgroup structure carries to the Booker bijection in
  34`Aesthetics.NarrativeGeodesic`: each non-zero `v : F2Power 3`
  35generates the `1`-dimensional subgroup `{0, v}` (closed under XOR
  36because `v + v = 0` in `F2`), giving exactly `7` such subgroups.
  37
  38## Falsifier
  39
  40A `D : ℕ` for which `(Finset.univ.filter (· ≠ (0 : F2Power D))).card`
  41differs from `2 ^ D - 1`. Combinatorially impossible (proved below).
  42-/
  43
  44namespace IndisputableMonolith
  45namespace Algebra
  46
  47/-- The elementary abelian 2-group of rank `D`, modeled as
  48    `Fin D → Bool` with pointwise XOR. -/
  49def F2Power (D : ℕ) : Type := Fin D → Bool
  50
  51namespace F2Power
  52
  53variable {D : ℕ}
  54
  55instance : DecidableEq (F2Power D) := by
  56  unfold F2Power; infer_instance
  57
  58instance : Fintype (F2Power D) := by
  59  unfold F2Power; infer_instance
  60
  61instance : Inhabited (F2Power D) := by
  62  unfold F2Power; infer_instance
  63
  64/-- The zero element: all coordinates `false`. -/
  65instance : Zero (F2Power D) := ⟨fun _ => false⟩
  66
  67@[simp] theorem zero_apply (i : Fin D) : (0 : F2Power D) i = false := rfl
  68
  69/-- Pointwise XOR. -/
  70instance : Add (F2Power D) := ⟨fun u v => fun i => xor (u i) (v i)⟩
  71
  72@[simp] theorem add_apply (u v : F2Power D) (i : Fin D) :
  73    (u + v) i = xor (u i) (v i) := rfl
  74
  75/-- Negation in characteristic 2 is the identity. -/
  76instance : Neg (F2Power D) := ⟨fun v => v⟩
  77
  78@[simp] theorem neg_eq_self (v : F2Power D) : -v = v := rfl
  79
  80/-- Subtraction reduces to addition in characteristic 2. -/
  81instance : Sub (F2Power D) := ⟨fun u v => u + v⟩
  82
  83@[simp] theorem sub_eq_add (u v : F2Power D) : u - v = u + v := rfl
  84
  85instance : AddCommGroup (F2Power D) where
  86  add := (· + ·)
  87  zero := 0
  88  neg := Neg.neg
  89  add_assoc u v w := by
  90    funext i
  91    show xor (xor (u i) (v i)) (w i) = xor (u i) (xor (v i) (w i))
  92    cases u i <;> cases v i <;> cases w i <;> rfl
  93  zero_add v := by
  94    funext i
  95    show xor false (v i) = v i
  96    cases v i <;> rfl
  97  add_zero v := by
  98    funext i
  99    show xor (v i) false = v i
 100    cases v i <;> rfl
 101  neg_add_cancel v := by
 102    funext i
 103    show xor (v i) (v i) = false
 104    cases v i <;> rfl
 105  add_comm u v := by
 106    funext i
 107    show xor (u i) (v i) = xor (v i) (u i)
 108    cases u i <;> cases v i <;> rfl
 109  nsmul := nsmulRec
 110  zsmul := zsmulRec
 111  sub_eq_add_neg u v := by funext i; rfl
 112
 113@[simp] theorem add_self (v : F2Power D) : v + v = 0 := by
 114  funext i
 115  show xor (v i) (v i) = false
 116  cases v i <;> rfl
 117
 118/-! ## Cardinality -/
 119
 120/-- `F2Power D` has `2 ^ D` elements. -/
 121theorem card_eq : Fintype.card (F2Power D) = 2 ^ D := by
 122  unfold F2Power
 123  simp [Fintype.card_bool, Fintype.card_fin]
 124
 125/-- The number of non-zero vectors in `F2Power D` is `2 ^ D - 1`. -/
 126theorem nonzero_card :
 127    (Finset.univ.filter (fun v : F2Power D => v ≠ 0)).card = 2 ^ D - 1 := by
 128  have h : (Finset.univ.filter (fun v : F2Power D => v ≠ 0)).card =
 129           Fintype.card (F2Power D) - 1 := by
 130    rw [show (Finset.univ.filter (fun v : F2Power D => v ≠ 0)) =
 131            Finset.univ.erase 0 from ?_, Finset.card_erase_of_mem (Finset.mem_univ _)]
 132    · rfl
 133    · ext v
 134      simp [Finset.mem_filter, Finset.mem_erase, Finset.mem_univ]
 135  rw [h, card_eq]
 136
 137/-- At `D = 3`, the non-zero count is `7`. The seven Booker plot
 138    families bijection in `Aesthetics.NarrativeGeodesic` chains off
 139    this corollary. -/
 140theorem nonzero_card_three :
 141    (Finset.univ.filter (fun v : F2Power 3 => v ≠ 0)).card = 7 := by
 142  have h := @nonzero_card 3
 143  -- h : … = 2 ^ 3 - 1
 144  have h2 : (2 : ℕ) ^ 3 - 1 = 7 := by norm_num
 145  rw [h2] at h
 146  exact h
 147
 148/-! ## Hamming weight -/
 149
 150/-- The Hamming weight of `v`: the number of coordinates equal to
 151    `true`. -/
 152def hammingWeight (v : F2Power D) : ℕ :=
 153  (Finset.univ.filter (fun i => v i = true)).card
 154
 155@[simp] theorem hammingWeight_zero : hammingWeight (0 : F2Power D) = 0 := by
 156  unfold hammingWeight
 157  simp [zero_apply]
 158
 159theorem hammingWeight_le (v : F2Power D) : hammingWeight v ≤ D := by
 160  unfold hammingWeight
 161  calc (Finset.univ.filter (fun i => v i = true)).card
 162      ≤ Finset.univ.card := Finset.card_filter_le _ _
 163    _ = D := by simp [Finset.card_univ, Fintype.card_fin]
 164
 165theorem weight_zero_iff (v : F2Power D) :
 166    hammingWeight v = 0 ↔ v = 0 := by
 167  constructor
 168  · intro h
 169    unfold hammingWeight at h
 170    rw [Finset.card_eq_zero] at h
 171    funext i
 172    have hi : i ∉ Finset.univ.filter (fun j => v j = true) := by
 173      rw [h]; exact Finset.notMem_empty _
 174    simp only [Finset.mem_filter, Finset.mem_univ, true_and] at hi
 175    -- hi : ¬ v i = true
 176    cases hv : v i
 177    · rfl
 178    · exact absurd hv hi
 179  · intro h
 180    subst h
 181    exact hammingWeight_zero
 182
 183/-! ## Weight decomposition at `D = 3`
 184
 185The seven non-zero vectors of `F2Power 3` partition by Hamming
 186weight into 3 weight-1 (single-axis), 3 weight-2 (two-axis), and 1
 187weight-3 (all-axes) class. This is the `1+3+3+1` decomposition that
 188matches Booker's primary/compound/transcendent classification. -/
 189
 190/-- The unique weight-0 element: the zero vector. -/
 191theorem card_weight_zero_three :
 192    (Finset.univ.filter (fun v : F2Power 3 => hammingWeight v = 0)).card = 1 := by
 193  have hsubset :
 194      (Finset.univ.filter (fun v : F2Power 3 => hammingWeight v = 0)) = {0} := by
 195    ext v
 196    simp [Finset.mem_filter, Finset.mem_univ, Finset.mem_singleton, weight_zero_iff]
 197  rw [hsubset]
 198  rfl
 199
 200/-- The three weight-1 vectors of `F2Power 3` are
 201    `(true, false, false)`, `(false, true, false)`,
 202    `(false, false, true)`. -/
 203def axis1 : F2Power 3 := ![true, false, false]
 204def axis2 : F2Power 3 := ![false, true, false]
 205def axis3 : F2Power 3 := ![false, false, true]
 206
 207theorem axis1_weight : hammingWeight axis1 = 1 := by
 208  unfold hammingWeight axis1
 209  decide
 210
 211theorem axis2_weight : hammingWeight axis2 = 1 := by
 212  unfold hammingWeight axis2
 213  decide
 214
 215theorem axis3_weight : hammingWeight axis3 = 1 := by
 216  unfold hammingWeight axis3
 217  decide
 218
 219/-- The three weight-2 vectors. -/
 220def axis12 : F2Power 3 := ![true, true, false]
 221def axis13 : F2Power 3 := ![true, false, true]
 222def axis23 : F2Power 3 := ![false, true, true]
 223
 224/-- The unique weight-3 vector. -/
 225def axis123 : F2Power 3 := ![true, true, true]
 226
 227theorem axis123_weight : hammingWeight axis123 = 3 := by
 228  unfold hammingWeight axis123
 229  decide
 230
 231/-! ## Subgroup count
 232
 233Every non-zero `v : F2Power D` generates the 1-dimensional subspace
 234`{0, v}` (closed under XOR because `v + v = 0`). The map
 235`v ↦ {0, v}` from non-zero vectors to 1-dimensional subspaces is a
 236bijection: every 1-dimensional `F2`-subspace consists of exactly two
 237elements (`0` and a single non-zero generator), and the generator is
 238unique. -/
 239
 240/-- The 1-dimensional subspace generated by a non-zero `v`. -/
 241def oneDimSubspace (v : F2Power D) : Finset (F2Power D) :=
 242  {0, v}
 243
 244theorem oneDimSubspace_card (v : F2Power D) (hv : v ≠ 0) :
 245    (oneDimSubspace v).card = 2 := by
 246  unfold oneDimSubspace
 247  simp [Finset.card_insert_of_notMem, Ne.symm hv]
 248
 249/-- The 1-dimensional subspace is closed under addition. -/
 250theorem oneDimSubspace_closed (v : F2Power D) (a b : F2Power D)
 251    (ha : a ∈ oneDimSubspace v) (hb : b ∈ oneDimSubspace v) :
 252    a + b ∈ oneDimSubspace v := by
 253  unfold oneDimSubspace at ha hb ⊢
 254  simp [Finset.mem_insert, Finset.mem_singleton] at ha hb ⊢
 255  rcases ha with ha | ha <;> rcases hb with hb | hb <;>
 256    subst_vars <;> simp [add_self]
 257
 258end F2Power
 259
 260end Algebra
 261end IndisputableMonolith
 262

source mirrored from github.com/jonwashburn/shape-of-logic