Salut Pollux,
Thanks for the prompt reply, that's much appreciated.
I did have a feeling that I was abusing the method, given its "semi-internal" status. :)
As for terminology, "defrag" didn't clearly indicate to me that it could only remove unreachable states. I agree that it shouldn't "remove anything that is used", but since we pass as argument a use-vector and a number of used states, I thought that the notion of "being used" was taken from these args.
In my use case, I compute a vector v of size num_states() via a fix point algorithm and every position above a given threshold corresponds to a state that I'd want flushed. In code, I was doing:
std::vector<unsigned> v = compute_fp (aut);
std::vector<unsigned> defrag (aut->num_states ());
unsigned used = 0, delta = 0;
for (size_t q = 0; q < aut->num_states(); ++q)
if (v[q] > threshold) {
delta++;
defrag[q] = -1;
}
else {
defrag[q] = q - delta;
used++;
}
aut->defrag_states (std::move (defrag), used);
(By the way, not sure why defrag_states insists on receiving an rvalue.)
This is certainly pandering to the oddity of erasing using defrag. I like your kill_state + purge suggestion, it seems to be more robust and less condition-dependent. It also leaves renumbering to the internals, which feels saner.
Cheers,
M.