00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "espresso.h"
00016
00017 void fprint_pla(fp, PLA, output_type)
00018 INOUT FILE *fp;
00019 IN pPLA PLA;
00020 IN int output_type;
00021 {
00022 int num;
00023 register pcube last, p;
00024
00025 if ((output_type & CONSTRAINTS_type) != 0) {
00026 output_symbolic_constraints(fp, PLA, 0);
00027 output_type &= ~ CONSTRAINTS_type;
00028 if (output_type == 0) {
00029 return;
00030 }
00031 }
00032
00033 if ((output_type & SYMBOLIC_CONSTRAINTS_type) != 0) {
00034 output_symbolic_constraints(fp, PLA, 1);
00035 output_type &= ~ SYMBOLIC_CONSTRAINTS_type;
00036 if (output_type == 0) {
00037 return;
00038 }
00039 }
00040
00041 if (output_type == PLEASURE_type) {
00042 pls_output(PLA);
00043 } else if (output_type == EQNTOTT_type) {
00044 eqn_output(PLA);
00045 } else if (output_type == KISS_type) {
00046 kiss_output(fp, PLA);
00047 } else {
00048 fpr_header(fp, PLA, output_type);
00049
00050 num = 0;
00051 if (output_type & F_type) num += (PLA->F)->count;
00052 if (output_type & D_type) num += (PLA->D)->count;
00053 if (output_type & R_type) num += (PLA->R)->count;
00054 (void) fprintf(fp, ".p %d\n", num);
00055
00056
00057 if (output_type == F_type) {
00058 foreach_set(PLA->F, last, p) {
00059 print_cube(fp, p, "01");
00060 }
00061 (void) fprintf(fp, ".e\n");
00062 } else {
00063 if (output_type & F_type) {
00064 foreach_set(PLA->F, last, p) {
00065 print_cube(fp, p, "~1");
00066 }
00067 }
00068 if (output_type & D_type) {
00069 foreach_set(PLA->D, last, p) {
00070 print_cube(fp, p, "~2");
00071 }
00072 }
00073 if (output_type & R_type) {
00074 foreach_set(PLA->R, last, p) {
00075 print_cube(fp, p, "~0");
00076 }
00077 }
00078 (void) fprintf(fp, ".end\n");
00079 }
00080 }
00081 }
00082
00083 void fpr_header(fp, PLA, output_type)
00084 FILE *fp;
00085 pPLA PLA;
00086 int output_type;
00087 {
00088 register int i, var;
00089 int first, last;
00090
00091
00092 if (output_type != F_type) {
00093 (void) fprintf(fp, ".type ");
00094 if (output_type & F_type) putc('f', fp);
00095 if (output_type & D_type) putc('d', fp);
00096 if (output_type & R_type) putc('r', fp);
00097 putc('\n', fp);
00098 }
00099
00100
00101 if (cube.num_mv_vars <= 1) {
00102 (void) fprintf(fp, ".i %d\n", cube.num_binary_vars);
00103 if (cube.output != -1)
00104 (void) fprintf(fp, ".o %d\n", cube.part_size[cube.output]);
00105 } else {
00106 (void) fprintf(fp, ".mv %d %d", cube.num_vars, cube.num_binary_vars);
00107 for(var = cube.num_binary_vars; var < cube.num_vars; var++)
00108 (void) fprintf(fp, " %d", cube.part_size[var]);
00109 (void) fprintf(fp, "\n");
00110 }
00111
00112
00113 if (PLA->label != NIL(char *) && PLA->label[1] != NIL(char)
00114 && cube.num_binary_vars > 0) {
00115 (void) fprintf(fp, ".ilb");
00116 for(var = 0; var < cube.num_binary_vars; var++)
00117
00118 if(INLABEL(var) == NIL(char)){
00119 (void) fprintf(fp, " (null)");
00120 }
00121 else{
00122 (void) fprintf(fp, " %s", INLABEL(var));
00123 }
00124 putc('\n', fp);
00125 }
00126
00127
00128 if (PLA->label != NIL(char *) &&
00129 PLA->label[cube.first_part[cube.output]] != NIL(char)
00130 && cube.output != -1) {
00131 (void) fprintf(fp, ".ob");
00132 for(i = 0; i < cube.part_size[cube.output]; i++)
00133
00134 if(OUTLABEL(i) == NIL(char)){
00135 (void) fprintf(fp, " (null)");
00136 }
00137 else{
00138 (void) fprintf(fp, " %s", OUTLABEL(i));
00139 }
00140 putc('\n', fp);
00141 }
00142
00143
00144 for(var = cube.num_binary_vars; var < cube.num_vars-1; var++) {
00145 first = cube.first_part[var];
00146 last = cube.last_part[var];
00147 if (PLA->label != NULL && PLA->label[first] != NULL) {
00148 (void) fprintf(fp, ".label var=%d", var);
00149 for(i = first; i <= last; i++) {
00150 (void) fprintf(fp, " %s", PLA->label[i]);
00151 }
00152 putc('\n', fp);
00153 }
00154 }
00155
00156 if (PLA->phase != (pcube) NULL) {
00157 first = cube.first_part[cube.output];
00158 last = cube.last_part[cube.output];
00159 (void) fprintf(fp, "#.phase ");
00160 for(i = first; i <= last; i++)
00161 putc(is_in_set(PLA->phase,i) ? '1' : '0', fp);
00162 (void) fprintf(fp, "\n");
00163 }
00164 }
00165
00166 void pls_output(PLA)
00167 IN pPLA PLA;
00168 {
00169 register pcube last, p;
00170
00171 (void) printf(".option unmerged\n");
00172 makeup_labels(PLA);
00173 pls_label(PLA, stdout);
00174 pls_group(PLA, stdout);
00175 (void) printf(".p %d\n", PLA->F->count);
00176 foreach_set(PLA->F, last, p) {
00177 print_expanded_cube(stdout, p, PLA->phase);
00178 }
00179 (void) printf(".end\n");
00180 }
00181
00182
00183 void pls_group(PLA, fp)
00184 pPLA PLA;
00185 FILE *fp;
00186 {
00187 int var, i, col, len;
00188
00189 (void) fprintf(fp, "\n.group");
00190 col = 6;
00191 for(var = 0; var < cube.num_vars-1; var++) {
00192 (void) fprintf(fp, " ("), col += 2;
00193 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00194 len = strlen(PLA->label[i]);
00195 if (col + len > 75)
00196 (void) fprintf(fp, " \\\n"), col = 0;
00197 else if (i != 0)
00198 putc(' ', fp), col += 1;
00199 (void) fprintf(fp, "%s", PLA->label[i]), col += len;
00200 }
00201 (void) fprintf(fp, ")"), col += 1;
00202 }
00203 (void) fprintf(fp, "\n");
00204 }
00205
00206
00207 void pls_label(PLA, fp)
00208 pPLA PLA;
00209 FILE *fp;
00210 {
00211 int var, i, col, len;
00212
00213 (void) fprintf(fp, ".label");
00214 col = 6;
00215 for(var = 0; var < cube.num_vars; var++)
00216 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00217 len = strlen(PLA->label[i]);
00218 if (col + len > 75)
00219 (void) fprintf(fp, " \\\n"), col = 0;
00220 else
00221 putc(' ', fp), col += 1;
00222 (void) fprintf(fp, "%s", PLA->label[i]), col += len;
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231 void eqn_output(PLA)
00232 pPLA PLA;
00233 {
00234 register pcube p, last;
00235 register int i, var, col, len;
00236 int x;
00237 bool firstand, firstor;
00238
00239 if (cube.output == -1)
00240 fatal("Cannot have no-output function for EQNTOTT output mode");
00241 if (cube.num_mv_vars != 1)
00242 fatal("Must have binary-valued function for EQNTOTT output mode");
00243 makeup_labels(PLA);
00244
00245
00246 for(i = 0; i < cube.part_size[cube.output]; i++) {
00247 (void) printf("%s = ", OUTLABEL(i));
00248 col = strlen(OUTLABEL(i)) + 3;
00249 firstor = TRUE;
00250
00251
00252 foreach_set(PLA->F, last, p)
00253 if (is_in_set(p, i + cube.first_part[cube.output])) {
00254 if (firstor)
00255 (void) printf("("), col += 1;
00256 else
00257 (void) printf(" | ("), col += 4;
00258 firstor = FALSE;
00259 firstand = TRUE;
00260
00261
00262 for(var = 0; var < cube.num_binary_vars; var++)
00263 if ((x=GETINPUT(p, var)) != DASH) {
00264 len = strlen(INLABEL(var));
00265 if (col+len > 72)
00266 (void) printf("\n "), col = 4;
00267 if (! firstand)
00268 (void) printf("&"), col += 1;
00269 firstand = FALSE;
00270 if (x == ZERO)
00271 (void) printf("!"), col += 1;
00272 (void) printf("%s", INLABEL(var)), col += len;
00273 }
00274 (void) printf(")"), col += 1;
00275 }
00276 (void) printf(";\n\n");
00277 }
00278 }
00279
00280
00281 char *fmt_cube(c, out_map, s)
00282 register pcube c;
00283 register char *out_map, *s;
00284 {
00285 register int i, var, last, len = 0;
00286
00287 for(var = 0; var < cube.num_binary_vars; var++) {
00288 s[len++] = "?01-" [GETINPUT(c, var)];
00289 }
00290 for(var = cube.num_binary_vars; var < cube.num_vars - 1; var++) {
00291 s[len++] = ' ';
00292 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00293 s[len++] = "01" [is_in_set(c, i) != 0];
00294 }
00295 }
00296 if (cube.output != -1) {
00297 last = cube.last_part[cube.output];
00298 s[len++] = ' ';
00299 for(i = cube.first_part[cube.output]; i <= last; i++) {
00300 s[len++] = out_map [is_in_set(c, i) != 0];
00301 }
00302 }
00303 s[len] = '\0';
00304 return s;
00305 }
00306
00307
00308 void print_cube(fp, c, out_map)
00309 register FILE *fp;
00310 register pcube c;
00311 register char *out_map;
00312 {
00313 register int i, var, ch;
00314 int last;
00315
00316 for(var = 0; var < cube.num_binary_vars; var++) {
00317 ch = "?01-" [GETINPUT(c, var)];
00318 putc(ch, fp);
00319 }
00320 for(var = cube.num_binary_vars; var < cube.num_vars - 1; var++) {
00321 putc(' ', fp);
00322 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00323 ch = "01" [is_in_set(c, i) != 0];
00324 putc(ch, fp);
00325 }
00326 }
00327 if (cube.output != -1) {
00328 last = cube.last_part[cube.output];
00329 putc(' ', fp);
00330 for(i = cube.first_part[cube.output]; i <= last; i++) {
00331 ch = out_map [is_in_set(c, i) != 0];
00332 putc(ch, fp);
00333 }
00334 }
00335 putc('\n', fp);
00336 }
00337
00338
00339 void print_expanded_cube(fp, c, phase)
00340 register FILE *fp;
00341 register pcube c;
00342 pcube phase;
00343 {
00344 register int i, var, ch;
00345 char *out_map;
00346
00347 for(var = 0; var < cube.num_binary_vars; var++) {
00348 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00349 ch = "~1" [is_in_set(c, i) != 0];
00350 putc(ch, fp);
00351 }
00352 }
00353 for(var = cube.num_binary_vars; var < cube.num_vars - 1; var++) {
00354 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00355 ch = "1~" [is_in_set(c, i) != 0];
00356 putc(ch, fp);
00357 }
00358 }
00359 if (cube.output != -1) {
00360 var = cube.num_vars - 1;
00361 putc(' ', fp);
00362 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00363 if (phase == (pcube) NULL || is_in_set(phase, i)) {
00364 out_map = "~1";
00365 } else {
00366 out_map = "~0";
00367 }
00368 ch = out_map[is_in_set(c, i) != 0];
00369 putc(ch, fp);
00370 }
00371 }
00372 putc('\n', fp);
00373 }
00374
00375
00376 char *pc1(c) pcube c;
00377 {static char s1[256];return fmt_cube(c, "01", s1);}
00378 char *pc2(c) pcube c;
00379 {static char s2[256];return fmt_cube(c, "01", s2);}
00380
00381
00382 void debug_print(T, name, level)
00383 pcube *T;
00384 char *name;
00385 int level;
00386 {
00387 register pcube *T1, p, temp;
00388 register int cnt;
00389
00390 cnt = CUBELISTSIZE(T);
00391 temp = new_cube();
00392 if (verbose_debug && level == 0)
00393 (void) printf("\n");
00394 (void) printf("%s[%d]: ord(T)=%d\n", name, level, cnt);
00395 if (verbose_debug) {
00396 (void) printf("cofactor=%s\n", pc1(T[0]));
00397 for(T1 = T+2, cnt = 1; (p = *T1++) != (pcube) NULL; cnt++)
00398 (void) printf("%4d. %s\n", cnt, pc1(set_or(temp, p, T[0])));
00399 }
00400 free_cube(temp);
00401 }
00402
00403
00404 void debug1_print(T, name, num)
00405 pcover T;
00406 char *name;
00407 int num;
00408 {
00409 register int cnt = 1;
00410 register pcube p, last;
00411
00412 if (verbose_debug && num == 0)
00413 (void) printf("\n");
00414 (void) printf("%s[%d]: ord(T)=%d\n", name, num, T->count);
00415 if (verbose_debug)
00416 foreach_set(T, last, p)
00417 (void) printf("%4d. %s\n", cnt++, pc1(p));
00418 }
00419
00420
00421 void cprint(T)
00422 pcover T;
00423 {
00424 register pcube p, last;
00425
00426 foreach_set(T, last, p)
00427 (void) printf("%s\n", pc1(p));
00428 }
00429
00430
00431 int makeup_labels(PLA)
00432 pPLA PLA;
00433 {
00434 int var, i, ind;
00435
00436 if (PLA->label == (char **) NULL)
00437 PLA_labels(PLA);
00438
00439 for(var = 0; var < cube.num_vars; var++)
00440 for(i = 0; i < cube.part_size[var]; i++) {
00441 ind = cube.first_part[var] + i;
00442 if (PLA->label[ind] == (char *) NULL) {
00443 PLA->label[ind] = ALLOC(char, 15);
00444 if (var < cube.num_binary_vars)
00445 if ((i % 2) == 0)
00446 (void) sprintf(PLA->label[ind], "v%d.bar", var);
00447 else
00448 (void) sprintf(PLA->label[ind], "v%d", var);
00449 else
00450 (void) sprintf(PLA->label[ind], "v%d.%d", var, i);
00451 }
00452 }
00453 }
00454
00455
00456 kiss_output(fp, PLA)
00457 FILE *fp;
00458 pPLA PLA;
00459 {
00460 register pset last, p;
00461
00462 foreach_set(PLA->F, last, p) {
00463 kiss_print_cube(fp, PLA, p, "~1");
00464 }
00465 foreach_set(PLA->D, last, p) {
00466 kiss_print_cube(fp, PLA, p, "~2");
00467 }
00468 }
00469
00470
00471 kiss_print_cube(fp, PLA, p, out_string)
00472 FILE *fp;
00473 pPLA PLA;
00474 pcube p;
00475 char *out_string;
00476 {
00477 register int i, var;
00478 int part, x;
00479
00480 for(var = 0; var < cube.num_binary_vars; var++) {
00481 x = "?01-" [GETINPUT(p, var)];
00482 putc(x, fp);
00483 }
00484
00485 for(var = cube.num_binary_vars; var < cube.num_vars - 1; var++) {
00486 putc(' ', fp);
00487 if (setp_implies(cube.var_mask[var], p)) {
00488 putc('-', fp);
00489 } else {
00490 part = -1;
00491 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00492 if (is_in_set(p, i)) {
00493 if (part != -1) {
00494 fatal("more than 1 part in a symbolic variable\n");
00495 }
00496 part = i;
00497 }
00498 }
00499 if (part == -1) {
00500 putc('~', fp);
00501 } else {
00502 (void) fputs(PLA->label[part], fp);
00503 }
00504 }
00505 }
00506
00507 if ((var = cube.output) != -1) {
00508 putc(' ', fp);
00509 for(i = cube.first_part[var]; i <= cube.last_part[var]; i++) {
00510 x = out_string [is_in_set(p, i) != 0];
00511 putc(x, fp);
00512 }
00513 }
00514
00515 putc('\n', fp);
00516 }
00517
00518 output_symbolic_constraints(fp, PLA, output_symbolic)
00519 FILE *fp;
00520 pPLA PLA;
00521 int output_symbolic;
00522 {
00523 pset_family A;
00524 register int i, j;
00525 int size, var, npermute, *permute, *weight, noweight;
00526
00527 if ((cube.num_vars - cube.num_binary_vars) <= 1) {
00528 return;
00529 }
00530 makeup_labels(PLA);
00531
00532 for(var=cube.num_binary_vars; var < cube.num_vars-1; var++) {
00533
00534
00535 npermute = cube.part_size[var];
00536 permute = ALLOC(int, npermute);
00537 for(i=0; i < npermute; i++) {
00538 permute[i] = cube.first_part[var] + i;
00539 }
00540 A = sf_permute(sf_save(PLA->F), permute, npermute);
00541 FREE(permute);
00542
00543
00544
00545 noweight = 0;
00546 for(i = 0; i < A->count; i++) {
00547 size = set_ord(GETSET(A,i));
00548 if (size == 1 || size == A->sf_size) {
00549 sf_delset(A, i--);
00550 noweight++;
00551 }
00552 }
00553
00554
00555
00556 weight = ALLOC(int, A->count);
00557 for(i = 0; i < A->count; i++) {
00558 RESET(GETSET(A, i), COVERED);
00559 }
00560 for(i = 0; i < A->count; i++) {
00561 weight[i] = 0;
00562 if (! TESTP(GETSET(A,i), COVERED)) {
00563 weight[i] = 1;
00564 for(j = i+1; j < A->count; j++) {
00565 if (setp_equal(GETSET(A,i), GETSET(A,j))) {
00566 weight[i]++;
00567 SET(GETSET(A,j), COVERED);
00568 }
00569 }
00570 }
00571 }
00572
00573
00574
00575 if (! output_symbolic) {
00576 (void) fprintf(fp,
00577 "# Symbolic constraints for variable %d (Numeric form)\n", var);
00578 (void) fprintf(fp, "# unconstrained weight = %d\n", noweight);
00579 (void) fprintf(fp, "num_codes=%d\n", cube.part_size[var]);
00580 for(i = 0; i < A->count; i++) {
00581 if (weight[i] > 0) {
00582 (void) fprintf(fp, "weight=%d: ", weight[i]);
00583 for(j = 0; j < A->sf_size; j++) {
00584 if (is_in_set(GETSET(A,i), j)) {
00585 (void) fprintf(fp, " %d", j);
00586 }
00587 }
00588 (void) fprintf(fp, "\n");
00589 }
00590 }
00591 } else {
00592 (void) fprintf(fp,
00593 "# Symbolic constraints for variable %d (Symbolic form)\n", var);
00594 for(i = 0; i < A->count; i++) {
00595 if (weight[i] > 0) {
00596 (void) fprintf(fp, "# w=%d: (", weight[i]);
00597 for(j = 0; j < A->sf_size; j++) {
00598 if (is_in_set(GETSET(A,i), j)) {
00599 (void) fprintf(fp, " %s",
00600 PLA->label[cube.first_part[var]+j]);
00601 }
00602 }
00603 (void) fprintf(fp, " )\n");
00604 }
00605 }
00606 FREE(weight);
00607 }
00608 }
00609 }