symplify_acceptance: More rules

Fixes #297. Implement the following rules.

Fin(i) & Fin(j) by f if i and j are complementary
Fin(i) & Inf(i) by f
Inf(i) | Inf(j) by t if i and j are complementary
Fin(i) | Inf(i) by t.

* spot/twaalgos/cleanacc.cc, spot/twaalgos/cleanacc.hh: Here.
* tests/python/merge.py: Add more test cases.
* NEWS: Mention the change.
This commit is contained in:
Alexandre Duret-Lutz 2017-11-06 17:25:38 +01:00
parent d9f8c517fa
commit e5a37ff98f
4 changed files with 222 additions and 29 deletions

View file

@ -174,15 +174,18 @@ namespace spot
{
auto tmp = remove_compl_rec(pos, complement);
if (tmp.back().sub.op == acc_cond::acc_op::Fin
&& tmp.front().mark.count() == 1)
seen_fin |= tmp.front().mark;
if (tmp.back().sub.op == acc_cond::acc_op::Inf)
if (!tmp.empty())
{
inf &= std::move(tmp);
pos -= pos->sub.size + 1;
continue;
if (tmp.back().sub.op == acc_cond::acc_op::Fin
&& tmp.front().mark.count() == 1)
seen_fin |= tmp.front().mark;
if (tmp.back().sub.op == acc_cond::acc_op::Inf)
{
inf &= std::move(tmp);
pos -= pos->sub.size + 1;
continue;
}
}
tmp &= std::move(res);
std::swap(tmp, res);
@ -190,8 +193,18 @@ namespace spot
}
while (pos > start);
// Fin(i) & Inf(i) = f;
if (inf.front().mark & seen_fin)
return acc_cond::acc_code::f();
for (auto m: seen_fin.sets())
inf.front().mark -= complement[m];
{
acc_cond::mark_t cm = complement[m];
// Fin(i) & Fin(!i) = f;
if (cm & seen_fin)
return acc_cond::acc_code::f();
// Inf({!i}) & Fin({i}) = Fin({i})
inf.front().mark -= complement[m];
}
return inf & res;
}
@ -205,15 +218,18 @@ namespace spot
{
auto tmp = remove_compl_rec(pos, complement);
if (tmp.back().sub.op == acc_cond::acc_op::Inf
&& tmp.front().mark.count() == 1)
seen_inf |= tmp.front().mark;
if (tmp.back().sub.op == acc_cond::acc_op::Fin)
if (!tmp.empty())
{
fin |= std::move(tmp);
pos -= pos->sub.size + 1;
continue;
if (tmp.back().sub.op == acc_cond::acc_op::Inf
&& tmp.front().mark.count() == 1)
seen_inf |= tmp.front().mark;
if (tmp.back().sub.op == acc_cond::acc_op::Fin)
{
fin |= std::move(tmp);
pos -= pos->sub.size + 1;
continue;
}
}
tmp |= std::move(res);
std::swap(tmp, res);
@ -221,9 +237,18 @@ namespace spot
}
while (pos > start);
// Fin(i) | Inf(i) = t;
if (fin.front().mark & seen_inf)
return acc_cond::acc_code::t();
for (auto m: seen_inf.sets())
fin.front().mark -= complement[m];
{
acc_cond::mark_t cm = complement[m];
// Inf({i}) | Inf({!i}) = t;
if (cm & seen_inf)
return acc_cond::acc_code::t();
// Fin({!i}) | Inf({i}) = Inf({i})
fin.front().mark -= complement[m];
}
return res | fin;
}
case acc_cond::acc_op::Fin:

View file

@ -23,28 +23,48 @@
namespace spot
{
/// \ingroup twa_algorithms
/// \brief Remove useless acceptance sets
///
/// This removes from the automaton the acceptance marks that are
/// not used in the acceptance condition. This also removes from
/// the acceptance conditions the terms that corresponds to empty
/// or full sets.
///
/// If \a strip is true (the default), the remaining acceptance set
/// numbers will be shifted down to reduce maximal number of
/// acceptance sets used.
SPOT_API twa_graph_ptr
cleanup_acceptance_here(twa_graph_ptr aut, bool strip = true);
/// \ingroup twa_algorithms
/// \brief Remove useless acceptance sets
///
/// This removes from the automaton the acceptance marks that are
/// not used in the acceptance condition. This also removes from
/// the acceptance conditions the terms that corresponds to empty
/// or full sets.
///
SPOT_API twa_graph_ptr
cleanup_acceptance(const_twa_graph_ptr aut);
/// @{
/// \ingroup twa_algorithms
/// \brief Simplify an acceptance condition
///
/// Remove useless acceptance sets.
/// Merge identical sets.
/// If some sets are complement to each other, might result in the
/// simplification of some clause in the acceptance condition.
/// Does evereything cleanup_acceptance() does, but additionally:
/// merge identical sets, detect whether to sets i and j are
/// complementary to apply the following reductions:
/// - `Fin(i) & Inf(j) = Fin(i)`
/// - `Fin(i) & Fin(j) = f`
/// - `Fin(i) & Inf(i) = f`
/// - `Fin(i) | Inf(j) = Inf(j)`
/// - `Inf(i) | Inf(j) = t`
/// - `Fin(i) | Inf(i) = t`
SPOT_API twa_graph_ptr
simplify_acceptance_here(twa_graph_ptr aut);
/// \brief Simplify an acceptance condition
SPOT_API twa_graph_ptr
simplify_acceptance(const_twa_graph_ptr aut);
/// @}
}