From c6e9ce63d2efc6b9f4baf98cfd02be1c5fcc4f98 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:32:26 +0800 Subject: [PATCH 01/23] Add VF-1 residue-state experiment interface --- source/vf_residue_state.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 source/vf_residue_state.h diff --git a/source/vf_residue_state.h b/source/vf_residue_state.h new file mode 100644 index 0000000..b751b02 --- /dev/null +++ b/source/vf_residue_state.h @@ -0,0 +1,29 @@ +#ifndef VF_RESIDUE_STATE_H +#define VF_RESIDUE_STATE_H +#include "own_solver.h" + +typedef struct VfResidueState { + OwnU128 p; + UINT64 *q; + UINT64 *r; + UINT64 count; + UINT64 capacity; + UINT64 last_gap; + UINT64 last_correction_rounds; +} VfResidueState; + +/* Experimental verification-free residue-state generator. + No Prime Gate, Miller-Rabin, q^2>x closure, conventional next-prime routine, + factorization routine, or reference answer is consulted by these functions. + + The dimension width is deliberately finite and therefore outputs are + PROVISIONAL / UNVERIFIED. The purpose of this module is to test whether the + large integer p can be removed from the inner survivor dynamics once the + residue state r_j = p mod q_j has been initialized. */ +int vf_residue_init(VfResidueState *s, OwnU128 p, UINT64 dimension_cap); +void vf_residue_free(VfResidueState *s); +int vf_residue_next(VfResidueState *s, volatile int *cancel, + UINT64 *gap, UINT64 *correction_rounds, + OwnSolveStats *stats); + +#endif From a8440090ec42aa62f74b121aea73dbb09953ea38 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:32:49 +0800 Subject: [PATCH 02/23] Implement verification-free residue-state survivor core --- source/vf_residue_state.c | 180 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 source/vf_residue_state.c diff --git a/source/vf_residue_state.c b/source/vf_residue_state.c new file mode 100644 index 0000000..83afea1 --- /dev/null +++ b/source/vf_residue_state.c @@ -0,0 +1,180 @@ +#include "vf_residue_state.h" + +/* + VERIFICATION-FREE RESIDUE-STATE EXPERIMENT + ------------------------------------------ + Fixed-K algebraic state: + r_j(p) = p mod q_j + r_j(p + d) = (r_j(p) + d) mod q_j + + After initialization, p is not used by the nested divisibility/survivor + recursion. Only q_j, r_j and a small travelled offset d participate. + + This does NOT solve the infinite-dimension closure problem. A finite + dimension_cap can miss a later divisor, so the output is provisional. +*/ + +static void vf_zero_stats(OwnSolveStats *s) { + if(!s)return; + s->layers=0;s->dimension_count=0;s->dimensions_generated=0; + s->survivor_hops=0;s->divisibility_tests=0; +} + +static int vf_add_u64(OwnU128 a, UINT64 b, OwnU128 *out) { + OwnU128 r; + r.lo=a.lo+b; + r.hi=a.hi+(r.lo>(63-i))&1ULL; + if(r > ((~(UINT64)0)-bit)/2ULL){ + UINT64 t=r; + if(t>=q-t)t=t-(q-t);else t=t+t; + r=t+bit;if(r>=q)r-=q; + }else{ + r=(r<<1)|bit; + if(r>=q)r-=q; + } + } + return r; +} + +/* Existing integer recurrence, used only to generate q_k itself. q generation + is independent of the large successor state p. */ +static UINT64 vf_M_q(const UINT64 *q, UINT64 level, UINT64 x, + volatile int *cancel, int *ok, OwnSolveStats *stats) { + UINT64 cur,total=0,d; + if(!ok||!*ok||!q){if(ok)*ok=0;return 0;} + if(cancel&&*cancel){*ok=0;return 0;} + if(level==0){ + cur=x; + for(;;){ + if(cur==(~(UINT64)0)){*ok=0;return 0;} + cur++;total++; + if(stats)stats->divisibility_tests++; + if((cur%q[0])!=0)return total; + if(stats)stats->survivor_hops++; + } + } + cur=x; + for(;;){ + d=vf_M_q(q,level-1,cur,cancel,ok,stats); + if(!*ok)return 0; + if(d>(~(UINT64)0)-cur || d>(~(UINT64)0)-total){*ok=0;return 0;} + cur+=d;total+=d; + if(stats){stats->survivor_hops++;stats->divisibility_tests++;} + if((cur%q[level])!=0)return total; + } +} + +/* Residue-space form of M_level(p+offset). The large integer p is absent. + For fixed q[0..level] this is algebraically equivalent to the full-integer + recurrence because divisibility depends only on residues modulo q_j. */ +static UINT64 vf_M_residue(const UINT64 *q,const UINT64 *r,UINT64 level, + UINT64 offset,volatile int *cancel,int *ok, + OwnSolveStats *stats) { + UINT64 total=0,d,m; + if(!ok||!*ok||!q||!r){if(ok)*ok=0;return 0;} + if(cancel&&*cancel){*ok=0;return 0;} + if(level==0){ + for(;;){ + if(total==(~(UINT64)0)){*ok=0;return 0;} + total++; + if(stats)stats->divisibility_tests++; + m=(offset%q[0]+total%q[0])%q[0]; + if((r[0]+m)%q[0]!=0)return total; + if(stats)stats->survivor_hops++; + } + } + for(;;){ + d=vf_M_residue(q,r,level-1,offset+total,cancel,ok,stats); + if(!*ok)return 0; + if(d>(~(UINT64)0)-total){*ok=0;return 0;} + total+=d; + if(stats){stats->survivor_hops++;stats->divisibility_tests++;} + m=(offset%q[level]+total%q[level])%q[level]; + if((r[level]+m)%q[level]!=0)return total; + } +} + +static int vf_build_dimensions(VfResidueState *s, UINT64 cap) { + UINT64 k,g,next; + int ok=1; + if(!s||cap<2)return 0; + s->q[0]=2; + for(k=0;k+1q,k,s->q[k],NULL,&ok,NULL); + if(!ok || g>(~(UINT64)0)-s->q[k])return 0; + next=s->q[k]+g; + if(next<=s->q[k])return 0; + s->q[k+1]=next; + } + s->count=cap; + return 1; +} + +int vf_residue_init(VfResidueState *s, OwnU128 p, UINT64 dimension_cap) { + HANDLE heap;UINT64 i; + if(!s||dimension_cap<2||dimension_cap>1048576ULL)return 0; + s->p=p;s->q=NULL;s->r=NULL;s->count=0;s->capacity=0; + s->last_gap=0;s->last_correction_rounds=0; + heap=GetProcessHeap(); + s->q=(UINT64*)HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(UINT64))); + s->r=(UINT64*)HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(UINT64))); + if(!s->q||!s->r){vf_residue_free(s);return 0;} + s->capacity=dimension_cap; + if(!vf_build_dimensions(s,dimension_cap)){vf_residue_free(s);return 0;} + for(i=0;icount;i++)s->r[i]=vf_u128_mod_u64(p,s->q[i]); + return 1; +} + +void vf_residue_free(VfResidueState *s) { + HANDLE heap; + if(!s)return; + heap=GetProcessHeap(); + if(s->q)HeapFree(heap,0,s->q); + if(s->r)HeapFree(heap,0,s->r); + s->q=NULL;s->r=NULL;s->count=0;s->capacity=0; + s->last_gap=0;s->last_correction_rounds=0; +} + +int vf_residue_next(VfResidueState *s, volatile int *cancel, + UINT64 *gap, UINT64 *correction_rounds, + OwnSolveStats *stats) { + UINT64 off,level,d,m,i,rounds=0; + OwnU128 nextp;int ok=1; + if(!s||!s->q||!s->r||s->count<2||!gap)return 0; + vf_zero_stats(stats); + if(stats)stats->dimension_count=s->count; + + off=vf_M_residue(s->q,s->r,0,0,cancel,&ok,stats); + if(!ok)return 0; + for(level=1;levelcount;level++){ + if(cancel&&*cancel)return 0; + if(stats)stats->layers++; + for(;;){ + if(stats)stats->divisibility_tests++; + m=off%s->q[level]; + if((s->r[level]+m)%s->q[level]!=0)break; + d=vf_M_residue(s->q,s->r,level-1,off,cancel,&ok,stats); + if(!ok || d>(~(UINT64)0)-off)return 0; + off+=d;rounds++; + if(stats)stats->survivor_hops++; + } + } + + /* Translation update. All future divisibility state is updated with the + small gap only; the large p participates only in this final output add. */ + for(i=0;icount;i++)s->r[i]=(s->r[i]+(off%s->q[i]))%s->q[i]; + if(!vf_add_u64(s->p,off,&nextp))return 0; + s->p=nextp;s->last_gap=off;s->last_correction_rounds=rounds; + *gap=off;if(correction_rounds)*correction_rounds=rounds; + return 1; +} From 9d00e30d644e8c939006de4b178de88216cd0ef5 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:33:10 +0800 Subject: [PATCH 03/23] Add formal VF-1 residue-state conjecture --- docs/VF1_RESIDUE_CONJECTURE.md | 203 +++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 docs/VF1_RESIDUE_CONJECTURE.md diff --git a/docs/VF1_RESIDUE_CONJECTURE.md b/docs/VF1_RESIDUE_CONJECTURE.md new file mode 100644 index 0000000..dac2b26 --- /dev/null +++ b/docs/VF1_RESIDUE_CONJECTURE.md @@ -0,0 +1,203 @@ +# VF-1 Residue-State Conjecture + +## Status + +This document defines an experimental, verification-free successor representation. It is a conjectural research branch. It does not claim a proof of exact prime succession, constant causal depth, or asymptotic `O(1)` running time. + +The exact 64-bit generator in the main branch remains separate and retains its exact closure. The VF-1 branch deliberately removes that closure from the generation stage so that scale dependence can be studied without feeding any traditional primality or next-prime result back into the generator. + +## 1. Existing survivor hierarchy + +Let + +\[ +q_0=2. +\] + +Let the level-0 survivor distance be + +\[ +M_0(x)=\min\{d\ge 1:q_0\nmid x+d\}. +\] + +For `k >= 1`, define the lower-level survivor orbit + +\[ +y_0=x,\qquad y_{r+1}=y_r+M_{k-1}(y_r). +\] + +Then + +\[ +r_k(x)=\min\{r\ge 1:q_k\nmid y_r\}, +\] + +and + +\[ +M_k(x)=y_{r_k(x)}-x. +\] + +The dimensions are generated recursively by + +\[ +q_{k+1}=q_k+M_k(q_k). +\] + +No prime table is required as generation input. + +## 2. Residue-state transform + +For a current large state `p`, define the residue field + +\[ +\rho_j(p)=p\bmod q_j. +\] + +For any travelled offset `delta`, translation gives the exact identity + +\[ +\rho_j(p+\delta)=\bigl(\rho_j(p)+\delta\bigr)\bmod q_j. +\] + +Therefore divisibility by every active dimension can be evaluated from the residue field without repeatedly using the large integer `p`: + +\[ +q_j\mid(p+\delta) +\iff +\bigl(\rho_j(p)+\delta\bigr)\bmod q_j=0. +\] + +Define the residue survivor operator `\widetilde M_k` recursively by replacing every divisibility test in `M_k` with the translated residue test above. For a fixed finite active dimension set `q_0,...,q_K`, the branch uses + +\[ +\boxed{\widetilde M_k(\rho(p),\delta)=M_k(p+\delta)} +\] + +as an algebraic equivalence, not as a conjecture. The identity follows by induction on `k` because each recurrence step depends only on divisibility modulo the active `q_j` and on accumulated offsets. + +The large integer participates once when the initial residue field is established and once when the final gap is added to the output state. It does not participate in the inner fixed-`K` survivor recursion. + +## 3. Verification-free finite-width successor + +For a finite dimension width `K`, initialize + +\[ +\delta_0=\widetilde M_0(\rho(p),0). +\] + +For each active dimension, a hit causes a lower-level survivor jump. Define the active-hit set + +\[ +H_K(\delta)=\{j\in\{1,\ldots,K\}: (\rho_j(p)+\delta)\bmod q_j=0\}. +\] + +If `H_K(delta)` is nonempty, select the first active dimension + +\[ +j^*(\delta)=\min H_K(\delta) +\] + +and advance + +\[ +\delta'=\delta+\widetilde M_{j^*(\delta)-1}(\rho(p),\delta). +\] + +The adaptive correction count is + +\[ +R(p,K)=\min\{r:H_K(\delta_r)=\varnothing\}. +\] + +The finite-width experimental output is + +\[ +\widehat p^+_K=p+\delta_{R(p,K)}. +\] + +This output is `PROVISIONAL / UNVERIFIED`. The condition `H_K = empty` certifies only that the finite active dimension set found no hit. It does not imply that no later dimension would hit the same state. + +## 4. Chain-resident update + +Once a provisional gap `g` has been produced, the residue field advances without recomputing the large integer modulo every dimension: + +\[ +\boxed{\rho_j(p+g)=\bigl(\rho_j(p)+g\bigr)\bmod q_j.} +\] + +Thus a chain-resident state can be written as + +\[ +(\rho_0,\rho_1,\ldots,\rho_K)\xrightarrow{\mathcal V_K}g\xrightarrow{\text{translation}}(\rho'_0,\rho'_1,\ldots,\rho'_K), +\] + +while the large integer itself only receives the final addition + +\[ +p'=p+g. +\] + +This is the specific representation tested by `source/vf_residue_state.c`. + +## 5. VF-1 conjecture + +The finite-width transform does not remove the dimension-coverage problem. VF-1 is therefore stated at the level of an implicit closure operator rather than a fixed finite `K`. + +**VF-1 Conjecture.** There exists an implicit residue-state operator `I` such that, for every prime `p`, + +\[ +\boxed{\mathfrak I(\rho(p))=p_{next}-p} +\] + +without a conventional primality test, conventional next-prime routine, factorization result, candidate interval, or `q^2 > candidate` verification closure participating in generation. + +The strongest causal-depth form is + +\[ +\boxed{D_{causal}(\mathfrak I)=1.} +\] + +This is a conjecture. The current code does not prove it. In particular, a finite `dimension_cap`, a fixed GPU launch width, or a fixed recursion cap must not be presented as proof of this statement. + +## 6. Complexity separation + +The branch separates four quantities: + +\[ +L=\lceil\log_2 p\rceil +\] + +for big-integer bit width, + +\[ +K +\] + +for explicit dimension coverage, + +\[ +D_{rec} +\] + +for nested survivor recursion depth, and + +\[ +R(p,K) +\] + +for adaptive survivor correction rounds. + +The fixed-`K` residue transform removes repeated dependence of the inner recurrence on the `L`-bit integer `p`, but it does not by itself make `K`, `D_rec`, or `R` constant. Consequently `D_causal = 1` and `T_bit = O(1)` are different claims. VF-1 concerns the former only. + +## 7. Post-generation checking protocol + +Generation and checking are deliberately one-way separated: + +```text +p -> VF residue generator -> freeze candidate -> independent post-checks +``` + +A Miller-Rabin post-check may be used after the output is frozen to reject composite outputs. Such a check must not feed a witness, factor, corrected candidate, or next-prime value back into the generator. + +A Miller-Rabin pass alone does not prove that a prime output is the immediate successor. When exact successor comparison is desired experimentally, a separate reference next-prime computation may be executed after the VF output has been frozen. Its result is evaluation data, not generation input. From 042079cbad5fb63789f82cdf57616ccb93b384bc Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:33:27 +0800 Subject: [PATCH 04/23] Add VF-1 residue-state cloud benchmark --- docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md | 124 +++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md diff --git a/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md b/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md new file mode 100644 index 0000000..c86e607 --- /dev/null +++ b/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md @@ -0,0 +1,124 @@ +# VF-1 Residue-State Cloud Benchmark, 2026-08-25 + +## Purpose + +This benchmark isolates one specific claim: after a residue field `r_j = p mod q_j` has been initialized, can a fixed-width survivor recurrence stop repeatedly using the large integer `p` in its inner divisibility dynamics? + +It is not an exact-prime benchmark and is not evidence that VF-1 is proved. + +## Environment + +- Linux x86-64 cloud container +- 5 online CPUs +- Intel Xeon Platinum 8573C +- GCC 14.2.0 +- C with GMP only for arbitrary-precision benchmark state +- single-threaded benchmark code +- `-O3 -march=native` +- active dimension width: `K = 256` +- largest generated dimension at this width: `q_255 = 1619` + +The checked-in Windows application does not acquire a GMP dependency. GMP was used only in this cloud benchmark so the same experiment could be extended far beyond 128 bits. + +## Compared inner representations + +**Full-big-integer fixed-K recurrence** + +Every divisibility test operates on the current arbitrary-precision integer state. + +**Residue-state fixed-K recurrence** + +The initial state computes + +\[ +r_j=p\bmod q_j, +\] + +then all inner divisibility tests use + +\[ +(r_j+\delta)\bmod q_j. +\] + +The two implementations were required to return the same finite-width gap before timing comparisons were accepted. + +## Single-state results + +| Input scale | Residue gap | Full-big-int gap | Residue inner call | Full-big-int inner call | +|---|---:|---:|---:|---:| +| `10^100 + 267` | 4 | 4 | 1.86 us | 5.90 us | +| `10^1000 + 267` | 4 | 4 | 1.79 us | 17.92 us | +| `10^10000 + 267` | 34 | 34 | 3.33 us | 296.28 us | +| `10^100000 + 267` | 10 | 10 | 2.14 us | 1386.27 us | + +Repeated evaluation of the unchanged residue state produced approximately: + +| Input scale | Residue call latency | +|---|---:| +| `10^100` | 1.77 us | +| `10^1000` | 1.72 us | +| `10^10000` | 2.76 us | +| `10^100000` | 2.01 us | + +The gap itself changes the path length, so these values should not be interpreted as a proof of perfectly constant latency. The important observation is that increasing the large integer from roughly 333 bits to roughly 332,193 bits did not produce the growth seen when the arbitrary-precision integer remained inside every divisibility operation. + +## Initialization cost + +The large integer has not disappeared from the entire computation. Establishing the residue field still costs `K` big-integer reductions. Measured initialization time at `K=256` was approximately: + +| Input scale | Residue initialization | +|---|---:| +| `10^100` | 8.35 us | +| `10^1000` | 19.39 us | +| `10^10000` | 67.80 us | +| `10^100000` | 629.58 us | + +This cost is paid once for a chain-resident residue state. Subsequent state updates use + +\[ +r'_j=(r_j+g)\bmod q_j +\] + +and only the final externally visible integer state requires `p <- p + g`. + +## Width scaling at `10^10000` + +| K | q_max | Residue inner call | Full-big-int inner call | +|---:|---:|---:|---:| +| 256 | 1619 | 4.45 us | 407.28 us | +| 512 | 3671 | 8.33 us | 2113.09 us | +| 1024 | 8161 | 18.13 us | 5104.62 us | +| 2048 | 17863 | 22.69 us | 4823.01 us | + +The residue transform therefore attacks bit-width participation, not the dimension-coverage problem. `K` remains an explicit source of cost. + +## 128-bit equivalence check against the current experiment + +Using the repository's record anchor + +```text +p = 10^29 - 27 +``` + +and `K=256`, the residue-state C module returned + +```text +gap = 18 +``` + +matching the existing fixed-depth 128-bit survivor experiment for the same finite dimension width. This checks the intended algebraic equivalence of the two fixed-K representations; it does not make `18` the exact next-prime gap. + +## Interpretation + +The benchmark supports a narrow representation claim: + +> Once the residue field is available, the large integer can be removed from the inner fixed-width survivor divisibility loop. + +It does not establish: + +- exact next-prime generation without closure, +- bounded required dimension width, +- bounded adaptive correction rounds, +- or causal depth `1`. + +Those remain the open VF-1 questions. From da93a2247b092ddca0ceac7d0de39e2ce5c94c75 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:33:39 +0800 Subject: [PATCH 05/23] Compile VF-1 residue-state module in experimental branch --- source/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/build.sh b/source/build.sh index db8c811..039e1f5 100644 --- a/source/build.sh +++ b/source/build.sh @@ -19,6 +19,7 @@ for n in kernel32 user32 gdi32; do CFLAGS="-target x86_64-pc-windows-msvc -fshort-wchar -ffreestanding -fno-stack-protector -fno-builtin -nostdlibinc -O2" $CLANG $CFLAGS -c own_solver.c -o own_solver.obj +$CLANG $CFLAGS -c vf_residue_state.c -o vf_residue_state.obj $CLANG $CFLAGS -c gpu_solver.c -o gpu_solver.obj $CLANG $CFLAGS -c traditional.c -o traditional.obj $CLANG $CFLAGS -c main.c -o main.obj @@ -28,5 +29,5 @@ if [ -f app.res ]; then RESARG="app.res"; fi $LLD /subsystem:windows /entry:WinMainCRTStartup /machine:x64 /nodefaultlib /opt:ref /opt:icf \ /manifest:embed /manifestinput:app.manifest \ - main.obj own_solver.obj gpu_solver.obj traditional.obj $RESARG imports/kernel32.lib imports/user32.lib imports/gdi32.lib \ + main.obj own_solver.obj vf_residue_state.obj gpu_solver.obj traditional.obj $RESARG imports/kernel32.lib imports/user32.lib imports/gdi32.lib \ /out:ZeroCandidatePrime.exe From 1d43670ac69c4fdc8f6bd97909de633d202b79ab Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:34:01 +0800 Subject: [PATCH 06/23] Document VF-1 residue-state experimental branch --- README.md | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 84b4611..9fec519 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,26 @@ A longer derivation is in [`docs/ALGORITHM.md`](docs/ALGORITHM.md). **Record-seeded experiment** starts from the exact `(n, p_n)` anchor embedded in the program and uses 128-bit state with a fixed live-recursion depth cap. Values generated beyond the seed are explicitly `PROVISIONAL / UNVERIFIED`; this path is an experiment, not an asymptotic-complexity proof. +## VF-1 residue-state experimental branch + +The `vf1-residue-state` branch adds a deliberately verification-free representation for studying whether the large integer can be removed from the inner survivor dynamics after initialization. + +For every active dimension it stores + +```text +r_j = p mod q_j +``` + +and uses the exact translation identity + +```text +r_j(p + d) = (r_j(p) + d) mod q_j +``` + +inside the finite-width survivor recurrence. The large integer is therefore used to establish the initial residue field and to receive the final output addition, but is not repeatedly used by the inner divisibility recursion. + +This branch does **not** claim exact prime succession without closure. Finite dimension width can miss a later divisor, so its verification-free outputs remain `PROVISIONAL / UNVERIFIED`. The formal conjecture and the cloud benchmark are documented in [`docs/VF1_RESIDUE_CONJECTURE.md`](docs/VF1_RESIDUE_CONJECTURE.md) and [`docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md`](docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md). + ## NVIDIA path The host side loads the NVIDIA Driver API dynamically from `nvcuda.dll`. The GPU kernels are written directly in NVIDIA PTX and are embedded into the executable at build time. @@ -58,20 +78,21 @@ The host side loads the NVIDIA Driver API dynamically from `nvcuda.dll`. The GPU ## Source layout ```text -source/main.c Win32 UI, task routing, gates and result presentation -source/own_solver.c CPU implementation of the survivor recurrence -source/gpu_solver.c NVIDIA Driver API host implementation -source/gpu_kernel.ptx CUDA/PTX device implementation -source/traditional.c isolated bootstrap / validation routines -source/winmini.h minimal Win32 declarations -source/build.sh freestanding Windows x64 build +source/main.c Win32 UI, task routing, gates and result presentation +source/own_solver.c CPU implementation of the survivor recurrence +source/vf_residue_state.c verification-free finite-width residue experiment +aource/gpu_solver.c NVIDIA Driver API host implementation +source/gpu_kernel.ptx CUDA/PTX device implementation +source/traditional.c isolated bootstrap / validation routines +source/winmini.h minimal Win32 declarations +source/build.sh freestanding Windows x64 build ``` The build has no Python dependency. A small host-side C utility converts the checked-in PTX text into the C header embedded by `gpu_solver.c`. ## Scope of the claim -This repository contains an implementation and an experimental representation of the recurrence. It does **not** claim that constant sequential depth has been proved. Matrix-Free storage, GPU parallelism, and a bounded experimental recursion depth are implementation properties; an asymptotic statement about scale-independent causal depth requires a separate proof. +This repository contains an implementation and an experimental representation of the recurrence. It does **not** claim that constant sequential depth has been proved. Matrix-Free storage, GPU parallelism, a bounded experimental recursion depth, and a finite residue-state width are implementation properties; an asymptotic statement about scale-independent causal depth requires a separate proof. ## Platform From d165abcf7c1b525b0168cd9c0e722de6be867254 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:34:39 +0800 Subject: [PATCH 07/23] Add reproducible GMP residue-state benchmark --- experiments/vf1_residue_gmp.c | 187 ++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 experiments/vf1_residue_gmp.c diff --git a/experiments/vf1_residue_gmp.c b/experiments/vf1_residue_gmp.c new file mode 100644 index 0000000..d57256a --- /dev/null +++ b/experiments/vf1_residue_gmp.c @@ -0,0 +1,187 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include + +typedef unsigned long long u64; + +typedef struct QChain { + u64 *q; + size_t n; +} QChain; + +static double now_s(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC,&t); + return (double)t.tv_sec + 1e-9*(double)t.tv_nsec; +} + +static u64 M_u64(const u64 *q,size_t level,u64 x) { + if(level==0) { + u64 d=0,cur=x; + do { cur++; d++; } while(cur%q[0]==0); + return d; + } + { + u64 total=0,cur=x; + for(;;) { + u64 d=M_u64(q,level-1,cur); + cur+=d; total+=d; + if(cur%q[level]!=0) return total; + } + } +} + +static void gen_q(QChain *qc,size_t K) { + size_t k; + qc->q=(u64*)calloc(K,sizeof(u64)); + qc->n=K; + qc->q[0]=2; + for(k=0;k+1q[k+1]=qc->q[k]+M_u64(qc->q,k,qc->q[k]); +} + +static u64 M_res(const u64 *q,const u64 *r,size_t level,u64 off) { + if(level==0) { + u64 d=0; + do { d++; } while((r[0]+((off+d)%q[0]))%q[0]==0); + return d; + } + { + u64 total=0; + for(;;) { + u64 d=M_res(q,r,level-1,off+total); + total+=d; + if((r[level]+((off+total)%q[level]))%q[level]!=0) return total; + } + } +} + +static u64 next_gap_res(const u64 *q,const u64 *r,size_t K) { + size_t level; + u64 off=M_res(q,r,0,0); + for(level=1;level1?(size_t)strtoull(argv[1],0,10):256; + unsigned exponent=argc>2?(unsigned)strtoul(argv[2],0,10):100; + size_t reps=argc>3?(size_t)strtoull(argv[3],0,10):1000; + QChain qc; + mpz_t p,chainp; + u64 *r,gr,gm,checksum=0,same_checksum=0; + double t0,tq,ti,tr,tm,ts,trr; + size_t it; + + t0=now_s(); + gen_q(&qc,K); + tq=now_s()-t0; + + mpz_init(p); + make_p(p,exponent); + r=(u64*)calloc(K,sizeof(u64)); + + t0=now_s(); + init_res(r,qc.q,K,p); + ti=now_s()-t0; + + t0=now_s(); + gr=next_gap_res(qc.q,r,K); + tr=now_s()-t0; + + t0=now_s(); + gm=next_gap_mpz(qc.q,K,p); + tm=now_s()-t0; + + printf("K=%zu exp10=%u qmax=%llu gap_res=%llu gap_mpz=%llu\n", + K,exponent,qc.q[K-1],gr,gm); + printf("qgen_us=%.3f init_res_us=%.3f res_one_us=%.3f mpz_one_us=%.3f\n", + tq*1e6,ti*1e6,tr*1e6,tm*1e6); + + t0=now_s(); + for(it=0;it Date: Tue, 25 Aug 2026 01:35:12 +0800 Subject: [PATCH 08/23] Harden VF residue arithmetic and overflow handling --- source/vf_residue_state.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/source/vf_residue_state.c b/source/vf_residue_state.c index 83afea1..2d3baa4 100644 --- a/source/vf_residue_state.c +++ b/source/vf_residue_state.c @@ -28,6 +28,13 @@ static int vf_add_u64(OwnU128 a, UINT64 b, OwnU128 *out) { *out=r;return 1; } +static UINT64 vf_mod_add(UINT64 a, UINT64 b, UINT64 m) { + if(m==0)return 0; + a%=m;b%=m; + if(a>=m-b)return a-(m-b); + return a+b; +} + static UINT64 vf_u128_mod_u64(OwnU128 a, UINT64 q) { UINT64 r,i,bit; if(q==0)return 0; @@ -80,7 +87,7 @@ static UINT64 vf_M_q(const UINT64 *q, UINT64 level, UINT64 x, static UINT64 vf_M_residue(const UINT64 *q,const UINT64 *r,UINT64 level, UINT64 offset,volatile int *cancel,int *ok, OwnSolveStats *stats) { - UINT64 total=0,d,m; + UINT64 total=0,d,m,child_offset; if(!ok||!*ok||!q||!r){if(ok)*ok=0;return 0;} if(cancel&&*cancel){*ok=0;return 0;} if(level==0){ @@ -88,19 +95,21 @@ static UINT64 vf_M_residue(const UINT64 *q,const UINT64 *r,UINT64 level, if(total==(~(UINT64)0)){*ok=0;return 0;} total++; if(stats)stats->divisibility_tests++; - m=(offset%q[0]+total%q[0])%q[0]; - if((r[0]+m)%q[0]!=0)return total; + m=vf_mod_add(offset,total,q[0]); + if(vf_mod_add(r[0],m,q[0])!=0)return total; if(stats)stats->survivor_hops++; } } for(;;){ - d=vf_M_residue(q,r,level-1,offset+total,cancel,ok,stats); + if(total>(~(UINT64)0)-offset){*ok=0;return 0;} + child_offset=offset+total; + d=vf_M_residue(q,r,level-1,child_offset,cancel,ok,stats); if(!*ok)return 0; if(d>(~(UINT64)0)-total){*ok=0;return 0;} total+=d; if(stats){stats->survivor_hops++;stats->divisibility_tests++;} - m=(offset%q[level]+total%q[level])%q[level]; - if((r[level]+m)%q[level]!=0)return total; + m=vf_mod_add(offset,total,q[level]); + if(vf_mod_add(r[level],m,q[level])!=0)return total; } } @@ -162,7 +171,7 @@ int vf_residue_next(VfResidueState *s, volatile int *cancel, for(;;){ if(stats)stats->divisibility_tests++; m=off%s->q[level]; - if((s->r[level]+m)%s->q[level]!=0)break; + if(vf_mod_add(s->r[level],m,s->q[level])!=0)break; d=vf_M_residue(s->q,s->r,level-1,off,cancel,&ok,stats); if(!ok || d>(~(UINT64)0)-off)return 0; off+=d;rounds++; @@ -172,7 +181,7 @@ int vf_residue_next(VfResidueState *s, volatile int *cancel, /* Translation update. All future divisibility state is updated with the small gap only; the large p participates only in this final output add. */ - for(i=0;icount;i++)s->r[i]=(s->r[i]+(off%s->q[i]))%s->q[i]; + for(i=0;icount;i++)s->r[i]=vf_mod_add(s->r[i],off,s->q[i]); if(!vf_add_u64(s->p,off,&nextp))return 0; s->p=nextp;s->last_gap=off;s->last_correction_rounds=rounds; *gap=off;if(correction_rounds)*correction_rounds=rounds; From 97a679f15d02506d78e14d6af9cc49749ee3889b Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:35:29 +0800 Subject: [PATCH 09/23] Fix VF branch source layout and benchmark note --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9fec519..d87d084 100644 --- a/README.md +++ b/README.md @@ -78,17 +78,18 @@ The host side loads the NVIDIA Driver API dynamically from `nvcuda.dll`. The GPU ## Source layout ```text -source/main.c Win32 UI, task routing, gates and result presentation -source/own_solver.c CPU implementation of the survivor recurrence -source/vf_residue_state.c verification-free finite-width residue experiment -aource/gpu_solver.c NVIDIA Driver API host implementation -source/gpu_kernel.ptx CUDA/PTX device implementation -source/traditional.c isolated bootstrap / validation routines -source/winmini.h minimal Win32 declarations -source/build.sh freestanding Windows x64 build +source/main.c Win32 UI, task routing, gates and result presentation +source/own_solver.c CPU implementation of the survivor recurrence +source/vf_residue_state.c verification-free finite-width residue experiment +source/gpu_solver.c NVIDIA Driver API host implementation +source/gpu_kernel.ptx CUDA/PTX device implementation +source/traditional.c isolated bootstrap / validation routines +source/winmini.h minimal Win32 declarations +source/build.sh freestanding Windows x64 build +experiments/vf1_residue_gmp.c arbitrary-precision cloud benchmark mirror ``` -The build has no Python dependency. A small host-side C utility converts the checked-in PTX text into the C header embedded by `gpu_solver.c`. +The build has no Python dependency. A small host-side C utility converts the checked-in PTX text into the C header embedded by `gpu_solver.c`. The GMP benchmark is isolated under `experiments/` and is not part of the Windows application build. ## Scope of the claim From 36fb3611045703b9839cefe224be88a2542eaa45 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:36:37 +0800 Subject: [PATCH 10/23] Add explicit VF residue work stack --- source/vf_residue_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/vf_residue_state.h b/source/vf_residue_state.h index b751b02..f27fa1f 100644 --- a/source/vf_residue_state.h +++ b/source/vf_residue_state.h @@ -6,6 +6,7 @@ typedef struct VfResidueState { OwnU128 p; UINT64 *q; UINT64 *r; + void *frames; UINT64 count; UINT64 capacity; UINT64 last_gap; From aad278e0011e819ea813853a4495d9218e1e7bd9 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:37:00 +0800 Subject: [PATCH 11/23] Replace VF recursion with explicit work stack --- source/vf_residue_state.c | 205 +++++--------------------------------- 1 file changed, 26 insertions(+), 179 deletions(-) diff --git a/source/vf_residue_state.c b/source/vf_residue_state.c index 2d3baa4..7c89ad3 100644 --- a/source/vf_residue_state.c +++ b/source/vf_residue_state.c @@ -1,189 +1,36 @@ #include "vf_residue_state.h" -/* - VERIFICATION-FREE RESIDUE-STATE EXPERIMENT - ------------------------------------------ - Fixed-K algebraic state: - r_j(p) = p mod q_j - r_j(p + d) = (r_j(p) + d) mod q_j +typedef struct VfFrame { + UINT64 level; + UINT64 cur; + UINT64 total; + int waiting; +} VfFrame; - After initialization, p is not used by the nested divisibility/survivor - recursion. Only q_j, r_j and a small travelled offset d participate. +static void vf_zero_stats(OwnSolveStats *s){if(!s)return;s->layers=0;s->dimension_count=0;s->dimensions_generated=0;s->survivor_hops=0;s->divisibility_tests=0;} +static int vf_add_u64(OwnU128 a,UINT64 b,OwnU128*out){OwnU128 r;r.lo=a.lo+b;r.hi=a.hi+(r.lo=m-b)return a-(m-b);return a+b;} +static UINT64 vf_u128_mod_u64(OwnU128 a,UINT64 q){UINT64 r,i,bit;if(!q)return 0;r=a.hi%q;for(i=0;i<64;i++){bit=(a.lo>>(63-i))&1ULL;if(r>((~(UINT64)0)-bit)/2ULL){UINT64 t=r;if(t>=q-t)t=t-(q-t);else t=t+t;r=t+bit;if(r>=q)r-=q;}else{r=(r<<1)|bit;if(r>=q)r-=q;}}return r;} - This does NOT solve the infinite-dimension closure problem. A finite - dimension_cap can miss a later divisor, so the output is provisional. -*/ +static int vf_base_q(UINT64 q,UINT64 x,UINT64*out,OwnSolveStats*stats){UINT64 cur=x,total=0;if(!q||!out)return 0;for(;;){if(cur==(~(UINT64)0))return 0;cur++;total++;if(stats)stats->divisibility_tests++;if(cur%q!=0){*out=total;return 1;}if(stats)stats->survivor_hops++;}} +static int vf_base_residue(UINT64 q,UINT64 residue,UINT64 offset,UINT64*out,OwnSolveStats*stats){UINT64 d=0;if(!q||!out)return 0;for(;;){if(d==(~(UINT64)0))return 0;d++;if(stats)stats->divisibility_tests++;if(vf_mod_add(residue,vf_mod_add(offset,d,q),q)!=0){*out=d;return 1;}if(stats)stats->survivor_hops++;}} -static void vf_zero_stats(OwnSolveStats *s) { - if(!s)return; - s->layers=0;s->dimension_count=0;s->dimensions_generated=0; - s->survivor_hops=0;s->divisibility_tests=0; +/* Explicit-stack M for q-chain generation. No C call-stack growth with level. */ +static int vf_M_q(VfResidueState*s,UINT64 level,UINT64 x,volatile int*cancel,UINT64*out,OwnSolveStats*stats){ + VfFrame*f;UINT64 depth=1,ret=0;if(!s||!s->frames||level>=s->capacity||!out)return 0;f=(VfFrame*)s->frames;f[0].level=level;f[0].cur=x;f[0].total=0;f[0].waiting=0; + while(depth){VfFrame*t;if(cancel&&*cancel)return 0;t=&f[depth-1];if(t->level==0){if(!vf_base_q(s->q[0],t->cur,&ret,stats))return 0;depth--;continue;}if(!t->waiting){if(depth>=s->capacity)return 0;t->waiting=1;f[depth].level=t->level-1;f[depth].cur=t->cur;f[depth].total=0;f[depth].waiting=0;depth++;continue;}if(ret>(~(UINT64)0)-t->total||ret>(~(UINT64)0)-t->cur)return 0;t->total+=ret;t->cur+=ret;if(stats){stats->survivor_hops++;stats->divisibility_tests++;}if(t->cur%s->q[t->level]!=0){ret=t->total;depth--;}else t->waiting=0;} + *out=ret;return 1; } -static int vf_add_u64(OwnU128 a, UINT64 b, OwnU128 *out) { - OwnU128 r; - r.lo=a.lo+b; - r.hi=a.hi+(r.loframes||!s->r||level>=s->count||!out)return 0;f=(VfFrame*)s->frames;f[0].level=level;f[0].cur=offset;f[0].total=0;f[0].waiting=0; + while(depth){VfFrame*t;UINT64 m;if(cancel&&*cancel)return 0;t=&f[depth-1];if(t->level==0){if(!vf_base_residue(s->q[0],s->r[0],t->cur,&ret,stats))return 0;depth--;continue;}if(!t->waiting){if(depth>=s->capacity)return 0;t->waiting=1;f[depth].level=t->level-1;f[depth].cur=t->cur;f[depth].total=0;f[depth].waiting=0;depth++;continue;}if(ret>(~(UINT64)0)-t->total||ret>(~(UINT64)0)-t->cur)return 0;t->total+=ret;t->cur+=ret;if(stats){stats->survivor_hops++;stats->divisibility_tests++;}m=t->cur%s->q[t->level];if(vf_mod_add(s->r[t->level],m,s->q[t->level])!=0){ret=t->total;depth--;}else t->waiting=0;} + *out=ret;return 1; } -static UINT64 vf_mod_add(UINT64 a, UINT64 b, UINT64 m) { - if(m==0)return 0; - a%=m;b%=m; - if(a>=m-b)return a-(m-b); - return a+b; -} - -static UINT64 vf_u128_mod_u64(OwnU128 a, UINT64 q) { - UINT64 r,i,bit; - if(q==0)return 0; - r=a.hi%q; - for(i=0;i<64;i++){ - bit=(a.lo>>(63-i))&1ULL; - if(r > ((~(UINT64)0)-bit)/2ULL){ - UINT64 t=r; - if(t>=q-t)t=t-(q-t);else t=t+t; - r=t+bit;if(r>=q)r-=q; - }else{ - r=(r<<1)|bit; - if(r>=q)r-=q; - } - } - return r; -} - -/* Existing integer recurrence, used only to generate q_k itself. q generation - is independent of the large successor state p. */ -static UINT64 vf_M_q(const UINT64 *q, UINT64 level, UINT64 x, - volatile int *cancel, int *ok, OwnSolveStats *stats) { - UINT64 cur,total=0,d; - if(!ok||!*ok||!q){if(ok)*ok=0;return 0;} - if(cancel&&*cancel){*ok=0;return 0;} - if(level==0){ - cur=x; - for(;;){ - if(cur==(~(UINT64)0)){*ok=0;return 0;} - cur++;total++; - if(stats)stats->divisibility_tests++; - if((cur%q[0])!=0)return total; - if(stats)stats->survivor_hops++; - } - } - cur=x; - for(;;){ - d=vf_M_q(q,level-1,cur,cancel,ok,stats); - if(!*ok)return 0; - if(d>(~(UINT64)0)-cur || d>(~(UINT64)0)-total){*ok=0;return 0;} - cur+=d;total+=d; - if(stats){stats->survivor_hops++;stats->divisibility_tests++;} - if((cur%q[level])!=0)return total; - } -} - -/* Residue-space form of M_level(p+offset). The large integer p is absent. - For fixed q[0..level] this is algebraically equivalent to the full-integer - recurrence because divisibility depends only on residues modulo q_j. */ -static UINT64 vf_M_residue(const UINT64 *q,const UINT64 *r,UINT64 level, - UINT64 offset,volatile int *cancel,int *ok, - OwnSolveStats *stats) { - UINT64 total=0,d,m,child_offset; - if(!ok||!*ok||!q||!r){if(ok)*ok=0;return 0;} - if(cancel&&*cancel){*ok=0;return 0;} - if(level==0){ - for(;;){ - if(total==(~(UINT64)0)){*ok=0;return 0;} - total++; - if(stats)stats->divisibility_tests++; - m=vf_mod_add(offset,total,q[0]); - if(vf_mod_add(r[0],m,q[0])!=0)return total; - if(stats)stats->survivor_hops++; - } - } - for(;;){ - if(total>(~(UINT64)0)-offset){*ok=0;return 0;} - child_offset=offset+total; - d=vf_M_residue(q,r,level-1,child_offset,cancel,ok,stats); - if(!*ok)return 0; - if(d>(~(UINT64)0)-total){*ok=0;return 0;} - total+=d; - if(stats){stats->survivor_hops++;stats->divisibility_tests++;} - m=vf_mod_add(offset,total,q[level]); - if(vf_mod_add(r[level],m,q[level])!=0)return total; - } -} - -static int vf_build_dimensions(VfResidueState *s, UINT64 cap) { - UINT64 k,g,next; - int ok=1; - if(!s||cap<2)return 0; - s->q[0]=2; - for(k=0;k+1q,k,s->q[k],NULL,&ok,NULL); - if(!ok || g>(~(UINT64)0)-s->q[k])return 0; - next=s->q[k]+g; - if(next<=s->q[k])return 0; - s->q[k+1]=next; - } - s->count=cap; - return 1; -} - -int vf_residue_init(VfResidueState *s, OwnU128 p, UINT64 dimension_cap) { - HANDLE heap;UINT64 i; - if(!s||dimension_cap<2||dimension_cap>1048576ULL)return 0; - s->p=p;s->q=NULL;s->r=NULL;s->count=0;s->capacity=0; - s->last_gap=0;s->last_correction_rounds=0; - heap=GetProcessHeap(); - s->q=(UINT64*)HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(UINT64))); - s->r=(UINT64*)HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(UINT64))); - if(!s->q||!s->r){vf_residue_free(s);return 0;} - s->capacity=dimension_cap; - if(!vf_build_dimensions(s,dimension_cap)){vf_residue_free(s);return 0;} - for(i=0;icount;i++)s->r[i]=vf_u128_mod_u64(p,s->q[i]); - return 1; -} - -void vf_residue_free(VfResidueState *s) { - HANDLE heap; - if(!s)return; - heap=GetProcessHeap(); - if(s->q)HeapFree(heap,0,s->q); - if(s->r)HeapFree(heap,0,s->r); - s->q=NULL;s->r=NULL;s->count=0;s->capacity=0; - s->last_gap=0;s->last_correction_rounds=0; -} - -int vf_residue_next(VfResidueState *s, volatile int *cancel, - UINT64 *gap, UINT64 *correction_rounds, - OwnSolveStats *stats) { - UINT64 off,level,d,m,i,rounds=0; - OwnU128 nextp;int ok=1; - if(!s||!s->q||!s->r||s->count<2||!gap)return 0; - vf_zero_stats(stats); - if(stats)stats->dimension_count=s->count; +static int vf_build_dimensions(VfResidueState*s,UINT64 cap){UINT64 k,g,next;if(!s||cap<2)return 0;s->q[0]=2;for(k=0;k+1count=k+1;if(!vf_M_q(s,k,s->q[k],NULL,&g,NULL))return 0;if(g>(~(UINT64)0)-s->q[k])return 0;next=s->q[k]+g;if(next<=s->q[k])return 0;s->q[k+1]=next;}s->count=cap;return 1;} - off=vf_M_residue(s->q,s->r,0,0,cancel,&ok,stats); - if(!ok)return 0; - for(level=1;levelcount;level++){ - if(cancel&&*cancel)return 0; - if(stats)stats->layers++; - for(;;){ - if(stats)stats->divisibility_tests++; - m=off%s->q[level]; - if(vf_mod_add(s->r[level],m,s->q[level])!=0)break; - d=vf_M_residue(s->q,s->r,level-1,off,cancel,&ok,stats); - if(!ok || d>(~(UINT64)0)-off)return 0; - off+=d;rounds++; - if(stats)stats->survivor_hops++; - } - } - - /* Translation update. All future divisibility state is updated with the - small gap only; the large p participates only in this final output add. */ - for(i=0;icount;i++)s->r[i]=vf_mod_add(s->r[i],off,s->q[i]); - if(!vf_add_u64(s->p,off,&nextp))return 0; - s->p=nextp;s->last_gap=off;s->last_correction_rounds=rounds; - *gap=off;if(correction_rounds)*correction_rounds=rounds; - return 1; -} +int vf_residue_init(VfResidueState*s,OwnU128 p,UINT64 dimension_cap){HANDLE heap;UINT64 i;if(!s||dimension_cap<2||dimension_cap>1048576ULL)return 0;s->p=p;s->q=NULL;s->r=NULL;s->frames=NULL;s->count=0;s->capacity=0;s->last_gap=0;s->last_correction_rounds=0;heap=GetProcessHeap();s->q=(UINT64*)HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(UINT64)));s->r=(UINT64*)HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(UINT64)));s->frames=HeapAlloc(heap,HEAP_ZERO_MEMORY,(UINT_PTR)(dimension_cap*sizeof(VfFrame)));if(!s->q||!s->r||!s->frames){vf_residue_free(s);return 0;}s->capacity=dimension_cap;if(!vf_build_dimensions(s,dimension_cap)){vf_residue_free(s);return 0;}for(i=0;icount;i++)s->r[i]=vf_u128_mod_u64(p,s->q[i]);return 1;} +void vf_residue_free(VfResidueState*s){HANDLE heap;if(!s)return;heap=GetProcessHeap();if(s->q)HeapFree(heap,0,s->q);if(s->r)HeapFree(heap,0,s->r);if(s->frames)HeapFree(heap,0,s->frames);s->q=NULL;s->r=NULL;s->frames=NULL;s->count=0;s->capacity=0;s->last_gap=0;s->last_correction_rounds=0;} +int vf_residue_next(VfResidueState*s,volatile int*cancel,UINT64*gap,UINT64*correction_rounds,OwnSolveStats*stats){UINT64 off,level,d,m,i,rounds=0;OwnU128 nextp;if(!s||!s->q||!s->r||!s->frames||s->count<2||!gap)return 0;vf_zero_stats(stats);if(stats)stats->dimension_count=s->count;if(!vf_M_residue(s,0,0,cancel,&off,stats))return 0;for(level=1;levelcount;level++){if(cancel&&*cancel)return 0;if(stats)stats->layers++;for(;;){if(stats)stats->divisibility_tests++;m=off%s->q[level];if(vf_mod_add(s->r[level],m,s->q[level])!=0)break;if(!vf_M_residue(s,level-1,off,cancel,&d,stats))return 0;if(d>(~(UINT64)0)-off)return 0;off+=d;rounds++;if(stats)stats->survivor_hops++;}}for(i=0;icount;i++)s->r[i]=vf_mod_add(s->r[i],off,s->q[i]);if(!vf_add_u64(s->p,off,&nextp))return 0;s->p=nextp;s->last_gap=off;s->last_correction_rounds=rounds;*gap=off;if(correction_rounds)*correction_rounds=rounds;return 1;} From bf498741e70b6f8aefedd9a75e6a9a59756b84ef Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:37:38 +0800 Subject: [PATCH 12/23] Extend VF residue benchmark to million-digit scale --- docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md b/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md index c86e607..378ce72 100644 --- a/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md +++ b/docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md @@ -50,6 +50,7 @@ The two implementations were required to return the same finite-width gap before | `10^1000 + 267` | 4 | 4 | 1.79 us | 17.92 us | | `10^10000 + 267` | 34 | 34 | 3.33 us | 296.28 us | | `10^100000 + 267` | 10 | 10 | 2.14 us | 1386.27 us | +| `10^1000000 + 267` | 12 | 12 | 3.31 us | 36422.87 us | Repeated evaluation of the unchanged residue state produced approximately: @@ -59,8 +60,9 @@ Repeated evaluation of the unchanged residue state produced approximately: | `10^1000` | 1.72 us | | `10^10000` | 2.76 us | | `10^100000` | 2.01 us | +| `10^1000000` | 2.86 us | -The gap itself changes the path length, so these values should not be interpreted as a proof of perfectly constant latency. The important observation is that increasing the large integer from roughly 333 bits to roughly 332,193 bits did not produce the growth seen when the arbitrary-precision integer remained inside every divisibility operation. +The gap itself changes the path length, so these values should not be interpreted as a proof of perfectly constant latency. The important observation is that increasing the large integer from roughly 333 bits to roughly 3.32 million bits did not produce the growth seen when the arbitrary-precision integer remained inside every divisibility operation. ## Initialization cost @@ -72,6 +74,7 @@ The large integer has not disappeared from the entire computation. Establishing | `10^1000` | 19.39 us | | `10^10000` | 67.80 us | | `10^100000` | 629.58 us | +| `10^1000000` | 5947.17 us | This cost is paid once for a chain-resident residue state. Subsequent state updates use @@ -106,7 +109,9 @@ and `K=256`, the residue-state C module returned gap = 18 ``` -matching the existing fixed-depth 128-bit survivor experiment for the same finite dimension width. This checks the intended algebraic equivalence of the two fixed-K representations; it does not make `18` the exact next-prime gap. +matching the existing fixed-depth 128-bit survivor experiment for the same finite dimension width. The repository implementation was additionally rewritten to use an explicit work stack rather than C recursion and still returned `gap = 18`, `q_max = 1619` for this check. + +This checks the intended algebraic equivalence of the two fixed-K representations; it does not make `18` the exact next-prime gap. ## Interpretation @@ -114,6 +119,8 @@ The benchmark supports a narrow representation claim: > Once the residue field is available, the large integer can be removed from the inner fixed-width survivor divisibility loop. +At `K=256`, the full-big-integer inner call grew from about 5.90 us near `10^100` to about 36.4 ms near `10^1000000`, while the residue-only inner call remained in the low-single-digit microsecond range for these tested states. Initialization still scales with bit width and explicit dimension width. + It does not establish: - exact next-prime generation without closure, From a790ed0ad22de7cb27c41cc29f72a38d7bf610b2 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:54:16 +0800 Subject: [PATCH 13/23] Add finite-K K/R collapse diagnostic --- experiments/vf1_kr_primorial_diagnostic.c | 196 ++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 experiments/vf1_kr_primorial_diagnostic.c diff --git a/experiments/vf1_kr_primorial_diagnostic.c b/experiments/vf1_kr_primorial_diagnostic.c new file mode 100644 index 0000000..cf57c3a --- /dev/null +++ b/experiments/vf1_kr_primorial_diagnostic.c @@ -0,0 +1,196 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include + +/* + DIAGNOSTIC ONLY. DO NOT LINK INTO THE GENERATOR. + + This file studies an exact finite-K algebraic compression of the survivor + state. The prime fixture below intentionally uses a conventional sieve only + to isolate the K/R representation experiment. It is not generation input for + ZeroCandidatePrime and is not part of the Windows build. + + P_K = product_{j < K} q_j + z = p mod P_K + + For fixed finite K: + + exists j < K : q_j divides p+d + iff gcd(z+d, P_K) > 1 + + Therefore the finite-width survivor gap can be written as the scalar map + + J_K(z) = min { d >= 1 : gcd(z+d, P_K) = 1 }. + + This collapses K and the nested correction sequence algebraically, but the + reference evaluator below still advances d one value at a time. Therefore it + is NOT a successful zero-candidate implementation and must remain diagnostic. +*/ + +typedef uint64_t u64; + +static double now_s(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (double)t.tv_sec + 1e-9 * (double)t.tv_nsec; +} + +static size_t estimate_nth_bound(size_t k) { + double n, b; + if (k < 6) return 16; + n = (double)k; + b = n * (log(n) + log(log(n))) + 32.0; + return (size_t)b + 1; +} + +/* Traditional fixture generation for this isolated diagnostic only. */ +static int first_k_primes(size_t k, u64 **out) { + size_t bound, i, j, n; + unsigned char *composite; + u64 *q; + if (k == 0 || !out) return 0; + bound = estimate_nth_bound(k); + for (;;) { + composite = (unsigned char *)calloc(bound + 1, 1); + q = (u64 *)malloc(k * sizeof(u64)); + if (!composite || !q) { + free(composite); + free(q); + return 0; + } + n = 0; + for (i = 2; i <= bound && n < k; ++i) { + if (!composite[i]) { + q[n++] = (u64)i; + if (i <= bound / i) { + for (j = i * i; j <= bound; j += i) composite[j] = 1; + } + } + } + free(composite); + if (n == k) { + *out = q; + return 1; + } + free(q); + bound *= 2; + } +} + +/* Balanced product construction. This changes construction depth from a long + left-associated multiply chain to a binary product tree. */ +static void product_tree(mpz_t out, const u64 *q, size_t lo, size_t hi) { + size_t mid; + mpz_t a, b; + if (hi - lo == 1) { + mpz_set_ui(out, (unsigned long)q[lo]); + return; + } + mid = lo + (hi - lo) / 2; + mpz_inits(a, b, NULL); + product_tree(a, q, lo, mid); + product_tree(b, q, mid, hi); + mpz_mul(out, a, b); + mpz_clears(a, b, NULL); +} + +/* Vector reference for the same finite K. It verifies the algebraic collapse; + it is not a production path. */ +static u64 vector_gap(const u64 *q, size_t k, const mpz_t p, u64 max_d) { + size_t j; + u64 d, m; + u64 *r = (u64 *)malloc(k * sizeof(u64)); + if (!r) return 0; + for (j = 0; j < k; ++j) r[j] = (u64)mpz_fdiv_ui(p, (unsigned long)q[j]); + for (d = 1; d <= max_d; ++d) { + int clean = 1; + for (j = 0; j < k; ++j) { + m = (r[j] + (d % q[j])) % q[j]; + if (m == 0) { + clean = 0; + break; + } + } + if (clean) { + free(r); + return d; + } + } + free(r); + return 0; +} + +/* Scalar evaluator of J_K. The d loop is intentionally visible so that an + algebraic collapse cannot be mistaken for a causal-depth-1 implementation. */ +static u64 collapsed_gcd_gap(const mpz_t primorial, const mpz_t z, + u64 max_d, u64 *gcd_calls) { + u64 d; + mpz_t x, g; + mpz_inits(x, g, NULL); + for (d = 1; d <= max_d; ++d) { + mpz_add_ui(x, z, (unsigned long)d); + if (mpz_cmp(x, primorial) >= 0) mpz_mod(x, x, primorial); + mpz_gcd(g, x, primorial); + ++(*gcd_calls); + if (mpz_cmp_ui(g, 1) == 0) { + mpz_clears(x, g, NULL); + return d; + } + } + mpz_clears(x, g, NULL); + return 0; +} + +int main(int argc, char **argv) { + size_t k = argc > 1 ? (size_t)strtoull(argv[1], NULL, 10) : 256; + unsigned exponent = argc > 2 ? (unsigned)strtoul(argv[2], NULL, 10) : 100; + u64 max_d = argc > 3 ? (u64)strtoull(argv[3], NULL, 10) : 4096; + u64 *q = NULL, g_collapsed, g_vector, gcd_calls = 0; + double t0, t_fixture, t_product, t_residue, t_collapsed, t_vector; + mpz_t p, primorial, z; + + if (k == 0) return 2; + mpz_inits(p, primorial, z, NULL); + mpz_ui_pow_ui(p, 10, exponent); + mpz_add_ui(p, p, 267); + + t0 = now_s(); + if (!first_k_primes(k, &q)) return 3; + t_fixture = now_s() - t0; + + t0 = now_s(); + product_tree(primorial, q, 0, k); + t_product = now_s() - t0; + + t0 = now_s(); + mpz_mod(z, p, primorial); + t_residue = now_s() - t0; + + t0 = now_s(); + g_collapsed = collapsed_gcd_gap(primorial, z, max_d, &gcd_calls); + t_collapsed = now_s() - t0; + + t0 = now_s(); + g_vector = vector_gap(q, k, p, max_d); + t_vector = now_s() - t0; + + printf("K=%zu qmax=%llu exp10=%u P_bits=%zu P_digits=%zu\n", + k, (unsigned long long)q[k - 1], exponent, + mpz_sizeinbase(primorial, 2), mpz_sizeinbase(primorial, 10)); + printf("collapsed_gap=%llu vector_gap=%llu gcd_calls=%llu equal=%s\n", + (unsigned long long)g_collapsed, + (unsigned long long)g_vector, + (unsigned long long)gcd_calls, + g_collapsed == g_vector ? "yes" : "NO"); + printf("fixture_ms=%.3f product_ms=%.3f residue_us=%.3f collapsed_ms=%.3f vector_ms=%.3f\n", + t_fixture * 1e3, t_product * 1e3, t_residue * 1e6, + t_collapsed * 1e3, t_vector * 1e3); + + free(q); + mpz_clears(p, primorial, z, NULL); + return g_collapsed == g_vector ? 0 : 4; +} From 5a16d72a5581b8f68aa07be473f455d3d2d5798c Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 01:54:52 +0800 Subject: [PATCH 14/23] Document K and R collapse attempt --- docs/VF1_KR_COLLAPSE_ATTEMPT.md | 205 ++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 docs/VF1_KR_COLLAPSE_ATTEMPT.md diff --git a/docs/VF1_KR_COLLAPSE_ATTEMPT.md b/docs/VF1_KR_COLLAPSE_ATTEMPT.md new file mode 100644 index 0000000..7ab476a --- /dev/null +++ b/docs/VF1_KR_COLLAPSE_ATTEMPT.md @@ -0,0 +1,205 @@ +# VF-1 K/R Collapse Attempt + +## Status + +This note records a finite-width algebraic collapse experiment. It is not a proof of VF-1 and it is not a production generator path. + +The experiment asks whether the two explicit axes + +- dimension coverage `K`, and +- survivor correction rounds `R` + +can be compressed into a single finite-width state operator without changing the finite-K survivor result. + +## 1. Exact finite-K compression + +For active dimensions + +\[ +q_0,q_1,\ldots,q_{K-1}, +\] + +define the square-free product + +\[ +P_K=\prod_{j=0}^{K-1}q_j +\] + +and the compressed residue + +\[ +z_K=p\bmod P_K. +\] + +Because the active dimensions are pairwise coprime primes, + +\[ +\exists j1. +\] + +Therefore the same finite-width survivor gap can be written as + +\[ +\boxed{ +J_K(z_K)=\min\{d\ge1:\gcd(z_K+d,P_K)=1\}. +} +\] + +This is an exact algebraic compression for fixed finite `K`. All active divisibility dimensions are represented by one product residue, and the nested survivor corrections are represented by one next-coprime map `J_K`. + +The identity is not the open conjecture. It is simply another representation of the same finite-width survivor set. + +## 2. What has actually collapsed + +At the representation level, + +\[ +(\rho_0,\rho_1,\ldots,\rho_{K-1}) +\] + +is replaced by + +\[ +z_K=p\bmod P_K. +\] + +A single gcd then answers whether a particular offset is hit by any active dimension. This removes the explicit `for j = 0..K-1` divisibility scan from that test. + +Likewise, the complete finite-K result can be named by the scalar operator `J_K` instead of exposing the original correction sequence. + +This is a useful collapse of the mathematical state graph, but it is not yet a causal-depth-1 implementation. + +## 3. Why R has not been computationally eliminated + +The diagnostic evaluator of `J_K` deliberately uses + +```text +for d = 1, 2, 3, ...: + if gcd(z_K + d, P_K) == 1: + return d +``` + +so the hidden minimization is visible. + +That loop is a candidate-offset search. It violates the ZeroCandidatePrime generation contract and therefore remains diagnostic only. + +A precomputed wheel table could make `J_K(z_K)` a direct lookup, but its period is `P_K`; the state size grows catastrophically and it would also violate the no-table direction of the project. + +A fully parallel batch of offsets could remove the sequential `R` dependency in an idealized machine model, but it would materialize a candidate domain and is therefore rejected for the same reason. + +The unresolved target is consequently stronger: + +\[ +\boxed{ +\text{find a compact evaluator of }J_K +\text{ that neither searches }d +\text{ nor stores the period }P_K. +} +\] + +## 4. Cloud experiment at the 10^100 scale + +Input: + +\[ +p=10^{100}+267. +\] + +The traditional prime fixture used by this isolated diagnostic is outside the generator and is used only to construct the finite-K comparison state. No result from the fixture is fed into the production recurrence. + +Single-threaded C + GMP measurements: + +| K | largest q | digits in P_K | collapsed finite-K gap | vector finite-K gap | gcd calls | +|---:|---:|---:|---:|---:|---:| +| 256 | 1,619 | 690 | 4 | 4 | 4 | +| 2,048 | 17,863 | 7,687 | 4 | 4 | 4 | +| 88,232 | 1,134,719 | 492,313 | 6 | 6 | 6 | +| 175,692 | 2,391,019 | 1,037,651 | 22 | 22 | 22 | + +The collapsed gcd representation and the explicit finite-K residue-vector reference agreed in every tested row. + +Measured wall-clock values on the cloud CPU were approximately: + +| K | product-tree build | collapsed evaluator | explicit vector evaluator | +|---:|---:|---:|---:| +| 256 | 0.016 ms | 0.020 ms | 0.009 ms | +| 2,048 | 0.136 ms | 0.032 ms | 0.085 ms | +| 88,232 | 15.689 ms | 1.767 ms | 2.460 ms | +| 175,692 | 44.426 ms | 12.870 ms | 5.535 ms | + +These times are diagnostic CPU numbers, not NVIDIA/PTX results. + +## 5. Exact-successor comparison remains negative + +After the generation result is frozen, an independent reference computation gives the immediate successor gap for this input as + +\[ +682. +\] + +Therefore even the `K = 175,692` compressed state still returns only + +\[ +22, +\] + +not the exact successor gap. + +A separate coverage diagnostic found that after all prime dimensions through `100,000,000` were considered, twenty offsets below `682` still had no divisor in that covered range; the first uncovered offset was still `22`. + +This is strong evidence that the difficult part is not merely the linear scan over the first few hundred thousand dimensions. Some composite states in the interval can hide their first active divisor far beyond that range. + +## 6. Asymptotic cost moved into P_K + +The product compression does not make dimension information disappear. It moves it into the bit width of `P_K`. + +By the prime number theorem for the Chebyshev function, + +\[ +\log P_K=\vartheta(q_{K-1})\sim q_{K-1}. +\] + +So an explicit primorial is not a constant-size representation as `K` grows. + +This means the current attempt achieves + +\[ +\boxed{K\text{-scan collapse}} +\] + +but not + +\[ +\boxed{K\text{-information collapse}}. +\] + +Likewise `J_K` achieves an algebraic naming of the full correction closure, but the available evaluator still exposes sequential offset work, so it is not an implementation-level `R=1` result. + +## 7. Result of this attempt + +The experiment found an exact finite-width identity: + +\[ +\boxed{ +J_K(p\bmod P_K) +=\text{the original finite-K survivor gap}. +} +\] + +That identity genuinely merges the explicit `K` dimension vector and the explicit nested correction trajectory into one scalar state map. + +However, every straightforward evaluator found so far leaks the hidden complexity back out in one of three forms: + +1. iterate offsets, which restores `R` and violates the no-candidate requirement; +2. store a wheel/lookup over `P_K`, which causes state explosion and violates the no-table direction; +3. expand the prime factors or the primorial construction, which restores `K`-dependent work. + +Therefore this attempt is retained as a structural reduction and a negative engineering result, not as VF-1 success. + +The next valid target is a non-table, non-candidate, non-factor-expansion evaluator for the compressed next-coprime map, or an alternative representation that avoids the primorial state entirely. From b1c99f66fbb5d34517e65fbb65c096cc87393b35 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:09:22 +0800 Subject: [PATCH 15/23] Add event-staircase jump diagnostic --- experiments/vf1_event_staircase_gmp.c | 296 ++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 experiments/vf1_event_staircase_gmp.c diff --git a/experiments/vf1_event_staircase_gmp.c b/experiments/vf1_event_staircase_gmp.c new file mode 100644 index 0000000..db44470 --- /dev/null +++ b/experiments/vf1_event_staircase_gmp.c @@ -0,0 +1,296 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include + +typedef uint32_t u32; +typedef uint64_t u64; + +typedef struct PrimeBlock { + size_t lo, hi; /* [lo, hi) indices in the diagnostic prime fixture */ + mpz_t product; +} PrimeBlock; + +static double now_s(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (double)t.tv_sec + 1e-9 * (double)t.tv_nsec; +} + +/* DIAGNOSTIC ONLY. This conventional sieve is intentionally outside the + generator. It exists to measure the staircase/event structure after the + mathematical recurrence has been specified. */ +static u32 *make_primes(u32 limit, size_t *count_out) { + unsigned char *composite; + u32 *primes; + size_t cap = 1024, n = 0; + u32 i; + + composite = (unsigned char *)calloc((size_t)limit + 1, 1); + primes = (u32 *)malloc(cap * sizeof(u32)); + if (!composite || !primes) { + free(composite); + free(primes); + return NULL; + } + + for (i = 2; i <= limit; ++i) { + if (!composite[i]) { + if (n == cap) { + u32 *grown; + cap *= 2; + grown = (u32 *)realloc(primes, cap * sizeof(u32)); + if (!grown) { + free(composite); + free(primes); + return NULL; + } + primes = grown; + } + primes[n++] = i; + if ((u64)i * (u64)i <= (u64)limit) { + u64 j; + for (j = (u64)i * (u64)i; j <= (u64)limit; j += i) + composite[(size_t)j] = 1; + } + } + } + + free(composite); + *count_out = n; + return primes; +} + +static PrimeBlock *make_blocks(const u32 *primes, size_t n, size_t block_size, + size_t *block_count_out) { + size_t block_count = (n + block_size - 1) / block_size; + PrimeBlock *blocks = (PrimeBlock *)calloc(block_count, sizeof(*blocks)); + size_t b, i; + + if (!blocks) + return NULL; + + for (b = 0; b < block_count; ++b) { + blocks[b].lo = b * block_size; + blocks[b].hi = (b + 1) * block_size; + if (blocks[b].hi > n) + blocks[b].hi = n; + mpz_init_set_ui(blocks[b].product, 1); + for (i = blocks[b].lo; i < blocks[b].hi; ++i) + mpz_mul_ui(blocks[b].product, blocks[b].product, primes[i]); + } + + *block_count_out = block_count; + return blocks; +} + +static void free_blocks(PrimeBlock *blocks, size_t block_count) { + size_t b; + if (!blocks) + return; + for (b = 0; b < block_count; ++b) + mpz_clear(blocks[b].product); + free(blocks); +} + +static int survives_width(const u32 *primes, const u32 *residue, + size_t width, u64 d, u64 *tests) { + size_t i; + for (i = 0; i < width; ++i) { + if (tests) + ++*tests; + if (((u64)residue[i] + (d % primes[i])) % primes[i] == 0) + return 0; + } + return 1; +} + +static u64 next_gap_after(const u32 *primes, const u32 *residue, + size_t width, u64 after, u64 *tests) { + u64 d = after; + for (;;) { + ++d; + if (survives_width(primes, residue, width, d, tests)) + return d; + } +} + +/* Find the first diagnostic dimension >= start that divides candidate. + + Full aligned blocks are rejected with one gcd(candidate, block_product). + A hit block is then resolved locally. This demonstrates plateau skipping, + but it is NOT an admissible VF-1 generator primitive: the block products are + built from a conventional prime fixture and the gcd result is a batched + factor-location oracle. The final project must not disguise this diagnostic + as verification-free generation. */ +static size_t next_collision(const u32 *primes, size_t prime_count, + const PrimeBlock *blocks, size_t block_count, + size_t block_size, size_t start, + const mpz_t candidate, + u64 *block_gcd_tests, u64 *local_prime_tests) { + size_t i = start; + mpz_t g; + mpz_init(g); + + while (i < prime_count && (i % block_size) != 0) { + if (local_prime_tests) + ++*local_prime_tests; + if (mpz_divisible_ui_p(candidate, primes[i])) { + mpz_clear(g); + return i; + } + ++i; + } + + while (i < prime_count) { + size_t b = i / block_size; + size_t j; + + if (b >= block_count) + break; + + if (blocks[b].lo != i || blocks[b].hi - blocks[b].lo < block_size) { + for (j = i; j < blocks[b].hi; ++j) { + if (local_prime_tests) + ++*local_prime_tests; + if (mpz_divisible_ui_p(candidate, primes[j])) { + mpz_clear(g); + return j; + } + } + i = blocks[b].hi; + continue; + } + + if (block_gcd_tests) + ++*block_gcd_tests; + mpz_gcd(g, candidate, blocks[b].product); + if (mpz_cmp_ui(g, 1) != 0) { + for (j = blocks[b].lo; j < blocks[b].hi; ++j) { + if (local_prime_tests) + ++*local_prime_tests; + if (mpz_divisible_ui_p(candidate, primes[j])) { + mpz_clear(g); + return j; + } + } + } + i = blocks[b].hi; + } + + mpz_clear(g); + return prime_count; +} + +int main(int argc, char **argv) { + unsigned exponent = argc > 1 ? (unsigned)strtoul(argv[1], NULL, 10) : 100; + u32 prime_limit = argc > 2 ? (u32)strtoul(argv[2], NULL, 10) : 3000000U; + size_t block_size = argc > 3 ? (size_t)strtoull(argv[3], NULL, 10) : 512; + unsigned add = argc > 4 ? (unsigned)strtoul(argv[4], NULL, 10) : 267; + + size_t prime_count = 0, block_count = 0, width = 1, events = 0; + size_t previous_width = 1; + u32 *primes, *residue; + PrimeBlock *blocks; + mpz_t p, candidate; + u64 gap; + u64 block_gcd_tests = 0, local_prime_tests = 0, survivor_tests = 0; + double t0, sieve_s, blocks_s, residue_s, run_s; + int postcheck; + + t0 = now_s(); + primes = make_primes(prime_limit, &prime_count); + sieve_s = now_s() - t0; + if (!primes || prime_count == 0) { + fprintf(stderr, "diagnostic prime fixture failed\n"); + return 2; + } + + t0 = now_s(); + blocks = make_blocks(primes, prime_count, block_size, &block_count); + blocks_s = now_s() - t0; + if (!blocks) { + free(primes); + return 2; + } + + mpz_init(p); + mpz_init(candidate); + mpz_ui_pow_ui(p, 10, exponent); + mpz_add_ui(p, p, add); + + residue = (u32 *)malloc(prime_count * sizeof(u32)); + if (!residue) { + free_blocks(blocks, block_count); + free(primes); + mpz_clear(candidate); + mpz_clear(p); + return 2; + } + + t0 = now_s(); + { + size_t i; + for (i = 0; i < prime_count; ++i) + residue[i] = (u32)mpz_fdiv_ui(p, primes[i]); + } + residue_s = now_s() - t0; + + gap = next_gap_after(primes, residue, width, 0, &survivor_tests); + printf("p=10^%u+%u prime_limit=%u primes=%zu block_size=%zu\n", + exponent, add, prime_limit, prime_count, block_size); + printf("initial K=%zu qmax=%u gap=%llu\n", + width, primes[width - 1], (unsigned long long)gap); + + t0 = now_s(); + for (;;) { + size_t j; + u64 old_gap; + + mpz_set(candidate, p); + mpz_add_ui(candidate, candidate, gap); + + j = next_collision(primes, prime_count, blocks, block_count, + block_size, width, candidate, + &block_gcd_tests, &local_prime_tests); + if (j == prime_count) + break; + + old_gap = gap; + previous_width = width; + width = j + 1; + gap = next_gap_after(primes, residue, width, old_gap, &survivor_tests); + ++events; + + printf("event=%zu K=%zu q=%u gap:%llu->%llu plateau_dimensions=%zu\n", + events, width, primes[j], + (unsigned long long)old_gap, + (unsigned long long)gap, + j - previous_width); + } + run_s = now_s() - t0; + + mpz_set(candidate, p); + mpz_add_ui(candidate, candidate, gap); + postcheck = mpz_probab_prime_p(candidate, 25); /* post-hoc only */ + + printf("final_within_limit K=%zu qmax=%u gap=%llu postcheck=%s\n", + width, primes[width - 1], (unsigned long long)gap, + postcheck ? "probable-prime" : "composite"); + printf("event_count=%zu block_gcd_tests=%llu local_prime_tests=%llu survivor_tests=%llu\n", + events, + (unsigned long long)block_gcd_tests, + (unsigned long long)local_prime_tests, + (unsigned long long)survivor_tests); + printf("sieve_ms=%.3f block_build_ms=%.3f residue_init_ms=%.3f event_run_ms=%.3f\n", + sieve_s * 1e3, blocks_s * 1e3, residue_s * 1e3, run_s * 1e3); + + free(residue); + free_blocks(blocks, block_count); + free(primes); + mpz_clear(candidate); + mpz_clear(p); + return 0; +} From 7f2753683b812d16972a678bd5f633f5e718a139 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:09:58 +0800 Subject: [PATCH 16/23] Document jump-style K/R event collapse --- docs/VF1_EVENT_STAIRCASE_2026-08-25.md | 176 +++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 docs/VF1_EVENT_STAIRCASE_2026-08-25.md diff --git a/docs/VF1_EVENT_STAIRCASE_2026-08-25.md b/docs/VF1_EVENT_STAIRCASE_2026-08-25.md new file mode 100644 index 0000000..d0c2b5c --- /dev/null +++ b/docs/VF1_EVENT_STAIRCASE_2026-08-25.md @@ -0,0 +1,176 @@ +# VF-1 Event Staircase Diagnostic, 2026-08-25 + +## Status + +This document studies the observed plateau-and-jump structure of the finite-width survivor output. It does not claim an exact verification-free next-prime generator and does not claim causal depth 1. + +The diagnostic code is `experiments/vf1_event_staircase_gmp.c`. It deliberately uses a conventional prime fixture and batched GCD products to measure the event structure. Those mechanisms are diagnostic only and are not admissible as the final ZeroCandidatePrime generation core. + +## 1. Finite-width staircase + +Let + +\[ +P_K=\prod_{j=0}^{K-1}q_j +\] + +and define + +\[ +g_K(p)=\min\{d\ge1:\gcd(p+d,P_K)=1\}. +\] + +For increasing dimension width, + +\[ +g_{K+1}(p)\ge g_K(p). +\] + +Therefore `g_K` is a monotone nondecreasing staircase in `K`. + +The plateau rule is exact: + +\[ +q_K\nmid p+g_K\quad\Longrightarrow\quad g_{K+1}=g_K. +\] + +A jump can occur only when the newly admitted dimension hits the current survivor: + +\[ +q_K\mid p+g_K. +\] + +If the dimension sequence is the consecutive-prime sequence and the current survivor `c=p+g_K` is composite, then the next jump dimension is the index of the least prime factor of `c` that is not already active. + +This statement is useful as a post-hoc characterization. It is not an admissible generation rule because directly computing that least prime factor would insert factor location into the generator. + +## 2. Event representation + +Instead of treating every dimension as a causal event, define the jump set + +\[ +\mathcal E(p)=\{K:g_K(p)>g_{K-1}(p)\}. +\] + +Let its ordered elements be + +\[ +K_1 Finite-width survivor evolution is sparse in K: most newly admitted dimensions are null events, and the output changes only at collision dimensions. The observed trajectory is therefore better represented as a jump staircase than as a uniform level-by-level evolution. + +The unresolved problem is no longer merely to make `K` larger. It is to predict or absorb the next collision event without computing the hidden least-prime-factor information that characterizes that event after the fact. From 9559629b3f5954a2da67d7e579be9213f8d2ded6 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:10:51 +0800 Subject: [PATCH 17/23] Link VF-1 event staircase diagnostic --- README.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d87d084..16e655f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,9 @@ r_j(p + d) = (r_j(p) + d) mod q_j inside the finite-width survivor recurrence. The large integer is therefore used to establish the initial residue field and to receive the final output addition, but is not repeatedly used by the inner divisibility recursion. -This branch does **not** claim exact prime succession without closure. Finite dimension width can miss a later divisor, so its verification-free outputs remain `PROVISIONAL / UNVERIFIED`. The formal conjecture and the cloud benchmark are documented in [`docs/VF1_RESIDUE_CONJECTURE.md`](docs/VF1_RESIDUE_CONJECTURE.md) and [`docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md`](docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md). +This branch does **not** claim exact prime succession without closure. Finite dimension width can miss a later divisor, so its verification-free outputs remain `PROVISIONAL / UNVERIFIED`. The formal conjecture and cloud measurements are documented in [`docs/VF1_RESIDUE_CONJECTURE.md`](docs/VF1_RESIDUE_CONJECTURE.md), [`docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md`](docs/VF1_RESIDUE_BENCHMARK_2026-08-25.md), and [`docs/VF1_EVENT_STAIRCASE_2026-08-25.md`](docs/VF1_EVENT_STAIRCASE_2026-08-25.md). + +The event-staircase diagnostic records the observed fact that finite-width gaps are monotone plateaus in `K` interrupted by sparse collision jumps. Its block-GCD locator is explicitly diagnostic because it uses a conventional prime fixture and batched factor-location information; it is not presented as the final VF-1 generation operator. ## NVIDIA path @@ -78,22 +80,23 @@ The host side loads the NVIDIA Driver API dynamically from `nvcuda.dll`. The GPU ## Source layout ```text -source/main.c Win32 UI, task routing, gates and result presentation -source/own_solver.c CPU implementation of the survivor recurrence -source/vf_residue_state.c verification-free finite-width residue experiment -source/gpu_solver.c NVIDIA Driver API host implementation -source/gpu_kernel.ptx CUDA/PTX device implementation -source/traditional.c isolated bootstrap / validation routines -source/winmini.h minimal Win32 declarations -source/build.sh freestanding Windows x64 build -experiments/vf1_residue_gmp.c arbitrary-precision cloud benchmark mirror +source/main.c Win32 UI, task routing, gates and result presentation +source/own_solver.c CPU implementation of the survivor recurrence +source/vf_residue_state.c verification-free finite-width residue experiment +source/gpu_solver.c NVIDIA Driver API host implementation +source/gpu_kernel.ptx CUDA/PTX device implementation +source/traditional.c isolated bootstrap / validation routines +source/winmini.h minimal Win32 declarations +source/build.sh freestanding Windows x64 build +experiments/vf1_residue_gmp.c arbitrary-precision cloud benchmark mirror +experiments/vf1_event_staircase_gmp.c event-staircase / plateau-skipping diagnostic ``` -The build has no Python dependency. A small host-side C utility converts the checked-in PTX text into the C header embedded by `gpu_solver.c`. The GMP benchmark is isolated under `experiments/` and is not part of the Windows application build. +The build has no Python dependency. A small host-side C utility converts the checked-in PTX text into the C header embedded by `gpu_solver.c`. The GMP benchmarks are isolated under `experiments/` and are not part of the Windows application build. ## Scope of the claim -This repository contains an implementation and an experimental representation of the recurrence. It does **not** claim that constant sequential depth has been proved. Matrix-Free storage, GPU parallelism, a bounded experimental recursion depth, and a finite residue-state width are implementation properties; an asymptotic statement about scale-independent causal depth requires a separate proof. +This repository contains an implementation and an experimental representation of the recurrence. It does **not** claim that constant sequential depth has been proved. Matrix-Free storage, GPU parallelism, a bounded experimental recursion depth, a finite residue-state width, and sparse observed collision events are implementation or experimental properties; an asymptotic statement about scale-independent causal depth requires a separate proof. ## Platform From c1cbc284c1cfcba218804d665cbbaea453812901 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:25:57 +0800 Subject: [PATCH 18/23] Add logarithmic event-tree diagnostic --- experiments/vf1_event_tree_gmp.c | 147 +++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 experiments/vf1_event_tree_gmp.c diff --git a/experiments/vf1_event_tree_gmp.c b/experiments/vf1_event_tree_gmp.c new file mode 100644 index 0000000..3a1fef3 --- /dev/null +++ b/experiments/vf1_event_tree_gmp.c @@ -0,0 +1,147 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include + +typedef uint32_t u32; + +static double now_s(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC,&t); + return (double)t.tv_sec + 1e-9*(double)t.tv_nsec; +} + +typedef struct PrimeFixture { + u32 *p; + size_t n; +} PrimeFixture; + +static PrimeFixture build_prime_fixture(u32 limit) { + unsigned char *composite=(unsigned char*)calloc((size_t)limit+1,1); + size_t cap=256,n=0; + u32 *p=(u32*)malloc(cap*sizeof(u32)); + u32 i; + if(!composite||!p){fprintf(stderr,"allocation failure\n");exit(2);} + for(i=2;i<=limit;i++) { + if(!composite[i]) { + uint64_t j; + if(n==cap){cap*=2;p=(u32*)realloc(p,cap*sizeof(u32));if(!p)exit(2);} + p[n++]=i; + if((uint64_t)i*(uint64_t)i<=limit) + for(j=(uint64_t)i*(uint64_t)i;j<=limit;j+=i)composite[j]=1; + } + } + free(composite); + {PrimeFixture r={p,n};return r;} +} + +typedef struct ProductTree { + mpz_t *node; + size_t size; + size_t n; + const u32 *prime; +} ProductTree; + +static void product_tree_build(ProductTree *t,const PrimeFixture *pf) { + size_t i,s=1; + while(sn)s<<=1; + t->size=s;t->n=pf->n;t->prime=pf->p; + t->node=(mpz_t*)malloc(2*s*sizeof(mpz_t)); + if(!t->node)exit(2); + for(i=0;i<2*s;i++)mpz_init(t->node[i]); + for(i=0;in)mpz_set_ui(t->node[s+i],pf->p[i]); + else mpz_set_ui(t->node[s+i],1); + } + for(i=s-1;i;i--)mpz_mul(t->node[i],t->node[i<<1],t->node[(i<<1)|1]); +} + +static void product_tree_free(ProductTree *t) { + size_t i; + if(!t||!t->node)return; + for(i=0;i<2*t->size;i++)mpz_clear(t->node[i]); + free(t->node);t->node=NULL; +} + +typedef struct EventQuery { + size_t index; + unsigned gcd_probes; + int found; +} EventQuery; + +static int find_first_hit_rec(const ProductTree *t,const mpz_t candidate, + size_t start,size_t node,size_t left,size_t right, + mpz_t scratch,unsigned *probes,size_t *out_index) { + size_t middle; + if(right<=start||left>=t->n)return 0; + if(left>=start) { + (*probes)++; + mpz_gcd(scratch,candidate,t->node[node]); + if(mpz_cmp_ui(scratch,1)==0)return 0; + } + if(right-left==1){*out_index=left;return 1;} + middle=(left+right)>>1; + if(find_first_hit_rec(t,candidate,start,node<<1,left,middle,scratch,probes,out_index))return 1; + return find_first_hit_rec(t,candidate,start,(node<<1)|1,middle,right,scratch,probes,out_index); +} + +static EventQuery find_first_hit(const ProductTree *t,const mpz_t candidate,size_t start) { + EventQuery q={0,0,0}; + mpz_t scratch; + mpz_init(scratch); + q.found=find_first_hit_rec(t,candidate,start,1,0,t->size,scratch,&q.gcd_probes,&q.index); + mpz_clear(scratch); + return q; +} + +static void make_candidate(mpz_t candidate,unsigned gap) { + mpz_ui_pow_ui(candidate,10,100); + mpz_add_ui(candidate,candidate,267+gap); +} + +int main(void) { + const u32 prime_limit=3000000U; + const struct {size_t start;unsigned gap;} cases[]={{2,4},{88231,6},{175692,22}}; + PrimeFixture pf; + ProductTree tree; + mpz_t candidate,root_mod,g; + double t0,fixture_s,tree_s,query_s; + size_t i; + + t0=now_s();pf=build_prime_fixture(prime_limit);fixture_s=now_s()-t0; + t0=now_s();product_tree_build(&tree,&pf);tree_s=now_s()-t0; + + printf("prime_limit=%u primes=%zu fixture_ms=%.3f tree_ms=%.3f root_bits=%zu\n", + prime_limit,pf.n,fixture_s*1e3,tree_s*1e3,mpz_sizeinbase(tree.node[1],2)); + + mpz_inits(candidate,root_mod,g,NULL); + for(i=0;i1"); + } else { + printf("gap=%u start_index0=%zu no_hit_through_%u gcd_probes=%u query_ms=%.3f root_gcd=%s\n", + cases[i].gap,cases[i].start,prime_limit,q.gcd_probes,query_s*1e3, + mpz_cmp_ui(g,1)==0?"1":">1"); + } + } + + mpz_clears(candidate,root_mod,g,NULL); + product_tree_free(&tree); + free(pf.p); + return 0; +} From e35a795298dd9179144a6990a8fe29daf19d6500 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:26:26 +0800 Subject: [PATCH 19/23] Document logarithmic event-tree collapse attempt --- docs/VF1_EVENT_TREE_2026-08-25.md | 196 ++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 docs/VF1_EVENT_TREE_2026-08-25.md diff --git a/docs/VF1_EVENT_TREE_2026-08-25.md b/docs/VF1_EVENT_TREE_2026-08-25.md new file mode 100644 index 0000000..5e846b2 --- /dev/null +++ b/docs/VF1_EVENT_TREE_2026-08-25.md @@ -0,0 +1,196 @@ +# VF-1 Event-Tree Collapse Attempt, 2026-08-25 + +## Status + +This is a diagnostic experiment. It is not the final verification-free generator and it does not claim causal depth 1. + +The purpose is to test whether the sparse plateau/jump geometry observed in the finite-width survivor can be represented as a balanced collision tree rather than as a linear scan over every active dimension. + +The diagnostic implementation is `experiments/vf1_event_tree_gmp.c`. + +## 1. Collision tree + +For a dimension interval `I`, define the product + +\[ +B_I=\prod_{j\in I}q_j. +\] + +For a current survivor candidate `c`, + +\[ +\gcd(c,B_I)=1 +\] + +means the whole interval is collision-free. A nontrivial GCD means that at least one dimension in the interval divides `c`. + +A balanced binary tree therefore allows an entire collision-free subtree to be skipped with one query, while a hit subtree is recursively split until the first hit dimension is reached. + +Given a prebuilt product tree, the number of tree levels is + +\[ +O(\log K), +\] + +rather than a linear `K` scan. + +This does not remove the information contained in the prime/dimension basis. The conventional prime fixture and its product tree are deliberately diagnostic and are not admissible as the final generation core. + +## 2. Bounded aggregate payload identity + +A useful exact identity emerged from this test. The full product itself is not required for a collision predicate once the current candidate `c` is fixed: + +\[ +\boxed{\gcd(c,B_I)=\gcd(c,B_I\bmod c).} +\] + +Define + +\[ +A_I(c)=B_I\bmod c. +\] + +Then + +\[ +\boxed{\gcd(c,A_I(c))=1} +\] + +if and only if no dimension in `I` divides `c`. + +The block-combination rule is associative: + +\[ +A_{I\cup J}(c)=A_I(c)A_J(c)\bmod c +\] + +for disjoint adjacent intervals. + +Therefore the aggregate collision certificate for an arbitrarily large interval can, in principle, remain bounded by the bit width of `c` rather than growing like an explicit primorial. This removes the *payload-size* objection to the earlier `P_K` formulation. It does not remove the cost of producing the leaves or the dimension information itself. + +## 3. Cloud run at the `10^100` target + +Environment: + +- Linux x86-64 cloud container +- Intel Xeon Platinum 8573C +- single-threaded C +- GCC `-O3 -march=native` +- GMP +- diagnostic prime fixture through `3,000,000` + +The fixture contained + +```text +216816 prime dimensions +``` + +and the product-tree root had approximately + +```text +4325355 bits +``` + +The measured build costs were approximately + +```text +prime fixture : 11.9 ms +product tree : 78.5 ms +``` + +The event queries were: + +| current gap | search starts after | event | tree GCD probes | query time | +|---:|---:|---:|---:|---:| +| 4 | prime index 1 | `q = 1,134,709`, active width `K = 88,231` | 39 | 0.99 ms | +| 6 | previous event | `q = 2,391,019`, active width `K = 175,692` | 36 | 1.56 ms | +| 22 | previous event | no event through `3,000,000` | 8 | 0.15 ms | + +The first two events agree with the previously measured staircase. + +The important structural point is that more than two hundred thousand explicit dimensions were not queried one-by-one. Given the tree, long null plateaus were rejected by subtree certificates. + +## 4. Post-hoc probe beyond the 3,000,000 fixture + +A separate post-generation factor probe found that + +\[ +450131585977\mid (10^{100}+267+22). +\] + +The factor `450131585977` is prime. Its prime index is + +\[ +\pi(450131585977)=17453354061. +\] + +This is **not** asserted to be the least prime factor of the survivor, because the remaining cofactor has not been fully factored in this experiment. It therefore gives an upper bound on a possible later collision dimension, not a proven next event location. + +The result nevertheless shows why an explicit event tree cannot simply be extended until every possible hidden collision appears: the relevant dimension index can jump from roughly `1.8e5` into the multi-billion range. + +## 5. What has actually collapsed + +The experiments now separate three different notions of collapse. + +### A. Large-integer inner arithmetic + +The residue-state transform removes repeated use of the full `p` inside fixed-width divisibility dynamics. + +### B. R correction representation + +The finite-width operator `J_K` absorbs repeated survivor corrections into one mathematical successor map. + +### C. K collision-query depth + +A balanced event tree changes a linear collision scan into a logarithmic tree query, provided the dimension-block certificates already exist. + +Thus a concrete intermediate target is now + +\[ +\boxed{D_{collision}=O(\log K)} +\] + +rather than `O(K)` linear projection depth. + +This is still not VF-1. + +## 6. Remaining obstruction + +The tree exposes the remaining problem sharply: the leaves still encode the dimension sequence. Building or storing billions of leaves simply moves the cost outside the query. + +The next admissible target is therefore an **implicit block transfer operator**. For an interval `I`, it should produce the effect of all dimensions in `I` without enumerating its leaves and without returning a hidden factor location. + +A candidate algebraic interface is + +\[ +\mathcal B_I(c,g)\mapsto g', +\] + +with composition + +\[ +\mathcal B_{I\cup J}=\mathcal B_J\circ\mathcal B_I. +\] + +The desired properties are: + +- no explicit prime/dimension table, +- no factorization output, +- no candidate interval, +- no explicit primorial, +- no dimension-by-dimension scan, +- and a compact representation whose size does not grow linearly with `|I|`. + +If such block operators can be composed in a balanced tree, the causal depth target becomes logarithmic in the number of blocks. A further algebraic collapse of that tree would then be the appropriate route toward the conjectural depth-1 operator. + +## 7. Main conclusion + +The plateau/jump structure is not merely descriptive. A balanced collision tree demonstrates a real reduction in **query depth** over finite K. The identity + +\[ +\gcd(c,B_I)=\gcd(c,B_I\bmod c) +\] + +also shows that the aggregate certificate need not inherit the enormous bit length of an explicit primorial. + +What remains unsolved is the generation of those block certificates or block transfer operators without enumerating the dimension leaves. That is now the most precise K-collapse target in the VF-1 branch. From caa230b0f45bad5963e42cffebb1a66cd2b6c359 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:30:22 +0800 Subject: [PATCH 20/23] Add bounded offset-mask monoid diagnostic --- experiments/vf1_offset_mask_monoid_gmp.c | 169 +++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 experiments/vf1_offset_mask_monoid_gmp.c diff --git a/experiments/vf1_offset_mask_monoid_gmp.c b/experiments/vf1_offset_mask_monoid_gmp.c new file mode 100644 index 0000000..245633c --- /dev/null +++ b/experiments/vf1_offset_mask_monoid_gmp.c @@ -0,0 +1,169 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include + +/* + Diagnostic only. + + This experiment compresses a finite active dimension set into a bounded + forbidden-offset mask over d=1..W: + + F_I(d)=1 iff some q_j in block I divides p+d. + + Block composition is bitwise OR. The first zero bit is exactly the finite-K + survivor gap whenever the requested gap lies inside the window. + + The experiment deliberately uses a conventional prime fixture and a bounded + offset window, so it is NOT admissible as the final ZeroCandidatePrime core. +*/ + +typedef uint64_t u64; + +static double now_s(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (double)t.tv_sec + 1e-9 * (double)t.tv_nsec; +} + +static int sieve_primes(uint32_t n, uint32_t **out, size_t *count) { + uint8_t *composite = (uint8_t*)calloc((size_t)n + 1u, 1u); + uint32_t *primes; + size_t c = 0, k = 0; + if (!composite) return 0; + + for (uint32_t i = 2; i <= n; ++i) { + if (!composite[i]) { + ++c; + if ((uint64_t)i * (uint64_t)i <= n) { + for (uint32_t j = i * i; j <= n; j += i) composite[j] = 1; + } + } + } + + primes = (uint32_t*)malloc(c * sizeof(uint32_t)); + if (!primes) { free(composite); return 0; } + for (uint32_t i = 2; i <= n; ++i) if (!composite[i]) primes[k++] = i; + free(composite); + *out = primes; + *count = c; + return 1; +} + +static inline void set_bit(u64 *mask, size_t d) { + mask[(d - 1u) >> 6] |= 1ULL << ((d - 1u) & 63u); +} + +static size_t first_zero(const u64 *mask, size_t W) { + size_t words = (W + 63u) >> 6; + for (size_t w = 0; w < words; ++w) { + u64 x = ~mask[w]; + if (w + 1u == words && (W & 63u)) x &= (1ULL << (W & 63u)) - 1ULL; + if (x) return (w << 6) + (size_t)__builtin_ctzll(x) + 1u; + } + return 0; +} + +static void dimension_into_mask(u64 *mask, size_t W, const mpz_t p, uint32_t q) { + unsigned long r = mpz_fdiv_ui(p, q); + u64 d = ((u64)q - (u64)r) % (u64)q; + if (d == 0) d = q; + for (u64 x = d; x <= (u64)W; x += q) set_bit(mask, (size_t)x); +} + +static void build_flat(u64 *mask, size_t W, const mpz_t p, + const uint32_t *primes, size_t count) { + size_t words = (W + 63u) >> 6; + memset(mask, 0, words * sizeof(u64)); + for (size_t i = 0; i < count; ++i) dimension_into_mask(mask, W, p, primes[i]); +} + +static size_t compare_shift_prefix(const u64 *old_mask, const u64 *new_mask, + size_t W, size_t g) { + size_t mismatch = 0; + for (size_t d = 1; d + g <= W; ++d) { + size_t aidx = d + g - 1u; + size_t bidx = d - 1u; + int a = (int)((old_mask[aidx >> 6] >> (aidx & 63u)) & 1ULL); + int b = (int)((new_mask[bidx >> 6] >> (bidx & 63u)) & 1ULL); + if (a != b) ++mismatch; + } + return mismatch; +} + +int main(int argc, char **argv) { + uint32_t prime_limit = argc > 1 ? (uint32_t)strtoul(argv[1], 0, 10) : 3000000u; + size_t W = argc > 2 ? (size_t)strtoull(argv[2], 0, 10) : 4096u; + size_t block_size = argc > 3 ? (size_t)strtoull(argv[3], 0, 10) : 512u; + uint32_t *primes = NULL; + size_t prime_count = 0; + size_t words, blocks; + u64 *block_masks, *root, *flat, *shifted_reference; + mpz_t p, p2; + double t0, sieve_s, leaf_s, reduce_s, flat_s; + size_t gap, mismatch; + + t0 = now_s(); + if (!sieve_primes(prime_limit, &primes, &prime_count)) return 2; + sieve_s = now_s() - t0; + + words = (W + 63u) >> 6; + blocks = (prime_count + block_size - 1u) / block_size; + block_masks = (u64*)calloc(blocks * words, sizeof(u64)); + root = (u64*)calloc(words, sizeof(u64)); + flat = (u64*)calloc(words, sizeof(u64)); + shifted_reference = (u64*)calloc(words, sizeof(u64)); + if (!block_masks || !root || !flat || !shifted_reference) return 3; + + mpz_init(p); + mpz_ui_pow_ui(p, 10, 100); + mpz_add_ui(p, p, 267); + mpz_init(p2); + + t0 = now_s(); + for (size_t b = 0; b < blocks; ++b) { + size_t begin = b * block_size; + size_t end = begin + block_size; + u64 *m = block_masks + b * words; + if (end > prime_count) end = prime_count; + for (size_t i = begin; i < end; ++i) dimension_into_mask(m, W, p, primes[i]); + } + leaf_s = now_s() - t0; + + t0 = now_s(); + for (size_t b = 0; b < blocks; ++b) { + const u64 *m = block_masks + b * words; + for (size_t w = 0; w < words; ++w) root[w] |= m[w]; + } + reduce_s = now_s() - t0; + + gap = first_zero(root, W); + + t0 = now_s(); + build_flat(flat, W, p, primes, prime_count); + flat_s = now_s() - t0; + + mpz_set(p2, p); + mpz_add_ui(p2, p2, gap); + build_flat(shifted_reference, W, p2, primes, prime_count); + mismatch = compare_shift_prefix(root, shifted_reference, W, gap); + + printf("prime_limit=%u primes=%zu W=%zu blocks=%zu root_bytes=%zu gap=%zu\n", + prime_limit, prime_count, W, blocks, words * sizeof(u64), gap); + printf("sieve_ms=%.3f block_leaf_ms=%.3f or_reduce_us=%.3f flat_ms=%.3f equal=%d\n", + sieve_s * 1e3, leaf_s * 1e3, reduce_s * 1e6, flat_s * 1e3, + memcmp(root, flat, words * sizeof(u64)) == 0); + printf("translation_shift_prefix_mismatch=%zu\n", mismatch); + + free(shifted_reference); + free(flat); + free(root); + free(block_masks); + free(primes); + mpz_clear(p2); + mpz_clear(p); + return 0; +} From c8aa71155297b1b33a4ef25a561fdb5ace76849e Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:30:56 +0800 Subject: [PATCH 21/23] Document bounded offset-mask monoid collapse --- docs/VF1_OFFSET_MASK_MONOID_2026-08-25.md | 172 ++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 docs/VF1_OFFSET_MASK_MONOID_2026-08-25.md diff --git a/docs/VF1_OFFSET_MASK_MONOID_2026-08-25.md b/docs/VF1_OFFSET_MASK_MONOID_2026-08-25.md new file mode 100644 index 0000000..4cdee0d --- /dev/null +++ b/docs/VF1_OFFSET_MASK_MONOID_2026-08-25.md @@ -0,0 +1,172 @@ +# VF-1 Bounded Offset-Mask Monoid Diagnostic, 2026-08-25 + +## Status + +This is a diagnostic representation experiment. It is not the final verification-free generator and it does not claim causal depth 1. + +The experiment asks whether the finite-K survivor effect can be compressed into a compact associative block state after the active dimension information has been supplied. + +The implementation is `experiments/vf1_offset_mask_monoid_gmp.c`. + +## 1. Forbidden-offset indicator + +For current state `p`, active dimension block `I`, and bounded horizon `1 <= d <= W`, define + +\[ +F_I^{(p)}(d)= +\begin{cases} +1,&\exists j\in I:\ q_j\mid p+d,\\ +0,&\text{otherwise}. +\end{cases} +\] + +The bit mask representing `F_I` has exactly `W` bits. The finite-width successor gap inside this horizon is the first zero bit of the union over all active blocks. + +For a single dimension `q_j`, its forbidden offsets are the arithmetic progression + +\[ +d\equiv -p\pmod{q_j}. +\] + +## 2. Exact block composition + +For disjoint active blocks `I` and `J`, + +\[ +\boxed{F_{I\cup J}^{(p)}=F_I^{(p)}\lor F_J^{(p)}} +\] + +where `OR` is bitwise OR over the bounded offset mask. + +Thus finite blocks form an associative monoid under OR. A balanced reduction over already-constructed block summaries has logarithmic parallel composition depth, while the root payload remains exactly `W` bits regardless of the number of active dimensions. + +This is a stronger payload compression than an explicit primorial representation for local survivor transport: + +\[ +\boxed{\text{summary size}=O(W)\text{ bits, independent of }K.} +\] + +It does not imply that the summary can be generated without dimension information. + +## 3. R collapse inside the window + +Once the root forbidden mask is available, repeated finite-K survivor corrections are not evaluated one event at a time. The finite-K result is simply + +\[ +\boxed{g_K=\min\{d\in[1,W]:F_{[0,K)}^{(p)}(d)=0\}} +\] + +provided such a zero exists in the chosen horizon. + +So, inside a fixed finite horizon, the mask absorbs the explicit correction-round sequence into one first-zero operation. + +This is an exact finite-K identity. The horizon itself is a bounded candidate-offset materialization, which makes this representation diagnostic only under the current project rules. + +## 4. Chain translation identity + +The aggregate forbidden state obeys an exact translation law. If a finite-K survivor step advances by `g`, then for every offset still inside the old horizon, + +\[ +\boxed{F^{(p+g)}(d)=F^{(p)}(d+g).} +\] + +Therefore a chain-resident aggregate mask can be shifted after a step. For a sufficiently long precomputed horizon, subsequent finite-K survivor states can be read from the same aggregate collision field without recomputing the large integer or the individual residue vector for the preserved prefix. + +The experiment verifies this identity by rebuilding the mask independently at `p+g` and comparing it with the shifted prefix of the old mask. + +## 5. Cloud measurements at `p = 10^100 + 267` + +Environment: + +- Linux x86-64 cloud container +- Intel Xeon Platinum 8573C +- single-threaded C +- GCC `-O3 -march=native` +- GMP only for the diagnostic large integer + +For `W=1024` the root mask is only `128 bytes`. + +| prime limit | active dimensions | finite-K gap | root payload | +|---:|---:|---:|---:| +| 1,619 | 256 | 4 | 128 B | +| 17,863 | 2,048 | 4 | 128 B | +| 1,134,709 | 88,231 | 6 | 128 B | +| 2,391,019 | 175,692 | 22 | 128 B | +| 3,000,000 | 216,816 | 22 | 128 B | + +The gaps exactly match the previously measured finite-K staircase at the corresponding widths. + +At prime limit `3,000,000`, block size `512`, and `W=4096`: + +```text +active dimensions : 216816 +block summaries : 424 +root payload : 512 bytes +finite-K gap : 22 +block leaf build : ~4.1 ms +OR reduction : ~3.6 us +flat rebuild : ~4.1 ms +block/flat equal : yes +shift mismatch : 0 +``` + +For `W=1024`, the same root payload is only `128 bytes`; the OR reduction was about `1.9 us` in the measured run. + +The exact timings are machine-specific. The structural observations are the important part: + +1. the root summary size depends on `W`, not on `K`; +2. block composition is associative and very cheap once leaf summaries exist; +3. the first-zero query absorbs the finite-K correction sequence; +4. the chain translation law holds exactly on the preserved mask prefix. + +## 6. What this does and does not collapse + +This experiment collapses three finite-state representation costs: + +\[ +\text{many block payloads}\to\text{one }W\text{-bit root}, +\] + +\[ +R\text{ correction steps}\to\text{one first-zero query}, +\] + +and, after a chain step, + +\[ +F^{(p)}\to\text{shifted }F^{(p+g)} +\] + +on the retained horizon. + +It does **not** solve the remaining K-information problem. Constructing the leaf masks still requires the active dimension sequence or an equivalent source of its congruence information. + +It also materializes a bounded offset window, which is intentionally excluded from the final ZeroCandidatePrime generation core. The mask therefore serves as a structural microscope, not as the final algorithm. + +## 7. Stronger target suggested by the experiment + +The experiment suggests that the desired implicit block transfer operator should not attempt to preserve every `q_j`. It should instead directly produce the aggregate local exclusion effect of a dimension interval. + +An ideal admissible interface would be + +\[ +\boxed{\mathcal C_I(p)\mapsto \Sigma_I} +\] + +where `Sigma_I` is a compact, non-candidate-array summary satisfying an associative composition law + +\[ +\boxed{\Sigma_{I\cup J}=\Sigma_I\star\Sigma_J} +\] + +and from the root summary the next survivor action can be extracted without enumerating offsets. + +The offset mask proves that such associative aggregate effects exist for a bounded materialized horizon. The unsolved step is to replace the materialized horizon by a symbolic or implicit summary whose size and construction depth do not grow linearly with either `W` or `K`. + +## 8. Main conclusion + +The K/R-collapse problem now has a sharper intermediate result: + +> For finite K and a bounded local horizon, all active dimension exclusions form an associative OR-monoid whose root state is only W bits, and the entire finite-K correction chain is reduced to one first-zero operation. The aggregate state also translates by a simple shift under a chain step. + +This demonstrates that the large explicit dimension list is not intrinsically required in the *query representation* after aggregation. What remains is to generate an equally compact aggregate symbolically, without enumerating the dimension leaves and without materializing the offset window. From 604da6c7e6e6659b4dc97f371170c96f9284aa84 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:36:14 +0800 Subject: [PATCH 22/23] Add factorial collision certificate diagnostic --- experiments/vf1_factorial_certificate_gmp.c | 110 ++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 experiments/vf1_factorial_certificate_gmp.c diff --git a/experiments/vf1_factorial_certificate_gmp.c b/experiments/vf1_factorial_certificate_gmp.c new file mode 100644 index 0000000..a2ffde3 --- /dev/null +++ b/experiments/vf1_factorial_certificate_gmp.c @@ -0,0 +1,110 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include + +/* + Diagnostic only. + + This experiment replaces an explicit prime-dimension fixture up to a bound B + by the exact identity + + gcd(c, B!) > 1 + + iff c has a prime divisor <= B. + + The modular factorial certificate is evaluated without materializing B!: + + Sigma_B(c) = B! mod c. + + Then + + gcd(c, Sigma_B(c)) = gcd(c, B!). + + The implementation uses a bounded-leaf divide-and-conquer product tree. It + does not build a prime table. It is not an admissible final generator because + the operation becomes a primality-style closure when B approaches sqrt(c), + and the total work still grows with B. The purpose is to isolate K-information + collapse and payload size. +*/ + +typedef unsigned long long u64; + +static double now_s(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return (double)t.tv_sec + 1e-9 * (double)t.tv_nsec; +} + +static void range_product_mod(mpz_t out, u64 lo, u64 hi, const mpz_t mod) { + if (lo > hi) { + mpz_set_ui(out, 1); + return; + } + + /* Constant-size leaf. Reductions keep the live payload bounded. */ + if (hi - lo <= 255ULL) { + unsigned batch = 0; + mpz_set_ui(out, 1); + for (u64 i = lo; i <= hi; ++i) { + mpz_mul_ui(out, out, (unsigned long)i); + if (++batch == 16U) { + mpz_mod(out, out, mod); + batch = 0; + } + } + mpz_mod(out, out, mod); + return; + } + + { + u64 mid = lo + (hi - lo) / 2ULL; + mpz_t left, right; + mpz_inits(left, right, NULL); + range_product_mod(left, lo, mid, mod); + range_product_mod(right, mid + 1ULL, hi, mod); + mpz_mul(out, left, right); + mpz_mod(out, out, mod); + mpz_clears(left, right, NULL); + } +} + +static int factorial_collision_certificate(mpz_t sigma, const mpz_t c, u64 B) { + mpz_t g; + int hit; + mpz_init(g); + range_product_mod(sigma, 2ULL, B, c); + mpz_gcd(g, c, sigma); + hit = mpz_cmp_ui(g, 1UL) != 0; +#ifdef VF1_DEBUG_FACTOR + gmp_printf("debug_gcd=%Zd\n", g); +#endif + mpz_clear(g); + return hit; +} + +int main(int argc, char **argv) { + u64 B = argc > 1 ? strtoull(argv[1], 0, 10) : 3000000ULL; + unsigned gap = argc > 2 ? (unsigned)strtoul(argv[2], 0, 10) : 4U; + mpz_t p, c, sigma; + double t0, elapsed; + int hit; + + mpz_inits(p, c, sigma, NULL); + mpz_ui_pow_ui(p, 10, 100); + mpz_add_ui(p, p, 267UL); + mpz_set(c, p); + mpz_add_ui(c, c, gap); + + t0 = now_s(); + hit = factorial_collision_certificate(sigma, c, B); + elapsed = now_s() - t0; + + printf("B=%llu gap=%u collision=%d sigma_bits=%zu time_ms=%.3f\n", + B, gap, hit, mpz_sizeinbase(sigma, 2), elapsed * 1e3); + + mpz_clears(p, c, sigma, NULL); + return 0; +} From 74cbbd0b3007a2a352de5dc356af41f7dc6e25b7 Mon Sep 17 00:00:00 2001 From: Kestis Date: Tue, 25 Aug 2026 02:36:47 +0800 Subject: [PATCH 23/23] Document symbolic collapse lower bound and factorial certificate --- docs/VF1_SYMBOLIC_COLLAPSE_2026-08-25.md | 148 +++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/VF1_SYMBOLIC_COLLAPSE_2026-08-25.md diff --git a/docs/VF1_SYMBOLIC_COLLAPSE_2026-08-25.md b/docs/VF1_SYMBOLIC_COLLAPSE_2026-08-25.md new file mode 100644 index 0000000..bfd2e48 --- /dev/null +++ b/docs/VF1_SYMBOLIC_COLLAPSE_2026-08-25.md @@ -0,0 +1,148 @@ +# VF-1 Symbolic Collapse Attempt, 2026-08-25 + +## Status + +This note records two results from the attempt to remove both the explicit dimension width K and the bounded offset-mask width W from the VF-1 diagnostic representation. + +The first result is a lower bound for any generic OR-monoid compression of the bounded forbidden-offset mask. The second is an arithmetic-specific K-collapse certificate based on a modular factorial product tree. + +Neither result is a final verification-free generator and neither proves causal depth 1. + +## 1. Generic W-bit compression has a worst-case lower bound + +For a bounded offset horizon U = {1,...,W}, let a forbidden set A be any subset of U. The finite-window survivor query is + +\[ +firstzero(A)=\min(U\setminus A). +\] + +Suppose a summary map S(A) is required to support exact associative union composition and exact first-zero recovery after arbitrary future unions. In other words, from S(A) and S(C) one must be able to obtain a summary for A union C, and from the resulting summary recover firstzero(A union C). + +Then S must distinguish every pair of distinct masks A and B. + +Proof: choose the least offset d where A and B differ. Without loss of generality d is in A and not in B. Let C contain every offset smaller than d and not contain d. Then firstzero(B union C) = d, while firstzero(A union C) is not d. Therefore S(A) and S(B) cannot be identical, otherwise composition with the same S(C) would give the same answer for both. Hence S is injective on the 2^W possible masks. + +Therefore any generic exact compositional summary needs at least + +\[ +\boxed{W\text{ bits}} +\] + +in the worst case. + +This means the W-bit forbidden mask used in the previous OR-monoid experiment is information-theoretically optimal for the unrestricted mask problem. A true sub-W symbolic collapse must exploit the arithmetic structure of the prime-dimension family rather than compressing an arbitrary OR mask. + +## 2. Arithmetic-specific K collapse without a prime table + +Let c be the current survivor candidate and let B be a dimension-value bound. The set of active prime dimensions up to B can be replaced by the factorial identity + +\[ +\boxed{\gcd(c,B!)>1} +\] + +if and only if c has a prime divisor not exceeding B. + +This does not require a precomputed prime list. Every prime q <= B is already a factor of B!, while every composite contribution is redundant for the boolean collision predicate. + +The enormous factorial itself need not be materialized. Define the bounded certificate + +\[ +\boxed{\Sigma_B(c)=B!\bmod c.} +\] + +Then + +\[ +\boxed{\gcd(c,\Sigma_B(c))=\gcd(c,B!).} +\] + +So the root payload is bounded by the bit width of c regardless of how many prime dimensions lie below B. + +The experiment `experiments/vf1_factorial_certificate_gmp.c` evaluates Sigma_B(c) with a divide-and-conquer modular product tree. The checked-in implementation is single-threaded, but the product DAG is balanced: with constant-size leaves its algebraic combination depth is O(log B), while total work still grows with B. + +This is a real K-representation collapse: + +\[ +\text{explicit }q_0,\ldots,q_K +\quad\longrightarrow\quad +\Sigma_B(c) +\] + +with no prime table and no explicit primorial payload. + +It is not yet an admissible VF-1 generator. If B is driven to sqrt(c), the boolean collision predicate becomes a primality-style exact closure. In addition, the modular factorial still performs B-dependent work. + +## 3. Cloud measurements at p = 10^100 + 267 + +Environment: + +- Linux x86-64 cloud container +- Intel Xeon Platinum 8573C +- single-threaded C +- GCC -O3 -march=native +- GMP + +The target input is + +\[ +p=10^{100}+267. +\] + +Measured modular-factorial collision certificates: + +| current gap g | bound B | collision | certificate time | +|---:|---:|---:|---:| +| 4 | 1,000,000 | no | 22.5 ms | +| 4 | 1,134,709 | yes | 31.0 ms | +| 4 | 3,000,000 | yes | 75.2 ms | +| 6 | 2,391,019 | yes | 59.7 ms | +| 6 | 3,000,000 | yes | 70.8 ms | +| 22 | 3,000,000 | no | 70.3 ms | +| 682 | 3,000,000 | no | 108.7 ms | + +For the first two known staircase events, a debug build of the diagnostic returned GCD values 1,134,709 and 2,391,019 respectively, matching the independently established collision dimensions. The normal diagnostic does not expose the factor value; it emits only the collision boolean. + +The live certificate payload stayed near the approximately 333-bit size of c instead of growing with an explicit factorial or primorial. + +## 4. What has now been learned about K, R, E and W + +The experiments distinguish four kinds of collapse: + +1. Residue-state collapse removes repeated full-p arithmetic from the finite-K inner recurrence. +2. Event-staircase collapse shows most K increments are null events. +3. OR-mask collapse absorbs finite-K correction rounds R and event sequence E into one first-zero query, but requires W bits. +4. Factorial-certificate collapse removes the explicit prime-dimension list from a single collision query and bounds its root payload by O(log c) bits, but retains B-dependent work and does not produce the next survivor gap by itself. + +The generic lower bound explains why the previous request for a summary whose size is independent of both K and W cannot be achieved by treating the forbidden-offset field as an arbitrary OR mask. Any successful VF-1 symbolic state must use additional number-theoretic structure. + +## 5. New target + +The remaining admissible target can now be stated more narrowly. + +We need an arithmetic-specific transfer object + +\[ +\boxed{\Theta(p;I)} +\] + +that represents the exclusion effect of a large implicit dimension interval I, supports associative or otherwise bounded-depth composition, and lets the next survivor action be extracted without: + +- enumerating prime dimensions, +- materializing an offset window, +- locating or returning a factor, +- invoking a conventional primality or next-prime routine, +- or doing work proportional to the raw interval width. + +The factorial certificate proves that prime-list information can disappear from a boolean collision query. The W-bit lower bound proves that a generic offset-mask monoid cannot by itself remove the candidate-offset horizon. Therefore the next step must fuse these two observations: an arithmetic-specific aggregate that acts directly on the survivor state rather than first constructing a generic forbidden-offset field. + +## 6. Current causal-depth boundary + +With a preexisting arithmetic interval bound B, the balanced modular product tree provides an intermediate collision-query DAG of + +\[ +\boxed{D_{collision}=O(\log B)}. +\] + +This is not O(1), and the sequential benchmark runtime is not a parallel-depth measurement. It is nevertheless a stronger structural bound than a dimension-by-dimension K scan because the explicit prime basis is absent from the query representation. + +A genuine VF-1 result would require an additional algebraic collapse from this balanced arithmetic aggregate to a scale-independent causal operator. That remains open.