4 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dfs, mc,
5 "Logging specific to MC DFS algorithm");
8 extern xbt_fifo_t mc_snapshot_stack;
9 xbt_dynar_t initial_pairs = NULL;
11 xbt_dynar_t list_pairs_reached = NULL;
12 extern mc_snapshot_t initial_snapshot;
13 xbt_dynar_t visited_pairs = NULL;
15 mc_pairs_t new_pair(mc_snapshot_t sn, mc_state_t sg, xbt_state_t st){
17 p = xbt_new0(s_mc_pairs_t, 1);
19 p->automaton_state = st;
22 p->pairs_reached = xbt_dynar_new(sizeof(int), NULL);
28 void set_pair_visited(int np, int sc){
29 mc_visited_pairs_t p = NULL;
30 p = xbt_new0(s_mc_visited_pairs_t, 1);
34 xbt_dynar_push(visited_pairs, &p);
35 //XBT_DEBUG("New visited pair , length of visited pairs : %lu", xbt_dynar_length(visited_pairs));
38 int pair_reached(xbt_dynar_t lpr, int num_pair){
40 //XBT_DEBUG("Search pair reached");
41 //XBT_DEBUG("Lpr length : %lu", xbt_dynar_length(lpr));
44 unsigned int cursor = 0;
46 xbt_dynar_foreach(lpr, cursor, n){
54 int visited(int np, int sc){
56 mc_visited_pairs_t p = NULL;
58 //XBT_DEBUG("Length of visited pairs : %lu", xbt_dynar_length(visited_pairs));
60 xbt_dynar_foreach(visited_pairs, c, p){
62 //XBT_DEBUG("Visited pair : %p", p);
63 if((p->num_pair == np) && (p->search_cycle == sc)){
71 void MC_dfs_init(xbt_automaton_t a){
73 mc_pairs_t mc_initial_pair = NULL;
74 mc_state_t initial_graph_state = NULL;
75 smx_process_t process;
79 MC_wait_for_requests();
83 //XBT_DEBUG("Taking initial snapshot");
85 initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
87 initial_graph_state = MC_state_new();
88 xbt_swag_foreach(process, simix_global->process_list){
89 if(MC_process_is_enabled(process)){
90 MC_state_interleave_process(initial_graph_state, process);
94 list_pairs_reached = xbt_dynar_new(sizeof(int), NULL);
95 visited_pairs = xbt_dynar_new(sizeof(mc_visited_pairs_t), NULL);
97 MC_take_snapshot(initial_snapshot);
102 /* regarder dans l'automate toutes les transitions activables grâce à l'état initial du système
103 -> donnera les états initiaux de la propriété consistants avec l'état initial du système */
105 unsigned int cursor = 0;
106 unsigned int cursor2 = 0;
107 xbt_state_t state = NULL;
109 xbt_transition_t transition_succ;
110 xbt_dynar_t elses = xbt_dynar_new(sizeof(mc_pairs_t), NULL);
111 xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pairs_t), NULL);
112 // int enabled_transition = 0;
113 mc_pairs_t pair_succ;
115 xbt_dynar_foreach(a->states, cursor, state){
116 if(state->type == -1){
117 xbt_dynar_foreach(state->out, cursor2, transition_succ){
118 res = MC_automaton_evaluate_label(a, transition_succ->label);
124 mc_initial_pair = new_pair(initial_snapshot, initial_graph_state, transition_succ->dst);
125 xbt_dynar_push(successors, &mc_initial_pair);
134 mc_initial_pair = new_pair(initial_snapshot, initial_graph_state, transition_succ->dst);
135 xbt_dynar_push(elses, &mc_initial_pair);
144 if(xbt_dynar_length(successors) > 0){
147 xbt_dynar_foreach(successors, cursor, pair_succ){
150 xbt_fifo_unshift(mc_snapshot_stack, pair_succ);
154 set_pair_visited(pair_succ->num, 0);
165 if(xbt_dynar_length(elses) > 0){
167 xbt_dynar_foreach(elses, cursor, pair_succ){
170 xbt_fifo_unshift(mc_snapshot_stack, pair_succ);
171 //XBT_DEBUG("New initial pair from elses");
175 set_pair_visited(pair_succ->num, 0);
184 XBT_DEBUG("No initial state !");
194 void MC_dfs(xbt_automaton_t a, int search_cycle, int restore){
197 if(xbt_fifo_size(mc_snapshot_stack) == 0)
200 //XBT_DEBUG("Lpr length before snapshot: %lu", xbt_dynar_length(lpr));
203 MC_restore_snapshot(((mc_pairs_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_snapshot_stack)))->system_state);
207 //XBT_DEBUG("Lpr length after restore snapshot: %lu", xbt_dynar_length(lpr));
209 /* Get current state */
210 mc_pairs_t current_pair = (mc_pairs_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_snapshot_stack));
212 XBT_DEBUG("**************************************************");
213 XBT_DEBUG("State=%p, %u interleave, mc_snapshot_stack size=%d",current_pair, MC_state_interleave_size(current_pair->graph_state), xbt_fifo_size(mc_snapshot_stack));
214 //XBT_DEBUG("Restore : %d", restore);
217 /* Update statistics */
218 mc_stats->visited_states++;
222 smx_process_t process = NULL;
224 mc_state_t next_graph_state = NULL;
225 smx_req_t req = NULL;
228 mc_pairs_t pair_succ;
229 xbt_transition_t transition_succ;
232 //int enabled_transition = 0;
234 xbt_dynar_t elses = xbt_dynar_new(sizeof(mc_pairs_t), NULL);
235 xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pairs_t), NULL);
237 mc_pairs_t next_pair;
238 mc_snapshot_t next_snapshot;
239 mc_snapshot_t current_snapshot = xbt_new0(s_mc_snapshot_t, 1);
241 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
243 XBT_DEBUG("Current pair : %p (%u interleave)", current_pair, MC_state_interleave_size(current_pair->graph_state)+1);
246 MC_take_snapshot(current_snapshot);
250 /* Debug information */
251 if(XBT_LOG_ISENABLED(mc_dfs, xbt_log_priority_debug)){
252 req_str = MC_request_to_string(req, value);
253 XBT_DEBUG("Execute: %s", req_str);
257 MC_state_set_executed_request(current_pair->graph_state, req, value);
258 mc_stats->executed_transitions++;
260 /* Answer the request */
261 SIMIX_request_pre(req, value);
263 /* Wait for requests (schedules processes) */
264 MC_wait_for_requests();
267 /* Create the new expanded graph_state */
270 next_graph_state = MC_state_new();
272 /* Get an enabled process and insert it in the interleave set of the next graph_state */
273 xbt_swag_foreach(process, simix_global->process_list){
274 if(MC_process_is_enabled(process)){
275 MC_state_interleave_process(next_graph_state, process);
279 next_snapshot = xbt_new0(s_mc_snapshot_t, 1);
280 MC_take_snapshot(next_snapshot);
284 xbt_dynar_reset(elses);
285 xbt_dynar_reset(successors);
288 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
290 res = MC_automaton_evaluate_label(a, transition_succ->label);
294 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
296 //XBT_DEBUG("Next pair : %p", next_pair);
298 if(res == 1){ // enabled transition in automaton
299 xbt_dynar_push(successors, &next_pair);
300 //XBT_DEBUG("New Successors length : %lu", xbt_dynar_length(successors));
303 xbt_dynar_push(elses, &next_pair);
304 //XBT_DEBUG("New Elses length : %lu", xbt_dynar_length(elses));
312 if((xbt_dynar_length(successors) == 0) && (xbt_dynar_length(elses) == 0) ){
316 next_pair = new_pair(next_snapshot, next_graph_state, current_pair->automaton_state);
317 xbt_dynar_push(successors, &next_pair);
323 //XBT_DEBUG("Successors length : %lu", xbt_dynar_length(successors));
324 //XBT_DEBUG("Elses length : %lu", xbt_dynar_length(elses));
326 if(xbt_dynar_length(successors) >0){
329 xbt_dynar_foreach(successors, cursor, pair_succ){
331 //XBT_DEBUG("Pair succ from successors : %p", pair_succ);
335 if(visited(pair_succ->num, search_cycle) == 0){
336 xbt_fifo_unshift(mc_snapshot_stack, pair_succ);
337 set_pair_visited(pair_succ->num, search_cycle);
338 MC_dfs(a, search_cycle, 0);
340 if((search_cycle == 0) && (pair_succ->automaton_state->type == 1)){
341 xbt_fifo_unshift(mc_snapshot_stack, pair_succ);
342 xbt_dynar_push(pair_succ->pairs_reached, &(pair_succ->num));
343 XBT_DEBUG("Acceptance state : %p (automaton state : %p)", pair_succ, pair_succ->automaton_state);
355 xbt_dynar_foreach(elses, cursor, pair_succ){
357 //XBT_DEBUG("Pair succ from elses : %p", pair_succ);
361 if(visited(pair_succ->num, search_cycle) == 0){
362 //XBT_DEBUG("Pair not visited");
363 xbt_fifo_unshift(mc_snapshot_stack, pair_succ);
364 set_pair_visited(pair_succ->num, search_cycle);
365 MC_dfs(a, search_cycle, 0);
367 if((search_cycle == 0) && (pair_succ->automaton_state->type == 1)){
368 xbt_fifo_unshift(mc_snapshot_stack, pair_succ);
369 xbt_dynar_push(pair_succ->pairs_reached, &(pair_succ->num));
370 XBT_DEBUG("Acceptance state : %p (automaton state : %p)", pair_succ, pair_succ->automaton_state);
383 XBT_DEBUG("Restoring snapshot");
385 MC_restore_snapshot(current_snapshot);
390 if((search_cycle == 1) && (pair_reached(current_pair->pairs_reached, current_pair->num) == 1)){
391 XBT_DEBUG("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
392 XBT_DEBUG("| ACCEPTANCE CYCLE |");
393 XBT_DEBUG("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
394 // afficher chemin menant au cycle d'acceptation
400 xbt_fifo_shift(mc_snapshot_stack);
403 XBT_DEBUG("Shift state in snapshot_stack, mc_snapshot_stack size=%d", xbt_fifo_size(mc_snapshot_stack));
408 int MC_automaton_evaluate_label(xbt_automaton_t a, xbt_exp_label_t l){
412 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
413 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
414 return (left_res || right_res);
418 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
419 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
420 return (left_res && right_res);
424 int res = MC_automaton_evaluate_label(a, l->u.exp_not);
429 unsigned int cursor = 0;
430 xbt_propositional_symbol_t p = NULL;
431 xbt_dynar_foreach(a->propositional_symbols, cursor, p){
432 if(strcmp(p->pred, l->u.predicat) == 0){
433 int (*f)() = p->function;
449 /*void MC_dfs(xbt_automaton_t a, int search_cycle){
451 xbt_state_t current_state = (xbt_state_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(stack_automaton_dfs));
452 xbt_transition_t transition_succ = NULL;
453 xbt_state_t successor = NULL;
454 unsigned int cursor = 0;
455 xbt_dynar_t elses = xbt_dynar_new(sizeof(xbt_transition_t), NULL);
458 //printf("++ current state : %s\n", current_state->id);
460 xbt_dynar_foreach(current_state->out, cursor, transition_succ){
461 successor = transition_succ->dst;
462 res = MC_automaton_evaluate_label(a, transition_succ->label);
463 //printf("-- state : %s, transition_label : %d, res = %d\n", successor->id, transition_succ->label->type, res);
465 if(search_cycle == 1 && reached_dfs != NULL){
466 if(strcmp(reached_dfs->id, successor->id) == 0){
467 xbt_dynar_push(state_automaton_visited_dfs, &successor);
468 printf("\n-*-*-*-*-*-*- ACCEPTANCE CYCLE -*-*-*-*-*-*-\n");
469 printf("Visited states : \n");
470 unsigned int cursor2 = 0;
471 xbt_state_t visited_state = NULL;
472 xbt_dynar_foreach(state_automaton_visited_dfs, cursor2, visited_state){
473 printf("State : %s\n", visited_state->id);
478 if(successor->visited == 0){
479 successor->visited = 1;
480 xbt_fifo_unshift(stack_automaton_dfs, successor);
481 xbt_dynar_push(state_automaton_visited_dfs, &successor);
482 MC_dfs(a, search_cycle);
483 if(search_cycle == 0 && successor->type == 1){
484 reached_dfs = successor;
490 xbt_dynar_push(elses,&transition_succ);
496 xbt_dynar_foreach(elses, cursor, transition_succ){
497 successor = transition_succ->dst;
498 if(search_cycle == 1 && reached_dfs != NULL){
499 if(strcmp(reached_dfs->id, successor->id) == 0){
500 xbt_dynar_push(state_automaton_visited_dfs, &successor);
501 printf("\n-*-*-*-*-*-*- ACCEPTANCE CYCLE -*-*-*-*-*-*-\n");
502 printf("Visited states : \n");
503 unsigned int cursor2 = 0;
504 xbt_state_t visited_state = NULL;
505 xbt_dynar_foreach(state_automaton_visited_dfs, cursor2, visited_state){
506 printf("State : %s\n", visited_state->id);
511 if(successor->visited == 0){
512 successor->visited = 1;
513 xbt_fifo_unshift(stack_automaton_dfs, successor);
514 xbt_dynar_push(state_automaton_visited_dfs, &successor);
515 MC_dfs(a, search_cycle);
516 if(search_cycle == 0 && successor->type == 1){
517 reached_dfs = successor;
523 xbt_fifo_shift(stack_automaton_dfs);