7#define CLO_GOOD_ELEMENTS 0
8#define CLO_BAD_ELEMENTS 1
9#define CLO_FAILED_SUB_TREES 2
13char *option[N_OPTIONS] = {
"goodElements",
"badElements",
"failedSubTrees",
"pipe",
"verbose"};
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";
28 double probability, ps, pes, MIF, DIF;
30 char *guidance, *description;
40 double probability, p1, p0, ps, pes;
42 char *description, *guidance, *label;
54 char *description, *tree_name, *typeDesc;
62ITE *bdd_ite_cal(
ITE *ite1,
ITE *ite2,
short type);
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);
70double compute_ps(
ITE *ite);
71void SetupOutputFile(
char *outputFile,
SDDS_DATASET *outData);
74long treeStack1[STACKSIZE];
75long treeStackptr1 = 0;
76long treeStack[STACKSIZE];
79long push_node(
long ID);
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);
87static BASE **base = NULL;
90static long sub_trees = 0;
91static ITE **ite = NULL;
94static ITE **ite_ptr = NULL;
95static long ite_ptrs = 0;
96static long verbose = 0;
98int main(
int argc,
char **argv) {
101 long i, j, alldone = 0, ready, tree_ID;
102 char *inputFile = NULL, *outputFile = NULL;
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;
108 argc =
scanargs(&s_arg, argc, argv);
112 for (i_arg = 1; i_arg < argc; i_arg++) {
113 if (s_arg[i_arg].arg_type == OPTION) {
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];
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];
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];
135 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
142 fprintf(stderr,
"Uknown option %s provided.\n", s_arg[i_arg].list[0]);
147 inputFile = s_arg[i_arg].list[0];
148 else if (!outputFile)
149 outputFile = s_arg[i_arg].list[0];
151 fprintf(stderr,
"argument %s is invalid: too many filenames\n", s_arg[i_arg].list[0]);
156 processFilenames(
"convert_to_bdd", &inputFile, &outputFile, pipeFlags, 1, &tmpfile_used);
158 load_data_base(inputFile);
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;
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;
182 SetupOutputFile(outputFile, &outData);
183 for (i = 0; i < sub_trees; i++) {
185 if (sub_tree[i].all_base) {
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);
191 for (j = 0; j < failedTrees; j++) {
192 if (strcmp(sub_tree[i].tree_name, failedTree[j]) == 0) {
200 compute_sub_tree_ps(sub_tree[i].CAL_ITE, &outData, i);
206 for (i = 0; i < sub_trees; i++) {
207 if (sub_tree[i].calculated)
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) {
220 if (sub_tree[i].ites == 1)
221 sub_tree[i].CAL_ITE = sub_tree[i].ite_ptr[0];
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];
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];
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];
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);
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);
245 for (j = 0; j < failedTrees; j++) {
246 if (strcmp(sub_tree[i].tree_name, failedTree[j]) == 0) {
254 compute_sub_tree_ps(sub_tree[i].CAL_ITE, &outData, i);
256 sub_tree[i].calculated = 1;
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;
277 for (i = 0; i < ites; i++) {
279 free((
ITE *)(ite[i]->left));
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;
292 ite[i]->label = NULL;
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);
305 free(sub_tree[i].ite_ptr);
306 free(sub_tree[i].tree_ID);
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);
325short is_base(
ITE *ite) {
326 if ((ite->left == NULL && ite->right == NULL) || (ite->is_base))
332ITE *bdd_base_base_cal(
BASE *base1,
BASE *base2,
short type) {
334 BASE *base_s, *base_b;
336 tmp = calloc(
sizeof(*tmp), 1);
337 tmp->left = tmp->right = NULL;
339 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
340 ite_ptr[ite_ptrs] = tmp;
343 if (base1->id == base2->id) {
347 tmp->left = tmp->right = NULL;
350 if (base1->id < base2->id) {
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;
366 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
367 ite_ptr[ite_ptrs] = (
ITE *)tmp->left;
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;
377 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
378 ite_ptr[ite_ptrs] = (
ITE *)tmp->right;
384ITE *bdd_base_ite_cal(
BASE *base,
ITE *ite,
short type) {
385 ITE *tmp = NULL, *left, *right;
386 BASE *base1 = ite->base;
389 return bdd_base_base_cal(base, ite->base, type);
391 tmp = calloc(
sizeof(*ite), 1);
393 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
394 ite_ptr[ite_ptrs] = tmp;
396 left = (
ITE *)ite->left;
397 right = (
ITE *)ite->right;
399 if (base->id < base1->id) {
410 }
else if (base->id > base1->id) {
412 tmp->base = ite->base;
427 tmp->left = (
ITE *)calloc(
sizeof(
ITE), 1);
428 ((
ITE *)tmp->left)->base = base;
429 ((
ITE *)tmp->left)->left = ((
ITE *)tmp->left)->right = NULL;
432 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
433 ite_ptr[ite_ptrs] = (
ITE *)tmp->left;
439 tmp->left = bdd_base_ite_cal(base, (
ITE *)(ite->left), type);
448 tmp->right = (
ITE *)calloc(
sizeof(
ITE), 1);
449 ((
ITE *)tmp->right)->base = base;
450 ((
ITE *)tmp->right)->left = ((
ITE *)tmp->right)->right = NULL;
453 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
454 ite_ptr[ite_ptrs] = (
ITE *)tmp->right;
458 tmp->right = bdd_base_ite_cal(base, (
ITE *)ite->right, type);
476ITE *bdd_ite_cal(
ITE *ite1,
ITE *ite2,
short type) {
477 ITE *ite = NULL, *ite_l, *ite_r;
478 BASE *base1 = NULL, *base2 = NULL;
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);
486 return bdd_base_ite_cal(ite1->base, ite2, type);
488 return bdd_base_ite_cal(ite2->base, ite1, type);
490 ite = calloc(
sizeof(*ite), 1);
494 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
495 ite_ptr[ite_ptrs] = ite;
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);
507 ite->left = ite1->left;
509 ite->left = ite2->left;
512 if (ite1->right && ite2->right)
513 ite->right = bdd_ite_cal((
ITE *)ite1->right, (
ITE *)ite2->right, type);
520 ite->right = ite1->right;
522 ite->right = ite2->right;
526 if (base1->id < base2->id) {
533 ite->base = ite_l->base;
541 ite->left = bdd_ite_cal(ite_l->left, ite_r, type);
550 ite->right = bdd_ite_cal(ite_l->right, ite_r, type);
562void load_data_base(
char *filename) {
563 int32_t i, rows, pages, j, allbase, index;
566 char **guid = NULL, **desc = NULL, **label = NULL;
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;
595 for (i = 0; i < rows; i++) {
602 for (j = 0; j < bases; j++) {
603 if (
id[i] == base[j]->
id) {
611 base[bases] = calloc(
sizeof(**base), 1);
612 base[bases]->id =
id[i];
613 base[bases]->probability = prob[i];
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;
630 ite_ptr =
SDDS_Realloc(ite_ptr,
sizeof(*ite_ptr) * (ite_ptrs + 1));
631 ite_ptr[ite_ptrs] = sub_tree[pages].ite_ptr[i];
637 for (j = 0; j < ites; j++) {
638 if (
id[i] == ite[j]->ID) {
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;
656 sub_tree[pages].ite_ptr[i] = ite[index];
660 sub_tree[pages].ites = rows;
661 sub_tree[pages].all_base = allbase;
666 sub_tree[pages].CAL_ITE = sub_tree[pages].ite_ptr[0];
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);
673 sub_tree[pages].calculated = 1;
688 fprintf(stdout,
"total bases %ld, total ites %ld\n", bases, ites);
694long push_node(
long ID) {
695 if (treeStackptr >= STACKSIZE) {
696 fprintf(stderr,
"stack overflow.\n");
699 treeStack[treeStackptr++] = ID;
704 if (treeStackptr < 1) {
705 fprintf(stderr,
"too few items on stack\n");
708 return (treeStack[--treeStackptr]);
712void print_sub_tree(
ITE *ite) {
716 push_node(ite->base->id);
717 fprintf(stdout,
"%ld\n", pop_node());
718 left = (
ITE *)ite->left;
719 right = (
ITE *)ite->right;
723 push_node(left->base->id);
724 fprintf(stdout,
"%ld ", pop_node());
728 push_node(right->base->id);
729 fprintf(stdout,
"%ld \n", pop_node());
731 print_sub_tree(left);
733 print_sub_tree(right);
736void free_cal_ite(
ITE *ite) {
740 left = (
ITE *)(ite->left);
741 right = (
ITE *)(ite->right);
742 if (!left && !right) {
756 if (is_base(right)) {
765void locate_tree_id() {
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;
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);
788void push_sub_tree(
ITE *ite) {
790 push_node((
long)ite);
796 push_node((
long)left);
800 push_node((
long)right);
804 push_sub_tree(right);
807double compute_ps(
ITE *ite) {
808 ITE *left, *right, *c_ite = NULL;
809 long left_adr, right_adr;
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;
820 left = (
ITE *)left_adr;
821 c_ite->p1 = left->ps;
823 if (right_adr == 0) {
826 right = (
ITE *)right_adr;
827 c_ite->p0 = right->ps;
829 c_ite->ps = p * c_ite->p1 + (1 - p) * c_ite->p0;
834void compute_sub_tree_ps(
ITE *ite,
SDDS_DATASET *outData,
long treeIndex) {
837 long t_bases = 0, i, index;
838 BASE **t_base = NULL, *base1;
841 PS = compute_ps(ite);
844 while (treeStackptr > 0) {
845 this_adr = pop_node();
846 if (this_adr != 1 && this_adr != 0) {
847 t_ite = (
ITE *)this_adr;
851 t_base =
SDDS_Realloc(t_base,
sizeof(*t_base) * (t_bases + 1));
852 t_base[t_bases] = base1;
855 for (i = 0; i < t_bases; i++) {
856 if (base1->id == t_base[i]->id) {
862 t_base =
SDDS_Realloc(t_base,
sizeof(*t_base) * (t_bases + 1));
863 t_base[t_bases] = base1;
869 prob = base1->probability;
871 base1->probability = 1.0;
872 base1->ps = compute_ps(ite);
874 base1->probability = 0.0;
875 base1->pes = compute_ps(ite);
877 base1->probability = prob;
878 base1->MIF = base1->ps - base1->pes;
879 base1->DIF = prob + prob * (1 - prob) * base1->MIF / PS;
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);
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))
894 for (i = 0; i < t_bases; 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,
902 "PES", t_base[i]->pes,
903 "Description", t_base[i]->description,
904 "Guidance", t_base[i]->guidance, NULL))
913long push_node1(
long ID) {
914 if (treeStackptr1 >= STACKSIZE) {
915 fprintf(stderr,
"stack overflow.\n");
918 treeStack1[treeStackptr1++] = ID;
922long pop_node1(
void) {
923 if (treeStackptr1 < 1) {
924 fprintf(stderr,
"too few items on stack\n");
927 return (treeStack1[--treeStackptr1]);
930void push_sub_tree1(
ITE *ite) {
932 push_node1((
long)ite);
938 push_node1((
long)left);
942 push_node1((
long)right);
944 push_sub_tree1(left);
946 push_sub_tree1(right);
949void SetupOutputFile(
char *outputFile,
SDDS_DATASET *outData) {
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,...)
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.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
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)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)