Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  dreadnaut.c   Sprache: C

 
/*****************************************************************************
*                                                                            *
* This is the main file for dreadnaut() version 2.7, which is a test-bed     *
*   for nauty() version 2.7 and traces version 2.2.                          *
*                                                                            *
*   Subject to the copyright notice in the file COPYRIGHT.                   *
*                                                                            *
*   CHANGE HISTORY                                                           *
*       10-Nov-87 : final changes for version 1.2                            *
*        5-Dec-87 - replaced all uses of fscanf() by appropriate uses        *
*                   of the new procedures readinteger() and readstring()     *
*                 - changed the '<' command slightly.  If a file of the      *
*                   given name cannot be openned, an attempt is made to      *
*                   open a file with the same name extended by DEFEXT.       *
*                 - improved error processing for 'n' command.               *
*       28-Sep-88 : changes for version 1.4 :                                *
*                 - replaced incorrect %d by %ld in fprintf for ? command    *
*       23-Mar-89 : changes for version 1.5 :                                *
*                 - added optional startup message                           *
*                 - enabled use of refine1 in 'i' command                    *
*                 - implemented $$ command                                   *
*                 - replaced ALLOCS test by DYNALLOC test                    *
*                 - modified @ command and added # command                   *
*                 - declared local procedures static                         *
*       25-Mar-89 - implemented k command                                    *
*       27-Mar-89 - implemented * and I commands                             *
*       29-Mar-89 - implemented K command                                    *
*        2-Apr-89 - added reporting of vertex-invariant statistics           *
*        2-Apr-89 - added ## command                                         *
*        4-Apr-89 - added triples(), quadruples(), adjtriang()               *
*                 - updated error reporting for nauty()                      *
*        5-Apr-89 - removed flushline() from g and e commands                *
*                 - added T command                                          *
*        6-Apr-89 - added cellquads() and distances()                        *
*       26-Apr-89 - modified ? command, added & and && commands              *
*                 - added indsets(), cliques(), cellquins()                  *
*       18-Aug-89 - made g, lab, canong dynamically allocated always         *
*        2-Mar-90 - added celltrips(), cellcliq(), cellind()                 *
*       13-Mar-90 - changed canong and savedg in output to h and h'          *
*       19-Mar-90 - revised help() a little                                  *
*       19-Apr-90 : changes for version 1.6                                  *
*                 - rewrote "*" command to avoid bug in Pyramid C compiler   *
*       20-Apr-90 - rewrote above rewrite to avoid bug in SUN3 gcc           *
*       23-Apr-90 - undid above rewrite and fixed *my* bug <blush> by        *
*                   making NUMINVARS have type int.  Sorry, gcc.             *
*       10-Nov-90 - added calls to null routines (see comment on code)       *
*       27-Aug-92 : renamed to version 1.7, no changes to this file          *
*        5-Jun-93 : renamed to version 1.7+, no changes to this file         *
*       18-Aug-93 : renamed to version 1.8, no changes to this file          *
*       17-Sep-93 : changes for version 1.9 :                                *
*                 - added invariant adjacencies()                            *
*        7-Jun-96 : changes for version 2.0 :                                *
*                 - added invariants cellfano() and cellfano2()              *
*                 - made y=10 the default                                    *
*       11-Jul-96 - added dynamic allocation                                 *
*                 - rewrote h command and added H command                    *
*                 - implemented M and R commands                             *
*       15-Aug-96 - changed z command to use sethash()                       *
*       30-Aug-96 - no need to declare seed; already in naututil.h           *
*       12-Sep-96 - let i and I commands use userrefproc                     *
*        9-Dec-96 - made y=infinity the default                              *
*        6-Sep-97 - allocated arrays before accepting commands               *
*        7-Sep-97 - make g,canong,savedg 1-d arrays even statically          *
*       22-Sep-97 - undid error introduced on 7-Sep (worksize)               *
*        9-Jan-00 - used *_check() instead of *_null()                       *
*       12-Feb-00 - minor code formatting                                    *
*       17-Aug-00 - now use tc_level from DEFAULTOPTIONS                     *
*       16-Nov-00 - made changes listed in nauty.h                           *
*       22-Apr-01 - include nautyinv.h                                       *
*                 - improve worksize processing for MAXN=0                   *
*        5-May-01 - k=0 1 automatic for *, also K=3 or K=0                   *
*        2-Jun-01 - added __ command for digraph converse                    *
*       18-Oct-01 - moved WORKSIZE to here                                   *
*       21-Nov-01 - use NAUTYREQUIRED in *_check() calls                     *
*        1-Sep-02 - Undid the previous change                                *
*       17-Nov-03 - Changed INFINITY to NAUTY_INFINITY                       *
*       15-Nov-04 - Completed all prototypes                                 *
*       23-Nov-06 - no usertcellproc() any more in version 2.4               *
*       10-Nov-09 - removed types shortish and permutation                   *
*       17-Nov-09 - added sparsegraphs, schreier, A and G commands           *
*       19-Nov-09 - added F command, stub for Traces                         *
*        1-Dec-09 - added traces refinement, M also applies to i             *
*       16-Dec-09 - added sr# command for random regular graphs              *
*       19-Dec-09 - added s# command for the sparse case                     *
*                 - w command is in units of 2*m now                         *
*       19-May-10 - Incorporate traces canonical labelling                   *
*        7-Jun-10 - implement %, _ and __ commands for sparse format         *
*        8-Jun-10 - add O and P commands, and sparse && command              *
*       11-Jun-10 - revise command-line parameters                           *
*       14-Jun-10 - digraphs and invariants (top level only) in Traces       *
*       26-Oct-10 - fix u command for sparse graphs; default G=10            *
*       14-Mar-11 - store partition with savedg                              *
*       21-Jul-11 - extend M command                                         *
*       24-Oct-11 - add S and OO commands                                    *
*       15-Jan-12 - use putorbitsplus() if USE_ANSICONTROLS                  *
*       20-Sep-12 - the first argument of ungetc is int, not char            *
*       18-Jan-13 - add code for ^C catching in nauty                        *
*                 - add usercanonproc sample                                 *
*                 - ->> means flush output file                              *
*       14-Nov-14 - fix numcells calculation in 'OO' command                 *
*       16-Mar-15 - add B command                                            *
*       16-Dec-15 - add r& command                                           *
*       22-Jan-16 - commands with short arguments must be all on one line    *
*                 - most errors cause rest of input line to be skipped       *
*       19-Feb-16 - make R command induce a partition if one is defined      *
*                                                                            *
*****************************************************************************/


#include "gtools.h"    /* which includes nauty.h, which includes stdio.h */
#include "nautinv.h"  
#include "schreier.h"
#include "traces.h"

#define USAGE "dreadnaut [-o options]"

#define HELPTEXT \
" Enter nauty+traces test program.\n\
\n\
  -o options  - set initial options.  The parameter value is a string of\n\
                dreadnaut commands from the following set:\n\
                a,c,d,m,p,l,G,P,w,y,$,A,V,M\n\
                The effect is the same as if these commands are entered\n\
                at the beginning of the standard input.\n\
  For help within dreadnaut, use the h command.\n"

#define PM(x) ((x) ? '+' : '-')
#define SS(n,sing,plur)  (n),((n)==1?(sing):(plur))
#define WORKSIZE 60
#define FLUSHANDPROMPT do { flushline(INFILE); if (prompt) fprintf(PROMPTFILE,"> "); } while (0)

#define SORT_OF_SORT 2
#define SORT_NAME sort2ints
#define SORT_TYPE1 int
#define SORT_TYPE2 int
#include "sorttemplates.c"   /* define sort2ints(a,b,n) */

#define INFILE fileptr[curfile]
#define SCHREIER_DEFAULT 10

static long seed;

#if !MAXN
DYNALLSTAT(graph,g,g_sz);
DYNALLSTAT(graph,canong,canong_sz);
DYNALLSTAT(graph,savedg,savedg_sz);
DYNALLSTAT(setword,workspace,workspace_sz);
DYNALLSTAT(int,lab,lab_sz);
DYNALLSTAT(int,ptn,ptn_sz);
DYNALLSTAT(int,orbits,orbits_sz);
DYNALLSTAT(int,templab,templab_sz);
DYNALLSTAT(int,tempptn,tempptn_sz);
DYNALLSTAT(int,perm,perm_sz);
DYNALLSTAT(int,savedlab,savedlab_sz);
DYNALLSTAT(int,savedptn,savedptn_sz);
DYNALLSTAT(set,tempactive,tempactive_sz);
DYNALLSTAT(set,active,active_sz);
#else
static graph g[MAXM*1L*MAXN];
static graph canong[MAXM*1L*MAXN];
static graph savedg[MAXM*1L*MAXN];
static setword workspace[MAXM*2L*WORKSIZE];
static int lab[MAXN];
static int ptn[MAXN];
static int orbits[MAXN];
static int savedlab[MAXN],savedptn[MAXN];
static int perm[MAXN];
static int templab[MAXN];
static int tempptn[MAXN];
static int tempactive[MAXM];
static set active[MAXM];
#endif

static sparsegraph g_sg;
static sparsegraph canong_sg;
static sparsegraph savedg_sg;

static DEFAULTOPTIONS_GRAPH(options);
static DEFAULTOPTIONS_SPARSEGRAPH(options_sg);
static statsblk stats;
static int curfile;
static FILE *fileptr[MAXIFILES];
static FILE *outfile;
static char def_ext[] = DEFEXT;
static boolean firstpath;       /* used in usernode() */

DEFAULTOPTIONS_TRACES(traces_opts);
static TracesStats traces_stats;

#define TMP

#define DENSE_MODE  0
#define SPARSE_MODE 1
#define TRACES_MODE 2
#define SPARSEREP(mode) ((mode)==1||(mode)==2)
#define NOSPARSEYET(c) else if (SPARSEREP(mode)) { fprintf(ERRFILE,\
              "command %s is not implemented in the sparse case\n",c); }
#define NODENSEYET else if (!SPARSEREP(mode)) { fprintf(ERRFILE,\
              "command %c is not implemented in the dense case\n",c); }
#define NOTRACESYET if (mode==TRACES_MODE) {  fprintf(ERRFILE,\
              "command %c is not implemented for Traces\n",c); }

static int mode;

#define U_NODE  1               /* masks for u values */
#define U_AUTOM 2
#define U_LEVEL 4
#define U_TCELL 8     /* At version 2.4, usertcellproc() is gone */
#define U_REF  16
#define U_CANON 32

#ifndef  NODEPROC
#define NODEPROC usernode
#else
extern void NODEPROC(graph*,int*,int*,int,int,int,int,int,int);
#endif

#ifndef  AUTOMPROC
#define AUTOMPROC userautom
#else
extern void AUTOMPROC(int,int*,int*,int,int,int);
#endif

#ifndef  LEVELPROC
#define LEVELPROC userlevel
#else
extern void LEVELPROC(int*,int*,int,int*,statsblk*,int,int,int,int,int,int);
#endif

#ifndef  REFPROC
#define REFPROC NULL
#else
extern void REFPROC(graph*,int*,int*,int,int*,int*,set*,int*,int,int);
#endif

#ifndef  CANONPROC
#define CANONPROC usercanon
#else
extern int CANONPROC(graph*,int*,graph*,unsigned long,int,int,int);
#endif

#ifndef  INVARPROC
#define INVARPROC NULL
#define INVARPROCNAME "none"
#else
extern void INVARPROC(graph*,int*,int*,int,int,int,int*,int,boolean,int,int);
#define INVARPROCNAME "user-defined"
#endif

#ifndef  INVARPROC_SG
#define INVARPROC_SG NULL
#define INVARPROCNAME_SG "none"
#else
extern void INVARPROC_SG(graph*,int*,int*,int,int,int,int*,int,boolean,int,int);
#define INVARPROCNAME_SG "user-defined"
#endif

static struct invarrec
{
    void (*entrypoint)(graph*,int*,int*,int,int,int,int*,int,boolean,int,int);
    char *name;
    void (*entrypoint_sg)(graph*,int*,int*,int,int,int,int*,int,boolean,int,int);
    char *name_sg;
} invarproc[]
    = {{INVARPROC, INVARPROCNAME, INVARPROC_SG, INVARPROCNAME_SG},
       {NULL,        "none",        NULL,           "none"},
       {twopaths,    "twopaths",    NULL,           "unavailable"},
       {adjtriang,   "adjtriang",   NULL,           "unavailable"},
       {triples,     "triples",     NULL,           "unavailable"},
       {quadruples,  "quadruples",  NULL,           "unavailable"},
       {celltrips,   "celltrips",   NULL,           "unavailable"},
       {cellquads,   "cellquads",   NULL,           "unavailable"},
       {cellquins,   "cellquins",   NULL,           "unavailable"},
       {distances,   "distances",   distances_sg,   "distances_sg"},
       {indsets,     "indsets",     NULL,           "unavailable"},
       {cliques,     "cliques",     NULL,           "unavailable"},
       {cellcliq,    "cellcliq",    NULL,           "unavailable"},
       {cellind,     "cellind",     NULL,           "unavailable"},
       {adjacencies, "adjacencies", adjacencies_sg, "adjacencies_sg"},
       {cellfano,    "cellfano",    NULL,           "unavailable"},
       {cellfano2,   "cellfano2",   NULL,           "unavailable"},
       {refinvar,    "refinvar",    NULL,           "unavailable"}
      };
#define NUMINVARS ((int)(sizeof(invarproc)/sizeof(struct invarrec)))

static void help(FILE*, int);
static void userautom(int,int*,int*,int,int,int);
static void usernode(graph*,int*,int*,int,int,int,int,int,int);
static void userlevel(int*,int*,int,int*,statsblk*,int,int,int,int,int,int);
static int usercanon(graph*,int*,graph*,unsigned long,int,int,int);

static boolean options_writeautoms,options_writemarkers,
            options_digraph,options_getcanon,options_linelength;
static int options_invarproc,options_mininvarlevel,options_maxinvarlevel,
            options_invararg,options_tc_level,options_cartesian;
static int options_schreier,options_keepgroup,options_verbosity,
           options_strategy;

#if USE_ANSICONTROLS && !DREADTEST
#define PUTORBITS putorbitsplus
#else
#define PUTORBITS putorbits
#endif

#ifdef  EXTRADECLS
EXTRADECLS
#endif

#if !HAVE_SIGACTION
#undef ALLOW_INTERRUPT
#define ALLOW_INTERRUPT 0
#endif

#if ALLOW_INTERRUPT
/*****************************************************************************
*                                                                            *
*  Routines for catching SIGINT                                              *
*                                                                            *
*****************************************************************************/


void
sigintcatcher(int sig)
/* This is the routine called on SIGINT receipt. */
{
    struct sigaction ss;

    nauty_kill_request = 1;
    ss.sa_handler = SIG_DFL;
    sigemptyset(&ss.sa_mask);
    ss.sa_flags = 0;
    sigaction(SIGINT,&ss,0);
}

static void
setsigcatcher(void)
{
    struct sigaction ss;

    nauty_kill_request = 0;
    ss.sa_handler = sigintcatcher;
    sigemptyset(&ss.sa_mask);
    ss.sa_flags = 0;
    sigaction(SIGINT,&ss,0);
}

static void
unsetsigcatcher(void)
{
    struct sigaction ss;

    nauty_kill_request = 0;
    ss.sa_handler = SIG_DFL;
    sigemptyset(&ss.sa_mask);
    ss.sa_flags = 0;
    sigaction(SIGINT,&ss,0);
}
#else
static void
setsigcatcher(void)
{
}

static void
unsetsigcatcher(void)
{
}
#endif

/*****************************************************************************
*                                                                            *
*  This is a program which illustrates the use of nauty.                     *
*  Commands are read from stdin, and may be separated by white space,        *
*  commas or not separated.  Output is written to stdout.                    *
*  For a short description, see the nauty User's Guide.                      *
*                                                                            *
*****************************************************************************/


int
main(int argc, char *argv[])
{
    int m,n,newm,newn;
    boolean gvalid,ovalid,cvalid,pvalid,minus,prompt,doquot;
    boolean gvalid_sg,cvalid_sg;
    int i,j,k,worksize,numcells,savednc,refcode,umask,qinvar;
    int oldorg,oldmode;
    int maxsize,cell1,cell2;
    boolean ranreg,same;
    char *s1,*s2;
    int c,d;
    unsigned long uli;
    size_t sli;
    set *gp;
    double timebefore,timeafter,mintime;
    char filename[515];
    int sgn,sgorg,nperm;
    int multiplicity,actmult;
    long zseed;
    permnode *generators;
    char *ap,*parameters;
    boolean flushing;

    HELP; PUTVERSION;

    if (argc == 3 && strcmp(argv[1],"-o") == 0)
        parameters = argv[2];
    else if (argc != 1)
    {
        fprintf(ERRFILE,USAGE);
        exit(1);
    }
    else
        parameters = "";
 
    mode = DENSE_MODE;
    curfile = 0;
    fileptr[curfile] = stdin;
#ifdef DREADTEST
    prompt = FALSE;
#else
    prompt = DOPROMPT(INFILE);
#endif
    outfile = stdout;
    options_writeautoms = options_writemarkers = TRUE;
    options_digraph = FALSE;
    options_getcanon = options.getcanon;
    options_mininvarlevel = options.mininvarlevel;
    options_maxinvarlevel = options.maxinvarlevel;
    options_invararg = options.invararg;
    options_invarproc = 1; /* index into invarproc[] */
    options_tc_level = options.tc_level;
    options_cartesian = options.cartesian;
    options_linelength = options.linelength;
    options_schreier = SCHREIER_DEFAULT;
    options_keepgroup = FALSE;
    generators = NULL;
    options_verbosity = 1;
    options_strategy = 0;

    n = m = 1;
    worksize = WORKSIZE;

#if !MAXN
    n = WORDSIZE;
    DYNALLOC2(graph,g,g_sz,n,m,"dreadnaut");
    DYNALLOC1(int,lab,lab_sz,n,"dreadnaut");
    DYNALLOC1(int,ptn,ptn_sz,n,"dreadnaut");
    DYNALLOC1(int,orbits,orbits_sz,n,"dreadnaut");
    DYNALLOC1(int,perm,perm_sz,n,"dreadnaut");
    DYNALLOC1(set,active,active_sz,m,"dreadnaut");
    n = 1;
#endif

#ifdef DREADTEST
    seed = 1;
    ran_init(seed);
#else
    seed = ran_init_time(0);
#endif

    umask = 0;
    pvalid = FALSE;
    ovalid = FALSE;
    gvalid = gvalid_sg = FALSE;  /* at most one valid */
    cvalid = cvalid_sg = FALSE;  /* at most one valid */
    sgorg = labelorg = oldorg = 0;
    sgn = 0;
    multiplicity = 1;
    mintime = 0.0;
    flushing = FALSE;

#ifdef  INITIALIZE
    INITIALIZE;
#endif

    if (prompt)
    {
        fprintf(PROMPTFILE,"Dreadnaut version %s.\n",NAUTYVERSION);
        fprintf(PROMPTFILE,"> ");
    }

    nauty_check(WORDSIZE,1,1,NAUTYVERSIONID);
    nautinv_check(WORDSIZE,1,1,NAUTYVERSIONID);
    nautil_check(WORDSIZE,1,1,NAUTYVERSIONID);
    naututil_check(WORDSIZE,1,1,NAUTYVERSIONID);
    nausparse_check(WORDSIZE,1,1,NAUTYVERSIONID);

    SG_INIT(g_sg);
    SG_INIT(canong_sg);
    SG_INIT(savedg_sg);

    minus = FALSE;
    for (ap = parameters; *ap != '\0'; )
    {
        c = *ap++;

        switch (c)
        {
        case ' ':
        case '\t':
            break;

        case '-':
            minus = TRUE;
            break;

        case '+':
            minus = FALSE;
            break;

        case 'a'
            options_writeautoms = !minus;
            minus = FALSE;
            break;

        case 'c'
            options_getcanon = !minus;
            minus = FALSE;
            break;

        case 'm'
            options_writemarkers = !minus;
            minus = FALSE;
            break;

        case 'p'
            options_cartesian = !minus;
            minus = FALSE;
            break;

        case 'B'
            flushing = !minus;
            minus = FALSE;
            break;

        case 'd'
            options_digraph = !minus;
            minus = FALSE;
            break;

        case 'P'
            options_keepgroup = !minus;
            minus = FALSE;
            break;

        case 'w':
            while (*ap == '=' || *ap == ' ') ++ap;
            arg_int(&ap,&worksize,"w");
#if MAXN
            if (worksize > 2*MAXM*WORKSIZE)
            {
                fprintf(ERRFILE,
                   "too big - setting worksize = %d\n",WORKSIZE);
                worksize = WORKSIZE;
            }
#endif
            minus = FALSE;
            break;

        case 'V':
            if (minus)
            {
                options_verbosity = 0;
                minus = FALSE;
            }
            else
            {
                while (*ap == '=' || *ap == ' ') ++ap;
                arg_int(&ap,&i,"V");
                if (i < 0) fprintf(ERRFILE,"verbosity must be >= 0\n");
                else       options_verbosity = i;
            }
            break;


        case 'S':
            if (minus)
            {
                options_strategy = 0;
                minus = FALSE;
            }
            else
            {
                while (*ap == '=' || *ap == ' ') ++ap;
                arg_int(&ap,&i,"S");
/*
                if (i < 0) fprintf(ERRFILE,"strategy must be >= 0\n");
                else       options_strategy = i;
*/

                if (i != 0) fprintf(ERRFILE,
                      "Only strategy 0 is supported in this version\n");
            }
            break;

        case 'G'
            if (minus)
            {
                options_schreier = 0;
                minus = FALSE;
            }
            else
            {
                while (*ap == '=' || *ap == ' ') ++ap;
                arg_int(&ap,&i,"G");
                if (i < 0)
                    fprintf(ERRFILE,"schreierfails must be >= 0\n");
                else
                {
                    options_schreier = i;
                    if (i > 0) schreier_fails(i);
                }
            }
            break;

        case 'y'
            while (*ap == '=' || *ap == ' ') ++ap;
            arg_int(&ap,&options_tc_level,"y");
            minus = FALSE;
            break;

        case '$'
            while (*ap == '=' || *ap == ' ') ++ap;
            arg_int(&ap,&labelorg,"$");
            minus = FALSE;
            break;

        case 'M'
            if (minus)
            {
                multiplicity = 1;
                mintime = 0.0;
                minus = FALSE;
            }
            else
            {
                actmult = 0;
                while (*ap == '=' || *ap == ' ') ++ap;
                arg_int(&ap,&multiplicity,"M");
                if (*ap == '/')
                {
                    ++ap;
                    arg_int(&ap,&actmult,"M/");
                }
                if (multiplicity < 0) multiplicity = 0;
                if (actmult < 0) actmult = 0;
                if (multiplicity == 0 && actmult == 0) multiplicity = 1;
                mintime = (double)actmult;
            }
            break;

        case 'l'
            while (*ap == '=' || *ap == ' ') ++ap;
            arg_int(&ap,&options_linelength,"l");
            minus = FALSE;
            break;

        case 'A'
            d = *ap++;
            if (d == 'n' || d == 'N' || d == 'd' || d == 'D')
                mode = DENSE_MODE;
            else if (d == 's' || d == 'S') mode = SPARSE_MODE;
            else if (d == 't' || d == 'T') mode = TRACES_MODE;
            else
            {
                fprintf(ERRFILE,"Mode %c is unknown\n",(d?d:'0'));
                break;
            }
            minus = FALSE;
            break;

        default:
            fprintf(ERRFILE,"Illegal initialization command %c\n",c);
            exit(1);
        }
    }

    minus = FALSE;
    while (curfile >= 0)
    {
        if ((c = getc(INFILE)) == EOF || c == '\004')
        {
            fclose(INFILE);
            --curfile;
            if (curfile >= 0) prompt = DOPROMPT(INFILE);
        }
        else switch (c)
        {
        case '\n':  /* possibly issue prompt */
            if (prompt) fprintf(PROMPTFILE,"> ");
            minus = FALSE;
            break;

        case ' ':   /* do nothing */
        case '\t':
#ifndef  NLMAP
        case '\r':
#endif
        case '\f':
            break;

        case '-':   /* remember this for next time */
            minus = TRUE;
            break;

        case '+':   /* forget - */
        case ',':
        case ';':
            minus = FALSE;
            break;

        case '<':   /* new input file */
            minus = FALSE;
            if (curfile == MAXIFILES - 1)
            {
                fprintf(ERRFILE,"exceeded maximum input nesting of %d\n",
                        MAXIFILES);
                FLUSHANDPROMPT;
                break;
            }
            if (!readstring(INFILE,filename,513))
            {
                fprintf(ERRFILE,
                        "missing file name on '<' command : ignored\n");
                break;
            }
            if ((fileptr[curfile+1] = fopen(filename,"r")) == NULL)
            {
                for (s1 = filename; *s1 != '\0'; ++s1) {}
                for (s2 = def_ext; (*s1 = *s2) != '\0'; ++s1, ++s2) {}
                fileptr[curfile+1] = fopen(filename,"r");
            }
            if (fileptr[curfile+1] != NULL)
            {
                ++curfile;
                prompt = DOPROMPT(INFILE);
                if (prompt)
                    fprintf(PROMPTFILE,"> ");
            }
            else
            {
                fprintf(ERRFILE,"can't open input file\n");
                FLUSHANDPROMPT;
            }
            break;

        case '>':   /* new output file, or flush output file */
            if ((d = getc(INFILE)) != '>') ungetc(d,INFILE);
            if (minus)
            {
                minus = FALSE;
                if (d == '>')
                    fflush(outfile);
                else if (outfile != stdout)
                {
                    fclose(outfile);
                    outfile = stdout;
                }
            }
            else
            {
                if (!readstring(INFILE,filename,513))
                {
                    fprintf(ERRFILE,
                        "improper file name, reverting to stdout\n");
                    outfile = stdout;
                    FLUSHANDPROMPT;
                    break;
                }
                OPENOUT(outfile,filename,d=='>');
                if (outfile == NULL)
                {
                    fprintf(ERRFILE,
                        "can't open output file, reverting to stdout\n");
                    outfile = stdout;
                    FLUSHANDPROMPT;
                }
            }
            break;

        case 'B'
            flushing = !minus;
            minus = FALSE;
            break;

        case '!':   /* ignore rest of line */
            do
                c = getc(INFILE);
            while (c != '\n' && c != EOF);
            if (c == '\n') ungetc('\n',INFILE);
            break;

        case 'n':   /* read n value */
            minus = FALSE;
            i = getint_sl(INFILE);
            if (i <= 0 || (MAXN && i > MAXN)
                       || (!MAXN && i > NAUTY_INFINITY-2))
            {
                fprintf(ERRFILE,
                     " n can't be less than 1 or more than %d\n",
                       MAXN ? MAXN : NAUTY_INFINITY-2);
                FLUSHANDPROMPT;
            }
            else
            {
                gvalid = FALSE;
                cvalid = FALSE;
                gvalid_sg = FALSE;
                cvalid_sg = FALSE;
                pvalid = FALSE;
                ovalid = FALSE;
                n = i;
                m = SETWORDSNEEDED(n);
                freeschreier(NULL,&generators); 
#if !MAXN
                DYNALLOC1(int,lab,lab_sz,n,"dreadnaut");
                DYNALLOC1(int,ptn,ptn_sz,n,"dreadnaut");
                DYNALLOC1(int,orbits,orbits_sz,n,"dreadnaut");
                DYNALLOC1(int,perm,perm_sz,n,"dreadnaut");
                DYNALLOC1(set,active,active_sz,m,"dreadnaut");
#endif
            }
            break;

        case 'g':   /* read graph */
            minus = FALSE;
            if (SPARSEREP(mode))
            {
                readgraph_sg(INFILE,&g_sg,options_digraph,prompt,
                             options_linelength,n);
                gvalid_sg = TRUE;
                cvalid_sg = FALSE;
            }
            else
            {
#if !MAXN
                DYNALLOC2(graph,g,g_sz,n,m,"dreadnaut");
#endif
                readgraph(INFILE,g,options_digraph,prompt,FALSE,
                          options_linelength,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
            }
            ovalid = FALSE;
            break;

        case 'e':   /* edit graph */
            minus = FALSE;
            if (SPARSEREP(mode))
            {
                fprintf(ERRFILE,"e command only works in dense mode\n");
                FLUSHANDPROMPT;
            }
            else
            {
                readgraph(INFILE,g,options_digraph,prompt,gvalid,
                          options_linelength,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
                ovalid = FALSE;
            }
            break;

        case 'r':   /* relabel graph and current partition */
            minus = FALSE;
            if ((d = getc(INFILE)) != '&') ungetc(d,INFILE);
            if (gvalid_sg)
            {
                if (d == '&')
                {
                    if (pvalid)
                        relabel_sg(&g_sg,lab,lab,&canong_sg);
                }
                else
                {
                    readvperm(INFILE,perm,prompt,n,&nperm);
                    relabel_sg(&g_sg,(pvalid ? lab : NULL),perm,&canong_sg);
                }
                cvalid_sg = FALSE;
                ovalid = FALSE;
            }
            else if (gvalid)
            {
                if (d == '&')
                {
                    if (pvalid)
                    {
#if !MAXN
                        DYNALLOC2(graph,canong,canong_sz,n,m,"dreadnaut");
#endif
                        relabel(g,lab,lab,canong,m,n);
                    }
                }
                else
                {
#if !MAXN
                    DYNALLOC2(graph,canong,canong_sz,n,m,"dreadnaut");
#endif
                    readvperm(INFILE,perm,prompt,n,&nperm);
                    relabel(g,(pvalid ? lab : NULL),perm,canong,m,n);
                }
                cvalid = FALSE;
                ovalid = FALSE;
            }
            else
            {
                fprintf(ERRFILE,"g is not defined\n");
                FLUSHANDPROMPT;
            }
            break;

        case 'R':   /* form subgraph */
            if (gvalid)
            {
#if !MAXN
                DYNALLOC2(graph,canong,canong_sz,n,m,"dreadnaut");
#endif
                readvperm(INFILE,perm,prompt,n,&nperm);
                if ((minus && nperm == n) || (!minus && nperm == 0))
                {
                    fprintf(ERRFILE,"can't form null graph\n");
                    FLUSHANDPROMPT;
                }
                else if (minus)
                {
                    sublabel(g,perm+nperm,n-nperm,canong,m,n);
                    if (pvalid) numcells = subpartition(lab,ptn,n,perm+nperm,n-nperm);
                    n = n - nperm;
                }
                else
                {
                    sublabel(g,perm,nperm,canong,m,n);
                    if (pvalid) numcells = subpartition(lab,ptn,n,perm,nperm);
                    n = nperm;
                }
                cvalid = FALSE;
                ovalid = FALSE;
                m = SETWORDSNEEDED(n);
            }
            else if (gvalid_sg)
            {
                readvperm(INFILE,perm,prompt,n,&nperm);
                if ((minus && nperm == n) || (!minus && nperm == 0))
                {
                    fprintf(ERRFILE,"can't form null graph\n");
                    FLUSHANDPROMPT;
                }
                else if (minus)
                {
                    sublabel_sg(&g_sg,perm+nperm,n-nperm,&canong_sg);
                    if (pvalid) numcells = subpartition(lab,ptn,n,perm+nperm,n-nperm);
                    n = n - nperm;
                }
                else
                {
                    sublabel_sg(&g_sg,perm,nperm,&canong_sg);
                    if (pvalid) numcells = subpartition(lab,ptn,n,perm,nperm);
                    n = nperm;
                }
                cvalid_sg = FALSE;
                ovalid = FALSE;
                m = SETWORDSNEEDED(n);
            }
            else
            {
                fprintf(ERRFILE,"g is not defined\n");
                FLUSHANDPROMPT;
            }
            minus = FALSE;
            break;

        case '_':   /* complement graph or converse digraph */
            minus = FALSE;
            if ((d = getc(INFILE)) != '_') ungetc(d,INFILE);

            if (!gvalid && !gvalid_sg)
            {
                fprintf(ERRFILE,"g is not defined\n");
                FLUSHANDPROMPT;
            }
            else if (gvalid)
            {
                if (d == '_') converse(g,m,n);
                else          complement(g,m,n);
                cvalid = FALSE;
            }
            else
            {
                if (d == '_')
                {
                    copy_sg(&g_sg,&canong_sg);
                    converse_sg(&canong_sg,&g_sg);
                    cvalid_sg = FALSE;
                }
                else
                {
                    copy_sg(&g_sg,&canong_sg);
                    complement_sg(&canong_sg,&g_sg);
                    cvalid_sg = FALSE;
                }
            }
            break;

        case '@':   /* copy canong into savedg */
            minus = FALSE;
            if (cvalid)
            {
#if !MAXN
                DYNALLOC2(graph,savedg,savedg_sz,n,m,"dreadnaut");
                DYNALLOC1(int,savedlab,savedlab_sz,n,"dreadnaut");
                DYNALLOC1(int,savedptn,savedptn_sz,n,"dreadnaut");
#endif
                sgn = n;
                memcpy(savedg,canong,m*(size_t)n*sizeof(setword));
                for (i = n; --i >= 0;)
                {
                    savedlab[i] = lab[i];
                    savedptn[i] = ptn[i];
                }
                sgorg = labelorg;
            }
            else if (cvalid_sg)
            {
#if !MAXN
                DYNALLOC1(int,savedlab,savedlab_sz,n,"dreadnaut");
                DYNALLOC1(int,savedptn,savedptn_sz,n,"dreadnaut");
#endif
                sgn = n;
                copy_sg(&canong_sg,&savedg_sg);
                for (i = n; --i >= 0;)
                {
                    savedlab[i] = lab[i];
                    savedptn[i] = ptn[i];
                }
                sgorg = labelorg;
            }
            else
            {
                fprintf(ERRFILE,"h is not defined\n");
                FLUSHANDPROMPT;
            }
            break;

        case '#':   /* compare canong to savedg */
            if ((d = getc(INFILE)) != '#') ungetc(d,INFILE);

            if (cvalid || cvalid_sg)
            {
                if (sgn > 0)
                {
                    if (sgn != n)
                        fprintf(outfile,
                              "h and h' have different sizes.\n");
                    else
                    {
                        if (cvalid)
                        {
                            for (sli = 0; sli < m*(size_t)n; ++sli)
                                if (savedg[sli] != canong[sli]) break;
                            same = (sli == m*(size_t)n); 
                        }
                        else
                            same = aresame_sg(&canong_sg,&savedg_sg);

                        if (!same)
                            fprintf(outfile,"h and h' are different.\n");
                        else
                        {
                            for (i = 0; i < n; ++i)
                                if ((ptn[i] == 0) != (savedptn[i] == 0))
                                    break;
                            if (i < n)
                                fprintf(outfile,
                 "h and h' are identical but have incompatible colourings.\n");
                            else
                                fprintf(outfile,
                                    "h and h' are identical.\n");
                            if (d == '#')
                                putmapping(outfile,savedlab,sgorg,
                                       lab,labelorg,options_linelength,n);
                        }
                    }
                }
                else
                {
                    fprintf(ERRFILE,"h' is not defined\n");
                    FLUSHANDPROMPT;
                }
            }
            else
            {
                fprintf(ERRFILE,"h is not defined\n");
                FLUSHANDPROMPT;
            }
            break;

        case 'j':   /* relabel graph randomly */
            minus = FALSE;
            if (gvalid)
            {
                ranperm(perm,n);
#if !MAXN
                DYNALLOC2(graph,canong,canong_sz,n,m,"dreadnaut");
#endif
                relabel(g,(pvalid?lab:NULL),perm,canong,m,n);
                cvalid = FALSE;
                ovalid = FALSE;
                freeschreier(NULL,&generators);
            }
            else if (gvalid_sg)
            {
                ranperm(perm,n);
                relabel_sg(&g_sg,(pvalid?lab:NULL),perm,&canong_sg);
                cvalid_sg = FALSE;
                ovalid = FALSE;
                freeschreier(NULL,&generators);
            }
            else
            {
                fprintf(ERRFILE,"g is not defined\n");
                FLUSHANDPROMPT;
            }
            break;

        case 'v':   /* write vertex degrees */
            minus = FALSE;
            if ((d = getc(INFILE)) != 'v') ungetc(d,INFILE);

            if (gvalid)
            {
                if (d == 'v') putdegseq(outfile,g,options_linelength,m,n);
                else          putdegs(outfile,g,options_linelength,m,n);
            }
            else if (gvalid_sg)
            {
                if (d == 'v') putdegseq_sg(outfile,&g_sg,options_linelength);
                else          putdegs_sg(outfile,&g_sg,options_linelength);
            }
            else
            {
                fprintf(ERRFILE,"g is not defined\n");
                FLUSHANDPROMPT;
            }
            break;

        case '%':   /* do Mathon doubling operation */
            minus = FALSE;
            if (gvalid || gvalid_sg)
            {
#if !MAXN
                if (2L * ((long)n + 1L) > NAUTY_INFINITY-2)
                {
                    fprintf(ERRFILE,
                         "n can't be more than %d\n",NAUTY_INFINITY-2);
                    break;
                }
#else
                if (2L * ((long)n + 1L) > MAXN)
                {
                    fprintf(ERRFILE,"n can't be more than %d\n",MAXN);
                    FLUSHANDPROMPT;
                    break;
                }
#endif
                newn = 2 * (n + 1);
                newm = SETWORDSNEEDED(newn);
#if !MAXN
                DYNALLOC1(int,lab,lab_sz,newn,"dreadnaut");
                DYNALLOC1(int,ptn,ptn_sz,newn,"dreadnaut");
                DYNALLOC1(int,orbits,orbits_sz,newn,"dreadnaut");
                DYNALLOC1(int,perm,perm_sz,newn,"dreadnaut");
                DYNALLOC1(set,active,active_sz,newm,"dreadnaut");
#endif
                ovalid = FALSE;
                pvalid = FALSE;
                freeschreier(NULL,&generators);
            }
            else
            {
                fprintf(ERRFILE,"g is not defined\n");
                FLUSHANDPROMPT;
            }

            if (gvalid)
            {
#if !MAXN
                DYNALLOC2(graph,canong,canong_sz,n,m,"dreadnaut");
#endif
                memcpy(canong,g,m*(size_t)n*sizeof(setword));

#if !MAXN
                DYNALLOC2(graph,g,g_sz,newn,newm,"dreadnaut");
#endif
                mathon(canong,m,n,g,newm,newn);
                m = newm;
                n = newn;
                cvalid = FALSE;
            }
            else if (gvalid_sg)
            {
                copy_sg(&g_sg,&canong_sg);
                mathon_sg(&canong_sg,&g_sg);
                m = newm;
                n = newn;
                cvalid_sg = FALSE;
            }
            break;

        case 's':   /* generate random graph */
            minus = FALSE;
            d = getc(INFILE);
            if (d == 'r')
                ranreg = TRUE;
            else
            {
                ranreg = FALSE;
                if (d != EOF) ungetc(d,INFILE);
            }

            i = getint_sl(INFILE);
            if (ranreg)
            {
                if (i < 0) i = 3;
                if (i > MAXREG)
                {
                    fprintf(ERRFILE,"sr is limited to degree %d\n",MAXREG);
                    FLUSHANDPROMPT;
                    break;
                }
                if (SPARSEREP(mode))
                {
                    ranreg_sg(&g_sg,i,n);
                    gvalid_sg = TRUE;
                    cvalid = FALSE;
                    ovalid = FALSE;
                    freeschreier(NULL,&generators);
                }
                NODENSEYET
            }
            else
            {
                if (i <= 0) i = 2;
                if (!SPARSEREP(mode))
                {
#if !MAXN
                    DYNALLOC2(graph,g,g_sz,n,m,"dreadnaut");
#endif
                    rangraph(g,options_digraph,i,m,n);
                    gvalid = TRUE;
                    cvalid = FALSE;
                    ovalid = FALSE;
                    freeschreier(NULL,&generators);
                }
                else
                {
                    rangraph2_sg(&g_sg,options_digraph,1,i,n);
                    gvalid_sg = TRUE;
                    cvalid = FALSE;
                    ovalid = FALSE;
                    freeschreier(NULL,&generators);
                }
            }
            break;

        case 'q':   /* quit */
            EXIT;
            break;

        case '"':   /* copy comment to output */
            minus = FALSE;
            copycomment(INFILE,outfile,'"');
            break;

        case 'I':   /* do refinement and invariants procedure */
            minus = FALSE;
            if (!gvalid && !gvalid_sg)
            {
                fprintf(ERRFILE,"g is not valid\n");
                FLUSHANDPROMPT;
                break;
            }
            if (!pvalid) unitptn(lab,ptn,&numcells,n);
            cellstarts(ptn,0,active,m,n);
#ifdef  CPUTIME
            timebefore = CPUTIME;
#endif
            if (gvalid)
            {
                doref(g,lab,ptn,0,&numcells,&qinvar,perm,active,&refcode,
                    options.userrefproc ? options.userrefproc : 
                    (m == 1 ? refine1 : refine),
                    invarproc[options_invarproc].entrypoint,0,0,
                    options_invararg,options_digraph,m,n);
                if (numcells > 1) pvalid = TRUE;
            }
            else if (gvalid_sg)
            {
                doref((graph*)&g_sg,lab,ptn,0,&numcells,&qinvar,perm,
                    active,&refcode,
                    options_sg.userrefproc ? options_sg.userrefproc : 
                    refine_sg,
                    invarproc[options_invarproc].entrypoint_sg,0,0,
                    options_invararg,options_digraph,m,n);
                if (numcells > 1) pvalid = TRUE;
            }
            else
            {
                fprintf(ERRFILE,"g is not valid\n");
                FLUSHANDPROMPT;
                break;
            }
#ifdef  CPUTIME
            timeafter = CPUTIME;
#endif
            fprintf(outfile," %d cell%s; code = %x",
                    SS(numcells,"","s"),refcode);
            if (mode == SPARSE_MODE)
            {
                if (invarproc[options_invarproc].entrypoint_sg)
                    fprintf(outfile,
                       " (%s %s)",invarproc[options_invarproc].name_sg,
                       (qinvar == 2 ? "worked" : "failed"));
            }
            else if (mode == DENSE_MODE)
            {
                if (invarproc[options_invarproc].entrypoint)
                    fprintf(outfile,
                       " (%s %s)",invarproc[options_invarproc].name,
                       (qinvar == 2 ? "worked" : "failed"));
            }
#ifdef  CPUTIME
            fprintf(outfile,"; cpu time = %.2f seconds\n",
                    timeafter-timebefore);
#else
            fprintf(outfile,"\n");
#endif
            if (numcells > 1) pvalid = TRUE;
            break;

        case 'i':   /* do refinement */
            minus = FALSE;
            if (!gvalid && !gvalid_sg)
            {
                fprintf(ERRFILE,"g is not valid\n");
                FLUSHANDPROMPT;
                break;
            }
            if (!pvalid) unitptn(lab,ptn,&numcells,n);
            cellstarts(ptn,0,active,m,n);

            if (multiplicity != 0 || mintime != 0.0)
            {
                savednc = numcells;
#if !MAXN
                DYNALLOC1(int,tempptn,tempptn_sz,n,"dreadnaut");
                DYNALLOC1(int,templab,templab_sz,n,"dreadnaut");
                DYNALLOC1(set,tempactive,tempactive_sz,m,"dreadnaut");
#endif
                memcpy(templab,lab,n*sizeof(int));
                memcpy(tempptn,ptn,n*sizeof(int));
                for (i = 0; i < m; ++i) tempactive[i] = active[i];
            }

#ifdef  CPUTIME
            timebefore = CPUTIME;
#endif
            actmult = 0;
            for (;;)
            {
                if (actmult > 0)
                {
                    memcpy(lab,templab,n*sizeof(int));
                    memcpy(ptn,tempptn,n*sizeof(int));
                    for (i = 0; i < m; ++i) active[i] = tempactive[i];
                    numcells = savednc;
                }

                if (options.userrefproc)
                    (*options.userrefproc)
                         (g,lab,ptn,0,&numcells,perm,active,&refcode,m,n);
                else if (gvalid)
                {
                    if (m == 1)
                        refine1(g,lab,ptn,0,&numcells,perm,active,&refcode,m,n);
                    else
                        refine(g,lab,ptn,0,&numcells,perm,active,&refcode,m,n);
                }
                else if (mode == SPARSE_MODE)
                    refine_sg((graph*)&g_sg,lab,ptn,0,&numcells,perm,active,
                                                                 &refcode,m,n);
                else  /* traces mode */
                    refine_tr(&g_sg,lab,ptn,&numcells,&refcode,&traces_opts);

                ++actmult;
                if (multiplicity > 0 && actmult >= multiplicity) break;
#ifdef  CPUTIME
                if (mintime > 0.0 && (actmult < 20 || !(actmult&7)) 
                        && CPUTIME >= timebefore+mintime)
                    break;
#endif
            }
#ifdef  CPUTIME
            timeafter = CPUTIME;
#endif
            if (numcells > 1) pvalid = TRUE;
            fprintf(outfile," %d cell%s; code = %x",
                    SS(numcells,"","s"),refcode);
#ifdef  CPUTIME
            fprintf(outfile,"; cpu time = %.7f seconds\n",
                              (timeafter-timebefore)/actmult);
#else
            fprintf(outfile,"\n");
#endif
            break;

        case 'x':   /* execute nauty */
            minus = FALSE;
            if (mode == TRACES_MODE)
            {
                ovalid = FALSE;
                cvalid_sg = FALSE;
                if (!gvalid_sg)
                {
                    fprintf(ERRFILE,"g is not defined\n");
                    FLUSHANDPROMPT;
                    break;
                }

                traces_opts.getcanon = options_getcanon;
                traces_opts.writeautoms = options_writeautoms;
                traces_opts.cartesian = options_cartesian;
                traces_opts.linelength = options_linelength;
                traces_opts.digraph = options_digraph;
                traces_opts.outfile = outfile;
                traces_opts.verbosity = options_verbosity;
                traces_opts.strategy = options_strategy;
                if (options_keepgroup)
                    traces_opts.generators = &generators;
                else
                    traces_opts.generators = NULL;

#if !MAXN
                DYNALLOC1(int,tempptn,tempptn_sz,n,"dreadnaut"); 
#endif
                if (!pvalid) unitptn(lab,ptn,&numcells,n);
                memcpy(tempptn,ptn,n*sizeof(int));
                savednc = numcells;
                if (options_invarproc != 1 && options_maxinvarlevel > 0)
                {
                    if (options_maxinvarlevel > 1) fprintf(ERRFILE,
                    "Warning: Traces only uses invariants at the top level\n");
                    if (invarproc[options_invarproc].entrypoint_sg)
                    {
#ifdef  CPUTIME
                        timebefore = CPUTIME;
#endif
                        cellstarts(tempptn,0,active,m,n);
                        doref((graph*)&g_sg,lab,tempptn,0,&savednc,&qinvar,perm,
                            active,&refcode,
                            options_sg.userrefproc ? options_sg.userrefproc : 
                            refine_sg,
                            invarproc[options_invarproc].entrypoint_sg,0,0,
                            options_invararg,options_digraph,m,n);
                        fprintf(outfile,"Invariant %s %s; %d cell%s",
                            invarproc[options_invarproc].name_sg,
                            (qinvar == 2 ? "worked" : "failed"),
                            SS(savednc,"","s"));
#ifdef  CPUTIME
                        timeafter = CPUTIME;
                        fprintf(outfile,"; cpu time = %.2f seconds\n",
                            timeafter-timebefore);
#else
                        fprintf(outfile,"\n");
#endif
                    }
                }

#ifdef  CPUTIME
                timebefore = CPUTIME;
#endif
                actmult = 0;
                setsigcatcher(); 
                for (;;)
                {
                    traces_opts.defaultptn = !pvalid;
                    Traces(&g_sg,lab,tempptn,orbits,&traces_opts,&traces_stats,
                       &canong_sg);
                    if (traces_stats.errstatus) break;
                    traces_opts.writeautoms = FALSE;
                    traces_opts.verbosity = 0;
                    ++actmult;
                    if (multiplicity > 0 && actmult >= multiplicity) break;
#ifdef  CPUTIME
                    if (mintime > 0.0 && (actmult < 20 || !(actmult&7))
                            && CPUTIME >= timebefore+mintime)
                        break;
#endif
                }
                unsetsigcatcher(); 
#ifdef  CPUTIME
                timeafter = CPUTIME;
#endif
            if (traces_stats.errstatus)
            {
                if (traces_stats.errstatus == NAUABORTED)
                    fprintf(ERRFILE,"Traces aborted\n");
                else if (traces_stats.errstatus == NAUKILLED)
                    fprintf(ERRFILE,"Traces interrupted\n");
                else
                    fprintf(ERRFILE,
                      "Traces returned error status %d [this can't happen]\n",
                      traces_stats.errstatus);
                cvalid = cvalid_sg = ovalid = FALSE;
            }
            else
            {
                fprintf(outfile,"%d orbit%s",
                                SS(traces_stats.numorbits,"","s"));
                fprintf(outfile,"; grpsize=");
                writegroupsize(outfile,
                               traces_stats.grpsize1,traces_stats.grpsize2);
                fprintf(outfile,"; %d gen%s",
                     SS(traces_stats.numgenerators,"","s"));
                fprintf(outfile,
                     "; %lu node%s ", SS(traces_stats.numnodes,"","s"));
                if (traces_stats.interrupted)
                    fprintf(outfile,
                            "(%lu interrupted, ",traces_stats.interrupted);
                else
                    fprintf(outfile,"(");
                fprintf(outfile,"%lu peak); maxlev=%d\n",
                    traces_stats.peaknodes,traces_stats.treedepth);
                if (options_getcanon)
                    fprintf(outfile,
                            "canupdates=%d; ",traces_stats.canupdates);
#ifdef  CPUTIME
                fprintf(outfile,actmult == 1 ?
                              "cpu time = %.2f seconds\n" :
                              "cpu time = %.7f seconds\n",
                              (timeafter-timebefore)/actmult);
#else
                fprintf(outfile,"\n");
#endif
                if (options_getcanon) cvalid_sg = TRUE;
                ovalid = TRUE;
            } 
            }
            else 
            {
                ovalid = FALSE;
                cvalid = cvalid_sg = FALSE;
                if (!gvalid && !gvalid_sg)
                {
                    fprintf(ERRFILE,"g is not defined\n");
                    FLUSHANDPROMPT;
                    break;
                }
                if (mode == DENSE_MODE)
                {
                    if (pvalid)
                    {
                        fprintf(outfile,"[fixing partition]\n");
                        options.defaultptn = FALSE;
                    }
                    else
                        options.defaultptn = TRUE;

                    options.outfile = outfile;
                    options.digraph = options_digraph;
                    options.cartesian = options_cartesian;
                    options.schreier = (options_schreier > 0);
                    options.getcanon = options_getcanon;
                    options.tc_level = options_tc_level;
                    options.linelength = options_linelength;
                    options.invarproc
                                = invarproc[options_invarproc].entrypoint;
                    options.mininvarlevel = options_mininvarlevel;
                    if (options.invarproc)
                       options.maxinvarlevel = options_maxinvarlevel;
                    else
                       options.maxinvarlevel = 0;
                    options.invararg = options_invararg;
                    if (options_schreier > 0)
                        schreier_fails(options_schreier);

                    if (umask & U_NODE)  options.usernodeproc = NODEPROC;
                    else                 options.usernodeproc = NULL;
                    if (umask & U_AUTOM) options.userautomproc = AUTOMPROC;
                    else                 options.userautomproc = NULL;
                    if (umask & U_LEVEL) options.userlevelproc = LEVELPROC;
                    else                 options.userlevelproc = NULL;
                    if (umask & U_REF)   options.userrefproc = REFPROC;
                    else                 options.userrefproc = NULL;
                    if (umask & U_CANON) options.usercanonproc = CANONPROC;
                    else                 options.usercanonproc = NULL;
#if !MAXN
                    if (options_getcanon)
                        DYNALLOC2(graph,canong,canong_sz,n,m,"dreadnaut");
                    DYNALLOC1(setword,workspace,workspace_sz,2*m*worksize,
                                                                "dreadnaut");
#endif
                    firstpath = TRUE;
                    options.writeautoms = options_writeautoms;
                    options.writemarkers = options_writemarkers;
#ifdef  CPUTIME
                    timebefore = CPUTIME;
#endif
                    actmult = 0;
                    setsigcatcher();
                    for (;;)
                    {
                        nauty(g,lab,ptn,NULL,orbits,&options,&stats,workspace,
                             2*m*worksize,m,n,canong);
                        if (stats.errstatus) break;
                        options.writeautoms = FALSE;
                        options.writemarkers = FALSE;
                        ++actmult;
                        if (multiplicity > 0 && actmult >= multiplicity)
                            break;
#ifdef  CPUTIME
                        if (mintime > 0.0 && (actmult < 20 || !(actmult&7)) 
                             && CPUTIME >= timebefore+mintime)
                                break;
#endif
                    }
                    unsetsigcatcher();
#ifdef  CPUTIME
                    timeafter = CPUTIME;
#endif
                }
                if (mode == SPARSE_MODE)
                {
                    if (pvalid)
                    {
                        fprintf(outfile,"[fixing partition]\n");
                        options_sg.defaultptn = FALSE;
                    }
                    else
                        options_sg.defaultptn = TRUE;

                    options_sg.outfile = outfile;
                    options_sg.digraph = options_digraph;
                    options_sg.cartesian = options_cartesian;
                    options_sg.schreier = (options_schreier > 0);
                    options_sg.getcanon = options_getcanon;
                    options_sg.linelength = options_linelength;
                    options_sg.invarproc
                         = invarproc[options_invarproc].entrypoint_sg;
                    options_sg.mininvarlevel = options_mininvarlevel;
                    if (options_sg.invarproc)
                       options_sg.maxinvarlevel = options_maxinvarlevel;
                    else
                       options_sg.maxinvarlevel = 0;
                    options_sg.invararg = options_invararg;
                    options_sg.tc_level = options_tc_level;
                    if (options_schreier > 0)
                        schreier_fails(options_schreier);

                    if (umask & U_NODE)  options_sg.usernodeproc = NODEPROC;
                    else                 options_sg.usernodeproc = NULL;
                    if (umask & U_AUTOM) options_sg.userautomproc = AUTOMPROC;
                    else                 options_sg.userautomproc = NULL;
                    if (umask & U_LEVEL) options_sg.userlevelproc = LEVELPROC;
                    else                 options_sg.userlevelproc = NULL;
                    if (umask & U_REF)   options_sg.userrefproc = REFPROC;
                    else                 options_sg.userrefproc = NULL;
                    if (umask & U_CANON) options_sg.usercanonproc = CANONPROC;
                    else                 options_sg.usercanonproc = NULL;
#if !MAXN
                    DYNALLOC1(setword,workspace,workspace_sz,2*m*worksize,
                                                                "dreadnaut");
#endif

                    firstpath = TRUE;
                    options_sg.writeautoms = options_writeautoms;
                    options_sg.writemarkers = options_writemarkers;
#ifdef  CPUTIME
                    timebefore = CPUTIME;
#endif
                    actmult = 0;
                    setsigcatcher();
                    for (;;)
                    {
                        nauty((graph*)&g_sg,lab,ptn,NULL,orbits,&options_sg,
                         &stats,workspace,2*m*worksize,m,n,(graph*)&canong_sg);
                        if (stats.errstatus) break;
                        options_sg.writeautoms = FALSE;
                        options_sg.writemarkers = FALSE;
                        ++actmult;
                        if (multiplicity > 0 && actmult >= multiplicity)
                            break;
#ifdef  CPUTIME
                        if (mintime > 0.0 && (actmult < 20 || !(actmult&7)) 
                               && CPUTIME >= timebefore+mintime)
                            break;
#endif
                    }
                    unsetsigcatcher();
#ifdef  CPUTIME
                    timeafter = CPUTIME;
#endif
                }

                if (stats.errstatus)
                {
                    if (stats.errstatus == NAUABORTED)
                        fprintf(ERRFILE,"nauty aborted\n");
                    else if (stats.errstatus == NAUKILLED)
                        fprintf(ERRFILE,"nauty interrupted\n");
                    else 
                        fprintf(ERRFILE,
                        "nauty returned error status %d [this can't happen]\n",
                           stats.errstatus);
                    cvalid = cvalid_sg = ovalid = FALSE;
                }
                else
                {
                    if (options_getcanon)
                    {
                        if (mode == DENSE_MODE) cvalid = TRUE;
                        else                    cvalid_sg = TRUE;
                    }
                    ovalid = TRUE;
                    fprintf(outfile,"%d orbit%s",SS(stats.numorbits,"","s"));
                    fprintf(outfile,"; grpsize=");
                    writegroupsize(outfile,stats.grpsize1,stats.grpsize2);
                    fprintf(outfile,"; %d gen%s",
                            SS(stats.numgenerators,"","s"));
                    fprintf(outfile,"; %lu node%s",SS(stats.numnodes,"","s"));
                    if (stats.numbadleaves)
                        fprintf(outfile," (%lu bad lea%s)",
                            SS(stats.numbadleaves,"f","ves"));
                    fprintf(outfile,"; maxlev=%d\n", stats.maxlevel);
                    /* fprintf(outfile,"tctotal=%lu",stats.tctotal); */
                    if (options_getcanon)
                        fprintf(outfile,"canupdates=%lu; ",stats.canupdates);
#ifdef  CPUTIME
                    fprintf(outfile,actmult == 1 ?
                              "cpu time = %.2f seconds\n" :
                              "cpu time = %.7f seconds\n",
                            (timeafter-timebefore)/actmult);
#else
                    fprintf(outfile,"\n");
#endif
                    if (mode == DENSE_MODE && options_maxinvarlevel != 0
                       && invarproc[options_invarproc].entrypoint)
                    {
                        fprintf(outfile,"invarproc \"%s\" succeeded %lu/%lu",
                            invarproc[options_invarproc].name,
                            stats.invsuccesses,stats.invapplics);
                        if (stats.invarsuclevel > 0)
                            fprintf(outfile," beginning at level %d.\n",
                                    stats.invarsuclevel);
                        else
                            fprintf(outfile,".\n");
                    }
                    if (mode == SPARSE_MODE && options_maxinvarlevel != 0
                       && invarproc[options_invarproc].entrypoint_sg)
                    {
                        fprintf(outfile,"invarproc \"%s\" succeeded %lu/%lu",
                            invarproc[options_invarproc].name_sg,
                            stats.invsuccesses,stats.invapplics);
                        if (stats.invarsuclevel > 0)
                            fprintf(outfile," beginning at level %d.\n",
                                    stats.invarsuclevel);
                        else
                            fprintf(outfile,".\n");
                    }
                }
            }
            break;

        case 'A':   /* change mode, with possible conversion */
            minus = FALSE;
            oldmode = mode;
            d = getc(INFILE);
            if (d == 'n' || d == 'N' || d == 'd' || d == 'D') mode = DENSE_MODE;
            else if (d == 's' || d == 'S') mode = SPARSE_MODE;
            else if (d == 't' || d == 'T') mode = TRACES_MODE;
            else
            {
                fprintf(ERRFILE,"Mode %c is unknown\n",(d?d:'0'));
                FLUSHANDPROMPT;
                break;
            }
            if ((d = getc(INFILE)) != '+')
            {
                ungetc(d,INFILE);
                gvalid = gvalid_sg = FALSE;
                pvalid = ovalid = FALSE;
            }
            else
            {
                if (SPARSEREP(oldmode) && !SPARSEREP(mode) && gvalid_sg)
                {
#if !MAXN
                    DYNALLOC2(graph,g,g_sz,n,m,"dreadnaut");
#endif
                    sg_to_nauty(&g_sg,g,m,&m);
                    gvalid_sg = FALSE;
                    gvalid = TRUE;
                }
                if (!SPARSEREP(oldmode) && SPARSEREP(mode) && gvalid)
                {
                    nauty_to_sg(g,&g_sg,m,n);
                    gvalid = FALSE;
                    gvalid_sg = TRUE;
                }
            }
            cvalid = cvalid_sg = FALSE;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=92 G=93

¤ Dauer der Verarbeitung: 0.32 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge