/* #um_optimizations @pprog_pattern_query_goal_20260706 @hutter_run_costs @hutter_metrics @pprogram_design_202606 @pp_wordsv2 Optimizations change HOW, never WHAT IS REPORTED ## The rule An optimization changes the operations the machine performs. It never changes what is reported, and what is reported is always in UM terms: E, T, P, f, Omega. Concretely, and these are the things that go wrong if it is left implicit: - the structural measurables count the atomic patterns the UM HAS, not the operations the C performs. A pattern that is never materialised is still a pattern, and is still counted. - --patterns enumerates every atom of every family, reconstructed on demand, whether or not the running program ever represents them. - --explain answers in events and patterns at a position, in the same sentences, whether or not the implementation visited that position at all. - the model file is unchanged. An optimization that changes the archive is not an optimization, it is a design change, and belongs in a variant with an axis. This is the standing discipline of #pprog_pattern_query_goal_20260706 -- "introspection is on-demand reconstruction, never de-optimization; every optimization admitted must be accompanied by its unfolding in the query layer" -- stated as a general rule rather than one about the query layer, because the pressure to let the reporting drift toward the implementation comes up every time the implementation gets cleverer, and it is exactly the failure mode the P-programming approach exists to prevent. ## Admitting one Three conditions, all of them checkable: 1. the program's output is byte-identical; 2. every UM-level quantity reported before is reported unchanged after; 3. it can be unfolded in the query layer on demand -- there is a stated rule that takes the optimized representation back to the atoms it stands for. An optimization that cannot meet (3) is dead on arrival regardless of its speed. Each one admitted gets a paragraph here saying what it collapses and what its unfolding is. ## Admitted: THE MEMORY CHAIN IS NOT SHIFTED The problem. #pp_pattern implemented the length-N copy chain literally: chain_shift moved every one of the N cells one position toward the tail on every single input byte. That is O(N) per byte and O(M*N) per run, and with N = M it is quadratic -- measured on the bare p3 memchain, net of pacing, 0.17 s / 0.51 s / 1.63 s at N = 2*10^4 / 4*10^4 / 8*10^4, converging on the 4 per doubling that quadratic predicts. It was the single largest cost in the system: ~125 of the 213 seconds a p8v2 run took at 10^6, ~3 hours at 10^7, and 10^18 byte moves at 10^9. It is why nothing on the compression ladder had ever been measured end-to-end at enwik9 scale by this interpreter, and it is the same bottleneck p8-opt.c was written to get around. The observation. Settling happens inside the uncertainty window. Everything to the left of that window has settled and will not change again, so it has no reason to move leftward byte by byte: only the window is live, and the rest is history. The shift was moving history. The collapse. The chain is stored as an append-only buffer with a cursor. An input byte is written at the cursor and the cursor advances -- O(1), no byte is ever copied -- and the cell mem_cell_i at any moment is the VIEW buf[cursor - i]. The delay line becomes an indexing convention over stored history instead of a physically moving structure. The unfolding, which is condition (3). Nothing about the UM changes: - E still has the N mem_cell ESs. The structural line still reports 2N+2 event spaces. - P still has the 256*N atomic identity patterns of the memchain family, and the structural line still counts them: 256*N. Not one of them is materialised at run time and every one of them is real. - --patterns still enumerates them, 256 atoms at strength 255 for each adjacent pair, input -> mem_cell_1 then mem_cell_i -> mem_cell_{i+1}, reconstructed from the program text exactly as before. The dump is byte-identical. - --explain still says "The input byte i time steps ago was X." for cell i. The rule that takes the representation back to the atoms is one line: the event in mem_cell_i at cursor position c is the byte at buf[c - i], and the copy pattern from mem_cell_i to mem_cell_{i+1} is the identity that holds between buf[c - i] and buf[c - i - 1] by construction of the buffer. - the always-absolute invariant still holds: each cell holds exactly one populated event, and a cell is populated exactly when c - i is in range. - the model file is untouched, and the round-trip is byte-identical. Measured. A p8v2 compress of a 10^6-byte enwik9 prefix went from 213.3 s to 144.7 s on the chain collapse alone, and to 24.4 s once the diagnostic dump was also capped (below): 8.7x overall, and the run is now linear where it was quadratic. The model file is byte-identical across all three -- same 5800 kept tokens, same 769922 class (c) bytes -- and the 10^6 round-trip is byte-identical, which is condition (1). The structural line and both query surfaces are unchanged, which is (2). Scope. Applied to the wordsv2 kind only. p1, p3, p4, p7 and p8 keep the literal shift, because their pp_main blocks index mem[] directly under the shifting convention -- the tail is mem[N-1] and the j-th input byte is mem[M-1-j] -- so the change is not confined to one block for them, and re-rolling five shipped fixtures and their acceptance tests is not this push's business. The same collapse is available to them whenever someone wants the ladder to go past 10^6 for p7. ## Admitted: THE DIAGNOSTIC DUMP IS CAPPED Not an optimization of the UM at all, and listed here so the distinction is visible. The .pos dump and the settled-argmax statistics are DIAGNOSTICS: they are not part of the compression, they do not touch the model, and nothing in E, T, P, f or Omega depends on them. Settling every window of the sample to produce them is linear in M with a large constant -- it was 90 of the 145 seconds left after the chain collapse at 10^6. It is capped at the first 65536 positions. That does change a reported number, so the number says so: the settling line reads "settled argmax correct of " where D is the positions actually settled, and the dump's header line carries "dumped " beside M. A diagnostic computed over a prefix must never be printed as though it covered the sample. ## Not admitted, recorded so they are not re-argued - the AND gate is evaluated only for the pair formed by the most active event at each of the two source positions, not for all 65536 pairs (#token_and). Exact when the sources are absolute, an approximation otherwise, so it is a DESIGN choice with an axis (C), not an optimization, and it is reported as such. - a settling message is computed from the source position's argmax event only, not from its whole distribution (#omega-p8-hyper's preamble). Same status: exact when the source is absolute, an approximation otherwise, and it belongs to f. Both are named in the fixture where they apply rather than here, because a reader of the fixture has to see them; this block is only for collapses that are exact. Written 2026-08-05. */