diff --git a/Makefile b/Makefile index 7367220..00cbba2 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ build: cabal run site -- build pagefind --site _site @if [ -d .venv ]; then \ - uv run python tools/embed.py || echo "Warning: embedding failed — data/similar-links.json not updated (build continues)"; \ + HF_HUB_DISABLE_IMPLICIT_TOKEN=1 uv run python tools/embed.py || echo "Warning: embedding failed — data/similar-links.json not updated (build continues)"; \ else \ echo "Embedding skipped: run 'uv sync' to enable similar-links (build continues)"; \ fi diff --git a/build/Now.hs b/build/Now.hs index 2381b42..d5a72e0 100644 --- a/build/Now.hs +++ b/build/Now.hs @@ -88,7 +88,8 @@ sectionOrder = nub . map neSection -- ranking next-to-the-top. statusRanks :: [(String, Int)] statusRanks = - [ ("in-review", 1) + [ ("accepted", 0) + , ("in-review", 1) , ("revising", 2) , ("drafting", 3) , ("building", 4) diff --git a/build/Patterns.hs b/build/Patterns.hs index d6138c8..20b41fd 100644 --- a/build/Patterns.hs +++ b/build/Patterns.hs @@ -19,6 +19,7 @@ module Patterns , photographyPattern , allPhotoEntries , standalonePagesPattern + , pageCollectionPattern -- * Aggregated patterns , allWritings -- essays + blog + poetry + fiction , allContent -- everything that backlinks should index @@ -32,11 +33,12 @@ import Hakyll -- Per-section -- --------------------------------------------------------------------------- --- | All published essays — flat files and directory-based (with co-located --- assets). Drafts under @content/drafts/essays/**@ are intentionally NOT --- included; 'Site.rules' unions them in conditionally when @SITE_ENV=dev@. +-- | All published essays — flat files, directory-based essays, and entries +-- inside one-level collection directories. essayPattern :: Pattern -essayPattern = "content/essays/*.md" .||. "content/essays/*/index.md" +essayPattern = + "content/essays/*.md" + .||. "content/essays/*/*.md" -- | In-progress essay drafts. Matches the flat and directory forms under -- @content/drafts/essays/@. Only 'Site.rules' consumes this, gated on @@ -48,10 +50,12 @@ draftEssayPattern = "content/drafts/essays/*.md" .||. "content/drafts/essays/*/index.md" --- | All blog posts. Currently flat-only; co-located blog assets would --- require a directory variant analogous to 'essayPattern'. +-- | All blog posts: flat posts plus entries inside collection directories. +-- Collection index pages are landing pages and compile separately. blogPattern :: Pattern -blogPattern = "content/blog/*.md" +blogPattern = + "content/blog/*.md" + .||. ("content/blog/*/*.md" .&&. complement "content/blog/*/index.md") -- | All poetry: flat poems plus collection poems, excluding collection -- index pages (which are landing pages, not poems). @@ -60,9 +64,12 @@ poetryPattern = "content/poetry/*.md" .||. ("content/poetry/*/*.md" .&&. complement "content/poetry/*/index.md") --- | All fiction. Currently flat-only. +-- | All fiction: flat stories plus entries inside collection directories. +-- Collection index pages are landing pages and compile separately. fictionPattern :: Pattern -fictionPattern = "content/fiction/*.md" +fictionPattern = + "content/fiction/*.md" + .||. ("content/fiction/*/*.md" .&&. complement "content/fiction/*/index.md") -- | Music compositions (landing pages live at @content/music//index.md@). musicPattern :: Pattern @@ -106,12 +113,34 @@ allPhotoEntries = photographyPattern .||. ("content/photography/*/*.md" .&&. complement "content/photography/*/index.md") --- | Top-level standalone pages (about, colophon, current, gpg, …) and --- the curated routing pages under @content/cv/@ (which render with the --- same @templates/page.html@ pipeline and need the same backlink and --- content-indexing treatment). +-- | Page collection entries live one directory below @content/@. Known +-- section directories are excluded so their files retain specialized +-- compilers and routes. +pageCollectionPattern :: Pattern +pageCollectionPattern = + "content/*/*.md" .&&. complement reservedSectionPages + where + reservedSectionPages = + "content/blog/*.md" + .||. "content/cv/*.md" + .||. "content/drafts/*.md" + .||. "content/essays/*.md" + .||. "content/fiction/*.md" + .||. "content/me/*.md" + .||. "content/memento-mori/*.md" + .||. "content/music/*.md" + .||. "content/photography/*.md" + .||. "content/poetry/*.md" + .||. "content/scripts/*.md" + .||. "content/tag-meta/*.md" + +-- | Top-level standalone pages, curated CV routing pages, and generic page +-- collections. standalonePagesPattern :: Pattern -standalonePagesPattern = "content/*.md" .||. "content/cv/*.md" +standalonePagesPattern = + "content/*.md" + .||. "content/cv/*.md" + .||. pageCollectionPattern -- --------------------------------------------------------------------------- -- Aggregations diff --git a/build/Site.hs b/build/Site.hs index def3d9e..f061984 100644 --- a/build/Site.hs +++ b/build/Site.hs @@ -365,6 +365,16 @@ rules = do >>= loadAndApplyTemplate "templates/default.html" pageCtx >>= relativizeUrls + -- Generic page collections + -- (content//.md → /.html). + match P.pageCollectionPattern $ do + route $ stripPrefixRoute "content/" + `composeRoutes` setExtension "html" + compile $ pageCompiler + >>= loadAndApplyTemplate "templates/page.html" pageCtx + >>= loadAndApplyTemplate "templates/default.html" pageCtx + >>= relativizeUrls + -- --------------------------------------------------------------------------- -- CV routing pages (content/cv/*.md → /cv//). -- These are narrative overlays pointing into the library; they render @@ -391,20 +401,23 @@ rules = do -- --------------------------------------------------------------------------- match allEssays $ do route $ customRoute $ \ident -> - let fp = toFilePath ident - fname = takeFileName fp - isIndex = fname == "index.md" - isDraft = "content/drafts/essays/" `isPrefixOf` fp + let fp = toFilePath ident + fname = takeFileName fp + isIndex = fname == "index.md" + isDraft = "content/drafts/essays/" `isPrefixOf` fp stripContent = fromMaybe fp (stripPrefix "content/" fp) + isNested = takeDirectory fp /= "content/essays" in case (isDraft, isIndex) of -- content/drafts/essays/slug/index.md → drafts/essays/slug/index.html (True, True) -> replaceExtension stripContent "html" - -- content/drafts/essays/foo.md → drafts/essays/foo.html + -- content/drafts/essays/foo.md → drafts/essays/foo.html (True, False) -> "drafts/essays/" ++ replaceExtension fname "html" - -- content/essays/slug/index.md → essays/slug/index.html - (False, True) -> replaceExtension stripContent "html" - -- content/essays/foo.md → essays/foo.html + -- Published directory essays and collection entries retain + -- their directory path below content/. + (False, _) | isNested -> replaceExtension stripContent "html" + -- content/essays/foo.md → essays/foo.html (False, False) -> "essays/" ++ replaceExtension fname "html" + (False, True) -> replaceExtension stripContent "html" compile $ essayCompiler >>= saveSnapshot "content" >>= loadAndApplyTemplate "templates/essay.html" essayCtx @@ -415,8 +428,7 @@ rules = do -- Build-time dimension sidecars are excluded; they're consumed by -- Filters/Images.hs at compile time, not shipped. match ("content/essays/**" - .&&. complement "content/essays/*.md" - .&&. complement "content/essays/*/index.md" + .&&. complement P.essayPattern .&&. complement "content/essays/**/*.dims.yaml") $ do route $ stripPrefixRoute "content/" compile copyFileCompiler @@ -432,7 +444,7 @@ rules = do -- --------------------------------------------------------------------------- -- Blog posts -- --------------------------------------------------------------------------- - match "content/blog/*.md" $ do + match P.blogPattern $ do route $ stripPrefixRoute "content/" `composeRoutes` setExtension "html" compile $ postCompiler @@ -441,6 +453,15 @@ rules = do >>= loadAndApplyTemplate "templates/default.html" postCtx >>= relativizeUrls + -- Blog collection index pages + -- (content/blog//index.md → blog//index.html). + match "content/blog/*/index.md" $ do + route $ stripPrefixRoute "content/" + `composeRoutes` setExtension "html" + compile $ pageCompiler + >>= loadAndApplyTemplate "templates/default.html" pageCtx + >>= relativizeUrls + -- --------------------------------------------------------------------------- -- Poetry -- --------------------------------------------------------------------------- @@ -468,7 +489,7 @@ rules = do -- --------------------------------------------------------------------------- -- Fiction -- --------------------------------------------------------------------------- - match "content/fiction/*.md" $ do + match P.fictionPattern $ do route $ stripPrefixRoute "content/" `composeRoutes` setExtension "html" compile $ fictionCompiler @@ -477,6 +498,15 @@ rules = do >>= loadAndApplyTemplate "templates/default.html" fictionCtx >>= relativizeUrls + -- Fiction collection index pages + -- (content/fiction//index.md → fiction//index.html). + match "content/fiction/*/index.md" $ do + route $ stripPrefixRoute "content/" + `composeRoutes` setExtension "html" + compile $ pageCompiler + >>= loadAndApplyTemplate "templates/default.html" pageCtx + >>= relativizeUrls + -- --------------------------------------------------------------------------- -- Music — catalog index -- --------------------------------------------------------------------------- diff --git a/build/Stats.hs b/build/Stats.hs index 8a42d2f..89859c1 100644 --- a/build/Stats.hs +++ b/build/Stats.hs @@ -820,9 +820,9 @@ statsRules tags = do -- Load all content items -- ---------------------------------------------------------------- essays <- loadAll (P.essayPattern .&&. hasNoVersion) - posts <- loadAll ("content/blog/*.md" .&&. hasNoVersion) - poems <- loadAll ("content/poetry/*.md" .&&. hasNoVersion) - fiction <- loadAll ("content/fiction/*.md" .&&. hasNoVersion) + posts <- loadAll (P.blogPattern .&&. hasNoVersion) + poems <- loadAll (P.poetryPattern .&&. hasNoVersion) + fiction <- loadAll (P.fictionPattern .&&. hasNoVersion) comps <- loadAll ("content/music/*/index.md" .&&. hasNoVersion) -- ---------------------------------------------------------------- @@ -1020,9 +1020,9 @@ statsRules tags = do _ <- load (fromFilePath "data/build-stamp.txt") :: Compiler (Item String) essays <- loadAll (P.essayPattern .&&. hasNoVersion) - posts <- loadAll ("content/blog/*.md" .&&. hasNoVersion) - poems <- loadAll ("content/poetry/*.md" .&&. hasNoVersion) - fiction <- loadAll ("content/fiction/*.md" .&&. hasNoVersion) + posts <- loadAll (P.blogPattern .&&. hasNoVersion) + poems <- loadAll (P.poetryPattern .&&. hasNoVersion) + fiction <- loadAll (P.fictionPattern .&&. hasNoVersion) comps <- loadAll ("content/music/*/index.md" .&&. hasNoVersion) essayWCs <- mapM loadWC essays diff --git a/cabal.project.freeze b/cabal.project.freeze index a7ad32d..b56f3d5 100644 --- a/cabal.project.freeze +++ b/cabal.project.freeze @@ -2,12 +2,12 @@ active-repositories: hackage.haskell.org:merge constraints: any.Glob ==0.10.2, any.HUnit ==1.6.2.0, any.JuicyPixels ==3.3.9, - any.OneTuple ==0.4.2.1, + any.OneTuple ==0.4.3, any.Only ==0.1, any.QuickCheck ==2.15.0.1, any.StateVar ==1.2.2, any.aeson ==2.2.2.0, - any.aeson-pretty ==0.8.10, + any.aeson-pretty ==0.8.11, any.ansi-terminal ==1.1, any.ansi-terminal-types ==1.1, any.appar ==0.1.8, @@ -18,17 +18,17 @@ constraints: any.Glob ==0.10.2, any.assoc ==1.1.1, any.async ==2.2.6, any.attoparsec ==0.14.4, - any.attoparsec-aeson ==2.2.0.1, + any.attoparsec-aeson ==2.2.2.0, any.auto-update ==0.1.6, any.base ==4.18.2.1, any.base-compat ==0.14.1, - any.base-orphans ==0.9.3, + any.base-orphans ==0.9.4, any.base16-bytestring ==1.0.2.0, any.base64-bytestring ==1.2.1.0, any.basement ==0.0.16, any.bifunctors ==5.6.3, any.binary ==0.8.9.1, - any.bitvec ==1.1.5.0, + any.bitvec ==1.1.6.0, any.blaze-builder ==0.4.4.1, any.blaze-html ==0.9.2.0, any.blaze-markup ==0.8.3.0, @@ -41,23 +41,24 @@ constraints: any.Glob ==0.10.2, any.cborg ==0.2.10.0, any.cereal ==0.5.8.3, any.character-ps ==0.1, - any.citeproc ==0.8.1.1, + any.citeproc ==0.8.1.2, any.colour ==2.3.7, any.commonmark ==0.2.6.1, - any.commonmark-extensions ==0.2.5.6, - any.commonmark-pandoc ==0.2.2.3, + any.commonmark-extensions ==0.2.6, + any.commonmark-pandoc ==0.2.3, any.comonad ==5.0.10, any.conduit ==1.3.6.1, any.conduit-extra ==1.3.8, any.containers ==0.6.7, any.contravariant ==1.5.6, any.cookie ==0.5.0, - any.crypton ==1.0.4, + any.cryptohash-md5 ==0.11.101.0, + any.crypton ==1.0.5, any.crypton-connection ==0.4.5, any.crypton-socks ==0.6.2, any.crypton-x509 ==1.7.7, - any.crypton-x509-store ==1.6.12, - any.crypton-x509-system ==1.6.7, + any.crypton-x509-store ==1.6.14, + any.crypton-x509-system ==1.6.8, any.crypton-x509-validation ==1.6.14, any.data-default ==0.7.1.3, any.data-default-class ==0.1.2.2, @@ -71,10 +72,10 @@ constraints: any.Glob ==0.10.2, any.distributive ==0.6.3, any.djot ==0.1.2.4, any.dlist ==1.0, - any.doclayout ==0.5.0.1, + any.doclayout ==0.5.0.2, any.doctemplates ==0.11.0.1, any.easy-file ==0.2.5, - any.emojis ==0.1.4.1, + any.emojis ==0.1.5, any.exceptions ==0.10.7, any.fast-logger ==3.2.4, any.file-embed ==0.0.16.0, @@ -99,8 +100,8 @@ constraints: any.Glob ==0.10.2, http-conduit +aeson, any.http-date ==0.0.11, any.http-types ==0.12.4, - any.http2 ==5.1.2, - any.indexed-traversable ==0.1.4, + any.http2 ==5.1.4, + any.indexed-traversable ==0.1.5, any.indexed-traversable-instances ==0.1.2.1, any.integer-conversion ==0.1.1, any.integer-gmp ==1.1, @@ -117,20 +118,20 @@ constraints: any.Glob ==0.10.2, any.mtl ==2.3.1, any.network ==3.1.4.0, any.network-byte-order ==0.1.7, - any.network-control ==0.1.3, + any.network-control ==0.1.4, any.network-uri ==2.6.4.2, any.old-locale ==1.0.0.7, - any.old-time ==1.1.0.5, + any.old-time ==1.1.1.0, any.optparse-applicative ==0.18.1.0, any.ordered-containers ==0.2.4, - any.os-string ==2.0.10, - any.pandoc ==3.6, - any.pandoc-types ==1.23.1, + any.os-string ==2.0.11, + any.pandoc ==3.6.1, + any.pandoc-types ==1.23.1.2, any.parsec ==3.1.16.1, any.pem ==0.2.4, any.pretty ==1.1.3.6, any.pretty-show ==1.10, - any.prettyprinter ==1.7.1, + any.prettyprinter ==1.7.2, any.prettyprinter-ansi-terminal ==1.1.4, any.primitive ==0.9.1.0, any.process ==1.6.19.0, @@ -139,7 +140,7 @@ constraints: any.Glob ==0.10.2, any.recv ==0.1.1, any.regex-base ==0.94.0.3, any.regex-tdfa ==1.3.2.5, - any.resourcet ==1.2.6, + any.resourcet ==1.3.0, any.rts ==1.0.2, any.safe ==0.3.21, any.safe-exceptions ==0.1.7.4, @@ -148,23 +149,23 @@ constraints: any.Glob ==0.10.2, any.semigroupoids ==6.0.2, any.serialise ==0.2.6.1, any.simple-sendfile ==0.2.32, - any.skylighting ==0.14.4, - any.skylighting-core ==0.14.4, + any.skylighting ==0.14.5, + any.skylighting-core ==0.14.5, any.skylighting-format-ansi ==0.1, - any.skylighting-format-blaze-html ==0.1.1.3, + any.skylighting-format-blaze-html ==0.1.2, any.skylighting-format-context ==0.1.0.2, any.skylighting-format-latex ==0.1, any.split ==0.2.5, - any.splitmix ==0.1.3, + any.splitmix ==0.1.3.1, any.stm ==2.5.1.0, any.streaming-commons ==0.2.3.1, any.strict ==0.5.1, - any.syb ==0.7.3, - any.tagged ==0.8.9, + any.syb ==0.7.4, + any.tagged ==0.8.10, any.tagsoup ==0.14.8, any.template-haskell ==2.20.0.0, any.temporary ==1.3, - any.texmath ==0.12.8.12, + any.texmath ==0.12.8.13, any.text ==2.0.2, any.text-conversions ==0.3.1.1, any.text-icu ==0.8.0.5, @@ -187,8 +188,8 @@ constraints: any.Glob ==0.10.2, any.typed-process ==0.2.13.0, any.typst ==0.6.1, any.typst-symbols ==0.1.7, - any.unicode-collation ==0.1.3.6, - any.unicode-data ==0.6.0, + any.unicode-collation ==0.1.3.7, + any.unicode-data ==0.7.0, any.unicode-transforms ==0.4.0.1, any.uniplate ==1.6.13, any.unix ==2.8.4.0, @@ -196,7 +197,7 @@ constraints: any.Glob ==0.10.2, any.unix-time ==0.4.17, any.unliftio ==0.2.25.1, any.unliftio-core ==0.2.1.0, - any.unordered-containers ==0.2.20.1, + any.unordered-containers ==0.2.21, any.utf8-string ==1.0.2, any.uuid-types ==1.0.6.1, any.vault ==0.3.1.6, @@ -204,11 +205,11 @@ constraints: any.Glob ==0.10.2, any.vector-algorithms ==0.9.1.0, any.vector-stream ==0.1.0.1, any.wai ==3.2.4, - any.wai-app-static ==3.1.9, + any.wai-app-static ==3.1.9.1, any.wai-extra ==3.1.18, any.wai-logger ==2.5.0, any.warp ==3.4.0, - any.witherable ==0.4.2, + any.witherable ==0.5, any.word8 ==0.1.3, any.xml ==1.3.14, any.xml-conduit ==1.9.1.4, diff --git a/data/ball-occupation-paper.bib b/data/ball-occupation-paper.bib new file mode 100644 index 0000000..85e82a4 --- /dev/null +++ b/data/ball-occupation-paper.bib @@ -0,0 +1,126 @@ +% ── Foundational papers (cops-and-robbers) ────────────────────────────────── + +@article{AignerFromme, + author = {Aigner, M. and Fromme, M.}, + title = {A game of cops and robbers}, + journal = {Discrete Applied Mathematics}, + volume = {8}, + year = {1984}, + pages = {1--12}, +} + +% ── Meyniel's conjecture: bounds and partial progress ─────────────────────── + +@article{LuPeng, + author = {Lu, L. and Peng, X.}, + title = {On {Meyniel}'s conjecture of the cop number}, + journal = {Journal of Graph Theory}, + volume = {71}, + number = {2}, + year = {2012}, + pages = {192--205}, +} + +@article{ScottSudakov, + author = {Scott, A. and Sudakov, B.}, + title = {A bound for the cops and robbers problem}, + journal = {SIAM Journal on Discrete Mathematics}, + volume = {25}, + number = {3}, + year = {2011}, + pages = {1438--1442}, +} + +@article{BoseEsperetHodorJoretMicekRambaud, + author = {Bose, P. and Esperet, L. and Hodor, J. and Joret, G. and Micek, P. and Rambaud, C.}, + title = {Cops and robber in graphs with bounded vertex cover number}, + journal = {arXiv:2602.07435}, + year = {2026}, +} + +@article{BradshawHosseiniMoharStacho, + author = {Bradshaw, P. and Hosseini, S. A. and Mohar, B. and Stacho, L.}, + title = {On the cop number of graphs of high girth}, + journal = {Journal of Graph Theory}, + volume = {102}, + year = {2023}, + pages = {15--34}, + note = {arXiv:2005.10849}, +} + +@misc{Clow, + author = {Clow, A.}, + title = {Expanders satisfy the weak {Meyniel} conjecture}, + year = {2023}, + note = {Withdrawn preprint, arXiv:2311.13792}, +} + +@article{HMG, + author = {Hosseini, S. A. and Mohar, B. and {Gonzalez Hermosillo de la Maza}, S.}, + title = {{Meyniel}'s conjecture on graphs of bounded degree}, + journal = {Journal of Graph Theory}, + volume = {97}, + year = {2021}, + pages = {401--407}, + note = {arXiv:1912.06957}, +} + +@article{PralatWormald, + author = {Pra{\l}at, P. and Wormald, N.}, + title = {{Meyniel}'s conjecture holds for random graphs}, + journal = {Random Structures \& Algorithms}, + volume = {48}, + number = {2}, + year = {2016}, + pages = {396--421}, + note = {arXiv:1301.2841}, +} + +% ── Expansion, isoperimetry, and product/replacement structures ──────────── + +@article{BollobasKunLeader, + author = {Bollob\'as, B. and Kun, G. and Leader, I.}, + title = {Cops and robbers in a random graph}, + journal = {Journal of Combinatorial Theory, Series B}, + volume = {103}, + year = {2013}, + pages = {226--236}, +} + +@article{BollobasLeader, + author = {Bollob\'as, B. and Leader, I.}, + title = {An isoperimetric inequality on the discrete torus}, + journal = {SIAM Journal on Discrete Mathematics}, + volume = {3}, + year = {1990}, + pages = {32--37}, +} + +@article{ReingoldVadhanWigderson, + author = {Reingold, O. and Vadhan, S. and Wigderson, A.}, + title = {Entropy waves, the zig-zag graph product, and new constant-degree expanders}, + journal = {Annals of Mathematics}, + volume = {155}, + year = {2002}, + pages = {157--187}, +} + +% ── Cop number on tori and products ───────────────────────────────────────── + +@article{Lehner, + author = {Lehner, F.}, + title = {On the cop number of toroidal graphs}, + journal = {Journal of Combinatorial Theory, Series B}, + volume = {151}, + year = {2021}, + pages = {250--262}, +} + +@article{NeufeldNowakowski, + author = {Neufeld, S. and Nowakowski, R.}, + title = {A game of cops and robbers played on products of graphs}, + journal = {Discrete Mathematics}, + volume = {186}, + year = {1998}, + pages = {253--268}, +} diff --git a/data/growing-radius-domination-preprint.bib b/data/growing-radius-domination-preprint.bib new file mode 100644 index 0000000..1c82a34 --- /dev/null +++ b/data/growing-radius-domination-preprint.bib @@ -0,0 +1,157 @@ +% ── Cops-and-robbers background ───────────────────────────────────────────── + +@article{AignerFromme, + author = {Aigner, M. and Fromme, M.}, + title = {A game of cops and robbers}, + journal = {Discrete Applied Mathematics}, + volume = {8}, + number = {1}, + year = {1984}, + pages = {1--12}, +} + +@article{LuPeng, + author = {Lu, L. and Peng, X.}, + title = {On {Meyniel}'s conjecture of the cop number}, + journal = {Journal of Graph Theory}, + volume = {71}, + number = {2}, + year = {2012}, + pages = {192--205}, +} + +@article{ScottSudakov, + author = {Scott, A. and Sudakov, B.}, + title = {A bound for the cops and robbers problem}, + journal = {SIAM Journal on Discrete Mathematics}, + volume = {25}, + number = {3}, + year = {2011}, + pages = {1438--1442}, +} + +@article{PralatWormald, + author = {Pra{\l}at, P. and Wormald, N.}, + title = {{Meyniel}'s conjecture holds for random graphs}, + journal = {Random Structures \& Algorithms}, + volume = {48}, + number = {2}, + year = {2016}, + pages = {396--421}, +} + +@article{PralatWormaldRegular, + author = {Pra{\l}at, P. and Wormald, N.}, + title = {{Meyniel}'s conjecture holds for random $d$-regular graphs}, + journal = {Random Structures \& Algorithms}, + volume = {55}, + number = {3}, + year = {2019}, + pages = {719--741}, +} + +@misc{NeuwirthBranchCapture, + author = {Neuwirth, Levi}, + title = {Branch-tube persistence and static coverage in tree-ball geometry}, + note = {Preprint}, + year = {2026}, + url = {https://levineuwirth.org/essays/branch-based-local-capture-in-tree-balls/index.html}, +} + +% ── Random-regular / configuration-model background ──────────────────────── + +@incollection{Wormald, + author = {Wormald, N. C.}, + title = {Models of random regular graphs}, + booktitle = {Surveys in Combinatorics, 1999}, + series = {London Mathematical Society Lecture Note Series}, + volume = {267}, + publisher = {Cambridge University Press}, + year = {1999}, + pages = {239--298}, +} + +@article{Janson, + author = {Janson, S.}, + title = {The probability that a random multigraph is simple}, + journal = {Combinatorics, Probability and Computing}, + volume = {18}, + year = {2009}, + pages = {205--225}, +} + +% ── Domination in regular / random graphs ─────────────────────────────────── + +@book{CohenHonkalaLitsynLobstein, + author = {Cohen, G. and Honkala, I. and Litsyn, S. and Lobstein, A.}, + title = {Covering Codes}, + series = {North-Holland Mathematical Library}, + volume = {54}, + publisher = {Elsevier}, + year = {1997}, +} + +@article{Duckworth, + author = {Duckworth, W.}, + title = {Randomized greedy algorithms for finding small $k$-dominating sets of regular graphs}, + journal = {Random Structures \& Algorithms}, + volume = {27}, + year = {2005}, + pages = {401--412}, +} + +@article{DuckworthWormald, + author = {Duckworth, W. and Wormald, N. C.}, + title = {On the independent domination number of random regular graphs}, + journal = {Combinatorics, Probability and Computing}, + volume = {15}, + year = {2006}, + pages = {513--522}, +} + +@article{CutlerRadcliffe, + author = {Cutler, J. and Radcliffe, A. J.}, + title = {Counting dominating sets and related structures in graphs}, + journal = {Discrete Mathematics}, + volume = {339}, + year = {2016}, + pages = {1593--1599}, +} + +@article{GlebovLiebenauSzabo, + author = {Glebov, R. and Liebenau, A. and Szab{\'o}, T.}, + title = {On the concentration of the domination number of the random graph}, + journal = {SIAM Journal on Discrete Mathematics}, + volume = {29}, + year = {2015}, + pages = {1186--1206}, +} + +% ── Statistical-mechanics / message-passing antecedents ───────────────────── + +@article{ZhaoHabibullaZhou, + author = {Zhao, J.-H. and Habibulla, Y. and Zhou, H.-J.}, + title = {Statistical mechanics of the minimum dominating set problem}, + journal = {Journal of Statistical Physics}, + volume = {159}, + year = {2015}, + pages = {1154--1174}, +} + +@misc{HabibullaQin, + author = {Habibulla, Y. and Qin, S.-m.}, + title = {Two-distance minimal dominating set problem studied by statistical mechanics and simulated annealing}, + howpublished = {arXiv:1910.07933}, + year = {2019}, +} + +% ── Variational-analysis background ───────────────────────────────────────── + +@book{RockafellarWets, + author = {Rockafellar, R. T. and Wets, R. J.-B.}, + title = {Variational Analysis}, + series = {Grundlehren der mathematischen Wissenschaften}, + volume = {317}, + publisher = {Springer}, + year = {1998}, +} diff --git a/data/now.yaml b/data/now.yaml index 3fc4432..8a36232 100644 --- a/data/now.yaml +++ b/data/now.yaml @@ -9,9 +9,11 @@ # - title : display name # - section : free-form section key (research, engineering, …); # sections render in first-appearance order -# - status : in-review | revising | drafting | building | early-stage | -# paused. Free-form, but the listed values are the canonical -# ladder (closest-to-shipping → furthest) and have CSS accents. +# - status : accepted | in-review | revising | drafting | building | +# early-stage | paused. Free-form, but the listed values are +# the canonical ladder (closest-to-shipping → furthest) and +# have CSS accents. "accepted" is for a paper/talk past review +# and locked in for publication or presentation. # - updated : YYYY-MM-DD when this entry last moved (NOT page-stamp) # - link : optional URL (artifact, preprint, repo, etc.) # - note : optional one-sentence what's-happening-now line @@ -29,22 +31,37 @@ # Sorted newest-first at render time. Curate by hand — items don't # auto-prune. Move things off the list when they stop earning the slot. -last-updated: 2026-05-06 +last-updated: 2026-07-24 entries: - - title: "Branch-Based Local Capture in Tree-Ball Geometry" + - title: "MARS V: Zero-Knowledge Proofs for LLM Verification" section: research - status: in-review - updated: 2026-05-06 - link: /essays/branch-based-local-capture-in-tree-balls/ - note: "First mathematics preprint. Sharp positive and negative results for local team-chase in d-regular tree-balls. arXiv submission pending." + status: building + updated: 2026-07-10 + priority: 1 + link: https://caish.org/mars + note: "MARS V fellowship at the Cambridge AI Safety Hub, mentored by James Petrie (Future of Life Institute). Zero-knowledge proofs for cryptographic verification of claims about LLM training, inference, and deployment — a mathematically dense, information-theoretic approach. July–October 2026; public write-up expected October 2026." - - title: "Order-Invariant ICD-10-CM Embedding (JAMA submission)" + - title: "Branch-Tube Persistence and Static Coverage in Tree-Ball Geometry" section: research status: in-review - updated: 2026-04-10 + updated: 2026-07-21 + link: /essays/branch-based-local-capture-in-tree-balls/ + note: "Mathematics preprint on path-tube persistence, exhaustive static coverage, conditional sampling thresholds, and information loss in d-regular tree-balls." + + - title: "The Annealed Critical Window for Growing-Radius Domination in Random Regular Graphs" + section: research + status: in-review + updated: 2026-07-24 + link: /essays/near-critical-growing-radius-domination.html + note: "Mathematics preprint determining the bounded annealed critical window for growing-radius domination in random regular graphs — its universal scaling function and a scalar coupon-root asymptotic expansion — resolving what an earlier near-critical version left open." + + - title: "Order-Invariant ICD-10-CM Embedding (JAMIA submission)" + section: research + status: in-review + updated: 2026-07-10 link: /essays/beyond-comorbidity-indices/ - note: "Under review at JAMA Network Open. Calculator deployed at levineuwirth.github.io/icd_embeddings." + note: "Under review at JAMIA (Journal of the American Medical Informatics Association), after moving from JAMA Network Open. Calculator deployed at levineuwirth.github.io/icd_embeddings." - title: "Semantic-embeddings citation work" section: research @@ -69,15 +86,15 @@ entries: - title: "Magic: The Gathering reinforcement learning" section: research - status: early-stage - updated: 2026-04-15 - note: "Early-stage RL on Brown's OSCAR HPC cluster; expected late 2026." + status: building + updated: 2026-07-10 + note: "Reinforcement-learning agent under active development on Brown's OSCAR HPC cluster; expected late 2026." - title: "CHASE 2026 conference submission" section: research - status: in-review - updated: 2026-04-05 - note: "IEEE/ACM Conference on Connected Health (CHASE), August 2026, in review." + status: accepted + updated: 2026-07-10 + note: "Accepted to the IEEE/ACM Conference on Connected Health (CHASE); presentation August 2026." - title: "Levshell" section: engineering @@ -88,8 +105,8 @@ entries: - title: "Pmacs" section: engineering status: building - updated: 2026-04-20 - note: "Emacs-inspired IDE in Zig with first-class parallelism." + updated: 2026-07-10 + note: "Emacs-inspired IDE in Rust with first-class parallelism; migrated from an earlier Zig prototype." shipped: - title: "Where Does SIMD Help Post-Quantum Cryptography?" diff --git a/paper/ball-occupation-under-coarse-projections.tex b/paper/ball-occupation-under-coarse-projections.tex new file mode 100644 index 0000000..2dd3b8c --- /dev/null +++ b/paper/ball-occupation-under-coarse-projections.tex @@ -0,0 +1,1099 @@ +\documentclass[11pt]{amsart} + +\usepackage[margin=1in]{geometry} +\usepackage{amsmath,amssymb,amsthm,mathtools} +\usepackage{microtype} +\usepackage{booktabs} +\usepackage{enumitem} +\usepackage{xcolor} +\usepackage{hyperref} +\usepackage[nameinlink,capitalize,noabbrev]{cleveref} + +\newtheorem{theorem}{Theorem}[section] +\newtheorem{proposition}[theorem]{Proposition} +\newtheorem{corollary}[theorem]{Corollary} +\newtheorem{lemma}[theorem]{Lemma} +\theoremstyle{definition} +\newtheorem{definition}[theorem]{Definition} +\newtheorem{remark}[theorem]{Remark} + +\newcommand{\cnum}{c} +\newcommand{\dist}{\operatorname{dist}} +\newcommand{\diam}{\operatorname{diam}} +\newcommand{\eps}{\varepsilon} +\newcommand{\whp}{\text{with high probability}} +\newcommand{\Occ}{\operatorname{Occ}} +\newcommand{\iotae}{\iota} + +\hypersetup{ + colorlinks=true, + linkcolor=blue!50!black, + citecolor=blue!50!black, + urlcolor=blue!50!black, + pdftitle={Ball-Occupation Certificates under Coarse Graph Projections}, + pdfauthor={Levi Neuwirth}, + pdfkeywords={Cops and Robber, Meyniel's conjecture, graph products, degree reduction, expansion} +} + +\title[Ball-Occupation Certificates under Coarse Graph Projections]{Ball-Occupation Certificates under Coarse Graph Projections\\ +Degree Reduction, Square-Root Hard Families, and Toroidal Barriers} +\author{Levi Neuwirth} +\address{Brown University} +\date{July 2026} +\subjclass[2020]{05C57, 05C40, 05C12} +\keywords{Cops and Robber; Meyniel's conjecture; graph products; degree reduction; coarse graph projections; expansion; occupation certificates} + +\begin{document} + +\begin{abstract} +We isolate an abstract strategy-transfer principle for Cops and Robber. Let +$\pi:V(H)\to V(G)$ have fibers of order at most $P$, and suppose that for a +scale factor $\lambda\ge1$ the distances between distinct fibers satisfy +\[ + \lambda(\dist_G(u,v)-1)+1 + \le \dist_H(x,y) + \le \lambda(\dist_G(u,v)+2)-2, +\] +while every fiber has diameter at most $2(\lambda-1)$. If the $N$-vertex +base graph has uniform multi-source growth at the square-root scale, then a +Hall assignment occupies a lifted macro-ball before the robber can leave it, +giving +\[ + \cnum(H)\le C P\bigl(d^3+\log(ePN)\bigr)\sqrt N +\] +and capture time at most $\lambda R$. The theorem uses only the displayed +projection properties, not the internal form of the fibers. + +Iterated degree reduction of Hosseini--Mohar--Gonzalez Hermosillo de la Maza +has exactly this geometry, with $\lambda=3^k$. Applied to +$G(N,p)$ of expected degree $(\log N)^4$, it yields connected subcubic graphs +of order $M$ with +\[ + h(H)\ge (\log M)^{-O(1)}, + \qquad + M^{\frac12-\frac{9+o(1)}{2\log\log\log M}} + \le \cnum(H) + \le \sqrt M\,(\log M)^{O(1)}. +\] +Thus the known stressing family has the square-root exponent, with a +polylogarithmically tight upper bound; the lower convergence to $1/2$ is only +triple-logarithmic. + +Finally, we prove a sharp limitation of the strategy class. If a common +prepositioned bank must, after learning a robber start $v$, match distinct cops +to every vertex of $B(v,R)$ using travel distance at most $R$, then +\[ + \Occ_R(G) + \ge + \frac{\sum_v |B(v,R)|}{\max_x |B(x,2R)|}. +\] +For every fixed $k\ge2$, the Cartesian torus $C_L^{\square k}$ has +$|V|=L^k$, vertex expansion $\Theta_k(L^{-1})$, exact cop number $k+1$, and +$\Occ_R=\Omega_k(L^k)$ for every radius $R$. Hence, for every $\delta>0$, +there are bounded-degree graphs with $h(G)\ge |G|^{-\delta}$ and constant cop +number on which one-shot occupation still costs a linear number of cops. A +cubic four-cycle replacement gives a degree-three instance at exponent +$\delta=1/2$. Any universal robustness theorem must therefore use adaptive +multi-round pursuit, cop reuse, or another strategy not reducible to one-shot +occupation. +\end{abstract} + +\maketitle + +\section{Introduction and main conclusions} + +The multi-cop version of Cops and Robber was developed by Aigner and Fromme, +who proved that three cops suffice on every planar graph +\cite{AignerFromme}. Meyniel's conjecture asks whether every connected +$n$-vertex graph has cop number $O(\sqrt n)$. The current best universal +upper bound remains +\[ + \frac{n}{2^{(1-o(1))\sqrt{\log_2 n}}}, +\] +proved independently by Lu--Peng and Scott--Sudakov +\cite{LuPeng,ScottSudakov}. Bose--Esperet--Hodor--Joret--Micek--Rambaud +recently extended the same scale of bound from graph order to vertex-cover +number \cite{CurrentFrontier}. Expansion is one of the principal settings in +which polynomial savings are known: Bradshaw--Hosseini--Mohar--Stacho obtain +weak Meyniel bounds from bounded-degree expansion restricted to sublinear set +scales \cite{BHMS}, while Clow's withdrawn preprint developed a closely +related structural program connecting failure of weak Meyniel to high-cop +expanding examples \cite{Clow}. + +The motivation here is the effect of bounded-degree replacement gadgets on +pursuit. The degree-reduction construction of Hosseini--Mohar--Gonzalez +Hermosillo de la Maza (HMGHM) preserves lower bounds on cop number and +produces subcubic graphs with cop number $M^{1/2-o(1)}$ \cite{HMGHM}. A +natural converse question is whether a useful upper strategy on the base +graph survives the replacement tower. + +An arbitrary winning strategy does not lift transparently. Moving one step +in the quotient may require a squad dispersed through a cloud to reorganize +while the robber continues moving. The successful object is narrower and +more stable: an \emph{occupation certificate} that assigns distinct cops to +all vertices of a region before the robber can leave it. Distance stretching +slows both deployment and escape, and a bounded normalized additive error +leaves a strict timing margin. + +The first result is therefore stated for an abstract projection, rather than +for the HMGHM gadget. The gadget enters only later, through an exact metric +calculation. The resulting upper bound is stronger quantitatively than the +notation $M^{1/2+o(1)}$ suggests: it is $\sqrt M$ times a polylogarithmic +factor. By contrast, the available lower bound approaches the square-root +exponent at the triple-logarithmic rate displayed in the abstract. These two +facts should not be conflated merely because both can be written +$M^{1/2+o(1)}$. + +The final result marks the boundary of the mechanism. A one-shot occupation +certificate needs polynomial ball amplification between radii $R$ and $2R$. +Polynomially weak expansion alone does not supply this. For every fixed +$k$, the Cartesian tori $C_L^{\square k}$ have bounded metric doubling, exact +cop number $k+1$, and linear one-shot occupation cost at every radius. Taking +$k>1/\delta$ puts these examples inside every window +$h(G)\ge |G|^{-\delta}$. A separate cubic replacement retains the barrier at +$\delta=1/2$. The obstacle in the universal problem is therefore not degree +reduction itself; it is the need for adaptive reuse over many weak-growth +layers. + +\section{Scale-adaptive cores and the robustness window} + +For a connected graph $J$, write +\[ + h(J)=\min_{\varnothing\ne A\subseteq V(J),\ |A|\le |J|/2} + \frac{|\partial_J A|}{|A|}. +\] +The following elementary reduction explains why polynomially weak expansion +is the relevant robustness window for the universal problem. + +\begin{proposition}[Scale-adaptive induced core]\label{prop:adaptive-core} +Let $J$ be a connected graph of order $n$, and let +$\eta(1)\ge\cdots\ge\eta(n)\ge0$. Then $J$ contains a connected induced +subgraph $K$, of order $m$, such that +\[ + \boxed{h(K)\ge\eta(m)} + \qquad\text{and}\qquad + \boxed{\cnum(J)\le \cnum(K)+\sum_{j=m+1}^{n}\eta(j).} +\] +\end{proposition} + +\begin{proof} +Maintain the connected induced region $J_i$ containing the robber. Whenever +$|J_i|=m_i$ and $h(J_i)<\eta(m_i)$, choose +$A_i\subseteq V(J_i)$ with $0<|A_i|\le m_i/2$ and +$|\partial_{J_i}A_i|<\eta(m_i)|A_i|$, and occupy its boundary. The robber is +then confined to one component $J_{i+1}$ of +$J_i-\partial_{J_i}A_i$. Whether that component lies inside $A_i$ or outside +it, one has +\[ + |A_i|\le m_i-m_{i+1}. +\] +Consequently the separator costs at most +\[ + \eta(m_i)(m_i-m_{i+1}) + \le + \sum_{j=m_{i+1}+1}^{m_i}\eta(j). +\] +These integer intervals are disjoint along the robber's nested component +chain. The process terminates at a connected induced $K$ with +$h(K)\ge\eta(|K|)$, and the separator costs telescope to the displayed sum. +\end{proof} + +Taking $\eta(j)=j^{-a}$ shows that a polynomial cop-number saving on +subcubic graphs with $h(K)\ge |K|^{-a}$ would imply a weak form of Meyniel for +arbitrary graphs after the bounded-degree transfer of +Hosseini--Mohar--Gonzalez Hermosillo de la Maza +\cite[Corollary~8]{HMGHM}. Bradshaw--Hosseini--Mohar--Stacho already treat +constant expansion restricted to sublinear set scales \cite{BHMS}; the +unresolved axis in this reduction is expansion that itself shrinks +polynomially. + +\section{Coarse occupation projections} + +\begin{definition}[Coarse occupation projection]\label{def:projection} +Let $G$ and $H$ be connected graphs. A surjection +$\pi:V(H)\to V(G)$ is a $(\lambda,P)$-occupation projection if, writing +$F_v=\pi^{-1}(v)$, +\begin{enumerate}[label=\textup{(\roman*)}] +\item $|F_v|\le P$ for every $v\in V(G)$; +\item for distinct $u,v\in V(G)$ and arbitrary $x\in F_u$, $y\in F_v$, +\[ + \lambda(\dist_G(u,v)-1)+1 + \le + \dist_H(x,y) + \le + \lambda(\dist_G(u,v)+2)-2; +\] +\item $\diam_H(F_v)\le2(\lambda-1)$ for every $v\in V(G)$. +\end{enumerate} +\end{definition} + +The particular constants in Definition~\ref{def:projection} are chosen because they are +exact for the HMGHM tower. The proof below only needs a bounded additive +slack after division by $\lambda$ and a strict gap between deployment and +escape deadlines. + +For $U\subseteq V(G)$, let $B_G(U,r)$ be its closed radius-$r$ +neighborhood. + +\begin{theorem}[Abstract macro-ball occupation transfer]\label{thm:abstract-transfer} +Let $G$ have $N$ vertices. Fix $d\ge2$, $R\ge2$, and constants $a,A_0>0$. +Assume +\begin{equation}\label{eq:scale} + \sqrt N\le d^{R-2}\frac{\sqrt N}{d}\ge N^{1/3}, +\] +so the polynomial prefactors are negligible. + +Hall's condition therefore holds simultaneously for all macro-balls with +probability $1-o(1)$. The total number of sampled tokens is at most +$2AP\Theta\sqrt N$ with probability $1-o(1)$, so a deterministic placement of +the claimed size exists. + +It remains to compare deadlines. A target $y\in X_v$ lies over some +$u\in B_G(v,R)$. Its assigned cop begins over $z$ with +$\dist_G(z,u)\le R-2$. If $z\ne u$, the upper distortion bound gives travel +time at most +\[ + \lambda((R-2)+2)-2=\lambda R-2. +\] +If $z=u$, the fiber-diameter bound gives at most +$2(\lambda-1)\le\lambda R-2$, since $R\ge2$. + +To leave $X_v$, the robber must enter a fiber over a base vertex at distance +at least $R+1$ from $v$. The lower distortion bound makes this require at +least +\[ + \lambda((R+1)-1)+1=\lambda R+1 +\] +steps. Every vertex of $X_v$ is occupied first, and the cop assigned to the +robber's current vertex captures her. +\end{proof} + +\begin{remark}[The quantifier needed from the random base]\label{rem:PW-uniform} +The use of \eqref{eq:lowergrowth} is graph-uniform, not a per-source-set +probability statement. In the dense theorem of Pra{\l}at and Wormald, +condition~(i) of their deterministic Theorem~3.1 is explicitly quantified over +\emph{every} source set and radius. Their Theorem~3.4 proves that a single +$G(N,p)$ satisfies those hypotheses asymptotically almost surely; its proof +unions over the bad source sets and concludes that the growth estimate holds +simultaneously for all sets and radii \cite[Theorems~3.1 and~3.4]{PW}. +Thus the external input has the quantifier order required by +\cref{thm:abstract-transfer}. +\end{remark} + +\section{The HMGHM replacement tower} + +For a vertex of degree $r$, the HMGHM replacement has one external port for +every incident edge. The ports are partitioned into nearly equal classes, +and for each pair of classes there is an internal vertex adjacent to every +port in the two classes \cite[Section~2]{HMGHM}. + +\begin{lemma}[One-round port geometry]\label{lem:portgeometry} +For every HMGHM replacement cloud of degree at least two: +\begin{enumerate}[label=\textup{(\roman*)}] +\item distinct ports are nonadjacent and have distance exactly two; +\item every cloud vertex is within distance at most three of every specified +port; +\item the cloud diameter is at most four. +\end{enumerate} +\end{lemma} + +\begin{proof} +Two ports in different classes share the internal vertex associated with +their class pair. Two ports in the same class share any internal vertex +associated with that class and another nonempty class. Since ports are +mutually nonadjacent, their distance is exactly two. + +An internal vertex is adjacent to every port in either of two classes. If a +specified port lies in neither class, travel to a port in one of the two +classes, then through the internal vertex corresponding to that class and the +specified port's class, and finally to the specified port. This takes three +steps. The diameter bound follows by routing arbitrary endpoints through a +specified port. +\end{proof} + +Let +\[ + G=G_0,G_1,\ldots,G_k=H +\] +be an iterated HMGHM tower, and let $\pi:V(H)\to V(G)$ map every final vertex +to its original ancestor. Put +\[ + F_v=\pi^{-1}(v), + \qquad + P=\max_v|F_v|, + \qquad + \lambda=3^k. +\] + +\begin{theorem}[Exact normalized distortion]\label{thm:metric} +The ancestry projection is a $(3^k,P)$-occupation projection. Explicitly, +for distinct base vertices $u,v$, $r=\dist_G(u,v)$, and arbitrary +$x\in F_u$, $y\in F_v$, +\[ + \boxed{ + 3^k(r-1)+1 + \le + \dist_H(x,y) + \le + 3^k(r+2)-2, + } +\] +and +\[ + \boxed{\diam_H(F_v)\le2(3^k-1).} +\] +\end{theorem} + +\begin{proof} +For one round, a shortest path between distinct clouds uses $e\ge r$ +external edges. Between consecutive external edges it enters and leaves an +intermediate cloud through distinct ports: otherwise it immediately traverses +one external edge back. By Lemma~\ref{lem:portgeometry}, each intermediate port +change costs at least two internal edges, and hence +\[ + \dist_{G_1}(x,y)\ge e+2(e-1)\ge3r-2. +\] +For the upper bound, follow a base geodesic. Reaching the first prescribed +port costs at most three, each intermediate port change costs two, the +external edges cost $r$, and reaching the final endpoint costs at most three. +Thus +\[ + \dist_{G_1}(x,y)\le3+r+2(r-1)+3=3r+4. +\] +The one-round fiber diameter is at most four. + +The lower and upper affine recurrences are +\[ + L_j(r)=3L_{j-1}(r)-2, + \qquad + U_j(r)=3U_{j-1}(r)+4, +\] +with $L_0(r)=U_0(r)=r$. Solving gives +\[ + L_k(r)=3^k(r-1)+1, + \qquad + U_k(r)=3^k(r+2)-2. +\] +The diameter recurrence $D_j\le3D_{j-1}+4$, $D_0=0$, gives +$D_k\le2(3^k-1)$. +\end{proof} + +The feature that matters is not the number of rounds but the normalized +additive error: after division by $3^k$, it remains two quotient layers. By +\cref{thm:abstract-transfer}, any other graph projection with the same three +properties inherits the same occupation-certificate transfer. + +\section{Expansion retention under port-cloud replacement} + +\begin{proposition}[Expansion under connected port replacement]\label{prop:port-exp} +Let $H$ be obtained from a base graph $G$ by replacing every vertex by a +connected cloud of order at most $L_0$, with distinct external ports for the +incident base edges. If $\iotae(G)$ is the edge-isoperimetric constant of +$G$, then +\[ + \boxed{ + \iotae(H) + \ge + \frac{1}{2L_0} + \min\left\{1,\frac{\iotae(G)}{L_0}\right\}. + } +\] +\end{proposition} + +\begin{proof} +Let $S\subseteq V(H)$ with $0<|S|\le|H|/2$. In each cloud, classify the +majority side and let $\mathcal M$ be the total number of minority vertices. Since +every partially cut cloud is connected and has at most $L_0$ vertices, its +internal cut contributes at least one edge, so the total internal contribution +is at least $\mathcal M/L_0$. + +Let $U$ be the set of base vertices whose clouds have majority in $S$, and +put $E=e_G(U,V(G)\setminus U)$. A base cut edge can fail to cross the lifted +cut only if one of its two ports is a minority vertex. Distinct base edges +use distinct ports, so at most $\mathcal M$ of the $E$ external cut edges fail. Hence +\[ + e_H(S,V(H)\setminus S) + \ge + \frac{\mathcal M}{L_0}+\max\{0,E-\mathcal M\} + \ge + \frac{E+\mathcal M}{2L_0}. +\] +Apply the same majority accounting to $S$ or its complement, according as +$|U|\le|G|/2$ or not, to obtain +\[ + \min\{|U|,|V(G)\setminus U|\} + \ge + \frac{|S|-\mathcal M}{L_0}. +\] +Thus +\[ + E\ge\frac{\iotae(G)}{L_0}(|S|-\mathcal M), +\] +and consequently +\[ + E+\mathcal M + \ge + \min\left\{1,\frac{\iotae(G)}{L_0}\right\}|S|. +\] +Combining the inequalities proves the proposition. +\end{proof} + +The HMGHM cloud-size recurrence turns the one-round estimate into a +subpolynomial-loss statement in the polylogarithmic-degree regime. If $D$ +is the initial maximum degree, $L_i$ is the largest cloud order in round $i$, +and $k$ rounds are used, HMGHM prove +\[ + \prod_{i=0}^{k-1}L_i + \le C D^2(\log D)^{\log_2(11/5)}, + \qquad + 2^k=O(\log D). +\] +Iterating Proposition~\ref{prop:port-exp} therefore gives the following. + +\begin{corollary}[Expansion retained by HMGHM reduction]\label{cor:exp-retention} +Let $H$ be the final subcubic graph obtained from a connected graph $G$ of +maximum degree $D\ge4$. Then +\[ + \boxed{ + h(H) + \ge + \frac{\iotae(G)}{C D^4(\log D)^{\kappa}}, + \qquad + \kappa=1+2\log_2(11/5)<3.28. + } +\] +In particular, if $D=|G|^{o(1)}$ and $\iotae(G)=|G|^{-o(1)}$, then +$|H|=|G|^{1+o(1)}$ and $h(H)=|H|^{-o(1)}$. +\end{corollary} + +\begin{proof} +At every round $\iotae(G_i)\le D_i\le L_i$, so +Proposition~\ref{prop:port-exp} gives +\[ + \iotae(G_{i+1})\ge\frac{\iotae(G_i)}{2L_i^2}. +\] +Thus +\[ + \iotae(H) + \ge + \frac{\iotae(G)}{2^k(\prod_iL_i)^2} + \ge + \frac{\iotae(G)}{C D^4(\log D)^\kappa}. +\] +Since $H$ has maximum degree at most three, its vertex expansion is at least +one third of its edge expansion. The order statement follows from the same +cloud-product bound. +\end{proof} + +\begin{remark}[Relation to replacement products] +The regular replacement-product literature proves stronger spectral +conclusions under much stronger hypotheses on the clouds; see, for example, +Reingold--Vadhan--Wigderson \cite{RVW}. Proposition~\ref{prop:port-exp} allows arbitrary +connected, nonuniform clouds and consequently gives only a crude +isoperimetric estimate. No novelty claim is made here beyond this precise +form without a fuller graph-substitution review. +\end{remark} + +\section{A polylogarithmically tight square-root family} + +Take +\[ + d=(\log N)^4, + \qquad + p=\frac{d}{N-1}, + \qquad + G\sim G(N,p). +\] +Iterate the HMGHM replacement until the graph $H$ is subcubic, and write +$M=|H|$. + +With high probability, $\Delta(G)\le2d$. By +Remark~\ref{rem:PW-uniform}, the dense Pra{\l}at--Wormald theorem supplies the +uniform lower growth in \eqref{eq:lowergrowth}; in the volume range used here +it also supplies the upper growth in \eqref{eq:uppergrowth} \cite{PW}. Choose +$R$ minimally so that $d^{R-2}\ge\sqrt N$. Since $d$ is polylogarithmic, +\eqref{eq:scale} holds. + +HMGHM give, both globally and along one ancestry fiber, +\begin{equation}\label{eq:Pbound} + P\le C d^2(\log d)^{1.14}, + \qquad + N\le M\le PN. +\end{equation} +Their shadow strategy gives $\cnum(H)\ge\cnum(G)$, and the random-graph lower +bound of Bollob\'as--Kun--Leader used in their argument yields +\[ + \cnum(G) + \ge + d^{-2}N^{\frac12-\frac{9}{2\log\log d}}. +\] +The abstract transfer theorem gives +\[ + \cnum(H) + \le + CP\bigl(d^3+\log(ePN)\bigr)\sqrt N + \le + \sqrt M\,(\log M)^{20+o(1)}. +\] +Using $d=(\log N)^4$ and $M=N(\log N)^{O(1)}$ in the lower bound gives the +following more informative formulation. + +\begin{theorem}[Quantitative HMGHM hard family]\label{thm:hardfamily} +There is a sequence of connected subcubic graphs $H$, of order $M\to\infty$, +for which +\[ + \boxed{ + M^{\frac12-\frac{9+o(1)}{2\log\log\log M}} + \le + \cnum(H) + \le + \sqrt M\,(\log M)^{20+o(1)}. + } +\] +The upper bound is $\sqrt M$ times a polylogarithmic factor. The lower +exponent tends to $1/2$ only at a triple-logarithmic rate. +\end{theorem} + +The base edge expansion is $\Omega(d)$ with high probability. Since +$d=\operatorname{polylog}N$, Corollary~\ref{cor:exp-retention} gives +\[ + h(H)\ge (\log M)^{-O(1)}=M^{-o(1)}. +\] +This is exactly the degree regime in which the retention factor is +informative; for polynomial initial degree the crude $D^4$ loss can be +vacuous. + +\begin{corollary}[Square-root weak-expander family]\label{cor:weakexpander} +There are connected subcubic graphs satisfying +\[ + h(H)\ge M^{-o(1)} + \qquad\text{and}\qquad + \cnum(H)=M^{1/2+o(1)}. +\] +More precisely, they obey the two-sided bounds of +\cref{thm:hardfamily}. +\end{corollary} + +\begin{remark}[What is forced, and what is achieved]\label{rem:robustness-endpoint} +By \cref{prop:adaptive-core}, polynomially weak expansion is a natural +robustness window for weak Meyniel. The HMGHM lower bound alone already +forces every proposed estimate +\[ + \cnum(J)\le C\phi^{-p}|J|^{1-\eps+o(1)} + \qquad(h(J)\ge\phi=|J|^{-o(1)}) +\] +to have $\eps\le1/2$. That restriction predates the upper transfer proved +here. The new conclusion is that the known stressing family itself achieves +the endpoint order $\sqrt M$ up to polylogarithmic factors, so this family is +not an obstruction to a Meyniel-strength theorem on polynomially weak +subcubic expanders. +\end{remark} + +\section{Why chase strategies need not transfer} + +The abstract theorem deliberately transfers a strategy class, not arbitrary +cop number. The smallest example explains the distinction. For a degree-two +vertex, one HMGHM cloud is a three-vertex path. Replacing every vertex of +$C_3$ therefore produces $C_9$. But +\[ + \cnum(C_3)=1, + \qquad + \cnum(C_9)=2. +\] +The one-cop win on $C_3$ is a direct chase/dismantling phenomenon. The +subdivision-like stretching destroys it. By contrast, an occupation +certificate is synchronized to a deadline: the replacement tower stretches +the cops' travel and the robber's escape by the same factor, and the bounded +normalized additive slack preserves a strict margin. The examples +$K_4$ and the diamond graph exhibit the same one-round increase, so the issue +is structural rather than peculiar to one cycle. + +\section{A one-shot occupation barrier} + +\begin{definition}[Universal one-shot occupation number]\label{def:occ} +For a connected graph $G$ and integer $R\ge0$, let $\Occ_R(G)$ be the minimum +size of a finite set $X$ of distinct cop tokens, equipped with a position map +$p:X\to V(G)$, such that for every $v\in V(G)$ there is an injection +\[ + f_v:B_G(v,R)\longrightarrow X +\] +with +\[ + \dist_G(u,p(f_v(u)))\le R + \qquad\text{for every }u\in B_G(v,R). +\] +Different tokens may have the same initial position. After learning the +robber's starting vertex, the common prepositioned bank can occupy her entire +radius-$R$ ball within $R$ moves. +\end{definition} + +\begin{remark}[Why the target and deadline are natural] +If the robber starts at $v$, she needs at least $R+1$ robber moves to leave +$B_G(v,R)$. Occupying that whole ball within $R$ cop moves is therefore the +canonical one-shot certificate: every vertex she could still occupy is filled +before her first possible escape. The parameter $\Occ_R$ measures this +specific strategy class, not ordinary cop number. +\end{remark} + +\begin{theorem}[Counting barrier]\label{thm:occ-lower} +Every connected graph satisfies +\[ + \boxed{ + \Occ_R(G) + \ge + \frac{\sum_{v\in V(G)}|B_G(v,R)|} + {\max_{x\in V(G)}|B_G(x,2R)|}. + } +\] +In particular, if $G$ is vertex-transitive, then +\[ + \boxed{ + \Occ_R(G) + \ge + |V(G)|\frac{|B_G(o,R)|}{|B_G(o,2R)|}. + } +\] +\end{theorem} + +\begin{proof} +Fix a feasible multiset $X$. For each possible robber start $v$, every cop +token used by the injection $f_v$ lies in $B_G(v,2R)$, by the triangle +inequality. Hence at least $|B_G(v,R)|$ tokens of $X$ lie in $B_G(v,2R)$. +Summing over $v$, the number of incident pairs $(v,x)$ with +$x\in X\cap B_G(v,2R)$ is at least +$\sum_v|B_G(v,R)|$. + +A fixed token based at $x$ is counted only for starts +$v\in B_G(x,2R)$, at most $\max_y|B_G(y,2R)|$ times. Therefore +\[ + |X|\max_y|B_G(y,2R)| + \ge + \sum_v|B_G(v,R)|, +\] +which proves the claim. +\end{proof} + +The theorem identifies the exact growth ratio demanded by one-shot +occupation. A polynomial saving from the trivial $|V(G)|$ bound requires +polynomial amplification from radius $R$ to radius $2R$. + +We now give subcubic witnesses showing that polynomially weak expansion does +not imply such amplification. + +\begin{definition}[The cubic truncated torus]\label{def:Qt} +For $L\ge5$, let $Q_L$ have vertex set +\[ + (\mathbb Z/L\mathbb Z)^2\times\mathbb Z/4\mathbb Z. +\] +Inside each fiber $(x,y)\times\mathbb Z/4\mathbb Z$, join the four vertices in +a cycle. Add the external edges +\[ + (x,y,0)(x,y+1,2) + \qquad\text{and}\qquad + (x,y,1)(x+1,y,3) +\] +for every $(x,y)$. Equivalently, $(x,y,2)$ receives its external edge from +$(x,y-1,0)$, and $(x,y,3)$ receives its external edge from $(x-1,y,1)$. +Thus every vertex has two internal cycle neighbors and one external neighbor, +and $Q_L$ is the four-cycle port replacement of the square torus +$C_L\square C_L$. +\end{definition} + +Every vertex of $Q_L$ has degree three, and the construction embeds on the +torus by replacing each base vertex inside a small disk. Its order is +$4L^2$. + + + +\begin{lemma}[Vertex transitivity and explicit doubling of $Q_L$]\label{lem:doubling} +The graph $Q_L$ is vertex-transitive and, for every vertex $x$ and radius +$R\ge0$, +\[ + |B_{Q_L}(x,2R)|\le 5500\,|B_{Q_L}(x,R)|. +\] +\end{lemma} + +\begin{proof} +Translations in the first two coordinates are automorphisms. The map +\[ + \rho(x,y,i)=(y,-x,i+1) +\] +(with coordinates interpreted cyclically) preserves internal cycle edges and +interchanges the two external edge directions. Translations together with +$\rho$ act transitively. + +Let $T_L=C_L\square C_L$ and project $(x,y,i)$ to $(x,y)$. Projection does +not increase distance, so +\[ + |B_{Q_L}(x,2R)|\le4|B_{T_L}(\pi x,2R)| + \le4\min\{L,4R+1\}^2. +\] +Conversely, from an arbitrary cloud vertex one can enter the required port in +at most two internal moves and then lift each base step using at most three +moves. Hence, with $r=\lfloor(R-2)/3\rfloor$ for $R\ge2$, +\[ + |B_{Q_L}(x,R)|\ge |B_{T_L}(\pi x,r)|. +\] +The coordinate box of cyclic radius $\lfloor r/2\rfloor$ lies inside the +$\ell_1$ ball, so +\[ + |B_{T_L}(\pi x,r)| + \ge \min\{L,2\lfloor r/2\rfloor+1\}^2. +\] +For $R<10$, the upper bound is at most $4\cdot37^2<5500$ and the denominator +is at least one. For $R\ge10$, one has $r\ge R/6$ and +$2\lfloor r/2\rfloor+1\ge r$, whence the ratio is at most +$4\cdot30^2<5500$. This proves the displayed constant. +\end{proof} + +\begin{theorem}[Cubic one-shot barrier]\label{thm:cubic-barrier} +For $L\ge5$, the connected cubic graphs $Q_L$, with $M=|Q_L|=4L^2$, satisfy +\[ + \boxed{ + h(Q_L)=\Theta(M^{-1/2}), + \qquad + \cnum(Q_L)\le3, + \qquad + \Occ_R(Q_L)\ge \frac{M}{5500} + \quad\text{for every }R\ge0. + } +\] +\end{theorem} + +\begin{proof} +The square torus has edge and vertex expansion $\Theta(1/L)$ by the discrete +torus isoperimetric inequality \cite{BL}. Applying +Proposition~\ref{prop:port-exp} with cloud size four gives the matching lower +bound for $Q_L$; lifting a coordinate slab of width $\lfloor L/2\rfloor$ +gives the upper bound for every $L$. Since $Q_L$ is cubic, edge and vertex +expansion differ by at most a constant factor. +Thus $h(Q_L)=\Theta(1/L)=\Theta(M^{-1/2})$. + +The graph $Q_L$ is toroidal, and every toroidal graph has cop number at most +three \cite{Lehner}. Vertex transitivity, Theorem~\ref{thm:occ-lower}, and +Lemma~\ref{lem:doubling} give +\[ + \Occ_R(Q_L) + \ge + M\frac{|B_{Q_L}(x,R)|}{|B_{Q_L}(x,2R)|} + \ge \frac{M}{5500}. +\] +The finite audit suggests that the optimal asymptotic constant is $1/4$, but +that sharpening is not needed here. +\end{proof} + +\subsection{The barrier throughout every polynomial expansion window} + +For integers $k\ge2$ and $L\ge4$, write +\[ + T_{L,k}=\underbrace{C_L\square\cdots\square C_L}_{k\text{ factors}}. +\] +Its order is $m=L^k$, its degree is $2k$, and its metric is the cyclic +$\ell_1$ metric. + +\begin{lemma}[Uniform doubling of Cartesian tori]\label{lem:ktorus-doubling} +For every fixed $k\ge2$, every $L\ge4$, every vertex $x$, and every radius +$R\ge0$, +\[ + |B_{T_{L,k}}(x,2R)|\le (5k)^k|B_{T_{L,k}}(x,R)|. +\] +\end{lemma} + +\begin{proof} +Every coordinate of a point in $B(x,2R)$ has cyclic distance at most $2R$, so +\[ + |B(x,2R)|\le \min\{L,4R+1\}^k. +\] +The coordinate box in which every coordinate has cyclic distance at most +$\lfloor R/k\rfloor$ lies in $B(x,R)$, and therefore +\[ + |B(x,R)|\ge\min\{L,2\lfloor R/k\rfloor+1\}^k. +\] +If $R0$ there is a constant-degree graph family +with +\[ + h(G)\ge |G|^{-\delta}, + \qquad + c(G)=O_\delta(1), + \qquad + \Occ_R(G)=\Omega_\delta(|G|) + \quad\text{for every radius }R. +\] +\end{theorem} + +\begin{proof} +The discrete-torus edge-isoperimetric inequality gives order $1/L$ +\cite{BL}. Since $T_{L,k}$ has degree $2k$, edge boundary and external +vertex boundary differ by at most the fixed factor $2k$; a coordinate slab of +width $\lfloor L/2\rfloor$ supplies the matching upper bound. Hence +$h(T_{L,k})=\Theta_k(1/L)=\Theta_k(m^{-1/k})$. Neufeld and Nowakowski proved +that a Cartesian product of $k$ cycles, each of length at least four, has cop +number exactly $k+1$ \cite{NeufeldNowakowski}. Since the torus is +vertex-transitive, Theorem~\ref{thm:occ-lower} and +Lemma~\ref{lem:ktorus-doubling} give the occupation lower bound. + +Given $\delta>0$, choose $k=\max\{2,\lfloor1/\delta\rfloor+1\}$. Then $1/k<\delta$, so for sufficiently large $m$ the expansion +lower bound $h(T_{L,k})\ge m^{-\delta}$ holds after absorbing the fixed +$k$-dependent constant. +\end{proof} + +\begin{remark}[The sharp metric constant] +For fixed $k$, choose radii $1\ll R\ll L$. Lattice-point asymptotics for the +$\ell_1$ ball give +\[ + \frac{|B_{T_{L,k}}(x,2R)|}{|B_{T_{L,k}}(x,R)|}=2^k+o(1). +\] +Thus no uniform doubling constant below $2^k$ is possible, and the counting +bound of \cref{thm:occ-lower} approaches the natural fraction $2^{-k}m$ on +these local radii. The explicit constant $(5k)^{-k}$ is chosen only for a +short all-radii proof. +\end{remark} + +\begin{corollary}[No expansion-only one-shot theorem]\label{cor:no-exp-occ} +For every $\delta>0$, there is no implication of the form +\[ + h(G)\ge |G|^{-\delta} + \quad\Longrightarrow\quad + \Occ_R(G)\le |G|^{1-\eps} + \text{ for some radius $R$} +\] +with any fixed $\eps>0$, even when the maximum degree is bounded by a constant +depending only on $\delta$. +\end{corollary} + +\begin{proof} +Take the family from \cref{thm:full-window}. It lies in the prescribed +expansion window, while $\Occ_R(G)=\Omega_\delta(|G|)$ for every $R$. +\end{proof} + +\begin{remark}[Architectural meaning] +The logical obstruction is not that tori are difficult pursuit instances; +they are not. Rather, \cref{thm:occ-lower} makes every vertex-transitive +bounded-doubling graph expensive for one-shot occupation, and bounded +doubling is compatible with every polynomial weak-expansion window by +\cref{thm:full-window}. The tori +certify that the hypothesis class contains such graphs while coordinate-wise +shadowing still uses exactly $k+1$ cops. Therefore ball amplification is the +wrong invariant for adaptive pursuit, not merely a poor description of one +particular easy family. The cubic family $Q_L$ records that the same +separation already occurs in maximum degree three at exponent $1/2$. +\end{remark} + +\section{Outlook} + +For vertex expansion $h(G)\ge\phi$, iterating the elementary growth factor +$1+\phi$ reaches global scale after $O(\phi^{-1}\log |G|)$ layers. The same +iteration gives the standard diameter bound of that order; these are two +forms of the same calculation, not independent evidence. The strategic +consequence is that, when $\phi=|G|^{-a}$, an amplification-based pursuit +scheme must operate over a full-traversal timescale $\Theta(|G|^a\log|G|)$. + +The present paper separates three phenomena: +\begin{enumerate}[label=\textup{(\arabic*)}] +\item bounded normalized metric distortion preserves a strong occupation +certificate through degree reduction; +\item the HMGHM stressing family itself meets the square-root endpoint up to +polylogarithmic factors; +\item one-shot occupation is nevertheless incapable of proving a universal +robustness theorem throughout any polynomial weak-expansion window, even on +bounded-degree graphs with constant cop number; a cubic instance already +appears at exponent $1/2$. +\end{enumerate} +The remaining universal question is therefore an adaptive one. On the tori, +ball growth carries essentially no information about pursuit cost; product +structure instead supports coordinate-wise shadowing. What geometric or +combinatorial quantity replaces product coordinates on a general +polynomially weak expander? Equivalently, can a capacitated, correlated, or +deferred witness system reuse the same cop resources over polynomially many +weak-growth layers, or must every such one-traversal certificate incur +polynomial congestion? + +\section*{Acknowledgments} +The author is grateful to Anthony Clow, Peter Bradshaw, Bojan Mohar, and +Florian Lehner for work and perspectives that helped shape the questions +addressed here. Additional acknowledgments will be added in a later version. +The author welcomes corrections concerning priority, related +graph-substitution inequalities, and the scope of the occupation framework. + +\section*{Audit and reproducibility} + +The metric inequalities were independently tested on HMGHM towers rebuilt +from the published gadget description, including structured base graphs not +used in the original audit. The Hall inequalities and timing margins were +checked numerically, and exact small replacement games were solved by +retrograde analysis. The toroidal barrier audit computes exact ball profiles of +$C_L^{\square k}$ by convolving cyclic distance distributions, verifies the +$(5k)^k$ doubling bound for $k=2,3,4,5$, constructs $Q_L$, checks cubicity, +connectivity, and the displayed rotation automorphism, and evaluates the +counting lower bound at every radius. No theorem depends on the +computations. + +\begin{thebibliography}{99} + +\bibitem{AignerFromme} +M.~Aigner and M.~Fromme, +\emph{A game of cops and robbers}, +Discrete Applied Mathematics 8 (1984), 1--12. + +\bibitem{CurrentFrontier} +P.~Bose, L.~Esperet, J.~Hodor, G.~Joret, P.~Micek, and C.~Rambaud, +\emph{Cops and robber in graphs with bounded vertex cover number}, +arXiv:2602.07435, 2026. + +\bibitem{BHMS} +P.~Bradshaw, S.~A. Hosseini, B.~Mohar, and L.~Stacho, +\emph{On the cop number of graphs of high girth}, +Journal of Graph Theory 102 (2023), 15--34; arXiv:2005.10849. + +\bibitem{BKL} +B.~Bollob\'as, G.~Kun, and I.~Leader, +\emph{Cops and robbers in a random graph}, +Journal of Combinatorial Theory, Series B 103 (2013), 226--236. + +\bibitem{BL} +B.~Bollob\'as and I.~Leader, +\emph{An isoperimetric inequality on the discrete torus}, +SIAM Journal on Discrete Mathematics 3 (1990), 32--37. + +\bibitem{Clow} +A.~Clow, +\emph{Expanders satisfy the weak Meyniel conjecture}, +withdrawn preprint, arXiv:2311.13792, 2023. + +\bibitem{HMGHM} +S.~A. Hosseini, B.~Mohar, and S.~Gonzalez Hermosillo de la Maza, +\emph{Meyniel's conjecture on graphs of bounded degree}, +Journal of Graph Theory 97 (2021), 401--407; arXiv:1912.06957. + +\bibitem{Lehner} +F.~Lehner, +\emph{On the cop number of toroidal graphs}, +Journal of Combinatorial Theory, Series B 151 (2021), 250--262. + +\bibitem{LuPeng} +L.~Lu and X.~Peng, +\emph{On Meyniel's conjecture of the cop number}, +Journal of Graph Theory 71 (2012), 192--205. + +\bibitem{NeufeldNowakowski} +S.~Neufeld and R.~Nowakowski, +\emph{A game of cops and robbers played on products of graphs}, +Discrete Mathematics 186 (1998), 253--268. + +\bibitem{PW} +P.~Pra{\l}at and N.~Wormald, +\emph{Meyniel's conjecture holds for random graphs}, +Random Structures \& Algorithms 48 (2016), 396--421; arXiv:1301.2841. + +\bibitem{RVW} +O.~Reingold, S.~Vadhan, and A.~Wigderson, +\emph{Entropy waves, the zig-zag graph product, and new constant-degree +expanders}, +Annals of Mathematics 155 (2002), 157--187. + +\bibitem{ScottSudakov} +A.~Scott and B.~Sudakov, +\emph{A bound for the cops and robbers problem}, +SIAM Journal on Discrete Mathematics 25 (2011), 1438--1442. + +\end{thebibliography} + +\end{document} diff --git a/paper/branch-capture-paper.tex b/paper/branch-capture-paper.tex new file mode 100644 index 0000000..46d3efc --- /dev/null +++ b/paper/branch-capture-paper.tex @@ -0,0 +1,658 @@ +\documentclass[11pt]{amsart} + +\usepackage[T1]{fontenc} +\usepackage{microtype} +\usepackage[margin=1in]{geometry} +\usepackage{amsmath,amssymb,amsthm} +\usepackage{enumitem} +\usepackage{xcolor} +\usepackage{hyperref} + +\hypersetup{ + colorlinks=true, + linkcolor=blue!50!black, + citecolor=blue!50!black, + urlcolor=blue!50!black +} + +\newtheorem{theorem}{Theorem}[section] +\newtheorem{lemma}[theorem]{Lemma} +\newtheorem{proposition}[theorem]{Proposition} +\newtheorem{corollary}[theorem]{Corollary} +\newtheorem{question}[theorem]{Question} + +\theoremstyle{definition} +\newtheorem{definition}[theorem]{Definition} +\newtheorem{remark}[theorem]{Remark} + +\DeclareMathOperator{\dist}{dist} +\DeclareMathOperator{\supp}{supp} + +\title[Branch-Tube Persistence and Static Coverage]{Branch-Tube Persistence and Static Coverage\\in Tree-Ball Geometry} +\author{Levi Neuwirth} +\address{Brown University} +\date{July 21, 2026} + +\begin{document} + +\begin{abstract} +We analyze exhaustive static coverage by path tubes indexed by length-$t$ nonbacktracking robber paths from $v_0$ in a finite-horizon local chase on a $d$-regular graph. An endpoint-sensitive geodesic lemma shows that, among possibly infinite $d$-regular graphs, radius $R+t$ is sharp for arbitrary pairs in $B_R(v_0)\times B_t(v_0)$, while synchronized witnesses along a prescribed path require only a radius-$R$ tree-ball. If every tube is occupied, each surviving round along every path in this class ends in capture, blockage, or branch-load support on at least two branches. The tubes partition the outer ball, so deterministic coverage has minimum cost $N_t=d(d-1)^{t-1}$; conditional on a specified root, i.i.d.\ uniform coverage has threshold $\Theta(N_t\log N_t)$ for fixed $d$. An augmented prefix-depth profile that retains the complete shallow configuration still need not determine later support. The result is local and root-dependent: it treats neither arbitrary robber walks nor a robber-independent cop strategy, and it gives no cop-number bound. +\end{abstract} + +\maketitle + + +\section{Introduction} + +\subsection{Motivation} + +The cops-and-robbers game, introduced independently in its one-cop form by Quilliot and by Nowakowski--Winkler and developed in its multiple-cop form by Aigner--Fromme~\cite{Quilliot,NowakowskiWinkler,AignerFromme}, is a pursuit-evasion game on a graph in which $k$ cops attempt to capture one robber. The minimum such $k$ is the \emph{cop number} $c(G)$. \emph{Meyniel's conjecture}, attributed to Henri Meyniel and appearing in the early literature in Frankl's work~\cite{Frankl}, asserts that $c(G)=O(\sqrt n)$ for every connected graph on $n$ vertices and remains a central open problem in the area. The best general upper bound, +\[ +c(G) \leq \frac{n}{2^{(1-o(1))\sqrt{\log_2 n}}}, +\] +was proved independently by Lu--Peng, Scott--Sudakov, and Frieze--Krivelevich--Loh~\cite{LuPeng,ScottSudakov,FriezeKrivelevichLoh}. + +Pra\l at--Wormald's random-graph argument combines an initial random cop placement with assignments made after the robber's start is revealed: in different regimes, cop teams fully occupy a neighborhood or densely cover a sphere~\cite{PralatWormald}. Tree-like geometry enters the literature in several other ways. Aigner--Fromme show that one moving cop can guard a fixed isometric path~\cite{AignerFromme}. Frankl established a high-girth lower bound~\cite{Frankl}, and Bradshaw--Hosseini--Mohar--Stacho refine that line through a branch-weight argument in which unique local geodesics let the robber choose a sufficiently lightly controlled forward branch~\cite{BradshawHosseiniMoharStacho}. Related bounded-degree reductions provide broader extremal context~\cite{HMG}. These mechanisms motivate a path-conditioned local question: whether cops near the robber can coordinate their distance-decreasing moves along every prescribed length-$t$ nonbacktracking path starting at the robber's initial vertex. + +The present paper instead isolates one rigid, root-dependent certificate: every length-$t$ nonbacktracking path from $v_0$ indexes an occupied descendant tube. Paths here index a static partition of the outer ball rather than a route guarded by one moving cop or an adaptively selected escape branch. We determine this certificate's guarantee and cost. Arbitrary robber walks, including stationary moves and reversals, are not analyzed, and exact tree geometry is not asserted to be necessary. + +The uniform sampling below is conditional on the fixed root $v_0$: the root is specified before cop positions are sampled from $B_R(v_0)$. This measures the local cost of the certificate, not a legal initial placement in the standard game, where cops choose positions before the robber chooses its start. A global strategy would need comparable coverage simultaneously or adaptively for an unknown robber position. Accordingly, the results neither construct a robber-independent global strategy nor improve the cop-number bound. + +\subsection{Setup and endpoint-sensitive tree-ball geodesics} + +Graphs are simple and undirected. The local results allow finite or infinite graphs unless finiteness is stated explicitly; discussion of the cop number and all $n$-vertex asymptotics concerns finite connected graphs. Throughout, $G$ denotes a $d$-regular graph with $d\geq3$, and $v_0\in V(G)$ is the robber's initial position in the rooted local experiment. All radii and time horizons are nonnegative integers, and $t,r\geq1$ whenever length-$t$ or order-$r$ objects are used. All unadorned logarithms are natural. We write +\[ +B_R(v)=\{x\in V(G):\dist(x,v)\leq R\}, +\qquad +S_j(v)=\{x\in V(G):\dist(x,v)=j\}. +\] + +\begin{definition}[Tree-ball] +\label{def:tree-ball} +The ball $B_R(v_0)$ is a \emph{tree-ball} if the induced subgraph $G[B_R(v_0)]$ is a tree. +\end{definition} + +This is a local condition at the specified center. The global condition $\operatorname{girth}(G)>2R+1$ implies that every radius-$R$ ball is a tree-ball. Conversely, if every radius-$R$ ball is a tree-ball, then $\operatorname{girth}(G)>2R+1$. + +An induced tree-ball does not control shortest paths between arbitrary pairs of its vertices: a competing path may leave the ball and re-enter. The required radius depends on the endpoint depths and on the length of their path inside the tree-ball. + +\begin{lemma}[Endpoint-sensitive tree-ball geodesics] +\label{lem:buffer} +Suppose $B_q(v_0)$ is a tree-ball, let $x,y\in B_q(v_0)$, and let $L$ be the length of the $x$--$y$ path in $G[B_q(v_0)]$. If +\[ +\dist(x,v_0)+\dist(y,v_0)+L\leq 2q, +\] +then every ambient $x$--$y$ geodesic lies in $B_q(v_0)$. Consequently, that geodesic is unique and equals the $x$--$y$ path in $G[B_q(v_0)]$. +\end{lemma} + +\begin{proof} +Let $P$ be an ambient $x$--$y$ geodesic of length $\ell$. The path in $G[B_q(v_0)]$ gives $\ell\leq L$. For $z\in P$, write $h=\dist_P(x,z)$. Then +\[ +\dist(z,v_0) +\leq \min\{\dist(x,v_0)+h,\ \dist(y,v_0)+\ell-h\} +\leq \frac{\dist(x,v_0)+\dist(y,v_0)+\ell}{2} +\leq q. +\] +Thus $P\subseteq B_q(v_0)$. Since the induced graph on this ball is a tree, $P$ is its unique $x$--$y$ path. +\end{proof} + +\begin{remark}[Uniform buffers versus chase endpoints] +For arbitrary $x\in B_R(v_0)$ and $y\in B_t(v_0)$, the walk from $x$ to $y$ through $v_0$ has length at most $R+t$. If $B_{R+t}(v_0)$ is a tree-ball, the path between $x$ and $y$ in the rooted tree $G[B_{R+t}(v_0)]$ is no longer than this walk, so Lemma~\ref{lem:buffer} applies. For $R,t\geq1$, this uniform radius cannot in general be reduced. Put $L=R+t$, begin with the rooted $d$-regular tree truncated at depth $L-1$, and choose vertices $x$ and $y$ at depths $R$ and $t$ in distinct root branches. Choose descendants $a$ of $x$ and $b$ of $y$ in $S_{L-1}(v_0)$, allowing equality, add a new vertex $z$, and join $z$ to $a$ and $b$. + +Complete the graph explicitly: for each remaining degree deficit at a vertex of $S_{L-1}(v_0)\cup\{z\}$, attach by one edge a separate infinite rooted $(d-1)$-ary tree. Every vertex then has degree $d$, and the resulting graph is infinite, simple, and connected. The induced ball $B_{L-1}(v_0)$ is still the original tree. The path from $x$ to $y$ through $v_0$ has length $L$, while the path through $z$ has length +\[ +\dist(x,a)+2+\dist(b,y)=(t-1)+2+(R-1)=L. +\] +Each attached infinite tree meets the displayed core at only one vertex, so it creates no additional route between $x$ and $y$. Thus the two displayed paths are distinct geodesics. This proves sharpness at radius $R+t-1$ among possibly infinite $d$-regular graphs. + +The endpoint pairs used along a prescribed length-$t$ nonbacktracking path are more restricted. Their rooted-tree path and endpoint depths satisfy Lemma~\ref{lem:buffer} with $q=R$, so the persistence result requires no tree-ball beyond the cop-placement radius. This does not assert that the radius-$R$ tree-ball hypothesis is necessary. Controlled cyclic geometry is not addressed here, and no cyclic extension is proved. +\end{remark} + +Whenever $B_q(v_0)$ is a tree-ball, we root $G[B_q(v_0)]$ at $v_0$. Every vertex other than $v_0$ has a unique parent, and every vertex of depth less than $q$ has $d-1$ children. + +\begin{definition}[Geodesic cone] +\label{def:cone} +Suppose $B_r(v)$ is a tree-ball and $u\in N(v)$. The \emph{geodesic cone} through $u$ at radius $r$ is +\[ +C_u(v,r):=\{x\in B_r(v)\setminus\{v\}:\text{the path from $x$ to $v$ in $B_r(v)$ has penultimate vertex $u$}\}. +\] +\end{definition} + +\begin{definition}[Path tube] +\label{def:tube} +Let $R\geq t$, suppose $B_R(v_0)$ is a tree-ball, and let +\[ +\sigma=(v_0,v_1,\ldots,v_t) +\] +be a length-$t$ nonbacktracking path starting at $v_0$: consecutive vertices are adjacent and $v_{i+1}\neq v_{i-1}$ whenever the latter condition is defined. The \emph{length-$t$ tube} associated with $\sigma$ is +\[ +T_\sigma(R):=\{x\in B_R(v_0):\text{the rooted path from $x$ to $v_0$ contains $v_t,v_{t-1},\ldots,v_1$ in order}\}. +\] +Equivalently, $T_\sigma(R)$ is the set of descendants of $v_t$ lying in $B_R(v_0)$. +\end{definition} + +\subsection{Game conventions} + +A \emph{cop configuration} $X$ is a finite multiset of vertices, represented by its finitely supported multiplicity function $X(v)\in\mathbb Z_{\geq0}$. For $A\subseteq V(G)$, set +\[ +X(A):=\sum_{v\in A}X(v), +\qquad +|X|:=X(V(G)), +\qquad +\supp(X):=\{v:X(v)>0\}. +\] +Thus counts of cops include multiplicity, several cops may occupy one vertex, and $A$ is occupied exactly when $X(A)>0$. We write $X=[x_1,\ldots,x_k]$ for a multiset of cop positions, with repeated entries allowed. Independent uniform sampling is with replacement and produces the multiset of sampled positions. + +Capture occurs whenever a cop and the robber occupy the same vertex, including before the first cop move; once capture occurs, no further move is made. Conditional on no capture, the cops move first in each round, simultaneously, and each cop moves to a neighboring vertex minimizing its distance to the robber's current vertex. Ties may be broken arbitrarily. Some formulations also allow cops to pass; the results remain valid there by having the selected witnesses make the prescribed distance-decreasing moves. Under the tree-ball hypotheses below, Lemma~\ref{lem:buffer} shows that each witness selected in our proofs has a unique distance-decreasing move. + +We analyze only length-$t$ nonbacktracking robber paths starting at $v_0$. In the full game a robber walk may reverse an edge or, under common conventions, remain stationary. Neither behavior is covered here. Fix a prescribed path +\[ +\tau=(v_0,v_1,\ldots,v_t). +\] +It survives through round $0$ precisely when no initial capture occurs. If it has survived through round $s-1$, then the robber is at $v_{s-1}$ when round $s$ begins. After the cops move toward $v_{s-1}$, the robber is captured if a cop occupies $v_{s-1}$. Otherwise the prescribed move $v_{s-1}\to v_s$ is \emph{legal} if no cop occupies $v_s$ after the cop move. The path survives through round $s$ if no capture or blockage has occurred through that move. + +For a robber position $v$ and a neighbor $u\in N(v)$, an individual cop at $c\neq v$ whose $c$--$v$ geodesic is unique \emph{contributes to branch $u$ at $v$} if that geodesic has penultimate vertex $u$. The \emph{branch-load support} at $v$ is the set of branches receiving at least one contributing cop; its size counts branches, not cops. + +\subsection{Main results and scope} + +Although $R+t$ is the sharp uniform radius for arbitrary endpoint pairs in $B_R(v_0)\times B_t(v_0)$, the synchronized pairs arising along a prescribed length-$t$ nonbacktracking path satisfy the endpoint-sensitive criterion already at radius $R$. Accordingly, the persistence theorem assumes only that the cop-placement ball $B_R(v_0)$ is a tree-ball. + +Exact rooted-tree counts identify first-level cones as the $t=1$ path tubes and show that the length-$t$ tubes partition the outer ball. Conditional on the prescribed path continuing, a witness's initial depth determines a potential capture or blockage time within the horizon or certifies descendant pressure throughout it. This yields a persistence theorem uniform over all length-$t$ nonbacktracking paths starting at $v_0$, and only over that class. + +The next results quantify the price of exhaustive static coverage. Exactly +\[ +N_t=d(d-1)^{t-1} +\] +cops are necessary and sufficient to occupy every tube at a fixed root. Along fixed-degree sequences with $t\to\infty$, conditional uniform sampling has a threshold of order $N_t\log N_t$; its leading factor depends explicitly on $R-t$ and tends to $1$ when $R-t\to\infty$. + +Finally, Section~\ref{sec:profile-loss} records information lost by finite-order tube profiles. Even after retaining every shallow cop multiplicity, such a profile need not determine branch support after $r+1$ rounds. This exact nondeterminacy does not rule out one-sided certificates that reject ambiguous profile fibers. + +\section{Cone and Tube Counts} + +\begin{lemma}[Sharp shell and cone counts] +\label{lem:shell} +Let $G$ be $d$-regular with $d\geq3$, and suppose $B_r(v)$ is a tree-ball. Then for every $u\in N(v)$ and $1\leq j\leq r$, +\[ +|C_u(v,r)\cap S_j(v)|=(d-1)^{j-1}, +\qquad +|S_j(v)|=d(d-1)^{j-1}. +\] +Hence +\[ +|C_u(v,r)|=\sum_{j=1}^r(d-1)^{j-1} +=\frac{(d-1)^r-1}{d-2}, +\] +and +\[ +|B_r(v)|=1+d\frac{(d-1)^r-1}{d-2}. +\] +\end{lemma} + +\begin{proof} +The branch rooted at $u$ is a $(d-1)$-ary rooted tree of depth $r-1$. Its level $j-1$ contains $(d-1)^{j-1}$ vertices, giving the first formula. Summing over the $d$ branches gives the shell count, and the remaining identities follow by summing the geometric series. +\end{proof} + +For $t=1$, geodesic cones are exactly the path tubes. We now count the general length-$t$ objects that drive the persistence argument. + + +\begin{lemma}[Tube count and partition] +\label{lem:tube-partition} +Let $R\geq t$, and suppose $B_R(v_0)$ is a tree-ball. For every length-$t$ nonbacktracking path $\sigma$ starting at $v_0$, +\[ +|T_\sigma(R)| +=\sum_{j=t}^R(d-1)^{j-t} +=\frac{(d-1)^{R-t+1}-1}{d-2}. +\] +The length-$t$ tubes are pairwise disjoint and form a partition +\[ +B_R(v_0)\setminus B_{t-1}(v_0) +=\bigsqcup_{\sigma}T_\sigma(R), +\] +where $\sigma$ ranges over all length-$t$ nonbacktracking paths from $v_0$. Their number is +\[ +N_t=d(d-1)^{t-1}. +\] +\end{lemma} + +\begin{proof} +At total depth $j\geq t$, the descendants of the terminal vertex $v_t$ form the depth-$(j-t)$ level of a $(d-1)$-ary rooted tree and hence contribute $(d-1)^{j-t}$ vertices. Summing gives the tube size. + +Every vertex of depth at least $t$ has a unique rooted prefix of length $t$, so it lies in exactly one tube. The first edge of such a prefix has $d$ choices, and every later edge has $d-1$ choices, giving $N_t=d(d-1)^{t-1}$. +\end{proof} + +For a fixed rooted tree-ball $(G,v_0,R)$, after the root has been specified, let $C$ be uniform on $B_R(v_0)$. The probability that $C$ lies in a prescribed length-$t$ tube is +\[ +q_{t,R}:=\Pr(C\in T_\sigma(R)\mid G,v_0,R) +=\frac{|T_\sigma(R)|}{|B_R(v_0)|}. +\] +The partition gives the exact identity +\begin{equation} +\label{eq:tube-mass} +N_tq_{t,R} +=1-\frac{|B_{t-1}(v_0)|}{|B_R(v_0)|}. +\end{equation} +Put $h=R-t$ and $b=d-1$. Lemmas~\ref{lem:shell} and~\ref{lem:tube-partition} give +\[ +q_{t,R}=\frac{b^{h+1}-1}{(b+1)b^{t+h}-2} +\] +and +\[ +\frac{1}{N_tq_{t,R}} +=\frac{b^{h+1}-2/((b+1)b^{t-1})}{b^{h+1}-1} +=\frac{1}{1-b^{-(h+1)}}+O(b^{-t}), +\] +uniformly for $h\geq0$. Thus $q_{t,R}=\Theta(N_t^{-1})$ uniformly over $R\geq t$, but its leading constant depends on $R-t$ when that difference remains bounded. + +\section{Path-Tube Persistence} + +\subsection{The interception schedule} + +\begin{lemma}[Interception schedule along a tube] +\label{lem:interception} +Let $R\geq t$, suppose $B_R(v_0)$ is a tree-ball, and let +\[ +\sigma=(v_0,v_1,\ldots,v_t) +\] +be a length-$t$ nonbacktracking path starting at $v_0$. Let a cop start at $c\in T_\sigma(R)$ at depth $j=\dist(c,v_0)$. Suppose the robber follows $\sigma$ for as long as the path survives. For every $s\in\{1,\ldots,t\}$ such that the path has survived through round $s-1$, after the cop move in round $s$: +\begin{enumerate}[label=(\roman*)] +\item if $j=2s-1$, the cop reaches $v_{s-1}$ and captures the robber; +\item if $j=2s$, the cop reaches $v_s$ and blocks the intended move; +\item if $j\geq2s+1$, the cop remains a strict descendant of $v_s$. +\end{enumerate} +The alternative $j\leq2s-2$ cannot occur: in that case the path was already captured or blocked by the end of round $s-1$. +\end{lemma} + +\begin{proof} +Set $s_*=\lceil j/2\rceil$. For every reached round $k\leq\min\{s_*,t\}$, an induction shows that before the cop move the cop is a descendant of $v_{k-1}$ and has depth $j-k+1$. This is true at $k=1$. At round $k$, the endpoint-depth sum for the cop and $v_{k-1}$ is $j$, while their rooted-path length is $j-2k+2$. Hence the left side of Lemma~\ref{lem:buffer}'s inequality, with $q=R$, is +\[ +j+(j-2k+2)=2(j-k+1)\leq2j\leq2R. +\] +The rooted path is therefore the unique ambient geodesic, and the cop moves one step toward $v_0$, to depth $j-k$. If $kt$, that time lies beyond the horizon and the cop remains descendant pressure throughout the first $t$ reached rounds. +\end{remark} + +\subsection{Persistence along nonbacktracking paths} + +\begin{theorem}[Nonbacktracking path-tube persistence] +\label{thm:persistence} +Let $d\geq3$ and $1\leq t\leq R$, suppose $B_R(v_0)$ is a tree-ball, and let $X_0$ be any initial cop configuration satisfying +\[ +X_0(T_\sigma(R))\geq1 +\] +for every length-$t$ tube. Cops outside $B_R(v_0)$ are permitted; the proof ignores them unless they cause capture, blockage, or additional branch support. If $X_0(\{v_0\})>0$, the robber is captured before any move. Otherwise, let +\[ +\tau=(v_0,v_1,\ldots,v_t) +\] +be any length-$t$ nonbacktracking path starting at $v_0$. At every round $s\in\{1,\ldots,t\}$ for which the robber has followed $\tau$ through round $s-1$, at least one of the following occurs during round $s$: +\begin{enumerate}[label=(\alph*)] +\item on the cops' move, a cop captures the robber at $v_{s-1}$; +\item after the cops' move, the robber is not captured, but a cop occupies $v_s$, so the intended move is illegal; +\item the move to $v_s$ is legal, and after that move the branch-load support at $v_s$ has size at least $2$. +\end{enumerate} +\end{theorem} + +\begin{proof} +Assume there was no initial capture, and fix a round $s$ reached along $\tau$. If a cop reaches $v_{s-1}$, then (a) holds. If no cop captures the robber but a cop occupies $v_s$, then (b) holds. Assume instead that the move to $v_s$ is legal and produce two branch witnesses. + +\emph{Descendant witness.} +Choose a cop $c^\downarrow$ from $T_\tau(R)$ and let $j_\downarrow$ be its initial depth. Survival through round $s-1$ rules out $j_\downarrow\leq2s-2$, while the failure of alternatives~(a) and~(b) rules out $j_\downarrow\in\{2s-1,2s\}$. Hence $j_\downarrow\geq2s+1$, and Lemma~\ref{lem:interception} implies that after the round-$s$ cop move it is a strict descendant of $v_s$, at depth $j_\downarrow-s$. Its rooted path to $v_s$ has length $j_\downarrow-2s$, so the endpoint-depth sum plus this length is +\[ +(j_\downarrow-s)+s+(j_\downarrow-2s) +=2(j_\downarrow-s)\leq2R. +\] +Lemma~\ref{lem:buffer}, with $q=R$, makes this the unique ambient geodesic. Thus the cop contributes to a child branch of $v_s$. + +\emph{Parent witness.} +Choose $u_0\in N(v_0)\setminus\{v_1\}$, extend $(v_0,u_0)$ to a length-$t$ nonbacktracking path $\sigma'$, and choose a cop $c^\uparrow\in T_{\sigma'}(R)$ of initial depth $j$. Then $R\geq j\geq t\geq s$. We prove by induction on $k\in\{1,\ldots,s\}$ that before its move in round $k$, the cop has depth $j-k+1$ and lies in the root branch through $u_0$. This is immediate for $k=1$. At round $k$, the rooted path from the cop to $v_{k-1}$ passes through $v_0$; both its length and the sum of the endpoint depths equal +\[ +(j-k+1)+(k-1)=j. +\] +Lemma~\ref{lem:buffer}, with $q=R$, therefore forces one step toward $v_0$. If $k0$. If $(m_n)$ is polylogarithmic and $\Pr(\mathcal C_n)\to1$, then $t_n=O(\log\log n)$. If $t_n=\Theta(\log n)$ and $\Pr(\mathcal C_n)\to1$, then +\[ +m_n=\Omega(N_{t_n}\log N_{t_n}), +\qquad +N_{t_n}=d(d-1)^{t_n-1}; +\] +in particular, $m_n\geq n^c$ eventually for some $c>0$. +\end{corollary} + +\begin{proof} +If $t_n\neq O(\log\log n)$, pass to a subsequence on which $t_n/\log\log n\to\infty$, and then to a further subsequence on which $t_n$ is strictly increasing. Apply the proof of Theorem~\ref{thm:sampling-threshold} along this subsequence, with $t$ replaced by $t_n$. Now $t_n\to\infty$ and $N_{t_n}=(\log n)^{\omega(1)}$. Because the threshold is $\Theta(N_{t_n}\log N_{t_n})$ uniformly in $R_n\geq t_n$, polylogarithmic $m_n$ satisfies +\[ +m_n\leq\frac12\frac{\log N_{t_n}}{q_n} +\] +eventually on this subsequence, where $q_n$ is the common tube mass. Part~(ii) of Theorem~\ref{thm:sampling-threshold}, with $\varepsilon=1/2$, then gives $\Pr(\mathcal C_n)\to0$, a contradiction. Hence $t_n=O(\log\log n)$. + +If $t_n=\Theta(\log n)$ and $m_n=o(N_{t_n}\log N_{t_n})$ along a subsequence, pass if necessary to a further subsequence with strictly increasing horizons and apply the same subsequence argument. This contradicts $\Pr(\mathcal C_n)\to1$. Thus $m_n=\Omega(N_{t_n}\log N_{t_n})$. Since $N_{t_n}=n^{\Omega(1)}$, this is at least $n^c$ eventually for some $c>0$. +\end{proof} + +\begin{remark}[Partial coverage is cheaper] +\label{rem:partial-coverage} +At one fixed, known root, the expected fraction of length-$t$ tubes occupied by $m$ independent uniform samples is +\[ +1-(1-q_{t,R})^m. +\] +Since $q_{t,R}=\Theta(N_t^{-1})$, $m=\Theta(N_t)$ samples occupy a fixed positive fraction of the tubes in expectation, while $m=\omega(N_t)$ occupies a $1-o(1)$ fraction in expectation. Under uniform sampling, reducing the expected number of empty tubes to $O(1)$ requires $\Theta(N_t\log N_t)$ samples; the same order is required to leave at most $O(1)$ tubes empty with probability tending to one. These are occupancy statements only: they give neither an adversarial guarantee over all paths from that root nor a root-independent placement, and they do not show that partial coverage supports an adaptive chase. +\end{remark} + +\section{Information Loss in Tube Profiles} +\label{sec:profile-loss} + +Fix integers $Q\geq r\geq1$ and $k\geq0$, and suppose $B_Q(v_0)$ is a tree-ball. Let $\mathcal P_r(v_0)$ be the set of length-$r$ nonbacktracking paths starting at $v_0$, and let +\[ +\mathcal C_{Q,k}(v_0) +:=\{X: X\text{ is a $k$-cop multiset with }\supp(X)\subseteq B_Q(v_0)\}. +\] +For $X\in\mathcal C_{Q,k}(v_0)$, $\sigma\in\mathcal P_r(v_0)$, and $r\leq j\leq Q$, set +\[ +N_X(\sigma,j) +:=\sum_{\substack{x\in S_j(v_0)\\ +\text{the rooted path from $v_0$ to $x$ begins with }\sigma}}X(x). +\] +The \emph{augmented order-$r$ tube profile} is +\[ +\Pi_{r;Q,k}(X) +:=\left( +\bigl(X(x)\bigr)_{x\in B_{r-1}(v_0)}, +\bigl(N_X(\sigma,j)\bigr)_{\substack{\sigma\in\mathcal P_r(v_0)\\ r\leq j\leq Q}} +\right). +\] +It records the complete configuration through depth $r-1$ and the exact depth histogram in every length-$r$ tube; the $j=r$ coordinates also recover the multiplicities at depth $r$. It forgets only how cops at a fixed greater depth split among descendants below the terminal vertex of a length-$r$ prefix. For an admissible profile $P$, define its fixed-universe fiber by +\[ +\mathcal F_{r;Q,k}(P) +:=\{X\in\mathcal C_{Q,k}(v_0):\Pi_{r;Q,k}(X)=P\}. +\] + +\begin{proposition}[Augmented tube profiles do not determine later support] +\label{prop:profile-nondeterminacy} +Fix $d\geq3$ and $r\geq1$, put $Q=2r+3$, and suppose $B_Q(v_0)$ is a tree-ball. There exist $X,Y\in\mathcal C_{Q,2}(v_0)$ and a length-$(r+1)$ nonbacktracking path $\tau=(v_0,\ldots,v_{r+1})$ such that +\[ +\Pi_{r;Q,2}(X)=\Pi_{r;Q,2}(Y). +\] +The path survives all $r+1$ rounds from both configurations, with all relevant cop moves unique, but immediately after the robber's legal move to $v_{r+1}$ the branch-load supports in $X$ and $Y$ have sizes $2$ and $1$, respectively. Hence, for this fixed path $\tau$, the predicate that the branch-load support after $r+1$ safe rounds has size at least $2$ does not factor through $\Pi_{r;Q,2}$. +\end{proposition} + +\begin{proof} +Choose $\tau$ and two distinct children $a,b$ of $v_{r+1}$. Choose descendants $x_a$ of $a$ and $x_b$ of $b$ at total depth $Q=2r+3$ from $v_0$, and choose two distinct descendants $y_a,y_a'$ of $a$ at the same total depth. Such choices exist because the vertices at descendant-distance $r+1$ below $a$ number $(d-1)^{r+1}\geq2$. Define +\[ +X=[x_a,x_b], +\qquad +Y=[y_a,y_a']. +\] +Both configurations have zero multiplicity on $B_{r-1}(v_0)$, and their only nonzero tube-depth coordinate is the cell indexed by $((v_0,\ldots,v_r),Q)$, where both have value $2$. Thus their augmented profiles agree. + +Every robber position on $\tau$ is an ancestor of every cop in the construction. Immediately before the cop move in round $s$, each cop has total depth $Q-s+1$, while the robber is at $v_{s-1}$. Their rooted path has length $Q-2s+2$, and +\[ +(Q-s+1)+(s-1)+(Q-2s+2)=2Q-2s+2\leq2Q. +\] +Lemma~\ref{lem:buffer}, with $q=Q$, therefore makes this path the unique ambient geodesic and forces one step upward. After that move, the cop's distances to $v_{s-1}$ and $v_s$ are +\[ +2r+4-2s\geq2 +\qquad\text{and}\qquad +2r+3-2s\geq1 +\] +for $1\leq s\leq r+1$. Thus no capture or blockage occurs. After $r+1$ cop moves, the configurations are $[a,b]$ and $[a,a]$, so the branch-load support sizes after the robber moves to $v_{r+1}$ are $2$ and $1$. +\end{proof} + +For $r=1$, the profile includes the multiplicity at $v_0$ as well as the depth histogram in every first-level tube, yet it still does not determine the two-round outcome. Proposition~\ref{prop:profile-nondeterminacy} identifies one ambiguous fiber, not a barrier to every one-sided certificate: a sound certificate may reject that fiber. + +\section{Limitations and Further Directions} +\label{sec:open} + +The present arguments do not address five natural directions; no claim of novelty is made for the questions themselves. + +\subsection{Arbitrary robber walks} + +Theorem~\ref{thm:persistence} treats only length-$t$ nonbacktracking paths starting at $v_0$. Stationary moves and reversals destroy the monotone depth evolution used by the interception schedule. + +\begin{question} +Can a static or adaptive local certificate give an analogue of Theorem~\ref{thm:persistence} for arbitrary length-$t$ robber walks from $v_0$, including stationary moves and reversals? How do repeated vertices and reversed edges change the required witnesses and coverage cost? +\end{question} + +\subsection{Partial and adaptive coverage} + +Remark~\ref{rem:partial-coverage} separates partial from exhaustive conditional coverage at one fixed root. Along a prescribed nonbacktracking path, the persistence proof uses its occupied tube for the descendant witness and a tube with a different first edge for the parent witness; exhaustive coverage supplies both uniformly. A large expected covered fraction alone gives no persistence or adaptive-chase guarantee. + +\begin{question} +For a fixed horizon $t$, is there a condition strictly weaker than occupancy of every length-$t$ tube that guarantees capture or a quantified decrease in the number of compatible future nonbacktracking continuations? Can it be updated after each move by reusing witnesses among tubes with a common shorter prefix? +\end{question} + +\subsection{Uniformly favorable augmented-profile fibers} + +Fix integers $Q\geq r+1\geq2$ and $k\geq1$, suppose $B_Q(v_0)$ is a tree-ball, and fix a length-$(r+1)$ nonbacktracking path $\tau=(v_0,\ldots,v_{r+1})$. The graph, root, radius, cop number, allowed support region, and allowed distance-minimizing tie-breaks are thereby fixed. + +\begin{question} +For which admissible profiles $P$ do both of the following hold? +\begin{enumerate}[label=(\roman*)] +\item Some $X\in\mathcal F_{r;Q,k}(P)$ and some allowed sequence of cop moves let $\tau$ survive through round $r+1$. +\item For every $X\in\mathcal F_{r;Q,k}(P)$ and every allowed sequence of cop moves, the robber is captured or blocked by round $r+1$, or $\tau$ survives and its final branch-load support has size at least $2$. +\end{enumerate} +\end{question} + +\subsection{Global overlap of tube systems} + +Fix a graph $G$, integers $R\geq t\geq1$, a set $A$ of admissible roots whose radius-$R$ balls are tree-balls, and a root-independent set $W$ of allowed cop locations. For $v\in A$ and a length-$t$ nonbacktracking path $\sigma$ from $v$, write $T_\sigma^v(R)$ for its rooted tube. Define the global tube hypergraph +\[ +\mathcal H_{R,t}(G,A;W) +:=\left(W,\{T_\sigma^v(R)\cap W:v\in A,\ \sigma\text{ is a length-$t$ nonbacktracking path from }v\}\right). +\] +A root-independent set of cop positions supplies the exhaustive tube certificate simultaneously for every $v\in A$ exactly when it is a transversal of $\mathcal H_{R,t}$. This is the local-to-global gap absent from the conditional sampling theorem; multiplicity at an already selected vertex does not improve coverage. + +\begin{question} +How do girth, expansion, and nonbacktracking path counts bound the transversal number, fractional transversal number, and codegrees of $\mathcal H_{R,t}$? Can these estimates produce a root-independent placement with controlled cost? +\end{question} + +\subsection{Beyond exact tree-balls} + +The persistence proof uses only the unique geodesics of synchronized witnesses inside $B_R(v_0)$. With cycles, rooted branches would have to give way to a shortest-path directed acyclic graph in which paths may split or merge. No persistence theorem or coverage bound is proved in that setting. + +\begin{question} +For a radius-$R$ ball obtained from a tree by adding one edge, can geodesic tubes and branch-load support be replaced by notions for which an analogue of Theorem~\ref{thm:persistence} holds? More generally, how do the answer and the minimum exhaustive-coverage cost depend on bounded tree excess? +\end{question} + +\section{Conclusion} + +We analyzed a local certificate indexed by length-$t$ nonbacktracking robber paths starting at a fixed root $v_0$ in radius-$R$ tree-ball geometry. The larger radius $R+t$ is sharp, among possibly infinite $d$-regular graphs, for uniform control of arbitrary endpoint pairs, but the synchronized chase witnesses require only $B_R(v_0)$. The length-$t$ tubes partition the outer ball into $N_t=d(d-1)^{t-1}$ parts, and occupying every tube gives the stated capture, blockage, or two-branch-support alternative along every prescribed path in this class. + +At one fixed root the deterministic occupancy cost is $N_t$. Along fixed-degree rooted sequences with $t\to\infty$, the conditional uniform-sampling threshold is +\[ +\left(\frac{1}{1-(d-1)^{-(h_t+1)}}+o(1)\right)N_t\log N_t, +\qquad h_t=R_t-t. +\] +Because the sampling distribution is chosen after the root, it is not a legal standard-game initial placement and gives no cop-number bound. The arbitrary-walk, partial/adaptive, global, augmented-profile, and cyclic directions above are not addressed by the present results. + +\section*{Acknowledgments} +I warmly thank Eric Jovinelly, who led me through Graph Theory at Brown and greatly assisted me in building both graph-theoretic and broader mathematical skills and intuition. I also thank my peers in the Spring 2026 S02 of Graph Theory at Brown. + +\begin{thebibliography}{99} + +\bibitem{AignerFromme} +M.~Aigner and M.~Fromme, +\emph{A game of cops and robbers}, +Discrete Applied Mathematics, vol.~8, no.~1, 1984, pp.~1--12. + +\bibitem{BradshawHosseiniMoharStacho} +P.~Bradshaw, S.~A.~Hosseini, B.~Mohar, and L.~Stacho, +\emph{On the cop number of graphs of high girth}, +Journal of Graph Theory, vol.~102, no.~1, 2023, pp.~15--34. + +\bibitem{Frankl} +P.~Frankl, +\emph{Cops and robbers in graphs with large girth and Cayley graphs}, +Discrete Applied Mathematics, vol.~17, no.~3, 1987, pp.~301--305. + +\bibitem{FriezeKrivelevichLoh} +A.~Frieze, M.~Krivelevich, and P.-S.~Loh, +\emph{Variations on cops and robbers}, +Journal of Graph Theory, vol.~69, no.~4, 2012, pp.~383--402. + +\bibitem{HMG} +S.~A.~Hosseini, B.~Mohar, and S.~Gonzalez Hermosillo de la Maza, +\emph{Meyniel's conjecture on graphs of bounded degree}, +Journal of Graph Theory, vol.~97, no.~3, 2021, pp.~401--407. + +\bibitem{LuPeng} +L.~Lu and X.~Peng, +\emph{On Meyniel's conjecture of the cop number}, +Journal of Graph Theory, vol.~71, no.~2, 2012, pp.~192--205. + +\bibitem{NowakowskiWinkler} +R.~Nowakowski and P.~Winkler, +\emph{Vertex-to-vertex pursuit in a graph}, +Discrete Mathematics, vol.~43, nos.~2--3, 1983, pp.~235--239. + +\bibitem{PralatWormald} +P.~Pra\l at and N.~Wormald, +\emph{Meyniel's conjecture holds for random graphs}, +Random Structures \& Algorithms, vol.~48, no.~2, 2016, pp.~396--421. + +\bibitem{Quilliot} +A.~Quilliot, +\emph{Jeux et points fixes sur les graphes}, +Th\`ese de 3\`eme cycle, Universit\'e de Paris~VI, 1978. + +\bibitem{ScottSudakov} +A.~Scott and B.~Sudakov, +\emph{A bound for the cops and robbers problem}, +SIAM Journal on Discrete Mathematics, vol.~25, no.~3, 2011, pp.~1438--1442. + +\end{thebibliography} + +\end{document} diff --git a/paper/near-critical-growing-radius-domination-paper.tex b/paper/near-critical-growing-radius-domination-paper.tex new file mode 100644 index 0000000..ffcb1c9 --- /dev/null +++ b/paper/near-critical-growing-radius-domination-paper.tex @@ -0,0 +1,2545 @@ +\documentclass[11pt]{amsart} +\usepackage[margin=1in]{geometry} +\usepackage{amsmath,amssymb,amsthm,mathtools} +\usepackage{booktabs} +\usepackage{enumitem} +\usepackage{xcolor} +\usepackage{hyperref} +\usepackage{microtype} +\usepackage[T1]{fontenc} +\usepackage{lmodern} + +\newtheorem{theorem}{Theorem}[section] +\newtheorem{proposition}[theorem]{Proposition} +\newtheorem{lemma}[theorem]{Lemma} +\newtheorem{corollary}[theorem]{Corollary} +\theoremstyle{definition} +\newtheorem{definition}[theorem]{Definition} +\newtheorem{remark}[theorem]{Remark} + +\newcommand{\eps}{\varepsilon} +\newcommand{\Fcal}{\mathcal F} +\newcommand{\Pcal}{\mathcal P} +\newcommand{\Dcal}{\mathcal D} +\newcommand{\E}{\mathbb E} +\newcommand{\Prb}{\mathbb P} +\newcommand{\R}{\mathbb R} + +\hypersetup{ + colorlinks=true, + linkcolor=blue!50!black, + citecolor=blue!50!black, + urlcolor=blue!50!black, + pdftitle={The Annealed Critical Window for Growing-Radius Domination in Random Regular Graphs}, + pdfauthor={Levi Neuwirth}, + pdfsubject={Growing-radius domination and random regular graphs}, + pdfkeywords={random regular graphs, domination, configuration model, method of types, first moment} +} + +\title[The Annealed Critical Window for Growing-Radius Domination]{The Annealed Critical Window for\\Growing-Radius Domination in Random Regular Graphs} +\author{Levi Neuwirth} +\address{Brown University} +\date{July 24, 2026} +\keywords{random regular graphs, domination, configuration model, method of types, first moment} + +\begin{document} + +\begin{abstract} +Fix $d\ge3$ and let +\[ + B_h=1+d\frac{(d-1)^h-1}{d-2} +\] +be the radius-$h$ volume of the infinite $d$-regular tree. We determine the bounded annealed critical window for distance-$h$ domination in the random $d$-regular configuration model. Writing $L_h=\log B_h$, uniformly for bounded $s$ we prove +\[ + \frac{B_h}{L_h^2} + \Psi_{d,h}\!\left( + \frac{L_h-2\log L_h+s}{B_h} + \right) + \longrightarrow 1-e^{-s}, +\] +where $\Psi_{d,h}$ is the exact microcanonical first-moment exponent. Equivalently, +\[ + H(\alpha)-\Psi_{d,h}(\alpha) + =(1-\alpha)^{B_h}(1+o(1)) +\] +throughout the critical window. The lower zero is pinned within +$B_h^{-1/7+o(1)}$ of the scalar coupon root +$H(C/B_h)=(1-C/B_h)^{B_h}$ and therefore has a complete fixed-order inverse-logarithmic expansion; in particular, +\[ + B_h\alpha_h^{\rm ann} + =L_h-2\log L_h + +\frac{3\log L_h-1}{L_h} + +O\!\left(\frac{(\log L_h)^2}{L_h^2}\right). +\] +Consequently, for every fixed $\omega>0$ and the stated growth condition, a uniformly random simple $d$-regular graph satisfies +\[ + \gamma_h(G_{n,d})\ge + \frac n{B_h} + \bigl(L_h-2\log L_h-\omega\bigr) +\] +with high probability. + +The proof uses exact graph-distance labels, a two-sided method-of-types count, and an exact reduction to a compact tridiagonal variational functional. Although that functional is nonconcave, boundary repulsion and a monotone reverse transfer identify its unique global optimizer. Quantitative stable/free shadowing gives the activity law at the required scale. The new upper half of the critical-window argument comes from an explicit capped-free profile: all nonterminal layers retain the free Bernoulli entropy, and the entire entropy defect is the cost of one terminal nonemptiness conditioning event. The result also transfers as a lower bound to internally two-path $(h,2)$ domination. It remains annealed: quenched matching and the direct two-branch leading constant are open. +\end{abstract} + +\maketitle + +\noindent\textbf{Keywords.} random regular graphs; domination number; growing-radius domination; configuration model; method of types; belief propagation; first moment. + +\section{Introduction and related work}\label{sec:intro} + +\subsection{Main result and scale} +A set $S\subseteq V(G)$ is \emph{distance-$h$ dominating} if every vertex of $G$ lies within graph distance $h$ of $S$; its minimum size is denoted $\gamma_h(G)$. For graphs of maximum degree $d$, one selected vertex can cover at most +\[ + B_h=1+d\frac{(d-1)^h-1}{d-2} +\] +vertices, so the elementary volume bound is $\gamma_h(G)\ge n/B_h$. In ideal tree-ball geometry, independent selection and patching place the natural covering scale at $n\log B_h/B_h$. + +The first-moment balance is subtler than the leading scale. If $\alpha=C/B_h$, subset entropy is approximately +$C(\log B_h-\log C+1)/B_h$, while the probability that a tree ball is missed is approximately $e^{-C}$. Equating these terms predicts +\[ + C=\log B_h-2\log\log B_h+O(1). +\] +The present paper determines that bounded annealed window and its entire limiting profile. With $L_h=\log B_h$, uniformly for bounded $s$, +\[ + \frac{B_h}{L_h^2} + \Psi_{d,h}\!\left( + \frac{L_h-2\log L_h+s}{B_h} + \right) + \longrightarrow 1-e^{-s}. +\] +Thus the annealed exponent changes sign at $s=0$, and its lower zero is governed, to power accuracy in $B_h$, by the scalar equation +\[ + H(C/B_h)=(1-C/B_h)^{B_h}. +\] +This gives not only the first two terms but the complete fixed-order inverse-logarithmic expansion of the annealed transition. + +For the random graph itself, the first moment yields a fixed-slack lower theorem: for every fixed $\omega>0$, subject to +\[ + \frac{n(\log B_h)^2}{B_h}\gg h\log n, +\] +one has with high probability +\[ + \gamma_h(G_{n,d})\ge + \frac n{B_h} + \bigl(\log B_h-2\log\log B_h-\omega\bigr). +\] +At the comparison scale $B_h\asymp\sqrt n$, this is +\[ + \gamma_h(G_{n,d})\ge + \frac n{B_h} + \bigl(\tfrac12\log n-2\log\log n-\omega+O(1)\bigr) + =\Omega(\sqrt n\log n). +\] +This is an annealed lower transition, not a quenched matching theorem. Proving the existence of dominating sets at the same coordinate remains separate. + +The comparison scale is also relevant to pursuit-evasion: Meyniel's conjecture predicts that $O(\sqrt n)$ cops suffice in every connected $n$-vertex graph~\cite{LuPeng2012,ScottSudakov2011}, and it is known for several random-graph models, including random regular graphs~\cite{PralatWormald2016,PralatWormald2019}. Our conclusion is not a cop-number lower bound. It says that one particular static exhaustive coverage mechanism can require a logarithmic factor more than the Meyniel scale. + +\subsection{Why the first moment is difficult} +For an independent random subset of density $\alpha$, a fixed tree-like radius-$h$ ball is missed with probability approximately $(1-\alpha)^{B_h}$. Balancing subset entropy against this coupon term predicts the coordinate +\[ + \alpha B_h\approx \log B_h-2\log\log B_h. +\] +Turning that heuristic into a theorem is not a product-measure calculation. In the configuration model, coverage events for different vertices overlap heavily, and optimizing over the selected set allows highly organized profiles. A direct bounded-differences argument is also ineffective in the growing-radius regime: changing one pairing can alter the radius-$h$ coverage status of order $B_h$ vertices, so the natural Lipschitz constant grows on exactly the scale that must be resolved. + +The key device is to label every vertex by its \emph{exact} distance to the candidate set. Local consistency of these labels---adjacent labels differ by at most one, and every positive label has a neighbor one level lower---forces them to be genuine graph distances on any graph. This removes the need to approximate neighborhoods by trees and converts the first moment into an exact finite-dimensional method-of-types problem. The price is a nonconcave variational functional whose global optimizer must be identified uniformly as the number of distance levels grows. + +\subsection{Related work} +The configuration or pairing model and its transfer to uniformly random simple regular graphs are standard; see Wormald's survey~\cite{Wormald1999} and Janson's simplicity theorem~\cite{Janson2009}. Fixed-radius domination in random regular graphs has been studied algorithmically: Duckworth analyzed randomized greedy algorithms for distance-$k$ dominating sets~\cite{Duckworth2005}, while Duckworth and Wormald treated independent domination~\cite{DuckworthWormald2006}. The broader covering viewpoint is classical in coding theory~\cite{CohenHonkalaLitsynLobstein1997}. + +The closest message-passing antecedents are statistical-mechanical. Zhao, Habibulla, and Zhou developed a cavity-method and belief-propagation treatment of minimum dominating sets~\cite{ZhaoHabibullaZhou2015}; Habibulla and Qin studied a distance-two version with distance-labeled messages~\cite{HabibullaQin2019}. Those works are replica-symmetric and fixed-radius. The transfer equations below are closely related in spirit; the distinctions here are the exact graph-level type count, the proof of global optimization, and the growing-radius asymptotics. + +Cutler and Radcliffe used Shearer entropy to obtain universal extremal bounds for domination polynomials of regular graphs~\cite{CutlerRadcliffe2016}. Such universal bounds cannot by themselves detect the random-covering penalty: structured regular graphs may admit efficient covering codes. In the binomial random graph, Glebov, Liebenau, and Szab\'o proved two-point concentration at the first-moment threshold in a sufficiently dense regime~\cite{GlebovLiebenauSzabo2015}. That result motivates, but does not supply, the corresponding quenched statement for random regular graphs. + +The pursuit application comes from branch-based local coverage. Aigner and Fromme introduced the multiple-cop game in its modern graph-theoretic form~\cite{AignerFromme1984}; Pra\l at and Wormald later combined random placement with deterministic pursuit in random graphs~\cite{PralatWormald2016,PralatWormald2019}. The local tube certificate in~\cite[Theorem~3.3 and Section~6.4]{Neuwirth2026Tube} motivates a root-independent two-witness covering problem. Section~\ref{subsec:tube-connection} states the exact graph-general parameter used here and carefully limits the resulting obstruction. + +\subsection{Proof architecture and contributions} +The proof has four acts. + +\paragraph{Act I: exact types and a compact functional.} +Exact distance labels produce a two-sided type estimate +\[ + \log \E N_{\mathbf n} + =n\Phi_{d,h}(\mathbf n/n)+O_d(h\log n). +\] +Optimizing the local profile entropy at fixed tridiagonal edge masses reduces $\Phi_{d,h}$ exactly to a compact functional $\Fcal_{d,h}$ in $2h+1$ variables. The lower side of the type estimate also yields the pointwise entropy anchor +$\Psi_{d,h}(\alpha)\le H(\alpha)$. + +\paragraph{Act II: globality without concavity.} +The compact functional is genuinely nonconcave. Nevertheless, entropy singularities repel every maximizing profile from the boundary. Interior KKT points are equivalent to positive message solutions. An exact reverse transfer reconstructs every positive stationary solution from one terminal parameter, and the associated activity is strictly increasing from $0$ to $\infty$. Hence the grand-canonical optimizer is unique at every activity, and duality gives +\[ + \Psi_{d,h}(\alpha)=\Psi^{\mathrm{stat}}_{d,h}(\alpha), + \qquad + \Psi_{d,h}'(\alpha)=-\log z(\alpha). +\] + +\paragraph{Act III: quantitative orbit matching.} +The reverse orbit has exact stable and free outer solutions. They overlap over linearly many levels. Retaining the actual transverse errors gives, for +$c=\alpha B_h/\log B_h<4/3$, +\[ + -\log z(\alpha)-\log\frac1\alpha + =B_h(1-\alpha)^{B_h} + \left(1+B_h^{-c/4+o(1)}\right) + +B_h^{-c/4+o(1)}. +\] +The restriction $c<4/3$ is exactly where the additive reconstruction error remains smaller than the coupon term. + +\paragraph{Act IV: one terminal conditioning cost.} +An explicit capped-free profile agrees with the free Bernoulli tree law at every nonterminal layer. Its only entropy loss comes from conditioning the terminal lower-neighbor set to be nonempty. That loss is exactly +\[ + p_h\Delta_d(\varepsilon_h), + \qquad + p_h\varepsilon_h^d=(1-\alpha)^{B_h}, + \qquad + \Delta_d(\varepsilon)=\varepsilon^d(1+o(1)). +\] +This supplies the sharp upper bound on $H-\Psi$. Integrating the quantitative activity law supplies the matching lower bound and the universal scaling function $1-e^{-s}$. + +The principal contributions are therefore: an exact growing-radius type count with no local-tree assumption; an exact compact reduction; a global solution of a nonconcave annealed variational problem; quantitative stable/free matching; and a bounded-window theorem anchored by a self-contained feasible profile. Quenched matching and direct two-branch asymptotics remain separate problems. + +\section{Models, notation, and main results}\label{sec:main} +Fix $d\ge3$ throughout and put +\[ + b=d-1,\qquad D=\frac{b+1}{b-1}=\frac d{d-2}, +\] +\begin{equation}\label{eq:Bh} + B_h=1+d\frac{b^h-1}{b-1}=Db^h-\frac2{b-1}. +\end{equation} +For a probability vector $r=(r_1,\ldots,r_k)$, write +\[ + H(r)=-\sum_{j=1}^k r_j\log r_j, +\] +with $0\log0=0$; for a scalar $a\in[0,1]$, $H(a)$ denotes the binary entropy $H(a,1-a)$. + +\begin{center} +\begin{tabular}{ll} +\toprule +Notation & Meaning\\ +\midrule +$B_h$ & maximum radius-$h$ ball volume at degree $d$\\ +$\gamma_h(G)$ & minimum size of a distance-$h$ dominating set\\ +$\Phi_{d,h}$ & full local-profile type functional\\ +$\Fcal_{d,h}$ & compact tridiagonal profile functional\\ +$\Psi_{d,h}(\alpha)$ & microcanonical annealed exponent at density $\alpha$\\ +$z=e^\theta$ & grand-canonical activity\\ +$b=d-1$, $D=d/(d-2)$ & recurring degree constants\\ +\bottomrule +\end{tabular} +\end{center} + +\begin{definition}[Internally two-path $(h,2)$ domination]\label{def:two-path} +A set $S\subseteq V(G)$ is \emph{internally two-path $(h,2)$ dominating} if every vertex $v\notin S$ has two $v$--$S$ paths of length at most $h$ whose only common vertex is $v$. In particular, the paths begin through distinct neighbors of $v$. Let $\gamma_{h,2}^{\mathrm{int}}(G)$ denote the minimum size of such a set. +\end{definition} + +Every internally two-path $(h,2)$-dominating set is distance-$h$ dominating, since either witness path alone ends in $S$ within distance $h$. Therefore +\begin{equation}\label{eq:two-path-dominates} + \gamma_{h,2}^{\mathrm{int}}(G)\ge \gamma_h(G). +\end{equation} + +\subsection{Connection with static tube coverage}\label{subsec:tube-connection} +In the tree-ball setting of~\cite{Neuwirth2026Tube}, a length-$t$ tube with residual depth $h=R-t$ depends, after the root is allowed to vary, only on its terminal directed edge. The resulting forward cone excludes one branch at its head. A root-independent set meets every such directed cone exactly when, at every unselected vertex, at least two distinct branches contain a selected vertex within distance $h$; in a tree-ball these are precisely the two internally disjoint paths of Definition~\ref{def:two-path}. Thus internally two-path domination is a graph-general strengthening of the global exhaustive tube certificate. + +Combining~\eqref{eq:two-path-dominates} with the main theorem shows that any such exhaustive static certificate has size $\Omega(\sqrt n\log n)$ at the comparison scale $B_h\asymp\sqrt n$. Meyniel's conjecture concerns the existence of a fully adaptive winning strategy with $O(\sqrt n)$ cops, so there is no contradiction: the lower bound applies only to this static exhaustive mechanism. Partial coverage, adaptive reassignment, and epoch-based pursuit remain outside the argument. + +The pairing model consists of $n$ labeled buckets of $d$ half-edges paired uniformly at random; conditioning the resulting multigraph on simplicity gives the uniformly random simple $d$-regular graph $G_{n,d}$, for $dn$ even. Let $Z_{n,d,h}(m)$ count distance-$h$ dominating $m$-sets in the pairing model. + +For a distance-$h$ dominating set $S$, assign each vertex its exact label $\operatorname{dist}(v,S)\in\{0,\ldots,h\}$. The local consistency used below is equivalent to genuine distance: adjacent labels differ by at most one, and every positive label has a neighbor one level lower. The descending condition gives a path to label zero of the displayed length, while the Lipschitz condition gives the reverse inequality. No tree-neighborhood assumption is involved. + +The type count developed below gives +\begin{equation}\label{eq:type-count-intro} + \log\E Z_{n,d,h}(m) + \le n\Psi_{d,h}(m/n)+O_d(h\log(n+1)), +\end{equation} +uniformly in $h$. Here $\Psi_{d,h}$ is the exact annealed variational exponent. + +\begin{theorem}[Bounded annealed critical window]\label{thm:bounded-critical-window} +Put $L_h=\log B_h$. For every fixed $M<\infty$, uniformly for +\[ + C=L_h-2\log L_h+s, + \qquad |s|\le M, + \qquad \alpha=C/B_h, +\] +one has +\begin{equation}\label{eq:defect-bounded-window} + H(\alpha)-\Psi_{d,h}(\alpha) + =(1-\alpha)^{B_h}\left(1+o(1)\right). +\end{equation} +More precisely, +\begin{equation}\label{eq:defect-bounded-two-sided} + 1-B_h^{-1/7+o(1)} + \le + \frac{H(\alpha)-\Psi_{d,h}(\alpha)}{(1-\alpha)^{B_h}} + \le + 1+B_h^{-(d-2)/d+o(1)}. +\end{equation} +All $o(1)$ terms are uniform over the displayed window. +\end{theorem} + +\begin{corollary}[Critical scaling function]\label{cor:critical-scaling-function} +Uniformly for bounded $s$, +\begin{equation}\label{eq:critical-scaling-function} + \boxed{ + \frac{B_h}{(\log B_h)^2} + \Psi_{d,h}\!\left( + \frac{\log B_h-2\log\log B_h+s}{B_h} + \right) + \longrightarrow 1-e^{-s}. + } +\end{equation} +\end{corollary} + +\begin{corollary}[Annealed zero and scalar expansion]\label{cor:annealed-zero-expansion} +Let +\[ + \alpha_h^{\rm ann} + =\inf\{\alpha:\Psi_{d,h}(\alpha)\ge0\}, + \qquad + C_h^{\rm ann}=B_h\alpha_h^{\rm ann}, +\] +and let $\widehat C_{B_h}$ be the solution near +$\log B_h-2\log\log B_h$ of +\begin{equation}\label{eq:scalar-coupon-root} + H(C/B_h)=(1-C/B_h)^{B_h}. +\end{equation} +Then +\begin{equation}\label{eq:graph-scalar-zero} + C_h^{\rm ann} + =\widehat C_{B_h}+O\!\left(B_h^{-1/7+o(1)}\right). +\end{equation} +Writing $L=\log B_h$ and $\ell=\log L$, +\begin{align} + C_h^{\rm ann} + ={}&L-2\ell + +\frac{3\ell-1}{L} + +\frac{5\ell^2-12\ell+3}{2L^2}\notag\\ + &+\frac{18\ell^3-81\ell^2+84\ell-17}{6L^3} + +O\!\left(\frac{\ell^4}{L^4}\right). + \label{eq:annealed-zero-expansion} +\end{align} +\end{corollary} + +\begin{theorem}[Fixed-slack random-regular lower bound]\label{thm:random-fixed-window} +Fix $\omega>0$. If $h=h(n)\to\infty$ and +\begin{equation}\label{eq:fixed-window-growth} + \frac{n(\log B_h)^2}{B_h}\gg h\log n, +\end{equation} +then, with high probability, +\begin{equation}\label{eq:random-fixed-window} + \gamma_h(G_{n,d}) + \ge + \frac n{B_h} + \left(\log B_h-2\log\log B_h-\omega\right). +\end{equation} +The same conclusion holds for every stronger feasible-set notion, including internally two-path $(h,2)$ domination. +\end{theorem} + +The following older-form consequences retain uniform information deeper in the subcritical region and will be useful for comparison. + +\begin{theorem}[Near-critical annealed negativity]\label{thm:near-critical} +Fix $\eta\in(0,1)$, put $L_h=\log B_h$, and let $W_h\to\infty$. Uniformly for real $C$ satisfying +\begin{equation}\label{eq:C-window} + \eta L_h\le C\le L_h-2\log L_h-W_h, +\end{equation} +one has +\begin{equation}\label{eq:near-critical-psi} + \Psi_{d,h}(C/B_h) + \le-\left(\frac12-o(1)\right)e^{-C} + \qquad(h\to\infty), +\end{equation} +where the $o(1)$ may depend on $d$, $\eta$, and the prescribed sequence $W_h$, but is uniform over the displayed interval. +\end{theorem} + +\begin{remark}[The coefficient $1/2$]\label{rem:half-artifact} +The coefficient $1/2$ is not predicted to be sharp. It comes from the symmetric choice of the upper integration point in Section~\ref{sec:integration}. The activity law and the diagnostics in Section~\ref{sec:numerics} are consistent with the normalized ratio approaching $1-O(e^{-W_h})$ deeper in the near-critical window. +\end{remark} + +\begin{corollary}[Fixed-fraction slack]\label{cor:fixed-slack} +For every fixed $00, + \qquad + \frac{n e^{W_h}L_h^2}{B_h}\gg h\log n. +\end{equation} +Then, with high probability, +\begin{equation}\label{eq:near-gamma-lower} + \gamma_h(G_{n,d})\ge + \frac n{B_h}\left(L_h-2\log L_h-W_h\right). +\end{equation} +The same conclusion holds for every parameter whose feasible sets are necessarily distance-$h$ dominating, including internally two-path $(h,2)$ domination. +\end{theorem} + +\begin{corollary}[Fixed-fraction random lower bound]\label{cor:random-fixed} +For every fixed $\eps\in(0,1)$, if +\[ + \frac{n}{B_h^{1-\eps}}\gg h\log n, +\] +then, with high probability, +\[ + \gamma_h(G_{n,d})\ge + (1-\eps)\frac{n\log B_h}{B_h}. +\] +\end{corollary} + +When $B_h\asymp\sqrt n$, one has $\log B_h=\tfrac12\log n+O(1)$, and Theorem~\ref{thm:random-near-critical} gives +\[ + \gamma_h(G_{n,d})\ge + \frac n{B_h}\left(\frac12\log n-2\log\log n-W_h+O(1)\right) + =\Omega(\sqrt n\log n). +\] +The implicit constant in the final order statement depends on the comparison constants in $B_h\asymp\sqrt n$; no exact prefactor $\sqrt n$ is asserted. + + +\section{Two-sided exact type counting and the entropy anchor}\label{sec:two-sided-types} +For completeness, we record the exact local-profile count that underlies both the variational formula and the pointwise entropy bound used later. + +Let $\mathcal T_{d,h}$ be the finite set of local profiles +\[ + \tau=(i,\mathbf c),\qquad + i\in\{0,\ldots,h\},\quad + \mathbf c=(c_0,\ldots,c_h),\quad + \sum_jc_j=d, +\] +with +\[ + c_j=0\quad\text{if }|i-j|>1, + \qquad + c_{i-1}\ge1\quad\text{if }i>0. +\] +For a probability vector $\xi=(\xi_\tau)_{\tau\in\mathcal T_{d,h}}$, put +\[ + q_{ij}(\xi) + =\frac1d\sum_{\tau=(i,\mathbf c)}\xi_\tau c_j, +\] +and call $\xi$ feasible when $q_{ij}=q_{ji}$. Its selected density is +\[ + \alpha(\xi)=\sum_{\tau:\,i(\tau)=0}\xi_\tau. +\] +Define +\begin{equation}\label{eq:full-profile-functional} + \Phi_{d,h}(\xi) + =-\sum_\tau\xi_\tau\log\xi_\tau + +\sum_\tau\xi_\tau\log\binom d{\mathbf c(\tau)} + +\frac d2\sum_{i,j}q_{ij}(\xi)\log q_{ij}(\xi), +\end{equation} +with $0\log0=0$. The exact variational exponent is +\[ + \Psi_{d,h}(\alpha) + =\max\{\Phi_{d,h}(\xi):\xi\text{ feasible},\ \alpha(\xi)=\alpha\}. +\] +Section~\ref{sec:compact-reduction} proves the exact reduction from this full profile functional to the compact tridiagonal functional~\eqref{eq:compact}. + +\begin{theorem}[Two-sided count for one integer type]\label{thm:two-sided-type} +There is a constant $K_d$ such that the following holds for every $h,n$ and every admissible integer profile $(n_\tau)_{\tau\in\mathcal T_{d,h}}$. Put +\[ + \xi_\tau=\frac{n_\tau}{n}, + \qquad + H_{ij}=\sum_{\tau=(i,\mathbf c)}n_\tau c_j=dnq_{ij}(\xi). +\] +Assume $\sum_\tau n_\tau=n$, $H_{ij}=H_{ji}$, and every $H_{ii}$ is even; these conditions define admissibility here. Let $N_{\mathbf n}$ denote the number of vertex sets whose exact-distance local-profile counts equal $\mathbf n$ in the $d$-regular pairing model. Then +\begin{equation}\label{eq:exact-type-count} + \E N_{\mathbf n} + =\frac{n!}{\prod_\tau n_\tau!} + \prod_\tau\binom d{\mathbf c(\tau)}^{n_\tau} + \frac{ + \displaystyle\prod_{0\le i0} + \left\{ + \log\bigl((1+\lambda)^d-1\bigr)-da\log\lambda + \right\}, + \qquad \frac1d\le a\le1. +\end{equation} +The minimizing parameter is characterized by +\begin{equation}\label{eq:sd-marginal} + a=\frac{\lambda(1+\lambda)^{d-1}}{(1+\lambda)^d-1}. +\end{equation} + + +\subsection{Exact local entropy reduction}\label{sec:compact-reduction} +The passage from the full profile functional to $\Fcal_{d,h}$ is exact. + +\begin{lemma}[Conditional-product reduction]\label{lem:compact-reduction} +Fix a symmetric tridiagonal directed-edge distribution $q$, and write $x_i,\ell_i,p_i,y_i,a_i$ as above, with $x_{h+1}=0$. Among all feasible local-profile laws inducing $q$, the maximum of the vertex entropy and arrangement terms in~\eqref{eq:full-profile-functional} is +\begin{align} + &H(p_0,\ldots,p_h) + +p_0 d\,H\!\left(\frac{\ell_0}{p_0},\frac{x_1}{p_0}\right)\notag\\ + &\quad+\sum_{i=1}^h p_i\left[ + s_d(a_i)+d(1-a_i) + H\!\left(\frac{\ell_i}{y_i},\frac{x_{i+1}}{y_i}\right) + \right].\label{eq:local-reduction} +\end{align} +The maximizing law is unique whenever all displayed masses are positive. Conditional on label $i\ge1$, the set of lower-label half-edges has the entropy-maximizing tilted nonempty-subset law with coordinate marginal $a_i$; conditional on that set, every remaining half-edge independently receives label $i$ or $i+1$ with probabilities $\ell_i/y_i$ and $x_{i+1}/y_i$. +\end{lemma} + +\begin{proof} +First expose the central label. Its entropy is $H(p_0,\ldots,p_h)$. Conditional on the central label $i$, choosing a local count vector and then assigning the $d$ labeled half-edges contributes exactly the entropy of the induced law on words of length $d$ over the allowed neighboring labels. + +For $i=0$, only labels $0$ and $1$ are allowed and their coordinate marginals are $\ell_0/p_0$ and $x_1/p_0$. Subadditivity of entropy is sharp only for independent coordinates, giving the first term of~\eqref{eq:local-reduction}. + +Fix $i\ge1$. Mark the coordinates whose neighbor label is $i-1$. Their random subset is nonempty and has common coordinate marginal +\[ + a_i=\frac{q_{i,i-1}}{p_i}=\frac{x_i}{p_i}. +\] +By definition, its entropy is at most $s_d(a_i)$, with equality for the exponential tilt +\[ + \Pr(A)\propto \lambda^{|A|},\qquad \varnothing\ne A\subseteq[d], +\] +where $\lambda$ satisfies~\eqref{eq:sd-marginal}; this also proves the dual formula~\eqref{eq:sd}. Given the lower-neighbor set, the remaining $d-|A|$ coordinates must split between labels $i$ and $i+1$. Conditional entropy is maximized by independent splitting with probabilities $\ell_i/y_i$ and $x_{i+1}/y_i$. Its expectation is +\[ + d(1-a_i)H\!\left(\frac{\ell_i}{y_i},\frac{x_{i+1}}{y_i}\right). +\] +The chain rule for entropy proves~\eqref{eq:local-reduction}; strict entropy concavity gives uniqueness in the positive interior. +\end{proof} + +\begin{proposition}[Exact compact functional]\label{prop:exact-compact} +For every feasible tridiagonal $q$, maximizing~\eqref{eq:full-profile-functional} over local-profile laws inducing $q$ gives exactly~\eqref{eq:compact}. Consequently the compact and full variational values agree at every selected density. +\end{proposition} + +\begin{proof} +Insert~\eqref{eq:local-reduction} into~\eqref{eq:full-profile-functional}. The edge term is +\[ + \frac d2\left(\sum_{i=0}^h\ell_i\log\ell_i+2\sum_{i=1}^h x_i\log x_i\right). +\] +Expanding the two categorical entropies in~\eqref{eq:local-reduction}, the $x_i\log x_i$ terms cancel against the off-diagonal edge terms. The remaining $p_i$, $y_i$, and $\ell_i$ terms collect to~\eqref{eq:compact}, including the root contribution $(d-1)p_0\log p_0$. Since every full feasible profile induces a feasible $q$ and Lemma~\ref{lem:compact-reduction} constructs a maximizing profile for every feasible $q$, the variational values coincide. +\end{proof} + +Define the feasible polytope +\[ + \Pcal_{d,h} + =\left\{(x,\ell): + x_i,\ell_i\ge0, + \ \sum_i p_i=1, + \ d x_i\ge p_i\ (1\le i\le h) + \right\}. +\] +With the convention $0\log0=0$, the exact microcanonical exponent at a profile is +\begin{equation}\label{eq:compact} +\begin{aligned} + \Fcal_{d,h}(x,\ell) + ={}&(d-1)p_0\log p_0\\ + &+\sum_{i=1}^h + \left[ + -p_i\log p_i+p_i s_d(a_i)+d y_i\log y_i + \right] + -\frac d2\sum_{i=0}^h\ell_i\log\ell_i. +\end{aligned} +\end{equation} +For activity $z=e^\theta>0$, the grand-canonical functional is +\begin{equation}\label{eq:grand-functional} + \Fcal_{d,h}^{(z)}(x,\ell) + =\Fcal_{d,h}(x,\ell)+p_0\log z. +\end{equation} +The exact variational values are +\[ + \Psi_{d,h}(\alpha) + =\max_{\substack{(x,\ell)\in\Pcal_{d,h}\\p_0=\alpha}} + \Fcal_{d,h}(x,\ell), +\] +\[ + \phi_{d,h}(z) + =\max_{(x,\ell)\in\Pcal_{d,h}} + \Fcal_{d,h}^{(z)}(x,\ell) + =\max_\alpha\{\Psi_{d,h}(\alpha)+\alpha\log z\}. +\] +The polytope is compact, so all maxima exist. + +\subsection{The feasible density interval} +The local capacities imply the Moore lower bound. First, +\[ + p_1\le d x_1\le d p_0. +\] +For $i\ge2$, symmetry and the preceding descent edge give +\[ + x_i\le p_{i-1}-x_{i-1} + \le\frac{d-1}{d}p_{i-1}, +\] +so +\[ + p_i\le d x_i\le(d-1)p_{i-1}. +\] +Therefore +\[ + 1=\sum_{i=0}^h p_i\le B_h p_0, + \qquad p_0\ge\frac1{B_h}. +\] +Equality is feasible in the type polytope: take +\[ + p_0=\frac1{B_h}, + \qquad + p_i=\frac{d(d-1)^{i-1}}{B_h}, + \qquad + x_i=\frac{(d-1)^{i-1}}{B_h}, +\] +with $\ell_i=0$ for $i0\}, +\] +and its positive support is the prefix $\{0,\dots,k\}$. + +\begin{lemma}[Relative boundary repulsion]\label{lem:relative-boundary} +Fix a finite activity $z>0$. A maximizer of $\Fcal_{d,h}^{(z)}$ cannot lie on any proper local face within its effective horizon. More precisely, if its effective horizon is $k$, then +\[ + \ell_i>0\quad(0\le i\le k), + \qquad + a_i>\frac1d\quad(1\le i\le k). +\] +In particular, $a_k<1$. +\end{lemma} + +\begin{proof} +For each $k\ge1$, a strictly interior feasible profile exists. Choose +\[ + \frac1d<\chi<\frac12, + \qquad + 00, + \quad + \ell_i=p_i-x_i-x_{i+1}>0\ (1\le i0. +\] + +Mix a proposed boundary maximizer with such an interior profile. If $a_i=1/d$, equation~\eqref{eq:sd-lower} contributes a strictly positive multiple of $t\log(1/t)$. If $\ell_i=0$, the term +\[ + -\frac d2\ell_i\log\ell_i +\] +contributes a strictly positive multiple of $t\log(1/t)$. All terms that remain away from their endpoints change by only $O(t)$. + +The only apparent negative singularity occurs if $a_k=1$, equivalently $y_k=\ell_k=0$. In that case, with $y_k(t)=\beta t+O(t^2)$ for some $\beta>0$, +\[ + p_k(t)s_d\left(1-\frac{y_k(t)}{p_k(t)}\right) + +d y_k(t)\log y_k(t)=O(t) +\] +by~\eqref{eq:sd-upper}; the two logarithmic singularities cancel. The remaining diagonal-edge term contributes +\[ + -\frac d2y_k(t)\log y_k(t) + =\frac d2\beta\,t\log\frac1t+O(t), +\] +which is strictly positive. If several faces are active simultaneously, all leading $t\log(1/t)$ coefficients are nonnegative and at least one is positive. Hence every proper relative boundary point admits an improving inward direction. +\end{proof} + +The horizon itself is also repelling. + +\begin{lemma}[Horizon extension]\label{lem:horizon-extension} +A maximizer of $\Fcal_{d,h}^{(z)}$ cannot have effective horizon $k0$, introduce a new level of mass $p_{k+1}=\tau$ with +\[ + x_{k+1}=a_*\tau, + \qquad + y_{k+1}=\ell_{k+1}=(1-a_*)\tau. +\] +Keep $p_k$ fixed by reducing $\ell_k$ by $a_*\tau$, and preserve total mass by reducing $\ell_0$ by $\tau$. All old variables remain feasible for sufficiently small $\tau$. When $k=0$, take instead +\[ + p_0=1-\tau, + \quad + x_1=a_*\tau, + \quad + \ell_0=1-(1+a_*)\tau. +\] + +The new level contributes +\[ + \left[1-\frac d2(1-a_*)\right] + \tau\log\frac1\tau+O(\tau). +\] +The coefficient is positive by the choice of $a_*$. All changes to previously positive coordinates are $O(\tau)$. Thus the extension strictly increases the grand functional. +\end{proof} + +\begin{theorem}[Full interiority]\label{thm:full-interiority} +For every $d\ge3$, $h\ge1$, and $z>0$, every maximizer of the exact grand-canonical functional~\eqref{eq:grand-functional} has full effective horizon $h$ and satisfies +\[ + x_i>0, + \quad + \ell_i>0, + \quad + a_i>\frac1d +\] +for all applicable indices. +\end{theorem} + +\begin{proof} +Combine Lemmas~\ref{lem:relative-boundary} and~\ref{lem:horizon-extension}. +\end{proof} + + + +\section{Stationary messages and exact KKT reconstruction}\label{sec:stationarity} +Recall $b=d-1$. For $1\le i\le h$, let $A_i$ be the cavity weight when the recipient edge already supplies a lower-label neighbor, and let $B_i$ be the weight when it does not. For label zero use $B_0$, and set $A_{h+1}=0$. Define +\[ + S_0=B_0+A_1, + \qquad + S_i=B_{i-1}+B_i+A_{i+1}\quad(1\le i\le h), +\] +where the terminal convention makes $S_h=B_{h-1}+B_h$. The positive stationary system is +\begin{align} + \kappa B_0&=zS_0^b,\label{eq:msg-root}\\ + \kappa A_i&=S_i^b,&&1\le i\le h,\label{eq:msg-A}\\ + \kappa B_i&=S_i^b-(S_i-B_{i-1})^b,&&1\le i\le h.\label{eq:msg-B} +\end{align} +The following subsection derives this system directly from the compact exact functional and proves the converse reconstruction. + + +\subsection{Full KKT-to-message correspondence}\label{sec:kkt} +We now derive the stationary message system directly from the compact KKT equations and prove the converse reconstruction. + +Let $\lambda_i$ be the minimizer in~\eqref{eq:sd}. Then +\begin{equation}\label{eq:sd-identities} + s_d'(a_i)=-d\log\lambda_i, + \qquad + s_d(a_i)-a_i s_d'(a_i)=\log((1+\lambda_i)^d-1). +\end{equation} +At an interior grand-canonical KKT point, let $\mu$ be the multiplier for +\[ + \sum_{i=0}^h\ell_i+2\sum_{i=1}^h x_i=1. +\] +Since $\ell_i$ enters one layer mass and $x_i$ enters two, the KKT equations are +\begin{equation}\label{eq:kkt-weight} + \frac{\partial\Fcal^{(z)}}{\partial\ell_i}=\mu, + \qquad + \frac{\partial\Fcal^{(z)}}{\partial x_i}=2\mu. +\end{equation} + +The analytic derivatives used below are, at the root, +\[ + g_0=(d-1)(\log p_0+1)+\log z-\frac d2(\log\ell_0+1), +\] +and, for $i\ge1$, +\[ + g_i=-\log p_i-1+s_d(a_i)-a_i s_d'(a_i) + +d(\log y_i+1)-\frac d2(\log\ell_i+1). +\] +Thus $\partial\Fcal^{(z)}/\partial\ell_i=g_i$. The derivative with respect to $x_i$ is the sum of the layer contribution immediately to its left and the $x_i$-derivative of the layer-$i$ contribution; explicitly, for $i\ge2$, +\[ + \frac{\partial\Fcal^{(z)}}{\partial x_i} + =g_{i-1}+\frac d2(\log\ell_{i-1}+1) + +g_i+s_d'(a_i)-d(\log y_i+1)+\frac d2(\log\ell_i+1), +\] +with the same formula at $i=1$ after replacing the left layer expression by its root analogue. + +Define, up to a common positive scale, +\begin{equation}\label{eq:belief-messages} + B_i=\sqrt{\ell_i}, + \qquad + A_i=\frac{x_i}{B_{i-1}} + \quad(1\le i\le h), + \qquad + A_{h+1}=0. +\end{equation} +Then +\[ + y_i=B_i(B_i+A_{i+1}). +\] + +\begin{lemma}[Edge KKT identifies the local tilt]\label{lem:kkt-lambda} +For every $1\le i\le h$, +\begin{equation}\label{eq:lambda-message} + \lambda_i + =\frac{B_{i-1}}{B_i+A_{i+1}}. +\end{equation} +\end{lemma} + +\begin{proof} +For $i\ge2$, the derivative of $\Fcal$ with respect to $x_i$ is the sum of the $p_{i-1}$ and $p_i$ contributions. Subtract the two diagonal equations in~\eqref{eq:kkt-weight}, use~\eqref{eq:sd-identities}, and cancel the common constants. The result is +\[ + \frac d2\log\ell_{i-1} + -d\log\left(\lambda_i\frac{y_i}{\sqrt{\ell_i}}\right)=0. +\] +Thus +\[ + \lambda_i y_i=\sqrt{\ell_{i-1}\ell_i}, +\] +which is~\eqref{eq:lambda-message}. The root contribution at $i=1$ has the same algebra, with the activity term cancelling through the root diagonal equation. +\end{proof} + +\begin{proposition}[Compact KKT equals two-message stationarity]\label{prop:kkt-message} +Every strict interior KKT point determines positive messages satisfying~\eqref{eq:msg-root}--\eqref{eq:msg-B}. Conversely, every positive message solution reconstructs a strict interior KKT point by +\[ + q_{ii}=\frac{B_i^2}{Z_e}, + \qquad + q_{i-1,i}=\frac{B_{i-1}A_i}{Z_e}. +\] +\end{proposition} + +\begin{proof} +Put +\[ + T_i=B_i+A_{i+1}, + \qquad + S_i=B_{i-1}+T_i. +\] +By Lemma~\ref{lem:kkt-lambda}, $\lambda_i=B_{i-1}/T_i$. Exponentiating the diagonal KKT equation and using~\eqref{eq:sd-identities} shows that one common constant $\kappa>0$ satisfies +\[ + \kappa + =\frac{((1+\lambda_i)^d-1)y_i^d}{p_iB_i^d} + =\frac{S_i^d-T_i^d}{p_i} +\] +for every $i\ge1$. Hence +\[ + p_i=\frac{S_i^d-T_i^d}{\kappa}. +\] +The descent marginal formula gives +\[ + x_i=a_ip_i + =\frac{B_{i-1}S_i^b}{\kappa}. +\] +Since $x_i=B_{i-1}A_i$, this is~\eqref{eq:msg-A}. Subtracting $x_i$ from $p_i$ gives +\[ + y_i=\frac{T_i(S_i^b-T_i^b)}{\kappa}. +\] +Since $y_i=B_iT_i$, this is~\eqref{eq:msg-B}. At the root, the diagonal KKT equation gives +\[ + \kappa=\frac{zp_0^b}{B_0^d}. +\] +Because $p_0=B_0(B_0+A_1)=B_0S_0$, this is~\eqref{eq:msg-root}. + +Conversely, let positive messages satisfy the stationarity equations. Put $\sigma=Z_e^{-1/2}$ and introduce normalized messages +\[ + \widehat A_i=\sigma A_i, + \qquad + \widehat B_i=\sigma B_i, + \qquad + \widehat\kappa=\sigma^{b-1}\kappa. +\] +Then +\[ + \widehat\kappa\widehat A_i=\widehat S_i^b, + \qquad + \widehat\kappa\widehat B_i + =\widehat S_i^b-(\widehat S_i-\widehat B_{i-1})^b, + \qquad + \widehat\kappa\widehat B_0=z\widehat S_0^b. +\] +The reconstructed beliefs are simply +\[ + \ell_i=\widehat B_i^2, + \qquad + x_i=\widehat B_{i-1}\widehat A_i. +\] +They have total mass one by the definition of $Z_e$. Writing +\[ + \widehat T_i=\widehat B_i+\widehat A_{i+1}, + \qquad + \lambda_i=\frac{\widehat B_{i-1}}{\widehat T_i}, +\] +the message equations give the exact row identities +\[ + p_i=\frac{\widehat S_i^d-\widehat T_i^d}{\widehat\kappa}, + \qquad + x_i=\frac{\widehat B_{i-1}\widehat S_i^b}{\widehat\kappa}, + \qquad + y_i=\frac{\widehat T_i(\widehat S_i^b-\widehat T_i^b)}{\widehat\kappa}. +\] +Consequently $a_i=x_i/p_i$ is exactly the tilted conditioned-binomial marginal with parameter $\lambda_i$, and +\[ + \lambda_i y_i + =\widehat B_{i-1}\widehat B_i + =\sqrt{\ell_{i-1}\ell_i}. +\] +Substitution into the diagonal derivative gives, for every $i\ge1$, +\[ + g_i=\log\widehat\kappa+\frac{d-2}{2}. +\] +The root equation gives the same value for $g_0$. Finally, the displayed edge identity and $s_d'(a_i)=-d\log\lambda_i$ make the difference between the $x_i$ derivative and $g_{i-1}+g_i$ vanish exactly. Thus, with +\[ + \mu=\log\widehat\kappa+\frac{d-2}{2}, +\] +one has +\[ + \frac{\partial\Fcal^{(z)}}{\partial\ell_i}=\mu, + \qquad + \frac{\partial\Fcal^{(z)}}{\partial x_i}=2\mu, +\] +which is~\eqref{eq:kkt-weight}. Positivity makes the point strict interior, and common message scaling cancels from the beliefs. +\end{proof} + + + +\subsection{One-dimensional positive stationary locus} +The equations are homogeneous: common message scaling changes $\kappa$ but not $z$ or the reconstructed profile. In the gauge $\kappa=1$, choosing $B_h>0$ determines all preceding messages uniquely by +\begin{equation}\label{eq:message-backward} + A_i=B_i+(B_i+A_{i+1})^b, + \qquad + B_{i-1}=A_i^{1/b}-B_i-A_{i+1}, +\end{equation} +for $i=h,h-1,\ldots,1$. Positivity is automatic because +\[ + B_{i-1}=\left((B_i+A_{i+1})^b+B_i\right)^{1/b}-(B_i+A_{i+1})>0. +\] +Thus the positive stationary locus is one dimensional before the activity is imposed. + + +\section{Exact reverse transfer and monotone activity shooting} +Normalize $A_1=1$ and put +\[ + \rho_i=\frac{B_i}{A_i}, + \qquad + u_i=\frac{A_{i+1}}{A_i}, + \qquad + v_i=\rho_i+u_i. +\] +At the terminal level, $u_h=0$, so +\[ + \rho_h=v_h=:s\in(0,1). +\] +Let +\[ + \Dcal=\{(\rho,v):0<\rho\le v\le1\}. +\] + +\begin{proposition}[Exact reverse map]\label{prop:reverse-map} +Given a next-level state $(\rho',v')\in\Dcal$, define +\[ + w=(1-\rho')^{1/b}, + \qquad + e=1-w, +\] +\[ + R=v'\frac ew, + \qquad + M=\left(e+\frac w{v'}\right)^b. +\] +Then its unique positive predecessor is +\begin{equation}\label{eq:reverse-map} + \boxed{ + \rho=\frac{R}{R+M}, + \qquad + v=\frac{1+R}{R+M}. + } +\end{equation} +The remaining coordinates are +\begin{equation}\label{eq:reverse-out} + u=\frac1{R+M},\qquad q=\frac{M-1}{R+M}. +\end{equation} +The map sends $\Dcal$ into itself. +\end{proposition} + +\begin{proof} +The forward transfer identities imply +\[ + \frac\rho u=v'\frac ew=R. +\] +The next lower-neighbor fraction also gives +\[ + e=\frac{\rho(1-\rho)^{1/b}} + {u^{1/b}(u+\rho)}. +\] +Substituting $\rho=Ru$ and solving yields +\[ + u=\frac1{R+M}, +\] +which gives~\eqref{eq:reverse-map}. Uniqueness follows from the algebraic solution. Since +\[ + e+\frac w{v'}\ge e+w=1, +\] +we have $M\ge1$, and therefore +\[ + 0<\rho0, +\] +\[ + \frac{\partial}{\partial m}\log z + =\frac1m+ + \frac{b(1-v)}{(1+m)(1+vm)}>0. +\] +The quantity $m$ is strictly increasing in $\rho_1$, so Proposition~\ref{prop:order-preserving} completes the proof. +\end{proof} + +\begin{lemma}[Endpoint activities]\label{lem:z-endpoints} +For fixed $d,h$, +\[ + \lim_{s\downarrow0}z_h(s)=0, + \qquad + \lim_{s\uparrow1}z_h(s)=\infty. +\] +\end{lemma} + +\begin{proof} +For terminal $(\rho',v')=(s,s)$ with $s\downarrow0$, one reverse step has $R=O(s^2)$ and $M=\Theta(s^{-b})$, so the predecessor tends to $(0,0)$. The reverse map is continuous at every interior state and has the displayed boundary limit; induction over the fixed number $h-1$ of reverse steps therefore sends every earlier state to $(0,0)$. Equation~\eqref{eq:z-root-reverse} then gives $z\to0$. + +As $s\uparrow1$, one has $w\to0$, $R\to\infty$, and $M\to1$, so one reverse step tends to $(1,1)$. The same finite-step induction sends every earlier state to $(1,1)$. Hence $m\to\infty$, $v_1\to1$, and~\eqref{eq:z-root-reverse} gives $z\to\infty$. Continuity of the reverse map and of~\eqref{eq:z-root-reverse} also makes $s\mapsto z_h(s)$ continuous. +\end{proof} + +\begin{theorem}[Unique positive stationary point]\label{thm:unique-stationary} +For every $d\ge3$, $h\ge1$, and $z>0$, the exact grand-canonical stationarity equations have exactly one positive solution up to common message scaling. +\end{theorem} + +\begin{proof} +Every positive solution has one terminal parameter $s=\rho_h\in(0,1)$ and is uniquely reconstructed by Proposition~\ref{prop:reverse-map}. Lemmas~\ref{lem:z-monotone} and~\ref{lem:z-endpoints} show that $s\mapsto z_h(s)$ is a strictly increasing bijection from $(0,1)$ to $(0,\infty)$. +\end{proof} + + +For a positive stationary message profile whose reconstructed selected density is $\alpha$, define +\[ + \Psi^{\mathrm{stat}}_{d,h}(\alpha) + :=\Fcal_{d,h}(x,\ell), +\] +where $(x,\ell)$ is its normalized compact profile. Theorem~\ref{thm:unique-stationary} shows that this value is single-valued along the positive reverse-transfer branch. + +\section{Exact grand- and microcanonical globality} +Although $\Fcal_{d,h}$ is nonconcave, the preceding interiority and uniqueness results determine its global optimizer. + +\begin{theorem}[Grand-canonical globality]\label{thm:grand-globality} +For every $d\ge3$, $h\ge1$, and $z>0$, the exact grand-canonical functional $\Fcal_{d,h}^{(z)}$ has a unique global maximizer. It is the positive stationary profile corresponding to the unique terminal parameter $s$ satisfying $z_h(s)=z$. +\end{theorem} + +\begin{proof} +A maximizer exists by compactness. Theorem~\ref{thm:full-interiority} places every maximizer in the strict interior, so every maximizer satisfies the interior stationarity equations. Theorem~\ref{thm:unique-stationary} gives only one such point. +\end{proof} + +The microcanonical problem follows by duality. + +\begin{theorem}[Microcanonical globality]\label{thm:micro-globality} +For every density +\[ + \frac1{B_h}<\alpha<1, +\] +the exact microcanonical functional has a unique global maximizer, and it is the positive stationary profile on the reverse-transfer branch with selected density $\alpha$. Equivalently, +\[ + \boxed{ + \Psi_{d,h}(\alpha)=\Psi^{\mathrm{stat}}_{d,h}(\alpha) + } +\] +throughout the interior feasible interval. +\end{theorem} + +\begin{proof} +Write $\theta=\log z$ and +\[ + \phi_{d,h}(\theta) + =\max_{(x,\ell)\in\Pcal_{d,h}} + \{\Fcal_{d,h}(x,\ell)+\theta p_0\}. +\] +By Theorem~\ref{thm:grand-globality}, the maximizer is unique for every $\theta$. Danskin's theorem~\cite{RockafellarWets1998} therefore gives +\[ + \phi_{d,h}'(\theta)=\alpha(\theta), +\] +the density of that maximizer. The derivative of a differentiable convex function is continuous here (equivalently, one may use continuity of the unique optimizer). It is also strictly increasing. Indeed, if $\theta_1<\theta_2$ had the same maximizing density, the two optimality inequalities would force each optimizer to maximize at both activities. Grand-canonical uniqueness would make the profiles equal, but the root equation assigns one activity to an interior stationary profile, a contradiction. To identify the endpoint limits, let $\theta_k\to-\infty$ and pass, by compactness, to a convergent subsequence of optimizers. Comparing with a feasible profile of density $1/B_h$ shows that any limit must minimize $p_0$ over the polytope, hence has density $1/B_h$. Similarly, along $\theta_k\to\infty$, comparison with the all-selected profile forces every subsequential limit to have density $1$. Therefore +\[ + \alpha(\theta)\longrightarrow\frac1{B_h} + \quad(\theta\to-\infty), + \qquad + \alpha(\theta)\longrightarrow1 + \quad(\theta\to\infty). +\] +Hence every interior density is attained. + +Fix $\alpha$ and choose $\theta$ with $\alpha(\theta)=\alpha$. For every profile $P$ of density $\alpha$, +\[ + \Fcal(P)+\theta\alpha + \le + \Fcal(P_\theta)+\theta\alpha, +\] +so $P_\theta$ is the microcanonical maximizer. Uniqueness follows from grand-canonical uniqueness. +\end{proof} + +\begin{corollary}[Concavity and the envelope identity]\label{cor:envelope} +The exact value function $\Psi_{d,h}$ is strictly concave on $(1/B_h,1)$ and differentiable there. If $z(\alpha)$ is the activity exposing density $\alpha$, then +\[ + \boxed{ + \Psi_{d,h}'(\alpha)=-\log z(\alpha). + } +\] +\end{corollary} + +\begin{proof} +This is the standard differentiable Legendre correspondence produced by the unique maximizers in Theorems~\ref{thm:grand-globality} and~\ref{thm:micro-globality}. Strict monotonicity of $\alpha(\theta)$ gives strict concavity. +\end{proof} + +For later use, we collect the two conclusions as +\begin{equation}\label{eq:globality} + \Psi_{d,h}(\alpha)=\Psi^{\rm stat}_{d,h}(\alpha), + \qquad + \Psi'_{d,h}(\alpha)=-\log z(\alpha). +\end{equation} + +Explicit positive Hessian directions at stratified profiles do not contradict these theorems: they occur at nonstationary stratified profiles. The compact functional is genuinely nonconcave, but no competing stationary maximum exists. + + +\section{Corrected stationary telescoping and root formulas}\label{sec:telescoping} +Define +\begin{align} + Z_v&=zS_0^d+ + \sum_{i=1}^h + \left[S_i^d-(S_i-B_{i-1})^d\right], + \label{eq:Zv}\\ + Z_e&=\sum_{i=0}^hB_i^2 + +2\sum_{i=0}^{h-1}B_iA_{i+1}. + \label{eq:Ze} +\end{align} +The stationary vertex and edge normalizers satisfy the following exact telescoping identity. + +\begin{proposition}[Corrected telescoping identity]\label{prop:correct-telescope} +Every positive stationary solution satisfies +\[ + \boxed{Z_v=\kappa Z_e.} +\] +\end{proposition} + +\begin{proof} +For $1\le i\le h$, put +\[ + V_i=S_i^d-(S_i-B_{i-1})^d. +\] +Using~\eqref{eq:msg-A}--\eqref{eq:msg-B}, +\begin{align*} + V_i + &=\kappa\left( + B_{i-1}A_i+B_i^2+B_iA_{i+1} + \right). +\end{align*} +The root contribution is +\[ + zS_0^d=\kappa(B_0^2+B_0A_1). +\] +After summation, every square $B_i^2$ appears once and every cross term $B_iA_{i+1}$ appears twice: once from each adjacent vertex contribution, with the root supplying the first copy of $B_0A_1$. This is exactly $\kappa Z_e$. +\end{proof} + +Normalize $A_1=1$ and write $r=B_0$. Proposition~\ref{prop:correct-telescope} gives +\begin{equation}\label{eq:alpha-root-correct} + \alpha=\frac{r(1+r)}{Z_e}. +\end{equation} +The pressure is +\[ + \phi=\log Z_v-\frac d2\log Z_e, +\] +and the root equation is +\[ + \log z=\log\kappa+\log r-(d-1)\log(1+r). +\] +Eliminating $Z_e$ gives the corrected root-only formulas +\begin{equation}\label{eq:root-pressure-correct} + \boxed{ + \phi + =\log z + +\frac d2\log\frac{1+r}{r} + +\frac{d-2}{2}\log\alpha, + } +\end{equation} +\begin{equation}\label{eq:root-micro-correct} +\boxed{ +\begin{aligned} + \Psi={}& + (1-\alpha)\log\kappa + -\left(\frac{d-2}{2}+\alpha\right)\log r + +\frac{d-2}{2}\log\alpha\\ + &+\left((d-1)\alpha-\frac{d-2}{2}\right)\log(1+r). +\end{aligned} +} +\end{equation} +The corrected formulas are used throughout this paper. Calculations made directly from $Z_v$ and $Z_e$ are unaffected, provided the power differences are evaluated stably as discussed in Section~\ref{sec:numerics}. + +For later diagnostics, the same telescope gives a cancellation-free identity for the entropy defect. Put +\[ + u=u_1=\frac{A_2}{A_1}, + \qquad c_0=\frac{d-2}{2}, +\] +and define +\[ + E_{\rm root}:=\log\kappa-b\log u, + \qquad + N_e:=\log Z_e-(D+1)\log u. +\] + +\begin{proposition}[Exact entropy-defect identity]\label{prop:defect-identity} +Every positive stationary solution of selected density $\alpha$ satisfies +\begin{equation}\label{eq:defect-identity} + \boxed{ + H(\alpha)-\Psi_{d,h}(\alpha) + =-(1-\alpha)\log(1-\alpha) + -E_{\rm root}+c_0N_e + +\alpha\log\frac z\alpha. + } +\end{equation} +\end{proposition} + +\begin{proof} +Proposition~\ref{prop:correct-telescope} gives +\[ + \phi=\log\kappa-c_0\log Z_e. +\] +Since $c_0(D+1)=b$, this is +$\phi=E_{\rm root}-c_0N_e$. Now use +$\Psi=\phi-\alpha\log z$ and expand +$H(\alpha)=-\alpha\log\alpha-(1-\alpha)\log(1-\alpha)$. +\end{proof} + + + +\section{Terminal logarithmic coordinate and exact outer orbits}\label{sec:terminal} +Retain the normalization $A_1=1$ and the reverse-transfer coordinates +\[ + \rho_i=\frac{B_i}{A_i},\qquad + u_i=\frac{A_{i+1}}{A_i},\qquad + v_i=\rho_i+u_i,\qquad + q_i=1-v_i. +\] +At the terminal wall $u_h=0$. We write +\begin{equation}\label{eq:terminal-t} + \rho_h=v_h=s=1-e^{-t},\qquad q_h=e^{-t}. +\end{equation} +The exact reverse dynamics are those of Proposition~\ref{prop:reverse-map}. + +Two boundary orbits are exact. On the stable boundary $\rho=0$, the forward map is +$u\mapsto u^{1/b}$ and the reverse map is $u'\mapsto (u')^b$. On the free boundary +$q=0$, the forward map is $u\mapsto u^b$ and the reverse map is +$u'\mapsto (u')^{1/b}$. + +For terminal parameter $t$, define the free density +\begin{equation}\label{eq:free-a} + a_h(t):=1-e^{-t/b^h}. +\end{equation} +The exact free orbit with this density is +\begin{equation}\label{eq:free-orbit} + \bar u_i=e^{-t/b^{h-i}},\qquad + \bar\rho_i=1-\bar u_i,\qquad + \bar q_i=0. +\end{equation} + + +\section{Uniform one-step estimates} +The slack theorem requires only terminal parameters linear in $h$ and uniformly below the critical coefficient. + +\begin{definition}[Subcritical terminal window]\label{def:terminal-window} +Fix constants +\[ + 0<\tau_-\le\tau_+<\frac{4\log b}{3D}. +\] +A sequence of terminal parameters is in the subcritical linear window if +\[ + \tau_-h\le t\le\tau_+h. +\] +\end{definition} + +All constants below may depend on $d,\tau_-,\tau_+$ but not on $h$ or $t$ in this window. + +\subsection{Free-side perturbations} +At one reverse step, keep $\rho'$ fixed and write $q'=1-v'$. The free predecessor with the same $\rho'$ has +\[ + w=(1-\rho')^{1/b}, + \qquad + \rho_0=1-w, + \qquad + u_0=w, + \qquad + q_0=0. +\] + +\begin{lemma}[Uniform free-side step]\label{lem:free-step} +There are $\delta_0,C>0$ such that, whenever $0\le q'\le\delta_0$, the actual predecessor satisfies +\begin{align} + 1-\rho&=w(1+\eta_\rho),\label{eq:free-rho-step}\\ + q&=bw^2q'(1+\eta_q),\label{eq:free-q-step} +\end{align} +with +\[ + |\eta_\rho|+|\eta_q|\le Cq'. +\] +The estimates are uniform for $00$ such that, whenever $0\le\delta\le\delta_1$, the predecessor satisfies +\begin{align} + \log u&=b\log V+O_d(V\delta),\label{eq:stable-logu}\\ + \frac\rho v&=\frac{V^2}{b}\delta(1+O_d(\delta)).\label{eq:stable-delta} +\end{align} +Put +\[ + \widetilde a_i:=\frac{\rho_i}{b^iu_i^D}. +\] +Then +\begin{equation}\label{eq:stable-invariant-step} + \frac{\widetilde a_i}{\widetilde a_{i+1}} + =1+O_d(\delta). +\end{equation} +For sufficiently small $\delta_1$, the transverse ratios contract backward: +\[ + \frac{\rho_i}{v_i}\le\frac{1+o(1)}b\frac{\rho_{i+1}}{v_{i+1}}. +\] +\end{lemma} + +\begin{proof} +Here +\[ + w=(1-V\delta)^{1/b}, + \qquad + e=1-w=\frac{V\delta}{b}(1+O_d(\delta)), +\] +so +\[ + R=V\frac ew=\frac{V^2\delta}{b}(1+O_d(\delta)). +\] +Also +\[ + e+\frac wV + =\frac1V\left(w+Ve\right) + =\frac1V\left(1-e(1-V)\right), +\] +whence +\[ + M=V^{-b}(1+O_d(V\delta)). +\] +Since $R/M=O_d(V^{b+2}\delta)$, equation~\eqref{eq:reverse-out} yields~\eqref{eq:stable-logu}; moreover $\rho/u=R$, which gives~\eqref{eq:stable-delta}. + +For~\eqref{eq:stable-invariant-step}, use $\rho=uR$ and compute +\[ + \frac{\widetilde a_i}{\widetilde a_{i+1}} + =\frac{bRu^{1-D}(u')^D}{\rho'}. +\] +The preceding expansions give +\[ + \frac{bR}{\rho'}=V(1+O_d(\delta)), + \qquad + u^{1-D}(u')^D=V^{-1}(1+O_d(\delta)), +\] +because $(b-1)D=b+1$. Their product is $1+O_d(\delta)$. +\end{proof} + + +\section{Free shadowing to an overlap layer} +In the quantitative statements below, notation of the form +$1+B_h^{-\eta+o(1)}$ denotes $1+\epsilon_h$ with +$|\epsilon_h|\le B_h^{-\eta+o(1)}$; no sign is implied. +For $t$ in the terminal window, choose +\begin{equation}\label{eq:H-choice} + H=\left\lfloor\frac{3Dt}{4\log b}\right\rfloor, + \qquad + m=h-H. +\end{equation} +Then $H,m$ are both linear in $h$. Define the formal free transverse sequence, for $m\le i\le h$, by +\begin{equation}\label{eq:qbar} + \bar q_i + =b^{h-i} + \exp\left\{-Dt+\frac{2t}{b-1}b^{i-h}\right\}. +\end{equation} +It satisfies $\bar q_h=e^{-t}$ and +\[ + \bar q_i=b\bar u_i^2\bar q_{i+1}. +\] + +\begin{proposition}[Uniform free shadow]\label{prop:free-shadow} +Uniformly in every subcritical terminal window, for every $m\le i\le h$, +\begin{align} + q_i&=\bar q_i\left(1+O\!\left(h e^{-Dt/4}\right)\right),\label{eq:q-shadow}\\ + 1-\rho_i&=\bar u_i\left(1+O\!\left(e^{-Dt/4}\right)\right).\label{eq:rho-shadow} +\end{align} +In particular, +\begin{align} + q_m&=b^H\exp\left\{-Dt+\frac{2t}{b-1}b^{-H}\right\} + \left(1+O\!\left(h e^{-Dt/4}\right)\right),\label{eq:qm}\\ + \rho_m&=t b^{-H} + \left(1+O\!\left(t b^{-H}+e^{-Dt/4}\right)\right),\label{eq:rhom}\\ + \frac{\rho_m}{q_m}&=\exp\{-Dt/2+o(h)\}.\label{eq:rho-over-q} +\end{align} +If $L=\log B_h$ and $c_t=Dt/L$, then, uniformly when $c_t$ stays in a compact subset of the terminal window, +\begin{equation}\label{eq:overlap-scales-quantitative} + q_m=B_h^{-c_t/4+o(1)},\qquad + \rho_m=B_h^{-3c_t/4+o(1)},\qquad + \frac{\rho_m}{q_m}=B_h^{-c_t/2+o(1)}. +\end{equation} +\end{proposition} + +\begin{proof} +Let +\[ + E_i=\log\frac{1-\rho_i}{\bar u_i}. +\] +Lemma~\ref{lem:free-step} gives +\[ + E_i=\frac1bE_{i+1}+O(q_{i+1}), +\] +and +\[ + \log\frac{q_i}{\bar q_i} + =\log\frac{q_{i+1}}{\bar q_{i+1}} + +\frac2bE_{i+1}+O(q_{i+1}). +\] +Both errors vanish at $i=h$. + +Write $r=h-i$. The logarithm of the formal transverse sequence is +\[ + f(r)=r\log b-Dt+\frac{2t}{b-1}b^{-r}. +\] +The function $f$ is convex, so its maximum on $0\le r\le H$ occurs at an endpoint. At $r=0$, $f(0)=-t$, while the definition of $H$ gives +\[ + f(H)\le-\frac14Dt+O_d(1). +\] +Since $D/4<1$, it follows that +\[ + \max_{m\le i\le h}\bar q_i=O_d(e^{-Dt/4}). +\] + +A first-failure bootstrap now gives +\[ + \max_i|E_i|=O(e^{-Dt/4}), + \qquad + \max_i\left|\log\frac{q_i}{\bar q_i}\right| + =O(h e^{-Dt/4}). +\] +For large $h$ these estimates prevent the first failure, proving +\eqref{eq:q-shadow}--\eqref{eq:rho-shadow} and the stated formula for $q_m$. +Furthermore, +\[ + 1-e^{-t/b^H}=t b^{-H}\left(1+O(t b^{-H})\right), +\] +which gives~\eqref{eq:rhom}. Finally, +\[ + \log\frac{\rho_m}{q_m} + =\log t-2H\log b+Dt+o(h) + =-\frac12Dt+o(h). +\] +Because $H=3Dt/(4\log b)+O(1)$ and $L=h\log b+O(1)$, the three estimates in~\eqref{eq:overlap-scales-quantitative} follow. +\end{proof} + + +\section{Stable shadowing from the overlap to the root} +Put +\[ + x=-\log u_1, + \qquad + \widetilde a=\widetilde a_1 + =\frac{\rho_1}{b u_1^D}. +\] + +\begin{proposition}[Uniform stable shadow]\label{prop:stable-shadow} +Under the terminal-window assumptions and the matching choice~\eqref{eq:H-choice}, put +\[ + \chi_m:=q_m+\frac{\rho_m}{q_m}. +\] +Then +\begin{align} + x&=b^{m-1}q_m\left(1+O(\chi_m)\right),\label{eq:x-from-q}\\ + \widetilde a&=\frac{\rho_m}{b^m} + \left(1+O(q_m+\rho_m)\right).\label{eq:atilde-from-rho} +\end{align} +If the messages are normalized by $A_1=1$, then +\begin{equation}\label{eq:Am-stable} + \log A_m + =\frac{b}{b-1}\left(1-b^{-(m-1)}\right)\log u_1 + +O(m\rho_m), +\end{equation} +and +\begin{equation}\label{eq:r-Am} + B_0=\widetilde a\,A_m^2 + \left(1+O(q_m+m\rho_m)\right). +\end{equation} +All constants are uniform in the terminal window. +\end{proposition} + +\begin{proof} +Set $\delta_i=\rho_i/v_i$. Proposition~\ref{prop:free-shadow} gives $\delta_m=O(\rho_m)$, and Lemma~\ref{lem:stable-step} implies geometric backward contraction. Hence +\[ + \sum_{i=2}^m\delta_i=O(\rho_m). +\] +Iteration of~\eqref{eq:stable-invariant-step} gives +\[ + \widetilde a + =\frac{\rho_m}{b^m u_m^D}\left(1+O(\rho_m)\right). +\] +Since $u_m=1-q_m-\rho_m$, this proves~\eqref{eq:atilde-from-rho}. + +The stable-step estimate also gives +\[ + \log v_i=b\log v_{i+1}+O(\rho_{i+1}). +\] +After iteration, +\[ + -\log v_1 + =b^{m-1}[-\log v_m] + +O\left(\sum_{j=2}^m b^{j-2}\rho_j\right) + =b^{m-1}[-\log v_m]+O(b^{m-1}\rho_m). +\] +Since $v_m=1-q_m$, +\[ + -\log v_m=q_m(1+O(q_m)). +\] +Backward contraction gives $\delta_1=O(b^{-(m-1)}\rho_m)$, and therefore +\[ + 0\le\log\frac{v_1}{u_1} + =\log\left(1+\frac{\rho_1}{u_1}\right) + =O(b^{-(m-1)}\rho_m). +\] +This is absorbed by the preceding error. Dividing by the main term +$b^{m-1}q_m$ proves~\eqref{eq:x-from-q}. + +Likewise,~\eqref{eq:stable-logu} and contraction give +\[ + \log u_i=b^{-(i-1)}\log u_1+O(\rho_m) +\] +uniformly for $1\le i0. +\end{equation} +In particular, for all sufficiently large $h$, +\begin{equation}\label{eq:activity-lower} + -\log z(\alpha) + \ge\log\frac1\alpha + +\frac12B_h(1-\alpha)^{B_h} +\end{equation} +uniformly on~\eqref{eq:density-window}. +\end{theorem} + +\begin{proof} +First work in a terminal window and put $c_t=Dt/\log B_h$. We spell out the quantitative root reconstruction because its additive error is later compared with a vanishing coupon term. Proposition~\ref{prop:stable-shadow} and the exact root formulas give +\[ + B_0=\widetilde a\,u_1^{D+1} + \left(1+O(q_m+m\rho_m)\right), + \qquad + \kappa=u_1^b\left(1+O(\rho_m)\right). +\] +Since $z=B_0\kappa/(1+B_0)^b$, $x=-\log u_1$, and +$B_0=B_h^{-1+o(1)}$, it follows that +\[ + -\log z + =\log\frac1{\widetilde a}+Kx + +O(q_m+m\rho_m+B_0) + =\log\frac1{\widetilde a}+Kx + +B_h^{-c_t/4+o(1)}, + \qquad K=b+D+1=bD. +\] +The arithmetic identity +\[ + Kb^{h-1}=Db^h=B_h+\frac2{b-1} +\] +and Theorem~\ref{thm:matching} yield +\[ + Kx + =B_h(1-a_h(t))^{B_h} + \left(1+B_h^{-c_t/4+o(1)}\right). +\] +Lemma~\ref{lem:Ze-localization} gives +\[ + \log\frac{\alpha}{\widetilde a}=B_h^{-c_t/4+o(1)}, + \qquad + B_h|\alpha-a_h(t)|=B_h^{-c_t/4+o(1)}. +\] +The latter estimate changes the coupon term relatively by +$1+B_h^{-c_t/4+o(1)}$. Hence +\begin{equation}\label{eq:activity-terminal-quantitative} + -\log z-\log\frac1\alpha + =B_h(1-\alpha)^{B_h} + \left(1+B_h^{-c_t/4+o(1)}\right) + +B_h^{-c_t/4+o(1)}. +\end{equation} + +It remains to identify the terminal range corresponding to~\eqref{eq:density-window}. By~\eqref{eq:alpha-atilde}, uniformly in every terminal window, +\[ + \alpha B_h=Dt\left(1+B_h^{-c_t/4+o(1)}\right). +\] +As in the qualitative proof, choose a slightly broader terminal window whose endpoint densities bracket~\eqref{eq:density-window}; strict activity and density monotonicity then expose every density in the displayed interval. Uniformly there, $c_t=c+o(1)$, and~\eqref{eq:activity-terminal-quantitative} becomes~\eqref{eq:activity-additive-quantitative}. + +Finally, +\[ + B_h(1-\alpha)^{B_h}=B_h^{1-c+o(1)}. +\] +The additive error in~\eqref{eq:activity-additive-quantitative} is therefore relatively +$B_h^{3c/4-1+o(1)}$, while the multiplicative orbit error is +$B_h^{-c/4+o(1)}$. Taking the worst exponent over $[c_-,c_+]$ proves +\eqref{eq:activity-law}--\eqref{eq:activity-delta}; +\eqref{eq:activity-lower} follows immediately. +\end{proof} + + +\section{A capped-free profile and the bounded critical window}\label{sec:bounded-window} +Put +\[ + B=B_h,\qquad L=\log B, + \qquad + \Dcal_h(\alpha):=H(\alpha)-\Psi_{d,h}(\alpha), + \qquad + Q_h(\alpha):=(1-\alpha)^B. +\] +We now construct a feasible profile whose only entropy loss is the conditioning event at the terminal wall. + +Put $r=1-\alpha$ and +\[ + T_j=1+b+\cdots+b^j=\frac{b^{j+1}-1}{b-1}. +\] +For $h\ge2$, define +\begin{equation}\label{eq:capped-free-messages} + A_i=r^{T_{i-1}}\quad(1\le i\le h), + \qquad A_{h+1}=0, +\end{equation} +\begin{equation}\label{eq:capped-free-B} + B_0=\alpha, + \qquad B_i=A_i-A_{i+1}\quad(1\le i\frac{C}{Db} + =\frac{d-2}{d(d-1)}C. +\] +Under~\eqref{eq:explicit-feasibility-threshold} and $|s|\le M$, this is at least $\log(d/(d-1))$. Therefore +\[ + \varepsilon_h=(1-\alpha)^{b^{h-1}} + \le e^{-\alpha b^{h-1}} + \le\frac{d-1}{d}, +\] +as required. +\end{proof} + +Define +\[ + \Delta_d(\varepsilon) + :=dH(\varepsilon)-s_d(1-\varepsilon). +\] + +\begin{lemma}[Exact capped-free entropy loss]\label{lem:capped-free-loss} +Let $\Fcal_{d,h}^{\rm cap}(\alpha)$ be the compact functional at the profile +\eqref{eq:capped-free-beliefs}. Then +\begin{equation}\label{eq:capped-free-loss} + H(\alpha)-\Fcal_{d,h}^{\rm cap}(\alpha) + =p_h\Delta_d(\varepsilon_h), +\end{equation} +and +\begin{equation}\label{eq:capped-coupon-exact} + p_h\varepsilon_h^d=(1-\alpha)^B. +\end{equation} +Moreover, as $\varepsilon\downarrow0$, +\begin{equation}\label{eq:terminal-gap-asymptotic} + \Delta_d(\varepsilon) + =\varepsilon^d\left(1+O_d(\varepsilon^{d-1})\right). +\end{equation} +\end{lemma} + +\begin{proof} +First replace the terminal entropy $s_d(a_h)$ by the unconstrained coordinate entropy $dH(a_h)=dH(\varepsilon_h)$. For every nonterminal layer, and for the relaxed terminal layer, the dual entropy identity and the message row identities reduce the layer contribution to +\[ + p_i\log\kappa + -d x_i\log B_{i-1} + +d x_{i+1}\log B_i, + \qquad x_{h+1}=0. +\] +The sum over $i=1,\ldots,h$ telescopes to +\[ + (1-\alpha)\log\kappa-dx_1\log B_0. +\] +The root contribution is +\[ + (d-1)\alpha\log\alpha + -\frac d2\alpha^2\log(\alpha^2). +\] +Using $\kappa=1/r$, $x_1=\alpha r$, and $B_0=\alpha$, the relaxed total is exactly $H(\alpha)$. Restoring the nonempty terminal condition subtracts the right side of~\eqref{eq:capped-free-loss}. + +Since $A_h=rA_{h-1}^b$, +\[ + p_h\varepsilon_h^d + =A_{h-1}A_h\left(\frac{A_h}{A_{h-1}}\right)^d + =rA_h^d + =r^{1+dT_{h-1}} + =r^B, +\] +which proves~\eqref{eq:capped-coupon-exact}. + +For~\eqref{eq:terminal-gap-asymptotic}, let $\eta$ be the coordinate-exclusion probability before conditioning on a nonempty subset. Then +\[ + \varepsilon=\frac{\eta-\eta^d}{1-\eta^d}, + \qquad + 1-\varepsilon=\frac{1-\eta}{1-\eta^d}, + \qquad + \eta-\varepsilon=(1-\varepsilon)\eta^d, +\] +so $\eta=\varepsilon+O(\varepsilon^d)$. Substituting the first two identities into the entropy of the conditioned product measure gives +\[ + \Delta_d(\varepsilon) + =-\log(1-\eta^d) + -d\,\mathrm{KL}\!\left( + \operatorname{Ber}(\varepsilon) + \Vert\operatorname{Ber}(\eta) + \right). +\] +The Bernoulli chi-square bound makes the KL term +$O_d(\varepsilon^{2d-1})$, while +$-\log(1-\eta^d)=\varepsilon^d(1+O_d(\varepsilon^{d-1}))$. +\end{proof} + +\begin{proof}[Proof of Theorem~\ref{thm:bounded-critical-window}] +The upper type anchor gives $\Psi_{d,h}(\alpha)\le H(\alpha)$, while +Lemma~\ref{lem:capped-free-feasible} supplies a feasible compact profile for every sufficiently large $h$, uniformly in the displayed window. Hence Lemma~\ref{lem:capped-free-loss} implies +\[ + 0\le \Dcal_h(\alpha) + \le Q_h(\alpha) + \left(1+O_d(\varepsilon_h^{d-1})\right). +\] +There, +\[ + \varepsilon_h=(1-\alpha)^{b^{h-1}} + =B^{-\frac{d-2}{d(d-1)}+o(1)}, +\] +which proves the upper bound in~\eqref{eq:defect-bounded-two-sided}. + +For the lower bound, define +\[ + \mathcal A_h(a) + :=-\log z(a)-\log\frac1a. +\] +The envelope identity~\eqref{eq:globality} gives +\begin{equation}\label{eq:defect-derivative} + -\Dcal_h'(a)=-\log(1-a)+\mathcal A_h(a). +\end{equation} +Put +\[ + C_0=L-2\log L+s, + \quad \alpha_0=C_0/B, + \qquad + C_1=\frac87L, + \quad \alpha_1=C_1/B. +\] +For all large $h$, the interval lies in the fixed density window with +$c_-=3/4$ and $c_+=8/7$. Theorem~\ref{thm:activity-law} applies uniformly there with relative error $B^{-1/7+o(1)}$. Since +$-\log(1-a)\ge0$ and $\Dcal_h(\alpha_1)\ge0$, +\begin{align*} + \Dcal_h(\alpha_0) + &\ge + \left(1-B^{-1/7+o(1)}\right) + B\int_{\alpha_0}^{\alpha_1}(1-a)^B\,da\\ + &=\left(1-B^{-1/7+o(1)}\right) + \frac{B}{B+1} + \left[(1-\alpha_0)^{B+1}-(1-\alpha_1)^{B+1}\right]. +\end{align*} +Finally, +\[ + \frac{(1-\alpha_1)^B}{(1-\alpha_0)^B} + =B^{-1/7}L^{-2}e^{s+o(1)}, +\] +and $\alpha_0=O(L/B)$. This proves the lower bound in +\eqref{eq:defect-bounded-two-sided} and hence~\eqref{eq:defect-bounded-window}. +\end{proof} + +\begin{proof}[Proof of Corollary~\ref{cor:critical-scaling-function}] +Uniformly for bounded $s$, +\[ + H\!\left(\frac{L-2\log L+s}{B}\right) + =\frac{L^2}{B}(1+o(1)), +\] +whereas +\[ + \left(1-\frac{L-2\log L+s}{B}\right)^B + =e^{-s}\frac{L^2}{B}(1+o(1)). +\] +Apply Theorem~\ref{thm:bounded-critical-window}. +\end{proof} + +\begin{proof}[Proof of Corollary~\ref{cor:annealed-zero-expansion}] +For every fixed $\epsilon>0$, Corollary~\ref{cor:critical-scaling-function} gives opposite signs at $s=-\epsilon$ and $s=\epsilon$ for all large $h$; because strict concavity makes the superlevel set +$\{\alpha:\Psi_{d,h}(\alpha)\ge0\}$ an interval, its lower endpoint satisfies +\[ + C_h^{\rm ann}=L-2\log L+o(1). +\] + +Let +\[ + F_B(C):=H(C/B)-(1-C/B)^B. +\] +Theorem~\ref{thm:bounded-critical-window} gives +\[ + \Psi_{d,h}(C/B) + =F_B(C)+O\!\left((1-C/B)^B B^{-1/7+o(1)}\right) +\] +uniformly in a fixed neighborhood of the scalar root. There, +\[ + F_B'(C)=(1+o(1))(1-C/B)^B, +\] +uniformly and with positive sign. A two-sided mean-value comparison therefore proves~\eqref{eq:graph-scalar-zero}. + +It remains to invert the scalar equation. For $C=L+O(\ell)$, +\eqref{eq:scalar-coupon-root} is equivalent to +\begin{equation}\label{eq:scalar-log-equation} + C+\log C+\log(L-\log C+1) + =L+O(L^2/B). +\end{equation} +The equation first gives $C=L-2\ell+O(\ell/L)$; substituting this estimate successively into the two logarithms determines the coefficients through order $L^{-3}$. If $P_3$ denotes the displayed polynomial in~\eqref{eq:annealed-zero-expansion}, direct expansion gives +\[ + P_3+\log P_3+\log(L-\log P_3+1)-L + =O(\ell^4/L^4), +\] +while the derivative of the left side of~\eqref{eq:scalar-log-equation} is $1+O(1/L)$. Thus the mean-value theorem yields +\[ + \widehat C_B-P_3 + =O(\ell^4/L^4+L^2/B) + =O(\ell^4/L^4), +\] +which supplies the claimed bootstrap remainder. Finally, +$B^{-1/7+o(1)}$ is smaller than every fixed inverse power of $L$, so~\eqref{eq:graph-scalar-zero} transfers the expansion to $C_h^{\rm ann}$. Repeating the same formal substitution and mean-value estimate yields the expansion to any prescribed fixed inverse power of $L$. +\end{proof} + +\section{Near-critical integration and the random-graph deduction}\label{sec:integration} +We first prove Theorem~\ref{thm:near-critical}. The pointwise anchor is Corollary~\ref{cor:Psi-le-H}. + +\begin{proof}[Proof of Theorem~\ref{thm:near-critical}] +Put $B=B_h$ and $L=\log B$. For a value $C$ in~\eqref{eq:C-window}, set +\[ + \alpha_- =\frac CB, + \qquad + C^\sharp=\frac{L+C}{2}, + \qquad + \alpha_+=\frac{C^\sharp}{B}. +\] +For large $h$, the interval $[\alpha_-,\alpha_+]$ lies in a fixed density window +\[ + \frac\eta2\frac LB + \le a\le + \frac LB, +\] +so Theorem~\ref{thm:activity-law} applies uniformly. Exact globality and the envelope identity~\eqref{eq:globality} give +\[ + \Psi(\alpha_-) + =\Psi(\alpha_+)+\int_{\alpha_-}^{\alpha_+}\log z(a)\,da. +\] +Corollary~\ref{cor:Psi-le-H} and~\eqref{eq:activity-lower} imply +\begin{align*} + \Psi(\alpha_-) + &\le H(\alpha_+) + -\int_{\alpha_-}^{\alpha_+}\log\frac1a\,da + -\frac12\int_{\alpha_-}^{\alpha_+}B(1-a)^B\,da\\ + &\le H(\alpha_-) + -\frac12\frac{B}{B+1} + \left[(1-\alpha_-)^{B+1}-(1-\alpha_+)^{B+1}\right]. +\end{align*} +The second inequality uses $H'(a)=\log(1/a)+\log(1-a)$. + +Write +\[ + W(C):=L-2\log L-C. +\] +By hypothesis $W(C)\ge W_h\to\infty$. Uniformly over~\eqref{eq:C-window}, +\[ + H(\alpha_-)=O\left(\frac{L^2}{B}\right) + =o(e^{-C}), +\] +because +\[ + e^{-C}=e^{W(C)}\frac{L^2}{B}. +\] +Also $C=O(L)$ gives +\[ + (1-\alpha_-)^{B+1}=e^{-C}(1+o(1)). +\] +Finally, +\[ + C^\sharp-C=\frac{L-C}{2} + \ge\log L+\frac{W_h}{2}, +\] +so +\[ + (1-\alpha_+)^{B+1} + =e^{-C^\sharp}(1+o(1)) + =o(e^{-C}). +\] +All estimates are uniform, proving~\eqref{eq:near-critical-psi}. +\end{proof} + +\begin{proof}[Proof of Corollary~\ref{cor:fixed-slack}] +For $C=cL$ with $c\in[c_-,c_+]$, one has +\[ + L-2\log L-C=(1-c)L-2\log L\to\infty +\] +uniformly. Theorem~\ref{thm:near-critical} gives $e^{-C}=B^{-c}$. +\end{proof} + +\begin{proof}[Proof of Theorem~\ref{thm:random-fixed-window}] +Put +\[ + C_h^*=L_h-2\log L_h-\omega, + \qquad + T_n=\frac{nC_h^*}{B_h}. +\] +If $T_n\le1$, then the real-valued lower bound follows from +$\gamma_h(G)\ge1$. Otherwise set +\[ + m_n=\lceil T_n\rceil-1, + \qquad + C_n=\frac{m_nB_h}{n}. +\] +Condition~\eqref{eq:fixed-window-growth} implies $B_h/n=o(1)$. Indeed, $h=\Theta_d(L_h)$. If $B_h\ge n$ along a subsequence and $x=B_h/n\ge1$, then +\[ + \frac{nL_h^2/B_h}{h\log n} + =\Theta_d\!\left( + \frac{L_h}{x\log n} + \right) + =\Theta_d\!\left( + \frac{1+\log x/\log n}{x} + \right) + =O_d(1), +\] +contradicting~\eqref{eq:fixed-window-growth}. Hence $B_h0$. If $T_n\le1$, the real-valued lower bound follows from $\gamma_h(G)\ge1$. Otherwise put +\[ + m_n=\lceil T_n\rceil-1, + \qquad + C_n=\frac{m_nB_h}{n}. +\] +Then $m_n0$ such that $C_h^*\ge2\eta L_h$ eventually. Then, for large $h$, +\[ + \eta L_h\le C_n\le C_h^*. +\] +Apply Theorem~\ref{thm:near-critical} with this $\eta$ and the same $W_h$. Since $e^{-C_n}\ge e^{-C_h^*}=e^{W_h}L_h^2/B_h$ and $\frac12-o(1)\ge\frac13$ for sufficiently large $h$, +\[ + \log\E Z_{n,d,h}(m_n) + \le-\frac13 + \frac{n e^{W_h}L_h^2}{B_h} + +O_d(h\log n), +\] +which tends to $-\infty$ by~\eqref{eq:near-growth-condition}. Markov's inequality shows that the configuration model has no dominating set of size exactly $m_n$ with high probability. Any smaller dominating set could be padded to size $m_n$, so +\[ + \gamma_h(G)\ge m_n+1=\lceil T_n\rceil\ge T_n. +\] +Conditioning on simplicity transfers the conclusion to the uniformly random simple $d$-regular graph. +\end{proof} + +\begin{proof}[Proof of Corollary~\ref{cor:random-fixed}] +Choose +\[ + W_h=\eps L_h-2\log L_h. +\] +Then $W_h\to\infty$, +\[ + C_h^*=(1-\eps)L_h, + \qquad + \frac{C_h^*}{L_h}=1-\eps>0, +\] +and +\[ + \frac{e^{W_h}L_h^2}{B_h}=B_h^{-(1-\eps)}. +\] +Thus Theorem~\ref{thm:random-near-critical} applies directly. +\end{proof} + + + +\section{Numerical verification and conditioning}\label{sec:numerics} +The proofs above do not use numerical evidence. The accompanying package nevertheless checks every stationary identity, the one-step shadowing expansions, the density targeting, and the activity law with controlled-precision arithmetic. + +A cancellation issue discovered during numerical verification is important for reproducibility. Direct evaluation of +\[ + \phi=\log Z_v-\frac d2\log Z_e +\] +can be ill-conditioned near criticality: both logarithms are large, and individual vertex terms of the form $S_i^d-(S_i-B_{i-1})^d$ may lose precision. The consolidated solver evaluates these differences as +\[ + S_i^d\bigl[-\operatorname{expm1}(d\log(1-B_{i-1}/S_i))\bigr] +\] +and reports the microcanonical exponent through the corrected root-only formula~\eqref{eq:root-micro-correct}. The direct partition-function route is retained as an independent comparison. A row is rejected unless +\[ + \frac{|\Psi_{Z_v}-\Psi_{\rm root}|}{|\Psi_{\rm root}|}\le10^{-6}. +\] +Thus a cross-check residual comparable to the reported quantity gates the record rather than remaining hidden in an internal data structure. + +For the diagnostic choice $W_h=\log\log B_h$, the regenerated cubic values are +\begin{center} +\begin{tabular}{cccc} +\toprule +$h$ & $C$ & $-\Psi/e^{-C}$ & activity-law ratio\\ +\midrule +20 & $6.8451$ & $0.6484$ & $0.5873$\\ +30 & $12.6345$ & $0.9418$ & $0.9520$\\ +40 & $18.7408$ & $0.9757$ & $0.9956$\\ +52 & $26.2980$ & $0.9819$ & $0.9997$\\ +\bottomrule +\end{tabular} +\end{center} +The activity-law ratio is +\[ + \frac{-\log z-\log(1/\alpha)}{B_h(1-\alpha)^{B_h}}. +\] +The effective onset is slower when $C/\log B_h$ is small, consistent with uniformity only on compact intervals bounded away from zero. Every numerical row records the checker hash, solver hash, precision, stationarity residual, telescoping residual, and the discrepancy between the direct and root-only free-energy routes. + + + + +The bounded-window audit evaluates both the true stationary optimizer and the capped-free profile at the center $s=0$. The two quantities approach the coupon term from opposite sides: +\begin{center} +\begin{tabular}{cccc} +\toprule +$(d,h)$ & $(H-\Psi)/Q_h$ & cap loss$/Q_h$ & $C_h^{\rm ann}-\widehat C_{B_h}$\\ +\midrule +$(3,20)$ & $0.8750056$ & $1.0593258$ & $-1.03077\times10^{-1}$\\ +$(3,30)$ & $0.9902396$ & $1.0076650$ & $-8.00386\times10^{-3}$\\ +$(3,40)$ & $0.9990005$ & $1.0009330$ & $-8.57353\times10^{-4}$\\ +$(4,24)$ & $0.9999148$ & $1.0000702$ & $-6.78418\times10^{-5}$\\ +$(4,32)$ & $0.9999988$ & $1.0000012$ & $-1.01763\times10^{-6}$\\ +\bottomrule +\end{tabular} +\end{center} +The cap-loss and product identities are evaluated independently from the compact functional; their recorded residuals are below $10^{-120}$ in the displayed high-precision runs. The stationary entropy-defect identity~\eqref{eq:defect-identity} and the graph-zero computations provide separate checks of the two sides of the proof. + +\section{Consequences and open problems}\label{sec:open} +Theorems~\ref{thm:bounded-critical-window} and~\ref{thm:random-fixed-window} determine the annealed transition, its bounded window, and its universal scaling function. The capped-free construction also isolates the mechanism behind the coupon term: at the critical scale, the leading entropy defect is the cost of forbidding one empty terminal branch set. Two harder frontiers remain logically separate. + +\paragraph{Quenched matching.} +The random-regular theorem is a first-moment lower bound. A matching upper bound near $C_h^{\rm ann}$ would require proving that dominating sets actually exist above the annealed crossing. Plausible routes include a second-moment analysis with an overlap variational problem, small-subgraph conditioning, or an algorithmic construction whose output reaches the scalar coupon coordinate. The bounded-window theorem now supplies a precise target and separates any quenched correction from uncertainty in the annealed calculation. + +\paragraph{Direct two-branch asymptotics.} +Internally two-path $(h,2)$ domination is stronger than ordinary distance domination, so the present lower bound transfers automatically. It does not identify the parameter's own leading constant or critical correction. A direct treatment must remember branch information without falsely treating two paths that later merge as internally disjoint. Directed nonbacktracking cavity states are a natural exact intermediary, but the corresponding type system and variational reduction remain to be developed. + +The exponent $1/7$ in the graph--scalar comparison is a bookkeeping exponent rather than a predicted optimum. Improving it would sharpen finite-$h$ convergence but would not change the scaling function or any fixed-order inverse-logarithmic term. + +\section*{Acknowledgements} +\emph{To be completed by the author before circulation.} + +\begin{thebibliography}{99} +\bibitem{AignerFromme1984} +M. Aigner and M. Fromme, +\emph{A game of cops and robbers}, +Discrete Applied Mathematics 8 (1984), 1--12; DOI: \href{https://doi.org/10.1016/0166-218X(84)90073-8}{10.1016/0166-218X(84)90073-8}. + +\bibitem{CohenHonkalaLitsynLobstein1997} +G. Cohen, I. Honkala, S. Litsyn, and A. Lobstein, +\emph{Covering Codes}, +North-Holland Mathematical Library 54, Elsevier, 1997. + +\bibitem{CutlerRadcliffe2016} +J. Cutler and A. J. Radcliffe, +\emph{Counting dominating sets and related structures in graphs}, +Discrete Mathematics 339 (2016), 1593--1599; DOI: \href{https://doi.org/10.1016/j.disc.2015.12.011}{10.1016/j.disc.2015.12.011}. + +\bibitem{Duckworth2005} +W. Duckworth, +\emph{Randomized greedy algorithms for finding small $k$-dominating sets of regular graphs}, +Random Structures \& Algorithms 27 (2005), 401--412; DOI: \href{https://doi.org/10.1002/rsa.20082}{10.1002/rsa.20082}. + +\bibitem{DuckworthWormald2006} +W. Duckworth and N. C. Wormald, +\emph{On the independent domination number of random regular graphs}, +Combinatorics, Probability and Computing 15 (2006), 513--522; DOI: \href{https://doi.org/10.1017/S0963548305007431}{10.1017/S0963548305007431}. + +\bibitem{GlebovLiebenauSzabo2015} +R. Glebov, A. Liebenau, and T. Szab\'o, +\emph{On the concentration of the domination number of the random graph}, +SIAM Journal on Discrete Mathematics 29 (2015), 1186--1206; DOI: \href{https://doi.org/10.1137/12090054X}{10.1137/12090054X}. + +\bibitem{HabibullaQin2019} +Y. Habibulla and S.-m. Qin, +\emph{Two-distance minimal dominating set problem studied by statistical mechanics and simulated annealing}, +arXiv:1910.07933, 2019; \href{https://arxiv.org/abs/1910.07933}{arXiv link}. + +\bibitem{Janson2009} +S. Janson, +\emph{The probability that a random multigraph is simple}, +Combinatorics, Probability and Computing 18 (2009), 205--225; DOI: \href{https://doi.org/10.1017/S0963548308009644}{10.1017/S0963548308009644}. + +\bibitem{LuPeng2012} +L. Lu and X. Peng, +\emph{On Meyniel's conjecture of the cop number}, +Journal of Graph Theory 71 (2012), 192--205; DOI: \href{https://doi.org/10.1002/jgt.20642}{10.1002/jgt.20642}. + +\bibitem{Neuwirth2026Tube} +L. Neuwirth, +\emph{Branch-tube persistence and static coverage in tree-ball geometry}, +preprint, 2026; \href{https://levineuwirth.org/essays/branch-based-local-capture-in-tree-balls/}{project page}. + +\bibitem{PralatWormald2016} +P. Pra\l at and N. C. Wormald, +\emph{Meyniel's conjecture holds for random graphs}, +Random Structures \& Algorithms 48 (2016), 396--421; DOI: \href{https://doi.org/10.1002/rsa.20587}{10.1002/rsa.20587}. + +\bibitem{PralatWormald2019} +P. Pra\l at and N. C. Wormald, +\emph{Meyniel's conjecture holds for random $d$-regular graphs}, +Random Structures \& Algorithms 55 (2019), 719--741; DOI: \href{https://doi.org/10.1002/rsa.20874}{10.1002/rsa.20874}. + +\bibitem{RockafellarWets1998} +R. T. Rockafellar and R. J.-B. Wets, +\emph{Variational Analysis}, +Grundlehren der mathematischen Wissenschaften 317, Springer, 1998; DOI: \href{https://doi.org/10.1007/978-3-642-02431-3}{10.1007/978-3-642-02431-3}. + +\bibitem{ScottSudakov2011} +A. Scott and B. Sudakov, +\emph{A bound for the cops and robbers problem}, +SIAM Journal on Discrete Mathematics 25 (2011), 1438--1442; DOI: \href{https://doi.org/10.1137/100812963}{10.1137/100812963}. + +\bibitem{Wormald1999} +N. C. Wormald, +\emph{Models of random regular graphs}, +in Surveys in Combinatorics, 1999, London Mathematical Society Lecture Note Series 267, Cambridge University Press, 1999, pp. 239--298; DOI: \href{https://doi.org/10.1017/CBO9780511721335.010}{10.1017/CBO9780511721335.010}. + +\bibitem{ZhaoHabibullaZhou2015} +J.-H. Zhao, Y. Habibulla, and H.-J. Zhou, +\emph{Statistical mechanics of the minimum dominating set problem}, +Journal of Statistical Physics 159 (2015), 1154--1174; DOI: \href{https://doi.org/10.1007/s10955-015-1220-2}{10.1007/s10955-015-1220-2}. +\end{thebibliography} + +\end{document} diff --git a/static/css/now.css b/static/css/now.css index 7a38aca..7c89d7d 100644 --- a/static/css/now.css +++ b/static/css/now.css @@ -159,7 +159,9 @@ /* Per-status accents — each is intentionally restrained. Active states (in-review, drafting, building) get slightly stronger - ink; passive states (paused, shipped) recede. */ + ink; passive states (paused, shipped) recede. "accepted" is the + one affirmative state — full ink and a solid, confident border. */ +.now-status--accepted { color: var(--text); border-color: var(--text); font-weight: 600; } .now-status--in-review { color: var(--text); border-color: var(--text-muted); } .now-status--revising { color: var(--text); border-color: var(--text-muted); } .now-status--drafting { color: var(--text); } diff --git a/static/cv.pdf b/static/cv.pdf index f8c5d92..1db9973 100644 Binary files a/static/cv.pdf and b/static/cv.pdf differ diff --git a/static/cv.thumb.png b/static/cv.thumb.png index 311cec0..953e585 100644 Binary files a/static/cv.thumb.png and b/static/cv.thumb.png differ diff --git a/static/js/gallery.js b/static/js/gallery.js index 5e53c0c..b41a6d9 100644 --- a/static/js/gallery.js +++ b/static/js/gallery.js @@ -22,7 +22,10 @@ document.querySelectorAll('.exhibit[data-exhibit-name]').forEach(function (el) { var name = el.dataset.exhibitName || ''; var type = el.dataset.exhibitType || 'equation'; - var id = 'exhibit-' + slugify(name); + /* Preserve an author-assigned id (e.g. #thm-persistence, used for + cross-references both within the page and from other essays) — + only generate one from the name when the element has none. */ + var id = el.id || ('exhibit-' + slugify(name)); el.id = id; exhibits.push({ el: el, type: type, name: name, id: id }); }); diff --git a/static/papers/ball-occupation-paper.pdf b/static/papers/ball-occupation-paper.pdf new file mode 100644 index 0000000..5b926f2 Binary files /dev/null and b/static/papers/ball-occupation-paper.pdf differ diff --git a/static/papers/ball-occupation-paper.thumb.png b/static/papers/ball-occupation-paper.thumb.png new file mode 100644 index 0000000..0207f1f Binary files /dev/null and b/static/papers/ball-occupation-paper.thumb.png differ diff --git a/static/papers/branch-capture-paper.pdf b/static/papers/branch-capture-paper.pdf index 921dd7a..3dcaf08 100644 Binary files a/static/papers/branch-capture-paper.pdf and b/static/papers/branch-capture-paper.pdf differ diff --git a/static/papers/branch-capture-paper.thumb.png b/static/papers/branch-capture-paper.thumb.png index 87a3b5d..8a45944 100644 Binary files a/static/papers/branch-capture-paper.thumb.png and b/static/papers/branch-capture-paper.thumb.png differ diff --git a/static/papers/growing-radius-domination-demo-output.csv b/static/papers/growing-radius-domination-demo-output.csv new file mode 100644 index 0000000..ca113ed --- /dev/null +++ b/static/papers/growing-radius-domination-demo-output.csv @@ -0,0 +1,8 @@ +d,h,dps,B_h,C,alpha_B_h,terminal_t,activity_ratio,minus_psi_over_exp_minus_C,psi_root,psi_direct,route_relative_disagreement,stationarity_residual,telescoping_residual,compact_residual,source_sha256 +3,12,90,12286.0,2.68891585501040013976745,2.68891585501040013976745,1.5649521817236902514912410604,0.43761910441011800655,0.38704929760879828092,-0.0263017693847861766925997,-0.0263017693847861766925997,8.69648997003e-88,8.28042160528e-171,5.58680599144e-250,1.49001860314e-84,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f +3,20,110,3145726.0,6.84510347814699949522998,6.84510347814699949522998,2.59233190755103757476376681408,0.58731966449413053705,0.64837167469537249632,-0.000690292834108247212221875,-0.000690292834108247212221875,2.66900925683e-105,1.14656253968e-538,5.53263399978e-965,1.17925528381e-108,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f +3,30,130,3221225470.0,12.6345230553746044619009,12.6345230553746044619009,4.24843522695731804549429347768,0.95204332641006628599,0.94176771565242100741,-0.00000306789261548327935842162,-0.00000306789261548327935842162,5.64116276476e-123,6.75776572086e-2301,4.05185949322e-4470,1.76048737805e-128,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f +3,40,160,3298534883326.0,18.7408224021000065352103,18.7408224021000065352103,6.25102199356755672760671381765,0.99562972566514808396,0.97573044303281005292,-7.08425360319143688355618e-9,-7.08425360319143688355618e-9,2.42607964143e-149,6.8404849326e-5339,-1.97357088308e-10516,1.14143107304e-157,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f +4,12,100,1062881.0,5.98590477925353559863557,5.98590477925353559863557,3.27430811180715697841994080308,0.68162323087349072876,0.72854684100301358049,-0.00183152168317342646402893,-0.00183152168317342646402893,6.57339657635e-97,5.62858267109e-629,-5.58589608171e-892,4.82863310106e-95,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f +4,20,130,6973568801.0,13.3028752886383745882347,13.3028752886383745882347,6.65792202872351594182004835315,0.99149489768252470055,0.97063642934364656966,-0.00000162065754589300041933,-0.00000162065754589300041933,4.39042055762e-122,1.83300664684e-3752,-4.99348900811e-5145,3.38121775554e-130,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f +4,28,160,45753584909921.0,21.1086850002637408299362,21.1086850002637408299362,10.5544288265371556225644335766,0.99990750838490069309,0.97999453596106802522,-6.66558450055970876728766e-10,-6.66558450055970876728766e-10,1.6950057681e-148,9.00394642419e-9922,2.57879588178e-13675,7.14127931035e-158,1c3e000366291ab800ca7ee68f13a02ef58de39e945e71ecc81a3a3b02023f5f diff --git a/static/papers/growing-radius-domination-demo.py b/static/papers/growing-radius-domination-demo.py new file mode 100755 index 0000000..296611a --- /dev/null +++ b/static/papers/growing-radius-domination-demo.py @@ -0,0 +1,570 @@ +#!/usr/bin/env python3 +"""Reader-facing computations for growing-radius domination. + +This script accompanies the essay version of the preprint + + Near-Critical First-Moment Lower Bounds for + Growing-Radius Domination in Random Regular Graphs. + +It deliberately keeps the mathematical structure visible. The core steps are: + +1. compute the tree-ball volume B_h; +2. evaluate the conditioned local entropy s_d(a); +3. evaluate the exact compact microcanonical functional; +4. solve the unique stationary orbit by reverse transfer; +5. reconstruct density, activity, and free energy at the root; +6. target the near-critical coordinate C = alpha B_h; +7. gate every reported row by independent residual checks. + +Only ``mpmath`` is required for the main calculations. ``matplotlib`` is +optional and is used only by ``--plot``. + +The code is expository, not optimized for maximum throughput. Numerical +calculations illustrate the theorem and audit the identities; they are not +used in its proof. +""" + +from __future__ import annotations + +import argparse +import csv +import hashlib +import math +from dataclasses import dataclass +from pathlib import Path +from typing import Iterable, Sequence + +import mpmath as mp + + +# --------------------------------------------------------------------------- +# 1. Geometry and the expected scale +# --------------------------------------------------------------------------- + + +def tree_ball_volume(d: int, h: int) -> mp.mpf: + """Radius-h volume of the infinite d-regular tree.""" + if d < 3: + raise ValueError("d must be at least 3") + if h < 0: + raise ValueError("h must be nonnegative") + b = d - 1 + return mp.mpf(1) + d * (mp.power(b, h) - 1) / (d - 2) + + +def near_critical_coordinate(d: int, h: int, W: mp.mpf | None = None) -> mp.mpf: + """Return C = log B_h - 2 log log B_h - W. + + The demonstration default W=log log B_h stays a diverging distance below + the bounded critical window while remaining close enough to show the + predicted second-order term. + """ + B = tree_ball_volume(d, h) + L = mp.log(B) + if W is None: + W = mp.log(L) + return L - 2 * mp.log(L) - W + + +# --------------------------------------------------------------------------- +# 2. Exact local entropy and compact functional +# --------------------------------------------------------------------------- + + +def _conditioned_marginal(d: int, lam: mp.mpf) -> mp.mpf: + """Marginal of one coordinate in a nonempty tilted subset of [d].""" + log1p_lam = mp.log1p(lam) + numerator = lam * mp.exp((d - 1) * log1p_lam) + denominator = mp.expm1(d * log1p_lam) + return numerator / denominator + + +def lambda_from_marginal(d: int, a: mp.mpf) -> mp.mpf: + """Solve a = lambda(1+lambda)^(d-1)/((1+lambda)^d-1). + + A precision-scaled lower endpoint is important near the Moore corner, + where a-1/d can be exponentially small. + """ + a = mp.mpf(a) + lower = mp.mpf(1) / d + if a < lower or a > 1: + raise ValueError("a must lie in [1/d, 1]") + tol = mp.power(10, -(mp.mp.dps - 12)) + if abs(a - lower) <= tol: + return mp.mpf(0) + if abs(a - 1) <= tol: + return mp.inf + + # Bisection in log lambda avoids an enormous dynamic range. + lo = -mp.mpf(2) * mp.mp.dps * mp.log(10) + hi = mp.mpf(2) * mp.mp.dps * mp.log(10) + for _ in range(max(160, 3 * mp.mp.dps)): + mid = (lo + hi) / 2 + lam = mp.exp(mid) + if _conditioned_marginal(d, lam) < a: + lo = mid + else: + hi = mid + return mp.exp((lo + hi) / 2) + + +def conditioned_subset_entropy(d: int, a: mp.mpf) -> mp.mpf: + r"""Maximum entropy s_d(a) on nonempty subsets with marginal a. + + s_d(a) = inf_{lambda>0} [log((1+lambda)^d-1)-da log lambda]. + """ + a = mp.mpf(a) + lower = mp.mpf(1) / d + tol = mp.power(10, -(mp.mp.dps - 12)) + if abs(a - lower) <= tol: + return mp.log(d) + if abs(a - 1) <= tol: + return mp.mpf(0) + lam = lambda_from_marginal(d, a) + log_partition = mp.log(mp.expm1(d * mp.log1p(lam))) + return log_partition - d * a * mp.log(lam) + + +def _xlogx(x: mp.mpf) -> mp.mpf: + return mp.mpf(0) if x == 0 else x * mp.log(x) + + +def compact_microcanonical_value( + d: int, + h: int, + x: Sequence[mp.mpf], + ell: Sequence[mp.mpf], +) -> tuple[mp.mpf, mp.mpf]: + r"""Evaluate the exact compact functional. + + Coordinates: + x_i = q_{i-1,i}, i=1,...,h, + ell_i = q_{i,i}, i=0,...,h. + + The layer masses are p_i = ell_i + x_i + x_{i+1}, with x_0=x_{h+1}=0. + Returns (F, alpha=p_0). + """ + if len(x) != h or len(ell) != h + 1: + raise ValueError("wrong coordinate lengths") + xx = [mp.mpf(0)] + [mp.mpf(v) for v in x] + [mp.mpf(0)] + ll = [mp.mpf(v) for v in ell] + if any(v < 0 for v in xx) or any(v < 0 for v in ll): + raise ValueError("coordinates must be nonnegative") + + p = [ll[i] + xx[i] + xx[i + 1] for i in range(h + 1)] + if abs(sum(p) - 1) > mp.power(10, -(mp.mp.dps // 2)): + raise ValueError("profile is not normalized") + + alpha = p[0] + value = (d - 1) * _xlogx(alpha) + for i in range(1, h + 1): + if p[i] == 0: + continue + a_i = xx[i] / p[i] + lower = mp.mpf(1) / d + numerical_tol = mp.power(10, -(mp.mp.dps // 3)) + if a_i < lower - numerical_tol or a_i > 1 + numerical_tol: + raise ValueError("descent marginal is infeasible") + a_i = min(mp.mpf(1), max(lower, a_i)) + y_i = p[i] - xx[i] + value += -_xlogx(p[i]) + value += p[i] * conditioned_subset_entropy(d, a_i) + value += d * _xlogx(y_i) + value -= mp.mpf(d) / 2 * sum(_xlogx(v) for v in ll) + return value, alpha + + +# --------------------------------------------------------------------------- +# 3. Reverse transfer and stationary reconstruction +# --------------------------------------------------------------------------- + + +@dataclass +class StationaryPoint: + d: int + h: int + terminal_t: mp.mpf + terminal: mp.mpf + z: mp.mpf + alpha: mp.mpf + phi_direct: mp.mpf + psi_direct: mp.mpf + phi_root: mp.mpf + psi_root: mp.mpf + kappa: mp.mpf + r0: mp.mpf + Zv: mp.mpf + Ze: mp.mpf + telescoping_residual: mp.mpf + root_pressure_residual: mp.mpf + root_micro_residual: mp.mpf + stationarity_residual: mp.mpf + compact_residual: mp.mpf + rho: list[mp.mpf] + u: list[mp.mpf] + A: list[mp.mpf] + Bmsg: list[mp.mpf] + + +def _w_e(rho: mp.mpf, b: int) -> tuple[mp.mpf, mp.mpf]: + """Return w=(1-rho)^(1/b) and e=1-w without cancellation.""" + log_w = mp.log1p(-rho) / b + return mp.exp(log_w), -mp.expm1(log_w) + + +def reverse_step(rho_next: mp.mpf, v_next: mp.mpf, b: int) -> tuple[mp.mpf, mp.mpf]: + r"""Invert one stationary transfer step. + + Input lies in D={(rho,v): 0 mp.mpf: + """Compute S^power-(S-B)^power stably when B/S is tiny.""" + ratio = B / S + return mp.power(S, power) * (-mp.expm1(power * mp.log1p(-ratio))) + + +def stationary_from_terminal_t( + d: int, h: int, terminal_t: mp.mpf, *, validate_compact: bool = True +) -> StationaryPoint: + r"""Construct the unique positive stationary orbit. + + We use t=-log(1-s) rather than s directly. At high density the terminal + parameter s is extraordinarily close to one, while t remains numerically + well scaled. + """ + if d < 3 or h < 1: + raise ValueError("require d>=3 and h>=1") + b = d - 1 + t = mp.mpf(terminal_t) + if t <= 0: + raise ValueError("terminal_t must be positive") + terminal = -mp.expm1(-t) + + rho = [mp.mpf(0)] * (h + 1) + v = [mp.mpf(0)] * (h + 1) + u = [mp.mpf(0)] * (h + 1) + rho[h] = v[h] = terminal + for i in range(h - 1, 0, -1): + rho[i], v[i] = reverse_step(rho[i + 1], v[i + 1], b) + u[i] = v[i] - rho[i] + u[h] = mp.mpf(0) + + w1, e1 = _w_e(rho[1], b) + if e1 == 0: + raise ArithmeticError("root coordinate under-resolved; increase mp.dps") + r0 = v[1] * e1 / w1 + kappa = mp.power(v[1] / w1, b) + z = r0 * kappa / mp.power(1 + r0, b) + + # Normalize A_1=1 and reconstruct the messages. + A = [mp.mpf(0)] * (h + 2) + Bmsg = [mp.mpf(0)] * (h + 1) + A[1] = mp.mpf(1) + for i in range(1, h): + A[i + 1] = u[i] * A[i] + Bmsg[0] = r0 + for i in range(1, h + 1): + Bmsg[i] = rho[i] * A[i] + + S = [mp.mpf(0)] * (h + 1) + S[0] = Bmsg[0] + A[1] + for i in range(1, h): + S[i] = Bmsg[i - 1] + Bmsg[i] + A[i + 1] + S[h] = Bmsg[h - 1] + Bmsg[h] + + vertex_terms = [z * mp.power(S[0], d)] + for i in range(1, h + 1): + vertex_terms.append(_stable_power_difference(S[i], Bmsg[i - 1], d)) + Zv = mp.fsum(vertex_terms) + Ze = mp.fsum(v * v for v in Bmsg) + 2 * mp.fsum( + Bmsg[i] * A[i + 1] for i in range(h) + ) + + alpha = Bmsg[0] * (Bmsg[0] + A[1]) / Ze + phi_direct = mp.log(Zv) - mp.mpf(d) / 2 * mp.log(Ze) + psi_direct = phi_direct - alpha * mp.log(z) + + # Correct, well-conditioned root-only formulas. + phi_root = ( + mp.log(z) + + mp.mpf(d) / 2 * mp.log((1 + r0) / r0) + + mp.mpf(d - 2) / 2 * mp.log(alpha) + ) + psi_root = ( + (1 - alpha) * mp.log(kappa) + - (mp.mpf(d - 2) / 2 + alpha) * mp.log(r0) + + mp.mpf(d - 2) / 2 * mp.log(alpha) + + (mp.mpf(d - 1) * alpha - mp.mpf(d - 2) / 2) * mp.log(1 + r0) + ) + + stationarity = [abs(kappa * Bmsg[0] - z * mp.power(S[0], b))] + for i in range(1, h + 1): + stationarity.append(abs(kappa * A[i] - mp.power(S[i], b))) + stationarity.append( + abs( + kappa * Bmsg[i] + - _stable_power_difference(S[i], Bmsg[i - 1], b) + ) + ) + + # Reconstruct the compact profile only for final diagnostic points. + if validate_compact: + x = [Bmsg[i - 1] * A[i] / Ze for i in range(1, h + 1)] + ell = [Bmsg[i] * Bmsg[i] / Ze for i in range(h + 1)] + compact_value, compact_alpha = compact_microcanonical_value(d, h, x, ell) + compact_residual = max(abs(compact_value - psi_root), abs(compact_alpha - alpha)) + else: + compact_residual = mp.nan + + return StationaryPoint( + d=d, + h=h, + terminal_t=t, + terminal=terminal, + z=z, + alpha=alpha, + phi_direct=phi_direct, + psi_direct=psi_direct, + phi_root=phi_root, + psi_root=psi_root, + kappa=kappa, + r0=r0, + Zv=Zv, + Ze=Ze, + telescoping_residual=Zv - kappa * Ze, + root_pressure_residual=phi_direct - phi_root, + root_micro_residual=psi_direct - psi_root, + stationarity_residual=max(stationarity), + compact_residual=compact_residual, + rho=rho, + u=u, + A=A, + Bmsg=Bmsg, + ) + + +# --------------------------------------------------------------------------- +# 4. Target-density solving and residual gates +# --------------------------------------------------------------------------- + + +def solve_for_alpha_B( + d: int, + h: int, + C: mp.mpf, + *, + iterations: int | None = None, +) -> StationaryPoint: + """Solve alpha B_h = C by bisection in terminal_t.""" + B = tree_ball_volume(d, h) + target_alpha = mp.mpf(C) / B + if not 0 < target_alpha < 1: + raise ValueError("target density must lie in (0,1)") + if iterations is None: + iterations = max(140, 2 * mp.mp.dps) + + D = mp.mpf(d) / (d - 2) + lo = mp.mpf("0.05") * C / D + hi = mp.mpf("3.0") * C / D + 1 + while stationary_from_terminal_t(d, h, lo, validate_compact=False).alpha > target_alpha: + lo /= 2 + while stationary_from_terminal_t(d, h, hi, validate_compact=False).alpha < target_alpha: + hi *= 2 + + for _ in range(iterations): + mid = (lo + hi) / 2 + point = stationary_from_terminal_t(d, h, mid, validate_compact=False) + if point.alpha < target_alpha: + lo = mid + else: + hi = mid + return stationary_from_terminal_t(d, h, (lo + hi) / 2, validate_compact=True) + + +def relative_residual(residual: mp.mpf, reference: mp.mpf) -> mp.mpf: + return abs(residual) / max(abs(reference), mp.mpf(1)) + + +def gate_point(point: StationaryPoint, route_tolerance: str = "1e-6") -> None: + """Reject a row if an internal cross-check is too large to ignore. + + The direct partition-function route can be ill conditioned near criticality. + The root-only formula is the reported value, but the direct route must still + agree to the requested relative tolerance at the working precision. + """ + tol = mp.mpf(route_tolerance) + if point.psi_root == 0: + raise RuntimeError("zero root-formula microcanonical exponent") + route_disagreement = abs(point.root_micro_residual / point.psi_root) + if route_disagreement > tol: + raise RuntimeError( + "microcanonical routes disagree: " + f"relative discrepancy={route_disagreement}; increase mp.dps" + ) + if point.compact_residual > mp.sqrt(tol): + raise RuntimeError( + f"compact-functional reconstruction failed: {point.compact_residual}" + ) + + +def diagnostic_row(d: int, h: int, W: mp.mpf | None = None) -> dict[str, str | int]: + """Solve one near-critical case and return an audit-friendly record.""" + B = tree_ball_volume(d, h) + L = mp.log(B) + if W is None: + W = mp.log(L) + C = near_critical_coordinate(d, h, W) + point = solve_for_alpha_B(d, h, C) + gate_point(point) + + coupon = B * mp.power(1 - point.alpha, B) + activity_ratio = (-mp.log(point.z) - mp.log(1 / point.alpha)) / coupon + scale = mp.exp(-C) + route_disagreement = abs(point.root_micro_residual / point.psi_root) + + return { + "d": d, + "h": h, + "dps": mp.mp.dps, + "B_h": mp.nstr(B, 30), + "C": mp.nstr(C, 24), + "alpha_B_h": mp.nstr(point.alpha * B, 24), + "terminal_t": mp.nstr(point.terminal_t, 30), + "activity_ratio": mp.nstr(activity_ratio, 20), + "minus_psi_over_exp_minus_C": mp.nstr(-point.psi_root / scale, 20), + "psi_root": mp.nstr(point.psi_root, 24), + "psi_direct": mp.nstr(point.psi_direct, 24), + "route_relative_disagreement": mp.nstr(route_disagreement, 12), + "stationarity_residual": mp.nstr(point.stationarity_residual, 12), + "telescoping_residual": mp.nstr(point.telescoping_residual, 12), + "compact_residual": mp.nstr(point.compact_residual, 12), + "source_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), + } + + +# --------------------------------------------------------------------------- +# 5. Tables and optional plotting +# --------------------------------------------------------------------------- + + +def default_cases() -> list[tuple[int, int, int]]: + """(d,h,dps) cases chosen to keep a demonstration run manageable.""" + return [ + (3, 12, 90), + (3, 20, 110), + (3, 30, 130), + (3, 40, 160), + (4, 12, 100), + (4, 20, 130), + (4, 28, 160), + ] + + +def make_table( + cases: Iterable[tuple[int, int, int]], + *, + csv_path: str | None = None, +) -> list[dict[str, str | int]]: + rows: list[dict[str, str | int]] = [] + for d, h, dps in cases: + mp.mp.dps = dps + row = diagnostic_row(d, h) + rows.append(row) + print( + f"d={d} h={h:>2} C={row['C']} " + f"activity={row['activity_ratio']} " + f"-Psi/e^-C={row['minus_psi_over_exp_minus_C']}" + ) + if csv_path: + with open(csv_path, "w", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=list(rows[0].keys())) + writer.writeheader() + writer.writerows(rows) + return rows + + +def plot_rows(rows: Sequence[dict[str, str | int]], output: str) -> None: + """Plot the two diagnostic ratios; matplotlib is optional.""" + try: + import matplotlib.pyplot as plt + except ImportError as exc: + raise RuntimeError("install matplotlib to use --plot") from exc + + by_d: dict[int, list[dict[str, str | int]]] = {} + for row in rows: + by_d.setdefault(int(row["d"]), []).append(row) + + # Separate figures keep the diagnostics readable. + for field, ylabel, suffix in [ + ("activity_ratio", "activity-law ratio", "activity"), + ("minus_psi_over_exp_minus_C", r"$-\Psi/e^{-C}$", "free_energy"), + ]: + plt.figure() + for d, group in sorted(by_d.items()): + group = sorted(group, key=lambda r: int(r["h"])) + plt.plot( + [int(r["h"]) for r in group], + [float(r[field]) for r in group], + marker="o", + label=f"d={d}", + ) + plt.axhline(1.0, linestyle="--") + plt.xlabel("radius h") + plt.ylabel(ylabel) + plt.legend() + plt.tight_layout() + path = str(Path(output).with_name(Path(output).stem + f"_{suffix}.png")) + plt.savefig(path, dpi=180) + plt.close() + print(path) + + +# --------------------------------------------------------------------------- +# 6. Command line interface +# --------------------------------------------------------------------------- + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--d", type=int, default=3) + parser.add_argument("--h", type=int, default=20) + parser.add_argument("--dps", type=int, default=110) + parser.add_argument( + "--W", + type=str, + default=None, + help="additive gap W; default is log log B_h", + ) + parser.add_argument("--table", action="store_true", help="run the curated table") + parser.add_argument("--csv", type=str, default=None, help="optional CSV output") + parser.add_argument("--plot", type=str, default=None, help="plot prefix for table output") + return parser.parse_args() + + +def main() -> None: + args = parse_args() + if args.table: + rows = make_table(default_cases(), csv_path=args.csv) + if args.plot: + plot_rows(rows, args.plot) + return + + mp.mp.dps = args.dps + W = None if args.W is None else mp.mpf(args.W) + row = diagnostic_row(args.d, args.h, W) + for key, value in row.items(): + print(f"{key}: {value}") + + +if __name__ == "__main__": + main() diff --git a/static/papers/growing-radius-domination-paper.pdf b/static/papers/growing-radius-domination-paper.pdf new file mode 100644 index 0000000..91fa57b Binary files /dev/null and b/static/papers/growing-radius-domination-paper.pdf differ diff --git a/static/papers/growing-radius-domination-paper.thumb.png b/static/papers/growing-radius-domination-paper.thumb.png new file mode 100644 index 0000000..ae21c1c Binary files /dev/null and b/static/papers/growing-radius-domination-paper.thumb.png differ diff --git a/static/papers/near-critical-growing-radius-domination-paper.pdf b/static/papers/near-critical-growing-radius-domination-paper.pdf new file mode 100644 index 0000000..095e5e6 Binary files /dev/null and b/static/papers/near-critical-growing-radius-domination-paper.pdf differ diff --git a/static/papers/near-critical-growing-radius-domination-paper.thumb.png b/static/papers/near-critical-growing-radius-domination-paper.thumb.png new file mode 100644 index 0000000..aa6e2ea Binary files /dev/null and b/static/papers/near-critical-growing-radius-domination-paper.thumb.png differ diff --git a/static/resume.pdf b/static/resume.pdf index ab726c2..de28135 100644 Binary files a/static/resume.pdf and b/static/resume.pdf differ diff --git a/static/resume.thumb.png b/static/resume.thumb.png index 99a0c1c..666b89d 100644 Binary files a/static/resume.thumb.png and b/static/resume.thumb.png differ diff --git a/tests/test_import_content.py b/tests/test_import_content.py new file mode 100644 index 0000000..d23e9a0 --- /dev/null +++ b/tests/test_import_content.py @@ -0,0 +1,265 @@ +from __future__ import annotations + +import argparse +import contextlib +import importlib.util +import io +import sys +import tempfile +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] +MODULE_PATH = REPO_ROOT / "tools" / "import-content.py" +SPEC = importlib.util.spec_from_file_location("import_content", MODULE_PATH) +assert SPEC is not None and SPEC.loader is not None +import_content = importlib.util.module_from_spec(SPEC) +sys.modules[SPEC.name] = import_content +SPEC.loader.exec_module(import_content) + + +def args_for(**overrides: object) -> argparse.Namespace: + values: dict[str, object] = { + "type": "page", + "title_prefix": None, + "date": None, + "tags": None, + "author": None, + "field": [], + "collection": None, + "overwrite": False, + } + values.update(overrides) + return argparse.Namespace(**values) + + +class ImportContentTests(unittest.TestCase): + def test_author_override_uses_authors_list(self) -> None: + doc = import_content.Document( + "Title\n\nBody", {"authors": ["Previous Author"]} + ) + + import_content.apply_schema( + [doc], args_for(author="Ada Lovelace") + ) + + self.assertEqual(doc.meta["authors"], ["Ada Lovelace"]) + + def test_duplicate_output_destinations_are_rejected(self) -> None: + docs = [ + import_content.Document("First", {"title": "Same"}), + import_content.Document("Second", {"title": "Same"}), + ] + + with self.assertRaisesRegex( + import_content.ContentImportError, + "duplicate output destination content/same.md", + ): + import_content.assemble_file_entries(docs, args_for()) + + def test_explicit_source_slugs_determine_output_paths(self) -> None: + docs = [ + import_content.Document( + "First", {"title": "Same", "slug": "source-one"} + ), + import_content.Document( + "Second", {"title": "Same", "slug": "source-two"} + ), + ] + + entries = import_content.assemble_file_entries(docs, args_for()) + + self.assertEqual( + {path.as_posix() for path, _content, _label in entries}, + {"content/source-one.md", "content/source-two.md"}, + ) + + def test_collections_support_every_content_type(self) -> None: + expected = { + "essay": ( + "content/essays/cycle", + "/essays/cycle/", + ), + "blog": ( + "content/blog/cycle", + "/blog/cycle/", + ), + "fiction": ( + "content/fiction/cycle", + "/fiction/cycle/", + ), + "poetry": ( + "content/poetry/cycle", + "/poetry/cycle/", + ), + "page": ( + "content/cycle", + "/cycle/", + ), + } + + for content_type, (directory, collection_url) in expected.items(): + with self.subTest(content_type=content_type): + doc = import_content.Document("Body", {"title": "Piece"}) + entries = import_content.assemble_file_entries( + [doc], + args_for(type=content_type, collection="Cycle"), + ) + + self.assertEqual( + {path.as_posix() for path, _content, _label in entries}, + {f"{directory}/piece.md", f"{directory}/index.md"}, + ) + self.assertEqual( + doc.meta["collection-url"], collection_url + ) + + def test_page_collection_rejects_reserved_section_slug(self) -> None: + docs = [import_content.Document("Body", {"title": "Piece"})] + + with self.assertRaisesRegex( + import_content.ContentImportError, + "conflicts with a reserved content directory", + ): + import_content.assemble_file_entries( + docs, args_for(type="page", collection="Fiction") + ) + + def test_writing_types_require_valid_iso_dates(self) -> None: + with self.assertRaisesRegex( + import_content.ContentImportError, + "a date in YYYY-MM-DD format is required", + ): + import_content.apply_schema( + [import_content.Document("Body", {"title": "Story"})], + args_for(type="fiction"), + ) + + with self.assertRaisesRegex( + import_content.ContentImportError, "invalid date" + ): + import_content.apply_schema( + [import_content.Document("Body", {"title": "Story"})], + args_for(type="fiction", date="2026-02-30"), + ) + + def test_opening_prose_is_not_consumed_as_a_title(self) -> None: + body = "This is the opening sentence.\nThe paragraph continues here." + doc = import_content.Document(body) + + import_content.apply_schema([doc], args_for()) + + self.assertEqual(doc.meta["title"], "Untitled") + self.assertEqual(doc.body, body) + self.assertEqual( + doc.meta["abstract"], + "This is the opening sentence. The paragraph continues here.", + ) + + def test_invalid_regex_exits_without_writing(self) -> None: + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + source = root / "source.txt" + source.write_text("Title\n\nBody\n", encoding="utf-8") + stdout = io.StringIO() + stderr = io.StringIO() + + with contextlib.chdir(root), contextlib.redirect_stdout(stdout), \ + contextlib.redirect_stderr(stderr): + status = import_content.main([ + str(source), "--splitter", "regex", "--regex", "(", + ]) + + self.assertEqual(status, 2) + self.assertIn("error: invalid regex pattern", stderr.getvalue()) + self.assertFalse((root / "content").exists()) + + def test_consecutive_headings_keep_the_nonempty_section_title(self) -> None: + docs = import_content.split_heading_1( + import_content.Document("# First\n# Second\nSecond body"), {} + ) + + self.assertEqual(len(docs), 1) + self.assertEqual(docs[0].meta, {"number": 1, "title": "Second"}) + self.assertEqual(docs[0].body, "Second body") + + def test_page_break_handles_form_feed_and_preserves_no_match(self) -> None: + split = import_content.split_page_break( + import_content.Document("first\fsecond"), {} + ) + untouched = import_content.Document("Body only") + + self.assertEqual( + [(doc.meta, doc.body) for doc in split], + [({"number": 1}, "first"), ({"number": 2}, "second")], + ) + self.assertEqual( + import_content.split_page_break(untouched, {}), [untouched] + ) + + def test_frontmatter_must_be_a_yaml_mapping(self) -> None: + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + source = root / "source.md" + source.write_text( + "---\nOrdinary paragraph.\n---\nThis survives.\n", + encoding="utf-8", + ) + + with contextlib.chdir(root), self.assertRaisesRegex( + import_content.ContentImportError, + "frontmatter must be a YAML mapping", + ): + import_content.read_file_per_document(["source.md"]) + + def test_structured_fields_are_validated(self) -> None: + with self.assertRaisesRegex( + import_content.ContentImportError, + "json entry 0 field 'body' must be a string", + ): + import_content._documents_from_records( + [{"title": "Bad", "body": 42}], Path("source.json"), "json" + ) + + with self.assertRaisesRegex( + import_content.ContentImportError, + "field 'number' must be a positive integer", + ): + import_content.apply_schema( + [ + import_content.Document( + "Body", {"title": "Bad", "number": "1"} + ) + ], + args_for(), + ) + + def test_collection_index_frontmatter_is_valid_yaml(self) -> None: + doc = import_content.Document( + "Body", + { + "title": "Piece", + "date": "2026-07-17", + "tags": ["poetry"], + "poet": "Ada Lovelace", + }, + ) + + rendered = import_content.generate_collection_index( + [doc], "Essays: 2026" + ) + metadata = import_content.yaml.safe_load(rendered.split("---", 2)[1]) + + self.assertEqual(metadata["title"], "Essays: 2026") + self.assertEqual(metadata["tags"], ["poetry"]) + + def test_abstract_respects_maximum_length_without_spaces(self) -> None: + abstract = import_content.auto_abstract("x" * 250, max_chars=200) + + self.assertEqual(len(abstract), 200) + self.assertTrue(abstract.endswith(" …")) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/import-content.py b/tools/import-content.py new file mode 100755 index 0000000..23368cf --- /dev/null +++ b/tools/import-content.py @@ -0,0 +1,960 @@ +#!/usr/bin/env python3 +""" +import-content.py — Import content from external sources into the site. + +Produces Markdown files under content/{type}/ from plain text, structured +data files, or existing Markdown files. + +Stages: + Reader → Splitter → Schema → Writer + +All four stages implemented. +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from dataclasses import dataclass, field +from datetime import date as date_type, datetime +from pathlib import Path +from typing import Any, Callable + +import yaml + + +# --------------------------------------------------------------------------- +# Types +# --------------------------------------------------------------------------- + +@dataclass +class Document: + body: str + meta: dict[str, Any] = field(default_factory=dict) + source_path: Path | None = None + +class ContentImportError(ValueError): + """Invalid source content or an unsupported import request.""" + + +# --------------------------------------------------------------------------- +# Reader registry +# --------------------------------------------------------------------------- + +ReaderFn = Callable[..., list[Document]] + +_readers: dict[str, ReaderFn] = {} + + +def reader(name: str) -> Callable[[ReaderFn], ReaderFn]: + def decorate(fn: ReaderFn) -> ReaderFn: + _readers[name] = fn + return fn + return decorate + + +def get_reader(name: str) -> ReaderFn: + fn = _readers.get(name) + if fn is None: + available = ", ".join(sorted(_readers)) + print(f"error: unknown reader {name!r} (available: {available})", + file=sys.stderr) + sys.exit(2) + return fn + + +# --------------------------------------------------------------------------- +# Built-in readers +# --------------------------------------------------------------------------- + +@reader("plain-text") +def read_plain_text(source: Path) -> list[Document]: + """Read a single plain-text file as one document.""" + body = source.read_text(encoding="utf-8", errors="replace") + return [Document(body=body, source_path=source)] + + +_FRONTMATTER_RE = re.compile( + r"\A---[ \t]*\r?\n(?P.*?)(?:\r?\n)---[ \t]*(?:\r?\n|\Z)", + re.DOTALL, +) + + +@reader("file-per-document") +def read_file_per_document(patterns: list[str]) -> list[Document]: + """Read files matching glob patterns, one document per file. + Each file's stem becomes meta['slug'], and frontmatter is parsed + when the file starts with delimiter-only `---` lines.""" + docs: list[Document] = [] + for pattern in patterns: + matched = sorted(Path().glob(pattern)) + if not matched: + print(f"warning: no files matched {pattern!r}", file=sys.stderr) + for path in matched: + text = path.read_text(encoding="utf-8", errors="replace") + meta: dict[str, Any] = {"slug": path.stem} + body = text + match = _FRONTMATTER_RE.match(text) + if match is not None: + try: + frontmatter = yaml.safe_load(match.group("frontmatter")) + except yaml.YAMLError as exc: + raise ContentImportError( + f"{path}: invalid YAML frontmatter: {exc}" + ) from exc + if frontmatter is None: + frontmatter = {} + if not isinstance(frontmatter, dict): + raise ContentImportError( + f"{path}: frontmatter must be a YAML mapping" + ) + meta.update(frontmatter) + body = text[match.end():] + docs.append(Document(body=body, meta=meta, source_path=path)) + return docs + + +def _documents_from_records( + raw: Any, source: Path, format_name: str, +) -> list[Document]: + records = raw if isinstance(raw, list) else [raw] + docs: list[Document] = [] + for index, record in enumerate(records): + label = f"{format_name} entry {index}" + if not isinstance(record, dict): + raise ContentImportError(f"{label} must be a mapping") + if not all(isinstance(key, str) for key in record): + raise ContentImportError(f"{label} contains a non-string field name") + meta = dict(record) + body = meta.pop("body", "") + if not isinstance(body, str): + raise ContentImportError( + f"{label} field 'body' must be a string, got " + f"{type(body).__name__}" + ) + docs.append(Document(body=body, meta=meta, source_path=source)) + return docs + + +@reader("yaml") +def read_yaml(source: Path) -> list[Document]: + """Read a YAML file containing one mapping or a list of mappings.""" + raw = yaml.safe_load(source.read_text(encoding="utf-8")) + return _documents_from_records(raw, source, "yaml") + + +@reader("json") +def read_json(source: Path) -> list[Document]: + """Read a JSON file containing one object or a list of objects.""" + raw = json.loads(source.read_text(encoding="utf-8")) + return _documents_from_records(raw, source, "json") + + +# --------------------------------------------------------------------------- +# Splitter registry +# --------------------------------------------------------------------------- + +SplitterFn = Callable[[Document, dict[str, Any]], list[Document]] + +_splitters: dict[str, SplitterFn] = {} + + +def splitter(name: str) -> Callable[[SplitterFn], SplitterFn]: + def decorate(fn: SplitterFn) -> SplitterFn: + _splitters[name] = fn + return fn + return decorate + + +def get_splitter(name: str) -> SplitterFn: + fn = _splitters.get(name) + if fn is None: + available = ", ".join(sorted(_splitters)) + print(f"error: unknown splitter {name!r} (available: {available})", + file=sys.stderr) + sys.exit(2) + return fn + + +# --------------------------------------------------------------------------- +# Built-in splitters +# --------------------------------------------------------------------------- + +@splitter("none") +def split_none(doc: Document, kwargs: dict[str, Any]) -> list[Document]: + """Pass through — return the document unchanged.""" + return [doc] + + +def _heading_title(line: str) -> str | None: + title = line.lstrip("# \t") + title = title.split(" {#")[0].split("{:")[0].strip() + return title or None + + +@splitter("heading-1") +def split_heading_1(doc: Document, kwargs: dict[str, Any]) -> list[Document]: + """Split on Markdown h1 headings (`# Title`). Each heading line becomes + the split document's `title`; content before the first heading is kept + as a preamble document without a title.""" + sections: list[tuple[str | None, list[str]]] = [] + current_title: str | None = None + current_lines: list[str] = [] + found_heading = False + + for line in doc.body.splitlines(): + if line.startswith("# ") or line.startswith("#\t"): + found_heading = True + if current_lines: + sections.append((current_title, current_lines)) + current_title = _heading_title(line) + current_lines = [] + else: + current_lines.append(line) + if current_lines: + sections.append((current_title, current_lines)) + + if not found_heading: + return [doc] + + result: list[Document] = [] + for title, lines in sections: + body = "\n".join(lines).strip() + if not body: + continue + meta = dict(doc.meta) + meta["number"] = len(result) + 1 + if title: + meta["title"] = title + result.append(Document(body=body, meta=meta, source_path=doc.source_path)) + + return result if result else [doc] + + +def compile_split_regex(pattern: str) -> re.Pattern[str]: + if not pattern: + raise ContentImportError("regex splitter requires --regex PATTERN") + try: + matcher = re.compile(pattern, re.MULTILINE) + except re.error as exc: + raise ContentImportError( + f"invalid regex pattern {pattern!r}: {exc}" + ) from exc + if matcher.groups > 0: + raise ContentImportError( + "regex splitter does not support capture groups " + "(use a non-capturing pattern)" + ) + return matcher + + +@splitter("regex") +def split_regex(doc: Document, kwargs: dict[str, Any]) -> list[Document]: + """Split on lines matching a regex pattern (non-capture only). Pass + the pattern via `--regex PATTERN`. Matched delimiter lines are + removed from the body; each segment between matches becomes a + document.""" + matcher = kwargs.get("matcher") + if matcher is None: + pattern = kwargs.get("pattern", "") + if not isinstance(pattern, str): + raise ContentImportError("regex splitter pattern must be a string") + matcher = compile_split_regex(pattern) + + parts = matcher.split(doc.body) + if len(parts) <= 1: + return [doc] + + result: list[Document] = [] + for segment in parts: + body = segment.strip() + if not body: + continue + meta = dict(doc.meta) + meta["number"] = len(result) + 1 + result.append(Document(body=body, meta=meta, + source_path=doc.source_path)) + + return result if result else [doc] + + +_PAGE_BREAK_RE = re.compile( + r"(?m)^[ \t]*---[ \t]*(?:\r?\n|$)|\f" +) + + +@splitter("page-break") +def split_page_break(doc: Document, kwargs: dict[str, Any]) -> list[Document]: + """Split on page-break markers: a line containing only `---` (with + optional surrounding whitespace) or a form-feed character (`\\f`). + The delimiter line is consumed.""" + parts = _PAGE_BREAK_RE.split(doc.body) + if len(parts) <= 1: + return [doc] + + result: list[Document] = [] + for segment in parts: + body = segment.strip() + if not body: + continue + meta = dict(doc.meta) + meta["number"] = len(result) + 1 + result.append(Document(body=body, meta=meta, + source_path=doc.source_path)) + + return result if result else [doc] + + +# --------------------------------------------------------------------------- +# Schema stage — augment Document.meta with frontmatter fields +# --------------------------------------------------------------------------- + +# Default per-type profiles. These set sensible defaults for output +# directory, template, and author field name. Overridable via --field. +TYPE_PROFILES: dict[str, dict[str, Any]] = { + "fiction": { + "output_dir": "content/fiction", + "author_field": "authors", + "body_hard_lines": True, + }, + "essay": { + "output_dir": "content/essays", + "author_field": "authors", + "body_hard_lines": False, + }, + "blog": { + "output_dir": "content/blog", + "author_field": "authors", + "body_hard_lines": False, + }, + "page": { + "output_dir": "content", + "author_field": "authors", + "body_hard_lines": False, + }, + "poetry": { + "output_dir": "content/poetry", + "author_field": "poet", + "body_hard_lines": True, + }, +} + + +def slugify(text: str) -> str: + s = text.lower() + s = re.sub(r"[^\w\s-]", "", s) + s = re.sub(r"[\s_]+", "-", s) + s = re.sub(r"-+", "-", s) + return s.strip("-") + + +def first_real_line(body: str) -> str: + """First non-empty, non-whitespace line of body.""" + for line in body.splitlines(): + stripped = line.strip() + if stripped: + return stripped + return "" + + +def auto_abstract(body: str, max_chars: int = 200) -> str: + """Best-effort abstract from the first paragraph.""" + para: list[str] = [] + for line in body.splitlines(): + stripped = line.strip() + if not stripped and para: + break + if stripped: + para.append(stripped) + text = " ".join(para) + if len(text) <= max_chars: + return text + if max_chars < 3: + return text[:max_chars] + + suffix = " …" + limit = max_chars - len(suffix) + cut = text.rfind(" ", 0, limit + 1) + if cut <= 0: + cut = limit + return text[:cut].rstrip() + suffix + + +WRITING_TYPES = frozenset({"essay", "blog", "fiction", "poetry"}) + + +def _document_label(doc: Document, index: int) -> str: + source = f" from {doc.source_path}" if doc.source_path else "" + return f"document {index + 1}{source}" + + +def _validate_document_fields(doc: Document, index: int) -> None: + label = _document_label(doc, index) + if not isinstance(doc.body, str): + raise ContentImportError( + f"{label}: body must be a string, got {type(doc.body).__name__}" + ) + + for key in ("title", "abstract", "slug", "collection", "poet"): + value = doc.meta.get(key) + if value is not None and not isinstance(value, str): + raise ContentImportError( + f"{label}: field {key!r} must be a string, got " + f"{type(value).__name__}" + ) + + for key in ("authors", "tags"): + value = doc.meta.get(key) + if value is None: + continue + if (not isinstance(value, list) + or not all(isinstance(entry, str) for entry in value)): + raise ContentImportError( + f"{label}: field {key!r} must be a list of strings" + ) + + number = doc.meta.get("number") + if (number is not None + and (not isinstance(number, int) or isinstance(number, bool) + or number < 1)): + raise ContentImportError( + f"{label}: field 'number' must be a positive integer" + ) + + +def _normalize_document_date( + doc: Document, index: int, required: bool, +) -> None: + label = _document_label(doc, index) + value = doc.meta.get("date") + if value is None or value == "": + if required: + raise ContentImportError( + f"{label}: a date in YYYY-MM-DD format is required" + ) + doc.meta.pop("date", None) + return + + if isinstance(value, datetime): + value = value.date() + if isinstance(value, date_type): + normalized = value.isoformat() + elif isinstance(value, str): + normalized = value.strip() + else: + raise ContentImportError( + f"{label}: field 'date' must use YYYY-MM-DD format" + ) + + if not re.fullmatch(r"\d{4}-\d{2}-\d{2}", normalized): + raise ContentImportError( + f"{label}: field 'date' must use YYYY-MM-DD format" + ) + try: + date_type.fromisoformat(normalized) + except ValueError as exc: + raise ContentImportError( + f"{label}: invalid date {normalized!r}" + ) from exc + doc.meta["date"] = normalized + + +def _infer_title(body: str) -> tuple[str | None, str]: + lines = body.splitlines() + first_index = next( + (index for index, line in enumerate(lines) if line.strip()), None + ) + if first_index is None: + return None, body + + first_line = lines[first_index].strip() + title: str | None = None + if first_line.startswith("# ") or first_line.startswith("#\t"): + title = _heading_title(first_line) + else: + followed_by_blank = ( + first_index + 1 < len(lines) + and not lines[first_index + 1].strip() + ) + if (followed_by_blank and len(first_line) < 80 + and not first_line.endswith((".", ",", ";", ":", "!", "?"))): + title = first_line + + if title is None: + return None, body + lines.pop(first_index) + return title, "\n".join(lines).strip() + + +def apply_schema(docs: list[Document], args: argparse.Namespace) -> list[Document]: + """Augment each document's meta with inferred fields and CLI overrides.""" + profile = TYPE_PROFILES.get(args.type, TYPE_PROFILES["page"]) + + for index, doc in enumerate(docs): + _validate_document_fields(doc, index) + body = doc.body.strip() + + title_prefix = getattr(args, "title_prefix", None) or "" + has_title = bool(doc.meta.get("title")) + + if title_prefix and doc.meta.get("number") is not None: + doc.meta["title"] = f"{title_prefix} {doc.meta['number']}" + elif not has_title: + inferred_title, body = _infer_title(body) + doc.meta["title"] = inferred_title or "Untitled" + + if "abstract" not in doc.meta: + doc.meta["abstract"] = auto_abstract(body) + + if args.date is not None: + doc.meta["date"] = args.date + + if args.tags is not None: + doc.meta["tags"] = [ + tag.strip() for tag in args.tags.split(",") if tag.strip() + ] + + if args.author is not None: + author_field = profile["author_field"] + doc.meta[author_field] = ( + args.author if author_field == "poet" else [args.author] + ) + + if hasattr(args, "field") and args.field: + for key_value in args.field: + if "=" not in key_value: + print( + f"warning: --field {key_value!r} is not key=value, " + "skipping", + file=sys.stderr, + ) + continue + key, value = key_value.split("=", 1) + doc.meta[key] = value + + lines = body.splitlines() + content_lines = [line for line in lines if line.strip()] + if content_lines: + indent = min( + len(line) - len(line.lstrip()) for line in content_lines + ) + lines = [ + line[indent:] if len(line) >= indent else line for line in lines + ] + + normalized: list[str] = [] + blank_run = 0 + for line in lines: + if not line.strip(): + blank_run += 1 + if blank_run <= 2: + normalized.append(line) + else: + blank_run = 0 + normalized.append(line) + doc.body = "\n".join(normalized).strip() + + _validate_document_fields(doc, index) + _normalize_document_date( + doc, index, required=args.type in WRITING_TYPES, + ) + + return docs + + +# --------------------------------------------------------------------------- +# Writer stage — generate Markdown files with YAML frontmatter +# --------------------------------------------------------------------------- + +INTERNAL_FIELDS = frozenset({ + "source_path", "delimiter", +}) + + +def yaml_frontmatter(meta: dict[str, Any]) -> str: + """Render meta dict as YAML frontmatter. Strips internal fields, + uses block scalar (`|`) for multi-line strings.""" + cleaned = {k: v for k, v in meta.items() if k not in INTERNAL_FIELDS} + # Use yaml.dump with block style; sort_keys=False preserves insertion + # order so title/date come first. + raw = yaml.dump(cleaned, default_flow_style=False, + allow_unicode=True, sort_keys=False) + return raw.strip() + + +def slugify_path(title: str, number: int | None = None) -> str: + """Derive a filesystem-safe slug from a title, optionally prefixed + with a zero-padded number for ordering.""" + base = slugify(title) + if number is not None: + base = f"{number:04d}-{base}" + return base or "untitled" + +def document_slug(doc: Document) -> str: + title = doc.meta.get("title", "Untitled") + slug_source = doc.meta.get("slug") or title + return slugify_path(slug_source, doc.meta.get("number")) + + +def detect_collection_slug( + docs: list[Document], cli_collection: str | None, +) -> str | None: + """Determine one non-empty collection slug from CLI or document metadata.""" + values = ( + [cli_collection] + if cli_collection + else [ + doc.meta["collection"] + for doc in docs + if doc.meta.get("collection") + ] + ) + if not values: + return None + + slugs = {slugify(value) for value in values} + if "" in slugs: + raise ContentImportError("collection name must contain a letter or number") + if len(slugs) > 1: + raise ContentImportError( + "all documents in one import must use the same collection" + ) + return slugs.pop() + + +def generate_collection_index( + docs: list[Document], collection_name: str, +) -> str: + """Generate a collection index.md with links to each document.""" + entries: list[str] = [] + for doc in sorted(docs, key=lambda item: item.meta.get("number") or 0): + title = doc.meta.get("title", "Untitled") + link_title = ( + title.replace("\\", "\\\\") + .replace("[", "\\[") + .replace("]", "\\]") + ) + abstract = " ".join(doc.meta.get("abstract", "").split()) + abstract_line = f" · {abstract[:120]}" if abstract else "" + entries.append( + f"- [{link_title}]({document_slug(doc)}.html){abstract_line}" + ) + + first = docs[0].meta if docs else {} + index_meta: dict[str, Any] = { + "title": collection_name, + "abstract": f"{len(docs)} piece{'s' if len(docs) != 1 else ''}", + } + if first.get("date"): + index_meta["date"] = first["date"] + if first.get("tags"): + index_meta["tags"] = first["tags"] + + authors = first.get("authors") + if isinstance(authors, list): + author = ", ".join(authors) + else: + author = first.get("poet", "") + details: list[str] = [] + if author: + details.append(f"*{author}*") + if first.get("date"): + details.append(str(first["date"])) + + detail_line = " · ".join(details) + body_parts = [part for part in (detail_line, "\n".join(entries)) if part] + body = "\n\n".join(body_parts) + return f"---\n{yaml_frontmatter(index_meta)}\n---\n\n{body}\n" + + +FileEntry = tuple[Path, str, str] + + +RESERVED_PAGE_COLLECTION_SLUGS = frozenset({ + "blog", + "cv", + "drafts", + "essays", + "fiction", + "me", + "memento-mori", + "music", + "photography", + "poetry", + "scripts", + "tag-meta", +}) + + +def validate_collection_request( + docs: list[Document], args: argparse.Namespace, +) -> None: + cli_collection = getattr(args, "collection", None) + collection_slug = detect_collection_slug(docs, cli_collection) + if (collection_slug and args.type == "page" + and collection_slug in RESERVED_PAGE_COLLECTION_SLUGS): + raise ContentImportError( + f"page collection slug {collection_slug!r} conflicts with a " + "reserved content directory" + ) + + +def assemble_file_entries( + docs: list[Document], args: argparse.Namespace, +) -> list[FileEntry]: + validate_collection_request(docs, args) + profile = TYPE_PROFILES.get(args.type, TYPE_PROFILES["page"]) + base_dir = Path(profile["output_dir"]) + cli_collection = getattr(args, "collection", None) + collection_slug = detect_collection_slug(docs, cli_collection) + + if collection_slug: + section_path = profile["output_dir"].removeprefix("content").strip("/") + collection_url = "/" + "/".join( + part for part in (section_path, collection_slug) if part + ) + "/" + for doc in docs: + if cli_collection: + doc.meta["collection"] = collection_slug + else: + doc.meta.setdefault("collection", collection_slug) + doc.meta["collection-url"] = collection_url + + entries: list[FileEntry] = [] + destinations: dict[Path, str] = {} + + def add_entry(path: Path, content: str, label: str) -> None: + previous = destinations.get(path) + if previous is not None: + raise ContentImportError( + f"duplicate output destination {path}: {previous} and {label}" + ) + destinations[path] = label + entries.append((path, content, label)) + + output_dir = base_dir / collection_slug if collection_slug else base_dir + for index, doc in enumerate(docs): + title = doc.meta.get("title", "Untitled") + path = output_dir / f"{document_slug(doc)}.md" + frontmatter = yaml_frontmatter(doc.meta) + content = f"---\n{frontmatter}\n---\n\n{doc.body}\n" + add_entry(path, content, f"document {index + 1} ({title})") + + if collection_slug and docs: + collection_name = cli_collection or next( + ( + doc.meta["collection"] + for doc in docs + if doc.meta.get("collection") + ), + collection_slug, + ) + index_path = base_dir / collection_slug / "index.md" + index_content = generate_collection_index(docs, collection_name) + add_entry(index_path, index_content, "collection index") + + return entries + + +def write_docs( + docs: list[Document], + args: argparse.Namespace, + file_entries: list[FileEntry] | None = None, +) -> int: + """Write documents as Markdown files with YAML frontmatter.""" + entries = file_entries if file_entries is not None else assemble_file_entries( + docs, args + ) + written = 0 + for path, content, _label in sorted(entries, key=lambda entry: entry[0]): + if path.exists() and not args.overwrite: + print(f" skip {path.relative_to(Path())}") + continue + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8") + print(f" write {path.relative_to(Path())}") + written += 1 + return written + + +# --------------------------------------------------------------------------- +# CLI +# --------------------------------------------------------------------------- + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Import content from external sources into the site.") + parser.add_argument("source", nargs="*", + help="Source path(s) or glob pattern(s)") + parser.add_argument("--reader", default="plain-text", + help="Input format reader (default: plain-text)") + parser.add_argument("--list-readers", action="store_true", + help="List available readers and exit") + parser.add_argument("--splitter", default="none", + help="Content splitting strategy (default: none)") + parser.add_argument("--regex", + help="Regex pattern for the 'regex' splitter") + parser.add_argument("--list-splitters", action="store_true", + help="List available splitters and exit") + parser.add_argument("--type", default="page", + choices=sorted(TYPE_PROFILES), + help="Content type (default: page)") + parser.add_argument("--date", + help="Publication date (ISO format, e.g. 2026-07-17)") + parser.add_argument("--tags", + help="Comma-separated tags (e.g. 'fiction,short-story')") + parser.add_argument("--author", + help="Author name (maps to 'poet' for poetry, 'authors' for others)") + parser.add_argument("--field", action="append", default=[], + help="Arbitrary frontmatter field (repeatable, e.g. --field key=val)") + parser.add_argument("--title-prefix", + help="Prefix for numbered titles (e.g. 'Chapter', 'Sonnet')") + parser.add_argument( + "--collection", + help="Collection name (groups documents under a directory with index)", + ) + parser.add_argument("--dry-run", action="store_true", + help="Show what would be written; write nothing") + parser.add_argument("--overwrite", action="store_true", + help="Overwrite existing files") + parser.add_argument("--dump", action="store_true", + help="Print parsed documents for debugging") + return parser + + +def main(argv: list[str]) -> int: + parser = build_parser() + args = parser.parse_args(argv) + + if args.list_readers: + print("Available readers:") + for name in sorted(_readers): + doc = (_readers[name].__doc__ or "").strip().split("\n")[0] + print(f" {name:22s} {doc}") + return 0 + + if args.list_splitters: + print("Available splitters:") + for name in sorted(_splitters): + doc = (_splitters[name].__doc__ or "").strip().split("\n")[0] + print(f" {name:22s} {doc}") + return 0 + + if not args.source: + print( + "error: source argument is required " + "(use --list-readers or --list-splitters to see available options)", + file=sys.stderr, + ) + return 2 + + reader_fn = get_reader(args.reader) + try: + if args.reader == "file-per-document": + docs = reader_fn(args.source) + else: + if len(args.source) > 1: + print( + f"error: {args.reader} reader expects a single source path", + file=sys.stderr, + ) + return 2 + source = Path(args.source[0]) + if not source.exists(): + print(f"error: source not found: {source}", file=sys.stderr) + return 2 + docs = reader_fn(source) + except ( + ContentImportError, + json.JSONDecodeError, + OSError, + yaml.YAMLError, + ) as exc: + print(f"error: {exc}", file=sys.stderr) + return 2 + + if not docs: + print("error: reader produced no documents", file=sys.stderr) + return 2 + print(f"[reader] {len(docs)} document(s) from {args.reader}", file=sys.stderr) + + splitter_fn = get_splitter(args.splitter) + splitter_kwargs: dict[str, Any] = {} + try: + if args.splitter == "regex": + splitter_kwargs["matcher"] = compile_split_regex(args.regex or "") + + split_docs: list[Document] = [] + for doc in docs: + split_docs.extend(splitter_fn(doc, splitter_kwargs)) + except ContentImportError as exc: + print(f"error: {exc}", file=sys.stderr) + return 2 + + print( + f"[splitter] {len(split_docs)} document(s) after {args.splitter}", + file=sys.stderr, + ) + + try: + schema_docs = apply_schema(split_docs, args) + validate_collection_request(schema_docs, args) + file_entries = assemble_file_entries(schema_docs, args) + except ContentImportError as exc: + print(f"error: {exc}", file=sys.stderr) + return 2 + + print( + f"[schema] {len(schema_docs)} document(s) after schema " + f"(type={args.type})", + file=sys.stderr, + ) + + if args.dump: + for index, doc in enumerate(schema_docs): + print(f"\n{'=' * 60}") + print(f"Document {index}") + print(f" source: {doc.source_path}") + print(f" meta: {json.dumps(doc.meta, indent=2, default=str)}") + preview = doc.body[:300].rstrip() + print(f" body ({len(doc.body)} chars, preview):") + for line in preview.splitlines()[:10]: + print(f" {line}") + if len(doc.body) > 300: + print(f" … ({len(doc.body) - 300} more chars)") + + if args.dry_run: + print( + f"\n[DRY RUN] Would process {len(schema_docs)} document(s):", + file=sys.stderr, + ) + for path, _content, label in sorted( + file_entries, key=lambda entry: entry[0] + ): + print(f" {path} ← {label}") + return 0 + + try: + written = write_docs(schema_docs, args, file_entries) + except OSError as exc: + print(f"error: could not write output: {exc}", file=sys.stderr) + return 2 + + if written: + print(f"\n{written} file(s) written to content/", file=sys.stderr) + print( + "Next: review the generated files, then make clean && make build", + file=sys.stderr, + ) + else: + print( + "\nNothing written (all files exist; use --overwrite to replace)", + file=sys.stderr, + ) + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:]))