1 /* File commut.c. Main program for program to compute commutator subgroups.
2 Specifically, if H is a subgroup of G, the program computes the commutator
3 group [G,H]. The formats for the command is
4
5 commut <options> <group> <subgroup> <commutator>
6 or
7 commut <options> <group> <commutator>
8
9 where in the second case it is understood that <subgroup> equals <group>.
10
11 The meaning of the parameters is as follows:
12
13 <group>: The group referred to as G above.
14
15 <subgroup>: The group referred to as H above. Defaults to G.
16
17 <commutator>: Set to the commutator group [G,H].
18
19 The options are as follows:
20
21 -i The generators of <commutator> are to be written in image format.
22
23 -overwrite: If the Cayley library file for <commutator> exists, it will
24 be overwritten to rather than appended to.
25
26 The return code for set or partition stabilizer computations is as follows:
27 0: computation successful,
28 1: computation terminated due to error.
29 */
30
31
32 #include <stddef.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 #include "group.h"
39 #include "groupio.h"
40
41 #include "ccommut.h"
42 #include "errmesg.h"
43 #include "factor.h"
44 #include "permgrp.h"
45 #include "readgrp.h"
46 #include "readper.h"
47 #include "storage.h"
48 #include "token.h"
49 #include "util.h"
50
51 GroupOptions options;
52
53 static void verifyOptions(void);
54
main(int argc,char * argv[])55 int main( int argc, char *argv[])
56 {
57 char groupFileName[MAX_FILE_NAME_LENGTH] = "",
58 subgroupFileName[MAX_FILE_NAME_LENGTH] = "",
59 commutatorFileName[MAX_FILE_NAME_LENGTH] = "";
60 Unsigned i, j, optionCountPlus1;
61 char groupLibraryName[MAX_NAME_LENGTH+1] = "",
62 subgroupLibraryName[MAX_NAME_LENGTH+1] = "",
63 commutatorLibraryName[MAX_NAME_LENGTH+1] = "",
64 prefix[MAX_FILE_NAME_LENGTH+1] = "",
65 suffix[MAX_NAME_LENGTH+1] = "",
66 commutatorName[MAX_NAME_LENGTH+1] = "";
67 PermGroup *G, *H, *C;
68 BOOLEAN imageFormatFlag = FALSE, HnotequalG, quietFlag, normalClosureFlag;
69 char comment[100];
70
71 /* If no arguments (except possibly -ncl) are given, provide help and exit. */
72 if ( argc == 1 ) {
73 printf( "\nUsage: commut [options] group subgroup commutatorGroup\n");
74 return 0;
75 }
76 else if ( argc == 2 && strcmp(argv[1],"-ncl") == 0 ) {
77 printf( "\nUsage: ncl [options] group subgroup normalClosure\n");
78 return 0;
79 }
80
81 /* Check for limits option. If present in position 1, give limits and
82 return. */
83 if ( argc > 1 && (strcmp( argv[1], "-l") == 0 || strcmp( argv[1], "-L") == 0) ) {
84 showLimits();
85 return 0;
86 }
87 /* Check for verify option. If present in position 1, perform verify
88 (Note verifyOptions terminates program). */
89 if ( argc > 1 && (strcmp( argv[1], "-v") == 0 || strcmp( argv[1], "-V") == 0) )
90 verifyOptions();
91
92 /* Check for exactly 2 or 3 parameters following options. */
93 for ( optionCountPlus1 = 1 ; optionCountPlus1 < argc &&
94 argv[optionCountPlus1][0] == '-' ; ++optionCountPlus1 )
95 ;
96
97 if ( argc - optionCountPlus1 < 2 || argc - optionCountPlus1 > 3 )
98 ERROR( "main (commut)", "Exactly 2 or 3 parameters are required.")
99
100 /* Process options. */
101 prefix[0] = '\0';
102 suffix[0] = '\0';
103 options.maxBaseSize = DEFAULT_MAX_BASE_SIZE;
104 imageFormatFlag = FALSE;
105 quietFlag = FALSE;
106 normalClosureFlag = FALSE;
107 strcpy( options.outputFileMode, "w");
108
109 /* Process options. */
110 for ( i = 1 ; i < optionCountPlus1 ; ++i ) {
111 for ( j = 1 ; argv[i][j] != ':' && argv[i][j] != '\0' ; ++j )
112 #ifdef EBCDIC
113 argv[i][j] = ( argv[i][j] >= 'A' && argv[i][j] <= 'I' ||
114 argv[i][j] >= 'J' && argv[i][j] <= 'R' ||
115 argv[i][j] >= 'S' && argv[i][j] <= 'Z' ) ?
116 (argv[i][j] + 'a' - 'A') : argv[i][j];
117 #else
118 argv[i][j] = (argv[i][j] >= 'A' && argv[i][j] <= 'Z') ?
119 (argv[i][j] + 'a' - 'A') : argv[i][j];
120 #endif
121 errno = 0;
122 if ( strncmp( argv[i], "-p:", 3) == 0 ) {
123 strcpy( prefix, argv[i]+3);
124 }
125 else if ( strncmp( argv[i], "-t:", 3) == 0 ) {
126 strcpy( suffix, argv[i]+3);
127 }
128 else if ( strcmp( argv[i], "-i") == 0 )
129 imageFormatFlag = TRUE;
130 else if ( strncmp( argv[i], "-mb:", 4) == 0 ) {
131 errno = 0;
132 options.maxBaseSize = (Unsigned) strtol(argv[i]+4,NULL,0);
133 if ( errno )
134 ERROR( "main (cent)", "Invalid syntax for -mb option")
135 }
136 else if ( strncmp( argv[i], "-mw:", 4) == 0 ) {
137 errno = 0;
138 options.maxWordLength = (Unsigned) strtol(argv[i]+4,NULL,0);
139 if ( errno )
140 ERROR( "main (cent)", "Invalid syntax for -mw option")
141 }
142 else if ( strncmp( argv[i], "-n:", 3) == 0 )
143 if ( isValidName( argv[i]+3) )
144 strcpy( commutatorName, argv[i]+3);
145 else
146 ERROR1s( "main (commut)", "Invalid name ", commutatorName,
147 " for commutator group.")
148 else if ( strcmp( argv[i], "-a") == 0 )
149 strcpy( options.outputFileMode, "a");
150 else if ( strcmp( argv[i], "-q") == 0 )
151 quietFlag = TRUE;
152 else if ( strcmp( argv[i], "-ncl") == 0 )
153 normalClosureFlag = TRUE;
154 else
155 ERROR1s( "main (compute subgroup)", "Invalid option ", argv[i], ".")
156 }
157
158 /* Compute maximum degree and word length. */
159 options.maxWordLength = 200 + 5 * options.maxBaseSize;
160 options.maxDegree = MAX_INT - 2 - options.maxBaseSize;
161
162 HnotequalG = (argc - optionCountPlus1 == 3);
163 if ( normalClosureFlag && !HnotequalG )
164 ERROR( "main (commut)", "Invalid number of arguments for normal closure")
165
166 /* Compute names for files and libraries. */
167 parseLibraryName( argv[optionCountPlus1], prefix, suffix,
168 groupFileName, groupLibraryName);
169 if ( HnotequalG )
170 parseLibraryName( argv[optionCountPlus1+1], prefix, suffix,
171 subgroupFileName, subgroupLibraryName);
172 parseLibraryName( argv[optionCountPlus1+1+HnotequalG], "", "",
173 commutatorFileName, commutatorLibraryName);
174
175 /* Read in the groups G and H. */
176 G = readPermGroup( groupFileName, groupLibraryName, 0, "Generate");
177 if ( HnotequalG )
178 if ( normalClosureFlag )
179 H = readPermGroup( subgroupFileName, subgroupLibraryName, G->degree,
180 "Generate");
181 else
182 H = readPermGroup( subgroupFileName, subgroupLibraryName, G->degree,
183 "");
184 else
185 H = G;
186
187 /* Now we set C to the commutator of [G,H] of G and H, and write out C. */
188 if ( normalClosureFlag )
189 C = normalClosure( G, H);
190 else
191 C = commutatorGroup( G, H);
192 if ( commutatorName[0] != '\0' )
193 strcpy( C->name, commutatorName);
194 else
195 strcpy( C->name, commutatorLibraryName);
196 C->printFormat = (imageFormatFlag ? imageFormat : cycleFormat);
197 if ( normalClosureFlag )
198 sprintf( comment, "The normal closure in %s of %s.", G->name, H->name);
199 else
200 sprintf( comment, "The commutator group [%s,%s].", G->name, H->name);
201 writePermGroup( commutatorFileName, commutatorLibraryName, C, comment);
202
203 /* Write commutator group order to std output. */
204 if ( !quietFlag ) {
205 if ( normalClosureFlag )
206 printf( "\nNormal closure %s of %s in %s has order ", C->name,
207 H->name, G->name);
208 else
209 printf( "\nCommutator group %s = [%s,%s] has order ", C->name,
210 G->name, H->name);
211 if ( C->order->noOfFactors == 0 )
212 printf( "%d", 1);
213 else
214 for ( i = 0 ; i < C->order->noOfFactors ; ++i ) {
215 if ( i > 0 )
216 printf( " * ");
217 printf( "%u", C->order->prime[i]);
218 if ( C->order->exponent[i] > 1 )
219 printf( "^%u", C->order->exponent[i]);
220 }
221 printf( " (random Schreier)\n");
222 }
223
224 /* Return to caller. */
225 if ( normalClosureFlag )
226 return 0;
227 else if ( C->order->noOfFactors == 0 )
228 return 0;
229 else if ( H->order )
230 if ( factEqual( H->order, C->order) )
231 return 3;
232 else
233 return 2;
234 else
235 return 4;
236 }
237
238
239 /*-------------------------- verifyOptions -------------------------------*/
240
verifyOptions(void)241 static void verifyOptions(void)
242 {
243 CompileOptions mainOpts = { DEFAULT_MAX_BASE_SIZE, MAX_NAME_LENGTH,
244 MAX_PRIME_FACTORS,
245 MAX_REFINEMENT_PARMS, MAX_FAMILY_PARMS,
246 MAX_EXTRA, XLARGE, SGND, NFLT};
247 extern void xaddsge( CompileOptions *cOpts);
248 extern void xbitman( CompileOptions *cOpts);
249 extern void xccommu( CompileOptions *cOpts);
250 extern void xcopy ( CompileOptions *cOpts);
251 extern void xcstbor( CompileOptions *cOpts);
252 extern void xerrmes( CompileOptions *cOpts);
253 extern void xessent( CompileOptions *cOpts);
254 extern void xfactor( CompileOptions *cOpts);
255 extern void xnew ( CompileOptions *cOpts);
256 extern void xoldcop( CompileOptions *cOpts);
257 extern void xpermgr( CompileOptions *cOpts);
258 extern void xpermut( CompileOptions *cOpts);
259 extern void xprimes( CompileOptions *cOpts);
260 extern void xrandgr( CompileOptions *cOpts);
261 extern void xrandsc( CompileOptions *cOpts);
262 extern void xreadgr( CompileOptions *cOpts);
263 extern void xstorag( CompileOptions *cOpts);
264 extern void xtoken ( CompileOptions *cOpts);
265 extern void xutil ( CompileOptions *cOpts);
266
267 xaddsge( &mainOpts);
268 xbitman( &mainOpts);
269 xccommu( &mainOpts);
270 xcopy ( &mainOpts);
271 xcstbor( &mainOpts);
272 xerrmes( &mainOpts);
273 xessent( &mainOpts);
274 xfactor( &mainOpts);
275 xnew ( &mainOpts);
276 xoldcop( &mainOpts);
277 xpermgr( &mainOpts);
278 xpermut( &mainOpts);
279 xprimes( &mainOpts);
280 xrandgr( &mainOpts);
281 xrandsc( &mainOpts);
282 xreadgr( &mainOpts);
283 xstorag( &mainOpts);
284 xutil ( &mainOpts);
285 }
286
287
288
289