SDDSlib
Loading...
Searching...
No Matches
convert_to_bdd.c
1#include "mdb.h"
2#include "scan.h"
3#include "SDDS.h"
4#include "SDDSaps.h"
5#include <sys/types.h>
6
7#define CLO_GOOD_ELEMENTS 0
8#define CLO_BAD_ELEMENTS 1
9#define CLO_FAILED_SUB_TREES 2
10#define CLO_PIPE 3
11#define CLO_VERBOSE 4
12#define N_OPTIONS 5
13char *option[N_OPTIONS] = {"goodElements", "badElements", "failedSubTrees", "pipe", "verbose"};
14
15static char *USAGE = "covnert_to_bdd <database file> <output file> [-pipe=[input][,output]] \n\
16[-goodElements=<list of base IDs>] [-badElements=<list of base IDs] [-verbose]\n\
17[-failedSubTrees=<list of sub tree IDs>\n\
18<database file> fault tree database in SDDS format.\n\
19<output file> the output file contains the fault probablity of each base elements in the fault sub tree.\n\
20-pipe=in|out pipe option.\n\
21-goodElements provide list of base elements which are known to be good, i.e., their fault probability is 0.\n\
22-badElements provide list of base elements which are known (found to be bad), i.e., their fault probability is 1.\n\
23-failedSubTrees provide list of sub trees that failed. By default, compute each sub-tree in the database.\n\n";
24
25typedef struct
26{
27 long id;
28 double probability, ps, pes, MIF, DIF;
29 char *label;
30 char *guidance, *description;
31} BASE;
32
33typedef struct
34{
35 BASE *base; /*first element is base */
36 void *left; /*second element is a pointer, could be base or ITE */
37 void *right; /*first element is pointer, couble be base or ITE */
38 /*left=NULL, means 1; right = NULL, means 0 */
39 short is_base;
40 double probability, p1, p0, ps, pes;
41 double MIF, DIF; /*pe1, pe0, pes for NO probability */
42 char *description, *guidance, *label;
43 long ID;
44} ITE;
45
46/*a base x can write as ITE(x, 1, 0) both left pointer and right point are NULLs*/
47
48typedef struct
49{
50 ITE **ite_ptr;
51 long ites;
52 long *tree_ID;
53 int32_t ID;
54 char *description, *tree_name, *typeDesc;
55 short type; /*and for 0, or for 1 */
56 short all_base; /*the member of sub-tree are all base elements */
57 short calculated;
58 double p1, p0, ps;
59 ITE *CAL_ITE;
60} SUB_TREE;
61
62ITE *bdd_ite_cal(ITE *ite1, ITE *ite2, short type); /*type=0 for AND, and type=1 for or */
63ITE *bdd_base_ite_cal(BASE *base, ITE *ite, short type);
64ITE *bdd_base_base_cal(BASE *base1, BASE *base2, short type);
65void load_data_base(char *filename);
66void print_sub_tree(ITE *ite);
67short is_base(ITE *ite);
68void free_cal_ite(ITE *ite);
69void locate_tree_id();
70double compute_ps(ITE *ite);
71void SetupOutputFile(char *outputFile, SDDS_DATASET *outData);
72
73#define STACKSIZE 2000
74long treeStack1[STACKSIZE];
75long treeStackptr1 = 0;
76long treeStack[STACKSIZE];
77long treeStackptr = 0;
78
79long push_node(long ID);
80long pop_node(void);
81void push_sub_tree(ITE *ite);
82void push_sub_tree1(ITE *ite);
83void compute_sub_tree_ps(ITE *ite, SDDS_DATASET *outData, long treeIndex);
84long push_node1(long ID);
85long pop_node1(void);
86
87static BASE **base = NULL;
88static long bases = 0;
89static SUB_TREE *sub_tree = NULL;
90static long sub_trees = 0;
91static ITE **ite = NULL;
92static long ites = 0;
93
94static ITE **ite_ptr = NULL;
95static long ite_ptrs = 0;
96static long verbose = 0;
97
98int main(int argc, char **argv) {
99 SCANNED_ARG *s_arg;
100 SDDS_DATASET outData;
101 long i, j, alldone = 0, ready, tree_ID;
102 char *inputFile = NULL, *outputFile = NULL;
103 ITE *ite1, *ite2;
104 char **badBase = NULL, **goodBase = NULL, **failedTree = NULL;
105 long badBases = 0, goodBases = 0, failedTrees = 0, i_arg, tmpfile_used = 0, compute = 0;
106 unsigned long pipeFlags = 0;
107
108 argc = scanargs(&s_arg, argc, argv);
109 if (argc < 3)
110 bomb(NULL, USAGE);
111
112 for (i_arg = 1; i_arg < argc; i_arg++) {
113 if (s_arg[i_arg].arg_type == OPTION) {
114 delete_chars(s_arg[i_arg].list[0], "_");
115 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
116 case CLO_GOOD_ELEMENTS:
117 goodBases = s_arg[i_arg].n_items - 1;
118 goodBase = malloc(sizeof(*goodBase) * goodBases);
119 for (i = 0; i < goodBases; i++)
120 goodBase[i] = s_arg[i_arg].list[i + 1];
121 break;
122 case CLO_BAD_ELEMENTS:
123 badBases = s_arg[i_arg].n_items - 1;
124 badBase = malloc(sizeof(*badBase) * badBases);
125 for (i = 0; i < badBases; i++)
126 badBase[i] = s_arg[i_arg].list[i + 1];
127 break;
128 case CLO_FAILED_SUB_TREES:
129 failedTrees = s_arg[i_arg].n_items - 1;
130 failedTree = malloc(sizeof(*failedTree) * failedTrees);
131 for (i = 0; i < failedTrees; i++)
132 failedTree[i] = s_arg[i_arg].list[i + 1];
133 break;
134 case CLO_PIPE:
135 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
136 SDDS_Bomb("invalid -pipe syntax");
137 break;
138 case CLO_VERBOSE:
139 verbose = 1;
140 break;
141 default:
142 fprintf(stderr, "Uknown option %s provided.\n", s_arg[i_arg].list[0]);
143 exit(1);
144 }
145 } else {
146 if (!inputFile)
147 inputFile = s_arg[i_arg].list[0];
148 else if (!outputFile)
149 outputFile = s_arg[i_arg].list[0];
150 else {
151 fprintf(stderr, "argument %s is invalid: too many filenames\n", s_arg[i_arg].list[0]);
152 exit(1);
153 }
154 }
155 }
156 processFilenames("convert_to_bdd", &inputFile, &outputFile, pipeFlags, 1, &tmpfile_used);
157 inputFile = argv[1];
158 load_data_base(inputFile);
159 locate_tree_id();
160 if (goodBases) {
161 for (i = 0; i < goodBases; i++) {
162 for (j = 0; j < bases; j++) {
163 if (strcmp(goodBase[i], base[j]->label) == 0) {
164 base[j]->probability = 0;
165 break;
166 }
167 }
168 }
169 free(goodBase);
170 }
171 if (badBases) {
172 for (i = 0; i < badBases; i++) {
173 for (j = 0; j < bases; j++) {
174 if (strcmp(badBase[i], base[j]->label) == 0) {
175 base[j]->probability = 1;
176 break;
177 }
178 }
179 }
180 free(badBase);
181 }
182 SetupOutputFile(outputFile, &outData);
183 for (i = 0; i < sub_trees; i++) {
184 compute = 0;
185 if (sub_tree[i].all_base) {
186 if (verbose) {
187 fprintf(stdout, "\nsub tree name %s, ID %d, the ite is\n", sub_tree[i].tree_name, sub_tree[i].ID);
188 print_sub_tree(sub_tree[i].CAL_ITE);
189 }
190 if (failedTrees) {
191 for (j = 0; j < failedTrees; j++) {
192 if (strcmp(sub_tree[i].tree_name, failedTree[j]) == 0) {
193 compute = 1;
194 break;
195 }
196 }
197 } else
198 compute = 1;
199 if (compute)
200 compute_sub_tree_ps(sub_tree[i].CAL_ITE, &outData, i);
201 }
202 }
203
204 while (1) {
205 alldone = 1;
206 for (i = 0; i < sub_trees; i++) {
207 if (sub_tree[i].calculated)
208 continue;
209 else {
210 alldone = 0;
211 ready = 1;
212 for (j = 0; j < sub_tree[i].ites; j++) {
213 tree_ID = sub_tree[i].tree_ID[j];
214 if (tree_ID >= 0 && sub_tree[tree_ID].calculated == 0) {
215 ready = 0;
216 break;
217 }
218 }
219 if (ready) {
220 if (sub_tree[i].ites == 1)
221 sub_tree[i].CAL_ITE = sub_tree[i].ite_ptr[0];
222 else {
223 if (sub_tree[i].ite_ptr[0]->base && is_base(sub_tree[i].ite_ptr[0]))
224 ite1 = sub_tree[i].ite_ptr[0];
225 else
226 ite1 = sub_tree[sub_tree[i].tree_ID[0]].CAL_ITE;
227 if (sub_tree[i].ite_ptr[1]->base && is_base(sub_tree[i].ite_ptr[1]))
228 ite2 = sub_tree[i].ite_ptr[1];
229 else
230 ite2 = sub_tree[sub_tree[i].tree_ID[1]].CAL_ITE;
231 sub_tree[i].CAL_ITE = bdd_ite_cal(ite1, ite2, sub_tree[i].type);
232 for (j = 2; j < sub_tree[i].ites; j++) {
233 if (sub_tree[i].ite_ptr[j]->base && is_base(sub_tree[i].ite_ptr[j]))
234 ite1 = sub_tree[i].ite_ptr[j];
235 else
236 ite1 = sub_tree[sub_tree[i].tree_ID[j]].CAL_ITE;
237 sub_tree[i].CAL_ITE = bdd_ite_cal(sub_tree[i].CAL_ITE, ite1, sub_tree[i].type);
238 }
239 if (verbose) {
240 fprintf(stdout, "\nsub tree name %s, ID %d, the ite is\n", sub_tree[i].tree_name, sub_tree[i].ID);
241 print_sub_tree(sub_tree[i].CAL_ITE);
242 }
243 compute = 0;
244 if (failedTrees) {
245 for (j = 0; j < failedTrees; j++) {
246 if (strcmp(sub_tree[i].tree_name, failedTree[j]) == 0) {
247 compute = 1;
248 break;
249 }
250 }
251 } else
252 compute = 1;
253 if (compute)
254 compute_sub_tree_ps(sub_tree[i].CAL_ITE, &outData, i);
255 }
256 sub_tree[i].calculated = 1;
257 }
258 }
259 }
260 if (alldone)
261 break;
262 }
263 if (failedTrees)
264 free(failedTree);
265 if (!SDDS_Terminate(&outData))
266 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
267 for (i = 0; i < bases; i++) {
268 free(base[i]->guidance);
269 base[i]->guidance = NULL;
270 free(base[i]->label);
271 base[i]->label = NULL;
272 free(base[i]->description);
273 base[i]->description = NULL;
274 free(base[i]);
275 }
276 free(base);
277 for (i = 0; i < ites; i++) {
278 if (ite[i]->left)
279 free((ITE *)(ite[i]->left));
280 ite[i]->left = NULL;
281 if (ite[i]->right)
282 free((ITE *)(ite[i]->right));
283 ite[i]->right = NULL;
284 if (ite[i]->description)
285 free(ite[i]->description);
286 ite[i]->description = NULL;
287 if (ite[i]->guidance)
288 free(ite[i]->guidance);
289 ite[i]->guidance = NULL;
290 if (ite[i]->label)
291 free(ite[i]->label);
292 ite[i]->label = NULL;
293 free(ite[i]);
294 ite[i] = NULL;
295 }
296 free(ite);
297
298 for (i = 0; i < sub_trees; i++) {
299 free(sub_tree[i].description);
300 free(sub_tree[i].tree_name);
301 free(sub_tree[i].typeDesc);
302 /* for (j=0; j<sub_tree[i].ites; j++) {
303 if (sub_tree[i].ite_ptr[j]) free(sub_tree[i].ite_ptr[j]); sub_tree[i].ite_ptr[j]=NULL;
304 } */
305 free(sub_tree[i].ite_ptr);
306 free(sub_tree[i].tree_ID);
307 /* if (sub_tree[i].CAL_ITE) free(sub_tree[i].CAL_ITE); sub_tree[i].CAL_ITE = NULL; */
308 }
309 free(sub_tree);
310 for (i = 0; i < ite_ptrs; i++) {
311 if (ite_ptr[i]->guidance)
312 free(ite_ptr[i]->guidance);
313 if (ite_ptr[i]->description)
314 free(ite_ptr[i]->description);
315 if (ite_ptr[i]->label)
316 free(ite_ptr[i]->label);
317 free(ite_ptr[i]);
318 }
319 free(ite_ptr);
320 free_scanargs(&s_arg, argc);
321
322 return 0;
323}
324
325short is_base(ITE *ite) {
326 if ((ite->left == NULL && ite->right == NULL) || (ite->is_base))
327 return 1;
328 else
329 return 0;
330}
331
332ITE *bdd_base_base_cal(BASE *base1, BASE *base2, short type) {
333 ITE *tmp = NULL;
334 BASE *base_s, *base_b;
335
336 tmp = calloc(sizeof(*tmp), 1);
337 tmp->left = tmp->right = NULL;
338 /*rememeber allocated ite pointers, in order to free them in the end */
339 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
340 ite_ptr[ite_ptrs] = tmp;
341 ite_ptrs++;
342
343 if (base1->id == base2->id) {
344 /* a+a = a; a*a = a */
345 tmp->base = base1;
346 tmp->is_base = 1;
347 tmp->left = tmp->right = NULL;
348 return tmp;
349 }
350 if (base1->id < base2->id) {
351 base_s = base1;
352 base_b = base2;
353 } else {
354 base_s = base2;
355 base_b = base1;
356 }
357 if (type == 0) {
358 /* and logical, returns ite(first, second, 0) */
359 tmp->base = base_s;
360 tmp->left = (ITE *)calloc(sizeof(ITE), 1);
361 ((ITE *)tmp->left)->base = base_b;
362 ((ITE *)tmp->left)->left = ((ITE *)tmp->left)->right = NULL;
363
364 tmp->right = NULL;
365 /*rememeber allocated ite pointers, in order to free them in the end */
366 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
367 ite_ptr[ite_ptrs] = (ITE *)tmp->left;
368 ite_ptrs++;
369 } else {
370 /* or logical ite(first, 1, second) */
371 tmp->base = base_s;
372 tmp->left = NULL;
373 tmp->right = (ITE *)calloc(sizeof(ITE), 1);
374 ((ITE *)tmp->right)->base = base_b;
375 ((ITE *)tmp->right)->left = ((ITE *)tmp->right)->right = NULL;
376 /*rememeber allocated ite pointers, in order to free them in the end */
377 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
378 ite_ptr[ite_ptrs] = (ITE *)tmp->right;
379 ite_ptrs++;
380 }
381 return tmp;
382}
383
384ITE *bdd_base_ite_cal(BASE *base, ITE *ite, short type) {
385 ITE *tmp = NULL, *left, *right;
386 BASE *base1 = ite->base;
387
388 if (is_base(ite))
389 return bdd_base_base_cal(base, ite->base, type);
390
391 tmp = calloc(sizeof(*ite), 1);
392 /*rememeber allocated ite pointers, in order to free them in the end */
393 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
394 ite_ptr[ite_ptrs] = tmp;
395 ite_ptrs++;
396 left = (ITE *)ite->left;
397 right = (ITE *)ite->right;
398
399 if (base->id < base1->id) {
400 tmp->base = base;
401 if (type == 1) {
402 /*or, ITE(base, 1, ite) */
403 tmp->left = NULL;
404 tmp->right = ite;
405 } else {
406 /*and ITE(base, ite, 0) */
407 tmp->left = ite;
408 tmp->right = NULL;
409 }
410 } else if (base->id > base1->id) {
411 /* ITE(ite->base, ite->left type base, ite->right type base */
412 tmp->base = ite->base;
413 /* ite(b,c,0) + d = ite(b,c+d, d) = ite(b,c,d) */
414 /*if (!right && type==1) {
415 tmp->right = (ITE*)calloc(sizeof(ITE), 1);
416 ((ITE*)tmp->right)->base = base;
417 ((ITE*)tmp->right)->left = ((ITE*)tmp->right)->right = NULL;
418 tmp->left = left;
419
420 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr)*(ite_ptrs+1));
421 ite_ptr[ite_ptrs] = (ITE*)tmp->right;
422 ite_ptrs ++;
423 return tmp;
424 } */
425 if (!left) {
426 if (type == 0) {
427 tmp->left = (ITE *)calloc(sizeof(ITE), 1);
428 ((ITE *)tmp->left)->base = base; /* left is one 1*base = base */
429 ((ITE *)tmp->left)->left = ((ITE *)tmp->left)->right = NULL;
430
431 /*rememeber allocated ite pointers, in order to free them in the end */
432 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
433 ite_ptr[ite_ptrs] = (ITE *)tmp->left;
434 ite_ptrs++;
435 } else {
436 tmp->left = NULL; /* 1+base = 1 , left pointer is NULL */
437 }
438 } else {
439 tmp->left = bdd_base_ite_cal(base, (ITE *)(ite->left), type);
440 }
441 if (!right) {
442 /*right is 0 */
443 if (type == 0)
444 /* 0 * base = 0 */
445 tmp->right = NULL;
446 else {
447 /* 0 + base = base */
448 tmp->right = (ITE *)calloc(sizeof(ITE), 1);
449 ((ITE *)tmp->right)->base = base;
450 ((ITE *)tmp->right)->left = ((ITE *)tmp->right)->right = NULL;
451
452 /*rememeber allocated ite pointers, in order to free them in the end */
453 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
454 ite_ptr[ite_ptrs] = (ITE *)tmp->right;
455 ite_ptrs++;
456 }
457 } else {
458 tmp->right = bdd_base_ite_cal(base, (ITE *)ite->right, type);
459 }
460 } else {
461 /*same */
462 tmp->base = base;
463 /* base, is ite(base, 1, 0) */
464 if (type == 0) {
465 /*and logical */
466 tmp->left = left; /* 1 * left */
467 tmp->right = NULL; /* 0 * right */
468 } else {
469 tmp->left = NULL; /* 1 + left = 1 */
470 tmp->right = right; /* 0 + right = right */
471 }
472 }
473 return tmp;
474}
475
476ITE *bdd_ite_cal(ITE *ite1, ITE *ite2, short type) {
477 ITE *ite = NULL, *ite_l, *ite_r;
478 BASE *base1 = NULL, *base2 = NULL;
479
480 if (!ite1 || !ite2)
481 SDDS_Bomb("Null pointer provided to bdd_ite_cal().");
482 if (is_base(ite1) && is_base(ite2))
483 return bdd_base_base_cal(ite1->base, ite2->base, type);
484
485 if (is_base(ite1))
486 return bdd_base_ite_cal(ite1->base, ite2, type);
487 if (is_base(ite2))
488 return bdd_base_ite_cal(ite2->base, ite1, type);
489
490 ite = calloc(sizeof(*ite), 1);
491 base1 = ite1->base;
492 base2 = ite2->base;
493 /*rememeber allocated ite pointers, in order to free them in the end */
494 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
495 ite_ptr[ite_ptrs] = ite;
496 ite_ptrs++;
497 if (base1->id == base2->id) {
498 ite->base = ite1->base;
499 if (ite1->left && ite2->left)
500 ite->left = bdd_ite_cal((ITE *)ite1->left, (ITE *)ite2->left, type);
501 else {
502 if (type == 1)
503 ite->left = NULL; /* one left is 1, 1+any = 1 */
504 else {
505 /* 1 * any = any */
506 if (ite1->left)
507 ite->left = ite1->left;
508 else
509 ite->left = ite2->left;
510 }
511 }
512 if (ite1->right && ite2->right)
513 ite->right = bdd_ite_cal((ITE *)ite1->right, (ITE *)ite2->right, type);
514 else {
515 if (type == 0)
516 ite->right = NULL; /* one left is 0, 0*any = 0 */
517 else {
518 /* 0 + any = any */
519 if (ite1->right)
520 ite->right = ite1->right;
521 else
522 ite->right = ite2->right;
523 }
524 }
525 } else {
526 if (base1->id < base2->id) {
527 ite_l = ite1;
528 ite_r = ite2;
529 } else {
530 ite_l = ite2;
531 ite_r = ite1;
532 }
533 ite->base = ite_l->base;
534 /* ite(b,c,0) + d = ite(b,c+d, d) = ite(b,c,d) */
535 /* if (!ite_l->right && type==1) {
536 ite->right = ite_r;
537 ite->left = ite_l->left;
538 return ite;
539 } */
540 if (ite_l->left)
541 ite->left = bdd_ite_cal(ite_l->left, ite_r, type);
542 else {
543 /*ite_l->left is NULL, i.e, 1 */
544 if (type == 0)
545 ite->left = ite_r;
546 else
547 ite->left = NULL;
548 }
549 if (ite_l->right)
550 ite->right = bdd_ite_cal(ite_l->right, ite_r, type);
551 else {
552 /*ite_l->left is NULL, i.e, 0 */
553 if (type == 0)
554 ite->right = NULL;
555 else
556 ite->right = ite_r;
557 }
558 }
559 return ite;
560}
561
562void load_data_base(char *filename) {
563 int32_t i, rows, pages, j, allbase, index;
564 int32_t *id = NULL;
565 double *prob = NULL;
566 char **guid = NULL, **desc = NULL, **label = NULL;
567 SDDS_DATASET table;
568
569 pages = 0;
570 if (!SDDS_InitializeInput(&table, filename))
571 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
572 pages = 0;
573 sub_tree = NULL;
574 ite = NULL;
575 while (SDDS_ReadPage(&table) > 0) {
576 if (!(rows = SDDS_CountRowsOfInterest(&table)))
577 continue;
578 sub_tree = SDDS_Realloc(sub_tree, sizeof(*sub_tree) * (pages + 1));
579 sub_tree[pages].ites = rows;
580 sub_tree[pages].ite_ptr = malloc(sizeof(ITE *) * rows);
581 sub_tree[pages].calculated = 0;
582 if (!SDDS_GetParameter(&table, "Description", &sub_tree[pages].description) ||
583 !SDDS_GetParameter(&table, "ID", &sub_tree[pages].ID) ||
584 !SDDS_GetParameter(&table, "LogicalType", &sub_tree[pages].type) ||
585 !SDDS_GetParameter(&table, "LogicalTypeDesc", &sub_tree[pages].typeDesc) ||
586 !SDDS_GetParameter(&table, "TreeName", &sub_tree[pages].tree_name))
587 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
588 if (!(id = SDDS_GetColumn(&table, "ID")) ||
589 !(prob = SDDS_GetColumn(&table, "Probability")) ||
590 !(desc = SDDS_GetColumn(&table, "Description")) ||
591 !(guid = SDDS_GetColumn(&table, "Guidance")) ||
592 !(label = SDDS_GetColumn(&table, "Label")))
593 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
594 allbase = 1;
595 for (i = 0; i < rows; i++) {
596 if (id[i] > 1000) {
597 /*base element */
598 index = -1;
599 if (bases) {
600 /*search if base already exist */
601 index = -1;
602 for (j = 0; j < bases; j++) {
603 if (id[i] == base[j]->id) {
604 index = j;
605 break;
606 }
607 }
608 }
609 if (index < 0) {
610 base = SDDS_Realloc(base, sizeof(*base) * (bases + 1));
611 base[bases] = calloc(sizeof(**base), 1);
612 base[bases]->id = id[i];
613 base[bases]->probability = prob[i];
614 SDDS_CopyString(&base[bases]->guidance, guid[i]);
615 SDDS_CopyString(&base[bases]->label, label[i]);
616 SDDS_CopyString(&base[bases]->description, desc[i]);
617 index = bases;
618 bases++;
619 }
620 sub_tree[pages].ite_ptr[i] = calloc(sizeof(ITE), 1);
621 sub_tree[pages].ite_ptr[i]->base = base[index];
622 sub_tree[pages].ite_ptr[i]->left = sub_tree[pages].ite_ptr[i]->right = NULL;
623 sub_tree[pages].ite_ptr[i]->ID = id[i];
624 sub_tree[pages].ite_ptr[i]->probability = prob[i];
625 sub_tree[pages].ite_ptr[i]->is_base = 1;
626 SDDS_CopyString(&sub_tree[pages].ite_ptr[i]->guidance, guid[i]);
627 SDDS_CopyString(&sub_tree[pages].ite_ptr[i]->label, label[i]);
628 SDDS_CopyString(&sub_tree[pages].ite_ptr[i]->description, desc[i]);
629 /*rememeber allocated ite pointers, in order to free them in the end */
630 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
631 ite_ptr[ite_ptrs] = sub_tree[pages].ite_ptr[i];
632 ite_ptrs++;
633 } else {
634 /* non base -- ITE */
635 index = -1;
636 if (ites) {
637 for (j = 0; j < ites; j++) {
638 if (id[i] == ite[j]->ID) {
639 index = j;
640 break;
641 }
642 }
643 }
644 if (index < 0) {
645 ite = SDDS_Realloc(ite, sizeof(*ite) * (ites + 1));
646 ite[ites] = calloc(sizeof(ITE), 1);
647 ite[ites]->ID = id[i];
648 ite[ites]->base = NULL;
649 ite[ites]->probability = prob[i];
650 ite[ites]->is_base = 0;
651 SDDS_CopyString(&ite[ites]->guidance, guid[i]);
652 SDDS_CopyString(&ite[ites]->description, desc[i]);
653 index = ites;
654 ites++;
655 }
656 sub_tree[pages].ite_ptr[i] = ite[index];
657 allbase = 0;
658 }
659 }
660 sub_tree[pages].ites = rows;
661 sub_tree[pages].all_base = allbase;
662 /*compute base sub_tree */
663 if (allbase) {
664 if (rows == 1) {
665 /*only have one base element, no need to do computation */
666 sub_tree[pages].CAL_ITE = sub_tree[pages].ite_ptr[0];
667 } else {
668 sub_tree[pages].CAL_ITE = bdd_ite_cal(sub_tree[pages].ite_ptr[0], sub_tree[pages].ite_ptr[1], sub_tree[pages].type);
669 for (j = 2; j < rows; j++) {
670 sub_tree[pages].CAL_ITE = bdd_ite_cal(sub_tree[pages].ite_ptr[j], sub_tree[pages].CAL_ITE, sub_tree[pages].type);
671 }
672 }
673 sub_tree[pages].calculated = 1;
674 }
675 free(id);
676 id = NULL;
677 free(prob);
678 prob = NULL;
679 SDDS_FreeStringArray(guid, rows);
680 SDDS_FreeStringArray(desc, rows);
681 SDDS_FreeStringArray(label, rows);
682 free(label);
683 free(guid);
684 free(desc);
685 pages++;
686 }
687 if (verbose)
688 fprintf(stdout, "total bases %ld, total ites %ld\n", bases, ites);
689 sub_trees = pages;
690 if (!SDDS_Terminate(&table))
691 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
692}
693
694long push_node(long ID) {
695 if (treeStackptr >= STACKSIZE) {
696 fprintf(stderr, "stack overflow.\n");
697 exit(1);
698 }
699 treeStack[treeStackptr++] = ID;
700 return 1;
701}
702
703long pop_node(void) {
704 if (treeStackptr < 1) {
705 fprintf(stderr, "too few items on stack\n");
706 exit(1);
707 }
708 return (treeStack[--treeStackptr]);
709}
710
711/*pos = 0, top, pos=1, left; pos=2 right */
712void print_sub_tree(ITE *ite) {
713 ITE *left, *right;
714 if (!ite->base)
715 return;
716 push_node(ite->base->id);
717 fprintf(stdout, "%ld\n", pop_node());
718 left = (ITE *)ite->left;
719 right = (ITE *)ite->right;
720 if (!left)
721 push_node(1);
722 else
723 push_node(left->base->id);
724 fprintf(stdout, "%ld ", pop_node());
725 if (!right)
726 push_node(0);
727 else
728 push_node(right->base->id);
729 fprintf(stdout, "%ld \n", pop_node());
730 if (left)
731 print_sub_tree(left);
732 if (right)
733 print_sub_tree(right);
734}
735
736void free_cal_ite(ITE *ite) {
737 ITE *left, *right;
738 if (!ite)
739 return;
740 left = (ITE *)(ite->left);
741 right = (ITE *)(ite->right);
742 if (!left && !right) {
743 free(ite);
744 ite = NULL;
745 return;
746 }
747 if (left) {
748 if (is_base(left)) {
749 free(left);
750 left = NULL;
751 } else {
752 free_cal_ite(left);
753 }
754 }
755 if (right) {
756 if (is_base(right)) {
757 free(right);
758 right = NULL;
759 } else {
760 free_cal_ite(right);
761 }
762 }
763}
764
765void locate_tree_id() {
766 long i, j, k;
767 for (i = 0; i < sub_trees; i++) {
768 sub_tree[i].tree_ID = NULL;
769 sub_tree[i].tree_ID = malloc(sizeof(long) * sub_tree[i].ites);
770 for (j = 0; j < sub_tree[i].ites; j++) {
771 sub_tree[i].tree_ID[j] = -1;
772 if (!(sub_tree[i].ite_ptr[j]->base)) {
773 for (k = 0; k < sub_trees; k++) {
774 if (sub_tree[i].ite_ptr[j]->ID == sub_tree[k].ID) {
775 sub_tree[i].tree_ID[j] = k;
776 break;
777 }
778 }
779 if (sub_tree[i].tree_ID[j] < 0) {
780 fprintf(stderr, "Error: no tree_ID found for ite %ld of tree %ld %s\n", j, i, sub_tree[i].tree_name);
781 exit(1);
782 }
783 }
784 }
785 }
786}
787
788void push_sub_tree(ITE *ite) {
789 ITE *left, *right;
790 push_node((long)ite);
791 left = ite->left;
792 right = ite->right;
793 if (!left)
794 push_node(1);
795 else
796 push_node((long)left);
797 if (!right)
798 push_node(0);
799 else
800 push_node((long)right);
801 if (left)
802 push_sub_tree(left);
803 if (right)
804 push_sub_tree(right);
805}
806
807double compute_ps(ITE *ite) {
808 ITE *left, *right, *c_ite = NULL;
809 long left_adr, right_adr;
810 double p;
811 push_sub_tree1(ite);
812 while (treeStackptr1 > 0) {
813 right_adr = pop_node1();
814 left_adr = pop_node1();
815 c_ite = (ITE *)pop_node1();
816 p = c_ite->base->probability;
817 if (left_adr == 1) {
818 c_ite->p1 = 1;
819 } else {
820 left = (ITE *)left_adr;
821 c_ite->p1 = left->ps;
822 }
823 if (right_adr == 0) {
824 c_ite->p0 = 0;
825 } else {
826 right = (ITE *)right_adr;
827 c_ite->p0 = right->ps;
828 }
829 c_ite->ps = p * c_ite->p1 + (1 - p) * c_ite->p0;
830 }
831 return c_ite->ps;
832}
833
834void compute_sub_tree_ps(ITE *ite, SDDS_DATASET *outData, long treeIndex) {
835 ITE *t_ite;
836 long this_adr;
837 long t_bases = 0, i, index;
838 BASE **t_base = NULL, *base1;
839 double prob, PS;
840 /*first compute system PS */
841 PS = compute_ps(ite);
842
843 push_sub_tree(ite);
844 while (treeStackptr > 0) {
845 this_adr = pop_node();
846 if (this_adr != 1 && this_adr != 0) {
847 t_ite = (ITE *)this_adr;
848 base1 = t_ite->base;
849 index = -1;
850 if (!t_bases) {
851 t_base = SDDS_Realloc(t_base, sizeof(*t_base) * (t_bases + 1));
852 t_base[t_bases] = base1;
853 t_bases++;
854 } else {
855 for (i = 0; i < t_bases; i++) {
856 if (base1->id == t_base[i]->id) {
857 index = i;
858 break;
859 }
860 }
861 if (index < 0) {
862 t_base = SDDS_Realloc(t_base, sizeof(*t_base) * (t_bases + 1));
863 t_base[t_bases] = base1;
864 t_bases++;
865 }
866 }
867 if (index >= 0)
868 continue;
869 prob = base1->probability; /* remember its original probability */
870 /*first compute ps when base1->probability=1 */
871 base1->probability = 1.0;
872 base1->ps = compute_ps(ite);
873 /*then compute pes when base1->probability=0 */
874 base1->probability = 0.0;
875 base1->pes = compute_ps(ite);
876
877 base1->probability = prob; /*restore base1->probability */
878 base1->MIF = base1->ps - base1->pes;
879 base1->DIF = prob + prob * (1 - prob) * base1->MIF / PS;
880 if (verbose)
881 fprintf(stdout, "base %ld, prob%f, ps %f, pes %f, mif %f, dif %f\n",
882 base1->id, base1->probability, base1->ps, base1->pes, base1->MIF, base1->DIF);
883 }
884 }
885 if (!SDDS_StartPage(outData, t_bases))
886 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
887 if (!SDDS_SetParameters(outData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
888 "TreeName", sub_tree[treeIndex].tree_name,
889 "Description", sub_tree[treeIndex].description,
890 "LogicalType", sub_tree[treeIndex].type,
891 "LogicalTypeDesc", sub_tree[treeIndex].typeDesc,
892 "ID", sub_tree[treeIndex].ID, NULL))
893 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
894 for (i = 0; i < t_bases; i++) {
895 if (!SDDS_SetRowValues(outData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, i,
896 "BaseID", t_base[i]->id,
897 "Label", t_base[i]->label,
898 "Probability", t_base[i]->probability,
899 "DIF", t_base[i]->DIF,
900 "MIF", t_base[i]->MIF,
901 "PS", t_base[i]->ps,
902 "PES", t_base[i]->pes,
903 "Description", t_base[i]->description,
904 "Guidance", t_base[i]->guidance, NULL))
905 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
906 }
907 if (!SDDS_WritePage(outData))
908 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
909 if (t_base)
910 free(t_base);
911}
912
913long push_node1(long ID) {
914 if (treeStackptr1 >= STACKSIZE) {
915 fprintf(stderr, "stack overflow.\n");
916 exit(1);
917 }
918 treeStack1[treeStackptr1++] = ID;
919 return 1;
920}
921
922long pop_node1(void) {
923 if (treeStackptr1 < 1) {
924 fprintf(stderr, "too few items on stack\n");
925 exit(1);
926 }
927 return (treeStack1[--treeStackptr1]);
928}
929
930void push_sub_tree1(ITE *ite) {
931 ITE *left, *right;
932 push_node1((long)ite);
933 left = ite->left;
934 right = ite->right;
935 if (!left)
936 push_node1(1);
937 else
938 push_node1((long)left);
939 if (!right)
940 push_node1(0);
941 else
942 push_node1((long)right);
943 if (left)
944 push_sub_tree1(left);
945 if (right)
946 push_sub_tree1(right);
947}
948
949void SetupOutputFile(char *outputFile, SDDS_DATASET *outData) {
950 if (!SDDS_InitializeOutput(outData, SDDS_ASCII, 1, NULL, NULL, outputFile))
951 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
952 if (!SDDS_DefineSimpleParameter(outData, "TreeName", NULL, SDDS_STRING) ||
953 !SDDS_DefineSimpleParameter(outData, "Description", NULL, SDDS_STRING) ||
954 !SDDS_DefineSimpleParameter(outData, "LogicalType", NULL, SDDS_SHORT) ||
955 !SDDS_DefineSimpleParameter(outData, "LogicalTypeDesc", NULL, SDDS_STRING) ||
956 !SDDS_DefineSimpleParameter(outData, "ID", NULL, SDDS_LONG) ||
957 !SDDS_DefineSimpleColumn(outData, "BaseID", NULL, SDDS_LONG) ||
958 !SDDS_DefineSimpleColumn(outData, "Label", NULL, SDDS_STRING) ||
959 !SDDS_DefineSimpleColumn(outData, "Probability", NULL, SDDS_DOUBLE) ||
960 !SDDS_DefineSimpleColumn(outData, "DIF", NULL, SDDS_DOUBLE) ||
961 !SDDS_DefineSimpleColumn(outData, "MIF", NULL, SDDS_DOUBLE) ||
962 !SDDS_DefineSimpleColumn(outData, "PS", NULL, SDDS_DOUBLE) ||
963 !SDDS_DefineSimpleColumn(outData, "PES", NULL, SDDS_DOUBLE) ||
964 !SDDS_DefineSimpleColumn(outData, "Description", NULL, SDDS_STRING) ||
965 !SDDS_DefineSimpleColumn(outData, "Guidance", NULL, SDDS_STRING))
966 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
967 if (!SDDS_WriteLayout(outData))
968 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
969}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_SetRowValues(SDDS_DATASET *SDDS_dataset, int32_t mode, int64_t row,...)
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_DefineSimpleParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data parameter within the SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * delete_chars(char *s, char *t)
Removes all occurrences of characters found in string t from string s.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
void free_scanargs(SCANNED_ARG **scanned, int argc)
Definition scanargs.c:584