Simulation keeps track of simulated states in the input automaton.
* NEWS: Document the change. * spot/twaalgos/simulation.cc: Implement the change. * spot/twa/twagraph.cc: `copy_state_names_from` uses simulated states info if present. * spot/twaalgos/determinize.cc: Pretty-print in determinization follows simulated states, avoiding possible confusion. * tests/Makefile.am, tests/python/simstate.py: Add a test.
This commit is contained in:
parent
967b1a4192
commit
7b5ab54530
6 changed files with 228 additions and 12 deletions
|
|
@ -635,11 +635,22 @@ namespace spot
|
|||
{
|
||||
if (other == shared_from_this())
|
||||
return;
|
||||
|
||||
auto orig = get_named_prop<std::vector<unsigned>>("original-states");
|
||||
auto sims = get_named_prop<std::vector<unsigned>>("simulated-states");
|
||||
|
||||
if (orig && sims)
|
||||
throw std::runtime_error("copy_state_names_from(): original-states and "
|
||||
"simulated-states are both set");
|
||||
|
||||
if (orig && orig->size() != num_states())
|
||||
throw std::runtime_error("copy_state_names_from(): unexpected size "
|
||||
"for original-states");
|
||||
|
||||
if (sims && sims->size() != other->num_states())
|
||||
throw std::runtime_error("copy_state_names_from(): unexpected size "
|
||||
"for simulated-states");
|
||||
|
||||
auto names = std::unique_ptr<std::vector<std::string>>
|
||||
(new std::vector<std::string>);
|
||||
unsigned ns = num_states();
|
||||
|
|
@ -647,11 +658,27 @@ namespace spot
|
|||
|
||||
for (unsigned s = 0; s < ns; ++s)
|
||||
{
|
||||
unsigned other_s = orig ? (*orig)[s] : s;
|
||||
if (other_s >= ons)
|
||||
throw std::runtime_error("copy_state_names_from(): state does not"
|
||||
" exist in source automaton");
|
||||
names->emplace_back(other->format_state(other_s));
|
||||
std::string newname = "";
|
||||
if (sims)
|
||||
{
|
||||
for (unsigned t = 0; t < ons; ++t)
|
||||
{
|
||||
if (s == (*sims)[t])
|
||||
newname += other->format_state(t) + ',';
|
||||
}
|
||||
assert(!newname.empty());
|
||||
newname.pop_back(); // remove trailing comma
|
||||
newname = '[' + newname + ']';
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned other_s = orig ? (*orig)[s] : s;
|
||||
if (other_s >= ons)
|
||||
throw std::runtime_error("copy_state_names_from(): state does not"
|
||||
" exist in source automaton");
|
||||
newname = other->format_state(other_s);
|
||||
}
|
||||
names->emplace_back(newname);
|
||||
}
|
||||
|
||||
set_named_prop("state-names", names.release());
|
||||
|
|
|
|||
|
|
@ -185,7 +185,8 @@ namespace spot
|
|||
}
|
||||
|
||||
std::string
|
||||
nodes_to_string(const safra_state::nodes_t& states)
|
||||
nodes_to_string(const const_twa_graph_ptr& aut,
|
||||
const safra_state::nodes_t& states)
|
||||
{
|
||||
auto copy = sorted_nodes(states);
|
||||
std::ostringstream os;
|
||||
|
|
@ -223,7 +224,7 @@ namespace spot
|
|||
}
|
||||
if (!first)
|
||||
os << ' ';
|
||||
os << n.first;
|
||||
os << aut->format_state(n.first);
|
||||
first = false;
|
||||
}
|
||||
// Finish unwinding stack to print last braces
|
||||
|
|
@ -236,11 +237,12 @@ namespace spot
|
|||
}
|
||||
|
||||
std::vector<std::string>*
|
||||
print_debug(std::map<safra_state, int>& states)
|
||||
print_debug(const const_twa_graph_ptr& aut,
|
||||
const std::map<safra_state, int>& states)
|
||||
{
|
||||
auto res = new std::vector<std::string>(states.size());
|
||||
for (auto& p: states)
|
||||
(*res)[p.second] = nodes_to_string(p.first.nodes_);
|
||||
for (const auto& p: states)
|
||||
(*res)[p.second] = nodes_to_string(aut, p.first.nodes_);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -576,11 +578,16 @@ namespace spot
|
|||
|
||||
// Degeneralize
|
||||
twa_graph_ptr aut = spot::degeneralize_tba(a);
|
||||
if (pretty_print)
|
||||
aut->copy_state_names_from(a);
|
||||
std::vector<bdd> implications;
|
||||
if (use_simulation)
|
||||
{
|
||||
aut = spot::scc_filter(aut);
|
||||
aut = simulation(aut, &implications);
|
||||
auto aut2 = simulation(aut, &implications);
|
||||
if (pretty_print)
|
||||
aut2->copy_state_names_from(aut);
|
||||
aut = aut2;
|
||||
}
|
||||
scc_info scc = scc_info(aut);
|
||||
std::vector<bool> is_connected = find_scc_paths(scc);
|
||||
|
|
@ -694,7 +701,7 @@ namespace spot
|
|||
res->prop_state_acc(false);
|
||||
|
||||
if (pretty_print)
|
||||
res->set_named_prop("state-names", print_debug(seen));
|
||||
res->set_named_prop("state-names", print_debug(aut, seen));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -439,6 +439,10 @@ namespace spot
|
|||
res->copy_ap_of(a_);
|
||||
res->copy_acceptance_of(a_);
|
||||
|
||||
auto state_mapping = new std::vector<unsigned>();
|
||||
state_mapping->resize(a_->num_states());
|
||||
res->set_named_prop("simulated-states", state_mapping);
|
||||
|
||||
// Non atomic propositions variables (= acc and class)
|
||||
bdd nonapvars = all_proms_ & bdd_support(all_class_var_);
|
||||
|
||||
|
|
@ -454,6 +458,9 @@ namespace spot
|
|||
// its class, or by all the implied classes.
|
||||
auto s = gb->new_state(cl.id());
|
||||
gb->alias_state(s, relation_[cl].id());
|
||||
// update state_mapping
|
||||
for (auto& st : p.second)
|
||||
(*state_mapping)[st] = s;
|
||||
if (implications)
|
||||
(*implications)[s] = relation_[cl];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue