4 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc,
5 "Logging specific to algorithms for liveness properties verification");
7 xbt_dynar_t initial_pairs = NULL;
9 xbt_dynar_t reached_pairs;
10 extern mc_snapshot_t initial_snapshot;
12 mc_pair_t new_pair(mc_snapshot_t sn, mc_state_t sg, xbt_state_t st){
14 p = xbt_new0(s_mc_pair_t, 1);
16 p->automaton_state = st;
20 mc_stats_pair->expanded_pairs++;
25 int reached(mc_pair_t pair){
27 char* hash_reached = malloc(sizeof(char)*160);
31 char *hash = malloc(sizeof(char)*160);
32 xbt_sha((char *)&pair, hash);
33 xbt_dynar_foreach(reached_pairs, c, hash_reached){
34 if(strcmp(hash, hash_reached) == 0){
44 void set_pair_reached(mc_pair_t pair){
46 if(reached(pair) == 0){
48 char *hash = malloc(sizeof(char)*160) ;
49 xbt_sha((char *)&pair, hash);
50 xbt_dynar_push(reached_pairs, &hash);
56 void MC_pair_delete(mc_pair_t pair){
57 xbt_free(pair->graph_state->proc_status);
58 xbt_free(pair->graph_state);
59 //xbt_free(pair->automaton_state); -> FIXME : à implémenter
64 int MC_automaton_evaluate_label(xbt_automaton_t a, xbt_exp_label_t l){
68 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
69 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
70 return (left_res || right_res);
74 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
75 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
76 return (left_res && right_res);
80 int res = MC_automaton_evaluate_label(a, l->u.exp_not);
85 unsigned int cursor = 0;
86 xbt_propositional_symbol_t p = NULL;
87 xbt_dynar_foreach(a->propositional_symbols, cursor, p){
88 if(strcmp(p->pred, l->u.predicat) == 0){
89 int (*f)() = p->function;
107 /******************************* DFS with visited state *******************************/
109 xbt_dynar_t visited_pairs;
111 void set_pair_visited(mc_pair_t pair, int sc){
114 mc_visited_pair_t p = NULL;
115 p = xbt_new0(s_mc_visited_pair_t, 1);
117 p->search_cycle = sc;
118 char *hash = malloc(sizeof(char)*160);
119 xbt_sha((char *)&p, hash);
120 xbt_dynar_push(visited_pairs, &hash);
125 int visited(mc_pair_t pair, int sc){
127 char* hash_visited = malloc(sizeof(char)*160);
131 mc_visited_pair_t p = NULL;
132 p = xbt_new0(s_mc_visited_pair_t, 1);
134 p->search_cycle = sc;
135 char *hash = malloc(sizeof(char)*160);
136 xbt_sha((char *)&p, hash);
137 xbt_dynar_foreach(visited_pairs, c, hash_visited){
138 if(strcmp(hash, hash_visited) == 0){
150 void MC_vddfs_stateful_init(xbt_automaton_t a){
152 XBT_DEBUG("**************************************************");
153 XBT_DEBUG("Double-DFS stateful with visited state init");
154 XBT_DEBUG("**************************************************");
156 mc_pair_t mc_initial_pair;
157 mc_state_t initial_graph_state;
158 smx_process_t process;
159 mc_snapshot_t init_snapshot;
161 MC_wait_for_requests();
165 init_snapshot = xbt_new0(s_mc_snapshot_t, 1);
167 initial_graph_state = MC_state_pair_new();
168 xbt_swag_foreach(process, simix_global->process_list){
169 if(MC_process_is_enabled(process)){
170 MC_state_interleave_process(initial_graph_state, process);
174 visited_pairs = xbt_dynar_new(sizeof(char *), NULL);
175 reached_pairs = xbt_dynar_new(sizeof(char *), NULL);
177 MC_take_snapshot(init_snapshot);
181 /* regarder dans l'automate toutes les transitions activables grâce à l'état initial du système
182 -> donnera les états initiaux de la propriété consistants avec l'état initial du système */
184 unsigned int cursor = 0;
185 //unsigned int cursor2 = 0;
186 xbt_state_t state = NULL;
188 //xbt_transition_t transition_succ;
189 //xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
190 //mc_pair_t pair_succ;
192 /* xbt_dynar_foreach(a->states, cursor, state){
193 if(state->type == -1){
194 xbt_dynar_foreach(state->out, cursor2, transition_succ){
195 res = MC_automaton_evaluate_label(a, transition_succ->label);
201 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, transition_succ->dst);
202 xbt_dynar_push(successors, &mc_initial_pair);
214 xbt_dynar_foreach(a->states, cursor, state){
215 if(state->type == -1){
216 xbt_dynar_foreach(state->out, cursor2, transition_succ){
217 res = MC_automaton_evaluate_label(a, transition_succ->label);
223 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, transition_succ->dst);
224 xbt_dynar_push(successors, &mc_initial_pair);
235 if(xbt_dynar_length(successors) == 0){
236 xbt_dynar_foreach(a->states, cursor, state){
237 if(state->type == -1){
240 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, transition_succ->dst);
241 xbt_dynar_push(successors, &mc_initial_pair);
249 xbt_dynar_foreach(successors, cursor, pair_succ){
252 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
257 MC_vddfs_stateful(a, 0, 0);
259 MC_vddfs_stateful(a, 0, 1);
264 xbt_dynar_foreach(a->states, cursor, state){
265 if(state->type == -1){
268 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, state);
269 xbt_fifo_unshift(mc_stack_liveness_stateful, mc_initial_pair);
273 MC_vddfs_stateful(a, 0, 0);
275 MC_vddfs_stateful(a, 0, 1);
282 void MC_vddfs_stateful(xbt_automaton_t a, int search_cycle, int restore){
284 smx_process_t process = NULL;
287 if(xbt_fifo_size(mc_stack_liveness_stateful) == 0)
291 MC_restore_snapshot(((mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful)))->system_state);
296 /* Get current state */
297 mc_pair_t current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
300 xbt_swag_foreach(process, simix_global->process_list){
301 if(MC_process_is_enabled(process)){
302 MC_state_interleave_process(current_pair->graph_state, process);
307 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness_stateful), search_cycle);
308 XBT_DEBUG("Pair : graph=%p, automaton=%p(%s), %u interleave", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id,MC_state_interleave_size(current_pair->graph_state));
311 mc_stats_pair->visited_pairs++;
314 mc_state_t next_graph_state = NULL;
315 smx_req_t req = NULL;
319 xbt_transition_t transition_succ;
323 xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
326 mc_snapshot_t next_snapshot;
327 mc_snapshot_t current_snapshot;
330 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
333 current_snapshot = xbt_new0(s_mc_snapshot_t, 1);
334 MC_take_snapshot(current_snapshot);
338 /* Debug information */
339 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
340 req_str = MC_request_to_string(req, value);
341 XBT_DEBUG("Execute: %s", req_str);
345 MC_state_set_executed_request(current_pair->graph_state, req, value);
347 /* Answer the request */
348 SIMIX_request_pre(req, value);
350 /* Wait for requests (schedules processes) */
351 MC_wait_for_requests();
354 /* Create the new expanded graph_state */
357 next_graph_state = MC_state_pair_new();
359 /* Get enabled process and insert it in the interleave set of the next graph_state */
360 xbt_swag_foreach(process, simix_global->process_list){
361 if(MC_process_is_enabled(process)){
362 MC_state_interleave_process(next_graph_state, process);
366 next_snapshot = xbt_new0(s_mc_snapshot_t, 1);
367 MC_take_snapshot(next_snapshot);
371 xbt_dynar_reset(successors);
374 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
376 res = MC_automaton_evaluate_label(a, transition_succ->label);
381 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
382 xbt_dynar_push(successors, &next_pair);
389 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
391 res = MC_automaton_evaluate_label(a, transition_succ->label);
396 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
397 xbt_dynar_push(successors, &next_pair);
405 if(xbt_dynar_length(successors) == 0){
408 next_pair = new_pair(next_snapshot, next_graph_state, current_pair->automaton_state);
409 xbt_dynar_push(successors, &next_pair);
415 //XBT_DEBUG("Successors length %lu", xbt_dynar_length(successors));
418 xbt_dynar_foreach(successors, cursor, pair_succ){
420 //XBT_DEBUG("Search visited pair : graph=%p, automaton=%p", pair_succ->graph_state, pair_succ->automaton_state);
422 if((search_cycle == 1) && (reached(pair_succ) == 1)){
423 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
424 XBT_INFO("| ACCEPTANCE CYCLE |");
425 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
426 XBT_INFO("Counter-example that violates formula :");
427 MC_show_stack_liveness_stateful(mc_stack_liveness_stateful);
428 MC_dump_stack_liveness_stateful(mc_stack_liveness_stateful);
429 MC_print_statistics_pairs(mc_stats_pair);
433 if(visited(pair_succ, search_cycle) == 0){
435 mc_stats_pair->executed_transitions++;
438 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
439 set_pair_visited(pair_succ, search_cycle);
440 //XBT_DEBUG("New pair (graph=%p, automaton=%p) in stack", pair_succ->graph_state, pair_succ->automaton_state);
443 MC_vddfs_stateful(a, search_cycle, 0);
445 //XBT_DEBUG("Pair (graph=%p, automaton=%p) expanded", pair_succ->graph_state, pair_succ->automaton_state);
449 XBT_DEBUG("Pair already visited !");
454 if((search_cycle == 0) && (current_pair->automaton_state->type == 1)){
456 /*MC_restore_snapshot(current_pair->system_state);
459 xbt_swag_foreach(process, simix_global->process_list){
460 if(MC_process_is_enabled(process)){
461 MC_state_interleave_process(current_pair->graph_state, process);
465 set_pair_reached(current_pair);
466 XBT_DEBUG("Acceptance pair : graph=%p, automaton=%p(%s)", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id);
467 MC_vddfs_stateful(a, 1, 1);
473 if(MC_state_interleave_size(current_pair->graph_state) > 0){
474 MC_restore_snapshot(current_snapshot);
481 mc_pair_t top_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
482 if((top_pair->graph_state == current_pair->graph_state) && (top_pair->automaton_state == current_pair->automaton_state)){
483 xbt_fifo_shift(mc_stack_liveness_stateful);
484 XBT_DEBUG("Pair (graph=%p, automaton =%p) shifted in stack", current_pair->graph_state, current_pair->automaton_state);
494 /********************* Double-DFS stateful without visited state *******************/
497 void MC_ddfs_stateful_init(xbt_automaton_t a){
499 XBT_DEBUG("**************************************************");
500 XBT_DEBUG("Double-DFS stateful without visited state init");
501 XBT_DEBUG("**************************************************");
503 mc_pair_t mc_initial_pair;
504 mc_state_t initial_graph_state;
505 smx_process_t process;
506 mc_snapshot_t init_snapshot;
508 MC_wait_for_requests();
512 init_snapshot = xbt_new0(s_mc_snapshot_t, 1);
514 initial_graph_state = MC_state_pair_new();
515 xbt_swag_foreach(process, simix_global->process_list){
516 if(MC_process_is_enabled(process)){
517 MC_state_interleave_process(initial_graph_state, process);
521 reached_pairs = xbt_dynar_new(sizeof(char *), NULL);
523 MC_take_snapshot(init_snapshot);
527 /* regarder dans l'automate toutes les transitions activables grâce à l'état initial du système
528 -> donnera les états initiaux de la propriété consistants avec l'état initial du système */
530 unsigned int cursor = 0;
531 //unsigned int cursor2 = 0;
532 xbt_state_t state = NULL;
534 //xbt_transition_t transition_succ;
535 //xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
536 //mc_pair_t pair_succ;
538 /*xbt_dynar_foreach(a->states, cursor, state){
539 if(state->type == -1){
540 xbt_dynar_foreach(state->out, cursor2, transition_succ){
541 res = MC_automaton_evaluate_label(a, transition_succ->label);
547 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, transition_succ->dst);
548 xbt_dynar_push(successors, &mc_initial_pair);
560 xbt_dynar_foreach(a->states, cursor, state){
561 if(state->type == -1){
562 xbt_dynar_foreach(state->out, cursor2, transition_succ){
563 res = MC_automaton_evaluate_label(a, transition_succ->label);
569 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, transition_succ->dst);
570 xbt_dynar_push(successors, &mc_initial_pair);
581 if(xbt_dynar_length(successors) == 0){
582 xbt_dynar_foreach(a->states, cursor, state){
583 if(state->type == -1){
586 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, transition_succ->dst);
587 xbt_dynar_push(successors, &mc_initial_pair);
595 xbt_dynar_foreach(a->states, cursor, state){
596 if(state->type == -1){
599 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, state);
600 xbt_fifo_unshift(mc_stack_liveness_stateful, mc_initial_pair);
604 MC_ddfs_stateful(a, 0, 0);
606 MC_ddfs_stateful(a, 0, 1);
613 void MC_ddfs_stateful(xbt_automaton_t a, int search_cycle, int restore){
615 smx_process_t process = NULL;
618 if(xbt_fifo_size(mc_stack_liveness_stateful) == 0)
622 MC_restore_snapshot(((mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful)))->system_state);
627 /* Get current state */
628 mc_pair_t current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
631 xbt_swag_foreach(process, simix_global->process_list){
632 if(MC_process_is_enabled(process)){
633 MC_state_interleave_process(current_pair->graph_state, process);
638 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness_stateful), search_cycle);
639 XBT_DEBUG("Pair : graph=%p, automaton=%p(%s), %u interleave", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id,MC_state_interleave_size(current_pair->graph_state));
641 mc_stats_pair->visited_pairs++;
644 mc_state_t next_graph_state = NULL;
645 smx_req_t req = NULL;
649 xbt_transition_t transition_succ;
653 xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
656 mc_snapshot_t next_snapshot;
657 mc_snapshot_t current_snapshot;
660 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
663 current_snapshot = xbt_new0(s_mc_snapshot_t, 1);
664 MC_take_snapshot(current_snapshot);
668 /* Debug information */
669 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
670 req_str = MC_request_to_string(req, value);
671 XBT_DEBUG("%u Execute: %s", search_cycle, req_str);
675 MC_state_set_executed_request(current_pair->graph_state, req, value);
677 /* Answer the request */
678 SIMIX_request_pre(req, value);
680 /* Wait for requests (schedules processes) */
681 MC_wait_for_requests();
684 /* Create the new expanded graph_state */
687 next_graph_state = MC_state_pair_new();
689 /* Get enabled process and insert it in the interleave set of the next graph_state */
690 xbt_swag_foreach(process, simix_global->process_list){
691 if(MC_process_is_enabled(process)){
692 MC_state_interleave_process(next_graph_state, process);
696 next_snapshot = xbt_new0(s_mc_snapshot_t, 1);
697 MC_take_snapshot(next_snapshot);
701 xbt_dynar_reset(successors);
704 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
706 res = MC_automaton_evaluate_label(a, transition_succ->label);
710 if(res == 1){ // enabled transition in automaton
711 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
712 xbt_dynar_push(successors, &next_pair);
719 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
721 res = MC_automaton_evaluate_label(a, transition_succ->label);
725 if(res == 2){ // enabled transition in automaton
726 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
727 xbt_dynar_push(successors, &next_pair);
734 if(xbt_dynar_length(successors) == 0){
737 next_pair = new_pair(next_snapshot, next_graph_state, current_pair->automaton_state);
738 xbt_dynar_push(successors, &next_pair);
743 //XBT_DEBUG("Successors in automaton %lu", xbt_dynar_length(successors));
746 xbt_dynar_foreach(successors, cursor, pair_succ){
748 //XBT_DEBUG("Search visited pair : graph=%p, automaton=%p", pair_succ->graph_state, pair_succ->automaton_state);
750 if((search_cycle == 1) && (reached(pair_succ) == 1)){
751 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
752 XBT_INFO("| ACCEPTANCE CYCLE |");
753 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
754 XBT_INFO("Counter-example that violates formula :");
755 MC_show_stack_liveness_stateful(mc_stack_liveness_stateful);
756 MC_dump_stack_liveness_stateful(mc_stack_liveness_stateful);
757 MC_print_statistics_pairs(mc_stats_pair);
761 mc_stats_pair->executed_transitions++;
764 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
767 MC_ddfs_stateful(a, search_cycle, 0);
770 if((search_cycle == 0) && (current_pair->automaton_state->type == 1)){
772 set_pair_reached(current_pair);
773 XBT_DEBUG("Acceptance pair : graph=%p, automaton=%p(%s)", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id);
775 /*MC_restore_snapshot(current_pair->system_state);
778 xbt_swag_foreach(process, simix_global->process_list){
779 if(MC_process_is_enabled(process)){
780 MC_state_interleave_process(current_pair->graph_state, process);
784 mc_pair_t top_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
785 if((top_pair->graph_state != current_pair->graph_state) || (top_pair->automaton_state != current_pair->automaton_state)){
787 xbt_fifo_unshift(mc_stack_liveness_stateful, current_pair);
791 MC_ddfs_stateful(a, 1, 1);
796 if(MC_state_interleave_size(current_pair->graph_state) > 0){
797 MC_restore_snapshot(current_snapshot);
805 mc_pair_t top_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
806 if((top_pair->graph_state == current_pair->graph_state) && (top_pair->automaton_state == current_pair->automaton_state)){
807 xbt_fifo_shift(mc_stack_liveness_stateful);
808 XBT_DEBUG("Pair (graph=%p, automaton =%p) shifted in stack", current_pair->graph_state, current_pair->automaton_state);
816 /********************* Double-DFS stateless *******************/
818 void MC_pair_stateless_delete(mc_pair_stateless_t pair){
819 xbt_free(pair->graph_state->proc_status);
820 xbt_free(pair->graph_state);
821 //xbt_free(pair->automaton_state); -> FIXME : à implémenter
825 mc_pair_stateless_t new_pair_stateless(mc_state_t sg, xbt_state_t st){
826 mc_pair_stateless_t p = NULL;
827 p = xbt_new0(s_mc_pair_stateless_t, 1);
828 p->automaton_state = st;
830 mc_stats_pair->expanded_pairs++;
835 int reached_stateless(mc_pair_stateless_t pair){
837 char* hash_reached = malloc(sizeof(char)*160);
841 char *hash = malloc(sizeof(char)*160);
842 xbt_sha((char *)&pair, hash);
843 xbt_dynar_foreach(reached_pairs, c, hash_reached){
844 if(strcmp(hash, hash_reached) == 0){
854 void set_pair_stateless_reached(mc_pair_stateless_t pair){
856 if(reached_stateless(pair) == 0){
859 char *hash = malloc(sizeof(char)*160) ;
860 xbt_sha((char *)&pair, hash);
861 xbt_dynar_push(reached_pairs, &hash);
868 void MC_ddfs_stateless_init(xbt_automaton_t a){
870 XBT_DEBUG("**************************************************");
871 XBT_DEBUG("Double-DFS stateless init");
872 XBT_DEBUG("**************************************************");
874 mc_pair_stateless_t mc_initial_pair;
875 mc_state_t initial_graph_state;
876 smx_process_t process;
878 MC_wait_for_requests();
882 initial_graph_state = MC_state_pair_new();
883 xbt_swag_foreach(process, simix_global->process_list){
884 if(MC_process_is_enabled(process)){
885 MC_state_interleave_process(initial_graph_state, process);
889 reached_pairs = xbt_dynar_new(sizeof(char *), NULL);
893 /* regarder dans l'automate toutes les transitions activables grâce à l'état initial du système
894 -> donnera les états initiaux de la propriété consistants avec l'état initial du système */
896 unsigned int cursor = 0;
897 //unsigned int cursor2 = 0;
898 xbt_state_t state = NULL;
900 //xbt_transition_t transition_succ;
901 //xbt_dynar_t successors = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
902 //xbt_dynar_t elses = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
903 //mc_pair_stateless_t pair_succ;
905 /*xbt_dynar_foreach(a->states, cursor, state){
906 if(state->type == -1){
907 xbt_dynar_foreach(state->out, cursor2, transition_succ){
908 res = MC_automaton_evaluate_label(a, transition_succ->label);
914 mc_initial_pair = new_pair_stateless(initial_graph_state, transition_succ->dst);
915 xbt_dynar_push(successors, &mc_initial_pair);
927 xbt_dynar_foreach(a->states, cursor, state){
928 if(state->type == -1){
929 xbt_dynar_foreach(state->out, cursor2, transition_succ){
930 res = MC_automaton_evaluate_label(a, transition_succ->label);
936 mc_initial_pair = new_pair_stateless(initial_graph_state, transition_succ->dst);
937 xbt_dynar_push(successors, &mc_initial_pair);
949 if((xbt_dynar_length(successors) == 0) && (xbt_dynar_length(elses) == 0)){
950 xbt_dynar_foreach(a->states, cursor, state){
951 if(state->type == -1){
954 mc_initial_pair = new_pair_stateless(initial_graph_state, transition_succ->dst);
955 xbt_dynar_push(successors, &mc_initial_pair);
964 xbt_dynar_foreach(successors, cursor, pair_succ){
967 xbt_fifo_unshift(mc_stack_liveness_stateless, pair_succ);
969 initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
970 MC_take_snapshot(initial_snapshot);
975 MC_ddfs_stateless(a, 0, 0);
977 MC_ddfs_stateless(a, 0, 1);
981 xbt_dynar_foreach(a->states, cursor, state){
982 if(state->type == -1){
985 mc_initial_pair = new_pair_stateless(initial_graph_state, state);
986 xbt_fifo_unshift(mc_stack_liveness_stateless, mc_initial_pair);
988 initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
989 MC_take_snapshot(initial_snapshot);
994 MC_ddfs_stateless(a, 0);
996 MC_restore_snapshot(initial_snapshot);
998 MC_ddfs_stateless(a, 0);
1005 void MC_ddfs_stateless(xbt_automaton_t a, int search_cycle){
1007 smx_process_t process = NULL;
1009 if(xbt_fifo_size(mc_stack_liveness_stateless) == 0)
1012 //XBT_DEBUG("Stack size before restore %u", xbt_fifo_size(mc_stack_liveness_stateless));
1014 /* Get current state */
1015 mc_pair_stateless_t current_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateless));
1017 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness_stateless), search_cycle);
1018 XBT_DEBUG("Pair : graph=%p, automaton=%p(%s), %u interleave", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id,MC_state_interleave_size(current_pair->graph_state));
1020 mc_stats_pair->visited_pairs++;
1023 mc_state_t next_graph_state = NULL;
1024 smx_req_t req = NULL;
1027 mc_pair_stateless_t pair_succ;
1028 xbt_transition_t transition_succ;
1029 unsigned int cursor;
1032 xbt_dynar_t successors;
1034 mc_pair_stateless_t next_pair;
1035 mc_snapshot_t current_snap;
1038 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
1041 current_snap = xbt_new0(s_mc_snapshot_t, 1);
1042 MC_take_snapshot(current_snap);
1045 //XBT_DEBUG("Interleave size %u", MC_state_interleave_size(current_pair->graph_state));
1047 /* Debug information */
1048 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
1049 req_str = MC_request_to_string(req, value);
1050 XBT_DEBUG("-- Pair : graph=%p, automaton=%p(%s), %u interleave", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id,MC_state_interleave_size(current_pair->graph_state));
1051 XBT_DEBUG("Execute: %s", req_str);
1057 MC_state_set_executed_request(current_pair->graph_state, req, value);
1059 /* Answer the request */
1060 SIMIX_request_pre(req, value);
1062 /* Wait for requests (schedules processes) */
1063 MC_wait_for_requests();
1066 /* Create the new expanded graph_state */
1069 next_graph_state = MC_state_pair_new();
1071 /* Get enabled process and insert it in the interleave set of the next graph_state */
1072 xbt_swag_foreach(process, simix_global->process_list){
1073 if(MC_process_is_enabled(process)){
1074 MC_state_interleave_process(next_graph_state, process);
1078 successors = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
1082 //xbt_dynar_reset(successors);
1086 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
1088 res = MC_automaton_evaluate_label(a, transition_succ->label);
1092 if(res == 1){ // enabled transition in automaton
1093 next_pair = new_pair_stateless(next_graph_state, transition_succ->dst);
1094 xbt_dynar_push(successors, &next_pair);
1102 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
1104 res = MC_automaton_evaluate_label(a, transition_succ->label);
1108 if(res == 2){ // enabled transition in automaton
1109 next_pair = new_pair_stateless(next_graph_state, transition_succ->dst);
1110 xbt_dynar_push(successors, &next_pair);
1117 if(xbt_dynar_length(successors) == 0){
1120 next_pair = new_pair_stateless(next_graph_state, current_pair->automaton_state);
1121 xbt_dynar_push(successors, &next_pair);
1127 //XBT_DEBUG("Successors length %lu", xbt_dynar_length(successors));
1129 xbt_dynar_foreach(successors, cursor, pair_succ){
1131 if((search_cycle == 1) && (reached_stateless(pair_succ) == 1)){
1132 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
1133 XBT_INFO("| ACCEPTANCE CYCLE |");
1134 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
1135 XBT_INFO("Counter-example that violates formula :");
1136 MC_show_stack_liveness_stateless(mc_stack_liveness_stateless);
1137 MC_dump_stack_liveness_stateless(mc_stack_liveness_stateless);
1138 MC_print_statistics_pairs(mc_stats_pair);
1142 mc_stats_pair->executed_transitions++;
1145 xbt_fifo_unshift(mc_stack_liveness_stateless, pair_succ);
1148 MC_ddfs_stateless(a, search_cycle);
1150 //XBT_DEBUG("Stack size %u", xbt_fifo_size(mc_stack_liveness_stateless));
1153 //xbt_dynar_reset(successors);
1155 if((search_cycle == 0) && (current_pair->automaton_state->type == 1)){
1157 set_pair_stateless_reached(current_pair);
1158 XBT_DEBUG("Acceptance pair : graph=%p, automaton=%p(%s)", current_pair->graph_state, current_pair->automaton_state, current_pair->automaton_state->id);
1159 MC_restore_snapshot(current_snap);
1162 xbt_swag_foreach(process, simix_global->process_list){
1163 if(MC_process_is_enabled(process)){
1164 MC_state_interleave_process(current_pair->graph_state, process);
1168 MC_ddfs_stateless(a, 1);
1171 if(MC_state_interleave_size(current_pair->graph_state) > 0){
1172 //XBT_DEBUG("Backtracking to depth %u", xbt_fifo_size(mc_stack_liveness_stateless));
1173 //MC_replay_liveness(mc_stack_liveness_stateless);
1174 MC_restore_snapshot(current_snap);
1182 mc_pair_stateless_t top_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateless));
1183 if((top_pair->graph_state == current_pair->graph_state) && (top_pair->automaton_state == current_pair->automaton_state)){
1184 xbt_fifo_shift(mc_stack_liveness_stateless);
1185 XBT_DEBUG("Pair (graph=%p, automaton =%p, search_cycle = %u) shifted in stack", current_pair->graph_state, current_pair->automaton_state, search_cycle);
1188 //XBT_DEBUG("Stack size after shift %u", xbt_fifo_size(mc_stack_liveness_stateless));