face_monochromatic_pairs: per-cycle refinement + Corollary 5.4

Empirical refinement of Lemma 5.3: h_phi is non-constant on V(K_b)
alone (not just on the union) and likewise on V(K_c) alone, in every
one of 142,812 chord-apex+Kempe colourings tested (n in [12, 20]).
This is strictly stronger than what we previously reported.

The proof of Lemma 5.3 already constructs the (F, e_1, e_2) witness
from any consecutive same-Heawood failure on either Kempe cycle
through merged -- never needing the other cycle. Pull that out into
a separate Corollary 5.4 ("Per-cycle form"), which makes the
empirical-to-conjecture path more direct.

Update Remark 5.5 to:
  - Cite Corollary 5.4 instead of the contrapositive of Lemma 5.3.
  - Replace "non-constant on V(K_b) U V(K_c)" with the per-cycle form.
  - Extend the empirical table with separate columns for K_b and K_c
    non-constancy.

Also commit experiments/check_constancy_obstruction.py, the script
that produced these refined empirical findings. It additionally
records that no single named vertex (v_n, A_i, ..., A_{i+4}) is
structurally majority or minority -- the minority rates cluster in
31-39%, ruling out a single-vertex-mismatch identity.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 00:43:35 -04:00
parent a29d145cec
commit 33b51b675b
5 changed files with 295 additions and 44 deletions
@@ -0,0 +1,224 @@
"""For each chord-apex+Kempe colouring, dissect WHERE the constancy
hypothesis fails:
(1) Is h_phi constant on V(K_b) alone? On V(K_c) alone? On the
intersection V(K_b) cap V(K_c)?
(2) Per colouring, distribution of (#+1, #-1) shared vertices.
(3) For each colouring, identify the "minority Heawood" shared
vertices (= those whose h differs from the more frequent value
on V(K_b) cup V(K_c)). How many are there? Are they
concentrated at specific structural positions (v_n, A_{i+1},
A_{i+3}, A_{i+4})?
(4) Is h(v_n) always equal to / always different from the majority?
Under the constancy hypothesis, all of these distributions would be
trivial (everything same Heawood, 0 minority vertices). Their
non-trivial empirical structure exposes where Path 4's "trap"
mechanism would have to apply.
Run with: sage experiments/check_constancy_obstruction.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,
trace_kempe_cycle,
edge_idx,
kempe_cycle_set,
)
from check_heawood_on_kempe import (
dual_of, heawood_numbers, vertices_of_kempe,
)
def named_vertices(named, v_n=9999):
"""Recover A_i, A_{i+1}, ..., A_{i+4}."""
def other(fs, v):
return next(iter(fs - {v}))
A_i = other(named['side_0'], v_n)
A_i1 = other(named['spike'], v_n)
A_i2 = other(named['side_1'], v_n)
A_i3, A_i4 = sorted(named['merged'])
return A_i, A_i1, A_i2, A_i3, A_i4
def test_one(D):
D.is_planar(set_embedding=True)
n_col = 0
rec = {
'const_kb': 0, 'const_kc': 0, 'const_cap': 0,
# (#+1, #-1) on V(K_b) cup V(K_c) histogram
'plus_minus_dist': {},
# # minority Heawood vertices on V(K_b) cup V(K_c)
'minority_count': {},
# Is v_n minority? majority?
'v_n_pos': {'minority': 0, 'majority': 0, 'tie': 0},
# Position-tallies of minority for each "named" vertex
'minority_at': {'v_n': 0, 'A_i': 0, 'A_i1': 0, 'A_i2': 0,
'A_i3': 0, 'A_i4': 0},
# Is h(v_n) == h(A_{i+3}) == h(A_{i+4}) always?
'v_n_eq_merged_endpts': 0,
# Is h constant on the 6 named vertices {v_n, A_0..A_4}?
'const_on_named6': 0,
}
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)]
v_n = 9999
A_i, A_i1, A_i2, A_i3, A_i4 = named_vertices(named, v_n)
for col in cand:
n_col += 1
try:
h = heawood_numbers(H, edges, col)
except RuntimeError:
continue
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
V_cap = V_b & V_c
h_b_vals = {h[v] for v in V_b}
h_c_vals = {h[v] for v in V_c}
h_cap_vals = {h[v] for v in V_cap}
if len(h_b_vals) == 1: rec['const_kb'] += 1
if len(h_c_vals) == 1: rec['const_kc'] += 1
if len(h_cap_vals) == 1: rec['const_cap'] += 1
plus = sum(1 for v in V_union if h[v] == 1)
minus = sum(1 for v in V_union if h[v] == -1)
rec['plus_minus_dist'][(plus, minus)] = \
rec['plus_minus_dist'].get((plus, minus), 0) + 1
# Majority sign on union
if plus > minus:
maj = 1
elif minus > plus:
maj = -1
else:
maj = 0
minority = sum(1 for v in V_union if h[v] != maj and maj != 0)
if maj == 0:
minority = min(plus, minus)
rec['minority_count'][minority] = \
rec['minority_count'].get(minority, 0) + 1
# v_n's position
hv = h.get(v_n)
if hv is not None and maj != 0:
if hv == maj:
rec['v_n_pos']['majority'] += 1
else:
rec['v_n_pos']['minority'] += 1
else:
rec['v_n_pos']['tie'] += 1
# Named vertices: minority count
for name, vv in [('v_n', v_n), ('A_i', A_i),
('A_i1', A_i1), ('A_i2', A_i2),
('A_i3', A_i3), ('A_i4', A_i4)]:
if vv in V_union and maj != 0 and h[vv] != maj:
rec['minority_at'][name] += 1
# h(v_n) == h(A_{i+3}) == h(A_{i+4}) ?
if h.get(v_n) == h.get(A_i3) == h.get(A_i4):
rec['v_n_eq_merged_endpts'] += 1
# h constant on the 6 named vertices?
named6 = [v_n, A_i, A_i1, A_i2, A_i3, A_i4]
named6_vals = {h[vv] for vv in named6 if vv in h}
if len(named6_vals) == 1:
rec['const_on_named6'] += 1
return n_col, rec
def merge_into(g, r):
for k in ('const_kb', 'const_kc', 'const_cap',
'v_n_eq_merged_endpts', 'const_on_named6'):
g[k] += r[k]
for k in ('plus_minus_dist', 'minority_count'):
for kk, vv in r[k].items():
g[k][kk] = g[k].get(kk, 0) + vv
for sub in ('v_n_pos', 'minority_at'):
for kk, vv in r[sub].items():
g[sub][kk] = g[sub].get(kk, 0) + vv
def main(max_n=18, time_budget_per_n=1800):
print(f"Constancy obstruction analysis, n in [12, {max_n}]\n")
grand = {
'const_kb': 0, 'const_kc': 0, 'const_cap': 0,
'plus_minus_dist': {}, 'minority_count': {},
'v_n_pos': {'minority': 0, 'majority': 0, 'tie': 0},
'minority_at': {'v_n': 0, 'A_i': 0, 'A_i1': 0, 'A_i2': 0,
'A_i3': 0, 'A_i4': 0},
'v_n_eq_merged_endpts': 0,
'const_on_named6': 0,
}
grand_col = 0
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
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, ri = test_one(D)
n_col_n += ni
merge_into(grand, ri)
elapsed = time.time() - start
print(f"n={n}: {n_col_n} col., [{elapsed:.0f}s]")
sys.stdout.flush()
grand_col += n_col_n
print()
print("=" * 78)
print(f"Grand totals (n in [12, {max_n}], {grand_col} colourings)")
print(f"\n h constant on V(K_b): {grand['const_kb']}/{grand_col}")
print(f" h constant on V(K_c): {grand['const_kc']}/{grand_col}")
print(f" h constant on V(K_b) cap V(K_c): {grand['const_cap']}/{grand_col}")
print(f" h constant on {{v_n, A_0..A_4}}: "
f"{grand['const_on_named6']}/{grand_col}")
print(f" h(v_n) == h(A_{{i+3}}) == h(A_{{i+4}}): "
f"{grand['v_n_eq_merged_endpts']}/{grand_col}")
print(f"\n Minority count (= #vertices on V(K_b) cup V(K_c) with "
f"non-majority h) distribution:")
for k, v in sorted(grand['minority_count'].items()):
pct = 100 * v / max(1, grand_col)
print(f" {k:>3}: {v} ({pct:.2f}%)")
print(f"\n v_n status on V(K_b) cup V(K_c):")
print(f" in majority: {grand['v_n_pos']['majority']} "
f"({100*grand['v_n_pos']['majority']/max(1,grand_col):.2f}%)")
print(f" in minority: {grand['v_n_pos']['minority']} "
f"({100*grand['v_n_pos']['minority']/max(1,grand_col):.2f}%)")
print(f" tie: {grand['v_n_pos']['tie']} "
f"({100*grand['v_n_pos']['tie']/max(1,grand_col):.2f}%)")
print(f"\n How often each named vertex is in the minority:")
for name, c in grand['minority_at'].items():
print(f" {name:>5}: {c}/{grand_col} "
f"({100*c/max(1,grand_col):.2f}%)")
if __name__ == '__main__':
main()
+6 -5
View File
@@ -40,10 +40,11 @@
\newlabel{lem:both-kempe-constant}{{5.3}{11}}
\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces The two cases in the proof of Lemma\nonbreakingspace 5.2\hbox {}. Vertices $v_0, v_1$ are consecutive on the $\{a, b\}$-Kempe cycle $K$, joined by an edge $e$, with the lemma's hypothesis $h_\varphi (v_0) = h_\varphi (v_1) = +1$ --- so both vertices share the clockwise colour order $(a, b, c)$. \emph {Left (Case\nonbreakingspace A):} when $\varphi (e) = a$, the colour-$b$ edge at $v_0$ lies south of $e$ (on $\partial F_R$) and the colour-$b$ edge at $v_1$ lies north of $e$ (on $\partial F_L$); the two would-be witness edges are on opposite faces, so no face of $\setbox \z@ \hbox {\mathsurround \z@ $\textstyle G$}\mathaccent "0362{G}'_{v,i}$ contains both. \emph {Right (Case\nonbreakingspace B):} when $\varphi (e) = b$, the colour-$a$ edges at $v_0, v_1$ are likewise on opposite sides of $e$. In either case the clause-$(3)$ arc of Conjecture\nonbreakingspace 5.1\hbox {} cannot be realised at $e$.}}{12}{}\protected@file@percent }
\newlabel{fig:lemma-kempe-heawood}{{5}{12}}
\newlabel{rem:heawood-empirical}{{5.4}{13}}
\newlabel{rem:conj-3-6-empirical}{{5.5}{13}}
\newlabel{conj:face-monochromatic-pair-strengthened}{{5.6}{14}}
\newlabel{rem:conj-3-8-empirical}{{5.7}{14}}
\newlabel{cor:single-cycle-non-constancy}{{5.4}{13}}
\newlabel{rem:heawood-empirical}{{5.5}{13}}
\newlabel{rem:conj-3-6-empirical}{{5.6}{13}}
\newlabel{conj:face-monochromatic-pair-strengthened}{{5.7}{14}}
\newlabel{rem:conj-3-8-empirical}{{5.8}{14}}
\bibcite{Heawood1898}{1}
\bibcite{AH77a}{2}
\bibcite{AHK77}{3}
@@ -54,6 +55,6 @@
\newlabel{tocindent1}{17.77782pt}
\newlabel{tocindent2}{0pt}
\newlabel{tocindent3}{0pt}
\newlabel{rem:implication-4ct}{{5.8}{15}}
\newlabel{rem:implication-4ct}{{5.9}{15}}
\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{15}{}\protected@file@percent }
\gdef \@abspage@last{15}
+14 -12
View File
@@ -1,4 +1,4 @@
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 00:21
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 00:43
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
@@ -272,26 +272,28 @@ Package pdftex.def Info: fig_lemma_kempe_heawood.png used on input line 727.
LaTeX Warning: `h' float specifier changed to `ht'.
[11] [12 <./fig_lemma_kempe_heawood.png>]
Underfull \vbox (badness 10000) has occurred while \output is active []
Overfull \hbox (45.67143pt too wide) in paragraph at lines 834--848
[]
[]
[13]
Underfull \hbox (badness 1648) in paragraph at lines 917--923
\OT1/cmr/m/it/10 Remark \OT1/cmr/m/n/10 5.7\OT1/cmr/m/it/10 . \OT1/cmr/m/n/10 T
[13]
Underfull \hbox (badness 1648) in paragraph at lines 941--947
\OT1/cmr/m/it/10 Remark \OT1/cmr/m/n/10 5.8\OT1/cmr/m/it/10 . \OT1/cmr/m/n/10 T
he strength-ened con-jec-ture was tested on the same chord-
[]
Underfull \hbox (badness 1014) in paragraph at lines 917--923
\OT1/cmr/m/n/10 apex+Kempe colour-ings as Re-mark 5.5[]; for each colour-ing we
Underfull \hbox (badness 1014) in paragraph at lines 941--947
\OT1/cmr/m/n/10 apex+Kempe colour-ings as Re-mark 5.6[]; for each colour-ing we
sought any
[]
[14] [15] (./paper.aux) )
Here is how much of TeX's memory you used:
3110 strings out of 478268
44641 string characters out of 5846347
349419 words of memory out of 5000000
21142 multiletter control sequences out of 15000+600000
3111 strings out of 478268
44673 string characters out of 5846347
350430 words of memory out of 5000000
21143 multiletter control sequences out of 15000+600000
478386 words of font info for 63 fonts, out of 8000000 for 9000
1302 hyphenation exceptions out of 8191
69i,12n,76p,1047b,366s stack positions out of 10000i,1000n,20000p,200000b,200000s
@@ -319,7 +321,7 @@ cal/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb></usr/loc
al/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb></usr/local
/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmtt10.pfb></usr/local/
texlive/2022/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pfb>
Output written on paper.pdf (15 pages, 1085520 bytes).
Output written on paper.pdf (15 pages, 1086630 bytes).
PDF statistics:
195 PDF objects out of 1000 (max. 8388607)
108 compressed objects within 2 object streams
Binary file not shown.
+51 -27
View File
@@ -795,43 +795,67 @@ cycles, so its two endpoints --- which lie on $V(K_b) \cap V(K_c)$ ---
force the two constants to coincide.
\end{proof}
\begin{remark}[Empirical near-proof of Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle} via Lemma~\ref{lem:both-kempe-constant}]
\begin{corollary}[Per-cycle form]
\label{cor:single-cycle-non-constancy}
Let $G$, $\widehat{G}'_{v,i}$, $\varphi$ be as in
Lemma~\ref{lem:both-kempe-constant}, and let $K$ be either of the two
Kempe cycles of $\varphi$ through the merged edge. If $h_\varphi$ is not
constant on $V(K)$, then a triple $(F, e_1, e_2)$ satisfying
clauses~(1)--(3) of
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle} on
$(G, \widehat{G}'_{v,i}, \varphi)$ exists.
\end{corollary}
\begin{proof}
This is precisely the case analysis used to prove
Lemma~\ref{lem:both-kempe-constant}: applied to any consecutive pair of
vertices on $K$ with differing Heawood numbers, the construction in
that proof produces a clauses-(1)--(3) witness without ever needing to
inspect the other Kempe cycle.
\end{proof}
\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
The contrapositive of Lemma~\ref{lem:both-kempe-constant} reduces
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle} to
the following structural claim:
By Corollary~\ref{cor:single-cycle-non-constancy},
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}
follows from the (a~priori weaker) structural claim:
\emph{for every chord-apex+Kempe colouring $\varphi$ of every reduced
dual $\widehat{G}'_{v,i}$, $h_\varphi$ is not constant on
$V(K_b) \cup V(K_c)$.} We have verified this claim computationally on
all chord-apex+Kempe colourings of reduced duals with $|V(G)| \le 20$
(including the six Holton--McKay duals at $n = 21$ as a special case);
see \texttt{experiments/check\_heawood\_on\_kempe.py}.
dual $\widehat{G}'_{v,i}$, $h_\varphi$ is not constant on $V(K_b)$
(equivalently, not constant on $V(K_c)$).} We have verified this claim
computationally on all chord-apex+Kempe colourings of reduced duals
with $|V(G)| \le 20$ (including the six Holton--McKay duals at
$n = 21$ as a special case); see
\texttt{experiments/check\_heawood\_on\_kempe.py} and
\texttt{experiments/check\_constancy\_obstruction.py}.
\begin{center}
\small
\renewcommand{\arraystretch}{1.15}
\begin{tabular}{r|r|r|l}
$n$ & \#col.\ tested & \#non-constant on $V(K_b)\cup V(K_c)$ & status \\
\begin{tabular}{r|r|r|r|l}
$n$ & \#col.\ tested
& \#non-const. on $V(K_b)$
& \#non-const. on $V(K_c)$ & status \\
\hline
$14$ & $216$ & $216$ & all non-constant \\
$16$ & $864$ & $864$ & all non-constant \\
$17$ & $4{,}650$ & $4{,}650$ & all non-constant \\
$18$ & $8{,}070$ & $8{,}070$ & all non-constant \\
$19$ & $21{,}138$ & $21{,}138$ & all non-constant \\
$20$ & $107{,}874$ & $107{,}874$ & all non-constant \\
$14$ & $216$ & $216$ & $216$ & all non-constant \\
$16$ & $864$ & $864$ & $864$ & all non-constant \\
$17$ & $4{,}650$ & $4{,}650$ & $4{,}650$ & all non-constant \\
$18$ & $8{,}070$ & $8{,}070$ & $8{,}070$ & all non-constant \\
$19$ & $21{,}138$ & $21{,}138$ & $21{,}138$ & all non-constant \\
$20$ & $107{,}874$ & $107{,}874$ & $107{,}874$ & all non-constant \\
\hline
total ($n \le 20$) & $142{,}812$ & $142{,}812$ & \\
total ($n \le 20$) & $142{,}812$ & $142{,}812$ & $142{,}812$ & \\
\end{tabular}
\end{center}
\noindent Since $h_\varphi$ on $V(K_b) \cup V(K_c)$ was non-constant in
every tested colouring, Lemma~\ref{lem:both-kempe-constant}'s
contrapositive supplies a Conjecture-\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}
witness in each case --- giving an empirical near-proof of the
conjecture for $|V(G)| \le 20$ that is independent of (and consistent
with) the direct witness-search check of
Remark~\ref{rem:conj-3-6-empirical}. A structural proof of
non-constancy on $V(K_b) \cup V(K_c)$ would convert this into a proof
of Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}
\noindent In particular, $h_\varphi$ is non-constant on $V(K_b)$ alone
in every tested colouring (and likewise on $V(K_c)$); by
Corollary~\ref{cor:single-cycle-non-constancy} each such colouring
admits a Conjecture-\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}
witness. This gives an empirical near-proof of the conjecture for
$|V(G)| \le 20$ independent of (and consistent with) the direct
witness-search check of Remark~\ref{rem:conj-3-6-empirical}. A
structural proof of non-constancy on $V(K_b)$ (or on $V(K_c)$) would
convert this into a proof of
Conjecture~\ref{conj:face-monochromatic-pair-on-merged-kempe-cycle}
proper.
\end{remark}