gb_basic.w
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:98k
源码类别:

通讯编程

开发平台:

Visual C++

  1. % This file is part of the Stanford GraphBase (c) Stanford University 1993
  2. @i boilerplate.w %<< legal stuff: PLEASE READ IT BEFORE MAKING ANY CHANGES!
  3. @i gb_types.w
  4. deftitle{GB_,BASIC}
  5. prerequisite{GB_,GRAPH}
  6. @* Introduction. This GraphBase module contains six subroutines that generate
  7. standard graphs of various types, together with six routines that combine or
  8. transform existing graphs.
  9. Simple examples of the use of these routines can be found in the
  10. demonstration programs {sc QUEEN} and {sc QUEEN_WRAP}.
  11. @<gb_basic.h@>=
  12. extern Graph *board(); /* moves on generalized chessboards */
  13. extern Graph *simplex(); /* generalized triangular configurations */
  14. extern Graph *subsets(); /* patterns of subset intersection */
  15. extern Graph *perms(); /* permutations of a multiset */
  16. extern Graph *parts(); /* partitions of an integer */
  17. extern Graph *binary(); /* binary trees */
  18. @#
  19. extern Graph *complement(); /* the complement of a graph */
  20. extern Graph *gunion(); /* the union of two graphs */
  21. extern Graph *intersection(); /* the intersection of two graphs */
  22. extern Graph *lines(); /* the line graph of a graph */
  23. extern Graph *product(); /* the product of two graphs */
  24. extern Graph *induced(); /* a graph induced from another */
  25. @ The CEE/ file .{gb_basic.c} has the following overall shape:
  26. @p
  27. #include "gb_graph.h" /* we use the {sc GB_,GRAPH} data structures */
  28. @h@#
  29. @<Private variables@>@;
  30. @<Basic subroutines@>@;
  31. @<Applications of basic subroutines@>@;
  32. @ Several of the programs below allocate arrays that will be freed again
  33. before the routine is finished.
  34. @<Private variables@>=
  35. static Area working_storage;
  36. @ If a graph-generating subroutine encounters a problem, it returns |NULL|
  37. (that is, .{NULL}), after putting a code number into the external variable
  38. |panic_code|. This code number identifies the type of failure.
  39. Otherwise the routine returns a pointer to the newly created graph, which
  40. will be represented with the data structures explained in {sc GB_,GRAPH}.
  41. (The external variable |panic_code| is itself defined in {sc GB_,GRAPH}.)
  42. @d panic(c) 
  43.   {@+panic_code=c;
  44.     gb_free(working_storage);
  45.     gb_trouble_code=0;
  46.     return NULL;
  47.   }
  48. @ The names of vertices are sometimes formed from the names of other
  49. vertices, or from potentially long sequences of numbers. We assemble
  50. them in the |buffer| array, which is sufficiently long that the
  51. vast majority of applications will be unconstrained by size limitations.
  52. The programs assume that |BUF_SIZE| is rather large, but in cases of
  53. doubt they ensure that |BUF_SIZE| will never be exceeded.
  54. @d BUF_SIZE 4096
  55. @<Private v...@>=
  56. static char buffer[BUF_SIZE];
  57. @*Grids and game boards. The subroutine call
  58. |board(n1,n2,n3,n4,piece,wrap,directed)|
  59. constructs a graph based on the moves of generalized chesspieces on a
  60. generalized rectangular board. Each vertex of the graph corresponds to a
  61. position on the board. Each arc of the graph corresponds to a move from
  62. one position to another.
  63. The first parameters, |n1| through |n4|, specify the size of the board.
  64. If, for example, a two-dimensional board with $n_1$ rows and $n_2$ columns
  65. is desired, you set $|n1|=n_1$, $|n2|=n_2$, and $|n3|=0$; the resulting
  66. graph will have $n_1n_2$ vertices. If you want a three-dimensional
  67. board with $n_3$ layers, set $|n3|=n_3$ and $n_4=0$. If you want
  68. a 4-{mc D} board, put the number of 4th coordinates in~|n4|.
  69. If you want a $d$-dimensional board with $2^d$ positions, set |n1=2|
  70. and |n2=-d|.
  71. In general, the |board| subroutine determines the dimensions by scanning the
  72. sequence |(n1,n2,n3,n4,0)=@t$(n_1,n_2,n_3,n_4,0)$@>| from left to right
  73. until coming to the first nonpositive parameter $n_{k+1}$. If $k=0$
  74. (i.e., if |n1<=0|), the default size $8times8$ will be used; this is
  75. an ordinary chessboard with 8~rows and 8~columns. Otherwise if $n_{k+1}=0$,
  76. the board will have $k$~dimensions $n_1$, dots,~$n_k$. Otherwise
  77. we must have $n_{k+1}<0$; in this case, the board will have $d=vert n_{k+1}
  78. vert$ dimensions, chosen as the first $d$ elements of the infinite
  79. periodic sequence $(n_1,ldots,n_k,n_1,ldots,n_k,n_1,ldots,)$.
  80. For example, the specification |(n1,n2,n3,n4)=(2,3,5,-7)| is about as
  81. tricky as you can get. It produces a seven-dimensional board with
  82. dimensions $(n_1,ldots,n_7)=(2,3,5,2,3,5,2)$, hence a graph with
  83. $2cdot3cdot5cdot2cdot3cdot5cdot2=1800$ vertices.
  84. The |piece| parameter specifies the legal moves of a generalized chesspiece.
  85. If |piece>0|, a move from position~|u| to position~|v| is considered legal
  86. if and only if the Euclidean distance between points |u| and~|v| is
  87. equal to $sqrt{vphantom1smash{|piece|}}$.
  88. For example, if |piece=1| and if we have a
  89. two-dimensional board, the legal moves from $(x,y)$ are to $(x,ypm1)$ and
  90. $(xpm1,y)$; these are the moves of a so-called wazir, the only moves that
  91. a king and a rook can both make. If |piece=2|, the legal moves from $(x,y)$
  92. are to $(xpm1,ypm1)$; these are the four moves that a king and a bishop
  93. can both make. (A piece that can make only these moves was called a ``fers''
  94. in ancient Muslim chess.) If |piece=5|, the legal moves are those of a
  95. knight, from $(x,y)$ to $(xpm1,ypm2)$ or to $(xpm2,ypm1)$. If |piece=3|,
  96. there are no legal moves on a two-dimensional board; but moves from
  97. $(x,y,z)$ to $(xpm1,ypm1,zpm1)$ would be legal in three dimensions.
  98. If |piece=0|, it is changed to the default value |piece=1|.
  99. If the value of |piece| is negative, arbitrary multiples of the basic moves
  100. for $vert|piece|vert$ are permitted. For example, |piece=-1| defines the
  101. moves of a rook, from $(x,y)$ to $(xpm a,y)$ or to $(x,ypm a)$ for all
  102. $a>0$; |piece=-2| defines the moves of a bishop, from $(x,y)$ to
  103. $(xpm a,ypm a)$. The literature of ``fairy chess'' assigns standard names
  104. to the following |piece| values: $rm wazir=1$, $rm fers=2$, $rm dabbaba=4$,
  105. $rm knight=5$, $rm alfil=8$, $rm camel=10$, $rm zebra=13$, $rm giraffe
  106. =17$, $rm fiveleaper=25$, $hbox{root-50-leaper}=50$, etc.; $rm rook=-1$,
  107. $rm bishop=-2$, $rm unicorn=-3$, $rm dabbabarider=-4$, $rm nightrider=-5$,
  108. $rm alfilrider=-8$, $rm camelrider=-10$, etc.
  109. To generate a board with the moves of a king, you can use the |gunion|
  110. subroutine below to take the union of boards with |piece=1| and
  111. |piece=2|. Similarly, you can get queen moves by taking the union of
  112. boards with |piece=-1| and |piece=-2|.
  113. If |piece>0|, all arcs of the graph will have length~1. If |piece<0|, the
  114. length of each arc will be the number of multiples of a basic move that
  115. produced the arc.
  116. @ If the |wrap| parameter is nonzero, it specifies a subset of coordinates
  117. in which values are computed modulo the corresponding size.
  118. For example, the coordinates $(x,y)$ for vertices on a two-dimensional
  119. board are restricted to the range $0le x<n_1$, $0le y<n_2$; therefore
  120. when |wrap=0|, a move from $(x,y)$ to $(x+delta_1,y+delta_2)$ is
  121. legal only if $0le x+delta_1<n_1$ and $0le y+delta_2<n_2$.
  122. But when |wrap=1|, the $x$~coordinates are allowed to ``wrap around'';
  123. the move would then be made to $((x+delta_1)bmod n_1,y+delta_2)$,
  124. provided that $0le y+delta_2<n_2$. Setting |wrap=1| effectively
  125. makes the board into a cylinder instead of a rectangle. Similarly, the
  126. $y$~coordinates are allowed to wrap around when |wrap=2|. Both $x$ and
  127. $y$ coordinates are treated modulo their corresponding sizes when
  128. |wrap=3|; the board is then effectively a torus.  In general,
  129. coordinates $k_1$, $k_2$, dots~ will wrap around when
  130. $|wrap|=2^{k_1-1}+2^{k_2-1}+cdots,$. Setting |wrap=-1| causes all
  131. coordinates to be computed modulo their size.
  132. The graph constructed by |board| will be undirected unless |directed!=0|.
  133. Directed |board| graphs will be acyclic when |wrap=0|, but they may
  134. have cycles when |wrap!=0|. Precise rules defining the directed arcs
  135. are given below.
  136. Several important special cases are worth noting. To get the complete graph
  137. on |n| vertices, you can say |board(n,0,0,0,-1,0,0)|. To get the
  138. transitive tournament on |n| vertices, i.e., the directed graph
  139. with arcs from |u| to |v| when |u<v|, you can say |board(n,0,0,0,-1,0,1)|.
  140. To get the empty graph on |n| vertices, you can say |board(n,0,0,0,2,0,0)|.
  141. To get a circuit (undirected) or a cycle (directed) of length~|n|,
  142. you can say |board(n,0,0,0,1,1,0)| and |board(n,0,0,0,1,1,1)|,
  143. respectively.
  144. @(gb_basic.h@>=
  145. #define complete(n) @[board((long)(n),0L,0L,0L,-1L,0L,0L)@]
  146. #define transitive(n) @[board((long)(n),0L,0L,0L,-1L,0L,1L)@]
  147. #define empty(n) @[board((long)(n),0L,0L,0L,2L,0L,0L)@]
  148. #define circuit(n) @[board((long)(n),0L,0L,0L,1L,1L,0L)@]
  149. #define cycle(n) @[board((long)(n),0L,0L,0L,1L,1L,1L)@]
  150. @ @<Basic subroutines@>=
  151. Graph *board(n1,n2,n3,n4,piece,wrap,directed)
  152.   long n1,n2,n3,n4; /* size of board desired */
  153.   long piece; /* type of moves desired */
  154.   long wrap; /* mask for coordinate positions that wrap around */
  155.   long directed; /* should the graph be directed? */
  156. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  157.   long n; /* total number of vertices */
  158.   long p; /* $vert|piece|vert$ */
  159.   long l; /* length of current arc */
  160.   @<Normalize the board-size parameters@>;
  161.   @<Set up a graph with |n| vertices@>;
  162.   @<Insert arcs or edges for all legal moves@>;
  163.   if (gb_trouble_code) {
  164.     gb_recycle(new_graph);
  165.     panic(alloc_fault); /* alas, we ran out of memory somewhere back there */
  166.   }
  167.   return new_graph;
  168. }
  169. @ Most of the subroutines in {sc GB_,BASIC} use the following local
  170. variables.
  171. @<Vanilla local variables@>=
  172. Graph *new_graph; /* the graph being constructed */
  173. register long i,j,k; /* all-purpose indices */
  174. register long d; /* the number of dimensions */
  175. register Vertex *v; /* the current vertex of interest */
  176. register long s; /* accumulator */
  177. @ Several arrays will facilitate the calculations that |board| needs to make.
  178. The number of distinct values in coordinate position~$k$ will be |nn[k]|;
  179. this coordinate position will wrap around if and only if |wr[k]!=0|.
  180. The current moves under consideration will be from $(x_1,ldots,x_d)$
  181. to $(x_1+delta_1,ldots, x_k+delta_k)$, where $delta_k$ is stored
  182. in |del[k]|. An auxiliary array |sig| holds the sums
  183. $sigma_k=delta_1^2+cdots+delta_{k-1}^2$.  Additional arrays |xx|
  184. and |yy| hold coordinates of vertices before and after a move is made.
  185. Some of these arrays are also used for other purposes by other programs
  186. besides |board|; we will meet those programs later.
  187. We limit the number of dimensions to 91 or less. This is hardly a limitation,
  188. since the number of vertices would be astronomical even if the dimensionality
  189. were only half this big. But some of our later programs will be able
  190. to make good use of 40 or 50 dimensions and perhaps more; the number 91
  191. is an upper limit imposed by the number of standard printable characters
  192. (see the convention for vertex names in the |perms| routine).
  193. @d MAX_D 91
  194. @<Private...@>=
  195. static long nn[MAX_D+1]; /* component sizes */
  196. static long wr[MAX_D+1]; /* does this component wrap around? */
  197. static long del[MAX_D+1]; /* displacements for the current move */
  198. static long sig[MAX_D+2]; /* partial sums of squares of displacements */
  199. static long xx[MAX_D+1], yy[MAX_D+1]; /* coordinate values */
  200. @ @<Normalize the board-size parameters@>=
  201. if (piece==0) piece=1;
  202. if (n1<=0) {@+n1=n2=8;@+n3=0;@+}
  203. nn[1]=n1;
  204. if (n2<=0) {@+k=2;@+d=-n2;@+n3=n4=0;@+}
  205. else {
  206.   nn[2]=n2;
  207.   if (n3<=0) {@+k=3;@+d=-n3;@+n4=0;@+}
  208.   else {
  209.     nn[3]=n3;
  210.     if (n4<=0) {@+k=4;@+d=-n4;@+}
  211.     else {@+nn[4]=n4;@+d=4;@+goto done;@+}
  212.   }
  213. }
  214. if (d==0) {@+d=k-1;@+goto done;@+}
  215. @<Compute component sizes periodically for |d| dimensions@>;
  216. done: /* now |nn[1]| through |nn[d]| are set up */
  217. @ At this point, |nn[1]| through |nn[k-1]| are the component sizes
  218. that should be replicated periodically. In unusual cases, the number
  219. of dimensions might not be as large as the number of specifications.
  220. @<Compute component sizes periodically...@>=
  221. if (d>MAX_D) panic(bad_specs); /* too many dimensions */
  222. for (j=1; k<=d; j++,k++) nn[k]=nn[j];
  223. @ We want to make the subroutine idiot-proof, so we use floating-point
  224. arithmetic to make sure that boards with more than a billion cells have
  225. not been specified.
  226. @d MAX_NNN 1000000000.0
  227. @<Set up a graph with |n| vertices@>=
  228. {@+float nnn; /* approximate size */
  229.   for (n=1,nnn=1.0,j=1; j<=d; j++) {
  230.     nnn *= (float)nn[j];
  231.     if (nnn>MAX_NNN) panic(very_bad_specs); /* way too big */
  232.     n *= nn[j]; /* this multiplication cannot cause integer overflow */
  233.   }
  234.   new_graph=gb_new_graph(n);
  235.   if (new_graph==NULL)
  236.     panic(no_room); /* out of memory before we're even started */
  237.   sprintf(new_graph->id,"board(%ld,%ld,%ld,%ld,%ld,%ld,%d)",
  238.     n1,n2,n3,n4,piece,wrap,directed?1:0);
  239.   strcpy(new_graph->util_types,"ZZZIIIZZZZZZZZ");
  240.   @<Give names to the vertices@>;
  241. }
  242. @ The symbolic name of a board position like $(3,1)$ will be the string
  243. `.{3.1}'. The first three coordinates are also stored as integers, in
  244. utility fields |x.I|, |y.I|, and |z.I|, because immediate access to
  245. those values will be helpful in certain applications. (The coordinates can,
  246. of course, always be recovered in a slower fashion from the vertex name,
  247. via |sscanf|.)
  248. The process of assigning coordinate values and names is equivalent to
  249. adding unity in a mixed-radix number system. Vertex $(x_1,ldots,x_d)$
  250. will be in position $x_1n_2ldots n_d+cdots+x_{d-1}n_d+x_d$ relative
  251. to the first vertex of the new graph; therefore it is also possible to
  252. deduce the coordinates of a vertex from its address.
  253. @<Give names...@>=
  254. {@+register char *q; /* string pointer */
  255.   nn[0]=xx[0]=xx[1]=xx[2]=xx[3]=0;
  256.   for (k=4;k<=d;k++) xx[k]=0;
  257.   for (v=new_graph->vertices;;v++) {
  258.     q=buffer;
  259.     for (k=1;k<=d;k++) {
  260.       sprintf(q,".%ld",xx[k]);
  261.       while (*q) q++;
  262.     }
  263.     v->name=gb_save_string(&buffer[1]); /* omit |buffer[0]|, which is |'.'| */
  264.     v->x.I=xx[1];@+v->y.I=xx[2];@+v->z.I=xx[3];
  265.     for (k=d;xx[k]+1==nn[k];k--) xx[k]=0;
  266.     if (k==0) break; /* a ``carry'' has occurred all the way to the left */
  267.     xx[k]++; /* increase coordinate |k| */
  268.   }
  269. }
  270.       
  271. @ Now we come to a slightly tricky part of the routine: the move generator.
  272. Let $p=vert|piece|vert$. The outer loop of this procedure runs through all
  273. solutions of the equation $delta_1^2+cdots+delta_d^2=p$, where the
  274. $delta$'s are nonnegative integers. Within that loop, we attach signs
  275. to the $delta$'s, but we always leave $delta_k$ positive if $delta_1=
  276. cdots=delta_{k-1}=0$. For every such vector~$delta$, we generate moves
  277. from |v| to $v+delta$ for every vertex |v|. When |directed=0|,
  278. we use |gb_new_edge| instead of |gb_new_arc|, so that the reverse arc
  279. from $v+delta$ to~|v| is also generated.
  280. @<Insert arcs or edges for all legal moves@>=
  281. @<Initialize the |wr|, |sig|, and |del| tables@>;
  282. p=piece;
  283. if (p<0) p=-p;
  284. while (1) {
  285.   @<Advance to the next nonnegative |del| vector, or |break| if done@>;
  286.   while (1) {
  287.     @<Generate moves for the current |del| vector@>;
  288.     @<Advance to the next signed |del| vector, or restore |del|
  289.           to nonnegative values and |break|@>;
  290.   }
  291. }
  292. @ The CEE/ language does not define |>>| unambiguously. If |w| is negative,
  293. the assignment `|w>>=1|' here should keep |w| negative.
  294. (However, this technicality doesn't matter except in highly unusual cases
  295. when there are more than 32 dimensions.)
  296. @^system dependencies@>
  297. @<Initialize the |wr|, |sig|, and |del| tables@>=
  298. {@+register long w=wrap;
  299.   for (k=1;k<=d;k++,w>>=1) {
  300.     wr[k]=w&1;
  301.     del[k]=sig[k]=0;
  302.   }
  303.   sig[0]=del[0]=sig[d+1]=0;
  304. }
  305. @ The |sig| array makes it easy to backtrack through all partitions
  306. of |p| into an ordered sum of squares.
  307. @<Advance to the next nonnegative |del|...@>=
  308. for (k=d;sig[k]+(del[k]+1)*(del[k]+1)>p;k--) del[k]=0;
  309. if (k==0) break;
  310. del[k]++;
  311. sig[k+1]=sig[k]+del[k]*del[k];
  312. for (k++;k<=d;k++) sig[k+1]=sig[k];
  313. if (sig[d+1]<p) continue;
  314. @ @<Advance to the next signed |del| vector, or restore |del|
  315.           to nonnegative values and |break|@>=
  316. for (k=d;del[k]<=0;k--) del[k]=-del[k];
  317. if (sig[k]==0) break; /* all but |del[k]| were negative or zero */
  318. del[k]=-del[k]; /* some entry preceding |del[k]| is positive */
  319. @ We use the mixed-radix addition technique again when generating moves.
  320. @<Generate moves for the current |del| vector@>=
  321. for (k=1;k<=d;k++) xx[k]=0;
  322. for (v=new_graph->vertices;;v++) {
  323.   @<Generate moves from |v| corresponding to |del|@>;
  324.   for (k=d;xx[k]+1==nn[k];k--) xx[k]=0;
  325.   if (k==0) break; /* a ``carry'' has occurred all the way to the left */
  326.   xx[k]++; /* increase coordinate |k| */
  327. }
  328. @ The legal moves when |piece| is negative are derived as follows, in
  329. the presence of possible wraparound: Starting at $(x_1,ldots,x_d)$, we
  330. move to $(x_1+delta_1,ldots,x_d+delta_d)$, $(x_1+2delta_1,ldots,
  331. x_d+2delta_d)$,~dots, until either coming to a position with a nonwrapped
  332. coordinate out of range or coming back to the original point.
  333. A subtle technicality should be noted: When coordinates are wrapped and
  334. |piece>0|, self-loops are possible---for example, in |board(1,0,0,0,1,1,1)|.
  335. But self-loops never arise when |piece<0|.
  336. @<Generate moves from |v|...@>=
  337. for (k=1;k<=d;k++) yy[k]=xx[k]+del[k];
  338. for (l=1;;l++) {
  339.   @<Correct for wraparound, or |goto no_more| if off the board@>;
  340.   if (piece<0) @<Go to |no_more| if |yy=xx|@>;
  341.   @<Record a legal move from |xx| to |yy|@>;
  342.   if (piece>0) goto no_more;
  343.   for (k=1;k<=d;k++) yy[k]+=del[k];
  344. }
  345. no_more:
  346. @ @<Go to |no_more|...@>=
  347. {
  348.   for (k=1;k<=d;k++) if (yy[k]!=xx[k]) goto unequal;
  349.   goto no_more;
  350.   unequal:;
  351. }
  352. @ @<Correct for wraparound, or |goto no_more| if off the board@>=
  353. for (k=1;k<=d;k++) {
  354.   if (yy[k]<0) {
  355.     if (!wr[k]) goto no_more;
  356.     do yy[k]+=nn[k];@+ while (yy[k]<0);
  357.   }@+else if (yy[k]>=nn[k]) {
  358.     if (!wr[k]) goto no_more;
  359.     do yy[k]-=nn[k];@+ while (yy[k]>=nn[k]);
  360.   }
  361. }
  362. @ @<Record a legal move from |xx| to |yy|@>=
  363. for (k=2,j=yy[1];k<=d;k++) j=nn[k]*j+yy[k];
  364. if (directed) gb_new_arc(v,new_graph->vertices+j,l);
  365. else gb_new_edge(v,new_graph->vertices+j,l);
  366. @* Generalized triangular boards. The subroutine call
  367. |simplex(n,n0,n1,n2,n3,n4,directed)| creates a graph based on
  368. generalized triangular or tetrahedral configurations. Such graphs are
  369. similar in spirit to the game boards created by |board|, but they
  370. pertain to nonrectangular grids like those in Chinese checkers. As
  371. with |board| in the case |piece=1|, the vertices represent board positions
  372. and the arcs run from board positions to their nearest neighbors. Each arc has
  373. length~1.{tolerance=1000par}
  374. More formally, the vertices can be defined as sequences of nonnegative
  375. integers $(x_0,x_1,ldots,x_d)$ whose sum is~|n|, where two sequences
  376. are considered adjacent if and only if they differ by $pm1$ in exactly
  377. two components---equivalently, if the Euclidean distance between them
  378. is~$sqrt2$. When $d=2$, for example, the vertices can be visualized
  379. as a triangular array
  380. $$vcenter{halign{&hbox to 2em{hss$#$hss}cr
  381. &&&(0,0,3)cr
  382. &&(0,1,2)&&(1,0,2)cr
  383. &(0,2,1)&&(1,1,1)&&(2,0,1)cr
  384. (0,3,0)&&(1,2,0)&&(2,1,0)&&(3,0,0)cr}}$$
  385. containing $(n+1)(n+2)/2$ elements, illustrated here when $n=3$; each vertex of
  386. the array has up to 6 neighbors. When $d=3$ the vertices form a tetrahedral
  387. array, a stack of triangular layers, and they can have as many as 12
  388. neighbors. In general, a vertex in a $d$-simplicial array will have up to
  389. $d(d+1)$ neighbors.
  390. If the |directed| parameter is nonzero, arcs run only from vertices to
  391. neighbors that are lexicographically greater---for example, downward
  392. or to the right in the triangular array shown. The directed graph is
  393. therefore acyclic, and a vertex of a $d$-simplicial array has
  394. out-degree at most $d(d+1)/2$.
  395. @ The first parameter, |n|, specifies the sum of the coordinates
  396. $(x_0,x_1,ldots,x_d)$. The following parameters |n0| through |n4|
  397. specify upper bounds on those coordinates, and they also specify the
  398. dimensionality~|d|.
  399. If, for example, |n0|, |n1|, and |n2| are positive while |n3=0|, the
  400. value of~|d| will be~2 and the coordinates will be constrained to
  401. satisfy $0le x_0le|n0|$, $0le x_1le|n1|$, $0le x_2le|n2|$. These
  402. upper bounds essentially lop off the corners of the triangular array.
  403. We obtain a hexagonal board with $6m$ boundary cells by asking for
  404. |simplex(3m,2m,2m,2m,0,0,0)|. We obtain the diamond-shaped board used
  405. in the game of Hex [Martin Gardner, {sl The Scientific American
  406. @^Gardner, Martin@>
  407. Book of Mathematical Puzzles {char`&} Diversions/} (Simon {char`&}
  408. Schuster, 1959), Chapter~8] by calling |simplex(20,10,20,10,0,0,0)|.
  409. In general, |simplex| determines |d| and upper bounds $(n_0,n_1,ldots,n_d)$
  410. in the following way: Let the first nonpositive entry of the sequence
  411. |(n0,n1,n2,n3,n4,0)|$null=(n_0,n_1,n_2,n_3,n_4,0)$ be~$n_k$. If $k>0$
  412. and $n_k=0$, the value of~$d$ will be $k-1$ and the coordinates will be
  413. bounded by the given numbers $(n_0,ldots,n_d)$. If $k>0$ and $n_k<0$,
  414. the value of~$d$ will be $vert n_kvert$ and the coordinates will be
  415. bounded by the first $d+1$ elements of the infinite periodic sequence
  416. $(n_0,ldots,n_{k-1},n_0,ldots,n_{k-1},n_0,ldots,)$. If $k=0$ and
  417. $n_0<0$, the value of~$d$ will be $vert n_0vert$ and the coordinates
  418. will be unbounded; equivalently, we may set $n_0=cdots=n_d=n$. In
  419. this case the number of vertices will be $n+dchoose d$. Finally,
  420. if $k=0$ and $n_0=0$, we have the default case of a triangular array
  421. with $3n$ boundary cells, exactly as if $n_0=-2$.
  422. For example, the specification |n0=3|, |n1=-5| will produce all vertices
  423. $(x_0,x_1,ldots,x_5)$ such that $x_0+x_1+cdots+x_5=n$ and $0le x_jle3$.
  424. The specification |n0=1|, |n1=-d| will essentially produce all $n$-element
  425. subsets of the $(d+1)$-element set ${0,1,ldots,d}$, because we can
  426. regard an element~$k$ as being present in the set if $x_k=1$ and absent
  427. if $x_k=0$. In that case two subsets are adjacent if and only if
  428. they have exactly $n-1$ elements in common. 
  429. @ @<Basic subroutines@>=
  430. Graph *simplex(n,n0,n1,n2,n3,n4,directed)
  431.   unsigned long n; /* the constant sum of all coordinates */
  432.   long n0,n1,n2,n3,n4; /* constraints on coordinates */
  433.   long directed; /* should the graph be directed? */
  434. {@+@<Vanilla local variables@>@;@#
  435.   @<Normalize the simplex parameters@>;
  436.   @<Create a graph with one vertex for each point@>;
  437.   @<Name the points and create the arcs or edges@>;
  438.   if (gb_trouble_code) {
  439.     gb_recycle(new_graph);
  440.     panic(alloc_fault); /* darn, we ran out of memory somewhere back there */
  441.   }
  442.   return new_graph;
  443. }
  444. @ @<Normalize the simplex parameters@>=
  445. if (n0==0) n0=-2;
  446. if (n0<0) {@+k=2;@+nn[0]=n;@+d=-n0;@+n1=n2=n3=n4=0;@+}
  447. else {
  448.   if (n0>n) n0=n;
  449.   nn[0]=n0;
  450.   if (n1<=0) {@+k=2;@+d=-n1;@+n2=n3=n4=0;@+}
  451.   else {
  452.     if (n1>n) n1=n;
  453.     nn[1]=n1;
  454.     if (n2<=0) {@+k=3;@+d=-n2;@+n3=n4=0;@+}
  455.     else {
  456.       if (n2>n) n2=n;
  457.       nn[2]=n2;
  458.       if (n3<=0) {@+k=4;@+d=-n3;@+n4=0;@+}
  459.       else {
  460.         if (n3>n) n3=n;
  461.         nn[3]=n3;
  462.         if (n4<=0) {@+k=5;@+d=-n4;@+}
  463.         else {@+if (n4>n) n4=n;
  464.           nn[4]=n4;@+d=4;@+goto done;@+}
  465.       }
  466.     }
  467.   }
  468. }
  469. if (d==0) {@+d=k-2;@+goto done;@+}
  470. nn[k-1]=nn[0];
  471. @<Compute component sizes periodically...@>;
  472. done: /* now |nn[0]| through |nn[d]| are set up */
  473. @ @<Create a graph with one vertex for each point@>=
  474. @<Determine the number of feasible $(x_0,ldots,x_d)$,
  475.   and allocate the graph@>;
  476. sprintf(new_graph->id,"simplex(%lu,%ld,%ld,%ld,%ld,%ld,%d)",
  477.     n,n0,n1,n2,n3,n4,directed?1:0);
  478. strcpy(new_graph->util_types,"VVZIIIZZZZZZZZ"); /* hash table will be used */
  479. @ We determine the number of vertices by determining the coefficient of~$z^n$
  480. in the power series
  481. $$(1+z+cdots+z^{n_0})(1+z+cdots+z^{n_1})ldots(1+z+cdots+z^{n_d}).$$
  482. @<Determine the number of feasible $(x_0,ldots,x_d)$...@>=
  483. {@+long nverts; /* the number of vertices */
  484.   register long *coef=gb_typed_alloc(n+1,long,working_storage);
  485.   if (gb_trouble_code) panic(no_room+1); /* can't allocate |coef| array */
  486.   for (k=0;k<=nn[0];k++) coef[k]=1;
  487.    /* now |coef| represents the coefficients of $1+z+cdots+z^{n_0}$ */
  488.   for (j=1;j<=d;j++)
  489.     @<Multiply the power series coefficients by $1+z+cdots+z^{n_j}$@>;
  490.   nverts=coef[n];
  491.   gb_free(working_storage); /* recycle the |coef| array */
  492.   new_graph=gb_new_graph(nverts);
  493.   if (new_graph==NULL)
  494.     panic(no_room); /* out of memory before we're even started */
  495. }
  496. @ There's a neat way to multiply by $1+z+cdots+z^{n_j}$: We multiply
  497. first by $1-z^{n_j+1}$, then sum the coefficients.
  498. We want to detect impossibly large specifications without risking
  499. integer overflow. It is easy to do this because multiplication is being
  500. done via addition.
  501. @<Multiply the power series coefficients by $1+z+cdots+z^{n_j}$@>=
  502. {
  503.   for (k=n,i=n-nn[j]-1;i>=0;k--,i--) coef[k]-=coef[i];
  504.   s=1;
  505.   for (k=1;k<=n;k++) {
  506.     s+=coef[k];
  507.     if (s>1000000000) panic(very_bad_specs); /* way too big */
  508.     coef[k]=s;
  509.   }
  510. }
  511. @ As we generate the vertices, it proves convenient to precompute an
  512. array containing the numbers $y_j=n_j+cdots+n_d$, which represent the
  513. largest possible sums $x_j+cdots+x_d$. We also want to maintain
  514. the numbers $sigma_j=n-(x_0+cdots+x_{j-1})=x_j+cdots+x_d$. The
  515. conditions
  516. $$0le x_jle n_j, qquad sigma_j-y_{j+1}le x_jle sigma_j$$
  517. are necessary and sufficient, in the sense that we can find at least
  518. one way to complete a partial solution $(x_0,ldots,x_k)$ to a full
  519. solution $(x_0,ldots,x_d)$ if and only if the conditions hold for
  520. all $jle k$.
  521. There is at least one solution if and only if $nle y_0$.
  522. We enter the name string into a hash table, using the |hash_in|
  523. routine of {sc GB_,GRAPH}, because there is no simple way to compute the
  524. location of a vertex from its coordinates.
  525. @<Name the points and create the arcs or edges@>=
  526. v=new_graph->vertices;
  527. yy[d+1]=0;@+sig[0]=n;
  528. for (k=d;k>=0;k--) yy[k]=yy[k+1]+nn[k];
  529. if (yy[0]>=n) {
  530.   k=0;@+xx[0]=(yy[1]>=n? 0: n-yy[1]);
  531.   while (1) {
  532.     @<Complete the partial solution $(x_0,ldots,x_k)$@>;
  533.     @<Assign a symbolic name for $(x_0,ldots,x_d)$ to vertex~|v|@>;
  534.     hash_in(v); /* enter |v->name| into the hash table
  535.                   (via utility fields |u,v|) */
  536.     @<Create arcs or edges from previous points to~|v|@>;
  537.     v++;
  538.     @<Advance to the next partial solution $(x_0,ldots,x_k)$, where |k| is
  539.        as large as possible; |goto last| if there are no more solutions@>;
  540.   }
  541. }
  542. last:@+if (v!=new_graph->vertices+new_graph->n)
  543.   panic(impossible); /* can't happen */
  544. @ @<Complete the partial solution $(x_0,ldots,x_k)$@>=
  545. for (s=sig[k]-xx[k],k++;k<=d;s-=xx[k],k++) {
  546.   sig[k]=s;
  547.   if (s<=yy[k+1]) xx[k]=0;
  548.   else xx[k]=s-yy[k+1];
  549. }
  550. if (s!=0) panic(impossible+1) /* can't happen */
  551. @ Here we seek the largest $k$ such that $x_k$ can be increased without
  552. violating the necessary and sufficient conditions stated earlier.
  553. @<Advance to the next partial solution $(x_0,ldots,x_k)$...@>=
  554. for (k=d-1;;k--) {
  555.   if (xx[k]<sig[k] && xx[k]<nn[k]) break;
  556.   if (k==0) goto last;
  557. }
  558. xx[k]++;
  559. @ As in the |board| routine, we represent the sequence of coordinates
  560. $(2,0,1)$ by the string `.{2.0.1}'.
  561. The string won't exceed |BUF_SIZE|, because the ratio |BUF_SIZE/MAX_D| is
  562. plenty big.
  563. The first three coordinate values, $(x_0,x_1,x_2)$, are placed into
  564. utility fields |x|, |y|, and |z|, so that they can be accessed immediately
  565. if an application needs them.
  566. @<Assign a symbolic name for $(x_0,ldots,x_d)$ to vertex~|v|@>=
  567. {@+register char *p=buffer; /* string pointer */
  568.   for (k=0;k<=d;k++) {
  569.     sprintf(p,".%ld",xx[k]);
  570.     while (*p) p++;
  571.   }
  572.   v->name=gb_save_string(&buffer[1]); /* omit |buffer[0]|, which is |'.'| */
  573.   v->x.I=xx[0];@+v->y.I=xx[1];@+v->z.I=xx[2];
  574. }
  575. @ Since we are generating the vertices in lexicographic order of their
  576. coordinates, it is easy to identify all adjacent vertices that
  577. precede the current setting of $(x_0,x_1,ldots,x_d)$. We locate them
  578. via their symbolic names.
  579. @<Create arcs or edges from previous points to~|v|@>=
  580. for (j=0;j<d;j++)
  581.   if (xx[j]) {@+register Vertex *u; /* previous vertex adjacent to |v| */
  582.     xx[j]--;
  583.     for (k=j+1;k<=d;k++)
  584.       if (xx[k]<nn[k]) {@+register char *p=buffer; /* string pointer */
  585.         xx[k]++;
  586.         for (i=0;i<=d;i++) {
  587.           sprintf(p,".%ld",xx[i]);
  588.           while (*p) p++;
  589.         }
  590.         u=hash_out(&buffer[1]);
  591.         if (u==NULL) panic(impossible+2); /* can't happen */
  592.         if (directed) gb_new_arc(u,v,1L);
  593.         else gb_new_edge(u,v,1L);
  594.         xx[k]--;
  595.       }
  596.     xx[j]++;
  597.   }
  598. @* Subset graphs. The subroutine call {advancethinmuskip 0mu plus 2mu
  599. |subsets(n,n0,n1,n2,n3,n4,size_bits,directed)|}
  600. creates a graph having the same vertices as
  601. |simplex(n,n0,n1,n2,n3,n4,directed)| but with a quite different notion
  602. of adjacency. In this we interpret a solution $(x_0,x_1,ldots,x_d)$ to
  603. the conditions $x_0+x_1+cdots+x_d=n$ and $0le x_jle n_j$ not as a
  604. position on a game board but as an $n$-element submultiset of the multiset
  605. ${n_0cdot0,n_1cdot 1,ldots,n_dcdot d}$ that has $x_j$ elements
  606. equal to~$j$. (If each $n_j=1$, the multiset is a set; this is an
  607. important special case.) Two vertices are adjacent if and only if
  608. their intersection has a cardinality that matches one of the bits in
  609. |size_bits|, which is an unsigned integer. Each arc has length~1.
  610. For example, suppose $n=3$ and |(n0,n1,n2,n3)=(2,2,2,0)|. Then the vertices
  611. are the 3-element submultisets of ${0,0,1,1,2,2}$, namely
  612. $${0,0,1},quad {0,0,2},quad {0,1,2},quad
  613. {0,2,2},quad {1,1,2},quad {1,2,2},$$
  614. which are represented by the respective vectors
  615. $$(2,1,0),quad (2,0,1),quad (1,1,1),quad
  616. (1,0,2),quad (0,2,1),quad (0,1,2).$$
  617. The intersection of multisets represented by $(x_0,x_1,ldots,x_d)$ and
  618. $(y_0,y_1,ldots,y_d)$ is $$bigl(min(x_0,y_0),min(x_1,y_1),ldots,
  619. min(x_d,y_d)bigr);$$ each element occurs as often as it occurs
  620. in both multisets being intersected. If now |size_bits=3|, the
  621. multisets will be considered adjacent whenever their
  622. intersection contains exactly 0 or~1 elements, because $3=2^0+2^1$.
  623. The vertices adjacent to ${0,0,1}$, for example, will be
  624. ${0,2,2}$ and ${1,2,2}$. In this case, every pair of submultisets
  625. has a nonempty intersection, so the same graph would be obtained
  626. if |size_bits=2|.
  627. If |directed| is nonzero, the graph will have directed arcs, from |u|
  628. to~|v| only if $ule v$. Notice that the graph will have self-loops if
  629. and only if the binary representation of |size_bits| contains the term
  630. $2^n$, in which case there will be a loop from every vertex to itself.
  631. (In an undirected graph, such loops are represented by two arcs.)
  632. We define a macro |disjoint_subsets(n,k)| for the case
  633. of $nchoose k$ vertices, adjacent if and only if they represent
  634. disjoint $k$-subsets of an $n$-set.
  635. One important special case is the Petersen graph, whose vertices
  636. @^Petersen, Julius Peter Christian, graph@>
  637. are the 2-element subsets of ${0,1,2,3,4}$, adjacent when they
  638. are disjoint. This graph is remarkable because it contains 10 vertices,
  639. each of degree~3, but it has no circuits of length less than~5.
  640. @(gb_basic.h@>=
  641. #define disjoint_subsets(n,k) @[subsets((long)(k),1L,(long)(1-(n)),0L,0L,0L,1L,0L)@]
  642. #define petersen() @[disjoint_subsets(5,2)@]
  643. @ @<Basic subroutines@>=
  644. Graph *subsets(n,n0,n1,n2,n3,n4,size_bits,directed)
  645.   unsigned long n; /* the number of elements in the multiset */
  646.   long n0,n1,n2,n3,n4; /* multiplicities of elements */
  647.   unsigned long size_bits; /* intersection sizes that trigger arcs */
  648.   long directed; /* should the graph be directed? */
  649. {@+@<Vanilla local variables@>@;@#
  650.   @<Normalize the simplex parameters@>;
  651.   @<Create a graph with one vertex for each subset@>;
  652.   @<Name the subsets and create the arcs or edges@>;
  653.   if (gb_trouble_code) {
  654.     gb_recycle(new_graph);
  655.     panic(alloc_fault); /* rats, we ran out of memory somewhere back there */
  656.   }
  657.   return new_graph;
  658. }
  659. @ @<Create a graph with one vertex for each subset@>=
  660. @<Determine the number of feasible $(x_0,ldots,x_d)$,
  661.   and allocate the graph@>;
  662. sprintf(new_graph->id,"subsets(%lu,%ld,%ld,%ld,%ld,%ld,0x%lx,%d)",
  663.     n,n0,n1,n2,n3,n4,size_bits,directed?1:0);
  664. strcpy(new_graph->util_types,"ZZZIIIZZZZZZZZ");
  665.  /* hash table will not be used */
  666. @ We generate the vertices with exactly the logic used in |simplex|.
  667. @<Name the subsets and create the arcs or edges@>=
  668. v=new_graph->vertices;
  669. yy[d+1]=0;@+sig[0]=n;
  670. for (k=d;k>=0;k--) yy[k]=yy[k+1]+nn[k];
  671. if (yy[0]>=n) {
  672.   k=0;@+xx[0]=(yy[1]>=n? 0: n-yy[1]);
  673.   while (1) {
  674.     @<Complete the partial solution $(x_0,ldots,x_k)$@>;
  675.     @<Assign a symbolic name for $(x_0,ldots,x_d)$ to vertex~|v|@>;
  676.     @<Create arcs or edges from previous subsets to~|v|@>;
  677.     v++;
  678.     @<Advance to the next partial solution $(x_0,ldots,x_k)$, where |k| is
  679.        as large as possible; |goto last| if there are no more solutions@>;
  680.   }
  681. }
  682. last:@+if (v!=new_graph->vertices+new_graph->n)
  683.   panic(impossible); /* can't happen */
  684. @ The only difference is that we generate the arcs or edges by brute
  685. force, examining each pair of vertices to see if they are adjacent or not.
  686. The code here is character-set dependent: It assumes that `..' and null
  687. have a character code less than `.0', as in ASCII. It also assumes
  688. that characters occupy exactly eight bits.
  689. @^system dependencies@>
  690. @d UL_BITS 8*sizeof(unsigned long) /* the number of bits in |size_bits| */
  691. @<Create arcs or edges from previous subsets to~|v|@>=
  692. {@+register Vertex *u;
  693.   for (u=new_graph->vertices;u<=v;u++) {@+register char *p=u->name;
  694.     long ss=0; /* the number of elements common to |u| and |v| */
  695.     for (j=0;j<=d;j++,p++) {
  696.       for (s=(*p++)-'0';*p>='0';p++) s=10*s+*p-'0'; /* |sscanf(p,"%ld",&s)| */
  697. @^character-set dependencies@>
  698.       if (xx[j]<s) ss+=xx[j];
  699.       else ss+=s;
  700.     }
  701.     if (ss<UL_BITS && (size_bits&(((unsigned long)1)<<ss))) {
  702.       if (directed) gb_new_arc(u,v,1L);
  703.       else gb_new_edge(u,v,1L);
  704.     }
  705.   }
  706. }
  707. @* Permutation graphs. The subroutine call
  708. |perms(n0,n1,n2,n3,n4,max_inv,directed)|
  709. creates a graph whose vertices represent the permutations of a
  710. multiset that have at most |max_inv| inversions. Two permutations are adjacent
  711. in the graph if one is obtained from the other by interchanging two
  712. adjacent elements. Each arc has length~1.
  713. For example, the multiset ${0,0,1,2}$ has the following twelve permutations:
  714. $$vcenter{halign{#&&quad#cr
  715. 0012,&0021,&0102,&0120,&0201,&0210,cr
  716. 1002,&1020,&1200,&2001,&2010,&2100.cr}}$$
  717. The first of these, 0012, has two neighbors, 0021 and 0102.
  718. The number of inversions is the number of pairs of elements $xy$ such
  719. that $x>y$ and $x$ precedes $y$ from left to right, counting
  720. multiplicity.  For example, 2010 has four inversions, corresponding to
  721. $xyin{20,21,20,10}$. It is not difficult to verify that the number
  722. of inversions of a permutation is the distance in the graph from that
  723. permutation to the lexicographically first permutation.
  724. Parameters |n0| through |n4| specify the composition of the multiset,
  725. just as in the |subsets| routine.
  726. Roughly speaking, there are |n0| elements equal to~0, |n1| elements
  727. equal to~1, and so on. The multiset ${0,0,1,2,3,3}$, for example, would
  728. be represented by |(n0,n1,n2,n3,n4)=(2,1,1,2,0)|.
  729. Of course, we sometimes want to have multisets with more than five distinct
  730. elements; when there are $d+1$ distinct elements, the multiset should have
  731. $n_k$ elements equal to~$k$ and $n=n_0+n_1+cdots+n_d$ elements in all.
  732. Larger values of $d$ can be specified by using |-d| as a parameter:
  733. If |n0=-d|, each multiplicity $n_k$ is taken to be~1; if |n0>0| and |n1=-d|,
  734. each multiplicity $n_k$ is taken to be equal to~|n0|;
  735. if |n0>0|, |n1>0|, and |n2=-d|, the multiplicities are alternately
  736. $(|n0|,|n1|,|n0|,|n1|,|n0|,ldots,)$; if  |n0>0|, |n1>0|, |n2>0|, and
  737. |n3=-d|, the multiplicities are the first~|d+1| elements of the
  738. periodic sequence $(|n0|,|n1|,|n2|,|n0|,|n1|,ldots,)$; and if all
  739. but |n4| are positive, while |n4=-d|, the multiplicities again
  740. are periodic.
  741. An example like |(n0,n1,n2,n3,n4)=(1,2,3,4,-8)| is about as tricky
  742. as you can get. It specifies the multiset ${0,1,1,2,2,2,3,3,3,3,4,5,5,
  743. 6,6,6,7,7,7,7,8}$.
  744. If any of the multiplicity parameters is negative or zero, the
  745. remaining multiplicities are ignored. For example, if |n2<=0|, the
  746. subroutine does not look at |n3| or~|n4|.
  747. You probably don't want to try |perms(n0,0,0,0,0,max_inv,directed)|
  748. when |n0>0|, because a multiset with |n0| identical elements has only
  749. one permutation.
  750. The special case when you want all $n!$ permutations of an $n$-element set
  751. can be obtained by calling |all_perms(n,directed)|.
  752. @(gb_basic.h@>=
  753. #define all_perms(n,directed) @[perms((long)(1-(n)),0L,0L,0L,0L,0L,
  754.    (long)(directed))@]
  755. @ If |max_inv=0|, all permutations will be considered, regardless of
  756. the number of inversions. In that case the total number of vertices in
  757. the graph will be the multinomial coefficient $${nchoose
  758. n_0,n_1,ldots,n_d},,qquad n=n_0+n_1+cdots+n_d.$$ The maximum
  759. number of inversions in general is the number of inversions of the
  760. lexicographically last permutation, namely ${nchoose2}-{n_0choose2}-
  761. {n_1choose2}-cdots-{n_dchoose2}=sum_{0le j<kle d}n_jn_k$.
  762. vskip1pt
  763. Notice that in the case $d=1$, we essentially obtain all combinations of
  764. |n0+n1| elements taken |n1| at a time. The positions of the 1's correspond
  765. to the elements of a subset or sample.
  766. If |directed| is nonzero, the graph will contain only directed arcs
  767. from permutations to neighboring permutations that have exactly one more
  768. inversion. In this case the graph corresponds to a partial ordering that is a
  769. lattice with interesting properties; see the article by Bennett and Birkhoff
  770. @^Bennett, Mary Katherine@>
  771. @^Birkhoff, Garrett@>
  772. in {sl Algebra Universalis/} (1994), to appear.
  773. @ The program for |perms| is very similar in structure to the program
  774. for |simplex| already considered.
  775. @<Basic subroutines@>=
  776. Graph *perms(n0,n1,n2,n3,n4,max_inv,directed)
  777.   long n0,n1,n2,n3,n4; /* composition of the multiset */
  778.   unsigned long max_inv; /* maximum number of inversions */
  779.   long directed; /* should the graph be directed? */
  780. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  781.   register long n; /* total number of elements in multiset */
  782.   @<Normalize the permutation parameters@>;
  783.   @<Create a graph with one vertex for each permutation@>;
  784.   @<Name the permutations and create the arcs or edges@>;
  785.   if (gb_trouble_code) {
  786.     gb_recycle(new_graph);
  787.     panic(alloc_fault); /* shucks, we ran out of memory somewhere back there */
  788.   }
  789.   return new_graph;
  790. }
  791. @ @<Normalize the permutation parameters@>=
  792. if (n0==0) {@+n0=1;@+n1=0;@+} /* convert the empty set into ${0}$ */
  793. else if (n0<0) {@+n1=n0;@+n0=1;@+}
  794. n=BUF_SIZE; /* this allows us to borrow code from |simplex|, already written */
  795. @<Normalize the simplex parameters@>;
  796. @<Determine |n| and the maximum possible number of inversions@>;
  797. @ Here we want to set |max_inv| to the maximum possible number of
  798. inversions, if the given value of |max_inv| is zero or
  799. if it exceeds that maximum number.
  800. @<Determine |n| and the maximum possible number of inversions@>=
  801. {@+register long ss; /* max inversions known to be possible */
  802.   for (k=0,s=ss=0;k<=d;ss+=s*nn[k],s+=nn[k],k++)
  803.     if (nn[k]>=BUF_SIZE) panic(bad_specs);
  804.       /* too many elements in the multiset */
  805.   if (s>=BUF_SIZE) panic(bad_specs+1); /* too many elements in the multiset */
  806.   n=s;
  807.   if (max_inv==0 || max_inv>ss) max_inv=ss;  
  808. }
  809. @ To determine the number of vertices, we sum the first |max_inv+1|
  810. coefficients of a power series in which the coefficient of~$z^j$
  811. is the number of permutations having $j$ inversions. It is known
  812. [{sl Sorting and Searching}, exercise 5.1.2--16] that this power series
  813. is the ``$z$-multinomial coefficient''
  814. $${nchoose n_0,ldots,n_d}_{!z}={n!_zover n_0!_zldots n_d!_z},,
  815. qquadhbox{where}qquad m!_z=prod_{k=1}^m{1-z^kover 1-z},.$$
  816. @<Create a graph with one vertex for each permutation@>=
  817. {@+long nverts; /* the number of vertices */
  818.   register long *coef=gb_typed_alloc(max_inv+1,long,working_storage);
  819.   if (gb_trouble_code) panic(no_room+1); /* can't allocate |coef| array */
  820.   coef[0]=1;
  821.   for (j=1,s=nn[0];j<=d;s+=nn[j],j++)
  822.     @<Multiply the power series coefficients by
  823.        $prod_{1le kle n_j}(1-z^{s+k})/(1-z^k)$@>;
  824.   for (k=1,nverts=1;k<=max_inv;k++) {
  825.     nverts+=coef[k];
  826.     if (nverts>1000000000) panic(very_bad_specs); /* way too big */
  827.   }
  828.   gb_free(working_storage); /* recycle the |coef| array */
  829.   new_graph=gb_new_graph(nverts);
  830.   if (new_graph==NULL)
  831.     panic(no_room); /* out of memory before we're even started */
  832.   sprintf(new_graph->id,"perms(%ld,%ld,%ld,%ld,%ld,%lu,%d)",
  833.     n0,n1,n2,n3,n4,max_inv,directed?1:0);
  834.   strcpy(new_graph->util_types,"VVZZZZZZZZZZZZ"); /* hash table will be used */
  835. }
  836. @ After multiplication by $(1-z^{k+s})/(1-z^k)$, the coefficients of the
  837. power series will be nonnegative, because they are the coefficients of
  838. a $z$-multinomial coefficient.
  839. @<Multiply the power series coefficients by
  840.        $prod_{1le kle n_j}(1-z^{s+k})/(1-z^k)$@>=
  841. for (k=1;k<=nn[j];k++) {@+register long ii;
  842.   for (i=max_inv,ii=i-k-s;ii>=0;ii--,i--) coef[i]-=coef[ii];
  843.   for (i=k,ii=0;i<=max_inv;i++,ii++) {
  844.     coef[i]+=coef[ii];
  845.     if (coef[i]>1000000000) panic(very_bad_specs+1); /* way too big */
  846.   }
  847. }
  848. @ As we generate the permutations, we maintain a table $(y_1,ldots,y_n)$,
  849. where $y_k$ is the number of
  850. inversions whose first element is the $k$th element of the multiset.
  851. For example, if the multiset is ${0,0,1,2}$ and the current permutation is
  852. $(2,0,1,0)$, the inversion table is $(y_1,y_2,y_3,y_4)=(0,0,1,3)$. Clearly
  853. $0le y_k<k$, and $y_kle y_{k-1}$ when the $k$th element of the multiset
  854. is the same as the $(k-1)$st element. These conditions are necessary
  855. and sufficient to define a valid inversion table. We will generate
  856. permutations in lexicographic order of their inversion tables.
  857. For convenience, we set up another array~|z|, which holds the
  858. initial inversion-free permutation.
  859. @<Name the permutations and create the arcs or edges@>=
  860. {@+register long *xtab,*ytab,*ztab; /* permutations and their inversions */
  861.   long m=0; /* current number of inversions */
  862.   @<Initialize |xtab|, |ytab|, and |ztab|@>;
  863.   v=new_graph->vertices;
  864.   while (1) {
  865.     @<Assign a symbolic name for $(x_1,ldots,x_n)$ to vertex~|v|@>;
  866.     @<Create arcs or edges from previous permutations to~|v|@>;
  867.     v++;
  868.     @<Advance to the next perm; |goto last| if there are no more solutions@>;
  869.   }
  870.   last:@+if (v!=new_graph->vertices+new_graph->n)
  871.     panic(impossible); /* can't happen */
  872.   gb_free(working_storage);
  873. }
  874. @ @<Initialize |xtab|, |ytab|, and |ztab|@>=
  875. xtab=gb_typed_alloc(3*n+3,long,working_storage);
  876. if (gb_trouble_code) { /* can't allocate |xtab| */
  877.  gb_recycle(new_graph);@+panic(no_room+2);@+}
  878. ytab=xtab+(n+1);
  879. ztab=ytab+(n+1);
  880. for (j=0,k=1,s=nn[0];;k++) {
  881.   xtab[k]=ztab[k]=j; /* |ytab[k]=0| */
  882.   if (k==s) {
  883.     if (++j>d) break;
  884.     else s+=nn[j];
  885.   }
  886. }
  887. @ Here is the heart of the permutation logic. We find the largest~$k$
  888. such that $y_k$ can legitimately be increased by~1. When we encounter
  889. a~$k$ for which $y_k$ cannot be increased, we set $y_k=0$ and adjust
  890. the $x$'s accordingly. If no $y_k$ can be increased, we are done.
  891. @<Advance to the next perm...@>=
  892. for (k=n;k;k--) {
  893.   if (m<max_inv && ytab[k]<k-1)
  894.     if (ytab[k]<ytab[k-1] || ztab[k]>ztab[k-1]) goto move;
  895.   if (ytab[k]) {
  896.     for (j=k-ytab[k];j<k;j++) xtab[j]=xtab[j+1];
  897.     m-=ytab[k];
  898.     ytab[k]=0;
  899.     xtab[k]=ztab[k];
  900.   }
  901. }
  902. goto last;
  903. move: j=k-ytab[k]; /* the current location of the $k$th element, $z_k$ */
  904. xtab[j]=xtab[j-1];@+xtab[j-1]=ztab[k];
  905. ytab[k]++;@+m++;
  906. @ A permutation is encoded as a sequence of nonblank characters,
  907. using an abbreviated copy of the |imap| code from {sc GB_,IO} and omitting
  908. the characters that need to be quoted within strings. If the
  909. number of distinct elements in the multiset is at most~62, only digits
  910. and letters will appear in the vertex name.
  911. @<Private variables@>=
  912. static char *short_imap="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
  913. abcdefghijklmnopqrstuvwxyz_^~&@@,;.:?!%#$+-*/|<=>()[]{}`'";
  914. @ @<Assign a symbolic name for $(x_1,ldots,x_n)...@>=
  915. {@+register char *p; register long *q;
  916.   for (p=&buffer[n-1],q=&xtab[n];q>xtab;p--,q--) *p=short_imap[*q];
  917.   v->name=gb_save_string(buffer);
  918.   hash_in(v); /* enter |v->name| into the hash table
  919.                   (via utility fields |u,v|) */
  920. }
  921. @ Since we are generating the vertices in lexicographic order of their
  922. inversions, it is easy to identify all adjacent vertices that
  923. precede the current setting of $(x_1,ldots,x_n)$. We locate them
  924. via their symbolic names.
  925. @<Create arcs or edges from previous permutations to~|v|@>=
  926. for (j=1;j<n;j++)
  927.   if (xtab[j]>xtab[j+1]) {@+register Vertex *u;
  928.                          /* previous vertex adjacent to |v| */
  929.     buffer[j-1]=short_imap[xtab[j+1]];@+buffer[j]=short_imap[xtab[j]];
  930.     u=hash_out(buffer);
  931.     if (u==NULL) panic(impossible+2); /* can't happen */
  932.     if (directed) gb_new_arc(u,v,1L);
  933.     else gb_new_edge(u,v,1L);
  934.     buffer[j-1]=short_imap[xtab[j]];@+buffer[j]=short_imap[xtab[j+1]];
  935.   }
  936. @* Partition graphs. The subroutine call
  937. |parts(n,max_parts,max_size,directed)|
  938. creates a graph whose vertices represent the different ways to partition
  939. the integer~|n| into at most |max_parts| parts, where each part is at most
  940. |max_size|. Two partitions are adjacent in the graph if
  941. one can be obtained from the other by combining two parts.
  942. Each arc has length~1.
  943. For example, the partitions of~5 are
  944. $$5,quad 4+1,quad 3+2,quad 3+1+1,quad 2+2+1,
  945.        quad 2+1+1+1,quad 1+1+1+1+1.$$
  946. Here 5 is adjacent to $4+1$ and to $3+2$; $4+1$ is adjacent also to
  947. $3+1+1$ and to $2+2+1$; $3+2$ is adjacent also to $3+1+1$ and to $2+2+1$; etc.
  948. If |max_size| is 3, the partitions 5 and $4+1$ would not be included in
  949. the graph. If |max_parts| is 3, the partitions $2+1+1+1$ and $1+1+1+1+1$
  950. would not be included.
  951. If |max_parts| or |max_size| are zero, they are reset to be equal to~|n|
  952. so that they make no restriction on the partitions.
  953. If |directed| is nonzero, the graph will contain only directed arcs from
  954. partitions to their neighbors that have exactly one more part.
  955. The special case when we want to generate all $p(n)$ partitions of the
  956. integer~$n$ can be obtained by calling |all_parts(n,directed)|.
  957. @(gb_basic.h@>=
  958. #define all_parts(n,directed) @[parts((long)(n),0L,0L,(long)(directed))@]
  959. @ The program for |parts| is very similar in structure to the program
  960. for |perms| already considered.
  961. @<Basic subroutines@>=
  962. Graph *parts(n,max_parts,max_size,directed)
  963.   unsigned long n; /* the number being partitioned */
  964.   unsigned long max_parts; /* maximum number of parts */
  965.   unsigned long max_size; /* maximum size of each part */ 
  966.   long directed; /* should the graph be directed? */
  967. {@+@<Vanilla local variables@>@;@#
  968.   if (max_parts==0 || max_parts>n) max_parts=n;
  969.   if (max_size==0 || max_size>n) max_size=n;
  970.   if (max_parts>MAX_D) panic(bad_specs); /* too many parts allowed */
  971.   @<Create a graph with one vertex for each partition@>;
  972.   @<Name the partitions and create the arcs or edges@>;
  973.   if (gb_trouble_code) {
  974.     gb_recycle(new_graph);
  975.     panic(alloc_fault);
  976.      /* doggone it, we ran out of memory somewhere back there */
  977.   }
  978.   return new_graph;
  979. }
  980. @ The number of vertices is the coefficient of $z^n$
  981. in the $z$-binomial coefficient ${m+pchoose m}_z$, where $m=|max_parts|$
  982. and $p=|max_size|$. This coefficient is calculated as in the |perms| routine.
  983. @<Create a graph with one vertex for each partition@>=
  984. {@+long nverts; /* the number of vertices */
  985.   register long *coef=gb_typed_alloc(n+1,long,working_storage);
  986.   if (gb_trouble_code) panic(no_room+1); /* can't allocate |coef| array */
  987.   coef[0]=1;
  988.   for (k=1;k<=max_parts;k++) {
  989.     for (j=n,i=n-k-max_size;i>=0;i--,j--) coef[j]-=coef[i];
  990.     for (j=k,i=0;j<=n;i++,j++) {
  991.       coef[j]+=coef[i];
  992.       if (coef[j]>1000000000) panic(very_bad_specs); /* way too big */
  993.     }
  994.   }
  995.   nverts=coef[n];
  996.   gb_free(working_storage); /* recycle the |coef| array */
  997.   new_graph=gb_new_graph(nverts);
  998.   if (new_graph==NULL)
  999.     panic(no_room); /* out of memory before we're even started */
  1000.   sprintf(new_graph->id,"parts(%lu,%lu,%lu,%d)",
  1001.     n,max_parts,max_size,directed?1:0);
  1002.   strcpy(new_graph->util_types,"VVZZZZZZZZZZZZ"); /* hash table will be used */
  1003. }
  1004. @ As we generate the partitions, we maintain
  1005. the numbers $sigma_j=n-(x_1+cdots+x_{j-1})=x_j+x_{j+1}+cdots,$,
  1006. somewhat as we did in the |simplex| routine. We set $x_0=|max_size|$
  1007. and $y_j=|max_parts|+1-j$; then when values $(x_1,ldots,x_{j-1})$ are
  1008. given, the conditions
  1009. $$sigma_j/y_jle x_jle sigma_j,qquad x_jle x_{j-1}$$
  1010. characterize the legal values of~$x_j$.
  1011. @<Name the partitions and create the arcs or edges@>=
  1012. v=new_graph->vertices;
  1013. xx[0]=max_size;@+sig[1]=n;
  1014. for (k=max_parts,s=1;k>0;k--,s++) yy[k]=s;
  1015. if (max_size*max_parts>=n) {
  1016.   k=1;@+xx[1]=(n-1)/max_parts+1; /* $lceil n/|max_parts|rceil$ */
  1017.   while (1) {
  1018.     @<Complete the partial solution $(x_1,ldots,x_k)$@>;
  1019.     @<Assign the name $x_1+cdots+x_d$ to vertex~|v|@>;
  1020.     @<Create arcs or edges from |v| to previous partitions@>;
  1021.     v++;
  1022.     @<Advance to the next partial solution $(x_1,ldots,x_k)$, where |k| is
  1023.        as large as possible; |goto last| if there are no more solutions@>;
  1024.   }
  1025. }
  1026. last:@+if (v!=new_graph->vertices+new_graph->n)
  1027.   panic(impossible); /* can't happen */
  1028. @ @<Complete the partial solution $(x_1,ldots,x_k)$@>=
  1029. for (s=sig[k]-xx[k],k++;s;k++) {
  1030.   sig[k]=s;
  1031.   xx[k]=(s-1)/yy[k]+1;
  1032.   s-=xx[k];
  1033. }
  1034. d=k-1; /* the smallest part is $x_d$ */
  1035. @ Here we seek the largest $k$ such that $x_k$ can be increased without
  1036. violating the necessary and sufficient conditions stated earlier.
  1037. @<Advance to the next partial solution $(x_1,ldots,x_k)$...@>=
  1038. if (d==1) goto last;
  1039. for (k=d-1;;k--) {
  1040.   if (xx[k]<sig[k] && xx[k]<xx[k-1]) break;
  1041.   if (k==1) goto last;
  1042. }
  1043. xx[k]++;
  1044. @ @<Assign the name $x_1+...@>=
  1045. {@+register char *p=buffer; /* string pointer */
  1046.   for (k=1;k<=d;k++) {
  1047.     sprintf(p,"+%ld",xx[k]);
  1048.     while (*p) p++;
  1049.   }
  1050.   v->name=gb_save_string(&buffer[1]); /* omit |buffer[0]|, which is |'+'| */
  1051.   hash_in(v); /* enter |v->name| into the hash table
  1052.                   (via utility fields |u,v|) */
  1053. }
  1054. @ Since we are generating the partitions in lexicographic order of their
  1055. parts, it is reasonably easy to identify all adjacent vertices that
  1056. precede the current setting of $(x_1,ldots,x_d)$, by splitting
  1057. $x_j$ into two parts when $x_jne x_{j+1}$. We locate previous partitions
  1058. via their symbolic names.
  1059. @<Create arcs or edges from |v| to previous partitions@>=
  1060. if (d<max_parts) {
  1061.   xx[d+1]=0;
  1062.   for (j=1;j<=d;j++) {
  1063.     if (xx[j]!=xx[j+1]) {@+long a,b;
  1064.       for (b=xx[j]/2,a=xx[j]-b;b;a++,b--)
  1065.         @<Generate a subpartition $(n_1,ldots,n_{d+1})$ by
  1066.               splitting $x_j$ into $a+b$, and make that subpartition
  1067.               adjacent to~|v|@>;
  1068.     }
  1069.     nn[j]=xx[j];
  1070.   }
  1071. }
  1072. @ The values of $(x_1,ldots,x_{j-1})$ have already been copied into
  1073. $(n_1,ldots,n_{j-1})$. Our job is to copy the smaller parts
  1074. $(x_{j+1},ldots,x_d)$ while
  1075. inserting $a$ and $b$ in their proper places, knowing that $age b$.
  1076. @<Generate a subpartition $(n_1,ldots,n_{d+1})$...@>=
  1077. {@+register Vertex *u; /* previous vertex adjacent to |v| */
  1078.   register char *p=buffer;
  1079.   for (k=j+1;xx[k]>a;k++) nn[k-1]=xx[k];
  1080.   nn[k-1]=a;
  1081.   for (;xx[k]>b;k++) nn[k]=xx[k];
  1082.   nn[k]=b;
  1083.   for (;k<=d;k++) nn[k+1]=xx[k];
  1084.   for (k=1;k<=d+1;k++) {
  1085.     sprintf(p,"+%ld",nn[k]);
  1086.     while (*p) p++;
  1087.   }
  1088.   u=hash_out(&buffer[1]);
  1089.   if (u==NULL) panic(impossible+2); /* can't happen */
  1090.   if (directed) gb_new_arc(v,u,1L);
  1091.   else gb_new_edge(v,u,1L);
  1092. }
  1093. @* Binary tree graphs. The subroutine call
  1094. |binary(n,max_height,directed)|
  1095. creates a graph whose vertices represent the binary trees with $n$ internal
  1096. nodes and with all leaves at a distance that is at most |max_height|
  1097. from the root. Two binary trees are adjacent in the graph if
  1098. one can be obtained from the other by a single application of the
  1099. associative law for binary operations, i.e., by replacing some subtree
  1100. of the form $(alphacdotbeta)cdotgamma$ by the subtree $alphacdot
  1101. (betacdotgamma)$. (This transformation on binary trees is often
  1102. called a ``rotation.'') If the |directed| parameter is nonzero, the
  1103. directed arcs go from a tree containing $(alphacdotbeta)cdotgamma$
  1104. to a tree containing $alphacdot(betacdotgamma)$ in its place; otherwise
  1105. the graph is undirected. Each arc has length~1.
  1106. For example, the binary trees with three internal nodes form a circuit of
  1107. length~5. They are
  1108. $$mathcode`.="2201 % cdot
  1109. (a.b).(c.d),quad a.(b.(c.d)),quad a.((b.c).d),quad (a.(b.c)).d,quad
  1110. ((a.b).c).d,$$
  1111. if we use infix notation and name the leaves $(a,b,c,d)$ from left to right.
  1112. Here each tree is related to its two neighbors by associativity. The
  1113. first and last trees are also related in the same way.
  1114. If |max_height=0|, it is changed to |n|, which means there is no
  1115. restriction on the height of a leaf. In this case the graph will have
  1116. exactly ${2n+1choose n}/ (2n+1)$ vertices; furthermore, each vertex
  1117. will have exactly $n-1$ neighbors, because a rotation will be possible
  1118. just above every internal node except the root.  The graph in this
  1119. case can also be interpreted geometrically: The vertices are in
  1120. one-to-one correspondence with the triangulations of a regular
  1121. $(n+2)$-gon; two triangulations are adjacent if and only if one is obtained
  1122. from the other by replacing the pair of adjacent triangles $ABC,DCB$
  1123. by the pair $ADC,BDA$.
  1124. The partial ordering corresponding to the directed graph on
  1125. ${2n+1choose n}/(2n+1)$ vertices created by |all_trees(n,1)|
  1126. is a lattice with interesting properties. See Huang and Tamari,
  1127. @^Huang, Samuel Shung@>
  1128. @^Tamari, Dov@>
  1129. {sl Journal of Combinatorial Theory/ bf A13} (1972), 7--13.
  1130. @(gb_basic.h@>=
  1131. #define all_trees(n,directed) @[binary((long)(n),0L,(long)(directed))@]
  1132. @ The program for |binary| is very similar in structure to the program
  1133. for |parts| already considered. But the details are more exciting.
  1134. @<Basic subroutines@>=
  1135. Graph *binary(n,max_height,directed)
  1136.   unsigned long n; /* the number of internal nodes */
  1137.   unsigned long max_height; /* maximum height of a leaf */
  1138.   long directed; /* should the graph be directed? */
  1139. {@+@<Vanilla local variables@>@;@#
  1140.   if (2*n+2>BUF_SIZE) panic(bad_specs); /* |n| is too huge for us */
  1141.   if (max_height==0 || max_height>n) max_height=n;
  1142.   if (max_height>30) panic(very_bad_specs); /* more than a billion vertices */
  1143.   @<Create a graph with one vertex for each binary tree@>;
  1144.   @<Name the trees and create the arcs or edges@>;
  1145.   if (gb_trouble_code) {
  1146.     gb_recycle(new_graph);
  1147.     panic(alloc_fault); /* uff da, we ran out of memory somewhere back there */
  1148.   }
  1149.   return new_graph;
  1150. }
  1151. @ The number of vertices is the coefficient of $z^n$
  1152. in the power series $G_h$, where $h=|max_height|$ and $G_h$ satisfies
  1153. the recurrence
  1154. $$G_0=1,qquad G_{h+1}=1+z G_h^2.$$
  1155. The coefficients of $G_5$ are $le55308$, but the
  1156. coefficients of $G_6$ are much larger; they exceed one billion when
  1157. $28le nle49$, and they exceed one million when $17le nle 56$.
  1158. In order to avoid overflow during this calculation, we use a
  1159. special method when $hge6$ and $nge20$: In such cases, graphs
  1160. of reasonable size arise only if $nge 2^h-7$, and we look at the
  1161. coefficient of $z^{-(2^h-1-n)}$ in $R_h=G_h/z^{2^h-1}$, which is a
  1162. power series in $z^{-1}$ defined by the recurrence
  1163. $$R_0=1,qquad R_{h+1}=R_h^2+z^{1-2^{h+1}}.$$
  1164. @<Create a graph with one vertex for each binary tree@>=
  1165. {@+long nverts; /* the number of vertices */
  1166.   if (n>=20 && max_height>=6) @<Compute |nverts| using the $R$ series@>@;
  1167.   else {
  1168.     nn[0]=nn[1]=1;
  1169.     for (k=2;k<=n;k++) nn[k]=0;
  1170.     for (j=2;j<=max_height;j++)
  1171.       for (k=n-1;k;k--) {
  1172.         for (s=0,i=k;i>=0;i--) s+=nn[i]*nn[k-i]; /* overflow impossible */
  1173.         nn[k+1]=s;
  1174.       }
  1175.     nverts=nn[n];
  1176.   }
  1177.   new_graph=gb_new_graph(nverts);
  1178.   if (new_graph==NULL)
  1179.     panic(no_room); /* out of memory before we're even started */
  1180.   sprintf(new_graph->id,"binary(%lu,%lu,%d)",
  1181.     n,max_height,directed?1:0);
  1182.   strcpy(new_graph->util_types,"VVZZZZZZZZZZZZ"); /* hash table will be used */
  1183. }
  1184. @ The smallest nontrivial graph that is unilaterally disallowed by
  1185. this procedure on the grounds of size limitations occurs when |max_height=6|
  1186. and |n=20|; it has 14,162,220 vertices.
  1187. @<Compute |nverts| using the $R$ series@>=
  1188. {@+register float ss;
  1189.   d=(1L<<max_height)-1-n;
  1190.   if (d>8) panic(bad_specs+1); /* too many vertices */
  1191.   if (d<0) nverts=0;
  1192.   else {
  1193.     nn[0]=nn[1]=1;
  1194.     for (k=2;k<=d;k++) nn[k]=0;
  1195.     for (j=2;j<=max_height;j++) {
  1196.       for (k=d;k;k--) {
  1197.         for (ss=0.0,i=k;i>=0;i--) ss+=((float)nn[i])*((float)nn[k-i]);
  1198.         if (ss>MAX_NNN) panic(very_bad_specs+1); /* way too big */
  1199.         for (s=0,i=k;i>=0;i--) s+=nn[i]*nn[k-i]; /* overflow impossible */
  1200.         nn[k]=s;
  1201.       }
  1202.       i=(1L<<j)-1;
  1203.       if (i<=d) nn[i]++; /* add $z^{1-2^j}$ */
  1204.     }
  1205.     nverts=nn[d];
  1206.   }
  1207. }
  1208. @ We generate the trees in lexicographic order of their Polish prefix
  1209. notation, encoded in binary notation as $x_0x_1ldots x_{2n}$, using `1'
  1210. for an internal node and `0' for a leaf. For example, the five
  1211. trees when $n=3$ are
  1212. $$1010100,quad 1011000,quad 1100100,quad 1101000,quad 1110000,$$
  1213. in lexicographic order. The algorithm for lexicographic generation maintains
  1214. three auxiliary arrays $l_j$, $y_j$, and $sigma_j$, where
  1215. $$sigma_j;=;n-j+sum_{i=0}^{j-1}x_i;=;-1+sum_{i=j}^{2n}(1-x_i)$$
  1216. is one less than the number of 0's (leaves) in $(x_j,ldots,x_{2n})$.
  1217. The values of $l_j$ and $y_j$ are harder
  1218. to describe formally; $l_j$ is $2^{h-l}$ when $h=|max_height|$ and when
  1219. $x_j$ represents a node at level~$l$ of the tree, based on the values
  1220. of $(x_0,ldots,x_{j-1})$. The value of $y_j$ is a binary encoding of
  1221. tree levels in which an internal node has not yet received a right child;
  1222. $y_j$ is also the maximum number of future leaves that can be produced by
  1223. previously specified internal nodes without exceeding the maximum height.
  1224. The number of 1-bits in $y_j$ is the minimum number of future leaves,
  1225. based on previous specifications.
  1226. Therefore if $sigma_j>y_j$, $x_j$ is forced to be~1. If $l_j=1$,
  1227. $x_j$ is forced to be~0. If the number of 1-bits of $y_j$ is equal
  1228. to $sigma_j$, $x_j$ is forced to be~0. Otherwise $x_j$ can be
  1229. either 0 or~1, and it will be possible to complete the partial
  1230. solution $x_0ldots x_j$ to a full Polish prefix code $x_0ldots x_{2n}$.
  1231. For example, here are the arrays for one of the binary trees
  1232. that is generated when $n=h=3$:
  1233. $$vcenter{halign{$hfil#$quad=&&quad#cr
  1234. j       &0&1&2&3&4&5&6cr
  1235. l_j     &8&4&2&2&1&1&4cr
  1236. y_j     &0&4&6&4&5&4&0cr
  1237. sigma_j&3&3&3&2&2&1&0cr
  1238. x_j     &1&1&0&1&0&0&0cr}}$$
  1239. If $x_j=1$ and $j<2n$, we have $l_{j+1}=l_j/2$, $y_{j+1}=y_j+l_{j+1}$,
  1240. and $sigma_{j+1}=sigma_j$. If $x_j=0$ and $j<2n$, we have $l_{j+1}=
  1241. 2^t$, $y_{j+1}=y_j-2^t$, and $sigma_{j+1}=sigma_j-1$, where $2^t$ is the
  1242. least power of~2 in the binary representation of~$y_j$. It is not difficult to
  1243. prove by induction that $sigma_j<y_j+l_j$, assuming that $n<2^h$.
  1244. @<Name the trees and create the arcs or edges@>=
  1245. {@+register long *xtab,*ytab,*ltab,*stab;
  1246.   @<Initialize |xtab|, |ytab|, |ltab|, and |stab|; also set |d=2n|@>;
  1247.   v=new_graph->vertices;
  1248.   if (ltab[0]>n) {
  1249.     k=0;@+xtab[0]=n?1:0;
  1250.     while (1) {
  1251.       @<Complete the partial tree $x_0ldots x_k$@>;
  1252.       @<Assign a Polish prefix code name to vertex~|v|@>;
  1253.       @<Create arcs or edges from |v| to previous trees@>;
  1254.       v++;
  1255.       @<Advance to the next partial tree $x_0ldots x_k$, where |k| is
  1256.        as large as possible; |goto last| if there are no more solutions@>;
  1257.     }
  1258.   }
  1259. }
  1260. last:@+if (v!=new_graph->vertices+new_graph->n)
  1261.   panic(impossible); /* can't happen */
  1262. gb_free(working_storage);
  1263. @ @<Initialize |xtab|, |ytab|, |ltab|, and |stab|...@>=
  1264. xtab=gb_typed_alloc(8*n+4,long,working_storage);
  1265. if (gb_trouble_code) { /* no room for |xtab| */
  1266.   gb_recycle(new_graph);@+panic(no_room+2);@+}
  1267. d=n+n;
  1268. ytab=xtab+(d+1);
  1269. ltab=ytab+(d+1);
  1270. stab=ltab+(d+1);
  1271. ltab[0]=1L<<max_height;
  1272. stab[0]=n; /* |ytab[0]=0| */
  1273. @ @<Complete the partial tree...@>=
  1274. for (j=k+1;j<=d;j++) {
  1275.   if (xtab[j-1]) {
  1276.     ltab[j]=ltab[j-1]>>1;
  1277.     ytab[j]=ytab[j-1]+ltab[j];
  1278.     stab[j]=stab[j-1];
  1279.   }@+else {
  1280.     ytab[j]=ytab[j-1]&(ytab[j-1]-1); /* remove least significant 1-bit */
  1281.     ltab[j]=ytab[j-1]-ytab[j];
  1282.     stab[j]=stab[j-1]-1;
  1283.   }
  1284.   if (stab[j]<=ytab[j]) xtab[j]=0;
  1285.   else xtab[j]=1;  /* this is the lexicographically smallest completion */
  1286. }
  1287. @ As in previous routines, we seek the largest $k$ such that $x_k$ can
  1288. be increased without violating the necessary and sufficient conditions
  1289. stated earlier.
  1290. @<Advance to the next partial tree...@>=
  1291. for (k=d-1;;k--) {
  1292.   if (k<=0) goto last; /* this happens only when |n<=1| */
  1293.   if (xtab[k]) break; /* find rightmost 1 */
  1294. }
  1295. for (k--;;k--) {
  1296.   if (xtab[k]==0 && ltab[k]>1) break;
  1297.   if (k==0) goto last;
  1298. }
  1299. xtab[k]++;
  1300. @ In the |name| field, we encode internal nodes of the binary tree by
  1301. `..' and leaves by `.x'. Thus the five trees shown above in binary
  1302. code will be named
  1303. $$.{.x.x.xx},quad .{.x..xxx},quad .{..xx.xx},quad .{..x.xxx},quad
  1304. .{...xxxx},$$
  1305. respectively.
  1306. @<Assign a Polish prefix...@>=
  1307. {@+register char *p=buffer; /* string pointer */
  1308.   for (k=0;k<=d;k++,p++) *p=(xtab[k]? '.': 'x');
  1309.   v->name=gb_save_string(buffer);
  1310.   hash_in(v); /* enter |v->name| into the hash table
  1311.                   (via utility fields |u,v|) */
  1312. }
  1313. @ Since we are generating the trees in lexicographic order of their
  1314. Polish prefix notation, it is relatively easy to find all pairs of trees that
  1315. are adjacent via one application of the associative law: We simply
  1316. replace a substring of the form $....alphabeta$ by
  1317. $..alpha..beta$, when $alpha$ and $beta$ are Polish prefix
  1318. strings. The result comes earlier in lexicographic order, so it will
  1319. be an existing vertex unless it violates the |max_height| restriction.
  1320. @<Create arcs or edges from |v| to previous trees@>=
  1321. for (j=0;j<d;j++)
  1322.   if (xtab[j]==1 && xtab[j+1]==1) {
  1323.     for (i=j+1,s=0;s>=0;s+=(xtab[i+1]<<1)-1,i++) xtab[i]=xtab[i+1];
  1324.     xtab[i]=1;
  1325.     {@+register char *p=buffer; /* string pointer */
  1326.       register Vertex *u;
  1327.       for (k=0;k<=d;k++,p++) *p=(xtab[k]? '.': 'x');
  1328.       u=hash_out(buffer);
  1329.       if (u) {
  1330.         if (directed) gb_new_arc(v,u,1L);
  1331.         else gb_new_edge(v,u,1L);
  1332.       }
  1333.     }
  1334.     for (i--;i>j;i--) xtab[i+1]=xtab[i]; /* restore |xtab| */
  1335.     xtab[i+1]=1;
  1336.   }
  1337. @* Complementing and copying. We have seen how to create a wide
  1338. variety of basic graphs with the |board|, |simplex|, |subsets|,
  1339. |perms|, |parts|, and |binary| procedures. The remaining routines
  1340. of {sc GB_,BASIC} are somewhat different. They transform existing
  1341. graphs into new ones, thereby presenting us with an almost
  1342. mind-boggling array of further possibilities.
  1343. The first of these transformations is perhaps the simplest. It
  1344. complements a given graph, making vertices adjacent if and only if
  1345. they were previously nonadjacent. More precisely, the subroutine call
  1346. |complement(g,copy,self,directed)| returns a graph with the
  1347. same vertices as |g|, but with complemented arcs.
  1348. If |self!=0|, the new graph will have a self-loop from a vertex |v| to itself
  1349. when the original graph did not; if |self=0|, the new graph will
  1350. have no self-loops. If |directed!=0|, the new graph will have
  1351. an arc from |u| to |v| when the original graph did not; if |directed=0|,
  1352. the new graph will be undirected, and it will have an edge between |u|
  1353. and~|v| when the original graph did not. In the latter case, the original
  1354. graph should also be undirected (that is, its arcs should come in pairs,
  1355. as described in the |gb_new_edge| routine of {sc GB_,GRAPH}).
  1356. If |copy!=0|, a double complement will actually be done. This means that
  1357. the new graph will essentially be a copy of the old, except that
  1358. duplicate arcs (and possibly self-loops) will be removed. Regardless of
  1359. the value of |copy|, information that might have been present in the utility
  1360. fields will not be copied, and arc lengths will all be set to~1.
  1361. One possibly useful feature of the graphs returned by |complement| is
  1362. worth noting. The vertices adjacent to~|v|, namely the list
  1363. $$hbox{|v->arcs->tip|,quad |v->arcs->next->tip|,quad
  1364.  |v->arcs->next->next->tip|,quad dotsthinspace,}$$
  1365. will be in strictly decreasing order (except in the case of an
  1366. undirected self-loop, when |v| itself will appear twice in succession).
  1367. @ @<Basic subroutines@>=
  1368. Graph *complement(g,copy,self,directed)
  1369.   Graph *g; /* graph to be complemented */
  1370.   long copy; /* should we double-complement? */
  1371.   long self; /* should we produce self-loops? */
  1372.   long directed; /* should the graph be directed? */
  1373. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  1374.   register long n;
  1375.   register Vertex *u;
  1376.   register siz_t delta; /* difference in memory addresses */
  1377.   if (g==NULL) panic(missing_operand); /* where's |g|? */
  1378.   @<Set up a graph with the vertices of |g|@>;
  1379.   sprintf(buffer,",%d,%d,%d)",copy?1:0,self?1:0,directed?1:0);
  1380.   make_compound_id(new_graph,"complement(",g,buffer);
  1381.   @<Insert complementary arcs or edges@>;
  1382.   if (gb_trouble_code) {
  1383.     gb_recycle(new_graph);
  1384.     panic(alloc_fault);
  1385.      /* worse luck, we ran out of memory somewhere back there */
  1386.   }
  1387.   return new_graph;
  1388. }
  1389. @ In several of the following routines, it is efficient to circumvent
  1390. CEE/'s normal rules for pointer arithmetic, and to use the
  1391. fact that the vertices of a graph being copied are a constant distance away
  1392. in memory from the vertices of its clone.
  1393. @d vert_offset(v,delta) ((Vertex*)(((siz_t)v)+delta))
  1394. @^pointer hacks@>
  1395. @<Set up a graph with the vertices of |g|@>=
  1396. n=g->n;
  1397. new_graph=gb_new_graph(n);
  1398. if (new_graph==NULL)
  1399.   panic(no_room); /* out of memory before we're even started */
  1400. delta=((siz_t)(new_graph->vertices))-((siz_t)(g->vertices));
  1401. for (u=new_graph->vertices,v=g->vertices;v<g->vertices+n;u++,v++)
  1402.   u->name=gb_save_string(v->name);
  1403. @ A temporary utility field in the new graph is used to remember which
  1404. vertices are adjacent to a given vertex in the old one. We stamp the |tmp|
  1405. field of~|v| with a pointer to~|u| when there's an arc from |u| to~|v|.
  1406. @d tmp u.V /* utility field |u| for temporary use as a vertex pointer */
  1407. @<Insert comp...@>=
  1408. for (v=g->vertices;v<g->vertices+n;v++) {@+register Vertex *vv;
  1409.   u=vert_offset(v,delta);
  1410.            /* vertex in |new_graph| corresponding to |v| in |g| */
  1411.   {@+register Arc *a;
  1412.     for (a=v->arcs;a;a=a->next) vert_offset(a->tip,delta)->tmp=u;
  1413.   }
  1414.   if (directed) {
  1415.     for (vv=new_graph->vertices;vv<new_graph->vertices+n;vv++)
  1416.       if ((vv->tmp==u && copy) || (vv->tmp!=u && !copy))
  1417.         if (vv!=u || self) gb_new_arc(u,vv,1L);
  1418.   }@+else {
  1419.     for (vv=(self?u:u+1);vv<new_graph->vertices+n;vv++)
  1420.       if ((vv->tmp==u && copy) || (vv->tmp!=u && !copy))
  1421.         gb_new_edge(u,vv,1L);
  1422.   }
  1423. }
  1424. for (v=new_graph->vertices;v<new_graph->vertices+n;v++) v->tmp=NULL;
  1425. @* Graph union and intersection. Another simple way to get new graphs
  1426. from old ones is to take the union or intersection of their sets of arcs. The
  1427. subroutine call |gunion(g,gg,multi,directed)| produces a graph
  1428. with the vertices and arcs of |g| together with the
  1429. arcs of another graph~|gg|. The subroutine call |intersection(g,gg,multi,
  1430. directed)| produces a graph with the vertices of |g| but with only the
  1431. arcs that appear in both |g| and |gg|. In both cases we assume
  1432. that |gg| has the same vertices as |g|, in the sense that vertices
  1433. in the same relative position from the beginning of the vertex array
  1434. are considered identical. If the actual number of vertices in |gg| exceeds
  1435. the number in |g|, the extra vertices and all arcs touching them in~|gg| are
  1436. suppressed.
  1437. The input graphs are assumed to be undirected, unless the |directed|
  1438. parameter is nonzero. Peculiar results might occur if you mix directed
  1439. and undirected graphs, but the subroutines will not ``crash''
  1440. when they are asked to produce undirected output from directed input.
  1441. If |multi| is nonzero, the new graph may have multiple edges: Suppose
  1442. there are $k_1$ arcs from $u$ to $v$ in |g| and $k_2$ such arcs in |gg|. Then
  1443. there will be $k_1+k_2$ in the union and $min(k_1,k_2)$ in the
  1444. intersection when |multi!=0|, but at most
  1445. one in the union or intersection when |multi=0|.
  1446. The lengths of arcs are copied to the union graph when |multi!=0|;
  1447. the minimum length of multiple arcs is retained in the union when |multi=0|.
  1448. The lengths of arcs in the intersection graph are a bit trickier.
  1449. If multiple arcs occur in |g|, their minimum length, |l|, is computed. Then
  1450. we compute the maximum of |l| and the lengths of corresponding arcs
  1451. in |gg|. If |multi=0|, only the minimum of those maxima will survive.
  1452. @ @<Basic subroutines@>=
  1453. Graph *gunion(g,gg,multi,directed)
  1454.   Graph *g,*gg; /* graphs to be united */
  1455.   long multi; /* should we reproduce multiple arcs? */
  1456.   long directed; /* should the graph be directed? */
  1457. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  1458.   register long n;
  1459.   register Vertex *u;
  1460.   register siz_t delta,ddelta; /* differences in memory addresses */
  1461.   if (g==NULL || gg==NULL) panic(missing_operand);
  1462.     /* where are |g| and |gg|? */
  1463.   @<Set up a graph with the vertices of |g|@>;
  1464.   sprintf(buffer,",%d,%d)",multi?1:0,directed?1:0);
  1465.   make_double_compound_id(new_graph,"gunion(",g,",",gg,buffer);
  1466.   ddelta=((siz_t)(new_graph->vertices))-
  1467.              ((siz_t)(gg->vertices));
  1468.   @<Insert arcs or edges present in either |g| or |gg|@>;
  1469.   if (gb_trouble_code) {
  1470.     gb_recycle(new_graph);
  1471.     panic(alloc_fault); /* uh oh, we ran out of memory somewhere back there */
  1472.   }
  1473.   return new_graph;
  1474. }
  1475. @ @<Insert arcs or edges present in either |g| or |gg|@>=
  1476. for (v=g->vertices;v<g->vertices+n;v++) {
  1477.   register Arc *a;
  1478.   register Vertex *vv=vert_offset(v,delta);
  1479.       /* vertex in |new_graph| corresponding to |v| in |g| */
  1480.   register Vertex *vvv=vert_offset(vv,-ddelta);
  1481.       /* vertex in |gg| corresponding to |v| in  |g| */
  1482.   for (a=v->arcs;a;a=a->next) {
  1483.     u=vert_offset(a->tip,delta);
  1484.     @<Insert a union arc or edge from |vv| to |u|, if appropriate@>;
  1485.   }
  1486.   if (vvv<gg->vertices+gg->n) for (a=vvv->arcs;a;a=a->next) {
  1487.     u=vert_offset(a->tip,ddelta);
  1488.     if (u<new_graph->vertices+n)
  1489.       @<Insert a union arc or edge from |vv| to |u|, if appropriate@>;
  1490.   }
  1491. }
  1492. for (v=new_graph->vertices;v<new_graph->vertices+n;v++)
  1493.   v->tmp=NULL,v->tlen=NULL;
  1494. @ We use the |tmp| trick of |complement| to remember which arcs have
  1495. already been recorded from |u|, and we extend it so that we can maintain
  1496. minimum lengths. Namely, |uu->tmp| will equal |u| if and only
  1497. if we have already seen an arc from |u| to |uu|; and if so, |uu->tlen|
  1498. will be one such arc. In the undirected case, |uu->tlen| will point to the
  1499. first arc of an edge pair that touches~|u|.
  1500. The only thing slightly nontrivial here is the way we keep undirected
  1501. edges grouped in pairs. We generate a new edge from |vv| to |u| only
  1502. if |vv<=u|, and if equality holds we advance~|a| so that we don't
  1503. see the self-loop in both directions. Similar logic will be repeated 
  1504. in many of the programs below.
  1505. @d tlen z.A /* utility field |z| regarded as a pointer to an arc */
  1506. @<Insert a union arc or edge from |vv| to |u|, if appropriate@>=
  1507. {@+register Arc *b;
  1508.   if (directed) {
  1509.     if (multi || u->tmp!=vv) gb_new_arc(vv,u,a->len);
  1510.     else {
  1511.       b=u->tlen;
  1512.       if (a->len<b->len) b->len=a->len;
  1513.     }
  1514.     u->tmp=vv; /* remember that we've seen this */
  1515.     u->tlen=vv->arcs;
  1516.   }@+else if (u>=vv) {
  1517.     if (multi || u->tmp!=vv) gb_new_edge(vv,u,a->len);
  1518.     else {
  1519.       b=u->tlen;
  1520.       if (a->len<b->len) b->len=(b+1)->len=a->len;
  1521.     }
  1522.     u->tmp=vv;
  1523.     u->tlen=vv->arcs;
  1524.     if (u==vv && a->next==a+1) a++; /* bypass second half of self-loop */
  1525.   }
  1526. }
  1527. @ @<Basic subroutines@>=
  1528. Graph *intersection(g,gg,multi,directed)
  1529.   Graph *g,*gg; /* graphs to be intersected */
  1530.   long multi; /* should we reproduce multiple arcs? */
  1531.   long directed; /* should the graph be directed? */
  1532. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  1533.   register long n;
  1534.   register Vertex *u;
  1535.   register siz_t delta,ddelta; /* differences in memory addresses */
  1536.   if (g==NULL || gg==NULL) panic(missing_operand); /* where are |g| and |gg|? */
  1537.   @<Set up a graph with the vertices of |g|@>;
  1538.   sprintf(buffer,",%d,%d)",multi?1:0,directed?1:0);
  1539.   make_double_compound_id(new_graph,"intersection(",g,",",gg,buffer);
  1540.   ddelta=((siz_t)(new_graph->vertices))-
  1541.                ((siz_t)(gg->vertices));
  1542.   @<Insert arcs or edges present in both |g| and |gg|@>;
  1543.   if (gb_trouble_code) {
  1544.     gb_recycle(new_graph);
  1545.     panic(alloc_fault); /* whoops, we ran out of memory somewhere back there */
  1546.   }
  1547.   return new_graph;
  1548. }
  1549. @ Two more temporary utility fields are needed here.
  1550. @d mult v.I /* utility field |v|, counts multiplicity of arcs */
  1551. @d minlen w.I /* utility field |w|, records the smallest length */
  1552. @<Insert arcs or edges present in both |g| and |gg|@>=
  1553. for (v=g->vertices;v<g->vertices+n;v++) {@+register Arc *a;
  1554.   register Vertex *vv=vert_offset(v,delta);
  1555.       /* vertex in |new_graph| corresponding to |v| in |g| */
  1556.   register Vertex *vvv=vert_offset(vv,-ddelta);
  1557.       /* vertex in |gg| corresponding to |v| in  |g| */
  1558.   if (vvv>=gg->vertices+gg->n) continue;
  1559.   @<Take note of all arcs from |v|@>;
  1560.   for (a=vvv->arcs;a;a=a->next) {
  1561.     u=vert_offset(a->tip,ddelta);
  1562.     if (u>=new_graph->vertices+n) continue;
  1563.     if (u->tmp==vv) {@+long l=u->minlen;
  1564.       if (a->len>l) l=a->len; /* maximum */
  1565.       if (u->mult<0) @<Update minimum of multiple maxima@>@;
  1566.       else @<Generate a new arc or edge for the intersection,
  1567.                 and reduce the multiplicity@>;
  1568.     }
  1569.   }
  1570. }
  1571. @<Clear out the temporary utility fields@>;
  1572. @ @<Generate a new arc or edge for the intersection...@>=
  1573. {
  1574.   if (directed) gb_new_arc(vv,u,l);
  1575.   else {
  1576.     if (vv<=u) gb_new_edge(vv,u,l);
  1577.     if (vv==u && a->next==a+1) a++; /* skip second half of self-loop */
  1578.   }
  1579.   if (!multi) {
  1580.     u->tlen=vv->arcs;
  1581.     u->mult=-1;
  1582.   }@+else if (u->mult==0) u->tmp=NULL;
  1583.   else u->mult--;
  1584. }
  1585. @ We get here if and only if |multi=0| and |gg|~has more than one arc from |vv|
  1586. to~|u| and |g|~has at least one arc from |vv| to~|u|.
  1587. @<Update minimum of multiple maxima@>=
  1588. {@+register Arc *b=u->tlen; /* previous arc or edge from |vv| to |u| */
  1589.   if (l<b->len) {
  1590.     b->len=l;
  1591.     if (!directed) (b+1)->len=l;
  1592.   }
  1593. }
  1594. @ @<Take note of all arcs from |v|@>=
  1595. for (a=v->arcs;a;a=a->next) {
  1596.   u=vert_offset(a->tip,delta);
  1597.   if (u->tmp==vv) {
  1598.     u->mult++;
  1599.     if (a->len<u->minlen) u->minlen=a->len;
  1600.   }@+else u->tmp=vv, u->mult=0, u->minlen=a->len;
  1601.   if (u==vv && !directed && a->next==a+1) a++;
  1602.            /* skip second half of self-loop */
  1603. }
  1604. @ @<Clear out the temporary utility fields@>=
  1605. for (v=new_graph->vertices;v<new_graph->vertices+n;v++) {
  1606.   v->tmp=NULL;
  1607.   v->tlen=NULL;
  1608.   v->mult=0;
  1609.   v->minlen=0;
  1610. }
  1611. @* Line graphs. The next operation in {sc GB_,BASIC}'s repertoire constructs
  1612. the so-called line graph of a given graph~$g$. The subroutine that does
  1613. this is invoked by calling `|lines(g,directed)|'.
  1614. If |directed=0|, the line graph has one vertex for each edge of~|g|;
  1615. two vertices are adjacent if and only if the corresponding edges
  1616. have a common vertex.
  1617. If |directed!=0|, the line graph has one vertex for each arc of~|g|;
  1618. there is an arc from vertex |u| to vertex |v| if and only if the
  1619. arc corresponding to~|u| ends at the vertex that begins the arc
  1620. corresponding to~|v|.
  1621. All arcs of the line graph will have length~1.
  1622. Utility fields |u.V| and |v.V| of each vertex in the line graph will point to
  1623. the vertices of |g| that define the corresponding arc or edge, and |w.A| will
  1624. point to the arc from |u.V| to |v.V| in~|g|. In the undirected case we will
  1625. have |u.V<=v.V|.
  1626. @<Basic subroutines@>=
  1627. Graph *lines(g,directed)
  1628.   Graph *g; /* graph whose lines will become vertices */
  1629.   long directed; /* should the graph be directed? */
  1630. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  1631.   register long m; /* the number of lines */
  1632.   register Vertex *u;
  1633.   if (g==NULL) panic(missing_operand); /* where is |g|? */
  1634.   @<Set up a graph whose vertices are the lines of |g|@>;
  1635.   if (directed) @<Insert arcs of a directed line graph@>@;
  1636.   else @<Insert edges of an undirected line graph@>;
  1637.   @<Restore |g| to its pristine original condition@>;
  1638.   if (gb_trouble_code) {
  1639.     gb_recycle(new_graph);
  1640.     panic(alloc_fault); /* (sigh) we ran out of memory somewhere back there */
  1641.   }
  1642.   return new_graph;
  1643. near_panic:@<Recover from potential disaster due to bad data@>;
  1644. }
  1645. @ We want to add a data structure to |g| so that the line graph can be
  1646. built efficiently. But we also want to preserve |g| so that it
  1647. exhibits no traces of occupation when |lines| has finished its
  1648. work.  To do this, we will move utility field~|v->z| temporarily into
  1649. a utility field~|u->z| of the line graph, where |u| is the first
  1650. vertex having |u->u.V==v|, whenever such a |u| exists. Then we'll
  1651. set |v->map=u|. We will then be able to find |u| when |v|
  1652. is given, and we'll be able to cover our tracks later.
  1653. In the undirected case, further structure is needed. We will temporarily
  1654. change the |tip| field in the second arc of each edge pair so that
  1655. it points to the line-graph vertex that points to the first arc of the pair.
  1656. The |util_types| field of the graph does not indicate the fact that utility
  1657. fields |u.V|, |v.V|, and |w.A| of each vertex will be set, because those
  1658. utility fields are pointers from the new graph to the original graph.
  1659. The |save_graph| procedure does not deal with pointers between graphs.
  1660. @d map z.V /* the |z| field treated as a vertex pointer */
  1661. @<Restore |g| to its pristine original condition@>=
  1662. for (u=new_graph->vertices,v=NULL;u<new_graph->vertices+m;u++) {
  1663.   if (u->u.V!=v) {
  1664.     v=u->u.V; /* original vertex of |g| */
  1665.     v->map=u->map; /* restore original value of |v->z| */
  1666.     u->map=NULL;
  1667.   }
  1668.   if (!directed) ((u->w.A)+1)->tip=v;
  1669. }
  1670. @ Special care must be taken to avoid chaos when the user is trying to
  1671. construct the undirected line graph of a directed graph.  Otherwise we
  1672. might trash the memory, or we might leave the original graph in a garbled state
  1673. with pointers leading into supposedly free space.
  1674. @<Set up a graph whose vertices are the lines of |g|@>=
  1675. m=(directed? g->m: (g->m)/2);
  1676. new_graph=gb_new_graph(m);
  1677. if (new_graph==NULL)
  1678.   panic(no_room); /* out of memory before we're even started */
  1679. make_compound_id(new_graph,"lines(",g,directed? ",1)": ",0)");
  1680. u=new_graph->vertices;
  1681. for (v=g->vertices+g->n-1;v>=g->vertices;v--) {@+register Arc *a;
  1682.   register long mapped=0; /* has |v->map| been set? */
  1683.   for (a=v->arcs;a;a=a->next) {@+register Vertex *vv=a->tip;
  1684.     if (!directed) {
  1685.       if (vv<v) continue;
  1686.       if (vv>=g->vertices+g->n) goto near_panic;
  1687.             /* original graph not undirected */
  1688.     }
  1689.     @<Make |u| a vertex representing the arc |a| from |v| to |vv|@>;
  1690.     if (!mapped) {
  1691.       u->map=v->map;  /* |z.V=map| incorporates all bits of utility field |z|,
  1692.                            whatever its type */
  1693.       v->map=u;
  1694.       mapped=1;
  1695.     }
  1696.     u++;
  1697.   }
  1698. }
  1699. if (u!=new_graph->vertices+m) goto near_panic;
  1700. @ @<Recover...@>=
  1701. m=u-new_graph->vertices;
  1702. @<Restore |g| to its pristine...@>;
  1703. gb_recycle(new_graph);
  1704. panic(invalid_operand);
  1705.  /* |g| did not obey the conventions for an undirected graph */
  1706. @ The vertex names in the line graph are pairs of original vertex names,
  1707. separated by `.{--}' when undirected, `.{->}' when directed. If either
  1708. of the original names is horrendously long, the villainous Procrustes
  1709. chops it off arbitrarily so that it fills at most half of the name buffer.
  1710. @<Make |u| a vertex representing the arc |a| from |v| to |vv|@>=
  1711. u->u.V=v;
  1712. u->v.V=vv;
  1713. u->w.A=a;
  1714. if (!directed) {
  1715.   if (u>=new_graph->vertices+m || (a+1)->tip!=v) goto near_panic;
  1716.   if (v==vv && a->next==a+1) a++; /* skip second half of self-loop */
  1717.   else (a+1)->tip=u;
  1718. }
  1719. sprintf(buffer,"%.*s-%c%.*s",(BUF_SIZE-3)/2,v->name,@|
  1720.    directed? '>': '-',BUF_SIZE/2-1,vv->name);
  1721. u->name=gb_save_string(buffer);
  1722. @ @<Insert arcs of a directed line graph@>=
  1723. for (u=new_graph->vertices;u<new_graph->vertices+m;u++) {
  1724.   v=u->v.V;
  1725.   if (v->arcs) { /* |v->map| has been set up */
  1726.     v=v->map;
  1727.     do@+{gb_new_arc(u,v,1L);
  1728.     v++;
  1729.     }@+while (v->u.V==u->v.V);
  1730.   }
  1731. }
  1732. @ An undirected line graph will contain no self-loops. It contains
  1733. multiple edges only if the original graph did; in that case, there
  1734. are two edges joining a line to each of its parallel mates, because
  1735. each mate hits both of its endpoints.
  1736. The details of this section deserve careful study.  We use the
  1737. fact that the first vertices of the lines occur in nonincreasing order.
  1738. @<Insert edges of an undirected line graph@>=
  1739. for (u=new_graph->vertices;u<new_graph->vertices+m;u++) {@+register Vertex *vv;
  1740.   register Arc *a;@+register long mapped=0;
  1741.   v=u->u.V; /* we look first for prior lines that touch the first vertex */
  1742.   for (vv=v->map;vv<u;vv++) gb_new_edge(u,vv,1L);
  1743.   v=u->v.V; /* then we look for prior lines that touch the other one */
  1744.   for (a=v->arcs;a;a=a->next) {
  1745.     vv=a->tip;
  1746.     if (vv<u && vv>=new_graph->vertices) gb_new_edge(u,vv,1L);
  1747.     else if (vv>=v && vv<g->vertices+g->n) mapped=1;
  1748.   }
  1749.   if (mapped && v>u->u.V)
  1750.     for (vv=v->map;vv->u.V==v;vv++) gb_new_edge(u,vv,1L);
  1751. }
  1752. @* Graph products. Three ways have traditionally been used to define the
  1753. product of two graphs. In all three cases the vertices of the product graph
  1754. are ordered pairs $(v,v')$, where $v$ and $v'$ are vertices of the original
  1755. graphs; the difference occurs in the definition of arcs. Suppose $g$ has
  1756. $m$ arcs and $n$ vertices, while $g'$ has $m'$ arcs and $n'$ vertices. The
  1757. {sl cartesian product/} of $g$ and~$g'$ has $mn'+m'n$ arcs, namely from
  1758. $(u,u')$ to $(v,u')$ whenever there's an arc from $u$ to $v$ in~$g$, and from
  1759. $(u,u')$ to $(u,v')$ whenever there's an arc from $u'$ to $v'$ in~$g'$.
  1760. The {sl direct product/} has $mm'$ arcs, namely from $(u,u')$ to
  1761. $(v,v')$ in the same circumstances. The {sl strong product/}
  1762. has both the arcs of the cartesian product and the direct product.
  1763. Notice that an undirected graph with $m$ edges has $2m$ arcs. Thus the
  1764. number of edges in the direct product of two undirected graphs is
  1765. twice the product of the number of edges in the individual graphs.
  1766. A self-loop in~$g$ will combine with an edge in~$g'$ to make
  1767. two parallel edges in the direct product.
  1768. The subroutine call |product(g,gg,type,directed)| produces the product
  1769. graph of one of these three types, where |type=0| for cartesian product,
  1770. |type=1| for direct product, and |type=2| for strong product.
  1771. The length of an arc in the cartesian product is copied from the length
  1772. of the original arc that it replicates; the length of an arc in the direct
  1773. product is the minimum of the two arc lengths that induce it. If |directed=0|,
  1774. the product graph will be an undirected graph with edges consisting
  1775. of consecutive arc pairs according to the standard GraphBase conventions,
  1776. and the input graphs should adhere to  the same conventions.
  1777. @(gb_basic.h@>=
  1778. #define cartesian 0
  1779. #define direct 1
  1780. #define strong 2
  1781. @ @<Basic subroutines@>=
  1782. Graph *product(g,gg,type,directed)
  1783.   Graph *g,*gg; /* graphs to be multiplied */
  1784.   long type; /* |cartesian|, |direct|, or |strong| */
  1785.   long directed; /* should the graph be directed? */
  1786. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  1787.   register Vertex *u,*vv;
  1788.   register long n; /* the number of vertices in the product graph */
  1789.   if (g==NULL || gg==NULL) panic(missing_operand); /* where are |g| and |gg|? */
  1790.   @<Set up a graph with ordered pairs of vertices@>;
  1791.   if ((type&1)==0) @<Insert arcs or edges for cartesian product@>;
  1792.   if (type) @<Insert arcs or edges for direct product@>;
  1793.   if (gb_trouble_code) {
  1794.     gb_recycle(new_graph);
  1795.     panic(alloc_fault);
  1796.       /* @@?`$*$#!&, we ran out of memory somewhere back there */
  1797.   }
  1798.   return new_graph;
  1799. }
  1800. @ We must be constantly on guard against running out of memory, especially
  1801. when multiplying information.
  1802. The vertex names in the product are pairs of original vertex names separated
  1803. by commas. Thus, for example, if you cross an |econ| graph with a |roget|
  1804. graph, you can get vertices like |"Financial services, mediocrity"|.
  1805. @<Set up a graph with ordered pairs of vertices@>=
  1806. {@+float test_product=((float)(g->n))*((float)(gg->n));
  1807.   if (test_product>MAX_NNN) panic(very_bad_specs); /* way too many vertices */
  1808. }
  1809. n=(g->n)*(gg->n);
  1810. new_graph=gb_new_graph(n);
  1811. if (new_graph==NULL)
  1812.   panic(no_room); /* out of memory before we're even started */
  1813. for (u=new_graph->vertices,v=g->vertices,vv=gg->vertices;@|
  1814.     u<new_graph->vertices+n;u++) {
  1815.   sprintf(buffer,"%.*s,%.*s",BUF_SIZE/2-1,v->name,(BUF_SIZE-1)/2,vv->name);
  1816.   u->name=gb_save_string(buffer);
  1817.   if (++vv==gg->vertices+gg->n) vv=gg->vertices,v++; /* ``carry'' */
  1818. }
  1819. sprintf(buffer,",%d,%d)",(type?2:0)-(int)(type&1),directed?1:0);
  1820. make_double_compound_id(new_graph,"product(",g,",",gg,buffer);
  1821. @ @<Insert arcs or edges for cartesian product@>=
  1822. {@+register Vertex *uu,*uuu;
  1823.   register Arc *a;
  1824.   register siz_t delta; /* difference in memory addresses */
  1825.   delta=((siz_t)(new_graph->vertices))-((siz_t)(gg->vertices));
  1826.   for (u=gg->vertices;u<gg->vertices+gg->n;u++)
  1827.     for (a=u->arcs;a;a=a->next) {
  1828.       v=a->tip;
  1829.       if (!directed) {
  1830.         if (u>v) continue;
  1831.         if (u==v && a->next==a+1) a++; /* skip second half of self-loop */
  1832.       }
  1833.       for (uu=vert_offset(u,delta),vv=vert_offset(v,delta);@|
  1834.              uu<new_graph->vertices+n;uu+=gg->n,vv+=gg->n)
  1835.         if (directed) gb_new_arc(uu,vv,a->len);
  1836.         else gb_new_edge(uu,vv,a->len);      
  1837.     }
  1838.   @<Insert arcs or edges for first component of cartesian product@>;
  1839. }
  1840. @ @<Insert arcs or edges for first component...@>=
  1841. for (u=g->vertices,uu=new_graph->vertices;uu<new_graph->vertices+n;
  1842.           u++,uu+=gg->n)
  1843.   for (a=u->arcs;a;a=a->next) {
  1844.     v=a->tip;
  1845.     if (!directed) {
  1846.       if (u>v) continue;
  1847.       if (u==v && a->next==a+1) a++; /* skip second half of self-loop */
  1848.     }
  1849.     vv=new_graph->vertices+((gg->n)*(v-g->vertices));
  1850.     for (uuu=uu;uuu<uu+gg->n;uuu++,vv++)
  1851.       if (directed) gb_new_arc(uuu,vv,a->len);
  1852.       else gb_new_edge(uuu,vv,a->len);
  1853.   }
  1854. @ @<Insert arcs or edges for direct product@>=
  1855. {@+Vertex *uu;@+Arc *a;
  1856.   siz_t delta0=
  1857.    ((siz_t)(new_graph->vertices))-((siz_t)(gg->vertices));
  1858.   siz_t del=(gg->n)*sizeof(Vertex);
  1859.   register siz_t delta,ddelta;
  1860.   for (uu=g->vertices,delta=delta0;uu<g->vertices+g->n;uu++,delta+=del)
  1861.     for (a=uu->arcs;a;a=a->next) {
  1862.       vv=a->tip;
  1863.       if (!directed) {
  1864.         if (uu>vv) continue;
  1865.         if (uu==vv && a->next==a+1) a++; /* skip second half of self-loop */
  1866.       }
  1867.       ddelta=delta0+del*(vv-g->vertices);
  1868.       for (u=gg->vertices;u<gg->vertices+gg->n;u++) {@+register Arc *aa;
  1869.         for (aa=u->arcs;aa;aa=aa->next) {@+long length=a->len;
  1870.           if (length>aa->len) length=aa->len;
  1871.           v=aa->tip;
  1872.           if (directed)
  1873.             gb_new_arc(vert_offset(u,delta),vert_offset(v,ddelta),length);
  1874.           else gb_new_edge(vert_offset(u,delta),
  1875.                            vert_offset(v,ddelta),length);
  1876.         }
  1877.       }
  1878.     }
  1879. }
  1880. @* Induced graphs. Another important way to transform a graph is to
  1881. remove, identify, or split some of its vertices. All of these
  1882. operations are performed by the |induced| routine, which users can
  1883. invoke by calling `|induced(g,description,self,multi,directed)|'.
  1884. Each vertex |v| of |g| should first be assigned an ``induction code'' in
  1885. its field |v->ind|, which is actually utility field~|z|. The
  1886. induction code is 0~if |v| is to be eliminated; it is 1~if |v| is to be
  1887. retained; it is |k>1| if |v| is to be split into $k$ nonadjacent vertices
  1888. having the same neighbors as~|v| did; and it is |k<0| if |v| is to be
  1889. identified with all other vertices having the same value of~|k|.
  1890. For example, suppose |g| is a circuit with vertices ${0,1,ldots,9}$,
  1891. where |j| is adjacent to~|k| if and only if $k=(jpm1)bmod10$.
  1892. If we set
  1893. $$vcenter{halign{hbox{hfil#hfil}cr
  1894. |0->ind=0|,quad |1->ind=5->ind=9->ind=-1|,quad |2->ind=3->ind=-2|,cr
  1895. |4->ind=6->ind=8->ind=1|,quad and |7->ind=3|,cr}}$$
  1896. the induced graph will have vertices ${-1,-2,4,6,7,7',7'',8}$.
  1897. The vertices adjacent to 6, say, will be $-1$ (formerly~5), 7, $7'$,
  1898. and~$7''$. The vertices adjacent to $-1$ will be those formerly
  1899. adjacent to 1, 5, or~9, namely $-2$ (formerly~2), 4, 6, and~8. The
  1900. vertices adjacent to $-2$ will be those formerly adjacent to 2 or~3,
  1901. namely $-1$ (formerly~1), $-2$ (formerly~3), $-2$ (formerly~2), and~4.
  1902. Duplicate edges will be discarded if |multi==0|, and self-loops will
  1903. be discarded if |self==0|.
  1904. The total number of vertices in the induced graph will be the sum
  1905. of the positive |ind| fields plus the absolute value of the most
  1906. negative |ind| field. This rule implies, for example, that if at least
  1907. one vertex has |ind=-5|, the induced graph will always have a vertex $-4$,
  1908. even though no |ind| field has been set to~$-4$.
  1909. The |description| parameter is a string that will appear as part of
  1910. the name of the induced graph; if |description=0|, this string will
  1911. be empty. In the latter case, users are encouraged to assign a suitable
  1912. name to the |id| field of the induced graph themselves, characterizing
  1913. the method by which the |ind| codes were set.
  1914. If the |directed| parameter is zero, the input graph will be assumed to
  1915. be undirected, and the output graph will be undirected.
  1916. When |multi=0|, the length of an arc that represents multiple arcs
  1917. will be the minimum of the multiple arc lengths.
  1918. @d ind z.I
  1919. @(gb_basic.h@>=
  1920. #define ind @[z.I /* utility field |z| when used to induce a graph */@]
  1921. @ Here's a simple example: To get a complete bipartite graph with
  1922. parts of sizes |n1| and |n2|, we can start with a trivial two-point
  1923. graph and split its vertices into |n1| and |n2| parts.
  1924. @<Applications...@>=
  1925. Graph *bi_complete(n1,n2,directed)
  1926.   unsigned long n1; /* size of first part */
  1927.   unsigned long n2; /* size of second part */
  1928.   long directed; /* should all arcs go from first part to second? */
  1929. {@+Graph *new_graph=board(2L,0L,0L,0L,1L,0L,directed);
  1930.   if (new_graph) {
  1931.     new_graph->vertices->ind=n1;
  1932.     (new_graph->vertices+1)->ind=n2;
  1933.     new_graph=induced(new_graph,NULL,0L,0L,directed);
  1934.     if (new_graph) {
  1935.       sprintf(new_graph->id,"bi_complete(%lu,%lu,%d)",@|
  1936.                               n1,n2,directed?1:0);
  1937.       mark_bipartite(new_graph,n1);
  1938.     }
  1939.   }
  1940.   return new_graph;
  1941. }
  1942. @ The |induced| routine also provides a special feature not mentioned
  1943. above: If the |ind| field of any vertex |v| is |IND_GRAPH| or greater
  1944. (where |IND_GRAPH| is a large constant, much larger than the number
  1945. of vertices that would fit in computer memory), then utility field |v->subst|
  1946. should point to a graph. A copy of the vertices of
  1947. that graph will then be substituted for |v| in the induced graph.
  1948. This feature extends the ordinary case when |v->ind>0|, which essentially
  1949. substitutes an empty graph for~|v|.
  1950. If substitution is being used to replace all of $g$'s vertices
  1951. by disjoint copies of some other graph~$g'$,
  1952. the induced graph will be somewhat similar to
  1953. a product graph. But it will not be the same as any of the three
  1954. types of output produced by |product|, because the relation between
  1955. $g$ and $g'$ is not symmetrical. Assuming that no self-loops are
  1956. present, and that graphs $(g,g')$ have respectively $(m,m')$ arcs and
  1957. $(n,n')$ vertices, the result of substituting $g'$ for all
  1958. vertices of~$g$ has $m'n+mn'^2$ arcs.
  1959. @d IND_GRAPH 1000000000 /* when |ind| is a billion or more, */
  1960. @d subst y.G /* we'll look at the |subst| field */
  1961. @(gb_basic.h@>=
  1962. #define IND_GRAPH 1000000000
  1963. #define subst @[y.G@]
  1964. @ For example, we can use the |IND_GRAPH| feature to create a
  1965. ``wheel'' of $n$ vertices arranged cyclically, all connected to one or
  1966. more center points. In the directed case, the arcs will run from the
  1967. center(s) to a cycle; in the undirected case, the edges will join the
  1968. center(s) to a circuit.
  1969. @<Applications...@>=
  1970. Graph *wheel(n,n1,directed)
  1971.   unsigned long n; /* size of the rim */
  1972.   unsigned long n1; /* number of center points */
  1973.   long directed; /* should all arcs go from center to rim and around? */
  1974. {@+Graph *new_graph=board(2L,0L,0L,0L,1L,0L,directed);
  1975.                                          /* trivial 2-vertex graph */
  1976.   if (new_graph) {
  1977.     new_graph->vertices->ind=n1;
  1978.     (new_graph->vertices+1)->ind=IND_GRAPH;
  1979.     (new_graph->vertices+1)->subst=board(n,0L,0L,0L,1L,1L,directed);
  1980.                              /* cycle or circuit */
  1981.     new_graph=induced(new_graph,NULL,0L,0L,directed);
  1982.     if (new_graph) {
  1983.       sprintf(new_graph->id,"wheel(%lu,%lu,%d)",@|
  1984.                               n,n1,directed?1:0);
  1985.     }
  1986.   }
  1987.   return new_graph;
  1988. }
  1989. @ @(gb_basic.h@>=
  1990. extern Graph *bi_complete();
  1991. extern Graph *wheel(); /* standard applications of |induced| */
  1992. @ @<Basic subroutines@>=
  1993. Graph *induced(g,description,self,multi,directed)
  1994.   Graph *g; /* graph marked for induction in its |ind| fields */
  1995.   char *description; /* string to be mentioned in |new_graph->id| */
  1996.   long self; /* should self-loops be permitted? */
  1997.   long multi; /* should multiple arcs be permitted? */
  1998.   long directed; /* should the graph be directed? */
  1999. {@+@<Vanilla local variables@>@;@+@q{@>@t}6{@>@q}@>
  2000.   register Vertex *u;
  2001.   register long n=0; /* total number of vertices in induced graph */
  2002.   register long nn=0; /* number of negative vertices in induced graph */
  2003.   if (g==NULL) panic(missing_operand); /* where is |g|? */
  2004.   @<Set up a graph with the induced vertices@>;
  2005.   @<Insert arcs or edges for induced vertices@>;
  2006.   @<Restore |g| to its original state@>;
  2007.   if (gb_trouble_code) {
  2008.     gb_recycle(new_graph);
  2009.     panic(alloc_fault); /* aargh, we ran out of memory somewhere back there */
  2010.   }
  2011.   return new_graph;
  2012. }
  2013. @ @<Set up a graph with the induced vertices@>=
  2014. @<Determine |n| and |nn|@>;
  2015. new_graph=gb_new_graph(n);
  2016. if (new_graph==NULL)
  2017.   panic(no_room); /* out of memory before we're even started */
  2018. @<Assign names to the new vertices, and create a map from |g| to |new_graph|@>;
  2019. sprintf(buffer,",%s,%d,%d,%d)",@|description?description:null_string,@|
  2020.                     self?1:0,multi?1:0,directed?1:0);
  2021. make_compound_id(new_graph,"induced(",g,buffer);
  2022. @ @<Determine |n| and |nn|@>=
  2023. for (v=g->vertices;v<g->vertices+g->n;v++)
  2024.   if (v->ind>0) {
  2025.     if (n>IND_GRAPH) panic(very_bad_specs); /* way too big */
  2026.     if (v->ind>=IND_GRAPH) {
  2027.       if (v->subst==NULL) panic(missing_operand+1);
  2028.         /* substitute graph is missing */
  2029.       n+=v->subst->n;
  2030.     }@+else n+=v->ind;
  2031.   }@+else if (v->ind<-nn) nn=-(v->ind);
  2032. if (n>IND_GRAPH || nn>IND_GRAPH) panic(very_bad_specs+1); /* gigantic */
  2033. n+=nn;
  2034. @ The negative vertices get the negative number as their name. Split vertices
  2035. get names with an optional prime appended, if the |ind| field is 2;
  2036. otherwise split vertex names are obtained by appending a colon and an index
  2037. number between |0| and~|ind-1|. The name of a vertex within a
  2038. graph |v->subst| is composed of the name of |v| followed by a
  2039. colon and the name within that graph.
  2040. We store the original |ind| field in the |mult| field of the first
  2041. corresponding vertex in the new graph, and change |ind| to point to
  2042. that vertex. This convention makes it easy
  2043. to determine the location of each vertex's clone or clones.
  2044. Of course, if the original |ind| field is zero, we leave it zero (|NULL|),
  2045. because it has no corresponding vertex in the new graph.
  2046. @<Assign names to the new vertices, and create a map from |g| to |new_graph|@>=
  2047. for (k=1,u=new_graph->vertices;k<=nn;k++,u++) {
  2048.   u->mult=-k;
  2049.   sprintf(buffer,"%ld",-k);
  2050.   u->name=gb_save_string(buffer);
  2051. }  
  2052. for (v=g->vertices;v<g->vertices+g->n;v++)
  2053.   if ((k=v->ind)<0) v->map=(new_graph->vertices)-(k+1);
  2054.   else if (k>0) {
  2055.     u->mult=k;
  2056.     v->map=u;
  2057.     if (k<=2) {
  2058.       u->name=gb_save_string(v->name);
  2059.       u++;
  2060.       if (k==2) {
  2061.         sprintf(buffer,"%s'",v->name);
  2062.         u->name=gb_save_string(buffer);
  2063.         u++;
  2064.       }
  2065.     }@+else if (k>=IND_GRAPH) @<Make names and arcs for a substituted graph@>@;
  2066.     else for (j=0;j<k;j++,u++) {
  2067.       sprintf(buffer,"%.*s:%ld",BUF_SIZE-12,v->name,j);
  2068.       u->name=gb_save_string(buffer);
  2069.     }
  2070.   }
  2071. @ @<Restore |g| to its original state@>=
  2072. for (v=g->vertices;v<g->vertices+g->n;v++)
  2073.   if (v->map) v->ind=v->map->mult;
  2074. for (v=new_graph->vertices;v<new_graph->vertices+n;v++)
  2075.   v->u.I=v->v.I=v->z.I=0; /* clear |tmp|, |mult|, |tlen| */
  2076. @ The heart of the procedure to construct an induced graph is, of course,
  2077. the part where we map the arcs of |g| into arcs of |new_graph|.
  2078. Notice that if |v| has a self-loop
  2079. in the original graph and if |v| is being split into several vertices,
  2080. it will produce arcs between different clones of itself, but it will not
  2081. produce self-loops unless |self!=0|. In an undirected graph, a loop
  2082. from a vertex to itself will not produce multiple edges among its clones,
  2083. even if |multi!=0|.
  2084. More precisely, if |v| has |k| clones |u| through |u+k-1|, an original
  2085. directed arc from |v| to~|v| will generate all $k^2$ possible arcs between
  2086. them, except that the |k| self-loops will be eliminated when
  2087. |self==0|.  An original undirected edge from |v| to~|v| will generate
  2088. $kchoose2$ edges between distinct clones, together with |k|
  2089. undirected self-loops if |self!=0|.
  2090. @<Insert arcs or edges for induced vertices@>=
  2091. for (v=g->vertices;v<g->vertices+g->n;v++) {
  2092.   u=v->map;
  2093.   if (u) {@+register Arc *a;@+register Vertex *uu,*vv;
  2094.     k=u->mult;
  2095.     if (k<0) k=1; /* |k| is the number of clones of |v| */
  2096.     else if (k>=IND_GRAPH) k=v->subst->n;
  2097.     for (;k;k--,u++) {
  2098.       if (!multi)
  2099.         @<Take note of existing edges that touch |u|@>;
  2100.       for (a=v->arcs;a;a=a->next) {
  2101.         vv=a->tip;
  2102.         uu=vv->map;
  2103.         if (uu==NULL) continue;
  2104.         j=uu->mult;
  2105.         if (j<0) j=1; /* |j| is the number of clones of |vv| */
  2106.         else if (j>=IND_GRAPH) j=vv->subst->n;
  2107.         if (!directed) {
  2108.           if (vv<v) continue;
  2109.           if (vv==v) {
  2110.             if (a->next==a+1) a++; /* skip second half of self-loop */
  2111.             j=k,uu=u; /* also skip duplicate edges generated by self-loop */
  2112.           }
  2113.         }
  2114.         @<Insert arcs or edges from vertex |u| to vertices
  2115.               |uu| through |uu+j-1|@>;
  2116.       }
  2117.     }
  2118.   }
  2119. }
  2120. @ Again we use the |tmp| and |tlen| trick of |gunion| to handle
  2121. multiple arcs. (This trick explains why the code in the previous
  2122. section tries to generate as many arcs as possible from a single
  2123. vertex |u|, before changing~|u|.)
  2124. @<Take note of existing edges that touch |u|@>=
  2125. for (a=u->arcs;a;a=a->next) {
  2126.   a->tip->tmp=u;
  2127.   if (directed || a->tip>u || a->next==a+1) a->tip->tlen=a;
  2128.   else a->tip->tlen=a+1;
  2129. }
  2130. @ @<Insert arcs or edges from vertex |u| to vertices |uu|...@>=
  2131. for (;j;j--,uu++) {
  2132.   if (u==uu && !self) continue;
  2133.   if (uu->tmp==u && !multi)
  2134.     @<Update the minimum arc length from |u| to |uu|, then |continue|@>;
  2135.   if (directed) gb_new_arc(u,uu,a->len);
  2136.   else gb_new_edge(u,uu,a->len);
  2137.   uu->tmp=u;
  2138.   uu->tlen=((directed || u<=uu)? u->arcs: uu->arcs);
  2139. }
  2140. @ @<Update the minimum arc length from |u| to |uu|, then |continue|@>=
  2141. {@+register Arc *b=uu->tlen; /* existing arc or edge from |u| to |uu| */
  2142.   if (a->len<b->len) {
  2143.     b->len=a->len; /* remember the minimum length */
  2144.     if (!directed) (b+1)->len=a->len;
  2145.   }
  2146.   continue;
  2147. }
  2148. @ We have now accumulated enough experience to finish off the one
  2149. remaining piece of program with ease.
  2150. @<Make names and arcs for a sub...@>=
  2151. {@+register Graph *gg=v->subst;
  2152.   register Vertex *vv=gg->vertices;
  2153.   register Arc *a;
  2154.   siz_t delta=((siz_t)u)-((siz_t)vv);
  2155.   for (j=0;j<v->subst->n;j++,u++,vv++) {
  2156.     sprintf(buffer,"%.*s:%.*s",BUF_SIZE/2-1,v->name,(BUF_SIZE-1)/2,vv->name);
  2157.     u->name=gb_save_string(buffer);
  2158.     for (a=vv->arcs;a;a=a->next) {@+register Vertex *vvv=a->tip;
  2159.       Vertex *uu=vert_offset(vvv,delta);
  2160.       if (vvv==vv && !self) continue;
  2161.       if (uu->tmp==u && !multi) @<Update the minimum arc length...@>;
  2162.       if (!directed) {
  2163.         if (vvv<vv) continue;
  2164.         if (vvv==vv && a->next==a+1) a++; /* skip second half of self-loop */
  2165.         gb_new_edge(u,uu,a->len);
  2166.       }@+else gb_new_arc(u,uu,a->len);
  2167.       uu->tmp=u;
  2168.       uu->tlen=((directed || u<=uu)? u->arcs: uu->arcs);
  2169.     }
  2170.   }
  2171. }
  2172. @* Index. As usual, we close with an index that
  2173. shows where the identifiers of \{gb_basic} are defined and used.