abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
espresso.c
Go to the documentation of this file.
1 /*
2  * Revision Control Information
3  *
4  * $Source$
5  * $Author$
6  * $Revision$
7  * $Date$
8  *
9  */
10 /*
11  * Module: espresso.c
12  * Purpose: The main espresso algorithm
13  *
14  * Returns a minimized version of the ON-set of a function
15  *
16  * The following global variables affect the operation of Espresso:
17  *
18  * MISCELLANEOUS:
19  * trace
20  * print trace information as the minimization progresses
21  *
22  * remove_essential
23  * remove essential primes
24  *
25  * single_expand
26  * if true, stop after first expand/irredundant
27  *
28  * LAST_GASP or SUPER_GASP strategy:
29  * use_super_gasp
30  * uses the super_gasp strategy rather than last_gasp
31  *
32  * SETUP strategy:
33  * recompute_onset
34  * recompute onset using the complement before starting
35  *
36  * unwrap_onset
37  * unwrap the function output part before first expand
38  *
39  * MAKE_SPARSE strategy:
40  * force_irredundant
41  * iterates make_sparse to force a minimal solution (used
42  * indirectly by make_sparse)
43  *
44  * skip_make_sparse
45  * skip the make_sparse step (used by opo only)
46  */
47 
48 #include "espresso.h"
49 
51 
52 
53 pcover espresso(F, D1, R)
54 pcover F, D1, R;
55 {
56  pcover E, D, Fsave;
57  pset last, p;
58  cost_t cost, best_cost;
59 
60 begin:
61  Fsave = sf_save(F); /* save original function */
62  D = sf_save(D1); /* make a scratch copy of D */
63 
64  /* Setup has always been a problem */
65  if (recompute_onset) {
66  EXEC(E = simplify(cube1list(F)), "SIMPLIFY ", E);
67  free_cover(F);
68  F = E;
69  }
70  cover_cost(F, &cost);
71  if (unwrap_onset && (cube.part_size[cube.num_vars - 1] > 1)
72  && (cost.out != cost.cubes*cube.part_size[cube.num_vars-1])
73  && (cost.out < 5000))
74  EXEC(F = sf_contain(unravel(F, cube.num_vars - 1)), "SETUP ", F);
75 
76  /* Initial expand and irredundant */
77  foreach_set(F, last, p) {
78  RESET(p, PRIME);
79  }
80  EXECUTE(F = expand(F, R, FALSE), EXPAND_TIME, F, cost);
81  EXECUTE(F = irredundant(F, D), IRRED_TIME, F, cost);
82 
83  if (! single_expand) {
84  if (remove_essential) {
85  EXECUTE(E = essential(&F, &D), ESSEN_TIME, E, cost);
86  } else {
87  E = new_cover(0);
88  }
89 
90  cover_cost(F, &cost);
91  do {
92 
93  /* Repeat inner loop until solution becomes "stable" */
94  do {
95  copy_cost(&cost, &best_cost);
96  EXECUTE(F = reduce(F, D), REDUCE_TIME, F, cost);
97  EXECUTE(F = expand(F, R, FALSE), EXPAND_TIME, F, cost);
98  EXECUTE(F = irredundant(F, D), IRRED_TIME, F, cost);
99  } while (cost.cubes < best_cost.cubes);
100 
101  /* Perturb solution to see if we can continue to iterate */
102  copy_cost(&cost, &best_cost);
103  if (use_super_gasp) {
104  F = super_gasp(F, D, R, &cost);
105  if (cost.cubes >= best_cost.cubes)
106  break;
107  } else {
108  F = last_gasp(F, D, R, &cost);
109  }
110 
111  } while (cost.cubes < best_cost.cubes ||
112  (cost.cubes == best_cost.cubes && cost.total < best_cost.total));
113 
114  /* Append the essential cubes to F */
115  F = sf_append(F, E); /* disposes of E */
116  if (trace) size_stamp(F, "ADJUST ");
117  }
118 
119  /* Free the D which we used */
120  free_cover(D);
121 
122  /* Attempt to make the PLA matrix sparse */
123  if (! skip_make_sparse) {
124  F = make_sparse(F, D1, R);
125  }
126 
127  /*
128  * Check to make sure function is actually smaller !!
129  * This can only happen because of the initial unravel. If we fail,
130  * then run the whole thing again without the unravel.
131  */
132  if (Fsave->count < F->count) {
133  free_cover(F);
134  F = Fsave;
136  goto begin;
137  } else {
138  free_cover(Fsave);
139  }
140 
141  return F;
142 }
144 
ABC_NAMESPACE_IMPL_START void cover_cost(IN pcover F, INOUT pcost cost)
Definition: cvrmisc.c:17
bool single_expand
Definition: globals.c:34
void copy_cost(pcost s, pcost d)
Definition: cvrmisc.c:86
#define FALSE
Definition: cudd.h:91
ABC_NAMESPACE_IMPL_START pcover espresso(pcover F, pcover D1, pcover R)
Definition: espresso.c:53
static Llb_Mgr_t * p
Definition: llb3Image.c:950
#define free_cover(r)
Definition: espresso.h:266
#define pcover
Definition: espresso.h:264
pcover unravel(IN pcover B, IN int start)
Definition: cvrm.c:113
bool unwrap_onset
Definition: globals.c:37
pcover last_gasp()
bool trace
Definition: globals.c:36
#define PRIME
Definition: espresso.h:127
#define foreach_set(R, last, p)
Definition: espresso.h:135
#define RESET(set, flag)
Definition: espresso.h:123
#define REDUCE_TIME
Definition: espresso.h:378
#define ESSEN_TIME
Definition: espresso.h:375
ABC_NAMESPACE_IMPL_START pset_family sf_contain(INOUT pset_family A)
Definition: contain.c:37
pcover expand()
pcover irredundant()
pcover essential()
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
#define new_cover(i)
Definition: espresso.h:265
unsigned int * pset
Definition: espresso.h:73
pcover reduce()
bool use_super_gasp
Definition: globals.c:39
pcover make_sparse()
bool skip_make_sparse
Definition: globals.c:28
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
void size_stamp(IN pcover T, IN char *name)
Definition: cvrmisc.c:99
#define IRRED_TIME
Definition: espresso.h:377
pcover super_gasp()
pcover simplify(pcube *T)
Definition: compl.c:566
pset_family sf_append()
#define EXEC(fct, name, S)
Definition: espresso.h:418
#define EXPAND_TIME
Definition: espresso.h:376
bool remove_essential
Definition: globals.c:33
#define EXECUTE(fct, i, S, cost)
Definition: espresso.h:422
static int best_cost
Definition: pair.c:366
pset_family sf_save()
bool recompute_onset
Definition: globals.c:32
pcube * cube1list(pcover A)
Definition: cofactor.c:289