24 #include <spot/mc/reachability.hh> 25 #include <spot/misc/timer.hh> 28 #include <bricks/brick-hashset> 33 template<
typename State,
typename SuccIterator,
34 typename StateHash,
typename StateEqual>
36 StateHash, StateEqual,
37 count_valid<State, SuccIterator,
38 StateHash, StateEqual>>
43 std::function<
bool(
const State)> count_valid_fun,
44 std::function<
int(State)> get_depth,
45 std::function<
int(State)> get_pos,
47 unsigned tid,
bool& stop, std::string algoname)
50 StateHash, StateEqual>>(sys, tid, stop),
51 new_initial_(new_initial), count_valid_fun_(count_valid_fun),
52 get_depth_(get_depth), get_pos_(get_pos), id_(
id), algoname_(algoname)
64 bool push(State st,
unsigned int dfsnum)
68 for (
auto& e: this->todo)
69 this->sys_.recycle(e.it, this->tid_);
74 this->visited.clear();
78 this->todo.push_back({new_initial_,
79 this->sys_.succ(new_initial_, this->tid_)});
80 this->visited[new_initial_] = this->dfs_number;
83 if (count_valid_fun_(new_initial_))
89 if (count_valid_fun_(st))
92 if (first_depth_ == -1)
94 first_depth_ = get_depth_(st);
95 first_pos_ = get_pos_(st);
106 void edge(
unsigned int,
unsigned int)
112 float x = (float) counter_ / this->states();
113 std::cout <<
'@' << id_
114 <<
",count_" << algoname_
115 <<
',' << first_depth_
118 <<
',' << this->states()
119 <<
',' << this->trans()
121 << (this->stop_?
",ABORTED" :
",FINISHED");
127 std::function<bool(const State)> count_valid_fun_;
128 std::function<int(State)> get_depth_;
129 std::function<int(State)> get_pos_;
130 unsigned int counter_ = 0;
131 int first_depth_ = -1;
134 std::string algoname_;
137 template<
typename State,
typename SuccIterator,
138 typename StateHash,
typename StateEqual>
140 StateHash, StateEqual,
141 interpolate<State, SuccIterator,
142 StateHash, StateEqual>>
146 std::function<
void(State,
unsigned int)> display,
147 std::function<std::vector<State>*(std::vector<State>&)> interpolate_fun,
148 unsigned tid,
bool& stop, std::string algoname,
int init_pop)
151 StateHash, StateEqual>>(sys, tid, stop),
152 display_(display), interpolate_fun_(interpolate_fun), algoname_(algoname),
165 tm_.start(
"original DFS");
168 bool push(State st,
unsigned int dfsnum)
170 if (((
int)dfsnum) <= init_pop_)
171 sample_.push_back(st);
173 depth.insert({st, (int) this->todo.size()});
174 dfspos.insert({st, (int) this->dfs_number});
184 void edge(
unsigned int,
unsigned int)
190 using namespace std::literals::chrono_literals;
191 tm_.stop(
"original DFS");
193 std::cout <<
"STATES : " << this->states() << std::endl;
194 std::cout <<
"TRANSITIONS : " << this->trans() << std::endl;
195 std::cout <<
"TIME : " << tm_.timer(
"original DFS").walltime()
197 tm_.start(
"Generation of states");
198 std::vector<State>* gen =
nullptr;
199 gen = interpolate_fun_(sample_);
200 tm_.stop(
"Generation of states");
202 std::cout <<
"GenPop : " << tm_.timer(
"Generation of states").walltime()
205 for (
unsigned i = 0; i < gen->size(); ++i)
210 cv(this->sys_, (*gen)[i], [
this](State s) ->
bool 212 return this->visited.find(s) != this->visited.end();
214 [
this](State s) ->
int 218 [
this](State s) ->
int 230 for (
unsigned t = 0; t < 600 && !stop; ++t)
231 std::this_thread::sleep_for(1s);
234 std::cout << std::endl;
240 std::function<void(State, unsigned int)> display_;
241 std::function<std::vector<State>*(std::vector<State>&)> interpolate_fun_;
242 std::vector<State> sample_;
244 typedef std::unordered_map<
const State, int,
245 StateHash, StateEqual> visited_map;
248 std::string algoname_;
253 template<
typename State,
typename SuccIterator,
254 typename StateHash,
typename StateEqual>
270 struct inner_pair_hasher
272 inner_pair_hasher(
const my_pair&)
275 inner_pair_hasher() =
default;
277 brick::hash::hash128_t
278 hash(
const my_pair& lhs)
const 282 unsigned u = hash(lhs.st) % (1<<30);
286 bool equal(
const my_pair& lhs,
287 const my_pair& rhs)
const 290 return equal(lhs.st, rhs.st);
295 using shared_map = brick::hashset::FastConcurrent <my_pair,
299 shared_map& map,
unsigned tid):
300 sys_(sys), tid_(tid), map_(map),
301 nb_th_(std::thread::hardware_concurrency()),
302 p_(
sizeof(
int)*std::thread::hardware_concurrency())
313 tm_.start(
"DFS thread " + std::to_string(this->tid_));
316 bool push(State s,
unsigned int tid)
320 int* ref = (
int*) p_.allocate();
321 for (
unsigned i = 0; i < nb_th_; ++i)
325 auto it = map_.insert({s, ref});
335 for (
unsigned i = 0; !b && i < nb_th_; ++i)
336 if (it->colors[i] == static_cast<int>(CLOSED))
340 if (it->colors[tid_] == static_cast<int>(OPEN))
344 refs_.push_back(it->colors);
347 it->colors[tid_] = OPEN;
357 refs_.back()[tid_] = CLOSED;
362 void edge(
unsigned int,
unsigned int)
369 tm_.stop(
"DFS thread " + std::to_string(this->tid_));
374 return tm_.timer(
"DFS thread " + std::to_string(this->tid_))
393 unsigned how_many_generations()
401 State initial = sys_.initial(tid_);
402 if (SPOT_LIKELY(push(initial, dfs_number)))
404 todo.push_back({initial, sys_.succ(initial, tid_)});
407 while (!todo.empty())
409 if (todo.back().it->done())
411 if (SPOT_LIKELY(pop(todo.back().s)))
413 sys_.recycle(todo.back().it, tid_);
420 State dst = todo.back().it->state();
422 if (SPOT_LIKELY(push(dst, dfs_number)))
425 todo.back().it->next();
426 todo.push_back({dst, sys_.succ(dst, tid_)});
430 todo.back().it->next();
445 std::vector<todo_element> todo;
446 unsigned int dfs_number = 0;
447 unsigned int transitions = 0;
452 unsigned inserted_ = 0;
453 unsigned nb_gens_ = 0;
454 unsigned states_ = 0;
458 std::vector<int*> refs_;
463 template<
typename State,
typename SuccIterator,
464 typename StateHash,
typename StateEqual>
482 struct inner_pair_hasher
484 inner_pair_hasher(
const my_pair&)
487 inner_pair_hasher() =
default;
489 brick::hash::hash128_t
490 hash(
const my_pair& lhs)
const 494 unsigned u = hash(lhs.st) % (1<<30);
498 bool equal(
const my_pair& lhs,
499 const my_pair& rhs)
const 502 return equal(lhs.st, rhs.st);
507 st_status insert_status_;
508 using shared_map = brick::hashset::FastConcurrent <my_pair,
512 shared_map& map,
unsigned tid,
513 std::function<std::vector<State>*(std::vector<State>&)> fun,
514 std::atomic<bool>& stop,
unsigned initial_population = 1000,
515 float strategy = 0.5):
516 sys_(sys), tid_(tid), map_(map),
517 nb_th_(std::thread::hardware_concurrency()),
518 p_(
sizeof(
int)*std::thread::hardware_concurrency()),
519 interpolate_fun_(fun), stop_(stop), THRESHOLD(initial_population)
529 else if (strategy >= 0 && strategy <= 1)
531 if (tid < (sys.nb_threads_ * strategy))
534 std::cout << tid <<
" "<< std::endl;
547 tm_.start(
"DFS thread " + std::to_string(this->tid_));
550 bool push(State s,
unsigned int tid)
555 int* ref = (
int*) p_.allocate();
556 for (
unsigned i = 0; i < nb_th_; ++i)
560 auto it = map_.insert({s, ref});
570 for (
unsigned i = 0; !b && i < nb_th_; ++i)
571 if (it->colors[i] == static_cast<int>(CLOSED))
575 if (it->colors[tid_] == static_cast<int>(insert_status_))
579 refs_.push_back(it->colors);
582 it->colors[tid_] = insert_status_;
592 refs_.back()[tid_] = CLOSED;
597 void edge(
unsigned int,
unsigned int)
604 tm_.stop(
"DFS thread " + std::to_string(this->tid_));
609 return tm_.timer(
"DFS thread " + std::to_string(this->tid_))
628 unsigned how_many_generations()
635 State initial = sys_.initial(tid_);
636 if (SPOT_LIKELY(push(initial, dfs_number)))
638 todo.push_back({initial, sys_.succ(initial, tid_)});
640 sample_.push_back(initial);
642 while (!todo.empty() && sample_.size() < THRESHOLD)
644 if (todo.back().it->done())
646 if (SPOT_LIKELY(pop(todo.back().s)))
648 sys_.recycle(todo.back().it, tid_);
655 State dst = todo.back().it->state();
657 if (SPOT_LIKELY(push(dst, dfs_number)))
660 todo.back().it->next();
661 todo.push_back({dst, sys_.succ(dst, tid_)});
662 sample_.push_back(dst);
666 todo.back().it->next();
679 void swarming(State initial)
681 if (SPOT_LIKELY(push(initial, dfs_number)))
683 todo.push_back({initial, sys_.succ(initial, tid_)});
686 while (!todo.empty() && !stop_.load(std::memory_order_relaxed))
688 if (todo.back().it->done())
690 if (SPOT_LIKELY(pop(todo.back().s)))
692 sys_.recycle(todo.back().it, tid_);
699 State dst = todo.back().it->state();
701 if (SPOT_LIKELY(push(dst, dfs_number)))
704 todo.back().it->next();
705 todo.push_back({dst, sys_.succ(dst, tid_)});
709 todo.back().it->next();
721 insert_status_ = PHASE_1;
726 new_gen_ = interpolate_fun_(sample_);
730 while (i < new_gen_->size() && !stop_.load(std::memory_order_relaxed))
732 insert_status_ = UNKNOWN_OPEN;
733 swarming(new_gen_->at(i));
740 insert_status_ = OPEN;
741 swarming(sys_.initial(tid_));
742 stop_.store(
true, std::memory_order_relaxed);
756 std::vector<todo_element> todo;
757 unsigned int dfs_number = 0;
758 unsigned int transitions = 0;
763 unsigned inserted_ = 0;
764 unsigned nb_gens_ = 0;
765 unsigned states_ = 0;
769 std::vector<int*> refs_;
770 std::function<std::vector<State>*(std::vector<State>&)> interpolate_fun_;
771 std::atomic<bool>& stop_;
772 std::vector<State> sample_;
774 std::vector<State>* new_gen_ =
nullptr;
775 unsigned THRESHOLD = 1000;
782 template<
typename State,
typename SuccIterator,
783 typename StateHash,
typename StateEqual>
799 struct inner_pair_hasher
801 inner_pair_hasher(
const my_pair&)
804 inner_pair_hasher() =
default;
806 brick::hash::hash128_t
807 hash(
const my_pair& lhs)
const 811 unsigned u = hash(lhs.st) % (1<<30);
815 bool equal(
const my_pair& lhs,
816 const my_pair& rhs)
const 819 return equal(lhs.st, rhs.st);
824 using shared_map = brick::hashset::FastConcurrent <my_pair,
828 shared_map& map,
unsigned tid, std::atomic<bool>& stop):
829 sys_(sys), tid_(tid), map_(map),
830 nb_th_(std::thread::hardware_concurrency()),
831 p_(
sizeof(
int)*std::thread::hardware_concurrency()), stop_(stop)
842 tm_.start(
"DFS thread " + std::to_string(this->tid_));
845 bool push(State s,
unsigned int tid)
849 int* ref = (
int*) p_.allocate();
850 for (
unsigned i = 0; i < nb_th_; ++i)
854 auto it = map_.insert({s, ref});
864 for (
unsigned i = 0; !b && i < nb_th_; ++i)
865 if (it->colors[i] == static_cast<int>(CLOSED))
869 if (it->colors[tid_] == static_cast<int>(OPEN))
873 refs_.push_back(it->colors);
876 it->colors[tid_] = OPEN;
886 refs_.back()[tid_] = CLOSED;
891 void edge(
unsigned int,
unsigned int)
899 tm_.stop(
"DFS thread " + std::to_string(this->tid_));
904 return tm_.timer(
"DFS thread " + std::to_string(this->tid_))
923 unsigned how_many_generations()
931 State initial = sys_.initial(tid_);
932 if (SPOT_LIKELY(push(initial, dfs_number)))
934 todo.push_back({initial, sys_.succ(initial, tid_), transitions});
937 while (!todo.empty() && !stop_.load(std::memory_order_relaxed))
939 if (todo.back().it->done())
941 if (SPOT_LIKELY(pop(todo.back().s)))
943 deadlock_ = todo.back().current_tr == transitions;
946 sys_.recycle(todo.back().it, tid_);
953 State dst = todo.back().it->state();
955 if (SPOT_LIKELY(push(dst, dfs_number)))
958 todo.back().it->next();
959 todo.push_back({dst, sys_.succ(dst, tid_), transitions});
963 todo.back().it->next();
983 std::vector<todo_element> todo;
984 unsigned int dfs_number = 0;
985 unsigned int transitions = 0;
990 unsigned inserted_ = 0;
991 unsigned nb_gens_ = 0;
992 unsigned states_ = 0;
996 std::vector<int*> refs_;
997 bool deadlock_ =
false;
998 std::atomic<bool>& stop_;
1002 template<
typename State,
typename SuccIterator,
1003 typename StateHash,
typename StateEqual>
1010 CLOSED_DEADLOCK = 3,
1022 struct inner_pair_hasher
1024 inner_pair_hasher(
const my_pair&)
1027 inner_pair_hasher() =
default;
1029 brick::hash::hash128_t
1030 hash(
const my_pair& lhs)
const 1034 unsigned u = hash(lhs.st) % (1<<30);
1038 bool equal(
const my_pair& lhs,
1039 const my_pair& rhs)
const 1042 return equal(lhs.st, rhs.st);
1047 st_status insert_status_;
1048 using shared_map = brick::hashset::FastConcurrent <my_pair,
1052 shared_map& map,
unsigned tid,
1053 std::function<std::vector<State>*(std::vector<State>&)> fun,
1054 std::atomic<bool>& stop,
unsigned initial_population = 1000,
1055 float strategy = 0.5):
1056 sys_(sys), tid_(tid), map_(map),
1057 nb_th_(std::thread::hardware_concurrency()),
1058 p_(
sizeof(
int)*std::thread::hardware_concurrency()),
1059 interpolate_fun_(fun), stop_(stop), THRESHOLD(initial_population)
1063 if (strategy == 0.5)
1069 else if (strategy >= 0 && strategy <= 1)
1071 if (tid < (sys.nb_threads_ * strategy))
1074 std::cout << tid <<
" "<< std::endl;
1086 tm_.start(
"DFS thread " + std::to_string(this->tid_));
1089 bool push(State s,
unsigned int tid)
1094 int* ref = (
int*) p_.allocate();
1095 for (
unsigned i = 0; i < nb_th_; ++i)
1099 auto it = map_.insert({s, ref});
1100 bool b = it.isnew();
1109 for (
unsigned i = 0; !b && i < nb_th_; ++i)
1111 if (it->colors[i] == static_cast<int>(CLOSED))
1113 if (it->colors[i] == static_cast<int>(CLOSED_DEADLOCK) &&
1114 insert_status_ == OPEN)
1117 stop_.store(
true, std::memory_order_relaxed);
1123 if (it->colors[tid_] == static_cast<int>(insert_status_))
1127 refs_.push_back(it->colors);
1130 it->colors[tid_] = insert_status_;
1140 refs_.back()[tid_] = CLOSED;
1145 void edge(
unsigned int,
unsigned int)
1152 tm_.stop(
"DFS thread " + std::to_string(this->tid_));
1157 return tm_.timer(
"DFS thread " + std::to_string(this->tid_))
1176 unsigned how_many_generations()
1183 State initial = sys_.initial(tid_);
1184 if (SPOT_LIKELY(push(initial, dfs_number)))
1186 todo.push_back({initial, sys_.succ(initial, tid_), transitions});
1188 sample_.push_back(initial);
1190 while (!todo.empty() && sample_.size() < THRESHOLD)
1192 if (todo.back().it->done())
1194 if (SPOT_LIKELY(pop(todo.back().s)))
1196 if (todo.back().current_tr == transitions)
1199 stop_.store(
true, std::memory_order_relaxed);
1202 sys_.recycle(todo.back().it, tid_);
1209 State dst = todo.back().it->state();
1211 if (SPOT_LIKELY(push(dst, dfs_number)))
1214 todo.back().it->next();
1215 todo.push_back({dst, sys_.succ(dst, tid_), transitions});
1216 sample_.push_back(dst);
1220 todo.back().it->next();
1233 void swarming(State initial)
1235 if (SPOT_LIKELY(push(initial, dfs_number)))
1237 todo.push_back({initial, sys_.succ(initial, tid_), transitions});
1240 while (!todo.empty() && !stop_.load(std::memory_order_relaxed))
1242 if (todo.back().it->done())
1244 if (SPOT_LIKELY(pop(todo.back().s)))
1247 if (todo.back().current_tr == transitions)
1249 if (insert_status_ == OPEN)
1251 stop_.store(
true, std::memory_order_relaxed);
1257 while (!refs_.empty())
1259 refs_.back()[tid_] = CLOSED_DEADLOCK;
1265 sys_.recycle(todo.back().it, tid_);
1272 State dst = todo.back().it->state();
1274 if (SPOT_LIKELY(push(dst, dfs_number)))
1277 todo.back().it->next();
1278 todo.push_back({dst, sys_.succ(dst, tid_), transitions});
1282 todo.back().it->next();
1294 insert_status_ = PHASE_1;
1299 new_gen_ = interpolate_fun_(sample_);
1303 while (i < new_gen_->size() && !stop_.load(std::memory_order_relaxed))
1305 insert_status_ = UNKNOWN_OPEN;
1306 swarming(new_gen_->at(i));
1314 insert_status_ = OPEN;
1315 swarming(sys_.initial(tid_));
1316 stop_.store(
true, std::memory_order_relaxed);
1332 unsigned current_tr;
1335 std::vector<todo_element> todo;
1336 unsigned int dfs_number = 0;
1337 unsigned int transitions = 0;
1342 unsigned inserted_ = 0;
1343 unsigned nb_gens_ = 0;
1344 unsigned states_ = 0;
1345 unsigned edges_ = 0;
1346 unsigned nb_th_ = 0;
1348 std::vector<int*> refs_;
1349 std::function<std::vector<State>*(std::vector<State>&)> interpolate_fun_;
1350 std::atomic<bool>& stop_;
1351 std::vector<State> sample_;
1353 std::vector<State>* new_gen_ =
nullptr;
1354 unsigned THRESHOLD = 1000;
1355 bool deadlock_ =
false;
Definition: interpolate.hh:465
Definition: interpolate.hh:255
bool is_a_kripkecube(kripkecube< State, SuccIter > &)
This method allows to ensure (at compile time) if a given parameter is of type kripkecube. It also check if the iterator has the good interface.
Definition: kripke.hh:63
This class is a template representation of a Kripke structure. It is composed of two template paramet...
Definition: kripke.hh:37
A map of timer, where each timer has a name.
Definition: timer.hh:227
Definition: interpolate.hh:784
Definition: interpolate.hh:35
Definition: interpolate.hh:1004
Definition: interpolate.hh:139
This template class provide a sequential reachability of a kripkecube. The algorithm uses a single DF...
Definition: reachability.hh:33
A fixed-size memory pool implementation.
Definition: fixpool.hh:31