Add a cleanup_acceptance() algorithm
* src/tgbaalgos/cleanacc.cc, src/tgbaalgos/cleanacc.hh: New file. * src/tgbaalgos/Makefile.am: Add them. * src/tgba/acc.hh, src/tgba/tgba.hh (get_acceptance): Return a reference. * src/bin/autfilt.cc: Add a --cleanup-acceptance option. * src/tgbatest/hoaparse.test: Test it.
This commit is contained in:
parent
85508a0ea6
commit
659107a000
7 changed files with 226 additions and 47 deletions
|
|
@ -50,6 +50,7 @@
|
||||||
#include "tgbaalgos/sbacc.hh"
|
#include "tgbaalgos/sbacc.hh"
|
||||||
#include "tgbaalgos/stripacc.hh"
|
#include "tgbaalgos/stripacc.hh"
|
||||||
#include "tgbaalgos/remfin.hh"
|
#include "tgbaalgos/remfin.hh"
|
||||||
|
#include "tgbaalgos/cleanacc.hh"
|
||||||
|
|
||||||
|
|
||||||
static const char argp_program_doc[] ="\
|
static const char argp_program_doc[] ="\
|
||||||
|
|
@ -82,6 +83,7 @@ Exit status:\n\
|
||||||
#define OPT_KEEP_STATES 20
|
#define OPT_KEEP_STATES 20
|
||||||
#define OPT_DNF_ACC 21
|
#define OPT_DNF_ACC 21
|
||||||
#define OPT_REM_FIN 22
|
#define OPT_REM_FIN 22
|
||||||
|
#define OPT_CLEAN_ACC 23
|
||||||
|
|
||||||
static const argp_option options[] =
|
static const argp_option options[] =
|
||||||
{
|
{
|
||||||
|
|
@ -125,6 +127,8 @@ static const argp_option options[] =
|
||||||
"put the acceptance condition in Disjunctive Normal Form", 0 },
|
"put the acceptance condition in Disjunctive Normal Form", 0 },
|
||||||
{ "remove-fin", OPT_REM_FIN, 0, 0,
|
{ "remove-fin", OPT_REM_FIN, 0, 0,
|
||||||
"rewrite the automaton without using Fin acceptance", 0 },
|
"rewrite the automaton without using Fin acceptance", 0 },
|
||||||
|
{ "cleanup-acceptance", OPT_CLEAN_ACC, 0, 0,
|
||||||
|
"remove unused acceptance sets from the automaton", 0 },
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ 0, 0, 0, 0, "Filtering options:", 6 },
|
{ 0, 0, 0, 0, "Filtering options:", 6 },
|
||||||
{ "are-isomorphic", OPT_ARE_ISOMORPHIC, "FILENAME", 0,
|
{ "are-isomorphic", OPT_ARE_ISOMORPHIC, "FILENAME", 0,
|
||||||
|
|
@ -206,6 +210,7 @@ static bool opt_sbacc = false;
|
||||||
static bool opt_stripacc = false;
|
static bool opt_stripacc = false;
|
||||||
static bool opt_dnf_acc = false;
|
static bool opt_dnf_acc = false;
|
||||||
static bool opt_rem_fin = false;
|
static bool opt_rem_fin = false;
|
||||||
|
static bool opt_clean_acc = false;
|
||||||
static spot::acc_cond::mark_t opt_mask_acc = 0U;
|
static spot::acc_cond::mark_t opt_mask_acc = 0U;
|
||||||
static std::vector<bool> opt_keep_states = {};
|
static std::vector<bool> opt_keep_states = {};
|
||||||
static unsigned int opt_keep_states_initial = 0;
|
static unsigned int opt_keep_states_initial = 0;
|
||||||
|
|
@ -251,6 +256,9 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
case OPT_ARE_ISOMORPHIC:
|
case OPT_ARE_ISOMORPHIC:
|
||||||
opt->are_isomorphic = read_automaton(arg, opt->dict);
|
opt->are_isomorphic = read_automaton(arg, opt->dict);
|
||||||
break;
|
break;
|
||||||
|
case OPT_CLEAN_ACC:
|
||||||
|
opt_clean_acc = true;
|
||||||
|
break;
|
||||||
case OPT_EDGES:
|
case OPT_EDGES:
|
||||||
opt_edges = parse_range(arg, 0, std::numeric_limits<int>::max());
|
opt_edges = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||||
break;
|
break;
|
||||||
|
|
@ -421,6 +429,8 @@ namespace
|
||||||
if (opt_dnf_acc)
|
if (opt_dnf_acc)
|
||||||
aut->set_acceptance(aut->acc().num_sets(),
|
aut->set_acceptance(aut->acc().num_sets(),
|
||||||
aut->get_acceptance().to_dnf());
|
aut->get_acceptance().to_dnf());
|
||||||
|
if (opt_clean_acc && !opt_rem_fin)
|
||||||
|
cleanup_acceptance(aut);
|
||||||
if (opt_rem_fin)
|
if (opt_rem_fin)
|
||||||
aut = remove_fin(aut);
|
aut = remove_fin(aut);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -585,7 +585,7 @@ namespace spot
|
||||||
uses_fin_acceptance_ = check_fin_acceptance();
|
uses_fin_acceptance_ = check_fin_acceptance();
|
||||||
}
|
}
|
||||||
|
|
||||||
acc_code get_acceptance() const
|
const acc_code& get_acceptance() const
|
||||||
{
|
{
|
||||||
return code_;
|
return code_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,7 @@ namespace spot
|
||||||
acc_cond acc_;
|
acc_cond acc_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
acc_cond::acc_code get_acceptance() const
|
const acc_cond::acc_code& get_acceptance() const
|
||||||
{
|
{
|
||||||
return acc_.get_acceptance();
|
return acc_.get_acceptance();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ tgbaalgos_HEADERS = \
|
||||||
are_isomorphic.hh \
|
are_isomorphic.hh \
|
||||||
bfssteps.hh \
|
bfssteps.hh \
|
||||||
canonicalize.hh \
|
canonicalize.hh \
|
||||||
|
cleanacc.hh \
|
||||||
complete.hh \
|
complete.hh \
|
||||||
compsusp.hh \
|
compsusp.hh \
|
||||||
cycles.hh \
|
cycles.hh \
|
||||||
|
|
@ -84,6 +85,7 @@ libtgbaalgos_la_SOURCES = \
|
||||||
are_isomorphic.cc \
|
are_isomorphic.cc \
|
||||||
bfssteps.cc \
|
bfssteps.cc \
|
||||||
canonicalize.cc \
|
canonicalize.cc \
|
||||||
|
cleanacc.cc \
|
||||||
complete.cc \
|
complete.cc \
|
||||||
compsusp.cc \
|
compsusp.cc \
|
||||||
cycles.cc \
|
cycles.cc \
|
||||||
|
|
|
||||||
135
src/tgbaalgos/cleanacc.cc
Normal file
135
src/tgbaalgos/cleanacc.cc
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2015 Laboratoire de Recherche et Développement
|
||||||
|
// de l'Epita.
|
||||||
|
//
|
||||||
|
// This file is part of Spot, a model checking library.
|
||||||
|
//
|
||||||
|
// Spot is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
// License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "tgbaalgos/cleanacc.hh"
|
||||||
|
|
||||||
|
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();
|
||||||
|
if (acc.num_sets() == 0)
|
||||||
|
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_aut = 0U;
|
||||||
|
for (auto& t: aut->transitions())
|
||||||
|
used_in_aut |= t.acc;
|
||||||
|
|
||||||
|
auto useful = used_in_aut & used_in_cond;
|
||||||
|
|
||||||
|
auto useless = acc.comp(useful);
|
||||||
|
|
||||||
|
if (!useless)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove useless marks from the automaton
|
||||||
|
for (auto& t: aut->transitions())
|
||||||
|
t.acc = acc.strip(t.acc, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
32
src/tgbaalgos/cleanacc.hh
Normal file
32
src/tgbaalgos/cleanacc.hh
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2015 Laboratoire de Recherche et Développement
|
||||||
|
// de l'Epita.
|
||||||
|
//
|
||||||
|
// This file is part of Spot, a model checking library.
|
||||||
|
//
|
||||||
|
// Spot is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
// License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef SPOT_TGBAALGOS_CLEANACC_HH
|
||||||
|
# define SPOT_TGBAALGOS_CLEANACC_HH
|
||||||
|
|
||||||
|
#include "tgba/tgbagraph.hh"
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
/// \brief Remove useless acceptance sets
|
||||||
|
SPOT_API void
|
||||||
|
cleanup_acceptance(tgba_digraph_ptr& aut);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SPOT_TGBAALGOS_CLEANACC_HH
|
||||||
|
|
@ -1394,48 +1394,48 @@ State: 0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
||||||
# FIXME: Test removal of useless acceptance sets
|
# Test removal of useless acceptance sets
|
||||||
#
|
|
||||||
# # The mapping of acceptance sets for the second automaton is
|
# The mapping of acceptance sets for the second automaton is
|
||||||
# # input -> output
|
# input -> output
|
||||||
# # 0 -> 0
|
# 0 -> 0
|
||||||
# # 1 -> removed
|
# 1 -> removed
|
||||||
# # 2 -> 1
|
# 2 -> 1
|
||||||
# # 3 -> removed
|
# 3 -> removed
|
||||||
# # 4 -> 2
|
# 4 -> 2
|
||||||
# # !2 -> 3
|
# !2 -> 3
|
||||||
# expectok input <<EOF
|
expectok input --cleanup-acc <<EOF
|
||||||
# HOA: v1
|
HOA: v1
|
||||||
# name: "TGBA for Fa"
|
name: "TGBA for Fa"
|
||||||
# States: 2
|
States: 2
|
||||||
# Start: 0
|
Start: 0
|
||||||
# AP: 1 "a"
|
AP: 1 "a"
|
||||||
# acc-name: all
|
acc-name: all
|
||||||
# Acceptance: 0 t
|
Acceptance: 0 t
|
||||||
# properties: trans-labels explicit-labels state-acc complete deterministic
|
properties: trans-labels explicit-labels state-acc complete deterministic
|
||||||
# --BODY--
|
--BODY--
|
||||||
# State: 0 "F(a)"
|
State: 0 "F(a)"
|
||||||
# [0] 1
|
[0] 1
|
||||||
# [!0] 0
|
[!0] 0
|
||||||
# State: 1 "t"
|
State: 1 "t"
|
||||||
# [t] 1
|
[t] 1
|
||||||
# --END--
|
--END--
|
||||||
# HOA: v1
|
HOA: v1
|
||||||
# States: 1
|
States: 1
|
||||||
# Start: 0
|
Start: 0
|
||||||
# AP: 3 "a" "b" "c"
|
AP: 3 "a" "b" "c"
|
||||||
# acc-name: generalized-Buchi 4
|
acc-name: generalized-Buchi 4
|
||||||
# Acceptance: 4 Inf(0)&Inf(1)&Inf(2)&Inf(3)
|
Acceptance: 4 Inf(0)&Inf(1)&Inf(2)&Inf(3)
|
||||||
# properties: trans-labels explicit-labels trans-acc complete deterministic
|
properties: trans-labels explicit-labels trans-acc complete deterministic
|
||||||
# --BODY--
|
--BODY--
|
||||||
# State: 0
|
State: 0
|
||||||
# [0&1&2] 0 {0 1 2}
|
[0&1&2] 0 {0 1 2}
|
||||||
# [!0&1&2] 0 {1 2}
|
[!0&1&2] 0 {1 2}
|
||||||
# [0&!1&2] 0 {0 1}
|
[0&!1&2] 0 {0 1}
|
||||||
# [!0&!1&2] 0 {1}
|
[!0&!1&2] 0 {1}
|
||||||
# [0&1&!2] 0 {0 2 3}
|
[0&1&!2] 0 {0 2 3}
|
||||||
# [!0&1&!2] 0 {2 3}
|
[!0&1&!2] 0 {2 3}
|
||||||
# [0&!1&!2] 0 {0 3}
|
[0&!1&!2] 0 {0 3}
|
||||||
# [!0&!1&!2] 0 {3}
|
[!0&!1&!2] 0 {3}
|
||||||
# --END--
|
--END--
|
||||||
# EOF
|
EOF
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue