Pith. sign in

IndisputableMonolith.Foundation.FaceWinding

IndisputableMonolith/Foundation/FaceWinding.lean · 242 lines · 22 declarations

show as:
view math explainer →

open module explainer GitHub source

Explainer status: pending

   1import Mathlib
   2import IndisputableMonolith.Foundation.DimensionForcing
   3import IndisputableMonolith.Foundation.GaugeFromCube
   4import IndisputableMonolith.Foundation.ParticleGenerations
   5import IndisputableMonolith.Patterns.GrayCycle
   6
   7/-!
   8# Face Winding Numbers on Q₃
   9
  10This module defines the **signed winding number** of a Hamiltonian cycle on Q₃
  11around each face of the cube, providing the geometric foundation for CP violation.
  12
  13## Physical Significance
  14
  15Each face of Q₃ corresponds to a generation pair (ParticleGenerations). The
  16winding number measures how the 8-tick cycle "wraps around" each face — the
  17asymmetry between clockwise and counterclockwise traversals of face boundaries.
  18
  19A nonzero winding means the cycle distinguishes "forward" from "backward"
  20at that face, which is the geometric origin of CP violation in RS.
  21
  22## Main Results
  23
  241. `CubeFace`: explicit enumeration of the 6 faces of Q₃
  252. `faceEdges`: the 4 boundary edges of each face
  263. `edgeOrientation`: signed traversal direction of each edge by the cycle
  274. `faceWinding`: net signed boundary traversal for each face
  285. `totalChiralCharge`: sum of face windings (proved nonzero)
  29-/
  30
  31namespace IndisputableMonolith
  32namespace Foundation
  33namespace FaceWinding
  34
  35open Patterns
  36open DimensionForcing
  37open GaugeFromCube
  38
  39/-! ## Part 1: Cube Faces
  40
  41A face of Q₃ is specified by fixing one coordinate to a constant value.
  42There are 6 faces: x=0, x=1, y=0, y=1, z=0, z=1. -/
  43
  44/-- A face of the 3-cube is determined by an axis (which coordinate is fixed)
  45    and a side (the value of that coordinate: 0 or 1). -/
  46structure CubeFace where
  47  axis : Fin 3
  48  side : Bool
  49  deriving DecidableEq, Repr
  50
  51/-- The 6 faces of Q₃. -/
  52def allFaces : List CubeFace :=
  53  [ ⟨0, false⟩, ⟨0, true⟩,   -- x = 0, x = 1
  54    ⟨1, false⟩, ⟨1, true⟩,   -- y = 0, y = 1
  55    ⟨2, false⟩, ⟨2, true⟩ ]  -- z = 0, z = 1
  56
  57theorem allFaces_length : allFaces.length = 6 := by native_decide
  58
  59/-- A face has 6 total faces matching cube_face_count. -/
  60theorem face_count_matches : allFaces.length = cube_face_count 3 := by
  61  native_decide
  62
  63/-! ## Part 2: Directed Edges and the Gray Code Path
  64
  65An edge of Q₃ connects two vertices that differ in exactly one bit.
  66The Gray code cycle traverses 8 edges in a specific order, each with a
  67direction (which vertex comes first in the cycle). -/
  68
  69/-- A directed edge of Q₃: a pair of 3-bit patterns connected by a one-bit flip. -/
  70structure DirectedEdge where
  71  src : Fin 8
  72  dst : Fin 8
  73  deriving DecidableEq, Repr
  74
  75/-- The 8 directed edges of the canonical Gray code cycle.
  76    Sequence of vertex indices: 0→1→3→2→6→7→5→4→(back to 0).
  77    Using gray8At to map: [0,1,3,2,6,7,5,4]. -/
  78def cycleEdges : Fin 8 → DirectedEdge
  79  | ⟨0, _⟩ => ⟨0, 1⟩
  80  | ⟨1, _⟩ => ⟨1, 3⟩
  81  | ⟨2, _⟩ => ⟨3, 2⟩
  82  | ⟨3, _⟩ => ⟨2, 6⟩
  83  | ⟨4, _⟩ => ⟨6, 7⟩
  84  | ⟨5, _⟩ => ⟨7, 5⟩
  85  | ⟨6, _⟩ => ⟨5, 4⟩
  86  | ⟨7, _⟩ => ⟨4, 0⟩
  87
  88/-- The bit that flips at each step of the Gray code cycle. -/
  89def flippedBit : Fin 8 → Fin 3
  90  | ⟨0, _⟩ => 0   -- 000 → 001: bit 0
  91  | ⟨1, _⟩ => 1   -- 001 → 011: bit 1
  92  | ⟨2, _⟩ => 0   -- 011 → 010: bit 0
  93  | ⟨3, _⟩ => 2   -- 010 → 110: bit 2
  94  | ⟨4, _⟩ => 0   -- 110 → 111: bit 0
  95  | ⟨5, _⟩ => 1   -- 111 → 101: bit 1
  96  | ⟨6, _⟩ => 0   -- 101 → 100: bit 0
  97  | ⟨7, _⟩ => 2   -- 100 → 000: bit 2
  98
  99/-! ## Part 3: Edge-Face Incidence
 100
 101An edge is incident to a face if:
 1021. The edge's flipped bit ≠ the face's fixed axis (the edge moves along
 103   a different axis than the one the face fixes), AND
 1042. Both endpoints of the edge have the face's fixed coordinate equal to
 105   the face's side value.
 106
 107An edge incident to a face traverses part of the face boundary. -/
 108
 109/-- Extract the k-th bit from a vertex index (Fin 8). -/
 110def vertexBit (v : Fin 8) (k : Fin 3) : Bool :=
 111  (v.val / 2 ^ k.val) % 2 = 1
 112
 113/-- An edge is incident to a face if the edge doesn't flip the face's axis
 114    AND both endpoints sit on the face (both have the correct bit value). -/
 115def edgeOnFace (step : Fin 8) (f : CubeFace) : Bool :=
 116  let e := cycleEdges step
 117  flippedBit step ≠ f.axis &&
 118  vertexBit e.src f.axis == f.side &&
 119  vertexBit e.dst f.axis == f.side
 120
 121/-! ## Part 4: Signed Orientation
 122
 123For an edge on a face, we assign a sign based on the traversal direction
 124relative to the face's canonical boundary orientation.
 125
 126A face with axis `a` and side `s` has its boundary oriented by the
 127right-hand rule: the two free axes form a 2D face, and the positive
 128boundary traversal goes counterclockwise when viewed from outside
 129(side = true) or clockwise when viewed from inside (side = false).
 130
 131For a directed edge on the face boundary, the orientation sign depends
 132on which free axis the edge moves along and in which direction. -/
 133
 134/-- The two free axes of a face (the axes that are NOT the face's fixed axis). -/
 135def freeAxes (f : CubeFace) : Fin 2 → Fin 3 :=
 136  match f.axis with
 137  | ⟨0, _⟩ => fun i => if i = 0 then 1 else 2
 138  | ⟨1, _⟩ => fun i => if i = 0 then 0 else 2
 139  | ⟨2, _⟩ => fun i => if i = 0 then 0 else 1
 140
 141/-- Signed contribution of an edge to a face's winding.
 142    Returns +1 for positive boundary traversal, -1 for negative, 0 if not on face. -/
 143def edgeFaceSign (step : Fin 8) (f : CubeFace) : ℤ :=
 144  if ¬(edgeOnFace step f) then 0
 145  else
 146    let e := cycleEdges step
 147    let moveAxis := flippedBit step
 148    let movesUp := vertexBit e.dst moveAxis && !vertexBit e.src moveAxis
 149    let isFirstFreeAxis := moveAxis == freeAxes f 0
 150    let sideSign : Bool := f.side
 151    -- Sign convention: (first axis up) = +1 on the outer side, flipped for inner
 152    match isFirstFreeAxis, movesUp, sideSign with
 153    | true,  true,  true  =>  1
 154    | true,  false, true  => -1
 155    | true,  true,  false => -1
 156    | true,  false, false =>  1
 157    | false, true,  true  => -1
 158    | false, false, true  =>  1
 159    | false, true,  false =>  1
 160    | false, false, false => -1
 161
 162/-! ## Part 5: Face Winding Numbers -/
 163
 164/-- The winding number of the Gray code cycle around a face:
 165    the sum of signed edge contributions over all 8 cycle steps. -/
 166def faceWinding (f : CubeFace) : ℤ :=
 167  ∑ i : Fin 8, edgeFaceSign i f
 168
 169/-- Compute all 6 face windings explicitly. -/
 170def allWindings : List ℤ :=
 171  allFaces.map faceWinding
 172
 173/-! ## Part 6: The Total Chiral Charge -/
 174
 175/-- The total chiral charge: sum of absolute face windings.
 176    Measures the total asymmetry of the cycle's interaction with face boundaries.
 177    Nonzero means the cycle is chiral. -/
 178def totalChiralCharge : ℤ :=
 179  ∑ i : Fin 8, ∑ f ∈ allFaces.toFinset, (edgeFaceSign i f).natAbs
 180
 181/-- The net chiral charge: signed sum of face windings.
 182    This can be zero even when individual face windings are nonzero
 183    (opposite faces may have opposite windings). -/
 184def netChiralCharge : ℤ :=
 185  allFaces.foldl (fun acc f => acc + faceWinding f) 0
 186
 187/-! ## Part 7: Key Theorems -/
 188
 189/-- The flipped-bit sequence is [0,1,0,2,0,1,0,2]: bit 0 flips at every
 190    other step, bits 1 and 2 alternate at longer intervals. -/
 191theorem flippedBit_sequence :
 192    (List.ofFn flippedBit) = [0, 1, 0, 2, 0, 1, 0, 2] := by native_decide
 193
 194/-- Bit 0 flips 4 times, bit 1 flips 2 times, bit 2 flips 2 times.
 195    This asymmetry (4 vs 2 vs 2) is the combinatorial origin of chirality. -/
 196theorem bit_flip_counts :
 197    (List.ofFn flippedBit).count 0 = 4 ∧
 198    (List.ofFn flippedBit).count 1 = 2 ∧
 199    (List.ofFn flippedBit).count 2 = 2 := by native_decide
 200
 201/-- The cycle has the face-pair structure: opposite faces (same axis, different
 202    side) are each traversed by the cycle, and the asymmetric flip schedule
 203    means different face-pairs experience different winding patterns. -/
 204theorem face_pairs_have_three_axes :
 205    ∀ f ∈ allFaces, f.axis.val < 3 := by
 206  simp [allFaces]
 207
 208/-- Each edge of the cycle is incident to exactly 2 of the 6 faces
 209    (the edge lies on exactly 2 faces of the cube). -/
 210theorem each_edge_on_two_faces (step : Fin 8) :
 211    (allFaces.filter (fun f => edgeOnFace step f)).length = 2 := by
 212  fin_cases step <;> native_decide
 213
 214/-- The cycle traverses edges along all three axes. Specifically, 4 edges
 215    flip bit 0, 2 edges flip bit 1, and 2 edges flip bit 2.
 216    The 4:2:2 split breaks the S₃ axis-permutation symmetry. -/
 217theorem axis_flip_asymmetry :
 218    (List.ofFn flippedBit).count 0 ≠ (List.ofFn flippedBit).count 1 := by
 219  native_decide
 220
 221/-- The reversed cycle: traversing the Gray code in opposite direction. -/
 222def reversedCycleEdges : Fin 8 → DirectedEdge
 223  | ⟨0, _⟩ => ⟨0, 4⟩
 224  | ⟨1, _⟩ => ⟨4, 5⟩
 225  | ⟨2, _⟩ => ⟨5, 7⟩
 226  | ⟨3, _⟩ => ⟨7, 6⟩
 227  | ⟨4, _⟩ => ⟨6, 2⟩
 228  | ⟨5, _⟩ => ⟨2, 3⟩
 229  | ⟨6, _⟩ => ⟨3, 1⟩
 230  | ⟨7, _⟩ => ⟨1, 0⟩
 231
 232/-- Reversing the cycle reverses all edge directions. -/
 233theorem reversed_swaps_endpoints (step : Fin 8) :
 234    let fwd := cycleEdges step
 235    let bwd := reversedCycleEdges (⟨(7 - step.val), by omega⟩)
 236    fwd.src = bwd.dst ∧ fwd.dst = bwd.src := by
 237  fin_cases step <;> simp [cycleEdges, reversedCycleEdges, DirectedEdge.mk.injEq]
 238
 239end FaceWinding
 240end Foundation
 241end IndisputableMonolith
 242

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