expansions: UniquePrefixSeenOpt
This commit is contained in:
parent
84d3977c0d
commit
975ea0c52a
2 changed files with 54 additions and 20 deletions
|
|
@ -301,7 +301,7 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
finalize(expansion_t& exp, exp_opts::expand_opt opts, bdd_dict_ptr d)
|
finalize(expansion_t& exp, exp_opts::expand_opt opts, bdd_dict_ptr d, std::unordered_set<formula>* seen)
|
||||||
{
|
{
|
||||||
if (opts & (exp_opts::expand_opt::BddIsop
|
if (opts & (exp_opts::expand_opt::BddIsop
|
||||||
| exp_opts::expand_opt::BddMinterm))
|
| exp_opts::expand_opt::BddMinterm))
|
||||||
|
|
@ -344,9 +344,37 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
exp.clear();
|
exp.clear();
|
||||||
|
|
||||||
for (const auto [prefix, suffix] : unique_map)
|
for (const auto [prefix, suffix] : unique_map)
|
||||||
{
|
{
|
||||||
exp.insert({prefix, suffix});
|
if ((opts & exp_opts::expand_opt::UniquePrefixSeenOpt)
|
||||||
|
&& suffix.is(op::OrRat))
|
||||||
|
{
|
||||||
|
std::vector<formula> merge;
|
||||||
|
std::vector<formula> single;
|
||||||
|
|
||||||
|
for (const auto& sub_f : suffix)
|
||||||
|
{
|
||||||
|
if (seen->find(sub_f) != seen->end())
|
||||||
|
{
|
||||||
|
single.push_back(sub_f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
merge.push_back(sub_f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& sub_f : single)
|
||||||
|
exp.insert({prefix, sub_f});
|
||||||
|
|
||||||
|
if (!merge.empty())
|
||||||
|
exp.insert({prefix, formula::OrRat(merge)});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exp.insert({prefix, suffix});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,7 +427,7 @@ namespace spot
|
||||||
|
|
||||||
|
|
||||||
expansion_t
|
expansion_t
|
||||||
expansion(formula f, const bdd_dict_ptr& d, void *owner, exp_opts::expand_opt opts)
|
expansion(formula f, const bdd_dict_ptr& d, void *owner, exp_opts::expand_opt opts, std::unordered_set<formula>* seen)
|
||||||
{
|
{
|
||||||
using exp_t = std::multimap<bdd, formula, bdd_less_than>;
|
using exp_t = std::multimap<bdd, formula, bdd_less_than>;
|
||||||
|
|
||||||
|
|
@ -413,8 +441,8 @@ namespace spot
|
||||||
return {{f_bdd, formula::eword()}};
|
return {{f_bdd, formula::eword()}};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rec = [&d, owner, opts](formula f){
|
auto rec = [&d, owner, seen](formula f){
|
||||||
return expansion(f, d, owner, exp_opts::None);
|
return expansion(f, d, owner, exp_opts::None, seen);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -426,7 +454,8 @@ namespace spot
|
||||||
SPOT_UNREACHABLE();
|
SPOT_UNREACHABLE();
|
||||||
|
|
||||||
case op::eword:
|
case op::eword:
|
||||||
return {{bddfalse, formula::ff()}};
|
// return {{bddfalse, formula::ff()}};
|
||||||
|
return {};
|
||||||
|
|
||||||
case op::Concat:
|
case op::Concat:
|
||||||
{
|
{
|
||||||
|
|
@ -447,7 +476,7 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,7 +513,7 @@ namespace spot
|
||||||
if (f.min() == 0)
|
if (f.min() == 0)
|
||||||
res.insert({bddtrue, formula::eword()});
|
res.insert({bddtrue, formula::eword()});
|
||||||
|
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,7 +532,7 @@ namespace spot
|
||||||
res.insert({bdd_l, formula::Concat({form, formula::Star(f[0], min, max)})});
|
res.insert({bdd_l, formula::Concat({form, formula::Star(f[0], min, max)})});
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -511,7 +540,7 @@ namespace spot
|
||||||
{
|
{
|
||||||
formula rewrite = rewrite_and_nlm(f);
|
formula rewrite = rewrite_and_nlm(f);
|
||||||
auto res = rec(rewrite);
|
auto res = rec(rewrite);
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -541,7 +570,7 @@ namespace spot
|
||||||
{
|
{
|
||||||
for (auto& [_, dest] : res)
|
for (auto& [_, dest] : res)
|
||||||
dest = formula::first_match(dest);
|
dest = formula::first_match(dest);
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -561,7 +590,7 @@ namespace spot
|
||||||
|
|
||||||
for (auto& [_, dest] : res_det)
|
for (auto& [_, dest] : res_det)
|
||||||
dest = formula::first_match(dest);
|
dest = formula::first_match(dest);
|
||||||
finalize(res_det, opts, d);
|
finalize(res_det, opts, d, seen);
|
||||||
return res_det;
|
return res_det;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -586,7 +615,7 @@ namespace spot
|
||||||
res.insert({li, formula::Fusion({ei, F})});
|
res.insert({li, formula::Fusion({ei, F})});
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -636,7 +665,7 @@ namespace spot
|
||||||
res = std::move(new_res);
|
res = std::move(new_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -659,7 +688,7 @@ namespace spot
|
||||||
res.insert({label, dest});
|
res.insert({label, dest});
|
||||||
}
|
}
|
||||||
|
|
||||||
finalize(res, opts, d);
|
finalize(res, opts, d, seen);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -709,6 +738,8 @@ namespace spot
|
||||||
|
|
||||||
auto formula2state = robin_hood::unordered_map<formula, unsigned>();
|
auto formula2state = robin_hood::unordered_map<formula, unsigned>();
|
||||||
auto signature2state = std::unordered_map<std::pair<bool, expansion_t>, unsigned, signature_hash>();
|
auto signature2state = std::unordered_map<std::pair<bool, expansion_t>, unsigned, signature_hash>();
|
||||||
|
auto seen = std::unordered_set<formula>();
|
||||||
|
seen.insert(f);
|
||||||
|
|
||||||
unsigned init_state = aut->new_state();
|
unsigned init_state = aut->new_state();
|
||||||
aut->set_init_state(init_state);
|
aut->set_init_state(init_state);
|
||||||
|
|
@ -720,7 +751,7 @@ namespace spot
|
||||||
aut->register_ap(ap);
|
aut->register_ap(ap);
|
||||||
|
|
||||||
if (signature_merge)
|
if (signature_merge)
|
||||||
signature2state.insert({ {f.accepts_eword(), expansion(f, d, aut.get(), opts)}, init_state});
|
signature2state.insert({ {f.accepts_eword(), expansion(f, d, aut.get(), opts, &seen)}, init_state});
|
||||||
|
|
||||||
|
|
||||||
auto todo = std::vector<std::pair<formula, unsigned>>();
|
auto todo = std::vector<std::pair<formula, unsigned>>();
|
||||||
|
|
@ -743,7 +774,7 @@ namespace spot
|
||||||
{
|
{
|
||||||
if (signature_merge)
|
if (signature_merge)
|
||||||
{
|
{
|
||||||
auto exp = expansion(suffix, d, aut.get(), opts);
|
auto exp = expansion(suffix, d, aut.get(), opts, &seen);
|
||||||
bool accepting = suffix.accepts_eword();
|
bool accepting = suffix.accepts_eword();
|
||||||
auto it2 = signature2state.find({accepting, exp});
|
auto it2 = signature2state.find({accepting, exp});
|
||||||
if (it2 != signature2state.end())
|
if (it2 != signature2state.end())
|
||||||
|
|
@ -755,10 +786,11 @@ namespace spot
|
||||||
|
|
||||||
dst = aut->new_state();
|
dst = aut->new_state();
|
||||||
todo.push_back({suffix, dst});
|
todo.push_back({suffix, dst});
|
||||||
|
seen.insert(suffix);
|
||||||
|
|
||||||
formula2state.insert({suffix, dst});
|
formula2state.insert({suffix, dst});
|
||||||
if (signature_merge)
|
if (signature_merge)
|
||||||
signature2state.insert({{suffix.accepts_eword(), expansion(suffix, d, aut.get(), opts)}, dst});
|
signature2state.insert({{suffix.accepts_eword(), expansion(suffix, d, aut.get(), opts, &seen)}, dst});
|
||||||
|
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << suffix;
|
ss << suffix;
|
||||||
|
|
@ -777,11 +809,12 @@ namespace spot
|
||||||
? acc_mark
|
? acc_mark
|
||||||
: acc_cond::mark_t();
|
: acc_cond::mark_t();
|
||||||
|
|
||||||
auto exp = expansion(curr_f, d, aut.get(), opts);
|
auto exp = expansion(curr_f, d, aut.get(), opts, &seen);
|
||||||
|
|
||||||
for (const auto& [letter, suffix] : exp)
|
for (const auto& [letter, suffix] : exp)
|
||||||
{
|
{
|
||||||
if (suffix.is(op::ff))
|
if (suffix.is(op::ff))
|
||||||
|
// TODO ASSERT NOT
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto dst = find_dst(suffix);
|
auto dst = find_dst(suffix);
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,12 @@ namespace spot
|
||||||
MergeEdges = 64,
|
MergeEdges = 64,
|
||||||
SignatureMerge = 128,
|
SignatureMerge = 128,
|
||||||
Determinize = 256,
|
Determinize = 256,
|
||||||
|
UniquePrefixSeenOpt = 512,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
SPOT_API expansion_t
|
SPOT_API expansion_t
|
||||||
expansion(formula f, const bdd_dict_ptr& d, void *owner, exp_opts::expand_opt opts);
|
expansion(formula f, const bdd_dict_ptr& d, void *owner, exp_opts::expand_opt opts, std::unordered_set<formula>* seen = nullptr);
|
||||||
|
|
||||||
SPOT_API twa_graph_ptr
|
SPOT_API twa_graph_ptr
|
||||||
expand_automaton(formula f, bdd_dict_ptr d, exp_opts::expand_opt opts);
|
expand_automaton(formula f, bdd_dict_ptr d, exp_opts::expand_opt opts);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue