src/misc/espresso/hack.c File Reference

#include "espresso.h"
Include dependency graph for hack.c:

Go to the source code of this file.

Functions

 map_dcset (pPLA PLA)
 map_output_symbolic (pPLA PLA)
 find_inputs (pcover A, pPLA PLA, symbolic_list_t *list, int base, int value, pcover *newF, pcover *newD)
 map_symbolic (pPLA PLA)
pcover map_symbolic_cover (pcover T, symbolic_list_t *list, int base)
 form_bitvector (pset p, int base, int value, symbolic_list_t *list)
 symbolic_hack_labels (pPLA PLA, symbolic_t *list, pset compress, int new_size, int old_size, int size_added)
static pcover fsm_simplify (pcover F)
 disassemble_fsm (pPLA PLA, int verbose_mode)

Function Documentation

disassemble_fsm ( pPLA  PLA,
int  verbose_mode 
)

Definition at line 479 of file hack.c.

00482 {
00483     int nin, nstates, nout;
00484     int before, after, present_state, next_state, i, j;
00485     pcube next_state_mask, present_state_mask, state_mask, p, p1, last;
00486     pcover go_nowhere, F, tF;
00487 
00488     /* We make the DISGUSTING assumption that the first 'n' outputs have
00489      *  been created by .symbolic-output, and represent a one-hot encoding
00490      * of the next state.  'n' is the size of the second-to-last multiple-
00491      * valued variable (i.e., before the outputs
00492      */
00493 
00494     if (cube.num_vars - cube.num_binary_vars != 2) {
00495         (void) fprintf(stderr,
00496         "use .symbolic and .symbolic-output to specify\n");
00497         (void) fprintf(stderr,
00498         "the present state and next state field information\n");
00499         fatal("disassemble_pla: need two multiple-valued variables\n");
00500     }
00501 
00502     nin = cube.num_binary_vars;
00503     nstates = cube.part_size[cube.num_binary_vars];
00504     nout = cube.part_size[cube.num_vars - 1];
00505     if (nout < nstates) {
00506         (void) fprintf(stderr,
00507             "use .symbolic and .symbolic-output to specify\n");
00508         (void) fprintf(stderr,
00509             "the present state and next state field information\n");
00510         fatal("disassemble_pla: # outputs < # states\n");
00511     }
00512 
00513 
00514     present_state = cube.first_part[cube.num_binary_vars];
00515     present_state_mask = new_cube();
00516     for(i = 0; i < nstates; i++) {
00517         set_insert(present_state_mask, i + present_state);
00518     }
00519 
00520     next_state = cube.first_part[cube.num_binary_vars+1];
00521     next_state_mask = new_cube();
00522     for(i = 0; i < nstates; i++) {
00523         set_insert(next_state_mask, i + next_state);
00524     }
00525 
00526     state_mask = set_or(new_cube(), next_state_mask, present_state_mask);
00527 
00528     F = new_cover(10);
00529 
00530 
00531     /*
00532      *  check for arcs which go from ANY state to state #i
00533      */
00534     for(i = 0; i < nstates; i++) {
00535         tF = new_cover(10);
00536         foreach_set(PLA->F, last, p) {
00537             if (setp_implies(present_state_mask, p)) { /* from any state ! */
00538                 if (is_in_set(p, next_state + i)) {
00539                     tF = sf_addset(tF, p);
00540                 }
00541             }
00542         }
00543         before = tF->count;
00544         if (before > 0) {
00545             tF = fsm_simplify(tF);
00546             /* don't allow the next state to disappear ... */
00547             foreach_set(tF, last, p) {
00548                 set_insert(p, next_state + i);
00549             }
00550             after = tF->count;
00551             F = sf_append(F, tF);
00552             if (verbose_mode) {
00553                 printf("# state EVERY to %d, before=%d after=%d\n",
00554                         i, before, after);
00555             }
00556         }
00557     }
00558 
00559 
00560     /*
00561      *  some 'arcs' may NOT have a next state -- handle these
00562      *  we must unravel the present state part
00563      */
00564     go_nowhere = new_cover(10);
00565     foreach_set(PLA->F, last, p) {
00566         if (setp_disjoint(p, next_state_mask)) { /* no next state !! */
00567             go_nowhere = sf_addset(go_nowhere, p);
00568         }
00569     }
00570     before = go_nowhere->count;
00571     go_nowhere = unravel_range(go_nowhere,
00572                                 cube.num_binary_vars, cube.num_binary_vars);
00573     after = go_nowhere->count;
00574     F = sf_append(F, go_nowhere);
00575     if (verbose_mode) {
00576         printf("# state ANY to NOWHERE, before=%d after=%d\n", before, after);
00577     }
00578 
00579 
00580     /*
00581      *  minimize cover for all arcs from state #i to state #j
00582      */
00583     for(i = 0; i < nstates; i++) {
00584         for(j = 0; j < nstates; j++) {
00585             tF = new_cover(10);
00586             foreach_set(PLA->F, last, p) {
00587                 /* not EVERY state */
00588                 if (! setp_implies(present_state_mask, p)) {
00589                     if (is_in_set(p, present_state + i)) {
00590                         if (is_in_set(p, next_state + j)) {
00591                             p1 = set_save(p);
00592                             set_diff(p1, p1, state_mask);
00593                             set_insert(p1, present_state + i);
00594                             set_insert(p1, next_state + j);
00595                             tF = sf_addset(tF, p1);
00596                             set_free(p1);
00597                         }
00598                     }
00599                 }
00600             }
00601             before = tF->count;
00602             if (before > 0) {
00603                 tF = fsm_simplify(tF);
00604                 /* don't allow the next state to disappear ... */
00605                 foreach_set(tF, last, p) {
00606                     set_insert(p, next_state + j);
00607                 }
00608                 after = tF->count;
00609                 F = sf_append(F, tF);
00610                 if (verbose_mode) {
00611                     printf("# state %d to %d, before=%d after=%d\n",
00612                             i, j, before, after);
00613                 }
00614             }
00615         }
00616     }
00617 
00618 
00619     free_cube(state_mask);
00620     free_cube(present_state_mask);
00621     free_cube(next_state_mask);
00622 
00623     free_cover(PLA->F);
00624     PLA->F = F;
00625     free_cover(PLA->D);
00626     PLA->D = new_cover(0);
00627 
00628     setdown_cube();
00629     FREE(cube.part_size);
00630     cube.num_binary_vars = nin;
00631     cube.num_vars = nin + 3;
00632     cube.part_size = ALLOC(int, cube.num_vars);
00633     cube.part_size[cube.num_binary_vars] = nstates;
00634     cube.part_size[cube.num_binary_vars+1] = nstates;
00635     cube.part_size[cube.num_binary_vars+2] = nout - nstates;
00636     cube_setup();
00637 
00638     foreach_set(PLA->F, last, p) {
00639         kiss_print_cube(stdout, PLA, p, "~1");
00640     }
00641 }

find_inputs ( pcover  A,
pPLA  PLA,
symbolic_list_t list,
int  base,
int  value,
pcover *  newF,
pcover *  newD 
)

Definition at line 190 of file hack.c.

00196 {
00197     pcover S, S1;
00198     register pset last, p;
00199 
00200     /*
00201      *  A represents th 'input' values for which the outputs assume
00202      *  the integer value 'value
00203      */
00204     if (list == NIL(symbolic_list_t)) {
00205         /*
00206          *  Simulate these inputs against the on-set; then, insert into the
00207          *  new on-set a 1 in the proper position
00208          */
00209         S = cv_intersect(A, PLA->F);
00210         foreach_set(S, last, p) {
00211             set_insert(p, base + value);
00212         }
00213         *newF = sf_append(*newF, S);
00214 
00215         /*
00216          *  'simulate' these inputs against the don't-care set
00217         S = cv_intersect(A, PLA->D);
00218         *newD = sf_append(*newD, S);
00219          */
00220 
00221     } else {
00222         /* intersect and recur with the OFF-set */
00223         S = cof_output(PLA->R, cube.first_part[cube.output] + list->pos);
00224         if (A != NIL(set_family_t)) {
00225             S1 = cv_intersect(A, S);
00226             free_cover(S);
00227             S = S1;
00228         }
00229         find_inputs(S, PLA, list->next, base, value*2, newF, newD);
00230         free_cover(S);
00231 
00232         /* intersect and recur with the ON-set */
00233         S = cof_output(PLA->F, cube.first_part[cube.output] + list->pos);
00234         if (A != NIL(set_family_t)) {
00235             S1 = cv_intersect(A, S);
00236             free_cover(S);
00237             S = S1;
00238         }
00239         find_inputs(S, PLA, list->next, base, value*2 + 1, newF, newD);
00240         free_cover(S);
00241     }
00242 }

form_bitvector ( pset  p,
int  base,
int  value,
symbolic_list_t list 
)

Definition at line 380 of file hack.c.

00385 {
00386     if (list == NIL(symbolic_list_t)) {
00387         set_insert(p, base + value);
00388     } else {
00389         switch(GETINPUT(p, list->variable)) {
00390             case ZERO:
00391                 form_bitvector(p, base, value*2, list->next);
00392                 break;
00393             case ONE:
00394                 form_bitvector(p, base, value*2+1, list->next);
00395                 break;
00396             case TWO:
00397                 form_bitvector(p, base, value*2, list->next);
00398                 form_bitvector(p, base, value*2+1, list->next);
00399                 break;
00400             default:
00401                 fatal("bad cube in form_bitvector");
00402         }
00403     }
00404 }

static pcover fsm_simplify ( pcover  F  )  [static]

Definition at line 466 of file hack.c.

00468 {
00469     pcover D, R;
00470     D = new_cover(0);
00471     R = complement(cube1list(F));
00472     F = espresso(F, D, R);
00473     free_cover(D);
00474     free_cover(R);
00475     return F;
00476 }

map_dcset ( pPLA  PLA  ) 

Definition at line 12 of file hack.c.

00014 {
00015     int var, i;
00016     pcover Tplus, Tminus, Tplusbar, Tminusbar;
00017     pcover newf, term1, term2, dcset, dcsetbar;
00018     pcube cplus, cminus, last, p;
00019 
00020     if (PLA->label == NIL(char *) || PLA->label[0] == NIL(char))
00021         return;
00022 
00023     /* try to find a binary variable named "DONT_CARE" */
00024     var = -1;
00025     for(i = 0; i < cube.num_binary_vars * 2; i++) {
00026         if (strncmp(PLA->label[i], "DONT_CARE", 9) == 0 ||
00027           strncmp(PLA->label[i], "DONTCARE", 8) == 0 ||
00028           strncmp(PLA->label[i], "dont_care", 9) == 0 ||
00029           strncmp(PLA->label[i], "dontcare", 8) == 0) {
00030             var = i/2;
00031             break;
00032         }
00033     }
00034     if (var == -1) {
00035         return;
00036     }
00037 
00038     /* form the cofactor cubes for the don't-care variable */
00039     cplus = set_save(cube.fullset);
00040     cminus = set_save(cube.fullset);
00041     set_remove(cplus, var*2);
00042     set_remove(cminus, var*2 + 1);
00043 
00044     /* form the don't-care set */
00045     EXEC(simp_comp(cofactor(cube1list(PLA->F), cplus), &Tplus, &Tplusbar),
00046         "simpcomp+", Tplus);
00047     EXEC(simp_comp(cofactor(cube1list(PLA->F), cminus), &Tminus, &Tminusbar),
00048         "simpcomp-", Tminus);
00049     EXEC(term1 = cv_intersect(Tplus, Tminusbar), "term1    ", term1);
00050     EXEC(term2 = cv_intersect(Tminus, Tplusbar), "term2    ", term2);
00051     EXEC(dcset = sf_union(term1, term2), "union     ", dcset);
00052     EXEC(simp_comp(cube1list(dcset), &PLA->D, &dcsetbar), "simplify", PLA->D);
00053     EXEC(newf = cv_intersect(PLA->F, dcsetbar), "separate  ", PLA->F);
00054     free_cover(PLA->F);
00055     PLA->F = newf;
00056     free_cover(Tplus);
00057     free_cover(Tminus);
00058     free_cover(Tplusbar);
00059     free_cover(Tminusbar);
00060     free_cover(dcsetbar);
00061 
00062     /* remove any cubes dependent on the DONT_CARE variable */
00063     (void) sf_active(PLA->F);
00064     foreach_set(PLA->F, last, p) {
00065         if (! is_in_set(p, var*2) || ! is_in_set(p, var*2+1)) {
00066             RESET(p, ACTIVE);
00067         }
00068     }
00069     PLA->F = sf_inactive(PLA->F);
00070 
00071     /* resize the cube and delete the don't-care variable */
00072     setdown_cube();
00073     for(i = 2*var+2; i < cube.size; i++) {
00074         PLA->label[i-2] = PLA->label[i];
00075     }
00076     for(i = var+1; i < cube.num_vars; i++) {
00077         cube.part_size[i-1] = cube.part_size[i];
00078     }
00079     cube.num_binary_vars--;
00080     cube.num_vars--;
00081     cube_setup();
00082     PLA->F = sf_delc(PLA->F, 2*var, 2*var+1);
00083     PLA->D = sf_delc(PLA->D, 2*var, 2*var+1);
00084 }

map_output_symbolic ( pPLA  PLA  ) 

Definition at line 86 of file hack.c.

00088 {
00089     pset_family newF, newD;
00090     pset compress;
00091     symbolic_t *p1;
00092     symbolic_list_t *p2;
00093     int i, bit, tot_size, base, old_size;
00094 
00095     /* Remove the DC-set from the ON-set (is this necessary ??) */
00096     if (PLA->D->count > 0) {
00097         sf_free(PLA->F);
00098         PLA->F = complement(cube2list(PLA->D, PLA->R));
00099     }
00100 
00101     /* tot_size = width added for all symbolic variables */
00102     tot_size = 0;
00103     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
00104         for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
00105             if (p2->pos<0 || p2->pos>=cube.part_size[cube.output]) {
00106                 fatal("symbolic-output index out of range");
00107 /*          } else if (p2->variable != cube.output) {
00108                 fatal("symbolic-output label must be an output");*/
00109             }
00110         }
00111         tot_size += 1 << p1->symbolic_list_length;
00112     }
00113 
00114     /* adjust the indices to skip over new outputs */
00115     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
00116         for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
00117             p2->pos += tot_size;
00118         }
00119     }
00120 
00121     /* resize the cube structure -- add enough for the one-hot outputs */
00122     old_size = cube.size;
00123     cube.part_size[cube.output] += tot_size;
00124     setdown_cube();
00125     cube_setup();
00126 
00127     /* insert space in the output part for the one-hot output */
00128     base = cube.first_part[cube.output];
00129     PLA->F = sf_addcol(PLA->F, base, tot_size);
00130     PLA->D = sf_addcol(PLA->D, base, tot_size);
00131     PLA->R = sf_addcol(PLA->R, base, tot_size);
00132 
00133     /* do the real work */
00134     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
00135         newF = new_cover(100);
00136         newD = new_cover(100);
00137         find_inputs(NIL(set_family_t), PLA, p1->symbolic_list, base, 0,
00138                             &newF, &newD);
00139 /*
00140  *  Not sure what this means
00141         find_dc_inputs(PLA, p1->symbolic_list,
00142                             base, 1 << p1->symbolic_list_length, &newF, &newD);
00143  */
00144         free_cover(PLA->F);
00145         PLA->F = newF;
00146 /*
00147  *  retain OLD DC-set -- but we've lost the don't-care arc information
00148  *  (it defaults to branch to the zero state)
00149         free_cover(PLA->D);
00150         PLA->D = newD;
00151  */
00152         free_cover(newD);
00153         base += 1 << p1->symbolic_list_length;
00154     }
00155 
00156     /* delete the old outputs, and resize the cube */
00157     compress = set_full(newF->sf_size);
00158     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
00159         for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
00160             bit = cube.first_part[cube.output] + p2->pos;
00161             set_remove(compress, bit);
00162         }
00163     }
00164     cube.part_size[cube.output] -= newF->sf_size - set_ord(compress);
00165     setdown_cube();
00166     cube_setup();
00167     PLA->F = sf_compress(PLA->F, compress);
00168     PLA->D = sf_compress(PLA->D, compress);
00169     if (cube.size != PLA->F->sf_size) fatal("error");
00170 
00171     /* Quick minimization */
00172     PLA->F = sf_contain(PLA->F);
00173     PLA->D = sf_contain(PLA->D);
00174     for(i = 0; i < cube.num_vars; i++) {
00175         PLA->F = d1merge(PLA->F, i);
00176         PLA->D = d1merge(PLA->D, i);
00177     }
00178     PLA->F = sf_contain(PLA->F);
00179     PLA->D = sf_contain(PLA->D);
00180 
00181     free_cover(PLA->R);
00182     PLA->R = new_cover(0);
00183 
00184     symbolic_hack_labels(PLA, PLA->symbolic_output,
00185                             compress, cube.size, old_size, tot_size);
00186     set_free(compress);
00187 }

map_symbolic ( pPLA  PLA  ) 

Definition at line 285 of file hack.c.

00287 {
00288     symbolic_t *p1;
00289     symbolic_list_t *p2;
00290     int var, base, num_vars, num_binary_vars, *new_part_size;
00291     int new_size, size_added, num_deleted_vars, num_added_vars, newvar;
00292     pset compress;
00293 
00294     /* Verify legal values are in the symbolic lists */
00295     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
00296         for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
00297             if (p2->variable  < 0 || p2->variable >= cube.num_binary_vars) {
00298                 fatal(".symbolic requires binary variables");
00299             }
00300         }
00301     }
00302 
00303     /*
00304      *  size_added = width added for all symbolic variables
00305      *  num_deleted_vars = # binary variables to be deleted
00306      *  num_added_vars = # new mv variables
00307      *  compress = a cube which will be used to compress the set families
00308      */
00309     size_added = 0;
00310     num_added_vars = 0;
00311     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
00312         size_added += 1 << p1->symbolic_list_length;
00313         num_added_vars++;
00314     }
00315     compress = set_full(PLA->F->sf_size + size_added);
00316     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
00317         for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
00318             set_remove(compress, p2->variable*2);
00319             set_remove(compress, p2->variable*2+1);
00320         }
00321     }
00322     num_deleted_vars = ((PLA->F->sf_size + size_added) - set_ord(compress))/2;
00323 
00324     /* compute the new cube constants */
00325     num_vars = cube.num_vars - num_deleted_vars + num_added_vars;
00326     num_binary_vars = cube.num_binary_vars - num_deleted_vars;
00327     new_size = cube.size - num_deleted_vars*2 + size_added;
00328     new_part_size = ALLOC(int, num_vars);
00329     new_part_size[num_vars-1] = cube.part_size[cube.num_vars-1];
00330     for(var = cube.num_binary_vars; var < cube.num_vars-1; var++) {
00331         new_part_size[var-num_deleted_vars] = cube.part_size[var];
00332     }
00333 
00334     /* re-size the covers, opening room for the new mv variables */
00335     base = cube.first_part[cube.output];
00336     PLA->F = sf_addcol(PLA->F, base, size_added);
00337     PLA->D = sf_addcol(PLA->D, base, size_added);
00338     PLA->R = sf_addcol(PLA->R, base, size_added);
00339 
00340     /* compute the values for the new mv variables */
00341     newvar = (cube.num_vars - 1) - num_deleted_vars;
00342     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
00343         PLA->F = map_symbolic_cover(PLA->F, p1->symbolic_list, base);
00344         PLA->D = map_symbolic_cover(PLA->D, p1->symbolic_list, base);
00345         PLA->R = map_symbolic_cover(PLA->R, p1->symbolic_list, base);
00346         base += 1 << p1->symbolic_list_length;
00347         new_part_size[newvar++] = 1 << p1->symbolic_list_length;
00348     }
00349 
00350     /* delete the binary variables which disappear */
00351     PLA->F = sf_compress(PLA->F, compress);
00352     PLA->D = sf_compress(PLA->D, compress);
00353     PLA->R = sf_compress(PLA->R, compress);
00354 
00355     symbolic_hack_labels(PLA, PLA->symbolic, compress,
00356                 new_size, cube.size, size_added);
00357     setdown_cube();
00358     FREE(cube.part_size);
00359     cube.num_vars = num_vars;
00360     cube.num_binary_vars = num_binary_vars;
00361     cube.part_size = new_part_size;
00362     cube_setup();
00363     set_free(compress);
00364 }

pcover map_symbolic_cover ( pcover  T,
symbolic_list_t list,
int  base 
)

Definition at line 367 of file hack.c.

00371 {
00372     pset last, p;
00373     foreach_set(T, last, p) {
00374         form_bitvector(p, base, 0, list);
00375     }
00376     return T;
00377 }

symbolic_hack_labels ( pPLA  PLA,
symbolic_t list,
pset  compress,
int  new_size,
int  old_size,
int  size_added 
)

Definition at line 407 of file hack.c.

00412 {
00413     int i, base;
00414     char **oldlabel;
00415     symbolic_t *p1;
00416     symbolic_label_t *p3;
00417 
00418     /* hack with the labels */
00419     if ((oldlabel = PLA->label) == NIL(char *))
00420         return;
00421     PLA->label = ALLOC(char *, new_size);
00422     for(i = 0; i < new_size; i++) {
00423         PLA->label[i] = NIL(char);
00424     }
00425 
00426     /* copy the binary variable labels and unchanged mv variable labels */
00427     base = 0;
00428     for(i = 0; i < cube.first_part[cube.output]; i++) {
00429         if (is_in_set(compress, i)) {
00430             PLA->label[base++] = oldlabel[i];
00431         } else {
00432             if (oldlabel[i] != NIL(char)) {
00433                 FREE(oldlabel[i]);
00434             }
00435         }
00436     }
00437 
00438     /* add the user-defined labels for the symbolic outputs */
00439     for(p1 = list; p1 != NIL(symbolic_t); p1 = p1->next) {
00440         p3 = p1->symbolic_label;
00441         for(i = 0; i < (1 << p1->symbolic_list_length); i++) {
00442             if (p3 == NIL(symbolic_label_t)) {
00443                 PLA->label[base+i] = ALLOC(char, 10);
00444                 (void) sprintf(PLA->label[base+i], "X%d", i);
00445             } else {
00446                 PLA->label[base+i] = p3->label;
00447                 p3 = p3->next;
00448             }
00449         }
00450         base += 1 << p1->symbolic_list_length;
00451     }
00452 
00453     /* copy the labels for the binary outputs which remain */
00454     for(i = cube.first_part[cube.output]; i < old_size; i++) {
00455         if (is_in_set(compress, i + size_added)) {
00456             PLA->label[base++] = oldlabel[i];
00457         } else {
00458             if (oldlabel[i] != NIL(char)) {
00459                 FREE(oldlabel[i]);
00460             }
00461         }
00462     }
00463     FREE(oldlabel);
00464 }


Generated on Tue Jan 5 12:19:11 2010 for abc70930 by  doxygen 1.6.1