21#include <spot/mc/intersect.hh>
22#include <spot/twa/twa.hh>
23#include <spot/twacube_algos/convert.hh>
30 template<
typename State,
typename SuccIterator,
31 typename StateHash,
typename StateEqual>
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_;
168 template<
typename State,
typename SuccIterator,
169 typename StateHash,
typename StateEqual>
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_;
This class allows to ensure (at compile time) if a given parameter is of type kripkecube....
Definition: kripke.hh:71
convert a (cube) model into a twa. Note that this algorithm cannot be run in parallel but could.
Definition: utils.hh:33
This class is a template representation of a Kripke structure. It is composed of two template paramet...
Definition: kripke.hh:40
convert a (cube) product automaton into a twa Note that this algorithm cannot be run in parallel.
Definition: utils.hh:171
A Transition-based ω-Automaton.
Definition: twa.hh:619
void set_named_prop(std::string s, void *val, std::function< void(void *)> destructor)
Declare a named property.
size_t wang32_hash(size_t key)
Thomas Wang's 32 bit hash function.
Definition: hashfunc.hh:37
twa_graph_ptr make_twa_graph(const bdd_dict_ptr &dict)
Build an explicit automaton from all states of aut,.
Definition: twagraph.hh:786
Definition: automata.hh:26
bdd cube_to_bdd(spot::cube cube, const cubeset &cubeset, std::unordered_map< int, int > &reverse_binder)
Transform a cube cube into bdd using the map that bind cube indexes to bdd indexes.
An acceptance mark.
Definition: acc.hh:84