示例#1
0
int 
main (void)
{ short i,j,m,n,y,np,nb,mxp,ord,im,len,*p,*q;
  int quot;
  int chct;
  char nt,f,id,eq,fault,flnm[80];
reenter:
  printf("Do you wish to read permutations from a file (y/n)?  ");
  if (getchar()=='y')
  { f=1; snl();
    printf("Input filename:    "); scanf("%s",flnm); snl();
    if ((ip=fopen(flnm,"r"))==0)
    { fprintf(stderr,"Cannot open %s.\n",flnm); goto reenter; }
    fscanf(ip,"%hd%hd%hd%hd",&npt,&np,&nb,&m); seeknln();
    if (nb!=0) 
    { if (nb>=mb)
      { fprintf(stderr,"Too many base points. Increase MB.\n"); return(-1);}
      for (i=1;i<=nb;i++) fscanf(ip,"%hd",base+i);
      seeknln();
    }
    if (m!=0) seeknln();
  }
  else
  { f=0; snl(); printf("Input npt:   "); scanf("%hd",&npt); snl(); nb=0; }
  if (npt>mpt) {fprintf(stderr,"npt too big. Increase NPT.\n"); exit(1); }
  quot=psp/npt; if (quot>mp) mxp=mp; else mxp=quot;
  printf("Perm nos 1 - %d can be read. Perm no 0 is always the identity\n",
          mxp-1);
  for (i=0;i<mxp;i++) { pptr[i]=perm-1+npt*i; pno[i]=0; }
  p=pptr[0]; for (i=1;i<=npt;i++) p[i]=i;
  pno[0]=1;
  if (f)
  { if (np>=mxp)
    { fprintf(stderr,"Not enough perm space to read perms from file.");
      fprintf(stderr," Increase PSP (or MP).\n"); exit(1);
    }
    for (i=1;i<=np;i++)
    { if (readperm(pptr[i])==2)
      { fprintf(stderr,"Perm no %i is not a permutation.\n"); exit(1);}
      pno[i]=1; seeknln();
    }
    fclose(ip);
  }

  while(1)
  { printf("Choose option. Print 'l' for list.\n");
    scanf("%s",opt);
    if (strcmp(opt,"l")==0)
    { snl();
      printf("rp  n                = read perm no n.\n");
      printf("pp  n                = print perm no n.\n");
      printf("ppc  n               = print perm no n in cycles.\n");
      printf("inv m n              = calc inverse p[n] of p[m].\n");
      printf("pr n l i(1)...i(l)   = calc prod p[n] of p[i(1)]...p[i(l)].\n");
      printf("im m x               = print image of point x under p[m].\n");
      printf("fp n                 = print fixed pts of p[n].\n");
      printf("fpn l i(1)...i(l)    = print common fixed pts of p[i(1)],...,p[i(l)].\n");
      printf("cyc n x              = print cycle of point x under p[n].\n");
      printf("ord n                = print order of p[n].\n");
      printf("orb l i(1)...i(l)    = print orbits of p[i(1)]...p[i(l)].\n");
      printf("rb                   = read in a base for the group.\n");
      printf("op filename          = output some perms to 'filename'.\n");
      printf("opord filename       = output some perms to 'filename' and\n");
      printf("                       compute order of group they generate.\n");
      printf("                      (Only works if base known for G!).\n");
      printf("rf n filename        = read in additional perms from filename\n");
      printf("                       starting at perm. no. n.\n");
      printf("q                    = quit.\n");
    }
    else if (strcmp(opt,"rp")==0)
    { scanf("%hd",&n); snl();
      if (n<=0 || n>=mxp)  fprintf(stderr,"Invalid perm.no %d.\n",n);
      else
      { while (rp(pptr[n])==2)
        { fprintf(stderr,"That is not a permutation. Try again!\n"); snl(); }
        pno[n]=1;
      }
    }
    else if (strcmp(opt,"pp")==0)
    { scanf("%hd",&n); snl();
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      p=pptr[n];
      for (i=1;i<=npt;i++) printf("%4d",p[i]); printf("\n");
    }
    else if (strcmp(opt,"ppc")==0)
    { scanf("%hd",&n); snl();
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      for (i=1;i<=npt;i++) orb[i]=1;
      p=pptr[n]; id=1;
      chct=0;
      for (m=1;m<=npt;m++) if (orb[m])
      { if ((im=p[m])!=m)
        { id=0; orb[im]=0; printf("(%d,%d",m,im);
          chct += (num_digits(m)+num_digits(im)+2);
          while ((im=p[im])!=m)
          { if (chct>=75) { printf(",\n%d",im); chct=num_digits(im);}
            else {printf(",%d",im); chct += (1+num_digits(im));}
            orb[im]=0;
          }
          printf(")");
          chct++;
          if (chct>=72) { printf("\n"); chct=0;}
        }
      }
      if (id) printf("Perm no %d is the identity.\n",n);
      else printf("\n");
    }
    else if (strcmp(opt,"inv")==0)
    { scanf("%hd%hd",&m,&n); snl();
      if (m<0 || m>=mxp || pno[m]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",m); continue;}
      if (n<=0 || n>=mxp)
      { fprintf(stderr,"Invalid perm. no. %d.\n",n); continue;}
      invert(pptr[m],pptr[n]); pno[n]=1;
    }
    else if (strcmp(opt,"pr")==0)
    { scanf("%hd%hd",&m,cp);
      if (m<=0 || m>=mxp)
      { fprintf(stderr,"Invalid perm no. %d\n",m);snl(); continue;}
      fault=0;
      for (i=1;i<= *cp;i++)
      { scanf("%hd",cp+i); n= *(cp+i);
        if (n<0 || n>=mxp || pno[n]==0)
        { fprintf(stderr,"Perm no %d is not defined.\n",n);fault=1; snl();
          break;
        }
      }
      if (fault) continue;
      snl();
      p=pptr[m];
      for (i=1;i<=npt;i++) p[i]=image(i);
      pno[m]=1;
    }
    else if (strcmp(opt,"im")==0)
    { scanf("%hd%hd",&n,&i); snl();
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      if (i<=0 || i>npt)
      { fprintf(stderr,"Inappropriate point %d.\n",i); continue;}
      printf("%d\n",pptr[n][i]);
    }
    else if (strcmp(opt,"fp")==0)
    { scanf("%hd",&n); snl();
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      p=pptr[n]; nt=1;
      for (i=1;i<=npt;i++) if (p[i]==i) { nt=0; printf("%4d",i);}
      if (nt) printf("No fixed points.\n"); else printf("\n");
    }
    else if (strcmp(opt,"fpn")==0)
    { scanf("%hd",cp);
      fault=0;
      for (i=1;i<= *cp;i++)
      { scanf("%hd",cp+i); n= *(cp+i);
        if (n<0 || n>=mxp || pno[n]==0)
        { fprintf(stderr,"Perm no %d is not defined.\n",n); fault=1; snl();
          break;
        }
      }
      if (fault) continue;
      snl(); nt=1;
      for (n=1;n<=npt;n++)
      { f=1;
        for (i=1;i<= *cp;i++) if (pptr[cp[i]][n]!=n) { f=0; break;}
        if (f) { nt=0; printf("%4d",n); }
      }
      if (nt) printf("No fixed points.\n"); else printf("\n");
    }
    else if (strcmp(opt,"cyc")==0)
    { scanf("%hd%hd",&n,&i); snl();
      if (i<=0 || i>npt)
      { fprintf(stderr,"Inappropriate point %d.\n",i); continue;}
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      p=pptr[n];
      if ((im=p[i])==i) printf("%d is fixed under p[%d].\n",i,n);
      else
      { printf("(%d,%d",i,im);
        while ((im=p[im])!=i) printf(",%d",im);
        printf(")\n");
      }
    }
    else if (strcmp(opt,"ord")==0)
    { scanf("%hd",&n); snl();
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      p=pptr[n]; id=1;
      for (i=1;i<=npt;i++) orb[i]=1;
      ord=1;
      for (m=1;m<=npt;m++) if (orb[m])
      { if ((im=p[m])!=m)
        { id=0; orb[im]=0; len=2;
          while ((im=p[im])!=m) { orb[im]=0; len++; }
          ord=lcm(ord,len);
        }
      }
      if (id) printf("Perm no %d is the identity.\n",n);
      else printf("%d\n",ord);
    }
    else if (strcmp(opt,"orb")==0)
    { scanf("%hd",cp);
      fault=0;
      for (i=1;i<= *cp;i++)
      { scanf("%hd",cp+i); n= *(cp+i);
        if (n<0 || n>=mxp || pno[n]==0)
        { fprintf(stderr,"Perm no %d is not defined.\n",n); fault=1; snl();
          break;
        }
      }
      if (fault) continue;
      snl();
      allorbs();
    }
    else if (strcmp(opt,"eq")==0)
    { scanf("%hd%hd",&m,&n); snl();
      if (n<0 || n>=mxp || pno[n]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",n); continue;}
      if (m<0 || m>=mxp || pno[m]==0)
      { fprintf(stderr,"Perm no %d is not defined.\n",m); continue;}
      p=pptr[m]; q=pptr[n]; eq=1;
      for (i=1;i<=npt;i++) if (p[i]!=q[i]) {eq=0; break;}
      if (eq) printf("Permutations are equal.\n");
      else printf("Permutations are not equal on point %d.\n",i);
    }
    else if (strcmp(opt,"rb")==0)
    { snl(); printf("Input base points, preceded by their number.\n");
      scanf("%hd",&nb);
      if (nb>=mb)
      { fprintf(stderr,"Too many base points. Increase MB.\n"); return(-1);}
      for (i=1;i<=nb;i++) scanf("%hd",base+i);
      snl();
    }
    else if ((y=strcmp(opt,"opord"))==0 || strcmp(opt,"op")==0)
    { if (y==0 && nb==0)
      { fprintf(stderr,"Order can only be computed when base is known.\n");
        continue;
      }
      scanf("%s",flnm); snl(); op=fopen(flnm,"w");
      printf("Input perm nos to be saved, preceded by their number.\n");
      scanf("%hd",&n); fprintf(op,"%3d %4d%4d%4d\n",npt,n,nb,0);
      if (nb!=0)
      if (npt>=10000)
      { for (i=1;i<=nb;i++) fprintf(op,"%6d",base[i]); fprintf(op,"\n");}
      else
      if (npt>=1000)
      { for (i=1;i<=nb;i++) fprintf(op,"%5d",base[i]); fprintf(op,"\n");}
      else
      { for (i=1;i<=nb;i++) fprintf(op,"%4d",base[i]); fprintf(op,"\n");}
      f=0;
      for (i=1;i<=n;i++)
      { scanf("%hd",&m);
        if (m<0 || m>=mxp || pno[m]==0)
        { printf("Perm no %d is not defined.\n",m);
          fclose(op); snl(); unlink(flnm); f=1; break;
        }
        printvec(pptr[m],0);
      }
      if (f) continue;
      snl(); fclose(op);
      if (y==0)
      { sprintf(sysstring,"cp %s optxxx.ip",flnm);
        system(sysstring); system("gprun -b optxxx ip ip");
        unlink("optxxx.ip");
      }
    }
    else if (strcmp(opt,"rf")==0)
    { scanf("%hd",&n); scanf("%s",flnm); snl();
      if ((ip=fopen(flnm,"r"))==0)
      { fprintf(stderr,"Cannot open %s.\n",flnm); continue; }
      fscanf(ip,"%hd%hd%hd%hd",&i,&np,&j,&m); seeknln();
      if (i!=npt)
      { fprintf(stderr,"npt does not agree.\n"); fclose(ip); continue;}
      if (j!=0) seeknln();
      if (m!=0) seeknln();
      if (n<=0 || np+n-1>=mxp)
      { fprintf(stderr,"Not enough perm space to read perms from file.");
        fclose(ip); continue;
      }
      for (i=1;i<=np;i++)
      { if (readperm(pptr[i+n-1])==2)
        { fprintf(stderr,"Perm no %i is not a permutation.\n");
          pno[i+n-1]=0; break;
        }
        pno[i+n-1]=1; seeknln();
      }
      fclose(ip);
    }
    else if (strcmp(opt,"q")==0) {snl(); break;}
    else {printf("Invalid option.\n"); snl();}
  }
  exit(0);
}
示例#2
0
文件: dreadnaut.c 项目: 3ki5tj/nauty
EXTRADECLS
#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.                      *
*                                                                            *
*****************************************************************************/

main()
{
        int m,n,newm,newn;
        boolean gvalid,ovalid,cvalid,pvalid,minus,prompt,doquot;
        int i,worksize,numcells,refcode,umask,qinvar;
        int oldorg;
        char *s1,*s2,*invarprocname;
        int c,d;
        register long li;
        set *gp;
        double timebefore,timeafter;
        char filename[100];
        graph *savedg;
        nvector *savedlab;
        int sgn,sgactn,sgorg;
        int cgactn,gactn;

        curfile = 0;
        fileptr[curfile] = stdin;
        prompt = DOPROMPT(INFILE);
        outfile = stdout;
        n = m = 1;

#ifdef  INITSEED
        INITSEED;
#endif

        umask = 0;
        pvalid = FALSE;
        gvalid = FALSE;
        ovalid = FALSE;
        cvalid = FALSE;
        minus = FALSE;
        worksize = 2*MAXM*WORKSIZE;
        labelorg = oldorg = 0;
        cgactn = sgactn = gactn = 0;

#ifdef  DYNALLOC
        workspace = (setword*) ALLOCS(WORKSIZE,2*MAXM*sizeof(setword));
        ptn = (nvector*) ALLOCS(MAXN,sizeof(nvector));
        orbits = (nvector*) ALLOCS(MAXN,sizeof(nvector));
        perm = (permutation*) ALLOCS(MAXN,sizeof(permutation));

        if (workspace == NILSET || ptn == (nvector*)NULL ||
                orbits == (nvector*)NULL || perm == (permutation*)NULL)
        {
            fprintf(ERRFILE,"ALLOCS failed; reduce MAXN.\n\n");
            EXIT;
        }
#endif

#ifdef  INITIALIZE
        INITIALIZE;
#endif

        allocg(&g,&lab,&gactn,n);
        if (gactn == 0)
        {
            fprintf(ERRFILE,"ALLOCS failed for g: this shouldn't happen.\n\n");
            EXIT;
        }

        invarprocname = "none";
        if (prompt)
        {
            fprintf(PROMPTFILE,"Dreadnaut version %s.\n",DREADVERSION);
            fprintf(PROMPTFILE,"> ");
        }

     /* Calling dummy routines in nautinv.c, nauty.c and nautil.c causes
        those segments to get loaded in various Macintosh variants.  This
        causes an apparent, but illusory, improvement in the time required
        for the first call to nauty().   */

        nautinv_null();
        nautil_null();
        nauty_null();

        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\n",
                            MAXIFILES);
                if (!readstring(INFILE,filename))
                {
                    fprintf(ERRFILE,
                            "missing file name on '>' command : ignored\n\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\n");
                break;

            case '>':   /* new output file */
                if ((d = getc(INFILE)) != '>')
                    ungetc((char)d,INFILE);
                if (minus)
                {
                    minus = FALSE;
                    if (outfile != stdout)
                    {
                        fclose(outfile);
                        outfile = stdout;
                    }
                }
                else
                {
                    if (!readstring(INFILE,filename))
                    {
                        fprintf(ERRFILE,
                            "improper file name, reverting to stdout\n\n");
                        outfile = stdout;
                        break;
                    }
                    OPENOUT(outfile,filename,d=='>');
                    if (outfile == NULL)
                    {
                        fprintf(ERRFILE,
                            "can't open output file, reverting to stdout\n\n");
                        outfile = stdout;
                    }
                }
                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(INFILE);
                if (i <= 0 || i > MAXN)
                    fprintf(ERRFILE,
                         " n can't be less than 1 or more than %d\n\n",MAXN);
                else
                {
                    gvalid = FALSE;
                    ovalid = FALSE;
                    cvalid = FALSE;
                    pvalid = FALSE;
                    n = i;
                    m = (n + WORDSIZE - 1) / WORDSIZE;
                    allocg(&g,&lab,&gactn,n);
                    if (gactn == 0)
                    {
                        fprintf(ERRFILE,"can't allocate space for graph\n");
                        n = m = 1;
                        break;
                    }
                }
                break;

            case 'g':   /* read graph */
                minus = FALSE;
                readgraph(INFILE,g,options.digraph,prompt,FALSE,
                          options.linelength,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
                ovalid = FALSE;
                break;

            case 'e':   /* edit graph */
                minus = FALSE;
                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 (gvalid)
                {
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,
                                "can't allocate work space for 'r'\n\n");
                        break;
                    }
                    readperm(INFILE,perm,prompt,n);
                    relabel(g,(pvalid ? lab : (nvector*)NULL),perm,canong,m,n);
                    cvalid = FALSE;
                    ovalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case '_':   /* complement graph */
                minus = FALSE;
                if (gvalid)
                {
                    complement(g,m,n);
                    cvalid = FALSE;
                    ovalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case '@':   /* copy canong into savedg */
                minus = FALSE;
                if (cvalid)
                {
                    allocg(&savedg,&savedlab,&sgactn,n);
                    if (sgactn == 0)
                    {
                        fprintf(ERRFILE,"can`t allocate space for h'\n\n");
                        break;
                    }
                    sgn = n;
                    for (li = (long)n * (long)m; --li >= 0;)
                        savedg[li] = canong[li];
                    for (i = n; --i >= 0;)
                        savedlab[i] = lab[i];
                    sgorg = labelorg;
                }
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

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

                if (cvalid)
                {
                    if (sgactn > 0)
                    {
                        if (sgn != n)
                            fprintf(OUTFILE,
                                  "h and h' have different sizes.\n");
                        else
                        {
                            for (li = (long)n * (long)m; --li >= 0;)
                                if (savedg[li] != canong[li])
                                    break;
                            if (li >= 0)
                                fprintf(OUTFILE,
                                   "h and h' are different.\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\n");
                }
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case 'j':   /* relabel graph randomly */
                minus = FALSE;
                if (gvalid)
                {
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,
                                "can't allocate work space for 'j'\n\n");
                        break;
                    }
                    ranperm(perm,n);
                    relabel(g,(pvalid ? lab : (nvector*)NULL),perm,canong,m,n);
                    cvalid = FALSE;
                    ovalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case 'v':   /* write vertex degrees */
                minus = FALSE;
                if (gvalid)
                    putdegs(OUTFILE,g,options.linelength,m,n);
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case '%':   /* do Mathon doubling operation */
                minus = FALSE;
                if (gvalid)
                {
                    if (2L * ((long)n + 1L) > MAXN)
                    {
                        fprintf(ERRFILE,"n can't be more than %d\n\n",MAXN);
                        break;
                    }
                    newn = 2 * (n + 1);
                    newm = (newn + WORDSIZE - 1) / WORDSIZE;
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,
                                "can't allocate work space for '%'\n\n");
                        break;
                    }

                    for (li = (long)n * (long)m; --li >= 0;)
                        canong[li] = g[li];

                    allocg(&g,&lab,&gactn,newn);
                    if (gactn == 0)
                    {
                        fprintf(ERRFILE,"can't allocate space for graph \n\n");
                        break;
                    }
                    mathon(canong,m,n,g,newm,newn);
                    m = newm;
                    n = newn;
                    cvalid = FALSE;
                    ovalid = FALSE;
                    pvalid = FALSE;
                }
                else
                    fprintf(ERRFILE,"g is not defined\n\n");
                break;

            case 's':   /* generate random graph */
                minus = FALSE;
                i = getint(INFILE);
                if (i <= 0)
                    i = 2;
                rangraph(g,options.digraph,i,m,n);
                gvalid = TRUE;
                cvalid = FALSE;
                ovalid = FALSE;
                break;

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

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

            case 'I':   /* do refinement and invariants procedure */
                if (!pvalid)
                    unitptn(lab,ptn,&numcells,n);
                cellstarts(ptn,0,active,m,n);
#ifdef  CPUTIME
                timebefore = CPUTIME;
#endif
                doref(g,lab,ptn,0,&numcells,&qinvar,perm,active,&refcode,
                      refine,options.invarproc,
                      0,0,options.invararg,options.digraph,m,n);
#ifdef  CPUTIME
                timeafter = CPUTIME;
#endif
                fprintf(OUTFILE," %d cell%s; code = %x",
                        SS(numcells,"","s"),refcode);
                if (options.invarproc != NILFUNCTION)
                    fprintf(OUTFILE," (%s %s)",invarprocname,
                        (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 */
                if (!pvalid)
                    unitptn(lab,ptn,&numcells,n);
                cellstarts(ptn,0,active,m,n);
                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);
                fprintf(OUTFILE," %d cell%s; code = %x\n",
                        SS(numcells,"","s"),refcode);
                if (numcells > 1)
                    pvalid = TRUE;
                break;

            case 'x':   /* execute nauty */
                minus = FALSE;
                ovalid = FALSE;
                cvalid = FALSE;
                if (!gvalid)
                {
                    fprintf(ERRFILE,"g is not defined\n\n");
                    break;
                }
                if (pvalid)
                {
                    fprintf(OUTFILE,"[fixing partition]\n");
                    options.defaultptn = FALSE;
                }
                else
                    options.defaultptn = TRUE;
                options.outfile = outfile;

                if (options.getcanon)
                {
                    allocg(&canong,(nvector**)NULL,&cgactn,n);
                    if (cgactn == 0)
                    {
                        fprintf(ERRFILE,"can't allocate space for h\n\n");
                        break;
                    }
                }

                firstpath = TRUE;
#ifdef  CPUTIME
                timebefore = CPUTIME;
#endif
                nauty(g,lab,ptn,NILSET,orbits,&options,&stats,workspace,
                      worksize,m,n,canong);
#ifdef  CPUTIME
                timeafter = CPUTIME;
#endif
                if (stats.errstatus != 0)
                    fprintf(ERRFILE,
                      "nauty returned error status %d [this can't happen]\n\n",
                       stats.errstatus);
                else
                {
                    if (options.getcanon)
                        cvalid = TRUE;
                    ovalid = TRUE;
                    fprintf(OUTFILE,"%d orbit%s",SS(stats.numorbits,"","s"));
                    if (stats.grpsize2 == 0)
                        fprintf(OUTFILE,"; grpsize=%.0f",stats.grpsize1+0.1);
                    else
                    {
                        while (stats.grpsize1 >= 10.0)
                        {
                            stats.grpsize1 /= 10.0;
                            ++stats.grpsize2;
                        }
                        fprintf(OUTFILE,"; grpsize=%12.10fe%d",
                                   stats.grpsize1,stats.grpsize2);
                    }
                    fprintf(OUTFILE,"; %d gen%s",
                            SS(stats.numgenerators,"","s"));
                    fprintf(OUTFILE,"; %ld node%s",SS(stats.numnodes,"","s"));
                    if (stats.numbadleaves)
                        fprintf(OUTFILE," (%ld bad lea%s)",
                                SS(stats.numbadleaves,"f","ves"));
                    fprintf(OUTFILE,"; maxlev=%d\n", stats.maxlevel);
                    fprintf(OUTFILE,"tctotal=%ld",stats.tctotal);
                    if (options.getcanon)
                        fprintf(OUTFILE,"; canupdates=%ld",stats.canupdates);
#ifdef  CPUTIME
                    fprintf(OUTFILE,"; cpu time = %.2f seconds\n",
                            timeafter-timebefore);
#else
                    fprintf(OUTFILE,"\n");
#endif
                    if (options.invarproc != NILFUNCTION &&
                                           options.maxinvarlevel != 0)
                    {
                        fprintf(OUTFILE,"invarproc \"%s\" succeeded %ld/%ld",
                            invarprocname,stats.invsuccesses,stats.invapplics);
                        if (stats.invarsuclevel > 0)
                            fprintf(OUTFILE," beginning at level %d.\n",
                                    stats.invarsuclevel);
                        else
                            fprintf(OUTFILE,".\n");
                    }
                }
                break;

            case 'f':   /* read initial partition */
                if (minus)
                {
                    pvalid = FALSE;
                    minus = FALSE;
                }
                else
                {
                    readptn(INFILE,lab,ptn,&numcells,prompt,n);
                    pvalid = TRUE;
                }
                break;

            case 't':   /* type graph */
                minus = FALSE;
                if (!gvalid)
                    fprintf(ERRFILE,"g is not defined\n\n");
                else
                    putgraph(OUTFILE,g,options.linelength,m,n);
                break;

            case 'T':   /* type graph preceded by n, $ and g commands */
                minus = FALSE;
                if (!gvalid)
                    fprintf(ERRFILE,"g is not defined\n\n");
                else
                {
                    fprintf(OUTFILE,"n=%d $=%d g\n",n,labelorg);
                    putgraph(OUTFILE,g,options.linelength,m,n);
                    fprintf(OUTFILE,"$$\n");
                }
                break;

            case 'u':   /* call user procs */
                if (minus)
                {
                    umask = 0;
                    minus = FALSE;
                }
                else
                {
                    umask = getint(INFILE);
                    if (umask < 0)
                        umask = ~0;
                }
                if (umask & U_NODE)
                    options.usernodeproc = NODEPROC;
                else
                    options.usernodeproc = NILFUNCTION;
                if (umask & U_AUTOM)
                    options.userautomproc = AUTOMPROC;
                else
                    options.userautomproc = NILFUNCTION;
                if (umask & U_LEVEL)
                    options.userlevelproc = LEVELPROC;
                else
                    options.userlevelproc = NILFUNCTION;
                if (umask & U_TCELL)
                    options.usertcellproc = TCELLPROC;
                else
                    options.usertcellproc = NILFUNCTION;
                if (umask & U_REF)
                    options.userrefproc = REFPROC;
                else
                    options.userrefproc = NILFUNCTION;
                break;

            case 'o':   /* type orbits */
                minus = FALSE;
                if (ovalid)
                    putorbits(OUTFILE,orbits,options.linelength,n);
                else
                    fprintf(ERRFILE,"orbits are not defined\n\n");
                break;

            case 'b':   /* type canonlab and canong */
                minus = FALSE;
                if (cvalid)
                    putcanon(OUTFILE,lab,canong,options.linelength,m,n);
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case 'z':   /* type hashcode for canong */
                minus = FALSE;
                if (cvalid)
                    fprintf(OUTFILE,"[%8lx %8lx]\n",
                                    hash(canong,(long)m * (long)n,13),
                                    hash(canong,(long)m * (long)n,7));
                else
                    fprintf(ERRFILE,"h is not defined\n\n");
                break;

            case 'c':   /* set getcanon option */
                options.getcanon = !minus;
                minus = FALSE;
                break;

            case 'w':   /* read size of workspace */
                minus = FALSE;
                worksize = getint(INFILE);
                if (worksize > 2*MAXM*WORKSIZE)
                {
                    fprintf(ERRFILE,
                       "too big - setting worksize = %d\n\n", 2*MAXM*WORKSIZE);
                    worksize = 2*MAXM*WORKSIZE;
                }
                break;

            case 'l':   /* read linelength for output */
                options.linelength = getint(INFILE);
                minus = FALSE;
                break;

            case 'y':   /* set tc_level field of options */
                options.tc_level = getint(INFILE);
                minus = FALSE;
                break;

            case 'k':   /* set invarlev fields of options */
                options.mininvarlevel = getint(INFILE);
                options.maxinvarlevel = getint(INFILE);
                minus = FALSE;
                break;

            case 'K':   /* set invararg field of options */
                options.invararg = getint(INFILE);
                minus = FALSE;
                break;

            case '*':   /* set invarproc field of options */
                minus = FALSE;
                d = getint(INFILE);
                if (d >= -1 && d <= NUMINVARS-2)
                {
                    options.invarproc = invarproc[d+1].entrypoint;
                    invarprocname = invarproc[d+1].name;
                }
                else
                    fprintf(ERRFILE,"no such vertex-invariant\n\n");
                break;

            case 'a':   /* set writeautoms option */
                options.writeautoms = !minus;
                minus = FALSE;
                break;

            case 'm':   /* set writemarkers option */
                options.writemarkers = !minus;
                minus = FALSE;
                break;

            case 'p':   /* set cartesian option */
                options.cartesian = !minus;
                minus = FALSE;
                break;

            case 'd':   /* set digraph option */
                if (options.digraph && minus)
                    gvalid = FALSE;
                options.digraph = !minus;
                minus = FALSE;
                break;

            case '$':   /* set label origin */
                if ((d = getc(INFILE)) == '$')
                    labelorg = oldorg;
                else
                {
                    ungetc((char)d,INFILE);
                    oldorg = labelorg;
                    i = getint(INFILE);
                    if (i < 0)
                        fprintf(ERRFILE,"labelorg must be >= 0\n\n");
                    else
                        labelorg = i;
                }
                break;

            case '?':   /* type options, etc. */
                minus = FALSE;
                fprintf(OUTFILE,"m=%d n=%d labelorg=%d",m,n,labelorg);
                if (!gvalid)
                    fprintf(OUTFILE," g=undef");
                else
                {
                    li = 0;
                    for (i = 0, gp = g; i < n; ++i, gp += m)
                        li += setsize(gp,m);
                    if (options.digraph)
                        fprintf(OUTFILE," arcs=%ld",li);
                    else
                        fprintf(OUTFILE," edges=%ld",li/2);
                }
                fprintf(OUTFILE," options=(%cc%ca%cm%cp%cd",
                            PM(options.getcanon),PM(options.writeautoms),
                            PM(options.writemarkers),PM(options.cartesian),
                            PM(options.digraph));
                if (umask & 31)
                    fprintf(OUTFILE," u=%d",umask&31);
                if (options.tc_level > 0)
                    fprintf(OUTFILE," y=%d",options.tc_level);
                if (options.mininvarlevel != 0 || options.maxinvarlevel != 0)
                    fprintf(OUTFILE," k=(%d,%d)",
                                  options.mininvarlevel,options.maxinvarlevel);
                if (options.invararg > 0)
                    fprintf(OUTFILE," K=%d",options.invararg);
                fprintf(OUTFILE,")\n");
                fprintf(OUTFILE,"linelen=%d worksize=%d input_depth=%d",
                                options.linelength,worksize,curfile);
                if (options.invarproc != NILFUNCTION)
                    fprintf(OUTFILE," invarproc=%s",invarprocname);
                if (pvalid)
                    fprintf(OUTFILE,"; %d cell%s",SS(numcells,"","s"));
                else
                    fprintf(OUTFILE,"; 1 cell");
                fprintf(OUTFILE,"\n");
                if (OUTFILE != PROMPTFILE)
                    fprintf(PROMPTFILE,"m=%d n=%d depth=%d labelorg=%d\n",
                            m,n,curfile,labelorg);
                break;

            case '&':   /* list the partition and possibly the quotient */
                if ((d = getc(INFILE)) == '&')
                    doquot = TRUE;
                else
                {
                    ungetc((char)d,INFILE);
                    doquot = FALSE;
                }
                minus = FALSE;
                if (pvalid)
                    putptn(OUTFILE,lab,ptn,0,options.linelength,n);
                else
                    fprintf(OUTFILE,"unit partition\n");
                if (doquot)
                {
                    if (!pvalid)
                        unitptn(lab,ptn,&numcells,n);
                    putquotient(OUTFILE,g,lab,ptn,0,options.linelength,m,n);
                }
                break;

            case 'h':   /* type help information */
                minus = FALSE;
                help(PROMPTFILE);
                break;

            default:    /* illegal command */
                fprintf(ERRFILE,"'%c' is illegal - type 'h' for help\n\n",c);
                flushline(INFILE);
                if (prompt)
                    fprintf(PROMPTFILE,"> ");
                break;

            }  /* end of switch */
}