static int do_search(struct saucy *s) { int min; unprepare_permutation(s); /* Backtrack to the ancestor with zeta */ if (s->lev > s->anc) s->lev = s->anc + 1; /* Perform additional backtracking */ min = backtrack(s); /* Keep going while there are tree nodes to expand */ while (s->lev) { /* Descend to a new leaf node */ if (descend(s, &s->right, s->start[s->lev], min) && descend_left(s)) { /* Prepare permutation */ prepare_permutation(s); /* If we found an automorphism, return it */ if (s->is_automorphism(s)) { ++s->stats->gens; s->stats->support += s->ndiffs; update_theta(s); return s->consumer(s->n, s->gamma, s->ndiffs, s->unsupp, s->arg); } else { unprepare_permutation(s); } } /* If we get here, something went wrong; backtrack */ ++s->stats->bads; min = backtrack_bad(s); } /* Normalize group size */ while (s->stats->grpsize_base >= 10.0) { s->stats->grpsize_base /= 10; ++s->stats->grpsize_exp; } return 0; }
int * saucy_search(void) { int i; /* Do initialization steps if necessary */ if (!init) { init = 1; /* Initialize stats */ stats->grpsize_base = 1.0; stats->grpsize_exp = stats->nodes = stats->bads = stats->gens = 0; /* Preprocessing after initial coloring */ refine(); } /* Keep going while there are tree nodes to expand */ while (lev) { if (desc) { desc = 0; descend(); } /* Find a target cell */ ++stats->nodes; target_cell(); if (target != n+1) { descend_left(); continue; } /* We don't have a target, so we're discrete */ if (!have_zeta) { have_zeta = 1; for (i = 0; i < n; ++i) zeta[lab[i]] = i; if (canon != NULL) memcpy(canon, lab, n * sizeof(int)); } else { /* Prepare permutation and check */ for (i = 0; i < n; ++i) gamma[i] = lab[zeta[i]]; is_automorphism(); /* Do some stuff if we actually got an automorphism */ if (flag) { ++stats->gens; update_theta(); } /* Keep track of leaf nodes that are not automorphisms */ else { ++stats->bads; } } /* Since we're discrete, we need to backtrack */ backtrack(stats); desc = 1; if (flag) return gamma; } /* Normalize group size */ while (stats->grpsize_base >= 10.0) { stats->grpsize_base /= 10; ++stats->grpsize_exp; } /* All done */ return NULL; }