face_monochromatic_pairs: reduce Conj 5.1 to a "deciding face" conjecture
NEW PROOF STRATEGY for Conjecture 5.1 (face-monochromatic-pair):
1. NEW Conjecture (Deciding face): For every chord-apex+Kempe
colouring φ of every reduced dual, the reduced dual has a face f
with ∂f ⊆ V(K_b) ∪ V(K_c) and |f| ≢ 0 (mod 3).
2. NEW Theorem: Deciding-face conjecture implies Conj 5.1.
Proof: contradiction. Assume no clauses-(1)-(3) witness for some
chord-apex+Kempe φ. By Lemma 5.3, h_φ ≡ ε ∈ {±1} on V(K_b) ∪ V(K_c).
By the deciding-face conjecture, ∃ face f with ∂f ⊆ V(K_b) ∪ V(K_c),
|f| ≢ 0 (mod 3). Heawood's face-sum identity (Heawood 1898) gives
Σ_{v ∈ ∂f} h_φ(v) = ε|f| ≡ 0 (mod 3). Since gcd(|f|, 3) = 1, we get
ε ≡ 0 (mod 3), but ε ∈ {±1} — contradiction.
3. EMPIRICAL: Conjecture (Deciding face) verified on 142,812 / 142,812
chord-apex+Kempe colourings of reduced duals up to |V(G)| ≤ 20 --
matching the full coverage of check_constancy_obstruction.py.
Face-length distribution:
|f| = 4: 13,074
|f| = 5: 102,498 (most common)
|f| = 7: 18,570
|f| = 8: 7,752
|f| = 10: 846
|f| = 11: 72
(All ≢ 0 mod 3.)
New scripts:
- check_kb_kc_coverage.py: |V(K_b) ∪ V(K_c)| / |V(Ĝ')| distribution.
73.87% of colourings have V(K_b) ∪ V(K_c) = V (full coverage); the
remaining 26% have coverage ≥ 70%, mostly ≥ 90%.
- check_deciding_face.py: existence of deciding face across all
colourings; 100.00% / 142,812.
Why this is the right reduction:
- It uses ALL THREE pieces of chord-apex+Kempe structure: Lemma 5.3
(constancy from no-witness), forced colour-equality at merged/spike,
and forced Kempe-cycle containment of merged + spike + side edges
(the latter two enter via V(K_b) ∪ V(K_c) covering specific
structural vertices).
- It uses Heawood's face-sum identity, which is the classical 3-fold
parity constraint on cubic plane 3-edge-colourings.
- The C28 counterexample to Conjecture 5.5 is not affected: it's not
a chord-apex+Kempe colouring of a reduced dual, so the deciding-face
structure doesn't apply.
Remaining work: prove the deciding-face conjecture structurally (likely
via the specific F_01 / F_12 "flank face" of the reduced dual, whose
length n_0 - 1 from the adjacent G'-face of length n_0 ≥ 5 is ≢ 0 mod 3
exactly when n_0 ≢ 1 mod 3, plus boundary-in-V(K_b) ∪ V(K_c) which
follows from Lemma 5.X kempe-spike + colour analysis at A_i).
Paper grows from 17 to 18 pages.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
"""For every chord-apex+Kempe colouring of every reduced dual (up to
|
||||
|V(G)| ≤ 18), check whether there exists a "deciding face": a face f
|
||||
of the reduced dual whose boundary lies entirely in V(K_b) ∪ V(K_c)
|
||||
and whose length is not divisible by 3.
|
||||
|
||||
If a deciding face exists, then under the (hypothetical) constancy
|
||||
hypothesis h_φ ≡ ε on V(K_b) ∪ V(K_c), Heawood's face-sum identity
|
||||
gives ε · |f| ≡ 0 (mod 3), which forces ε ≡ 0 since |f| ≢ 0 (mod 3) --
|
||||
contradicting ε ∈ {±1}. So existence of a deciding face in every
|
||||
chord-apex+Kempe colouring of every reduced dual would *prove*
|
||||
Conjecture 5.1 via the contrapositive of Lemma 5.3.
|
||||
|
||||
This script reports, per (n_G, colouring): does a deciding face exist?
|
||||
And if not, why not (insufficient coverage, all in-coverage faces have
|
||||
length ≡ 0 mod 3, etc.).
|
||||
|
||||
Run with: sage experiments/check_deciding_face.py
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from sage.all import Graph
|
||||
from sage.graphs.graph_generators import graphs
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
|
||||
from check_conj_3_8_scaled import (
|
||||
apply_reduction,
|
||||
proper_3_edge_colorings,
|
||||
matches_chord_apex_kempe,
|
||||
kempe_cycle_set,
|
||||
edge_idx,
|
||||
)
|
||||
from check_heawood_on_kempe import (
|
||||
dual_of, vertices_of_kempe,
|
||||
)
|
||||
|
||||
|
||||
def find_deciding_face(H, V_union):
|
||||
"""Return (face, |face| mod 3) of a deciding face (all boundary in
|
||||
V_union, length not divisible by 3). None if no such face exists."""
|
||||
for face in H.faces():
|
||||
verts = {u for (u, v) in face} | {v for (u, v) in face}
|
||||
if not verts.issubset(V_union):
|
||||
continue
|
||||
L = len(face)
|
||||
if L % 3 != 0:
|
||||
return face, L, L % 3
|
||||
return None
|
||||
|
||||
|
||||
def test_one(D):
|
||||
D.is_planar(set_embedding=True)
|
||||
n_col = 0
|
||||
n_with_deciding = 0
|
||||
no_deciding_examples = []
|
||||
deciding_lengths = {} # |f| of deciding face -> count
|
||||
for face in D.faces():
|
||||
if len(face) != 5: continue
|
||||
for i_red in range(5):
|
||||
res = apply_reduction(D, face, i_red, 9999)
|
||||
if res is None: continue
|
||||
H = res['H']; named = res['named']
|
||||
H.is_planar(set_embedding=True)
|
||||
edges, colorings = proper_3_edge_colorings(H)
|
||||
cand = [c for c in colorings
|
||||
if matches_chord_apex_kempe(edges, c, named)]
|
||||
for col in cand:
|
||||
n_col += 1
|
||||
merged_idx = edge_idx(edges, named['merged'])
|
||||
a = col[merged_idx]
|
||||
bs = [c for c in range(3) if c != a]
|
||||
kc_b = kempe_cycle_set(edges, col, merged_idx, (a, bs[0]))
|
||||
kc_c = kempe_cycle_set(edges, col, merged_idx, (a, bs[1]))
|
||||
V_b = vertices_of_kempe(edges, kc_b)
|
||||
V_c = vertices_of_kempe(edges, kc_c)
|
||||
V_union = V_b | V_c
|
||||
deciding = find_deciding_face(H, V_union)
|
||||
if deciding is not None:
|
||||
n_with_deciding += 1
|
||||
_, L, mod_r = deciding
|
||||
deciding_lengths[L] = deciding_lengths.get(L, 0) + 1
|
||||
else:
|
||||
cov_ratio = len(V_union) / H.order()
|
||||
in_cov_face_lens = sorted([
|
||||
len(f) for f in H.faces()
|
||||
if {u for (u, v) in f} | {v for (u, v) in f}
|
||||
<= V_union])
|
||||
if len(no_deciding_examples) < 3:
|
||||
no_deciding_examples.append({
|
||||
'cov_ratio': cov_ratio,
|
||||
'in_cov_face_lens': in_cov_face_lens,
|
||||
'V_union_size': len(V_union),
|
||||
'V_total': H.order(),
|
||||
})
|
||||
return n_col, n_with_deciding, deciding_lengths, no_deciding_examples
|
||||
|
||||
|
||||
def main(max_n=20, time_budget_per_n=1800):
|
||||
print(f"Deciding-face existence on chord-apex+Kempe colourings, "
|
||||
f"n_G ∈ [12, {max_n}]\n")
|
||||
grand_col = 0
|
||||
grand_dec = 0
|
||||
grand_lens = {}
|
||||
grand_no_dec_examples = []
|
||||
for n in range(12, max_n + 1):
|
||||
start = time.time()
|
||||
try:
|
||||
triangulations = list(graphs.triangulations(n, minimum_degree=5))
|
||||
except Exception as ex:
|
||||
print(f"n={n}: cannot enumerate ({ex})")
|
||||
continue
|
||||
n_col_n = 0
|
||||
n_dec_n = 0
|
||||
for tri_idx, G in enumerate(triangulations):
|
||||
if time.time() - start > time_budget_per_n:
|
||||
print(f" n={n}: timeout at tri {tri_idx}/{len(triangulations)}")
|
||||
break
|
||||
G.is_planar(set_embedding=True)
|
||||
D = dual_of(G)
|
||||
ni, ndec, lens, no_dec_ex = test_one(D)
|
||||
n_col_n += ni
|
||||
n_dec_n += ndec
|
||||
for k, v in lens.items():
|
||||
grand_lens[k] = grand_lens.get(k, 0) + v
|
||||
if len(grand_no_dec_examples) < 5:
|
||||
grand_no_dec_examples.extend(
|
||||
no_dec_ex[:5 - len(grand_no_dec_examples)])
|
||||
elapsed = time.time() - start
|
||||
pct = 100 * n_dec_n / max(n_col_n, 1)
|
||||
print(f"n={n}: {n_col_n} col., {n_dec_n} with deciding face "
|
||||
f"({pct:.2f}%) [{elapsed:.0f}s]")
|
||||
sys.stdout.flush()
|
||||
grand_col += n_col_n
|
||||
grand_dec += n_dec_n
|
||||
|
||||
print()
|
||||
print("=" * 70)
|
||||
print(f"Grand totals: {grand_col} chord-apex+Kempe colourings")
|
||||
pct = 100 * grand_dec / max(grand_col, 1)
|
||||
print(f" with deciding face: {grand_dec} ({pct:.2f}%)")
|
||||
print(f" without : {grand_col - grand_dec} "
|
||||
f"({100 - pct:.2f}%)")
|
||||
if grand_lens:
|
||||
print()
|
||||
print(" Deciding face length distribution:")
|
||||
for L in sorted(grand_lens):
|
||||
print(f" |f| = {L} (mod 3 = {L % 3}): {grand_lens[L]}")
|
||||
if grand_no_dec_examples:
|
||||
print()
|
||||
print(" Sample colourings WITHOUT a deciding face:")
|
||||
for ex in grand_no_dec_examples[:5]:
|
||||
print(f" coverage = {ex['V_union_size']}/{ex['V_total']} "
|
||||
f"({100*ex['cov_ratio']:.0f}%); in-coverage face "
|
||||
f"lengths = {ex['in_cov_face_lens']}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,132 @@
|
||||
"""Check what fraction of V(Ĝ'_{v,i}) is covered by V(K_b) ∪ V(K_c)
|
||||
across all chord-apex+Kempe colourings of all reduced duals up to
|
||||
|V(G)| ≤ 18.
|
||||
|
||||
This is the key prerequisite for the Heawood-face-sum proof attempt:
|
||||
if V(K_b) ∪ V(K_c) = V(reduced dual) in many cases, then under
|
||||
constancy on V(K_b) ∪ V(K_c) every face of the reduced dual must
|
||||
satisfy ε * |f| ≡ 0 (mod 3); since ε = ±1, this forces |f| ≡ 0 mod 3
|
||||
for every face -- and any reduced dual with a face of length 4, 5, or
|
||||
7 (etc., not multiple of 3) would yield an immediate contradiction.
|
||||
|
||||
Run with: sage experiments/check_kb_kc_coverage.py
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from sage.all import Graph
|
||||
from sage.graphs.graph_generators import graphs
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
|
||||
from check_conj_3_8_scaled import (
|
||||
apply_reduction,
|
||||
proper_3_edge_colorings,
|
||||
matches_chord_apex_kempe,
|
||||
kempe_cycle_set,
|
||||
edge_idx,
|
||||
)
|
||||
from check_heawood_on_kempe import (
|
||||
dual_of, heawood_numbers, vertices_of_kempe,
|
||||
)
|
||||
|
||||
|
||||
def test_one(D):
|
||||
D.is_planar(set_embedding=True)
|
||||
n_col = 0
|
||||
coverage_dist = {} # |V(K_b)∪V(K_c)| / |V| as ratio (rounded) -> count
|
||||
full_coverage = 0
|
||||
face_lengths_at_full = {} # face length distribution when full coverage
|
||||
for face in D.faces():
|
||||
if len(face) != 5: continue
|
||||
for i_red in range(5):
|
||||
res = apply_reduction(D, face, i_red, 9999)
|
||||
if res is None: continue
|
||||
H = res['H']; named = res['named']
|
||||
H.is_planar(set_embedding=True)
|
||||
edges, colorings = proper_3_edge_colorings(H)
|
||||
cand = [c for c in colorings
|
||||
if matches_chord_apex_kempe(edges, c, named)]
|
||||
n_v = H.order()
|
||||
face_lens = sorted([len(f) for f in H.faces()])
|
||||
for col in cand:
|
||||
n_col += 1
|
||||
merged_idx = edge_idx(edges, named['merged'])
|
||||
a = col[merged_idx]
|
||||
bs = [c for c in range(3) if c != a]
|
||||
kc_b = kempe_cycle_set(edges, col, merged_idx, (a, bs[0]))
|
||||
kc_c = kempe_cycle_set(edges, col, merged_idx, (a, bs[1]))
|
||||
V_b = vertices_of_kempe(edges, kc_b)
|
||||
V_c = vertices_of_kempe(edges, kc_c)
|
||||
cov = len(V_b | V_c)
|
||||
cov_ratio = cov / n_v
|
||||
bucket = round(cov_ratio * 20) / 20 # bucket in 5% increments
|
||||
coverage_dist[bucket] = coverage_dist.get(bucket, 0) + 1
|
||||
if cov == n_v:
|
||||
full_coverage += 1
|
||||
key = tuple(face_lens)
|
||||
face_lengths_at_full[key] = (
|
||||
face_lengths_at_full.get(key, 0) + 1)
|
||||
return n_col, coverage_dist, full_coverage, face_lengths_at_full
|
||||
|
||||
|
||||
def main(max_n=18, time_budget_per_n=300):
|
||||
print(f"V(K_b) ∪ V(K_c) coverage / V(Ĝ'_{{v,i}}) "
|
||||
f"on chord-apex+Kempe colourings, n_G ∈ [12, {max_n}]\n")
|
||||
grand_col = 0
|
||||
grand_dist = {}
|
||||
grand_full = 0
|
||||
grand_full_faces = {}
|
||||
for n in range(12, max_n + 1):
|
||||
start = time.time()
|
||||
try:
|
||||
triangulations = list(graphs.triangulations(n, minimum_degree=5))
|
||||
except Exception as ex:
|
||||
print(f"n={n}: cannot enumerate ({ex})")
|
||||
continue
|
||||
n_col_n = 0
|
||||
n_full_n = 0
|
||||
for tri_idx, G in enumerate(triangulations):
|
||||
if time.time() - start > time_budget_per_n:
|
||||
print(f" n={n}: timeout at tri {tri_idx}/{len(triangulations)}")
|
||||
break
|
||||
G.is_planar(set_embedding=True)
|
||||
D = dual_of(G)
|
||||
ni, dist, full, full_faces = test_one(D)
|
||||
n_col_n += ni
|
||||
n_full_n += full
|
||||
for k, v in dist.items():
|
||||
grand_dist[k] = grand_dist.get(k, 0) + v
|
||||
for k, v in full_faces.items():
|
||||
grand_full_faces[k] = grand_full_faces.get(k, 0) + v
|
||||
elapsed = time.time() - start
|
||||
print(f"n={n}: {n_col_n} col., {n_full_n} full-coverage "
|
||||
f"({100 * n_full_n / max(n_col_n, 1):.1f}%) [{elapsed:.0f}s]")
|
||||
sys.stdout.flush()
|
||||
grand_col += n_col_n
|
||||
grand_full += n_full_n
|
||||
|
||||
print()
|
||||
print("=" * 70)
|
||||
print(f"Grand totals: {grand_col} chord-apex+Kempe colourings")
|
||||
print(f" full coverage (V(K_b)∪V(K_c) = V): {grand_full} "
|
||||
f"({100 * grand_full / max(grand_col, 1):.2f}%)")
|
||||
print()
|
||||
print(" Coverage ratio distribution "
|
||||
"(|V(K_b)∪V(K_c)| / |V(Ĝ')|):")
|
||||
for r in sorted(grand_dist):
|
||||
c = grand_dist[r]
|
||||
pct = 100 * c / max(grand_col, 1)
|
||||
bar = '#' * max(1, int(pct))
|
||||
print(f" {r:5.2f}: {c:>7} ({pct:5.2f}%) {bar[:50]}")
|
||||
if grand_full > 0:
|
||||
print()
|
||||
print(" Face-length distributions among full-coverage cases:")
|
||||
for key in sorted(grand_full_faces, key=lambda k: -grand_full_faces[k]):
|
||||
print(f" {key}: {grand_full_faces[key]}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Binary file not shown.
@@ -891,6 +891,108 @@ $V(K_0) \cup V(K_1) \setminus V(K_0) \cap V(K_1)$; grey on neither.}
|
||||
\label{fig:no-two-constant-kempe-counterexample}
|
||||
\end{figure}
|
||||
|
||||
\subsection*{A reduction of Conjecture
|
||||
\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle} via Heawood's
|
||||
face-sum identity}
|
||||
|
||||
The empirical work of Section~\ref{sec:reduced-dual} (the
|
||||
$0/142{,}812$ result on chord-apex+Kempe colourings, recorded in
|
||||
Remark~\ref{rem:heawood-empirical}) suggests a structural proof
|
||||
strategy via the classical Heawood face-sum identity
|
||||
\cite{Heawood1898}:
|
||||
\begin{equation}
|
||||
\label{eq:heawood-face-sum}
|
||||
\sum_{v \in \partial f} h_\varphi(v) \;\equiv\; 0 \pmod 3
|
||||
\qquad\text{for every face $f$ of $H$,}
|
||||
\end{equation}
|
||||
which holds for any proper $3$-edge-colouring $\varphi$ of any cubic
|
||||
plane graph $H$.
|
||||
|
||||
\begin{conjecture}[Deciding face]
|
||||
\label{conj:deciding-face}
|
||||
Let $G$ be a minimal counterexample to the Four Colour Theorem, let
|
||||
$\widehat{G}'_{v,i}$ be a reduced dual of $G'$, and let $\varphi$ be
|
||||
a chord-apex+Kempe colouring of $\widehat{G}'_{v,i}$. Write $K_b$ and
|
||||
$K_c$ for the two Kempe cycles through the spike edge
|
||||
(Lemma~\ref{lem:kempe-spike}). Then $\widehat{G}'_{v,i}$ has a face
|
||||
$f$ satisfying
|
||||
\[
|
||||
\partial f \subseteq V(K_b) \cup V(K_c)
|
||||
\qquad\text{and}\qquad
|
||||
|f| \not\equiv 0 \pmod 3.
|
||||
\]
|
||||
\end{conjecture}
|
||||
|
||||
\begin{theorem}
|
||||
\label{thm:deciding-face-implies-conj-5-1}
|
||||
Conjecture~\ref{conj:deciding-face} implies
|
||||
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}.
|
||||
\end{theorem}
|
||||
|
||||
\begin{proof}
|
||||
We argue by contradiction. Suppose
|
||||
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}
|
||||
fails: there exist a minimal counterexample $G$, a reduced dual
|
||||
$\widehat{G}'_{v,i}$, and a chord-apex+Kempe colouring $\varphi$ of
|
||||
$\widehat{G}'_{v,i}$ admitting no clauses-(1)-(3) witness of
|
||||
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}.
|
||||
|
||||
By Lemma~\ref{lem:both-kempe-constant}, the absence of any
|
||||
clauses-(1)-(3) witness forces $h_\varphi$ to be constant on
|
||||
$V(K_b) \cup V(K_c)$; write the common value as
|
||||
$\varepsilon \in \{+1, -1\}$.
|
||||
|
||||
By Conjecture~\ref{conj:deciding-face}, there is a face $f$ of
|
||||
$\widehat{G}'_{v,i}$ with $\partial f \subseteq V(K_b) \cup V(K_c)$
|
||||
and $|f| \not\equiv 0 \pmod 3$. Applying~\eqref{eq:heawood-face-sum}
|
||||
to $f$ and using $h_\varphi(v) = \varepsilon$ for every
|
||||
$v \in \partial f$:
|
||||
\[
|
||||
\sum_{v \in \partial f} h_\varphi(v)
|
||||
\;=\; \varepsilon \cdot |f|
|
||||
\;\equiv\; 0 \pmod 3.
|
||||
\]
|
||||
Since $3$ is prime and $\gcd(|f|, 3) = 1$, we obtain
|
||||
$\varepsilon \equiv 0 \pmod 3$. But $\varepsilon \in \{+1, -1\}$,
|
||||
so $\varepsilon \not\equiv 0 \pmod 3$ --- contradiction.
|
||||
\end{proof}
|
||||
|
||||
\begin{remark}[Empirical verification of
|
||||
Conjecture~\ref{conj:deciding-face}]
|
||||
\label{rem:deciding-face-empirical}
|
||||
We have verified
|
||||
Conjecture~\ref{conj:deciding-face} computationally on every
|
||||
chord-apex+Kempe colouring of every reduced dual of every
|
||||
triangulation $G$ of minimum degree $5$ with $|V(G)| \le 20$. Across
|
||||
$142{,}812$ such colourings, every single one admits a deciding face.
|
||||
The empirical face-length distribution is:
|
||||
\begin{center}
|
||||
\small
|
||||
\begin{tabular}{r|r|r}
|
||||
$|f|$ & $|f| \bmod 3$ & \#colourings \\
|
||||
\hline
|
||||
$4$ & $1$ & $13{,}074$ \\
|
||||
$5$ & $2$ & $102{,}498$ \\
|
||||
$7$ & $1$ & $18{,}570$ \\
|
||||
$8$ & $2$ & $7{,}752$ \\
|
||||
$10$ & $1$ & $846$ \\
|
||||
$11$ & $2$ & $72$ \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
(Every length appearing is $\not\equiv 0 \pmod 3$, as required.)
|
||||
See \texttt{experiments/check\_deciding\_face.py}.
|
||||
|
||||
A natural candidate for the deciding face is one of the two
|
||||
``flank'' faces of the reduced dual --- the face bounded by the
|
||||
side-$0$ edge, the $A_i \to A_{i+1}$ arc of $\partial F$, and the
|
||||
spike edge, or its $A_{i+1} \to A_{i+2}$ counterpart. When the
|
||||
parent triangulation's vertex $v$ has a degree-$5$ neighbour $B_k$
|
||||
(i.e.\ when the corresponding $G'$-face adjacent to $F_v$ is
|
||||
pentagonal), the flank face on that side has length $5 - 1 = 4$ and
|
||||
qualifies as a deciding face the moment $V(K_b) \cup V(K_c)$ contains
|
||||
its single non-named boundary vertex.
|
||||
\end{remark}
|
||||
|
||||
\begin{remark}[Empirical near-proof of Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle} via Corollary~\ref{cor:single-cycle-non-constancy}]
|
||||
\label{rem:heawood-empirical}
|
||||
\sloppy
|
||||
|
||||
Reference in New Issue
Block a user