diff --git a/.github/workflows/telperion-lean-e2e.yml b/.github/workflows/telperion-lean-e2e.yml index 6ec50fb10..68176bfde 100644 --- a/.github/workflows/telperion-lean-e2e.yml +++ b/.github/workflows/telperion-lean-e2e.yml @@ -51,7 +51,6 @@ jobs: - name: Build the emitted Lean (the actual verification) working-directory: telperion/examples/toy_box/lean run: lake build - jensen-hyperbolicity-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -126,159 +125,11 @@ jobs: working-directory: telperion/examples/li_positivity/lean run: lake build - - name: "Axiom guard (Li ladder anchors): exact axiom set, no sorryAx, guard actually ran" - working-directory: telperion/examples/li_positivity/lean - shell: bash - run: | - set -euo pipefail - lake env lean AxiomGuardLiPositivity.lean 2>&1 | tee axioms.out - n=$(grep -cE "depends on axioms|does not depend on any axioms" axioms.out || true) - if [ "$n" -lt "163" ]; then - echo "::error::axiom guard printed $n axiom lines, expected at least 163 -- the guard did not run or was silently truncated"; exit 1; fi - if grep -q "sorryAx" axioms.out; then echo "::error::sorryAx present"; exit 1; fi - # every printed axioms line must be EXACTLY Lean's three standard axioms - # Lean WRAPS a long axiom list across lines, so a line-based grep sees a truncated - # list and reports a false positive. Join lines, then extract each complete - # "depends on axioms: [...]" group and require it to be exactly the three. - if tr "\n" " " < axioms.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ - | grep -vq "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$"; then - echo "::error::unexpected axiom beyond [propext, Classical.choice, Quot.sound]" - tr "\n" " " < axioms.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ - | grep -v "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$" - exit 1; fi - - # The two zero-free-region node artifacts (ZeroFreePolylog + ZeroFreeElementary) are imported - # by nothing, so until 2026-09-18 no build compiled them and no guard elaborated them. They - # need a SEPARATE guard: ZeroFreeElementary re-declares ZeroFreeBridge.zeta_sphere_bound, - # which DlvpZetaDisk already declares, so they cannot share an import closure. - - name: "Axiom guard (zero-free-region artifacts): exact axiom set, no sorryAx, guard actually ran" + - name: Axiom guard (fails on sorryAx anywhere in the anchors) working-directory: telperion/examples/li_positivity/lean - shell: bash - run: | - set -euo pipefail - lake env lean AxiomGuardZeroFree.lean 2>&1 | tee zerofree.out - n=$(grep -c "depends on axioms" zerofree.out || true) - if [ "$n" -lt "2" ]; then - echo "::error::zero-free guard printed $n axiom lines, expected 2 -- the guard did not run"; exit 1; fi - if grep -q "sorryAx" zerofree.out; then echo "::error::sorryAx present"; exit 1; fi - # Lean WRAPS a long axiom list across lines, so a line-based grep sees a truncated - # list and reports a false positive. Join lines, then extract each complete - # "depends on axioms: [...]" group and require it to be exactly the three. - if tr "\n" " " < zerofree.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ - | grep -vq "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$"; then - echo "::error::unexpected axiom beyond [propext, Classical.choice, Quot.sound]" - tr "\n" " " < zerofree.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ - | grep -v "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$" - exit 1; fi - - weil-form-enclosure-compiles: - runs-on: ubuntu-latest - timeout-minutes: 90 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - run: pip install sympy pytest python-flint - - # Regenerates the E8 Weil-pairing enclosures from scratch with Arb (archimedean - # quadrature to |r| <= 1024 plus a 5-fold integration-by-parts tail) and checks the - # frozen Lean matches byte-for-byte; also gates the WeilExplicit vocabulary mirror - # against the PROVED node in examples/rvm_bridge/lean/E6Bridge4.lean. ~4 min. - - name: Regenerate the Weil-form ladder (enclose -> certify -> emit) and check it matches on-disk - working-directory: telperion - run: | - python examples/weil_form_enclosure/generate.py --check - - - name: Cache elan toolchain - uses: actions/cache@v4 - with: - path: ~/.elan - key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/weil_form_enclosure/lean/lean-toolchain') }} - - - name: Install elan - run: | - curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none - echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - - name: Fetch Mathlib olean cache - working-directory: telperion/examples/weil_form_enclosure/lean - run: lake exe cache get - - - name: Build the vocabulary mirror and the emitted ladder (the actual verification) - working-directory: telperion/examples/weil_form_enclosure/lean - run: lake build - - - name: Axiom guard (fails on sorryAx anywhere in the emitted theorems) - working-directory: telperion/examples/weil_form_enclosure/lean run: | - lake env lean AxiomGuardWeilForm.lean | tee axioms.out + lake env lean AxiomGuardLiPositivity.lean | tee axioms.out ! grep -q "sorryAx" axioms.out - - rvm-bridge-compiles: - runs-on: ubuntu-latest - timeout-minutes: 90 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - # The drift check imports the telperion package (statement-port matching), which pulls - # sympy. Without this the step dies with ModuleNotFoundError before it checks anything -- - # a drift check that cannot start is a drift check that cannot fail on drift. - - run: pip install sympy - - - run: pip install sympy - - - name: Drift check (node statements + mirrored defs still match the mirrormere and rh registries) - working-directory: telperion - run: | - python examples/rvm_bridge/generate.py --check - - - name: Cache elan toolchain - uses: actions/cache@v4 - with: - path: ~/.elan - key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/rvm_bridge/lean/lean-toolchain') }} - - - name: Install elan - run: | - curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none - echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - # Zeta23 (anthropics/formal-math, public, Apache-2.0; ~1.6 MB repo) is cloned by Lake at the - # pinned commit; Mathlib oleans come from the cache through that dependency. Zeta23 itself - # (118 modules) compiles from source: ~2 min on 32 cores locally, expect ~15-25 min on a - # 4-core hosted runner. - - name: Fetch Mathlib olean cache (through the Zeta23 dependency) - working-directory: telperion/examples/rvm_bridge/lean - run: lake exe cache get - - - name: Build the bridge against the pinned zeta-23-lean (the actual verification) - working-directory: telperion/examples/rvm_bridge/lean - run: lake build - - - name: "Axiom guard (45 anchors incl. consumed upstream inputs): exact axiom set, no sorryAx, guard actually ran" - working-directory: telperion/examples/rvm_bridge/lean - shell: bash - run: | - set -euo pipefail - lake env lean AxiomGuardRvMBridge.lean 2>&1 | tee axioms.out - n=$(grep -cE "depends on axioms|does not depend on any axioms" axioms.out || true) - if [ "$n" -lt "45" ]; then - echo "::error::axiom guard printed $n axiom lines, expected at least 45 -- the guard did not run or was silently truncated"; exit 1; fi - if grep -q "sorryAx" axioms.out; then echo "::error::sorryAx present"; exit 1; fi - # every printed axioms line must be EXACTLY Lean's three standard axioms - # Lean WRAPS a long axiom list across lines, so a line-based grep sees a truncated - # list and reports a false positive. Join lines, then extract each complete - # "depends on axioms: [...]" group and require it to be exactly the three. - if tr "\n" " " < axioms.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ - | grep -vq "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$"; then - echo "::error::unexpected axiom beyond [propext, Classical.choice, Quot.sound]" - tr "\n" " " < axioms.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ - | grep -v "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$" - exit 1; fi - tangent-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -312,8 +163,6 @@ jobs: - name: Build the emitted Lean (the actual verification — tangent-line trick) working-directory: telperion/examples/tangent_sum/lean run: lake build - - primality-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -347,7 +196,6 @@ jobs: - name: Build the emitted Lean (the actual verification — Lucas/Pratt primality) working-directory: telperion/examples/primality/lean run: lake build - cs-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -381,7 +229,6 @@ jobs: - name: Build the emitted Lean (the actual verification — Cauchy-Schwarz) working-directory: telperion/examples/cauchy_schwarz/lean run: lake build - bilinear-corner-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -415,7 +262,6 @@ jobs: - name: Build the emitted Lean (the actual verification — bilinear worst-corner box) working-directory: telperion/examples/bilinear_corner/lean run: lake build - algebraic-bracket-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -449,7 +295,6 @@ jobs: - name: Build the emitted Lean (the actual verification — algebraic √ bracket) working-directory: telperion/examples/algebraic_bracket/lean run: lake build - halfplane-disk-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -483,7 +328,6 @@ jobs: - name: Build the emitted Lean (the actual verification — Borel–Carathéodory half-plane→disk) working-directory: telperion/examples/halfplane_disk/lean run: lake build - finite-argmax-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -517,7 +361,6 @@ jobs: - name: Build the emitted Lean (the actual verification — finite-argmax margin) working-directory: telperion/examples/finite_argmax/lean run: lake build - magnitude-split-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -551,7 +394,6 @@ jobs: - name: Build the emitted Lean (the actual verification — triangle magnitude split) working-directory: telperion/examples/magnitude_split/lean run: lake build - disk-coord-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -585,7 +427,6 @@ jobs: - name: Build the emitted Lean (the actual verification — disk→coordinate bounds) working-directory: telperion/examples/disk_coord/lean run: lake build - cauchy-deriv-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -619,7 +460,6 @@ jobs: - name: Build the emitted Lean (the actual verification — Cauchy derivative estimate) working-directory: telperion/examples/cauchy_deriv/lean run: lake build - logderiv-region-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -653,7 +493,6 @@ jobs: - name: Build the emitted Lean (the actual verification — dVP log-derivative region core) working-directory: telperion/examples/logderiv_region/lean run: lake build - pe-duality-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -687,7 +526,6 @@ jobs: - name: Build the emitted Lean (the actual verification — pseudo-expectation SoS-duality) working-directory: telperion/examples/pe_duality/lean run: lake build - order-balance-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -721,7 +559,6 @@ jobs: - name: Build the emitted Lean (the actual verification — order-balance boundary hinge) working-directory: telperion/examples/order_balance/lean run: lake build - lfunction-product-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -755,7 +592,6 @@ jobs: - name: Build the emitted Lean (the actual verification — nonneg-cosine L-product) working-directory: telperion/examples/lfunction_product/lean run: lake build - parametric-holomorphy-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -789,7 +625,6 @@ jobs: - name: Build the emitted Lean (the actual verification — parametric-integral holomorphy) working-directory: telperion/examples/parametric_holomorphy/lean run: lake build - symmetric-quad-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -823,7 +658,6 @@ jobs: - name: Build the emitted Lean (the actual verification — symbolic-n moment PSD) working-directory: telperion/examples/symmetric_quad/lean run: lake build - polytope-max-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -857,7 +691,6 @@ jobs: - name: Build the emitted Lean (the actual verification — multi-affine corner box positivity) working-directory: telperion/examples/polytope_max/lean run: lake build - second-order-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -891,7 +724,6 @@ jobs: - name: Build the emitted Lean (the actual verification — 2nd-order recurrence closed form) working-directory: telperion/examples/second_order/lean run: lake build - integrality-gate-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -925,7 +757,6 @@ jobs: - name: Build the emitted Lean (the actual verification — p-adic integrality gate) working-directory: telperion/examples/integrality_gate/lean run: lake build - domination-ratio-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -959,7 +790,6 @@ jobs: - name: Build the emitted Lean (the actual verification — rational domination ratio) working-directory: telperion/examples/domination_ratio/lean run: lake build - achievability-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -993,7 +823,6 @@ jobs: - name: Build the emitted Lean (the actual verification — achievability closure) working-directory: telperion/examples/achievability/lean run: lake build - separable-convex-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1027,7 +856,6 @@ jobs: - name: Build the emitted Lean (the actual verification — separable-convex min/homogeneous) working-directory: telperion/examples/separable_convex/lean run: lake build - scale-invariance-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1061,7 +889,6 @@ jobs: - name: Build the emitted Lean (the actual verification — objective-degeneracy / homogeneity) working-directory: telperion/examples/scale_invariance/lean run: lake build - concave-stationary-max-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1095,7 +922,6 @@ jobs: - name: Build the emitted Lean (the actual verification — Kelly concave-stationary max) working-directory: telperion/examples/concave_stationary_max/lean run: lake build - symmetric-quad-d2-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1129,7 +955,6 @@ jobs: - name: Build the emitted Lean (the actual verification — symbolic-in-n d=2 moment PSD) working-directory: telperion/examples/symmetric_quad_d2/lean run: lake build - tight-cap-enclosure-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1163,7 +988,6 @@ jobs: - name: Build the emitted Lean (the actual verification — BG g-step fixed-config tight-cap closure) working-directory: telperion/examples/tight_cap_enclosure/lean run: lake build - affine-param-endpoint-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1197,7 +1021,6 @@ jobs: - name: Build the emitted Lean (the actual verification — affine-in-parameter interval -> two endpoints (SCLStep price collapse)) working-directory: telperion/examples/affine_param_endpoint/lean run: lake build - recursion-closure-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1231,7 +1054,6 @@ jobs: - name: Build the emitted Lean (the actual verification — node tangent+ceiling assembly at fixed price) working-directory: telperion/examples/recursion_closure/lean run: lake build - cavity-exchange-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1265,7 +1087,6 @@ jobs: - name: Build the emitted Lean (the actual verification — Kelmans de-branch bilinear-corner exchange) working-directory: telperion/examples/cavity_exchange/lean run: lake build - per-size-dominance-sweep-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1299,7 +1120,6 @@ jobs: - name: Build the emitted Lean (the actual verification — finite per-size dominance sweep) working-directory: telperion/examples/per_size_dominance_sweep/lean run: lake build - curvature-boundary-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1333,7 +1153,6 @@ jobs: - name: Build the emitted Lean (the actual verification — curvature-sign -> boundary extremum (AxiomMath port)) working-directory: telperion/examples/curvature_boundary/lean run: lake build - transcendental-enclosure-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1367,7 +1186,6 @@ jobs: - name: Build the emitted Lean (the actual verification — rational enclosure of log(1+x) (BG cells)) working-directory: telperion/examples/transcendental_enclosure/lean run: lake build - log-combination-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1401,7 +1219,6 @@ jobs: - name: Build the emitted Lean (the actual verification — F*-folding log-combination (BG dogfood)) working-directory: telperion/examples/log_combination/lean run: lake build - psd-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1435,7 +1252,6 @@ jobs: - name: Build the emitted Lean (the actual verification — LDLT PSD form) working-directory: telperion/examples/psd_form/lean run: lake build - xor3-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1469,7 +1285,6 @@ jobs: - name: Build the emitted Lean (the actual verification — 3-XOR moment PSD) working-directory: telperion/examples/xor3_moment/lean run: lake build - bg-family-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1503,7 +1318,6 @@ jobs: - name: Build the emitted Lean (the actual verification — BG base-cell Bernstein positivity) working-directory: telperion/examples/bg_family/lean run: lake build - bg-floor-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1531,7 +1345,6 @@ jobs: - name: Build the emitted Lean (the actual verification — BG R7 chain-class ledger floor) working-directory: telperion/examples/bg_floor/lean run: lake build - bg-floor-families-compiles: runs-on: ubuntu-latest timeout-minutes: 90 @@ -1559,7 +1372,6 @@ jobs: - name: Build the emitted Lean (the actual verification — BG R7 bare-leaf + nl=2 floors) working-directory: telperion/examples/bg_floor_families/lean run: lake build - bg-floor-r7-facets-compiles: runs-on: ubuntu-latest timeout-minutes: 90 @@ -1587,7 +1399,6 @@ jobs: - name: Build the emitted Lean (the actual verification — BG R7 m=0/m>=4/tax-window facets) working-directory: telperion/examples/bg_floor_r7_facets/lean run: lake build - hinge-floor-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1621,7 +1432,6 @@ jobs: - name: Build the emitted Lean (the actual verification — hinge floor) working-directory: telperion/examples/hinge_floor/lean run: lake build - borel-caratheodory-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1646,7 +1456,6 @@ jobs: - name: Build the drafted Borel-Caratheodory theorem (Moebius-Schwarz, 12 theorems) working-directory: telperion/examples/borel_caratheodory/lean run: lake build - bg-flag-discharge-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1680,7 +1489,6 @@ jobs: - name: Build the emitted Lean (the actual verification — flag-discharge m_2 cut norm_num atoms) working-directory: telperion/examples/bg_flag_discharge/lean run: lake build - bg-caterpillar-concavity-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1714,7 +1522,6 @@ jobs: - name: Build the emitted Lean (the actual verification — density concavity + strict max at a=7) working-directory: telperion/examples/bg_caterpillar_concavity/lean run: lake build - bg-m3-moment-cut-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1748,7 +1555,6 @@ jobs: - name: Build the emitted Lean (the actual verification — caterpillar = degree-3 moment argmax) working-directory: telperion/examples/bg_m3_moment_cut/lean run: lake build - bg-arm-balancing-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1782,7 +1588,6 @@ jobs: - name: Build the emitted Lean (the actual verification — m=2 arm-balancing strictly increases Z) working-directory: telperion/examples/bg_arm_balancing/lean run: lake build - bg-broom-optimum-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1816,7 +1621,6 @@ jobs: - name: Build the emitted Lean (the actual verification — star-of-brooms c=5 optimum) working-directory: telperion/examples/bg_broom_optimum/lean run: lake build - bg-tie-cherry-worst-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1850,7 +1654,6 @@ jobs: - name: Build the emitted Lean (the actual verification — tie-regime cherry-worst k<=20) working-directory: telperion/examples/bg_tie_cherry_worst/lean run: lake build - bg-tie-slack-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1884,7 +1687,6 @@ jobs: - name: Build the emitted Lean (the actual verification — slack bound slack_g(k)<=F* for k>=16) working-directory: telperion/examples/bg_tie_slack/lean run: lake build - bg-mixed-kkt-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -1918,7 +1720,6 @@ jobs: - name: Build the emitted Lean (the actual verification — mixed<=B(k) k<=15 via per-child KKT V(c)=7 envelope tail V(c) F*, the integrality-gap no-go) working-directory: telperion/examples/bg_smooth_nogo/lean run: lake build - bg-spider-vs-caterpillar-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -2020,7 +1819,6 @@ jobs: - name: Build the emitted Lean (the actual verification — spider F*>F(a) beats every caterpillar) working-directory: telperion/examples/bg_spider_vs_caterpillar/lean run: lake build - bg-broom-vs-cherry-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -2054,7 +1852,6 @@ jobs: - name: Build the emitted Lean (broom-vs-cherry-on-I norm_num atoms) working-directory: telperion/examples/bg_broom_vs_cherry/lean run: lake build - bg-leaf-exchange-compiles: runs-on: ubuntu-latest timeout-minutes: 60 @@ -2322,43 +2119,14 @@ jobs: if echo "$out" | grep -qE 'error:'; then echo "::error::$G did not elaborate cleanly"; exit 1; fi done echo "OK: all guarded theorems kernel-clean." - - dbn-compiles: - runs-on: ubuntu-latest - timeout-minutes: 90 - steps: - - uses: actions/checkout@v4 - - - name: Cache elan toolchain - uses: actions/cache@v4 - with: - path: ~/.elan - key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/dbn/lean/lean-toolchain') }} - - - name: Install elan - run: | - curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none - echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - - name: Fetch Mathlib olean cache (through the LiCriterion dependency) - working-directory: telperion/examples/dbn/lean - run: lake exe cache get - - - name: No `sorry` in the island (the registry statements live in missions/rh, not here) - working-directory: telperion/examples/dbn/lean - run: | - ! grep -rnwE "sorry|admit" --include='*.lean' --exclude-dir=.lake . - - - name: Build the DBN foundations island (DBNDefs + AxiomGuardDBN) - working-directory: telperion/examples/dbn/lean - run: lake build - - - name: Axiom guard (fails on sorryAx anywhere in the island) - working-directory: telperion/examples/dbn/lean - run: | - lake env lean AxiomGuardDBN.lean | tee axioms.out - ! grep -q "sorryAx" axioms.out - + # B2 ladder suite (replaces the monolith `lake build` that hit E2BIG at ~16k targets). + # Builds zzl_core + ZeroFreeBridge + zzl_aux (height-100 island, Bragg, zoo; the 669 legacy + # RHInBox_* boxes live in zzl_legacy_boxes and run weekly, see telperion-legacy-boxes.yml) and then the + # 25k-height block packages in ascending order up to H_CI, running the axiom battery on + # each block-top capstone. Green == every `all_nontrivial_zeros_up_to_height__of_bands` + # up to H_CI compiles with axioms exactly [propext, Classical.choice, Quot.sound], 0 sorryAx. + # H_CI is a policy dial (telperion/docs/B2_MAIN_CI.md): the climb runs hotter than CI; + # the paper cites H_CI, campaign_state tracks H. conjecture1_proved = False. zeta-ladder-suite: runs-on: ubuntu-latest timeout-minutes: 360 @@ -2422,44 +2190,342 @@ jobs: rm -rf "$d/.lake/build/ir" done echo "OK: ladder CI-verified to H_CI=$H_CI (kernel-clean, 3 standard axioms, via Guard_h modules)." - bragg-amplitude-compiles: + weil-form-enclosure-compiles: runs-on: ubuntu-latest - timeout-minutes: 180 + timeout-minutes: 90 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - - run: pip install sympy pytest + - run: pip install sympy pytest python-flint - - name: Regenerate the Bragg-amplitude instances from the family definition + # Regenerates the E8 Weil-pairing enclosures from scratch with Arb (archimedean + # quadrature to |r| <= 1024 plus a 5-fold integration-by-parts tail) and checks the + # frozen Lean matches byte-for-byte; also gates the WeilExplicit vocabulary mirror + # against the PROVED node in examples/rvm_bridge/lean/E6Bridge4.lean. ~4 min. + - name: Regenerate the Weil-form ladder (enclose -> certify -> emit) and check it matches on-disk working-directory: telperion run: | - python examples/bragg_amplitude/generate.py --check + python examples/weil_form_enclosure/generate.py --check - name: Cache elan toolchain uses: actions/cache@v4 with: path: ~/.elan - key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/zeta_zero_localization/lean/lean-toolchain') }} + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/weil_form_enclosure/lean/lean-toolchain') }} - name: Install elan run: | curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - name: Wire the sharded packages to one shared deps dir (B2 layout; .lake is gitignored) - working-directory: telperion/examples/zeta_zero_localization/lean - run: | - mkdir -p .lake/packages - for d in zzl_core zzl_aux ZetaBands_h*; do - mkdir -p "$d/.lake" && ln -sfn ../../.lake/packages "$d/.lake/packages" - done - mkdir -p ../../zero_free_bridge/lean/.lake - ln -sfn ../../../zeta_zero_localization/lean/.lake/packages ../../zero_free_bridge/lean/.lake/packages - - - name: Fetch Mathlib olean cache (into the shared deps dir) - working-directory: telperion/examples/zeta_zero_localization/lean/zzl_aux + - name: Fetch Mathlib olean cache + working-directory: telperion/examples/weil_form_enclosure/lean + run: lake exe cache get + + - name: Build the vocabulary mirror and the emitted ladder (the actual verification) + working-directory: telperion/examples/weil_form_enclosure/lean + run: lake build + + - name: Axiom guard (fails on sorryAx anywhere in the emitted theorems) + working-directory: telperion/examples/weil_form_enclosure/lean + run: | + lake env lean AxiomGuardWeilForm.lean | tee axioms.out + ! grep -q "sorryAx" axioms.out + rvm-bridge-compiles: + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + # The drift check imports the telperion package (statement-port matching), which pulls + # sympy. Without this the step dies with ModuleNotFoundError before it checks anything -- + # a drift check that cannot start is a drift check that cannot fail on drift. + - run: pip install sympy + + - run: pip install sympy + + - name: Drift check (node statements + mirrored defs still match the mirrormere and rh registries) + working-directory: telperion + run: | + python examples/rvm_bridge/generate.py --check + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/rvm_bridge/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + # Zeta23 (anthropics/formal-math, public, Apache-2.0; ~1.6 MB repo) is cloned by Lake at the + # pinned commit; Mathlib oleans come from the cache through that dependency. Zeta23 itself + # (118 modules) compiles from source: ~2 min on 32 cores locally, expect ~15-25 min on a + # 4-core hosted runner. + - name: Fetch Mathlib olean cache (through the Zeta23 dependency) + working-directory: telperion/examples/rvm_bridge/lean + run: lake exe cache get + + - name: Build the bridge against the pinned zeta-23-lean (the actual verification) + working-directory: telperion/examples/rvm_bridge/lean + run: lake build + + - name: "Axiom guard (45 anchors incl. consumed upstream inputs): exact axiom set, no sorryAx, guard actually ran" + working-directory: telperion/examples/rvm_bridge/lean + shell: bash + run: | + set -euo pipefail + lake env lean AxiomGuardRvMBridge.lean 2>&1 | tee axioms.out + n=$(grep -cE "depends on axioms|does not depend on any axioms" axioms.out || true) + if [ "$n" -lt "45" ]; then + echo "::error::axiom guard printed $n axiom lines, expected at least 45 -- the guard did not run or was silently truncated"; exit 1; fi + if grep -q "sorryAx" axioms.out; then echo "::error::sorryAx present"; exit 1; fi + # every printed axioms line must be EXACTLY Lean's three standard axioms + # Lean WRAPS a long axiom list across lines, so a line-based grep sees a truncated + # list and reports a false positive. Join lines, then extract each complete + # "depends on axioms: [...]" group and require it to be exactly the three. + if tr "\n" " " < axioms.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ + | grep -vq "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$"; then + echo "::error::unexpected axiom beyond [propext, Classical.choice, Quot.sound]" + tr "\n" " " < axioms.out | grep -oE "depends on axioms: \[[^]]*\]" | tr -s " " \ + | grep -v "^depends on axioms: \[propext, Classical.choice, Quot.sound\]$" + exit 1; fi + dbn-compiles: + runs-on: ubuntu-latest + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/dbn/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + - name: Fetch Mathlib olean cache (through the LiCriterion dependency) + working-directory: telperion/examples/dbn/lean + run: lake exe cache get + + - name: No `sorry` in the island (the registry statements live in missions/rh, not here) + working-directory: telperion/examples/dbn/lean + run: | + ! grep -rnwE "sorry|admit" --include='*.lean' --exclude-dir=.lake . + + - name: Build the DBN foundations island (DBNDefs + AxiomGuardDBN) + working-directory: telperion/examples/dbn/lean + run: lake build + + - name: Axiom guard (fails on sorryAx anywhere in the island) + working-directory: telperion/examples/dbn/lean + run: | + lake env lean AxiomGuardDBN.lean | tee axioms.out + ! grep -q "sorryAx" axioms.out + exp-enclosure-compiles: + runs-on: ubuntu-latest + timeout-minutes: 180 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install sympy pytest + + - name: Regenerate the exp-enclosure instances from the family definition + working-directory: telperion + run: | + python examples/exp_enclosure/generate.py --check + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/zeta_zero_localization/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + - name: Wire the sharded packages to one shared deps dir (B2 layout; .lake is gitignored) + working-directory: telperion/examples/zeta_zero_localization/lean + run: | + mkdir -p .lake/packages + for d in zzl_core zzl_aux ZetaBands_h*; do + mkdir -p "$d/.lake" && ln -sfn ../../.lake/packages "$d/.lake/packages" + done + mkdir -p ../../zero_free_bridge/lean/.lake + ln -sfn ../../../zeta_zero_localization/lean/.lake/packages ../../zero_free_bridge/lean/.lake/packages + + - name: Fetch Mathlib olean cache (into the shared deps dir) + working-directory: telperion/examples/zeta_zero_localization/lean/zzl_aux + run: lake exe cache get + + - name: Build the emitted exp-enclosure lib (zzl_aux owns BraggDefect, which the bridge imports) + working-directory: telperion/examples/zeta_zero_localization/lean/zzl_aux + run: lake build ExpEnclosureInstances + disjoint-discs-compiles: + runs-on: ubuntu-latest + timeout-minutes: 180 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install sympy pytest + + - name: Regenerate the disjoint-discs isolation instances from the family definition + working-directory: telperion + run: | + python examples/disjoint_discs/generate.py --check + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/quasicrystal/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + - name: Fetch Mathlib olean cache + working-directory: telperion/examples/quasicrystal/lean + run: lake exe cache get + + - name: Build the E4b isolation lemma and the emitted instances + working-directory: telperion/examples/quasicrystal/lean + run: | + # The guard below imports the whole island, so build every default + # target, not just this branch's two modules: a partial build leaves + # the guard's own imports unbuilt and it fails with 'unknown module + # prefix', which is a false red on a proof that is fine. + lake build + + - name: Axiom guard (OfflineDiscs + instances must be sorry-free and axiom-clean) + working-directory: telperion/examples/quasicrystal/lean + run: | + lake env lean AxiomGuardQC.lean 2>&1 | tee guard.txt + if grep -q "sorryAx" guard.txt; then echo "GUARD FAILED: sorryAx present"; exit 1; fi + grep -q "Quasicrystal.offline_disjoint_discs" guard.txt || { echo "GUARD FAILED: node theorem not printed"; exit 1; } + grep -q "OfflineDiscsInstances.offline_discs_offline_bank" guard.txt || { echo "GUARD FAILED: instance not printed"; exit 1; } + gram-inertia-compiles: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install sympy pytest + + - name: Regenerate the inertia boxes (certify -> emit) and check they match on-disk + working-directory: telperion + run: | + python examples/gram_inertia/generate.py --check + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/gram_inertia/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + - name: Fetch Mathlib olean cache + working-directory: telperion/examples/gram_inertia/lean + run: lake exe cache get + + - name: Build the bridge + the emitted certificates (the actual verification) + working-directory: telperion/examples/gram_inertia/lean + run: lake build + + - name: Axiom guard (fails on sorryAx anywhere in the bridge or the certificates) + working-directory: telperion/examples/gram_inertia/lean + run: | + lake env lean AxiomGuardGramInertia.lean | tee axioms.out + ! grep -q "sorryAx" axioms.out + mission-statements-compile: + # Design invariant (MISSIONS_DESIGN_2026-09-11 section 2): "CI builds each + # statement package: a statement that does not elaborate cannot enter the + # graph." This job closes the gap for ALL four campaigns (bg/rh predate it + # too). `by sorry` bodies are expected (statements, not proofs) -- lake + # emits warnings, not errors; the gate is elaboration. + strategy: + fail-fast: false + matrix: + campaign: [bg, rh, anduril, mirrormere] + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles(format('telperion/missions/{0}/lean/lean-toolchain', matrix.campaign)) }} + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + - name: Fetch Mathlib olean cache + working-directory: telperion/missions/${{ matrix.campaign }}/lean + run: lake exe cache get + - name: Build the statement package (statements must elaborate; sorry bodies expected) + working-directory: telperion/missions/${{ matrix.campaign }}/lean + run: lake build + bragg-amplitude-compiles: + runs-on: ubuntu-latest + timeout-minutes: 180 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install sympy pytest + + - name: Regenerate the Bragg-amplitude instances from the family definition + working-directory: telperion + run: | + python examples/bragg_amplitude/generate.py --check + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/zeta_zero_localization/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + - name: Wire the sharded packages to one shared deps dir (B2 layout; .lake is gitignored) + working-directory: telperion/examples/zeta_zero_localization/lean + run: | + mkdir -p .lake/packages + for d in zzl_core zzl_aux ZetaBands_h*; do + mkdir -p "$d/.lake" && ln -sfn ../../.lake/packages "$d/.lake/packages" + done + mkdir -p ../../zero_free_bridge/lean/.lake + ln -sfn ../../../zeta_zero_localization/lean/.lake/packages ../../zero_free_bridge/lean/.lake/packages + + - name: Fetch Mathlib olean cache (into the shared deps dir) + working-directory: telperion/examples/zeta_zero_localization/lean/zzl_aux run: lake exe cache get - name: Build the emitted Bragg-amplitude lib (zzl_aux owns CosEnclosure + the Bragg family) @@ -2531,6 +2597,45 @@ jobs: - name: Build the emitted rigidity lib (uses the island's TwoFreqRigidity) working-directory: telperion/examples/quasicrystal/lean run: lake build SelfInversiveRigidityInstances + twofreq-offline-compiles: + runs-on: ubuntu-latest + timeout-minutes: 180 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - run: pip install sympy pytest + + - name: Unit tests (self-check pass + anti-phantom refusals + negative-control twins) + working-directory: telperion + run: | + PYTHONPATH=src python -m pytest tests/test_emit_twofreq_offline.py \ + tests/test_negctrl_twofreq_offline.py -q + + - name: Regenerate the Euler-factor off-line sections from the family definition + working-directory: telperion + run: | + python examples/twofreq_offline/generate.py --check + + - name: Cache elan toolchain + uses: actions/cache@v4 + with: + path: ~/.elan + key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/quasicrystal/lean/lean-toolchain') }} + + - name: Install elan + run: | + curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none + echo "$HOME/.elan/bin" >> "$GITHUB_PATH" + + - name: Fetch Mathlib olean cache + working-directory: telperion/examples/quasicrystal/lean + run: lake exe cache get + + - name: Build the emitted off-line sections (uses the island's TwoFreqRigidity) + working-directory: telperion/examples/quasicrystal/lean + run: lake build EulerFactorSectionOffline winding-box-zero-compiles: runs-on: ubuntu-latest timeout-minutes: 20 @@ -2696,71 +2801,3 @@ jobs: - name: Build the emitted Lean (RH Face 4 — Bagchi recurrence) working-directory: telperion/examples/bagchi_recurrence/lean run: lake build - gram-inertia-compiles: - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - run: pip install sympy pytest - - - name: Regenerate the inertia boxes (certify -> emit) and check they match on-disk - working-directory: telperion - run: | - python examples/gram_inertia/generate.py --check - - - name: Cache elan toolchain - uses: actions/cache@v4 - with: - path: ~/.elan - key: elan-${{ runner.os }}-${{ hashFiles('telperion/examples/gram_inertia/lean/lean-toolchain') }} - - - name: Install elan - run: | - curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none - echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - - name: Fetch Mathlib olean cache - working-directory: telperion/examples/gram_inertia/lean - run: lake exe cache get - - - name: Build the bridge + the emitted certificates (the actual verification) - working-directory: telperion/examples/gram_inertia/lean - run: lake build - - - name: Axiom guard (fails on sorryAx anywhere in the bridge or the certificates) - working-directory: telperion/examples/gram_inertia/lean - run: | - lake env lean AxiomGuardGramInertia.lean | tee axioms.out - ! grep -q "sorryAx" axioms.out - mission-statements-compile: - # Design invariant (MISSIONS_DESIGN_2026-09-11 section 2): "CI builds each - # statement package: a statement that does not elaborate cannot enter the - # graph." This job closes the gap for ALL four campaigns (bg/rh predate it - # too). `by sorry` bodies are expected (statements, not proofs) -- lake - # emits warnings, not errors; the gate is elaboration. - strategy: - fail-fast: false - matrix: - campaign: [bg, rh, anduril, mirrormere] - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - name: Cache elan toolchain - uses: actions/cache@v4 - with: - path: ~/.elan - key: elan-${{ runner.os }}-${{ hashFiles(format('telperion/missions/{0}/lean/lean-toolchain', matrix.campaign)) }} - - name: Install elan - run: | - curl https://elan.lean-lang.org/elan-init.sh -sSf | sh -s -- -y --default-toolchain none - echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - name: Fetch Mathlib olean cache - working-directory: telperion/missions/${{ matrix.campaign }}/lean - run: lake exe cache get - - name: Build the statement package (statements must elaborate; sorry bodies expected) - working-directory: telperion/missions/${{ matrix.campaign }}/lean - run: lake build diff --git a/telperion/README.md b/telperion/README.md index 2a1a77c78..3e79c7fb0 100644 --- a/telperion/README.md +++ b/telperion/README.md @@ -168,6 +168,7 @@ under [`examples/`](examples/). | `IntervalGramInertiaEmitter` | the **exact inertia of an INTERVAL matrix**: for a rational box `lo ≤ G ≤ hi`, EVERY real symmetric `G` inside it has signature exactly `(p, q)` — `RHLinalg.posIndex hG = p ∧ RHInertia.defect hG = q`. Untrusted Python computes the midpoint `M`, an exact rational congruence `BᵀMB = D` (symmetric Gaussian elimination with pivoting — `psd_form`'s LDLᵀ primitive run to a full diagonalization), and the witness bases `X` (positive pivots) / `Y` (negative pivots) rescaled to unit column absolute-sum; the box is absorbed by `|xᵀ(G−M)x| ≤ w·(Σ|xᵢ|)²` and Cauchy–Schwarz, so the certificate is sound exactly when the pivot margin beats the slack, `w·S < δ`. Fills the gap `psd_form` (one explicit matrix, definite only), `rayleigh_gram` (one direction) and `hermitian_moment` (scalar shadows) leave open — the D2/D3/T3 shape "this Arb-enclosed Hermitian matrix has negative index exactly q". REFUSES an asymmetric/empty box (the phantom: no Hermitian matrix in it), a singular midpoint, a definite box (that is `psd_form`), and any box wider than the pivot margin. **Island-pinned** to the ported RHLinalg block (v4.32.0); real-symmetric only | per-entry `inertia_entries` + `linarith only` for the box, `nlinarith` for the compressed margin, then RHInertia's `compress_posDef_of_interval` + `inertia_eq_of_witnesses` (Sylvester both ways) | | `BraggAmplitudeEmitter` | a **certified truncated diffraction sum** `Σ_k cos(γ_k·u) ∈ [A,B]` over rational ordinate brackets `[a_k,b_k]` at a rational Bragg frequency `u` (PROGRAM ANDÚRIL × MIRRORMERE). The `BraggH100` `CosEnclosure` pipeline reduced to a small base-case instance (3–5 ordinates, `|c_k|≤1`): a per-ordinate cos box (order-4 Taylor bracket + Lipschitz width absorption) folded by `add_encl`, PER-ZERO LEMMA SPLIT. Refuses a claimed `[A,B]` that does not enclose the folded box (negative control) or an out-of-range sample `|c_k|>1` | per-box `CosEnclosure.cos_base_interval` + `cos_encl_bracket` (`norm_num`/`nlinarith`); fold `CosEnclosure.add_encl` + `linarith` | | `DefectWitnessEmitter` | the **two-configuration inertia gap** (MIRRORMERE `BraggDefect`): on-line defect functional `q(0)=0 ∈ [A,B]`, off-line `q(d)=−d² ∈ [−d_hi²,−d_lo²]` strictly `< 0` for excess `d ∈ [d_lo,d_hi]`, and the **leakage gap** `−d_lo² < 0 = q(0)` — the Alpöge–Furman signature-(1,1) leakage as a kernel-observable separation. Self-contained on the given rational excess bracket (no Arb `exp` hypothesis). Refuses a degenerate/swapped configuration `d_lo=0` (no excess) or `0 ∉ [A,B]` | `unfold` + `norm_num`/`nlinarith` (three theorems: online / offline / leakage_gap) | +| `ExpEnclosureEmitter` | a **certified rational bracket of a transcendental exponential** at a rational point (MIRRORMERE): `lo ≤ Real.exp x ≤ hi` for `|x| ≤ 1`, plus the `exp_neg`, **deficit** (`lo ≤ e^x + e^{−x} − 2 ≤ hi`, the QC_RECURRENCE row-(a) excess) and `cosh` faces. The exact rational order-`n` Taylor box of `Real.exp_bound` (`S = Σ_{m1`, order `<1` or `>64`, an inverted bracket, a non-positive deficit displacement, or non-rational input | `Real.exp_bound` + `simp only [Finset.sum_range_succ, Finset.sum_range_zero]` + `norm_num [Nat.factorial]` + `linarith` (two-sided modes fold the two faces; `cosh` via `Real.cosh_eq`) | | `SelfInversiveRigidityEmitter` | **equal-modulus real-rootedness** (MIRRORMERE R3, n=2): for Gaussian-rational `c₁,c₂` with `\|c₁\|²=\|c₂\|²` EXACTLY, the two-frequency sum `c₁e^{iλ₁x}+c₂e^{iλ₂x}` is real-rooted — reverse-Dyson rigidity forced by an equal-modulus condition on the coefficients. Applies the in-island `Quasicrystal.twoFreq_realRooted_iff`. Refuses unequal modulus (negative control — every zero then off the real line), a zero coefficient, or `λ₁=λ₂` | `Complex.norm_def` + exact rational `normSq` equality (`norm_num`) fed into `twoFreq_realRooted_iff.mpr` | | `WindingBoxZeroEmitter` | **Arb-trust-class winding-number box certificate** for a zero (the `turing_band` sidecar trust class): the rigorous zero count of an analytic `f` on a rational-cornered box via the quadrant-advance argument principle over Arb-ball boundary samples. Ships **no kernel theorem** — a `.cert.json` sidecar (box, edge-sample count, precision, winding integer, `trust_class="arb"`) + a documentation stub honestly stating the trust boundary. Self-check RE-VERIFIES the winding at doubled precision + density; refuses a claimed count the argument principle does not support (negative control) | none (Arb sidecar + doc stub; `nthm=0`) | | `CustomAssemblyEmitter` | escape hatch for a hand-designed assembly | your skeleton | @@ -176,6 +177,8 @@ under [`examples/`](examples/). | `LehmerPairEmitter` | **RH Face 5 (de Bruijn–Newman / criticality).** A certified *Lehmer pair* — two consecutive ζ-zeros anomalously close (Face 5: RH ⟺ Λ ≤ 0, Λ ≥ 0 by Rodgers–Tao): from Arb-certified ordinates (`hardy_z_zeros`) the exact rational quality `δ²·C_n` (`C_n` = neighboring-zero curvature) is emitted as `quality_short ≤ qcap < 1`, the anomalous-closeness signature. Ships the WIP Λ-bound skeleton `lehmer_lambda_bound_wip` (the CNV Λ-lower-bound constant is UNVERIFIED this pass, carried as hypothesis, no numeric kernel claim) + `lehmer_neg_refutes`. Refuses a non-Lehmer pair (quality ≥ 1) or `qcap` below the quality / ≥ 1 | `by norm_num` on the exact-rational quality inequality; the Λ-bound WIP skeleton is `le_trans hround hCNV` | | `BagchiRecurrenceEmitter` | **RH Face 4 (recurrence).** A finite recurrence observation (Bagchi 1981: RH ⟺ ζ strongly recurrent in the strip): over a compact rational box K (a σ×t grid inside `1/2 < Re s < 1`) and a shift τ, the certified grid-max `M = max_grid |ζ(s+iτ) − ζ(s)|` (each per-point deviation a rigorous flint/Arb `acb.zeta` `abs_upper`) satisfies `M ≤ ε`; `M` carried as hypothesis `hdev`, `ε` a readable rounded-up cap. Ships `bagchi_recurrence_refutes`. Arb-trust class; scope = sup over the GRID (continuous sup needs a modulus argument, documented not claimed). Refuses `ε < M` or an empty grid. A finite observation, NOT RH | `le_trans hdev (by norm_num)` — the Arb grid-max carried as hypothesis, `M ≤ ε` closed by `norm_num` | +| `ExpLaurentIdentityEmitter` | **RH Face 4 <-> Face 1 dictionary bookkeeping.** An identity in `Real.exp d` and `Real.exp (-d)` -- amplitude sums `e^d + e^(-d)` (a `2 cosh` channel), one-sided clearances `e^d - 1` / `1 - e^(-d)`, their products and squares -- certified as an EXACT reduction of `lhs - rhs` modulo the single relation `e^d * e^(-d) = 1` in `Q[y, z]`; the quotient (cofactor) is the load-bearing certificate. Refuses a nonzero remainder (the motivating case: the clearances' SUM is `2d + O(d^3)`, NOT the amplification excess -- QC_RECURRENCE section 6's own corrected mistake) and refuses a cofactor-0 plain ring identity (that shape is `IdentityEmitter`'s). Unconditional, zeta-free; dictionary bookkeeping, NOT an analytic theorem and NOT a step toward RH | `have hrel : Real.exp d * Real.exp (-d) = 1 := by rw [<- Real.exp_add]; norm_num` then `linear_combination (cofactor) * hrel` | + *Candidate (not-yet-built) shapes are tracked in the emitter roadmaps under [`docs/`](docs/) — `EMITTER_ROADMAP_2026-08-21.md` (BG / P=NP backlog: `SymmetricQuadForm`, `PolytopeMaxMonotone`, `SingularPSD`, …), `EMITTER_ROADMAP_2026-09-02_RH_CROSSCUT.md` diff --git a/telperion/docs/EMITTER_MIRRORMERE_2026-09-18.md b/telperion/docs/EMITTER_MIRRORMERE_2026-09-18.md new file mode 100644 index 000000000..0035b237a --- /dev/null +++ b/telperion/docs/EMITTER_MIRRORMERE_2026-09-18.md @@ -0,0 +1,98 @@ +# MIRRORMERE emitter additions -- 2026-09-18 + +conjecture1_proved = False. Nothing in this document, and nothing emitted by the tools it +describes, is progress toward RH. Each entry is a finite, unconditional, kernel-checked +fact, and several of them are explicitly NEGATIVE controls: they certify that a hoped-for +property FAILS at finite truncation. + +## `twofreq_offline` -- certified OFF-line displacement of a two-frequency section + +**Module** `telperion/src/telperion/emit_twofreq_offline.py` · +**Emitter** `TwoFreqOfflineEmitter` · +**Dogfood** `telperion/examples/twofreq_offline/generate.py` -> +`examples/quasicrystal/lean/EulerFactorSectionOffline.lean` · +**CI** `twofreq-offline-compiles` · +**Adapter** `negctrl_adapters/adapter_twofreq_offline.py` · +**Stance** `STRUCTURALLY_NONVACUOUS` + `NEG_CONTROL_ADAPTER`. + +### The shape + +The quasicrystal island proves (`TwoFreqRigidity.lean:92`, v4.32) + +``` +twoFreq_realRooted_iff : + c1 != 0 -> c2 != 0 -> lam1 != lam2 -> + ((forall x : C, twoFreq c1 c2 lam1 lam2 x = 0 -> x.im = 0) <-> ||c1|| = ||c2||) +``` + +`selfinversive_rigidity` (2026-09-14) emits the POSITIVE direction: `|c1|^2 = |c2|^2` +EXACTLY, hence real-rooted. `twofreq_offline` emits the NEGATIVE direction: `|c1|^2 != +|c2|^2` EXACTLY, hence NOT real-rooted -- some zero lies strictly off the real line. + +The two emitters **partition the coefficient space**. Each REFUSES precisely the regime +the other certifies (`selfinversive_rigidity` refuses unequal modulus; `twofreq_offline` +refuses equal modulus), so neither can emit a false theorem, and the pair of refusals is +the anti-phantom guard for both. + +### Why it was needed + +`MM_euler_factor_section_offline` (ladder rung T2, `QC_TORUS_SECTION_LADDER_MEMO` +sections 4b/5) is exactly the negative direction at the `p = 2` Euler factor, and its +coefficient is the IRRATIONAL `-1/sqrt 2` -- which the Gaussian-rational-only +`selfinversive_rigidity` emitter cannot take. So the emitter adds: + +* three coefficient literal shapes with EXACT rational moduli -- + `gauss(re, im)` (`|c|^2 = re^2 + im^2`), `inv_sqrt(s, sign)` (`|c|^2 = 1/s`), + `real_sqrt(q, s)` (`|c|^2 = q^2 s`); +* two frequency literal shapes -- `rat(r)` and `neglog(p)` (the literal `-(Real.log p)`). + +That turns the single registry node into the whole T2 FAMILY: for every `p >= 2`, the +Euler factor `1 - p^(-s)` read on `s = 1/2 + i x` is the section +`twoFreq 1 (-(1/sqrt p)) 0 (-(log p))`, whose moduli `1` and `1/sqrt p` never agree. + +### What each instance emits + +1. `{nm}` -- `NOT (forall x : C, twoFreq c1 c2 lam1 lam2 x = 0 -> x.im = 0)`; +2. `{nm}_offline_zero` -- the existence corollary `exists x, ... = 0 AND x.im != 0`; +3. `{nm}_displacement` (mode `displacement`, Euler-factor shape ONLY) -- the certified + LOCATION: `forall x, ... = 0 -> x.im = 1/2`, i.e. every zero sits on `Re s = 0`, + uniformly, with no dependence on the truncation. + +### Refusals (all EXACT rational arithmetic, no floats) + +`|c1|^2 == |c2|^2` (the sum IS real-rooted -- the emitted negation would be FALSE); a zero +coefficient; `lam1 == lam2` including the disguised `neglog(1) == rat(0)` (log 1 = 0); a +negative rational frequency opposite a `-log p` frequency (the emitted separation is +`-log p < 0 <= r`); a radicand that is not an integer `>= 2`; `mode='displacement'` +outside the Euler-factor shape (the general displacement is +`-log(|c1|/|c2|) / (lam2 - lam1)`, not `1/2` -- refused rather than guessed); `p < 2`. + +### Negative control + +`adapter_twofreq_offline` forges the `selfinversive_rigidity` TRUE instance +(`c1 = 3/5 + 4/5 i`, `c2 = 1`, equal moduli 1) by hand-minting the frozen dataclass, thus +bypassing the Layer-1 refusal. The forged proof reaches `h2 : (1 : R) = 1` with goal +`False` and the kernel rejects it (observed: `unsolved goals ... h2 : True |- False`). The +true twin -- the `p = 2` Euler factor, moduli 1 vs 1/2 -- compiles clean. Both twins are +rendered in BRIDGE-HYPOTHESIS mode (the island `twoFreq` copied verbatim into the prelude, +the island iff carried as an explicit hypothesis `hiff`), because the harness elaborates +against plain `import Mathlib`; the same discipline as `adapter_bragg_floor`. The +hypothesis-FREE island theorem is what the `twofreq-offline-compiles` CI job builds. + +### Verification performed (2026-09-18, local, v4.32 quasicrystal island) + +* `lake build EulerFactorSectionOffline` -- green, 8 theorems, no warnings; +* `#print axioms` on all 8 -- `[propext, Classical.choice, Quot.sound]`; +* `telperion.statement_match.statement_match_check` -- 2/2 match, so + `euler_factor_section_offline` and its displacement companion state EXACTLY the intended + propositions (kernel-level defeq, not string containment); +* `generic_negative_control` against the island env -- `kernel_rejects=True`, + `true_compiles=True`, `okay=True`. + +### Honest scope + +A finite fact about ONE Euler factor at a time. It says nothing about zeta, about the +Euler product, or about RH. Read positively it is a WARNING: per-rung line membership +genuinely fails, at every rung and every prime, with a uniform displacement of 1/2, so +critical-line membership can only ever be an infinite-N continuation phenomenon -- never a +finite-section fact. conjecture1_proved = False. diff --git a/telperion/docs/MM_mm-euler-factor-offline_2026-09-18.md b/telperion/docs/MM_mm-euler-factor-offline_2026-09-18.md new file mode 100644 index 000000000..8adbbf389 --- /dev/null +++ b/telperion/docs/MM_mm-euler-factor-offline_2026-09-18.md @@ -0,0 +1,110 @@ +# MM_euler_factor_section_offline -- the p = 2 Euler-factor section is NOT real-rooted + +**conjecture1_proved = False.** This closes ONE registry node: a finite, unconditional +*negative control*. It is not RH progress, not a step toward RH, and by construction it is the +statement that a per-rung line-membership claim FAILS. + +Date: 2026-09-18. Branch `mm/mm-euler-factor-offline` (base `origin/rh/million-turing`). +Island: `telperion/examples/quasicrystal/lean` (Mathlib v4.32.0). +Node: `MM_euler_factor_section_offline` (MIRRORMERE, torus-section ladder rung T2). + +## 1. What was proved + +The p-th Euler factor `1 - p^{-s}`, read on the critical line `s = 1/2 + i x`, is the +two-frequency section `twoFreq(1, -(1/sqrt p); 0, -log p)`. For p = 2 the registry statement is + +```lean +theorem euler_factor_section_offline : + ¬ (∀ x : ℂ, + twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 → x.im = 0) +``` + +proved sorry-free in `telperion/examples/quasicrystal/lean/EulerFactorOffline.lean` +(namespace `TorusSectionLadder`). Route: the `.mp` direction of the island's R3(n=2) rigidity +theorem `Quasicrystal.twoFreq_realRooted_iff` turns real-rootedness into `‖c₁‖ = ‖c₂‖`, i.e. +`1 = 1/sqrt 2`, refuted by `Real.one_lt_sqrt_two` through `div_lt_one`. The two side facts the +kernel needs are `-(1/sqrt 2) ≠ 0` and `0 ≠ -log 2` (from `Real.log_pos`), each its own lemma. + +Three companion theorems in the same file (NOT nodes): + +* `euler_factor_section_witness` -- the EXPLICIT off-line zero `x = i/2`: + `e^{-i (log 2)(i/2)} = e^{(log 2)/2} = sqrt 2` (via `Real.exp_half` + `Real.exp_log`), so + `1 - (1/sqrt 2)·sqrt 2 = 0`. The negative control therefore carries a witness, not merely a + refuted universal. +* `euler_factor_section_witness_im` -- `Im (i/2) = 1/2`, the uniform off-line displacement + (the zeros are `s = 2 pi i k / log 2`, i.e. `Re s = 0`). +* `euler_factor_section_offline_of_witness` -- the SAME node statement re-derived directly from + the witness, an independent second route that does not use the iff at all. + +`statement_match_check` (telperion/src/telperion/statement_match.py) reports `all_match=True` +against the registry statement text for the node theorem and for the emitted `_node` form below. + +## 2. New certificate shape: selfinversive_rigidity `mode="offline"` + +The natural shape here is a certificate, so rather than leave it hand-written the existing +`SelfInversiveRigidityEmitter` gained a second MODE (the item's tool request +`tool-selfinversive-offline-mode`). `telperion/src/telperion/emit_selfinversive_rigidity.py`: + +* **Coefficients** may now be radicals `r·sqrt(q)` (r, q rational, r ≠ 0, q > 0), so the modulus + `|c|² = r²·q` stays EXACT rational arithmetic -- the `1/sqrt p` of an Euler factor is expressible + without leaving exact arithmetic. +* **Frequencies** may be rational or `r·log q` (q an integer ≥ 2). +* **Verdict** `|c₁|² ≠ |c₂|²` emits `¬ real-rooted` through the `.mp` direction; the kernel + re-derives `‖c‖² = r²·q` (`Complex.norm_real`, `sq_abs`, `Real.sq_sqrt`) and closes the + inequality by `norm_num`, so a corrupted normSq breaks the emitted rewrite rather than + silently weakening the statement. +* **Euler-factor shape** `twoFreq(1, -(1/sqrt p); 0, -log p)` is detected, and the emitter + additionally ships the `x = i/2` witness, the witness-route refutation, the two coefficient + normalisation lemmas, and `…_node`: the SAME refutation restated with the coefficients spelled + `1` and `-(1/sqrt p)` -- i.e. the mission-registry statement VERBATIM, emitted. +* **NEGATIVE CONTROL of the offline mode** (mirror of the default mode's): EQUAL modulus is + REFUSED -- equal modulus forces real-rootedness, so there is no off-line zero to certify. Also + refused: a zero coefficient, a non-positive radicand, and any frequency pair whose distinctness + is not kernel-certifiable (a nonzero rational against `r·log q`, or two logs of different bases, + would need transcendence / independence of logarithms -- refused, not faked). + +Dogfood: `telperion/examples/selfinversive_rigidity/generate.py` now also emits +`SelfInversiveOfflineInstances.lean` into the island, with p = 2, 3, 5 (18 theorems; p = 3 and 5 +are free extras and are NOT nodes). The existing `[[check]] selfinversive_rigidity` in +`telperion/telperion.toml` covers both libs, because it runs the same generator with `--check`; +drift check passes byte-for-byte. The frozen `SelfInversiveRigidityInstances.lean` changed only +in its input-hash header line (the hash covers the emitter source). + +Sensitivity registry (`emitter_sensitivity.py`) stance text extended to document the mode. Tests: +`telperion/tests/test_emit_selfinversive_rigidity.py`, 13 passed (6 new, covering the positive +certificate, the equal-modulus refusal, zero/negative-radicand refusal, the uncertifiable +frequency pairs, the accepted distinctness cases, the emitted refutation/witness/node forms, the +witness-free generic instance, and an unknown mode). + +## 3. Registration + +* `lakefile.toml`: `EulerFactorOffline` and `SelfInversiveOfflineInstances` added as `lean_lib`s + and to `defaultTargets`. +* `AxiomGuardQC.lean`: 6 + 12 new `#print axioms` lines; all report + `[propext, Classical.choice, Quot.sound]`, no `sorryAx`, no `ofReduceBool`. +* CI (`.github/workflows/telperion-lean-e2e.yml`, job `selfinversive-rigidity-compiles`): builds + the offline lib and the node module, then runs the axiom guard. +* Registry: `telperion mission link` (artifact `EulerFactorOffline.lean`, `lean_module`, `direct`) + and `telperion mission attempt` (verdict `Proved`). Status left `open`; the grant is deferred + to the branch reconcile, as for the island's other million-turing artifacts. + `telperion mission verify mirrormere` -> `verify [mirrormere]: OK`. + +## 4. Footgun found (island-wide) + +Worktrees that symlink the same built `.lake` share one olean build directory. A module built +under a name a teammate also uses is silently CLOBBERED: my first `TorusSectionLadder.lean` +guarded clean, then a teammate's same-named module replaced the olean and `import +TorusSectionLadder` stopped resolving my declarations, surfacing as "unknown namespace", not as a +build error. The module was renamed `EulerFactorOffline.lean` (namespace kept as +`TorusSectionLadder`, so it merges with the T1 ladder file at reconcile). Rule of thumb: one +module name per agent per shared cache, and re-run `lake build` immediately before any guard or +statement-match run. + +## 5. Scope + +The content is the `.mp` direction of an existing island iff plus one exact norm inequality +(`1 ≠ 1/sqrt 2`, needing `1 < sqrt 2`) and one `log 2 ≠ 0` fact -- deliberately small, and not +simp-trivial. Its value is as a CERTIFIED negative control: it pins down that the torus-section +ladder's per-rung sections are uniformly off-line at displacement 1/2, so critical-line membership +cannot be read off any finite rung (the Turan/Montgomery obstruction, in-house). Nothing here +bears on RH. conjecture1_proved = False. diff --git a/telperion/docs/MM_mm-offline-disjoint-discs_2026-09-18.md b/telperion/docs/MM_mm-offline-disjoint-discs_2026-09-18.md new file mode 100644 index 000000000..6e65551fc --- /dev/null +++ b/telperion/docs/MM_mm-offline-disjoint-discs_2026-09-18.md @@ -0,0 +1,168 @@ +# MM_offline_disjoint_discs -- the E4b isolation lemma, closed (and given a certificate kind) + +**Date** 2026-09-18 - **Branch** `mm/offline-disjoint-discs` (base `origin/rh/million-turing`, not pushed) +**Worktree** `/Users/peterwmurphy/arda-mm-offline-disjoint-discs` +**Island** `telperion/examples/quasicrystal/lean` (Lean 4.32.0, Mathlib v4.32.0) + +**conjecture1_proved = False.** Nothing here is progress on the Riemann Hypothesis. The lemma proved +below is elementary metric topology about an arbitrary finite set of points; the instances emitted +below take their points as INPUT and assert nothing about where zeta vanishes. + +## 1. What the node asked for + +Registry node `MM_offline_disjoint_discs` (kind `lemma`, `depends_on = []`, status `open`, blind +read-back by `blind-auditor-2` on 2026-09-16 with no flags). It is the Routes-roadmap E4b isolation +lemma from `QC_RECURRENCE_MEMO.md` section 4.3: the geometric substrate for counting off-line zeros +by disjoint recurrence-deficit discs -- the Rouche-template leg of the finite-grade interderivability +E5. + +The statement in `missions/mirrormere/lean/Statements/MM_offline_disjoint_discs.lean` +(node sha256 `bac57ccef7c3f828`): + +```lean +theorem offline_disjoint_discs (S : Finset ℂ) + (hstrip : ∀ z ∈ S, 0 < z.re ∧ z.re < 1) : + ∃ r : ℝ, 0 < r ∧ + (∀ z ∈ S, ∀ w ∈ S, z ≠ w → Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧ + (∀ z ∈ S, Metric.closedBall z r ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1}) := by sorry +``` + +## 2. What was delivered + +### 2a. The lemma, proved sorry-free + +`telperion/examples/quasicrystal/lean/OfflineDiscs.lean` (new `lean_lib` + `defaultTarget`) states +the node's theorem VERBATIM in the island's `Quasicrystal` namespace and proves it. The `diff` +between the node statement and the island statement is empty modulo the stripped `:= by sorry`. + +The route avoids `Finset.inf'` and its non-emptiness bookkeeping entirely -- which is where the work +item flagged the only friction -- by proving a one-line-idea helper first: + +```lean +theorem exists_pos_lower_bound_of_finset (T : Finset ℝ) (hT : ∀ x ∈ T, 0 < x) : + ∃ ε : ℝ, 0 < ε ∧ ∀ x ∈ T, ε ≤ x +``` + +by `Finset.induction_on` (`min` at each step; the empty set takes `ε = 1`). Applying it to + +* the image of `S.offDiag` under `fun p => dist p.1 p.2` (positive by `dist_pos.mpr` on the + `mem_offDiag` distinctness witness) gives a separation scale `ε₁`, and +* the image of `S` under `fun z => min z.re (1 - z.re)` (positive by `hstrip`) gives a margin `ε₂`, + +the radius is `r := min (ε₁ / 3) (ε₂ / 2)`. Both degenerate cases fall out for free: an empty +`offDiag` makes the pair clause vacuous, an empty `S` makes both clauses vacuous, and the helper +still returns a positive `ε`, so no case split is written anywhere in the proof. + +Disjointness is `Metric.closedBall_disjoint_closedBall (h : δ + ε < dist x y)` with +`r + r ≤ 2ε₁/3 < ε₁ ≤ dist z w` closed by `linarith`. Strip containment goes through the second +helper, + +```lean +theorem abs_re_sub_le_dist (s z : ℂ) : |s.re - z.re| ≤ dist s z +``` + +(`Complex.abs_re_le_norm` on `s - z`, `Complex.sub_re`, `dist_eq_norm`) -- the real part is +1-Lipschitz -- so `|s.re - z.re| ≤ r ≤ ε₂/2 < min z.re (1 - z.re)` and `linarith` closes both sides +of the strip. + +### 2b. The missing certificate kind, built: `DisjointDiscsEmitter` + +The work item asked for exactly this and it is the honest gap: the general lemma is a lemma-pack +entry with NO certificate (there are no numbers in it), but what E5 actually consumes is the +INSTANCE -- a concrete certified point list turned into concrete Rouche discs with an explicit +radius. No existing Telperion kind fit; the nearest geometric shape, `two_scale_separation`, carries +two radii about one centre and has no multi-point or containment content. So a new kind was minted: + +| piece | path | +|---|---| +| emitter (kind `disjoint_discs`) | `telperion/src/telperion/emit_disjoint_discs.py` | +| dispatch wiring | `certify.py` `_SPECIAL_KINDS` + `_SPECIAL_DISPATCH`, `__init__.py` exports | +| sensitivity registry stance | `emitter_sensitivity.py` -> `DisjointDiscsEmitter`, `CERTIFICATE_SENSITIVE` + `NEG_CONTROL_ADAPTER` | +| two-sided kernel negative control | `telperion/src/telperion/negctrl_adapters/adapter_disjoint_discs.py` | +| unit tests | `telperion/tests/test_emit_disjoint_discs.py` (8 tests) | +| example + drift gate | `telperion/examples/disjoint_discs/generate.py`, listed in `telperion.toml` as check `disjoint_discs` (group `quick`) | +| emitted island lib | `telperion/examples/quasicrystal/lean/OfflineDiscsInstances.lean` | +| CI job | `.github/workflows/telperion-lean-e2e.yml` -> `disjoint-discs-compiles` | + +**Certificate.** Gaussian-rational points `((re_i, im_i))` plus an explicit positive rational radius +`r`. The Layer-1 self-check is exact rational arithmetic, never a float: + +* pairwise STRICT separation `(2r)^2 < (re_i - re_j)^2 + (im_i - im_j)^2`; +* strict strip margins `0 < re_i - r` and `re_i + r < 1`. + +**Emitted Lean.** Per instance: the point defs, the concrete `Finset`, one disjointness theorem per +pair, one strip-containment theorem per point, and an assembly theorem whose statement is the +registry node's own conclusion with `S` instantiated to that `Finset` -- so the instance literally +witnesses the general lemma's existential at explicit data -- followed by a `statement_match` gate +`example` against the same type string. Squaring is what keeps the pair proof rational: after +`Complex.dist_eq`, `Complex.norm_def` and `Real.lt_sqrt` the square root is GONE before any +arithmetic happens, and `norm_num` finishes on rationals. No root is ever approximated. + +**Stance: `CERTIFICATE_SENSITIVE`, with an adapter.** The radius `r` is a supplied number that +appears in the statement AND is what the kernel arithmetic must clear, so inflating it produces a +theorem that is genuinely FALSE, not merely unprovable -- the discs really do intersect. That is a +falsifiable seam, so this kind gets a real Layer-2 control rather than a `not_applicable`. + +**Negative controls.** Refused at certify (Layer 1): an overlapping/touching pair `(2r)^2 >= dist^2`; +a radius reaching the strip boundary `r >= min(re, 1 - re)`; a point ON or outside the boundary +(`re = 0`, `re = 1`); a duplicate point; `r <= 0`; non-rational input. Kernel-rejected (Layer 2, +`adapter_disjoint_discs`, bypassing Layer 1 by minting the frozen dataclass by hand): two points +exactly `1/10` apart with a forged `r = 1/10`, so `(2r)^2 = 1/25` is four times the true +`dist^2 = 1/100`. Run against the quasicrystal env: + +``` +[DisjointDiscsEmitter] negative[kernel REJECTED the forged FALSE proof] | positive[TRUE twin compiled clean] +okay: True +``` + +The TRUE twin (same points, honest `r = 1/50`) compiles clean -- both bytes of truth, so the control +is valid and not a compile-error artefact. The adapter carries `abs_re_sub_le_dist` in its Lean +`prelude` (a two-line consequence of `Complex.abs_re_le_norm`) so it still runs against a bare +Mathlib env. + +### 2c. The instances + +`examples/disjoint_discs/generate.py` emits two, both at radius `1/50`: + +* `offline_discs_online_pair` -- two centre-line points (`re = 1/2`) at heights `7067/500` and + `10511/500`; +* `offline_discs_offline_bank` -- the E5-shaped case: those two PLUS a symmetric OFF-LINE pair + (`re = 2/5` and `re = 3/5`) at height `12505/500`. The off-line pair is `1/5` apart, the tight + constraint, and `(2r)^2 = 1/625 < 1/25`. + +15 theorems, byte-for-byte reproducible (`generate.py --check` is a `quick`-group manifest gate). +**The points are input.** Choosing heights that resemble familiar ordinates makes the instance look +like the object E5 wants to count; it asserts nothing about zeta. + +## 3. Guard output (verbatim, new lines only) + +Full run is `lake env lean AxiomGuardQC.lean` in `telperion/examples/quasicrystal/lean`; every +pre-existing line is unchanged; all 51 printed declarations carry the three standard axioms, 0 `sorryAx`. + +``` +'Quasicrystal.exists_pos_lower_bound_of_finset' depends on axioms: [propext, Classical.choice, Quot.sound] +'Quasicrystal.abs_re_sub_le_dist' depends on axioms: [propext, Classical.choice, Quot.sound] +'Quasicrystal.offline_disjoint_discs' depends on axioms: [propext, Classical.choice, Quot.sound] +'OfflineDiscsInstances.offline_discs_online_pair' depends on axioms: [propext, Classical.choice, Quot.sound] +'OfflineDiscsInstances.offline_discs_offline_bank' depends on axioms: [propext, Classical.choice, Quot.sound] +``` + +## 4. Registry + +`telperion mission link MM_offline_disjoint_discs --artifact ../../examples/quasicrystal/lean/OfflineDiscs.lean +--kind lean_module --via direct` and a `Stalled` attempt recorded in `attempts.jsonl` (the campaign +convention for "proved on a branch, GRANT after reconcile to main"). `telperion mission verify` +reports `verify [mirrormere]: OK`. **The node is NOT granted here** -- the grant gate belongs on +`main` after the reconcile, exactly as `MM_rect_trace_reading` and `MM_spectral_cooked_control` were +handled. Nothing was edited under `missions/` except through the CLI. + +## 5. What is NOT closed + +* The node is proved but still `open` in the registry pending the reconcile-then-grant. +* E5 itself is untouched. This is the isolation substrate only: no Rouche count, no winding number, + no argument-principle assembly is claimed. Wiring `offline_discs_offline_bank`-shaped disc banks + into `WindingCountEmitter` / `AnnulusCountEmitter` is the next joint, and it is not done. +* The general lemma gives SOME radius, not a good one (`min (ε₁/3) (ε₂/2)` is deliberately lossy). + If a downstream argument ever needs a near-optimal radius, the `disjoint_discs` instance shape -- + where the radius is chosen by hand and only checked -- is the place to put it. +* `conjecture1_proved = False`, unchanged. diff --git a/telperion/docs/MM_mm-recurrence-deficit_2026-09-18.md b/telperion/docs/MM_mm-recurrence-deficit_2026-09-18.md new file mode 100644 index 000000000..cc7f8c76c --- /dev/null +++ b/telperion/docs/MM_mm-recurrence-deficit_2026-09-18.md @@ -0,0 +1,247 @@ +# MM_recurrence_deficit_eq_excess — the Face 4 ⟷ Face 1 dictionary row, discharged + +> **`conjecture1_proved = False`.** What is proved below is a ONE-RELATION ring +> identity in `Real.exp` plus a two-factor positivity. It is a *dictionary row* +> between two finite instruments — the Bagchi recurrence clearance (Face 4) and +> the Bragg/Weil amplification excess (Face 1) — and says nothing about zeta. +> Certifying one recurrence instance is not progress toward RH; the UNIFORM +> Bagchi recurrence **is** RH and is untouched here. + +**Agent:** `mm-recurrence-deficit` (MIRRORMERE prover). +**Branch:** `mm/recurrence-deficit` (worktree `/Users/peterwmurphy/arda-mm-recurrence-deficit`), +base `origin/rh/million-turing`. **Not pushed; no PR.** +**Island:** `telperion/examples/zeta_zero_localization` (v4.32.0, shard `zzl_aux`), +`.lake` symlinked to the built cache at +`/Users/peterwmurphy/arda-million/telperion/examples/zeta_zero_localization/lean/.lake` +(and `zzl_aux/.lake` to the matching shard cache). No `lake exe cache get` was run. + +--- + +## 1. What was proved + +`telperion/examples/zeta_zero_localization/lean/RecurrenceDeficit.lean`, namespace +`Quasicrystal`, sorry-free: + +```lean +theorem recurrence_deficit_eq_excess : + recurrenceDeficit (1 / 10) = excess ∧ + ∀ δ : ℝ, 0 < δ → 0 < recurrenceDeficit δ +``` + +stated VERBATIM from the registry statement file +`telperion/missions/mirrormere/lean/Statements/MM_recurrence_deficit_eq_excess.lean` +(the grant gate's normalized containment check was pre-flighted in-session and +MATCHES). `excess` is verbatim island vocabulary (`BraggDefect.lean`: +`excess = Aoff - Aon = e^(1/10) + e^(-1/10) - 2`); `recurrenceDeficit` is AUTHORED +in the registry's vocabulary mirror `Statements/MMDefs.lean` (lines 61–62) and is +mirrored into the artifact **byte-identically**, in the same namespace +`Quasicrystal`, as the `rvm_bridge` `E6Bridge*.lean` modules do (verified in-session +by substring equality against MMDefs, so a drift would be caught before the gate). + +A companion, explicitly NOT a registry node (QC_RECURRENCE §4 item 2 names it): + +```lean +theorem recurrence_deficit_sq_eq_abs_defect : + recurrenceDeficit (1 / 10) ^ 2 = |defectFunctional excess| +``` + +— the second-order (Weil-energy) reading of the same row: the squared *linear* +clearance is the magnitude of the *quadratic* defect witness. + +### The mathematics, stated plainly + +For displacement `δ` the two one-sided clearances of the modelled off-line pair are +`g₊(δ) = e^δ − 1` (outer mirror factor) and `g₋(δ) = 1 − e^(−δ)` (inner +transported-zero factor). Their PRODUCT telescopes against the single relation +`e^δ · e^(−δ) = 1`: + +``` +(e^δ − 1)(1 − e^(−δ)) = e^δ + e^(−δ) − 1 − e^δ e^(−δ) = e^δ + e^(−δ) − 2 . +``` + +At `δ = 1/10` the right side is exactly `BraggDefect.excess` +(`0.01000833611160719797…`, re-checked numerically against the memo). Positivity is +the product of two strictly positive factors (`Real.one_lt_exp_iff`, +`Real.exp_lt_one_iff`). + +**Adversarial note (kept from the brief, and endorsed):** the content is one ring +relation. It is legitimately a lemma and a legitimate dictionary row; it is *not* +evidence, and must not be sold as more. The memo's own §4 item 2 grades it exactly +this way ("kernel-ready now"), and its §4 item 5 marks the RH-hard wall it does not +approach. + +--- + +## 2. The new certificate kind — `exp_laurent_identity` + +The brief flagged this shape as lacking a certificate type. It now has one, built +and dogfooded here rather than hand-written. + +**Emitter:** `telperion/src/telperion/emit_exp_laurent_identity.py` +(`ExpLaurentIdentityEmitter`, kind `exp_laurent_identity`). + +**The shape.** Many "exp bookkeeping" rows in this corpus are Laurent polynomials +in the single transcendental `y = e^d` with `z = e^(−d)` its formal inverse: +amplitude sums `y + z` (a `2 cosh` channel), one-sided clearances `y − 1`, `1 − z`, +their products and squares. Every TRUE identity among them is a polynomial identity +in `ℚ[y, z]` modulo the one relation `y·z − 1`; every FALSE one leaves a nonzero +remainder. + +``` +claim lhs = rhs +certify lhs − rhs = cofactor · (y·z − 1) in ℚ[y, z] (sympy, exact; re-multiplied and re-checked) +emit have hrel : Real.exp d * Real.exp (-d) = 1 := by rw [← Real.exp_add]; norm_num + linear_combination (cofactor : ℝ) * hrel +``` + +The **cofactor is the load-bearing certificate**: `linear_combination` re-derives +the goal from it by `ring`, so a corrupted cofactor — or a corrupted side — leaves +a residue the kernel will not close. Stance declared in +`emitter_sensitivity.REGISTRY` as `CERTIFICATE_SENSITIVE` with +`NEG_CONTROL_ADAPTER`. + +**Two Layer-1 refusals** (both unit-tested, both re-run by the generator before it +writes anything): + +1. **Non-identity** — nonzero remainder. The motivating instance is the mistake + QC_RECURRENCE §6 caught in ITSELF and corrected: the clearances' **SUM**, + `(e^d − 1) + (1 − e^(−d)) = 2d + O(d³)`, is **not** the excess; only the product + is. Residue `2 − 2e^(−d)`; REFUSED. +2. **Relation not load-bearing** — cofactor `0`, i.e. the claim never uses + `e^d · e^(−d) = 1`. That is an ordinary ring identity and belongs to + `IdentityEmitter`; emitting it here would advertise a certificate carrying no + information. REFUSED. + +Plus two contract refusals (symbols outside the two generators; a non-polynomial +side). + +**Negative control (kernel-gated, two-sided).** +`telperion/src/telperion/negctrl_adapters/adapter_exp_laurent_identity.py` forges the +SUM-for-PRODUCT twin *while keeping the true row's cofactor* `−1`, bypassing Layer 1 +so that Layer 2 decides. Run in-session against the built v4.32 env: + +``` +[ExpLaurentIdentityEmitter] negative[kernel REJECTED the forged FALSE proof] | positive[TRUE twin compiled clean] +kernel_rejects: True true_compiles: True okay: True +``` + +It is picked up automatically by the existing parametrized gate +`tests/test_certificate_sensitivity.py::test_generic_negative_control_holds`. + +**Generator / drift gate.** `telperion/examples/exp_laurent_deficit/generate.py` +emits both rows INTO the zzl island as +`examples/zeta_zero_localization/lean/ExpLaurentDeficit.lean` (same toolchain pin, +same `zzl_aux` lakefile, next to its consumer). It is listed in `telperion.toml` as +`[[check]] name = "exp_laurent_deficit"`, group `quick` +(`telperion verify` manifest-completeness: green; `--check` drift: byte-for-byte +green). Emitted theorems: + +```lean +theorem expLaurent_recurrence_deficit (d : ℝ) : + (Real.exp d - 1) * (1 - Real.exp (-d)) = Real.exp d + Real.exp (-d) - 2 +theorem expLaurent_recurrence_deficit_sq (d : ℝ) : + (Real.exp d - 1) ^ 2 * (1 - Real.exp (-d)) ^ 2 = (Real.exp d + Real.exp (-d) - 2) ^ 2 +``` + +`RecurrenceDeficit.lean` consumes the first one at `δ = 1/10` after unfolding +`recurrenceDeficit`, `excess`, `Aoff`, `Aon` — so the node's algebraic core is the +emitted certificate, not hand-rolled tactics. + +Renderer note (a real footgun, handled): sympy canonicalizes `Mul`/`Add` argument +order and Lean multiplication is **not** definitionally commutative, so the emitter +reassembles each side in a fixed channel order (`e^d` before `e^(−d)` before +constants). Without that, the emitted statement would read +`(1 − e^(−d)) * (e^d − 1)` and the consumer's `exact` would fail. + +--- + +## 3. Island wiring and the guard + +* `zzl_aux/lakefile.toml`: `ExpLaurentDeficit` and `RecurrenceDeficit` added as + `lean_lib`s and to `defaultTargets`. +* `AxiomGuardBragg.lean`: imports both modules, documents the new anchors, and adds + four `#print axioms` lines. CI already runs this guard after `lake build` in + `telperion-lean-e2e.yml` (the `for g in AxiomGuardBragg AxiomGuardDefect + AxiomGuardZoo` loop), so no workflow change was needed. +* `lake build` in `zzl_aux`: `Build completed successfully (8775 jobs)`. + +Guard output (verbatim, run exactly as CI runs it): + +``` +== AxiomGuardBragg +'CosEnclosure.cos_base' depends on axioms: [propext, Classical.choice, Quot.sound] +'CosEnclosure.cos_base_interval' depends on axioms: [propext, Classical.choice, Quot.sound] +'CosEnclosure.cos_step' depends on axioms: [propext, Classical.choice, Quot.sound] +'CosEnclosure.cos_double_interval' depends on axioms: [propext, Classical.choice, Quot.sound] +'CosEnclosure.cos_encl' depends on axioms: [propext, Classical.choice, Quot.sound] +'CosEnclosure.cos_encl_bracket' depends on axioms: [propext, Classical.choice, Quot.sound] +'CosEnclosure.add_encl' depends on axioms: [propext, Classical.choice, Quot.sound] +'RHInBoxCore.support_eq_witnesses' depends on axioms: [propext, Classical.choice, Quot.sound] +'RHInBoxCore.sum_over_box_zeros_eq' depends on axioms: [propext, Classical.choice, Quot.sound] +'BraggSupport.sum_cos_over_zero_support_eq' depends on axioms: [propext, Classical.choice, Quot.sound] +'ExpLaurentDeficit.expLaurent_recurrence_deficit' depends on axioms: [propext, Classical.choice, Quot.sound] +'ExpLaurentDeficit.expLaurent_recurrence_deficit_sq' depends on axioms: [propext, Classical.choice, Quot.sound] +'Quasicrystal.recurrence_deficit_eq_excess' depends on axioms: [propext, Classical.choice, Quot.sound] +'Quasicrystal.recurrence_deficit_sq_eq_abs_defect' depends on axioms: [propext, Classical.choice, Quot.sound] +'BraggH100.bragg_amplitude_h100' depends on axioms: [propext, Classical.choice, Quot.sound] +'BraggH100.bragg_amplitude_h100_complete' depends on axioms: [propext, Classical.choice, Quot.sound] +``` + +No `sorryAx`, no `ofReduceBool`, no `error:`. + + +### Python test status + +`pytest tests` (full suite, 39m): **2224 passed, 109 skipped, 14 failed**. Every +failure is in `tests/test_rhinbox.py` / `tests/test_zeroloc_end_to_end.py` and is +ENVIRONMENTAL, not a regression: those tests call `lake exe cache get` inside the +zzl island, which in this worktree has its `.lake` symlinked to the shared built +cache whose mathlib `cache` executable is not built +(`could not execute external process .../mathlib/.lake/build/bin/cache`, exit 255). +They touch nothing this change introduces. The gates that DO cover this work all +pass: `tests/test_emit_exp_laurent_identity.py` (9 tests), +`tests/test_certificate_sensitivity.py` (including the parametrized kernel-gated +`test_generic_negative_control_holds`), `tests/test_emitter_registry.py`, +`tests/test_missions_registry.py`, and `telperion verify` (manifest completeness + +the new `--check` drift gate). + +--- + +## 4. Registry + +Through the mission CLI only (no hand edits under `telperion/missions/`): + +* `mission link MM_recurrence_deficit_eq_excess --artifact + ../../examples/zeta_zero_localization/lean/RecurrenceDeficit.lean --kind lean_module + --via direct` — recorded; **status unchanged (`open`)**. +* `mission attempt … --verdict Proved` — ledger row appended to + `missions/mirrormere/attempts.jsonl`. +* `mission verify mirrormere` — `verify [mirrormere]: OK`. +* **`mission grant` NOT run.** Per `mission.toml` design §9 the artifact lives on + the `rh/million-turing` line, and grants are deferred to the branch reconcile — + the same discipline the `MM_bragg_defect_witness` and `MM_offline_pairs_le_defect` + ledger rows record. The gate's containment check was pre-flighted and passes, so + the grant is a mechanical step at reconcile time. + +--- + +## 5. What is NOT claimed + +* No RH progress. `conjecture1_proved = False`. +* The node is a dictionary row between two *finite, synthetic* instruments: the + `BraggDefect` configuration is a planted off-line pair, not a zero of ζ. +* The `ε₀ = d` identification is exact only for the rank-1 pair-block model of + QC_RECURRENCE §2 row (a); the conversion of the dimensionless deficit into a + genuine `sup_K |ζ(·+iτ) − ζ|` tolerance is leading-order in `|ζ′|` and remains + open (memo §4 item 4), as does the disjoint-disc/deficit-count row (§4 item 3). +* The new emitter certifies *identities*, not positivity; the strict-positivity leg + of the node is proved directly (`mul_pos` over the two clearances) and is not a + certificate shape. + +## 6. Follow-on the new kind unlocks (not done here) + +`exp_laurent_identity` is the natural certifier for the rest of the `2 cosh` +bookkeeping on this island — `Aoff`/`Aon` channel algebra, the `defect_eq_two` +two-channel excesses `d₁, d₂`, and any future `e^{kδ}` ladder rows — each of which +is currently hand-written or inline. Migrating those to the emitter would put the +same kernel-gated cofactor control under all of them. diff --git a/telperion/docs/MM_mm-torus-ladder-t1_2026-09-18.md b/telperion/docs/MM_mm-torus-ladder-t1_2026-09-18.md new file mode 100644 index 000000000..b34bbfdd5 --- /dev/null +++ b/telperion/docs/MM_mm-torus-ladder-t1_2026-09-18.md @@ -0,0 +1,127 @@ +# MM torus-section ladder T1 -- MM_torus_section_dictionary + MM_torus_section_n2_rigidity + +Session `mm-torus-ladder-t1-2026-09-18`. Branch `mm/torus-ladder-t1` (base +`origin/rh/million-turing`). Island: `telperion/examples/quasicrystal` (Lean +v4.32.0, Mathlib v4.32.0). + +**conjecture1_proved = False.** No RH progress is claimed here, and neither of the +two nodes below is counted as a win -- see the grade section. + +## 1. What was delivered + +One new artifact, `telperion/examples/quasicrystal/lean/TorusSectionLadder.lean`, +sorry-free, registered as a `lean_lib` and a `defaultTarget`, guarded in +`AxiomGuardQC.lean`. It contains: + +| Theorem | Registry node | Route | +|---|---|---| +| `Quasicrystal.torus_section_dictionary` | `MM_torus_section_dictionary` (draft) | `simp [twoFreq, linearTorusForm, torusOrbit, Fin.sum_univ_two]` | +| `Quasicrystal.torus_section_n2_rigidity` | `MM_torus_section_n2_rigidity` (open) | `simp only [<- torus_section_dictionary]; exact twoFreq_realRooted_iff ...` | +| `Quasicrystal.expSum_eq_linearTorusForm_torusOrbit` | (none -- vocabulary anchor only) | `rfl` | + +Both node theorems are stated VERBATIM from the registry statement files +`telperion/missions/mirrormere/lean/Statements/MM_torus_section_{dictionary,n2_rigidity}.lean` +(same names, same binder lists). The three ladder definitions (`torusOrbit`, +`linearTorusForm`, `expSum`) are MIRRORED verbatim from `MMDefs.lean:69-76` into the +module's own `Quasicrystal` namespace, following the `E6Bridge.lean` precedent, so +the registry's normalized-containment grant gate matches the artifact. + +The general-N identity `expSum = linearTorusForm on torusOrbit` is recorded as +`rfl` -- exactly the zero-content statement the 2026-09-14 blind audit flagged. It +is kept as an explicit vocabulary anchor and is deliberately NOT a node. + +## 2. Grade (adversarial verdict, recorded rather than hidden) + +Both nodes are **simp-grade vocabulary bridges, not mathematics**: + +- The dictionary is a Fin-2 sum unfolding across two vocabularies. The audit's + "non-rfl" note is technically correct (it is not definitional -- `Fin.sum_univ_two` + plus `Matrix.cons_val_zero`/`cons_val_one` fire), but `simp` closes it in one line. +- `torus_section_n2_rigidity` is a one-line rewrite into the island's already-proved + `twoFreq_realRooted_iff` (`TwoFreqRigidity.lean:92-94`). All mathematical content + lives there. Its registry `kind = "milestone"` is **inflated**: it is a lemma. + +They are delivered because the ladder's vocabulary needs them and the registry +consumes them (the T1 track of `QC_TORUS_SECTION_LADDER_MEMO_2026-09-14`, sections +5-6), not because they advance anything. Both attempts are logged in +`attempts.jsonl` with that verdict written out. + +## 3. Registry actions taken (and deliberately not taken) + +- `telperion mission link` recorded on BOTH nodes: artifact + `../../examples/quasicrystal/lean/TorusSectionLadder.lean`, kind `lean_module`, + via `direct`. `set_proof` does not gate on status, so the draft node accepts the + link. +- `telperion mission attempt` recorded for both (verdict `Proved`, with the + simp-grade verdict spelled out in the detail field). +- **No grant.** Two independent blocks: + 1. `MM_torus_section_dictionary` is still `draft` (its statement was REVISED after + the 2026-09-14 audit refuted the original general-N form); `grant_status` + refuses any node whose status is not `open`. The re-audit is the author item + `mm-dictionary-reaudit` and must land first. + 2. The artifact lives on the climb branch while the registry lives on `main`, so + the grant is deferred to the branch reconcile, matching every other + climb-linked MIRRORMERE node (e.g. `MM_twofreq_realrooted_iff`). +- The containment gate was nevertheless dry-run offline against the artifact for + both nodes: `stmt_in_artifact = True` in each case, so the grant is a formality + once status and branch allow it. + +## 4. Telperion certificate-kind verdict + +No new emitter kind was built, and none is missing for this shape. The shape here is +"a variable-map / reparametrization between two vocabularies over an underlying +certificate", which the registry already classifies: +`VarMapAdapterEmitter` (MapSpec-driven substitution rewrite, `STRUCTURALLY_NONVACUOUS`, +"no new identity") and `ReparamAdapterEmitter` (cast-rewrite adapter, +`STRUCTURALLY_NONVACUOUS`, "no new identity"). Both stances say in as many words +what this bridge is: structural, carrying no independent identity. Staffing a +generator to emit a single one-line `simp` lemma would manufacture ceremony, not +verification. + +The certificate-bearing neighbour already exists and is untouched: +`SelfInversiveRigidityEmitter` (`examples/selfinversive_rigidity/generate.py`) emits +exact equal-modulus rigidity INSTANCES against `twoFreq_realRooted_iff`, and its +drift gate is green (`check: OK (regeneration matches frozen output byte-for-byte)`). +The concrete future hook, if the ladder ever needs it: point that emitter's profile +at `torus_section_n2_rigidity` instead, which is exactly a `VarMapAdapter` over the +existing family -- no new kind, a target swap. + +## 5. Build and guard evidence + +`lake build` (all defaultTargets, island): `Build completed successfully (3116 jobs).` +`lake build TorusSectionLadder`: `Built TorusSectionLadder`, clean on first pass. +`lake env lean AxiomGuardQC.lean`: 45 theorems printed, zero `sorryAx`, zero +`ofReduceBool`. The three new lines: + +``` +'Quasicrystal.expSum_eq_linearTorusForm_torusOrbit' depends on axioms: [propext, Classical.choice, Quot.sound] +'Quasicrystal.torus_section_dictionary' depends on axioms: [propext, Classical.choice, Quot.sound] +'Quasicrystal.torus_section_n2_rigidity' depends on axioms: [propext, Classical.choice, Quot.sound] +``` + +## 6. Notes for the next hand + +- **COLLISION, must be resolved at reconcile.** `TorusSectionLadder.lean` was + assigned to BOTH this item and `mm-euler-factor-offline` (the T2 negative control, + memo section 4b), and the two were executed in parallel in separate worktrees. + The sibling's version of the same path declares `namespace TorusSectionLadder` and + carries `euler_factor_section_offline` + witnesses (observed in a guard run against + the SHARED `.lake` at `~/arda-million/.../quasicrystal/lean/.lake`, which both + islands symlink); this version declares `namespace Quasicrystal` and carries the T1 + bridges. The two branches therefore conflict on this file and on the same + `lean_lib` name, and while both are live they clobber each other's olean in the + shared build cache. Resolution is a straight union -- the file already imports + `TwoFreqRigidity` and carries the ladder vocabulary, so the T2 rung appends with no + new lakefile plumbing beyond its `#print axioms` lines -- but the namespaces must be + reconciled first (the registry statements for T1 are `open Quasicrystal`, so the T1 + theorems must stay resolvable as `Quasicrystal.torus_section_*`). My guard output + below was re-run after a clean rebuild of MY source to make sure it reflects this + branch and not the sibling's cached olean. +- The v4.32 simp spellings did fire as predicted (`Matrix.cons_val_zero`, + `Matrix.cons_val_one`, `Matrix.head_cons` are reached through the default simp set + via `Fin.sum_univ_two`); the risk flagged in the work item did not materialize. +- CI: the island is built by the `selfinversive-rigidity-compiles` job, which runs + `lake build SelfInversiveRigidityInstances` only. Adding `TorusSectionLadder` to + `defaultTargets` does not put it in that job's path; a reconcile PR should either + widen that step to a bare `lake build` or add a guard step. Flagged, not done here + (CI edits are out of this item's scope). diff --git a/telperion/docs/NEW_EMITTERS_SUMMARY.md b/telperion/docs/NEW_EMITTERS_SUMMARY.md index 2a65fcafe..89270beeb 100644 --- a/telperion/docs/NEW_EMITTERS_SUMMARY.md +++ b/telperion/docs/NEW_EMITTERS_SUMMARY.md @@ -91,6 +91,11 @@ Grouped by the front that motivated them. All kernel-green (local `lake build`), | `CurvatureBoundaryEmitter` | `curvature_boundary` | a function with definite `f''` sign has its extremum at the boundary (concave→min, convex→max, affine→endpoints) — ports their `extremalG_const`, generalizes `affine_param_endpoint`, covers the BG concave-corner case | interval-aware curvature check | | `TranscendentalEnclosureEmitter` | `transcendental_enclosure` | rational `L ≤ expr ≤ U` over a box — **log face** (`log(1+x)`, discharges the BG per-cell `log(1+S/d)`); Montgomery–Taylor `C₀` trig face deferred/refused | | +### MIRRORMERE exp seam (2026-09-18) +| Emitter | kind | Certifies | Scope note | +|---|---|---|---| +| `ExpEnclosureEmitter` | `exp_enclosure` | rational brackets of `Real.exp x` (`|x| ≤ 1`) from `Real.exp_bound`'s exact order-`n` Taylor box — plus the `exp_neg`, **deficit** (`e^x + e^{-x} - 2`) and `cosh` faces; the exp face that `transcendental_enclosure` (log only) and `log_combination` (internal degree-3 step) never exposed as a standalone certificate | **dogfooded**: discharges the Arb `hexp` of `BraggDefect.bragg_defect_witness` (→ `bragg_defect_witness_unconditional`, MM_bragg_defect_witness) and reproduces the `excess_bracket` / `ZooDH.cosh_bracket` constants. A finite arithmetic fact; conjecture1_proved = False | + ### F\*-fold (cross-front dogfood) | Emitter | kind | Certifies | Scope note | |---|---|---|---| diff --git a/telperion/docs/SECOND_PASS_EMITTER_CATALOG.md b/telperion/docs/SECOND_PASS_EMITTER_CATALOG.md index 389fcda71..638142502 100644 --- a/telperion/docs/SECOND_PASS_EMITTER_CATALOG.md +++ b/telperion/docs/SECOND_PASS_EMITTER_CATALOG.md @@ -153,3 +153,32 @@ generator-producible / kernel-checkable certificate boundary. autocorrelation pairing is what RH PREDICTS; Weil positivity over EVERY admissible test function is RH-equivalent and no finite family approaches "every". Arb is a non-kernel trust seam. `conjecture1_proved = False`. +## Addendum 2026-09-18 -- shape BUILT, not just catalogued + +### `DisjointDiscs` -- finite point bank -> explicit pairwise-disjoint discs inside the open strip +- **Source:** MIRRORMERE node `MM_offline_disjoint_discs` / `QC_RECURRENCE_MEMO.md` section 4.3; + general lemma in `examples/quasicrystal/lean/OfflineDiscs.lean`. +- **Shape:** Gaussian-rational strip points + an explicit rational radius `r` ⟹ kernel proves each + pair `Disjoint (closedBall z r) (closedBall w r)` from `(2r)^2 < dist^2` (square root eliminated + by `Real.lt_sqrt` BEFORE any arithmetic, so the goal is pure rational `norm_num`) and each disc + `⊆ {0 < re < 1}` from the 1-Lipschitz `abs_re_sub_le_dist`; assembly restates the registry node's + existential at the concrete `Finset`. +- **Negative control:** an inflated `r` makes a pair theorem genuinely FALSE, so the kernel rejects + it -- a real Layer-2 seam (`negctrl_adapters/adapter_disjoint_discs.py`, two-sided, passing). + Layer 1 also refuses boundary-reaching radii, off-strip points, duplicates and `r <= 0`. +- **Status:** BUILT (kind `disjoint_discs`, `DisjointDiscsEmitter`). Distinct from + `TwoScaleSeparation` (one centre, two radii, no containment) and from `SpacingTailBound` (1-D + separated support, inverse-power sums). The consumer joint -- feeding a certified disc bank into + `WindingCountEmitter` / `AnnulusCountEmitter` for the E5 Rouche count -- is NOT built. +- conjecture1_proved = False. +## Addendum 2026-09-18 -- MIRRORMERE ladder rung T2 +- `twofreq_offline` (`TwoFreqOfflineEmitter`) -- certified OFF-line displacement of a + two-frequency section: `|c1|^2 != |c2|^2` EXACTLY refutes real-rootedness via + `TwoFreqRigidity.twoFreq_realRooted_iff`, and for the Euler-factor family + `1 - p^(-s)` on `s = 1/2 + i x` it also certifies `Im x = 1/2` for EVERY zero. + The exact COMPLEMENT of `selfinversive_rigidity`: the two partition the coefficient + space, each refusing the other's regime. Adds irrational coefficient literals + (`inv_sqrt`, `real_sqrt`) and the `-(Real.log p)` frequency literal, which the + Gaussian-rational-only rigidity emitter cannot express. Kernel-gated negative-control + adapter (equal-modulus forgery). Full write-up: `EMITTER_MIRRORMERE_2026-09-18.md`. + conjecture1_proved = False. diff --git a/telperion/examples/disjoint_discs/generate.py b/telperion/examples/disjoint_discs/generate.py new file mode 100644 index 000000000..4f56be778 --- /dev/null +++ b/telperion/examples/disjoint_discs/generate.py @@ -0,0 +1,85 @@ +"""Generate the disjoint-discs example: certify -> emit -> write INTO the quasicrystal island. + + python examples/disjoint_discs/generate.py # write the island lib + python examples/disjoint_discs/generate.py --check # drift check (no write) + +The general MIRRORMERE E4b isolation lemma (registry node ``MM_offline_disjoint_discs``) is proved +in the island's ``OfflineDiscs.lean``: SOME positive radius always works. What the Rouche/E5 leg +consumes is the INSTANCE -- explicit strip points plus an EXPLICIT rational radius -- and that is +this example, emitted through the ``disjoint_discs`` kind (``DisjointDiscsEmitter``). + +Because the emitted strip-containment proofs call the in-island lemma +``Quasicrystal.abs_re_sub_le_dist``, the instances are written as a NEW lib inside the quasicrystal +island (``OfflineDiscsInstances.lean``, registered in its lakefile), exactly as the sibling +``selfinversive_rigidity`` example does, and the ``disjoint-discs-compiles`` CI job builds it there. + +Two instances: + - ``offline_discs_online_pair`` -- two centre-line points (re = 1/2) at heights 7067/500 and + 10511/500, radius 1/50. + - ``offline_discs_offline_bank`` -- the E5-shaped case: the same two centre-line points PLUS a + symmetric OFF-LINE pair (re = 2/5 and re = 3/5) at height 12505/500, radius 1/50; the off-line + pair is 1/5 apart, so a radius-1/50 disc bank isolates all four. + +THE POINTS ARE INPUT, not output: nothing here asserts that zeta vanishes at any of them. The +heights merely make the instance look like the object E5 wants to count. conjecture1_proved = False. +""" +import argparse +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "src")) + +from telperion import ( # noqa: E402 + DisjointDiscsEmitter, ValidationReport, certify, emit, +) +from telperion.emit_disjoint_discs import disjoint_discs_family # noqa: E402 +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 + +_ON_LINE = [("1/2", "7067/500"), ("1/2", "10511/500")] +_OFF_LINE_BANK = _ON_LINE + [("2/5", "12505/500"), ("3/5", "12505/500")] + +_SPECS = { + 0: {"points": _ON_LINE, "r": "1/50"}, + 1: {"points": _OFF_LINE_BANK, "r": "1/50"}, +} +_NAMES = {0: "offline_discs_online_pair", 1: "offline_discs_offline_bank"} +# Emitted INTO the quasicrystal island (which carries the OfflineDiscs olean cache). +_ISLAND = Path(__file__).resolve().parents[1] / "quasicrystal" / "lean" +_OUT = _ISLAND / "OfflineDiscsInstances.lean" + + +def build() -> str: + fam = disjoint_discs_family( + "OfflineDiscsInstances", + GridSpec([("case", [0, 1])]), + lambda pt: _NAMES[pt["case"]], + spec=lambda pt: _SPECS[pt["case"]], + ) + report = emit( + certify(fam), + LeanProfile(namespace=("OfflineDiscsInstances",), + imports=("Mathlib", "OfflineDiscs")), + [DisjointDiscsEmitter()], + ValidationReport(checks=(("disjoint_discs", True),)), + ) + return next(iter(report.files.values())) + + +def main(*, check: bool = False) -> int: + text = build() + if check: + if not _OUT.exists() or _OUT.read_text(encoding="utf-8") != text: + print("DRIFT: OfflineDiscsInstances.lean does not match regeneration") + return 1 + print("check: OK (regeneration matches frozen output byte-for-byte)") + return 0 + _OUT.write_text(text, encoding="utf-8") + print(f"wrote {_OUT} ({len(text)} bytes)") + return 0 + + +if __name__ == "__main__": + ap = argparse.ArgumentParser() + ap.add_argument("--check", action="store_true", help="drift check; do not write") + raise SystemExit(main(check=ap.parse_args().check)) diff --git a/telperion/examples/exp_enclosure/generate.py b/telperion/examples/exp_enclosure/generate.py new file mode 100644 index 000000000..cce896ba9 --- /dev/null +++ b/telperion/examples/exp_enclosure/generate.py @@ -0,0 +1,242 @@ +"""Generate the exp-enclosure example: certify -> emit -> write INTO the zeta island. + + python examples/exp_enclosure/generate.py # write the island lib + python examples/exp_enclosure/generate.py --check # drift check (no write) + +WHAT THIS DOGFOODS +------------------ +Four certified rational enclosures, all from Mathlib's `Real.exp_bound`, each one the exact +numeric seam some MIRRORMERE artifact currently carries as an Arb hypothesis or an ad-hoc +local bracket: + + (i) `exp_tenth_bracket` -- `expLo <= e^(1/10) <= expHi` with BraggDefect's OWN 40-digit + literals, READ VERBATIM out of `BraggDefect.lean` at generation time (so a drift in the + driver that produced those literals breaks `--check` here, not silently downstream). + This discharges the `hexp` hypothesis of `BraggDefect.bragg_defect_witness`, and the + hand-written bridge below states the MIRRORMERE node's witness UNCONDITIONALLY. + (ii) `deficit_tenth_bracket` -- `e^(1/10) + e^(-1/10) - 2` bracketed by BraggDefect's own + `excess_bracket` constants (QC_RECURRENCE row a; the numeric twin of + MM_recurrence_deficit_eq_excess). + (iii) `deficit_fifth_bracket` -- the same deficit at `d = 1/5`, `defect_eq_two`'s second + synthetic channel. + (iv) `cosh_zoodh_bracket` -- `cosh (21487557/100000000)` with ZooDH's own order-6 + bracket constants, read verbatim out of `ZooDH.lean`. + +The lib is emitted INTO the `zeta_zero_localization` island (as `BraggAmplitudeInstances` is), +because the bridge imports `BraggDefect`; the `exp-enclosure-compiles` CI job builds it in +`zzl_aux`. + +conjecture1_proved = False -- rational enclosures of transcendental constants at four rational +points, plus one hypothesis discharge. Nothing about RH. +""" +import argparse +import re +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "src")) + +import sympy as sp # noqa: E402 + +from telperion import ( # noqa: E402 + ExpEnclosureEmitter, ValidationReport, certify, emit, +) +from telperion.emit_exp_enclosure import exp_enclosure_family # noqa: E402 +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 + +_ISLAND = Path(__file__).resolve().parents[1] / "zeta_zero_localization" / "lean" +_OUT = _ISLAND / "ExpEnclosureInstances.lean" +_BRAGG_DEFECT = _ISLAND / "BraggDefect.lean" +_ZOODH = _ISLAND / "ZooDH.lean" + +# --- literals that MUST match the island sources verbatim (asserted at generate time) ------ + +# BraggDefect.lean:68-69 -- the Arb enclosure of e^(1/10) carried by `hexp`. +_EXP_LO = sp.Rational(442068367230259049924676660787771898883, + 400000000000000000000000000000000000000) +_EXP_HI = sp.Rational(11051709180756476248117094953514706601127, + 10000000000000000000000000000000000000000) +# BraggDefect.excess_bracket -- the bracket of excess = e^(1/10) + e^(-1/10) - 2. +_D_LO = sp.Rational( + 44243688035498337190547890814412959087189025996450853896963629856431657841141, + 4420683672302590499246837981405882640450800000000000000000000000000000000000000) +_D_HI = sp.Rational( + 44243688035498337190690637870740262328789025996450853896963629856431657841141, + 4420683672302590499246766607877718988830000000000000000000000000000000000000000) +# ZooDH.lean -- the order-6 cosh bracket used by the off-line DH diffraction term at u2. +_COSH_X = sp.Rational(21487557, 100000000) +_COSH_LO = sp.Rational(511587210574920885840517, 500000000000000000000000) +_COSH_HI = sp.Rational(511587370066054060481853, 500000000000000000000000) +# defect_eq_two's second channel d = 1/5 (no island constants exist for it; these are the +# generator's own claim, a plain 21-decimal bracket that the Taylor box must imply). +_D5_LO = sp.Rational(40133511238151692591, 10 ** 21) +_D5_HI = sp.Rational(401335112381516925911, 10 ** 22) + +# The off-line bracket constants of `BraggDefect.bragg_defect_witness` are NOT pinned here as +# hand-typed numerals (a truncated pin would still substring-match the source); they are +# EXTRACTED from BraggDefect.lean at generate time by `_island_offline_bracket()` below and +# rendered into the bridge, so the bridge cannot drift from the island statement it applies. + +_CASES = { + 0: ("exp_tenth_bracket", {"x": sp.Rational(1, 10), "lo": _EXP_LO, "hi": _EXP_HI, + "mode": "exp"}), + 1: ("deficit_tenth_bracket", {"x": sp.Rational(1, 10), "lo": _D_LO, "hi": _D_HI, + "mode": "deficit"}), + 2: ("deficit_fifth_bracket", {"x": sp.Rational(1, 5), "lo": _D5_LO, "hi": _D5_HI, + "mode": "deficit"}), + 3: ("cosh_zoodh_bracket", {"x": _COSH_X, "lo": _COSH_LO, "hi": _COSH_HI, + "mode": "cosh"}), +} + + +def _one_rational(src: str, pattern: str, what: str) -> sp.Rational: + """Extract exactly one ` / ` literal matched by `pattern` from `src`.""" + hits = re.findall(pattern, src) + if len(hits) != 1: + raise SystemExit(f"DRIFT: expected exactly one {what} literal, found {len(hits)}") + p, q = hits[0] + return sp.Rational(int(p), int(q)) + + +def _island_offline_bracket() -> tuple[str, str]: + """The two off-line defect constants, read VERBATIM out of `bragg_defect_witness`. + + Returned as source text (not parsed rationals) so the bridge reproduces the island + statement numeral-for-numeral; a drift in BraggDefect.lean changes these bytes and the + `--check` gate fires here rather than at CI build time.""" + bd = _BRAGG_DEFECT.read_text(encoding="utf-8") + start = bd.index("theorem bragg_defect_witness") + body = bd[start:bd.index("defect_leakage_gap", start)] + hits = re.findall(r"\(-(\d+) / (\d+) : ℝ\)", body) + if len(hits) != 2: + raise SystemExit( + f"DRIFT: bragg_defect_witness no longer carries exactly two negative rational " + f"literals (found {len(hits)})") + return tuple(f"-{p} / {q}" for p, q in hits) # type: ignore[return-value] + + +def _assert_island_literals() -> None: + """The instances quote island literals; pin them EXACTLY so driver drift breaks --check + HERE. Every comparison is on the parsed rational (not a substring), so a truncated or + extended numeral cannot slip through.""" + bd = _BRAGG_DEFECT.read_text(encoding="utf-8") + for name, q in (("expLo", _EXP_LO), ("expHi", _EXP_HI)): + got = _one_rational( + bd, rf"noncomputable def {name} : ℝ := \((\d+) / (\d+) : ℝ\)", f"BraggDefect.{name}") + if got != q: + raise SystemExit( + f"DRIFT: BraggDefect.{name} is {got}, the certified bracket uses {q}") + ex_start = bd.index("theorem excess_bracket") + ex_body = bd[ex_start:bd.index("theorem defect_witness_offline", ex_start)] + ex_hits = [sp.Rational(int(p), int(q)) for p, q in re.findall(r"\((\d+) / (\d+) : ℝ\)", ex_body)] + for label, q in (("excess_bracket lower", _D_LO), ("excess_bracket upper", _D_HI)): + if q not in ex_hits: + raise SystemExit( + f"DRIFT: BraggDefect.excess_bracket no longer carries the {label} constant {q}") + zd = _ZOODH.read_text(encoding="utf-8") + for label, q in (("cosh lower", _COSH_LO), ("cosh upper", _COSH_HI)): + if f"({q.p} / {q.q} : ℝ)" not in zd: + raise SystemExit( + f"DRIFT: ZooDH.lean no longer carries the {label} constant {q.p}/{q.q}") + + +def _bridge() -> str: + """The hand-written bridge: BraggDefect's vocabulary, then the UNCONDITIONAL witness. + + Five lines of real content. `exp_tenth_bracket` is the emitted certificate; `expLo`/`expHi` + are definitionally those literals, so unfolding them turns the certificate into exactly the + `hexp` the MIRRORMERE artifact assumes -- and `bragg_defect_witness` then applies with no + hypothesis left. The hypothesis-carrying form is kept (and gated by the `example` below) + because the registry's grant gate matches the node statement syntactically. + """ + off_lo, off_hi = _island_offline_bracket() + return f""" +/-- `exp_tenth_bracket_defs` -- the SAME certified bracket in BraggDefect's own vocabulary: + `expLo`/`expHi` are by definition the two literals `exp_tenth_bracket` brackets between, + so this is a pure unfolding. It is the exact shape of the `hexp` hypothesis that + `BraggDefect.bragg_defect_witness` (and the MIRRORMERE node `MM_bragg_defect_witness`) + carries as an Arb input. conjecture1_proved = False. -/ +theorem exp_tenth_bracket_defs : + BraggDefect.expLo ≤ Real.exp (1 / 10) ∧ Real.exp (1 / 10) ≤ BraggDefect.expHi := by + unfold BraggDefect.expLo BraggDefect.expHi + exact exp_tenth_bracket + +/-- **`bragg_defect_witness_unconditional`** -- the MIRRORMERE defect witness with its Arb + exponential-enclosure hypothesis DISCHARGED in the kernel. Identical conclusion to + `BraggDefect.bragg_defect_witness`; the `hexp` binder is gone, supplied by + `exp_tenth_bracket_defs` (order-14 `Real.exp_bound`). + + SCOPE, unchanged: this is the finite synthetic-pair diffraction experiment of + `BraggDefect.lean` -- the on-line configuration's defect functional is exactly 0 and the + one-off-line-pair configuration's is bracketed strictly below 0. Discharging a NUMERIC + hypothesis makes the witness unconditional; it does not enlarge what the witness says, and + the experiment's other trust seams (the BraggH100 Arb sign boxes, the band `hLine`) are + untouched. Nothing here is about RH. conjecture1_proved = False. -/ +theorem bragg_defect_witness_unconditional : + BraggDefect.defectFunctional 0 = 0 ∧ + (({off_lo} : ℝ) ≤ BraggDefect.defectFunctional BraggDefect.excess ∧ + BraggDefect.defectFunctional BraggDefect.excess ≤ ({off_hi} : ℝ)) := + BraggDefect.bragg_defect_witness exp_tenth_bracket_defs + +/-- The hypothesis-carrying form, kept so the MIRRORMERE grant gate's syntactic match against + `Statements/MM_bragg_defect_witness.lean` still finds its statement. The hypothesis is now + inert -- the conclusion is `bragg_defect_witness_unconditional`. -/ +theorem bragg_defect_witness_hyp_form + (_hexp : BraggDefect.expLo ≤ Real.exp (1 / 10) ∧ Real.exp (1 / 10) ≤ BraggDefect.expHi) : + BraggDefect.defectFunctional 0 = 0 ∧ + (({off_lo} : ℝ) ≤ BraggDefect.defectFunctional BraggDefect.excess ∧ + BraggDefect.defectFunctional BraggDefect.excess ≤ ({off_hi} : ℝ)) := + bragg_defect_witness_unconditional + +-- STATEMENT GATE (kernel-enforced): the node statement of MM_bragg_defect_witness, written +-- exactly as `Statements/MM_bragg_defect_witness.lean` writes it (under `open BraggDefect`), +-- is inhabited by the hypothesis-carrying form. A drift in either statement fails the build. +open BraggDefect in +example (hexp : expLo ≤ Real.exp (1 / 10) ∧ Real.exp (1 / 10) ≤ expHi) : + defectFunctional 0 = 0 ∧ + (({off_lo} : ℝ) ≤ defectFunctional excess ∧ + defectFunctional excess ≤ ({off_hi} : ℝ)) := + bragg_defect_witness_hyp_form hexp +""" + + +def build() -> str: + _assert_island_literals() + fam = exp_enclosure_family( + "ExpEnclosureInstances", + GridSpec([("case", sorted(_CASES))]), + lambda pt: _CASES[pt["case"]][0], + spec=lambda pt: dict(_CASES[pt["case"]][1]), + ) + report = emit( + certify(fam), + LeanProfile(namespace=("ExpEnclosureInstances",), + imports=("Mathlib", "BraggDefect")), + [ExpEnclosureEmitter()], + ValidationReport(checks=(("exp_enclosure", True),)), + ) + text = next(iter(report.files.values())) + end = "end ExpEnclosureInstances" + if end not in text: + raise SystemExit("emitted file has no namespace footer to splice the bridge into") + return text.replace(end, _bridge().lstrip("\n") + "\n" + end) + + +def main(*, check: bool = False) -> int: + text = build() + if check: + if not _OUT.exists() or _OUT.read_text(encoding="utf-8") != text: + print("DRIFT: ExpEnclosureInstances.lean does not match regeneration") + return 1 + print("check: OK (regeneration matches frozen output byte-for-byte)") + return 0 + _OUT.write_text(text, encoding="utf-8") + print(f"wrote {_OUT} ({len(text)} bytes)") + return 0 + + +if __name__ == "__main__": + ap = argparse.ArgumentParser() + ap.add_argument("--check", action="store_true", help="drift check; do not write") + raise SystemExit(main(check=ap.parse_args().check)) diff --git a/telperion/examples/exp_laurent_deficit/generate.py b/telperion/examples/exp_laurent_deficit/generate.py new file mode 100644 index 000000000..931a08aee --- /dev/null +++ b/telperion/examples/exp_laurent_deficit/generate.py @@ -0,0 +1,148 @@ +"""Generate the exp-Laurent deficit certificate -- the Face 4 <-> Face 1 dictionary row. + + python examples/exp_laurent_deficit/generate.py # write the zzl-island Lean + python examples/exp_laurent_deficit/generate.py --check # drift check (no write) + +QC_RECURRENCE section 2 row (a) models an off-line pair at displacement `d` by two +one-sided clearances -- the outer mirror factor `e^d - 1` and the inner +transported-zero factor `1 - e^(-d)` -- and identifies their PRODUCT, the +recurrence deficit, with the Bragg amplification excess `e^d + e^(-d) - 2`. Both +rows emitted here are that identity and its Weil-energy square: + + expLaurent_recurrence_deficit (e^d - 1) * (1 - e^(-d)) = e^d + e^(-d) - 2 + expLaurent_recurrence_deficit_sq (e^d - 1)^2 * (1 - e^(-d))^2 = (e^d + e^(-d) - 2)^2 + +Each is certified (kind `exp_laurent_identity`) as an EXACT reduction of +`lhs - rhs` modulo the single relation `e^d * e^(-d) = 1` in Q[y, z]; the quotient +-- the cofactor -- is the load-bearing certificate the emitted `linear_combination` +consumes. Corrupt it and the Lean kernel rejects the theorem +(`negctrl_adapters/adapter_exp_laurent_identity.py`). + +NEGATIVE CONTROL (always runs, before anything is written): the mistake +QC_RECURRENCE section 6 caught in ITSELF -- the SUM of the clearances, +`(e^d - 1) + (1 - e^(-d)) = 2d + O(d^3)`, is NOT the excess; only the product is. +The certifier must REFUSE the sum form with a nonzero remainder. A second control +refuses a plain ring identity, where the relation would not be load-bearing. + +OUTPUT LOCATION. The emitted file is written into the zeta_zero_localization +island (`examples/zeta_zero_localization/lean/ExpLaurentDeficit.lean`), where its +consumer lives: `RecurrenceDeficit.lean` specializes the first row at d = 1/10 to +prove the MIRRORMERE node `MM_recurrence_deficit_eq_excess` against the island's +own `BraggDefect.excess`. Same toolchain pin (v4.32.0), same lakefile (zzl_aux). + +HONEST SCOPE: a dictionary row between two finite instruments, unconditional and +zeta-free. Certifying one recurrence instance is not progress toward RH; the +UNIFORM Bagchi recurrence IS RH and is untouched here. conjecture1_proved = False. +""" +import argparse +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "src")) + +from telperion import ValidationReport, certify, emit # noqa: E402 +from telperion.emit_exp_laurent_identity import ( # noqa: E402 + Y, + Z, + ExpLaurentIdentityEmitter, + exp_laurent_certificate, + exp_laurent_identity_family, +) +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 + +_OUT = (Path(__file__).resolve().parents[1] + / "zeta_zero_localization" / "lean" / "ExpLaurentDeficit.lean") + +# The two clearances of QC_RECURRENCE row (a), in the exp generators. +_G_PLUS = Y - 1 # outer mirror factor e^d - 1 +_G_MINUS = 1 - Z # inner factor 1 - e^(-d) +_EXCESS = Y + Z - 2 # Bragg amplification excess + +# Row index -> (Lean theorem name, lhs, rhs). The grid axis is the integer index +# (GridSpec axes are integer-valued); the displacement binder is the Lean name `d`. +_ROWS = ( + ("expLaurent_recurrence_deficit", _G_PLUS * _G_MINUS, _EXCESS), + ("expLaurent_recurrence_deficit_sq", (_G_PLUS * _G_MINUS) ** 2, _EXCESS ** 2), +) +_VAR = "d" + +_PRELUDE = """-- THE EXP-LAURENT DEFICIT ROWS (QC_RECURRENCE section 2 row (a), section 4 item 2). +-- +-- For an off-line pair at displacement d, the two one-sided clearances are the outer mirror +-- factor e^d - 1 and the inner transported-zero factor 1 - e^(-d). Their PRODUCT -- the +-- two-sided clearance a recurrence shift must bridge -- is the RECURRENCE DEFICIT, and it +-- equals the Bragg amplification EXCESS e^d + e^(-d) - 2. The square is the Weil-energy +-- (quadratic-form) reading of the same row. +-- +-- Certificate: an exact reduction of lhs - rhs modulo the single relation e^d * e^(-d) = 1, +-- with the quotient (cofactor) carried into `linear_combination`. Corrupt the cofactor or +-- either side and the kernel rejects the theorem. +-- +-- HONEST SCOPE: unconditional, zeta-free bookkeeping between two finite instruments. It is +-- a dictionary row, not an analytic theorem, and NOT a step toward RH (the uniform Bagchi +-- recurrence IS RH and is untouched). conjecture1_proved = False.""" + + +def _negative_controls() -> None: + """Layer-1 refusals that must fire before anything is emitted. + + (1) The memo's own corrected mistake: the SUM of the clearances is not the + excess (remainder 2 - 2*e^(-d) != 0). + (2) A plain ring identity, where the relation e^d * e^(-d) = 1 carries no + information (cofactor 0) -- that shape belongs to IdentityEmitter. + """ + controls = ( + ("sum_not_product", _G_PLUS + _G_MINUS, _EXCESS, + "the SUM of the two clearances (QC_RECURRENCE section 6's corrected mistake)"), + ("relation_not_load_bearing", (Y - 1) * (Y + 1), Y ** 2 - 1, + "a plain ring identity (cofactor 0)"), + ) + for name, lhs, rhs, why in controls: + try: + exp_laurent_certificate(lhs, rhs, name=name) + except ValueError: + continue + raise AssertionError( + f"exp_laurent_identity negative control FAILED: accepted {why}") + print("exp_laurent_identity: OK (product row accepted; the SUM form and the " + "cofactor-0 ring identity are refused)") + + +def build() -> str: + fam = exp_laurent_identity_family( + "ExpLaurentDeficit", + GridSpec([("row", range(len(_ROWS)))]), + lambda pt: _ROWS[pt["row"]][0], + spec=lambda pt: (_ROWS[pt["row"]][1], _ROWS[pt["row"]][2], _VAR), + ) + report = emit( + certify(fam), + LeanProfile(namespace=("ExpLaurentDeficit",), prelude=_PRELUDE), + [ExpLaurentIdentityEmitter()], + ValidationReport(checks=(("exp_laurent_identity", True),)), + ) + return next(iter(report.files.values())) + + +def main(*, check: bool = False) -> int: + _negative_controls() + text = build() + if check: + if not _OUT.exists() or _OUT.read_text(encoding="utf-8") != text: + print("DRIFT: ExpLaurentDeficit.lean does not match regeneration") + return 1 + print("check: OK (regeneration matches frozen output byte-for-byte)") + return 0 + _OUT.parent.mkdir(parents=True, exist_ok=True) + _OUT.write_text(text, encoding="utf-8") + print(f"wrote {_OUT} ({len(text)} bytes)") + return 0 + + +if __name__ == "__main__": + ap = argparse.ArgumentParser( + description="Emit the exp-Laurent recurrence-deficit rows onto the " + "zeta_zero_localization island.") + ap.add_argument("--check", action="store_true", help="drift check; do not write") + raise SystemExit(main(check=ap.parse_args().check)) diff --git a/telperion/examples/quasicrystal/lean/AxiomGuardQC.lean b/telperion/examples/quasicrystal/lean/AxiomGuardQC.lean index d800e5d59..bf89f5242 100644 --- a/telperion/examples/quasicrystal/lean/AxiomGuardQC.lean +++ b/telperion/examples/quasicrystal/lean/AxiomGuardQC.lean @@ -15,6 +15,12 @@ import BoundaryLemmas import TwoFreqRigidity import RationalFreqReduction import InvolutionDictionary +import TorusSectionLadder +import OfflineDiscs +import OfflineDiscsInstances +import EulerFactorOffline +import SelfInversiveOfflineInstances +import EulerFactorSectionOffline open Quasicrystal @@ -75,6 +81,46 @@ open Quasicrystal #print axioms Quasicrystal.selfInversive_binomial_realRooted #print axioms Quasicrystal.fixed_locus_dichotomy +/-! ### MIRRORMERE torus-section ladder T1 -- TorusSectionLadder (2026-09-18): + registry nodes MM_torus_section_dictionary + MM_torus_section_n2_rigidity. + Vocabulary bridges over TwoFreqRigidity (simp-grade; recorded, not counted). -/ +#print axioms Quasicrystal.expSum_eq_linearTorusForm_torusOrbit +#print axioms Quasicrystal.torus_section_dictionary +#print axioms Quasicrystal.torus_section_n2_rigidity +/-! ### MIRRORMERE E4b -- OfflineDiscs (registry node MM_offline_disjoint_discs, + QC_RECURRENCE section 4.3 isolation lemma) -/ +#print axioms Quasicrystal.exists_pos_lower_bound_of_finset +#print axioms Quasicrystal.abs_re_sub_le_dist +#print axioms Quasicrystal.offline_disjoint_discs + +/-! ### MIRRORMERE E4b instances -- OfflineDiscsInstances (emitted by the Telperion + `disjoint_discs` kind; the points are INPUT, not a claim about zeta) -/ +#print axioms OfflineDiscsInstances.offline_discs_online_pair +#print axioms OfflineDiscsInstances.offline_discs_offline_bank +/-! ### torus-section ladder T2 -- TorusSectionLadder, THE NEGATIVE CONTROL + (registry node MM_euler_factor_section_offline + explicit off-line witness) -/ +#print axioms TorusSectionLadder.euler_factor_coeff_ne_zero +#print axioms TorusSectionLadder.euler_factor_freq_ne +#print axioms TorusSectionLadder.euler_factor_section_offline +#print axioms TorusSectionLadder.euler_factor_section_witness +#print axioms TorusSectionLadder.euler_factor_section_witness_im +#print axioms TorusSectionLadder.euler_factor_section_offline_of_witness + +/-! ### torus-section ladder T2 -- the emitter dogfood (selfinversive_rigidity mode="offline"): + the p = 2, 3, 5 Euler-factor sections, refuted from the exact normSq inequality -/ +#print axioms SelfInversiveOfflineInstances.euler_factor_p2_offline +#print axioms SelfInversiveOfflineInstances.euler_factor_p2_offline_witness +#print axioms SelfInversiveOfflineInstances.euler_factor_p2_offline_of_witness +#print axioms SelfInversiveOfflineInstances.euler_factor_p2_offline_node +#print axioms SelfInversiveOfflineInstances.euler_factor_p3_offline +#print axioms SelfInversiveOfflineInstances.euler_factor_p3_offline_witness +#print axioms SelfInversiveOfflineInstances.euler_factor_p3_offline_of_witness +#print axioms SelfInversiveOfflineInstances.euler_factor_p3_offline_node +#print axioms SelfInversiveOfflineInstances.euler_factor_p5_offline +#print axioms SelfInversiveOfflineInstances.euler_factor_p5_offline_witness +#print axioms SelfInversiveOfflineInstances.euler_factor_p5_offline_of_witness +#print axioms SelfInversiveOfflineInstances.euler_factor_p5_offline_node + /-! ### increment (iii) -- CharacterizationStatements DELIBERATELY NOT GUARDED HERE. `CharacterizationStatements.lean` contains only @@ -84,3 +130,14 @@ open Quasicrystal theorem, so there are no axioms to print. It builds green (no sorry) and is a defaultTarget; listing its `def`s under `#print axioms` would be a category error (they are Props, not proofs). -/ + +-- MM_euler_factor_section_offline's proof-link artifact (emitter-generated, +-- drift-gated by examples/twofreq_offline/generate.py --check). +#print axioms EulerFactorSectionOffline.euler_factor_section_offline +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_offline_zero +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_displacement +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_p3 +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_p3_offline_zero +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_p3_displacement +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_p5 +#print axioms EulerFactorSectionOffline.euler_factor_section_offline_p5_offline_zero diff --git a/telperion/examples/quasicrystal/lean/EulerFactorOffline.lean b/telperion/examples/quasicrystal/lean/EulerFactorOffline.lean new file mode 100644 index 000000000..ad0f0960b --- /dev/null +++ b/telperion/examples/quasicrystal/lean/EulerFactorOffline.lean @@ -0,0 +1,114 @@ +/- + EulerFactorOffline.lean -- PROGRAM MIRRORMERE torus-section ladder, rung T2: + THE NEGATIVE CONTROL (QC_TORUS_SECTION_LADDER memo section 4b). + + The p = 2 Euler factor 1 - 2^(-s), read on the critical line s = 1/2 + ix, is the + two-frequency section + twoFreq (1, -(1/sqrt 2); 0, -log 2) (x) = 1 - (1/sqrt 2) * e^{-i (log 2) x}. + Its zeros sit UNIFORMLY at Im x = 1/2 (they are the points Re s = 0, s = 2 pi i k / log 2), + so per-rung real-rootedness FAILS. This is exactly what `twoFreq_realRooted_iff` + (TwoFreqRigidity, R3(n=2)) predicts: the coefficient moduli are ||1|| = 1 and + ||-(1/sqrt 2)|| = 1/sqrt 2 < 1, and unequal modulus puts every zero on the single + off-line horizontal Im x = -(1/w) log|c1/c2| = (1/log 2) * log(sqrt 2) = 1/2. + + Registry node: MM_euler_factor_section_offline (statement mirrored VERBATIM below, + name `euler_factor_section_offline`). The `not` is the content: it certifies that no + per-rung line-membership claim survives finite truncation (Turan/Montgomery + obstruction, in-house); critical-line membership is an infinite-N continuation + phenomenon. + + Companion (NOT a node): the explicit witness x = i/2, so the negative control carries + a concrete off-line zero and not merely a refuted universal. + + Certificate shape: the Telperion SelfInversiveRigidityEmitter `mode="offline"` + (examples/selfinversive_rigidity/generate.py) emits the same refutation for the + p = 2, 3, 5 Euler-factor sections from an exact rational normSq inequality; this file + is the hand-stated node so the registry statement text appears verbatim. + + MODULE NAME: the ladder's T1 (dictionary / N=2 rigidity) items live in a sibling + `TorusSectionLadder` module authored in parallel; this rung is kept in its own module so + the two can be built independently (the islands share one on-disk .lake olean cache, in + which a same-named module would clobber). Both declare into namespace `TorusSectionLadder` + and merge into one file whenever the branches are reconciled. + + conjecture1_proved = False. Unconditional finite fact; NOT a proof of RH, and NOT a + step toward one (it is the obstruction, not the ladder). +-/ +import TwoFreqRigidity + +open Quasicrystal + +namespace TorusSectionLadder + +noncomputable section + +/-- `-(1/sqrt 2)` is a nonzero real: the p = 2 Euler-factor coefficient. -/ +theorem euler_factor_coeff_ne_zero : (-(1 / Real.sqrt 2) : ℝ) ≠ 0 := + neg_ne_zero.mpr (by positivity) + +/-- The frequencies `0` and `-log 2` differ (`log 2 > 0`). -/ +theorem euler_factor_freq_ne : (0 : ℝ) ≠ -(Real.log 2) := by + have := Real.log_pos (by norm_num : (1 : ℝ) < 2) + intro h + linarith + +/-- **MM_euler_factor_section_offline** (VERBATIM registry statement). The p = 2 +Euler-factor section is NOT real-rooted: the two-frequency sum +`twoFreq 1 (-(1/sqrt 2)) 0 (-log 2)` has a zero with nonzero imaginary part. +Proof: `.mp` of `twoFreq_realRooted_iff` would force `‖1‖ = ‖-(1/sqrt 2)‖`, i.e. +`1 = 1/sqrt 2`, contradicting `1 < sqrt 2`. conjecture1_proved = False. -/ +theorem euler_factor_section_offline : + ¬ (∀ x : ℂ, + twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 → x.im = 0) := by + intro hall + have hs : (0 : ℝ) < Real.sqrt 2 := Real.sqrt_pos.mpr (by norm_num) + have hc₂ : ((-(1 / Real.sqrt 2) : ℝ) : ℂ) ≠ 0 := + Complex.ofReal_ne_zero.mpr euler_factor_coeff_ne_zero + have hn := (twoFreq_realRooted_iff 1 _ 0 _ one_ne_zero hc₂ euler_factor_freq_ne).mp hall + rw [norm_one, Complex.norm_real, Real.norm_eq_abs, abs_neg, + abs_of_pos (by positivity)] at hn + -- hn : 1 = 1 / sqrt 2, but 1 / sqrt 2 < 1 since 1 < sqrt 2 + have hlt : 1 / Real.sqrt 2 < 1 := by + rw [div_lt_one hs] + exact Real.one_lt_sqrt_two + linarith + +/-- **Explicit off-line witness** (companion, NOT a node): `x = i/2` is a zero of the +p = 2 Euler-factor section. Indeed `e^{-i (log 2) (i/2)} = e^{(log 2)/2} = sqrt 2`, so +`1 - (1/sqrt 2) * sqrt 2 = 0`. Its imaginary part is `1/2`, the uniform off-line +displacement predicted by `twoFreq_zero_norm`. conjecture1_proved = False. -/ +theorem euler_factor_section_witness : + twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) (Complex.I / 2) = 0 := by + have hc₂ : ((-(1 / Real.sqrt 2) : ℝ) : ℂ) ≠ 0 := + Complex.ofReal_ne_zero.mpr euler_factor_coeff_ne_zero + rw [twoFreq_eq_zero_iff _ _ _ _ _ one_ne_zero hc₂] + have harg : (((-(Real.log 2)) - 0 : ℝ) : ℂ) * (Complex.I / 2) * Complex.I + = ((Real.log 2 / 2 : ℝ) : ℂ) := by + push_cast + ring_nf + rw [Complex.I_sq] + ring + rw [harg, ← Complex.ofReal_exp, Real.exp_half, Real.exp_log (by norm_num)] + have hs : (Real.sqrt 2 : ℂ) ≠ 0 := by + exact_mod_cast (ne_of_gt (Real.sqrt_pos.mpr (by norm_num : (0 : ℝ) < 2))) + push_cast + rw [neg_div_neg_eq, one_div_one_div] + +/-- The witness lies off the real line: `Im (i/2) = 1/2 ≠ 0`. -/ +theorem euler_factor_section_witness_im : (Complex.I / 2 : ℂ).im = 1 / 2 := by + simp [Complex.div_ofNat_im] + +/-- **Refutation via the witness** (companion): the same node statement, discharged +directly from the explicit zero rather than through the `.mp` direction of the iff. +Two independent routes to the same negative control. -/ +theorem euler_factor_section_offline_of_witness : + ¬ (∀ x : ℂ, + twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 → x.im = 0) := by + intro hall + have h := hall (Complex.I / 2) euler_factor_section_witness + rw [euler_factor_section_witness_im] at h + norm_num at h + +end + +end TorusSectionLadder diff --git a/telperion/examples/quasicrystal/lean/EulerFactorSectionOffline.lean b/telperion/examples/quasicrystal/lean/EulerFactorSectionOffline.lean new file mode 100644 index 000000000..9f761e331 --- /dev/null +++ b/telperion/examples/quasicrystal/lean/EulerFactorSectionOffline.lean @@ -0,0 +1,183 @@ +/- telperion 0.1.6 | family EulerFactorSectionOffline | input-hash a5a4a9c76c5bb5e5 + 8 theorems, 3 generation-time self-checks passed. + Regenerate & verify: forge diff --family --manifest --check + DO NOT EDIT BY HAND — edits are flagged by the regeneration diff. -/ + +import Mathlib +import TwoFreqRigidity + +namespace EulerFactorSectionOffline + +open Quasicrystal + +/-- **Off-line displacement** (euler_factor_section_offline): the two-frequency sum + `F(x) = c₁·e^{iλ₁x} + c₂·e^{iλ₂x}` with `|c₁|² = 1` and + `|c₂|² = 1/2` is NOT real-rooted -- some zero lies strictly off the + real line. By `Quasicrystal.twoFreq_realRooted_iff` real-rootedness is + EQUIVALENT to `‖c₁‖ = ‖c₂‖`, and the two moduli differ EXACTLY, so the + universal statement is refuted. Ladder rung T2 (p = 2). + A finite section fact; nothing about ζ or RH. conjecture1_proved = False. -/ +theorem euler_factor_section_offline : + ¬ (∀ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 → x.im = 0) := by + have hc1 : (1 : ℂ) ≠ 0 := by + norm_num [Complex.ext_iff] + have hc2 : (((-(1 / Real.sqrt 2) : ℝ) : ℂ) : ℂ) ≠ 0 := by + have hs : (0 : ℝ) < Real.sqrt 2 := Real.sqrt_pos.mpr (by norm_num) + intro hzero + have hre := Complex.ofReal_eq_zero.mp hzero + have hp : (0 : ℝ) < 1 / Real.sqrt 2 := by positivity + linarith + have hlam : (0 : ℝ) ≠ ((-(Real.log 2))) := by + have hlp := Real.log_pos (show (1 : ℝ) < 2 by norm_num) + intro hlog + linarith + rw [twoFreq_realRooted_iff _ _ _ _ hc1 hc2 hlam] + intro h + have h2 : Complex.normSq (1) = Complex.normSq (((-(1 / Real.sqrt 2) : ℝ) : ℂ)) := by + rw [Complex.normSq_eq_norm_sq, Complex.normSq_eq_norm_sq, h] + have hns1 : Complex.normSq (1) = (1 : ℝ) := by + norm_num [Complex.normSq_apply] + have hns2 : Complex.normSq (((-(1 / Real.sqrt 2) : ℝ) : ℂ)) = ((1 / 2) : ℝ) := by + rw [Complex.normSq_ofReal, neg_mul_neg, div_mul_div_comm, one_mul, + Real.mul_self_sqrt (show (0 : ℝ) ≤ 2 by norm_num)] + rw [hns1, hns2] at h2 + norm_num at h2 + +/-- Existence form of `euler_factor_section_offline`: an explicit zero off the real line. + conjecture1_proved = False. -/ +theorem euler_factor_section_offline_offline_zero : + ∃ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 ∧ x.im ≠ 0 := by + obtain ⟨x, hx⟩ := not_forall.mp euler_factor_section_offline + exact ⟨x, (Classical.not_imp.mp hx).1, (Classical.not_imp.mp hx).2⟩ + +/-- **Certified displacement** (euler_factor_section_offline_displacement): for the Euler factor + `1 - 2^(-s)` read on `s = 1/2 + i x`, EVERY zero of the section sits at + `Im x = 1/2` -- i.e. on `Re s = 0`, uniformly. The ladder's negative control: + the off-line displacement is 1/2 at this rung, for this prime, with no + dependence on the truncation. conjecture1_proved = False. -/ +theorem euler_factor_section_offline_displacement : + ∀ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 → x.im = 1 / 2 := by + intro x hz + have hc1 : (1 : ℂ) ≠ 0 := by + norm_num [Complex.ext_iff] + have hc2 : (((-(1 / Real.sqrt 2) : ℝ) : ℂ) : ℂ) ≠ 0 := by + have hs : (0 : ℝ) < Real.sqrt 2 := Real.sqrt_pos.mpr (by norm_num) + intro hzero + have hre := Complex.ofReal_eq_zero.mp hzero + have hp : (0 : ℝ) < 1 / Real.sqrt 2 := by positivity + linarith + have hn := twoFreq_zero_norm _ _ _ _ x hc1 hc2 hz + rw [norm_one, Complex.norm_real, Real.norm_eq_abs, abs_neg, + abs_of_pos (show (0 : ℝ) < 1 / Real.sqrt 2 by positivity), one_div_one_div] at hn + have hlog := congrArg Real.log hn + rw [Real.log_exp, Real.log_sqrt (show (0 : ℝ) ≤ 2 by norm_num)] at hlog + have hl : (0 : ℝ) < Real.log 2 := Real.log_pos (by norm_num) + have hkey : Real.log 2 * x.im = Real.log 2 * (1 / 2) := by linarith + exact mul_left_cancel₀ hl.ne' hkey + +/-- **Off-line displacement** (euler_factor_section_offline_p3): the two-frequency sum + `F(x) = c₁·e^{iλ₁x} + c₂·e^{iλ₂x}` with `|c₁|² = 1` and + `|c₂|² = 1/3` is NOT real-rooted -- some zero lies strictly off the + real line. By `Quasicrystal.twoFreq_realRooted_iff` real-rootedness is + EQUIVALENT to `‖c₁‖ = ‖c₂‖`, and the two moduli differ EXACTLY, so the + universal statement is refuted. Ladder rung T2 (p = 3). + A finite section fact; nothing about ζ or RH. conjecture1_proved = False. -/ +theorem euler_factor_section_offline_p3 : + ¬ (∀ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 3) : ℝ) : ℂ) 0 (-(Real.log 3)) x = 0 → x.im = 0) := by + have hc1 : (1 : ℂ) ≠ 0 := by + norm_num [Complex.ext_iff] + have hc2 : (((-(1 / Real.sqrt 3) : ℝ) : ℂ) : ℂ) ≠ 0 := by + have hs : (0 : ℝ) < Real.sqrt 3 := Real.sqrt_pos.mpr (by norm_num) + intro hzero + have hre := Complex.ofReal_eq_zero.mp hzero + have hp : (0 : ℝ) < 1 / Real.sqrt 3 := by positivity + linarith + have hlam : (0 : ℝ) ≠ ((-(Real.log 3))) := by + have hlp := Real.log_pos (show (1 : ℝ) < 3 by norm_num) + intro hlog + linarith + rw [twoFreq_realRooted_iff _ _ _ _ hc1 hc2 hlam] + intro h + have h2 : Complex.normSq (1) = Complex.normSq (((-(1 / Real.sqrt 3) : ℝ) : ℂ)) := by + rw [Complex.normSq_eq_norm_sq, Complex.normSq_eq_norm_sq, h] + have hns1 : Complex.normSq (1) = (1 : ℝ) := by + norm_num [Complex.normSq_apply] + have hns2 : Complex.normSq (((-(1 / Real.sqrt 3) : ℝ) : ℂ)) = ((1 / 3) : ℝ) := by + rw [Complex.normSq_ofReal, neg_mul_neg, div_mul_div_comm, one_mul, + Real.mul_self_sqrt (show (0 : ℝ) ≤ 3 by norm_num)] + rw [hns1, hns2] at h2 + norm_num at h2 + +/-- Existence form of `euler_factor_section_offline_p3`: an explicit zero off the real line. + conjecture1_proved = False. -/ +theorem euler_factor_section_offline_p3_offline_zero : + ∃ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 3) : ℝ) : ℂ) 0 (-(Real.log 3)) x = 0 ∧ x.im ≠ 0 := by + obtain ⟨x, hx⟩ := not_forall.mp euler_factor_section_offline_p3 + exact ⟨x, (Classical.not_imp.mp hx).1, (Classical.not_imp.mp hx).2⟩ + +/-- **Certified displacement** (euler_factor_section_offline_p3_displacement): for the Euler factor + `1 - 3^(-s)` read on `s = 1/2 + i x`, EVERY zero of the section sits at + `Im x = 1/2` -- i.e. on `Re s = 0`, uniformly. The ladder's negative control: + the off-line displacement is 1/2 at this rung, for this prime, with no + dependence on the truncation. conjecture1_proved = False. -/ +theorem euler_factor_section_offline_p3_displacement : + ∀ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 3) : ℝ) : ℂ) 0 (-(Real.log 3)) x = 0 → x.im = 1 / 2 := by + intro x hz + have hc1 : (1 : ℂ) ≠ 0 := by + norm_num [Complex.ext_iff] + have hc2 : (((-(1 / Real.sqrt 3) : ℝ) : ℂ) : ℂ) ≠ 0 := by + have hs : (0 : ℝ) < Real.sqrt 3 := Real.sqrt_pos.mpr (by norm_num) + intro hzero + have hre := Complex.ofReal_eq_zero.mp hzero + have hp : (0 : ℝ) < 1 / Real.sqrt 3 := by positivity + linarith + have hn := twoFreq_zero_norm _ _ _ _ x hc1 hc2 hz + rw [norm_one, Complex.norm_real, Real.norm_eq_abs, abs_neg, + abs_of_pos (show (0 : ℝ) < 1 / Real.sqrt 3 by positivity), one_div_one_div] at hn + have hlog := congrArg Real.log hn + rw [Real.log_exp, Real.log_sqrt (show (0 : ℝ) ≤ 3 by norm_num)] at hlog + have hl : (0 : ℝ) < Real.log 3 := Real.log_pos (by norm_num) + have hkey : Real.log 3 * x.im = Real.log 3 * (1 / 2) := by linarith + exact mul_left_cancel₀ hl.ne' hkey + +/-- **Off-line displacement** (euler_factor_section_offline_p5): the two-frequency sum + `F(x) = c₁·e^{iλ₁x} + c₂·e^{iλ₂x}` with `|c₁|² = 1` and + `|c₂|² = 1/5` is NOT real-rooted -- some zero lies strictly off the + real line. By `Quasicrystal.twoFreq_realRooted_iff` real-rootedness is + EQUIVALENT to `‖c₁‖ = ‖c₂‖`, and the two moduli differ EXACTLY, so the + universal statement is refuted. Ladder rung T2 (p = 5). + A finite section fact; nothing about ζ or RH. conjecture1_proved = False. -/ +theorem euler_factor_section_offline_p5 : + ¬ (∀ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 5) : ℝ) : ℂ) 0 (-(Real.log 5)) x = 0 → x.im = 0) := by + have hc1 : (1 : ℂ) ≠ 0 := by + norm_num [Complex.ext_iff] + have hc2 : (((-(1 / Real.sqrt 5) : ℝ) : ℂ) : ℂ) ≠ 0 := by + have hs : (0 : ℝ) < Real.sqrt 5 := Real.sqrt_pos.mpr (by norm_num) + intro hzero + have hre := Complex.ofReal_eq_zero.mp hzero + have hp : (0 : ℝ) < 1 / Real.sqrt 5 := by positivity + linarith + have hlam : (0 : ℝ) ≠ ((-(Real.log 5))) := by + have hlp := Real.log_pos (show (1 : ℝ) < 5 by norm_num) + intro hlog + linarith + rw [twoFreq_realRooted_iff _ _ _ _ hc1 hc2 hlam] + intro h + have h2 : Complex.normSq (1) = Complex.normSq (((-(1 / Real.sqrt 5) : ℝ) : ℂ)) := by + rw [Complex.normSq_eq_norm_sq, Complex.normSq_eq_norm_sq, h] + have hns1 : Complex.normSq (1) = (1 : ℝ) := by + norm_num [Complex.normSq_apply] + have hns2 : Complex.normSq (((-(1 / Real.sqrt 5) : ℝ) : ℂ)) = ((1 / 5) : ℝ) := by + rw [Complex.normSq_ofReal, neg_mul_neg, div_mul_div_comm, one_mul, + Real.mul_self_sqrt (show (0 : ℝ) ≤ 5 by norm_num)] + rw [hns1, hns2] at h2 + norm_num at h2 + +/-- Existence form of `euler_factor_section_offline_p5`: an explicit zero off the real line. + conjecture1_proved = False. -/ +theorem euler_factor_section_offline_p5_offline_zero : + ∃ x : ℂ, twoFreq 1 ((-(1 / Real.sqrt 5) : ℝ) : ℂ) 0 (-(Real.log 5)) x = 0 ∧ x.im ≠ 0 := by + obtain ⟨x, hx⟩ := not_forall.mp euler_factor_section_offline_p5 + exact ⟨x, (Classical.not_imp.mp hx).1, (Classical.not_imp.mp hx).2⟩ + +end EulerFactorSectionOffline diff --git a/telperion/examples/quasicrystal/lean/OfflineDiscs.lean b/telperion/examples/quasicrystal/lean/OfflineDiscs.lean new file mode 100644 index 000000000..df89aa134 --- /dev/null +++ b/telperion/examples/quasicrystal/lean/OfflineDiscs.lean @@ -0,0 +1,86 @@ +/- OfflineDiscs.lean -- PROGRAM MIRRORMERE E4b isolation lemma (QC_RECURRENCE section 4.3). + + Registry node: MM_offline_disjoint_discs (telperion/missions/mirrormere). + Statement is mirrored VERBATIM from + telperion/missions/mirrormere/lean/Statements/MM_offline_disjoint_discs.lean + (node sha256 bac57ccef7c3f828) into this island's namespace. + + Content: finitely many distinct points of the open critical strip + {0 < re < 1} admit a single positive radius r whose closed discs are + pairwise disjoint and each contained in the strip. Pure Mathlib metric + topology; no MMDefs vocabulary is involved. + + This is the geometric substrate for counting off-line zeros by disjoint + recurrence-deficit discs (the Rouche-template leg of E5). It says NOTHING + about where zeta's zeros are; it is a lemma about finite sets of points. + + conjecture1_proved = False (NOT a proof of RH). +-/ +import Mathlib + +namespace Quasicrystal + +/-- Any finite set of positive reals has a positive common lower bound. + (Finset induction; the empty set gets the default bound 1.) -/ +theorem exists_pos_lower_bound_of_finset (T : Finset ℝ) (hT : ∀ x ∈ T, 0 < x) : + ∃ ε : ℝ, 0 < ε ∧ ∀ x ∈ T, ε ≤ x := by + classical + induction T using Finset.induction_on with + | empty => exact ⟨1, one_pos, by simp⟩ + | @insert a T _ ih => + obtain ⟨ε, hε, hle⟩ := ih (fun x hx => hT x (Finset.mem_insert_of_mem hx)) + refine ⟨min ε a, lt_min hε (hT a (Finset.mem_insert_self a T)), ?_⟩ + intro x hx + rcases Finset.mem_insert.mp hx with rfl | hx + · exact min_le_right _ _ + · exact (min_le_left _ _).trans (hle x hx) + +/-- The real part is 1-Lipschitz: |s.re - z.re| <= dist s z. -/ +theorem abs_re_sub_le_dist (s z : ℂ) : |s.re - z.re| ≤ dist s z := by + have h := Complex.abs_re_le_norm (s - z) + rw [Complex.sub_re] at h + rwa [dist_eq_norm] + +/-- MM_offline_disjoint_discs (VERBATIM statement of the registry node): + finitely many points strictly inside the open critical strip admit a common + positive radius whose closed discs are pairwise disjoint (for distinct + centres) and each contained in the strip. -/ +theorem offline_disjoint_discs (S : Finset ℂ) + (hstrip : ∀ z ∈ S, 0 < z.re ∧ z.re < 1) : + ∃ r : ℝ, 0 < r ∧ + (∀ z ∈ S, ∀ w ∈ S, z ≠ w → Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧ + (∀ z ∈ S, Metric.closedBall z r ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1}) := by + classical + -- separation scale: a positive lower bound on all pairwise distances + obtain ⟨ε₁, hε₁, h₁⟩ := exists_pos_lower_bound_of_finset + ((S.offDiag).image (fun p => dist p.1 p.2)) (by + intro x hx + obtain ⟨p, hp, rfl⟩ := Finset.mem_image.mp hx + exact dist_pos.mpr (Finset.mem_offDiag.mp hp).2.2) + -- strip margin: a positive lower bound on all distances to the strip boundary + obtain ⟨ε₂, hε₂, h₂⟩ := exists_pos_lower_bound_of_finset + (S.image (fun z => min z.re (1 - z.re))) (by + intro x hx + obtain ⟨z, hz, rfl⟩ := Finset.mem_image.mp hx + exact lt_min (hstrip z hz).1 (by linarith [(hstrip z hz).2])) + refine ⟨min (ε₁ / 3) (ε₂ / 2), lt_min (by positivity) (by positivity), ?_, ?_⟩ + · -- pairwise disjointness: r + r <= 2 ε₁ / 3 < ε₁ <= dist z w + intro z hz w hw hzw + apply Metric.closedBall_disjoint_closedBall + have hd : ε₁ ≤ dist z w := + h₁ _ (Finset.mem_image.mpr ⟨(z, w), Finset.mem_offDiag.mpr ⟨hz, hw, hzw⟩, rfl⟩) + have hm := min_le_left (ε₁ / 3) (ε₂ / 2) + linarith + · -- strip containment: |s.re - z.re| <= r <= ε₂ / 2 < min z.re (1 - z.re) + intro z hz s hs + have hd : dist s z ≤ min (ε₁ / 3) (ε₂ / 2) := Metric.mem_closedBall.mp hs + have hm : ε₂ ≤ min z.re (1 - z.re) := h₂ _ (Finset.mem_image.mpr ⟨z, hz, rfl⟩) + have hre := abs_le.mp (abs_re_sub_le_dist s z) + have hmr := min_le_right (ε₁ / 3) (ε₂ / 2) + have hz1 := min_le_left z.re (1 - z.re) + have hz2 := min_le_right z.re (1 - z.re) + constructor <;> linarith [hre.1, hre.2] + +end Quasicrystal + +-- conjecture1_proved = False diff --git a/telperion/examples/quasicrystal/lean/OfflineDiscsInstances.lean b/telperion/examples/quasicrystal/lean/OfflineDiscsInstances.lean new file mode 100644 index 000000000..b451f2b0a --- /dev/null +++ b/telperion/examples/quasicrystal/lean/OfflineDiscsInstances.lean @@ -0,0 +1,243 @@ +/- telperion 0.1.6 | family OfflineDiscsInstances | input-hash 84e0fedfd1b01edb + 15 theorems, 2 generation-time self-checks passed. + Regenerate & verify: forge diff --family --manifest --check + DO NOT EDIT BY HAND — edits are flagged by the regeneration diff. -/ + +import Mathlib +import OfflineDiscs + +namespace OfflineDiscsInstances + +/-- Isolation instance `offline_discs_online_pair`: 2 explicitly given point(s) of the open + critical strip, with the rational radius `r = (1 / 50)`. Certified separation + `min dist² = 741321/15625` and strip margin `min (re, 1 - re) = 1/2`, + both strictly beating `(2r)² = 1/625` resp. `r`. + conjecture1_proved = False — the points are INPUT, not a claim about ζ. -/ +noncomputable def offline_discs_online_pair_p0 : ℂ := ⟨((1 / 2)), ((7067 / 500))⟩ +noncomputable def offline_discs_online_pair_p1 : ℂ := ⟨((1 / 2)), ((10511 / 500))⟩ + +noncomputable def offline_discs_online_pair_S : Finset ℂ := {offline_discs_online_pair_p0, offline_discs_online_pair_p1} + +/-- Pair (0,1): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_online_pair_pair_0_1 : + Disjoint (Metric.closedBall offline_discs_online_pair_p0 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_online_pair_p1 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_online_pair_p0, offline_discs_online_pair_p1, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Point 0: the closed disc of radius `(1 / 50)` about `offline_discs_online_pair_p0` + (real part `(1 / 2)`) stays inside the OPEN strip. -/ +theorem offline_discs_online_pair_strip_0 : + Metric.closedBall offline_discs_online_pair_p0 (((1 / 50)) : ℝ) ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1} := by + intro s hs + have hd : dist s offline_discs_online_pair_p0 ≤ (((1 / 50)) : ℝ) := Metric.mem_closedBall.mp hs + have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s offline_discs_online_pair_p0) + have hz : (offline_discs_online_pair_p0).re = (((1 / 2)) : ℝ) := by + simp only [offline_discs_online_pair_p0] + rw [hz] at hre + exact ⟨by linarith [hre.1], by linarith [hre.2]⟩ + +/-- Point 1: the closed disc of radius `(1 / 50)` about `offline_discs_online_pair_p1` + (real part `(1 / 2)`) stays inside the OPEN strip. -/ +theorem offline_discs_online_pair_strip_1 : + Metric.closedBall offline_discs_online_pair_p1 (((1 / 50)) : ℝ) ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1} := by + intro s hs + have hd : dist s offline_discs_online_pair_p1 ≤ (((1 / 50)) : ℝ) := Metric.mem_closedBall.mp hs + have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s offline_discs_online_pair_p1) + have hz : (offline_discs_online_pair_p1).re = (((1 / 2)) : ℝ) := by + simp only [offline_discs_online_pair_p1] + rw [hz] at hre + exact ⟨by linarith [hre.1], by linarith [hre.2]⟩ + +/-- **Isolation instance** (offline_discs_online_pair): the concrete witness for the registry node + `MM_offline_disjoint_discs` at these 2 point(s) — radius `r = (1 / 50)` makes the + closed discs pairwise disjoint and keeps each inside the open critical strip. + conjecture1_proved = False. -/ +theorem offline_discs_online_pair : + ∃ r : ℝ, 0 < r ∧ + (∀ z ∈ offline_discs_online_pair_S, ∀ w ∈ offline_discs_online_pair_S, z ≠ w → + Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧ + (∀ z ∈ offline_discs_online_pair_S, Metric.closedBall z r ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1}) := by + refine ⟨(((1 / 50)) : ℝ), by norm_num, ?_, ?_⟩ + · intro z hz w hw hzw + simp only [offline_discs_online_pair_S, Finset.mem_insert, Finset.mem_singleton] at hz hw + rcases hz with rfl | rfl <;> rcases hw with rfl | rfl <;> + first + | exact absurd rfl hzw + | exact offline_discs_online_pair_pair_0_1 + | exact offline_discs_online_pair_pair_0_1.symm + · intro z hz + simp only [offline_discs_online_pair_S, Finset.mem_insert, Finset.mem_singleton] at hz + rcases hz with rfl | rfl + · exact offline_discs_online_pair_strip_0 + · exact offline_discs_online_pair_strip_1 + +example : ∃ r : ℝ, 0 < r ∧ + (∀ z ∈ offline_discs_online_pair_S, ∀ w ∈ offline_discs_online_pair_S, z ≠ w → + Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧ + (∀ z ∈ offline_discs_online_pair_S, Metric.closedBall z r ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1}) := offline_discs_online_pair + +/-- Isolation instance `offline_discs_offline_bank`: 4 explicitly given point(s) of the open + critical strip, with the rational radius `r = (1 / 50)`. Certified separation + `min dist² = 1/25` and strip margin `min (re, 1 - re) = 2/5`, + both strictly beating `(2r)² = 1/625` resp. `r`. + conjecture1_proved = False — the points are INPUT, not a claim about ζ. -/ +noncomputable def offline_discs_offline_bank_p0 : ℂ := ⟨((1 / 2)), ((7067 / 500))⟩ +noncomputable def offline_discs_offline_bank_p1 : ℂ := ⟨((1 / 2)), ((10511 / 500))⟩ +noncomputable def offline_discs_offline_bank_p2 : ℂ := ⟨((2 / 5)), ((2501 / 100))⟩ +noncomputable def offline_discs_offline_bank_p3 : ℂ := ⟨((3 / 5)), ((2501 / 100))⟩ + +noncomputable def offline_discs_offline_bank_S : Finset ℂ := {offline_discs_offline_bank_p0, offline_discs_offline_bank_p1, offline_discs_offline_bank_p2, offline_discs_offline_bank_p3} + +/-- Pair (0,1): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_offline_bank_pair_0_1 : + Disjoint (Metric.closedBall offline_discs_offline_bank_p0 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_offline_bank_p1 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_offline_bank_p0, offline_discs_offline_bank_p1, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Pair (0,2): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_offline_bank_pair_0_2 : + Disjoint (Metric.closedBall offline_discs_offline_bank_p0 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_offline_bank_p2 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_offline_bank_p0, offline_discs_offline_bank_p2, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Pair (0,3): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_offline_bank_pair_0_3 : + Disjoint (Metric.closedBall offline_discs_offline_bank_p0 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_offline_bank_p3 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_offline_bank_p0, offline_discs_offline_bank_p3, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Pair (1,2): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_offline_bank_pair_1_2 : + Disjoint (Metric.closedBall offline_discs_offline_bank_p1 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_offline_bank_p2 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_offline_bank_p1, offline_discs_offline_bank_p2, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Pair (1,3): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_offline_bank_pair_1_3 : + Disjoint (Metric.closedBall offline_discs_offline_bank_p1 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_offline_bank_p3 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_offline_bank_p1, offline_discs_offline_bank_p3, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Pair (2,3): `(2·(1 / 50))² < dist²`, so the closed discs are disjoint. -/ +theorem offline_discs_offline_bank_pair_2_3 : + Disjoint (Metric.closedBall offline_discs_offline_bank_p2 (((1 / 50)) : ℝ)) + (Metric.closedBall offline_discs_offline_bank_p3 (((1 / 50)) : ℝ)) := by + apply Metric.closedBall_disjoint_closedBall + rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)] + simp only [offline_discs_offline_bank_p2, offline_discs_offline_bank_p3, Complex.normSq_apply, + Complex.sub_re, Complex.sub_im] + norm_num + +/-- Point 0: the closed disc of radius `(1 / 50)` about `offline_discs_offline_bank_p0` + (real part `(1 / 2)`) stays inside the OPEN strip. -/ +theorem offline_discs_offline_bank_strip_0 : + Metric.closedBall offline_discs_offline_bank_p0 (((1 / 50)) : ℝ) ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1} := by + intro s hs + have hd : dist s offline_discs_offline_bank_p0 ≤ (((1 / 50)) : ℝ) := Metric.mem_closedBall.mp hs + have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s offline_discs_offline_bank_p0) + have hz : (offline_discs_offline_bank_p0).re = (((1 / 2)) : ℝ) := by + simp only [offline_discs_offline_bank_p0] + rw [hz] at hre + exact ⟨by linarith [hre.1], by linarith [hre.2]⟩ + +/-- Point 1: the closed disc of radius `(1 / 50)` about `offline_discs_offline_bank_p1` + (real part `(1 / 2)`) stays inside the OPEN strip. -/ +theorem offline_discs_offline_bank_strip_1 : + Metric.closedBall offline_discs_offline_bank_p1 (((1 / 50)) : ℝ) ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1} := by + intro s hs + have hd : dist s offline_discs_offline_bank_p1 ≤ (((1 / 50)) : ℝ) := Metric.mem_closedBall.mp hs + have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s offline_discs_offline_bank_p1) + have hz : (offline_discs_offline_bank_p1).re = (((1 / 2)) : ℝ) := by + simp only [offline_discs_offline_bank_p1] + rw [hz] at hre + exact ⟨by linarith [hre.1], by linarith [hre.2]⟩ + +/-- Point 2: the closed disc of radius `(1 / 50)` about `offline_discs_offline_bank_p2` + (real part `(2 / 5)`) stays inside the OPEN strip. -/ +theorem offline_discs_offline_bank_strip_2 : + Metric.closedBall offline_discs_offline_bank_p2 (((1 / 50)) : ℝ) ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1} := by + intro s hs + have hd : dist s offline_discs_offline_bank_p2 ≤ (((1 / 50)) : ℝ) := Metric.mem_closedBall.mp hs + have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s offline_discs_offline_bank_p2) + have hz : (offline_discs_offline_bank_p2).re = (((2 / 5)) : ℝ) := by + simp only [offline_discs_offline_bank_p2] + rw [hz] at hre + exact ⟨by linarith [hre.1], by linarith [hre.2]⟩ + +/-- Point 3: the closed disc of radius `(1 / 50)` about `offline_discs_offline_bank_p3` + (real part `(3 / 5)`) stays inside the OPEN strip. -/ +theorem offline_discs_offline_bank_strip_3 : + Metric.closedBall offline_discs_offline_bank_p3 (((1 / 50)) : ℝ) ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1} := by + intro s hs + have hd : dist s offline_discs_offline_bank_p3 ≤ (((1 / 50)) : ℝ) := Metric.mem_closedBall.mp hs + have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s offline_discs_offline_bank_p3) + have hz : (offline_discs_offline_bank_p3).re = (((3 / 5)) : ℝ) := by + simp only [offline_discs_offline_bank_p3] + rw [hz] at hre + exact ⟨by linarith [hre.1], by linarith [hre.2]⟩ + +/-- **Isolation instance** (offline_discs_offline_bank): the concrete witness for the registry node + `MM_offline_disjoint_discs` at these 4 point(s) — radius `r = (1 / 50)` makes the + closed discs pairwise disjoint and keeps each inside the open critical strip. + conjecture1_proved = False. -/ +theorem offline_discs_offline_bank : + ∃ r : ℝ, 0 < r ∧ + (∀ z ∈ offline_discs_offline_bank_S, ∀ w ∈ offline_discs_offline_bank_S, z ≠ w → + Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧ + (∀ z ∈ offline_discs_offline_bank_S, Metric.closedBall z r ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1}) := by + refine ⟨(((1 / 50)) : ℝ), by norm_num, ?_, ?_⟩ + · intro z hz w hw hzw + simp only [offline_discs_offline_bank_S, Finset.mem_insert, Finset.mem_singleton] at hz hw + rcases hz with rfl | rfl | rfl | rfl <;> rcases hw with rfl | rfl | rfl | rfl <;> + first + | exact absurd rfl hzw + | exact offline_discs_offline_bank_pair_0_1 + | exact offline_discs_offline_bank_pair_0_1.symm + | exact offline_discs_offline_bank_pair_0_2 + | exact offline_discs_offline_bank_pair_0_2.symm + | exact offline_discs_offline_bank_pair_0_3 + | exact offline_discs_offline_bank_pair_0_3.symm + | exact offline_discs_offline_bank_pair_1_2 + | exact offline_discs_offline_bank_pair_1_2.symm + | exact offline_discs_offline_bank_pair_1_3 + | exact offline_discs_offline_bank_pair_1_3.symm + | exact offline_discs_offline_bank_pair_2_3 + | exact offline_discs_offline_bank_pair_2_3.symm + · intro z hz + simp only [offline_discs_offline_bank_S, Finset.mem_insert, Finset.mem_singleton] at hz + rcases hz with rfl | rfl | rfl | rfl + · exact offline_discs_offline_bank_strip_0 + · exact offline_discs_offline_bank_strip_1 + · exact offline_discs_offline_bank_strip_2 + · exact offline_discs_offline_bank_strip_3 + +example : ∃ r : ℝ, 0 < r ∧ + (∀ z ∈ offline_discs_offline_bank_S, ∀ w ∈ offline_discs_offline_bank_S, z ≠ w → + Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧ + (∀ z ∈ offline_discs_offline_bank_S, Metric.closedBall z r ⊆ {s : ℂ | 0 < s.re ∧ s.re < 1}) := offline_discs_offline_bank + +end OfflineDiscsInstances diff --git a/telperion/examples/quasicrystal/lean/SelfInversiveOfflineInstances.lean b/telperion/examples/quasicrystal/lean/SelfInversiveOfflineInstances.lean new file mode 100644 index 000000000..b29c062c0 --- /dev/null +++ b/telperion/examples/quasicrystal/lean/SelfInversiveOfflineInstances.lean @@ -0,0 +1,305 @@ +/- telperion 0.1.6 | family SelfInversiveOfflineInstances | input-hash d198bd17e6d2864e + 18 theorems, 3 generation-time self-checks passed. + Regenerate & verify: forge diff --family --manifest --check + DO NOT EDIT BY HAND — edits are flagged by the regeneration diff. -/ + +import Mathlib +import TwoFreqRigidity + +namespace SelfInversiveOfflineInstances + +/-- Concrete two-frequency sum `F(x) = c₁·e^{iλ₁x} + c₂·e^{iλ₂x}` with REAL radical + coefficients `c₁ = 1·√1`, `c₂ = (-(1 / 2))·√2` (so `|c₁|² = 1`, + `|c₂|² = 1/2`, EXACT) and frequencies `λ₁ = (0)`, `λ₂ = (-(Real.log 2))`. -/ +noncomputable def euler_factor_p2_offline_c1 : ℂ := ((1 * Real.sqrt 1 : ℝ) : ℂ) +noncomputable def euler_factor_p2_offline_c2 : ℂ := (((-(1 / 2)) * Real.sqrt 2 : ℝ) : ℂ) + +/-- **Off-line refutation** (euler_factor_p2_offline): since `|c₁|² = 1 ≠ 1/2 = |c₂|²` + EXACTLY, `‖c₁‖ ≠ ‖c₂‖`, so by the `.mp` direction of `Quasicrystal.twoFreq_realRooted_iff` + the two-frequency sum is NOT real-rooted — some zero has nonzero imaginary part (in + fact every zero sits on the single line `Im x = −(1/w)·log|c₁/c₂| ≠ 0`). Reverse-Dyson + R3(n=2) negative control: unequal modulus is exactly the off-line signature. + conjecture1_proved = False. -/ +theorem euler_factor_p2_offline : + ¬ (∀ x : ℂ, Quasicrystal.twoFreq euler_factor_p2_offline_c1 euler_factor_p2_offline_c2 (0) (-(Real.log 2)) x = 0 → x.im = 0) := by + intro hall + have hq1 : (0 : ℝ) < 1 := by norm_num + have hq2 : (0 : ℝ) < 2 := by norm_num + have hc1 : euler_factor_p2_offline_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1)) + have hc2 : euler_factor_p2_offline_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2)) + have hlam : ((0) : ℝ) ≠ (-(Real.log 2)) := by + have hlog2 := Real.log_pos (by norm_num : (1 : ℝ) < 2) + intro h + linarith + have hn := (Quasicrystal.twoFreq_realRooted_iff euler_factor_p2_offline_c1 euler_factor_p2_offline_c2 (0) (-(Real.log 2)) + hc1 hc2 hlam).mp hall + -- the kernel checks the EXACT normSq inequality 1 ≠ 1/2 + have hsq : ‖euler_factor_p2_offline_c1‖ ^ 2 ≠ ‖euler_factor_p2_offline_c2‖ ^ 2 := by + unfold euler_factor_p2_offline_c1 euler_factor_p2_offline_c2 + rw [Complex.norm_real, Complex.norm_real, Real.norm_eq_abs, Real.norm_eq_abs, + sq_abs, sq_abs, mul_pow, mul_pow, Real.sq_sqrt hq1.le, Real.sq_sqrt hq2.le] + norm_num + exact hsq (by rw [hn]) + +/-- **Explicit off-line witness** (euler_factor_p2_offline_witness): `x = i/2` is a zero of the p = 2 + Euler-factor section `1 − (1/√2)·e^{−i (log 2) x}`, since + `e^{−i (log 2) (i/2)} = e^{(log 2)/2} = √2`. `Im (i/2) = 1/2`: the uniform + off-line displacement (the zeros are `s = 2πik/log 2`, i.e. `Re s = 0`). + conjecture1_proved = False. -/ +theorem euler_factor_p2_offline_witness : + Quasicrystal.twoFreq euler_factor_p2_offline_c1 euler_factor_p2_offline_c2 (0) (-(Real.log 2)) (Complex.I / 2) = 0 := by + have hq1 : (0 : ℝ) < 1 := by norm_num + have hq2 : (0 : ℝ) < 2 := by norm_num + have hc1 : euler_factor_p2_offline_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1)) + have hc2 : euler_factor_p2_offline_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2)) + rw [Quasicrystal.twoFreq_eq_zero_iff _ _ _ _ _ hc1 hc2] + have harg : (((-(Real.log 2)) - 0 : ℝ) : ℂ) * (Complex.I / 2) * Complex.I + = ((Real.log 2 / 2 : ℝ) : ℂ) := by + push_cast + ring_nf + rw [Complex.I_sq] + ring + rw [harg, ← Complex.ofReal_exp, Real.exp_half, Real.exp_log hq2] + unfold euler_factor_p2_offline_c1 euler_factor_p2_offline_c2 + rw [← Complex.ofReal_neg, ← Complex.ofReal_div, Complex.ofReal_inj, Real.sqrt_one] + have hs : Real.sqrt 2 ≠ 0 := Real.sqrt_ne_zero'.mpr hq2 + have hsq : Real.sqrt 2 * Real.sqrt 2 = 2 := Real.mul_self_sqrt hq2.le + field_simp + linarith [hsq] + +/-- The witness is off the real line: `Im (i/2) = 1/2 ≠ 0`, so `euler_factor_p2_offline` also follows + directly from `euler_factor_p2_offline_witness` (second, independent route). -/ +theorem euler_factor_p2_offline_of_witness : + ¬ (∀ x : ℂ, Quasicrystal.twoFreq euler_factor_p2_offline_c1 euler_factor_p2_offline_c2 (0) (-(Real.log 2)) x = 0 → x.im = 0) := by + intro hall + have h := hall (Complex.I / 2) euler_factor_p2_offline_witness + simp [Complex.div_ofNat_im] at h + +/-- The p = 2 Euler-factor coefficients in the registry's spelling: + `1·√1 = 1` and `(-(1 / 2))·√2 = -(1/√2)` (since `√2·√2 = 2`). -/ +theorem euler_factor_p2_offline_c1_eq : euler_factor_p2_offline_c1 = 1 := by + unfold euler_factor_p2_offline_c1 + rw [Real.sqrt_one] + norm_num + +theorem euler_factor_p2_offline_c2_eq : euler_factor_p2_offline_c2 = ((-(1 / Real.sqrt 2) : ℝ) : ℂ) := by + unfold euler_factor_p2_offline_c2 + have hq : (0 : ℝ) < 2 := by norm_num + have hs : Real.sqrt 2 ≠ 0 := Real.sqrt_ne_zero'.mpr hq + have hsq : Real.sqrt 2 * Real.sqrt 2 = 2 := Real.mul_self_sqrt hq.le + rw [Complex.ofReal_inj] + field_simp + linarith [hsq] + +/-- **The registry-verbatim form** (euler_factor_p2_offline_node): the p = 2 Euler-factor section + `twoFreq 1 (-(1/√2)) 0 (-log 2)` is NOT real-rooted. Identical content to + `euler_factor_p2_offline`, restated with the coefficients in the mission-registry spelling. + conjecture1_proved = False. -/ +theorem euler_factor_p2_offline_node : + ¬ (∀ x : ℂ, + Quasicrystal.twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2)) x = 0 + → x.im = 0) := by + rw [← euler_factor_p2_offline_c1_eq, ← euler_factor_p2_offline_c2_eq] + exact euler_factor_p2_offline + +/-- Concrete two-frequency sum `F(x) = c₁·e^{iλ₁x} + c₂·e^{iλ₂x}` with REAL radical + coefficients `c₁ = 1·√1`, `c₂ = (-(1 / 3))·√3` (so `|c₁|² = 1`, + `|c₂|² = 1/3`, EXACT) and frequencies `λ₁ = (0)`, `λ₂ = (-(Real.log 3))`. -/ +noncomputable def euler_factor_p3_offline_c1 : ℂ := ((1 * Real.sqrt 1 : ℝ) : ℂ) +noncomputable def euler_factor_p3_offline_c2 : ℂ := (((-(1 / 3)) * Real.sqrt 3 : ℝ) : ℂ) + +/-- **Off-line refutation** (euler_factor_p3_offline): since `|c₁|² = 1 ≠ 1/3 = |c₂|²` + EXACTLY, `‖c₁‖ ≠ ‖c₂‖`, so by the `.mp` direction of `Quasicrystal.twoFreq_realRooted_iff` + the two-frequency sum is NOT real-rooted — some zero has nonzero imaginary part (in + fact every zero sits on the single line `Im x = −(1/w)·log|c₁/c₂| ≠ 0`). Reverse-Dyson + R3(n=2) negative control: unequal modulus is exactly the off-line signature. + conjecture1_proved = False. -/ +theorem euler_factor_p3_offline : + ¬ (∀ x : ℂ, Quasicrystal.twoFreq euler_factor_p3_offline_c1 euler_factor_p3_offline_c2 (0) (-(Real.log 3)) x = 0 → x.im = 0) := by + intro hall + have hq1 : (0 : ℝ) < 1 := by norm_num + have hq2 : (0 : ℝ) < 3 := by norm_num + have hc1 : euler_factor_p3_offline_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1)) + have hc2 : euler_factor_p3_offline_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2)) + have hlam : ((0) : ℝ) ≠ (-(Real.log 3)) := by + have hlog3 := Real.log_pos (by norm_num : (1 : ℝ) < 3) + intro h + linarith + have hn := (Quasicrystal.twoFreq_realRooted_iff euler_factor_p3_offline_c1 euler_factor_p3_offline_c2 (0) (-(Real.log 3)) + hc1 hc2 hlam).mp hall + -- the kernel checks the EXACT normSq inequality 1 ≠ 1/3 + have hsq : ‖euler_factor_p3_offline_c1‖ ^ 2 ≠ ‖euler_factor_p3_offline_c2‖ ^ 2 := by + unfold euler_factor_p3_offline_c1 euler_factor_p3_offline_c2 + rw [Complex.norm_real, Complex.norm_real, Real.norm_eq_abs, Real.norm_eq_abs, + sq_abs, sq_abs, mul_pow, mul_pow, Real.sq_sqrt hq1.le, Real.sq_sqrt hq2.le] + norm_num + exact hsq (by rw [hn]) + +/-- **Explicit off-line witness** (euler_factor_p3_offline_witness): `x = i/2` is a zero of the p = 3 + Euler-factor section `1 − (1/√3)·e^{−i (log 3) x}`, since + `e^{−i (log 3) (i/2)} = e^{(log 3)/2} = √3`. `Im (i/2) = 1/2`: the uniform + off-line displacement (the zeros are `s = 2πik/log 3`, i.e. `Re s = 0`). + conjecture1_proved = False. -/ +theorem euler_factor_p3_offline_witness : + Quasicrystal.twoFreq euler_factor_p3_offline_c1 euler_factor_p3_offline_c2 (0) (-(Real.log 3)) (Complex.I / 2) = 0 := by + have hq1 : (0 : ℝ) < 1 := by norm_num + have hq2 : (0 : ℝ) < 3 := by norm_num + have hc1 : euler_factor_p3_offline_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1)) + have hc2 : euler_factor_p3_offline_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2)) + rw [Quasicrystal.twoFreq_eq_zero_iff _ _ _ _ _ hc1 hc2] + have harg : (((-(Real.log 3)) - 0 : ℝ) : ℂ) * (Complex.I / 2) * Complex.I + = ((Real.log 3 / 2 : ℝ) : ℂ) := by + push_cast + ring_nf + rw [Complex.I_sq] + ring + rw [harg, ← Complex.ofReal_exp, Real.exp_half, Real.exp_log hq2] + unfold euler_factor_p3_offline_c1 euler_factor_p3_offline_c2 + rw [← Complex.ofReal_neg, ← Complex.ofReal_div, Complex.ofReal_inj, Real.sqrt_one] + have hs : Real.sqrt 3 ≠ 0 := Real.sqrt_ne_zero'.mpr hq2 + have hsq : Real.sqrt 3 * Real.sqrt 3 = 3 := Real.mul_self_sqrt hq2.le + field_simp + linarith [hsq] + +/-- The witness is off the real line: `Im (i/2) = 1/2 ≠ 0`, so `euler_factor_p3_offline` also follows + directly from `euler_factor_p3_offline_witness` (second, independent route). -/ +theorem euler_factor_p3_offline_of_witness : + ¬ (∀ x : ℂ, Quasicrystal.twoFreq euler_factor_p3_offline_c1 euler_factor_p3_offline_c2 (0) (-(Real.log 3)) x = 0 → x.im = 0) := by + intro hall + have h := hall (Complex.I / 2) euler_factor_p3_offline_witness + simp [Complex.div_ofNat_im] at h + +/-- The p = 3 Euler-factor coefficients in the registry's spelling: + `1·√1 = 1` and `(-(1 / 3))·√3 = -(1/√3)` (since `√3·√3 = 3`). -/ +theorem euler_factor_p3_offline_c1_eq : euler_factor_p3_offline_c1 = 1 := by + unfold euler_factor_p3_offline_c1 + rw [Real.sqrt_one] + norm_num + +theorem euler_factor_p3_offline_c2_eq : euler_factor_p3_offline_c2 = ((-(1 / Real.sqrt 3) : ℝ) : ℂ) := by + unfold euler_factor_p3_offline_c2 + have hq : (0 : ℝ) < 3 := by norm_num + have hs : Real.sqrt 3 ≠ 0 := Real.sqrt_ne_zero'.mpr hq + have hsq : Real.sqrt 3 * Real.sqrt 3 = 3 := Real.mul_self_sqrt hq.le + rw [Complex.ofReal_inj] + field_simp + linarith [hsq] + +/-- **The registry-verbatim form** (euler_factor_p3_offline_node): the p = 3 Euler-factor section + `twoFreq 1 (-(1/√3)) 0 (-log 3)` is NOT real-rooted. Identical content to + `euler_factor_p3_offline`, restated with the coefficients in the mission-registry spelling. + conjecture1_proved = False. -/ +theorem euler_factor_p3_offline_node : + ¬ (∀ x : ℂ, + Quasicrystal.twoFreq 1 ((-(1 / Real.sqrt 3) : ℝ) : ℂ) 0 (-(Real.log 3)) x = 0 + → x.im = 0) := by + rw [← euler_factor_p3_offline_c1_eq, ← euler_factor_p3_offline_c2_eq] + exact euler_factor_p3_offline + +/-- Concrete two-frequency sum `F(x) = c₁·e^{iλ₁x} + c₂·e^{iλ₂x}` with REAL radical + coefficients `c₁ = 1·√1`, `c₂ = (-(1 / 5))·√5` (so `|c₁|² = 1`, + `|c₂|² = 1/5`, EXACT) and frequencies `λ₁ = (0)`, `λ₂ = (-(Real.log 5))`. -/ +noncomputable def euler_factor_p5_offline_c1 : ℂ := ((1 * Real.sqrt 1 : ℝ) : ℂ) +noncomputable def euler_factor_p5_offline_c2 : ℂ := (((-(1 / 5)) * Real.sqrt 5 : ℝ) : ℂ) + +/-- **Off-line refutation** (euler_factor_p5_offline): since `|c₁|² = 1 ≠ 1/5 = |c₂|²` + EXACTLY, `‖c₁‖ ≠ ‖c₂‖`, so by the `.mp` direction of `Quasicrystal.twoFreq_realRooted_iff` + the two-frequency sum is NOT real-rooted — some zero has nonzero imaginary part (in + fact every zero sits on the single line `Im x = −(1/w)·log|c₁/c₂| ≠ 0`). Reverse-Dyson + R3(n=2) negative control: unequal modulus is exactly the off-line signature. + conjecture1_proved = False. -/ +theorem euler_factor_p5_offline : + ¬ (∀ x : ℂ, Quasicrystal.twoFreq euler_factor_p5_offline_c1 euler_factor_p5_offline_c2 (0) (-(Real.log 5)) x = 0 → x.im = 0) := by + intro hall + have hq1 : (0 : ℝ) < 1 := by norm_num + have hq2 : (0 : ℝ) < 5 := by norm_num + have hc1 : euler_factor_p5_offline_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1)) + have hc2 : euler_factor_p5_offline_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2)) + have hlam : ((0) : ℝ) ≠ (-(Real.log 5)) := by + have hlog5 := Real.log_pos (by norm_num : (1 : ℝ) < 5) + intro h + linarith + have hn := (Quasicrystal.twoFreq_realRooted_iff euler_factor_p5_offline_c1 euler_factor_p5_offline_c2 (0) (-(Real.log 5)) + hc1 hc2 hlam).mp hall + -- the kernel checks the EXACT normSq inequality 1 ≠ 1/5 + have hsq : ‖euler_factor_p5_offline_c1‖ ^ 2 ≠ ‖euler_factor_p5_offline_c2‖ ^ 2 := by + unfold euler_factor_p5_offline_c1 euler_factor_p5_offline_c2 + rw [Complex.norm_real, Complex.norm_real, Real.norm_eq_abs, Real.norm_eq_abs, + sq_abs, sq_abs, mul_pow, mul_pow, Real.sq_sqrt hq1.le, Real.sq_sqrt hq2.le] + norm_num + exact hsq (by rw [hn]) + +/-- **Explicit off-line witness** (euler_factor_p5_offline_witness): `x = i/2` is a zero of the p = 5 + Euler-factor section `1 − (1/√5)·e^{−i (log 5) x}`, since + `e^{−i (log 5) (i/2)} = e^{(log 5)/2} = √5`. `Im (i/2) = 1/2`: the uniform + off-line displacement (the zeros are `s = 2πik/log 5`, i.e. `Re s = 0`). + conjecture1_proved = False. -/ +theorem euler_factor_p5_offline_witness : + Quasicrystal.twoFreq euler_factor_p5_offline_c1 euler_factor_p5_offline_c2 (0) (-(Real.log 5)) (Complex.I / 2) = 0 := by + have hq1 : (0 : ℝ) < 1 := by norm_num + have hq2 : (0 : ℝ) < 5 := by norm_num + have hc1 : euler_factor_p5_offline_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1)) + have hc2 : euler_factor_p5_offline_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr + (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2)) + rw [Quasicrystal.twoFreq_eq_zero_iff _ _ _ _ _ hc1 hc2] + have harg : (((-(Real.log 5)) - 0 : ℝ) : ℂ) * (Complex.I / 2) * Complex.I + = ((Real.log 5 / 2 : ℝ) : ℂ) := by + push_cast + ring_nf + rw [Complex.I_sq] + ring + rw [harg, ← Complex.ofReal_exp, Real.exp_half, Real.exp_log hq2] + unfold euler_factor_p5_offline_c1 euler_factor_p5_offline_c2 + rw [← Complex.ofReal_neg, ← Complex.ofReal_div, Complex.ofReal_inj, Real.sqrt_one] + have hs : Real.sqrt 5 ≠ 0 := Real.sqrt_ne_zero'.mpr hq2 + have hsq : Real.sqrt 5 * Real.sqrt 5 = 5 := Real.mul_self_sqrt hq2.le + field_simp + linarith [hsq] + +/-- The witness is off the real line: `Im (i/2) = 1/2 ≠ 0`, so `euler_factor_p5_offline` also follows + directly from `euler_factor_p5_offline_witness` (second, independent route). -/ +theorem euler_factor_p5_offline_of_witness : + ¬ (∀ x : ℂ, Quasicrystal.twoFreq euler_factor_p5_offline_c1 euler_factor_p5_offline_c2 (0) (-(Real.log 5)) x = 0 → x.im = 0) := by + intro hall + have h := hall (Complex.I / 2) euler_factor_p5_offline_witness + simp [Complex.div_ofNat_im] at h + +/-- The p = 5 Euler-factor coefficients in the registry's spelling: + `1·√1 = 1` and `(-(1 / 5))·√5 = -(1/√5)` (since `√5·√5 = 5`). -/ +theorem euler_factor_p5_offline_c1_eq : euler_factor_p5_offline_c1 = 1 := by + unfold euler_factor_p5_offline_c1 + rw [Real.sqrt_one] + norm_num + +theorem euler_factor_p5_offline_c2_eq : euler_factor_p5_offline_c2 = ((-(1 / Real.sqrt 5) : ℝ) : ℂ) := by + unfold euler_factor_p5_offline_c2 + have hq : (0 : ℝ) < 5 := by norm_num + have hs : Real.sqrt 5 ≠ 0 := Real.sqrt_ne_zero'.mpr hq + have hsq : Real.sqrt 5 * Real.sqrt 5 = 5 := Real.mul_self_sqrt hq.le + rw [Complex.ofReal_inj] + field_simp + linarith [hsq] + +/-- **The registry-verbatim form** (euler_factor_p5_offline_node): the p = 5 Euler-factor section + `twoFreq 1 (-(1/√5)) 0 (-log 5)` is NOT real-rooted. Identical content to + `euler_factor_p5_offline`, restated with the coefficients in the mission-registry spelling. + conjecture1_proved = False. -/ +theorem euler_factor_p5_offline_node : + ¬ (∀ x : ℂ, + Quasicrystal.twoFreq 1 ((-(1 / Real.sqrt 5) : ℝ) : ℂ) 0 (-(Real.log 5)) x = 0 + → x.im = 0) := by + rw [← euler_factor_p5_offline_c1_eq, ← euler_factor_p5_offline_c2_eq] + exact euler_factor_p5_offline + +end SelfInversiveOfflineInstances diff --git a/telperion/examples/quasicrystal/lean/SelfInversiveRigidityInstances.lean b/telperion/examples/quasicrystal/lean/SelfInversiveRigidityInstances.lean index ad26a963f..9f3f732bc 100644 --- a/telperion/examples/quasicrystal/lean/SelfInversiveRigidityInstances.lean +++ b/telperion/examples/quasicrystal/lean/SelfInversiveRigidityInstances.lean @@ -1,4 +1,4 @@ -/- telperion 0.1.6 | family SelfInversiveRigidityInstances | input-hash 5732b68f4be985e3 +/- telperion 0.1.6 | family SelfInversiveRigidityInstances | input-hash a763749ebea430d8 2 theorems, 2 generation-time self-checks passed. Regenerate & verify: forge diff --family --manifest --check DO NOT EDIT BY HAND — edits are flagged by the regeneration diff. -/ diff --git a/telperion/examples/quasicrystal/lean/TorusSectionLadder.lean b/telperion/examples/quasicrystal/lean/TorusSectionLadder.lean new file mode 100644 index 000000000..56292175b --- /dev/null +++ b/telperion/examples/quasicrystal/lean/TorusSectionLadder.lean @@ -0,0 +1,78 @@ +/- + TorusSectionLadder.lean -- PROGRAM MIRRORMERE torus-section ladder, rung T1 + (QC_TORUS_SECTION_LADDER_MEMO_2026-09-14, sections 5-6). + + Discharges the two registry nodes of the ladder's T1 track, stated VERBATIM from + telperion/missions/mirrormere/lean/Statements/: + * MM_torus_section_dictionary -- twoFreq (the island's verbatim two-frequency + sum, TwoFreqRigidity.lean:40-42) IS the N = 2 instance of the ladder's section + vocabulary: linearTorusForm 2 ![c₁, c₂] on torusOrbit 2 ![lam₁, lam₂]. + * MM_torus_section_n2_rigidity -- the R3(n=2) rigidity biconditional + (twoFreq_realRooted_iff, TwoFreqRigidity.lean:92-94) restated in ladder + vocabulary; the discharge is the dictionary rewrite followed by the island + theorem. + + GRADE (recorded honestly, per the 2026-09-18 adversarial re-read): BOTH are + vocabulary bridges, not mathematics. The dictionary closes by `simp` (a Fin-2 sum + unfolding: Fin.sum_univ_two + Matrix.cons_val_zero/one); the rigidity rung is a + one-line rewrite into the already-proved island theorem. They are what the + ladder's vocabulary needs and what the registry consumes; they are NOT counted as + wins. The general-N identity expSum = linearTorusForm on torusOrbit is + definitional (rfl) and is recorded below only so the vocabulary anchor is explicit. + + The three definitions MIRROR MMDefs.lean:69-76 verbatim (AUTHORED registry + vocabulary, not island extracts), so the registry's normalized-containment grant + gate matches the theorem lines. + + No RH progress is claimed. conjecture1_proved = False. +-/ +import Mathlib.Data.Fin.VecNotation +import Mathlib.Algebra.BigOperators.Fin +import TwoFreqRigidity + +open Complex + +namespace Quasicrystal + +noncomputable section + +-- ===== MIRROR of MMDefs.lean:69-70 (AUTHORED for the torus-section ladder, T1) ===== +noncomputable def torusOrbit (N : ℕ) (lam : Fin N → ℝ) (x : ℂ) : Fin N → ℂ := + fun j => Complex.exp ((lam j : ℂ) * x * Complex.I) + +-- ===== MIRROR of MMDefs.lean:72-73 ===== +def linearTorusForm (N : ℕ) (c : Fin N → ℂ) (z : Fin N → ℂ) : ℂ := + ∑ j, c j * z j + +-- ===== MIRROR of MMDefs.lean:75-76 ===== +noncomputable def expSum (N : ℕ) (c : Fin N → ℂ) (lam : Fin N → ℝ) (x : ℂ) : ℂ := + ∑ j, c j * Complex.exp ((lam j : ℂ) * x * Complex.I) + +/-- The general-N section identity. DEFINITIONAL (rfl): this is the statement the +2026-09-14 blind audit flagged as zero-content; kept only as the explicit vocabulary +anchor, never as a node. -/ +theorem expSum_eq_linearTorusForm_torusOrbit (N : ℕ) (c : Fin N → ℂ) (lam : Fin N → ℝ) + (x : ℂ) : + expSum N c lam x = linearTorusForm N c (torusOrbit N lam x) := rfl + +/-- **MM_torus_section_dictionary** (statement VERBATIM from the registry). The +island's `twoFreq` is the N = 2 section: a Fin-2 sum unfolding across the two +vocabularies. simp-grade. -/ +theorem torus_section_dictionary (c₁ c₂ : ℂ) (lam₁ lam₂ : ℝ) (x : ℂ) : + twoFreq c₁ c₂ lam₁ lam₂ x + = linearTorusForm 2 ![c₁, c₂] (torusOrbit 2 ![lam₁, lam₂] x) := by + simp [twoFreq, linearTorusForm, torusOrbit, Fin.sum_univ_two] + +/-- **MM_torus_section_n2_rigidity** (statement VERBATIM from the registry). The +N = 2 rung in ladder vocabulary: rewrite through the dictionary and apply the island's +`twoFreq_realRooted_iff`. Pure bridge; the mathematics lives in TwoFreqRigidity. -/ +theorem torus_section_n2_rigidity (c₁ c₂ : ℂ) (lam₁ lam₂ : ℝ) + (hc₁ : c₁ ≠ 0) (hc₂ : c₂ ≠ 0) (hlam : lam₁ ≠ lam₂) : + (∀ x : ℂ, linearTorusForm 2 ![c₁, c₂] (torusOrbit 2 ![lam₁, lam₂] x) = 0 → x.im = 0) + ↔ ‖c₁‖ = ‖c₂‖ := by + simp only [← torus_section_dictionary] + exact twoFreq_realRooted_iff c₁ c₂ lam₁ lam₂ hc₁ hc₂ hlam + +end + +end Quasicrystal diff --git a/telperion/examples/quasicrystal/lean/lakefile.toml b/telperion/examples/quasicrystal/lean/lakefile.toml index 5ac33c945..7725a4353 100644 --- a/telperion/examples/quasicrystal/lean/lakefile.toml +++ b/telperion/examples/quasicrystal/lean/lakefile.toml @@ -1,5 +1,5 @@ name = "Quasicrystal" -defaultTargets = ["LeeYangCore", "KSConstruction", "BoundaryLemmas", "CharacterizationStatements", "TwoFreqRigidity", "RationalFreqReduction", "InvolutionDictionary"] +defaultTargets = ["LeeYangCore", "KSConstruction", "BoundaryLemmas", "CharacterizationStatements", "TwoFreqRigidity", "RationalFreqReduction", "InvolutionDictionary", "TorusSectionLadder", "OfflineDiscs", "OfflineDiscsInstances", "EulerFactorOffline", "SelfInversiveOfflineInstances", "EulerFactorSectionOffline"] # PROGRAM MIRRORMERE (reverse-Dyson) QC-1 island: formalize the Lee-Yang / # stable-polynomial classification frontier. conjecture1_proved = False -- @@ -44,6 +44,15 @@ roots = ["TwoFreqRigidity"] name = "SelfInversiveRigidityInstances" roots = ["SelfInversiveRigidityInstances"] +# Telperion twofreq_offline emitter example (2026-09-18): the COMPLEMENT of the +# rigidity instances -- certified OFF-line displacement of the Euler-factor sections +# 1 - p^(-s) on s = 1/2 + i x (MIRRORMERE ladder rung T2), emitted by +# examples/twofreq_offline/generate.py. In defaultTargets: it is the proof-link artifact +# of MM_euler_factor_section_offline, so a bare `lake build` must compile it. +[[lean_lib]] +name = "EulerFactorSectionOffline" +roots = ["EulerFactorSectionOffline"] + [[lean_lib]] name = "RationalFreqReduction" roots = ["RationalFreqReduction"] @@ -51,3 +60,35 @@ roots = ["RationalFreqReduction"] [[lean_lib]] name = "InvolutionDictionary" roots = ["InvolutionDictionary"] + +# MIRRORMERE torus-section ladder T1 (2026-09-18): the registry nodes +# MM_torus_section_dictionary + MM_torus_section_n2_rigidity, stated verbatim, +# discharged as vocabulary bridges over TwoFreqRigidity (simp-grade; not a win). +[[lean_lib]] +name = "TorusSectionLadder" +roots = ["TorusSectionLadder"] +# PROGRAM MIRRORMERE E4b isolation lemma (2026-09-18): registry node +# MM_offline_disjoint_discs stated verbatim and proved (pure Mathlib metric +# topology). conjecture1_proved = False. +[[lean_lib]] +name = "OfflineDiscs" +roots = ["OfflineDiscs"] + +# Telperion disjoint_discs emitter example (2026-09-18): concrete isolation +# instances applying OfflineDiscs, emitted by examples/disjoint_discs/generate.py. +[[lean_lib]] +name = "OfflineDiscsInstances" +roots = ["OfflineDiscsInstances"] +# MIRRORMERE torus-section ladder rung T2, THE NEGATIVE CONTROL (2026-09-18): registry node +# MM_euler_factor_section_offline -- the p = 2 Euler-factor section is NOT real-rooted, with the +# explicit off-line witness x = i/2. conjecture1_proved = False. +[[lean_lib]] +name = "EulerFactorOffline" +roots = ["EulerFactorOffline"] + +# Telperion selfinversive_rigidity emitter, mode="offline" (2026-09-18): the p = 2, 3, 5 +# Euler-factor sections certified NOT real-rooted from the exact normSq INEQUALITY, emitted by +# examples/selfinversive_rigidity/generate.py (the T2 dogfood; p = 3, 5 are not nodes). +[[lean_lib]] +name = "SelfInversiveOfflineInstances" +roots = ["SelfInversiveOfflineInstances"] diff --git a/telperion/examples/selfinversive_rigidity/generate.py b/telperion/examples/selfinversive_rigidity/generate.py index 121c7381d..4cef63689 100644 --- a/telperion/examples/selfinversive_rigidity/generate.py +++ b/telperion/examples/selfinversive_rigidity/generate.py @@ -12,6 +12,14 @@ Two equal-modulus instances (|c₁|² = |c₂|² exactly ⟹ real-rooted): - c₁ = 3/5 + 4/5 i, c₂ = 1 (|c|² = 1), λ = 1, 2 - c₁ = 1 + i, c₂ = 1 − i (|c|² = 2), λ = 0, 3 + +OFFLINE mode (2026-09-18, MIRRORMERE torus-section ladder T2 / node +MM_euler_factor_section_offline): a SECOND lib `SelfInversiveOfflineInstances.lean` with the +p = 2, 3, 5 Euler-factor sections twoFreq(1, −(1/√p); 0, −log p) — |c₁|² = 1 ≠ 1/p = |c₂|² EXACTLY, +so each is certified NOT real-rooted (.mp of twoFreq_realRooted_iff) and ships the explicit +witness x = i/2. The p = 2 instance is the emitter dogfood of the registry node, whose VERBATIM +statement lives hand-stated in the island's TorusSectionLadder.lean; p = 3, 5 are free extras +and are NOT nodes. conjecture1_proved = False. """ import argparse import sys @@ -35,6 +43,16 @@ _ISLAND = Path(__file__).resolve().parents[1] / "quasicrystal" / "lean" _OUT = _ISLAND / "SelfInversiveRigidityInstances.lean" +# OFFLINE mode: the p-th Euler-factor section on s = 1/2 + ix is twoFreq(1, −(1/√p); 0, −log p), +# and −(1/√p) = (−1/p)·√p in the emitter's r·√q coefficient form. +_OFFLINE_PRIMES = {0: 2, 1: 3, 2: 5} +_OFFLINE_OUT = _ISLAND / "SelfInversiveOfflineInstances.lean" + + +def _euler_spec(p: int) -> dict: + return {"mode": "offline", "c1": "1", "c2": {"rat": f"-1/{p}", "sqrt": p}, + "lam1": "0", "lam2": {"rat": "-1", "log": p}} + def build() -> str: fam = selfinversive_rigidity_family( @@ -53,16 +71,35 @@ def build() -> str: return next(iter(report.files.values())) +def build_offline() -> str: + fam = selfinversive_rigidity_family( + "SelfInversiveOfflineInstances", + GridSpec([("case", [0, 1, 2])]), + lambda pt: f"euler_factor_p{_OFFLINE_PRIMES[pt['case']]}_offline", + spec=lambda pt: _euler_spec(_OFFLINE_PRIMES[pt["case"]]), + ) + report = emit( + certify(fam), + LeanProfile(namespace=("SelfInversiveOfflineInstances",), + imports=("Mathlib", "TwoFreqRigidity")), + [SelfInversiveRigidityEmitter()], + ValidationReport(checks=(("selfinversive_rigidity_offline", True),)), + ) + return next(iter(report.files.values())) + + def main(*, check: bool = False) -> int: - text = build() + outputs = ((_OUT, build()), (_OFFLINE_OUT, build_offline())) if check: - if not _OUT.exists() or _OUT.read_text(encoding="utf-8") != text: - print("DRIFT: SelfInversiveRigidityInstances.lean does not match regeneration") - return 1 - print("check: OK (regeneration matches frozen output byte-for-byte)") + for out, text in outputs: + if not out.exists() or out.read_text(encoding="utf-8") != text: + print(f"DRIFT: {out.name} does not match regeneration") + return 1 + print("check: OK (regeneration matches frozen output byte-for-byte, both libs)") return 0 - _OUT.write_text(text, encoding="utf-8") - print(f"wrote {_OUT} ({len(text)} bytes)") + for out, text in outputs: + out.write_text(text, encoding="utf-8") + print(f"wrote {out} ({len(text)} bytes)") return 0 diff --git a/telperion/examples/twofreq_offline/generate.py b/telperion/examples/twofreq_offline/generate.py new file mode 100644 index 000000000..948f20325 --- /dev/null +++ b/telperion/examples/twofreq_offline/generate.py @@ -0,0 +1,87 @@ +"""Generate the twofreq-offline example: certify -> emit -> write INTO the quasicrystal island. + + python examples/twofreq_offline/generate.py # write the island lib + python examples/twofreq_offline/generate.py --check # drift check (no write) + +The emitted Lean applies `Quasicrystal.twoFreq_realRooted_iff` (the R3(n=2) rigidity +theorem) in its NOT-real-rooted direction, so -- exactly as for the sibling +`selfinversive_rigidity` example -- the instances are written as a NEW lib inside the +quasicrystal island (`EulerFactorSectionOffline.lean`, registered in its lakefile) and the +`twofreq-offline-compiles` CI job builds that lib there. + +Instances: the Euler factor `1 - p^(-s)` read on `s = 1/2 + i x` at p = 2, 3, 5, in both +modes -- the p = 2 and p = 3 rungs in 'displacement' mode (which additionally certifies +that EVERY zero sits at `Im x = 1/2`), and p = 5 in plain 'offline' mode. + +The p = 2 theorem is named `euler_factor_section_offline` and its statement is +byte-identical (modulo the missions normalizer) to the MIRRORMERE registry node +`MM_euler_factor_section_offline`; `tests/test_emit_twofreq_offline.py` pins that. + +conjecture1_proved = False -- a finite fact about single Euler factors, at fixed primes. +Nothing here is about zeta, the Euler product, or RH; on the contrary, it certifies that +per-rung line-membership FAILS, so critical-line membership can only be an infinite-N +continuation phenomenon. +""" +import argparse +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "src")) + +from telperion import ( # noqa: E402 + TwoFreqOfflineEmitter, ValidationReport, certify, emit, +) +from telperion.emit_twofreq_offline import ( # noqa: E402 + euler_factor_spec, twofreq_offline_family, +) +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 + +_SPECS = { + 2: euler_factor_spec(2, mode="displacement"), + 3: euler_factor_spec(3, mode="displacement"), + 5: euler_factor_spec(5, mode="offline"), +} +# p = 2 carries the MIRRORMERE node's exact theorem name. +_NAMES = {2: "euler_factor_section_offline", + 3: "euler_factor_section_offline_p3", + 5: "euler_factor_section_offline_p5"} +_ISLAND = Path(__file__).resolve().parents[1] / "quasicrystal" / "lean" +_OUT = _ISLAND / "EulerFactorSectionOffline.lean" + + +def build() -> str: + fam = twofreq_offline_family( + "EulerFactorSectionOffline", + GridSpec([("p", [2, 3, 5])]), + lambda pt: _NAMES[pt["p"]], + spec=lambda pt: _SPECS[pt["p"]], + ) + report = emit( + certify(fam), + LeanProfile(namespace=("EulerFactorSectionOffline",), + imports=("Mathlib", "TwoFreqRigidity"), + prelude="open Quasicrystal\n"), + [TwoFreqOfflineEmitter()], + ValidationReport(checks=(("twofreq_offline", True),)), + ) + return next(iter(report.files.values())) + + +def main(*, check: bool = False) -> int: + text = build() + if check: + if not _OUT.exists() or _OUT.read_text(encoding="utf-8") != text: + print("DRIFT: EulerFactorSectionOffline.lean does not match regeneration") + return 1 + print("check: OK (regeneration matches frozen output byte-for-byte)") + return 0 + _OUT.write_text(text, encoding="utf-8") + print(f"wrote {_OUT} ({len(text)} bytes)") + return 0 + + +if __name__ == "__main__": + ap = argparse.ArgumentParser() + ap.add_argument("--check", action="store_true", help="drift check; do not write") + raise SystemExit(main(check=ap.parse_args().check)) diff --git a/telperion/examples/zeta_zero_localization/lean/AxiomGuardBragg.lean b/telperion/examples/zeta_zero_localization/lean/AxiomGuardBragg.lean index 668139521..42731ced5 100644 --- a/telperion/examples/zeta_zero_localization/lean/AxiomGuardBragg.lean +++ b/telperion/examples/zeta_zero_localization/lean/AxiomGuardBragg.lean @@ -14,6 +14,17 @@ * CosEnclosure.cos_encl / cos_encl_bracket -- terminal cos contract + Lipschitz bracket-width absorption (`Real.abs_cos_sub_cos_le`). * CosEnclosure.add_encl -- interval-sum fold glue. + * ExpLaurentDeficit.expLaurent_recurrence_deficit{,_sq} -- the emitted exp-Laurent + certificates (kind `exp_laurent_identity`): the clearance PRODUCT equals the + amplification excess, and its Weil-energy square, both an exact reduction modulo + the single relation e^d * e^(-d) = 1. + * Quasicrystal.recurrence_deficit_eq_excess -- MIRRORMERE node + MM_recurrence_deficit_eq_excess: the Face 4 (Bagchi recurrence) <-> Face 1 (Bragg + defect) dictionary row at the certified displacement delta = 1/10, plus strict + positivity of the deficit at every positive displacement. A dictionary row between + two finite instruments -- NOT an analytic theorem and NOT a step toward RH. + * Quasicrystal.recurrence_deficit_sq_eq_abs_defect -- its second-order (Weil-energy) + companion: the squared deficit is |defectFunctional excess|. * BraggH100.bragg_amplitude_h100 -- THE HEADLINE: the first kernel-certified truncated Bragg amplitude F_100(u*) = sum cos(gamma_k * u*) over the 29 certified zeros up to height 100, enclosed in the certified interval. The gLine sign @@ -29,6 +40,8 @@ import CosEnclosure import BraggH100 import BraggSupport import RHInBoxCore +import ExpLaurentDeficit +import RecurrenceDeficit /-! ### CosEnclosure -- certified cos machinery -/ #print axioms CosEnclosure.cos_base @@ -44,6 +57,12 @@ import RHInBoxCore #print axioms RHInBoxCore.sum_over_box_zeros_eq #print axioms BraggSupport.sum_cos_over_zero_support_eq +/-! ### ExpLaurentDeficit / RecurrenceDeficit -- the Face 4 <-> Face 1 dictionary row -/ +#print axioms ExpLaurentDeficit.expLaurent_recurrence_deficit +#print axioms ExpLaurentDeficit.expLaurent_recurrence_deficit_sq +#print axioms Quasicrystal.recurrence_deficit_eq_excess +#print axioms Quasicrystal.recurrence_deficit_sq_eq_abs_defect + /-! ### BraggH100 -- the headline certified Bragg amplitudes -/ #print axioms BraggH100.bragg_amplitude_h100 #print axioms BraggH100.bragg_amplitude_h100_complete diff --git a/telperion/examples/zeta_zero_localization/lean/ExpEnclosureInstances.lean b/telperion/examples/zeta_zero_localization/lean/ExpEnclosureInstances.lean new file mode 100644 index 000000000..c49754c1a --- /dev/null +++ b/telperion/examples/zeta_zero_localization/lean/ExpEnclosureInstances.lean @@ -0,0 +1,185 @@ +/- telperion 0.1.6 | family ExpEnclosureInstances | input-hash 83a662d62bb41760 + 10 theorems, 4 generation-time self-checks passed. + Regenerate & verify: forge diff --family --manifest --check + DO NOT EDIT BY HAND — edits are flagged by the regeneration diff. -/ + +import Mathlib +import BraggDefect + +namespace ExpEnclosureInstances + +/-- `exp_tenth_bracket` -- a certified RATIONAL ENCLOSURE of `Real.exp (1/10)`. + Order-14 `Real.exp_bound` box `[S - r, S + r]` (exact rationals, + S = sum_(m < 14) x^m/m!, r = |x|^14 * (14+1)/(14! * 14)), + which lies inside the claimed bracket with slack (75976562500000000119119/4767562800000000000000000000000000000000000000, 198025173611111118808189/119189070000000000000000000000000000000000000000) >= 0; + box = [26977135394095642634038549/24409921536000000000000000, 5395427078819128526807711/4881984307200000000000000]. The order is the LEAST one whose box fits -- the + generator REFUSES a bracket the box does not imply rather than widening it. + A finite arithmetic fact about a transcendental constant at one rational + point; nothing about RH. conjecture1_proved = False. -/ + +theorem exp_tenth_bracket : (((442068367230259049924676660787771898883 / 400000000000000000000000000000000000000)) : ℝ) ≤ Real.exp ((1 / 10)) ∧ Real.exp ((1 / 10)) ≤ (((11051709180756476248117094953514706601127 / 10000000000000000000000000000000000000000)) : ℝ) := by + have hx : |(((1 / 10)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hb := Real.exp_bound hx (n := 14) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +/-- `deficit_tenth_bracket` -- a certified RATIONAL ENCLOSURE of `Real.exp (1/10) + Real.exp (-(1/10)) - 2`. + Order-14 `Real.exp_bound` box `[S - r, S + r]` (exact rationals, + S = sum_(m < 14) x^m/m!, r = |x|^14 * (14+1)/(14! * 14)), + which lies inside the claimed bracket with slack (899183891901596078882526032824609234226561405642718335619647113/52689717566593052019606631944444444444447523275600000000000000000000000000000000000000, 23782320894641569211942655988551850468682727291129747405465239/1596658108078577333927447916666666666666630570000000000000000000000000000000000000000) >= 0; + box = [122151349595123520722957/12204960768000000000000000, 11104668145011229156633/1109541888000000000000000]. The order is the LEAST one whose box fits -- the + generator REFUSES a bracket the box does not imply rather than widening it. + A finite arithmetic fact about a transcendental constant at one rational + point; nothing about RH. conjecture1_proved = False. -/ + +-- the `exp (1/10)` face of deficit_tenth_bracket (its own exact order-14 box) +theorem deficit_tenth_bracket_pos : (((26977135394095642634038549 / 24409921536000000000000000)) : ℝ) ≤ Real.exp ((1 / 10)) ∧ Real.exp ((1 / 10)) ≤ (((5395427078819128526807711 / 4881984307200000000000000)) : ℝ) := by + have hx : |(((1 / 10)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hb := Real.exp_bound hx (n := 14) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +-- the `exp (-(1/10))` face of deficit_tenth_bracket (same order, same remainder) +theorem deficit_tenth_bracket_neg : (((1472467358472973627160491 / 1627328102400000000000000)) : ℝ) ≤ Real.exp (-((1 / 10))) ∧ Real.exp (-((1 / 10))) ≤ (((7362336792364868135802457 / 8136640512000000000000000)) : ℝ) := by + have hx : |(((1 / 10)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hx' : |((-((1 / 10))) : ℝ)| ≤ 1 := by rwa [abs_neg] + have hb := Real.exp_bound hx' (n := 14) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +theorem deficit_tenth_bracket : (((44243688035498337190547890814412959087189025996450853896963629856431657841141 / 4420683672302590499246837981405882640450800000000000000000000000000000000000000)) : ℝ) ≤ Real.exp ((1 / 10)) + Real.exp (-((1 / 10))) - 2 ∧ + Real.exp ((1 / 10)) + Real.exp (-((1 / 10))) - 2 ≤ (((44243688035498337190690637870740262328789025996450853896963629856431657841141 / 4420683672302590499246766607877718988830000000000000000000000000000000000000000)) : ℝ) := by + constructor <;> linarith [deficit_tenth_bracket_pos.1, deficit_tenth_bracket_pos.2, deficit_tenth_bracket_neg.1, deficit_tenth_bracket_neg.2] + +/-- `deficit_fifth_bracket` -- a certified RATIONAL ENCLOSURE of `Real.exp (1/5) + Real.exp (-(1/5)) - 2`. + Order-16 `Real.exp_bound` box `[S - r, S + r]` (exact rationals, + S = sum_(m < 16) x^m/m!, r = |x|^16 * (16+1)/(16! * 16)), + which lies inside the claimed bracket with slack (31727/5108103000000000000000000000, 4722833/51081030000000000000000000000) >= 0; + box = [1025030545780681876895983/25540515000000000000000000, 1025030545780681876896017/25540515000000000000000000]. The order is the LEAST one whose box fits -- the + generator REFUSES a bracket the box does not imply rather than widening it. + A finite arithmetic fact about a transcendental constant at one rational + point; nothing about RH. conjecture1_proved = False. -/ + +-- the `exp (1/5)` face of deficit_fifth_bracket (its own exact order-16 box) +theorem deficit_fifth_bracket_pos : (((6932278992406931121290807 / 5675670000000000000000000)) : ℝ) ≤ Real.exp ((1 / 5)) ∧ Real.exp ((1 / 5)) ≤ (((62390510931662380091617297 / 51081030000000000000000000)) : ℝ) := by + have hx : |(((1 / 5)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hb := Real.exp_bound hx (n := 16) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +-- the `exp (-(1/5))` face of deficit_fifth_bracket (same order, same remainder) +theorem deficit_fifth_bracket_neg : (((853502248161203748207647 / 1042470000000000000000000)) : ℝ) ≤ Real.exp (-((1 / 5))) ∧ Real.exp (-((1 / 5))) ≤ (((4646845573322109295797193 / 5675670000000000000000000)) : ℝ) := by + have hx : |(((1 / 5)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hx' : |((-((1 / 5))) : ℝ)| ≤ 1 := by rwa [abs_neg] + have hb := Real.exp_bound hx' (n := 16) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +theorem deficit_fifth_bracket : (((40133511238151692591 / 1000000000000000000000)) : ℝ) ≤ Real.exp ((1 / 5)) + Real.exp (-((1 / 5))) - 2 ∧ + Real.exp ((1 / 5)) + Real.exp (-((1 / 5))) - 2 ≤ (((401335112381516925911 / 10000000000000000000000)) : ℝ) := by + constructor <;> linarith [deficit_fifth_bracket_pos.1, deficit_fifth_bracket_pos.2, deficit_fifth_bracket_neg.1, deficit_fifth_bracket_neg.2] + +/-- `cosh_zoodh_bracket` -- a certified RATIONAL ENCLOSURE of `Real.cosh (21487557/100000000)`. + Order-6 `Real.exp_bound` box `[S - r, S + r]` (exact rationals, + S = sum_(m < 6) x^m/m!, r = |x|^6 * (6+1)/(6! * 6)), + which lies inside the claimed bracket with slack (137747013258117884884353491/160000000000000000000000000000000000000000000000000, 99559546458117884884353491/160000000000000000000000000000000000000000000000000) >= 0; + box = [163707907383974683468965577747013258117884884353491/160000000000000000000000000000000000000000000000000, 163707958421137299354192860440453541882115115646509/160000000000000000000000000000000000000000000000000]. The order is the LEAST one whose box fits -- the + generator REFUSES a bracket the box does not imply rather than widening it. + A finite arithmetic fact about a transcendental constant at one rational + point; nothing about RH. conjecture1_proved = False. -/ + +-- the `exp (21487557/100000000)` face of cosh_zoodh_bracket (its own exact order-6 box) +theorem cosh_zoodh_bracket_pos : (((198353172806144997105636607607597427668492484353491 / 160000000000000000000000000000000000000000000000000)) : ℝ) ≤ Real.exp ((21487557 / 100000000)) ∧ Real.exp ((21487557 / 100000000)) ≤ (((198353223843307612990863890301037711432722715646509 / 160000000000000000000000000000000000000000000000000)) : ℝ) := by + have hx : |(((21487557 / 100000000)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hb := Real.exp_bound hx (n := 6) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +-- the `exp (-(21487557/100000000))` face of cosh_zoodh_bracket (same order, same remainder) +theorem cosh_zoodh_bracket_neg : (((129062641961804369832294547886429088567277284353491 / 160000000000000000000000000000000000000000000000000)) : ℝ) ≤ Real.exp (-((21487557 / 100000000))) ∧ Real.exp (-((21487557 / 100000000))) ≤ (((129062692998966985717521830579869372331507515646509 / 160000000000000000000000000000000000000000000000000)) : ℝ) := by + have hx : |(((21487557 / 100000000)) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num + have hx' : |((-((21487557 / 100000000))) : ℝ)| ≤ 1 := by rwa [abs_neg] + have hb := Real.exp_bound hx' (n := 6) (by norm_num) + simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb + rw [abs_le] at hb + obtain ⟨h1, h2⟩ := hb + constructor + · norm_num [Nat.factorial] at h1 ⊢; linarith + · norm_num [Nat.factorial] at h2 ⊢; linarith + +theorem cosh_zoodh_bracket : (((511587210574920885840517 / 500000000000000000000000)) : ℝ) ≤ Real.cosh ((21487557 / 100000000)) ∧ Real.cosh ((21487557 / 100000000)) ≤ (((511587370066054060481853 / 500000000000000000000000)) : ℝ) := by + rw [Real.cosh_eq] + constructor <;> linarith [cosh_zoodh_bracket_pos.1, cosh_zoodh_bracket_pos.2, cosh_zoodh_bracket_neg.1, cosh_zoodh_bracket_neg.2] + +/-- `exp_tenth_bracket_defs` -- the SAME certified bracket in BraggDefect's own vocabulary: + `expLo`/`expHi` are by definition the two literals `exp_tenth_bracket` brackets between, + so this is a pure unfolding. It is the exact shape of the `hexp` hypothesis that + `BraggDefect.bragg_defect_witness` (and the MIRRORMERE node `MM_bragg_defect_witness`) + carries as an Arb input. conjecture1_proved = False. -/ +theorem exp_tenth_bracket_defs : + BraggDefect.expLo ≤ Real.exp (1 / 10) ∧ Real.exp (1 / 10) ≤ BraggDefect.expHi := by + unfold BraggDefect.expLo BraggDefect.expHi + exact exp_tenth_bracket + +/-- **`bragg_defect_witness_unconditional`** -- the MIRRORMERE defect witness with its Arb + exponential-enclosure hypothesis DISCHARGED in the kernel. Identical conclusion to + `BraggDefect.bragg_defect_witness`; the `hexp` binder is gone, supplied by + `exp_tenth_bracket_defs` (order-14 `Real.exp_bound`). + + SCOPE, unchanged: this is the finite synthetic-pair diffraction experiment of + `BraggDefect.lean` -- the on-line configuration's defect functional is exactly 0 and the + one-off-line-pair configuration's is bracketed strictly below 0. Discharging a NUMERIC + hypothesis makes the witness unconditional; it does not enlarge what the witness says, and + the experiment's other trust seams (the BraggH100 Arb sign boxes, the band `hLine`) are + untouched. Nothing here is about RH. conjecture1_proved = False. -/ +theorem bragg_defect_witness_unconditional : + BraggDefect.defectFunctional 0 = 0 ∧ + ((-1957503930982498711627558116252003079150110082803036995985602456729126067929069837779873677055641334915004924707647824293913235373458273903210508792181881 / 19542444130562717342736579894714125276139669165907166175656490622972757664768900000000000000000000000000000000000000000000000000000000000000000000000000000000 : ℝ) ≤ BraggDefect.defectFunctional BraggDefect.excess ∧ + BraggDefect.defectFunctional BraggDefect.excess ≤ (-1957503930982498711614926803795741251867682177931660778058090203284392257792384397626586656512971699612677910422316624293913235373458273903210508792181881 / 19542444130562717342737210934295300643770643047158621178046789521488913388427220640000000000000000000000000000000000000000000000000000000000000000000000000000 : ℝ)) := + BraggDefect.bragg_defect_witness exp_tenth_bracket_defs + +/-- The hypothesis-carrying form, kept so the MIRRORMERE grant gate's syntactic match against + `Statements/MM_bragg_defect_witness.lean` still finds its statement. The hypothesis is now + inert -- the conclusion is `bragg_defect_witness_unconditional`. -/ +theorem bragg_defect_witness_hyp_form + (_hexp : BraggDefect.expLo ≤ Real.exp (1 / 10) ∧ Real.exp (1 / 10) ≤ BraggDefect.expHi) : + BraggDefect.defectFunctional 0 = 0 ∧ + ((-1957503930982498711627558116252003079150110082803036995985602456729126067929069837779873677055641334915004924707647824293913235373458273903210508792181881 / 19542444130562717342736579894714125276139669165907166175656490622972757664768900000000000000000000000000000000000000000000000000000000000000000000000000000000 : ℝ) ≤ BraggDefect.defectFunctional BraggDefect.excess ∧ + BraggDefect.defectFunctional BraggDefect.excess ≤ (-1957503930982498711614926803795741251867682177931660778058090203284392257792384397626586656512971699612677910422316624293913235373458273903210508792181881 / 19542444130562717342737210934295300643770643047158621178046789521488913388427220640000000000000000000000000000000000000000000000000000000000000000000000000000 : ℝ)) := + bragg_defect_witness_unconditional + +-- STATEMENT GATE (kernel-enforced): the node statement of MM_bragg_defect_witness, written +-- exactly as `Statements/MM_bragg_defect_witness.lean` writes it (under `open BraggDefect`), +-- is inhabited by the hypothesis-carrying form. A drift in either statement fails the build. +open BraggDefect in +example (hexp : expLo ≤ Real.exp (1 / 10) ∧ Real.exp (1 / 10) ≤ expHi) : + defectFunctional 0 = 0 ∧ + ((-1957503930982498711627558116252003079150110082803036995985602456729126067929069837779873677055641334915004924707647824293913235373458273903210508792181881 / 19542444130562717342736579894714125276139669165907166175656490622972757664768900000000000000000000000000000000000000000000000000000000000000000000000000000000 : ℝ) ≤ defectFunctional excess ∧ + defectFunctional excess ≤ (-1957503930982498711614926803795741251867682177931660778058090203284392257792384397626586656512971699612677910422316624293913235373458273903210508792181881 / 19542444130562717342737210934295300643770643047158621178046789521488913388427220640000000000000000000000000000000000000000000000000000000000000000000000000000 : ℝ)) := + bragg_defect_witness_hyp_form hexp + +end ExpEnclosureInstances diff --git a/telperion/examples/zeta_zero_localization/lean/ExpLaurentDeficit.lean b/telperion/examples/zeta_zero_localization/lean/ExpLaurentDeficit.lean new file mode 100644 index 000000000..595f57444 --- /dev/null +++ b/telperion/examples/zeta_zero_localization/lean/ExpLaurentDeficit.lean @@ -0,0 +1,44 @@ +/- telperion 0.1.6 | family ExpLaurentDeficit | input-hash 5df1013b28977a78 + 2 theorems, 6 generation-time self-checks passed. + Regenerate & verify: forge diff --family --manifest --check + DO NOT EDIT BY HAND — edits are flagged by the regeneration diff. -/ + +import Mathlib + +namespace ExpLaurentDeficit + +-- THE EXP-LAURENT DEFICIT ROWS (QC_RECURRENCE section 2 row (a), section 4 item 2). +-- +-- For an off-line pair at displacement d, the two one-sided clearances are the outer mirror +-- factor e^d - 1 and the inner transported-zero factor 1 - e^(-d). Their PRODUCT -- the +-- two-sided clearance a recurrence shift must bridge -- is the RECURRENCE DEFICIT, and it +-- equals the Bragg amplification EXCESS e^d + e^(-d) - 2. The square is the Weil-energy +-- (quadratic-form) reading of the same row. +-- +-- Certificate: an exact reduction of lhs - rhs modulo the single relation e^d * e^(-d) = 1, +-- with the quotient (cofactor) carried into `linear_combination`. Corrupt the cofactor or +-- either side and the kernel rejects the theorem. +-- +-- HONEST SCOPE: unconditional, zeta-free bookkeeping between two finite instruments. It is +-- a dictionary row, not an analytic theorem, and NOT a step toward RH (the uniform Bagchi +-- recurrence IS RH and is untouched). conjecture1_proved = False. + +-- expLaurent_recurrence_deficit: exp-Laurent identity in e^d, e^(-d), certified as an exact +-- reduction modulo the single relation e^d * e^(-d) = 1 with cofactor -1. +-- Unconditional; no enclosure, no analytic hypothesis. conjecture1_proved = False. +theorem expLaurent_recurrence_deficit (d : ℝ) : + (Real.exp d - 1) * (1 - Real.exp (-d)) = Real.exp d + Real.exp (-d) - 2 := by + have hrel : Real.exp d * Real.exp (-d) = 1 := by + rw [← Real.exp_add]; norm_num + linear_combination (-1 : ℝ) * hrel + +-- expLaurent_recurrence_deficit_sq: exp-Laurent identity in e^d, e^(-d), certified as an exact +-- reduction modulo the single relation e^d * e^(-d) = 1 with cofactor expNeg*expPos - 2*expNeg - 2*expPos + 3. +-- Unconditional; no enclosure, no analytic hypothesis. conjecture1_proved = False. +theorem expLaurent_recurrence_deficit_sq (d : ℝ) : + (Real.exp d - 1) ^ 2 * (1 - Real.exp (-d)) ^ 2 = (Real.exp d + Real.exp (-d) - 2) ^ 2 := by + have hrel : Real.exp d * Real.exp (-d) = 1 := by + rw [← Real.exp_add]; norm_num + linear_combination ((Real.exp d * Real.exp (-d)) + 3 - (Real.exp d * 2) - (Real.exp (-d) * 2) : ℝ) * hrel + +end ExpLaurentDeficit diff --git a/telperion/examples/zeta_zero_localization/lean/RecurrenceDeficit.lean b/telperion/examples/zeta_zero_localization/lean/RecurrenceDeficit.lean new file mode 100644 index 000000000..1fdcd79a8 --- /dev/null +++ b/telperion/examples/zeta_zero_localization/lean/RecurrenceDeficit.lean @@ -0,0 +1,80 @@ +/- RecurrenceDeficit -- MIRRORMERE node `MM_recurrence_deficit_eq_excess` (Routes-roadmap E4a). + + THE DICTIONARY ROW, Face 4 (Bagchi recurrence) <-> Face 1 (Weil/Bragg defect). QC_RECURRENCE + section 2 row (a) derives, for a synthetic off-line pair at displacement `delta`, the two + one-sided clearances `g+(delta) = e^delta - 1` (outer mirror factor) and + `g-(delta) = 1 - e^(-delta)` (inner transported-zero factor), and identifies their PRODUCT -- + the two-sided clearance a recurrence shift must bridge -- as the recurrence deficit + + recurrenceDeficit delta = (e^delta - 1) * (1 - e^(-delta)) . + + This file proves that this deficit is, at the certified displacement `delta = 1/10` of the + `BraggDefect` configuration (`beta = 3/5`, `gamma0 = 50`), EXACTLY the Bragg amplification + `excess = Aoff - Aon = e^(1/10) + e^(-1/10) - 2`, and that it is strictly positive at every + positive displacement. The two instruments -- the dynamical clearance and the diffraction + amplitude excess -- read the same off-line signal off the same number. + + HONEST SCOPE. The content is a ONE-RELATION ring identity in `Real.exp` (the relation being + `e^delta * e^(-delta) = 1`) plus a two-factor positivity. It is a DICTIONARY ROW, not an + analytic theorem: it says the Face-4 and Face-1 bookkeeping agree, and nothing about zeta. + Nothing here is conditional on, nor evidence for, the Riemann Hypothesis -- the memo is + explicit that certifying one recurrence instance is not progress toward RH, and that the + UNIFORM Bagchi recurrence IS RH and is untouched. conjecture1_proved = False. + + VOCABULARY. `recurrenceDeficit` is AUTHORED in the registry's vocabulary mirror + `telperion/missions/mirrormere/lean/Statements/MMDefs.lean` (lines 61-62); it is mirrored here + BYTE-IDENTICALLY, in the same namespace `Quasicrystal`, exactly as the `rvm_bridge` E6Bridge + modules mirror their MMDefs vocabulary. `excess` is verbatim island vocabulary from + `BraggDefect.lean` (line 60). Any drift between this def and MMDefs is a grant-gate failure. + + CERTIFICATE PROVENANCE. The algebraic core is the emitted Telperion certificate + `ExpLaurentDeficit.expLaurent_recurrence_deficit` (kind `exp_laurent_identity`, generator + `telperion/examples/exp_laurent_deficit/generate.py`): the identity is certified in sympy as an + exact reduction modulo the single relation `y * z = 1` with the LOAD-BEARING cofactor `-1`, and + the emitted Lean discharges it by `linear_combination` against that cofactor. This file + consumes the emitted general-delta identity and specializes it. +-/ +import Mathlib +import BraggDefect +import ExpLaurentDeficit + +namespace Quasicrystal + +/-- The recurrence deficit of an off-line displacement `delta` (QC_RECURRENCE section 4.2 / W3d). +MIRROR of `telperion/missions/mirrormere/lean/Statements/MMDefs.lean` lines 61-62, byte-identical; +the registry's vocabulary is authoritative. -/ +noncomputable def recurrenceDeficit (δ : ℝ) : ℝ := + (Real.exp δ - 1) * (1 - Real.exp (-δ)) + +open Quasicrystal BraggDefect + +/-- **`recurrence_deficit_eq_excess`** -- the MIRRORMERE node `MM_recurrence_deficit_eq_excess`, +stated verbatim. At the certified displacement `delta = 1/10` the recurrence deficit equals the +Bragg amplification excess `Aoff - Aon`, and the deficit is strictly positive at every positive +displacement. Unconditional; the exp-Laurent identity is the emitted Telperion certificate +`ExpLaurentDeficit.expLaurent_recurrence_deficit`. conjecture1_proved = False. -/ +theorem recurrence_deficit_eq_excess : + recurrenceDeficit (1 / 10) = excess ∧ + ∀ δ : ℝ, 0 < δ → 0 < recurrenceDeficit δ := by + refine ⟨?_, ?_⟩ + · -- the exp-Laurent row: (e^d - 1)(1 - e^(-d)) = e^d + e^(-d) - 2, at d = 1/10 + unfold recurrenceDeficit excess Aoff Aon + exact ExpLaurentDeficit.expLaurent_recurrence_deficit (1 / 10) + · -- both clearances are strictly positive at a positive displacement + intro δ hδ + unfold recurrenceDeficit + exact mul_pos (sub_pos.mpr (Real.one_lt_exp_iff.mpr hδ)) + (sub_pos.mpr (Real.exp_lt_one_iff.mpr (by linarith))) + +/-- Companion (NOT a registry node; QC_RECURRENCE section 4 item 2 names it): the SQUARED +recurrence deficit at `delta = 1/10` is the magnitude of the Bragg defect functional. This is the +"second-order (Weil-energy) form" of the same dictionary row -- one power of the linear clearance +for each of the two evaluation-vector legs of the pair block -- and it is immediate from the +identity above plus `defectFunctional d = -(d^2)`. -/ +theorem recurrence_deficit_sq_eq_abs_defect : + recurrenceDeficit (1 / 10) ^ 2 = |defectFunctional excess| := by + have h := recurrence_deficit_eq_excess.1 + have hpos : (0 : ℝ) ≤ excess ^ 2 := sq_nonneg _ + rw [h, defectFunctional, abs_neg, abs_of_nonneg hpos] + +end Quasicrystal diff --git a/telperion/examples/zeta_zero_localization/lean/zzl_aux/lakefile.toml b/telperion/examples/zeta_zero_localization/lean/zzl_aux/lakefile.toml index 4f5c1bf76..8f2ff7bf3 100644 --- a/telperion/examples/zeta_zero_localization/lean/zzl_aux/lakefile.toml +++ b/telperion/examples/zeta_zero_localization/lean/zzl_aux/lakefile.toml @@ -1,5 +1,5 @@ name = "zzl_aux" -defaultTargets = ["AllZeros_h100", "AllZeros_h200", "AxiomGuardDefect", "BraggAmplitudeInstances", "BraggDefect", "BraggH100", "BraggSupport", "CosEnclosure", "DefectDictionary", "NoZerosInBox_0_1d1000_0_55d16", "NoZerosInBox_1d1000_999d1000_0_55d16", "R2Rigidity", "RHInBox_1d1000000_999999d1000000_0_100", "RHInBox_1d1000000_999999d1000000_100_200", "RHLinalg", "StripClear", "ZooDH"] +defaultTargets = ["AllZeros_h100", "AllZeros_h200", "AxiomGuardDefect", "BraggAmplitudeInstances", "BraggDefect", "BraggH100", "BraggSupport", "CosEnclosure", "DefectDictionary", "ExpLaurentDeficit", "NoZerosInBox_0_1d1000_0_55d16", "NoZerosInBox_1d1000_999d1000_0_55d16", "R2Rigidity", "RecurrenceDeficit", "RHInBox_1d1000000_999999d1000000_0_100", "RHInBox_1d1000000_999999d1000000_100_200", "RHLinalg", "StripClear", "ZooDH", "ExpEnclosureInstances"] srcDir = ".." [[require]] @@ -34,12 +34,18 @@ name = "CosEnclosure" [[lean_lib]] name = "DefectDictionary" [[lean_lib]] +name = "ExpLaurentDeficit" +[[lean_lib]] +name = "ExpEnclosureInstances" +[[lean_lib]] name = "NoZerosInBox_0_1d1000_0_55d16" [[lean_lib]] name = "NoZerosInBox_1d1000_999d1000_0_55d16" [[lean_lib]] name = "R2Rigidity" [[lean_lib]] +name = "RecurrenceDeficit" +[[lean_lib]] name = "RHInBox_1d1000000_999999d1000000_0_100" [[lean_lib]] name = "RHInBox_1d1000000_999999d1000000_100_200" diff --git a/telperion/missions/mirrormere/attempts.jsonl b/telperion/missions/mirrormere/attempts.jsonl index 64082c528..6947a9d4a 100644 --- a/telperion/missions/mirrormere/attempts.jsonl +++ b/telperion/missions/mirrormere/attempts.jsonl @@ -42,3 +42,10 @@ {"node": "MM_spectral_cooked_control", "session": "integrator-2026-09-18", "route": "grant pass after the rh/million-turing reconcile landed on main (#506)", "verdict": "Proved", "detail": "GRANTED. The node's artifact reached main with #506; the grant gate (statement_matches, normalized containment) PASSED. Pre-flight had already matched all 15 linked nodes against the climb artifacts before the merge. Campaign verify OK. conjecture1_proved = False.", "date": "2026-09-18"} {"node": "MM_twofreq_realrooted_iff", "session": "integrator-2026-09-18", "route": "grant pass after the rh/million-turing reconcile landed on main (#506)", "verdict": "Proved", "detail": "GRANTED. The node's artifact reached main with #506; the grant gate (statement_matches, normalized containment) PASSED. Pre-flight had already matched all 15 linked nodes against the climb artifacts before the merge. Campaign verify OK. conjecture1_proved = False.", "date": "2026-09-18"} {"node": "MM_zeta_ordinates_not_uniformly_discrete", "session": "integrator-2026-09-18", "route": "cross-island grant: W2cAssembly.lean on the rvm_bridge island (#567), pigeonhole transcription composing rvm_unbounded_mean_density with the conditional quasicrystal brick", "verdict": "Proved", "detail": "GRANTED. Artifact on main since #567; gate statement_matches PASS; CI guard rvm-bridge-compiles. W2c is unconditional: the zeta ordinates are not uniformly discrete, no hypotheses. Independently verified by a second agent during the Mirrormere team run. conjecture1_proved = False.", "date": "2026-09-18"} +{"node": "MM_torus_section_dictionary", "session": "mm-torus-ladder-t1-2026-09-18", "route": "TorusSectionLadder.lean (quasicrystal island, rh/million-turing): simp [twoFreq, linearTorusForm, torusOrbit, Fin.sum_univ_two]", "verdict": "Proved", "detail": "DISCHARGED sorry-free, axioms [propext, Classical.choice, Quot.sound] (AxiomGuardQC). GRADE: simp-level Fin-2 sum unfolding across the two vocabularies (Matrix.cons_val_zero/one); a vocabulary bridge, NOT mathematics; recorded, not counted as a win. Node still DRAFT: grant blocked until the post-revision re-audit promotes it to open (mm-dictionary-reaudit); link recorded now (set_proof does not gate on status). Artifact lives on the climb branch; grant also deferred to the branch reconcile like the other climb-linked nodes.", "date": "2026-09-18"} +{"node": "MM_torus_section_n2_rigidity", "session": "mm-torus-ladder-t1-2026-09-18", "route": "TorusSectionLadder.lean: simp only [<- torus_section_dictionary]; exact twoFreq_realRooted_iff", "verdict": "Proved", "detail": "DISCHARGED sorry-free, axioms [propext, Classical.choice, Quot.sound] (AxiomGuardQC). GRADE: pure one-line bridge into the island's twoFreq_realRooted_iff through the dictionary rewrite; kind 'milestone' is inflated (it is a lemma); not counted as a win. Normalized-containment gate checked offline against the artifact: statement found. Grant deferred to the branch reconcile (artifact on rh/million-turing, registry on main) and to the dictionary dependency leaving draft.", "date": "2026-09-18"} +{"node": "MM_offline_disjoint_discs", "session": "mm-offline-disjoint-discs-2026-09-18", "route": "E4b isolation lemma (QC_RECURRENCE section 4.3) proved directly in the quasicrystal island + new Telperion disjoint_discs emitter kind for the instance shape", "verdict": "Stalled", "detail": "PROVED sorry-free on mm/offline-disjoint-discs (base rh/million-turing): telperion/examples/quasicrystal/lean/OfflineDiscs.lean, decl Quasicrystal.offline_disjoint_discs, statement mirrored VERBATIM from Statements/MM_offline_disjoint_discs.lean (node sha256 bac57ccef7c3f828; diff is empty modulo the stripped ':= by sorry'). Route: Finset.induction positive-lower-bound helper (exists_pos_lower_bound_of_finset) over the offDiag distance image and the strip-margin image, r := min (eps1/3) (eps2/2); disjointness via Metric.closedBall_disjoint_closedBall, containment via the 1-Lipschitz abs_re_sub_le_dist. Registered as lean_lib + defaultTarget; AxiomGuardQC prints [propext, Classical.choice, Quot.sound] for all three new decls, 0 sorryAx. ALSO minted the missing certificate kind: DisjointDiscsEmitter (kind disjoint_discs) emitting the concrete instance shape E5 consumes, with a two-sided kernel negative control (adapter_disjoint_discs) that PASSES. GRANT after reconcile to main. conjecture1_proved = False.", "date": "2026-09-18"} +{"node": "MM_recurrence_deficit_eq_excess", "session": "mm-recurrence-deficit-2026-09-18", "route": "exp-Laurent certificate (new emitter kind exp_laurent_identity) + specialization at delta = 1/10 on the zzl island", "verdict": "Proved", "detail": "PROVED sorry-free on branch mm/recurrence-deficit (base origin/rh/million-turing); artifact examples/zeta_zero_localization/lean/RecurrenceDeficit.lean, registered as a zzl_aux lean_lib + defaultTarget; axioms [propext, Classical.choice, Quot.sound] via AxiomGuardBragg. recurrenceDeficit mirrored BYTE-IDENTICALLY from MMDefs lines 61-62; grant-gate statement containment pre-flight MATCHES. Algebraic core dogfooded through a NEW Telperion certificate kind exp_laurent_identity (ExpLaurentIdentityEmitter): lhs - rhs reduced EXACTLY modulo the single relation e^d * e^(-d) = 1, cofactor -1 carried into linear_combination; emitted lean/ExpLaurentDeficit.lean from generator examples/exp_laurent_deficit/generate.py (telperion.toml [[check]] group quick, drift check green). Two-sided kernel-gated negative control registered and PASSING: the forged FALSE twin is the memo's own corrected mistake (the clearances' SUM substituted for their PRODUCT, QC_RECURRENCE section 6) -- kernel REJECTED it, TRUE twin compiled clean. Companion recurrence_deficit_sq_eq_abs_defect (NOT a node) also proved. SCOPE: a one-relation ring identity plus a two-factor positivity -- a Face 4 <-> Face 1 dictionary row, not an analytic theorem; conjecture1_proved = False. Grant DEFERRED to the branch reconcile.", "date": "2026-09-18"} +{"node": "MM_bragg_defect_witness", "session": "mm-exp-enclosure-emitter-2026-09-18", "route": "exp_enclosure emitter (kind exp_enclosure) reflects the Arb hexp seam into the kernel", "verdict": "Stalled", "detail": "New emitter ExpEnclosureEmitter (telperion/src/telperion/emit_exp_enclosure.py, Real.exp_bound Taylor-box brackets, refuses any claim the exact box does not imply) dogfooded as examples/exp_enclosure/generate.py -> ExpEnclosureInstances.lean in the v4.32 zzl_aux island. exp_tenth_bracket carries BraggDefect expLo/expHi VERBATIM (order-14 box) and exp_tenth_bracket_defs is exactly the hexp hypothesis, so the bridge lemma bragg_defect_witness_unconditional := BraggDefect.bragg_defect_witness exp_tenth_bracket_defs states this node WITHOUT the Arb enclosure hypothesis; the hypothesis-carrying form bragg_defect_witness_hyp_form is kept and kernel-gated by an open BraggDefect example that reproduces the node statement. lake build ExpEnclosureInstances GREEN locally; axioms of all four instances plus all three bridge theorems are [propext, Classical.choice, Quot.sound]. Two-sided negative control green against the real kernel (forged bracket rejected, true twin accepted). Verdict Stalled not Proved: no grant, no push - closure_clean can flip at the branch reconcile once the artifact lands. conjecture1_proved = False.", "date": "2026-09-18"} +{"node": "MM_euler_factor_section_offline", "session": "mm-euler-factor-offline 2026-09-18", "route": "twoFreq_realRooted_iff .mp + exact normSq inequality ||1||=1 /= 1/sqrt 2 (1 < sqrt 2), plus explicit witness x = i/2 via twoFreq_eq_zero_iff + exp((log 2)/2) = sqrt 2; dogfooded through the NEW selfinversive_rigidity emitter mode='offline' (p=2,3,5)", "verdict": "Proved", "detail": "euler_factor_section_offline kernel-clean on mm/mm-euler-factor-offline (quasicrystal island, EulerFactorOffline.lean; guard AxiomGuardQC [propext, Classical.choice, Quot.sound], no sorryAx). statement_match_check all_match=True against the registry statement for BOTH the hand-stated theorem and the emitted SelfInversiveOfflineInstances.euler_factor_p2_offline_node. Companion (not a node): euler_factor_section_witness (x = i/2 is a zero) + second refutation route from it. conjecture1_proved = False; grant deferred to branch reconcile.", "date": "2026-09-18"} +{"node": "MM_euler_factor_section_offline", "session": "mm-twofreq-offline-emitter-2026-09-18", "route": "new telperion emitter kind twofreq_offline (TwoFreqOfflineEmitter): the NOT-real-rooted direction of twoFreq_realRooted_iff from the EXACT rational inequality |c1|^2 != |c2|^2, with irrational coefficient literals (inv_sqrt/real_sqrt) and the -(Real.log p) frequency literal; dogfooded into the quasicrystal island as EulerFactorSectionOffline.lean", "verdict": "Proved", "detail": "PROVED in-island, no sorry. lake build EulerFactorSectionOffline green on the v4.32 quasicrystal island (8 theorems, no warnings); #print axioms on all 8 gives [propext, Classical.choice, Quot.sound]. The p=2 theorem euler_factor_section_offline matches this node under missions.verify.normalize_lean containment AND under the kernel-level telperion.statement_match gate (2/2 defeq match, together with its displacement companion). Emitter also certifies the whole T2 family: p=2,3,5 instances, each with an existence corollary, and p=2,3 with the certified displacement theorem forall x, section x = 0 -> x.im = 1/2. Two-sided kernel negative control green via generic_negative_control (kernel_rejects=True on the equal-modulus forgery c1=3/5+4/5i,c2=1, which fails with h2 : True |- False; true_compiles=True on the p=2 twin). NOT granted: deferred to the main/million-turing reconcile per campaign instruction. conjecture1_proved = False.", "date": "2026-09-18"} diff --git a/telperion/missions/mirrormere/nodes/MM_euler_factor_section_offline.toml b/telperion/missions/mirrormere/nodes/MM_euler_factor_section_offline.toml index d09b94f08..9f9cebaa5 100644 --- a/telperion/missions/mirrormere/nodes/MM_euler_factor_section_offline.toml +++ b/telperion/missions/mirrormere/nodes/MM_euler_factor_section_offline.toml @@ -5,7 +5,13 @@ name = "MM.euler_factor_section_offline" statement_module = "Statements.MM_euler_factor_section_offline" status = "open" title = "Torus-section ladder T2, THE NEGATIVE CONTROL: the p=2 Euler factor 1 - 2^(-s), read on s = 1/2 + ix as the two-frequency section twoFreq(1, -1/sqrt 2; 0, -log 2), is NOT real-rooted -- its zeros sit uniformly at Im x = 1/2 (the Re s = 0 line). Certifies that no per-rung line-membership claim survives finite truncation (the Turan/Montgomery obstruction, in-house); critical-line membership is an infinite-N continuation phenomenon. Discharge route: twoFreq_realRooted_iff + norm arithmetic, ||1|| /= 2^(-1/2) (QC_TORUS_SECTION_LADDER memo section 4b)" -updated = "2026-09-14" +updated = "2026-09-18" + +[proof] +artifact = "../../examples/quasicrystal/lean/EulerFactorSectionOffline.lean" +artifact_kind = "lean_module" +closure_clean = false +via = "direct" [readback] auditor = "blind-auditor 2026-09-14 (independent blind read-back, AUDIT_TESTIMONY_ANDURIL_MIRRORMERE_2026-09-14.md)" diff --git a/telperion/missions/mirrormere/nodes/MM_offline_disjoint_discs.toml b/telperion/missions/mirrormere/nodes/MM_offline_disjoint_discs.toml index f173f9daf..ac08177bd 100644 --- a/telperion/missions/mirrormere/nodes/MM_offline_disjoint_discs.toml +++ b/telperion/missions/mirrormere/nodes/MM_offline_disjoint_discs.toml @@ -5,7 +5,13 @@ name = "MM.offline_disjoint_discs" statement_module = "Statements.MM_offline_disjoint_discs" status = "open" title = "Routes-roadmap E4b (the isolation lemma, QC_RECURRENCE section 4.3): any finite set of points in the open critical strip admits a single positive radius whose closed discs are pairwise disjoint and stay inside the strip -- the geometric substrate for counting off-line zeros by disjoint recurrence-deficit discs (Rouche-template leg of the finite-grade interderivability E5). Pure metric topology, dischargeable now (RH_ROUTES_ROADMAP_2026-09-16 section 9)" -updated = "2026-09-16" +updated = "2026-09-18" + +[proof] +artifact = "../../examples/quasicrystal/lean/OfflineDiscs.lean" +artifact_kind = "lean_module" +closure_clean = false +via = "direct" [readback] auditor = "blind-auditor-2 2026-09-16 (independent blind read-back, AUDIT_TESTIMONY_ROUTES_2026-09-16.md)" diff --git a/telperion/missions/mirrormere/nodes/MM_recurrence_deficit_eq_excess.toml b/telperion/missions/mirrormere/nodes/MM_recurrence_deficit_eq_excess.toml index 8b3024078..cdc1a9df0 100644 --- a/telperion/missions/mirrormere/nodes/MM_recurrence_deficit_eq_excess.toml +++ b/telperion/missions/mirrormere/nodes/MM_recurrence_deficit_eq_excess.toml @@ -5,7 +5,13 @@ name = "MM.recurrence_deficit_eq_excess" statement_module = "Statements.MM_recurrence_deficit_eq_excess" status = "open" title = "Routes-roadmap E4a (Face 4 <-> Face 1 witness bridge): the Bagchi recurrence deficit (e^delta - 1)(1 - e^(-delta)) equals the Bragg amplification excess at the certified displacement delta = 1/10, and is strictly positive for every positive displacement -- the recurrence and defect instruments measure the same off-line signal. Discharge: Real.exp ring algebra + strict monotonicity; QC_RECURRENCE section 4.2 says kernel-ready now (RH_ROUTES_ROADMAP_2026-09-16 section 9)" -updated = "2026-09-16" +updated = "2026-09-18" + +[proof] +artifact = "../../examples/zeta_zero_localization/lean/RecurrenceDeficit.lean" +artifact_kind = "lean_module" +closure_clean = false +via = "direct" [readback] auditor = "blind-auditor-2 2026-09-16 (independent blind read-back, AUDIT_TESTIMONY_ROUTES_2026-09-16.md)" diff --git a/telperion/missions/mirrormere/nodes/MM_torus_section_dictionary.toml b/telperion/missions/mirrormere/nodes/MM_torus_section_dictionary.toml index bd403498a..75b139bd0 100644 --- a/telperion/missions/mirrormere/nodes/MM_torus_section_dictionary.toml +++ b/telperion/missions/mirrormere/nodes/MM_torus_section_dictionary.toml @@ -5,4 +5,10 @@ name = "MM.torus_section_dictionary" statement_module = "Statements.MM_torus_section_dictionary" status = "draft" title = "Torus-section ladder T1, the dictionary BRIDGE: the island's verbatim twoFreq is the N=2 instance of the section vocabulary (twoFreq = linearTorusForm 2 on torusOrbit 2) -- the lemma the N=2 rigidity discharge consumes. REVISED post-audit: the original general-N identity was flagged TRIVIAL (definitionally rfl) by the 2026-09-14 blind read-back; replaced with this contentful bridge; awaiting re-audit" -updated = "2026-09-14" +updated = "2026-09-18" + +[proof] +artifact = "../../examples/quasicrystal/lean/TorusSectionLadder.lean" +artifact_kind = "lean_module" +closure_clean = false +via = "direct" diff --git a/telperion/missions/mirrormere/nodes/MM_torus_section_n2_rigidity.toml b/telperion/missions/mirrormere/nodes/MM_torus_section_n2_rigidity.toml index 5600a2f24..3f19cde46 100644 --- a/telperion/missions/mirrormere/nodes/MM_torus_section_n2_rigidity.toml +++ b/telperion/missions/mirrormere/nodes/MM_torus_section_n2_rigidity.toml @@ -5,7 +5,13 @@ name = "MM.torus_section_n2_rigidity" statement_module = "Statements.MM_torus_section_n2_rigidity" status = "open" title = "Torus-section ladder T1, the N=2 rung in ladder vocabulary: the section of the linear form c1 z1 + c2 z2 along the T^2 orbit is real-rooted iff the coefficient moduli are equal -- KS section theory at d=2, 2-D parent governing 1-D rigidity. Discharge route: short bridge from twoFreq_realRooted_iff (QC_TORUS_SECTION_LADDER memo sections 1, 5)" -updated = "2026-09-14" +updated = "2026-09-18" + +[proof] +artifact = "../../examples/quasicrystal/lean/TorusSectionLadder.lean" +artifact_kind = "lean_module" +closure_clean = false +via = "direct" [readback] auditor = "blind-auditor 2026-09-14 (independent blind read-back, AUDIT_TESTIMONY_ANDURIL_MIRRORMERE_2026-09-14.md)" diff --git a/telperion/src/telperion/__init__.py b/telperion/src/telperion/__init__.py index 2e6842384..9d6eb0f96 100644 --- a/telperion/src/telperion/__init__.py +++ b/telperion/src/telperion/__init__.py @@ -101,6 +101,10 @@ weil_form_enclosure_certificate, weil_form_enclosure_family, certify_weil_form_enclosure_point, weil_form_prelude_lean, ) +from .emit_exp_enclosure import ( # noqa: F401 + ExpEnclosureEmitter, ExpEnclosureCert, exp_enclosure_certificate, + exp_enclosure_family, certify_exp_enclosure_point, taylor_box, taylor_parts, +) from .emit_enclosure_fold import ( # noqa: F401 EnclosureIntervalFoldEmitter, enclosure_interval_fold_certificate, enclosure_interval_fold_family, @@ -200,6 +204,10 @@ PolyExpAbsorptionEmitter, poly_exp_absorption_certificate, poly_exp_absorption_family, ) +from .emit_exp_laurent_identity import ( # noqa: F401 + ExpLaurentIdentityEmitter, exp_laurent_certificate, + exp_laurent_identity_family, +) from .emit_graded_convolution import ( # noqa: F401 GradedConvolutionEmitter, graded_convolution_certificate, graded_convolution_family, @@ -369,6 +377,14 @@ SelfInversiveRigidityEmitter, selfinversive_rigidity_certificate, selfinversive_rigidity_family, certify_selfinversive_rigidity_point, ) +from .emit_disjoint_discs import ( # noqa: F401 + DisjointDiscsEmitter, disjoint_discs_certificate, + disjoint_discs_family, certify_disjoint_discs_point, +) +from .emit_twofreq_offline import ( # noqa: F401 + TwoFreqOfflineEmitter, twofreq_offline_certificate, + twofreq_offline_family, certify_twofreq_offline_point, +) from .emit_winding_box_zero import ( # noqa: F401 WindingBoxZeroEmitter, winding_box_zero_certificate, winding_box_zero_family, certify_winding_box_zero_point, diff --git a/telperion/src/telperion/certify.py b/telperion/src/telperion/certify.py index a86edaa6e..0d3b68eaf 100644 --- a/telperion/src/telperion/certify.py +++ b/telperion/src/telperion/certify.py @@ -341,6 +341,10 @@ class _Guard: "comparability_envelope", "discrete_moment", "poly_exp_absorption", + # MIRRORMERE W3d (2026-09-18): exp-Laurent identities in e^d, e^(-d) + # certified as an exact reduction modulo the single relation + # e^d * e^(-d) = 1 (the Face 4 <-> Face 1 recurrence-deficit rows). + "exp_laurent_identity", # NS/Euler wave-6 (2026-09-09, campaign closeout): graded-convolution # endpoint identities, power-tower recurrence closure, Faa di Bruno # partition-sum bound, forbidden-factor word invariant (first discrete @@ -366,6 +370,14 @@ class _Guard: "bragg_amplitude", "defect_witness", "selfinversive_rigidity", + # disjoint_discs -- MIRRORMERE E4b isolation INSTANCE (OfflineDiscs): explicit + # strip points + explicit rational radius, pairwise (2r)^2 < + # dist^2 and strict strip margins, all norm_num-decided. + "disjoint_discs", + # twofreq_offline -- the COMPLEMENT of selfinversive_rigidity: |c1|^2 != |c2|^2 + # EXACTLY ==> the two-frequency sum is NOT real-rooted (and, + # for the Euler-factor family, every zero sits at Im x = 1/2). + "twofreq_offline", "winding_box_zero", # RH SEVEN-FACES instruments (2026-09-14, face-emitters agent): per-instance, # kernel-checkable shadows of four RH faces. Each carries the transcendental / @@ -401,6 +413,10 @@ class _Guard: # emitted as a NAMED-HYPOTHESIS seam whose kernel consequence is positivity / a positive # 2x2 Sylvester minor. Finite category-b; conjecture1_proved = False. "weil_form_enclosure", + # MIRRORMERE exp-enclosure (2026-09-18): rational brackets of Real.exp at a rational point + # from Real.exp_bound -- reflects BraggDefect's Arb `hexp` seam into the kernel and brackets + # the recurrence deficit e^d + e^-d - 2. A finite arithmetic fact; nothing about RH. + "exp_enclosure", ) # kind -> "module:certify_point_fn" for the generic (family.special) emitters. @@ -588,6 +604,9 @@ class _Guard: "poly_exp_absorption": ("emit_poly_exp_absorption", "certify_poly_exp_absorption_point", "PolyExpAbsorptionEmitter"), + "exp_laurent_identity": + ("emit_exp_laurent_identity", "certify_exp_laurent_identity_point", + "ExpLaurentIdentityEmitter"), "graded_convolution": ("emit_graded_convolution", "certify_graded_convolution_point", "GradedConvolutionEmitter"), @@ -611,6 +630,10 @@ class _Guard: "selfinversive_rigidity": ("emit_selfinversive_rigidity", "certify_selfinversive_rigidity_point", "SelfInversiveRigidityEmitter"), + "disjoint_discs": + ("emit_disjoint_discs", "certify_disjoint_discs_point", "DisjointDiscsEmitter"), + "twofreq_offline": + ("emit_twofreq_offline", "certify_twofreq_offline_point", "TwoFreqOfflineEmitter"), "winding_box_zero": ("emit_winding_box_zero", "certify_winding_box_zero_point", "WindingBoxZeroEmitter"), # RH SEVEN-FACES instruments (2026-09-14, face-emitters agent). @@ -636,6 +659,10 @@ class _Guard: "weil_form_enclosure": ("emit_weil_form_enclosure", "certify_weil_form_enclosure_point", "WeilFormEnclosureEmitter"), + # MIRRORMERE exp-enclosure (rational Real.exp brackets via Real.exp_bound; the + # BraggDefect hexp seam, the QC_RECURRENCE deficit row, the ZooDH cosh input). + "exp_enclosure": + ("emit_exp_enclosure", "certify_exp_enclosure_point", "ExpEnclosureEmitter"), } diff --git a/telperion/src/telperion/emit_disjoint_discs.py b/telperion/src/telperion/emit_disjoint_discs.py new file mode 100644 index 000000000..1e3f803eb --- /dev/null +++ b/telperion/src/telperion/emit_disjoint_discs.py @@ -0,0 +1,320 @@ +"""Disjoint-discs emitter -- the CONCRETE-INSTANCE shape of the MIRRORMERE E4b isolation lemma. + +The general lemma (registry node ``MM_offline_disjoint_discs``, proved in the quasicrystal island's +``OfflineDiscs.lean``) says: any finite set of points strictly inside the open critical strip admits +SOME common positive radius whose closed discs are pairwise disjoint and stay inside the strip. It +is an existence statement with no numbers in it. + +What the E5 Rouche-template leg actually consumes is the INSTANCE: a concrete list of certified +ordinates (say Platt/Turing-verified zero locations, or any rational strip points) together with an +EXPLICIT rational radius, so that the discs can be handed to a winding/Rouche count. This emitter +is that shape -- the certificate is + + points = ((re_0, im_0), ..., (re_{n-1}, im_{n-1})) Gaussian-rational strip points + r = an explicit positive rational radius + +and the kernel checks, per instance: + + * PAIRWISE SEPARATION (2r)^2 < (re_i - re_j)^2 + (im_i - im_j)^2 for every i < j + -- exactly the hypothesis of `Metric.closedBall_disjoint_closedBall (h : d + e < dist x y)`, + reached through `Complex.dist_eq`, `Complex.norm_def` and `Real.lt_sqrt`, all closed by + `norm_num` on rational data. Squaring is what keeps it rational: no square root is ever + approximated, the `√` is eliminated by `Real.lt_sqrt` before any arithmetic happens. + * STRIP MARGIN 0 < re_i - r and re_i + r < 1 + -- the closed disc of radius r about a point of real part `re_i` lies in the OPEN strip iff + the radius is strictly below both margins; the containment proof is the 1-Lipschitz bound + |s.re - z.re| <= dist s z (`Quasicrystal.abs_re_sub_le_dist`, the island lemma). + +The emitted theorem is the registry node's own conclusion with `S` instantiated to the concrete +`Finset`, so the instance literally witnesses the general lemma's existential at explicit data. + +SELF-CHECK (exact rational arithmetic, no floats): r > 0; the points pairwise distinct; the squared +separation and both strip margins STRICT. + +NEGATIVE CONTROL (refused at certification with ``ValueError``, and kernel-rejected if forged past +Layer 1 -- see ``negctrl_adapters/adapter_disjoint_discs.py``): + * a radius too large for some pair, `(2r)^2 >= dist^2` -- the discs touch or overlap, so + `closedBall_disjoint_closedBall` has no hypothesis to take and `norm_num` refutes the emitted + strict inequality; + * a point ON the strip boundary (re = 0 or re = 1), or a radius reaching it (`re <= r` or + `re + r >= 1`) -- the disc leaves the OPEN strip; + * a duplicate point (the pair would demand `Disjoint` of a ball with itself), or r <= 0. + +conjecture1_proved = False -- a finite, unconditional geometry certificate about explicitly given +points. It says NOTHING about where the zeros of zeta are; the points are INPUT. +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Callable + +import sympy as sp + +try: # normal package import + from .certify import CertifiedInstance + from .expr import rat_lean + from .family import GridSpec, InequalityFamily + from .lean import LeanProfile + from .workflow import Emitter +except ImportError: # run directly + import os + import sys + + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + from telperion.certify import CertifiedInstance + from telperion.expr import rat_lean + from telperion.family import GridSpec, InequalityFamily + from telperion.lean import LeanProfile + from telperion.workflow import Emitter + + +@dataclass(frozen=True) +class DisjointDiscsCertificate: + """A verified isolation certificate: distinct Gaussian-rational points of the OPEN strip and an + explicit rational radius `r > 0` with `(2r)^2 < dist^2` for every pair and `r` strictly below + every strip margin `min(re, 1 - re)`.""" + + points: tuple[tuple[sp.Rational, sp.Rational], ...] + r: sp.Rational + min_sep_sq: sp.Rational # the smallest pairwise squared distance (0 for < 2 points) + min_margin: sp.Rational # the smallest min(re, 1 - re) over the points + + +def disjoint_discs_certificate(points, r) -> DisjointDiscsCertificate: + """Build and EXACTLY self-check a disjoint-discs certificate. + + ``points``: an iterable of ``(re, im)`` rational pairs. ``r``: a positive rational radius. + + REFUSES (``ValueError``): non-rational input; ``r <= 0``; a duplicate point; a point outside the + OPEN strip; a radius reaching the strip boundary (``r >= min(re, 1 - re)``); a pair with + ``(2r)^2 >= dist^2`` (touching or overlapping discs). + """ + pts = [] + for k, p in enumerate(points): + if len(tuple(p)) != 2: + raise ValueError(f"disjoint_discs: point {k} must be an (re, im) pair; got {p!r}") + re_, im_ = sp.nsimplify(p[0]), sp.nsimplify(p[1]) + for nm, v in ((f"re[{k}]", re_), (f"im[{k}]", im_)): + if not v.is_rational: + raise ValueError(f"disjoint_discs: {nm} must be rational; got {v!r}") + pts.append((sp.Rational(re_), sp.Rational(im_))) + rq = sp.nsimplify(r) + if not rq.is_rational: + raise ValueError(f"disjoint_discs: radius must be rational; got {r!r}") + rq = sp.Rational(rq) + if rq <= 0: + raise ValueError(f"disjoint_discs: radius must be positive; got r={rq}") + if not pts: + raise ValueError("disjoint_discs: need at least one point (the empty instance is vacuous)") + + # strip membership + margin (the boundary negative control) + margins = [] + for k, (re_, im_) in enumerate(pts): + if not (0 < re_ < 1): + raise ValueError( + f"disjoint_discs: point {k} = ({re_}, {im_}) is not in the OPEN strip 0 < re < 1; " + f"refused (a boundary point has no disc inside the strip)") + m = min(re_, 1 - re_) + if rq >= m: + raise ValueError( + f"disjoint_discs: radius r={rq} reaches the strip boundary at point {k} " + f"(margin min(re, 1-re) = {m}); the closed disc leaves the OPEN strip; refused") + margins.append(m) + + # pairwise strict separation (the overlap negative control) + seps = [] + two_r_sq = (2 * rq) ** 2 + for i in range(len(pts)): + for j in range(i + 1, len(pts)): + dx = pts[i][0] - pts[j][0] + dy = pts[i][1] - pts[j][1] + d2 = dx ** 2 + dy ** 2 + if d2 == 0: + raise ValueError( + f"disjoint_discs: points {i} and {j} coincide ({pts[i]}); distinct centres are " + f"required (a ball is never disjoint from itself); refused") + if two_r_sq >= d2: + raise ValueError( + f"disjoint_discs: pair ({i},{j}) has (2r)^2 = {two_r_sq} >= dist^2 = {d2} — the " + f"discs touch or overlap, so they are NOT disjoint; refused") + seps.append(d2) + + return DisjointDiscsCertificate( + points=tuple(pts), r=rq, + min_sep_sq=(min(seps) if seps else sp.Integer(0)), + min_margin=min(margins), + ) + + +def certify_disjoint_discs_point(family, pt, name): + """Certify one instance from ``family.special[1](pt)`` — a dict with keys ``points`` and ``r``.""" + spec = family.special[1](pt) + if isinstance(spec, dict): + cert = disjoint_discs_certificate(spec["points"], spec["r"]) + elif isinstance(spec, (tuple, list)): + cert = disjoint_discs_certificate(spec[0], spec[1]) + else: + raise ValueError(f"disjoint_discs spec must be a dict or (points, r) tuple; got {spec!r}") + inst = CertifiedInstance(point=dict(pt), lean_name=name, corners=(), payload=cert) + return inst, 1 + + +_STRIP = "{s : ℂ | 0 < s.re ∧ s.re < 1}" + + +@dataclass +class DisjointDiscsEmitter(Emitter): + """Emit the concrete isolation instance: point defs, the `Finset`, one disjointness theorem per + pair, one strip-containment theorem per point, and the assembled existential — the registry + node `MM_offline_disjoint_discs`'s conclusion at explicit data. + + The emitted file uses `Quasicrystal.abs_re_sub_le_dist` from the island's `OfflineDiscs` lib, so + it must be built inside the quasicrystal island (profile imports `Mathlib` and `OfflineDiscs`). + """ + + def __post_init__(self): + self.kind = "disjoint_discs" + self.requires_prelude = () + + def _gate_type(self, base: str) -> str: + return ( + f"∃ r : ℝ, 0 < r ∧\n" + f" (∀ z ∈ {base}_S, ∀ w ∈ {base}_S, z ≠ w →\n" + f" Disjoint (Metric.closedBall z r) (Metric.closedBall w r)) ∧\n" + f" (∀ z ∈ {base}_S, Metric.closedBall z r ⊆ {_STRIP})" + ) + + def emit_body(self, fam, profile: LeanProfile) -> tuple[str, int]: + lines: list[str] = [] + nthm = 0 + for inst in fam.instances: + cert: DisjointDiscsCertificate = inst.payload # type: ignore[assignment] + base = inst.lean_name + n = len(cert.points) + rr = rat_lean(cert.r) + + lines.append( + f"/-- Isolation instance `{base}`: {n} explicitly given point(s) of the open\n" + f" critical strip, with the rational radius `r = {rr}`. Certified separation\n" + f" `min dist² = {cert.min_sep_sq}` and strip margin `min (re, 1 - re) = {cert.min_margin}`,\n" + f" both strictly beating `(2r)² = {(2 * cert.r) ** 2}` resp. `r`.\n" + f" conjecture1_proved = False — the points are INPUT, not a claim about ζ. -/\n" + ) + for k, (re_, im_) in enumerate(cert.points): + lines.append( + f"noncomputable def {base}_p{k} : ℂ := ⟨({rat_lean(re_)}), ({rat_lean(im_)})⟩\n") + elems = ", ".join(f"{base}_p{k}" for k in range(n)) + lines.append(f"\nnoncomputable def {base}_S : Finset ℂ := {{{elems}}}\n\n") + + # per-pair disjointness + for i in range(n): + for j in range(i + 1, n): + lines.append( + f"/-- Pair ({i},{j}): `(2·{rr})² < dist²`, so the closed discs are disjoint. -/\n" + f"theorem {base}_pair_{i}_{j} :\n" + f" Disjoint (Metric.closedBall {base}_p{i} (({rr}) : ℝ))\n" + f" (Metric.closedBall {base}_p{j} (({rr}) : ℝ)) := by\n" + f" apply Metric.closedBall_disjoint_closedBall\n" + f" rw [Complex.dist_eq, Complex.norm_def, Real.lt_sqrt (by norm_num)]\n" + f" simp only [{base}_p{i}, {base}_p{j}, Complex.normSq_apply,\n" + f" Complex.sub_re, Complex.sub_im]\n" + f" norm_num\n\n" + ) + nthm += 1 + + # per-point strip containment + for k, (re_, _im) in enumerate(cert.points): + lines.append( + f"/-- Point {k}: the closed disc of radius `{rr}` about `{base}_p{k}`\n" + f" (real part `{rat_lean(re_)}`) stays inside the OPEN strip. -/\n" + f"theorem {base}_strip_{k} :\n" + f" Metric.closedBall {base}_p{k} (({rr}) : ℝ) ⊆ {_STRIP} := by\n" + f" intro s hs\n" + f" have hd : dist s {base}_p{k} ≤ (({rr}) : ℝ) := Metric.mem_closedBall.mp hs\n" + f" have hre := abs_le.mp (Quasicrystal.abs_re_sub_le_dist s {base}_p{k})\n" + f" have hz : ({base}_p{k}).re = (({rat_lean(re_)}) : ℝ) := by\n" + f" simp only [{base}_p{k}]\n" + f" rw [hz] at hre\n" + f" exact ⟨by linarith [hre.1], by linarith [hre.2]⟩\n\n" + ) + nthm += 1 + + # the assembly: the registry node's conclusion at this concrete Finset + pair_arms = [] + for i in range(n): + for j in range(n): + if i == j: + continue + a, b = min(i, j), max(i, j) + suffix = "" if (i, j) == (a, b) else ".symm" + pair_arms.append(f" | exact {base}_pair_{a}_{b}{suffix}\n") + pair_block = "".join(sorted(set(pair_arms))) + strip_arms = "".join(f" · exact {base}_strip_{k}\n" for k in range(n)) + rcases_z = " | ".join(["rfl"] * n) + + lines.append( + f"/-- **Isolation instance** ({base}): the concrete witness for the registry node\n" + f" `MM_offline_disjoint_discs` at these {n} point(s) — radius `r = {rr}` makes the\n" + f" closed discs pairwise disjoint and keeps each inside the open critical strip.\n" + f" conjecture1_proved = False. -/\n" + f"theorem {base} :\n" + f" {self._gate_type(base)} := by\n" + f" refine ⟨(({rr}) : ℝ), by norm_num, ?_, ?_⟩\n" + f" · intro z hz w hw hzw\n" + f" simp only [{base}_S, Finset.mem_insert, Finset.mem_singleton] at hz hw\n" + f" rcases hz with {rcases_z} <;> rcases hw with {rcases_z} <;>\n" + f" first\n" + f" | exact absurd rfl hzw\n" + f"{pair_block}" + f" · intro z hz\n" + f" simp only [{base}_S, Finset.mem_insert, Finset.mem_singleton] at hz\n" + f" rcases hz with {rcases_z}\n" + f"{strip_arms}\n" + ) + nthm += 1 + gate = self.emit_gate(base, self._gate_type(base)) + if gate: + lines.append(gate + "\n") + return "".join(lines), nthm + + +def disjoint_discs_family( + name: str, grid: GridSpec, lean_name: Callable, spec: Callable, constants: dict | None = None +) -> InequalityFamily: + """Build a disjoint_discs family (kind='disjoint_discs'). ``spec``: ``pt -> {"points": [...], + "r": ...}`` or ``pt -> (points, r)``. Refuses overlapping discs, boundary-reaching radii, + duplicate points and non-positive radii at certification.""" + return InequalityFamily( + name=name, symbols=(), grid=grid, lean_name=lean_name, + special=("disjoint_discs", spec), constants=dict(constants or {}), + ) + + +if __name__ == "__main__": + PTS = [("1/2", "7067/500"), ("1/2", "10511/500"), ("2/5", "10511/500")] + print("=== positive cert (3 strip points, r = 1/50) ===") + c = disjoint_discs_certificate(PTS, "1/50") + print(f"cert OK: min dist² = {c.min_sep_sq}, (2r)² = {(2 * c.r) ** 2}, margin = {c.min_margin}") + print("\n=== NEGATIVE CONTROL 1: radius too large (r = 1/20, pair (1,2) at dist 1/10) ===") + try: + disjoint_discs_certificate(PTS, "1/20") + raise SystemExit("FAIL: overlapping discs not refused") + except ValueError as e: + print(f"refused as expected: {e}") + print("\n=== NEGATIVE CONTROL 2: a point on the strip boundary (re = 1) ===") + try: + disjoint_discs_certificate([("1", "5"), ("1/2", "9")], "1/100") + raise SystemExit("FAIL: boundary point not refused") + except ValueError as e: + print(f"refused as expected: {e}") + print("\n=== emitted Lean ===") + fam = disjoint_discs_family( + "T", GridSpec([("case", [0])]), lambda pt: "disjoint_discs_demo", + spec=lambda pt: {"points": PTS, "r": "1/50"}) + inst, _ = certify_disjoint_discs_point(fam, {"case": 0}, "disjoint_discs_demo") + + class _V: + instances = [inst] + + body, nthm = DisjointDiscsEmitter().emit_body(_V(), LeanProfile(namespace=("X",))) + print(f"\n-- {nthm} theorems --\n{body}") diff --git a/telperion/src/telperion/emit_exp_enclosure.py b/telperion/src/telperion/emit_exp_enclosure.py new file mode 100644 index 000000000..d413c487b --- /dev/null +++ b/telperion/src/telperion/emit_exp_enclosure.py @@ -0,0 +1,379 @@ +"""exp-enclosure emitter -- kernel-checked RATIONAL BRACKETS of `Real.exp` (and of the +recurrence deficit `e^d + e^-d - 2` and `Real.cosh`) from Mathlib's `Real.exp_bound`. + +WHY THIS EMITTER EXISTS +----------------------- +MIRRORMERE's `MM_bragg_defect_witness` (artifact +`examples/zeta_zero_localization/lean/BraggDefect.lean`) states its off-line leakage witness +UNDER a named hypothesis + + hexp : expLo <= Real.exp (1 / 10) /\\ Real.exp (1 / 10) <= expHi , + +an Arb (python-flint) enclosure carried as an assumption -- the node's read-back says +`closure_clean` stays false "until that enclosure is itself reflected". The registry had no +emitter for `exp` brackets: `emit_transcendental_enclosure` ships only a `log` face, and +`emit_log_combination` uses `Real.exp_bound'` as an internal degree-3 step, never as a +standalone certificate. This emitter is that missing face: it turns the Arb seam into a +kernel theorem, so the hypothesis can be discharged and the witness stated unconditionally. + +THE MATHEMATICS (one Mathlib fact, no analysis of our own) +---------------------------------------------------------- + Real.exp_bound {x : R} (hx : |x| <= 1) {n : N} (hn : 0 < n) : + |Real.exp x - sum_{m in range n} x^m / m!| <= |x|^n * (n.succ / (n! * n)) + +For a RATIONAL `x` with `|x| <= 1` both the partial sum `S_n = sum_{m 1` -- outside `Real.exp_bound`'s hypothesis. (The halving trick + `exp x = (exp (x/2))^2` would extend the range; it is deliberately + NOT implemented silently -- a follow-on, stated here so the + limitation is visible rather than worked around.) +* `n < 1` or `n > 64` -- the order cap; beyond it the `norm_num [Nat.factorial]` step is not + the intended cheap kernel check, so we refuse rather than emit Lean + we have not sized. +* `lo > hi` -- an inverted claim. +* `lo > S_n - r_n` or `hi < S_n + r_n` -- THE FORGE CASE: a claimed bracket the Taylor box + does NOT imply. This is refused at EVERY order up to the cap, so a + too-tight (or simply false) claim can never ship. +* deficit mode with `x <= 0` -- the deficit is 0 at `x = 0`, and the QC_RECURRENCE row-(a) + reading needs a strictly positive displacement. +* non-rational input -- symbolic or float `x`/`lo`/`hi` (a float would silently smuggle in + its binary expansion). + +MODES +----- +* `exp` -- `lo <= Real.exp x <= hi` +* `exp_neg` -- `lo <= Real.exp (-x) <= hi` +* `deficit` -- `lo <= Real.exp x + Real.exp (-x) - 2 <= hi` (QC_RECURRENCE row a; the numeric + twin of `MM_recurrence_deficit_eq_excess`, and `BraggDefect.excess`'s bracket). + Carries BOTH Taylor boxes and self-checks the claim against their sum. +* `cosh` -- `lo <= Real.cosh x <= hi` via `Real.cosh_eq` on the same two boxes (the + `ZooDH.cosh_bracket` input shape). + +conjecture1_proved = False. +""" +from __future__ import annotations + +from dataclasses import dataclass +from fractions import Fraction +from math import factorial +from typing import Callable + +import sympy as sp + +from .certify import CertifiedInstance +from .expr import rat_lean +from .family import GridSpec, InequalityFamily +from .lean import LeanProfile +from .workflow import Emitter + +#: Taylor orders above this are refused (the `norm_num [Nat.factorial]` step is sized for +#: orders the BraggDefect / ZooDH literals actually need -- `n = 14` at `x = 1/10`). +MAX_ORDER = 64 + +MODES = ("exp", "exp_neg", "deficit", "cosh") + + +def _rat(v, what: str) -> sp.Rational: + """Exactly-rational coercion; REFUSES floats and symbolic values.""" + if isinstance(v, float): + raise ValueError( + f"exp_enclosure REFUSED: {what} was given as a float ({v!r}); a float carries its " + "binary expansion, not the rational you wrote -- pass a str/Fraction/sp.Rational") + try: + q = sp.Rational(v) + except (TypeError, ValueError) as exc: + raise ValueError( + f"exp_enclosure REFUSED: {what} = {v!r} is not rational ({exc})") from None + if not isinstance(q, sp.Rational): + raise ValueError(f"exp_enclosure REFUSED: {what} = {v!r} is not rational") + return q + + +def _F(q: sp.Rational) -> Fraction: + return Fraction(int(q.p), int(q.q)) + + +def taylor_box(x: sp.Rational, n: int) -> tuple[sp.Rational, sp.Rational]: + """The EXACT rational order-`n` Taylor box `[S_n - r_n, S_n + r_n]` for `Real.exp x`.""" + S, r = taylor_parts(x, n) + return S - r, S + r + + +def taylor_parts(x: sp.Rational, n: int) -> tuple[sp.Rational, sp.Rational]: + """`(S_n, r_n)`: the exact partial sum and the exact `Real.exp_bound` remainder.""" + xf = _F(x) + S = sum((xf ** m / factorial(m) for m in range(n)), Fraction(0)) + r = abs(xf) ** n * Fraction(n + 1, factorial(n) * n) + return sp.Rational(S.numerator, S.denominator), sp.Rational(r.numerator, r.denominator) + + +@dataclass(frozen=True) +class ExpEnclosureCert: + """One exp-enclosure certificate. + + `partial_sum`/`remainder` are the EXACT order-`n` `Real.exp_bound` data at `x` + (`remainder` depends only on `|x|`, so it serves the `-x` box too); + `partial_sum_neg` is the partial sum at `-x`, carried in the two-sided modes + (`deficit`, `cosh`). `lo`/`hi` are the CLAIMED bracket -- the statement itself. + """ + + x: sp.Rational + n: int + partial_sum: sp.Rational + remainder: sp.Rational + lo: sp.Rational + hi: sp.Rational + mode: str + partial_sum_neg: sp.Rational | None = None + + @property + def box(self) -> tuple[sp.Rational, sp.Rational]: + """The Taylor box of the QUANTITY THIS CERTIFICATE CLAIMS (mode-dependent).""" + S, r = self.partial_sum, self.remainder + if self.mode == "exp": + return S - r, S + r + if self.mode == "exp_neg": + Sm = self.partial_sum_neg if self.partial_sum_neg is not None else S + return Sm - r, Sm + r + Sm = self.partial_sum_neg + if Sm is None: # pragma: no cover -- constructor always supplies it + raise ValueError(f"exp_enclosure REFUSED: mode {self.mode} needs partial_sum_neg") + if self.mode == "deficit": + return (S - r) + (Sm - r) - 2, (S + r) + (Sm + r) - 2 + if self.mode == "cosh": + return ((S - r) + (Sm - r)) / 2, ((S + r) + (Sm + r)) / 2 + raise ValueError(f"exp_enclosure REFUSED: unknown mode {self.mode!r}") + + @property + def slack(self) -> tuple[sp.Rational, sp.Rational]: + """`(box_lo - lo, hi - box_hi)` -- both must be >= 0 for the claim to be implied.""" + blo, bhi = self.box + return blo - self.lo, self.hi - bhi + + +def _mode_box(x: sp.Rational, n: int, mode: str) -> tuple[sp.Rational, sp.Rational]: + plo, phi = taylor_box(x, n) + if mode == "exp": + return plo, phi + mlo, mhi = taylor_box(-x, n) + if mode == "exp_neg": + return mlo, mhi + if mode == "deficit": + return plo + mlo - 2, phi + mhi - 2 + return (plo + mlo) / 2, (phi + mhi) / 2 # cosh + + +def exp_enclosure_certificate(x, lo, hi, *, mode: str = "exp", n: int | None = None, + max_order: int = MAX_ORDER) -> ExpEnclosureCert: + """Build (and exactly re-check) an exp-enclosure certificate. + + `n=None` selects the LEAST Taylor order (<= `max_order`) whose exact box fits inside the + CLAIMED `[lo, hi]`; if no order fits, the claim is REFUSED -- never widened. An explicit + `n` is checked at that order alone. See the module docstring for the refusal list. + """ + if mode not in MODES: + raise ValueError( + f"exp_enclosure REFUSED: unknown mode {mode!r} (expected one of {MODES})") + xq = _rat(x, "x") + loq = _rat(lo, "lo") + hiq = _rat(hi, "hi") + if abs(xq) > 1: + raise ValueError( + f"exp_enclosure REFUSED: |x| = {abs(xq)} > 1 is outside Real.exp_bound's hypothesis " + "(the halving identity exp x = (exp (x/2))^2 would extend the range; it is a " + "deliberate follow-on, not applied silently)") + if loq > hiq: + raise ValueError(f"exp_enclosure REFUSED: inverted bracket lo = {loq} > hi = {hiq}") + if mode == "deficit" and xq <= 0: + raise ValueError( + f"exp_enclosure REFUSED: deficit mode needs x > 0, got x = {xq} (the deficit " + "e^x + e^-x - 2 vanishes at 0; the QC_RECURRENCE row-(a) reading needs d > 0)") + if n is not None: + if not isinstance(n, int) or isinstance(n, bool): + raise ValueError(f"exp_enclosure REFUSED: Taylor order n = {n!r} is not an int") + if n < 1: + raise ValueError(f"exp_enclosure REFUSED: Taylor order n = {n} < 1 " + "(Real.exp_bound needs 0 < n)") + if n > max_order: + raise ValueError( + f"exp_enclosure REFUSED: Taylor order n = {n} exceeds the cap {max_order}") + orders = [n] + else: + orders = list(range(1, max_order + 1)) + + chosen = None + for k in orders: + blo, bhi = _mode_box(xq, k, mode) + if loq <= blo and bhi <= hiq: + chosen = k + break + if chosen is None: + blo, bhi = _mode_box(xq, orders[-1], mode) + raise ValueError( + f"exp_enclosure REFUSED at x = {xq} (mode {mode}): the claimed bracket " + f"[{loq}, {hiq}] is NOT implied by the Taylor box -- at order {orders[-1]} the box " + f"is [{blo}, {bhi}] (box_lo - lo = {blo - loq}, hi - box_hi = {hiq - bhi}; both must " + "be >= 0). Widen the claim or raise the order cap; the emitter does neither for you") + + S, r = taylor_parts(xq, chosen) + Sneg, _ = taylor_parts(-xq, chosen) + cert = ExpEnclosureCert( + x=xq, n=chosen, partial_sum=S, remainder=r, lo=loq, hi=hiq, mode=mode, + partial_sum_neg=Sneg, + ) + slo, shi = cert.slack + if slo < 0 or shi < 0: # pragma: no cover -- the search above already guarantees this + raise ValueError( + f"exp_enclosure REFUSED: post-check failed, slack = ({slo}, {shi})") + return cert + + +def certify_exp_enclosure_point(family, pt, name): + """Certify one exp-enclosure point: ``(CertifiedInstance, 1)``. + + Reads the spec dict from ``family.special[1](pt)`` -- keys ``x``, ``lo``, ``hi`` and the + optional ``mode`` / ``n`` / ``max_order`` -- and re-checks it via + :func:`exp_enclosure_certificate` (which raises on every dishonest claim).""" + spec = family.special[1](pt) + cert = exp_enclosure_certificate( + spec["x"], spec["lo"], spec["hi"], + mode=spec.get("mode", "exp"), + n=spec.get("n"), + max_order=spec.get("max_order", MAX_ORDER), + ) + return CertifiedInstance(point=dict(pt), lean_name=name, corners=(), payload=cert), 1 + + +# --- Lean rendering --------------------------------------------------------- + +_TACTIC = ( + " have hb := Real.exp_bound {habs} (n := {n}) (by norm_num)\n" + " simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb\n" + " rw [abs_le] at hb\n" + " obtain ⟨h1, h2⟩ := hb\n" + " constructor\n" + " · norm_num [Nat.factorial] at h1 ⊢; linarith\n" + " · norm_num [Nat.factorial] at h2 ⊢; linarith\n" +) + + +def _exp_lemma(nm: str, xs: str, n: int, lo: str, hi: str, *, neg: bool) -> str: + """One `Real.exp_bound` bracket lemma, for `exp x` (`neg=False`) or `exp (-x)`.""" + arg = f"(-({xs}))" if neg else f"({xs})" + habs = (f" have hx : |(({xs}) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num\n" + f" have hx' : |((-({xs})) : ℝ)| ≤ 1 := by rwa [abs_neg]\n") if neg else ( + f" have hx : |(({xs}) : ℝ)| ≤ 1 := by rw [abs_le]; constructor <;> norm_num\n") + return ( + f"theorem {nm} : (({lo}) : ℝ) ≤ Real.exp {arg} ∧ Real.exp {arg} ≤ (({hi}) : ℝ) := by\n" + + habs + + _TACTIC.format(habs="hx'" if neg else "hx", n=n) + ) + + +@dataclass +class ExpEnclosureEmitter(Emitter): + """Emit rational brackets of `Real.exp` / the recurrence deficit / `Real.cosh` at a + rational point, each proved from Mathlib's `Real.exp_bound` at the certified order by + `norm_num [Nat.factorial]` + `linarith`. No `decide`, no `sorry`; the claimed bracket IS + the statement and `exp_enclosure_certificate` refuses any claim the exact Taylor box does + not imply. conjecture1_proved = False.""" + + def __post_init__(self): + self.kind = "exp_enclosure" + + def _header(self, cert: ExpEnclosureCert, nm: str) -> str: + slo, shi = cert.slack + blo, bhi = cert.box + what = { + "exp": f"Real.exp ({cert.x})", + "exp_neg": f"Real.exp (-({cert.x}))", + "deficit": f"Real.exp ({cert.x}) + Real.exp (-({cert.x})) - 2", + "cosh": f"Real.cosh ({cert.x})", + }[cert.mode] + return ( + f"/-- `{nm}` -- a certified RATIONAL ENCLOSURE of `{what}`.\n" + f" Order-{cert.n} `Real.exp_bound` box `[S - r, S + r]` (exact rationals,\n" + f" S = sum_(m < {cert.n}) x^m/m!, r = |x|^{cert.n} * ({cert.n}+1)/({cert.n}! * {cert.n})),\n" + f" which lies inside the claimed bracket with slack ({slo}, {shi}) >= 0;\n" + f" box = [{blo}, {bhi}]. The order is the LEAST one whose box fits -- the\n" + f" generator REFUSES a bracket the box does not imply rather than widening it.\n" + f" A finite arithmetic fact about a transcendental constant at one rational\n" + f" point; nothing about RH. conjecture1_proved = False. -/\n" + ) + + def emit_body(self, fam, profile: LeanProfile) -> tuple[str, int]: + lines: list[str] = [] + n_thm = 0 + for inst in fam.instances: + cert: ExpEnclosureCert = inst.payload # type: ignore[assignment] + nm = inst.lean_name + xs = rat_lean(cert.x) + lo = rat_lean(cert.lo) + hi = rat_lean(cert.hi) + lines.append(self._header(cert, nm)) + if cert.mode in ("exp", "exp_neg"): + lines.append(_exp_lemma(nm, xs, cert.n, lo, hi, neg=(cert.mode == "exp_neg"))) + n_thm += 1 + continue + + # two-sided modes: both exp faces as named lemmas, then the combination + plo, phi = taylor_box(cert.x, cert.n) + mlo, mhi = taylor_box(-cert.x, cert.n) + lines.append( + f"-- the `exp ({cert.x})` face of {nm} (its own exact order-{cert.n} box)\n" + + _exp_lemma(f"{nm}_pos", xs, cert.n, rat_lean(plo), rat_lean(phi), neg=False)) + lines.append( + f"-- the `exp (-({cert.x}))` face of {nm} (same order, same remainder)\n" + + _exp_lemma(f"{nm}_neg", xs, cert.n, rat_lean(mlo), rat_lean(mhi), neg=True)) + n_thm += 2 + if cert.mode == "deficit": + lines.append( + f"theorem {nm} : (({lo}) : ℝ) ≤ Real.exp ({xs}) + Real.exp (-({xs})) - 2 ∧\n" + f" Real.exp ({xs}) + Real.exp (-({xs})) - 2 ≤ (({hi}) : ℝ) := by\n" + f" constructor <;> linarith [{nm}_pos.1, {nm}_pos.2, {nm}_neg.1, {nm}_neg.2]\n" + ) + else: # cosh + lines.append( + f"theorem {nm} : (({lo}) : ℝ) ≤ Real.cosh ({xs}) ∧ " + f"Real.cosh ({xs}) ≤ (({hi}) : ℝ) := by\n" + f" rw [Real.cosh_eq]\n" + f" constructor <;> linarith [{nm}_pos.1, {nm}_pos.2, {nm}_neg.1, {nm}_neg.2]\n" + ) + n_thm += 1 + return "\n".join(lines), n_thm + + +def exp_enclosure_family( + name: str, + grid: GridSpec, + lean_name: Callable, + spec: Callable, + constants: dict | None = None, +) -> InequalityFamily: + """Build an exp-enclosure family (kind ``exp_enclosure``). + + ``spec: pt -> {"x", "lo", "hi", optional "mode"/"n"/"max_order"}`` -- the rational point + and the CLAIMED bracket; the order is chosen (least fitting) at certify time.""" + return InequalityFamily( + name=name, + symbols=(), + grid=grid, + lean_name=lean_name, + special=("exp_enclosure", spec), + constants=dict(constants or {}), + ) diff --git a/telperion/src/telperion/emit_exp_laurent_identity.py b/telperion/src/telperion/emit_exp_laurent_identity.py new file mode 100644 index 000000000..cb86342f8 --- /dev/null +++ b/telperion/src/telperion/emit_exp_laurent_identity.py @@ -0,0 +1,274 @@ +"""ExpLaurentIdentity emitter -- identities in ``Real.exp d`` and ``Real.exp (-d)`` +certified as an exact reduction modulo the SINGLE relation ``e^d * e^(-d) = 1``. + +THE SHAPE. A great many "exp bookkeeping" rows in the RH-adjacent corpus are +Laurent polynomials in the one transcendental ``y = exp d``, with ``z = exp (-d)`` +its formal inverse: amplitude sums ``y + z`` (a ``2 cosh`` channel), one-sided +clearances ``y - 1`` and ``1 - z``, their products and squares. Every TRUE +identity among them is exactly a polynomial identity in ``Q[y, z]`` modulo the one +relation ``y*z - 1``; every FALSE one leaves a nonzero remainder. This emitter +makes that the certificate: + + claim lhs = rhs (Laurent polynomials in y, z) + certify lhs - rhs = cofactor * (y*z - 1) in Q[y, z] (exact, sympy) + emit have hrel : Real.exp d * Real.exp (-d) = 1 := by + rw [<- Real.exp_add]; norm_num + linear_combination (cofactor) * hrel + +The COFACTOR is the load-bearing certificate: `linear_combination` re-derives the +goal from it by `ring`, so a corrupted cofactor -- or a corrupted side -- leaves a +nonzero residue and the Lean KERNEL rejects the theorem. That is the emitter's +negative control (``negctrl_adapters/adapter_exp_laurent_identity.py``). + +TWO REFUSALS (Layer-1 self-check, both exercised in the tests): + + * NON-IDENTITY -- the remainder of ``lhs - rhs`` modulo ``y*z - 1`` is nonzero. + The motivating instance is the mistake QC_RECURRENCE section 6 caught in + itself: the SUM of the two clearances, ``(y - 1) + (1 - z) = 2d + O(d^3)``, is + NOT the amplitude excess ``y + z - 2``; only the PRODUCT is. Certifying the + sum is refused with a nonzero remainder ``2 - 2z``. + * RELATION NOT LOAD-BEARING -- the cofactor is 0, i.e. ``lhs - rhs`` vanishes as + a polynomial and the claim never uses ``e^d * e^(-d) = 1``. That is an + ordinary ring identity; it belongs to ``IdentityEmitter``, and emitting it here + would advertise a certificate that carries no information. Refused. + +HONESTY SEAM: none. Every emitted theorem is an unconditional statement about +``Real.exp`` at a universally quantified real ``d`` -- no enclosure, no Arb input, +no analytic hypothesis. What the emitter does NOT do is supply the meaning: an +exp-Laurent row is dictionary bookkeeping between two instruments, never evidence +about zeta. conjecture1_proved = False. +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Callable, Sequence + +import sympy as sp + +from .certify import CertifiedInstance +from .family import GridSpec, InequalityFamily +from .lean import LeanProfile +from .workflow import Emitter + +# The two formal generators: y = exp(d), z = exp(-d). A family's `spec` returns +# its claimed (lhs, rhs) as sympy expressions in exactly these symbols. +Y = sp.Symbol("expPos") +Z = sp.Symbol("expNeg") + +#: The single relation the certificate reduces against. +RELATION = Y * Z - 1 + + +@dataclass(frozen=True) +class ExpLaurentCert: + """A certified exp-Laurent identity. + + ``lhs``/``rhs`` are the claimed sides, kept UNEXPANDED (the emitted statement + must read like the mathematics, not like sympy's canonical form); ``cofactor`` + is the exact quotient with ``lhs - rhs = cofactor * (y*z - 1)``; ``var`` is the + Lean binder name for the real displacement. + """ + + lhs: sp.Expr + rhs: sp.Expr + cofactor: sp.Expr + var: str = "d" + + +def _assert_exp_laurent(expr: sp.Expr, name: str) -> None: + """Refuse anything that is not a polynomial in the two generators.""" + extra = expr.free_symbols - {Y, Z} + if extra: + raise ValueError( + f"exp_laurent_identity instance '{name}' REFUSED: side {expr} carries " + f"symbols {sorted(map(str, extra))} outside the exp generators " + f"(expPos = e^d, expNeg = e^(-d))") + try: + sp.Poly(sp.expand(expr), Y, Z) + except sp.PolynomialError as exc: + raise ValueError( + f"exp_laurent_identity instance '{name}' REFUSED: side {expr} is not a " + f"polynomial in the exp generators ({exc})") from exc + + +def exp_laurent_certificate(lhs, rhs, *, var: str = "d", + name: str = "") -> ExpLaurentCert: + """Certify ``lhs = rhs`` modulo ``e^d * e^(-d) = 1`` and return the cofactor. + + EXACT: the quotient/remainder are computed in ``Q[y, z]`` and the cofactor is + re-multiplied and compared against ``lhs - rhs`` before it is returned. + """ + lhs, rhs = sp.sympify(lhs), sp.sympify(rhs) + _assert_exp_laurent(lhs, name) + _assert_exp_laurent(rhs, name) + + diff = sp.expand(lhs - rhs) + if diff == 0: + raise ValueError( + f"exp_laurent_identity instance '{name}' REFUSED: the cofactor is 0, " + f"so the relation e^{var} * e^(-{var}) = 1 is NOT load-bearing -- this " + "is a plain ring identity and belongs to IdentityEmitter") + quotients, remainder = sp.reduced(diff, [RELATION], Y, Z) + cofactor = sp.expand(quotients[0]) + remainder = sp.expand(remainder) + + if remainder != 0: + raise ValueError( + f"exp_laurent_identity instance '{name}' REFUSED: lhs - rhs does not " + f"reduce to 0 modulo e^{var} * e^(-{var}) = 1 (remainder " + f"{remainder}) -- not an identity") + if cofactor == 0: + raise ValueError( + f"exp_laurent_identity instance '{name}' REFUSED: the cofactor is 0, " + f"so the relation e^{var} * e^(-{var}) = 1 is NOT load-bearing -- this " + "is a plain ring identity and belongs to IdentityEmitter") + # exact re-validation of the returned certificate + if sp.expand(cofactor * RELATION - diff) != 0: # pragma: no cover + raise ValueError( + f"exp_laurent_identity instance '{name}' REFUSED: cofactor " + f"re-multiplication failed the exact re-check") + return ExpLaurentCert(lhs=lhs, rhs=rhs, cofactor=cofactor, var=var) + + +def certify_exp_laurent_identity_point(family, pt, name): + """``spec(pt) -> (lhs, rhs)`` or ``(lhs, rhs, var)``. + + n_checks = 3: the two-sided generator audit, the exact reduction to remainder + 0, and the cofactor re-multiplication. + """ + spec = family.special[1](pt) + if len(spec) == 3: + lhs, rhs, var = spec + else: + lhs, rhs = spec + var = family.constants.get("var", "d") + cert = exp_laurent_certificate(lhs, rhs, var=var, name=name) + inst = CertifiedInstance(point=dict(pt), lean_name=name, corners=(), + payload=cert) + return inst, 3 + + +# --------------------------------------------------------------------------- +# Lean rendering: structure-preserving (the STATEMENT must read as written). +# --------------------------------------------------------------------------- + +def _order_key(term: sp.Expr): + """Deterministic, READABLE ordering: the e^d channel before the e^(-d) channel + before the constants. + + sympy discards the order the author wrote (`Mul`/`Add` args are canonicalized), + and Lean multiplication is not definitionally commutative, so the emitted + statement must be reassembled in a FIXED order -- the one the corpus writes + these rows in: ``(e^d - 1) * (1 - e^(-d))``, ``e^d + e^(-d) - 2``. + """ + free = term.free_symbols + channel = 0 if Y in free else (1 if Z in free else 2) + return (channel, sp.default_sort_key(term)) + + +def _render(expr: sp.Expr, var: str) -> str: + """Render a polynomial in the exp generators as Lean, preserving structure. + + Canonicalization is the PROOF's job (`linear_combination`/`ring`); the emitted + statement keeps the shape the mathematics was written in -- so + ``(expPos - 1) * (1 - expNeg)`` emits as ``(Real.exp d - 1) * (1 - Real.exp (-d))`` + and NOT as an expanded sum. + """ + if expr is Y or expr == Y: + return f"Real.exp {var}" + if expr is Z or expr == Z: + return f"Real.exp (-{var})" + if isinstance(expr, sp.Integer): + return str(expr) if expr >= 0 else f"(-{-expr})" + if isinstance(expr, sp.Rational): + return f"({expr.p} / {expr.q})" if expr >= 0 else f"(-({-expr.p} / {expr.q}))" + if isinstance(expr, sp.Add): + terms = sorted(expr.args, key=_order_key) + pos = [t for t in terms if not t.could_extract_minus_sign()] + neg = [t for t in terms if t.could_extract_minus_sign()] + if not pos: # all-negative sum: lead with the first negated term + head, rest = f"-{_render(-neg[0], var)}", neg[1:] + else: + head, rest = _render(pos[0], var), neg + for t in pos[1:]: + head = f"{head} + {_render(t, var)}" + for t in rest: + head = f"{head} - {_render(-t, var)}" + return f"({head})" + if isinstance(expr, sp.Mul): + factors = sorted(expr.args, key=_order_key) + return "(" + " * ".join(_render(a, var) for a in factors) + ")" + if isinstance(expr, sp.Pow): + base, exponent = expr.args + if not (isinstance(exponent, sp.Integer) and exponent > 0): + raise ValueError(f"unsupported exponent {exponent} in {expr}") + return f"{_render(base, var)} ^ {int(exponent)}" + raise ValueError(f"unsupported node {type(expr).__name__} in {expr}") + + +def _strip_outer(text: str) -> str: + """Drop one redundant outer parenthesis pair (readability only).""" + if not (text.startswith("(") and text.endswith(")")): + return text + depth = 0 + for i, ch in enumerate(text): + if ch == "(": + depth += 1 + elif ch == ")": + depth -= 1 + if depth == 0 and i != len(text) - 1: + return text + return text[1:-1] + + +@dataclass +class ExpLaurentIdentityEmitter(Emitter): + """Emit ``forall d : R, lhs = rhs`` via the one relation ``e^d * e^(-d) = 1`` + and the certified cofactor, discharged by ``linear_combination``.""" + + def __post_init__(self): + self.kind = "exp_laurent_identity" + + def emit_body(self, fam, profile: LeanProfile) -> tuple[str, int]: + lines: list[str] = [] + n_thm = 0 + for inst in fam.instances: + cert: ExpLaurentCert = inst.payload # type: ignore[assignment] + var = cert.var + lhs_s = _strip_outer(_render(cert.lhs, var)) + rhs_s = _strip_outer(_render(cert.rhs, var)) + cof_s = _strip_outer(_render(sp.sympify(cert.cofactor), var)) + lines.append( + f"-- {inst.lean_name}: exp-Laurent identity in e^{var}, e^(-{var}), " + f"certified as an exact\n" + f"-- reduction modulo the single relation e^{var} * e^(-{var}) = 1 " + f"with cofactor {cert.cofactor}.\n" + f"-- Unconditional; no enclosure, no analytic hypothesis. " + f"conjecture1_proved = False.\n" + f"theorem {inst.lean_name} ({var} : ℝ) :\n" + f" {lhs_s} = {rhs_s} := by\n" + f" have hrel : Real.exp {var} * Real.exp (-{var}) = 1 := by\n" + f" rw [← Real.exp_add]; norm_num\n" + f" linear_combination ({cof_s} : ℝ) * hrel\n") + n_thm += 1 + return "\n".join(lines), n_thm + + +def exp_laurent_identity_family( + name: str, + grid: GridSpec, + lean_name: Callable, + spec: Callable, + constants: dict | None = None, + symbols: Sequence[sp.Symbol] = (Y, Z), +) -> InequalityFamily: + """Kind ``exp_laurent_identity``; ``spec: pt -> (lhs, rhs[, var])`` in the + generators ``Y = expPos`` (= ``e^d``) and ``Z = expNeg`` (= ``e^(-d)``).""" + return InequalityFamily( + name=name, + symbols=tuple(symbols), + grid=grid, + lean_name=lean_name, + special=("exp_laurent_identity", spec), + constants=dict(constants or {}), + ) diff --git a/telperion/src/telperion/emit_selfinversive_rigidity.py b/telperion/src/telperion/emit_selfinversive_rigidity.py index 80cd4da6a..e05cda415 100644 --- a/telperion/src/telperion/emit_selfinversive_rigidity.py +++ b/telperion/src/telperion/emit_selfinversive_rigidity.py @@ -19,6 +19,18 @@ NEGATIVE CONTROL: `|c₁|² ≠ |c₂|²` is REFUSED to certify real-rootedness — equal modulus is exactly the forcing condition, and unequal modulus puts every zero off the real line (on the single line `Im x = −(1/w)·log|c₁/c₂| ≠ 0`). Also refused: a zero coefficient, or `λ₁ = λ₂`. + +OFFLINE MODE (``spec["mode"] == "offline"``, 2026-09-18, MIRRORMERE torus-section ladder T2): +the REFUTATION-shaped mirror. Real coefficients of the form `r·√q` (r, q rational, q > 0, so +`|c|² = r²·q` is EXACT rational arithmetic) and frequencies that are rational or `r·log q` +(q integer ≥ 2). When `|c₁|² ≠ |c₂|²` EXACTLY the emitter proves +`¬ (∀ x, twoFreq c₁ c₂ λ₁ λ₂ x = 0 → x.im = 0)` — the `.mp` direction of the iff would force +`‖c₁‖ = ‖c₂‖`, and the kernel checks `‖c₁‖² = r₁²q₁ ≠ r₂²q₂ = ‖c₂‖²` by `norm_num`. The p-th +Euler-factor section `1 − p^{−s}` on `s = 1/2 + ix` is `twoFreq(1, −(1/√p); 0, −log p)`, whose zeros +sit uniformly at `Im x = 1/2`; for that exact shape the emitter ALSO ships the explicit witness +`x = i/2`. NEGATIVE CONTROL of the offline mode: EQUAL modulus is REFUSED (mirror of the default +mode's refusal), as is any frequency pair whose distinctness the kernel cannot certify without +transcendence (`λ₁ ∈ ℚ∖{0}` against `r·log q` needs Lindemann — refused, not faked). conjecture1_proved = False — an unconditional finite rigidity fact, NOT a proof of RH. """ from __future__ import annotations @@ -93,11 +105,265 @@ def selfinversive_rigidity_certificate(c1, c2, lam1, lam2) -> SelfInversiveRigid re1=re1, im1=im1, re2=re2, im2=im2, lam1=l1, lam2=l2, normsq=sp.nsimplify(ns1)) + +# -------------------------------------------------------------------------------------------- +# OFFLINE MODE — refutation-shaped negative control (unequal modulus ⟹ NOT real-rooted). +# -------------------------------------------------------------------------------------------- + +@dataclass(frozen=True) +class RadicalCoeff: + """A real coefficient `r·√q` with r, q rational, r ≠ 0, q > 0. `normsq = r²·q` exactly.""" + + r: sp.Rational + q: sp.Rational + + @property + def normsq(self) -> sp.Rational: + return sp.nsimplify(self.r ** 2 * self.q) + + +@dataclass(frozen=True) +class LogFreq: + """A real frequency: rational `rat` (when ``logq`` is None) or `rat·log(logq)` with + ``logq`` an integer ≥ 2 (so `log logq > 0` is a `norm_num`-discharged fact).""" + + rat: sp.Rational + logq: sp.Integer | None = None + + @property + def is_rational(self) -> bool: + return self.logq is None + + +@dataclass(frozen=True) +class SelfInversiveOfflineCertificate: + """A verified UNEQUAL-modulus refutation certificate: radical real coefficients with + `|c₁|² ≠ |c₂|²` EXACTLY, frequencies certifiably distinct, both coefficients nonzero. + ``euler_p`` is set when the instance is exactly the p-th Euler-factor section + `twoFreq(1, −(1/√p); 0, −log p)`, for which the explicit witness `x = i/2` is emitted.""" + + c1: RadicalCoeff + c2: RadicalCoeff + lam1: LogFreq + lam2: LogFreq + normsq1: sp.Rational + normsq2: sp.Rational + euler_p: int | None + + +def _radical_coeff(nm, spec) -> RadicalCoeff: + if isinstance(spec, dict): + r, q = spec.get("rat", 0), spec.get("sqrt", 1) + else: # a bare rational + r, q = spec, 1 + r, q = sp.nsimplify(r), sp.nsimplify(q) + if not (r.is_rational and q.is_rational): + raise ValueError(f"selfinversive_rigidity[offline]: {nm} must be r·√q with r, q rational") + if r == 0: + raise ValueError(f"selfinversive_rigidity[offline]: {nm} must be nonzero (|c|² > 0)") + if q <= 0: + raise ValueError(f"selfinversive_rigidity[offline]: {nm} radicand must be > 0; got {q}") + return RadicalCoeff(r=r, q=q) + + +def _log_freq(nm, spec) -> LogFreq: + if isinstance(spec, dict): + rat, logq = spec.get("rat", 1), spec.get("log") + else: + rat, logq = spec, None + rat = sp.nsimplify(rat) + if not rat.is_rational: + raise ValueError(f"selfinversive_rigidity[offline]: {nm} coefficient must be rational") + if logq is None: + return LogFreq(rat=rat) + logq = sp.nsimplify(logq) + if not (logq.is_integer and logq >= 2): + raise ValueError(f"selfinversive_rigidity[offline]: {nm} log base must be an integer ≥ 2") + if rat == 0: + raise ValueError(f"selfinversive_rigidity[offline]: {nm} = 0·log q is degenerate; write 0") + return LogFreq(rat=rat, logq=sp.Integer(logq)) + + +def _freqs_certifiably_distinct(l1: LogFreq, l2: LogFreq) -> bool: + """The kernel-certifiable distinctness cases (each discharged by `intro h; linarith` given + `0 < log q`): both rational and different; `0` against `r·log q`; `r₁·log q` against + `r₂·log q` with the SAME base. Everything else (a nonzero rational against a log, or two + logs with different bases) would need transcendence/independence of logarithms — REFUSED.""" + if l1.is_rational and l2.is_rational: + return l1.rat != l2.rat + if l1.is_rational or l2.is_rational: + rat = l1 if l1.is_rational else l2 + return rat.rat == 0 + return l1.logq == l2.logq and l1.rat != l2.rat + + +def selfinversive_offline_certificate(c1, c2, lam1, lam2) -> SelfInversiveOfflineCertificate: + """Build and EXACTLY self-check an OFFLINE (refutation) certificate. + + ``c1``, ``c2``: rational, or ``{"rat": r, "sqrt": q}`` meaning `r·√q`. + ``lam1``, ``lam2``: rational, or ``{"rat": r, "log": q}`` meaning `r·log q` (q integer ≥ 2). + + REFUSES (``ValueError``): + * a zero coefficient, a non-positive radicand, a non-rational input; + * frequencies whose distinctness is not kernel-certifiable (see + ``_freqs_certifiably_distinct``) — including `λ₁ = λ₂`; + * `|c₁|² = |c₂|²` (THE negative control of this mode: equal modulus forces + real-rootedness, so there is no off-line zero to certify). + """ + a, b = _radical_coeff("c1", c1), _radical_coeff("c2", c2) + l1, l2 = _log_freq("lam1", lam1), _log_freq("lam2", lam2) + if not _freqs_certifiably_distinct(l1, l2): + raise ValueError( + f"selfinversive_rigidity[offline]: frequencies λ₁={lam1!r}, λ₂={lam2!r} are not " + f"kernel-certifiably distinct (equal, or would need transcendence of log); refused") + ns1, ns2 = a.normsq, b.normsq + if ns1 == ns2: + raise ValueError( + f"selfinversive_rigidity[offline]: |c₁|²=|c₂|²={ns1} — EQUAL modulus forces " + f"real-rootedness (twoFreq_realRooted_iff .mpr), there is no off-line zero; refused") + euler_p = None + if (a.r == 1 and a.q == 1 and l1.is_rational and l1.rat == 0 + and not l2.is_rational and l2.rat == -1 + and b.q == l2.logq and b.r == -1 / b.q): + euler_p = int(l2.logq) + return SelfInversiveOfflineCertificate( + c1=a, c2=b, lam1=l1, lam2=l2, normsq1=ns1, normsq2=ns2, euler_p=euler_p) + + +def _freq_lean(f: LogFreq) -> str: + if f.is_rational: + return f"({rat_lean(f.rat)})" + if f.rat == 1: + return f"(Real.log {f.logq})" + if f.rat == -1: + return f"(-(Real.log {f.logq}))" + return f"({rat_lean(f.rat)} * Real.log {f.logq})" + + +def _emit_offline_instance(base: str, cert: SelfInversiveOfflineCertificate) -> str: + r1, q1 = rat_lean(cert.c1.r), rat_lean(cert.c1.q) + r2, q2 = rat_lean(cert.c2.r), rat_lean(cert.c2.q) + l1, l2 = _freq_lean(cert.lam1), _freq_lean(cert.lam2) + log_facts = "" + for f in (cert.lam1, cert.lam2): + if not f.is_rational: + log_facts += (f" have hlog{f.logq} := Real.log_pos " + f"(by norm_num : (1 : ℝ) < {f.logq})\n") + break # same base by construction when both are logs + # The nonvanishing + iff-application prelude, shared by the refutation and the witness. + prelude = ( + f" have hq1 : (0 : ℝ) < {q1} := by norm_num\n" + f" have hq2 : (0 : ℝ) < {q2} := by norm_num\n" + f" have hc1 : {base}_c1 ≠ 0 := Complex.ofReal_ne_zero.mpr\n" + f" (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq1))\n" + f" have hc2 : {base}_c2 ≠ 0 := Complex.ofReal_ne_zero.mpr\n" + f" (mul_ne_zero (by norm_num) (Real.sqrt_ne_zero'.mpr hq2))\n" + ) + text = ( + f"/-- Concrete two-frequency sum `F(x) = c₁·e^{{iλ₁x}} + c₂·e^{{iλ₂x}}` with REAL radical\n" + f" coefficients `c₁ = {r1}·√{q1}`, `c₂ = {r2}·√{q2}` (so `|c₁|² = {cert.normsq1}`,\n" + f" `|c₂|² = {cert.normsq2}`, EXACT) and frequencies `λ₁ = {l1}`, `λ₂ = {l2}`. -/\n" + f"noncomputable def {base}_c1 : ℂ := (({r1} * Real.sqrt {q1} : ℝ) : ℂ)\n" + f"noncomputable def {base}_c2 : ℂ := (({r2} * Real.sqrt {q2} : ℝ) : ℂ)\n\n" + f"/-- **Off-line refutation** ({base}): since `|c₁|² = {cert.normsq1} ≠ {cert.normsq2} = |c₂|²`\n" + f" EXACTLY, `‖c₁‖ ≠ ‖c₂‖`, so by the `.mp` direction of `Quasicrystal.twoFreq_realRooted_iff`\n" + f" the two-frequency sum is NOT real-rooted — some zero has nonzero imaginary part (in\n" + f" fact every zero sits on the single line `Im x = −(1/w)·log|c₁/c₂| ≠ 0`). Reverse-Dyson\n" + f" R3(n=2) negative control: unequal modulus is exactly the off-line signature.\n" + f" conjecture1_proved = False. -/\n" + f"theorem {base} :\n" + f" ¬ (∀ x : ℂ, Quasicrystal.twoFreq {base}_c1 {base}_c2 {l1} {l2} x = 0 → x.im = 0) := by\n" + f" intro hall\n" + f"{prelude}" + f" have hlam : ({l1} : ℝ) ≠ {l2} := by\n" + f"{log_facts}" + f" intro h\n" + f" linarith\n" + f" have hn := (Quasicrystal.twoFreq_realRooted_iff {base}_c1 {base}_c2 {l1} {l2}\n" + f" hc1 hc2 hlam).mp hall\n" + f" -- the kernel checks the EXACT normSq inequality {cert.normsq1} ≠ {cert.normsq2}\n" + f" have hsq : ‖{base}_c1‖ ^ 2 ≠ ‖{base}_c2‖ ^ 2 := by\n" + f" unfold {base}_c1 {base}_c2\n" + f" rw [Complex.norm_real, Complex.norm_real, Real.norm_eq_abs, Real.norm_eq_abs,\n" + f" sq_abs, sq_abs, mul_pow, mul_pow, Real.sq_sqrt hq1.le, Real.sq_sqrt hq2.le]\n" + f" norm_num\n" + f" exact hsq (by rw [hn])\n\n" + ) + if cert.euler_p is not None: + p = cert.euler_p + text += ( + f"/-- **Explicit off-line witness** ({base}_witness): `x = i/2` is a zero of the p = {p}\n" + f" Euler-factor section `1 − (1/√{p})·e^{{−i (log {p}) x}}`, since\n" + f" `e^{{−i (log {p}) (i/2)}} = e^{{(log {p})/2}} = √{p}`. `Im (i/2) = 1/2`: the uniform\n" + f" off-line displacement (the zeros are `s = 2πik/log {p}`, i.e. `Re s = 0`).\n" + f" conjecture1_proved = False. -/\n" + f"theorem {base}_witness :\n" + f" Quasicrystal.twoFreq {base}_c1 {base}_c2 {l1} {l2} (Complex.I / 2) = 0 := by\n" + f"{prelude}" + f" rw [Quasicrystal.twoFreq_eq_zero_iff _ _ _ _ _ hc1 hc2]\n" + f" have harg : (((-(Real.log {p})) - 0 : ℝ) : ℂ) * (Complex.I / 2) * Complex.I\n" + f" = ((Real.log {p} / 2 : ℝ) : ℂ) := by\n" + f" push_cast\n" + f" ring_nf\n" + f" rw [Complex.I_sq]\n" + f" ring\n" + f" rw [harg, ← Complex.ofReal_exp, Real.exp_half, Real.exp_log hq2]\n" + f" unfold {base}_c1 {base}_c2\n" + f" rw [← Complex.ofReal_neg, ← Complex.ofReal_div, Complex.ofReal_inj, Real.sqrt_one]\n" + f" have hs : Real.sqrt {p} ≠ 0 := Real.sqrt_ne_zero'.mpr hq2\n" + f" have hsq : Real.sqrt {p} * Real.sqrt {p} = {p} := Real.mul_self_sqrt hq2.le\n" + f" field_simp\n" + f" linarith [hsq]\n\n" + f"/-- The witness is off the real line: `Im (i/2) = 1/2 ≠ 0`, so `{base}` also follows\n" + f" directly from `{base}_witness` (second, independent route). -/\n" + f"theorem {base}_of_witness :\n" + f" ¬ (∀ x : ℂ, Quasicrystal.twoFreq {base}_c1 {base}_c2 {l1} {l2} x = 0 → x.im = 0) := by\n" + f" intro hall\n" + f" have h := hall (Complex.I / 2) {base}_witness\n" + f" simp [Complex.div_ofNat_im] at h\n\n" + # The SAME refutation restated in the registry's own spelling of the coefficients + # (1 and -(1/sqrt p)), so the emitted Lean carries the node statement verbatim. + f"/-- The p = {p} Euler-factor coefficients in the registry's spelling:\n" + f" `{r1}·√{q1} = 1` and `{r2}·√{p} = -(1/√{p})` (since `√{p}·√{p} = {p}`). -/\n" + f"theorem {base}_c1_eq : {base}_c1 = 1 := by\n" + f" unfold {base}_c1\n" + f" rw [Real.sqrt_one]\n" + f" norm_num\n\n" + f"theorem {base}_c2_eq : {base}_c2 = ((-(1 / Real.sqrt {p}) : ℝ) : ℂ) := by\n" + f" unfold {base}_c2\n" + f" have hq : (0 : ℝ) < {p} := by norm_num\n" + f" have hs : Real.sqrt {p} ≠ 0 := Real.sqrt_ne_zero'.mpr hq\n" + f" have hsq : Real.sqrt {p} * Real.sqrt {p} = {p} := Real.mul_self_sqrt hq.le\n" + f" rw [Complex.ofReal_inj]\n" + f" field_simp\n" + f" linarith [hsq]\n\n" + f"/-- **The registry-verbatim form** ({base}_node): the p = {p} Euler-factor section\n" + f" `twoFreq 1 (-(1/√{p})) 0 (-log {p})` is NOT real-rooted. Identical content to\n" + f" `{base}`, restated with the coefficients in the mission-registry spelling.\n" + f" conjecture1_proved = False. -/\n" + f"theorem {base}_node :\n" + f" ¬ (∀ x : ℂ,\n" + f" Quasicrystal.twoFreq 1 ((-(1 / Real.sqrt {p}) : ℝ) : ℂ) 0 (-(Real.log {p})) x = 0\n" + f" → x.im = 0) := by\n" + f" rw [← {base}_c1_eq, ← {base}_c2_eq]\n" + f" exact {base}\n\n" + ) + return text + + def certify_selfinversive_rigidity_point(family, pt, name): """Certify one instance from ``family.special[1](pt)`` — a dict with keys ``c1``, ``c2`` - ((re,im) pairs) and ``lam1``, ``lam2`` (rational frequencies).""" + ((re,im) pairs) and ``lam1``, ``lam2`` (rational frequencies); with ``mode="offline"`` the + coefficients are radicals ``{"rat": r, "sqrt": q}`` and frequencies may be ``{"rat": r, + "log": q}`` (see ``selfinversive_offline_certificate``).""" spec = family.special[1](pt) - cert = selfinversive_rigidity_certificate(spec["c1"], spec["c2"], spec["lam1"], spec["lam2"]) + mode = spec.get("mode", "rigidity") + if mode == "offline": + cert = selfinversive_offline_certificate(spec["c1"], spec["c2"], spec["lam1"], spec["lam2"]) + elif mode == "rigidity": + cert = selfinversive_rigidity_certificate(spec["c1"], spec["c2"], spec["lam1"], spec["lam2"]) + else: + raise ValueError(f"selfinversive_rigidity: unknown mode {mode!r} (rigidity | offline)") inst = CertifiedInstance(point=dict(pt), lean_name=name, corners=(), payload=cert) return inst, 1 @@ -106,7 +372,13 @@ def certify_selfinversive_rigidity_point(family, pt, name): class SelfInversiveRigidityEmitter(Emitter): """Emit equal-modulus real-rootedness — `‖c₁‖ = ‖c₂‖` (from the exact rational normSq equality) fed into `Quasicrystal.twoFreq_realRooted_iff`. One theorem per instance. The emitted file - imports the in-island `TwoFreqRigidity`, so it must be built inside the quasicrystal island.""" + imports the in-island `TwoFreqRigidity`, so it must be built inside the quasicrystal island. + + OFFLINE-mode instances (payload ``SelfInversiveOfflineCertificate``) emit the refutation + `¬ real-rooted` from the exact normSq INEQUALITY via the `.mp` direction, plus — for the exact + Euler-factor shape `twoFreq(1, −(1/√p); 0, −log p)` — the explicit witness `x = i/2`, the + witness-route refutation, and the MISSION-REGISTRY-VERBATIM restatement `…_node` whose + coefficients are spelled `1` and `−(1/√p)` (six theorems).""" def __post_init__(self): self.kind = "selfinversive_rigidity" @@ -115,6 +387,10 @@ def emit_body(self, fam, profile: LeanProfile) -> tuple[str, int]: lines: list[str] = [] nthm = 0 for inst in fam.instances: + if isinstance(inst.payload, SelfInversiveOfflineCertificate): + lines.append(_emit_offline_instance(inst.lean_name, inst.payload)) + nthm += 1 + (5 if inst.payload.euler_p is not None else 0) + continue cert: SelfInversiveRigidityCertificate = inst.payload # type: ignore[assignment] base = inst.lean_name re1, im1 = rat_lean(cert.re1), rat_lean(cert.im1) @@ -158,7 +434,9 @@ def selfinversive_rigidity_family( ) -> InequalityFamily: """Build a selfinversive_rigidity family (kind='selfinversive_rigidity'). ``spec``: ``pt -> dict`` with keys ``c1``, ``c2`` ((re,im) rational pairs), ``lam1``, ``lam2``. Refuses unequal modulus - (the negative control), a zero coefficient, or equal frequencies.""" + (the negative control), a zero coefficient, or equal frequencies. A spec with + ``"mode": "offline"`` instead certifies the REFUTATION (unequal modulus ⟹ NOT real-rooted) + and refuses EQUAL modulus.""" return InequalityFamily( name=name, symbols=(), grid=grid, lean_name=lean_name, special=("selfinversive_rigidity", spec), constants=dict(constants or {}), @@ -186,3 +464,25 @@ class _V: body, nthm = SelfInversiveRigidityEmitter().emit_body(_V(), LeanProfile(namespace=("X",))) print(f"\n-- {nthm} theorems --\n{body}") + + print("\n=== OFFLINE mode: p=2 Euler-factor section (must certify, ships witness) ===") + euler2 = {"mode": "offline", "c1": "1", "c2": {"rat": "-1/2", "sqrt": 2}, + "lam1": "0", "lam2": {"rat": "-1", "log": 2}} + oc = selfinversive_offline_certificate(euler2["c1"], euler2["c2"], euler2["lam1"], euler2["lam2"]) + print(f"cert OK: |c₁|²={oc.normsq1} ≠ |c₂|²={oc.normsq2}, euler_p={oc.euler_p}") + print("\n=== OFFLINE NEGATIVE CONTROL: equal modulus (must raise) ===") + try: + selfinversive_offline_certificate({"rat": "1/2", "sqrt": 2}, {"rat": "-1/2", "sqrt": 2}, + "0", {"rat": "-1", "log": 2}) + raise SystemExit("FAIL: equal modulus not refused in offline mode") + except ValueError as e: + print(f"refused as expected: {e}") + fam2 = selfinversive_rigidity_family( + "T2", GridSpec([("case", [0])]), lambda pt: "euler_factor_p2", spec=lambda pt: euler2) + inst2, _ = certify_selfinversive_rigidity_point(fam2, {"case": 0}, "euler_factor_p2") + + class _V2: + instances = [inst2] + + body2, nthm2 = SelfInversiveRigidityEmitter().emit_body(_V2(), LeanProfile(namespace=("X",))) + print(f"\n-- {nthm2} theorems --\n{body2}") diff --git a/telperion/src/telperion/emit_twofreq_offline.py b/telperion/src/telperion/emit_twofreq_offline.py new file mode 100644 index 000000000..2ed3a86c5 --- /dev/null +++ b/telperion/src/telperion/emit_twofreq_offline.py @@ -0,0 +1,528 @@ +"""twofreq_offline emitter -- certified OFF-line displacement of a two-frequency section. + +MIRRORMERE torus-section ladder, rung T2 (QC_TORUS_SECTION_LADDER memo sections 4b/5). +The EXACT COMPLEMENT of `emit_selfinversive_rigidity`. For a two-frequency exponential sum + + F(x) = c1 * e^{i lam1 x} + c2 * e^{i lam2 x}, c1,c2 in C*, lam1 != lam2 in R, + +the island lemma `Quasicrystal.twoFreq_realRooted_iff` (TwoFreqRigidity.lean:92) says + + (every zero of F is real) <-> ||c1|| = ||c2||. + +`selfinversive_rigidity` emits the POSITIVE direction from |c1|^2 = |c2|^2 EXACTLY. +This emitter certifies the NEGATIVE direction: when |c1|^2 != |c2|^2 EXACTLY, F is NOT +real-rooted -- some zero sits strictly off the real line. Together the two emitters +PARTITION the coefficient space: each REFUSES precisely the regime the other certifies, +so neither can emit a false theorem. + +THE FAMILY. The motivating instance is the Euler factor at a prime p, read on the +critical line s = 1/2 + i x: + + 1 - p^{-s} = 1 - p^{-1/2} e^{-i (log p) x} = twoFreq 1 (-(1/sqrt p)) 0 (-(log p)) (x), + +whose moduli are 1 and 1/sqrt p -- never equal. So NO single Euler-factor section is +real-rooted, at any prime, at any rung of the ladder. In `mode='displacement'` the +emitter additionally certifies WHERE the zeros go: uniformly at `Im x = 1/2`, i.e. on +`Re s = 0`, the memo's "uniform off-line displacement 1/2, at every rung, for every p". +This is the ladder's certified NEGATIVE CONTROL: it shows no per-rung line-membership +claim can survive finite truncation, so critical-line membership is an infinite-N +continuation phenomenon and never a finite-section fact. + +COEFFICIENT LITERALS. `selfinversive_rigidity` takes Gaussian rationals only; the Euler +factor needs the IRRATIONAL coefficient -1/sqrt p, so this emitter carries three literal +shapes with EXACT rational moduli: + + gauss(re, im) -> `re + im * Complex.I` |c|^2 = re^2 + im^2 + inv_sqrt(s, sign) -> `((+-(1 / Real.sqrt s) : R) : C)` |c|^2 = 1/s + real_sqrt(q, s) -> `((q * Real.sqrt s : R) : C)` |c|^2 = q^2 * s + +and two frequency shapes: `rat(r)` and `neglog(p)` (the literal `-(Real.log p)`). + +SELF-CHECK / REFUSALS (ValueError, all EXACT rational arithmetic -- no floats): + * |c1|^2 == |c2|^2 -- equal modulus: the sum IS real-rooted and the + emitted negation would be FALSE. THE anti- + phantom guard, and the exact complement of + selfinversive_rigidity's refusal. + * a zero coefficient (|c|^2 == 0); + * lam1 == lam2, including the disguised forms (neglog 1 IS rat 0, since log 1 = 0); + * a negative rational frequency opposite a -log p frequency (the emitted separation + argument is 0 <= r and -log p < 0; anything else is refused, not guessed); + * a radicand s that is not an integer >= 2 (the emitted sqrt arithmetic is exact only + there), or non-rational input; + * mode='displacement' outside the p-family shape, or p < 2 -- honest scope: the + certified displacement 1/2 is a fact about 1 - p^{-1/2} e^{-i log p x} ONLY. + +conjecture1_proved = False. A finite fact about ONE Euler factor (or one two-frequency +sum); it says nothing about zeta, about the full Euler product, or about RH. +""" +from __future__ import annotations + +from dataclasses import dataclass +from typing import Callable + +import sympy as sp + +try: # normal package import + from .certify import CertifiedInstance + from .expr import rat_lean + from .family import GridSpec, InequalityFamily + from .lean import LeanProfile + from .workflow import Emitter +except ImportError: # run directly + import os + import sys + + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + from telperion.certify import CertifiedInstance + from telperion.expr import rat_lean + from telperion.family import GridSpec, InequalityFamily + from telperion.lean import LeanProfile + from telperion.workflow import Emitter + + +# --------------------------------------------------------------------------- +# Literal constructors (CoefLit / LamLit are plain tuples so a negative-control +# adapter can hand-forge one, bypassing the Layer-1 self-check below). +# --------------------------------------------------------------------------- + +def gauss(re, im) -> tuple: + """Gaussian-rational coefficient `re + im*I`.""" + return ("gauss", sp.nsimplify(re), sp.nsimplify(im)) + + +def inv_sqrt(s, sign: int = -1) -> tuple: + """Coefficient `sign * (1 / sqrt s)` -- the Euler-factor shape (sign = -1).""" + return ("inv_sqrt", int(sign), sp.nsimplify(s)) + + +def real_sqrt(q, s) -> tuple: + """Coefficient `q * sqrt s` with rational `q`.""" + return ("real_sqrt", sp.nsimplify(q), sp.nsimplify(s)) + + +def rat(r) -> tuple: + """Rational frequency.""" + return ("rat", sp.nsimplify(r)) + + +def neglog(p) -> tuple: + """Frequency `-(Real.log p)` -- the Euler-factor shape.""" + return ("neglog", int(p)) + + +@dataclass(frozen=True) +class TwoFreqOfflineCert: + """A verified off-line displacement certificate: two coefficient literals whose EXACT + rational moduli DIFFER, and two distinct frequency literals.""" + + c1: tuple # CoefLit + c2: tuple # CoefLit + lam1: tuple # LamLit + lam2: tuple # LamLit + normsq1: sp.Rational # EXACT |c1|^2 + normsq2: sp.Rational # EXACT |c2|^2 + p: int | None = None # Euler-factor parameter, when the instance is one + displacement: sp.Rational | None = None # certified Im x, 1/2 for the p-family + mode: str = "offline" # 'offline' | 'displacement' + + +# --------------------------------------------------------------------------- +# Exact arithmetic on the literals +# --------------------------------------------------------------------------- + +def _coef_normsq(c: tuple, which: str) -> sp.Rational: + """EXACT |c|^2 of a coefficient literal. Raises on a malformed / out-of-scope one.""" + tag = c[0] + if tag == "gauss": + re, im = c[1], c[2] + for nm, v in (("re", re), ("im", im)): + if not sp.nsimplify(v).is_rational: + raise ValueError(f"twofreq_offline: {which}.{nm} must be rational; got {v!r}") + return sp.nsimplify(re) ** 2 + sp.nsimplify(im) ** 2 + if tag == "inv_sqrt": + sign, s = c[1], sp.nsimplify(c[2]) + if sign not in (1, -1): + raise ValueError(f"twofreq_offline: {which} sign must be +-1; got {sign!r}") + _check_radicand(s, which) + return sp.Rational(1, 1) / s + if tag == "real_sqrt": + q, s = sp.nsimplify(c[1]), sp.nsimplify(c[2]) + if not q.is_rational: + raise ValueError(f"twofreq_offline: {which} coefficient must be rational; got {q!r}") + _check_radicand(s, which) + return q ** 2 * s + raise ValueError(f"twofreq_offline: unknown coefficient literal {tag!r}") + + +def _check_radicand(s, which: str) -> None: + if not sp.nsimplify(s).is_rational: + raise ValueError(f"twofreq_offline: {which} radicand must be rational; got {s!r}") + if s <= 0: + raise ValueError(f"twofreq_offline: {which} radicand must be positive; got {s}") + if not (s.is_Integer and s >= 2): + raise ValueError( + f"twofreq_offline: {which} radicand must be an integer >= 2 (the emitted sqrt " + f"arithmetic is exact only there); got {s}") + + +def _lam_value(lam: tuple, which: str): + """The frequency as a sympy expression (`-log p` stays symbolic).""" + tag = lam[0] + if tag == "rat": + r = sp.nsimplify(lam[1]) + if not r.is_rational: + raise ValueError(f"twofreq_offline: {which} must be rational; got {r!r}") + return r + if tag == "neglog": + p = int(lam[1]) + if p < 1: + raise ValueError(f"twofreq_offline: {which} = -log p needs p >= 1; got {p}") + return -sp.log(sp.Integer(p)) + raise ValueError(f"twofreq_offline: unknown frequency literal {tag!r}") + + +# --------------------------------------------------------------------------- +# Layer 1: build + EXACTLY self-check a certificate +# --------------------------------------------------------------------------- + +def twofreq_offline_certificate(c1, c2, lam1, lam2, *, p=None, mode: str = "offline", + ) -> TwoFreqOfflineCert: + """Build and EXACTLY self-check an off-line displacement certificate. + + `c1`, `c2`: coefficient literals from :func:`gauss` / :func:`inv_sqrt` / + :func:`real_sqrt`. `lam1`, `lam2`: frequency literals from :func:`rat` / + :func:`neglog`. `mode='displacement'` additionally certifies `Im x = 1/2` and is + accepted ONLY for the Euler-factor shape `twoFreq 1 (-(1/sqrt p)) 0 (-(log p))`. + + Every refusal is listed in the module docstring. conjecture1_proved = False. + """ + ns1 = _coef_normsq(c1, "c1") + ns2 = _coef_normsq(c2, "c2") + if ns1 == 0 or ns2 == 0: + raise ValueError("twofreq_offline: coefficients must be nonzero (|c|^2 > 0)") + + v1, v2 = _lam_value(lam1, "lam1"), _lam_value(lam2, "lam2") + if sp.simplify(v1 - v2) == 0: + raise ValueError( + f"twofreq_offline: frequencies must differ; lam1 = lam2 = {v1} (note log 1 = 0, " + f"so neglog(1) IS rat(0))") + # The emitted separation for a rational-vs-(-log p) pair is `-log p < 0 <= r`. + for a, b in ((lam1, lam2), (lam2, lam1)): + if a[0] == "rat" and b[0] == "neglog" and sp.nsimplify(a[1]) < 0: + raise ValueError( + "twofreq_offline: a rational frequency opposite a -log p frequency must be " + f"nonnegative (the emitted separation is -log p < 0 <= r); got {a[1]}") + + # THE anti-phantom self-check (and the exact complement of selfinversive_rigidity). + if ns1 == ns2: + raise ValueError( + f"twofreq_offline: |c1|^2 = |c2|^2 = {ns1} -- equal modulus means the sum IS " + f"real-rooted (twoFreq_realRooted_iff), so the emitted negation would be FALSE; " + f"refused. Use the selfinversive_rigidity emitter for that regime.") + + if mode not in ("offline", "displacement"): + raise ValueError(f"twofreq_offline: unknown mode {mode!r}") + + is_p_family = ( + c1 == ("gauss", sp.Integer(1), sp.Integer(0)) + and c2[0] == "inv_sqrt" and c2[1] == -1 + and lam1 == ("rat", sp.Integer(0)) + and lam2[0] == "neglog" and int(lam2[1]) == int(c2[2]) + ) + p_val = int(c2[2]) if is_p_family else (int(p) if p is not None else None) + if p is not None and is_p_family and int(p) != int(c2[2]): + raise ValueError( + f"twofreq_offline: declared p = {p} disagrees with the Euler-factor literals " + f"(p = {int(c2[2])})") + if is_p_family and p_val < 2: + raise ValueError(f"twofreq_offline: the Euler-factor parameter needs p >= 2; got {p_val}") + if mode == "displacement": + if not is_p_family: + raise ValueError( + "twofreq_offline: mode='displacement' certifies Im x = 1/2 for the Euler-factor " + "shape twoFreq 1 (-(1/sqrt p)) 0 (-(log p)) ONLY; this instance is not that " + "shape, and the displacement of a general pair is -(log(|c1|/|c2|))/(lam2-lam1), " + "not 1/2. Refused rather than guessed.") + if p_val < 2: + raise ValueError(f"twofreq_offline: the Euler-factor parameter needs p >= 2; got {p_val}") + + return TwoFreqOfflineCert( + c1=tuple(c1), c2=tuple(c2), lam1=tuple(lam1), lam2=tuple(lam2), + normsq1=sp.nsimplify(ns1), normsq2=sp.nsimplify(ns2), + p=p_val if is_p_family else None, + displacement=sp.Rational(1, 2) if (is_p_family and mode == "displacement") else None, + mode=mode, + ) + + +def certify_twofreq_offline_point(family, pt, name): + """Certify one instance from ``family.special[1](pt)`` -- a dict with keys ``c1``, + ``c2``, ``lam1``, ``lam2`` and optional ``p`` / ``mode``.""" + spec = dict(family.special[1](pt)) + cert = twofreq_offline_certificate( + spec["c1"], spec["c2"], spec["lam1"], spec["lam2"], + p=spec.get("p"), mode=spec.get("mode", "offline"), + ) + inst = CertifiedInstance(point=dict(pt), lean_name=name, corners=(), payload=cert) + return inst, 1 + + +# --------------------------------------------------------------------------- +# Lean rendering +# --------------------------------------------------------------------------- + +def _coef_lean(c: tuple) -> str: + tag = c[0] + if tag == "gauss": + re, im = sp.nsimplify(c[1]), sp.nsimplify(c[2]) + if im == 0: + return rat_lean(re) + return f"({rat_lean(re)} + {rat_lean(im)} * Complex.I : ℂ)" + if tag == "inv_sqrt": + sign, s = int(c[1]), sp.nsimplify(c[2]) + inner = f"1 / Real.sqrt {rat_lean(s)}" + body = f"-({inner})" if sign < 0 else f"({inner})" + return f"(({body} : ℝ) : ℂ)" + if tag == "real_sqrt": + q, s = sp.nsimplify(c[1]), sp.nsimplify(c[2]) + return f"(({rat_lean(q)} * Real.sqrt {rat_lean(s)} : ℝ) : ℂ)" + raise ValueError(f"twofreq_offline: unknown coefficient literal {tag!r}") + + +def _lam_lean(lam: tuple) -> str: + if lam[0] == "rat": + return rat_lean(sp.nsimplify(lam[1])) + return f"(-(Real.log {int(lam[1])}))" + + +def _coef_ne_tac(c: tuple, ind: str) -> str: + """Tactic block proving the coefficient literal is nonzero.""" + tag = c[0] + if tag == "gauss": + return f"{ind}norm_num [Complex.ext_iff]" + if tag == "inv_sqrt": + s = rat_lean(sp.nsimplify(c[2])) + sign = int(c[1]) + pos = f"1 / Real.sqrt {s}" + return ( + f"{ind}have hs : (0 : ℝ) < Real.sqrt {s} := Real.sqrt_pos.mpr (by norm_num)\n" + f"{ind}intro hzero\n" + f"{ind}have hre := Complex.ofReal_eq_zero.mp hzero\n" + f"{ind}have hp : (0 : ℝ) < {pos} := by positivity\n" + f"{ind}linarith" if sign < 0 else + f"{ind}have hs : (0 : ℝ) < Real.sqrt {s} := Real.sqrt_pos.mpr (by norm_num)\n" + f"{ind}intro hzero\n" + f"{ind}have hre := Complex.ofReal_eq_zero.mp hzero\n" + f"{ind}have hp : (0 : ℝ) < {pos} := by positivity\n" + f"{ind}linarith") + if tag == "real_sqrt": + q, s = rat_lean(sp.nsimplify(c[1])), rat_lean(sp.nsimplify(c[2])) + return ( + f"{ind}have hs : (0 : ℝ) < Real.sqrt {s} := Real.sqrt_pos.mpr (by norm_num)\n" + f"{ind}intro hzero\n" + f"{ind}have hre := Complex.ofReal_eq_zero.mp hzero\n" + f"{ind}exact absurd hre (mul_ne_zero (by norm_num) hs.ne')") + raise ValueError(f"twofreq_offline: unknown coefficient literal {tag!r}") + + +def _lam_ne_tac(lam1: tuple, lam2: tuple, ind: str) -> str: + """Tactic block proving the two frequency literals differ.""" + t1, t2 = lam1[0], lam2[0] + if t1 == "rat" and t2 == "rat": + return f"{ind}norm_num" + if t1 == "neglog" and t2 == "neglog": + a, b = int(lam1[1]), int(lam2[1]) + lo, hi = (a, b) if a < b else (b, a) + return ( + f"{ind}intro hlog\n" + f"{ind}have hlt := Real.log_lt_log (show (0 : ℝ) < {lo} by norm_num) " + f"(show ({lo} : ℝ) < {hi} by norm_num)\n" + f"{ind}linarith") + # one rational (necessarily >= 0, enforced at certify time) against one -log p (< 0) + p = int(lam1[1]) if t1 == "neglog" else int(lam2[1]) + return ( + f"{ind}have hlp := Real.log_pos (show (1 : ℝ) < {p} by norm_num)\n" + f"{ind}intro hlog\n" + f"{ind}linarith") + + +def _normsq_tac(c: tuple, ns: sp.Rational, ind: str) -> str: + """Tactic block evaluating `Complex.normSq c` to its EXACT rational value.""" + tag = c[0] + if tag == "gauss": + return f"{ind}norm_num [Complex.normSq_apply]" + if tag == "inv_sqrt": + sign, s = int(c[1]), sp.nsimplify(c[2]) + neg = "neg_mul_neg, " if sign < 0 else "" + return ( + f"{ind}rw [Complex.normSq_ofReal, {neg}div_mul_div_comm, one_mul,\n" + f"{ind} Real.mul_self_sqrt (show (0 : ℝ) ≤ {rat_lean(s)} by norm_num)]") + if tag == "real_sqrt": + q, s = sp.nsimplify(c[1]), sp.nsimplify(c[2]) + return ( + f"{ind}rw [Complex.normSq_ofReal]\n" + f"{ind}have hss := Real.mul_self_sqrt (show (0 : ℝ) ≤ {rat_lean(s)} by norm_num)\n" + f"{ind}linear_combination ({rat_lean(q)} ^ 2 : ℝ) * hss") + raise ValueError(f"twofreq_offline: unknown coefficient literal {tag!r}") + + +_BRIDGE_HYP = ( + " (hiff : ∀ (c₁ c₂ : ℂ) (lam₁ lam₂ : ℝ), c₁ ≠ 0 → c₂ ≠ 0 → lam₁ ≠ lam₂ →\n" + " ((∀ x : ℂ, twoFreq c₁ c₂ lam₁ lam₂ x = 0 → x.im = 0) ↔ ‖c₁‖ = ‖c₂‖))\n" +) + +#: The island definition, copied VERBATIM from TwoFreqRigidity.lean:40-42 -- the prelude a +#: plain-Mathlib (negative-control) elaboration needs. +TWOFREQ_PRELUDE = """noncomputable section +namespace Quasicrystal + +-- ===== TwoFreqRigidity.lean:40-42 (v4.32 quasicrystal island), VERBATIM ===== +def twoFreq (c₁ c₂ : ℂ) (lam₁ lam₂ : ℝ) (x : ℂ) : ℂ := + c₁ * Complex.exp ((lam₁ : ℂ) * x * Complex.I) + + c₂ * Complex.exp ((lam₂ : ℂ) * x * Complex.I) + +end Quasicrystal +end + +open Quasicrystal +""" + + +@dataclass +class TwoFreqOfflineEmitter(Emitter): + """Emit the NOT-real-rooted direction of `Quasicrystal.twoFreq_realRooted_iff` from the + EXACT rational inequality `|c1|^2 != |c2|^2`, plus the existence corollary and (for the + Euler-factor family) the certified displacement `Im x = 1/2`. One instance per point. + + The emitted file imports the in-island `TwoFreqRigidity`, so it builds inside the + quasicrystal island. `bridge=True` on :meth:`emit_theorem` renders the same arithmetic + against plain Mathlib with the island iff as an explicit hypothesis -- the form the + negative-control harness elaborates.""" + + def __post_init__(self): + self.kind = "twofreq_offline" + + # ---- per-instance renderer (also the negative-control adapter's entry point) ---- + def emit_theorem(self, cert: TwoFreqOfflineCert, name: str, *, bridge: bool = False) -> str: + c1, c2 = _coef_lean(cert.c1), _coef_lean(cert.c2) + l1, l2 = _lam_lean(cert.lam1), _lam_lean(cert.lam2) + ns1, ns2 = rat_lean(cert.normsq1), rat_lean(cert.normsq2) + iff_call = "hiff _ _ _ _ hc1 hc2 hlam" if bridge else \ + "twoFreq_realRooted_iff _ _ _ _ hc1 hc2 hlam" + p_txt = f"p = {cert.p}" if cert.p is not None else "a two-frequency section" + + head = ( + f"/-- **Off-line displacement** ({name}): the two-frequency sum\n" + f" `F(x) = c₁·e^{{iλ₁x}} + c₂·e^{{iλ₂x}}` with `|c₁|² = {cert.normsq1}` and\n" + f" `|c₂|² = {cert.normsq2}` is NOT real-rooted -- some zero lies strictly off the\n" + f" real line. By `Quasicrystal.twoFreq_realRooted_iff` real-rootedness is\n" + f" EQUIVALENT to `‖c₁‖ = ‖c₂‖`, and the two moduli differ EXACTLY, so the\n" + f" universal statement is refuted. Ladder rung T2 ({p_txt}).\n" + f" A finite section fact; nothing about ζ or RH. conjecture1_proved = False. -/\n" + ) + # In bridge mode the island iff rides in as an explicit hypothesis, so the + # signature opens with the binder instead of a bare `:`. + sig = (f"theorem {name}\n{_BRIDGE_HYP} :\n " if bridge + else f"theorem {name} :\n ") + out = [head, sig] + out.append( + f"\u00ac (\u2200 x : \u2102, twoFreq {c1} {c2} {l1} {l2} x = 0 \u2192 x.im = 0) := by\n" + f" have hc1 : ({c1} : \u2102) \u2260 0 := by\n{_coef_ne_tac(cert.c1, ' ')}\n" + f" have hc2 : ({c2} : \u2102) \u2260 0 := by\n{_coef_ne_tac(cert.c2, ' ')}\n" + f" have hlam : ({l1} : \u211d) \u2260 ({l2}) := by\n{_lam_ne_tac(cert.lam1, cert.lam2, ' ')}\n" + f" rw [{iff_call}]\n" + f" intro h\n" + f" have h2 : Complex.normSq ({c1}) = Complex.normSq ({c2}) := by\n" + f" rw [Complex.normSq_eq_norm_sq, Complex.normSq_eq_norm_sq, h]\n" + f" have hns1 : Complex.normSq ({c1}) = ({ns1} : \u211d) := by\n" + f"{_normsq_tac(cert.c1, cert.normsq1, ' ')}\n" + f" have hns2 : Complex.normSq ({c2}) = ({ns2} : \u211d) := by\n" + f"{_normsq_tac(cert.c2, cert.normsq2, ' ')}\n" + f" rw [hns1, hns2] at h2\n" + f" norm_num at h2\n\n" + ) + if bridge: + return "".join(out) + + # Existence corollary: the negation, unpacked, so the off-line zero is visible. + out.append( + f"/-- Existence form of `{name}`: an explicit zero off the real line.\n" + f" conjecture1_proved = False. -/\n" + f"theorem {name}_offline_zero :\n" + f" ∃ x : ℂ, twoFreq {c1} {c2} {l1} {l2} x = 0 ∧ x.im ≠ 0 := by\n" + f" obtain ⟨x, hx⟩ := not_forall.mp {name}\n" + f" exact ⟨x, (Classical.not_imp.mp hx).1, (Classical.not_imp.mp hx).2⟩\n\n" + ) + if cert.mode == "displacement": + out.append(self._emit_displacement(cert, name)) + return "".join(out) + + def _emit_displacement(self, cert: TwoFreqOfflineCert, name: str) -> str: + """The p-family's certified location: EVERY zero sits at `Im x = 1/2`.""" + p = cert.p + c1, c2 = _coef_lean(cert.c1), _coef_lean(cert.c2) + l1, l2 = _lam_lean(cert.lam1), _lam_lean(cert.lam2) + return ( + f"/-- **Certified displacement** ({name}_displacement): for the Euler factor\n" + f" `1 - {p}^(-s)` read on `s = 1/2 + i x`, EVERY zero of the section sits at\n" + f" `Im x = 1/2` -- i.e. on `Re s = 0`, uniformly. The ladder's negative control:\n" + f" the off-line displacement is 1/2 at this rung, for this prime, with no\n" + f" dependence on the truncation. conjecture1_proved = False. -/\n" + f"theorem {name}_displacement :\n" + f" ∀ x : ℂ, twoFreq {c1} {c2} {l1} {l2} x = 0 → x.im = 1 / 2 := by\n" + f" intro x hz\n" + f" have hc1 : ({c1} : ℂ) ≠ 0 := by\n{_coef_ne_tac(cert.c1, ' ')}\n" + f" have hc2 : ({c2} : ℂ) ≠ 0 := by\n{_coef_ne_tac(cert.c2, ' ')}\n" + f" have hn := twoFreq_zero_norm _ _ _ _ x hc1 hc2 hz\n" + f" rw [norm_one, Complex.norm_real, Real.norm_eq_abs, abs_neg,\n" + f" abs_of_pos (show (0 : ℝ) < 1 / Real.sqrt {p} by positivity), one_div_one_div] at hn\n" + f" have hlog := congrArg Real.log hn\n" + f" rw [Real.log_exp, Real.log_sqrt (show (0 : ℝ) ≤ {p} by norm_num)] at hlog\n" + f" have hl : (0 : ℝ) < Real.log {p} := Real.log_pos (by norm_num)\n" + f" have hkey : Real.log {p} * x.im = Real.log {p} * (1 / 2) := by linarith\n" + f" exact mul_left_cancel₀ hl.ne' hkey\n\n" + ) + + def emit_body(self, fam, profile: LeanProfile) -> tuple[str, int]: + lines: list[str] = [] + nthm = 0 + for inst in fam.instances: + cert: TwoFreqOfflineCert = inst.payload # type: ignore[assignment] + lines.append(self.emit_theorem(cert, inst.lean_name)) + nthm += 2 + (1 if cert.mode == "displacement" else 0) + return "".join(lines), nthm + + +def twofreq_offline_family( + name: str, grid: GridSpec, lean_name: Callable, spec: Callable, constants: dict | None = None +) -> InequalityFamily: + """Build a twofreq_offline family (kind='twofreq_offline'). ``spec``: ``pt -> dict`` with + keys ``c1``, ``c2`` (coefficient literals), ``lam1``, ``lam2`` (frequency literals) and + optional ``p`` / ``mode``. Refuses equal modulus (the sum would be real-rooted), a zero + coefficient, equal frequencies, and 'displacement' outside the Euler-factor shape.""" + return InequalityFamily( + name=name, symbols=(), grid=grid, lean_name=lean_name, + special=("twofreq_offline", spec), constants=dict(constants or {}), + ) + + +def euler_factor_spec(p: int, mode: str = "displacement") -> dict: + """The Euler-factor section at the prime `p`: `1 - p^(-s)` on `s = 1/2 + i x`.""" + return {"c1": gauss(1, 0), "c2": inv_sqrt(p, sign=-1), + "lam1": rat(0), "lam2": neglog(p), "p": int(p), "mode": mode} + + +if __name__ == "__main__": + print("=== positive cert (Euler factor p = 2) ===") + c = twofreq_offline_certificate(**{k: v for k, v in euler_factor_spec(2).items() + if k != "p" and k != "mode"}, + p=2, mode="displacement") + print(f"cert OK: |c1|^2 = {c.normsq1} != |c2|^2 = {c.normsq2}; displacement {c.displacement}") + print("\n=== NEGATIVE CONTROL: equal modulus (must raise) ===") + try: + twofreq_offline_certificate(gauss("3/5", "4/5"), gauss(1, 0), rat(1), rat(2)) + raise SystemExit("FAIL: equal modulus not refused") + except ValueError as e: + print(f"refused as expected: {e}") + print("\n=== emitted Lean ===") + print(TwoFreqOfflineEmitter().emit_theorem(c, "euler_factor_section_offline")) diff --git a/telperion/src/telperion/emitter_sensitivity.py b/telperion/src/telperion/emitter_sensitivity.py index 8ae9fa0ae..8c8fe8eae 100644 --- a/telperion/src/telperion/emitter_sensitivity.py +++ b/telperion/src/telperion/emitter_sensitivity.py @@ -226,6 +226,25 @@ class SensitivityStance: "(conjecture1_proved = False)", # See negctrl_adapters/adapter_weil_form_enclosure.py. neg_control=NegControlStance(NEG_CONTROL_ADAPTER)), + "ExpEnclosureEmitter": _S(STRUCTURALLY_NONVACUOUS, + "rational bracket lo <= Real.exp x <= hi (and the deficit " + "e^x + e^-x - 2 / cosh faces) at a rational x with |x| <= 1: the " + "bracket IS the statement, re-derived in the kernel from Mathlib's " + "Real.exp_bound at the certified Taylor order by norm_num " + "[Nat.factorial] + linarith -- no separately-supplied identity to " + "corrupt, so the shape is structural. certify REFUSES a bracket the " + "exact rational Taylor box does not imply (and |x| > 1, order < 1 or " + "> 64, inverted brackets, non-positive deficit displacement, " + "non-rational input), so no widened or false enclosure ships. A " + "finite arithmetic fact about a transcendental constant at one " + "rational point; it discharges the Arb hexp hypothesis of " + "BraggDefect.bragg_defect_witness and says nothing about RH " + "(conjecture1_proved = False)", + # Structural, yet a kernel control exists: a hand-minted bracket + # NARROWER than the Taylor box (which Layer 1 refuses) makes the + # emitted linarith unprovable, so the kernel rejects it. + # See negctrl_adapters/adapter_exp_enclosure.py. + neg_control=NegControlStance(NEG_CONTROL_ADAPTER)), "EnclosureIntervalFoldEmitter": _S(STRUCTURALLY_NONVACUOUS, "integer near-CUE row-band check rowsOK…=true by decide; " "the Arb enclosures are the input trust seam, the kernel " @@ -560,6 +579,12 @@ class SensitivityStance: "power m and exact constant (4m)^m ARE the statement, re-decided in-kernel " "(add_one_le_exp + pow + norm_num); m=0 refused at certify time (negative " "control); no corruptible cofactor"), + "ExpLaurentIdentityEmitter": _S(CERTIFICATE_SENSITIVE, + "an exp-Laurent identity in e^d, e^(-d) certified as an exact reduction of " + "lhs - rhs modulo the single relation e^d * e^(-d) = 1; the QUOTIENT " + "(cofactor) is carried into linear_combination, so a corrupted cofactor or " + "a corrupted side leaves a nonzero residue and ring cannot close it", + neg_control=NegControlStance(NEG_CONTROL_ADAPTER)), "TwoRowSolveEmitter": _S(STRUCTURALLY_NONVACUOUS, "2x2 solution-entry bound from row-scale + ratio-gap hypotheses: a single " "fully-generic fixed atom (eq_div_iff/abs algebra + nlinarith), no per-instance " @@ -639,12 +664,42 @@ class SensitivityStance: "to corrupt; the winding integer is RE-VERIFIED at doubled precision + density at certify " "time and a claimed count the argument principle does not support is REFUSED (the negative " "control). conjecture1_proved = False"), + # --- 2026-09-18: MIRRORMERE E4b isolation INSTANCE emitter (the concrete shape the + # Rouche/E5 leg consumes; the general lemma is OfflineDiscs.offline_disjoint_discs). --- + "DisjointDiscsEmitter": _S(CERTIFICATE_SENSITIVE, + "Concrete isolation instance (OfflineDiscs shape): explicit Gaussian-rational strip points " + "plus an explicit rational radius r. The load-bearing facts are the per-pair STRICT " + "separation (2r)^2 < dist^2 (reached by Complex.dist_eq + Complex.norm_def + Real.lt_sqrt, " + "so no square root is ever approximated) and the per-point strict strip margins r < re, " + "r < 1 - re, all closed by norm_num on rational data. r is a SUPPLIED number that appears " + "in the statement AND is what the kernel arithmetic must clear, so an inflated r yields a " + "FALSE pair theorem the kernel rejects -- hence an adapter, not not_applicable. certify " + "REFUSES an overlapping pair, a boundary-reaching radius, a point off the open strip, a " + "duplicate point, or r <= 0. conjecture1_proved = False", + neg_control=NegControlStance(NEG_CONTROL_ADAPTER)), "SelfInversiveRigidityEmitter": _S(STRUCTURALLY_NONVACUOUS, "Equal-modulus real-rootedness (TwoFreqRigidity.twoFreq_realRooted_iff): the Gaussian-rational " "coefficients c₁,c₂ ARE the statement; the emitted proof discharges ‖c₁‖=‖c₂‖ from the EXACT " "rational equality |c₁|²=|c₂|² (Complex.norm via norm_num on re²+im²) and applies the in-island " "iff lemma; no separately-supplied corruptible identity. certify REFUSES |c₁|²≠|c₂|² (real-" - "rootedness not forced) — the negative control. conjecture1_proved = False"), + "rootedness not forced) — the negative control. MODE offline (2026-09-18): the mirror, " + "refutation-shaped — radical coefficients r*sqrt(q) with |c1|^2 != |c2|^2 EXACTLY emit " + "NOT-real-rooted via the .mp direction, the kernel re-deriving ||c||^2 = r^2*q by norm_num " + "(so a corrupted normSq breaks the emitted rewrite, not the statement), plus the explicit " + "x = i/2 witness for the Euler-factor shape; certify REFUSES EQUAL modulus and any " + "frequency pair needing transcendence of log. conjecture1_proved = False"), + "TwoFreqOfflineEmitter": _S(STRUCTURALLY_NONVACUOUS, + "Off-line displacement, the EXACT COMPLEMENT of SelfInversiveRigidityEmitter " + "(TwoFreqRigidity.twoFreq_realRooted_iff): the coefficient literals ARE the statement, " + "and the emitted proof refutes real-rootedness from the EXACT rational inequality " + "|c1|^2 != |c2|^2 (normSq by norm_num / Real.mul_self_sqrt); no separately-supplied " + "corruptible identity. certify REFUSES equal modulus -- precisely the regime the " + "rigidity emitter certifies -- so the two partition the coefficient space and neither " + "can emit a false theorem; also refuses a zero coefficient, equal frequencies " + "(including the disguised neglog(1) = rat(0)) and mode='displacement' outside the " + "Euler-factor shape. A kernel-gated adapter renders the equal-modulus forgery in " + "bridge-hypothesis mode. conjecture1_proved = False", + neg_control=NegControlStance(NEG_CONTROL_ADAPTER)), "SqrtRootEliminationEmitter": _S( CERTIFICATE_SENSITIVE, "radical elimination v < E - u*sqrt(rad) <-> (v < E and 0 < Q): the " diff --git a/telperion/src/telperion/negctrl_adapters/__init__.py b/telperion/src/telperion/negctrl_adapters/__init__.py index ce37c9a7e..159547e10 100644 --- a/telperion/src/telperion/negctrl_adapters/__init__.py +++ b/telperion/src/telperion/negctrl_adapters/__init__.py @@ -6,8 +6,11 @@ from . import adapter_concave_stationary_max # noqa: F401 from . import adapter_cone_farkas # noqa: F401 from . import adapter_consequence # noqa: F401 +from . import adapter_disjoint_discs # noqa: F401 from . import adapter_constrained_s_o_s # noqa: F401 from . import adapter_exact_fact # noqa: F401 +from . import adapter_exp_laurent_identity # noqa: F401 +from . import adapter_exp_enclosure # noqa: F401 from . import adapter_finite_argmax # noqa: F401 from . import adapter_fwd_telescope # noqa: F401 from . import adapter_handelman # noqa: F401 @@ -28,9 +31,14 @@ from . import adapter_telescoping_potential # noqa: F401 from . import adapter_transcendental_enclosure # noqa: F401 from . import adapter_two_moment_count # noqa: F401 +from . import adapter_twofreq_offline # noqa: F401 from . import adapter_w_z # noqa: F401 from . import adapter_weil_form_enclosure # noqa: F401 from . import adapter_zero_free_cosine # noqa: F401 __all__ = ['adapter_bragg_floor', 'adapter_c_g_round', 'adapter_concave_stationary_max', 'adapter_cone_farkas', 'adapter_consequence', 'adapter_constrained_s_o_s', 'adapter_exact_fact', 'adapter_finite_argmax', 'adapter_fwd_telescope', 'adapter_handelman', 'adapter_identity', 'adapter_infeasibility', 'adapter_interval_gram_inertia', 'adapter_li_positivity', 'adapter_nullstellensatz', 'adapter_order_balance', 'adapter_rational_identity', 'adapter_rational_s_o_s', 'adapter_real_nullstellensatz', 'adapter_recursive_domination_ratio', 'adapter_s_o_s', 'adapter_s_o_s_refutation', 'adapter_second_order', 'adapter_symmetric_quad_d2', 'adapter_telescoping_potential', 'adapter_transcendental_enclosure', 'adapter_two_moment_count', 'adapter_w_z', 'adapter_zero_free_cosine'] __all__ = ['adapter_bragg_floor', 'adapter_c_g_round', 'adapter_concave_stationary_max', 'adapter_cone_farkas', 'adapter_consequence', 'adapter_constrained_s_o_s', 'adapter_exact_fact', 'adapter_finite_argmax', 'adapter_fwd_telescope', 'adapter_handelman', 'adapter_identity', 'adapter_infeasibility', 'adapter_li_positivity', 'adapter_nullstellensatz', 'adapter_order_balance', 'adapter_rational_identity', 'adapter_rational_s_o_s', 'adapter_real_nullstellensatz', 'adapter_recursive_domination_ratio', 'adapter_s_o_s', 'adapter_s_o_s_refutation', 'adapter_second_order', 'adapter_symmetric_quad_d2', 'adapter_telescoping_potential', 'adapter_transcendental_enclosure', 'adapter_two_moment_count', 'adapter_w_z', 'adapter_weil_form_enclosure', 'adapter_zero_free_cosine'] +__all__ = ['adapter_bragg_floor', 'adapter_c_g_round', 'adapter_concave_stationary_max', 'adapter_cone_farkas', 'adapter_consequence', 'adapter_disjoint_discs', 'adapter_constrained_s_o_s', 'adapter_exact_fact', 'adapter_finite_argmax', 'adapter_fwd_telescope', 'adapter_handelman', 'adapter_identity', 'adapter_infeasibility', 'adapter_li_positivity', 'adapter_nullstellensatz', 'adapter_order_balance', 'adapter_rational_identity', 'adapter_rational_s_o_s', 'adapter_real_nullstellensatz', 'adapter_recursive_domination_ratio', 'adapter_s_o_s', 'adapter_s_o_s_refutation', 'adapter_second_order', 'adapter_symmetric_quad_d2', 'adapter_telescoping_potential', 'adapter_transcendental_enclosure', 'adapter_two_moment_count', 'adapter_w_z', 'adapter_zero_free_cosine'] +__all__ = ['adapter_bragg_floor', 'adapter_c_g_round', 'adapter_concave_stationary_max', 'adapter_cone_farkas', 'adapter_consequence', 'adapter_constrained_s_o_s', 'adapter_exact_fact', 'adapter_exp_laurent_identity', 'adapter_finite_argmax', 'adapter_fwd_telescope', 'adapter_handelman', 'adapter_identity', 'adapter_infeasibility', 'adapter_li_positivity', 'adapter_nullstellensatz', 'adapter_order_balance', 'adapter_rational_identity', 'adapter_rational_s_o_s', 'adapter_real_nullstellensatz', 'adapter_recursive_domination_ratio', 'adapter_s_o_s', 'adapter_s_o_s_refutation', 'adapter_second_order', 'adapter_symmetric_quad_d2', 'adapter_telescoping_potential', 'adapter_transcendental_enclosure', 'adapter_two_moment_count', 'adapter_w_z', 'adapter_zero_free_cosine'] +__all__ = ['adapter_bragg_floor', 'adapter_c_g_round', 'adapter_concave_stationary_max', 'adapter_cone_farkas', 'adapter_consequence', 'adapter_constrained_s_o_s', 'adapter_exact_fact', 'adapter_exp_enclosure', 'adapter_finite_argmax', 'adapter_fwd_telescope', 'adapter_handelman', 'adapter_identity', 'adapter_infeasibility', 'adapter_li_positivity', 'adapter_nullstellensatz', 'adapter_order_balance', 'adapter_rational_identity', 'adapter_rational_s_o_s', 'adapter_real_nullstellensatz', 'adapter_recursive_domination_ratio', 'adapter_s_o_s', 'adapter_s_o_s_refutation', 'adapter_second_order', 'adapter_symmetric_quad_d2', 'adapter_telescoping_potential', 'adapter_transcendental_enclosure', 'adapter_two_moment_count', 'adapter_w_z', 'adapter_zero_free_cosine'] +__all__ = ['adapter_bragg_floor', 'adapter_c_g_round', 'adapter_concave_stationary_max', 'adapter_cone_farkas', 'adapter_consequence', 'adapter_constrained_s_o_s', 'adapter_exact_fact', 'adapter_finite_argmax', 'adapter_fwd_telescope', 'adapter_handelman', 'adapter_identity', 'adapter_infeasibility', 'adapter_li_positivity', 'adapter_nullstellensatz', 'adapter_order_balance', 'adapter_rational_identity', 'adapter_rational_s_o_s', 'adapter_real_nullstellensatz', 'adapter_recursive_domination_ratio', 'adapter_s_o_s', 'adapter_s_o_s_refutation', 'adapter_second_order', 'adapter_symmetric_quad_d2', 'adapter_telescoping_potential', 'adapter_transcendental_enclosure', 'adapter_two_moment_count', 'adapter_twofreq_offline', 'adapter_w_z', 'adapter_zero_free_cosine'] diff --git a/telperion/src/telperion/negctrl_adapters/adapter_disjoint_discs.py b/telperion/src/telperion/negctrl_adapters/adapter_disjoint_discs.py new file mode 100644 index 000000000..1ea111283 --- /dev/null +++ b/telperion/src/telperion/negctrl_adapters/adapter_disjoint_discs.py @@ -0,0 +1,95 @@ +"""Negative-control adapter for DisjointDiscsEmitter (MIRRORMERE E4b isolation instances). + +The load-bearing content of an isolation instance is the per-pair STRICT separation +`(2r)^2 < dist^2`, emitted as a `norm_num` goal after `Real.lt_sqrt` eliminates the square root. +The radius `r` is a supplied number: inflate it past half the true separation and the emitted +theorem becomes FALSE (the two closed discs genuinely intersect), so the trusted kernel must reject +it. Layer 1 (`disjoint_discs_certificate`) already refuses such an r; this adapter mints the frozen +dataclass BY HAND to bypass that guard and let the kernel be the arbiter. + +FALSE forgery: the two points `1/2 + (7067/500) i` and `2/5 + (7067/500) i` are exactly `1/10` apart, +with the forged radius `r = 1/10` -- so `(2r)^2 = 1/25` is FOUR times the true `dist^2 = 1/100`, the +discs overlap grossly, and `norm_num` refutes the emitted strict inequality. + +TRUE twin: the same two points with the honest radius `r = 1/50` -- `(2r)^2 = 1/625 < 1/100`, and +both strip margins (`1/2` and `2/5`) clear `1/50` -- a genuine isolation instance, compiles clean. + +The emitted strip-containment proofs call the island lemma `Quasicrystal.abs_re_sub_le_dist` +(`OfflineDiscs.lean`), so the adapter supplies it verbatim as its Lean `prelude`; it is a two-line +consequence of `Complex.abs_re_le_norm`, proved from plain Mathlib, so the control still runs against +a bare Mathlib env. + +conjecture1_proved = False. +""" +from __future__ import annotations + +import sympy as sp + +from telperion.emit_disjoint_discs import DisjointDiscsCertificate, DisjointDiscsEmitter +from telperion.negative_control_harness import ( + NegativeControlAdapter, + emit_via_single_instance_family, + register, +) + +# The two strip points used by both twins: real parts 1/2 and 2/5 at a common height, so the true +# separation is exactly 1/10 and dist^2 = 1/100 -- small, exact, and easy to read off. +_PTS = ( + (sp.Rational(1, 2), sp.Rational(7067, 500)), + (sp.Rational(2, 5), sp.Rational(7067, 500)), +) + +# The island lemma the emitted strip-containment proofs call, restated from plain Mathlib. +_PRELUDE = """namespace Quasicrystal + +theorem abs_re_sub_le_dist (s z : ℂ) : |s.re - z.re| ≤ dist s z := by + have h := Complex.abs_re_le_norm (s - z) + rw [Complex.sub_re] at h + rwa [dist_eq_norm] + +end Quasicrystal +""" + + +def make_false_cert() -> DisjointDiscsCertificate: + """Hand-forged FALSE cert: r = 1/10, so (2r)^2 = 1/25 EXCEEDS dist^2 = 1/100 -- the discs + overlap and the emitted pair theorem is false (Layer 1 would refuse this cert).""" + return DisjointDiscsCertificate( + points=_PTS, r=sp.Rational(1, 10), + min_sep_sq=sp.Rational(1, 100), min_margin=sp.Rational(2, 5), + ) + + +def make_true_cert() -> DisjointDiscsCertificate: + """Paired TRUE twin: the same points with r = 1/50 -- (2r)^2 = 1/625 < 1/100 = dist^2 and both + strip margins clear the radius; a genuine isolation instance.""" + return DisjointDiscsCertificate( + points=_PTS, r=sp.Rational(1, 50), + min_sep_sq=sp.Rational(1, 100), min_margin=sp.Rational(2, 5), + ) + + +def _emit(cert: DisjointDiscsCertificate, name: str) -> str: + return emit_via_single_instance_family( + DisjointDiscsEmitter(), + lean_name=name, + instance_kwargs={"payload": cert}, + ) + + +register( + NegativeControlAdapter( + emitter_name="DisjointDiscsEmitter", + make_false_cert=make_false_cert, + make_true_cert=make_true_cert, + emit_call=_emit, + prelude=_PRELUDE, + allow_axioms=(), + label=( + "forged isolation instance with r = 1/10 on two points 1/10 apart: (2r)^2 = 1/25 " + "exceeds dist^2 = 1/100, the closed discs overlap, kernel rejects the norm_num " + "separation goal; true twin (same points, r = 1/50) compiles" + ), + imports_line="import Mathlib", + ) +) diff --git a/telperion/src/telperion/negctrl_adapters/adapter_exp_enclosure.py b/telperion/src/telperion/negctrl_adapters/adapter_exp_enclosure.py new file mode 100644 index 000000000..35711347c --- /dev/null +++ b/telperion/src/telperion/negctrl_adapters/adapter_exp_enclosure.py @@ -0,0 +1,89 @@ +"""Negative-control adapter for ExpEnclosureEmitter (rational `Real.exp` brackets). + +The emitted theorem is `lo <= Real.exp x /\\ Real.exp x <= hi`, proved from Mathlib's +`Real.exp_bound` at the certified Taylor order: the tactic derives `S - r <= exp x <= S + r` +for the EXACT rational partial sum `S` and remainder `r`, then closes the claimed bracket by +`linarith`. The load-bearing content is therefore exactly the pair `(lo, hi)`: a claim the +Taylor box does not imply cannot be reached by that `linarith`, and the TRUSTED Lean kernel +rejects the proof. + +FALSE forgery: `x = 1/10`, `n = 6`, `lo = 1`, `hi = 1105/1000`. Now `e^(1/10) = 1.1051709...` +and the order-6 box is `[1.1051709150..., 1.1051709182...]`, so the claimed `hi` sits BELOW the +box's lower endpoint -- the claim is not merely unproved, it is FALSE. Layer 1 +(`exp_enclosure_certificate`) refuses it (no order up to the cap fits, and this one is +explicitly pinned at `n = 6`); the adapter mints the frozen dataclass BY HAND, bypassing that +guard exactly as `adapter_bragg_floor` does, so the kernel is the arbiter: the final +`linarith` cannot get `exp (1/10) <= 1105/1000` out of `h2 : exp (1/10) <= S_6 + r_6`. + +TRUE twin: the same point and order with an honest bracket, `lo = 110517/100000`, +`hi = 110518/100000` (which does contain the order-6 box) -- compiles clean and axiom-clean. + +Both twins are plain `(· : ℝ)` statements over Mathlib alone (imports_line `import Mathlib`, +empty prelude), so the control needs no island definitions. + +conjecture1_proved = False. +""" +from __future__ import annotations + +import sympy as sp + +from telperion.emit_exp_enclosure import ( + ExpEnclosureCert, + ExpEnclosureEmitter, + taylor_parts, +) +from telperion.negative_control_harness import ( + NegativeControlAdapter, + emit_via_single_instance_family, + register, +) + +_X = sp.Rational(1, 10) +_N = 6 +_S, _R = taylor_parts(_X, _N) + + +def make_false_cert(): + """Hand-forged FALSE cert: hi = 1105/1000 is BELOW the order-6 Taylor lower endpoint + S_6 - r_6 = 1.10517091..., so `exp (1/10) <= hi` is false and unreachable by linarith.""" + return ExpEnclosureCert( + x=_X, n=_N, partial_sum=_S, remainder=_R, + lo=sp.Rational(1), hi=sp.Rational(1105, 1000), mode="exp", + partial_sum_neg=taylor_parts(-_X, _N)[0], + ) + + +def make_true_cert(): + """Paired TRUE twin: an honest bracket at the same point and order (it contains the box).""" + return ExpEnclosureCert( + x=_X, n=_N, partial_sum=_S, remainder=_R, + lo=sp.Rational(110517, 100000), hi=sp.Rational(110518, 100000), mode="exp", + partial_sum_neg=taylor_parts(-_X, _N)[0], + ) + + +def _emit(cert, name: str) -> str: + return emit_via_single_instance_family( + ExpEnclosureEmitter(), + lean_name=name, + instance_kwargs={"payload": cert}, + ) + + +register( + NegativeControlAdapter( + emitter_name="ExpEnclosureEmitter", + make_false_cert=make_false_cert, + make_true_cert=make_true_cert, + emit_call=_emit, + prelude="", + allow_axioms=(), + label=( + "forged exp bracket [1, 1105/1000] at x = 1/10 whose upper endpoint lies BELOW the " + "order-6 Real.exp_bound box (e^(1/10) = 1.1051709...): the final linarith cannot " + "reach the claim and the kernel rejects it; the true twin [110517/100000, " + "110518/100000] at the same point and order compiles" + ), + imports_line="import Mathlib", + ) +) diff --git a/telperion/src/telperion/negctrl_adapters/adapter_exp_laurent_identity.py b/telperion/src/telperion/negctrl_adapters/adapter_exp_laurent_identity.py new file mode 100644 index 000000000..b7910ba6b --- /dev/null +++ b/telperion/src/telperion/negctrl_adapters/adapter_exp_laurent_identity.py @@ -0,0 +1,84 @@ +"""Negative-control adapter for ExpLaurentIdentityEmitter. + +The forged twin is the mistake QC_RECURRENCE section 6 caught in ITSELF and +corrected: the two one-sided clearances of an off-line pair are `e^d - 1` and +`1 - e^(-d)`, and it is their PRODUCT -- not their SUM -- that equals the Bragg +amplification excess `e^d + e^(-d) - 2`. The sum is `2d + O(d^3)`; the claim + + (e^d - 1) + (1 - e^(-d)) = e^d + e^(-d) - 2 [FALSE] + +leaves the residue `2 - 2*e^(-d)`, which no cofactor multiple of the relation +`e^d * e^(-d) = 1` can absorb. `certify` REFUSES it at Layer 1; this adapter +bypasses that refusal, hands the emitter a hand-built certificate carrying the +TRUE row's cofactor `-1`, and checks that the Lean KERNEL rejects the emitted +theorem anyway -- `linear_combination (-1) * hrel` faces a goal `ring` cannot +close. + +The TRUE twin is the same row with the product restored, cofactor `-1`, which +compiles clean: the rejection is for falsity, not for a malformed spine. +conjecture1_proved = False. +""" +from __future__ import annotations + +import sympy as sp + +from telperion.emit_exp_laurent_identity import ( + Y, + Z, + ExpLaurentCert, + ExpLaurentIdentityEmitter, +) +from telperion.negative_control_harness import ( + NegativeControlAdapter, + emit_via_single_instance_family, + register, +) + +_G_PLUS = Y - 1 # outer mirror clearance e^d - 1 +_G_MINUS = 1 - Z # inner clearance 1 - e^(-d) +_EXCESS = Y + Z - 2 # Bragg amplification excess +_COFACTOR = sp.Integer(-1) # the TRUE row's certificate: lhs - rhs = -(y*z - 1) + + +def make_true_cert() -> ExpLaurentCert: + """The genuine row: the PRODUCT of the clearances is the excess, cofactor -1.""" + return ExpLaurentCert(lhs=_G_PLUS * _G_MINUS, rhs=_EXCESS, + cofactor=_COFACTOR, var="d") + + +def make_false_cert() -> ExpLaurentCert: + """Forged twin: product -> SUM, with the true row's cofactor kept. + + `exp_laurent_certificate` would REFUSE this (remainder 2 - 2*expNeg != 0); + the certificate is assembled BY HAND so Layer 2 -- the kernel -- decides. + """ + return ExpLaurentCert(lhs=_G_PLUS + _G_MINUS, rhs=_EXCESS, + cofactor=_COFACTOR, var="d") + + +def _emit_call(cert: ExpLaurentCert, name: str) -> str: + return emit_via_single_instance_family( + ExpLaurentIdentityEmitter(), + lean_name=name, + instance_kwargs={"payload": cert}, + family_kwargs={"symbols": (Y, Z)}, + ) + + +register( + NegativeControlAdapter( + emitter_name="ExpLaurentIdentityEmitter", + make_false_cert=make_false_cert, + make_true_cert=make_true_cert, + emit_call=_emit_call, + prelude="", + allow_axioms=(), + label=( + "FALSE exp-Laurent row (e^d - 1) + (1 - e^(-d)) = e^d + e^(-d) - 2 " + "(the clearances' SUM substituted for their PRODUCT, QC_RECURRENCE " + "section 6's own corrected mistake); linear_combination (-1) * hrel " + "cannot close the residue 2 - 2*e^(-d)." + ), + imports_line="import Mathlib", + ) +) diff --git a/telperion/src/telperion/negctrl_adapters/adapter_twofreq_offline.py b/telperion/src/telperion/negctrl_adapters/adapter_twofreq_offline.py new file mode 100644 index 000000000..5043dafba --- /dev/null +++ b/telperion/src/telperion/negctrl_adapters/adapter_twofreq_offline.py @@ -0,0 +1,90 @@ +"""Negative-control adapter for TwoFreqOfflineEmitter (MIRRORMERE ladder rung T2). + +The emitted theorem REFUTES real-rootedness of a two-frequency section, and its whole +load-bearing content is the EXACT inequality `|c1|^2 != |c2|^2`: the proof rewrites with +the island iff, turns the resulting `||c1|| = ||c2||` into a normSq equality, evaluates +both sides to rational literals, and closes by `norm_num` deriving False from them. If +the two moduli are EQUAL that last step has nothing to work with -- and, worse, the +theorem is then genuinely FALSE (equal modulus IS real-rootedness). The kernel is the +arbiter. + +FALSE forgery: the selfinversive_rigidity TRUE instance, `c1 = 3/5 + 4/5 i`, `c2 = 1`, +frequencies 1 and 2 -- equal moduli `|c1|^2 = |c2|^2 = 1`. Layer 1 +(`twofreq_offline_certificate`) refuses it outright; the adapter mints the frozen +dataclass BY HAND to bypass that guard, so the forged proof reaches `h2 : (1 : R) = 1` +and must derive False from it. `norm_num` cannot, and the theorem is rejected. + +TRUE twin: the Euler factor at p = 2, `1 - 2^(-s)` on `s = 1/2 + i x`, i.e. +`twoFreq 1 (-(1/sqrt 2)) 0 (-(log 2))`, whose moduli are 1 and 1/2 -- a genuine off-line +section, compiles clean and axiom-clean. + +BRIDGE-HYPOTHESIS MODE. The harness elaborates twins against plain `import Mathlib`, so +both carry `twoFreq` VERBATIM from TwoFreqRigidity.lean:40-42 in the prelude and take the +island iff `twoFreq_realRooted_iff` as an EXPLICIT hypothesis `hiff`. This is the same +discipline as `adapter_bragg_floor`: the control tests the EMITTER's own arithmetic, and +nothing else. The hypothesis-free island theorem (which discharges `hiff` from the real +lemma) is compiled by the `twofreq-offline-compiles` CI job inside the quasicrystal +island. + +conjecture1_proved = False. +""" +from __future__ import annotations + +import sympy as sp + +from telperion.emit_twofreq_offline import ( + TWOFREQ_PRELUDE, + TwoFreqOfflineCert, + TwoFreqOfflineEmitter, +) +from telperion.negative_control_harness import NegativeControlAdapter, register + + +def make_false_cert() -> TwoFreqOfflineCert: + """Hand-forged FALSE cert: EQUAL moduli (|c1|^2 = |c2|^2 = 1), which makes the sum + genuinely real-rooted, so the emitted negation is false. twofreq_offline_certificate + refuses exactly this.""" + return TwoFreqOfflineCert( + c1=("gauss", sp.Rational(3, 5), sp.Rational(4, 5)), + c2=("gauss", sp.Integer(1), sp.Integer(0)), + lam1=("rat", sp.Integer(1)), + lam2=("rat", sp.Integer(2)), + normsq1=sp.Integer(1), normsq2=sp.Integer(1), + p=None, displacement=None, mode="offline", + ) + + +def make_true_cert() -> TwoFreqOfflineCert: + """Paired TRUE twin: the p = 2 Euler-factor section, moduli 1 and 1/2.""" + return TwoFreqOfflineCert( + c1=("gauss", sp.Integer(1), sp.Integer(0)), + c2=("inv_sqrt", -1, sp.Integer(2)), + lam1=("rat", sp.Integer(0)), + lam2=("neglog", 2), + normsq1=sp.Integer(1), normsq2=sp.Rational(1, 2), + p=2, displacement=sp.Rational(1, 2), mode="offline", + ) + + +def _emit(cert: TwoFreqOfflineCert, name: str) -> str: + # Private route: the emitter's per-instance renderer, in bridge-hypothesis mode. + return TwoFreqOfflineEmitter().emit_theorem(cert, name, bridge=True) + + +register( + NegativeControlAdapter( + emitter_name="TwoFreqOfflineEmitter", + make_false_cert=make_false_cert, + make_true_cert=make_true_cert, + emit_call=_emit, + prelude=TWOFREQ_PRELUDE, + allow_axioms=(), + label=( + "forged two-frequency section with EQUAL moduli (c1 = 3/5 + 4/5 i, c2 = 1, " + "|c1|^2 = |c2|^2 = 1): equal modulus IS real-rootedness, so the emitted " + "negation is false and the closing norm_num cannot derive False from 1 = 1; " + "kernel rejects. True twin (the p = 2 Euler factor, moduli 1 vs 1/2) compiles" + ), + imports_line="import Mathlib", + ) +) diff --git a/telperion/telperion.toml b/telperion/telperion.toml index 6bcd9cc93..cb4538ec0 100644 --- a/telperion/telperion.toml +++ b/telperion/telperion.toml @@ -628,6 +628,12 @@ name = "zeta_zero_localization" script = "examples/zeta_zero_localization/generate.py" group = "flint" # Arb lambda-enclosures for xi-line zeros; needs python-flint +[[check]] +name = "exp_laurent_deficit" +script = "examples/exp_laurent_deficit/generate.py" +group = "quick" # exp-Laurent recurrence-deficit rows (MIRRORMERE W3d); pure sympy, ~0.1 s. + # Emits INTO the zeta_zero_localization island (lean/ExpLaurentDeficit.lean). + [[check]] name = "jensen_hyperbolicity" script = "examples/jensen_hyperbolicity/generate.py" @@ -653,6 +659,11 @@ name = "bragg_amplitude" script = "examples/bragg_amplitude/generate.py" group = "quick" # exact rational Bragg amplitudes (no flint) +[[check]] +name = "exp_enclosure" +script = "examples/exp_enclosure/generate.py" +group = "quick" # exact rational Real.exp brackets from Real.exp_bound (no flint) + [[check]] name = "defect_witness" script = "examples/defect_witness/generate.py" @@ -673,6 +684,16 @@ name = "selfinversive_rigidity" script = "examples/selfinversive_rigidity/generate.py" group = "quick" # exact self-inversive rigidity certificate (no flint) +[[check]] +name = "disjoint_discs" +script = "examples/disjoint_discs/generate.py" +group = "quick" # MIRRORMERE E4b isolation instances (exact rationals, no flint) + +[[check]] +name = "twofreq_offline" +script = "examples/twofreq_offline/generate.py" +group = "quick" # exact off-line displacement certificate (no flint) + [[check]] name = "winding_box_zero" script = "examples/winding_box_zero/generate.py" diff --git a/telperion/tests/test_emit_disjoint_discs.py b/telperion/tests/test_emit_disjoint_discs.py new file mode 100644 index 000000000..f5bc89b6c --- /dev/null +++ b/telperion/tests/test_emit_disjoint_discs.py @@ -0,0 +1,99 @@ +"""disjoint_discs emitter — MIRRORMERE E4b isolation INSTANCES (OfflineDiscs shape). + +Explicit strip points + an explicit rational radius, with the per-pair STRICT separation +`(2r)^2 < dist^2` and the strict strip margins as the load-bearing, norm_num-decided facts. +The negative controls are an inflated radius (overlapping discs), a boundary-reaching radius, a +point off the open strip, a duplicate point and a non-positive radius — all REFUSED at certify. +""" +import sys +from pathlib import Path + +import pytest +import sympy as sp + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from telperion import ( # noqa: E402 + DisjointDiscsEmitter, ValidationReport, certify, emit, +) +from telperion.emit_disjoint_discs import ( # noqa: E402 + disjoint_discs_certificate, disjoint_discs_family, +) +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 +from telperion.lean_lint import lint_lean_text # noqa: E402 + +_PTS = [("1/2", "7067/500"), ("1/2", "10511/500"), ("2/5", "12505/500"), ("3/5", "12505/500")] + + +def _spec(points, r): + return lambda pt: {"points": points, "r": r} + + +def _refused(points, r): + fam = disjoint_discs_family("Bad", GridSpec([("_", [0])]), lambda pt: "bad", + spec=_spec(points, r)) + with pytest.raises(Exception): + certify(fam) + + +def test_positive_cert_records_the_exact_separation_and_margin(): + cert = disjoint_discs_certificate(_PTS, "1/50") + # the off-line pair (2/5, 3/5) at a common height is the tight one: dist = 1/5 + assert cert.min_sep_sq == sp.Rational(1, 25) + assert cert.min_margin == sp.Rational(2, 5) + assert (2 * cert.r) ** 2 < cert.min_sep_sq + + +def test_refuses_overlapping_discs(): + # NEGATIVE CONTROL: r = 1/10 on points 1/5 apart gives (2r)^2 = 1/25 = dist^2 — NOT strict. + _refused(_PTS, "1/10") + + +def test_refuses_radius_reaching_the_strip_boundary(): + # NEGATIVE CONTROL: margin at re = 2/5 is 2/5; r = 1/2 pushes the disc out of the open strip. + _refused([("2/5", "1"), ("2/5", "100")], "1/2") + + +def test_refuses_point_on_the_strip_boundary(): + # NEGATIVE CONTROL: re = 1 is ON the boundary — no disc about it lies in the OPEN strip. + _refused([("1", "5"), ("1/2", "9")], "1/100") + + +def test_refuses_duplicate_points_and_nonpositive_radius(): + _refused([("1/2", "3"), ("1/2", "3")], "1/100") + _refused([("1/2", "3"), ("1/2", "9")], "0") + + +def test_emit_is_lint_clean_and_deterministic(): + fam = disjoint_discs_family("DD", GridSpec([("_", [0])]), lambda pt: "isolation_bank", + spec=_spec(_PTS, "1/50")) + report = emit(certify(fam), + LeanProfile(namespace=("DD",), imports=("Mathlib", "OfflineDiscs")), + [DisjointDiscsEmitter()], + ValidationReport(checks=(("disjoint_discs", True),))) + text = next(iter(report.files.values())) + # the two load-bearing routes, plus the statement gate against the registry-node shape + assert "Metric.closedBall_disjoint_closedBall" in text + assert "Real.lt_sqrt" in text + assert "Quasicrystal.abs_re_sub_le_dist" in text + assert "example : ∃ r : ℝ, 0 < r ∧" in text + # 6 pairs + 4 strip lemmas + 1 assembly + assert text.count("theorem isolation_bank") >= 11 + errors = [i for i in lint_lean_text(text) if i.severity == "error"] + assert errors == [], errors + + +def test_emitter_is_classified_in_the_sensitivity_registry_with_an_adapter(): + from telperion.emitter_sensitivity import REGISTRY + import telperion.negctrl_adapters # noqa: F401 (registers the adapters) + from telperion.negative_control_harness import registered_adapters + assert "DisjointDiscsEmitter" in REGISTRY + assert "DisjointDiscsEmitter" in registered_adapters() + + +def test_kind_is_wired_into_the_dispatch_tables(): + from telperion.certify import _SPECIAL_DISPATCH, _SPECIAL_KINDS, emitter_for + assert "disjoint_discs" in _SPECIAL_KINDS + assert len(_SPECIAL_DISPATCH["disjoint_discs"]) == 3 + assert emitter_for("disjoint_discs").kind == "disjoint_discs" diff --git a/telperion/tests/test_emit_exp_enclosure.py b/telperion/tests/test_emit_exp_enclosure.py new file mode 100644 index 000000000..6e32d3f9d --- /dev/null +++ b/telperion/tests/test_emit_exp_enclosure.py @@ -0,0 +1,260 @@ +"""exp_enclosure emitter -- kernel-checked rational brackets of Real.exp from Real.exp_bound. + +The shape: for a rational `x` with `|x| <= 1`, Mathlib's `Real.exp_bound` gives the order-`n` +Taylor box `[S_n - r_n, S_n + r_n]` around `Real.exp x` with `S_n = sum_{m emit -> lint + refusals. + +The shape: identities in ``e^d`` and ``e^(-d)`` certified as an exact reduction of +``lhs - rhs`` modulo the single relation ``e^d * e^(-d) = 1``, with the quotient +(cofactor) carried into the emitted ``linear_combination``. + +The load-bearing refusal is the mistake QC_RECURRENCE section 6 caught in itself: +the SUM of the two off-line clearances is NOT the amplification excess -- only +their PRODUCT is. conjecture1_proved = False. +""" +import sys +from pathlib import Path + +import pytest +import sympy as sp + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +from telperion import ValidationReport, certify, emit # noqa: E402 +from telperion.emit_exp_laurent_identity import ( # noqa: E402 + RELATION, + Y, + Z, + ExpLaurentIdentityEmitter, + exp_laurent_certificate, + exp_laurent_identity_family, +) +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 + +_G_PLUS = Y - 1 +_G_MINUS = 1 - Z +_EXCESS = Y + Z - 2 + + +def test_recurrence_deficit_row_cofactor_is_minus_one(): + """(e^d - 1)(1 - e^(-d)) = e^d + e^(-d) - 2 with the exact cofactor -1.""" + cert = exp_laurent_certificate(_G_PLUS * _G_MINUS, _EXCESS, name="row") + assert cert.cofactor == -1 + # the certificate re-multiplies exactly: lhs - rhs = cofactor * (y*z - 1) + assert sp.expand(cert.cofactor * RELATION - (cert.lhs - cert.rhs)) == 0 + + +def test_squared_row_cofactor_is_exact(): + """The Weil-energy square is certified too, with a nontrivial cofactor.""" + cert = exp_laurent_certificate((_G_PLUS * _G_MINUS) ** 2, _EXCESS ** 2, + name="row_sq") + assert cert.cofactor != 0 + assert sp.expand(cert.cofactor * RELATION - (cert.lhs - cert.rhs)) == 0 + + +def test_refuses_the_sum_of_the_clearances(): + """NEGATIVE CONTROL -- the memo's own corrected mistake. + + `(e^d - 1) + (1 - e^(-d))` is `2d + O(d^3)`, not the excess; the reduction + leaves the residue `2 - 2*e^(-d)`, so the certifier must refuse. + """ + with pytest.raises(ValueError) as exc: + exp_laurent_certificate(_G_PLUS + _G_MINUS, _EXCESS, name="sum") + assert "does not reduce to 0" in str(exc.value) + + +def test_refuses_a_plain_ring_identity(): + """A claim that never uses the relation has cofactor 0 and is refused: the + certificate would carry no information (that shape is IdentityEmitter's).""" + with pytest.raises(ValueError) as exc: + exp_laurent_certificate((Y - 1) * (Y + 1), Y ** 2 - 1, name="ring") + assert "NOT load-bearing" in str(exc.value) + + +def test_refuses_symbols_outside_the_exp_generators(): + with pytest.raises(ValueError) as exc: + exp_laurent_certificate(Y * sp.Symbol("q"), Y, name="alien") + assert "outside the exp generators" in str(exc.value) + + +def test_refuses_a_non_polynomial_side(): + with pytest.raises(ValueError) as exc: + exp_laurent_certificate(Y / (Z - 1), Y, name="nonpoly") + assert "not a polynomial" in str(exc.value) + + +def _emit_rows(rows): + fam = exp_laurent_identity_family( + "TestExpLaurent", + GridSpec([("row", range(len(rows)))]), + lambda pt: rows[pt["row"]][0], + spec=lambda pt: (rows[pt["row"]][1], rows[pt["row"]][2], "d"), + ) + report = emit( + certify(fam), + LeanProfile(namespace=("TestExpLaurent",)), + [ExpLaurentIdentityEmitter()], + ValidationReport(checks=(("exp_laurent_identity", True),)), + ) + return next(iter(report.files.values())) + + +def test_emitted_lean_is_structure_preserving_and_sorry_free(): + """The STATEMENT must read as the mathematics was written (Lean `*` is not + definitionally commutative, so the emitted order is fixed and deterministic), + and the certified cofactor must appear in the proof.""" + text = _emit_rows((("row", _G_PLUS * _G_MINUS, _EXCESS),)) + assert ("theorem row (d : ℝ) :\n" + " (Real.exp d - 1) * (1 - Real.exp (-d)) = " + "Real.exp d + Real.exp (-d) - 2") in text + assert "have hrel : Real.exp d * Real.exp (-d) = 1" in text + assert "linear_combination (-1 : ℝ) * hrel" in text + assert "sorry" not in text + + +def test_emission_is_deterministic(): + rows = (("row", _G_PLUS * _G_MINUS, _EXCESS), + ("row_sq", (_G_PLUS * _G_MINUS) ** 2, _EXCESS ** 2)) + assert _emit_rows(rows) == _emit_rows(rows) + + +def test_adapter_is_registered_for_the_generic_negative_control(): + """The kernel-gated two-sided control is wired (it RUNS in + tests/test_certificate_sensitivity.py::test_generic_negative_control_holds).""" + from telperion.negative_control_harness import registered_adapters + + import telperion.negctrl_adapters # noqa: F401 (registers every adapter) + + adapters = registered_adapters() + assert "ExpLaurentIdentityEmitter" in adapters + adapter = adapters["ExpLaurentIdentityEmitter"] + # the forged twin really is the sum-for-product substitution + assert sp.expand(adapter.make_false_cert().lhs + - (_G_PLUS + _G_MINUS)) == 0 + assert sp.expand(adapter.make_true_cert().lhs + - _G_PLUS * _G_MINUS) == 0 diff --git a/telperion/tests/test_emit_selfinversive_rigidity.py b/telperion/tests/test_emit_selfinversive_rigidity.py index 346f58f47..fda1893a3 100644 --- a/telperion/tests/test_emit_selfinversive_rigidity.py +++ b/telperion/tests/test_emit_selfinversive_rigidity.py @@ -12,7 +12,8 @@ SelfInversiveRigidityEmitter, ValidationReport, certify, emit, ) from telperion.emit_selfinversive_rigidity import ( # noqa: E402 - selfinversive_rigidity_certificate, selfinversive_rigidity_family, + selfinversive_offline_certificate, selfinversive_rigidity_certificate, + selfinversive_rigidity_family, ) from telperion.family import GridSpec # noqa: E402 from telperion.lean import LeanProfile # noqa: E402 @@ -69,6 +70,121 @@ def test_emit_is_lint_clean_and_deterministic(): assert errors == [], errors +# --------------------------------------------------------------------------------------------- +# OFFLINE mode (2026-09-18): the refutation-shaped mirror — unequal modulus ⟹ NOT real-rooted. +# --------------------------------------------------------------------------------------------- + + +def _euler_spec(p): + """The p-th Euler-factor section twoFreq(1, −(1/√p); 0, −log p); −(1/√p) = (−1/p)·√p.""" + return {"mode": "offline", "c1": "1", "c2": {"rat": f"-1/{p}", "sqrt": p}, + "lam1": "0", "lam2": {"rat": "-1", "log": p}} + + +def test_offline_positive_cert_euler_factor(): + import sympy as sp + + spec = _euler_spec(2) + cert = selfinversive_offline_certificate(spec["c1"], spec["c2"], spec["lam1"], spec["lam2"]) + # |c₁|² = 1, |c₂|² = (1/2)²·2 = 1/2 — EXACT rational arithmetic on r·√q coefficients. + assert cert.normsq1 == 1 and cert.normsq2 == sp.Rational(1, 2) + assert cert.euler_p == 2 + + +def test_offline_refuses_equal_modulus(): + # NEGATIVE CONTROL of the offline mode: equal modulus FORCES real-rootedness, so there is + # no off-line zero to certify — the mirror of the default mode's refusal. + try: + selfinversive_offline_certificate({"rat": "1/2", "sqrt": 2}, {"rat": "-1/2", "sqrt": 2}, + "0", {"rat": "-1", "log": 2}) + raised = False + except ValueError: + raised = True + assert raised, "equal modulus must be refused in offline mode" + + +def test_offline_refuses_zero_coefficient_and_bad_radicand(): + for c2 in ({"rat": "0", "sqrt": 2}, {"rat": "-1", "sqrt": "-2"}): + try: + selfinversive_offline_certificate("1", c2, "0", {"rat": "-1", "log": 2}) + raised = False + except ValueError: + raised = True + assert raised, f"must refuse coefficient {c2}" + + +def test_offline_refuses_uncertifiable_frequency_pair(): + # A NONZERO rational against r·log q would need transcendence of log to separate — refused, + # not faked. Equal frequencies and equal-base logs with equal rational factor too. + for lam1, lam2 in (("1", {"rat": "-1", "log": 2}), + ({"rat": "1", "log": 2}, {"rat": "1", "log": 2}), + ({"rat": "1", "log": 2}, {"rat": "1", "log": 3}), + ("0", "0")): + try: + selfinversive_offline_certificate("1", {"rat": "-1/2", "sqrt": 2}, lam1, lam2) + raised = False + except ValueError: + raised = True + assert raised, f"must refuse frequency pair {lam1!r}, {lam2!r}" + + +def test_offline_accepts_zero_against_log_and_same_base_logs(): + # The kernel-certifiable distinctness cases: 0 vs r·log q, and r₁·log q vs r₂·log q. + selfinversive_offline_certificate("1", {"rat": "-1/2", "sqrt": 2}, "0", {"rat": "-1", "log": 2}) + selfinversive_offline_certificate("1", {"rat": "-1/2", "sqrt": 2}, + {"rat": "1", "log": 2}, {"rat": "3", "log": 2}) + + +def test_offline_emit_carries_refutation_witness_and_node_form(): + fam = selfinversive_rigidity_family("OFF", GridSpec([("_", [0])]), + lambda pt: "euler_factor_p2_offline", + spec=lambda pt: _euler_spec(2)) + report = emit(certify(fam), + LeanProfile(namespace=("OFF",), imports=("Mathlib", "TwoFreqRigidity")), + [SelfInversiveRigidityEmitter()], + ValidationReport(checks=(("selfinversive_rigidity_offline", True),))) + text = next(iter(report.files.values())) + # the refutation, via the .mp direction and the EXACT normSq inequality + assert "¬ (∀ x : ℂ" in text + assert ".mp hall" in text + assert "‖euler_factor_p2_offline_c1‖ ^ 2 ≠ ‖euler_factor_p2_offline_c2‖ ^ 2" in text + # the explicit witness x = i/2 and the second, witness-route refutation + assert "euler_factor_p2_offline_witness :" in text + assert "Complex.I / 2" in text + assert "euler_factor_p2_offline_of_witness :" in text + # the mission-registry-verbatim restatement + assert "twoFreq 1 ((-(1 / Real.sqrt 2) : ℝ) : ℂ) 0 (-(Real.log 2))" in text + errors = [i for i in lint_lean_text(text) if i.severity == "error"] + assert errors == [], errors + + +def test_offline_non_euler_instance_ships_no_witness(): + # An unequal-modulus instance that is NOT the Euler-factor shape still refutes, but there is + # no closed-form witness to ship — exactly one theorem. + fam = selfinversive_rigidity_family("OFF2", GridSpec([("_", [0])]), lambda pt: "generic_offline", + spec=lambda pt: {"mode": "offline", "c1": "2", "c2": "3", + "lam1": "0", "lam2": {"rat": "-1", "log": 2}}) + report = emit(certify(fam), + LeanProfile(namespace=("OFF2",), imports=("Mathlib", "TwoFreqRigidity")), + [SelfInversiveRigidityEmitter()], + ValidationReport(checks=(("selfinversive_rigidity_offline", True),))) + text = next(iter(report.files.values())) + assert "generic_offline_witness" not in text + assert "¬ (∀ x : ℂ" in text + + +def test_unknown_mode_is_refused(): + fam = selfinversive_rigidity_family("OFF3", GridSpec([("_", [0])]), lambda pt: "bogus", + spec=lambda pt: {"mode": "bogus", "c1": "1", "c2": "2", + "lam1": "0", "lam2": "1"}) + try: + certify(fam) + raised = False + except Exception: + raised = True + assert raised, "an unknown mode must be refused" + + def test_emitter_is_classified_in_the_sensitivity_registry(): from telperion.emitter_sensitivity import REGISTRY assert "SelfInversiveRigidityEmitter" in REGISTRY diff --git a/telperion/tests/test_emit_twofreq_offline.py b/telperion/tests/test_emit_twofreq_offline.py new file mode 100644 index 000000000..1f797f8b5 --- /dev/null +++ b/telperion/tests/test_emit_twofreq_offline.py @@ -0,0 +1,166 @@ +"""twofreq_offline emitter -- certified OFF-line displacement of a two-frequency section. + +The exact complement of `selfinversive_rigidity`: there, |c1|^2 = |c2|^2 EXACTLY forces +real-rootedness; here, |c1|^2 != |c2|^2 EXACTLY REFUTES it (every zero sits off the real +line). The two emitters partition the coefficient space and neither can emit a false +theorem: each REFUSES precisely the other's regime. + +conjecture1_proved = False -- a finite section fact about one Euler factor; nothing about +zeta or RH. +""" +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +import pytest # noqa: E402 + +from telperion import ( # noqa: E402 + TwoFreqOfflineEmitter, ValidationReport, certify, emit, +) +from telperion.emit_twofreq_offline import ( # noqa: E402 + gauss, inv_sqrt, neglog, rat, real_sqrt, + twofreq_offline_certificate, twofreq_offline_family, +) +from telperion.family import GridSpec # noqa: E402 +from telperion.lean import LeanProfile # noqa: E402 +from telperion.lean_lint import lint_lean_text # noqa: E402 + +_NODE = (Path(__file__).resolve().parents[1] / "missions" / "mirrormere" / "lean" + / "Statements" / "MM_euler_factor_section_offline.lean") + + +def _euler_spec(p, mode="displacement"): + return {"c1": gauss(1, 0), "c2": inv_sqrt(p, sign=-1), + "lam1": rat(0), "lam2": neglog(p), "p": p, "mode": mode} + + +def _emit_one(spec, name="tfo_demo"): + fam = twofreq_offline_family("TFO", GridSpec([("_", [0])]), lambda pt: name, + spec=lambda pt: spec) + report = emit(certify(fam), + LeanProfile(namespace=("TFO",), imports=("Mathlib", "TwoFreqRigidity"), + prelude="open Quasicrystal\n"), + [TwoFreqOfflineEmitter()], + ValidationReport(checks=(("twofreq_offline", True),))) + return next(iter(report.files.values())) + + +# --------------------------------------------------------------------------- positive + +def test_positive_cert_p2_normsq(): + cert = twofreq_offline_certificate(**_euler_spec(2)) + assert cert.normsq1 == 1 + assert cert.normsq2 == pytest.approx(0.5) + assert cert.normsq1 != cert.normsq2 + assert cert.p == 2 + assert cert.displacement == pytest.approx(0.5) + assert cert.mode == "displacement" + + +def test_positive_cert_gauss_and_real_sqrt(): + # Gaussian-rational vs real: |c1|^2 = 1, |c2|^2 = 4. + c = twofreq_offline_certificate(c1=gauss("3/5", "4/5"), c2=gauss(2, 0), + lam1=rat(1), lam2=rat(2)) + assert (c.normsq1, c.normsq2) == (1, 4) + # q * sqrt s: |c1|^2 = (3/2)^2 * 3 = 27/4. + c2 = twofreq_offline_certificate(c1=real_sqrt("-3/2", 3), c2=gauss(1, 0), + lam1=rat(0), lam2=rat(7)) + assert c2.normsq1 == pytest.approx(27 / 4) and c2.normsq2 == 1 + + +# --------------------------------------------------------------------------- refusals + +def test_refuses_equal_modulus(): + # THE anti-phantom refusal: equal modulus means the sum IS real-rooted, so the + # emitted negation would be FALSE. Exact complement of selfinversive_rigidity. + with pytest.raises(ValueError, match="equal modulus"): + twofreq_offline_certificate(c1=gauss("3/5", "4/5"), c2=gauss(1, 0), + lam1=rat(1), lam2=rat(2)) + + +def test_refuses_zero_coefficient(): + with pytest.raises(ValueError, match="nonzero"): + twofreq_offline_certificate(c1=gauss(0, 0), c2=gauss(1, 0), + lam1=rat(1), lam2=rat(2)) + + +def test_refuses_equal_frequencies(): + with pytest.raises(ValueError, match="differ"): + twofreq_offline_certificate(c1=gauss(1, 0), c2=gauss(2, 0), + lam1=rat(3), lam2=rat(3)) + # log 1 = 0, so ('neglog', 1) IS ('rat', 0) -- the disguised degeneracy. + with pytest.raises(ValueError): + twofreq_offline_certificate(c1=gauss(1, 0), c2=gauss(2, 0), + lam1=rat(0), lam2=neglog(1)) + + +def test_refuses_nonpositive_radicand(): + with pytest.raises(ValueError): + twofreq_offline_certificate(c1=real_sqrt(1, -3), c2=gauss(1, 0), + lam1=rat(0), lam2=rat(1)) + + +def test_refuses_displacement_mode_outside_p_family(): + # Honest scope: the certified displacement 1/2 is a fact about 1 - p^(-1/2) e^(-i log p x) + # ONLY. Any other shape is refused rather than guessed at. + with pytest.raises(ValueError, match="displacement"): + twofreq_offline_certificate(c1=gauss("3/5", "4/5"), c2=gauss(2, 0), + lam1=rat(1), lam2=rat(2), mode="displacement") + + +def test_refuses_p_below_two(): + with pytest.raises(ValueError): + twofreq_offline_certificate(**_euler_spec(1)) + + +def test_refuses_negative_rational_frequency_against_a_log(): + # The emitted separation 0 <= r < log p needs the rational side nonnegative. + with pytest.raises(ValueError, match="nonnegative"): + twofreq_offline_certificate(c1=gauss(1, 0), c2=gauss(2, 0), + lam1=rat("-5"), lam2=neglog(3)) + + +# --------------------------------------------------------------------------- emission + +def test_statement_matches_mm_node(): + """The p = 2 theorem must be byte-identical (modulo the missions normalizer) to the + registry's MM_euler_factor_section_offline statement.""" + from telperion.missions.verify import normalize_lean + + text = _emit_one(_euler_spec(2), name="euler_factor_section_offline") + node_body = "\n".join( + ln for ln in _NODE.read_text(encoding="utf-8").splitlines()[1:] + if not ln.strip().startswith(("import ", "open "))) + assert normalize_lean(node_body) in normalize_lean(text) + + +def test_emit_is_lint_clean_and_deterministic(): + text = _emit_one(_euler_spec(2)) + again = _emit_one(_euler_spec(2)) + assert text == again + assert "twoFreq_realRooted_iff" in text + assert "conjecture1_proved = False" in text + assert "sorry" not in text + errors = [i for i in lint_lean_text(text) if i.severity == "error"] + assert errors == [], errors + + +def test_displacement_and_existence_theorems_are_emitted(): + text = _emit_one(_euler_spec(3), name="tfo_p3") + assert "theorem tfo_p3 :" in text + assert "theorem tfo_p3_offline_zero :" in text + assert "theorem tfo_p3_displacement :" in text + assert "x.im = 1 / 2" in text + # 'offline' mode drops the displacement theorem but keeps the existence corollary. + plain = _emit_one({**_euler_spec(3), "mode": "offline"}, name="tfo_p3") + assert "theorem tfo_p3_displacement :" not in plain + assert "theorem tfo_p3_offline_zero :" in plain + + +def test_emitter_is_classified_in_the_sensitivity_registry(): + from telperion.emitter_sensitivity import NEG_CONTROL_ADAPTER, REGISTRY + assert "TwoFreqOfflineEmitter" in REGISTRY + stance = REGISTRY["TwoFreqOfflineEmitter"] + assert stance.neg_control is not None + assert stance.neg_control.kind == NEG_CONTROL_ADAPTER diff --git a/telperion/tests/test_negctrl_exp_enclosure.py b/telperion/tests/test_negctrl_exp_enclosure.py new file mode 100644 index 000000000..d170ec88e --- /dev/null +++ b/telperion/tests/test_negctrl_exp_enclosure.py @@ -0,0 +1,96 @@ +"""Negative control for ExpEnclosureEmitter -- the too-tight (hence FALSE) exp bracket. + +The emitted proof reaches its claimed bracket from `Real.exp_bound`'s exact rational Taylor +box by `linarith`. Corrupt the claim so the box no longer implies it and the proof cannot +close: the TRUSTED Lean kernel is the arbiter. The forgery here is not merely unprovable, it +is FALSE -- at `x = 1/10` the claimed `hi = 1105/1000` sits strictly BELOW `e^(1/10)` itself. + +These tests are OFFLINE (string/arithmetic level): they pin the adapter registration, the +byte-level relationship between the twins, and the registry declaration. The kernel run +happens through the generic harness in `test_certificate_sensitivity` / CI (lean-gated). + +conjecture1_proved = False. +""" +import sys +from fractions import Fraction +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +import pytest # noqa: E402 +import sympy as sp # noqa: E402 + +import telperion.negctrl_adapters # noqa: E402,F401 (registers adapters) +from telperion.emit_exp_enclosure import ( # noqa: E402 + exp_enclosure_certificate, + taylor_box, +) +from telperion.emitter_sensitivity import ( # noqa: E402 + NEG_CONTROL_ADAPTER, + REGISTRY, +) +from telperion.negative_control_harness import registered_adapters # noqa: E402 + + +def _adapter(): + ad = registered_adapters().get("ExpEnclosureEmitter") + assert ad is not None, "no adapter registered for ExpEnclosureEmitter" + return ad + + +def test_adapter_is_registered(): + _adapter() + + +def test_registry_declares_wired_adapter(): + stance = REGISTRY["ExpEnclosureEmitter"] + assert stance.neg_control is not None + assert stance.neg_control.kind == NEG_CONTROL_ADAPTER + + +def test_false_cert_is_refused_by_layer_one(): + """Layer 1 would never mint the forgery: the adapter hand-builds the frozen dataclass.""" + cert = _adapter().make_false_cert() + with pytest.raises(ValueError, match="REFUSED"): + exp_enclosure_certificate(cert.x, cert.lo, cert.hi, mode=cert.mode, n=cert.n) + + +def test_false_claim_is_genuinely_false_not_merely_unproved(): + """Pin the arithmetic: the forged hi is BELOW the order-6 Taylor lower endpoint, so + `exp (1/10) <= hi` is false -- the forgery can never rot into a hard-but-true claim.""" + cert = _adapter().make_false_cert() + box_lo, box_hi = taylor_box(cert.x, cert.n) + assert cert.hi < box_lo, (cert.hi, box_lo) + # and the true twin does contain the same box + true_cert = _adapter().make_true_cert() + assert true_cert.lo <= box_lo and box_hi <= true_cert.hi + + +def test_true_twin_is_accepted_by_layer_one(): + cert = _adapter().make_true_cert() + ok = exp_enclosure_certificate(cert.x, cert.lo, cert.hi, mode=cert.mode, n=cert.n) + assert ok.n == cert.n and ok.lo == cert.lo and ok.hi == cert.hi + + +def test_twins_differ_only_in_the_claimed_bracket(): + ad = _adapter() + false_txt = ad.emit_call(ad.make_false_cert(), "exp_twin") + true_txt = ad.emit_call(ad.make_true_cert(), "exp_twin") + # Same point, same order, same tactic script -- only the two literals move. + for line in ("have hb := Real.exp_bound hx (n := 6)", + "simp only [Finset.sum_range_succ, Finset.sum_range_zero] at hb", + "norm_num [Nat.factorial] at h1 ⊢; linarith"): + assert line in false_txt and line in true_txt + # 1105/1000 renders in lowest terms as 221/200 (rat_lean canonicalizes). + assert "(221 / 200)" in false_txt and "(221 / 200)" not in true_txt + assert "(110517 / 100000)" in true_txt and "(110517 / 100000)" not in false_txt + assert "sorry" not in false_txt and "sorry" not in true_txt + + +def test_true_twin_bracket_is_a_real_decimal_enclosure_of_e_tenth(): + """Sanity: 1.10517 <= e^(1/10) <= 1.10518 (the honest twin's claim).""" + import math + + lo, hi = Fraction(110517, 100000), Fraction(110518, 100000) + assert float(lo) <= math.exp(0.1) <= float(hi) + assert sp.Rational(1105, 1000) < sp.Rational(110517, 100000) diff --git a/telperion/tests/test_negctrl_twofreq_offline.py b/telperion/tests/test_negctrl_twofreq_offline.py new file mode 100644 index 000000000..aca9551f7 --- /dev/null +++ b/telperion/tests/test_negctrl_twofreq_offline.py @@ -0,0 +1,99 @@ +"""Negative control for TwoFreqOfflineEmitter -- the equal-modulus forgery. + +The emitted theorem NEGATES real-rootedness, and the only load-bearing arithmetic is +the EXACT inequality |c1|^2 != |c2|^2. Forge a cert whose two moduli are EQUAL (the +selfinversive_rigidity TRUE instance c1 = 3/5 + 4/5 i, c2 = 1) and the final norm_num +is asked to derive False from (1 : R) = 1: it cannot, and the kernel rejects. + +The twins are rendered in BRIDGE-HYPOTHESIS mode (the island iff carried as an explicit +hypothesis, twoFreq copied verbatim into the prelude) because the harness elaborates +against plain Mathlib -- same discipline as adapter_bragg_floor, which likewise tests +only the emitter's own arithmetic. The hypothesis-free island theorem is what the +`twofreq-offline-compiles` CI job builds. + +These tests are OFFLINE (string level); the kernel run itself is driven by the generic +harness in test_certificate_sensitivity / CI. + +conjecture1_proved = False. +""" +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) + +import telperion.negctrl_adapters # noqa: F401, E402 (registers adapters) +from telperion.emitter_sensitivity import NEG_CONTROL_ADAPTER, REGISTRY # noqa: E402 +from telperion.negative_control_harness import registered_adapters # noqa: E402 + + +def _adapter(): + ad = registered_adapters().get("TwoFreqOfflineEmitter") + assert ad is not None, "no adapter registered for TwoFreqOfflineEmitter" + return ad + + +def test_adapter_is_registered(): + _adapter() + + +def test_registry_declares_wired_adapter(): + stance = REGISTRY["TwoFreqOfflineEmitter"] + assert stance.neg_control is not None + assert stance.neg_control.kind == NEG_CONTROL_ADAPTER + + +def test_prelude_carries_twofreq_verbatim(): + ad = _adapter() + assert "def twoFreq (c₁ c₂ : ℂ) (lam₁ lam₂ : ℝ) (x : ℂ) : ℂ :=" in ad.prelude + assert "open Quasicrystal" in ad.prelude + assert ad.imports_line == "import Mathlib" + + +def test_true_twin_is_the_p2_euler_factor_and_carries_the_bridge_hypothesis(): + ad = _adapter() + txt = ad.emit_call(ad.make_true_cert(), "tfo_twin") + assert "hiff :" in txt, "bridge-hypothesis mode required (plain-Mathlib elaboration)" + assert "rw [hiff _ _ _ _ hc1 hc2 hlam]" in txt + assert "((-(1 / Real.sqrt 2) : ℝ) : ℂ)" in txt + assert "(-(Real.log 2))" in txt + # normSq 1 vs 1/2 -- the genuinely unequal moduli. + assert "= (1 : ℝ) := by" in txt and "= ((1 / 2) : ℝ) := by" in txt + assert "sorry" not in txt + + +def test_false_twin_differs_only_in_the_coefficient_and_frequency_literals(): + ad = _adapter() + true_txt = ad.emit_call(ad.make_true_cert(), "tfo_twin") + false_txt = ad.emit_call(ad.make_false_cert(), "tfo_twin") + assert true_txt != false_txt + # Same skeleton: identical theorem shape, identical bridge hypothesis, identical + # closing move. Only the literals move. + for line in ("theorem tfo_twin", "hiff :", "rw [hiff _ _ _ _ hc1 hc2 hlam]", + "intro h", "rw [hns1, hns2] at h2", "norm_num at h2"): + assert line in true_txt and line in false_txt, line + # The forged cert is the selfinversive_rigidity TRUE instance: EQUAL moduli. + assert "(3 / 5) + (4 / 5) * Complex.I" in false_txt + assert "(3 / 5) + (4 / 5) * Complex.I" not in true_txt + + +def test_false_twin_statement_is_genuinely_false(): + """Pin the arithmetic so the forgery can never rot into a merely-hard-for-norm_num + truth: |3/5 + 4/5 i|^2 = 1 = |1|^2 exactly, so by twoFreq_realRooted_iff the sum IS + real-rooted and the emitted negation is FALSE.""" + from fractions import Fraction as Fr + assert Fr(3, 5) ** 2 + Fr(4, 5) ** 2 == Fr(1) == Fr(1) ** 2 + Fr(0) ** 2 + # And the emitter's own Layer-1 self-check refuses to build it. + import pytest + + from telperion.emit_twofreq_offline import gauss, rat, twofreq_offline_certificate + with pytest.raises(ValueError, match="equal modulus"): + twofreq_offline_certificate(c1=gauss("3/5", "4/5"), c2=gauss(1, 0), + lam1=rat(1), lam2=rat(2)) + + +def test_false_twin_final_step_has_nothing_to_close_with(): + """The forged proof reaches `h2 : (1 : R) = 1` and must derive False from it.""" + ad = _adapter() + false_txt = ad.emit_call(ad.make_false_cert(), "tfo_twin") + assert "= (1 : ℝ) := by" in false_txt + assert "((1 / 2) : ℝ)" not in false_txt