1 #ifndef VCSN_ALGOS_MINIMIZE_SIGNATURE_HH
2 # define VCSN_ALGOS_MINIMIZE_SIGNATURE_HH
4 # include <unordered_map>
5 # include <unordered_set>
22 namespace detail_signature
24 template <
typename Aut>
28 "minimize: signature: requires Boolean weights");
41 using set_t = std::vector<state_t>;
45 constexpr
static const char*
me() {
return "minimize-signature"; }
71 for (
unsigned i = 0; i < c2ss.size(); ++i)
73 o << sep <<
'[' << i <<
"] = ";
91 o <<
"out{" << out.
label <<
" => ";
110 for (
const auto& out: outs)
144 for (
auto& t : state_output)
147 std::hash_combine(res, label);
151 for (
auto s : t.to_states)
153 std::hash_combine(res, bits);
156 print_(state_output, std::cerr) <<
" = " << res << std::endl;
187 print_(as, std::cerr) <<
" =? ";
188 print_(bs, std::cerr) <<
" = ";
190 if (as.size() != bs.size())
193 std::cerr <<
"false 1" << std::endl;
198 auto b_i = bs.cbegin();
200 for (
const auto& a : as)
202 const label_t& a_label = a.label;
203 const label_t& b_label = b_i->label;
204 const std::vector<state_t>& a_states = a.to_states;
205 const std::vector<state_t>& b_states = b_i->to_states;
207 if (!
ls_.equals(a_label, b_label))
210 std::cerr <<
"false 2" << std::endl;
221 a_bits.reset(); b_bits.reset();
222 for (
auto s : a_states)
224 for (
auto s : b_states)
226 if (a_bits != b_bits)
229 std::cerr <<
"false 3" << std::endl;
239 std::cerr <<
"true" << std::endl;
248 :
public std::unordered_map<state_output_t*, set_t,
249 signature_hasher, signature_equal_to>
261 const size_t class_bound)
265 ls, state_to_class, class_bound))
274 for (
const auto& o_s : mm)
278 const char* sep =
"";
279 for (
auto s: o_s.second)
281 o << sep << s <<
'%' << mm.state_to_class_.at(s);
321 ,
ls_(*
a_->labelset())
326 for (
auto s :
a_->all_states())
330 for (
auto t :
a_->all_out(s))
331 label_to_states[
a_->label_of(t)].emplace_back(
a_->dst_of(t));
335 for (
auto& l_ss : label_to_states)
337 std::sort(l_ss.second.begin(), l_ss.second.end());
339 std::move(l_ss.second)});
349 std::unordered_set<class_t> classes;
351 const auto& all =
a_->all_states();
362 for (
auto i = std::begin(classes), end = std::end(classes);
369 if (c_states.size() < 2)
371 i = classes.erase(i);
377 signature_to_state(*
this,
380 for (
auto s : c_states)
383 std::cerr <<
"class %" << c <<
" state: " << s <<
' ';
389 std::cerr <<
"signature_to_state: " << signature_to_state
392 if (2 <= signature_to_state.size())
395 i = classes.erase(i);
396 for (
auto p: signature_to_state)
420 template <
typename Aut>
432 #endif // !VCSN_ALGOS_MINIMIZE_SIGNATURE_HH
std::enable_if< std::is_same< weightset_t_of< Aut >, b >::value &&labelset_t_of< Aut >::is_free(), partition_automaton< Aut > >::type minimize(const Aut &a, const std::string &algo)
label_t_of< automaton_t > label_t
class_to_set_t class_to_set_
std::vector< state_t > to_states
std::unordered_map< state_t, class_t > state_to_class_t
state_t_of< automaton_t > state_t
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
std::vector< set_t > class_to_set_t
static constexpr const char * me()
signature_equal_to(minimizer &the_minimizer, const labelset_t &ls, const state_to_class_t &state_to_class, size_t class_bound)
std::unordered_map< state_output_t *, set_t, signature_hasher, signature_equal_to > super_t
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
const state_to_class_t & state_to_class_
bool is_trim(const Aut &a)
Indentation relative functions.
friend std::ostream & operator<<(std::ostream &o, const state_output_for_label_t &out)
const state_to_class_t & state_to_class_
class_t make_class(set_t &&set, class_t number=class_invalid)
Make a new class with the given set of states.
const state_to_class_t & state_to_class_
auto quotient(const Aut &a, typename detail::quotienter< Aut >::class_to_set_t &classes) -> partition_automaton< Aut >
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
static std::ostream & print_(const class_to_set_t &c2ss, std::ostream &o)
size_t operator()(const state_output_t *state_output_) const noexcept
auto minimize_signature(const Aut &a) -> partition_automaton< Aut >
partition_automaton< automaton_t > operator()()
The minimized automaton.
static std::ostream & print_(const set_t &ss, std::ostream &o)
auto sort(const Aut &a) -> permutation_automaton< Aut >
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
signature_hasher(minimizer &the_minimizer, size_t num_classes)
std::vector< state_output_for_label_t > state_output_t
bool operator()(const state_output_t *as_, const state_output_t *bs_) const noexcept
friend std::ostream & operator<<(std::ostream &o, const signature_multimap &mm)
signature_multimap(minimizer &the_minimizer, const labelset_t &ls, state_to_class_t &state_to_class, const size_t class_bound)
state_to_class_t state_to_class_
std::shared_ptr< const detail::label_base > label
static constexpr class_t class_invalid
An invalid class.
Provide a variadic mul on top of a binary mul(), and one().
std::map< label_t, std::vector< state_t >, vcsn::less< labelset_t >> label_to_states_t
static std::ostream & print_(const state_output_t &outs, std::ostream &o)
std::vector< state_t > set_t
friend class signature_hasher
const automaton_t & a_
Input automaton, supplied at construction time.
boost::dynamic_bitset<> dynamic_bitset
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
std::shared_ptr< detail::partition_automaton_impl< Aut >> partition_automaton
A partition automaton as a shared pointer.
void build_classes_()
Build the initial classes, and split until fix point.
const size_t class_bound_
labelset_t_of< automaton_t > labelset_t
std::unordered_map< state_t, state_output_t > state_to_state_output_
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.