1 /* Copyright (c) 2011-2013 Da SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "mc_private.h"
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc,
11 "Logging specific to algorithms for liveness properties verification");
13 /********* Global variables *********/
15 xbt_dynar_t acceptance_pairs;
16 xbt_dynar_t visited_pairs;
17 xbt_dynar_t successors;
20 /********* Static functions *********/
22 static xbt_dynar_t get_atomic_propositions_values(){
25 unsigned int cursor = 0;
26 xbt_automaton_propositional_symbol_t ps = NULL;
27 xbt_dynar_t values = xbt_dynar_new(sizeof(int), NULL);
29 xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
30 f = (int_f_void_t)ps->function;
32 xbt_dynar_push_as(values, int, res);
38 static int is_reached_acceptance_pair(mc_pair_t pair){
40 int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
42 if(xbt_dynar_is_empty(acceptance_pairs)){
45 if(pair->graph_state->system_state == NULL)
46 pair->graph_state->system_state = MC_take_snapshot();
47 xbt_dynar_push(acceptance_pairs, &pair);
59 if(pair->graph_state->system_state == NULL)
60 pair->graph_state->system_state = MC_take_snapshot();
62 size_t current_bytes_used = pair->heap_bytes_used;
63 int current_nb_processes = pair->nb_processes;
65 unsigned int cursor = 0;
66 int previous_cursor = 0, next_cursor = 0;
68 int end = xbt_dynar_length(acceptance_pairs) - 1;
70 mc_pair_t pair_test = NULL;
71 size_t bytes_used_test;
72 int nb_processes_test;
73 int same_processes_and_bytes_not_found = 1;
75 while(start <= end && same_processes_and_bytes_not_found){
76 cursor = (start + end) / 2;
77 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
78 bytes_used_test = pair_test->heap_bytes_used;
79 nb_processes_test = pair_test->nb_processes;
80 if(nb_processes_test < current_nb_processes)
82 if(nb_processes_test > current_nb_processes)
84 if(nb_processes_test == current_nb_processes){
85 if(bytes_used_test < current_bytes_used)
87 if(bytes_used_test > current_bytes_used)
89 if(bytes_used_test == current_bytes_used){
90 same_processes_and_bytes_not_found = 0;
91 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
92 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
93 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
98 return pair_test->num;
102 /* Search another pair with same number of bytes used in std_heap */
103 previous_cursor = cursor - 1;
104 while(previous_cursor >= 0){
105 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, previous_cursor, mc_pair_t);
106 bytes_used_test = pair_test->heap_bytes_used;
107 if(bytes_used_test != current_bytes_used)
109 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
110 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
111 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
116 return pair_test->num;
122 next_cursor = cursor + 1;
123 while(next_cursor < xbt_dynar_length(acceptance_pairs)){
124 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, next_cursor, mc_pair_t);
125 bytes_used_test = pair_test->heap_bytes_used;
126 if(bytes_used_test != current_bytes_used)
128 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
129 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
130 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
135 return pair_test->num;
145 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
146 bytes_used_test = pair_test->heap_bytes_used;
148 if(bytes_used_test < current_bytes_used)
149 xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair);
151 xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
165 static void set_acceptance_pair_reached(mc_pair_t pair){
167 int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
169 if(xbt_dynar_is_empty(acceptance_pairs)){
172 if(pair->graph_state->system_state == NULL)
173 pair->graph_state->system_state = MC_take_snapshot();
174 xbt_dynar_push(acceptance_pairs, &pair);
181 if(pair->graph_state->system_state == NULL)
182 pair->graph_state->system_state = MC_take_snapshot();
184 size_t current_bytes_used = pair->heap_bytes_used;
185 int current_nb_processes = pair->nb_processes;
187 unsigned int cursor = 0;
189 int end = xbt_dynar_length(acceptance_pairs) - 1;
191 mc_pair_t pair_test = NULL;
192 size_t bytes_used_test = 0;
193 int nb_processes_test;
196 cursor = (start + end) / 2;
197 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
198 bytes_used_test = pair_test->heap_bytes_used;
199 nb_processes_test = pair_test->nb_processes;
200 if(nb_processes_test < current_nb_processes)
202 if(nb_processes_test > current_nb_processes)
204 if(nb_processes_test == current_nb_processes){
205 if(bytes_used_test < current_bytes_used)
207 if(bytes_used_test > current_bytes_used)
209 if(bytes_used_test == current_bytes_used)
214 if(bytes_used_test < current_bytes_used)
215 xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair);
217 xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
228 static void remove_acceptance_pair(mc_pair_t pair){
230 int index = xbt_dynar_search_or_negative(acceptance_pairs, pair);
232 xbt_dynar_remove_at(acceptance_pairs, index, NULL);
233 pair->acceptance_removed = 1;
235 if(pair->stack_removed && pair->acceptance_removed){
236 if(_sg_mc_visited == 0){
237 MC_pair_delete(pair);
238 }else if(pair->visited_removed){
239 MC_pair_delete(pair);
245 static int is_visited_pair(mc_pair_t pair){
247 if(_sg_mc_visited == 0)
250 int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
252 if(xbt_dynar_is_empty(visited_pairs)){
255 if(pair->graph_state->system_state == NULL)
256 pair->graph_state->system_state = MC_take_snapshot();
257 xbt_dynar_push(visited_pairs, &pair);
269 if(pair->graph_state->system_state == NULL)
270 pair->graph_state->system_state = MC_take_snapshot();
272 size_t current_bytes_used = pair->heap_bytes_used;
273 int current_nb_processes = pair->nb_processes;
275 unsigned int cursor = 0;
276 int previous_cursor = 0, next_cursor = 0;
278 int end = xbt_dynar_length(visited_pairs) - 1;
280 mc_pair_t pair_test = NULL;
281 size_t bytes_used_test;
282 int nb_processes_test;
283 int same_processes_and_bytes_not_found = 1;
286 while(start <= end && same_processes_and_bytes_not_found){
287 cursor = (start + end) / 2;
288 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t);
289 bytes_used_test = pair_test->heap_bytes_used;
290 nb_processes_test = pair_test->nb_processes;
291 if(nb_processes_test < current_nb_processes)
293 if(nb_processes_test > current_nb_processes)
295 if(nb_processes_test == current_nb_processes){
296 if(bytes_used_test < current_bytes_used)
298 if(bytes_used_test > current_bytes_used)
300 if(bytes_used_test == current_bytes_used){
301 same_processes_and_bytes_not_found = 0;
302 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
303 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
304 XBT_DEBUG("Pair %d", pair_test->num);
305 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
306 xbt_dynar_remove_at(visited_pairs, cursor, NULL);
307 xbt_dynar_insert_at(visited_pairs, cursor, &pair);
308 pair_test->visited_removed = 1;
309 result = pair_test->num;
310 if(pair_test->stack_removed && pair_test->visited_removed){
311 if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
312 if(pair_test->acceptance_removed){
313 MC_pair_delete(pair_test);
316 MC_pair_delete(pair_test);
320 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
329 /* Search another pair with same number of bytes used in std_heap */
330 previous_cursor = cursor - 1;
331 while(previous_cursor >= 0){
332 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, previous_cursor, mc_pair_t);
333 bytes_used_test = pair_test->heap_bytes_used;
334 if(bytes_used_test != current_bytes_used)
336 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
337 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
338 XBT_DEBUG("Pair %d", pair_test->num);
339 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
340 xbt_dynar_remove_at(visited_pairs, previous_cursor, NULL);
341 xbt_dynar_insert_at(visited_pairs, previous_cursor, &pair);
342 pair_test->visited_removed = 1;
343 result = pair_test->num;
344 if(pair_test->stack_removed && pair_test->visited_removed){
345 if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
346 if(pair_test->acceptance_removed){
347 MC_pair_delete(pair_test);
350 MC_pair_delete(pair_test);
353 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
364 next_cursor = cursor + 1;
365 while(next_cursor < xbt_dynar_length(visited_pairs)){
366 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, next_cursor, mc_pair_t);
367 bytes_used_test = pair_test->heap_bytes_used;
368 if(bytes_used_test != current_bytes_used)
370 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
371 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
372 XBT_DEBUG("Pair %d", pair_test->num);
373 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
374 xbt_dynar_remove_at(visited_pairs, next_cursor, NULL);
375 xbt_dynar_insert_at(visited_pairs, next_cursor, &pair);
376 pair_test->visited_removed = 1;
377 result = pair_test->num;
378 if(pair_test->stack_removed && pair_test->visited_removed){
379 if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
380 if(pair_test->acceptance_removed){
381 MC_pair_delete(pair_test);
384 MC_pair_delete(pair_test);
387 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
402 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t);
403 bytes_used_test = pair_test->heap_bytes_used;
405 if(bytes_used_test < current_bytes_used)
406 xbt_dynar_insert_at(visited_pairs, cursor + 1, &pair);
408 xbt_dynar_insert_at(visited_pairs, cursor, &pair);
410 if(xbt_dynar_length(visited_pairs) > _sg_mc_visited){
411 int min = mc_stats->expanded_states;
412 unsigned int cursor2 = 0;
413 unsigned int index = 0;
414 xbt_dynar_foreach(visited_pairs, cursor2, pair_test){
415 if(pair_test->num < min){
417 min = pair_test->num;
420 xbt_dynar_remove_at(visited_pairs, index, &pair_test);
421 pair_test->visited_removed = 1;
422 if(pair_test->stack_removed && pair_test->acceptance_removed && pair_test->visited_removed)
423 MC_pair_delete(pair_test);
428 xbt_dynar_foreach(visited_pairs, cursor, pair_test){
429 fprintf(stderr, "Visited pair %d, nb_processes %d and heap_bytes_used %zu\n", pair_test->num, pair_test->nb_processes, pair_test->heap_bytes_used);
443 static int MC_automaton_evaluate_label(xbt_automaton_exp_label_t l){
447 int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp);
448 int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp);
449 return (left_res || right_res);
452 int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp);
453 int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp);
454 return (left_res && right_res);
457 int res = MC_automaton_evaluate_label(l->u.exp_not);
461 unsigned int cursor = 0;
462 xbt_automaton_propositional_symbol_t p = NULL;
464 xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, p){
465 if(strcmp(p->pred, l->u.predicat) == 0){
466 f = (int_f_void_t)p->function;
481 /********* DDFS Algorithm *********/
484 void MC_ddfs_init(void){
486 initial_state_liveness->raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
488 XBT_DEBUG("**************************************************");
489 XBT_DEBUG("Double-DFS init");
490 XBT_DEBUG("**************************************************");
492 mc_pair_t initial_pair = NULL;
493 smx_process_t process;
495 MC_wait_for_requests();
499 acceptance_pairs = xbt_dynar_new(sizeof(mc_pair_t), NULL);
500 visited_pairs = xbt_dynar_new(sizeof(mc_pair_t), NULL);
501 successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
503 initial_state_liveness->snapshot = MC_take_snapshot();
507 unsigned int cursor = 0;
508 xbt_automaton_state_t automaton_state;
510 xbt_dynar_foreach(_mc_property_automaton->states, cursor, automaton_state){
511 if(automaton_state->type == -1){ /* Initial automaton state */
515 initial_pair = MC_pair_new();
516 initial_pair->automaton_state = automaton_state;
517 initial_pair->graph_state = MC_state_new();
518 initial_pair->atomic_propositions = get_atomic_propositions_values();
520 /* Get enabled process and insert it in the interleave set of the graph_state */
521 xbt_swag_foreach(process, simix_global->process_list){
522 if(MC_process_is_enabled(process)){
523 MC_state_interleave_process(initial_pair->graph_state, process);
527 initial_pair->requests = MC_state_interleave_size(initial_pair->graph_state);
529 xbt_fifo_unshift(mc_stack_liveness, initial_pair);
534 MC_restore_snapshot(initial_state_liveness->snapshot);
540 }else if(automaton_state->type == 2){ /* Acceptance automaton state */
544 initial_pair = MC_pair_new();
545 initial_pair->automaton_state = automaton_state;
546 initial_pair->graph_state = MC_state_new();
547 initial_pair->atomic_propositions = get_atomic_propositions_values();
549 /* Get enabled process and insert it in the interleave set of the graph_state */
550 xbt_swag_foreach(process, simix_global->process_list){
551 if(MC_process_is_enabled(process)){
552 MC_state_interleave_process(initial_pair->graph_state, process);
556 initial_pair->requests = MC_state_interleave_size(initial_pair->graph_state);
558 xbt_fifo_unshift(mc_stack_liveness, initial_pair);
562 set_acceptance_pair_reached(initial_pair);
565 MC_restore_snapshot(initial_state_liveness->snapshot);
573 if(initial_state_liveness->raw_mem_set)
582 void MC_ddfs(int search_cycle){
584 smx_process_t process;
585 mc_pair_t current_pair = NULL;
587 if(xbt_fifo_size(mc_stack_liveness) == 0)
591 /* Get current pair */
592 current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness));
594 /* Update current state in buchi automaton */
595 _mc_property_automaton->current_state = current_pair->automaton_state;
598 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness), search_cycle);
600 mc_stats->visited_pairs++;
603 smx_simcall_t req = NULL;
606 xbt_automaton_transition_t transition_succ;
607 unsigned int cursor = 0;
611 mc_pair_t next_pair = NULL;
614 if(xbt_fifo_size(mc_stack_liveness) < _sg_mc_max_depth){
616 if(current_pair->requests > 0){
618 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
620 /* Debug information */
622 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
623 req_str = MC_request_to_string(req, value);
624 XBT_DEBUG("Execute: %s", req_str);
628 MC_state_set_executed_request(current_pair->graph_state, req, value);
629 mc_stats->executed_transitions++;
631 /* Answer the request */
632 SIMIX_simcall_pre(req, value);
634 /* Wait for requests (schedules processes) */
635 MC_wait_for_requests();
639 xbt_dynar_reset(successors);
645 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
647 res = MC_automaton_evaluate_label(transition_succ->label);
649 if(res == 1){ // enabled transition in automaton
653 next_pair = MC_pair_new();
654 next_pair->graph_state = MC_state_new();
655 next_pair->automaton_state = transition_succ->dst;
656 next_pair->atomic_propositions = get_atomic_propositions_values();
658 /* Get enabled process and insert it in the interleave set of the next graph_state */
659 xbt_swag_foreach(process, simix_global->process_list){
660 if(MC_process_is_enabled(process)){
661 MC_state_interleave_process(next_pair->graph_state, process);
665 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
667 xbt_dynar_push(successors, &next_pair);
676 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
678 res = MC_automaton_evaluate_label(transition_succ->label);
680 if(res == 2){ // true transition in automaton
684 next_pair = MC_pair_new();
685 next_pair->graph_state = MC_state_new();
686 next_pair->automaton_state = transition_succ->dst;
687 next_pair->atomic_propositions = get_atomic_propositions_values();
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_pair->graph_state, process);
696 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
698 xbt_dynar_push(successors, &next_pair);
707 xbt_dynar_foreach(successors, cursor, pair_succ){
709 if(search_cycle == 1){
711 if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){
713 if((reached_num = is_reached_acceptance_pair(pair_succ)) != -1){
715 XBT_INFO("Next pair (depth = %d, %u interleave) already reached (equal to state %d) !", xbt_fifo_size(mc_stack_liveness) + 1, MC_state_interleave_size(pair_succ->graph_state), reached_num);
717 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
718 XBT_INFO("| ACCEPTANCE CYCLE |");
719 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
720 XBT_INFO("Counter-example that violates formula :");
721 MC_show_stack_liveness(mc_stack_liveness);
722 MC_dump_stack_liveness(mc_stack_liveness);
723 MC_print_statistics(mc_stats);
728 if(is_visited_pair(pair_succ) != -1){
730 XBT_DEBUG("Next pair already visited !");
735 XBT_DEBUG("Next pair (depth =%d) -> Acceptance pair (%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->automaton_state->id);
738 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
741 MC_ddfs(search_cycle);
749 if(is_visited_pair(pair_succ) != -1){
751 XBT_DEBUG("Next pair already visited !");
757 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
760 MC_ddfs(search_cycle);
767 if(is_visited_pair(pair_succ) != -1){
769 XBT_DEBUG("Next pair already visited !");
774 if(((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
776 XBT_DEBUG("Next pair (depth =%d) -> Acceptance pair (%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->automaton_state->id);
778 set_acceptance_pair_reached(pair_succ);
785 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
788 MC_ddfs(search_cycle);
794 /* Restore system before checking others successors */
795 if(cursor != (xbt_dynar_length(successors) - 1))
796 MC_replay_liveness(mc_stack_liveness, 1);
800 if(MC_state_interleave_size(current_pair->graph_state) > 0){
801 XBT_DEBUG("Backtracking to depth %d", xbt_fifo_size(mc_stack_liveness));
802 MC_replay_liveness(mc_stack_liveness, 0);
809 mc_stats->executed_transitions++;
811 XBT_DEBUG("No more request to execute in this state, search evolution in Büchi Automaton.");
815 xbt_dynar_reset(successors);
821 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
823 res = MC_automaton_evaluate_label(transition_succ->label);
825 if(res == 1){ // enabled transition in automaton
829 next_pair = MC_pair_new();
830 next_pair->graph_state = MC_state_new();
831 next_pair->automaton_state = transition_succ->dst;
832 next_pair->atomic_propositions = get_atomic_propositions_values();
834 /* Get enabled process and insert it in the interleave set of the next graph_state */
835 xbt_swag_foreach(process, simix_global->process_list){
836 if(MC_process_is_enabled(process)){
837 MC_state_interleave_process(next_pair->graph_state, process);
841 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
843 xbt_dynar_push(successors, &next_pair);
852 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
854 res = MC_automaton_evaluate_label(transition_succ->label);
856 if(res == 2){ // true transition in automaton
860 next_pair = MC_pair_new();
861 next_pair->graph_state = MC_state_new();
862 next_pair->automaton_state = transition_succ->dst;
863 next_pair->atomic_propositions = get_atomic_propositions_values();
865 /* Get enabled process and insert it in the interleave set of the next graph_state */
866 xbt_swag_foreach(process, simix_global->process_list){
867 if(MC_process_is_enabled(process)){
868 MC_state_interleave_process(next_pair->graph_state, process);
872 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
874 xbt_dynar_push(successors, &next_pair);
883 xbt_dynar_foreach(successors, cursor, pair_succ){
885 if(search_cycle == 1){
887 if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){
889 if((reached_num = is_reached_acceptance_pair(pair_succ)) != -1){
891 XBT_INFO("Next pair (depth = %d) already reached (equal to state %d)!", xbt_fifo_size(mc_stack_liveness) + 1, reached_num);
893 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
894 XBT_INFO("| ACCEPTANCE CYCLE |");
895 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
896 XBT_INFO("Counter-example that violates formula :");
897 MC_show_stack_liveness(mc_stack_liveness);
898 MC_dump_stack_liveness(mc_stack_liveness);
899 MC_print_statistics(mc_stats);
904 if(is_visited_pair(pair_succ) != -1){
906 XBT_DEBUG("Next pair already visited !");
911 XBT_INFO("Next pair (depth = %d) -> Acceptance pair (%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->automaton_state->id);
914 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
917 MC_ddfs(search_cycle);
925 if(is_visited_pair(pair_succ) != -1){
927 XBT_DEBUG("Next pair already visited !");
933 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
936 MC_ddfs(search_cycle);
945 if(is_visited_pair(pair_succ) != -1){
947 XBT_DEBUG("Next pair already visited !");
952 if(((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
954 set_acceptance_pair_reached(pair_succ);
961 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
964 MC_ddfs(search_cycle);
970 /* Restore system before checking others successors */
971 if(cursor != xbt_dynar_length(successors) - 1)
972 MC_replay_liveness(mc_stack_liveness, 1);
980 XBT_WARN("/!\\ Max depth reached ! /!\\ ");
981 if(MC_state_interleave_size(current_pair->graph_state) > 0){
982 XBT_WARN("/!\\ But, there are still processes to interleave. Model-checker will not be able to ensure the soundness of the verification from now. /!\\ ");
983 XBT_WARN("Notice : the default value of max depth is 1000 but you can change it with cfg=model-check/max_depth:value.");
988 if(xbt_fifo_size(mc_stack_liveness) == _sg_mc_max_depth ){
989 XBT_DEBUG("Pair (depth = %d) shifted in stack, maximum depth reached", xbt_fifo_size(mc_stack_liveness) );
991 XBT_DEBUG("Pair (depth = %d) shifted in stack", xbt_fifo_size(mc_stack_liveness) );
996 xbt_fifo_remove(mc_stack_liveness, current_pair);
997 current_pair->stack_removed = 1;
998 if((current_pair->automaton_state->type == 1) || (current_pair->automaton_state->type == 2)){
999 remove_acceptance_pair(current_pair);
1001 if(_sg_mc_visited == 0)
1002 MC_pair_delete(current_pair);
1003 else if(current_pair->visited_removed)
1004 MC_pair_delete(current_pair);