00001
00004 #ifndef DIVINE_DVE_EXPLICIT_SYSTEM_HH
00005 #define DIVINE_DVE_EXPLICIT_SYSTEM_HH
00006
00007 #ifndef DOXYGEN_PROCESSING
00008 #include "system/explicit_system.hh"
00009 #include "system/dve/syntax_analysis/dve_symbol_table.hh"
00010 #include "system/dve/dve_system.hh"
00011 #include "system/state.hh"
00012 #include "system/dve/dve_system_trans.hh"
00013 #include "common/types.hh"
00014 #include "common/deb.hh"
00015
00016 namespace divine {
00017 using std::cerr; using std::endl;
00018 #endif //DOXYGEN_PROCESSING
00019
00020 class dve_process_decomposition_t;
00021
00023 const size_int_t ES_FMT_PRINT_STATE_NAMES = 1;
00025 const size_int_t ES_FMT_PRINT_VAR_NAMES = 2;
00027 const size_int_t ES_FMT_PRINT_PROCESS_NAMES = 4;
00029 const size_int_t ES_FMT_DIVIDE_PROCESSES_BY_CR = 8;
00033 const size_int_t ES_FMT_PRINT_ALL_NAMES = ES_FMT_PRINT_VAR_NAMES |
00034 ES_FMT_PRINT_STATE_NAMES |
00035 ES_FMT_PRINT_PROCESS_NAMES |
00036 ES_FMT_DIVIDE_PROCESSES_BY_CR;
00037
00040 typedef ushort_int_t dve_state_int_t;
00041
00043
00050 struct ES_parameters_t
00051 {
00052 state_t state;
00053 size_int_t * state_positions_var;
00054 size_int_t * state_positions_state;
00055 size_int_t * state_positions_proc;
00056 SYS_initial_values_t * initial_values;
00057 size_int_t * initial_states;
00058 size_int_t * state_lids;
00059 dve_var_type_t * var_types;
00060 size_int_t * array_sizes;
00061 };
00062
00064 typedef ES_parameters_t * ES_p_parameters_t;
00065
00066 class succ_container_t;
00067 class enabled_trans_container_t;
00068 class dve_system_trans_t;
00069 class dve_enabled_trans_t;
00070
00071
00072
00074
00092 class dve_explicit_system_t : public virtual explicit_system_t,
00093 public virtual dve_system_t
00094 {
00095
00096 private:
00097
00098 process_decomposition_t *property_decomposition;
00099
00100
00101 void process_variable(const size_int_t gid);
00102 void process_channel(const size_int_t gid);
00103 void another_read_stuff(bool do_expr_compaction = true);
00104 state_t create_state_by_composition
00105 (state_t initial_state, enabled_trans_t * const p_enabled,
00106 succ_container_t & succs, size_int_t * trans_indexes,
00107 size_int_t * bounds);
00108 bool not_in_glob_conflict(size_int_t * trans_indexes,
00109 size_int_t * bounds);
00110
00111
00112 public:
00113
00115
00117
00118 dve_explicit_system_t(error_vector_t & evect = gerr);
00120 virtual ~dve_explicit_system_t();
00121
00126
00127 virtual bool is_erroneous(state_t state)
00128 {
00129 return (processes[0]->get_state_count() ==
00130 (state_pos_to<dve_state_int_t>(state,
00131 state_positions_proc[processes[0]->get_gid()])));
00132 }
00133
00141
00144 virtual bool is_accepting(state_t state, size_int_t acc_group=0, size_int_t pair_member=1)
00145 {
00146 return (get_with_property() &&
00147 pproperty->get_acceptance(state_pos_to<dve_state_int_t>(state, property_position),
00148 acc_group, pair_member));
00149 }
00150
00152 virtual bool violates_assertion(const state_t state) const;
00153
00155 virtual size_int_t violated_assertion_count(const state_t state) const;
00156
00158 virtual std::string violated_assertion_string(const state_t state,
00159 const size_int_t index) const;
00160
00162 size_int_t get_preallocation_count() const { return max_succ_count; }
00163
00165 virtual void print_state(state_t state, std::ostream & outs = std::cout)
00166 {
00167 DBG_print_state(state,outs);
00168 }
00169
00171 virtual state_t get_initial_state();
00172
00175 virtual int get_succs
00176 (state_t state, succ_container_t & succs)
00177 {
00178 if (system_synchro==SYSTEM_ASYNC)
00179 return get_async_succs(state, succs);
00180 else
00181 return get_sync_succs(state, succs);
00182 }
00183
00186
00190 virtual int get_ith_succ(state_t state, const int i, state_t & succ);
00196
00197 process_decomposition_t *get_property_decomposition()
00198 {
00199 return property_decomposition;
00200 }
00204
00205
00209
00210
00211 virtual int get_succs(state_t state, succ_container_t & succs,
00212 enabled_trans_container_t & etc)
00213 {
00214 if (system_synchro==SYSTEM_ASYNC)
00215 return get_async_succs(state, succs, etc);
00216 else
00217 return get_sync_succs(state, succs, etc);
00218 }
00219
00221 virtual int get_enabled_trans(const state_t state,
00222 enabled_trans_container_t & enb_trans)
00223 {
00224 if (system_synchro==SYSTEM_ASYNC)
00225 return get_async_enabled_trans(state,enb_trans);
00226 else
00227 return get_sync_enabled_trans(state,enb_trans);
00228 }
00229
00231
00233 virtual int get_enabled_trans_count(const state_t state, size_int_t & count);
00234
00237
00240 virtual int get_enabled_ith_trans(const state_t state,
00241 const size_int_t i,
00242 enabled_trans_t & enb_trans);
00243
00245 virtual bool get_enabled_trans_succ
00246 (const state_t state, const enabled_trans_t & enabled,
00247 state_t & new_state)
00248 {
00249 if (system_synchro==SYSTEM_ASYNC)
00250 return get_async_enabled_trans_succ(state, enabled, new_state);
00251 else
00252 return get_sync_enabled_trans_succ(state, enabled, new_state);
00253 }
00254
00256 virtual bool get_enabled_trans_succs
00257 (const state_t state, succ_container_t & succs,
00258 const enabled_trans_container_t & enabled_trans)
00259 {
00260 if (system_synchro==SYSTEM_ASYNC)
00261 return get_async_enabled_trans_succs(state, succs, enabled_trans);
00262 else
00263 return get_sync_enabled_trans_succs(state, succs, enabled_trans);
00264 }
00265
00267 virtual enabled_trans_t * new_enabled_trans() const;
00268
00271
00272
00275
00276 virtual bool eval_expr(const expression_t * const expr,
00277 const state_t state,
00278 data_t & data) const
00279 {
00280 bool eval_err;
00281 data.assign<all_values_t>(eval_expr(dynamic_cast<const dve_expression_t*>(expr),
00282 state, eval_err));
00283 return eval_err;
00284 }
00288
00289
00294
00296
00307 void DBG_print_state(state_t state, std::ostream & outs = std::cerr,
00308 const ulong_int_t format = ES_FMT_PRINT_ALL_NAMES);
00309
00312 void DBG_print_state_CR(state_t state, std::ostream & outs = std::cerr,
00313 const ulong_int_t format = ES_FMT_PRINT_ALL_NAMES)
00314 { DBG_print_state(state,outs,format); outs << std::endl; }
00315
00316
00318
00323 bool is_accepting(state_t state, size_int_t process_id)
00324 {
00325 return processes[process_id]->get_acceptance(
00326 state_pos_to<dve_state_int_t>(state,
00327 state_positions_proc[processes[process_id]->get_gid()]));
00328 }
00329
00331
00336 virtual slong_int_t read(const char * const filename)
00337 { return read(filename,true); }
00339
00344 virtual slong_int_t read(const char * const filename, bool do_comp);
00345
00346
00348 size_int_t get_space_sum() const;
00349
00351
00358 all_values_t eval_expr(const dve_expression_t * const expr,
00359 const state_t state,
00360 bool & eval_err) const
00361 { ES_p_parameters_t(parameters)->state = state;
00362 if (expr->is_compacted())
00363 {
00364
00365 return dve_system_t::fast_eval(expr->get_p_compact(),eval_err);
00366 }
00367 else
00368 return dve_system_t::eval_expr(expr,eval_err);
00369 }
00370
00372 all_values_t get_var_value
00373 (const state_t state, size_int_t var_gid, const size_int_t index=0)
00374 {
00375 return (
00376 constants[var_gid]?
00377 (
00378 (initial_values_counts[var_gid]!=MAX_INIT_VALUES_SIZE)?
00379 initial_values[var_gid].all_value:
00380 initial_values[var_gid].all_values[index]
00381 ):
00382 get_state_creator_value_of_var_type(state,var_gid,
00383 var_types[var_gid],index)
00384 );
00385 }
00386
00388
00396 bool set_var_value(state_t state, const size_int_t var_gid,
00397 const all_values_t v, const size_int_t index=0)
00398 {
00399 return constants[var_gid] ||
00400 set_state_creator_value(state,var_gid,v,index);
00401 }
00402
00405 size_int_t get_state_of_process(const state_t state, size_int_t process_id) const;
00406
00408
00419 dve_transition_t * get_sending_or_normal_trans(const system_trans_t & sys_trans)
00420 const;
00421
00423
00431 dve_transition_t * get_receiving_trans(const system_trans_t & sys_trans) const;
00432
00434
00443 dve_transition_t * get_property_trans(const system_trans_t & sys_trans) const;
00446
00447 size_int_t get_var_pos(const size_int_t gid) const
00448 { return state_positions_var[gid]; }
00449
00451 size_int_t get_channel_pos(const size_int_t gid) const
00452 { return state_positions_channel[gid]; }
00453
00455 size_int_t get_process_pos(const size_int_t gid) const
00456 { return process_positions[gid].begin; }
00457
00459 size_int_t get_process_size(const size_int_t gid) const
00460 { return process_positions[gid].size; }
00461
00462
00463
00464 protected:
00465
00466 struct proc_and_trans_t
00467 { size_int_t proc; size_int_t trans;
00468 proc_and_trans_t() {}
00469 proc_and_trans_t(size_int_t p, size_int_t t): proc(p), trans(t) {}
00470 };
00471
00472 struct channels_t
00473 {
00474 size_int_t count;
00475 bool error;
00476 proc_and_trans_t * list;
00477
00478 channels_t(const size_int_t alloc) { allocate(alloc); }
00479 channels_t() { list = 0; }
00480 ~channels_t() { DEBAUX(std::cerr << "BEGIN of destructor of channels_t" << std::endl;) if (list) delete [] list; DEBAUX(std::cerr << "END of destructor of channels_t" << std::endl;)}
00481 void set_error(const bool new_error) { error = new_error; }
00482 bool get_error() { return error; }
00483 void allocate(const size_int_t alloc) { list = new proc_and_trans_t[alloc]; }
00484 void push_back(const proc_and_trans_t & pat) { list[count] = pat; ++count; }
00485 };
00486
00487 struct process_position_t
00488 {
00489 size_int_t begin;
00490 size_int_t size;
00491 };
00492
00495
00497 struct state_creator_t
00498 {
00499 enum state_creator_type_t { VARIABLE, PROCESS_STATE, CHANNEL_BUFFER };
00500 state_creator_type_t type;
00501 dve_var_type_t var_type;
00502 size_int_t array_size;
00503
00504 size_int_t gid;
00505 state_creator_t
00506 (const state_creator_type_t sc_type,
00507 dve_var_type_t vtype, const size_int_t arr_size,
00508 const size_int_t gid_arg):
00509 type(sc_type), var_type(vtype), array_size(arr_size), gid(gid_arg) {}
00510 };
00511
00512 struct prop_trans_t
00513 {
00514 dve_transition_t * trans;
00515 bool error;
00516 void assign(dve_transition_t * const transition, const bool erroneous)
00517 { trans = transition; error = erroneous; }
00518 };
00519
00520
00521 array_t<byte_t *> glob_filters;
00522 size_int_t first_in_succs;
00523
00524 size_int_t trans_count;
00525
00526 size_int_t max_succ_count;
00527 enabled_trans_container_t * p_enabled_trans;
00528 enabled_trans_container_t * aux_enabled_trans;
00529 enabled_trans_container_t * aux_enabled_trans2;
00530 succ_container_t * aux_succ_container;
00531
00532 channels_t * channels;
00533 array_t<prop_trans_t> property_trans;
00534 size_int_t * state_positions_var;
00535 size_int_t * state_positions_state;
00536 size_int_t * state_positions_proc;
00537 size_int_t * state_positions_channel;
00538 size_int_t * channel_buffer_size;
00539 size_int_t * channel_element_size;
00540 dve_var_type_t ** channel_item_type;
00541 size_int_t ** channel_item_pos;
00542 size_int_t * state_sizes_var;
00543 size_int_t * array_sizes;
00544 process_position_t * process_positions;
00545 process_position_t global_position;
00546 size_int_t process_count;
00547 size_int_t space_sum;
00548
00549
00550 std::vector<state_creator_t> state_creators;
00551 size_int_t state_creators_count;
00552 size_int_t property_position;
00553 size_int_t prop_begin;
00554 size_int_t prop_size;
00555 size_int_t glob_count;
00556
00557
00560
00561
00562
00563
00564 void go_to_error(state_t state);
00565
00568 bool not_in_glob_conflict(const dve_transition_t * const t1,
00569 const dve_transition_t * const t2)
00570 { return (t1->get_glob_mask() & t2->get_glob_mask()); }
00571
00573
00574
00575
00576
00577
00578 bool apply_transition_effects
00579 (const state_t state, const dve_transition_t * const trans);
00580
00582
00583
00584
00585
00586
00587
00588
00589
00590 bool apply_effect
00591 (const state_t state, const dve_expression_t * const effect);
00592
00593
00595 int get_async_succs(const state_t state, succ_container_t & succs)
00596 { p_enabled_trans = aux_enabled_trans;
00597 return get_async_succs_internal(state,succs); }
00598
00600 int get_sync_succs(state_t state, succ_container_t & succs)
00601 { return get_sync_succs_internal(state, succs, aux_enabled_trans2); }
00602
00604 int get_async_succs(const state_t state, succ_container_t & succs,
00605 enabled_trans_container_t & enb_trans)
00606 { p_enabled_trans = &enb_trans; return get_async_succs_internal(state,succs); }
00607
00609 int get_sync_succs(state_t state, succ_container_t & succs,
00610 enabled_trans_container_t & etc)
00611 { return get_sync_succs_internal(state, succs, &etc); }
00612
00613
00615 int get_async_enabled_trans(const state_t state,
00616 enabled_trans_container_t & enb_trans);
00617
00619 int get_sync_enabled_trans(const state_t state,
00620 enabled_trans_container_t & enb_trans);
00621
00623 bool get_async_enabled_trans_succ
00624 (const state_t state, const enabled_trans_t & enabled,
00625 state_t & new_state);
00626
00628 bool get_sync_enabled_trans_succ
00629 (const state_t state, const enabled_trans_t & enabled,
00630 state_t & new_state);
00631
00634
00637 bool get_async_enabled_trans_succ
00638 (const state_t state, const enabled_trans_t & enabled,
00639 state_t & new_state, const state_t property_state);
00640
00642 bool get_async_enabled_trans_succs
00643 (const state_t state, succ_container_t & succs,
00644 const enabled_trans_container_t & enabled_trans);
00645
00646
00648 bool get_sync_enabled_trans_succs
00649 (const state_t state, succ_container_t & succs,
00650 const enabled_trans_container_t & enabled_trans);
00651
00654 bool get_async_enabled_trans_succ_without_property
00655 (const state_t state, const enabled_trans_t & enabled, state_t & new_state);
00656
00657
00659
00665 state_t create_error_state();
00666
00669 bool compute_successors_without_sync
00670 (const size_int_t process_number,
00671 succ_container_t & succs, const state_t state);
00672
00675
00681 void append_new_enabled(dve_transition_t * const t_answ,
00682 dve_transition_t * const t_ask,
00683 const bool trans_err);
00684
00686
00692 void append_new_enabled_prop_sync(dve_transition_t * const t_answ,
00693 dve_transition_t * const t_prop,
00694 const bool trans_err);
00695
00698 bool compute_enabled_stage1
00699 (const size_int_t process_number,
00700 channels_t * channels, const state_t state, const bool only_commited);
00701
00704
00708 bool compute_enabled_stage2
00709 (const size_int_t process_number,
00710 channels_t * channels, const state_t state, const bool only_commited);
00711
00714 bool compute_enabled_of_property(const state_t state);
00715
00717
00726 all_values_t get_state_creator_value_of_var_type
00727 (const state_t state, size_int_t var_gid, const dve_var_type_t var_type,
00728 const size_int_t index=0);
00729
00731
00739 bool set_state_creator_value_of_var_type(state_t state,
00740 const size_int_t var_gid, const dve_var_type_t var_type, const all_values_t v,
00741 const size_int_t index);
00742
00745 bool set_state_creator_value(state_t state, const size_int_t var_gid,
00746 const all_values_t v, const size_int_t index=0)
00747 { return set_state_creator_value_of_var_type(state,var_gid,var_types[var_gid],
00748 v,index); }
00750
00758 void set_state_creator_value_extended(
00759 const state_t & state, const state_t & new_state,
00760 const dve_expression_t & to_assign, const all_values_t & val, bool & error);
00761
00763 int get_async_succs_internal(const state_t state, succ_container_t & succs);
00764
00766 int get_sync_succs_internal(state_t state, succ_container_t & succs,
00767 enabled_trans_container_t * const etc);
00768
00771 size_int_t channel_content_count(const state_t & state, const size_int_t gid);
00772
00774 bool channel_is_empty(const state_t & state, const size_int_t gid);
00775
00777 bool channel_is_full(const state_t & state, const size_int_t gid);
00778
00779 void push_back_channel(state_t & state, const size_int_t gid);
00780 void pop_front_channel(state_t & state, const size_int_t gid);
00781 void write_to_channel(state_t & state, const size_int_t gid,
00782 const size_int_t item_index, const all_values_t value);
00783 all_values_t read_from_channel(const state_t & state, const size_int_t gid,
00784 const size_int_t item_index,
00785 const size_int_t elem_index = 0);
00786
00787
00790
00791 bool inline passed_through
00792 (const state_t state, const dve_transition_t * const t,
00793 const dve_state_int_t state1, bool & eval_err)
00794 {
00795 DEB(cerr << dve_state_int_t(t->get_state1_lid()) << "?=?" << state1 << " and ")
00796 DEB( << "guard pointer = " << int(t->get_guard()) << endl;)
00797 if ((dve_state_int_t(t->get_state1_lid()) == state1) &&
00798 (t->get_guard() == 0 || eval_expr(t->get_guard(),state,eval_err)))
00799 { DEB(cerr << "Passed through" << endl;) return true; }
00800 else
00801 if (eval_err) return true;
00802 else return false;
00803 }
00804
00806 void prepare_channels_info()
00807 {
00808 for (size_int_t i = 0; i!=get_channel_count(); ++i)
00809 { channels[i].count = 0; channels[i].error = false; }
00810 }
00811
00813 bool is_commited(state_t state)
00814 {
00815 bool result = false;
00816 for (size_int_t i = 0; i!=processes.size() && !result; ++i)
00817 if (processes[i]->get_commited(get_state_of_process(state,i)))
00818 result = true;
00819 return result;
00820 }
00821
00822 all_values_t retype(dve_var_type_t type, all_values_t value)
00823 {
00824 switch (type)
00825 {
00826 case VAR_BYTE: return byte_t(value); break;
00827 case VAR_INT: return sshort_int_t(value); break;
00828 default: gerr << "Unexpected error: dve_explicit_system_t::retype: "
00829 "unknown type" << thr(); return 0; break;
00830 };
00831 }
00832 };
00833
00834
00835
00836 #ifndef DOXYGEN_PROCESSING
00837 }
00838 #include "common/undeb.hh"
00839
00840 #endif //DOXYGEN_PROCESSING
00841
00842 #endif