acc: introduce top_conjuncts() and top_disjuncts()
* spot/twa/acc.cc, spot/twa/acc.hh: Add the new functions. * python/spot/impl.i: Add bindings. * tests/python/acc_cond.ipynb: Add tests. * NEWS: Mention it.
This commit is contained in:
parent
55c50c65c8
commit
510a18b156
5 changed files with 202 additions and 73 deletions
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015-2018 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2015-2019 Laboratoire de Recherche et Développement
|
||||
// de l'Epita.
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -1232,6 +1232,74 @@ namespace spot
|
|||
return rescode;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static std::vector<acc_cond::acc_code>
|
||||
top_clauses(const acc_cond::acc_code& code,
|
||||
acc_cond::acc_op connect, acc_cond::acc_op inf_fin)
|
||||
{
|
||||
std::vector<acc_cond::acc_code> res;
|
||||
|
||||
if (!code.empty())
|
||||
{
|
||||
auto pos = &code.back();
|
||||
auto start = &code.front();
|
||||
assert(pos - pos->sub.size == start);
|
||||
if (pos->sub.op == connect)
|
||||
{
|
||||
do
|
||||
{
|
||||
--pos;
|
||||
if (pos->sub.op == inf_fin)
|
||||
{
|
||||
for (unsigned d: pos[-1].mark.sets())
|
||||
{
|
||||
acc_cond::acc_code tmp;
|
||||
tmp.resize(2);
|
||||
tmp[0].mark = {d};
|
||||
tmp[1].sub.op = inf_fin;
|
||||
tmp[1].sub.size = 1;
|
||||
res.emplace_back(tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res.emplace_back(pos);
|
||||
}
|
||||
pos -= pos->sub.size;
|
||||
}
|
||||
while (pos > start);
|
||||
return res;
|
||||
}
|
||||
if (pos->sub.op == inf_fin)
|
||||
{
|
||||
for (unsigned d: pos[-1].mark.sets())
|
||||
{
|
||||
acc_cond::acc_code tmp;
|
||||
tmp.resize(2);
|
||||
tmp[0].mark = {d};
|
||||
tmp[1].sub.op = inf_fin;
|
||||
tmp[1].sub.size = 1;
|
||||
res.emplace_back(tmp);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
res.emplace_back(code);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<acc_cond::acc_code> acc_cond::acc_code::top_disjuncts() const
|
||||
{
|
||||
return top_clauses(*this, acc_cond::acc_op::Or, acc_cond::acc_op::Fin);
|
||||
}
|
||||
|
||||
std::vector<acc_cond::acc_code> acc_cond::acc_code::top_conjuncts() const
|
||||
{
|
||||
return top_clauses(*this, acc_cond::acc_op::And, acc_cond::acc_op::Inf);
|
||||
}
|
||||
|
||||
std::pair<bool, acc_cond::mark_t>
|
||||
acc_cond::sat_unsat_mark(bool sat) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014-2018 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2014-2019 Laboratoire de Recherche et Développement
|
||||
// de l'Epita.
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -1120,6 +1120,27 @@ namespace spot
|
|||
/// This implementation is the dual of `to_dnf()`.
|
||||
acc_code to_cnf() const;
|
||||
|
||||
|
||||
/// \brief Return the top-level disjuncts.
|
||||
///
|
||||
/// For instance, if the formula is
|
||||
/// Fin(0)|Fin(1)|(Fin(2)&(Inf(3)|Fin(4))), this returns
|
||||
/// [Fin(0), Fin(1), Fin(2)&(Inf(3)|Fin(4))].
|
||||
///
|
||||
/// If the formula is not a disjunction, this returns
|
||||
/// a vector with the formula as only element.
|
||||
std::vector<acc_code> top_disjuncts() const;
|
||||
|
||||
/// \brief Return the top-level conjuncts.
|
||||
///
|
||||
/// For instance, if the formula is
|
||||
/// Fin(0)|Fin(1)|(Fin(2)&(Inf(3)|Fin(4))), this returns
|
||||
/// [Fin(0), Fin(1), Fin(2)&(Inf(3)|Fin(4))].
|
||||
///
|
||||
/// If the formula is not a conjunction, this returns
|
||||
/// a vector with the formula as only element.
|
||||
std::vector<acc_code> top_conjuncts() const;
|
||||
|
||||
/// \brief Complement an acceptance formula.
|
||||
///
|
||||
/// Also known as "dualizing the acceptance condition" since
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue