@@ -74,17 +74,19 @@ bool ReachabilitySearcher::IsQuerySatisfied(const Query& query, const TTA &state
7474}
7575
7676void ReachabilitySearcher::AreQueriesSatisfied (std::vector<QueryResultPair>& queries, const TTA& state, size_t state_hash) {
77- for (auto & query : queries) {
78- if (!query.answer ) {
79- query.answer = IsQuerySatisfied (*query.query , state);
80- if (query.answer ) {
81- query.acceptingStateHash = state_hash;
82- query.acceptingState .tta = state; // TODO: This is terrible
83- auto ss = ConvertASTToString (*query.query );
84- spdlog::info (" Query '{0}' is satisfied!" , ss);
85- spdlog::debug (" Query '{0}' was satisfied in state: \n {1}" , ss, state.GetCurrentStateString ());
86- }
87- }
77+ for (auto & query : queries) {
78+ if (query.answer )
79+ continue ;
80+ if (!IsQuerySatisfied (*query.query , state))
81+ continue ;
82+ query.answer = true ;
83+ query.acceptingStateHash = state_hash;
84+ query.acceptingState .tta = state; // TODO: This is terrible
85+ auto ss = ConvertASTToString (*query.query );
86+ spdlog::info (" Query '{0}' is satisfied!" , ss);
87+ spdlog::debug (" Query '{0}' was satisfied in state: \n {1}" , ss, state.GetCurrentStateString ());
88+ if (CLIConfig::getInstance ()[" immediate-output" ])
89+ PrintResults ({query});
8890 }
8991}
9092
@@ -117,8 +119,21 @@ auto ReachabilitySearcher::PrintResults(const std::vector<QueryResultPair>& resu
117119 if (exists) {
118120 auto range = Passed.equal_range (stateHash);
119121 auto count = Passed.count (stateHash);
120- if (count > 1 )
121- spdlog::warn (" HASH COLLISIONS: {0}" , count);
122+ if (count > 1 ) {
123+ std::stringstream ss{};
124+ int c = 0 ;
125+ for (auto it = range.first ; it != range.second ; ++it) {
126+ ss << it->second .tta .GetCurrentStateString ();
127+ for (auto t = range.first ; t != range.second ; ++t) {
128+ if (it->second .tta != t->second .tta )
129+ c++;
130+ }
131+ }
132+ if (c > 0 ) {
133+ spdlog::warn (" HASH COLLISIONS: {0}" , c);
134+ spdlog::warn (ss.str ());
135+ }
136+ }
122137
123138 if (stateHash == range.first ->second .prevStateHash ) {
124139 spdlog::critical (" Breaking out of infinite loop. Something is wrong." );
@@ -127,10 +142,6 @@ auto ReachabilitySearcher::PrintResults(const std::vector<QueryResultPair>& resu
127142
128143 stateHash = range.first ->second .prevStateHash ;
129144 trace.push_back (range.first ->second .tta .GetCurrentStateString ());
130- if (count > 1 ) {
131- for (auto it = range.first ; it != range.second ; ++it)
132- spdlog::warn (it->second .tta .GetCurrentStateString ());
133- }
134145 } else {
135146 spdlog::critical (" Unable to resolve witnessing trace. " );
136147 break ;
@@ -206,10 +217,19 @@ std::string debug_get_symbol_map_string_representation(const TTA::SymbolMap& map
206217
207218bool ReachabilitySearcher::ForwardReachabilitySearch (const nondeterminism_strategy_t & strategy) {
208219 auto stateit = Waiting.begin ();
220+ Timer<unsigned int > periodic_timer{};
221+ periodic_timer.start ();
209222 while (stateit != Waiting.end ()) {
223+ if (CLIConfig::getInstance ()[" print-memory" ]) {
224+ if (periodic_timer.milliseconds_elapsed () >= CLIConfig::getInstance ()[" print-memory" ].as_integer ()) {
225+ spdlog::debug (" Waiting list size: {0}" , Waiting.size ());
226+ periodic_timer.start ();
227+ }
228+ }
229+
210230 auto & state = stateit->second ;
211231 auto curstatehash = stateit->first ;
212- AreQueriesSatisfied (query_results, state. tta , curstatehash);
232+
213233 if (AreQueriesAnswered (query_results)) {
214234 Passed.emplace (std::make_pair (curstatehash, state));
215235 if (CLIConfig::getInstance ()[" verbosity" ] && CLIConfig::getInstance ()[" verbosity" ].as_integer () >= 6 )
@@ -229,6 +249,7 @@ bool ReachabilitySearcher::ForwardReachabilitySearch(const nondeterminism_strate
229249 AddToWaitingList (state.tta , allTickStateChanges, false , curstatehash);
230250
231251 Passed.emplace (std::make_pair (curstatehash, state));
252+ AreQueriesSatisfied (query_results, state.tta , curstatehash);
232253
233254 cleanup_waiting_list (*this , curstatehash, state);
234255 stateit = PickStateFromWaitingList (strategy);
@@ -259,12 +280,22 @@ void ReachabilitySearcher::AddToWaitingList(const TTA &state, const std::vector<
259280 // / This is a lot of copying large data objects... Figure something out with maybe std::move
260281 auto nstate = state << change;
261282 auto nstatehash = nstate.GetCurrentStateHash ();
262- if (Passed.find (nstatehash) == Passed.end ()) {
283+ auto passed_it = Passed.find (nstatehash);
284+ if (passed_it == Passed.end ()) {
263285 if (nstatehash == state_hash) {
286+ if (nstate == state)
287+ continue ;
264288 spdlog::warn (" Recursive state hashes!" );
265- continue ;
266289 }
267290 Waiting.emplace (std::make_pair (nstatehash, SearchState{nstate, state_hash, justTocked}));
291+ } else {
292+ auto r = Passed.equal_range (nstatehash);
293+ for (auto it = r.first ; it != r.second ; ++it) {
294+ if (nstate != it->second .tta ) {
295+ Waiting.emplace (std::make_pair (nstatehash, SearchState{nstate, state_hash, justTocked}));
296+ break ;
297+ }
298+ }
268299 }
269300 }
270301 }
@@ -277,12 +308,22 @@ void ReachabilitySearcher::AddToWaitingList(const TTA &state, const std::vector<
277308 // / This is a lot of copying large data objects... Figure something out with maybe std::move
278309 auto nstate = baseChanges << *it;
279310 auto nstatehash = nstate.GetCurrentStateHash ();
280- if (Passed.find (nstatehash) == Passed.end ()) {
311+ auto passed_it = Passed.find (nstatehash);
312+ if (passed_it == Passed.end ()) {
281313 if (nstatehash == state_hash) {
314+ if (nstate == state)
315+ continue ;
282316 spdlog::warn (" Recursive state hashes!" );
283- continue ;
284317 }
285318 Waiting.emplace (std::make_pair (nstatehash, SearchState{nstate, state_hash, justTocked}));
319+ } else {
320+ auto r = Passed.equal_range (nstatehash);
321+ for (auto it = r.first ; it != r.second ; ++it) {
322+ if (nstate != it->second .tta ) {
323+ Waiting.emplace (std::make_pair (nstatehash, SearchState{nstate, state_hash, justTocked}));
324+ break ;
325+ }
326+ }
286327 }
287328 }
288329 }
@@ -293,9 +334,12 @@ bool ReachabilitySearcher::AreQueriesAnswered(const std::vector<QueryResultPair>
293334}
294335
295336bool ReachabilitySearcher::IsSearchStateTockable (const SearchState& state) {
296- return (!state.justTocked && !state.tta .IsCurrentStateImmediate ());
337+ return !state.justTocked
338+ && !state.tta .IsCurrentStateImmediate ();
297339}
298340
341+ #include < random>
342+ std::random_device r;
299343ReachabilitySearcher::StateList::iterator ReachabilitySearcher::PickStateFromWaitingList (const nondeterminism_strategy_t & strategy) {
300344 if (Waiting.empty ())
301345 return Waiting.end ();
@@ -309,14 +353,17 @@ ReachabilitySearcher::StateList::iterator ReachabilitySearcher::PickStateFromWai
309353 return Waiting.begin ();
310354 case nondeterminism_strategy_t ::PICK_LAST: {
311355 auto begin = Waiting.begin ();
312- for (auto i = 0 ; i < Waiting.size (); i++)
356+ for (auto i = 0 ; i < Waiting.size ()- 1 ; i++)
313357 begin++;
314358 return begin;
315359 }
316360 case nondeterminism_strategy_t ::PICK_RANDOM:
317- auto randomPick = rand () % Waiting.size ();
361+ // auto randomPick = rand() % Waiting.size();
362+ std::default_random_engine e1 (r ());
363+ std::uniform_int_distribution<size_t > uniform_dist (0 , Waiting.size ()-1 );
364+ auto randomPick = uniform_dist (e1 );
318365 auto picked = Waiting.begin ();
319- for (int i = 0 ; i < randomPick; i++)
366+ for (auto i = 0 ; i < randomPick; i++)
320367 picked++;
321368 return picked;
322369 }
0 commit comments