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 mc_snapshot_t snapshot = NULL;
10 xbt_dynar_t successors = NULL;
11 extern mc_snapshot_t initial_snapshot;
13 mc_pair_t new_pair(mc_snapshot_t sn, mc_state_t sg, xbt_state_t st){
15 p = xbt_new0(s_mc_pair_t, 1);
17 p->automaton_state = st;
19 mc_stats_pair->expanded_pairs++;
24 int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){
26 if(s1->num_reg != s2->num_reg)
31 for(i=0 ; i< s1->num_reg ; i++){
33 if(s1->regions[i]->size != s2->regions[i]->size)
36 if(s1->regions[i]->start_addr != s2->regions[i]->start_addr)
39 if(s1->regions[i]->type != s2->regions[i]->type)
42 if(s1->regions[i]->type == 0){
43 if(mmalloc_compare_heap(s1->regions[i]->start_addr, s2->regions[i]->start_addr)){
44 XBT_DEBUG("Different heap (mmalloc_compare)");
49 if(memcmp(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
50 XBT_DEBUG("Different memcmp for data in libsimgrid");
63 int reached(xbt_automaton_t a, xbt_state_t st, mc_snapshot_t s){
66 if(xbt_dynar_is_empty(reached_pairs)){
71 xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
73 /* Get values of propositional symbols */
74 unsigned int cursor = 0;
75 xbt_propositional_symbol_t ps = NULL;
76 xbt_dynar_foreach(a->propositional_symbols, cursor, ps){
77 int (*f)() = ps->function;
79 xbt_dynar_push_as(prop_ato, int, res);
83 mc_pair_reached_t pair_test;
85 xbt_dynar_foreach(reached_pairs, cursor, pair_test){
86 if(automaton_state_compare(pair_test->automaton_state, st) == 0){
87 if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
88 if(snapshot_compare(pair_test->system_state, s) == 0){
102 int set_pair_reached(xbt_automaton_t a, xbt_state_t st, mc_snapshot_t sn){
104 if(reached(a, st, sn) == 0){
108 mc_pair_reached_t pair = NULL;
109 pair = xbt_new0(s_mc_pair_reached_t, 1);
110 pair->automaton_state = st;
111 pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
112 pair->system_state = sn;
114 /* Get values of propositional symbols */
115 unsigned int cursor = 0;
116 xbt_propositional_symbol_t ps = NULL;
117 xbt_dynar_foreach(a->propositional_symbols, cursor, ps){
118 int (*f)() = ps->function;
120 xbt_dynar_push_as(pair->prop_ato, int, res);
123 xbt_dynar_push(reached_pairs, &pair);
134 void MC_pair_delete(mc_pair_t pair){
135 xbt_free(pair->graph_state->proc_status);
136 xbt_free(pair->graph_state);
137 //xbt_free(pair->automaton_state); -> FIXME : à implémenter
143 int MC_automaton_evaluate_label(xbt_automaton_t a, xbt_exp_label_t l){
147 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
148 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
149 return (left_res || right_res);
153 int left_res = MC_automaton_evaluate_label(a, l->u.or_and.left_exp);
154 int right_res = MC_automaton_evaluate_label(a, l->u.or_and.right_exp);
155 return (left_res && right_res);
159 int res = MC_automaton_evaluate_label(a, l->u.exp_not);
164 unsigned int cursor = 0;
165 xbt_propositional_symbol_t p = NULL;
166 xbt_dynar_foreach(a->propositional_symbols, cursor, p){
167 if(strcmp(p->pred, l->u.predicat) == 0){
168 int (*f)() = p->function;
188 /********************* Double-DFS stateless *******************/
190 void MC_pair_stateless_delete(mc_pair_stateless_t pair){
191 xbt_free(pair->graph_state->proc_status);
192 xbt_free(pair->graph_state);
193 //xbt_free(pair->automaton_state); -> FIXME : à implémenter
197 mc_pair_stateless_t new_pair_stateless(mc_state_t sg, xbt_state_t st){
198 mc_pair_stateless_t p = NULL;
199 p = xbt_new0(s_mc_pair_stateless_t, 1);
200 p->automaton_state = st;
202 mc_stats_pair->expanded_pairs++;
208 void MC_ddfs_stateless_init(xbt_automaton_t a){
210 XBT_DEBUG("**************************************************");
211 XBT_DEBUG("Double-DFS stateless init");
212 XBT_DEBUG("**************************************************");
214 mc_pair_stateless_t mc_initial_pair = NULL;
215 mc_state_t initial_graph_state = NULL;
216 smx_process_t process;
218 MC_wait_for_requests();
222 initial_graph_state = MC_state_pair_new();
223 xbt_swag_foreach(process, simix_global->process_list){
224 if(MC_process_is_enabled(process)){
225 MC_state_interleave_process(initial_graph_state, process);
229 reached_pairs = xbt_dynar_new(sizeof(mc_pair_reached_t), NULL);
230 successors = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
231 snapshot = xbt_new0(s_mc_snapshot_t, 1);
233 initial_snapshot = xbt_new0(s_mc_snapshot_t, 1);
234 MC_take_snapshot(initial_snapshot);
238 unsigned int cursor = 0;
241 xbt_dynar_foreach(a->states, cursor, state){
242 if(state->type == -1){
245 mc_initial_pair = new_pair_stateless(initial_graph_state, state);
246 xbt_fifo_unshift(mc_stack_liveness_stateless, mc_initial_pair);
250 MC_ddfs_stateless(a, 0, 0);
252 MC_restore_snapshot(initial_snapshot);
254 MC_ddfs_stateless(a, 0, 0);
257 if(state->type == 2){
260 mc_initial_pair = new_pair_stateless(initial_graph_state, state);
261 xbt_fifo_unshift(mc_stack_liveness_stateless, mc_initial_pair);
265 MC_ddfs_stateless(a, 1, 0);
267 MC_restore_snapshot(initial_snapshot);
269 MC_ddfs_stateless(a, 1, 0);
278 void MC_ddfs_stateless(xbt_automaton_t a, int search_cycle, int replay){
280 smx_process_t process;
281 mc_pair_stateless_t current_pair = NULL;
283 if(xbt_fifo_size(mc_stack_liveness_stateless) == 0)
287 MC_replay_liveness(mc_stack_liveness_stateless);
288 current_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateless));
289 xbt_swag_foreach(process, simix_global->process_list){
290 if(MC_process_is_enabled(process)){
291 MC_state_interleave_process(current_pair->graph_state, process);
296 /* Get current pair */
297 current_pair = (mc_pair_stateless_t)xbt_fifo_get_item_content(xbt_fifo_get_first_item(mc_stack_liveness_stateless));
299 /* Update current state in buchi automaton */
300 a->current_state = current_pair->automaton_state;
303 XBT_DEBUG("********************* ( Depth = %d, search_cycle = %d )", xbt_fifo_size(mc_stack_liveness_stateless), search_cycle);
304 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));
308 mc_stats_pair->visited_pairs++;
311 mc_state_t next_graph_state = NULL;
312 smx_req_t req = NULL;
315 xbt_transition_t transition_succ;
316 unsigned int cursor = 0;
319 mc_pair_stateless_t next_pair = NULL;
320 mc_pair_stateless_t pair_succ;
321 //mc_snapshot_t next_snapshot = NULL;
323 while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
325 /* Debug information */
326 if(XBT_LOG_ISENABLED(mc_liveness, xbt_log_priority_debug)){
327 req_str = MC_request_to_string(req, value);
328 XBT_DEBUG("Execute: %s", req_str);
334 MC_state_set_executed_request(current_pair->graph_state, req, value);
336 /* Answer the request */
337 SIMIX_request_pre(req, value);
339 /* Wait for requests (schedules processes) */
340 MC_wait_for_requests();
345 /* Create the new expanded graph_state */
346 next_graph_state = MC_state_pair_new();
348 /* Get enabled process and insert it in the interleave set of the next graph_state */
349 xbt_swag_foreach(process, simix_global->process_list){
350 if(MC_process_is_enabled(process)){
351 MC_state_interleave_process(next_graph_state, process);
355 xbt_dynar_reset(successors);
361 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
363 res = MC_automaton_evaluate_label(a, transition_succ->label);
365 if(res == 1){ // enabled transition in automaton
367 next_pair = new_pair_stateless(next_graph_state, transition_succ->dst);
368 xbt_dynar_push(successors, &next_pair);
376 xbt_dynar_foreach(current_pair->automaton_state->out, cursor, transition_succ){
378 res = MC_automaton_evaluate_label(a, transition_succ->label);
380 if(res == 2){ // true transition in automaton
382 next_pair = new_pair_stateless(next_graph_state, transition_succ->dst);
383 xbt_dynar_push(successors, &next_pair);
390 if(xbt_dynar_length(successors) == 0){
392 next_pair = new_pair_stateless(next_graph_state, current_pair->automaton_state);
393 xbt_dynar_push(successors, &next_pair);
399 xbt_dynar_foreach(successors, cursor, pair_succ){
400 if((search_cycle == 1) && ((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
402 MC_take_snapshot(snapshot);
405 if(reached(a, pair_succ->automaton_state, snapshot) == 1){
406 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
407 XBT_INFO("| ACCEPTANCE CYCLE |");
408 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
409 XBT_INFO("Counter-example that violates formula :");
410 MC_show_stack_liveness_stateless(mc_stack_liveness_stateless);
411 MC_dump_stack_liveness_stateless(mc_stack_liveness_stateless);
412 MC_print_statistics_pairs(mc_stats_pair);
413 //MC_exit_liveness();
419 xbt_fifo_unshift(mc_stack_liveness_stateless, pair_succ);
422 //XBT_DEBUG("Stack size before : %d", xbt_fifo_size(mc_stack_liveness_stateless));
424 MC_ddfs_stateless(a, search_cycle, 0);
426 //XBT_DEBUG("Stack size after : %d", xbt_fifo_size(mc_stack_liveness_stateless));
429 if((search_cycle == 0) && ((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
431 XBT_DEBUG("Acceptance pair : graph=%p, automaton=%p(%s)", pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
434 MC_take_snapshot(snapshot);
437 int pr = set_pair_reached(a, pair_succ->automaton_state, snapshot);
440 /* pair shifted from stack when first MC_ddfs finished and returned at this point */
442 xbt_fifo_unshift(mc_stack_liveness_stateless, pair_succ);
445 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);
682 if((search_cycle == 1) && ((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
684 next_snapshot = xbt_new0(s_mc_snapshot_t, 1);
685 MC_take_snapshot(current_snapshot);
688 if(reached(a, pair_succ->automaton_state, next_snapshot) == 1){
689 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
690 XBT_INFO("| ACCEPTANCE CYCLE |");
691 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
692 XBT_INFO("Counter-example that violates formula :");
693 MC_show_stack_liveness_stateful(mc_stack_liveness_stateful);
694 MC_dump_stack_liveness_stateful(mc_stack_liveness_stateful);
695 MC_print_statistics_pairs(mc_stats_pair);
700 //mc_stats_pair->executed_transitions++;
703 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
706 MC_ddfs_stateful(a, search_cycle, 0);
709 if((search_cycle == 0) && ((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
711 int res = set_pair_reached(a, pair_succ->automaton_state, next_snapshot);
712 XBT_DEBUG("Acceptance pair : graph=%p, automaton=%p(%s)", pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
715 xbt_fifo_unshift(mc_stack_liveness_stateful, pair_succ);
718 MC_ddfs_stateful(a, 1, 1);
722 xbt_dynar_pop(reached_pairs, NULL);
729 if(MC_state_interleave_size(current_pair->graph_state) > 0){
730 XBT_DEBUG("Backtracking to depth %u", xbt_fifo_size(mc_stack_liveness_stateful));
731 MC_restore_snapshot(current_snapshot);
739 xbt_fifo_shift(mc_stack_liveness_stateful);
740 XBT_DEBUG("Pair (graph=%p, automaton =%p) shifted in stack", current_pair->graph_state, current_pair->automaton_state);