37 sys_(sys), dict_(dict)
40 State, SuccIterator>::value,
41 "error: does not match the kripkecube requirements");
52 State initial = sys_.initial(0);
53 if (SPOT_LIKELY(push(initial, dfs_number_+1)))
55 visited_[initial] = dfs_number_++;
56 todo_.push_back({initial, sys_.succ(initial, 0)});
58 while (!todo_.empty())
60 if (todo_.back().it->done())
62 if (SPOT_LIKELY(pop(todo_.back().s)))
64 sys_.recycle(todo_.back().it, 0);
71 State dst = todo_.back().it->state();
72 auto it = visited_.find(dst);
73 if (it == visited_.end())
75 if (SPOT_LIKELY(push(dst, dfs_number_+1)))
77 visited_[dst] = dfs_number_++;
78 todo_.back().it->next();
79 todo_.push_back({dst, sys_.succ(dst, 0)});
84 edge(visited_[todo_.back().s], visited_[dst]);
85 todo_.back().it->next();
94 auto d = spot::make_bdd_dict();
96 names_ =
new std::vector<std::string>();
99 for (
auto ap : sys_.ap())
101 auto idx = res_->register_ap(
ap);
102 reverse_binder_[i++] = idx;
106 bool push(State s,
unsigned i)
109 unsigned st = res_->new_state();
110 names_->push_back(sys_.to_string(s));
113 edge(visited_[todo_.back().s], st);
116 SPOT_ASSERT(st+1 == i);
125 void edge(
unsigned src,
unsigned dst)
128 bdd cond =
cube_to_bdd(todo_.back().it->condition(),
129 cs, reverse_binder_);
130 res_->new_edge(src, dst, cond);
135 res_->purge_unreachable_states();
136 res_->set_named_prop<std::vector<std::string>>(
"state-names", names_);
151 typedef std::unordered_map<
const State, int,
152 StateHash, StateEqual> visited__map;
155 std::vector<todo__element> todo_;
156 visited__map visited_;
157 unsigned int dfs_number_ = 0;
158 unsigned int transitions_ = 0;
159 spot::twa_graph_ptr res_;
160 std::vector<std::string>* names_;
162 std::unordered_map<int, int> reverse_binder_;
178 struct product_state_equal
181 operator()(
const product_state lhs,
182 const product_state rhs)
const
185 return (lhs.st_prop == rhs.st_prop) &&
186 equal(lhs.st_kripke, rhs.st_kripke);
190 struct product_state_hash
193 operator()(
const product_state lhs)
const noexcept
196 unsigned u = hash(lhs.st_kripke) % (1<<30);
209 State, SuccIterator>::value,
210 "error: does not match the kripkecube requirements");
221 product_state initial = {sys_.initial(0), twa_->get_initial()};
222 if (SPOT_LIKELY(push_state(initial, dfs_number_+1, {})))
224 todo_.push_back({initial, sys_.succ(initial.st_kripke, 0),
225 twa_->succ(initial.st_prop)});
228 if (todo_.back().it_prop->done())
231 forward_iterators(sys_, twa_, todo_.back().it_kripke,
232 todo_.back().it_prop,
true, 0);
233 map[initial] = ++dfs_number_;
235 while (!todo_.empty())
239 if (todo_.back().it_kripke->done())
241 bool is_init = todo_.size() == 1;
242 auto newtop = is_init? todo_.back().st: todo_[todo_.size() -2].st;
243 if (SPOT_LIKELY(pop_state(todo_.back().st,
244 map[todo_.back().st],
249 sys_.recycle(todo_.back().it_kripke, 0);
256 product_state dst = {
257 todo_.back().it_kripke->state(),
258 twa_->trans_storage(todo_.back().it_prop, 0).dst
260 auto acc = twa_->trans_data(todo_.back().it_prop, 0).acc_;
261 forward_iterators(sys_, twa_, todo_.back().it_kripke,
262 todo_.back().it_prop,
false, 0);
263 auto it = map.find(dst);
266 if (SPOT_LIKELY(push_state(dst, dfs_number_+1, acc)))
268 map[dst] = ++dfs_number_;
269 todo_.push_back({dst, sys_.succ(dst.st_kripke, 0),
270 twa_->succ(dst.st_prop)});
271 forward_iterators(sys_, twa_, todo_.back().it_kripke,
272 todo_.back().it_prop,
true, 0);
275 else if (SPOT_UNLIKELY(update(todo_.back().st, dfs_number_,
276 dst, map[dst], acc)))
285 res_->purge_unreachable_states();
286 res_->
set_named_prop<std::vector<std::string>>(
"state-names", names_);
292 auto d = spot::make_bdd_dict();
294 names_ =
new std::vector<std::string>();
297 for (
auto ap : sys_.ap())
299 auto idx = res_->register_ap(
ap);
300 reverse_binder_[i++] = idx;
306 unsigned st = res_->new_state();
310 auto c = twa_->get_cubeset()
311 .intersection(twa_->trans_data
312 (todo_.back().it_prop).cube_,
313 todo_.back().it_kripke->condition());
317 twa_->get_cubeset().release(c);
318 res_->new_edge(map[todo_.back().st]-1, st, x,
320 (todo_.back().it_prop).acc_);
324 names_->push_back(sys_.to_string(s.st_kripke) +
325 (
'*' + std::to_string(s.st_prop)));
326 SPOT_ASSERT(st+1 == i);
330 bool update(product_state,
unsigned src,
331 product_state,
unsigned dst,
334 auto c = twa_->get_cubeset()
335 .intersection(twa_->trans_data
336 (todo_.back().it_prop).cube_,
337 todo_.back().it_kripke->condition());
341 twa_->get_cubeset().release(c);
342 res_->new_edge(src-1, dst-1, x, cond);
346 bool pop_state(product_state,
unsigned,
bool, product_state,
unsigned)
355 SuccIterator* it_kripke;
356 std::shared_ptr<trans_index> it_prop;
359 typedef std::unordered_map<
const product_state, int,
361 product_state_equal> visited_map;
365 std::vector<todo__element> todo_;
367 unsigned int dfs_number_ = 0;
368 unsigned int transitions_ = 0;
369 spot::twa_graph_ptr res_;
370 std::vector<std::string>* names_;
371 std::unordered_map<int, int> reverse_binder_;