Inf(i)|Inf(j) -> Inf(k) and Fin(i)&Fin(j) -> Fin(k)

Implement those rules in simplify_acceptance_here().

* NEWS: Mention the change.
* spot/twa/acc.cc,
spot/twa/acc.hh (acc_cond::acc_code::used_once_sets): New method.
* spot/twaalgos/cleanacc.cc, spot/twaalgos/cleanacc.hh:
Implement the above rule.
* tests/core/remfin.test: Adjust expected results.
* tests/python/simplacc.py: New file.
* tests/Makefile.am: Add it.
This commit is contained in:
Alexandre Duret-Lutz 2020-01-27 22:50:17 +01:00
parent 5dc6da0b20
commit 50c0f880dc
8 changed files with 416 additions and 23 deletions

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015-2019 Laboratoire de Recherche et Développement
// Copyright (C) 2015-2020 Laboratoire de Recherche et Développement
// de l'Epita.
//
// This file is part of Spot, a model checking library.
@ -2340,6 +2340,7 @@ namespace spot
std::swap(c, *this);
}
int acc_cond::acc_code::fin_one() const
{
if (empty() || is_f())
@ -2398,4 +2399,34 @@ namespace spot
while (pos >= &front());
return res;
}
acc_cond::mark_t acc_cond::acc_code::used_once_sets() const
{
mark_t seen = {};
mark_t dups = {};
if (empty())
return {};
const acc_cond::acc_word* pos = &back();
do
{
switch (pos->sub.op)
{
case acc_cond::acc_op::And:
case acc_cond::acc_op::Or:
--pos;
break;
case acc_cond::acc_op::Inf:
case acc_cond::acc_op::InfNeg:
case acc_cond::acc_op::FinNeg:
case acc_cond::acc_op::Fin:
auto m = pos[-1].mark;
pos -= 2;
dups |= m & seen;
seen |= m;
break;
}
}
while (pos >= &front());
return seen - dups;
}
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014-2019 Laboratoire de Recherche et Développement
// Copyright (C) 2014-2020 Laboratoire de Recherche et Développement
// de l'Epita.
//
// This file is part of Spot, a model checking library.
@ -1199,7 +1199,7 @@ namespace spot
///
/// If multiple unit-Fin appear as unit-clauses, the set of
/// those will be returned. For instance applied to
/// `Fin(0)&Fin(1)&(Inf(2)|Fin(3))``, this will return `{0,1}`.
/// `Fin(0)&Fin(1)&(Inf(2)|Fin(3))`, this will return `{0,1}`.
mark_t fin_unit() const;
/// \brief Return one acceptance set i that appear as `Fin(i)`
@ -1286,6 +1286,14 @@ namespace spot
/// \brief Return the set of sets appearing in the condition.
acc_cond::mark_t used_sets() const;
/// \brief Return the sets that appears only once in the
/// acceptance.
///
/// For instance if the condition is
/// `Fin(0)&(Inf(1)|(Fin(1)&Inf(2)))`, this returns `{0,2}`,
/// because set `1` is used more than once.
mark_t used_once_sets() const;
/// \brief Return the sets used as Inf or Fin in the acceptance condition
std::pair<acc_cond::mark_t, acc_cond::mark_t> used_inf_fin_sets() const;