00026 {
00027 int i, j, first, last, strategy, out_type, option;
00028 pPLA PLA, PLA1;
00029 pcover F, Fold, Dold;
00030 pset last1, p;
00031 cost_t cost;
00032 bool error, exact_cover;
00033 long start;
00034 extern char *util_optarg;
00035 extern int util_optind;
00036
00037 start = ptime();
00038
00039 error = FALSE;
00040 init_runtime();
00041 #ifdef RANDOM
00042 srandom(314973);
00043 #endif
00044
00045 option = 0;
00046 out_type = F_type;
00047 debug = 0;
00048 verbose_debug = FALSE;
00049 print_solution = TRUE;
00050 summary = FALSE;
00051 trace = FALSE;
00052 strategy = 0;
00053 first = -1;
00054 last = -1;
00055 remove_essential = TRUE;
00056 force_irredundant = TRUE;
00057 unwrap_onset = TRUE;
00058 single_expand = FALSE;
00059 pos = FALSE;
00060 recompute_onset = FALSE;
00061 use_super_gasp = FALSE;
00062 use_random_order = FALSE;
00063 kiss = FALSE;
00064 echo_comments = TRUE;
00065 echo_unknown_commands = TRUE;
00066 exact_cover = FALSE;
00067
00068 backward_compatibility_hack(&argc, argv, &option, &out_type);
00069
00070
00071
00072 while ((i = util_getopt(argc, argv, "D:S:de:o:r:stv:x")) != EOF) {
00073 switch(i) {
00074 case 'D':
00075 for(j = 0; option_table[j].name != 0; j++) {
00076 if (strcmp(util_optarg, option_table[j].name) == 0) {
00077 option = j;
00078 break;
00079 }
00080 }
00081 if (option_table[j].name == 0) {
00082 (void) fprintf(stderr, "%s: bad subcommand \"%s\"\n",
00083 argv[0], util_optarg);
00084 exit(1);
00085 }
00086 break;
00087
00088 case 'o':
00089 for(j = 0; pla_types[j].key != 0; j++) {
00090 if (strcmp(util_optarg, pla_types[j].key+1) == 0) {
00091 out_type = pla_types[j].value;
00092 break;
00093 }
00094 }
00095 if (pla_types[j].key == 0) {
00096 (void) fprintf(stderr, "%s: bad output type \"%s\"\n",
00097 argv[0], util_optarg);
00098 exit(1);
00099 }
00100 break;
00101
00102 case 'e':
00103 for(j = 0; esp_opt_table[j].name != 0; j++) {
00104 if (strcmp(util_optarg, esp_opt_table[j].name) == 0) {
00105 *(esp_opt_table[j].variable) = esp_opt_table[j].value;
00106 break;
00107 }
00108 }
00109 if (esp_opt_table[j].name == 0) {
00110 (void) fprintf(stderr, "%s: bad espresso option \"%s\"\n",
00111 argv[0], util_optarg);
00112 exit(1);
00113 }
00114 break;
00115
00116 case 'd':
00117 debug = debug_table[0].value;
00118 trace = TRUE;
00119 summary = TRUE;
00120 break;
00121
00122 case 'v':
00123 verbose_debug = TRUE;
00124 for(j = 0; debug_table[j].name != 0; j++) {
00125 if (strcmp(util_optarg, debug_table[j].name) == 0) {
00126 debug |= debug_table[j].value;
00127 break;
00128 }
00129 }
00130 if (debug_table[j].name == 0) {
00131 (void) fprintf(stderr, "%s: bad debug type \"%s\"\n",
00132 argv[0], util_optarg);
00133 exit(1);
00134 }
00135 break;
00136
00137 case 't':
00138 trace = TRUE;
00139 break;
00140
00141 case 's':
00142 summary = TRUE;
00143 break;
00144
00145 case 'x':
00146 print_solution = FALSE;
00147 break;
00148
00149 case 'S':
00150 strategy = atoi(util_optarg);
00151 break;
00152
00153 case 'r':
00154 if (sscanf(util_optarg, "%d-%d", &first, &last) < 2) {
00155 (void) fprintf(stderr, "%s: bad output range \"%s\"\n",
00156 argv[0], util_optarg);
00157 exit(1);
00158 }
00159 break;
00160
00161 default:
00162 usage();
00163 exit(1);
00164 }
00165 }
00166
00167
00168 if (summary || trace) {
00169
00170 printf("#");
00171 for(i = 0; i < argc; i++) {
00172 printf(" %s", argv[i]);
00173 }
00174 printf("\n");
00175 printf("# %s\n", VERSION);
00176 }
00177
00178
00179 PLA = PLA1 = NIL(PLA_t);
00180 switch(option_table[option].num_plas) {
00181 case 2:
00182 if (util_optind+2 < argc) fatal("trailing arguments on command line");
00183 getPLA(util_optind++, argc, argv, option, &PLA, out_type);
00184 getPLA(util_optind++, argc, argv, option, &PLA1, out_type);
00185 break;
00186 case 1:
00187 if (util_optind+1 < argc) fatal("trailing arguments on command line");
00188 getPLA(util_optind++, argc, argv, option, &PLA, out_type);
00189 break;
00190 }
00191 if (util_optind < argc) fatal("trailing arguments on command line");
00192
00193 if (summary || trace) {
00194 if (PLA != NIL(PLA_t)) PLA_summary(PLA);
00195 if (PLA1 != NIL(PLA_t)) PLA_summary(PLA1);
00196 }
00197
00198
00199
00200
00201
00202 switch(option_table[option].key) {
00203
00204
00205
00206
00207 case KEY_ESPRESSO:
00208 Fold = sf_save(PLA->F);
00209 PLA->F = espresso(PLA->F, PLA->D, PLA->R);
00210 EXECUTE(error=verify(PLA->F,Fold,PLA->D), VERIFY_TIME, PLA->F, cost);
00211 if (error) {
00212 print_solution = FALSE;
00213 PLA->F = Fold;
00214 (void) check_consistency(PLA);
00215 } else {
00216 free_cover(Fold);
00217 }
00218 break;
00219
00220 case KEY_MANY_ESPRESSO: {
00221 int pla_type;
00222 do {
00223 EXEC(PLA->F=espresso(PLA->F,PLA->D,PLA->R),"ESPRESSO ",PLA->F);
00224 if (print_solution) {
00225 fprint_pla(stdout, PLA, out_type);
00226 (void) fflush(stdout);
00227 }
00228 pla_type = PLA->pla_type;
00229 free_PLA(PLA);
00230 setdown_cube();
00231 FREE(cube.part_size);
00232 } while (read_pla(last_fp, TRUE, TRUE, pla_type, &PLA) != EOF);
00233 exit(0);
00234 }
00235
00236 case KEY_simplify:
00237 EXEC(PLA->F = simplify(cube1list(PLA->F)), "SIMPLIFY ", PLA->F);
00238 break;
00239
00240 case KEY_so:
00241 if (strategy < 0 || strategy > 1) {
00242 strategy = 0;
00243 }
00244 so_espresso(PLA, strategy);
00245 break;
00246
00247 case KEY_so_both:
00248 if (strategy < 0 || strategy > 1) {
00249 strategy = 0;
00250 }
00251 so_both_espresso(PLA, strategy);
00252 break;
00253
00254 case KEY_expand:
00255 EXECUTE(PLA->F=expand(PLA->F,PLA->R,FALSE),EXPAND_TIME, PLA->F, cost);
00256 break;
00257
00258 case KEY_irred:
00259 EXECUTE(PLA->F = irredundant(PLA->F, PLA->D), IRRED_TIME, PLA->F, cost);
00260 break;
00261
00262 case KEY_reduce:
00263 EXECUTE(PLA->F = reduce(PLA->F, PLA->D), REDUCE_TIME, PLA->F, cost);
00264 break;
00265
00266 case KEY_essen:
00267 foreach_set(PLA->F, last1, p) {
00268 SET(p, RELESSEN);
00269 RESET(p, NONESSEN);
00270 }
00271 EXECUTE(F = essential(&(PLA->F), &(PLA->D)), ESSEN_TIME, PLA->F, cost);
00272 free_cover(F);
00273 break;
00274
00275 case KEY_super_gasp:
00276 PLA->F = super_gasp(PLA->F, PLA->D, PLA->R, &cost);
00277 break;
00278
00279 case KEY_gasp:
00280 PLA->F = last_gasp(PLA->F, PLA->D, PLA->R, &cost);
00281 break;
00282
00283 case KEY_make_sparse:
00284 PLA->F = make_sparse(PLA->F, PLA->D, PLA->R);
00285 break;
00286
00287 case KEY_exact:
00288 exact_cover = TRUE;
00289
00290 case KEY_qm:
00291 Fold = sf_save(PLA->F);
00292 PLA->F = minimize_exact(PLA->F, PLA->D, PLA->R, exact_cover);
00293 EXECUTE(error=verify(PLA->F,Fold,PLA->D), VERIFY_TIME, PLA->F, cost);
00294 if (error) {
00295 print_solution = FALSE;
00296 PLA->F = Fold;
00297 (void) check_consistency(PLA);
00298 }
00299 free_cover(Fold);
00300 break;
00301
00302 case KEY_primes:
00303 EXEC(PLA->F = primes_consensus(cube2list(PLA->F, PLA->D)),
00304 "PRIMES ", PLA->F);
00305 break;
00306
00307 case KEY_map:
00308 map(PLA->F);
00309 print_solution = FALSE;
00310 break;
00311
00312
00313
00314
00315
00316 case KEY_opo:
00317 phase_assignment(PLA, strategy);
00318 break;
00319
00320 case KEY_opoall:
00321 if (first < 0 || first >= cube.part_size[cube.output]) {
00322 first = 0;
00323 }
00324 if (last < 0 || last >= cube.part_size[cube.output]) {
00325 last = cube.part_size[cube.output] - 1;
00326 }
00327 opoall(PLA, first, last, strategy);
00328 break;
00329
00330 case KEY_pair:
00331 find_optimal_pairing(PLA, strategy);
00332 break;
00333
00334 case KEY_pairall:
00335 pair_all(PLA, strategy);
00336 break;
00337
00338
00339
00340
00341
00342 case KEY_echo:
00343 break;
00344
00345 case KEY_taut:
00346 printf("ON-set is%sa tautology\n",
00347 tautology(cube1list(PLA->F)) ? " " : " not ");
00348 print_solution = FALSE;
00349 break;
00350
00351 case KEY_contain:
00352 PLA->F = sf_contain(PLA->F);
00353 break;
00354
00355 case KEY_intersect:
00356 PLA->F = cv_intersect(PLA->F, PLA1->F);
00357 break;
00358
00359 case KEY_union:
00360 PLA->F = sf_union(PLA->F, PLA1->F);
00361 break;
00362
00363 case KEY_disjoint:
00364 PLA->F = make_disjoint(PLA->F);
00365 break;
00366
00367 case KEY_dsharp:
00368 PLA->F = cv_dsharp(PLA->F, PLA1->F);
00369 break;
00370
00371 case KEY_sharp:
00372 PLA->F = cv_sharp(PLA->F, PLA1->F);
00373 break;
00374
00375 case KEY_lexsort:
00376 PLA->F = lex_sort(PLA->F);
00377 break;
00378
00379 case KEY_stats:
00380 if (! summary) PLA_summary(PLA);
00381 print_solution = FALSE;
00382 break;
00383
00384 case KEY_minterms:
00385 if (first < 0 || first >= cube.num_vars) {
00386 first = 0;
00387 }
00388 if (last < 0 || last >= cube.num_vars) {
00389 last = cube.num_vars - 1;
00390 }
00391 PLA->F = sf_dupl(unravel_range(PLA->F, first, last));
00392 break;
00393
00394 case KEY_d1merge:
00395 if (first < 0 || first >= cube.num_vars) {
00396 first = 0;
00397 }
00398 if (last < 0 || last >= cube.num_vars) {
00399 last = cube.num_vars - 1;
00400 }
00401 for(i = first; i <= last; i++) {
00402 PLA->F = d1merge(PLA->F, i);
00403 }
00404 break;
00405
00406 case KEY_d1merge_in:
00407 for(i = 0; i < cube.num_binary_vars; i++) {
00408 PLA->F = d1merge(PLA->F, i);
00409 }
00410 break;
00411
00412 case KEY_PLA_verify:
00413 EXECUTE(error = PLA_verify(PLA, PLA1), VERIFY_TIME, PLA->F, cost);
00414 if (error) {
00415 printf("PLA comparison failed; the PLA's are not equivalent\n");
00416 exit(1);
00417 } else {
00418 printf("PLA's compared equal\n");
00419 exit(0);
00420 }
00421 break;
00422
00423 case KEY_verify:
00424 Fold = PLA->F; Dold = PLA->D; F = PLA1->F;
00425 EXECUTE(error=verify(F, Fold, Dold), VERIFY_TIME, PLA->F, cost);
00426 if (error) {
00427 printf("PLA comparison failed; the PLA's are not equivalent\n");
00428 exit(1);
00429 } else {
00430 printf("PLA's compared equal\n");
00431 exit(0);
00432 }
00433 break;
00434
00435 case KEY_check:
00436 (void) check_consistency(PLA);
00437 print_solution = FALSE;
00438 break;
00439
00440 case KEY_mapdc:
00441 map_dcset(PLA);
00442 out_type = FD_type;
00443 break;
00444
00445 case KEY_equiv:
00446 find_equiv_outputs(PLA);
00447 print_solution = FALSE;
00448 break;
00449
00450 case KEY_separate:
00451 PLA->F = complement(cube2list(PLA->D, PLA->R));
00452 break;
00453
00454 case KEY_xor: {
00455 pcover T1 = cv_intersect(PLA->F, PLA1->R);
00456 pcover T2 = cv_intersect(PLA1->F, PLA->R);
00457 free_cover(PLA->F);
00458 PLA->F = sf_contain(sf_join(T1, T2));
00459 free_cover(T1);
00460 free_cover(T2);
00461 break;
00462 }
00463
00464 case KEY_fsm: {
00465 disassemble_fsm(PLA, summary);
00466 print_solution = FALSE;
00467 break;
00468 }
00469
00470 case KEY_test: {
00471 pcover T, E;
00472 T = sf_join(PLA->D, PLA->R);
00473 E = new_cover(10);
00474 sf_free(PLA->F);
00475 EXECUTE(PLA->F = complement(cube1list(T)), COMPL_TIME, PLA->F, cost);
00476 EXECUTE(PLA->F = expand(PLA->F, T, FALSE), EXPAND_TIME, PLA->F, cost);
00477 EXECUTE(PLA->F = irredundant(PLA->F, E), IRRED_TIME, PLA->F, cost);
00478 sf_free(T);
00479 T = sf_join(PLA->F, PLA->R);
00480 EXECUTE(PLA->D = expand(PLA->D, T, FALSE), EXPAND_TIME, PLA->D, cost);
00481 EXECUTE(PLA->D = irredundant(PLA->D, E), IRRED_TIME, PLA->D, cost);
00482 sf_free(T);
00483 sf_free(E);
00484 break;
00485 }
00486
00487
00488 }
00489
00490
00491 if (trace) {
00492 runtime();
00493 }
00494
00495
00496 if (summary || trace) {
00497 print_trace(PLA->F, option_table[option].name, ptime()-start);
00498 }
00499
00500
00501 if (print_solution) {
00502 EXECUTE(fprint_pla(stdout, PLA, out_type), WRITE_TIME, PLA->F, cost);
00503 }
00504
00505
00506 if (error) {
00507 fatal("cover verification failed");
00508 }
00509
00510
00511 free_PLA(PLA);
00512 FREE(cube.part_size);
00513 setdown_cube();
00514 sf_cleanup();
00515 sm_cleanup();
00516
00517 exit(0);
00518 }