00001
00015 extern "C" {
00016
00017 #include "tarski.h"
00018
00019
00022
00023
00024
00025
00026 static Fnode *node_dup_recur( Net_t *net, Fnode *formula, char *suf, st_table *processedTable );
00027
00030 F Fnil;
00031 st_table *nodeHash= ( st_table * ) 0;
00032 st_table *stringHash= ( st_table * ) 0;
00033
00034
00035
00036 char *typeString[] = {
00037 "Undef",
00038 "LIST",
00039 "PAIR",
00040 "SI",
00041 "BI",
00042 "SR",
00043 "BR",
00044 "IntSV",
00045 "IntBV",
00046 "Assign",
00047 "And",
00048 "Or",
00049 "Not",
00050 "Iff",
00051 "TRUE",
00052 "FALSE",
00053 "Mux",
00054 "EQ",
00055 "UIF1",
00056 "UIF",
00057 "Reln",
00058 "Const",
00059 };
00060
00061
00062
00063
00064
00077 Fnode *
00078 new_node(
00079 Operator_t type,
00080 Fnode * lchild,
00081 Fnode * rchild )
00082 {
00083 Fnode * tnode;
00084 tnode = new_node_raw( type, lchild, rchild );
00085 Fnode * result = node_register( tnode );
00086
00087 return result;
00088 }
00089
00090
00098 Fnode *
00099 new_node_raw(
00100 Operator_t type,
00101 Fnode * lchild,
00102 Fnode * rchild )
00103 {
00104 Fnode * tnode;
00105
00106 tnode = ( Fnode * ) malloc( sizeof( Fnode ) );
00107 tnode->type = type;
00108 tnode->lchild = lchild; tnode->rchild = rchild;
00109
00110 return tnode;
00111 }
00112
00122 char *
00123 string_register(
00124 char *aString
00125 )
00126 {
00127 char *result;
00128
00129 if ( stringHash == NIL(st_table) ) {
00130 stringHash = st_init_table( (int (*)()) strcmp, (int (*)()) st_strhash );
00131 }
00132
00133 if ( st_lookup( stringHash, (char *) aString, (char **) & result ) ) {
00134
00135 return result;
00136 }
00137 else {
00138 st_insert( stringHash, (char *) util_strsav( aString), (char *) aString );
00139 return aString;
00140 }
00141 }
00142
00143
00154 Fnode *
00155 node_register(
00156 Fnode * aNode
00157 )
00158 {
00159 Fnode * result;
00160 if ( aNode == nil ) {
00161 printf("# attempting to register nil node\n");
00162 return nil;
00163 }
00164
00165 if ( nodeHash == NIL(st_table) ) {
00166 nodeHash = st_init_table( (int (*)()) node_cmp, (int (*)()) node_hash );
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 if ( st_lookup( nodeHash, (char *) aNode, (char **) & result ) ) {
00182 if ( result == aNode ) {
00183 printf("Serious problem, registering a node that's identical to existing one\n");
00184 assert(0);
00185 }
00186 free( aNode );
00187 if ( ( result->type == ScalarPI_c ) ||
00188 ( result->type == BooleanPI_c ) ) {
00189
00190 }
00191 if ( ( result->type == BooleanReg_c ) ||
00192 ( result->type == ScalarReg_c ) ) {
00193 printf("--Warning: already defined node %s to be a register\n", (char *) result->lchild );
00194 }
00195 if ( ( result->type == InternalScalarVar_c ) ||
00196 ( result->type == InternalBooleanVar_c ) ) {
00197 printf("--Warning: already defined node %s to be an internal Boolean var\n", (char *) result->lchild );
00198 }
00199 return result;
00200 }
00201 else {
00202 Fnode * dupNode = (Fnode *) malloc( sizeof( Fnode ) );
00203
00204 dupNode->type = aNode->type;
00205 dupNode->lchild = aNode->lchild;
00206 dupNode->rchild = aNode->rchild;
00207
00208 st_insert( nodeHash, (char *) dupNode, (char *) dupNode );
00209
00210 free( aNode );
00211 return dupNode;
00212 }
00213 }
00214
00215
00216
00228 int
00229 node_cmp(
00230 Fnode * aNode,
00231 Fnode * bNode
00232 )
00233 {
00234 if ( aNode->type < bNode->type ) {
00235 return -1;
00236 }
00237 else if ( aNode->type > bNode->type ) {
00238 return 1;
00239 }
00240 if ( aNode->lchild < bNode->lchild ) {
00241 return -1;
00242 }
00243 else if ( aNode->lchild > bNode->lchild ) {
00244 return 1;
00245 }
00246 if ( aNode->rchild < bNode->rchild ) {
00247 return -1;
00248 }
00249 else if ( aNode->rchild > bNode->rchild ) {
00250 return 1;
00251 }
00252 return 0;
00253 }
00254
00263 int
00264 node_hash(
00265 Fnode * aNode,
00266 int modulus
00267 )
00268 {
00269 int val = 7*( (int) aNode->type + 1) + 3*( (int) aNode->lchild) + 17*( (int) aNode->rchild);
00270
00271 return ( (val < 0) ? -val : val) % modulus;
00272 }
00273
00274
00275
00283 Fnode *
00284 node_dup(
00285 Net_t *net,
00286 Fnode * formula,
00287 char *suf,
00288 st_table *processedTable
00289 )
00290 {
00291
00292 Fnode * result = node_dup_recur( net, formula, suf, processedTable );
00293 return result;
00294 }
00295
00296
00297
00304 static Fnode *
00305 node_dup_recur(
00306 Net_t *net,
00307 Fnode * formula,
00308 char *suf,
00309 st_table *processedTable
00310 )
00311 {
00312 Fnode * result;
00313
00314 if ( formula == nil ) {
00315 return nil;
00316 }
00317
00318 if ( !st_lookup( net->nodeToId, (char *) formula, (char **) 0) ) {
00319
00320
00321 char *newName = (char *) rs( util_strcat( (char *) formula, suf ) );
00322 return (Fnode * ) newName;
00323 }
00324
00325 if ( st_lookup( processedTable, (char *) formula, (char **) & result ) ) {
00326 return result;
00327 }
00328 result = new_node_raw( formula->type, nil, nil );
00329 st_insert( processedTable, (char *) formula, (char *) result );
00330
00331 Fnode * ldup;
00332 if ( ( formula->type == UnaryFunc_c ) ||
00333 ( formula->type == Func_c ) ||
00334 ( formula->type == ScalarConst_c ) ) {
00335
00336 ldup = (Fnode *) formula->lchild;
00337 }
00338 else {
00339 ldup = node_dup_recur( net, (Fnode *) formula->lchild, suf, processedTable );
00340 }
00341 Fnode *rdup = node_dup_recur( net, (Fnode *) formula->rchild, suf, processedTable );
00342
00343 result->lchild = ldup;
00344 result->rchild = rdup;
00345
00346 return result;
00347 }
00348
00349
00357 int
00358 F::node_print(
00359 )
00360 {
00361 Fnode *a = this->raw;
00362 if ( a == nil ) {
00363 printf(" nil \n");
00364 return 0;
00365 }
00366 printf("Type: %d, Left: %p, Right %p\n", a->type, a->lchild, a->rchild ); return 0;
00367 }
00368
00369
00376 Fnode *
00377 Fnode::operator&(
00378 Fnode * q
00379 )
00380 {
00381 assert( node_test_is_boolean( this ) &&
00382 node_test_is_boolean( q ) );
00383
00384
00385 Fnode* lchild = ( this < q ) ? this : q;
00386 Fnode* rchild = ( this < q ) ? q : this;
00387
00388 Fnode * result = new_node_raw( And_c, lchild, rchild );
00389 Fnode * tmp = rn( result );
00390 return tmp;
00391 }
00392
00398 Fnode *
00399 Fnode::operator,(
00400 Fnode *q
00401 )
00402 {
00403 printf("You've made a mistake, don't use the comma op! q = %p\n", q);
00404 assert(0);
00405 }
00406
00407
00413 Fnode *
00414 Fnode::operator!(
00415 )
00416 {
00417 assert( node_test_is_boolean( this ) );
00418 Fnode * result = new_node_raw( Not_c, this, nil );
00419 Fnode * tmp = rn( result );
00420 return tmp;
00421 }
00422
00428 Fnode *
00429 Fnode::operator|(
00430 Fnode * q
00431 )
00432 {
00433 assert( node_test_is_boolean( this ) &&
00434 node_test_is_boolean( q ) );
00435
00436 Fnode* lchild = ( this < q ) ? this : q;
00437 Fnode* rchild = ( this < q ) ? q : this;
00438 Fnode * result = new_node_raw( Or_c, lchild, rchild );
00439 Fnode * tmp = rn( result );
00440 return tmp;
00441 }
00442
00448 Fnode *
00449 Fnode::operator^(
00450 Fnode * q
00451 )
00452 {
00453 assert( node_test_is_boolean( this ) &&
00454 node_test_is_boolean( q ) );
00455
00456
00457 Fnode* lchild = ( this < q ) ? this : q;
00458 Fnode* rchild = ( this < q ) ? q : this;
00459
00460 Fnode * notThis = ! (*lchild );
00461
00462 Fnode * notq = ! (*rchild );
00463
00464 Fnode * not_thisANDnotq = *notThis & notq;
00465
00466 Fnode * not_notThisANDq = *lchild & rchild;
00467
00468 Fnode * result = *not_notThisANDq | not_thisANDnotq;
00469
00470 return result;
00471 }
00472
00478 Fnode *
00479 Fnode::operator%(
00480 Fnode * q
00481 )
00482 {
00483 if ( !( ( ( node_test_is_scalar( this ) ) &&
00484 ( node_test_is_scalar( q ) ) ) ||
00485 ( ( node_test_is_boolean( this ) ) &&
00486 ( node_test_is_boolean( q ) ) ) ) ) {
00487 printf("Arguments to pair operator (percent) need to be \
00488 scalar or both boolean\n");
00489 assert(0);
00490 }
00491 Fnode * tmp1 = new_node_raw( Pair_c, this, q );
00492 Fnode * tmp2 = rn( tmp1 );
00493 return tmp2;
00494 }
00495
00506 Fnode *
00507 Fnode::operator==(
00508 Fnode *B
00509 )
00510 {
00511 if ( !( ( ( node_test_is_scalar( this ) ) &&
00512 ( node_test_is_scalar( B ) ) ) ||
00513 ( ( node_test_is_boolean( this ) ) &&
00514 ( node_test_is_boolean( B ) ) ) ) ) {
00515 printf("Arguments to operator == both need to be "
00516 "scalar or both boolean\n");
00517 assert(0);
00518 }
00519
00520
00521 Fnode* lchild = ( this < B ) ? this : B;
00522 Fnode* rchild = ( this < B ) ? B : this;
00523
00524 Fnode* result;
00525 if ( node_test_is_scalar( lchild ) ) {
00526 Fnode* tmp = new_node_raw( Equal_c, lchild, rchild );
00527 result = rn( tmp );
00528 }
00529 else {
00530 Fnode* tmp = (*lchild) ^ rchild;
00531 result = !(*tmp);
00532 }
00533 return result;
00534 }
00535
00536
00543 int
00544 node_test_is_boolean(
00545 Fnode* A
00546 )
00547 {
00548
00549 int result = ( A->type == BooleanPI_c ) ||
00550 ( A->type == BooleanReg_c ) ||
00551 ( A->type == InternalBooleanVar_c ) ||
00552 ( A->type == Relation_c ) ||
00553 ( A->type == And_c ) ||
00554 ( A->type == Or_c ) ||
00555 ( A->type == Not_c ) ||
00556 ( A->type == Iff_c ) ||
00557 ( A->type == TRUE_c ) ||
00558 ( A->type == FALSE_c ) ||
00559 ( A->type == Equal_c );
00560
00561 return result;
00562 }
00563
00570 int
00571 node_test_is_scalar(
00572 Fnode * A
00573 )
00574 {
00575 int result = ( A->type == ScalarPI_c ) ||
00576 ( A->type == ScalarReg_c ) ||
00577 ( A->type == InternalScalarVar_c ) ||
00578 ( A->type == Mux_c ) ||
00579 ( A->type == UnaryFunc_c ) ||
00580 ( A->type == Func_c ) ||
00581 ( A->type == ScalarConst_c );
00582
00583 return result;
00584 }
00585
00586
00593 F
00594 TRUE()
00595 {
00596 F result;
00597 result.raw = nn( TRUE_c, nil, nil );
00598 return result;
00599 }
00600
00601
00608 F
00609 FALSE()
00610 {
00611 F result;
00612 result.raw = nn( FALSE_c, nil, nil );
00613 return result;
00614 }
00615
00616
00623 F
00624 si(
00625 char *name
00626 )
00627 {
00628 F result;
00629 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00630 strcpy(new_name, name);
00631 result.raw = nn( ScalarPI_c, (Fnode *) rs(new_name), nil );
00632 return result;
00633 }
00634
00635
00642 F
00643 bi(
00644 char *name
00645 )
00646 {
00647 F result;
00648 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00649 strcpy(new_name, name);
00650 result.raw = nn( BooleanPI_c, (Fnode *) rs(new_name), nil );
00651 return result;
00652 }
00653
00654
00655
00666 Fnode *
00667 Fnode::operator<<(
00668 Fnode * q
00669 )
00670 {
00671 if ( q->type != Pair_c ) {
00672 printf("Incorrect use of << operator, need list to tack on\n");
00673 assert(0);
00674 }
00675 if ( ( this-> type != BooleanReg_c ) &&
00676 ( this-> type != ScalarReg_c ) ) {
00677 printf("Can only tack on to a reg!\n");
00678 assert(0);
00679 }
00680 this->rchild = q;
00681 return this;
00682 }
00683
00684
00685
00686
00695 F
00696 sr(
00697 char *name
00698 )
00699 {
00700 F result;
00701 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00702 strcpy(new_name, name);
00703 result.raw = nn( ScalarReg_c, (Fnode *) rs(new_name), nil );
00704 return result;
00705 }
00706
00707
00715 F
00716 br(
00717 char *name
00718 )
00719 {
00720 F result;
00721 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00722 strcpy(new_name, name);
00723 result.raw = nn( BooleanReg_c, (Fnode *) rs(new_name), nil );
00724 return result;
00725 }
00726
00727
00734 F
00735 sc(
00736 char *name
00737 )
00738 {
00739 F result;
00740 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00741 strcpy(new_name, name);
00742 result.raw = nn( ScalarConst_c, (Fnode *) rs(new_name), nil );
00743 return result;
00744 }
00745
00756 F
00757 bc(
00758 char *name
00759 )
00760 {
00761 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00762 strcpy(new_name, name);
00763 char *pi_name = util_strcat( "SC_", new_name );
00764 F pi = bi( pi_name );
00765 F reg = br( new_name );
00766 F pair = pi % reg;
00767 reg << pair;
00768
00769 return reg;
00770 }
00771
00778 F
00779 uif2(
00780 char *name,
00781 F arg1,
00782 F arg2
00783 )
00784 {
00785 F result;
00786 char *new_name = (char *) malloc((strlen(name)+2)*sizeof(char));
00787 strcpy(new_name, name);
00788 result.raw = new_node( Func_c, (Fnode *) rs(new_name), (list( arg1, arg2, Fnil )).raw );
00789 return result;
00790 }
00791
00798 F
00799 uir3(
00800 char *name,
00801 F arg1,
00802 F arg2,
00803 F arg3
00804 )
00805 {
00806 F truenode = sc("TRUE_c");
00807 F tmp = uif3( name, arg1, arg2, arg3 );
00808 F result = (tmp == truenode );
00809
00810 return result;
00811 }
00812
00819 F
00820 uif3(
00821 char *name,
00822 F arg1,
00823 F arg2,
00824 F arg3
00825 )
00826 {
00827 F result;
00828 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00829 strcpy(new_name, name);
00830 result.raw = new_node( Func_c, (Fnode *) rs(new_name), (list( arg1, arg2, arg3, Fnil )).raw );
00831 return result;
00832 }
00833
00834
00841 F
00842 uif(
00843 char *name,
00844 F arg
00845 )
00846 {
00847 F result;
00848 char *new_name = (char *) malloc(sizeof(char)*(strlen(name)+2));
00849 strcpy(new_name, name);
00850 result.raw = new_node( Func_c, (Fnode *) rs(new_name), (list( arg, Fnil )).raw );
00851 return result;
00852 }
00853
00862 F
00863 assign(
00864 char *name,
00865 F arg
00866 )
00867 {
00868 F result;
00869 char *new_name = (char *) malloc((strlen(name) + 3)*sizeof(char));
00870 strcpy(new_name, name);
00871 result.raw = new_node( Assign_c, (Fnode *) rs(new_name), arg.raw );
00872 return result;
00873 }
00874
00875
00882 F
00883 mux(
00884 F c,
00885 F D1,
00886 F D0
00887 )
00888 {
00889 F pair = D1 % D0;
00890 F result;
00891 result.raw = new_node( Mux_c, c.raw, pair.raw );
00892 return result;
00893 }
00894
00895
00903 int
00904 Node_HasLeftChildNode(
00905 Fnode* node
00906 )
00907 {
00908 if ( node == nil ) {
00909 return 0;
00910 }
00911 int result = ( node->type == List_c ) ||
00912 (node->type == Pair_c ) ||
00913 (node->type == Equal_c ) ||
00914 (node->type == And_c ) ||
00915 (node->type == Or_c ) ||
00916 (node->type == Not_c ) ||
00917 (node->type == Mux_c ) ||
00918 (node->type == Iff_c );
00919
00920 return result;
00921 }
00922
00930 int
00931 Node_HasRightChildNode(
00932 Fnode* node
00933 )
00934 {
00935 if ( node == nil ) {
00936 return 0;
00937 }
00938 int result = (node->type == List_c ) ||
00939 (node->type == Pair_c ) ||
00940 (node->type == ScalarReg_c ) ||
00941 (node->type == BooleanReg_c ) ||
00942 (node->type == Relation_c ) ||
00943 (node->type == Assign_c ) ||
00944 (node->type == And_c ) ||
00945 (node->type == Or_c ) ||
00946 (node->type == Iff_c ) ||
00947 (node->type == Mux_c ) ||
00948 (node->type == Equal_c ) ||
00949 (node->type == UnaryFunc_c ) ||
00950 (node->type == Func_c );
00951
00952 return result;
00953 }
00954
00961 Fnode *
00962 cons(
00963 Fnode * a,
00964 Fnode * b )
00965 {
00966 Fnode * tnode;
00967
00968 tnode = ( Fnode * ) malloc( sizeof( Fnode ) );
00969 tnode->type = List_c;
00970 tnode->lchild = a; tnode->rchild = b;
00971
00972 return tnode;
00973 }
00974
00981 Fnode * car(
00982 Fnode * a
00983 )
00984 {
00985 return (Fnode *) a->lchild;
00986 }
00987
00994 Fnode * cdr(
00995 Fnode * a
00996 )
00997 {
00998 return (Fnode *) a->rchild;
00999 }
01000
01010 F
01011 list(
01012 F startNode, ... )
01013 {
01014 va_list ap;
01015 F p;
01016 array_t *tmpNodes = array_alloc( F, 0 );
01017
01018 array_insert_last( F, tmpNodes, startNode );
01019 va_start( ap, startNode );
01020 p = va_arg( ap, F );
01021 while ( p.raw != Fnil.raw ) {
01022 array_insert_last( F, tmpNodes, p );
01023 p = va_arg(ap, F );
01024 }
01025 va_end( ap );
01026
01027 int i;
01028 F result;
01029 result.raw = nil;
01030 for ( i = array_n( tmpNodes ) - 1 ; i >= 0 ; i-- ) {
01031 F aNode = array_fetch( F, tmpNodes, i );
01032 result.raw = new_node( List_c, aNode.raw, result.raw );
01033 }
01034 return result;
01035
01036 }
01037
01038
01039
01046 int
01047 listlength(
01048 F aList
01049 )
01050 {
01051 if ( aList.rchild() == nil ) {
01052 return 0;
01053 }
01054 else {
01055 assert (aList.type() == List_c );
01056 F tmp;
01057 tmp.raw = aList.rchild();
01058 return listlength( tmp ) + 1;
01059 }
01060 }
01061
01069 F
01070 ri(
01071 char *name,
01072 F restrictedList
01073 )
01074 {
01075 F unrestrictedInput = si( name );
01076
01077 F pred;
01078 pred.raw = nil;
01079 F first;
01080 first.raw = restrictedList.lchild();
01081
01082 F tmp = restrictedList;
01083 while ( tmp.raw != nil ) {
01084 F lchild;
01085 lchild.raw = tmp.lchild();
01086 assert( lchild.type() == ScalarConst_c );
01087 if ( pred.raw != nil ) {
01088 pred = pred | ( unrestrictedInput == lchild );
01089 }
01090 else {
01091 pred = ( unrestrictedInput == lchild );
01092 }
01093 tmp.raw = tmp.rchild();
01094 }
01095 F result = mux( pred, unrestrictedInput, first );
01096 return result;
01097 }
01098
01099
01120 F
01121 restrict(
01122 F aNode,
01123 F restrictedList
01124 )
01125 {
01126 F first;
01127 first.raw = restrictedList.lchild();
01128
01129 F pred;
01130 pred.raw=nil;
01131 F tmp = restrictedList;
01132 while ( tmp.raw != nil ) {
01133 F lchild;
01134 lchild.raw = tmp.lchild();
01135 assert( lchild.type() == ScalarConst_c );
01136 if ( pred.raw != nil ) {
01137 pred = pred | ( aNode == lchild );
01138 }
01139 else {
01140 pred = ( aNode == lchild );
01141 }
01142 tmp.raw = tmp.rchild();
01143 }
01144 F result = mux( pred, aNode, first );
01145 return result;
01146 }
01147
01155 Fnode *
01156 nn(
01157 Operator_t a,
01158 Fnode * b,
01159 Fnode * c)
01160 {
01161 return new_node( a, b, c );
01162 }
01163
01171 Fnode *
01172 rn(
01173 Fnode * aNode
01174 )
01175 {
01176 return node_register( aNode );
01177 }
01178
01186 char* rs(
01187 char* aString
01188 )
01189 {
01190 return string_register( aString );
01191 }
01192
01199 Fnode*
01200 Mux_ThenInput(
01201 Fnode* aNode
01202 )
01203 {
01204 assert( aNode->type == Mux_c);
01205 return (Fnode *) ( (Fnode *) aNode->rchild)->lchild;
01206 }
01207
01214 Fnode*
01215 Mux_ElseInput(
01216 Fnode* aNode
01217 )
01218 {
01219 assert( aNode->type == Mux_c);
01220 return (Fnode *) ( (Fnode *) aNode->rchild)->rchild;
01221 }
01222
01229 Fnode *
01230 Reg_InitFunc(
01231 Fnode * node
01232 )
01233 {
01234 assert( ( node->type == BooleanReg_c ) || ( node->type == ScalarReg_c ) );
01235 return (Fnode *) ((Fnode *) ((node->rchild)->lchild));
01236 }
01237
01244 Fnode *
01245 Reg_NsFunc(
01246 Fnode * node
01247 )
01248 {
01249 assert( ( node->type == BooleanReg_c ) || ( node->type == ScalarReg_c ) );
01250 return (Fnode *) ((Fnode *) ((node->rchild)->rchild));
01251 }
01252
01259 Fnode *
01260 Func_FirstArg(
01261 Fnode * node
01262 )
01263 {
01264 assert( ( node->type == UnaryFunc_c ) || ( node->type == Func_c ) );
01265 return (Fnode *) ((Fnode *) ((node->rchild)->lchild));
01266 }
01267
01274 Fnode *
01275 Func_SecondArg(
01276 Fnode * node
01277 )
01278 {
01279 assert(node->type == Func_c);
01280 if((node->rchild != nil) &&
01281 ((Fnode *) node->rchild)->rchild != nil) {
01282 return (Fnode *) ( ((Fnode *) ((Fnode *) node->rchild)->rchild)->lchild);
01283 }
01284 else {
01285 return nil;
01286 }
01287 }
01288
01295 Fnode *
01296 Func_ThirdArg(
01297 Fnode * node
01298 )
01299 {
01300 assert(node->type == Func_c);
01301 if((node->rchild != nil) &&
01302 (((Fnode *) node->rchild)->rchild != nil) &&
01303 ((Fnode *) ((Fnode *) node->rchild)->rchild)->rchild != nil) {
01304 return (Fnode *) ( ((Fnode *) ((Fnode *) ((Fnode *) node->rchild)->rchild)->rchild) ->lchild);
01305 }
01306 else {
01307 return nil;
01308 }
01309 }
01310
01316 Fnode *
01317 Func_NextArg(
01318 Fnode * func_node,
01319 Fnode * rchild_node
01320 )
01321 {
01322 assert(func_node != nil);
01323 assert((func_node->type == Func_c) || (func_node->type == UnaryFunc_c)) ;
01324 if(rchild_node == nil) {
01325 return nil;
01326 }
01327 else {
01328 return (Fnode *) rchild_node->lchild;
01329 }
01330 }
01331
01337 st_table *
01338 nodeGetSupport(
01339 F aNode
01340 )
01341 {
01342 st_table *result = st_init_table( (int (*)()) node_cmp, (int (*)()) node_hash );
01343 st_table *processedTable = st_init_table( (int (*)()) node_cmp, (int (*)()) node_hash );
01344 nodeGetSupportRecur( aNode, result, processedTable);
01345 st_free_table( processedTable );
01346
01347 return result;
01348 }
01349
01350
01361 void
01362 nodeGetSupportRecur(
01363 F aNode,
01364 st_table *result,
01365 st_table *processedTable
01366 )
01367 {
01368 if ( aNode.raw == NIL( Fnode ) ) {
01369 return;
01370 }
01371 assert( node_test_is_boolean( aNode.raw ) );
01372 if ( st_lookup( processedTable, (char *) aNode.raw, (char **) 0 ) ) {
01373 return;
01374 }
01375
01376 F leftNodeWrapped;
01377 F rightNodeWrapped;
01378 leftNodeWrapped.raw = aNode.lchild();
01379 rightNodeWrapped.raw = aNode.rchild();
01380
01381 Operator_t type = aNode.type();
01382 if ( ( type == BooleanPI_c ) ||
01383 ( type == BooleanReg_c ) ) {
01384 st_insert( result, ( char *) aNode.raw, ( char * ) 0 );
01385 return;
01386 }
01387 if ( ( type == InternalBooleanVar_c ) ||
01388 ( type == Assign_c ) ) {
01389 nodeGetSupportRecur( rightNodeWrapped, result, processedTable );
01390 }
01391 nodeGetSupportRecur( leftNodeWrapped, result, processedTable );
01392 nodeGetSupportRecur( rightNodeWrapped, result, processedTable );
01393
01394 st_insert( processedTable, (char *) aNode.raw, (char *) 0 );
01395
01396 return;
01397 }
01398
01406 void
01407 reg(
01408 F aReg,
01409 F nextState,
01410 F initState
01411 )
01412 {
01413 aReg << ( initState % nextState );
01414 return;
01415 }
01416
01423 Fnode *
01424 node_GetUnique(
01425 Fnode * aNode
01426 )
01427 {
01428 Fnode *unique_aNode = nil;
01429 if(!st_lookup( nodeHash, (char *) aNode, (char **) & unique_aNode)) {
01430 unique_aNode = aNode;
01431 st_insert( nodeHash, (char *) unique_aNode, (char *) unique_aNode );
01432 }
01433 return unique_aNode;
01434 }
01435
01440 void
01441 NodeAssignRegister(F reg,
01442 F init_state,
01443 F next_state)
01444 {
01445
01446 reg << (init_state % next_state);
01447 }
01448
01449
01450 }