1 | /**CFile*********************************************************************** |
---|
2 | |
---|
3 | FileName [imgHybrid.c] |
---|
4 | |
---|
5 | PackageName [img] |
---|
6 | |
---|
7 | Synopsis [Routines for hybrid image computation.] |
---|
8 | |
---|
9 | Description [The hybrid image computation method combines transition function |
---|
10 | and relation methods, in other words, combines splitting and conjunction |
---|
11 | methods.] |
---|
12 | |
---|
13 | SeeAlso [] |
---|
14 | |
---|
15 | Author [In-Ho Moon] |
---|
16 | |
---|
17 | Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of Colorado. |
---|
18 | All rights reserved. |
---|
19 | |
---|
20 | Permission is hereby granted, without written agreement and without license |
---|
21 | or royalty fees, to use, copy, modify, and distribute this software and its |
---|
22 | documentation for any purpose, provided that the above copyright notice and |
---|
23 | the following two paragraphs appear in all copies of this software. |
---|
24 | |
---|
25 | IN NO EVENT SHALL THE UNIVERSITY OF COLORADO BE LIABLE TO ANY PARTY FOR |
---|
26 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
---|
27 | OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
---|
28 | COLORADO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
29 | |
---|
30 | THE UNIVERSITY OF COLORADO SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
---|
31 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
---|
32 | FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN |
---|
33 | "AS IS" BASIS, AND THE UNIVERSITY OF COLORADO HAS NO OBLIGATION TO PROVIDE |
---|
34 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] |
---|
35 | |
---|
36 | ******************************************************************************/ |
---|
37 | #include "imgInt.h" |
---|
38 | |
---|
39 | static char rcsid[] UNUSED = "$Id: imgHybrid.c,v 1.27 2008/11/27 02:19:53 fabio Exp $"; |
---|
40 | |
---|
41 | /*---------------------------------------------------------------------------*/ |
---|
42 | /* Constant declarations */ |
---|
43 | /*---------------------------------------------------------------------------*/ |
---|
44 | |
---|
45 | /*---------------------------------------------------------------------------*/ |
---|
46 | /* Type declarations */ |
---|
47 | /*---------------------------------------------------------------------------*/ |
---|
48 | |
---|
49 | /*---------------------------------------------------------------------------*/ |
---|
50 | /* Structure declarations */ |
---|
51 | /*---------------------------------------------------------------------------*/ |
---|
52 | |
---|
53 | /*---------------------------------------------------------------------------*/ |
---|
54 | /* Variable declarations */ |
---|
55 | /*---------------------------------------------------------------------------*/ |
---|
56 | |
---|
57 | /*---------------------------------------------------------------------------*/ |
---|
58 | /* Macro declarations */ |
---|
59 | /*---------------------------------------------------------------------------*/ |
---|
60 | |
---|
61 | /**AutomaticStart*************************************************************/ |
---|
62 | |
---|
63 | /*---------------------------------------------------------------------------*/ |
---|
64 | /* Static function prototypes */ |
---|
65 | /*---------------------------------------------------------------------------*/ |
---|
66 | |
---|
67 | static float ComputeSupportLambda(ImgTfmInfo_t *info, array_t *relationArray, mdd_t *cofactorCube, mdd_t *abstractCube, mdd_t *from, array_t *vector, int newRelationFlag, int preFlag, float *improvedLambda); |
---|
68 | |
---|
69 | /**AutomaticEnd***************************************************************/ |
---|
70 | |
---|
71 | |
---|
72 | /*---------------------------------------------------------------------------*/ |
---|
73 | /* Definition of exported functions */ |
---|
74 | /*---------------------------------------------------------------------------*/ |
---|
75 | |
---|
76 | |
---|
77 | /**Function******************************************************************** |
---|
78 | |
---|
79 | Synopsis [Prints the options for hybrid image computation.] |
---|
80 | |
---|
81 | Description [Prints the options for hybrid image computation.] |
---|
82 | |
---|
83 | SideEffects [] |
---|
84 | |
---|
85 | SeeAlso [] |
---|
86 | |
---|
87 | ******************************************************************************/ |
---|
88 | void |
---|
89 | Img_PrintHybridOptions(void) |
---|
90 | { |
---|
91 | ImgTfmOption_t *options; |
---|
92 | char dummy[80]; |
---|
93 | |
---|
94 | options = ImgTfmGetOptions(Img_Hybrid_c); |
---|
95 | |
---|
96 | switch (options->hybridMode) { |
---|
97 | case 0 : |
---|
98 | sprintf(dummy, "with only transition function"); |
---|
99 | break; |
---|
100 | case 1 : |
---|
101 | sprintf(dummy, "with both transition function and relation"); |
---|
102 | break; |
---|
103 | case 2 : |
---|
104 | sprintf(dummy, "with only transition relation"); |
---|
105 | break; |
---|
106 | default : |
---|
107 | sprintf(dummy, "invalid"); |
---|
108 | break; |
---|
109 | } |
---|
110 | fprintf(vis_stdout, "HYB: hybrid_mode = %d (%s)\n", |
---|
111 | options->hybridMode, dummy); |
---|
112 | |
---|
113 | switch (options->trSplitMethod) { |
---|
114 | case 0 : |
---|
115 | sprintf(dummy, "support"); |
---|
116 | break; |
---|
117 | case 1 : |
---|
118 | sprintf(dummy, "estimate BDD size"); |
---|
119 | break; |
---|
120 | default : |
---|
121 | sprintf(dummy, "invalid"); |
---|
122 | break; |
---|
123 | } |
---|
124 | fprintf(vis_stdout, "HYB: hybrid_tr_split_method = %d (%s)\n", |
---|
125 | options->trSplitMethod, dummy); |
---|
126 | |
---|
127 | if (options->buildPartialTR) |
---|
128 | sprintf(dummy, "yes"); |
---|
129 | else |
---|
130 | sprintf(dummy, "no"); |
---|
131 | fprintf(vis_stdout, "HYB: hybrid_build_partial_tr = %s\n", dummy); |
---|
132 | |
---|
133 | fprintf(vis_stdout, "HYB: hybrid_partial_num_vars = %d\n", |
---|
134 | options->nPartialVars); |
---|
135 | |
---|
136 | switch (options->partialMethod) { |
---|
137 | case 0 : |
---|
138 | sprintf(dummy, "BDD size"); |
---|
139 | break; |
---|
140 | case 1 : |
---|
141 | sprintf(dummy, "support"); |
---|
142 | break; |
---|
143 | default : |
---|
144 | sprintf(dummy, "invalid"); |
---|
145 | break; |
---|
146 | } |
---|
147 | fprintf(vis_stdout, "HYB: hybrid_partial_method = %d (%s)\n", |
---|
148 | options->partialMethod, dummy); |
---|
149 | |
---|
150 | if (options->delayedSplit) |
---|
151 | sprintf(dummy, "yes"); |
---|
152 | else |
---|
153 | sprintf(dummy, "no"); |
---|
154 | fprintf(vis_stdout, "HYB: hybrid_delayed_split = %s\n", dummy); |
---|
155 | |
---|
156 | fprintf(vis_stdout, "HYB: hybrid_split_min_depth = %d\n", |
---|
157 | options->splitMinDepth); |
---|
158 | fprintf(vis_stdout, "HYB: hybrid_split_max_depth = %d\n", |
---|
159 | options->splitMaxDepth); |
---|
160 | fprintf(vis_stdout, "HYB: hybrid_pre_split_min_depth = %d\n", |
---|
161 | options->preSplitMinDepth); |
---|
162 | fprintf(vis_stdout, "HYB: hybrid_pre_split_max_depth = %d\n", |
---|
163 | options->preSplitMaxDepth); |
---|
164 | |
---|
165 | fprintf(vis_stdout, "HYB: hybrid_lambda_threshold = %.2f\n", |
---|
166 | options->lambdaThreshold); |
---|
167 | fprintf(vis_stdout, "HYB: hybrid_pre_lambda_threshold = %.2f\n", |
---|
168 | options->preLambdaThreshold); |
---|
169 | fprintf(vis_stdout, "HYB: hybrid_conjoin_vector_size = %d\n", |
---|
170 | options->conjoinVectorSize); |
---|
171 | fprintf(vis_stdout, "HYB: hybrid_conjoin_relation_size = %d\n", |
---|
172 | options->conjoinRelationSize); |
---|
173 | fprintf(vis_stdout, "HYB: hybrid_conjoin_relation_bdd_size = %d\n", |
---|
174 | options->conjoinRelationBddSize); |
---|
175 | fprintf(vis_stdout, "HYB: hybrid_improve_lambda = %.2f\n", |
---|
176 | options->improveLambda); |
---|
177 | fprintf(vis_stdout, "HYB: hybrid_improve_vector_size = %d\n", |
---|
178 | options->improveVectorSize); |
---|
179 | fprintf(vis_stdout, "HYB: hybrid_improve_vector_bdd_size = %.2f\n", |
---|
180 | options->improveVectorBddSize); |
---|
181 | |
---|
182 | switch (options->decideMode) { |
---|
183 | case 0 : |
---|
184 | sprintf(dummy, "use only lambda"); |
---|
185 | break; |
---|
186 | case 1 : |
---|
187 | sprintf(dummy, "lambda + special check"); |
---|
188 | break; |
---|
189 | case 2 : |
---|
190 | sprintf(dummy, "lambda + improvement"); |
---|
191 | break; |
---|
192 | case 3 : |
---|
193 | sprintf(dummy, "use all"); |
---|
194 | break; |
---|
195 | default : |
---|
196 | sprintf(dummy, "invalid"); |
---|
197 | break; |
---|
198 | } |
---|
199 | fprintf(vis_stdout, "HYB: hybrid_decide_mode = %d (%s)\n", |
---|
200 | options->decideMode, dummy); |
---|
201 | |
---|
202 | if (options->reorderWithFrom) |
---|
203 | sprintf(dummy, "yes"); |
---|
204 | else |
---|
205 | sprintf(dummy, "no"); |
---|
206 | fprintf(vis_stdout, "HYB: hybrid_reorder_with_from = %s\n", dummy); |
---|
207 | |
---|
208 | if (options->preReorderWithFrom) |
---|
209 | sprintf(dummy, "yes"); |
---|
210 | else |
---|
211 | sprintf(dummy, "no"); |
---|
212 | fprintf(vis_stdout, "HYB: hybrid_pre_reorder_with_from = %s\n", dummy); |
---|
213 | |
---|
214 | switch (options->lambdaMode) { |
---|
215 | case 0 : |
---|
216 | sprintf(dummy, "total lifetime with ps/pi variables"); |
---|
217 | break; |
---|
218 | case 1 : |
---|
219 | sprintf(dummy, "active lifetime with ps/pi variables"); |
---|
220 | break; |
---|
221 | case 2 : |
---|
222 | sprintf(dummy, "total lifetime with ps/ns/pi variables"); |
---|
223 | break; |
---|
224 | default : |
---|
225 | sprintf(dummy, "invalid"); |
---|
226 | break; |
---|
227 | } |
---|
228 | fprintf(vis_stdout, "HYB: hybrid_lambda_mode = %d (%s)\n", |
---|
229 | options->lambdaMode, dummy); |
---|
230 | |
---|
231 | switch (options->preLambdaMode) { |
---|
232 | case 0 : |
---|
233 | sprintf(dummy, "total lifetime with ns/pi variables"); |
---|
234 | break; |
---|
235 | case 1 : |
---|
236 | sprintf(dummy, "active lifetime with ps/pi variables"); |
---|
237 | break; |
---|
238 | case 2 : |
---|
239 | sprintf(dummy, "total lifetime with ps/ns/pi variables"); |
---|
240 | break; |
---|
241 | case 3 : |
---|
242 | sprintf(dummy, "total lifetime with ps/pi variables"); |
---|
243 | break; |
---|
244 | default : |
---|
245 | sprintf(dummy, "invalid"); |
---|
246 | break; |
---|
247 | } |
---|
248 | fprintf(vis_stdout, "HYB: hybrid_pre_lambda_mode = %d (%s)\n", |
---|
249 | options->preLambdaMode, dummy); |
---|
250 | |
---|
251 | if (options->lambdaWithFrom) |
---|
252 | sprintf(dummy, "yes"); |
---|
253 | else |
---|
254 | sprintf(dummy, "no"); |
---|
255 | fprintf(vis_stdout, "HYB: hybrid_lambda_with_from = %s\n", dummy); |
---|
256 | |
---|
257 | if (options->lambdaWithTr) |
---|
258 | sprintf(dummy, "yes"); |
---|
259 | else |
---|
260 | sprintf(dummy, "no"); |
---|
261 | fprintf(vis_stdout, "HYB: hybrid_lambda_with_tr = %s\n", dummy); |
---|
262 | |
---|
263 | if (options->lambdaWithClustering) |
---|
264 | sprintf(dummy, "yes"); |
---|
265 | else |
---|
266 | sprintf(dummy, "no"); |
---|
267 | fprintf(vis_stdout, "HYB: hybrid_lambda_with_clustering = %s\n", dummy); |
---|
268 | |
---|
269 | if (options->synchronizeTr) |
---|
270 | sprintf(dummy, "yes"); |
---|
271 | else |
---|
272 | sprintf(dummy, "no"); |
---|
273 | fprintf(vis_stdout, "HYB: hybrid_synchronize_tr = %s\n", dummy); |
---|
274 | |
---|
275 | if (options->imgKeepPiInTr) |
---|
276 | sprintf(dummy, "yes"); |
---|
277 | else |
---|
278 | sprintf(dummy, "no"); |
---|
279 | fprintf(vis_stdout, "HYB: hybrid_img_keep_pi = %s\n", dummy); |
---|
280 | |
---|
281 | if (options->preKeepPiInTr) |
---|
282 | sprintf(dummy, "yes"); |
---|
283 | else |
---|
284 | sprintf(dummy, "no"); |
---|
285 | fprintf(vis_stdout, "HYB: hybrid_pre_keep_pi = %s\n", dummy); |
---|
286 | |
---|
287 | if (options->preCanonical) |
---|
288 | sprintf(dummy, "yes"); |
---|
289 | else |
---|
290 | sprintf(dummy, "no"); |
---|
291 | fprintf(vis_stdout, "HYB: hybrid_pre_canonical = %s\n", dummy); |
---|
292 | |
---|
293 | switch (options->trMethod) { |
---|
294 | case Img_Iwls95_c : |
---|
295 | sprintf(dummy, "IWLS95"); |
---|
296 | break; |
---|
297 | case Img_Mlp_c : |
---|
298 | sprintf(dummy, "MLP"); |
---|
299 | break; |
---|
300 | default : |
---|
301 | sprintf(dummy, "invalid"); |
---|
302 | break; |
---|
303 | } |
---|
304 | fprintf(vis_stdout, "HYB: hybrid_tr_method = %s\n", dummy); |
---|
305 | |
---|
306 | FREE(options); |
---|
307 | } |
---|
308 | |
---|
309 | |
---|
310 | /*---------------------------------------------------------------------------*/ |
---|
311 | /* Definition of internal functions */ |
---|
312 | /*---------------------------------------------------------------------------*/ |
---|
313 | |
---|
314 | |
---|
315 | /**Function******************************************************************** |
---|
316 | |
---|
317 | Synopsis [Decides whether to split or to conjoin.] |
---|
318 | |
---|
319 | Description [Decides whether to split or to conjoin.] |
---|
320 | |
---|
321 | SideEffects [] |
---|
322 | |
---|
323 | ******************************************************************************/ |
---|
324 | int |
---|
325 | ImgDecideSplitOrConjoin(ImgTfmInfo_t *info, array_t *vector, mdd_t *from, |
---|
326 | int preFlag, array_t *relationArray, |
---|
327 | mdd_t *cofactorCube, mdd_t *abstractCube, |
---|
328 | int useBothFlag, int depth) |
---|
329 | { |
---|
330 | int conjoin = 0; |
---|
331 | float lambda, improvedLambda; |
---|
332 | int vectorBddSize, vectorSize; |
---|
333 | int improved; |
---|
334 | int minDepth; |
---|
335 | int checkSpecialCases; |
---|
336 | int checkImprovement; |
---|
337 | int relationSize = 0; |
---|
338 | |
---|
339 | if (!preFlag) { |
---|
340 | if (vector && array_n(vector) <= 2) |
---|
341 | return(0); /* terminal case */ |
---|
342 | } |
---|
343 | |
---|
344 | if (info->option->decideMode == 1 || info->option->decideMode == 3) |
---|
345 | checkSpecialCases = 1; |
---|
346 | else |
---|
347 | checkSpecialCases = 0; |
---|
348 | if (info->option->decideMode == 2 || info->option->decideMode == 3) |
---|
349 | checkImprovement = 1; |
---|
350 | else |
---|
351 | checkImprovement = 0; |
---|
352 | |
---|
353 | if (checkSpecialCases) { |
---|
354 | if (vector && array_n(vector) <= info->option->conjoinVectorSize) { |
---|
355 | if (preFlag) |
---|
356 | info->nConjoinsB++; |
---|
357 | else |
---|
358 | info->nConjoins++; |
---|
359 | if (info->option->printLambda) { |
---|
360 | fprintf(vis_stdout, "%d: conjoin - small vector size (%d)\n", |
---|
361 | depth, array_n(vector)); |
---|
362 | } |
---|
363 | return(1); |
---|
364 | } |
---|
365 | } |
---|
366 | |
---|
367 | if (preFlag) |
---|
368 | minDepth = info->option->preSplitMinDepth; |
---|
369 | else |
---|
370 | minDepth = info->option->splitMinDepth; |
---|
371 | |
---|
372 | if (useBothFlag && relationArray && vector) { |
---|
373 | lambda = ComputeSupportLambda(info, relationArray, cofactorCube, |
---|
374 | abstractCube, from, vector, |
---|
375 | 0, preFlag, &improvedLambda); |
---|
376 | } else if (relationArray) { |
---|
377 | if (checkSpecialCases) { |
---|
378 | if (array_n(relationArray) <= info->option->conjoinRelationSize || |
---|
379 | (relationSize = (int)bdd_size_multiple(relationArray)) <= |
---|
380 | info->option->conjoinRelationBddSize) { |
---|
381 | if (preFlag) |
---|
382 | info->nConjoinsB++; |
---|
383 | else |
---|
384 | info->nConjoins++; |
---|
385 | if (info->option->printLambda) { |
---|
386 | fprintf(vis_stdout, "%d: conjoin - small relation array (%d, %ld)\n", |
---|
387 | depth, array_n(relationArray), |
---|
388 | bdd_size_multiple(relationArray)); |
---|
389 | } |
---|
390 | return(1); |
---|
391 | } |
---|
392 | } |
---|
393 | |
---|
394 | lambda = ComputeSupportLambda(info, relationArray, cofactorCube, |
---|
395 | abstractCube, from, NIL(array_t), |
---|
396 | 0, preFlag, &improvedLambda); |
---|
397 | } else { |
---|
398 | int i; |
---|
399 | ImgComponent_t *comp; |
---|
400 | |
---|
401 | relationArray = array_alloc(mdd_t *, 0); |
---|
402 | for (i = 0; i < array_n(vector); i++) { |
---|
403 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
404 | array_insert_last(mdd_t *, relationArray, comp->func); |
---|
405 | } |
---|
406 | |
---|
407 | lambda = ComputeSupportLambda(info, relationArray, NIL(mdd_t), |
---|
408 | NIL(mdd_t), from, NIL(array_t), |
---|
409 | 1, preFlag, &improvedLambda); |
---|
410 | |
---|
411 | array_free(relationArray); |
---|
412 | } |
---|
413 | |
---|
414 | if ((preFlag == 0 && lambda <= info->option->lambdaThreshold) || |
---|
415 | (preFlag == 1 && lambda <= info->option->preLambdaThreshold)) { |
---|
416 | if (preFlag) |
---|
417 | info->nConjoinsB++; |
---|
418 | else |
---|
419 | info->nConjoins++; |
---|
420 | if (info->option->printLambda) { |
---|
421 | fprintf(vis_stdout, "%d: conjoin - small lambda (%.2f)\n", |
---|
422 | depth, lambda); |
---|
423 | } |
---|
424 | conjoin = 1; |
---|
425 | } else { |
---|
426 | if (checkImprovement) { |
---|
427 | if (vector) { |
---|
428 | vectorBddSize = ImgVectorBddSize(vector); |
---|
429 | vectorSize = array_n(vector); |
---|
430 | if (depth == minDepth || |
---|
431 | improvedLambda >= info->option->improveLambda || |
---|
432 | ((float)vectorBddSize * 100.0 / (float)info->prevVectorBddSize) <= |
---|
433 | info->option->improveVectorBddSize || |
---|
434 | (info->prevVectorSize - vectorSize) >= |
---|
435 | info->option->improveVectorSize) { |
---|
436 | improved = 1; |
---|
437 | } else |
---|
438 | improved = 0; |
---|
439 | info->prevVectorBddSize = vectorBddSize; |
---|
440 | info->prevVectorSize = vectorSize; |
---|
441 | } else { |
---|
442 | if (relationSize) |
---|
443 | vectorBddSize = relationSize; |
---|
444 | else |
---|
445 | vectorBddSize = (int)bdd_size_multiple(relationArray); |
---|
446 | if (depth == minDepth || |
---|
447 | improvedLambda >= info->option->improveLambda || |
---|
448 | ((float)vectorBddSize * 100.0 / (float)info->prevVectorBddSize) <= |
---|
449 | info->option->improveVectorBddSize) { |
---|
450 | improved = 1; |
---|
451 | } else |
---|
452 | improved = 0; |
---|
453 | info->prevVectorBddSize = vectorBddSize; |
---|
454 | } |
---|
455 | if (improved) { |
---|
456 | if (preFlag) |
---|
457 | info->nSplitsB++; |
---|
458 | else |
---|
459 | info->nSplits++; |
---|
460 | if (info->option->printLambda) { |
---|
461 | fprintf(vis_stdout, "%d: split - big lambda (%.2f) - improved\n", |
---|
462 | depth, lambda); |
---|
463 | } |
---|
464 | conjoin = 0; |
---|
465 | } else { |
---|
466 | if (preFlag) |
---|
467 | info->nConjoinsB++; |
---|
468 | else |
---|
469 | info->nConjoins++; |
---|
470 | if (info->option->printLambda) { |
---|
471 | fprintf(vis_stdout, "%d: conjon - big lambda (%.2f) - not improved\n", |
---|
472 | depth, lambda); |
---|
473 | } |
---|
474 | conjoin = 1; |
---|
475 | } |
---|
476 | } else { |
---|
477 | if (preFlag) |
---|
478 | info->nSplitsB++; |
---|
479 | else |
---|
480 | info->nSplits++; |
---|
481 | if (info->option->printLambda) { |
---|
482 | fprintf(vis_stdout, "%d: split - big lambda (%.2f)\n", |
---|
483 | depth, lambda); |
---|
484 | } |
---|
485 | conjoin = 0; |
---|
486 | } |
---|
487 | } |
---|
488 | |
---|
489 | return(conjoin); /* 0 : split, 1 : conjoin */ |
---|
490 | } |
---|
491 | |
---|
492 | |
---|
493 | /**Function******************************************************************** |
---|
494 | |
---|
495 | Synopsis [Computes an image by transition relation.] |
---|
496 | |
---|
497 | Description [Computes an image by transition relation.] |
---|
498 | |
---|
499 | SideEffects [] |
---|
500 | |
---|
501 | ******************************************************************************/ |
---|
502 | mdd_t * |
---|
503 | ImgImageByHybrid(ImgTfmInfo_t *info, array_t *vector, mdd_t *from) |
---|
504 | { |
---|
505 | int i, j, nVars; |
---|
506 | array_t *relationArray; |
---|
507 | mdd_t *result, *domain, *relation, *var, *nextVar; |
---|
508 | ImgComponent_t *comp; |
---|
509 | char *support; |
---|
510 | array_t *smoothVarsBddArray, *introducedVarsBddArray; |
---|
511 | array_t *domainVarsBddArray; |
---|
512 | int bddId; |
---|
513 | |
---|
514 | if (from && bdd_is_tautology(from, 0)) |
---|
515 | return(mdd_zero(info->manager)); |
---|
516 | |
---|
517 | nVars = info->nVars; |
---|
518 | support = ALLOC(char, sizeof(char) * nVars); |
---|
519 | memset(support, 0, sizeof(char) * nVars); |
---|
520 | |
---|
521 | relationArray = array_alloc(mdd_t *, 0); |
---|
522 | introducedVarsBddArray = array_alloc(mdd_t *, 0); |
---|
523 | |
---|
524 | for (i = 0; i < array_n(vector); i++) { |
---|
525 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
526 | if (comp->intermediate) { |
---|
527 | relation = mdd_xnor(comp->var, comp->func); |
---|
528 | bddId = (int)bdd_top_var_id(comp->var); |
---|
529 | support[bddId] = 1; |
---|
530 | } else { |
---|
531 | nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); |
---|
532 | relation = mdd_xnor(nextVar, comp->func); |
---|
533 | array_insert_last(mdd_t *, introducedVarsBddArray, nextVar); |
---|
534 | } |
---|
535 | array_insert_last(mdd_t *, relationArray, relation); |
---|
536 | |
---|
537 | for (j = 0; j < nVars; j++) |
---|
538 | support[j] = support[j] | comp->support[j]; |
---|
539 | } |
---|
540 | |
---|
541 | if (from && (!bdd_is_tautology(from, 1))) { |
---|
542 | if (info->option->reorderWithFrom) |
---|
543 | array_insert_last(mdd_t *, relationArray, mdd_dup(from)); |
---|
544 | |
---|
545 | comp = ImgComponentAlloc(info); |
---|
546 | comp->func = from; |
---|
547 | ImgComponentGetSupport(comp); |
---|
548 | for (i = 0; i < nVars; i++) |
---|
549 | support[i] = support[i] | comp->support[i]; |
---|
550 | comp->func = NIL(mdd_t); |
---|
551 | ImgComponentFree(comp); |
---|
552 | } |
---|
553 | |
---|
554 | smoothVarsBddArray = array_alloc(mdd_t *, 0); |
---|
555 | if (!info->option->reorderWithFrom) |
---|
556 | domainVarsBddArray = array_alloc(mdd_t *, 0); |
---|
557 | else |
---|
558 | domainVarsBddArray = NIL(array_t); |
---|
559 | for (i = 0; i < nVars; i++) { |
---|
560 | if (support[i]) { |
---|
561 | var = bdd_var_with_index(info->manager, i); |
---|
562 | if ((!from) || info->option->reorderWithFrom) |
---|
563 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
564 | else { |
---|
565 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *)) || |
---|
566 | (info->intermediateVarsTable && |
---|
567 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
568 | NIL(char *)))) { |
---|
569 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
570 | } else { |
---|
571 | array_insert_last(mdd_t *, domainVarsBddArray, var); |
---|
572 | } |
---|
573 | } |
---|
574 | } |
---|
575 | } |
---|
576 | FREE(support); |
---|
577 | |
---|
578 | if ((!from) || info->option->reorderWithFrom) { |
---|
579 | result = ImgMultiwayLinearAndSmooth(info->manager, |
---|
580 | relationArray, |
---|
581 | smoothVarsBddArray, |
---|
582 | introducedVarsBddArray, |
---|
583 | info->option->trMethod, |
---|
584 | Img_Forward_c, |
---|
585 | info->trmOption); |
---|
586 | } else { |
---|
587 | result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, |
---|
588 | relationArray, from, |
---|
589 | smoothVarsBddArray, |
---|
590 | domainVarsBddArray, |
---|
591 | introducedVarsBddArray, |
---|
592 | info->option->trMethod, |
---|
593 | Img_Forward_c, |
---|
594 | info->trmOption); |
---|
595 | mdd_array_free(domainVarsBddArray); |
---|
596 | } |
---|
597 | mdd_array_free(relationArray); |
---|
598 | mdd_array_free(smoothVarsBddArray); |
---|
599 | mdd_array_free(introducedVarsBddArray); |
---|
600 | domain = ImgSubstitute(result, info->functionData, Img_R2D_c); |
---|
601 | mdd_free(result); |
---|
602 | return(domain); |
---|
603 | } |
---|
604 | |
---|
605 | |
---|
606 | /**Function******************************************************************** |
---|
607 | |
---|
608 | Synopsis [Computes an image by transition relation.] |
---|
609 | |
---|
610 | Description [Computes an image by transition relation.] |
---|
611 | |
---|
612 | SideEffects [] |
---|
613 | |
---|
614 | ******************************************************************************/ |
---|
615 | mdd_t * |
---|
616 | ImgImageByHybridWithStaticSplit(ImgTfmInfo_t *info, array_t *vector, |
---|
617 | mdd_t *from, array_t *relationArray, |
---|
618 | mdd_t *cofactorCube, mdd_t *abstractCube) |
---|
619 | { |
---|
620 | int i, j; |
---|
621 | array_t *mergedRelationArray; |
---|
622 | mdd_t *result, *domain, *relation, *var, *nextVar; |
---|
623 | ImgComponent_t *comp, *supportComp; |
---|
624 | int nVars; |
---|
625 | char *support; |
---|
626 | array_t *smoothVarsBddArray, *introducedVarsBddArray; |
---|
627 | array_t *domainVarsBddArray; |
---|
628 | |
---|
629 | if (from && bdd_is_tautology(from, 0)) |
---|
630 | return(mdd_zero(info->manager)); |
---|
631 | |
---|
632 | if (cofactorCube && abstractCube) { |
---|
633 | if (!bdd_is_tautology(cofactorCube, 1) && |
---|
634 | !bdd_is_tautology(abstractCube, 1)) { |
---|
635 | mergedRelationArray = ImgGetCofactoredAbstractedRelationArray( |
---|
636 | info->manager, relationArray, |
---|
637 | cofactorCube, abstractCube); |
---|
638 | } else if (!bdd_is_tautology(cofactorCube, 1)) { |
---|
639 | mergedRelationArray = ImgGetCofactoredRelationArray(relationArray, |
---|
640 | cofactorCube); |
---|
641 | } else if (!bdd_is_tautology(abstractCube, 1)) { |
---|
642 | mergedRelationArray = ImgGetAbstractedRelationArray(info->manager, |
---|
643 | relationArray, |
---|
644 | abstractCube); |
---|
645 | } else |
---|
646 | mergedRelationArray = mdd_array_duplicate(relationArray); |
---|
647 | } else |
---|
648 | mergedRelationArray = mdd_array_duplicate(relationArray); |
---|
649 | |
---|
650 | nVars = info->nVars; |
---|
651 | support = ALLOC(char, sizeof(char) * nVars); |
---|
652 | memset(support, 0, sizeof(char) * nVars); |
---|
653 | |
---|
654 | supportComp = ImgComponentAlloc(info); |
---|
655 | for (i = 0; i < array_n(mergedRelationArray); i++) { |
---|
656 | supportComp->func = array_fetch(mdd_t *, mergedRelationArray, i);; |
---|
657 | ImgSupportClear(info, supportComp->support); |
---|
658 | ImgComponentGetSupport(supportComp); |
---|
659 | for (j = 0; j < nVars; j++) |
---|
660 | support[j] = support[j] | supportComp->support[j]; |
---|
661 | } |
---|
662 | |
---|
663 | if (vector && array_n(vector) > 0) { |
---|
664 | for (i = 0; i < array_n(vector); i++) { |
---|
665 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
666 | if (comp->intermediate) { |
---|
667 | relation = mdd_xnor(comp->var, comp->func); |
---|
668 | support[(int)bdd_top_var_id(comp->var)] = 1; |
---|
669 | } else { |
---|
670 | nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); |
---|
671 | relation = mdd_xnor(nextVar, comp->func); |
---|
672 | support[(int)bdd_top_var_id(nextVar)] = 1; |
---|
673 | mdd_free(nextVar); |
---|
674 | } |
---|
675 | array_insert_last(mdd_t *, mergedRelationArray, relation); |
---|
676 | |
---|
677 | for (j = 0; j < nVars; j++) |
---|
678 | support[j] = support[j] | comp->support[j]; |
---|
679 | } |
---|
680 | } |
---|
681 | |
---|
682 | if (from) { |
---|
683 | if ((!bdd_is_tautology(from, 1)) && info->option->reorderWithFrom) |
---|
684 | array_insert_last(mdd_t *, mergedRelationArray, mdd_dup(from)); |
---|
685 | |
---|
686 | supportComp->func = from; |
---|
687 | ImgSupportClear(info, supportComp->support); |
---|
688 | ImgComponentGetSupport(supportComp); |
---|
689 | for (i = 0; i < nVars; i++) |
---|
690 | support[i] = support[i] | supportComp->support[i]; |
---|
691 | } |
---|
692 | supportComp->func = NIL(mdd_t); |
---|
693 | ImgComponentFree(supportComp); |
---|
694 | |
---|
695 | smoothVarsBddArray = array_alloc(mdd_t *, 0); |
---|
696 | introducedVarsBddArray = array_alloc(mdd_t *, 0); |
---|
697 | if (!info->option->reorderWithFrom) |
---|
698 | domainVarsBddArray = array_alloc(mdd_t *, 0); |
---|
699 | else |
---|
700 | domainVarsBddArray = NIL(array_t); |
---|
701 | for (i = 0; i < nVars; i++) { |
---|
702 | if (support[i]) { |
---|
703 | var = bdd_var_with_index(info->manager, i); |
---|
704 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) |
---|
705 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
706 | else if ((!from) || info->option->reorderWithFrom) |
---|
707 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
708 | else { |
---|
709 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *)) || |
---|
710 | (info->intermediateVarsTable && |
---|
711 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
712 | NIL(char *)))) { |
---|
713 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
714 | } else { |
---|
715 | array_insert_last(mdd_t *, domainVarsBddArray, var); |
---|
716 | } |
---|
717 | } |
---|
718 | } |
---|
719 | } |
---|
720 | FREE(support); |
---|
721 | |
---|
722 | if ((!from) || info->option->reorderWithFrom) { |
---|
723 | result = ImgMultiwayLinearAndSmooth(info->manager, |
---|
724 | mergedRelationArray, |
---|
725 | smoothVarsBddArray, |
---|
726 | introducedVarsBddArray, |
---|
727 | info->option->trMethod, |
---|
728 | Img_Forward_c, |
---|
729 | info->trmOption); |
---|
730 | } else { |
---|
731 | result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, |
---|
732 | mergedRelationArray, from, |
---|
733 | smoothVarsBddArray, |
---|
734 | domainVarsBddArray, |
---|
735 | introducedVarsBddArray, |
---|
736 | info->option->trMethod, |
---|
737 | Img_Forward_c, |
---|
738 | info->trmOption); |
---|
739 | mdd_array_free(domainVarsBddArray); |
---|
740 | } |
---|
741 | mdd_array_free(mergedRelationArray); |
---|
742 | mdd_array_free(smoothVarsBddArray); |
---|
743 | mdd_array_free(introducedVarsBddArray); |
---|
744 | |
---|
745 | domain = ImgSubstitute(result, info->functionData, Img_R2D_c); |
---|
746 | mdd_free(result); |
---|
747 | return(domain); |
---|
748 | } |
---|
749 | |
---|
750 | |
---|
751 | /**Function******************************************************************** |
---|
752 | |
---|
753 | Synopsis [Computes a preimage by transition relation.] |
---|
754 | |
---|
755 | Description [Computes a preimage by transition relation.] |
---|
756 | |
---|
757 | SideEffects [] |
---|
758 | |
---|
759 | ******************************************************************************/ |
---|
760 | mdd_t * |
---|
761 | ImgPreImageByHybrid(ImgTfmInfo_t *info, array_t *vector, mdd_t *from) |
---|
762 | { |
---|
763 | int i, j, nVars; |
---|
764 | array_t *relationArray; |
---|
765 | mdd_t *result, *relation, *var, *nextVar; |
---|
766 | ImgComponent_t *comp; |
---|
767 | char *support; |
---|
768 | array_t *smoothVarsBddArray, *introducedVarsBddArray; |
---|
769 | array_t *rangeVarsBddArray; |
---|
770 | mdd_t *fromRange; |
---|
771 | |
---|
772 | if (bdd_is_tautology(from, 1)) |
---|
773 | return(mdd_one(info->manager)); |
---|
774 | else if (bdd_is_tautology(from, 0)) |
---|
775 | return(mdd_zero(info->manager)); |
---|
776 | |
---|
777 | nVars = info->nVars; |
---|
778 | support = ALLOC(char, sizeof(char) * nVars); |
---|
779 | memset(support, 0, sizeof(char) * nVars); |
---|
780 | |
---|
781 | relationArray = array_alloc(mdd_t *, 0); |
---|
782 | |
---|
783 | for (i = 0; i < array_n(vector); i++) { |
---|
784 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
785 | if (comp->intermediate) { |
---|
786 | relation = mdd_xnor(comp->var, comp->func); |
---|
787 | support[(int)bdd_top_var_id(comp->var)] = 1; |
---|
788 | } else { |
---|
789 | nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); |
---|
790 | relation = mdd_xnor(nextVar, comp->func); |
---|
791 | support[(int)bdd_top_var_id(nextVar)] = 1; |
---|
792 | mdd_free(nextVar); |
---|
793 | } |
---|
794 | array_insert_last(mdd_t *, relationArray, relation); |
---|
795 | |
---|
796 | for (j = 0; j < nVars; j++) |
---|
797 | support[j] = support[j] | comp->support[j]; |
---|
798 | } |
---|
799 | |
---|
800 | fromRange = ImgSubstitute(from, info->functionData, Img_D2R_c); |
---|
801 | comp = ImgComponentAlloc(info); |
---|
802 | comp->func = fromRange; |
---|
803 | ImgComponentGetSupport(comp); |
---|
804 | for (i = 0; i < nVars; i++) |
---|
805 | support[i] = support[i] | comp->support[i]; |
---|
806 | comp->func = NIL(mdd_t); |
---|
807 | ImgComponentFree(comp); |
---|
808 | |
---|
809 | smoothVarsBddArray = array_alloc(mdd_t *, 0); |
---|
810 | introducedVarsBddArray = array_alloc(mdd_t *, 0); |
---|
811 | if (!info->option->preReorderWithFrom) |
---|
812 | rangeVarsBddArray = array_alloc(mdd_t *, 0); |
---|
813 | else |
---|
814 | rangeVarsBddArray = NIL(array_t); |
---|
815 | for (i = 0; i < nVars; i++) { |
---|
816 | if (support[i]) { |
---|
817 | var = bdd_var_with_index(info->manager, i); |
---|
818 | if (info->intermediateVarsTable && |
---|
819 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
820 | NIL(char *))) { |
---|
821 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
822 | } else if (st_lookup(info->rangeVarsTable, (char *)(long)i, |
---|
823 | NIL(char *))) { |
---|
824 | if (info->option->preReorderWithFrom) |
---|
825 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
826 | else |
---|
827 | array_insert_last(mdd_t *, rangeVarsBddArray, var); |
---|
828 | } else { |
---|
829 | if (info->preKeepPiInTr) |
---|
830 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
831 | else { |
---|
832 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
833 | NIL(char *))) { |
---|
834 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
835 | } else |
---|
836 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
837 | } |
---|
838 | } |
---|
839 | } |
---|
840 | } |
---|
841 | FREE(support); |
---|
842 | |
---|
843 | if (info->option->preReorderWithFrom) { |
---|
844 | array_insert_last(mdd_t *, relationArray, fromRange); |
---|
845 | result = ImgMultiwayLinearAndSmooth(info->manager, |
---|
846 | relationArray, |
---|
847 | smoothVarsBddArray, |
---|
848 | introducedVarsBddArray, |
---|
849 | info->option->trMethod, |
---|
850 | Img_Backward_c, |
---|
851 | info->trmOption); |
---|
852 | } else { |
---|
853 | result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, |
---|
854 | relationArray, fromRange, |
---|
855 | smoothVarsBddArray, |
---|
856 | rangeVarsBddArray, |
---|
857 | introducedVarsBddArray, |
---|
858 | info->option->trMethod, |
---|
859 | Img_Backward_c, |
---|
860 | info->trmOption); |
---|
861 | mdd_free(fromRange); |
---|
862 | mdd_array_free(rangeVarsBddArray); |
---|
863 | } |
---|
864 | mdd_array_free(relationArray); |
---|
865 | mdd_array_free(smoothVarsBddArray); |
---|
866 | mdd_array_free(introducedVarsBddArray); |
---|
867 | return(result); |
---|
868 | } |
---|
869 | |
---|
870 | |
---|
871 | /**Function******************************************************************** |
---|
872 | |
---|
873 | Synopsis [Computes a preimage by transition relation.] |
---|
874 | |
---|
875 | Description [Computes a preimage by transition relation.] |
---|
876 | |
---|
877 | SideEffects [] |
---|
878 | |
---|
879 | ******************************************************************************/ |
---|
880 | mdd_t * |
---|
881 | ImgPreImageByHybridWithStaticSplit(ImgTfmInfo_t *info, array_t *vector, |
---|
882 | mdd_t *from, array_t *relationArray, |
---|
883 | mdd_t *cofactorCube, mdd_t *abstractCube) |
---|
884 | { |
---|
885 | int i, j; |
---|
886 | array_t *mergedRelationArray; |
---|
887 | mdd_t *result, *relation, *var, *nextVar, *fromRange; |
---|
888 | ImgComponent_t *comp, *supportComp; |
---|
889 | int nVars; |
---|
890 | char *support; |
---|
891 | array_t *smoothVarsBddArray, *introducedVarsBddArray; |
---|
892 | array_t *rangeVarsBddArray; |
---|
893 | |
---|
894 | if (bdd_is_tautology(from, 1)) |
---|
895 | return(mdd_one(info->manager)); |
---|
896 | if (bdd_is_tautology(from, 0)) |
---|
897 | return(mdd_zero(info->manager)); |
---|
898 | |
---|
899 | if (cofactorCube && abstractCube) { |
---|
900 | if (!bdd_is_tautology(cofactorCube, 1) && |
---|
901 | !bdd_is_tautology(abstractCube, 1)) { |
---|
902 | mergedRelationArray = ImgGetCofactoredAbstractedRelationArray( |
---|
903 | info->manager, relationArray, |
---|
904 | cofactorCube, abstractCube); |
---|
905 | } else if (!bdd_is_tautology(cofactorCube, 1)) { |
---|
906 | mergedRelationArray = ImgGetCofactoredRelationArray(relationArray, |
---|
907 | cofactorCube); |
---|
908 | } else if (!bdd_is_tautology(abstractCube, 1)) { |
---|
909 | mergedRelationArray = ImgGetAbstractedRelationArray(info->manager, |
---|
910 | relationArray, |
---|
911 | abstractCube); |
---|
912 | } else |
---|
913 | mergedRelationArray = mdd_array_duplicate(relationArray); |
---|
914 | } else |
---|
915 | mergedRelationArray = mdd_array_duplicate(relationArray); |
---|
916 | |
---|
917 | nVars = info->nVars; |
---|
918 | support = ALLOC(char, sizeof(char) * nVars); |
---|
919 | memset(support, 0, sizeof(char) * nVars); |
---|
920 | |
---|
921 | supportComp = ImgComponentAlloc(info); |
---|
922 | for (i = 0; i < array_n(mergedRelationArray); i++) { |
---|
923 | supportComp->func = array_fetch(mdd_t *, mergedRelationArray, i);; |
---|
924 | ImgSupportClear(info, supportComp->support); |
---|
925 | ImgComponentGetSupport(supportComp); |
---|
926 | for (j = 0; j < nVars; j++) |
---|
927 | support[j] = support[j] | supportComp->support[j]; |
---|
928 | } |
---|
929 | |
---|
930 | if (vector && array_n(vector) > 0) { |
---|
931 | for (i = 0; i < array_n(vector); i++) { |
---|
932 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
933 | if (comp->intermediate) { |
---|
934 | relation = mdd_xnor(comp->var, comp->func); |
---|
935 | support[(int)bdd_top_var_id(comp->var)] = 1; |
---|
936 | } else { |
---|
937 | nextVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); |
---|
938 | relation = mdd_xnor(nextVar, comp->func); |
---|
939 | support[(int)bdd_top_var_id(nextVar)] = 1; |
---|
940 | mdd_free(nextVar); |
---|
941 | } |
---|
942 | array_insert_last(mdd_t *, mergedRelationArray, relation); |
---|
943 | |
---|
944 | for (j = 0; j < nVars; j++) |
---|
945 | support[j] = support[j] | comp->support[j]; |
---|
946 | } |
---|
947 | } |
---|
948 | |
---|
949 | fromRange = ImgSubstitute(from, info->functionData, Img_D2R_c); |
---|
950 | supportComp->func = fromRange; |
---|
951 | ImgSupportClear(info, supportComp->support); |
---|
952 | ImgComponentGetSupport(supportComp); |
---|
953 | for (i = 0; i < nVars; i++) |
---|
954 | support[i] = support[i] | supportComp->support[i]; |
---|
955 | supportComp->func = NIL(mdd_t); |
---|
956 | ImgComponentFree(supportComp); |
---|
957 | |
---|
958 | smoothVarsBddArray = array_alloc(mdd_t *, 0); |
---|
959 | introducedVarsBddArray = array_alloc(mdd_t *, 0); |
---|
960 | if (!info->option->preReorderWithFrom) |
---|
961 | rangeVarsBddArray = array_alloc(mdd_t *, 0); |
---|
962 | else |
---|
963 | rangeVarsBddArray = NIL(array_t); |
---|
964 | for (i = 0; i < nVars; i++) { |
---|
965 | if (support[i]) { |
---|
966 | var = bdd_var_with_index(info->manager, i); |
---|
967 | if (info->intermediateVarsTable && |
---|
968 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
969 | NIL(char *))) { |
---|
970 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
971 | } else if (st_lookup(info->rangeVarsTable, (char *)(long)i, |
---|
972 | NIL(char *))) { |
---|
973 | if (info->option->preReorderWithFrom) |
---|
974 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
975 | else |
---|
976 | array_insert_last(mdd_t *, rangeVarsBddArray, var); |
---|
977 | } else { |
---|
978 | if (info->preKeepPiInTr) |
---|
979 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
980 | else { |
---|
981 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
982 | NIL(char *))) { |
---|
983 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
984 | } else |
---|
985 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
986 | } |
---|
987 | } |
---|
988 | } |
---|
989 | } |
---|
990 | FREE(support); |
---|
991 | |
---|
992 | if (info->option->preReorderWithFrom) { |
---|
993 | array_insert_last(mdd_t *, mergedRelationArray, fromRange); |
---|
994 | result = ImgMultiwayLinearAndSmooth(info->manager, |
---|
995 | mergedRelationArray, |
---|
996 | smoothVarsBddArray, |
---|
997 | introducedVarsBddArray, |
---|
998 | info->option->trMethod, |
---|
999 | Img_Backward_c, |
---|
1000 | info->trmOption); |
---|
1001 | } else { |
---|
1002 | result = ImgMultiwayLinearAndSmoothWithFrom(info->manager, |
---|
1003 | mergedRelationArray, fromRange, |
---|
1004 | smoothVarsBddArray, |
---|
1005 | rangeVarsBddArray, |
---|
1006 | introducedVarsBddArray, |
---|
1007 | info->option->trMethod, |
---|
1008 | Img_Backward_c, |
---|
1009 | info->trmOption); |
---|
1010 | mdd_free(fromRange); |
---|
1011 | mdd_array_free(rangeVarsBddArray); |
---|
1012 | } |
---|
1013 | mdd_array_free(mergedRelationArray); |
---|
1014 | mdd_array_free(smoothVarsBddArray); |
---|
1015 | mdd_array_free(introducedVarsBddArray); |
---|
1016 | |
---|
1017 | return(result); |
---|
1018 | } |
---|
1019 | |
---|
1020 | |
---|
1021 | /**Function******************************************************************** |
---|
1022 | |
---|
1023 | Synopsis [Checks whether a vector is equivalent to a relation array.] |
---|
1024 | |
---|
1025 | Description [Checks whether a vector is equivalent to a relation array.] |
---|
1026 | |
---|
1027 | SideEffects [] |
---|
1028 | |
---|
1029 | ******************************************************************************/ |
---|
1030 | int |
---|
1031 | ImgCheckEquivalence(ImgTfmInfo_t *info, array_t *vector, array_t *relationArray, |
---|
1032 | mdd_t *cofactorCube, mdd_t *abstractCube, int preFlag) |
---|
1033 | { |
---|
1034 | int i, equal; |
---|
1035 | mdd_t *product1, *product2; |
---|
1036 | mdd_t *var, *tmp, *relation; |
---|
1037 | ImgComponent_t *comp; |
---|
1038 | array_t *newRelationArray, *tmpRelationArray; |
---|
1039 | array_t *domainVarBddArray, *quantifyVarBddArray; |
---|
1040 | |
---|
1041 | tmpRelationArray = array_alloc(mdd_t *, 0); |
---|
1042 | for (i = 0; i < array_n(vector); i++) { |
---|
1043 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
1044 | if (comp->intermediate) |
---|
1045 | relation = mdd_xnor(comp->var, comp->func); |
---|
1046 | else { |
---|
1047 | var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); |
---|
1048 | relation = mdd_xnor(var, comp->func); |
---|
1049 | mdd_free(var); |
---|
1050 | } |
---|
1051 | array_insert_last(mdd_t *, tmpRelationArray, relation); |
---|
1052 | } |
---|
1053 | |
---|
1054 | if (preFlag) { |
---|
1055 | if (info->preKeepPiInTr) { |
---|
1056 | quantifyVarBddArray = array_alloc(mdd_t *, 0); |
---|
1057 | domainVarBddArray = array_join(info->domainVarBddArray, |
---|
1058 | info->quantifyVarBddArray); |
---|
1059 | } else { |
---|
1060 | quantifyVarBddArray = info->quantifyVarBddArray; |
---|
1061 | domainVarBddArray = info->domainVarBddArray; |
---|
1062 | } |
---|
1063 | newRelationArray = ImgClusterRelationArray(info->manager, |
---|
1064 | info->functionData, info->option->trMethod, Img_Backward_c, |
---|
1065 | info->trmOption, tmpRelationArray, domainVarBddArray, |
---|
1066 | quantifyVarBddArray, info->rangeVarBddArray, |
---|
1067 | NIL(array_t *), NIL(array_t *), 0); |
---|
1068 | if (info->preKeepPiInTr) { |
---|
1069 | array_free(quantifyVarBddArray); |
---|
1070 | array_free(domainVarBddArray); |
---|
1071 | } |
---|
1072 | } else { |
---|
1073 | newRelationArray = ImgClusterRelationArray(info->manager, |
---|
1074 | info->functionData, info->option->trMethod, Img_Forward_c, |
---|
1075 | info->trmOption, tmpRelationArray, info->domainVarBddArray, |
---|
1076 | info->quantifyVarBddArray, info->rangeVarBddArray, |
---|
1077 | NIL(array_t *), NIL(array_t *), 0); |
---|
1078 | } |
---|
1079 | mdd_array_free(tmpRelationArray); |
---|
1080 | |
---|
1081 | product1 = mdd_one(info->manager); |
---|
1082 | for (i = 0; i < array_n(newRelationArray); i++) { |
---|
1083 | relation = array_fetch(mdd_t *, newRelationArray, i); |
---|
1084 | tmp = product1; |
---|
1085 | product1 = mdd_and(tmp, relation, 1, 1); |
---|
1086 | mdd_free(tmp); |
---|
1087 | } |
---|
1088 | mdd_array_free(newRelationArray); |
---|
1089 | |
---|
1090 | if (cofactorCube && abstractCube) { |
---|
1091 | newRelationArray = ImgGetCofactoredAbstractedRelationArray(info->manager, |
---|
1092 | relationArray, cofactorCube, abstractCube); |
---|
1093 | } else |
---|
1094 | newRelationArray = relationArray; |
---|
1095 | |
---|
1096 | product2 = mdd_one(info->manager); |
---|
1097 | for (i = 0; i < array_n(newRelationArray); i++) { |
---|
1098 | relation = array_fetch(mdd_t *, newRelationArray, i); |
---|
1099 | tmp = product2; |
---|
1100 | product2 = mdd_and(tmp, relation, 1, 1); |
---|
1101 | mdd_free(tmp); |
---|
1102 | } |
---|
1103 | |
---|
1104 | if (newRelationArray != relationArray) |
---|
1105 | mdd_array_free(newRelationArray); |
---|
1106 | |
---|
1107 | if (mdd_equal(product1, product2)) |
---|
1108 | equal = 1; |
---|
1109 | else |
---|
1110 | equal = 0; |
---|
1111 | |
---|
1112 | mdd_free(product1); |
---|
1113 | mdd_free(product2); |
---|
1114 | |
---|
1115 | return(equal); |
---|
1116 | } |
---|
1117 | |
---|
1118 | |
---|
1119 | /**Function******************************************************************** |
---|
1120 | |
---|
1121 | Synopsis [Checks whether a vector corresponds to its relation array.] |
---|
1122 | |
---|
1123 | Description [Checks whether a vector corresponds to its relation array. |
---|
1124 | This function is used only for debugging with image_cluster_size = 1. |
---|
1125 | Checks each function vector whether its relation exists in the transition |
---|
1126 | relation.] |
---|
1127 | |
---|
1128 | SideEffects [] |
---|
1129 | |
---|
1130 | ******************************************************************************/ |
---|
1131 | int |
---|
1132 | ImgCheckMatching(ImgTfmInfo_t *info, array_t *vector, array_t *relationArray) |
---|
1133 | { |
---|
1134 | int i, equal = 1; |
---|
1135 | mdd_t *var, *relation; |
---|
1136 | ImgComponent_t *comp; |
---|
1137 | st_table *relationTable; |
---|
1138 | int *ptr; |
---|
1139 | |
---|
1140 | relationTable = st_init_table(st_ptrcmp, st_ptrhash); |
---|
1141 | |
---|
1142 | for (i = 0; i < array_n(relationArray); i++) { |
---|
1143 | relation = array_fetch(mdd_t *, relationArray, i); |
---|
1144 | ptr = (int *)bdd_pointer(relation); |
---|
1145 | st_insert(relationTable, (char *)ptr, NULL); |
---|
1146 | } |
---|
1147 | |
---|
1148 | for (i = 0; i < array_n(vector); i++) { |
---|
1149 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
1150 | if (comp->intermediate) |
---|
1151 | relation = mdd_xnor(comp->var, comp->func); |
---|
1152 | else { |
---|
1153 | var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); |
---|
1154 | relation = mdd_xnor(var, comp->func); |
---|
1155 | mdd_free(var); |
---|
1156 | } |
---|
1157 | ptr = (int *)bdd_pointer(relation); |
---|
1158 | if (!st_lookup(relationTable, (char *)ptr, NULL)) { |
---|
1159 | if (comp->intermediate) { |
---|
1160 | fprintf(vis_stderr, |
---|
1161 | "Error : relation of varId[%d - intermediate] not found\n", |
---|
1162 | (int)bdd_top_var_id(comp->var)); |
---|
1163 | } else { |
---|
1164 | fprintf(vis_stderr, "Error : relation of varId[%d] not found\n", |
---|
1165 | (int)bdd_top_var_id(comp->var)); |
---|
1166 | } |
---|
1167 | equal = 0; |
---|
1168 | } |
---|
1169 | mdd_free(relation); |
---|
1170 | } |
---|
1171 | |
---|
1172 | st_free_table(relationTable); |
---|
1173 | return(equal); |
---|
1174 | } |
---|
1175 | |
---|
1176 | |
---|
1177 | /*---------------------------------------------------------------------------*/ |
---|
1178 | /* Definition of static functions */ |
---|
1179 | /*---------------------------------------------------------------------------*/ |
---|
1180 | |
---|
1181 | |
---|
1182 | /**Function******************************************************************** |
---|
1183 | |
---|
1184 | Synopsis [Computes variable lifetime lambda.] |
---|
1185 | |
---|
1186 | Description [Computes variable lifetime lambda. newRelationFlag is 1 when |
---|
1187 | relationArray is made from the function vector directly, in other words, |
---|
1188 | relationArray is an array of next state functions in this case.] |
---|
1189 | |
---|
1190 | SideEffects [] |
---|
1191 | |
---|
1192 | ******************************************************************************/ |
---|
1193 | static float |
---|
1194 | ComputeSupportLambda(ImgTfmInfo_t *info, array_t *relationArray, |
---|
1195 | mdd_t *cofactorCube, mdd_t *abstractCube, |
---|
1196 | mdd_t *from, array_t *vector, int newRelationFlag, |
---|
1197 | int preFlag, float *improvedLambda) |
---|
1198 | { |
---|
1199 | array_t *newRelationArray, *clusteredRelationArray; |
---|
1200 | ImgComponent_t *comp; |
---|
1201 | int i, j, nVars, nSupports; |
---|
1202 | mdd_t *newFrom, *var; |
---|
1203 | char *support; |
---|
1204 | array_t *smoothVarsBddArray, *introducedVarsBddArray; |
---|
1205 | array_t *domainVarsBddArray; |
---|
1206 | array_t *smoothSchedule, *smoothVars; |
---|
1207 | float lambda; |
---|
1208 | int size, total, lifetime; |
---|
1209 | Img_DirectionType direction; |
---|
1210 | int lambdaWithFrom, prevArea; |
---|
1211 | array_t *orderedRelationArray; |
---|
1212 | int nIntroducedVars; |
---|
1213 | int *highest, *lowest; |
---|
1214 | mdd_t *relation; |
---|
1215 | int asIs; |
---|
1216 | |
---|
1217 | if (cofactorCube && abstractCube) { |
---|
1218 | newRelationArray = ImgGetCofactoredAbstractedRelationArray(info->manager, |
---|
1219 | relationArray, cofactorCube, abstractCube); |
---|
1220 | if (from && info->option->lambdaWithFrom) { |
---|
1221 | if (preFlag) |
---|
1222 | newFrom = ImgSubstitute(from, info->functionData, Img_D2R_c); |
---|
1223 | else |
---|
1224 | newFrom = mdd_dup(from); |
---|
1225 | array_insert_last(mdd_t *, newRelationArray, newFrom); |
---|
1226 | lambdaWithFrom = 1; |
---|
1227 | } else { |
---|
1228 | lambdaWithFrom = 0; |
---|
1229 | newFrom = NIL(mdd_t); |
---|
1230 | } |
---|
1231 | } else { |
---|
1232 | if (from && info->option->lambdaWithFrom) { |
---|
1233 | if (newRelationFlag) { |
---|
1234 | newRelationArray = relationArray; |
---|
1235 | if (preFlag) |
---|
1236 | newFrom = ImgSubstitute(from, info->functionData, Img_D2R_c); |
---|
1237 | else |
---|
1238 | newFrom = from; |
---|
1239 | } else { |
---|
1240 | /* We don't want to modify the original relation array */ |
---|
1241 | newRelationArray = mdd_array_duplicate(relationArray); |
---|
1242 | if (preFlag) |
---|
1243 | newFrom = ImgSubstitute(from, info->functionData, Img_D2R_c); |
---|
1244 | else |
---|
1245 | newFrom = mdd_dup(from); |
---|
1246 | } |
---|
1247 | array_insert_last(mdd_t *, newRelationArray, newFrom); |
---|
1248 | lambdaWithFrom = 1; |
---|
1249 | } else { |
---|
1250 | newRelationArray = relationArray; |
---|
1251 | newFrom = NIL(mdd_t); |
---|
1252 | lambdaWithFrom = 0; |
---|
1253 | } |
---|
1254 | } |
---|
1255 | |
---|
1256 | if (vector) { |
---|
1257 | for (i = 0; i < array_n(vector); i++) { |
---|
1258 | comp = array_fetch(ImgComponent_t *, vector, i); |
---|
1259 | array_insert_last(mdd_t *, newRelationArray, mdd_dup(comp->func)); |
---|
1260 | } |
---|
1261 | } |
---|
1262 | |
---|
1263 | nVars = info->nVars; |
---|
1264 | support = ALLOC(char, sizeof(char) * nVars); |
---|
1265 | memset(support, 0, sizeof(char) * nVars); |
---|
1266 | |
---|
1267 | comp = ImgComponentAlloc(info); |
---|
1268 | for (i = 0; i < array_n(newRelationArray); i++) { |
---|
1269 | comp->func = array_fetch(mdd_t *, newRelationArray, i);; |
---|
1270 | ImgSupportClear(info, comp->support); |
---|
1271 | ImgComponentGetSupport(comp); |
---|
1272 | for (j = 0; j < nVars; j++) |
---|
1273 | support[j] = support[j] | comp->support[j]; |
---|
1274 | } |
---|
1275 | comp->func = NIL(mdd_t); |
---|
1276 | ImgComponentFree(comp); |
---|
1277 | |
---|
1278 | nSupports = 0; |
---|
1279 | smoothVarsBddArray = array_alloc(mdd_t *, 0); |
---|
1280 | domainVarsBddArray = array_alloc(mdd_t *, 0); |
---|
1281 | introducedVarsBddArray = array_alloc(mdd_t *, 0); |
---|
1282 | for (i = 0; i < nVars; i++) { |
---|
1283 | if (support[i]) { |
---|
1284 | var = bdd_var_with_index(info->manager, i); |
---|
1285 | if (preFlag) { |
---|
1286 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) { |
---|
1287 | if (lambdaWithFrom) |
---|
1288 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
1289 | else |
---|
1290 | array_insert_last(mdd_t *, domainVarsBddArray, var); |
---|
1291 | if (info->option->preLambdaMode == 0 || |
---|
1292 | info->option->preLambdaMode == 2) |
---|
1293 | nSupports++; |
---|
1294 | } else { |
---|
1295 | if (info->preKeepPiInTr) { |
---|
1296 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
1297 | NIL(char *))) { |
---|
1298 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
1299 | nSupports++; |
---|
1300 | } else if (info->intermediateVarsTable && |
---|
1301 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
1302 | NIL(char *))) { |
---|
1303 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
1304 | nSupports++; |
---|
1305 | } else { /* ps variables */ |
---|
1306 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
1307 | if (info->option->preLambdaMode != 0) |
---|
1308 | nSupports++; |
---|
1309 | } |
---|
1310 | } else { |
---|
1311 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
1312 | NIL(char *)) || |
---|
1313 | (info->intermediateVarsTable && |
---|
1314 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
1315 | NIL(char *)))) { |
---|
1316 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
1317 | nSupports++; |
---|
1318 | } else { /* ps variables */ |
---|
1319 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
1320 | if (info->option->preLambdaMode != 0) |
---|
1321 | nSupports++; |
---|
1322 | } |
---|
1323 | } |
---|
1324 | } |
---|
1325 | } else { /* image computation */ |
---|
1326 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) { |
---|
1327 | array_insert_last(mdd_t *, introducedVarsBddArray, var); |
---|
1328 | if (info->option->lambdaMode == 2) |
---|
1329 | nSupports++; |
---|
1330 | } else { |
---|
1331 | if (lambdaWithFrom) |
---|
1332 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
1333 | else { |
---|
1334 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
1335 | NIL(char *)) || |
---|
1336 | (info->intermediateVarsTable && |
---|
1337 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
1338 | NIL(char *)))) { |
---|
1339 | array_insert_last(mdd_t *, smoothVarsBddArray, var); |
---|
1340 | } else |
---|
1341 | array_insert_last(mdd_t *, domainVarsBddArray, var); |
---|
1342 | } |
---|
1343 | nSupports++; |
---|
1344 | } |
---|
1345 | } |
---|
1346 | } |
---|
1347 | } |
---|
1348 | |
---|
1349 | if (preFlag) |
---|
1350 | direction = Img_Backward_c; |
---|
1351 | else |
---|
1352 | direction = Img_Forward_c; |
---|
1353 | |
---|
1354 | if (info->option->lambdaFromMlp) { |
---|
1355 | FREE(support); |
---|
1356 | if (info->option->lambdaWithClustering) { |
---|
1357 | ImgMlpClusterRelationArray(info->manager, info->functionData, |
---|
1358 | newRelationArray, domainVarsBddArray, |
---|
1359 | smoothVarsBddArray, introducedVarsBddArray, |
---|
1360 | direction, &clusteredRelationArray, NIL(array_t *), |
---|
1361 | info->trmOption); |
---|
1362 | if (newRelationArray != relationArray) |
---|
1363 | mdd_array_free(newRelationArray); |
---|
1364 | newRelationArray = clusteredRelationArray; |
---|
1365 | } |
---|
1366 | prevArea = info->prevTotal; |
---|
1367 | asIs = newRelationFlag ? 0 : 1; /* 0 when relationArray is an array of |
---|
1368 | functions, i.e. without next state |
---|
1369 | variables */ |
---|
1370 | lambda = ImgMlpComputeLambda(info->manager, newRelationArray, |
---|
1371 | domainVarsBddArray, smoothVarsBddArray, |
---|
1372 | introducedVarsBddArray, direction, |
---|
1373 | info->option->lambdaMode, asIs, &prevArea, |
---|
1374 | improvedLambda, info->trmOption); |
---|
1375 | info->prevTotal = prevArea; |
---|
1376 | } else { |
---|
1377 | smoothSchedule = ImgGetQuantificationSchedule(info->manager, |
---|
1378 | info->functionData, info->option->trMethod, |
---|
1379 | direction, info->trmOption, newRelationArray, |
---|
1380 | smoothVarsBddArray, domainVarsBddArray, |
---|
1381 | introducedVarsBddArray, |
---|
1382 | info->option->lambdaWithClustering, |
---|
1383 | &orderedRelationArray); |
---|
1384 | |
---|
1385 | if (direction == Img_Forward_c) { |
---|
1386 | size = array_n(smoothSchedule); |
---|
1387 | lifetime = 0; |
---|
1388 | if (info->option->lambdaMode == 0) { /* total lifetime (lambda) */ |
---|
1389 | for (i = 1; i < size; i++) { |
---|
1390 | smoothVars = array_fetch(array_t *, smoothSchedule, i); |
---|
1391 | lifetime += array_n(smoothVars) * i; |
---|
1392 | } |
---|
1393 | total = nSupports * (size - 1); |
---|
1394 | } else if (info->option->lambdaMode == 1) { /* active lifetime (lambda) */ |
---|
1395 | lowest = ALLOC(int, sizeof(int) * nVars); |
---|
1396 | for (i = 0; i < nVars; i++) |
---|
1397 | lowest[i] = nVars; |
---|
1398 | highest = ALLOC(int, sizeof(int) * nVars); |
---|
1399 | memset(highest, 0, sizeof(int) * nVars); |
---|
1400 | |
---|
1401 | comp = ImgComponentAlloc(info); |
---|
1402 | for (i = 0; i < size - 1; i++) { |
---|
1403 | relation = array_fetch(mdd_t *, orderedRelationArray, i); |
---|
1404 | comp->func = relation; |
---|
1405 | ImgSupportClear(info, comp->support); |
---|
1406 | ImgComponentGetSupport(comp); |
---|
1407 | for (j = 0; j < nVars; j++) { |
---|
1408 | if (!comp->support[j]) |
---|
1409 | continue; |
---|
1410 | if (st_lookup(info->rangeVarsTable, (char *)(long)j, NIL(char *))) |
---|
1411 | continue; |
---|
1412 | if (i < lowest[j]) |
---|
1413 | lowest[j] = i; |
---|
1414 | if (i > highest[j]) |
---|
1415 | highest[j] = i; |
---|
1416 | } |
---|
1417 | } |
---|
1418 | comp->func = NIL(mdd_t); |
---|
1419 | ImgComponentFree(comp); |
---|
1420 | |
---|
1421 | for (i = 0; i < nVars; i++) { |
---|
1422 | if (lowest[i] == nVars) |
---|
1423 | continue; |
---|
1424 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) |
---|
1425 | continue; |
---|
1426 | lifetime += highest[i] - lowest[i] + 1; |
---|
1427 | } |
---|
1428 | |
---|
1429 | if (newRelationFlag) |
---|
1430 | lifetime += array_n(newRelationArray); |
---|
1431 | total = nSupports * (size - 1); |
---|
1432 | |
---|
1433 | FREE(lowest); |
---|
1434 | FREE(highest); |
---|
1435 | } else { /* total lifetime (lambda) with introduced variables */ |
---|
1436 | for (i = 1; i < size; i++) { |
---|
1437 | smoothVars = array_fetch(array_t *, smoothSchedule, i); |
---|
1438 | lifetime += array_n(smoothVars) * i; |
---|
1439 | } |
---|
1440 | |
---|
1441 | if (newRelationFlag) { |
---|
1442 | nIntroducedVars = array_n(newRelationArray); |
---|
1443 | lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; |
---|
1444 | } else { |
---|
1445 | comp = ImgComponentAlloc(info); |
---|
1446 | for (i = 0; i < size - 1; i++) { |
---|
1447 | relation = array_fetch(mdd_t *, orderedRelationArray, i); |
---|
1448 | comp->func = relation; |
---|
1449 | ImgSupportClear(info, comp->support); |
---|
1450 | ImgComponentGetSupport(comp); |
---|
1451 | nIntroducedVars = 0; |
---|
1452 | for (j = 0; j < nVars; j++) { |
---|
1453 | if (!comp->support[j]) |
---|
1454 | continue; |
---|
1455 | if (st_lookup(info->rangeVarsTable, (char *)(long)j, NIL(char *))) |
---|
1456 | nIntroducedVars++; |
---|
1457 | } |
---|
1458 | lifetime += (size - i - 1) * nIntroducedVars; |
---|
1459 | } |
---|
1460 | comp->func = NIL(mdd_t); |
---|
1461 | ImgComponentFree(comp); |
---|
1462 | } |
---|
1463 | total = nSupports * (size - 1); |
---|
1464 | } |
---|
1465 | mdd_array_array_free(smoothSchedule); |
---|
1466 | } else if (info->option->preLambdaMode == 0) { /* total lifetime (lambda) */ |
---|
1467 | /* direction == Img_Backward_c */ |
---|
1468 | size = array_n(smoothSchedule); |
---|
1469 | lifetime = 0; |
---|
1470 | for (i = 1; i < size; i++) { |
---|
1471 | smoothVars = array_fetch(array_t *, smoothSchedule, i); |
---|
1472 | lifetime += array_n(smoothVars) * i; |
---|
1473 | } |
---|
1474 | total = nSupports * (size - 1); |
---|
1475 | mdd_array_array_free(smoothSchedule); |
---|
1476 | } else { /* direction == Img_Backward_c */ |
---|
1477 | size = array_n(smoothSchedule); |
---|
1478 | mdd_array_array_free(smoothSchedule); |
---|
1479 | lifetime = 0; |
---|
1480 | |
---|
1481 | lowest = ALLOC(int, sizeof(int) * nVars); |
---|
1482 | for (i = 0; i < nVars; i++) |
---|
1483 | lowest[i] = nVars; |
---|
1484 | highest = ALLOC(int, sizeof(int) * nVars); |
---|
1485 | memset(highest, 0, sizeof(int) * nVars); |
---|
1486 | |
---|
1487 | comp = ImgComponentAlloc(info); |
---|
1488 | for (i = 0; i < size - 1; i++) { |
---|
1489 | relation = array_fetch(mdd_t *, orderedRelationArray, i); |
---|
1490 | comp->func = relation; |
---|
1491 | ImgSupportClear(info, comp->support); |
---|
1492 | ImgComponentGetSupport(comp); |
---|
1493 | for (j = 0; j < nVars; j++) { |
---|
1494 | if (!comp->support[j]) |
---|
1495 | continue; |
---|
1496 | if (i < lowest[j]) |
---|
1497 | lowest[j] = i; |
---|
1498 | if (i > highest[j]) |
---|
1499 | highest[j] = i; |
---|
1500 | } |
---|
1501 | } |
---|
1502 | comp->func = NIL(mdd_t); |
---|
1503 | ImgComponentFree(comp); |
---|
1504 | |
---|
1505 | if (info->option->preLambdaMode == 1) { /* active lifetime (lambda) */ |
---|
1506 | for (i = 0; i < nVars; i++) { |
---|
1507 | if (lowest[i] == nVars) |
---|
1508 | continue; |
---|
1509 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *)) || |
---|
1510 | st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
1511 | NIL(char *)) || |
---|
1512 | (info->intermediateVarsTable && |
---|
1513 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
1514 | NIL(char *)))) { |
---|
1515 | lifetime += highest[i] - lowest[i] + 1; |
---|
1516 | } |
---|
1517 | } |
---|
1518 | if (newRelationFlag) |
---|
1519 | lifetime += array_n(newRelationArray); |
---|
1520 | total = nSupports * (size - 1); |
---|
1521 | } else if (info->option->preLambdaMode == 2) { |
---|
1522 | /* total lifetime (lambda) with introduced variables */ |
---|
1523 | for (i = 0; i < nVars; i++) { |
---|
1524 | if (lowest[i] == nVars) |
---|
1525 | continue; |
---|
1526 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *)) || |
---|
1527 | st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
1528 | NIL(char *)) || |
---|
1529 | (info->intermediateVarsTable && |
---|
1530 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
1531 | NIL(char *)))) { |
---|
1532 | lifetime += highest[i] + 1; |
---|
1533 | } else { |
---|
1534 | lifetime += size - lowest[i] - 1; |
---|
1535 | } |
---|
1536 | } |
---|
1537 | if (newRelationFlag) { |
---|
1538 | nIntroducedVars = array_n(newRelationArray); |
---|
1539 | lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; |
---|
1540 | } |
---|
1541 | total = nSupports * (size - 1); |
---|
1542 | } else { /* total lifetime (lambda) with ps/pi variables */ |
---|
1543 | for (i = 0; i < nVars; i++) { |
---|
1544 | if (lowest[i] == nVars) |
---|
1545 | continue; |
---|
1546 | if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) |
---|
1547 | continue; |
---|
1548 | if (st_lookup(info->quantifyVarsTable, (char *)(long)i, |
---|
1549 | NIL(char *)) || |
---|
1550 | (info->intermediateVarsTable && |
---|
1551 | st_lookup(info->intermediateVarsTable, (char *)(long)i, |
---|
1552 | NIL(char *)))) { |
---|
1553 | lifetime += highest[i] + 1; |
---|
1554 | } else { |
---|
1555 | lifetime += size - lowest[i] - 1; |
---|
1556 | } |
---|
1557 | } |
---|
1558 | if (newRelationFlag) { |
---|
1559 | nIntroducedVars = array_n(newRelationArray); |
---|
1560 | lifetime += nIntroducedVars * (nIntroducedVars + 1) / 2; |
---|
1561 | } |
---|
1562 | total = nSupports * (size - 1); |
---|
1563 | } |
---|
1564 | |
---|
1565 | FREE(lowest); |
---|
1566 | FREE(highest); |
---|
1567 | } |
---|
1568 | |
---|
1569 | FREE(support); |
---|
1570 | mdd_array_free(orderedRelationArray); |
---|
1571 | |
---|
1572 | if (total == 0.0) { |
---|
1573 | lambda = 0.0; |
---|
1574 | *improvedLambda = 0.0; |
---|
1575 | } else { |
---|
1576 | lambda = (float)lifetime / (float)total; |
---|
1577 | if (info->prevTotal) { |
---|
1578 | *improvedLambda = info->prevLambda - |
---|
1579 | (float)lifetime / (float)info->prevTotal; |
---|
1580 | } else |
---|
1581 | *improvedLambda = 0.0; |
---|
1582 | } |
---|
1583 | info->prevTotal = total; |
---|
1584 | } |
---|
1585 | |
---|
1586 | mdd_array_free(smoothVarsBddArray); |
---|
1587 | mdd_array_free(domainVarsBddArray); |
---|
1588 | mdd_array_free(introducedVarsBddArray); |
---|
1589 | if (newRelationArray != relationArray) |
---|
1590 | mdd_array_free(newRelationArray); |
---|
1591 | if (newRelationFlag && from && info->option->lambdaWithFrom && |
---|
1592 | newFrom != from) { |
---|
1593 | mdd_free(newFrom); |
---|
1594 | } |
---|
1595 | |
---|
1596 | if (info->option->verbosity >= 2) { |
---|
1597 | if (preFlag) |
---|
1598 | fprintf(vis_stdout, "** tfm info: lambda for preimage = %.2f\n", lambda); |
---|
1599 | else |
---|
1600 | fprintf(vis_stdout, "** tfm info: lambda for image = %.2f\n", lambda); |
---|
1601 | } |
---|
1602 | |
---|
1603 | info->prevLambda = lambda; |
---|
1604 | return(lambda); |
---|
1605 | } |
---|