void insert_from_file(Ty_Node **root){ char sentence[100]; element data; while(!feof(fp)){ // 파일의 끝까지 반복 fgets(sentence, sizeof(sentence), fp); // sentence에 한줄을 입력받음 char *token = NULL; char *separator = " ,\n"; token = strtok(sentence, separator); // strtok 를 통해 한줄을 단어로 분할 data.key = atoi(token); token = strtok(NULL, separator); strcpy(data.name, token); // element 자료형의 데이타에 key 와 name 을 token 을 통해 분리된 정보를 넣어준다. insert_anode(root, data); // data를 노드에 삽입 } }
int main( int argc, char **argv ) { char *result; FILE *fp; char filename[STRING_MAXLEN]; char instr[STRING_MAXLEN]; anode_t *head, *node, *out_node; vartype state[2], next_state[2]; strcpy( filename, "temp_automaton_io_dumpXXXXXX" ); result = mktemp( filename ); if (result == NULL) { perror( "test_automaton_io, mktemp" ); abort(); } fp = fopen( filename, "w+" ); if (fp == NULL) { perror( "test_automaton_io, fopen" ); abort(); } fprintf( fp, REF_GR1CAUT_TRIVIAL ); if (fseek( fp, 0, SEEK_SET )) { perror( "test_automaton_io, fseek" ); abort(); } /* Load in "gr1c automaton" format */ head = aut_aut_load( 2, fp ); if (head == NULL) { ERRPRINT( "Failed to read 3-node automaton in \"gr1c automaton\" format." ); abort(); } /* Check number of nodes, labels, and outgoing edges */ if (aut_size( head ) != 3) { ERRPRINT1( "size 3 automaton detected as having size %d.", aut_size( head ) ); abort(); } state[0] = 1; state[1] = 0; node = find_anode( head, 0, state, 2 ); if (node == NULL) { ERRPRINT2( "could not find expected node with state [%d %d].", state[0], state[1] ); abort(); } if (node->rgrad != 2) { ERRPRINT1( "node should have reach annotation value of 2 but actually has %d", node->rgrad ); abort(); } state[0] = 0; state[1] = 0; out_node = find_anode( head, 0, state, 2 ); if (out_node == NULL) { ERRPRINT2( "could not find expected node with state [%d %d].", state[0], state[1] ); abort(); } if (out_node->rgrad != 1) { ERRPRINT1( "node should have reach annotation value of 1 but actually has %d", out_node->rgrad ); abort(); } if (node->trans_len != 2) { ERRPRINT1( "node should have 2 outgoing transitions but actually has %d.", node->trans_len ); abort(); } if (*(node->trans) != out_node && *(node->trans+1) != out_node) { ERRPRINT( "an edge is missing." ); abort(); } /* Modify the automaton and dump the result */ *(node->trans+1) = node; state[0] = 0; state[1] = 1; head = insert_anode( head, 0, -1, False, state, 2 ); if (head == NULL) { ERRPRINT( "failed to insert new node into automaton." ); abort(); } next_state[0] = 1; next_state[1] = 0; head = append_anode_trans( head, 0, state, 2, 0, next_state ); if (head == NULL) { ERRPRINT( "failed to append transition to new node." ); abort(); } fclose( fp ); fp = fopen( filename, "w+" ); if (fp == NULL) { perror( "test_automaton_io, fopen" ); abort(); } aut_aut_dump( head, 2, fp ); if (fseek( fp, 0, SEEK_SET )) { perror( "test_automaton_io, fseek" ); abort(); } /* NB, assumed width may cause problems if we start using Unicode. */ if (fread( instr, sizeof(char), strlen(REF_GR1CAUT_TRIVIAL_MOD), fp ) < strlen(REF_GR1CAUT_TRIVIAL_MOD)) { ERRPRINT( "output of aut_aut_dump is too short." ); abort(); } if (!strncmp( instr, REF_GR1CAUT_TRIVIAL_MOD, strlen(REF_GR1CAUT_TRIVIAL_MOD) )) { ERRPRINT( "output of aut_aut_dump does not match expectation." ); abort(); } fclose( fp ); if (remove( filename )) { perror( "test_automaton_io, remove" ); abort(); } return 0; }
anode_t *synthesize( DdManager *manager, unsigned char init_flags, unsigned char verbose ) { anode_t *strategy = NULL; anode_t *this_node_stack = NULL; anode_t *node, *new_node; bool initial; vartype *state; vartype **env_moves; int emoves_len; ptree_t *var_separator; DdNode *W; DdNode *strans_into_W; DdNode *einit, *sinit, *etrans, *strans, **egoals, **sgoals; DdNode *ddval; /* Store result of evaluating a BDD */ DdNode ***Y = NULL; DdNode *Y_i_primed; int *num_sublevels; DdNode ****X_ijr = NULL; DdNode *tmp, *tmp2; int i, j, r, k; /* Generic counters */ int offset; bool env_nogoal_flag = False; /* Indicate environment has no goals */ int loop_mode; int next_mode; int num_env, num_sys; int *cube; /* length will be twice total number of variables (to account for both variables and their primes). */ /* Variables used during CUDD generation (state enumeration). */ DdGen *gen; CUDD_VALUE_TYPE gvalue; int *gcube; /* Set environment goal to True (i.e., any state) if none was given. This simplifies the implementation below. */ if (spc.num_egoals == 0) { env_nogoal_flag = True; spc.num_egoals = 1; spc.env_goals = malloc( sizeof(ptree_t *) ); *spc.env_goals = init_ptree( PT_CONSTANT, NULL, 1 ); } num_env = tree_size( spc.evar_list ); num_sys = tree_size( spc.svar_list ); /* State vector (i.e., valuation of the variables) */ state = malloc( sizeof(vartype)*(num_env+num_sys) ); if (state == NULL) { perror( __FILE__ ", malloc" ); exit(-1); } /* Allocate cube array, used later for quantifying over variables. */ cube = (int *)malloc( sizeof(int)*2*(num_env+num_sys) ); if (cube == NULL) { perror( __FILE__ ", malloc" ); exit(-1); } /* Chain together environment and system variable lists for working with BDD library. */ if (spc.evar_list == NULL) { var_separator = NULL; spc.evar_list = spc.svar_list; /* that this is the deterministic case is indicated by var_separator = NULL. */ } else { var_separator = get_list_item( spc.evar_list, -1 ); if (var_separator == NULL) { fprintf( stderr, "Error: get_list_item failed on environment variables" " list.\n" ); free( state ); free( cube ); return NULL; } var_separator->left = spc.svar_list; } /* Generate BDDs for the various parse trees from the problem spec. */ if (spc.env_init != NULL) { einit = ptree_BDD( spc.env_init, spc.evar_list, manager ); } else { einit = Cudd_ReadOne( manager ); Cudd_Ref( einit ); } if (spc.sys_init != NULL) { sinit = ptree_BDD( spc.sys_init, spc.evar_list, manager ); } else { sinit = Cudd_ReadOne( manager ); Cudd_Ref( sinit ); } if (verbose > 1) logprint( "Building environment transition BDD..." ); etrans = ptree_BDD( spc.env_trans, spc.evar_list, manager ); if (verbose > 1) { logprint( "Done." ); logprint( "Building system transition BDD..." ); } strans = ptree_BDD( spc.sys_trans, spc.evar_list, manager ); if (verbose > 1) logprint( "Done." ); /* Build goal BDDs, if present. */ if (spc.num_egoals > 0) { egoals = malloc( spc.num_egoals*sizeof(DdNode *) ); for (i = 0; i < spc.num_egoals; i++) *(egoals+i) = ptree_BDD( *(spc.env_goals+i), spc.evar_list, manager ); } else { egoals = NULL; } if (spc.num_sgoals > 0) { sgoals = malloc( spc.num_sgoals*sizeof(DdNode *) ); for (i = 0; i < spc.num_sgoals; i++) *(sgoals+i) = ptree_BDD( *(spc.sys_goals+i), spc.evar_list, manager ); } else { sgoals = NULL; } if (var_separator == NULL) { spc.evar_list = NULL; } else { var_separator->left = NULL; } W = compute_winning_set_BDD( manager, etrans, strans, egoals, sgoals, verbose ); if (W == NULL) { fprintf( stderr, "Error synthesize: failed to construct winning set.\n" ); free( state ); free( cube ); return NULL; } Y = compute_sublevel_sets( manager, W, etrans, strans, egoals, spc.num_egoals, sgoals, spc.num_sgoals, &num_sublevels, &X_ijr, verbose ); if (Y == NULL) { fprintf( stderr, "Error synthesize: failed to construct sublevel sets.\n" ); free( state ); free( cube ); return NULL; } /* The sublevel sets are exactly as resulting from the vanilla fixed point formula. Thus for each system goal i, Y_0 = \emptyset, and Y_1 is a union of i-goal states and environment-blocking states. For the purpose of synthesis, it is enough to delete Y_0 and replace Y_1 with the intersection of i-goal states and the winning set, and then shift the indices down (so that Y_1 is now called Y_0, Y_2 is now called Y_1, etc.) */ for (i = 0; i < spc.num_sgoals; i++) { Cudd_RecursiveDeref( manager, *(*(Y+i)) ); Cudd_RecursiveDeref( manager, *(*(Y+i)+1) ); for (r = 0; r < spc.num_egoals; r++) Cudd_RecursiveDeref( manager, *(*(*(X_ijr+i))+r) ); free( *(*(X_ijr+i)) ); *(*(Y+i)+1) = Cudd_bddAnd( manager, *(sgoals+i), W ); Cudd_Ref( *(*(Y+i)+1) ); (*(num_sublevels+i))--; for (j = 0; j < *(num_sublevels+i); j++) { *(*(Y+i)+j) = *(*(Y+i)+j+1); *(*(X_ijr+i)+j) = *(*(X_ijr+i)+j+1); } assert( *(num_sublevels+i) > 0 ); *(Y+i) = realloc( *(Y+i), (*(num_sublevels+i))*sizeof(DdNode *) ); *(X_ijr+i) = realloc( *(X_ijr+i), (*(num_sublevels+i))*sizeof(DdNode **) ); if (*(Y+i) == NULL || *(X_ijr+i) == NULL) { perror( __FILE__ ", realloc" ); exit(-1); } } /* Make primed form of W and take conjunction with system transition (safety) formula, for use while stepping down Y_i sets. Note that we assume the variable map has been appropriately defined in the CUDD manager, after the call to compute_winning_set_BDD above. */ tmp = Cudd_bddVarMap( manager, W ); if (tmp == NULL) { fprintf( stderr, "Error synthesize: Error in swapping variables with primed" " forms.\n" ); free( state ); free( cube ); return NULL; } Cudd_Ref( tmp ); strans_into_W = Cudd_bddAnd( manager, strans, tmp ); Cudd_Ref( strans_into_W ); Cudd_RecursiveDeref( manager, tmp ); /* From each initial state, build strategy by propagating forward toward the next goal (current target goal specified by "mode" of a state), and iterating until every reached state and mode combination has already been encountered (whence the strategy already built). */ if (init_flags == ALL_INIT || (init_flags == ONE_SIDE_INIT && spc.sys_init == NULL)) { if (init_flags == ALL_INIT) { if (verbose > 1) logprint( "Enumerating initial states, given init_flags =" " ALL_INIT" ); tmp = Cudd_bddAnd( manager, einit, sinit ); } else { if (verbose > 1) logprint( "Enumerating initial states, given init_flags =" " ONE_SIDE_INIT and empty SYSINIT" ); tmp = einit; Cudd_Ref( tmp ); } Cudd_Ref( tmp ); Cudd_AutodynDisable( manager ); Cudd_ForeachCube( manager, tmp, gen, gcube, gvalue ) { initialize_cube( state, gcube, num_env+num_sys ); while (!saturated_cube( state, gcube, num_env+num_sys )) { this_node_stack = insert_anode( this_node_stack, 0, -1, False, state, num_env+num_sys ); if (this_node_stack == NULL) { fprintf( stderr, "Error synthesize: building list of initial" " states.\n" ); return NULL; } increment_cube( state, gcube, num_env+num_sys ); } this_node_stack = insert_anode( this_node_stack, 0, -1, False, state, num_env+num_sys ); if (this_node_stack == NULL) { fprintf( stderr, "Error synthesize: building list of initial" " states.\n" ); return NULL; } } Cudd_AutodynEnable( manager, CUDD_REORDER_SAME ); Cudd_RecursiveDeref( manager, tmp ); } else if (init_flags == ALL_ENV_EXIST_SYS_INIT) {
int main(){ Ty_Node *root= NULL; Ty_Node *p = NULL; char fpath[100]; char order[100]; element data; char a[100]; char *token = NULL; char *token1 = NULL; char *separator = " ,\n"; int level = 0; printf("파일 이름이 뭐인가요?\n"); scanf("%s", &fpath); // 파일이름 입력 fp = fopen(fpath, "r"); if(fp){ // 파일이름이 존재할 때 insert_from_file(&root); // 파일로부터 노드 삽입 while(1){ printf("명령어를 입력하세요\n"); fflush(stdin); // scanf 버퍼 비우기 scanf("%[^\n]s", &order); // scanf 를 마치 gets 처럼 공백 무시하고 \n 까지 읽어들이는 방법 token = strtok(order, separator); // token 을 이용해 단어 분할 switch(token[0]){ // 첫번째 명령어 부분을 switch 에 넣어 사용 case는 아스키코드값으로 case 105 : // i token = strtok(NULL, separator); strcpy(data.name, token); token = strtok(NULL, separator); data.key = atoi(token); insert_anode(&root, data); // 추가정보를 data에 넣어서 노드에 삽입 break; case 112 : // p inorder(root); // 중위순회방식으로 출력 break; case 100 : // d token = strtok(NULL, separator); delete_anode(root, token); // 삭제 break; case 115 : // s token = strtok(NULL, separator); p = search_anode(root, token); // 해당 키값의 노드정보 출력 if(p !=NULL) printf("%s %d\n", p->data.name, p->data.key); else printf("%s을 찾을 수 없습니다\n", token); break; case 118 : // v token = strtok(NULL, separator); level = get_level(root, token); // 해당 키값의 노드 높이 출력 if(level !=0) printf("%s의 높이 : %d\n", token, level); else printf("%s을 찾을 수 없습니다\n", token); break; case 98 : // b token = strtok(NULL, separator); get_sibling(root, token); // 해당 키값의 노드 형제 출력 break; case 104 : // h level = get_height(root); // 높이 출력 if(level !=NULL) printf("높이 : %d\n", level); break; case 101 : exit(0); // 종료 } } } else { printf("file 이름을 찾을 수 없습니다\n"); } }