acc: refactor strip() routines

* src/tgba/acc.cc, src/tgba/acc.hh: Move the strip() routine from
acc_cond into acc_cond::mark_t, and the strip() routine from
cleanacc.cc into acc_cond::acc_code.  Introduce helper functions
to create inf()/fin()/t()/f() at the acc_code level.
* src/tgbaalgos/cleanacc.cc: Simplify, using the strip() function
from acc_code.
* src/tgbaalgos/mask.cc (mask_acc_sets): Use the strip() function
from acc_code so that it work on non-Buchi acceptance.
* src/tgbatest/maskacc.test: Add a test for the latter change.
* src/tgbaalgos/sccfilter.cc, src/tgbatest/acc.cc: Adjust the
use mark_t::strip().
This commit is contained in:
Alexandre Duret-Lutz 2015-02-25 22:36:13 +01:00
parent 717c857794
commit 5b2c7b55ed
7 changed files with 267 additions and 165 deletions

View file

@ -21,61 +21,6 @@
namespace spot
{
namespace
{
acc_cond::acc_code strip(const acc_cond& acc,
const acc_cond::acc_word* pos,
acc_cond::mark_t useless)
{
auto start = pos - pos->size;
switch (pos->op)
{
case acc_cond::acc_op::And:
{
--pos;
acc_cond::acc_code res;
do
{
auto tmp = strip(acc, pos, useless);
tmp.append_and(std::move(res));
std::swap(tmp, res);
pos -= pos->size + 1;
}
while (pos > start);
return res;
}
case acc_cond::acc_op::Or:
{
--pos;
acc_cond::acc_code res = acc.fin(0); // f
do
{
auto tmp = strip(acc, pos, useless);
tmp.append_or(std::move(res));
std::swap(tmp, res);
pos -= pos->size + 1;
}
while (pos > start);
return res;
}
case acc_cond::acc_op::Fin:
if (pos[-1].mark & useless)
return acc.inf(0U); // t
return acc.fin(acc.strip(pos[-1].mark, useless));
case acc_cond::acc_op::Inf:
if (pos[-1].mark & useless)
return acc.fin(0U); // f
return acc.inf(acc.strip(pos[-1].mark, useless));
case acc_cond::acc_op::FinNeg:
case acc_cond::acc_op::InfNeg:
SPOT_UNREACHABLE();
return acc_cond::acc_code{};
}
SPOT_UNREACHABLE();
return acc_cond::acc_code{};
}
}
void cleanup_acceptance(tgba_digraph_ptr& aut)
{
auto& acc = aut->acc();
@ -83,29 +28,7 @@ namespace spot
return;
auto& c = aut->get_acceptance();
acc_cond::mark_t used_in_cond = 0U;
if (!c.is_true())
{
auto pos = &c.back();
auto end = &c.front();
while (pos > end)
{
switch (pos->op)
{
case acc_cond::acc_op::And:
case acc_cond::acc_op::Or:
--pos;
break;
case acc_cond::acc_op::Fin:
case acc_cond::acc_op::Inf:
case acc_cond::acc_op::FinNeg:
case acc_cond::acc_op::InfNeg:
used_in_cond |= pos[-1].mark;
pos -= 2;
break;
}
}
}
acc_cond::mark_t used_in_cond = c.used_sets();
acc_cond::mark_t used_in_aut = 0U;
for (auto& t: aut->transitions())
@ -120,16 +43,10 @@ namespace spot
// Remove useless marks from the automaton
for (auto& t: aut->transitions())
t.acc = acc.strip(t.acc, useless);
t.acc = t.acc.strip(useless);
// Remove useless marks from the acceptance condition
acc_cond::acc_code newc;
if (c.is_true() || c.is_false())
newc = c;
else
newc = strip(acc, &c.back(), useless);
aut->set_acceptance(useful.count(), newc);
aut->set_acceptance(useful.count(), c.strip(useless, true));
}
}

View file

@ -24,14 +24,14 @@ namespace spot
tgba_digraph_ptr mask_acc_sets(const const_tgba_digraph_ptr& in,
acc_cond::mark_t to_remove)
{
auto& inacc = in->acc();
auto res = make_tgba_digraph(in->get_dict());
res->copy_ap_of(in);
res->prop_copy(in, { true, false, true, true });
unsigned na = inacc.num_sets();
unsigned na = in->acc().num_sets();
unsigned tr = to_remove.count();
assert(tr <= na);
res->set_generalized_buchi(na - tr);
res->set_acceptance(na - tr,
in->get_acceptance().strip(to_remove, false));
transform_accessible(in, res, [&](unsigned,
bdd& cond,
acc_cond::mark_t& acc,
@ -40,7 +40,7 @@ namespace spot
if (acc & to_remove)
cond = bddfalse;
else
acc = inacc.strip(acc, to_remove);
acc = acc.strip(to_remove);
});
return res;
}

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
// Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire
// de Recherche et Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -240,7 +240,7 @@ namespace spot
if (!this->si->is_accepting_scc(u))
acc = 0U;
else
acc = this->si->get_aut()->acc().strip(acc, strip_[u]);
acc = acc.strip(strip_[u]);
}
return filtered_trans{keep, cond, acc};
}