research: preserve solver experiments and reproducible benchmarks

This commit is contained in:
Yaossg 2026-10-11 12:28:02 +08:00
parent 12e4266950
commit e93bc20b0a
85 changed files with 518443 additions and 0 deletions

View file

@ -0,0 +1,99 @@
// Isolated feasibility experiment; not wired into production search entry points.
// Build: g++ -O3 -std=c++17 -march=native research/upper_interval_probe.cpp -o /tmp/upper_interval_probe
// Tests/benchmark: /tmp/upper_interval_probe
// mode=0: existing sorted-event solver; mode=1: two running residue intervals.
#include "slime_solver_core.hpp"
#include <algorithm>
#include <array>
#include <chrono>
#include <iostream>
#include <random>
#include <vector>
#include <stdexcept>
namespace sr=slime_research;
using Clock=std::chrono::steady_clock;
using Cells=std::array<sr::CellTerm,25>;
struct Emit { std::vector<uint64_t>& v; void operator()(uint64_t s){v.push_back(s);} };
Cells cells(int x,int z){Cells c;for(int j=0;j<5;j++)for(int i=0;i<5;i++)c[j*5+i]={sr::coordinateTerm(x+i,z+j),sr::kSlime};return c;}
std::vector<uint32_t> roots(const Cells& c){std::vector<uint32_t> r;for(uint32_t p=0;p<(1u<<18);p++)if(sr::partialPatternPossible(p,18,c.data(),25))r.push_back(p);return r;}
uint64_t visits=0;
void fast(uint64_t low,const Cells& c,Emit& emit){
uint32_t q=sr::nextStateFromTerm(low,c[0].term)>>17;
++visits;
if(q&1)return;
uint32_t b=q>>18,r=q&((1u<<18)-1),t=8192-b;
uint32_t residue[2]={(r%5+5-b%5)%5,0};residue[1]=(residue[0]+2)%5;
uint32_t lo[2]={0,t},hi[2]={t,8192};
unsigned mask=0;
for(int k=0;k<2;k++)if(sr::firstWithResidue(lo[k],residue[k])<hi[k])mask|=1u<<k;
for(int i=1;i<25&&mask;i++){
q=sr::nextStateFromTerm(low,c[i].term)>>17;++visits;
if(q&1)return;
b=q>>18;r=q&((1u<<18)-1);t=8192-b;
uint32_t before=(r%5+5-b%5)%5,after=(before+2)%5;
for(int k=0;k<2;k++)if(mask&(1u<<k)){
if(residue[k]==before)hi[k]=std::min(hi[k],t);
else if(residue[k]==after)lo[k]=std::max(lo[k],t);
else{mask&=~(1u<<k);continue;}
if(sr::firstWithResidue(lo[k],residue[k])>=hi[k])mask&=~(1u<<k);
}
}
for(int k=0;k<2;k++)if(mask&(1u<<k))for(uint32_t t0=sr::firstWithResidue(lo[k],residue[k]);t0<hi[k];t0+=5){
uint64_t s=low+((uint64_t((4965u*t0)&8191))<<35);
if(sr::verifyPattern(s,c.data(),25))emit(s);
}
}
int main(){
auto c=cells(51069,419124);auto rr=roots(c);
std::vector<uint64_t> baseline;
for(int round=0;round<3;round++)for(int mode=0;mode<2;mode++){
std::vector<uint64_t> result;Emit e{result};visits=0;auto start=Clock::now();
for(auto p:rr)for(uint64_t m=0;m<(1u<<17);m++){
uint64_t s=p+(m<<18);
if(mode)fast(s,c,e);else sr::solveUpper13(s,c.data(),25,e);
}
double sec=std::chrono::duration<double>(Clock::now()-start).count();
std::sort(result.begin(),result.end());
if(!mode)baseline=result;else if(result!=baseline)throw std::runtime_error("full search mismatch");
std::cout<<"round="<<round<<" mode="<<mode<<" seconds="<<sec<<" results="<<result.size()<<" avg_cells="<<double(visits)/(rr.size()*(1u<<17))<<std::endl;
}
std::mt19937_64 rng(20261011);
for(int p=0;p<20;p++){
auto cc=cells(int(rng()%3750000)-1875000,int(rng()%3750000)-1875000);
auto rt=roots(cc);
for(int k=0;k<2000;k++){
uint64_t s=rt.empty()?(rng()&((1ull<<35)-1)):(rt[rng()%rt.size()]+((rng()%131072)<<18));
std::vector<uint64_t> a,b;Emit ea{a},eb{b};sr::solveUpper13(s,cc.data(),25,ea);fast(s,cc,eb);
std::sort(a.begin(),a.end());std::sort(b.begin(),b.end());if(a!=b)throw std::runtime_error("random differential mismatch");
}
}
std::cout<<"differential_cases=40000 passed"<<std::endl;
// Directly enumerate upper bits as an independent reference, including known-hit planes.
for(int k=0;k<128;k++){
uint64_t s=k<int(baseline.size())?(baseline[k]&((1ull<<35)-1)):(rr[rng()%rr.size()]+((rng()%131072)<<18));
std::vector<uint64_t>a,b;Emit eb{b};fast(s,c,eb);
for(uint64_t h=0;h<8192;h++){
uint64_t seed=s+(h<<35);bool ok=true;
for(auto cell:c)if((sr::nextStateFromTerm(seed,cell.term)>>17)%10){ok=false;break;}
if(ok&&sr::verifyPattern(seed,c.data(),25))a.push_back(seed);
}
std::sort(b.begin(),b.end());if(a!=b)throw std::runtime_error("direct enumeration mismatch");
}
std::cout<<"direct_upper_cases=128 passed"<<std::endl;
auto start=Clock::now();std::vector<unsigned> counts;uint64_t sum=0;unsigned zero=0;
for(int i=0;i<4096;i++){
auto cc=cells(int(rng()%3750000)-1875000,int(rng()%3750000)-1875000);
unsigned n=roots(cc).size();counts.push_back(n);sum+=n;zero+=n==0;
}
std::sort(counts.begin(),counts.end());
std::cout<<"uniform_positions=4096 zero="<<zero<<" roots_mean="<<double(sum)/4096<<" roots_median="<<counts[2048]<<" roots_p95="<<counts[3891]<<" roots_max="<<counts.back()<<" seconds="<<std::chrono::duration<double>(Clock::now()-start).count()<<std::endl;
start=Clock::now();std::vector<uint64_t> tail;
const uint64_t inverse=0xDFE05BCB1365ull;
for(auto cell:c)for(uint64_t v=(uint64_t(2147483640)<<17);v<(1ull<<48);v++){
uint64_t u=((v-11)*inverse)&sr::kMask48;
uint64_t seed=((u^sr::kCombinedXor)-cell.term)&sr::kMask48;
if(sr::verifyPattern(seed,c.data(),25))tail.push_back(seed);
}
std::sort(tail.begin(),tail.end());tail.erase(std::unique(tail.begin(),tail.end()),tail.end());
std::cout<<"rejection_tail_candidates="<<(25ull<<20)<<" exact_unique_matches="<<tail.size()<<" seconds="<<std::chrono::duration<double>(Clock::now()-start).count()<<std::endl;
}