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>
38 sys_(sys), dict_(dict)
41 State, SuccIterator>::value,
42 "error: does not match the kripkecube requirements");
55 State initial = sys_.initial(0);
56 if (SPOT_LIKELY(push(initial, dfs_number_+1)))
58 visited_[initial] = dfs_number_++;
59 todo_.push_back({initial, sys_.succ(initial, 0)});
61 while (!todo_.empty())
63 if (todo_.back().it->done())
65 if (SPOT_LIKELY(pop(todo_.back().s)))
67 sys_.recycle(todo_.back().it, 0);
74 State dst = todo_.back().it->state();
75 auto it = visited_.find(dst);
76 if (it == visited_.end())
78 if (SPOT_LIKELY(push(dst, dfs_number_+1)))
80 visited_[dst] = dfs_number_++;
81 todo_.back().it->next();
82 todo_.push_back({dst, sys_.succ(dst, 0)});
87 edge(visited_[todo_.back().s], visited_[dst]);
88 todo_.back().it->next();
100 names_ =
new std::vector<std::string>();
103 for (
auto ap : sys_.ap())
105 auto idx = res_->register_ap(
ap);
106 reverse_binder_[i++] = idx;
114 unsigned st = res_->new_state();
115 names_->push_back(sys_.to_string(s));
118 edge(visited_[todo_.back().s], st);
121 SPOT_ASSERT(st+1 == i);
132 void edge(
unsigned src,
unsigned dst)
135 bdd cond =
cube_to_bdd(todo_.back().it->condition(),
136 cs, reverse_binder_);
137 res_->new_edge(src, dst, cond);
143 res_->purge_unreachable_states();
144 res_->set_named_prop<std::vector<std::string>>(
"state-names", names_);
164 typedef std::unordered_map<
const State, int,
174 unsigned int dfs_number_ = 0;
176 unsigned int transitions_ = 0;
190 template<
typename State,
typename SuccIterator,
191 typename StateHash,
typename StateEqual>
200 struct product_state_equal
203 operator()(
const product_state lhs,
204 const product_state rhs)
const
207 return (lhs.st_prop == rhs.st_prop) &&
208 equal(lhs.st_kripke, rhs.st_kripke);
212 struct product_state_hash
215 operator()(
const product_state lhs)
const noexcept
218 unsigned u = hash(lhs.st_kripke) % (1<<30);
232 State, SuccIterator>::value,
233 "error: does not match the kripkecube requirements");
246 product_state initial = {sys_.initial(0), twa_->get_initial()};
247 if (SPOT_LIKELY(push_state(initial, dfs_number_+1, {})))
249 todo_.push_back({initial, sys_.succ(initial.st_kripke, 0),
250 twa_->succ(initial.st_prop)});
253 if (todo_.back().it_prop->done())
256 forward_iterators(sys_, twa_, todo_.back().it_kripke,
257 todo_.back().it_prop,
true, 0);
258 map[initial] = ++dfs_number_;
260 while (!todo_.empty())
264 if (todo_.back().it_kripke->done())
266 bool is_init = todo_.size() == 1;
267 auto newtop = is_init? todo_.back().st: todo_[todo_.size() -2].st;
268 if (SPOT_LIKELY(pop_state(todo_.back().st,
269 map[todo_.back().st],
274 sys_.recycle(todo_.back().it_kripke, 0);
281 product_state dst = {
282 todo_.back().it_kripke->state(),
283 twa_->trans_storage(todo_.back().it_prop, 0).dst
285 auto acc = twa_->trans_data(todo_.back().it_prop, 0).acc_;
286 forward_iterators(sys_, twa_, todo_.back().it_kripke,
287 todo_.back().it_prop,
false, 0);
288 auto it = map.find(dst);
291 if (SPOT_LIKELY(push_state(dst, dfs_number_+1, acc)))
293 map[dst] = ++dfs_number_;
294 todo_.push_back({dst, sys_.succ(dst.st_kripke, 0),
295 twa_->succ(dst.st_prop)});
296 forward_iterators(sys_, twa_, todo_.back().it_kripke,
297 todo_.back().it_prop,
true, 0);
300 else if (SPOT_UNLIKELY(update(todo_.back().st, dfs_number_,
301 dst, map[dst], acc)))
311 res_->purge_unreachable_states();
312 res_->set_named_prop<std::vector<std::string>>(
"state-names", names_);
321 names_ =
new std::vector<std::string>();
324 for (
auto ap : sys_.ap())
326 auto idx = res_->register_ap(
ap);
327 reverse_binder_[i++] = idx;
334 unsigned st = res_->new_state();
338 auto c = twa_->get_cubeset()
339 .intersection(twa_->trans_data
340 (todo_.back().it_prop).cube_,
341 todo_.back().it_kripke->condition());
345 twa_->get_cubeset().release(c);
346 res_->new_edge(map[todo_.back().st]-1, st, x,
348 (todo_.back().it_prop).acc_);
352 names_->push_back(sys_.to_string(s.st_kripke) +
353 (
'*' + std::to_string(s.st_prop)));
354 SPOT_ASSERT(st+1 == i);
360 product_state,
unsigned dst,
363 auto c = twa_->get_cubeset()
364 .intersection(twa_->trans_data
365 (todo_.back().it_prop).cube_,
366 todo_.back().it_kripke->condition());
370 twa_->get_cubeset().release(c);
371 res_->new_edge(src-1, dst-1, x, cond);
376 bool pop_state(product_state,
unsigned,
bool, product_state,
unsigned)
386 SuccIterator* it_kripke;
387 std::shared_ptr<trans_index> it_prop;
391 typedef std::unordered_map<
const product_state, int,
393 product_state_equal> visited_map;
396 kripkecube<State, SuccIterator>& sys_;
400 std::vector<todo__element> todo_;
404 unsigned int dfs_number_ = 0;
406 unsigned int transitions_ = 0;
410 std::vector<std::string>* names_;
412 std::unordered_map<int, int> reverse_binder_;
Manager for allocating and manipulating cubes (bit-encoded partial assignments over APs).
Definition cube.hh:72
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
void run()
Run the conversion algorithm.
Definition utils.hh:52
kripkecube< State, SuccIterator > & sys_
Reference to system model.
Definition utils.hh:168
~kripkecube_to_twa()
Destructor.
Definition utils.hh:46
kripkecube_to_twa(kripkecube< State, SuccIterator > &sys, bdd_dict_ptr dict)
Constructor for kripkecube-to-twa conversion.
Definition utils.hh:37
bool push(State s, unsigned i)
Push state to stack.
Definition utils.hh:111
spot::twa_graph_ptr res_
Result twa.
Definition utils.hh:178
visited__map visited_
Visited states map.
Definition utils.hh:172
std::vector< todo__element > todo_
DFS todo stack.
Definition utils.hh:170
bool pop(State)
Pop state from stack.
Definition utils.hh:126
void finalize()
Finalize the result twa.
Definition utils.hh:141
twa_graph_ptr twa()
Return the resulting twa.
Definition utils.hh:148
void edge(unsigned src, unsigned dst)
Add edge from src to dst.
Definition utils.hh:132
std::vector< std::string > * names_
State names.
Definition utils.hh:180
std::unordered_map< int, int > reverse_binder_
Reverse binding for APs.
Definition utils.hh:184
std::unordered_map< const State, int, StateHash, StateEqual > visited__map
Type alias for visited map.
Definition utils.hh:165
bdd_dict_ptr dict_
BDD dictionary.
Definition utils.hh:182
void setup()
Setup algorithm resources.
Definition utils.hh:96
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:193
bool push_state(product_state s, unsigned i, acc_cond::mark_t)
Push product state to stack.
Definition utils.hh:332
bool update(product_state, unsigned src, product_state, unsigned dst, acc_cond::mark_t cond)
Update state with acceptance condition.
Definition utils.hh:359
virtual ~product_to_twa()
Destructor.
Definition utils.hh:237
product_to_twa(kripkecube< State, SuccIterator > &sys, twacube_ptr twa)
Constructor for product-to-twa conversion.
Definition utils.hh:227
bool pop_state(product_state, unsigned, bool, product_state, unsigned)
Pop state from stack.
Definition utils.hh:376
bool run()
Run the conversion algorithm.
Definition utils.hh:243
twa_graph_ptr twa()
Return the resulting twa.
Definition utils.hh:309
void setup()
Setup algorithm resources.
Definition utils.hh:317
A Transition-based ω-Automaton.
Definition twa.hh:648
size_t wang32_hash(size_t key)
Thomas Wang's 32 bit hash function.
Definition hashfunc.hh:37
bdd_dict_ptr make_bdd_dict()
Create a new, empty bdd_dict wrapped in a shared pointer.
Definition bdddict.hh:308
std::shared_ptr< bdd_dict > bdd_dict_ptr
Shared pointer to a bdd_dict.
Definition bdddict.hh:304
std::shared_ptr< twa_graph > twa_graph_ptr
Shared pointer to a mutable twa_graph.
Definition fwd.hh:44
twa_graph_ptr make_twa_graph(const bdd_dict_ptr &dict)
Build an explicit automaton from all states of aut,.
Definition twagraph.hh:865
bdd cube_to_bdd(spot::cube cube, const cubeset &cubeset, std::unordered_map< int, int > &reverse_binder)
Transform a cube cube into a BDD using the map that binds cube indexes to BDD indexes.
std::shared_ptr< twacube > twacube_ptr
Definition fwd.hh:28
Definition automata.hh:26
An acceptance mark.
Definition acc.hh:76
DFS stack element pairing a state its with successor iterator.
Definition utils.hh:156
SuccIterator * it
Iterator over successors.
Definition utils.hh:160
State s
State.
Definition utils.hh:158