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;
8 xbt_dynar_t reached_pairs;
9 extern mc_snapshot_t initial_snapshot;
11 mc_pair_t new_pair(mc_snapshot_t sn, mc_state_t sg, xbt_state_t st){
13 p = xbt_new0(s_mc_pair_t, 1);
15 p->automaton_state = st;
17 mc_stats_pair->expanded_pairs++;
22 int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){
24 if(s1->num_reg != s2->num_reg)
29 for(i=0 ; i< s1->num_reg ; i++){
31 if(s1->regions[i]->size != s2->regions[i]->size)
34 if(s1->regions[i]->start_addr != s2->regions[i]->start_addr)
37 if(s1->regions[i]->type != s2->regions[i]->type)
40 if(s1->regions[i]->type == 0){
41 if(mmalloc_compare_heap(s1->regions[i]->start_addr, s2->regions[i]->start_addr)){
42 XBT_DEBUG("Different heap (mmalloc_compare)");
47 if(memcmp(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
48 XBT_DEBUG("Different memcmp for data in libsimgrid (%d)", i);
61 int reached(xbt_automaton_t a, mc_snapshot_t s){
63 XBT_DEBUG("Test reached");
65 if(xbt_dynar_is_empty(reached_pairs)){
70 mc_pair_reached_t pair = NULL;
71 pair = xbt_new0(s_mc_pair_reached_t, 1);
72 pair->automaton_state = a->current_state;
73 pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
74 pair->system_state = s;
76 /* Get values of propositional symbols */
77 unsigned int cursor = 0;
78 xbt_propositional_symbol_t ps = NULL;
79 xbt_dynar_foreach(a->propositional_symbols, cursor, ps){
80 int (*f)() = ps->function;
82 xbt_dynar_push_as(pair->prop_ato, int, res);
86 mc_pair_reached_t pair_test;
87 //int (*compare_dynar)(const void*, const void*) = &propositional_symbols_compare_value;
88 xbt_dynar_foreach(reached_pairs, cursor, pair_test){
89 if(automaton_state_compare(pair_test->automaton_state, pair->automaton_state) == 0){
90 if(propositional_symbols_compare_value(pair_test->prop_ato, pair->prop_ato) == 0){
91 if(snapshot_compare(pair_test->system_state, pair->system_state) == 0){
105 int set_pair_reached(xbt_automaton_t a, mc_snapshot_t s){
107 if(reached(a, s) == 0){
111 mc_pair_reached_t pair = NULL;
112 pair = xbt_new0(s_mc_pair_reached_t, 1);
113 pair->automaton_state = a->current_state;
114 pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
115 pair->system_state = s;
117 /* Get values of propositional symbols */
118 unsigned int cursor = 0;
119 xbt_propositional_symbol_t ps = NULL;
120 xbt_dynar_foreach(a->propositional_symbols, cursor, ps){
121 int (*f)() = ps->function;
123 xbt_dynar_push_as(pair->prop_ato, int, res);
126 xbt_dynar_push(reached_pairs, &pair);
137 void MC_pair_delete(mc_pair_t pair){
138 xbt_free(pair->graph_state->proc_status);
139 xbt_free(pair->graph_state);
140 //xbt_free(pair->automaton_state); -> FIXME : à implémenter
145 int MC_automaton_evaluate_label(xbt_automaton_t a, xbt_exp_label_t l){
149 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
150 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
151 return (left_res || right_res);
155 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
156 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
157 return (left_res && right_res);
161 int res = MC_automaton_evaluate_label(a, l->u.exp_not);
166 unsigned int cursor = 0;
167 xbt_propositional_symbol_t p = NULL;
168 xbt_dynar_foreach(a->propositional_symbols, cursor, p){
169 if(strcmp(p->pred, l->u.predicat) == 0){
170 int (*f)() = p->function;
190 /********************* Double-DFS stateless *******************/
192 void MC_pair_stateless_delete(mc_pair_stateless_t pair){
193 xbt_free(pair->graph_state->proc_status);
194 xbt_free(pair->graph_state);
195 //xbt_free(pair->automaton_state); -> FIXME : à implémenter
199 mc_pair_stateless_t new_pair_stateless(mc_state_t sg, xbt_state_t st){
200 mc_pair_stateless_t p = NULL;
201 p = xbt_new0(s_mc_pair_stateless_t, 1);
202 p->automaton_state = st;
204 mc_stats_pair->expanded_pairs++;
210 void MC_ddfs_stateless_init(xbt_automaton_t a){
212 XBT_DEBUG("**************************************************");
213 XBT_DEBUG("Double-DFS stateless init");
214 XBT_DEBUG("**************************************************");
216 mc_pair_stateless_t mc_initial_pair = NULL;
217 mc_state_t initial_graph_state = NULL;
218 smx_process_t process;
220 MC_wait_for_requests();
223 initial_graph_state = MC_state_pair_new();
224 xbt_swag_foreach(process, simix_global->process_list){
225 if(MC_process_is_enabled(process)){
226 MC_state_interleave_process(initial_graph_state, process);
230 reached_pairs = xbt_dynar_new(sizeof(mc_pair_reached_t), NULL);
232 initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
233 MC_take_snapshot(initial_snapshot);
237 unsigned int cursor = 0;
240 xbt_dynar_foreach(a->states, cursor, state){
241 if(state->type == -1){
244 mc_initial_pair = new_pair_stateless(initial_graph_state, state);
245 xbt_fifo_unshift(mc_stack_liveness_stateless, mc_initial_pair);
249 MC_ddfs_stateless(a, 0, 0);
251 MC_restore_snapshot(initial_snapshot);
253 MC_ddfs_stateless(a, 0, 0);
256 if(state->type == 2){
259 mc_initial_pair = new_pair_stateless(initial_graph_state, state);
260 xbt_fifo_unshift(mc_stack_liveness_stateless, mc_initial_pair);
264 MC_ddfs_stateless(a, 1, 0);
266 MC_restore_snapshot(initial_snapshot);
268 MC_ddfs_stateless(a, 1, 0);
277 void MC_ddfs_stateless(xbt_automaton_t a, int search_cycle, int replay){
279 smx_process_t process;
280 mc_pair_stateless_t current_pair = NULL;
282 if(xbt_fifo_size(mc_stack_liveness_stateless) == 0)
286 MC_replay_liveness(mc_stack_liveness_stateless);
287 current_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateless));
288 xbt_swag_foreach(process, simix_global->process_list){
289 if(MC_process_is_enabled(process)){
290 MC_state_interleave_process(current_pair->graph_state, process);
295 /* Get current pair */
296 current_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateless));
298 /* Update current state in buchi automaton */
299 a->current_state = current_pair->automaton_state;
301 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness_stateless), search_cycle);
302 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));
305 mc_stats_pair->visited_pairs++;
308 mc_state_t next_graph_state = NULL;
309 smx_req_t req = NULL;
312 xbt_transition_t transition_succ;
313 unsigned int cursor = 0;
316 mc_pair_stateless_t next_pair = NULL;
317 mc_pair_stateless_t pair_succ;
318 mc_snapshot_t next_snapshot = NULL;
319 mc_snapshot_t current_snapshot = NULL;
321 xbt_dynar_t successors = NULL;
324 successors = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
327 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
330 current_snapshot = xbt_new0(s_mc_snapshot_t, 1);
331 MC_take_snapshot(current_snapshot);
334 /* Debug information */
335 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
336 req_str = MC_request_to_string(req, value);
337 XBT_DEBUG("Execute: %s", req_str);
343 MC_state_set_executed_request(current_pair->graph_state, req, value);
345 /* Answer the request */
346 SIMIX_request_pre(req, value);
348 /* Wait for requests (schedules processes) */
349 MC_wait_for_requests();
354 /* Create the new expanded graph_state */
355 next_graph_state = MC_state_pair_new();
357 /* Get enabled process and insert it in the interleave set of the next graph_state */
358 xbt_swag_foreach(process, simix_global->process_list){
359 if(MC_process_is_enabled(process)){
360 MC_state_interleave_process(next_graph_state, process);
364 next_snapshot = xbt_new0(s_mc_snapshot_t, 1);
365 MC_take_snapshot(next_snapshot);
367 xbt_dynar_reset(successors);
369 if(snapshot_compare(current_snapshot,next_snapshot)){
370 XBT_DEBUG("Different snapshot");
379 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
381 res = MC_automaton_evaluate_label(a, transition_succ->label);
383 if(res == 1){ // enabled transition in automaton
385 next_pair = new_pair_stateless(next_graph_state, transition_succ->dst);
386 xbt_dynar_push(successors, &next_pair);
394 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
396 res = MC_automaton_evaluate_label(a, transition_succ->label);
398 if(res == 2){ // true transition in automaton
400 next_pair = new_pair_stateless(next_graph_state, transition_succ->dst);
401 xbt_dynar_push(successors, &next_pair);
408 if(xbt_dynar_length(successors) == 0){
410 next_pair = new_pair_stateless(next_graph_state, current_pair->automaton_state);
411 xbt_dynar_push(successors, &next_pair);
417 xbt_dynar_foreach(successors, cursor, pair_succ){
419 if((search_cycle == 1) && (reached(a, next_snapshot) == 1)){
420 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
421 XBT_INFO("| ACCEPTANCE CYCLE |");
422 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
423 XBT_INFO("Counter-example that violates formula :");
424 MC_show_stack_liveness_stateless(mc_stack_liveness_stateless);
425 MC_dump_stack_liveness_stateless(mc_stack_liveness_stateless);
426 MC_print_statistics_pairs(mc_stats_pair);
431 xbt_fifo_unshift(mc_stack_liveness_stateless, pair_succ);
434 MC_ddfs_stateless(a, search_cycle, 0);
437 if((search_cycle == 0) && ((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
439 XBT_DEBUG("Acceptance pair %p : graph=%p, automaton=%p(%s)", pair_succ, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
440 int res = set_pair_reached(a, next_snapshot);
443 xbt_fifo_unshift(mc_stack_liveness_stateless, pair_succ);
446 MC_ddfs_stateless(a, 1, 1);
450 xbt_dynar_pop(reached_pairs, NULL);
456 if(MC_state_interleave_size(current_pair->graph_state) > 0){
457 XBT_DEBUG("Backtracking to depth %u", xbt_fifo_size(mc_stack_liveness_stateless));
458 MC_replay_liveness(mc_stack_liveness_stateless);
464 xbt_fifo_shift(mc_stack_liveness_stateless);
465 XBT_DEBUG("Pair (graph=%p, automaton =%p, search_cycle = %u) shifted in stack", current_pair->graph_state, current_pair->automaton_state, search_cycle);
470 /********************* Double-DFS stateful without visited state *******************/
473 void MC_ddfs_stateful_init(xbt_automaton_t a){
475 XBT_DEBUG("**************************************************");
476 XBT_DEBUG("Double-DFS stateful without visited state init");
477 XBT_DEBUG("**************************************************");
479 mc_pair_t mc_initial_pair;
480 mc_state_t initial_graph_state;
481 smx_process_t process;
482 mc_snapshot_t init_snapshot;
484 MC_wait_for_requests();
488 init_snapshot = xbt_new0(s_mc_snapshot_t, 1);
490 initial_graph_state = MC_state_pair_new();
491 xbt_swag_foreach(process, simix_global->process_list){
492 if(MC_process_is_enabled(process)){
493 MC_state_interleave_process(initial_graph_state, process);
497 reached_pairs = xbt_dynar_new(sizeof(mc_pair_reached_t), NULL);
499 MC_take_snapshot(init_snapshot);
503 unsigned int cursor = 0;
504 xbt_state_t state = NULL;
506 xbt_dynar_foreach(a->states, cursor, state){
507 if(state->type == -1){
510 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, state);
511 xbt_fifo_unshift(mc_stack_liveness_stateful, mc_initial_pair);
515 MC_ddfs_stateful(a, 0, 0);
517 MC_restore_snapshot(init_snapshot);
519 MC_ddfs_stateful(a, 0, 0);
522 if(state->type == 2){
525 mc_initial_pair = new_pair(init_snapshot, initial_graph_state, state);
526 xbt_fifo_unshift(mc_stack_liveness_stateful, mc_initial_pair);
530 MC_ddfs_stateful(a, 1, 0);
532 MC_restore_snapshot(init_snapshot);
534 MC_ddfs_stateful(a, 1, 0);
542 void MC_ddfs_stateful(xbt_automaton_t a, int search_cycle, int restore){
544 smx_process_t process = NULL;
545 mc_pair_t current_pair = NULL;
547 if(xbt_fifo_size(mc_stack_liveness_stateful) == 0)
551 current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
552 MC_restore_snapshot(current_pair->system_state);
553 xbt_swag_foreach(process, simix_global->process_list){
554 if(MC_process_is_enabled(process)){
555 MC_state_interleave_process(current_pair->graph_state, process);
561 /* Get current state */
562 current_pair = (mc_pair_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateful));
565 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness_stateful), search_cycle);
566 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));
568 a->current_state = current_pair->automaton_state;
570 mc_stats_pair->visited_pairs++;
573 mc_state_t next_graph_state = NULL;
574 smx_req_t req = NULL;
578 xbt_transition_t transition_succ;
582 xbt_dynar_t successors = NULL;
584 mc_pair_t next_pair = NULL;
585 mc_snapshot_t next_snapshot = NULL;
586 mc_snapshot_t current_snapshot = NULL;
590 successors = xbt_dynar_new(sizeof(mc_pair_t), NULL);
593 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
596 current_snapshot = xbt_new0(s_mc_snapshot_t, 1);
597 MC_take_snapshot(current_snapshot);
601 /* Debug information */
602 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
603 req_str = MC_request_to_string(req, value);
604 XBT_DEBUG("Execute: %s", req_str);
608 MC_state_set_executed_request(current_pair->graph_state, req, value);
610 /* Answer the request */
611 SIMIX_request_pre(req, value);
613 /* Wait for requests (schedules processes) */
614 MC_wait_for_requests();
617 /* Create the new expanded graph_state */
620 next_graph_state = MC_state_pair_new();
622 /* Get enabled process and insert it in the interleave set of the next graph_state */
623 xbt_swag_foreach(process, simix_global->process_list){
624 if(MC_process_is_enabled(process)){
625 MC_state_interleave_process(next_graph_state, process);
629 next_snapshot = xbt_new0(s_mc_snapshot_t, 1);
630 MC_take_snapshot(next_snapshot);
632 xbt_dynar_reset(successors);
638 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
640 res = MC_automaton_evaluate_label(a, transition_succ->label);
642 if(res == 1){ // enabled transition in automaton
644 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
645 xbt_dynar_push(successors, &next_pair);
652 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
654 res = MC_automaton_evaluate_label(a, transition_succ->label);
656 if(res == 2){ // transition always enabled in automaton
658 next_pair = new_pair(next_snapshot,next_graph_state, transition_succ->dst);
659 xbt_dynar_push(successors, &next_pair);
667 if(xbt_dynar_length(successors) == 0){
670 next_pair = new_pair(next_snapshot, next_graph_state, current_pair->automaton_state);
671 xbt_dynar_push(successors, &next_pair);
676 //XBT_DEBUG("Successors in automaton %lu", xbt_dynar_length(successors));
679 xbt_dynar_foreach(successors, cursor, pair_succ){
681 //XBT_DEBUG("Search visited pair : graph=%p, automaton=%p", pair_succ->graph_state, pair_succ->automaton_state);
683 if((search_cycle == 1) && (reached(a, next_snapshot) == 1)){
684 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
685 XBT_INFO("| ACCEPTANCE CYCLE |");
686 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
687 XBT_INFO("Counter-example that violates formula :");
688 MC_show_stack_liveness_stateful(mc_stack_liveness_stateful);
689 MC_dump_stack_liveness_stateful(mc_stack_liveness_stateful);
690 MC_print_statistics_pairs(mc_stats_pair);
694 //mc_stats_pair->executed_transitions++;
697 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
700 MC_ddfs_stateful(a, search_cycle, 0);
703 if((search_cycle == 0) && ((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
705 int res = set_pair_reached(a, next_snapshot);
706 XBT_DEBUG("Acceptance pair : graph=%p, automaton=%p(%s)", pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
709 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
712 MC_ddfs_stateful(a, 1, 1);
716 xbt_dynar_pop(reached_pairs, NULL);
723 if(MC_state_interleave_size(current_pair->graph_state) > 0){
724 XBT_DEBUG("Backtracking to depth %u", xbt_fifo_size(mc_stack_liveness_stateful));
725 MC_restore_snapshot(current_snapshot);
733 xbt_fifo_shift(mc_stack_liveness_stateful);
734 XBT_DEBUG("Pair (graph=%p, automaton =%p) shifted in stack", current_pair->graph_state, current_pair->automaton_state);