SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
convert_to_bdd.c File Reference

Detailed Description

Converts a fault tree database in SDDS format to a Binary Decision Diagram (BDD) representation.

This program processes a fault tree database, computes the fault probabilities of each base element within the fault sub-trees, and outputs the results in a specified format. It supports various options to customize the processing, including specifying known good or bad elements, piping input/output, and verbose output for detailed processing information.

Usage

convert_to_bdd <database_file> <output_file>
[-pipe=[input][,output]]
[-goodElements=<list_of_base_IDs>]
[-badElements=<list_of_base_IDs>]
[-verbose]
[-failedSubTrees=<list_of_sub_tree_IDs>]

Options

Optional Description
-pipe Enables piping for input and/or output.
-goodElements Base elements with fault probability 0.
-badElements Base elements with fault probability 1.
-verbose Enables verbose output.
-failedSubTrees List of sub-trees to compute (default: all).

Incompatibilities

  • Only one of the following can be specified:
    • -goodElements
    • -badElements
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
H. Shang, R. Soliday

Definition in file convert_to_bdd.c.

#include "mdb.h"
#include "scan.h"
#include "SDDS.h"
#include <sys/types.h>

Go to the source code of this file.

Functions

ITEbdd_ite_cal (ITE *ite1, ITE *ite2, short type)
 
ITEbdd_base_ite_cal (BASE *base, ITE *ite, short type)
 
ITEbdd_base_base_cal (BASE *base1, BASE *base2, short type)
 
void load_data_base (char *filename)
 
void print_sub_tree (ITE *ite)
 
short is_base (ITE *ite)
 
void free_cal_ite (ITE *ite)
 
void locate_tree_id ()
 
double compute_ps (ITE *ite)
 
void SetupOutputFile (char *outputFile, SDDS_DATASET *outData)
 
long push_node (long ID)
 
long pop_node (void)
 
void push_sub_tree (ITE *ite)
 
void push_sub_tree1 (ITE *ite)
 
void compute_sub_tree_ps (ITE *ite, SDDS_DATASET *outData, long treeIndex)
 
long push_node1 (long ID)
 
long pop_node1 (void)
 
int main (int argc, char **argv)
 

Function Documentation

◆ bdd_base_base_cal()

ITE * bdd_base_base_cal ( BASE * base1,
BASE * base2,
short type )

Definition at line 406 of file convert_to_bdd.c.

406 {
407 ITE *tmp = calloc(1, sizeof(*tmp));
408 BASE *base_s, *base_b;
409
410 if (!tmp) {
411 fprintf(stderr, "Error: Memory allocation failed in bdd_base_base_cal.\n");
412 exit(EXIT_FAILURE);
413 }
414
415 tmp->left = tmp->right = NULL;
416
417 /* Remember allocated ITE pointers for later freeing */
418 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
419 if (!ite_ptr) {
420 fprintf(stderr, "Error: Memory reallocation failed in bdd_base_base_cal.\n");
421 exit(EXIT_FAILURE);
422 }
423 ite_ptr[ite_ptrs++] = tmp;
424
425 if (base1->id == base2->id) {
426 /* a + a = a; a * a = a */
427 tmp->base = base1;
428 tmp->is_base = 1;
429 return tmp;
430 }
431
432 if (base1->id < base2->id) {
433 base_s = base1;
434 base_b = base2;
435 } else {
436 base_s = base2;
437 base_b = base1;
438 }
439
440 if (type == 0) {
441 /* AND logic: ITE(base_s, base_b, 0) */
442 tmp->base = base_s;
443 tmp->left = calloc(1, sizeof(ITE));
444 if (!tmp->left) {
445 fprintf(stderr, "Error: Memory allocation failed for tmp->left in bdd_base_base_cal.\n");
446 exit(EXIT_FAILURE);
447 }
448 ((ITE *)tmp->left)->base = base_b;
449 ((ITE *)tmp->left)->left = ((ITE *)tmp->left)->right = NULL;
450
451 tmp->right = NULL;
452
453 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
454 if (!ite_ptr) {
455 fprintf(stderr, "Error: Memory reallocation failed for tmp->left in bdd_base_base_cal.\n");
456 exit(EXIT_FAILURE);
457 }
458 ite_ptr[ite_ptrs++] = (ITE *)tmp->left;
459 } else {
460 /* OR logic: ITE(base_s, 1, base_b) */
461 tmp->base = base_s;
462 tmp->left = NULL;
463 tmp->right = calloc(1, sizeof(ITE));
464 if (!tmp->right) {
465 fprintf(stderr, "Error: Memory allocation failed for tmp->right in bdd_base_base_cal.\n");
466 exit(EXIT_FAILURE);
467 }
468 ((ITE *)tmp->right)->base = base_b;
469 ((ITE *)tmp->right)->left = ((ITE *)tmp->right)->right = NULL;
470
471 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
472 if (!ite_ptr) {
473 fprintf(stderr, "Error: Memory reallocation failed for tmp->right in bdd_base_base_cal.\n");
474 exit(EXIT_FAILURE);
475 }
476 ite_ptr[ite_ptrs++] = (ITE *)tmp->right;
477 }
478
479 return tmp;
480}
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:677

◆ bdd_base_ite_cal()

ITE * bdd_base_ite_cal ( BASE * base,
ITE * ite,
short type )

Definition at line 482 of file convert_to_bdd.c.

482 {
483 ITE *tmp = calloc(1, sizeof(*tmp));
484 ITE *left, *right;
485 BASE *base1 = ite->base;
486
487 if (!tmp) {
488 fprintf(stderr, "Error: Memory allocation failed in bdd_base_ite_cal.\n");
489 exit(EXIT_FAILURE);
490 }
491
492 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
493 if (!ite_ptr) {
494 fprintf(stderr, "Error: Memory reallocation failed in bdd_base_ite_cal.\n");
495 exit(EXIT_FAILURE);
496 }
497 ite_ptr[ite_ptrs++] = tmp;
498
499 left = (ITE *)ite->left;
500 right = (ITE *)ite->right;
501
502 if (base->id < base1->id) {
503 tmp->base = base;
504 if (type == 1) {
505 /* OR logic: ITE(base, 1, ite) */
506 tmp->left = NULL;
507 tmp->right = ite;
508 } else {
509 /* AND logic: ITE(base, ite, 0) */
510 tmp->left = ite;
511 tmp->right = NULL;
512 }
513 } else if (base->id > base1->id) {
514 tmp->base = ite->base;
515 if (!left) {
516 if (type == 0) {
517 tmp->left = calloc(1, sizeof(ITE));
518 if (!tmp->left) {
519 fprintf(stderr, "Error: Memory allocation failed for tmp->left in bdd_base_ite_cal.\n");
520 exit(EXIT_FAILURE);
521 }
522 ((ITE *)tmp->left)->base = base;
523 ((ITE *)tmp->left)->left = ((ITE *)tmp->left)->right = NULL;
524
525 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
526 if (!ite_ptr) {
527 fprintf(stderr, "Error: Memory reallocation failed for tmp->left in bdd_base_ite_cal.\n");
528 exit(EXIT_FAILURE);
529 }
530 ite_ptr[ite_ptrs++] = (ITE *)tmp->left;
531 } else {
532 tmp->left = NULL; /* OR logic: 1 */
533 }
534 } else {
535 tmp->left = bdd_base_ite_cal(base, (ITE *)ite->left, type);
536 }
537
538 if (!right) {
539 if (type == 0)
540 tmp->right = NULL; /* AND logic: 0 */
541 else {
542 tmp->right = calloc(1, sizeof(ITE));
543 if (!tmp->right) {
544 fprintf(stderr, "Error: Memory allocation failed for tmp->right in bdd_base_ite_cal.\n");
545 exit(EXIT_FAILURE);
546 }
547 ((ITE *)tmp->right)->base = base;
548 ((ITE *)tmp->right)->left = ((ITE *)tmp->right)->right = NULL;
549
550 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
551 if (!ite_ptr) {
552 fprintf(stderr, "Error: Memory reallocation failed for tmp->right in bdd_base_ite_cal.\n");
553 exit(EXIT_FAILURE);
554 }
555 ite_ptr[ite_ptrs++] = (ITE *)tmp->right;
556 }
557 } else {
558 tmp->right = bdd_base_ite_cal(base, (ITE *)ite->right, type);
559 }
560 } else {
561 tmp->base = base;
562 if (type == 0) {
563 tmp->left = left; /* AND logic: 1 * left */
564 tmp->right = NULL; /* AND logic: 0 */
565 } else {
566 tmp->left = NULL; /* OR logic: 1 */
567 tmp->right = right; /* OR logic: right */
568 }
569 }
570
571 return tmp;
572}

◆ bdd_ite_cal()

ITE * bdd_ite_cal ( ITE * ite1,
ITE * ite2,
short type )

Definition at line 574 of file convert_to_bdd.c.

574 {
575 ITE *ite = calloc(1, sizeof(*ite));
576 ITE *ite_l, *ite_r;
577 BASE *base1 = NULL, *base2 = NULL;
578
579 if (!ite) {
580 fprintf(stderr, "Error: Memory allocation failed in bdd_ite_cal.\n");
581 exit(EXIT_FAILURE);
582 }
583
584 if (!ite1 || !ite2) {
585 fprintf(stderr, "Error: Null pointer provided to bdd_ite_cal().\n");
586 exit(EXIT_FAILURE);
587 }
588
589 if (is_base(ite1) && is_base(ite2))
590 return bdd_base_base_cal(ite1->base, ite2->base, type);
591
592 if (is_base(ite1))
593 return bdd_base_ite_cal(ite1->base, ite2, type);
594 if (is_base(ite2))
595 return bdd_base_ite_cal(ite2->base, ite1, type);
596
597 base1 = ite1->base;
598 base2 = ite2->base;
599
600 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
601 if (!ite_ptr) {
602 fprintf(stderr, "Error: Memory reallocation failed in bdd_ite_cal.\n");
603 exit(EXIT_FAILURE);
604 }
605 ite_ptr[ite_ptrs++] = ite;
606
607 if (base1->id == base2->id) {
608 ite->base = ite1->base;
609 if (ite1->left && ite2->left)
610 ite->left = bdd_ite_cal((ITE *)ite1->left, (ITE *)ite2->left, type);
611 else {
612 if (type == 1)
613 ite->left = NULL; /* OR logic: 1 */
614 else {
615 /* AND logic: any left */
616 ite->left = ite1->left ? ite1->left : ite2->left;
617 }
618 }
619
620 if (ite1->right && ite2->right)
621 ite->right = bdd_ite_cal((ITE *)ite1->right, (ITE *)ite2->right, type);
622 else {
623 if (type == 0)
624 ite->right = NULL; /* AND logic: 0 */
625 else {
626 /* OR logic: any right */
627 ite->right = ite1->right ? ite1->right : ite2->right;
628 }
629 }
630 } else {
631 if (base1->id < base2->id) {
632 ite_l = ite1;
633 ite_r = ite2;
634 } else {
635 ite_l = ite2;
636 ite_r = ite1;
637 }
638 ite->base = ite_l->base;
639
640 if (ite_l->left)
641 ite->left = bdd_ite_cal(ite_l->left, ite_r, type);
642 else {
643 if (type == 0)
644 ite->left = ite_r;
645 else
646 ite->left = NULL;
647 }
648
649 if (ite_l->right)
650 ite->right = bdd_ite_cal(ite_l->right, ite_r, type);
651 else {
652 if (type == 0)
653 ite->right = NULL;
654 else
655 ite->right = ite_r;
656 }
657 }
658
659 return ite;
660}

◆ compute_ps()

double compute_ps ( ITE * ite)

Definition at line 955 of file convert_to_bdd.c.

955 {
956 ITE *left, *right, *c_ite = NULL;
957 long left_adr, right_adr;
958 double p;
959 push_sub_tree1(ite);
960 while (treeStackptr1 > 0) {
961 right_adr = pop_node1();
962 left_adr = pop_node1();
963 c_ite = (ITE *)pop_node1();
964 p = c_ite->base->probability;
965 if (left_adr == 1) {
966 c_ite->p1 = 1.0;
967 } else {
968 left = (ITE *)left_adr;
969 c_ite->p1 = left->ps;
970 }
971 if (right_adr == 0) {
972 c_ite->p0 = 0.0;
973 } else {
974 right = (ITE *)right_adr;
975 c_ite->p0 = right->ps;
976 }
977 c_ite->ps = p * c_ite->p1 + (1.0 - p) * c_ite->p0;
978 }
979 return c_ite->ps;
980}

◆ compute_sub_tree_ps()

void compute_sub_tree_ps ( ITE * ite,
SDDS_DATASET * outData,
long treeIndex )

Definition at line 982 of file convert_to_bdd.c.

982 {
983 ITE *t_ite;
984 long this_adr;
985 long t_bases = 0, i, index;
986 BASE **t_base = NULL, *base1;
987 double prob, PS;
988
989 /* First compute system PS */
990 PS = compute_ps(ite);
991
992 push_sub_tree(ite);
993 while (treeStackptr > 0) {
994 this_adr = pop_node();
995 if (this_adr != 1 && this_adr != 0) {
996 t_ite = (ITE *)this_adr;
997 base1 = t_ite->base;
998 index = -1;
999 if (!t_bases) {
1000 t_base = SDDS_Realloc(t_base, sizeof(*t_base) * (t_bases + 1));
1001 if (!t_base) {
1002 fprintf(stderr, "Error: Memory reallocation failed for t_base in compute_sub_tree_ps.\n");
1003 exit(EXIT_FAILURE);
1004 }
1005 t_base[t_bases] = base1;
1006 t_bases++;
1007 } else {
1008 for (i = 0; i < t_bases; i++) {
1009 if (base1->id == t_base[i]->id) {
1010 index = i;
1011 break;
1012 }
1013 }
1014 if (index < 0) {
1015 t_base = SDDS_Realloc(t_base, sizeof(*t_base) * (t_bases + 1));
1016 if (!t_base) {
1017 fprintf(stderr, "Error: Memory reallocation failed for t_base in compute_sub_tree_ps.\n");
1018 exit(EXIT_FAILURE);
1019 }
1020 t_base[t_bases] = base1;
1021 t_bases++;
1022 }
1023 }
1024 if (index >= 0)
1025 continue;
1026
1027 prob = base1->probability; /* Remember original probability */
1028
1029 /* Compute ps when probability = 1 */
1030 base1->probability = 1.0;
1031 base1->ps = compute_ps(ite);
1032
1033 /* Compute pes when probability = 0 */
1034 base1->probability = 0.0;
1035 base1->pes = compute_ps(ite);
1036
1037 /* Restore original probability */
1038 base1->probability = prob;
1039
1040 base1->MIF = base1->ps - base1->pes;
1041 base1->DIF = prob + prob * (1.0 - prob) * base1->MIF / PS;
1042
1043 if (verbose)
1044 fprintf(stdout, "Base %ld: prob=%.6f, ps=%.6f, pes=%.6f, MIF=%.6f, DIF=%.6f\n",
1045 base1->id, base1->probability, base1->ps, base1->pes, base1->MIF, base1->DIF);
1046 }
1047 }
1048
1049 if (!SDDS_StartPage(outData, t_bases))
1050 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1051
1052 if (!SDDS_SetParameters(outData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE,
1053 "TreeName", sub_tree[treeIndex].tree_name,
1054 "Description", sub_tree[treeIndex].description,
1055 "LogicalType", sub_tree[treeIndex].type,
1056 "LogicalTypeDesc", sub_tree[treeIndex].typeDesc,
1057 "ID", sub_tree[treeIndex].ID, NULL))
1058 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
1059
1060 for (i = 0; i < t_bases; i++) {
1061 if (!SDDS_SetRowValues(outData, SDDS_SET_BY_NAME | SDDS_PASS_BY_VALUE, i,
1062 "BaseID", t_base[i]->id,
1063 "Label", t_base[i]->label,
1064 "Probability", t_base[i]->probability,
1065 "DIF", t_base[i]->DIF,
1066 "MIF", t_base[i]->MIF,
1067 "PS", t_base[i]->ps,
1068 "PES", t_base[i]->pes,
1069 "Description", t_base[i]->description,
1070 "Guidance", t_base[i]->guidance, NULL))
1071 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1072 }
1073
1074 if (!SDDS_WritePage(outData))
1075 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1076
1077 if (t_base)
1078 free(t_base);
1079}
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_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432

◆ free_cal_ite()

void free_cal_ite ( ITE * ite)

Definition at line 883 of file convert_to_bdd.c.

883 {
884 ITE *left, *right;
885 if (!ite)
886 return;
887 left = (ITE *)(ite->left);
888 right = (ITE *)(ite->right);
889 if (!left && !right) {
890 free(ite);
891 return;
892 }
893 if (left) {
894 if (is_base(left)) {
895 free(left);
896 } else {
897 free_cal_ite(left);
898 }
899 }
900 if (right) {
901 if (is_base(right)) {
902 free(right);
903 } else {
904 free_cal_ite(right);
905 }
906 }
907}

◆ is_base()

short is_base ( ITE * ite)

Definition at line 402 of file convert_to_bdd.c.

402 {
403 return (ite->left == NULL && ite->right == NULL) || ite->is_base;
404}

◆ load_data_base()

void load_data_base ( char * filename)

Definition at line 662 of file convert_to_bdd.c.

662 {
663 int32_t i, rows, pages, j, allbase, index;
664 int32_t *id = NULL;
665 double *prob = NULL;
666 char **guid = NULL, **desc = NULL, **label = NULL;
667 SDDS_DATASET table;
668
669 if (!SDDS_InitializeInput(&table, filename))
670 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
671
672 pages = 0;
673 sub_tree = NULL;
674 ite = NULL;
675
676 while (SDDS_ReadPage(&table) > 0) {
677 if (!(rows = SDDS_CountRowsOfInterest(&table)))
678 continue;
679
680 sub_tree = SDDS_Realloc(sub_tree, sizeof(*sub_tree) * (pages + 1));
681 if (!sub_tree) {
682 fprintf(stderr, "Error: Memory reallocation failed for sub_tree.\n");
683 exit(EXIT_FAILURE);
684 }
685
686 sub_tree[pages].ites = rows;
687 sub_tree[pages].ite_ptr = malloc(sizeof(ITE *) * rows);
688 if (!sub_tree[pages].ite_ptr) {
689 fprintf(stderr, "Error: Memory allocation failed for sub_tree[%" PRId32 "].ite_ptr.\n", pages);
690 exit(EXIT_FAILURE);
691 }
692
693 sub_tree[pages].calculated = 0;
694
695 if (!SDDS_GetParameter(&table, "Description", &sub_tree[pages].description) ||
696 !SDDS_GetParameter(&table, "ID", &sub_tree[pages].ID) ||
697 !SDDS_GetParameter(&table, "LogicalType", &sub_tree[pages].type) ||
698 !SDDS_GetParameter(&table, "LogicalTypeDesc", &sub_tree[pages].typeDesc) ||
699 !SDDS_GetParameter(&table, "TreeName", &sub_tree[pages].tree_name))
700 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
701
702 if (!(id = SDDS_GetColumn(&table, "ID")) ||
703 !(prob = SDDS_GetColumn(&table, "Probability")) ||
704 !(desc = SDDS_GetColumn(&table, "Description")) ||
705 !(guid = SDDS_GetColumn(&table, "Guidance")) ||
706 !(label = SDDS_GetColumn(&table, "Label")))
707 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
708
709 allbase = 1;
710 for (i = 0; i < rows; i++) {
711 if (id[i] > 1000) {
712 /* Base element */
713 index = -1;
714 if (bases) {
715 for (j = 0; j < bases; j++) {
716 if (id[i] == base[j]->id) {
717 index = j;
718 break;
719 }
720 }
721 }
722
723 if (index < 0) {
724 base = SDDS_Realloc(base, sizeof(*base) * (bases + 1));
725 if (!base) {
726 fprintf(stderr, "Error: Memory reallocation failed for base.\n");
727 exit(EXIT_FAILURE);
728 }
729 base[bases] = calloc(1, sizeof(**base));
730 if (!base[bases]) {
731 fprintf(stderr, "Error: Memory allocation failed for base[%ld].\n", bases);
732 exit(EXIT_FAILURE);
733 }
734 base[bases]->id = id[i];
735 base[bases]->probability = prob[i];
736 SDDS_CopyString(&base[bases]->guidance, guid[i]);
737 SDDS_CopyString(&base[bases]->label, label[i]);
738 SDDS_CopyString(&base[bases]->description, desc[i]);
739 index = bases;
740 bases++;
741 }
742
743 sub_tree[pages].ite_ptr[i] = calloc(1, sizeof(ITE));
744 if (!sub_tree[pages].ite_ptr[i]) {
745 fprintf(stderr, "Error: Memory allocation failed for sub_tree[%" PRId32 "].ite_ptr[%d].\n", pages, i);
746 exit(EXIT_FAILURE);
747 }
748
749 sub_tree[pages].ite_ptr[i]->base = base[index];
750 sub_tree[pages].ite_ptr[i]->left = sub_tree[pages].ite_ptr[i]->right = NULL;
751 sub_tree[pages].ite_ptr[i]->ID = id[i];
752 sub_tree[pages].ite_ptr[i]->probability = prob[i];
753 sub_tree[pages].ite_ptr[i]->is_base = 1;
754 SDDS_CopyString(&sub_tree[pages].ite_ptr[i]->guidance, guid[i]);
755 SDDS_CopyString(&sub_tree[pages].ite_ptr[i]->label, label[i]);
756 SDDS_CopyString(&sub_tree[pages].ite_ptr[i]->description, desc[i]);
757
758 /* Remember allocated ITE pointers for later freeing */
759 ite_ptr = SDDS_Realloc(ite_ptr, sizeof(*ite_ptr) * (ite_ptrs + 1));
760 if (!ite_ptr) {
761 fprintf(stderr, "Error: Memory reallocation failed for ite_ptr in load_data_base.\n");
762 exit(EXIT_FAILURE);
763 }
764 ite_ptr[ite_ptrs++] = sub_tree[pages].ite_ptr[i];
765 } else {
766 /* Non-base ITE */
767 index = -1;
768 if (ites) {
769 for (j = 0; j < ites; j++) {
770 if (id[i] == ite[j]->ID) {
771 index = j;
772 break;
773 }
774 }
775 }
776
777 if (index < 0) {
778 ite = SDDS_Realloc(ite, sizeof(*ite) * (ites + 1));
779 if (!ite) {
780 fprintf(stderr, "Error: Memory reallocation failed for ite.\n");
781 exit(EXIT_FAILURE);
782 }
783 ite[ites] = calloc(1, sizeof(ITE));
784 if (!ite[ites]) {
785 fprintf(stderr, "Error: Memory allocation failed for ite[%ld].\n", ites);
786 exit(EXIT_FAILURE);
787 }
788 ite[ites]->ID = id[i];
789 ite[ites]->base = NULL;
790 ite[ites]->probability = prob[i];
791 ite[ites]->is_base = 0;
792 SDDS_CopyString(&ite[ites]->guidance, guid[i]);
793 SDDS_CopyString(&ite[ites]->description, desc[i]);
794 SDDS_CopyString(&ite[ites]->label, label[i]);
795 index = ites;
796 ites++;
797 }
798
799 sub_tree[pages].ite_ptr[i] = ite[index];
800 allbase = 0;
801 }
802 }
803
804 sub_tree[pages].ites = rows;
805 sub_tree[pages].all_base = allbase;
806
807 /* Compute base sub-tree */
808 if (allbase) {
809 if (rows == 1) {
810 sub_tree[pages].CAL_ITE = sub_tree[pages].ite_ptr[0];
811 } else {
812 sub_tree[pages].CAL_ITE = bdd_ite_cal(sub_tree[pages].ite_ptr[0], sub_tree[pages].ite_ptr[1], sub_tree[pages].type);
813 for (j = 2; j < rows; j++) {
814 sub_tree[pages].CAL_ITE = bdd_ite_cal(sub_tree[pages].CAL_ITE, sub_tree[pages].ite_ptr[j], sub_tree[pages].type);
815 }
816 }
817 sub_tree[pages].calculated = 1;
818 }
819
820 /* Free temporary arrays */
821 free(id);
822 free(prob);
823 SDDS_FreeStringArray(guid, rows);
824 SDDS_FreeStringArray(desc, rows);
825 SDDS_FreeStringArray(label, rows);
826 free(label);
827 free(guid);
828 free(desc);
829
830 pages++;
831 }
832
833 if (verbose)
834 fprintf(stdout, "Total Bases: %ld, Total ITEs: %ld\n", bases, ites);
835
836 sub_trees = pages;
837
838 if (!SDDS_Terminate(&table))
839 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
840}
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_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
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

◆ locate_tree_id()

void locate_tree_id ( )

Definition at line 909 of file convert_to_bdd.c.

909 {
910 long i, j, k;
911 for (i = 0; i < sub_trees; i++) {
912 sub_tree[i].tree_ID = malloc(sizeof(long) * sub_tree[i].ites);
913 if (!sub_tree[i].tree_ID) {
914 fprintf(stderr, "Error: Memory allocation failed for sub_tree[%ld].tree_ID.\n", i);
915 exit(EXIT_FAILURE);
916 }
917 for (j = 0; j < sub_tree[i].ites; j++) {
918 sub_tree[i].tree_ID[j] = -1;
919 if (!(sub_tree[i].ite_ptr[j]->base)) {
920 for (k = 0; k < sub_trees; k++) {
921 if (sub_tree[i].ite_ptr[j]->ID == sub_tree[k].ID) {
922 sub_tree[i].tree_ID[j] = k;
923 break;
924 }
925 }
926 if (sub_tree[i].tree_ID[j] < 0) {
927 fprintf(stderr, "Error: No tree_ID found for ITE %ld of tree %ld (%s).\n",
928 j, i, sub_tree[i].tree_name);
929 exit(EXIT_FAILURE);
930 }
931 }
932 }
933 }
934}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 156 of file convert_to_bdd.c.

156 {
157 SCANNED_ARG *s_arg;
158 SDDS_DATASET outData;
159 long i, j, alldone = 0, ready, tree_ID;
160 char *inputFile = NULL, *outputFile = NULL;
161 ITE *ite1, *ite2;
162 char **badBase = NULL, **goodBase = NULL, **failedTree = NULL;
163 long badBases = 0, goodBases = 0, failedTrees = 0, i_arg, tmpfile_used = 0, compute = 0;
164 unsigned long pipeFlags = 0;
165
166 argc = scanargs(&s_arg, argc, argv);
167 if (argc < 3) {
168 fprintf(stderr, "Error: Insufficient arguments provided.\n\n%s", USAGE);
169 exit(EXIT_FAILURE);
170 }
171
172 for (i_arg = 1; i_arg < argc; i_arg++) {
173 if (s_arg[i_arg].arg_type == OPTION) {
174 delete_chars(s_arg[i_arg].list[0], "_");
175 switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
176 case CLO_GOOD_ELEMENTS:
177 goodBases = s_arg[i_arg].n_items - 1;
178 goodBase = malloc(sizeof(*goodBase) * goodBases);
179 if (!goodBase) {
180 fprintf(stderr, "Error: Memory allocation failed for goodBase.\n");
181 exit(EXIT_FAILURE);
182 }
183 for (i = 0; i < goodBases; i++)
184 goodBase[i] = s_arg[i_arg].list[i + 1];
185 break;
186 case CLO_BAD_ELEMENTS:
187 badBases = s_arg[i_arg].n_items - 1;
188 badBase = malloc(sizeof(*badBase) * badBases);
189 if (!badBase) {
190 fprintf(stderr, "Error: Memory allocation failed for badBase.\n");
191 exit(EXIT_FAILURE);
192 }
193 for (i = 0; i < badBases; i++)
194 badBase[i] = s_arg[i_arg].list[i + 1];
195 break;
196 case CLO_FAILED_SUB_TREES:
197 failedTrees = s_arg[i_arg].n_items - 1;
198 failedTree = malloc(sizeof(*failedTree) * failedTrees);
199 if (!failedTree) {
200 fprintf(stderr, "Error: Memory allocation failed for failedTree.\n");
201 exit(EXIT_FAILURE);
202 }
203 for (i = 0; i < failedTrees; i++)
204 failedTree[i] = s_arg[i_arg].list[i + 1];
205 break;
206 case CLO_PIPE:
207 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags)) {
208 fprintf(stderr, "Error: Invalid -pipe syntax.\n");
209 exit(EXIT_FAILURE);
210 }
211 break;
212 case CLO_VERBOSE:
213 verbose = 1;
214 break;
215 default:
216 fprintf(stderr, "Unknown option: %s\n", s_arg[i_arg].list[0]);
217 exit(EXIT_FAILURE);
218 }
219 } else {
220 if (!inputFile)
221 inputFile = s_arg[i_arg].list[0];
222 else if (!outputFile)
223 outputFile = s_arg[i_arg].list[0];
224 else {
225 fprintf(stderr, "Error: Too many filenames provided (%s).\n", s_arg[i_arg].list[0]);
226 exit(EXIT_FAILURE);
227 }
228 }
229 }
230
231 processFilenames("convert_to_bdd", &inputFile, &outputFile, pipeFlags, 1, &tmpfile_used);
232
233 load_data_base(inputFile);
234 locate_tree_id();
235
236 if (goodBases) {
237 for (i = 0; i < goodBases; i++) {
238 for (j = 0; j < bases; j++) {
239 if (strcmp(goodBase[i], base[j]->label) == 0) {
240 base[j]->probability = 0.0;
241 break;
242 }
243 }
244 }
245 free(goodBase);
246 }
247
248 if (badBases) {
249 for (i = 0; i < badBases; i++) {
250 for (j = 0; j < bases; j++) {
251 if (strcmp(badBase[i], base[j]->label) == 0) {
252 base[j]->probability = 1.0;
253 break;
254 }
255 }
256 }
257 free(badBase);
258 }
259
260 SetupOutputFile(outputFile, &outData);
261
262 for (i = 0; i < sub_trees; i++) {
263 compute = 0;
264 if (sub_tree[i].all_base) {
265 if (verbose) {
266 fprintf(stdout, "\nSub-tree Name: %s, ID: %d, ITE Structure:\n", sub_tree[i].tree_name, sub_tree[i].ID);
267 print_sub_tree(sub_tree[i].CAL_ITE);
268 }
269 if (failedTrees) {
270 for (j = 0; j < failedTrees; j++) {
271 if (strcmp(sub_tree[i].tree_name, failedTree[j]) == 0) {
272 compute = 1;
273 break;
274 }
275 }
276 } else {
277 compute = 1;
278 }
279 if (compute)
280 compute_sub_tree_ps(sub_tree[i].CAL_ITE, &outData, i);
281 }
282 }
283
284 while (1) {
285 alldone = 1;
286 for (i = 0; i < sub_trees; i++) {
287 if (sub_tree[i].calculated)
288 continue;
289 else {
290 alldone = 0;
291 ready = 1;
292 for (j = 0; j < sub_tree[i].ites; j++) {
293 tree_ID = sub_tree[i].tree_ID[j];
294 if (tree_ID >= 0 && sub_tree[tree_ID].calculated == 0) {
295 ready = 0;
296 break;
297 }
298 }
299 if (ready) {
300 if (sub_tree[i].ites == 1)
301 sub_tree[i].CAL_ITE = sub_tree[i].ite_ptr[0];
302 else {
303 if (sub_tree[i].ite_ptr[0]->base && is_base(sub_tree[i].ite_ptr[0]))
304 ite1 = sub_tree[i].ite_ptr[0];
305 else
306 ite1 = sub_tree[sub_tree[i].tree_ID[0]].CAL_ITE;
307
308 if (sub_tree[i].ite_ptr[1]->base && is_base(sub_tree[i].ite_ptr[1]))
309 ite2 = sub_tree[i].ite_ptr[1];
310 else
311 ite2 = sub_tree[sub_tree[i].tree_ID[1]].CAL_ITE;
312
313 sub_tree[i].CAL_ITE = bdd_ite_cal(ite1, ite2, sub_tree[i].type);
314
315 for (j = 2; j < sub_tree[i].ites; j++) {
316 if (sub_tree[i].ite_ptr[j]->base && is_base(sub_tree[i].ite_ptr[j]))
317 ite1 = sub_tree[i].ite_ptr[j];
318 else
319 ite1 = sub_tree[sub_tree[i].tree_ID[j]].CAL_ITE;
320
321 sub_tree[i].CAL_ITE = bdd_ite_cal(sub_tree[i].CAL_ITE, ite1, sub_tree[i].type);
322 }
323
324 if (verbose) {
325 fprintf(stdout, "\nSub-tree Name: %s, ID: %d, ITE Structure:\n", sub_tree[i].tree_name, sub_tree[i].ID);
326 print_sub_tree(sub_tree[i].CAL_ITE);
327 }
328
329 compute = 0;
330 if (failedTrees) {
331 for (j = 0; j < failedTrees; j++) {
332 if (strcmp(sub_tree[i].tree_name, failedTree[j]) == 0) {
333 compute = 1;
334 break;
335 }
336 }
337 } else {
338 compute = 1;
339 }
340 if (compute)
341 compute_sub_tree_ps(sub_tree[i].CAL_ITE, &outData, i);
342 }
343 sub_tree[i].calculated = 1;
344 }
345 }
346 }
347 if (alldone)
348 break;
349 }
350
351 if (failedTrees)
352 free(failedTree);
353
354 if (!SDDS_Terminate(&outData))
355 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
356
357 /* Freeing allocated memory */
358 for (i = 0; i < bases; i++) {
359 free(base[i]->guidance);
360 free(base[i]->label);
361 free(base[i]->description);
362 free(base[i]);
363 }
364 free(base);
365
366 for (i = 0; i < ites; i++) {
367 if (ite[i]->left)
368 free((ITE *)(ite[i]->left));
369 if (ite[i]->right)
370 free((ITE *)(ite[i]->right));
371 free(ite[i]->description);
372 free(ite[i]->guidance);
373 free(ite[i]->label);
374 free(ite[i]);
375 }
376 free(ite);
377
378 for (i = 0; i < sub_trees; i++) {
379 free(sub_tree[i].description);
380 free(sub_tree[i].tree_name);
381 free(sub_tree[i].typeDesc);
382 free(sub_tree[i].ite_ptr);
383 free(sub_tree[i].tree_ID);
384 }
385 free(sub_tree);
386
387 for (i = 0; i < ite_ptrs; i++) {
388 if (ite_ptr[i]->guidance)
389 free(ite_ptr[i]->guidance);
390 if (ite_ptr[i]->description)
391 free(ite_ptr[i]->description);
392 if (ite_ptr[i]->label)
393 free(ite_ptr[i]->label);
394 free(ite_ptr[i]);
395 }
396 free(ite_ptr);
397 free_scanargs(&s_arg, argc);
398
399 return EXIT_SUCCESS;
400}
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

◆ pop_node()

long pop_node ( void )

Definition at line 851 of file convert_to_bdd.c.

851 {
852 if (treeStackptr < 1) {
853 fprintf(stderr, "Error: Too few items on stack.\n");
854 exit(EXIT_FAILURE);
855 }
856 return treeStack[--treeStackptr];
857}

◆ pop_node1()

long pop_node1 ( void )

Definition at line 1090 of file convert_to_bdd.c.

1090 {
1091 if (treeStackptr1 < 1) {
1092 fprintf(stderr, "Error: Too few items on stack in pop_node1.\n");
1093 exit(EXIT_FAILURE);
1094 }
1095 return treeStack1[--treeStackptr1];
1096}

◆ print_sub_tree()

void print_sub_tree ( ITE * ite)

Definition at line 859 of file convert_to_bdd.c.

859 {
860 ITE *left, *right;
861 if (!ite->base)
862 return;
863 push_node(ite->base->id);
864 fprintf(stdout, "%ld\n", pop_node());
865 left = (ITE *)ite->left;
866 right = (ITE *)ite->right;
867 if (!left)
868 push_node(1);
869 else
870 push_node(left->base->id);
871 fprintf(stdout, "%ld ", pop_node());
872 if (!right)
873 push_node(0);
874 else
875 push_node(right->base->id);
876 fprintf(stdout, "%ld \n", pop_node());
877 if (left)
878 print_sub_tree(left);
879 if (right)
880 print_sub_tree(right);
881}

◆ push_node()

long push_node ( long ID)

Definition at line 842 of file convert_to_bdd.c.

842 {
843 if (treeStackptr >= STACKSIZE) {
844 fprintf(stderr, "Error: Stack overflow.\n");
845 exit(EXIT_FAILURE);
846 }
847 treeStack[treeStackptr++] = ID;
848 return 1;
849}

◆ push_node1()

long push_node1 ( long ID)

Definition at line 1081 of file convert_to_bdd.c.

1081 {
1082 if (treeStackptr1 >= STACKSIZE) {
1083 fprintf(stderr, "Error: Stack overflow in push_node1.\n");
1084 exit(EXIT_FAILURE);
1085 }
1086 treeStack1[treeStackptr1++] = ID;
1087 return 1;
1088}

◆ push_sub_tree()

void push_sub_tree ( ITE * ite)

Definition at line 936 of file convert_to_bdd.c.

936 {
937 ITE *left, *right;
938 push_node((long)ite);
939 left = ite->left;
940 right = ite->right;
941 if (!left)
942 push_node(1);
943 else
944 push_node((long)left);
945 if (!right)
946 push_node(0);
947 else
948 push_node((long)right);
949 if (left)
950 push_sub_tree(left);
951 if (right)
952 push_sub_tree(right);
953}

◆ push_sub_tree1()

void push_sub_tree1 ( ITE * ite)

Definition at line 1098 of file convert_to_bdd.c.

1098 {
1099 ITE *left, *right;
1100 push_node1((long)ite);
1101 left = ite->left;
1102 right = ite->right;
1103 if (!left)
1104 push_node1(1);
1105 else
1106 push_node1((long)left);
1107 if (!right)
1108 push_node1(0);
1109 else
1110 push_node1((long)right);
1111 if (left)
1112 push_sub_tree1(left);
1113 if (right)
1114 push_sub_tree1(right);
1115}

◆ SetupOutputFile()

void SetupOutputFile ( char * outputFile,
SDDS_DATASET * outData )

Definition at line 1117 of file convert_to_bdd.c.

1117 {
1118 if (!SDDS_InitializeOutput(outData, SDDS_ASCII, 1, NULL, NULL, outputFile))
1119 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1120
1121 if (!SDDS_DefineSimpleParameter(outData, "TreeName", NULL, SDDS_STRING) ||
1122 !SDDS_DefineSimpleParameter(outData, "Description", NULL, SDDS_STRING) ||
1123 !SDDS_DefineSimpleParameter(outData, "LogicalType", NULL, SDDS_SHORT) ||
1124 !SDDS_DefineSimpleParameter(outData, "LogicalTypeDesc", NULL, SDDS_STRING) ||
1125 !SDDS_DefineSimpleParameter(outData, "ID", NULL, SDDS_LONG) ||
1126 !SDDS_DefineSimpleColumn(outData, "BaseID", NULL, SDDS_LONG) ||
1127 !SDDS_DefineSimpleColumn(outData, "Label", NULL, SDDS_STRING) ||
1128 !SDDS_DefineSimpleColumn(outData, "Probability", NULL, SDDS_DOUBLE) ||
1129 !SDDS_DefineSimpleColumn(outData, "DIF", NULL, SDDS_DOUBLE) ||
1130 !SDDS_DefineSimpleColumn(outData, "MIF", NULL, SDDS_DOUBLE) ||
1131 !SDDS_DefineSimpleColumn(outData, "PS", NULL, SDDS_DOUBLE) ||
1132 !SDDS_DefineSimpleColumn(outData, "PES", NULL, SDDS_DOUBLE) ||
1133 !SDDS_DefineSimpleColumn(outData, "Description", NULL, SDDS_STRING) ||
1134 !SDDS_DefineSimpleColumn(outData, "Guidance", NULL, SDDS_STRING))
1135 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1136
1137 if (!SDDS_WriteLayout(outData))
1138 SDDS_PrintErrors(stdout, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
1139}
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_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
#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