1 /*========================================================================
2 Copyright (C) 1996-2002 by Jorn Lind-Nielsen
3 All rights reserved
4
5 Permission is hereby granted, without written agreement and without
6 license or royalty fees, to use, reproduce, prepare derivative
7 works, distribute, and display this software and its documentation
8 for any purpose, provided that (1) the above copyright notice and
9 the following two paragraphs appear in all copies of the source code
10 and (2) redistributions, including without limitation binaries,
11 reproduce these notices in the supporting documentation. Substantial
12 modifications to this software may be copyrighted by their authors
13 and need not follow the licensing terms described here, provided
14 that the new terms are clearly indicated in all files where they apply.
15
16 IN NO EVENT SHALL JORN LIND-NIELSEN, OR DISTRIBUTORS OF THIS
17 SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
18 INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
19 SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE
20 ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
22 JORN LIND-NIELSEN SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
23 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24 FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
25 ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
26 OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
27 MODIFICATIONS.
28 ========================================================================*/
29
30 /*************************************************************************
31 $Header: /Volumes/CVS/repository/spot/spot/buddy/src/pairs.c,v 1.7 2003/05/22 15:07:27 aduret Exp $
32 FILE: pairs.c
33 DESCR: Pair management for BDD package.
34 AUTH: Jorn Lind
35 DATE: february 1997
36 *************************************************************************/
37 #include <stdlib.h>
38 #include <limits.h>
39 #include "kernel.h"
40
41 /*======================================================================*/
42
43 static int pairsid; /* Pair identifier */
44 static bddPair* pairs; /* List of all replacement pairs in use */
45
46
47 /*************************************************************************
48 *************************************************************************/
49
bdd_pairs_init(void)50 void bdd_pairs_init(void)
51 {
52 pairsid = 0;
53 pairs = NULL;
54 }
55
56
bdd_pairs_done(void)57 void bdd_pairs_done(void)
58 {
59 bddPair *p = pairs;
60 int n;
61
62 while (p != NULL)
63 {
64 bddPair *next = p->next;
65 for (n=0 ; n<bddvarnum ; n++)
66 bdd_delref( p->result[n] );
67 free(p->result);
68 free(p);
69 p = next;
70 }
71 }
72
73
update_pairsid(void)74 static int update_pairsid(void)
75 {
76 pairsid++;
77
78 if (pairsid == (INT_MAX >> 2))
79 {
80 bddPair *p;
81 pairsid = 0;
82 for (p=pairs ; p!=NULL ; p=p->next)
83 p->id = pairsid++;
84 bdd_operator_reset();
85 }
86
87 return pairsid;
88 }
89
90
bdd_register_pair(bddPair * p)91 void bdd_register_pair(bddPair *p)
92 {
93 p->next = pairs;
94 pairs = p;
95 }
96
97
bdd_pairs_vardown(int level)98 void bdd_pairs_vardown(int level)
99 {
100 bddPair *p;
101
102 for (p=pairs ; p!=NULL ; p=p->next)
103 {
104 int tmp;
105
106 tmp = p->result[level];
107 p->result[level] = p->result[level+1];
108 p->result[level+1] = tmp;
109
110 if (p->last == level)
111 p->last++;
112 }
113 }
114
115
bdd_pairalloc(void)116 static bddPair *bdd_pairalloc(void)
117 {
118 bddPair *p;
119 if ((p=(bddPair*)malloc(sizeof(bddPair))) == NULL)
120 {
121 bdd_error(BDD_MEMORY);
122 return NULL;
123 }
124
125 if ((p->result=(BDD*)malloc(sizeof(BDD)*bddvarnum)) == NULL)
126 {
127 free(p);
128 bdd_error(BDD_MEMORY);
129 return NULL;
130 }
131 return p;
132 }
133
134
bdd_pairs_resize(int oldsize,int newsize)135 int bdd_pairs_resize(int oldsize, int newsize)
136 {
137 bddPair *p;
138 int n;
139
140 for (p=pairs ; p!=NULL ; p=p->next)
141 {
142 if ((p->result=(BDD*)realloc(p->result,sizeof(BDD)*newsize)) == NULL)
143 return bdd_error(BDD_MEMORY);
144
145 for (n=oldsize ; n<newsize ; n++)
146 p->result[n] = bdd_ithvar(bddlevel2var[n]);
147 }
148
149 return 0;
150 }
151
152
153 /*
154 NAME {* bdd\_newpair *}
155 SECTION {* kernel *}
156 SHORT {* creates an empty variable pair table *}
157 PROTO {* bddPair *bdd_newpair(void) *}
158 DESCR {* Variable pairs of the type {\tt bddPair} are used in
159 {\tt bdd\_replace} to define which variables to replace with
160 other variables. This function allocates such an empty table. The
161 table can be freed by a call to {\tt bdd\_freepair}. *}
162 RETURN {* Returns a new table of pairs. *}
163 ALSO {* bdd\_freepair, bdd\_replace, bdd\_setpair, bdd\_setpairs *}
164 */
bdd_newpair(void)165 bddPair *bdd_newpair(void)
166 {
167 int n;
168 bddPair *p;
169
170 p = bdd_pairalloc();
171 if (p == NULL)
172 return NULL;
173
174 for (n=0 ; n<bddvarnum ; n++)
175 p->result[n] = bdd_ithvar(bddlevel2var[n]);
176
177 p->id = update_pairsid();
178 p->last = -1;
179
180 bdd_register_pair(p);
181 return p;
182 }
183
184
185 /*
186 NAME {* bdd\_copypair *}
187 SECTION {* kernel *}
188 SHORT {* clone a pair table *}
189 PROTO {* bddPair *bdd_copypair(bddPair *from) *}
190 DESCR {* Duplicate the table of pairs {\tt from}.
191 This function allocates the cloned table. The
192 table can be freed by a call to {\tt bdd\_freepair}. *}
193 RETURN {* Returns a new table of pairs. *}
194 ALSO {* bdd\_newpair, bdd\_freepair, bdd\_replace, bdd\_setpair, bdd\_setpairs *}
195 */
bdd_copypair(bddPair * from)196 bddPair *bdd_copypair(bddPair *from)
197 {
198 int n;
199 bddPair *p;
200
201 p = bdd_pairalloc();
202 if (p == NULL)
203 return NULL;
204
205 for (n=0 ; n<bddvarnum ; n++)
206 p->result[n] = bdd_addref(from->result[n]);
207
208 p->id = update_pairsid();
209 p->last = from->last;
210
211 bdd_register_pair(p);
212 return p;
213 }
214
215 /*
216 NAME {* bdd\_mergepairs *}
217 SECTION {* kernel *}
218 SHORT {* merge two pair tables *}
219 PROTO {* bddPair *bdd_mergepairs(bddPair *left, bddPairs *right) *}
220 DESCR {* Create a table of pairs that can be used to perform the
221 rewritings of both {\tt left} and {\tt right}. This cannot work if
222 the two tables contain incompatible rewrite pairs (for instance
223 if left rewrite 1 to 2, and right rewrite 1 to 3).
224
225 This function allocates a new table. The
226 table can be freed by a call to {\tt bdd\_freepair}. *}
227 RETURN {* Returns a new table of pairs. *}
228 ALSO {* bdd\_newpair, bdd\_freepair, bdd\_replace, bdd\_setpair, bdd\_setpairs *}
229 */
bdd_mergepairs(bddPair * left,bddPair * right)230 bddPair *bdd_mergepairs(bddPair *left, bddPair *right)
231 {
232 int n;
233 bddPair *p;
234
235 p = bdd_copypair(left);
236 if (p == NULL)
237 return NULL;
238
239 for (n=0; n<bddvarnum; n++)
240 {
241 bdd nl = bdd_ithvar(n);
242
243 /* If P performs no rewriting for N, blindly use that of RIGHT. */
244 if (nl == p->result[n])
245 {
246 bdd_delref(p->result[n]);
247 p->result[n] = bdd_addref(right->result[n]);
248 }
249 else
250 /* If P rewrites N, make sure RIGHT doesn't rewrite it, or that
251 it rewrites it to the same variable. */
252 if (nl != right->result[n] && right->result[n] != p->result[n])
253 {
254 bdd_freepair(p);
255 bdd_error(BDD_INVMERGE);
256 return NULL;
257 }
258 }
259
260 if (p->last < right->last)
261 p->last = right->last;
262
263 /* We don't have to update the ID, because this pair was not
264 used since bdd_copypair were called. */
265 return p;
266 }
267
268
269 /*
270 NAME {* bdd\_setpair *}
271 EXTRA {* bdd\_setbddpair *}
272 SECTION {* kernel *}
273 SHORT {* set one variable pair *}
274 PROTO {* int bdd_setpair(bddPair *pair, int oldvar, int newvar)
275 int bdd_setbddpair(bddPair *pair, int oldvar, BDD newvar) *}
276 DESCR {* Adds the pair {\tt (oldvar,newvar)} to the table of pairs
277 {\tt pair}. This results in {\tt oldvar} being substituted
278 with {\tt newvar} in a call to {\tt bdd\_replace}. In the first
279 version {\tt newvar} is an integer representing the variable
280 to be replaced with the old variable.
281 In the second version {\tt oldvar} is a BDD.
282 In this case the variable {\tt oldvar} is substituted with the
283 BDD {\tt newvar}.
284 The possibility to substitute with any BDD as {\tt newvar} is
285 utilized in bdd\_compose, whereas only the topmost variable
286 in the BDD is used in bdd\_replace. *}
287 RETURN {* Zero on success, otherwise a negative error code. *}
288 ALSO {* bdd\_newpair, bdd\_setpairs, bdd\_resetpair, bdd\_replace, bdd\_compose *}
289 */
bdd_setpair(bddPair * pair,int oldvar,int newvar)290 int bdd_setpair(bddPair *pair, int oldvar, int newvar)
291 {
292 if (pair == NULL)
293 return 0;
294
295 if (oldvar < 0 || oldvar > bddvarnum-1)
296 return bdd_error(BDD_VAR);
297 if (newvar < 0 || newvar > bddvarnum-1)
298 return bdd_error(BDD_VAR);
299
300 bdd_delref( pair->result[bddvar2level[oldvar]] );
301 pair->result[bddvar2level[oldvar]] = bdd_ithvar(newvar);
302 pair->id = update_pairsid();
303
304 if (bddvar2level[oldvar] > pair->last)
305 pair->last = bddvar2level[oldvar];
306
307 return 0;
308 }
309
310
bdd_setbddpair(bddPair * pair,int oldvar,BDD newvar)311 int bdd_setbddpair(bddPair *pair, int oldvar, BDD newvar)
312 {
313 int oldlevel;
314
315 if (pair == NULL)
316 return 0;
317
318 CHECK(newvar);
319 if (oldvar < 0 || oldvar >= bddvarnum)
320 return bdd_error(BDD_VAR);
321 oldlevel = bddvar2level[oldvar];
322
323 bdd_delref( pair->result[oldlevel] );
324 pair->result[oldlevel] = bdd_addref(newvar);
325 pair->id = update_pairsid();
326
327 if (oldlevel > pair->last)
328 pair->last = oldlevel;
329
330 return 0;
331 }
332
333
334 /*
335 NAME {* bdd\_setpairs *}
336 EXTRA {* bdd\_setbddpairs *}
337 SECTION {* kernel *}
338 SHORT {* defines a whole set of pairs *}
339 PROTO {* int bdd_setpairs(bddPair *pair, int *oldvar, int *newvar, int size)
340 int bdd_setbddpairs(bddPair *pair, int *oldvar, BDD *newvar, int size) *}
341 DESCR {* As for {\tt bdd\_setpair} but with {\tt oldvar} and {\tt newvar}
342 being arrays of variables (BDDs) of size {\tt size}. *}
343 RETURN {* Zero on success, otherwise a negative error code. *}
344 ALSO {* bdd\_newpair, bdd\_setpair, bdd\_replace, bdd\_compose *}
345 */
bdd_setpairs(bddPair * pair,int * oldvar,int * newvar,int size)346 int bdd_setpairs(bddPair *pair, int *oldvar, int *newvar, int size)
347 {
348 int n,e;
349 if (pair == NULL)
350 return 0;
351
352 for (n=0 ; n<size ; n++)
353 if ((e=bdd_setpair(pair, oldvar[n], newvar[n])) < 0)
354 return e;
355
356 return 0;
357 }
358
359
bdd_setbddpairs(bddPair * pair,int * oldvar,BDD * newvar,int size)360 int bdd_setbddpairs(bddPair *pair, int *oldvar, BDD *newvar, int size)
361 {
362 int n,e;
363 if (pair == NULL)
364 return 0;
365
366 for (n=0 ; n<size ; n++)
367 if ((e=bdd_setbddpair(pair, oldvar[n], newvar[n])) < 0)
368 return e;
369
370 return 0;
371 }
372
373
374 /*
375 NAME {* bdd\_freepair *}
376 SECTION {* kernel *}
377 SHORT {* frees a table of pairs *}
378 PROTO {* void bdd_freepair(bddPair *pair) *}
379 DESCR {* Frees the table of pairs {\tt pair} that has been allocated
380 by a call to {\tt bdd\_newpair}. *}
381 ALSO {* bdd\_replace, bdd\_newpair, bdd\_setpair, bdd\_resetpair *}
382 */
bdd_freepair(bddPair * p)383 void bdd_freepair(bddPair *p)
384 {
385 int n;
386
387 if (p == NULL)
388 return;
389
390 if (pairs != p)
391 {
392 bddPair *bp = pairs;
393 while (bp != NULL && bp->next != p)
394 bp = bp->next;
395
396 if (bp != NULL)
397 bp->next = p->next;
398 }
399 else
400 pairs = p->next;
401
402 for (n=0 ; n<bddvarnum ; n++)
403 bdd_delref( p->result[n] );
404 free(p->result);
405 free(p);
406 }
407
408
409 /*
410 NAME {* bdd\_resetpair *}
411 SECTION {* kernel *}
412 SHORT {* clear all variable pairs *}
413 PROTO {* void bdd_resetpair(bddPair *pair) *}
414 DESCR {* Resets the table of pairs {\tt pair} by setting all substitutions
415 to their default values (that is no change). *}
416 ALSO {* bdd\_newpair, bdd\_setpair, bdd\_freepair *}
417 */
bdd_resetpair(bddPair * p)418 void bdd_resetpair(bddPair *p)
419 {
420 int n;
421
422 for (n=0 ; n<bddvarnum ; n++)
423 p->result[n] = bdd_ithvar(n);
424 p->last = 0;
425 }
426
427
428 /* EOF */
429