1 /****************************************************************************
2 **
3 *A  main.c                      ANUPQ source                   Eamonn O'Brien
4 **
5 *Y  Copyright 1995-2001,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
6 *Y  Copyright 1995-2001,  School of Mathematical Sciences, ANU,     Australia
7 **
8 */
9 
10 #include "pq_defs.h"
11 #include "pcp_vars.h"
12 #include "pq_functions.h"
13 #include "constants.h"
14 #include "pq_author.h"
15 #include "menus.h"
16 #include "global.h"
17 #include "standard.h"
18 
19 #if defined(RUN_TIME)
20 #include "runtime.h"
21 #endif
22 
23 /* main routine for p-quotient program; the run-time parameters are
24 
25    -b to choose basic format for input of presentation;
26    -G used by GAP 4, essentially equivalent to: -i -g -k simultaneously
27       except that it also sends requests back via GAP's iostream when
28       it needs GAP to compute stabilisers;
29    -g to write GAP group library and to run pq from within GAP;
30    -i to choose standard presentation menu;
31    -k to read from file using key words;
32    -s <integer> to allocate array of size <integer> for workspace y;
33    -t to pass time limit in CPU seconds for computation
34       where t = 0 implies infinite time;
35    -v prints the version of the pq binary and exits;
36    -w <filename> to write group descriptions in GAP format
37       to <filename> -- used in conjunction -g
38 
39    if compiled with RUN_TIME flag then there are two additional options:
40    -c to set class bound;
41    -d to set defining generator bound;
42 
43    if workspace not passed, the default size of y is the constant PQSPACE */
44 
45 int work_space = PQSPACE;
46 int format = PRETTY;
47 int menu = DEFAULT_MENU;
48 Logical StandardPresentation = FALSE;
49 Logical GAP4iostream = FALSE;
50 
main(int argc,char ** argv)51 int main(int argc, char **argv)
52 {
53    int t;
54    struct pcp_vars pcp;
55 #include "access.h"
56 
57    setbuf(stdout, NULL);
58 
59    Compact_Description = FALSE;
60 
61    /* process run-time parameters */
62    if (process_parameters(argc, argv) == 0) {
63 #if defined(RUN_TIME)
64       printf("Usage: pq [-b] [-c] [-d] [-G] [-g] [-i] [-k] [-s <integer>] [-v] "
65              "[-w <filename>]\n");
66 #else
67       printf("Usage: pq [-b] [-G] [-g] [-i] [-k] [-s <integer>] [-v] [-w "
68              "<filename>]\n");
69 #endif
70       exit(INPUT_ERROR);
71    }
72 
73    Allocate_WorkSpace(work_space, &pcp);
74 
75    /* print startup message */
76    print_message(work_space);
77 
78 #if defined(GROUP)
79 #if defined(STANDARD_PCP)
80    if (menu == ISOM_MENU)
81       isom_options(format, &pcp);
82    else
83 #endif
84 #endif
85       options(DEFAULT_MENU, format, &pcp);
86 
87    t = runTime();
88    printf("Total user time in seconds is %.2f\n", t * CLK_SCALE);
89 
90    exit(SUCCESS);
91 }
92 
93 /* process run-time parameters */
94 
process_parameters(int argc,char ** argv)95 int process_parameters(int argc, char **argv)
96 {
97    int i;
98    Logical error;
99 
100 #if defined(RUN_TIME)
101    int A1, A3;
102    A1 = 0;
103    A3 = 0;
104 #endif
105 
106    Group_library_file = NULL;
107 
108    for (i = 1; i < argc; ++i) {
109       if (strcmp(argv[i], "-s") == 0) {
110          if (i == argc - 1)
111             return (0);
112          work_space = string_to_int(argv[++i], &error);
113          if (error)
114             return (0);
115       } else if (strcmp(argv[i], "-w") == 0) {
116          if (i == argc - 1 || argv[++i][0] == '-')
117             return (0);
118          Group_library_file = allocate_char_vector(strlen(argv[i]), 0, FALSE);
119          strcpy(Group_library_file, argv[i]);
120       } else if (strcmp(argv[i], "-b") == 0)
121          format = BASIC;
122 #if defined(RUN_TIME)
123       else if (strcmp(argv[i], "-d") == 0) {
124          if (i == argc - 1)
125             return (0);
126          A1 = string_to_int(argv[++i], &error);
127          if (error)
128             return (0);
129       } else if (strcmp(argv[i], "-c") == 0) {
130          if (i == argc - 1)
131             return (0);
132          A3 = string_to_int(argv[++i], &error);
133          if (error)
134             return (0);
135       }
136 #endif
137 #if defined(STANDARD_PCP)
138       else if (strcmp(argv[i], "-i") == 0)
139          menu = ISOM_MENU;
140 #endif
141       else if (strcmp(argv[i], "-k") == 0)
142          format = FILE_INPUT;
143       else if (strcmp(argv[i], "-G") == 0) {
144          Group_library = GAP_LIBRARY;
145          menu = ISOM_MENU;
146          format = FILE_INPUT;
147          GAP4iostream = TRUE;
148       } else if (strcmp(argv[i], "-g") == 0)
149          Group_library = GAP_LIBRARY;
150       else if (strcmp(argv[i], "-v") == 0) {
151          printf("%s\n", PQ_VERSION);
152          exit(SUCCESS);
153       } else
154          return (0);
155    }
156 
157 #if defined(RUN_TIME)
158    ExamineOptions(A1, A3);
159 #endif
160 
161 #if defined(GAP)
162    CreateGAPLibraryFile();
163 #endif
164 
165    return 1;
166 }
167 
168 #if defined(RUN_TIME)
169 
170 /* how many bits are needed to store x? */
171 
NmrOfBits(int x)172 int NmrOfBits(int x)
173 {
174    int nmr = 0;
175    while (x >= 1) {
176       x = x >> 1;
177       ++nmr;
178    }
179    return nmr;
180 }
181 
ExamineOptions(int A1,int A3)182 int ExamineOptions(int A1, int A3)
183 {
184    if (A1 == 0 && A3 == 0)
185       return;
186 
187    if (A1 <= 0 || A3 <= 0) {
188       printf("You must supply positive values for each of -d and -c\n");
189       exit(INPUT_ERROR);
190    }
191 
192    A1 = NmrOfBits(A1);
193    A3 = NmrOfBits(A3);
194 
195    if (A1 + A3 >= WORD_LENGTH) {
196       printf("Product of the values for -d and -c must need at most %d bits\n",
197              WORD_LENGTH - 1);
198       exit(INPUT_ERROR);
199    }
200 
201    GSC1 = A1;
202    GSC2 = WORD_LENGTH - (A1 + A3);
203 
204    MAXGENS = int_power(2, GSC1) - 1;
205    MAXPC = int_power(2, GSC2) - 1;
206    MAXCLASS = int_power(2, A3) - 1;
207 
208    printf("********************************************\n");
209    printf("Program now uses the following bounds:\n");
210    printf("Number of defining generators: %d\n", MAXGENS);
211    printf("Number of pc generators: %d\n", MAXPC);
212    printf("Class bound: %d\n", MAXCLASS);
213    printf("********************************************\n");
214 }
215 
216 #endif
217 
218 #if defined(GAP)
219 
220 /* if pq is called successfully from GAP, we want GAP_library file to exist
221    in all cases, even if no group descriptions have been saved to it */
222 
CreateGAPLibraryFile(void)223 void CreateGAPLibraryFile(void)
224 {
225    FILE *GAP_library;
226 
227    if (Group_library == GAP_LIBRARY) {
228       if (Group_library_file == NULL)
229          Group_library_file = "GAP_library";
230       GAP_library = OpenFile(Group_library_file, "a+");
231       fprintf(GAP_library, "ANUPQmagic := \"groups saved to file\";\n");
232       CloseFile(GAP_library);
233    }
234 }
235 
236 #endif
237