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 pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
49 xbt_dynar_push(acceptance_pairs, &pair);
61 if(pair->graph_state->system_state == NULL){
62 pair->graph_state->system_state = MC_take_snapshot();
63 pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
66 size_t current_bytes_used = pair->heap_bytes_used;
67 int current_nb_processes = pair->nb_processes;
69 unsigned int cursor = 0;
70 int previous_cursor = 0, next_cursor = 0;
72 int end = xbt_dynar_length(acceptance_pairs) - 1;
74 mc_pair_t pair_test = NULL;
75 size_t bytes_used_test;
76 int nb_processes_test;
77 int same_processes_and_bytes_not_found = 1;
79 while(start <= end && same_processes_and_bytes_not_found){
80 cursor = (start + end) / 2;
81 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
82 bytes_used_test = pair_test->heap_bytes_used;
83 nb_processes_test = pair_test->nb_processes;
84 if(nb_processes_test < current_nb_processes)
86 else if(nb_processes_test > current_nb_processes)
88 else if(nb_processes_test == current_nb_processes){
89 if(bytes_used_test < current_bytes_used)
91 else if(bytes_used_test > current_bytes_used)
93 else if(bytes_used_test == current_bytes_used){
94 same_processes_and_bytes_not_found = 0;
95 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
96 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
97 XBT_DEBUG("Compare with state %d", pair_test->num);
98 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
103 return pair_test->num;
107 /* Search another pair with same number of bytes used in std_heap */
108 previous_cursor = cursor - 1;
109 while(previous_cursor >= 0){
110 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, previous_cursor, mc_pair_t);
111 bytes_used_test = pair_test->heap_bytes_used;
112 if(bytes_used_test != current_bytes_used)
114 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
115 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
116 XBT_DEBUG("Compare with state %d", pair_test->num);
117 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
122 return pair_test->num;
128 next_cursor = cursor + 1;
129 while(next_cursor < xbt_dynar_length(acceptance_pairs)){
130 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, next_cursor, mc_pair_t);
131 bytes_used_test = pair_test->heap_bytes_used;
132 if(bytes_used_test != current_bytes_used)
134 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
135 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
136 XBT_DEBUG("Compare with state %d", pair_test->num);
137 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
142 return pair_test->num;
152 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
153 bytes_used_test = pair_test->heap_bytes_used;
155 if(bytes_used_test < current_bytes_used)
156 xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair);
158 xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
173 static void set_acceptance_pair_reached(mc_pair_t pair){
175 int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
177 if(xbt_dynar_is_empty(acceptance_pairs)){
180 if(pair->graph_state->system_state == NULL){
181 pair->graph_state->system_state = MC_take_snapshot();
182 pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
184 xbt_dynar_push(acceptance_pairs, &pair);
191 if(pair->graph_state->system_state == NULL){
192 pair->graph_state->system_state = MC_take_snapshot();
193 pair->heap_bytes_used = mmalloc_get_bytes_used(std_heap);
196 size_t current_bytes_used = pair->heap_bytes_used;
197 int current_nb_processes = pair->nb_processes;
199 unsigned int cursor = 0;
201 int end = xbt_dynar_length(acceptance_pairs) - 1;
203 mc_pair_t pair_test = NULL;
204 size_t bytes_used_test = 0;
205 int nb_processes_test;
208 cursor = (start + end) / 2;
209 pair_test = (mc_pair_t)xbt_dynar_get_as(acceptance_pairs, cursor, mc_pair_t);
210 bytes_used_test = pair_test->heap_bytes_used;
211 nb_processes_test = pair_test->nb_processes;
212 if(nb_processes_test < current_nb_processes)
214 if(nb_processes_test > current_nb_processes)
216 if(nb_processes_test == current_nb_processes){
217 if(bytes_used_test < current_bytes_used)
219 if(bytes_used_test > current_bytes_used)
221 if(bytes_used_test == current_bytes_used)
226 if(bytes_used_test < current_bytes_used)
227 xbt_dynar_insert_at(acceptance_pairs, cursor + 1, &pair);
229 xbt_dynar_insert_at(acceptance_pairs, cursor, &pair);
240 static void remove_acceptance_pair(mc_pair_t pair){
242 unsigned int cursor = 0;
246 xbt_dynar_foreach(acceptance_pairs, cursor, pair_test){
247 if(pair_test->num == pair->num){
254 xbt_dynar_remove_at(acceptance_pairs, cursor, NULL);
256 pair->acceptance_removed = 1;
258 if(pair->stack_removed && pair->acceptance_removed){
259 if(_sg_mc_visited == 0){
260 MC_pair_delete(pair);
261 }else if(pair->visited_removed){
262 MC_pair_delete(pair);
268 static int is_visited_pair(mc_pair_t pair){
270 if(_sg_mc_visited == 0)
273 int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
275 if(xbt_dynar_is_empty(visited_pairs)){
278 if(pair->graph_state->system_state == NULL)
279 pair->graph_state->system_state = MC_take_snapshot();
280 xbt_dynar_push(visited_pairs, &pair);
292 if(pair->graph_state->system_state == NULL)
293 pair->graph_state->system_state = MC_take_snapshot();
295 size_t current_bytes_used = pair->heap_bytes_used;
296 int current_nb_processes = pair->nb_processes;
298 unsigned int cursor = 0;
299 int previous_cursor = 0, next_cursor = 0;
301 int end = xbt_dynar_length(visited_pairs) - 1;
303 mc_pair_t pair_test = NULL;
304 size_t bytes_used_test;
305 int nb_processes_test;
306 int same_processes_and_bytes_not_found = 1;
308 while(start <= end && same_processes_and_bytes_not_found){
309 cursor = (start + end) / 2;
310 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t);
311 bytes_used_test = pair_test->heap_bytes_used;
312 nb_processes_test = pair_test->nb_processes;
313 if(nb_processes_test < current_nb_processes)
315 else if(nb_processes_test > current_nb_processes)
317 else if(nb_processes_test == current_nb_processes){
318 if(bytes_used_test < current_bytes_used)
320 else if(bytes_used_test > current_bytes_used)
322 else if(bytes_used_test == current_bytes_used){
323 same_processes_and_bytes_not_found = 0;
324 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
325 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
326 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
327 if(pair_test->other_num == -1)
328 pair->other_num = pair_test->num;
330 pair->other_num = pair_test->other_num;
331 if(dot_output == NULL)
332 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
334 XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
335 xbt_dynar_remove_at(visited_pairs, cursor, NULL);
336 xbt_dynar_insert_at(visited_pairs, cursor, &pair);
337 pair_test->visited_removed = 1;
338 if(pair_test->stack_removed && pair_test->visited_removed){
339 if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
340 if(pair_test->acceptance_removed){
341 MC_pair_delete(pair_test);
344 MC_pair_delete(pair_test);
351 return pair->other_num;
355 /* Search another pair with same number of bytes used in std_heap */
356 previous_cursor = cursor - 1;
357 while(previous_cursor >= 0){
358 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, previous_cursor, mc_pair_t);
359 bytes_used_test = pair_test->heap_bytes_used;
360 if(bytes_used_test != current_bytes_used)
362 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
363 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
364 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
365 if(pair_test->other_num == -1)
366 pair->other_num = pair_test->num;
368 pair->other_num = pair_test->other_num;
369 if(dot_output == NULL)
370 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
372 XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
373 xbt_dynar_remove_at(visited_pairs, previous_cursor, NULL);
374 xbt_dynar_insert_at(visited_pairs, previous_cursor, &pair);
375 pair_test->visited_removed = 1;
376 if(pair_test->stack_removed && pair_test->visited_removed){
377 if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
378 if(pair_test->acceptance_removed){
379 MC_pair_delete(pair_test);
382 MC_pair_delete(pair_test);
389 return pair->other_num;
395 next_cursor = cursor + 1;
396 while(next_cursor < xbt_dynar_length(visited_pairs)){
397 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, next_cursor, mc_pair_t);
398 bytes_used_test = pair_test->heap_bytes_used;
399 if(bytes_used_test != current_bytes_used)
401 if(xbt_automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
402 if(xbt_automaton_propositional_symbols_compare_value(pair_test->atomic_propositions, pair->atomic_propositions) == 0){
403 if(snapshot_compare(pair->graph_state->system_state, pair_test->graph_state->system_state) == 0){
404 if(pair_test->other_num == -1)
405 pair->other_num = pair_test->num;
407 pair->other_num = pair_test->other_num;
408 if(dot_output == NULL)
409 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", pair->num, pair_test->num);
411 XBT_DEBUG("Pair %d already visited ! (equal to pair %d (pair %d in dot_output))", pair->num, pair_test->num, pair->other_num);
412 xbt_dynar_remove_at(visited_pairs, next_cursor, NULL);
413 xbt_dynar_insert_at(visited_pairs, next_cursor, &pair);
414 pair_test->visited_removed = 1;
415 if(pair_test->stack_removed && pair_test->visited_removed){
416 if((pair_test->automaton_state->type == 1) || (pair_test->automaton_state->type == 2)){
417 if(pair_test->acceptance_removed){
418 MC_pair_delete(pair_test);
421 MC_pair_delete(pair_test);
428 return pair->other_num;
438 pair_test = (mc_pair_t)xbt_dynar_get_as(visited_pairs, cursor, mc_pair_t);
439 bytes_used_test = pair_test->heap_bytes_used;
441 if(bytes_used_test < current_bytes_used)
442 xbt_dynar_insert_at(visited_pairs, cursor + 1, &pair);
444 xbt_dynar_insert_at(visited_pairs, cursor, &pair);
446 if(xbt_dynar_length(visited_pairs) > _sg_mc_visited){
447 int min = mc_stats->expanded_states;
448 unsigned int cursor2 = 0;
449 unsigned int index = 0;
450 xbt_dynar_foreach(visited_pairs, cursor2, pair_test){
451 if(pair_test->num < min){
453 min = pair_test->num;
456 xbt_dynar_remove_at(visited_pairs, index, &pair_test);
457 pair_test->visited_removed = 1;
458 if(pair_test->stack_removed && pair_test->acceptance_removed && pair_test->visited_removed)
459 MC_pair_delete(pair_test);
474 static int MC_automaton_evaluate_label(xbt_automaton_exp_label_t l, xbt_dynar_t atomic_propositions_values){
478 int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp, atomic_propositions_values);
479 int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp, atomic_propositions_values);
480 return (left_res || right_res);
483 int left_res = MC_automaton_evaluate_label(l->u.or_and.left_exp, atomic_propositions_values);
484 int right_res = MC_automaton_evaluate_label(l->u.or_and.right_exp, atomic_propositions_values);
485 return (left_res && right_res);
488 int res = MC_automaton_evaluate_label(l->u.exp_not, atomic_propositions_values);
492 unsigned int cursor = 0;
493 xbt_automaton_propositional_symbol_t p = NULL;
494 xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, p){
495 if(strcmp(p->pred, l->u.predicat) == 0)
496 return (int)xbt_dynar_get_as(atomic_propositions_values, cursor, int);
509 /********* DDFS Algorithm *********/
512 void MC_ddfs_init(void){
514 initial_state_liveness->raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
516 XBT_DEBUG("**************************************************");
517 XBT_DEBUG("Double-DFS init");
518 XBT_DEBUG("**************************************************");
520 mc_pair_t initial_pair = NULL;
521 smx_process_t process;
523 MC_wait_for_requests();
527 acceptance_pairs = xbt_dynar_new(sizeof(mc_pair_t), NULL);
528 visited_pairs = xbt_dynar_new(sizeof(mc_pair_t), NULL);
529 successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
531 initial_state_liveness->snapshot = MC_take_snapshot();
532 initial_state_liveness->prev_pair = 0;
536 unsigned int cursor = 0;
537 xbt_automaton_state_t automaton_state;
539 xbt_dynar_foreach(_mc_property_automaton->states, cursor, automaton_state){
540 if(automaton_state->type == -1){ /* Initial 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);
557 initial_pair->search_cycle = 0;
559 xbt_fifo_unshift(mc_stack_liveness, initial_pair);
566 MC_restore_snapshot(initial_state_liveness->snapshot);
571 }else if(automaton_state->type == 2){ /* Acceptance automaton state */
575 initial_pair = MC_pair_new();
576 initial_pair->automaton_state = automaton_state;
577 initial_pair->graph_state = MC_state_new();
578 initial_pair->atomic_propositions = get_atomic_propositions_values();
580 /* Get enabled process and insert it in the interleave set of the graph_state */
581 xbt_swag_foreach(process, simix_global->process_list){
582 if(MC_process_is_enabled(process)){
583 MC_state_interleave_process(initial_pair->graph_state, process);
587 initial_pair->requests = MC_state_interleave_size(initial_pair->graph_state);
588 initial_pair->search_cycle = 1;
590 xbt_fifo_unshift(mc_stack_liveness, initial_pair);
594 set_acceptance_pair_reached(initial_pair);
599 MC_restore_snapshot(initial_state_liveness->snapshot);
605 if(initial_state_liveness->raw_mem_set)
616 smx_process_t process;
617 mc_pair_t current_pair = NULL;
619 if(xbt_fifo_size(mc_stack_liveness) == 0)
622 /* Get current pair */
623 current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness));
625 /* Update current state in buchi automaton */
626 _mc_property_automaton->current_state = current_pair->automaton_state;
628 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness), current_pair->search_cycle);
630 mc_stats->visited_pairs++;
633 smx_simcall_t req = NULL;
636 xbt_automaton_transition_t transition_succ;
637 unsigned int cursor = 0;
639 int reached_num, visited_num;
641 mc_pair_t next_pair = NULL;
642 xbt_dynar_t prop_values = NULL;
644 if(xbt_fifo_size(mc_stack_liveness) < _sg_mc_max_depth){
646 if(current_pair->requests > 0){
648 if(current_pair->search_cycle){
650 if((current_pair->automaton_state->type == 1) || (current_pair->automaton_state->type == 2)){
652 if((reached_num = is_reached_acceptance_pair(current_pair)) != -1){
654 XBT_INFO("Pair %d already reached (equal to pair %d) !", current_pair->num, reached_num);
657 xbt_fifo_shift(mc_stack_liveness);
658 if(dot_output != NULL)
659 fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_state_liveness->prev_pair, reached_num, initial_state_liveness->prev_req);
662 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
663 XBT_INFO("| ACCEPTANCE CYCLE |");
664 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
665 XBT_INFO("Counter-example that violates formula :");
666 MC_show_stack_liveness(mc_stack_liveness);
667 MC_dump_stack_liveness(mc_stack_liveness);
668 MC_print_statistics(mc_stats);
675 if((visited_num = is_visited_pair(current_pair)) != -1){
678 if(dot_output != NULL)
679 fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_state_liveness->prev_pair, visited_num, initial_state_liveness->prev_req);
685 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
688 if(dot_output != NULL){
689 if(initial_state_liveness->prev_pair != 0 && initial_state_liveness->prev_pair != current_pair->num){
690 fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", initial_state_liveness->prev_pair, current_pair->num, initial_state_liveness->prev_req);
691 xbt_free(initial_state_liveness->prev_req);
693 initial_state_liveness->prev_pair = current_pair->num;
697 /* Debug information */
698 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
699 req_str = MC_request_to_string(req, value);
700 XBT_DEBUG("Execute: %s", req_str);
705 if(dot_output != NULL){
706 initial_state_liveness->prev_req = MC_request_get_dot_output(req, value);
707 if(current_pair->search_cycle)
708 fprintf(dot_output, "%d [shape=doublecircle];\n", current_pair->num);
712 MC_state_set_executed_request(current_pair->graph_state, req, value);
713 mc_stats->executed_transitions++;
715 /* Answer the request */
716 SIMIX_simcall_pre(req, value);
718 /* Wait for requests (schedules processes) */
719 MC_wait_for_requests();
722 prop_values = get_atomic_propositions_values();
725 /* Evaluate enabled transition according to atomic propositions values */
727 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
729 res = MC_automaton_evaluate_label(transition_succ->label, prop_values);
731 if(res == 1){ // enabled transition in automaton
735 next_pair = MC_pair_new();
736 next_pair->graph_state = MC_state_new();
737 next_pair->automaton_state = transition_succ->dst;
738 next_pair->atomic_propositions = get_atomic_propositions_values();
740 /* Get enabled process and insert it in the interleave set of the next graph_state */
741 xbt_swag_foreach(process, simix_global->process_list){
742 if(MC_process_is_enabled(process)){
743 MC_state_interleave_process(next_pair->graph_state, process);
747 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
749 if(next_pair->automaton_state->type == 1 || next_pair->automaton_state->type == 2 || current_pair->search_cycle)
750 next_pair->search_cycle = 1;
752 xbt_fifo_unshift(mc_stack_liveness, next_pair);
754 if(mc_stats->expanded_pairs%1000000 == 0)
755 XBT_INFO("Expanded pairs : %lu", mc_stats->expanded_pairs);
765 /* Then, evaluate true transitions (always true, whatever atomic propositions values) */
767 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
769 res = MC_automaton_evaluate_label(transition_succ->label, prop_values);
771 if(res == 2){ // true transition in automaton
775 next_pair = MC_pair_new();
776 next_pair->graph_state = MC_state_new();
777 next_pair->automaton_state = transition_succ->dst;
778 next_pair->atomic_propositions = get_atomic_propositions_values();
780 /* Get enabled process and insert it in the interleave set of the next graph_state */
781 xbt_swag_foreach(process, simix_global->process_list){
782 if(MC_process_is_enabled(process)){
783 MC_state_interleave_process(next_pair->graph_state, process);
787 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
789 if(next_pair->automaton_state->type == 1 || next_pair->automaton_state->type == 2 || current_pair->search_cycle)
790 next_pair->search_cycle = 1;
792 xbt_fifo_unshift(mc_stack_liveness, next_pair);
794 if(mc_stats->expanded_pairs%1000000 == 0)
795 XBT_INFO("Expanded pairs : %lu", mc_stats->expanded_pairs);
805 if(MC_state_interleave_size(current_pair->graph_state) > 0){
806 XBT_DEBUG("Backtracking to depth %d", xbt_fifo_size(mc_stack_liveness));
807 MC_replay_liveness(mc_stack_liveness, 0);
816 mc_stats->executed_transitions++;
818 XBT_DEBUG("No request to execute in this state, search evolution in Büchi Automaton.");
820 if(current_pair->search_cycle){
822 if((current_pair->automaton_state->type == 1) || (current_pair->automaton_state->type == 2)){
824 if((reached_num = is_reached_acceptance_pair(current_pair)) != -1){
826 XBT_INFO("Pair %d already reached (equal to pair %d) !", current_pair->num, reached_num);
829 xbt_fifo_shift(mc_stack_liveness);
832 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
833 XBT_INFO("| ACCEPTANCE CYCLE |");
834 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
835 XBT_INFO("Counter-example that violates formula :");
836 MC_show_stack_liveness(mc_stack_liveness);
837 MC_dump_stack_liveness(mc_stack_liveness);
838 MC_print_statistics(mc_stats);
845 if((visited_num = is_visited_pair(current_pair)) != -1){
847 XBT_DEBUG("Pair %d already visited ! (equal to pair %d)", current_pair->num, visited_num);
852 prop_values = get_atomic_propositions_values();
855 /* Evaluate enabled transition according to atomic propositions values */
857 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
859 res = MC_automaton_evaluate_label(transition_succ->label, prop_values);
861 if(res == 1){ // enabled transition in automaton
865 next_pair = MC_pair_new();
866 next_pair->graph_state = MC_state_new();
867 next_pair->automaton_state = transition_succ->dst;
868 next_pair->atomic_propositions = get_atomic_propositions_values();
869 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
871 if(next_pair->automaton_state->type == 1 || next_pair->automaton_state->type == 2 || current_pair->search_cycle)
872 next_pair->search_cycle = 1;
874 xbt_fifo_unshift(mc_stack_liveness, next_pair);
876 if(mc_stats->expanded_pairs%1000 == 0)
877 XBT_INFO("Expanded pairs : %lu", mc_stats->expanded_pairs);
879 if(dot_output != NULL)
880 fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", current_pair->num, next_pair->num, "");
890 /* Then, evaluate true transitions (always true, whatever atomic propositions values) */
892 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
894 res = MC_automaton_evaluate_label(transition_succ->label, prop_values);
896 if(res == 2){ // true transition in automaton
900 next_pair = MC_pair_new();
901 next_pair->graph_state = MC_state_new();
902 next_pair->automaton_state = transition_succ->dst;
903 next_pair->atomic_propositions = get_atomic_propositions_values();
904 next_pair->requests = MC_state_interleave_size(next_pair->graph_state);
906 if(next_pair->automaton_state->type == 1 || next_pair->automaton_state->type == 2 || current_pair->search_cycle)
907 next_pair->search_cycle = 1;
909 xbt_fifo_unshift(mc_stack_liveness, next_pair);
911 if(mc_stats->expanded_pairs%1000 == 0)
912 XBT_INFO("Expanded pairs : %lu", mc_stats->expanded_pairs);
914 if(dot_output != NULL)
915 fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", current_pair->num, next_pair->num, "");
929 XBT_WARN("/!\\ Max depth reached ! /!\\ ");
930 if(MC_state_interleave_size(current_pair->graph_state) > 0){
931 XBT_WARN("/!\\ But, there are still processes to interleave. Model-checker will not be able to ensure the soundness of the verification from now. /!\\ ");
932 if(_sg_mc_max_depth == 1000)
933 XBT_WARN("Notice : the default value of max depth is 1000 but you can change it with cfg=model-check/max_depth:value.");
938 if(xbt_fifo_size(mc_stack_liveness) == _sg_mc_max_depth ){
939 XBT_DEBUG("Pair %d (depth = %d) shifted in stack, maximum depth reached", current_pair->num, xbt_fifo_size(mc_stack_liveness) );
941 XBT_DEBUG("Pair %d (depth = %d) shifted in stack", current_pair->num, xbt_fifo_size(mc_stack_liveness) );
946 xbt_dynar_free(&prop_values);
947 current_pair = xbt_fifo_shift(mc_stack_liveness);
948 current_pair->stack_removed = 1;
949 if(current_pair->search_cycle){
950 remove_acceptance_pair(current_pair);
952 if(_sg_mc_visited == 0)
953 MC_pair_delete(current_pair);
954 else if(current_pair->visited_removed)
955 MC_pair_delete(current_pair);