The Sylvester-Gallai theorem in Lean 4

[2026-08-07 Fri] #permalink

Today we saw a blog post about Kelly's elegant proof of the Sylvester-Gallai theorem. Out of curiosity, we ran Harmonic's Aristotle to formalize it in Lean 4. The AI succeeded the task in 80 minutes, as follows: shared link.

The code excerpt:

/-
# The Sylvester–Gallai theorem

Every finite set of points of a real inner product space which is not collinear admits an
*ordinary line*: a line through exactly two of the points.

The proof formalised here is Kelly's proof: among all pairs consisting of a point `p` of the set
and a connecting line `ℓ` (a line through two points of the set) with `p ∉ ℓ`, pick one minimising
the distance from `p` to `ℓ`.  If `ℓ` contained three points of the set, two of them, `B` and `C`,
would lie on the same side of the foot of the perpendicular from `p` to `ℓ`, with `B` the closer
one; then the distance from `B` to the line through `p` and `C` would be smaller, a contradiction.

Distances are handled through the Gram determinant `gram x y = ‖x‖²‖y‖² - ⟪x,y⟫²`, which is the
square of the area of the parallelogram spanned by `x` and `y`; this way only *squared* distances
occur and no square roots are needed.
-/

import Mathlib

open RealInnerProductSpace

namespace SylvesterGallai

variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace ℝ V]

/-! ## The Gram determinant -/

/-- The Gram determinant of two vectors, `‖x‖²‖y‖² - ⟪x,y⟫²`.  It is the square of the area of
the parallelogram spanned by `x` and `y`. -/
noncomputable def gram (x y : V) : ℝ := ‖x‖ ^ 2 * ‖y‖ ^ 2 - ⟪x, y⟫ ^ 2

lemma gram_comm (x y : V) : gram x y = gram y x := by
  simp [gram, real_inner_comm x y]; ring

lemma gram_nonneg (x y : V) : 0 ≤ gram x y := by
  have h := abs_real_inner_le_norm x y
  have h2 : ⟪x, y⟫ ^ 2 ≤ (‖x‖ * ‖y‖) ^ 2 := by
    rw [← sq_abs]; exact pow_le_pow_left₀ (abs_nonneg _) h 2
  simp only [gram]; nlinarith

lemma gram_smul_left (r : ℝ) (x y : V) : gram (r • x) y = r ^ 2 * gram x y := by
  simp [gram, norm_smul, real_inner_smul_left, mul_pow]; ring

lemma gram_neg_right (x y : V) : gram x (-y) = gram x y := by simp [gram]

lemma gram_neg_left (x y : V) : gram (-x) y = gram x y := by simp [gram]

lemma norm_add_smul_sq (r : ℝ) (x y : V) :
    ‖y + r • x‖ ^ 2 = ‖y‖ ^ 2 + 2 * r * ⟪x, y⟫ + r ^ 2 * ‖x‖ ^ 2 := by
  rw [norm_add_sq_real]
  simp [real_inner_smul_right, norm_smul, mul_pow, real_inner_comm y x]
  ring

/-- Shearing invariance: adding a multiple of `x` to `y` does not change `gram x y`. -/
lemma gram_shear (r : ℝ) (x y : V) : gram x (y + r • x) = gram x y := by
  simp only [gram, norm_add_smul_sq, inner_add_right, real_inner_smul_right,
    real_inner_self_eq_norm_sq]
  ring

/-- The Gram determinant of the sides of a triangle does not depend on the chosen vertex. -/
lemma gram_tri (x y z : V) : gram (y - x) (z - x) = gram (z - y) (x - y) := by
  have h1 : x - y = -(y - x) := by module
  have h2 : z - y = (z - x) + (-1 : ℝ) • (y - x) := by module
  rw [h2, h1, gram_comm ((z - x) + (-1 : ℝ) • (y - x)) (-(y - x)), gram_neg_left, gram_shear]

lemma gram_eq_zero_iff {x y : V} (hx : x ≠ 0) : gram x y = 0 ↔ ∃ r : ℝ, y = r • x := by
  have hx2 : (0 : ℝ) < ‖x‖ ^ 2 := by positivity
  constructor
  · intro h
    refine ⟨⟪x, y⟫ / ‖x‖ ^ 2, ?_⟩
    have key : ‖y - (⟪x, y⟫ / ‖x‖ ^ 2) • x‖ ^ 2 = 0 := by
      rw [norm_sub_sq_real, real_inner_smul_right, real_inner_comm y x, norm_smul,
        Real.norm_eq_abs, mul_pow, sq_abs]
      simp only [gram] at h
      rw [← real_inner_comm x y] at h
      field_simp
      nlinarith [h]
    have h0 : y - (⟪x, y⟫ / ‖x‖ ^ 2) • x = 0 := by
      simpa using (pow_eq_zero_iff (n := 2) (by norm_num)).mp key
    exact sub_eq_zero.mp h0
  · rintro ⟨r, rfl⟩
    simp only [gram, real_inner_smul_right, norm_smul, Real.norm_eq_abs, mul_pow, sq_abs,
      real_inner_self_eq_norm_sq]
    ring

/-! ## Lines -/

lemma mem_line_iff {a b x : V} : x ∈ line[ℝ, a, b] ↔ ∃ t : ℝ, x = a + t • (b - a) := by
  rw [mem_affineSpan_pair_iff_exists_lineMap_eq]
  simp only [AffineMap.lineMap_apply, vsub_eq_sub, vadd_eq_add]
  constructor
  · rintro ⟨t, rfl⟩; exact ⟨t, by abel⟩
  · rintro ⟨t, rfl⟩; exact ⟨t, by abel⟩

/-- The squared distance from the point `p` to the line through `a` and `b`. -/
noncomputable def sqDistLine (p a b : V) : ℝ := gram (b - a) (p - a) / ‖b - a‖ ^ 2

lemma sqDistLine_nonneg (p a b : V) : 0 ≤ sqDistLine p a b :=
  div_nonneg (gram_nonneg _ _) (by positivity)

lemma sqDistLine_eq_zero_iff {p a b : V} (hab : a ≠ b) :
    sqDistLine p a b = 0 ↔ p ∈ line[ℝ, a, b] := by
  have hv : b - a ≠ 0 := sub_ne_zero.mpr (Ne.symm hab)
  have hv2 : (0 : ℝ) < ‖b - a‖ ^ 2 := by positivity
  rw [sqDistLine, div_eq_zero_iff]
  constructor
  · rintro (h | h)
    · obtain ⟨r, hr⟩ := (gram_eq_zero_iff hv).mp h
      exact mem_line_iff.mpr ⟨r, by rw [← hr]; abel⟩
    · exact absurd h (by positivity)
  · intro h
    obtain ⟨t, ht⟩ := mem_line_iff.mp h
    left
    exact (gram_eq_zero_iff hv).mpr ⟨t, by rw [ht]; abel⟩

lemma sqDistLine_pos {p a b : V} (hab : a ≠ b) (hp : p ∉ line[ℝ, a, b]) :
    0 < sqDistLine p a b :=
  lt_of_le_of_ne (sqDistLine_nonneg _ _ _) fun h =>
    hp ((sqDistLine_eq_zero_iff hab).mp h.symm)

lemma gram_pos_of_not_mem_line {p a b : V} (hab : a ≠ b) (hp : p ∉ line[ℝ, a, b]) :
    0 < gram (b - a) (p - a) := by
  have hv2 : (0 : ℝ) < ‖b - a‖ ^ 2 := by
    have : b - a ≠ 0 := sub_ne_zero.mpr (Ne.symm hab)
    positivity
  have := sqDistLine_pos hab hp
  rw [sqDistLine, lt_div_iff₀ hv2] at this
  linarith

/-- On a line, a point is determined by its inner product with the direction vector. -/
lemma line_inner_inj {p a b X Y : V} (hab : a ≠ b) (hX : X ∈ line[ℝ, a, b])
    (hY : Y ∈ line[ℝ, a, b]) (h : ⟪X - p, b - a⟫ = ⟪Y - p, b - a⟫) : X = Y := by
  have hv : b - a ≠ 0 := sub_ne_zero.mpr (Ne.symm hab)
  have hv2 : (0 : ℝ) < ‖b - a‖ ^ 2 := by positivity
  obtain ⟨s, hs⟩ := mem_line_iff.mp hX
  obtain ⟨t, ht⟩ := mem_line_iff.mp hY
  have hd : ⟪X - Y, b - a⟫ = (s - t) * ‖b - a‖ ^ 2 := by
    have : X - Y = (s - t) • (b - a) := by rw [hs, ht]; module
    rw [this, real_inner_smul_left, real_inner_self_eq_norm_sq]
  have h0 : ⟪X - Y, b - a⟫ = 0 := by
    have : X - Y = (X - p) - (Y - p) := by abel
    rw [this, inner_sub_left, h, sub_self]
  have hst : s = t := by
    rw [h0] at hd
    have : s - t = 0 := by
      rcases mul_eq_zero.mp hd.symm with h' | h'
      · exact h'
      · exact absurd h' (by positivity)
    linarith
  rw [hs, ht, hst]

/-- If `p` is off the line `ab` and `B ≠ C` are two points of that line, then `B` is not on the
line through `p` and `C`. -/
lemma not_mem_line_aux {p a b B C : V} (hp : p ∉ line[ℝ, a, b])
    (hB : B ∈ line[ℝ, a, b]) (hC : C ∈ line[ℝ, a, b]) (hBC : B ≠ C) :
    B ∉ line[ℝ, p, C] := by
  intro hmem
  have hcol : Collinear ℝ ({B, p, C} : Set V) := collinear_insert_of_mem_affineSpan_pair hmem
  have hpBC : p ∈ line[ℝ, B, C] :=
    hcol.mem_affineSpan_of_mem_of_ne (by simp) (by simp) (by simp) hBC
  have hle : line[ℝ, B, C] ≤ line[ℝ, a, b] := affineSpan_pair_le_of_mem_of_mem hB hC
  exact hp (hle hpBC)

/-! ## Kelly's key inequality -/

/-- **Kelly's step.**  Let `p` be a point off the line `ab`, and let `B`, `C` be two distinct
points of that line lying on the same side of the foot of the perpendicular from `p`, with `B`
no further from the foot than `C` (this is expressed by the two hypotheses on the inner products
`⟪B - p, b - a⟫` and `⟪C - p, b - a⟫`, which are, up to a positive factor, the signed
coordinates of `B` and `C` relative to that foot).  Then `B` is strictly closer to the line `pC`
than `p` is to the line `ab`. -/
lemma kelly {p a b B C : V} (hab : a ≠ b) (hp : p ∉ line[ℝ, a, b])
    (hB : B ∈ line[ℝ, a, b]) (hC : C ∈ line[ℝ, a, b])
    (hsign : 0 ≤ ⟪B - p, b - a⟫ * ⟪C - p, b - a⟫)
    (hsq : ⟪B - p, b - a⟫ ^ 2 ≤ ⟪C - p, b - a⟫ ^ 2) :
    sqDistLine B p C < sqDistLine p a b := by
  have hv : b - a ≠ 0 := sub_ne_zero.mpr (Ne.symm hab)
  have hv2 : (0 : ℝ) < ‖b - a‖ ^ 2 := by positivity
  set v := b - a with hvdef
  obtain ⟨s, hs⟩ := mem_line_iff.mp hB
  obtain ⟨t, ht⟩ := mem_line_iff.mp hC
  set G := gram v (p - a) with hGdef
  have hG : 0 < G := gram_pos_of_not_mem_line hab hp
  set al := ⟪B - p, v⟫ with haldef
  set be := ⟪C - p, v⟫ with hbedef
  have hCp : (0 : ℝ) < ‖C - p‖ ^ 2 := by
    have h1 : C ≠ p := fun h => hp (h ▸ hC)
    have h2 : C - p ≠ 0 := sub_ne_zero.mpr h1
    positivity
  have F1 : gram (C - p) (B - p) = (t - s) ^ 2 * G := by
    have e1 : gram (C - p) (B - p) = gram (B - C) (p - C) := gram_tri p C B
    have e2 : B - C = (s - t) • v := by rw [hs, ht]; module
    have e3 : p - C = (p - a) + (-t) • v := by rw [ht]; module
    rw [e1, e2, e3, gram_smul_left, gram_shear]
    ring
  have F2 : ‖C - p‖ ^ 2 * ‖v‖ ^ 2 = G + be ^ 2 := by
    have e3 : C - p = -(p - a) + t • v := by rw [ht]; module
    have h1 : gram v (C - p) = G := by rw [e3, gram_shear, gram_neg_right]
    have h2 : ⟪v, C - p⟫ = be := real_inner_comm (C - p) v
    simp only [gram, h2] at h1
    linear_combination h1
  have F3 : be - al = (t - s) * ‖v‖ ^ 2 := by
    rw [haldef, hbedef, ← inner_sub_left]
    have e : C - p - (B - p) = (t - s) • v := by rw [hs, ht]; module
    rw [e, real_inner_smul_left, real_inner_self_eq_norm_sq]
  have hprod : al ^ 2 ≤ al * be := by
    nlinarith [hsign, hsq, sq_nonneg al, sq_nonneg (al * be - al ^ 2)]
  have hmain : (be - al) ^ 2 < G + be ^ 2 := by nlinarith [hprod, hsign, hG]
  rw [sqDistLine, sqDistLine, div_lt_div_iff₀ hCp hv2]
  have hLHS : gram (C - p) (B - p) * ‖v‖ ^ 2 * ‖v‖ ^ 2 = G * (be - al) ^ 2 := by
    rw [F1, F3]; ring
  have hRHS : G * ‖C - p‖ ^ 2 * ‖v‖ ^ 2 = G * (G + be ^ 2) := by rw [mul_assoc, F2]
  have hlt : gram (C - p) (B - p) * ‖v‖ ^ 2 * ‖v‖ ^ 2 < G * ‖C - p‖ ^ 2 * ‖v‖ ^ 2 := by
    rw [hLHS, hRHS]; exact mul_lt_mul_of_pos_left hmain hG
  nlinarith [hlt, hv2]

/-! ## Pigeonhole -/

/-- Among any three reals, two have a nonnegative product. -/
lemma exists_same_sign (x y z : ℝ) : 0 ≤ x * y ∨ 0 ≤ y * z ∨ 0 ≤ x * z := by
  rcases le_total 0 x with hx | hx <;> rcases le_total 0 y with hy | hy <;>
    rcases le_total 0 z with hz | hz <;>
    first
      | (left; nlinarith)
      | (right; left; nlinarith)
      | (right; right; nlinarith)

/-- Among three distinct reals there are two distinct ones, `f i` and `f j`, of the same sign
with `|f i| ≤ |f j|`. -/
lemma exists_pair_same_side (f : Fin 3 → ℝ) (hf : Function.Injective f) :
    ∃ i j, f i ≠ f j ∧ 0 ≤ f i * f j ∧ (f i) ^ 2 ≤ (f j) ^ 2 := by
  have key : ∀ i j : Fin 3, i ≠ j → 0 ≤ f i * f j →
      ∃ i' j', f i' ≠ f j' ∧ 0 ≤ f i' * f j' ∧ (f i') ^ 2 ≤ (f j') ^ 2 := by
    intro i j hij h
    rcases le_total ((f i) ^ 2) ((f j) ^ 2) with h' | h'
    · exact ⟨i, j, fun e => hij (hf e), h, h'⟩
    · exact ⟨j, i, fun e => hij (hf e).symm, by rwa [mul_comm], h'⟩
  rcases exists_same_sign (f 0) (f 1) (f 2) with h | h | h
  · exact key 0 1 (by decide) h
  · exact key 1 2 (by decide) h
  · exact key 0 2 (by decide) h

/-! ## The theorem -/

/-- **The Sylvester–Gallai theorem** in a real inner product space: a finite set of points that
is not collinear has an *ordinary line*, i.e. two of its points `a ≠ b` such that the line
through `a` and `b` contains no other point of the set. -/
theorem sylvester_gallai (S : Finset V) (hS : ¬ Collinear ℝ (S : Set V)) :
    ∃ a ∈ S, ∃ b ∈ S, a ≠ b ∧ ∀ p ∈ S, p ∈ line[ℝ, a, b] → p = a ∨ p = b := by
  classical
  -- `T` is the set of all triples `(p, a, b)` of points of `S` with `a ≠ b` and `p` off the
  -- line through `a` and `b`.
  set T : Finset (V × V × V) :=
    (S ×ˢ S ×ˢ S).filter (fun q => q.2.1 ≠ q.2.2 ∧ q.1 ∉ line[ℝ, q.2.1, q.2.2]) with hT
  have hmemT : ∀ q : V × V × V, q ∈ T ↔
      ((q.1 ∈ S ∧ q.2.1 ∈ S ∧ q.2.2 ∈ S) ∧ q.2.1 ≠ q.2.2 ∧ q.1 ∉ line[ℝ, q.2.1, q.2.2]) := by
    intro q
    simp [hT, Finset.mem_filter, Finset.mem_product, and_assoc]
  -- `S` is not collinear, so `T` is nonempty.
  have hTne : T.Nonempty := by
    rw [Finset.nonempty_iff_ne_empty]
    intro hempty
    apply hS
    rcases Finset.eq_empty_or_nonempty S with rfl | ⟨a, ha⟩
    · simpa using collinear_empty ℝ V
    by_cases hall : ∀ x ∈ S, x = a
    · exact (collinear_singleton ℝ a).subset (fun x hx => hall x hx)
    push_neg at hall
    obtain ⟨b, hb, hba⟩ := hall
    have hmem : ∀ x ∈ S, x ∈ line[ℝ, a, b] := by
      intro x hx
      by_contra hcon
      have : (x, a, b) ∈ T := (hmemT _).mpr ⟨⟨hx, ha, hb⟩, Ne.symm hba, hcon⟩
      rw [hempty] at this
      exact absurd this (Finset.notMem_empty _)
    rw [collinear_iff_of_mem (show a ∈ (S : Set V) from ha)]
    refine ⟨b - a, fun x hx => ?_⟩
    obtain ⟨r, hr⟩ := mem_line_iff.mp (hmem x hx)
    exact ⟨r, by rw [hr]; simp [add_comm]⟩
  -- Choose a triple minimising the distance from the point to the line.
  obtain ⟨⟨p, a, b⟩, hqT, hmin⟩ :=
    T.exists_min_image (fun q => sqDistLine q.1 q.2.1 q.2.2) hTne
  obtain ⟨⟨hpS, haS, hbS⟩, hab, hp⟩ := (hmemT _).mp hqT
  refine ⟨a, haS, b, hbS, hab, ?_⟩
  -- Suppose the line through `a` and `b` contained a third point `c` of `S`.
  intro c hcS hc
  by_contra hcon
  push_neg at hcon
  obtain ⟨hca, hcb⟩ := hcon
  set P : Fin 3 → V := ![a, b, c] with hP
  have hPS : ∀ i, P i ∈ S := by intro i; fin_cases i <;> assumption
  have hPline : ∀ i, P i ∈ line[ℝ, a, b] := by
    intro i
    fin_cases i
    · exact left_mem_affineSpan_pair ℝ a b
    · exact right_mem_affineSpan_pair ℝ a b
    · exact hc
  have hPinj : Function.Injective P := by
    intro i j hij
    fin_cases i <;> fin_cases j <;> simp_all
  set f : Fin 3 → ℝ := fun i => ⟪P i - p, b - a⟫ with hf
  have hfinj : Function.Injective f :=
    fun i j hij => hPinj (line_inner_inj hab (hPline i) (hPline j) hij)
  obtain ⟨i, j, hne, hsign, hsq⟩ := exists_pair_same_side f hfinj
  have hBC : P i ≠ P j := fun h => hne (by rw [hf]; simp only [h])
  have hlt : sqDistLine (P i) p (P j) < sqDistLine p a b :=
    kelly hab hp (hPline i) (hPline j) hsign hsq
  have hpj : p ≠ P j := fun h => hp (h ▸ hPline j)
  have hmemT' : (P i, p, P j) ∈ T :=
    (hmemT _).mpr ⟨⟨hPS i, hpS, hPS j⟩, hpj, not_mem_line_aux hp (hPline i) (hPline j) hBC⟩
  exact absurd (hmin _ hmemT') (not_le.mpr hlt)

/-- The Sylvester–Gallai theorem in the Euclidean plane. -/
theorem sylvester_gallai_plane (S : Finset (EuclideanSpace ℝ (Fin 2)))
    (hS : ¬ Collinear ℝ (S : Set (EuclideanSpace ℝ (Fin 2)))) :
    ∃ a ∈ S, ∃ b ∈ S, a ≠ b ∧ ∀ p ∈ S, p ∈ line[ℝ, a, b] → p = a ∨ p = b :=
  sylvester_gallai S hS

/-- The same statement, phrased as: some connecting line meets the set in exactly two points. -/
theorem sylvester_gallai_plane' (S : Finset (EuclideanSpace ℝ (Fin 2)))
    (hS : ¬ Collinear ℝ (S : Set (EuclideanSpace ℝ (Fin 2)))) :
    ∃ a ∈ S, ∃ b ∈ S, a ≠ b ∧
      (S : Set (EuclideanSpace ℝ (Fin 2))) ∩ (line[ℝ, a, b] : Set _) = {a, b} := by
  obtain ⟨a, ha, b, hb, hab, h⟩ := sylvester_gallai_plane S hS
  refine ⟨a, ha, b, hb, hab, ?_⟩
  ext x
  simp only [Set.mem_inter_iff, Set.mem_insert_iff, Set.mem_singleton_iff,
    SetLike.mem_coe]
  constructor
  · rintro ⟨hx, hx'⟩; exact h x hx hx'
  · rintro (rfl | rfl)
    · exact ⟨ha, left_mem_affineSpan_pair ℝ _ _⟩
    · exact ⟨hb, right_mem_affineSpan_pair ℝ _ _⟩

/-! ## A sanity check: the hypothesis is satisfiable -/

/-- The three vertices of a right triangle in the plane are not collinear, so the hypothesis of
the theorem above is not vacuous. -/
example : ¬ Collinear ℝ
    ({!₂[(0:ℝ), 0], !₂[(1:ℝ), 0], !₂[(0:ℝ), 1]} : Set (EuclideanSpace ℝ (Fin 2))) := by
  intro h
  rw [collinear_iff_of_mem (show (!₂[(0:ℝ), 0] : EuclideanSpace ℝ (Fin 2)) ∈ _ by simp)] at h
  obtain ⟨v, hv⟩ := h
  obtain ⟨r, hr⟩ := hv !₂[(1:ℝ), 0] (by simp)
  obtain ⟨s, hs⟩ := hv !₂[(0:ℝ), 1] (by simp)
  have h1 := congrFun (congrArg WithLp.ofLp hr) 0
  have h4 := congrFun (congrArg WithLp.ofLp hs) 1
  have h3 := congrFun (congrArg WithLp.ofLp hs) 0
  simp at h1 h3 h4
  rcases h3 with h3 | h3 <;> simp [h3] at h1 h4

#print axioms SylvesterGallai.sylvester_gallai_plane
#print axioms SylvesterGallai.sylvester_gallai_plane'

end SylvesterGallai

In hindsight, the Sylvester-Gallai theorem is one of Freek Wiedijk's 1000+ theorems. A generalized (metric space) version of the theorem has already been established in Lean 4, but not (yet) in Mathlib4.


Archives

2024-05-13: Minasp v0.6.11 released for Mew v6.11

2024-04-11: Running Torch for R with CUDA in a Docker container

2024-03-17: Introducing Minasp, a Nix package of Mew

2024-03-02: How to view a figure plotted by Plotly R from macOS Terminal

2024-02-20: How to cite references in Org Mode with Zotero

2024-02-18: Heads up for endangered "404 Not Found" pages

2024-02-17: Finding another blog about Nix: Nixcademy

2024-02-12: Writing blog articles with Org Mode

2023: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2022: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2021: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2020: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2019: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2018: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2017: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2016: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2015: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2014: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2013: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2012: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2011: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2010: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2009: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2008: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2007: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

2006: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec


© 2006-2026 fixedpoint.jp