4 #ifndef CONFIG_H_INCLUDED 5 #define CONFIG_H_INCLUDED 18 #define DUMMYUSE(x) (void)(x) 26 #define MAXNCLASSES 100 37 const int CHECK = True;
39 const int MONITOR = False;
41 const int OPTPRINT = False;
43 const int DEBUG0 = False;
45 const int DEBUG = False;
59 Extern
void toForm(
EGraph *egraph);
60 Extern
int countPhiCon(
int ex,
int lp,
int v4);
63 Local BigInt factorial(
int n);
64 Local BigInt ipow(
int n,
int p);
67 Local
int nextPerm(
int nelem,
int nclass,
int *cl,
int *r,
int *q,
int *p,
int count);
69 Local
void erEnd(
const char *msg);
70 Local
int *newArray(
int size,
int val);
71 Local
void deletArray(
int *a);
72 Local
void copyArray(
int size,
int *a0,
int *a1);
73 Local
int **newMat(
int n0,
int n1,
int val);
74 Local
void deleteMat(
int **m,
int n0,
int n1);
75 Local
void printArray(
int n,
int *p);
76 Local
void printMat(
int n0,
int n1,
int **m);
79 static int countNMC = 0;
80 static int countEG = 0;
81 static int countMG = 0;
87 EGraph::EGraph(
int nnodes,
int nedges,
int mxdeg)
96 nodes =
new ENode[nNodes];
97 edges =
new EEdge[nEdges+1];
98 for (j = 0; j < nNodes; j++) {
100 nodes[j].edges =
new int[maxdeg];
103 printf(
"+++ new EGraph %d\n", ++countEG);
104 if(countEG > 100) { exit(1); }
112 for (j = 0; j < nNodes; j++) {
113 delete[] nodes[j].edges;
118 printf(
"+++ delete EGraph %d\n", countEG--);
123 void EGraph::init(
int pid,
long gid,
int **adjmat, Bool sopi, BigInt nsm, BigInt esm)
125 int n0, n1, ed, e, eext, eint;
134 for (n0 = 0; n0 < nNodes; n0++) {
138 for (n0 = 0; n0 < nNodes; n0++) {
139 for (e = 0; e < adjmat[n0][n0]/2; e++, ed++) {
140 edges[ed].nodes[0] = n0;
141 edges[ed].nodes[1] = n0;
142 nodes[n0].edges[nodes[n0].deg++] = - ed;
143 nodes[n0].edges[nodes[n0].deg++] = ed;
144 edges[ed].ext = nodes[n0].ext;
146 for (n1 = n0+1; n1 < nNodes; n1++) {
147 for (e = 0; e < adjmat[n0][n1]; e++, ed++) {
148 edges[ed].nodes[0] = n0;
149 edges[ed].nodes[1] = n1;
150 nodes[n0].edges[nodes[n0].deg++] = - ed;
151 nodes[n1].edges[nodes[n1].deg++] = ed;
152 edges[ed].ext = (nodes[n0].ext || nodes[n1].ext);
157 if (ed != nEdges+1) {
158 printf(
"*** EGraph::init: ed=%d != nEdges=%d\n", ed, nEdges);
159 erEnd(
"*** EGraph::init: illegal connection\n");
166 for (ed = 1; ed <= nEdges; ed++) {
168 edges[ed].momn = eext++;
169 edges[ed].momc[0] =
'Q';
170 edges[ed].momc[1] = ((char)0);
172 edges[ed].momn = eint++;
173 edges[ed].momc[0] =
'P';
174 edges[ed].momc[1] = ((char)0);
180 void EGraph::setExtern(
int nd, Bool val)
186 void EGraph::endSetExtern(
void)
191 for (n = 0; n < nNodes; n++) {
203 nlp = nEdges - nNodes + 1;
205 printf(
"EGraph: pId=%d gId=%ld nExtern=%d nLoops=%d nNodes=%d nEdges=%d\n",
206 pId, gId, nExtern, nlp, nNodes, nEdges);
207 printf(
" sym = (%ld * %ld) maxdeg=%d\n", nsym, esym, maxdeg);
209 for (nd = 0; nd < nNodes; nd++) {
211 printf(
" %2d Extern ", nd);
213 printf(
" %2d Vertex ", nd);
215 printf(
"deg=%d [", nodes[nd].deg);
216 for (lg = 0; lg < nodes[nd].deg; lg++) {
217 printf(
" %3d", nodes[nd].edges[lg]);
222 for (ed = 1; ed <= nEdges; ed++) {
224 printf(
" %2d Extern ", ed);
226 printf(
" %2d Intern ", ed);
228 printf(
"%s%d", (edges[ed].ext)?
"Q":
"p", edges[ed].momn);
229 printf(
" [%3d %3d]\n", edges[ed].nodes[1], edges[ed].nodes[0]);
236 MNode::MNode(
int vid,
int vdeg, Bool vext,
int vclss)
261 void init(
int *cl,
int mxdeg,
int **adjmat);
263 int clCmp(
int nd0,
int nd1,
int cn);
268 void mkClMat(
int **adjmat);
269 void incMat(
int nd,
int td,
int val);
270 Bool chkOrd(
int nd,
int ndc,
MNodeClass *cl,
int *dtcl);
271 int cmpArray(
int *a0,
int *a1,
int ma);
274 MNodeClass::MNodeClass(
int nnodes,
int ncl)
278 clist =
new int[nClasses];
279 ndcl =
new int[nNodes];
280 clmat = newMat(nNodes, nClasses, 0);
281 flist =
new int[nClasses+1];
284 printf(
"+++ new MNodeClass %d\n", ++countNMC);
285 if(countNMC > 100) { exit(1); }
289 MNodeClass::~MNodeClass()
293 deleteMat(clmat, nNodes, nClasses);
297 printf(
"+++ delete MNodeClass %d\n", countNMC--);
301 void MNodeClass::init(
int *cl,
int mxdeg,
int **adjmat)
305 for (j = 0; j < nClasses; j++) {
318 for (k = 0; k < nClasses; k++) {
319 clist[k] = mnc->clist[k];
321 maxdeg = mnc->maxdeg;
322 for (j = 0; j < nNodes; j++) {
323 ndcl[j] = mnc->ndcl[j];
324 for (k = 0; k < nClasses; k++) {
325 clmat[j][k] = mnc->clmat[j][k];
328 for (k = 0; k < nClasses+1; k++) {
329 flist[k] = mnc->flist[k];
335 void MNodeClass::mkFlist(
void)
340 for (j = 0; j < nClasses; j++) {
349 void MNodeClass::mkNdCl(
void)
354 for (c = 0; c < nClasses; c++) {
355 for (k = 0; k < clist[c]; k++) {
363 int MNodeClass::clCmp(
int nd0,
int nd1,
int cn)
367 int cmp = ndcl[nd0] - ndcl[nd1];
373 cmp = - cmpArray(clmat[nd0], clmat[nd1], cn);
383 void MNodeClass::mkClMat(
int **adjmat)
387 for (nd = 0; nd < nNodes; nd++) {
388 for (td = 0; td < nNodes; td++) {
390 clmat[nd][tc] += adjmat[nd][td];
397 void MNodeClass::incMat(
int nd,
int td,
int val)
400 clmat[nd][tdc] += val;
404 Bool MNodeClass::chkOrd(
int nd,
int ndc,
MNodeClass *cl,
int *dtcl)
406 Bool tcl[MAXNCLASSES];
408 int tn, tc, mxn, cmp, n;
411 for (tc = 0; tc < cl->nClasses; tc++) {
414 for (tn = 0; tn < nNodes; tn++) {
416 tcl[cl->ndcl[tn]] = False;
419 for (tc = 0; tc < cl->nClasses; tc++) {
420 if (tcl[tc] && ndc != tc) {
422 for (n = flist[tc]+1; n < mxn; n++) {
423 cmp = - clmat[n-1][tc] + clmat[n][tc];
434 void MNodeClass::printMat(
void)
441 cout << setw(2) <<
"nd" <<
": " << setw(2) <<
"cl: ";
442 for (j2 = 0; j2 < nClasses; j2++) {
443 cout << setw(2) << j2 <<
" ";
448 for (j1 = 0; j1 < nNodes; j1++) {
449 cout << setw(2) << j1 <<
": " << setw(2) << ndcl[j1] <<
": [";
450 for (j2 = 0; j2 < nClasses; j2++) {
451 cout <<
" " << setw(2) << clmat[j1][j2];
453 cout <<
"] " << endl;
457 int MNodeClass::cmpArray(
int *a0,
int *a1,
int ma)
459 for (
int j = 0; j < ma; j++) {
462 }
else if (a0[j] > a1[j]) {
472 MGraph::MGraph(
int pid,
int ncl,
int *cldeg,
int *clnum,
int *clext, Bool sopi)
478 clist =
new int[ncl];
484 for (j = 0; j < nClasses; j++) {
487 ne += cldeg[j]*clnum[j];
491 mindeg = min(mindeg, cldeg[j]);
496 maxdeg = max(maxdeg, cldeg[j]);
500 printf(
"Sum of degrees are not even\n");
501 for (j = 0; j < nClasses; j++) {
502 printf(
"class %2d: %2d %2d %2d\n",
503 j, cldeg[j], clnum[j], clext[j]);
505 erEnd(
"illegal degrees of nodes");
509 nodes =
new MNode*[nNodes];
514 nLoops = nEdges - nNodes + 1;
516 egraph =
new EGraph(nNodes, nEdges, maxdeg);
518 for (j = 0; j < nClasses; j++) {
519 for (k = 0; k < clist[j]; k++, nn++) {
520 nodes[nn] =
new MNode(nn, cldeg[j], clext[j], j);
521 egraph->setExtern(nn, clext[j]);
524 egraph->endSetExtern();
531 adjMat = newMat(nNodes, nNodes, 0);
535 wsum = ToFraction(0, 1);
536 wsopi = ToFraction(0, 1);
554 modmat = newMat(nNodes, nNodes, 0);
555 permp = newArray(nNodes, 0);
556 permq = newArray(nNodes, 0);
557 permr = newArray(nNodes, 0);
560 bidef = newArray(nNodes, 0);
561 bilow = newArray(nNodes, 0);
566 printf(
"+++ new MGraph %d\n", ++countMG);
567 if(countEG > 100) { exit(1); }
581 deleteMat(modmat, nNodes, nNodes);
583 deleteMat(adjMat, nNodes, nNodes);
585 for (j = 0; j < nNodes; j++) {
592 printf(
"+++ delete MGraph %d\n", countMG++);
602 for (j2 = 0; j2 < nNodes; j2++) {
603 cout <<
" " << setw(2) << j2;
606 for (j1 = 0; j1 < nNodes; j1++) {
607 cout << setw(2) << j1 <<
": [";
608 for (j2 = 0; j2 < nNodes; j2++) {
609 cout <<
" " << setw(2) << adjMat[j1][j2];
611 cout <<
"] " << cl->ndcl[j1] << endl;
619 Bool MGraph::isConnected(
void)
623 for (j = 0; j < nNodes; j++) {
624 nodes[j]->visited = -1;
630 for (n = 0; n < nNodes; n++) {
631 if (nodes[n]->visited >= 0) {
635 return (nv == nNodes);
641 Bool MGraph::visit(
int nd)
646 if (nodes[nd]->freelg > 0) {
649 nodes[nd]->visited = 0;
650 for (td = 0; td < nNodes; td++) {
651 if ((adjMat[nd][td] > 0) and (nodes[td]->visited < 0)) {
667 int j1, j2, cmp, count, nself;
674 count = nextPerm(nNodes, cl->nClasses, cl->clist,
675 permr, permq, permp, count);
680 for (j1 = 0; j1 < nNodes; j1++) {
681 if (adjMat[j1][j1] > 0) {
682 nself = adjMat[j1][j1]/2;
683 esym *= factorial(nself);
684 esym *= ipow(2, nself);
686 for (j2 = j1+1; j2 < nNodes; j2++) {
687 if (adjMat[j1][j2] > 0) {
688 esym *= factorial(adjMat[j1][j2]);
695 permMat(nNodes, permp, adjMat, modmat);
696 cmp = compMat(nNodes, adjMat, modmat);
699 }
else if (cmp == 0) {
701 nsym = nsym + ToBigInt(1);
707 void MGraph::permMat(
int size,
int *perm,
int **mat0,
int **mat1)
711 for (j1 = 0; j1 < size; j1++) {
712 for (j2 = 0; j2 < size; j2++) {
713 mat1[j1][j2] = mat0[perm[j1]][perm[j2]];
719 int MGraph::compMat(
int size,
int **mat0,
int **mat1)
723 for (j1 = 0; j1 < size; j1++) {
724 for (j2 = 0; j2 < size; j2++) {
725 cmp = mat0[j1][j2] - mat1[j1][j2];
750 while (ccl->nClasses != nucl) {
753 for (td = 1; td < nNodes; td++) {
758 cmp = ccl->clCmp(td-1, td, ccn);
763 cout <<
"refine: cls = " << cl->clist << endl;
765 cout <<
"clmat" << endl;
767 cout <<
"refine: discard: cls = " << ccl->clist
768 <<
"ucl = " << ucl << endl;
775 }
else if (cmp < 0) {
787 ucl[nucl++] = nce + 1;
790 if (nucl == ccl->nClasses) {
795 }
else if (nucl < ccl->nClasses) {
796 erEnd(
"refineClasses : smaller number of classes");
800 if (cn == ccl->nClasses) {
803 td = ccl->flist[cn+1]-1;
809 ccl->init(ucl, maxdeg, adjMat);
820 cout <<
"refine: ucl = " << ucl << endl;
821 cout <<
"refine: ncl = " << ncl->clist << endl;
831 void MGraph::bisearchM(
int nd,
int pd,
int ne)
839 for (td = 0; td < nNodes; td++) {
840 if (nodes[td]->ext) {
843 }
else if (td == nd) {
846 }
else if (td == pd) {
848 bilow[nd] = min(bilow[nd], bidef[pd]);
851 }
else if (adjMat[td][nd] < 1) {
854 }
else if (bidef[td] >= 0) {
855 bilow[nd] = min(bilow[nd], bidef[td]);
860 bisearchM(td, nd, adjMat[td][nd]);
863 if (bilow[td] > bidef[nd]) {
866 bilow[nd] = min(bilow[nd], bilow[td]);
873 if (pd < 0 && nodes[nd]->deg != 1) {
885 int MGraph::count1PI(
void)
896 for (j = 0; j < nNodes; j++) {
910 long MGraph::generate(
void)
916 for (n = 0; n < nNodes; n++) {
922 cl->init(clist, maxdeg, adjMat);
923 connectClass(cl, dscl);
930 cout <<
"* Total " << ndiag <<
" Graphs.";
931 cout <<
"(" << n1PI <<
" 1PI)";
937 cout <<
"* refine: " << nCallRefine << endl;
938 cout <<
"* discard for ordering: " << discardOrd << endl;
939 cout <<
"* discard for refinement: " << discardRefine << endl;
940 cout <<
"* discard for disconnected: " << discardDisc << endl;
941 cout <<
"* discard for duplication: " << discardIso << endl;
948 int MGraph::findNextCl(
MNodeClass *cl,
int *dscl)
950 int mine, cr, c, n, me;
954 for (c = 0; c < cl->nClasses; c++) {
957 me = nodes[n]->freelg;
959 if (nodes[n]->freelg < nodes[n]->deg) {
962 if (mine < 0 || mine > me) {
972 int MGraph::findNextTCl(
MNodeClass *cl,
int *dtcl)
974 int c, n, mine, cr, me;
978 for (c = 0; c < cl->nClasses; c++) {
979 for (n = cl->flist[c]; n < cl->flist[c+1]; n++) {
981 me = nodes[n]->freelg;
983 if (nodes[n]->freelg < nodes[n]->deg) {
986 if (mine < 0 || mine > me) {
998 void MGraph::connectClass(
MNodeClass *cl,
int *dscl)
1004 printf(
"connectClass:begin:");
1005 printf(
" dscl="); printArray(nNodes, dscl);
1008 xcl = refineClass(cl, cl->nClasses);
1015 sc = findNextCl(xcl, dscl);
1019 sn = xcl->flist[sc];
1020 connectNode(sc, sn, xcl, dscl);
1023 if (xcl != cl && xcl != NULL) {
1027 printf(
"connectClass:end\n");
1032 void MGraph::connectNode(
int sc,
int ss,
MNodeClass *cl,
int *dscl)
1038 printf(
"connectNode:begin:(%d,%d)", sc, ss);
1039 printf(
" dscl="); printArray(nNodes, dscl);
1042 if (ss >= cl->flist[sc+1]) {
1043 connectClass(cl, dscl);
1045 printf(
"connectNode:end1\n");
1050 copyArray(nNodes, dscl, dtcl);
1051 for (sn = ss; sn < cl->flist[sc+1]; sn++) {
1053 connectLeg(sc, sn, sc, sn, cl, dscl, dtcl);
1055 printf(
"connectNode:end2\n");
1061 printf(
"connectNode:end3\n");
1075 void MGraph::connectLeg(
int sc,
int sn,
int tc,
int ts,
MNodeClass *cl,
int *dscl,
int* dtcl)
1077 int tn, maxself, nc2, nc, maxcon, ts1, wc, ncm;
1078 int dtcl1[MAXNODES];
1081 printf(
"connectLeg:begin:(%d,%d,%d,%d)", sc, sn, tc, ts);
1082 printf(
" dscl="); printArray(nNodes, dscl);
1083 printf(
" dtcl="); printArray(nNodes, dtcl);
1088 if (sn >= cl->flist[sc+1]) {
1089 erEnd(
"*** connectLeg : illegal control");
1093 }
else if (nodes[sn]->freelg < 1) {
1095 if (!isConnected()) {
1097 printf(
"connectLeg:disconnected\n");
1104 printf(
"connectLeg: call conNode\n");
1109 connectNode(sc, sn+1, cl, dscl);
1116 copyArray(nNodes, dtcl, dtcl1);
1119 for (wc = 0; wc < nNodes; wc++) {
1120 if (ts1 >= cl->flist[tc+1]) {
1121 tc = findNextTCl(cl, dtcl1);
1123 printf(
"connectLeg:1:tc=%d\n", tc);
1127 printf(
"connectLeg:end1:(%d,%d,%d,%d)\n", sc, sn, tc, ts);
1131 if (tc != sc && !cl->chkOrd(sn, sc, cl, dtcl)) {
1136 printf(
"connectLeg:end2:(%d,%d,%d,%d)\n", sc, sn, tc, ts);
1147 printf(
"connectLeg:2:tc=%d, fl:%d-->%d\n", tc, cl->flist[tc], cl->flist[tc+1]);
1149 for (tn = cl->flist[tc]; tn < cl->flist[tc+1]; tn++) {
1151 printf(
"connectLeg:2:%d=>try %d\n", sn, tn);
1156 printf(
"connectLeg:3\n");
1162 if (sc == tc && sn > tn) {
1164 printf(
"connectLeg:4\n");
1169 }
else if (sn == tn) {
1173 maxself = min((nodes[sn]->freelg)/2, (nodes[sn]->deg-1)/2);
1176 maxself = nodes[sn]->freelg/2;
1180 if (selOPI and nNodes > 2) {
1181 maxself = min((nodes[sn]->deg-2)/2, maxself);
1185 for (nc2 = maxself; nc2 > 0; nc2--) {
1191 printf(
"connectLeg: call conLeg: (same) %d=>%d(%d)\n", sn, tn,nc);
1194 adjMat[sn][sn] = nc;
1195 nodes[sn]->freelg -= nc;
1196 cl->incMat(sn, tn, ncm);
1200 connectLeg(sc, sn, tc, ts1, cl, dscl, dtcl1);
1203 cl->incMat(tn, sn, - ncm);
1205 nodes[sn]->freelg += nc;
1207 printf(
"connectLeg: ret conLeg: (same) %d=>%d(%d)\n", sn, tn,nc);
1214 maxcon = min(nodes[sn]->freelg, nodes[tn]->freelg);
1217 if (nNodes > 2 && nodes[sn]->deg == nodes[tn]->deg) {
1218 maxcon = min(maxcon, nodes[sn]->deg-1);
1222 if ((adjMat[sn][tn] != 0) || (adjMat[sn][tn] != adjMat[tn][sn])) {
1223 printf(
"*** inconsistent connection: sn=%d, tn=%d", sn, tn);
1224 printf(
" dscl="); printArray(nNodes, dscl);
1225 printf(
" dtcl="); printArray(nNodes, dtcl);
1228 erEnd(
"*** inconsistent connection ");
1233 for (nc = maxcon; nc > 0; nc--) {
1235 printf(
"connectLeg: call conLeg: (diff) %d=>%d(%d)", sn, tn,nc);
1236 printf(
" dtcl="); printArray(nNodes, dtcl);
1239 adjMat[sn][tn] = nc;
1240 adjMat[tn][sn] = nc;
1241 nodes[sn]->freelg -= nc;
1242 nodes[tn]->freelg -= nc;
1243 cl->incMat(sn, tn, nc);
1244 cl->incMat(tn, sn, nc);
1248 connectLeg(sc, sn, tc, ts1, cl, dscl, dtcl1);
1251 cl->incMat(sn, tn, - nc);
1252 cl->incMat(tn, sn, - nc);
1255 nodes[sn]->freelg += nc;
1256 nodes[tn]->freelg += nc;
1258 printf(
"connectLeg: ret conLeg: (diff) %d=>%d(%d)\n", sn, tn,nc);
1259 printf(
" dtcl="); printArray(nNodes, dtcl);
1267 ts1 = cl->flist[tc+1];
1272 printf(
"connectLeg:end3:(%d,%d,%d,%d)\n", sc, sn, tc, ts);
1289 xcl = refineClass(cl, cl->nClasses);
1298 connected = isConnected();
1302 cout <<
"+++ disconnected graph" << ngen << endl;
1313 if (!isIsomorphic(xcl)) {
1316 cout <<
"+++ duplicated graph" << ngen << ngconn << endl;
1328 if (!selOPI || c1PI == 1) {
1329 wsum = wsum + ToFraction(1, nsym*esym);
1331 wsopi = wsopi + ToFraction(1, nsym*esym);
1342 cout <<
"Graph :" << ndiag
1343 <<
"(" << ngen <<
")" 1344 <<
" 1PI comp. = " << c1PI
1345 <<
" sym. factor = (" << nsym <<
"*" << esym <<
")" 1350 cout <<
"refine: " << nCallRefine << endl;
1351 cout <<
"discard for ordering: " << discardOrd << endl;
1352 cout <<
"discard for refinement: " << discardRefine << endl;
1353 cout <<
"discard for disconnected: " << discardDisc << endl;
1354 cout <<
"discard for duplication: " << discardIso << endl;
1359 egraph->init(pId, ndiag, adjMat, sopi, nsym, esym);
1366 if (xcl != cl && xcl != NULL) {
1380 Local
int nextPerm(
int nelem,
int nclass,
int *cl,
int *r,
int *q,
int *p,
int count)
1385 for (j = 0; j < nelem; j++) {
1389 for (j = 0; j < nelem; j++) {
1394 for (k = 0; k < nclass; k++) {
1396 for (e = 0; e < n; e++) {
1402 erEnd(
"*** inconsistent # elements");
1407 for (j = nelem-1; j >= 0; j--) {
1409 for (k = j+1; k < nelem; k++) {
1421 for (j = 0; j < nelem; j++) {
1430 Local BigInt factorial(
int n)
1437 for (j = 2; j <= n; j++) {
1443 Local BigInt ipow(
int n,
int p)
1449 for (j = 2; j <= n; j++) {
1456 Local
void erEnd(
const char *msg)
1458 printf(
"*** Error : %s\n", msg);
1463 Local
int *newArray(
int size,
int val)
1468 for (j = 0; j < size; j++) {
1474 Local
void deletArray(
int *a)
1479 Local
void copyArray(
int size,
int *a0,
int *a1)
1482 for (j = 0; j < size; j++) {
1487 Local
int **newMat(
int n0,
int n1,
int val)
1492 for (j = 0; j < n0; j++) {
1493 m[j] = newArray(n1, val);
1498 Local
void deleteMat(
int **m,
int n0,
int n1)
1503 for (j = 0; j < n0; j++) {
1515 Local
void printArray(
int n,
int *p)
1520 for (j = 0; j < n; j++) {
1521 printf(
" %2d", p[j]);
1526 Local
void printMat(
int n0,
int n1,
int **m)
1530 for (j = 0; j < n0; j++) {
1531 printArray(n1, m[j]);
1536 Global
void testPerm()
1538 int nelem, nperm, nclist, n, count;
1540 int clist[] = {1, 2, 2, 3};
1542 nclist =
sizeof(clist)/
sizeof(
int);
1545 for (n = 0; n < nclist; n++) {
1547 nperm *= factorial(clist[n]);
1550 printf(
"+++ clist = (%d) ", nclist);
1551 printArray(nclist, clist);
1553 printf(
"+++ nelem = %d, nperm = %d\n", nelem, nperm);
1560 count = nextPerm(nelem, nclist, clist, r, q, p, count);
1565 printf(
"%4d:", count);
1566 printArray(nelem, p);
1569 if (count > nperm) {
1573 if (count != nperm) {
1574 printf(
"*** %d != %d\n", count, nperm);