From 3d1ccdc45ed12b8609ccc831042077aaff203e26 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Thu, 14 May 2015 13:21:09 +0200 Subject: [PATCH] autfilt: new --separate-sets option * src/twaalgos/sepsets.cc, src/twaalgos/sepsets.hh: New files. * src/twaalgos/Makefile.am: Add them. * src/twa/acc.hh (get_acceptance): Add a non-const version. * src/bin/autfilt.cc: Add the --separate-sets option. * src/tests/sepsets.test: New file. * src/tests/Makefile.am: Add it. --- src/bin/autfilt.cc | 12 ++++- src/tests/Makefile.am | 1 + src/tests/sepsets.test | 66 +++++++++++++++++++++++++ src/twa/acc.hh | 5 ++ src/twaalgos/Makefile.am | 2 + src/twaalgos/sepsets.cc | 101 +++++++++++++++++++++++++++++++++++++++ src/twaalgos/sepsets.hh | 36 ++++++++++++++ 7 files changed, 222 insertions(+), 1 deletion(-) create mode 100755 src/tests/sepsets.test create mode 100644 src/twaalgos/sepsets.cc create mode 100644 src/twaalgos/sepsets.hh diff --git a/src/bin/autfilt.cc b/src/bin/autfilt.cc index 33a3065a4..3da677203 100644 --- a/src/bin/autfilt.cc +++ b/src/bin/autfilt.cc @@ -51,6 +51,7 @@ #include "twaalgos/canonicalize.hh" #include "twaalgos/mask.hh" #include "twaalgos/sbacc.hh" +#include "twaalgos/sepsets.hh" #include "twaalgos/stripacc.hh" #include "twaalgos/remfin.hh" #include "twaalgos/cleanacc.hh" @@ -93,6 +94,7 @@ enum { OPT_REM_FIN, OPT_SBACC, OPT_SEED, + OPT_SEP_SETS, OPT_SIMPLIFY_EXCLUSIVE_AP, OPT_STATES, OPT_STRIPACC, @@ -167,7 +169,9 @@ static const argp_option options[] = { "remove-dead-states", OPT_REM_DEAD, 0, 0, "remove states that are unreachable, or that cannot belong to an " "infinite path", 0 }, - /**************************************************/ + { "separate-sets", OPT_SEP_SETS, 0, 0, + "if both Inf(x) and Fin(x) appear in the acceptance condition, replace " + "Fin(x) by a new Fin(y) and adjust the automaton", 0 }, { 0, 0, 0, 0, "Filtering options:", 6 }, { "are-isomorphic", OPT_ARE_ISOMORPHIC, "FILENAME", 0, "keep automata that are isomorphic to the automaton in FILENAME", 0 }, @@ -262,6 +266,7 @@ static spot::remove_ap rem_ap; static bool opt_simplify_exclusive_ap = false; static bool opt_rem_dead = false; static bool opt_rem_unreach = false; +static bool opt_sep_sets = false; static int parse_opt(int key, char* arg, struct argp_state*) @@ -438,6 +443,9 @@ parse_opt(int key, char* arg, struct argp_state*) case OPT_SEED: opt_seed = to_int(arg); break; + case OPT_SEP_SETS: + opt_sep_sets = true; + break; case OPT_SIMPLIFY_EXCLUSIVE_AP: opt_simplify_exclusive_ap = true; opt_merge = true; @@ -507,6 +515,8 @@ namespace aut->merge_transitions(); if (opt_clean_acc || opt_rem_fin) cleanup_acceptance_here(aut); + if (opt_sep_sets) + separate_sets_here(aut); if (opt_complement_acc) aut->set_acceptance(aut->acc().num_sets(), aut->get_acceptance().complement()); diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 31527fffc..543fe6548 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -204,6 +204,7 @@ TESTS_twa = \ scc.test \ sccdot.test \ sccsimpl.test \ + sepsets.test \ dbacomp.test \ obligation.test \ wdba.test \ diff --git a/src/tests/sepsets.test b/src/tests/sepsets.test new file mode 100755 index 000000000..457e502e0 --- /dev/null +++ b/src/tests/sepsets.test @@ -0,0 +1,66 @@ +#!/bin/sh +# -*- coding: utf-8 -*- +# Copyright (C) 2015 Laboratoire de Recherche et Développement de +# l'Epita (LRDE). +# +# 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 . + +. ./defs + +cat >in <expected < out +diff out expected diff --git a/src/twa/acc.hh b/src/twa/acc.hh index 879e03e94..d759af105 100644 --- a/src/twa/acc.hh +++ b/src/twa/acc.hh @@ -744,6 +744,11 @@ namespace spot return code_; } + acc_code& get_acceptance() + { + return code_; + } + bool uses_fin_acceptance() const { return uses_fin_acceptance_; diff --git a/src/twaalgos/Makefile.am b/src/twaalgos/Makefile.am index ee8317328..b7c51bdd3 100644 --- a/src/twaalgos/Makefile.am +++ b/src/twaalgos/Makefile.am @@ -73,6 +73,7 @@ twaalgos_HEADERS = \ scc.hh \ sccinfo.hh \ se05.hh \ + sepsets.hh \ simulation.hh \ stats.hh \ stripacc.hh \ @@ -130,6 +131,7 @@ libtwaalgos_la_SOURCES = \ sccinfo.cc \ sccfilter.cc \ se05.cc \ + sepsets.cc \ simulation.cc \ stats.cc \ stripacc.cc \ diff --git a/src/twaalgos/sepsets.cc b/src/twaalgos/sepsets.cc new file mode 100644 index 000000000..e9d9051c0 --- /dev/null +++ b/src/twaalgos/sepsets.cc @@ -0,0 +1,101 @@ +// -*- 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 . + +#include "sepsets.hh" +#include "sccinfo.hh" + + +namespace spot +{ + namespace + { + static acc_cond::mark_t common_sets(const const_twa_graph_ptr& aut) + { + auto p = aut->get_acceptance().used_inf_fin_sets(); + return p.first & p.second; + } + } + + bool has_separate_sets(const const_twa_graph_ptr& aut) + { + return common_sets(aut) == 0U; + } + + twa_graph_ptr + separate_sets_here(const twa_graph_ptr& aut) + { + auto common = common_sets(aut); + if (common == 0U) + return aut; + // Each Fin(first) should be replaced by Fin(second). + std::vector> map; + { + unsigned base = aut->acc().add_sets(common.count()); + for (auto s: common.sets()) + map.emplace_back(acc_cond::mark_t({s}), + acc_cond::mark_t({base++})); + } + + // Fix the acceptance condition + auto& code = aut->acc().get_acceptance(); + // If code were empty, then common would have been 0. + assert (!code.empty()); + acc_cond::acc_word* pos = &code.back(); + acc_cond::acc_word* start = &code.front(); + while (pos > start) + { + switch (pos->op) + { + case acc_cond::acc_op::Or: + case acc_cond::acc_op::And: + --pos; + break; + case acc_cond::acc_op::Fin: + case acc_cond::acc_op::FinNeg: + if ((pos[-1].mark & common) == 0U) + break; + for (auto p: map) + if (pos[-1].mark & p.first) + { + pos[-1].mark -= p.first; + pos[-1].mark |= p.second; + } + /* fall through */ + case acc_cond::acc_op::Inf: + case acc_cond::acc_op::InfNeg: + pos -= 2; + break; + } + } + + // Fix the transitions + for (auto& t: aut->transitions()) + { + if ((t.acc & common) == 0U) + continue; + for (auto p: map) + if (t.acc & p.first) + t.acc |= p.second; + } + return aut; + } + + + +} diff --git a/src/twaalgos/sepsets.hh b/src/twaalgos/sepsets.hh new file mode 100644 index 000000000..334f7d489 --- /dev/null +++ b/src/twaalgos/sepsets.hh @@ -0,0 +1,36 @@ +// -*- 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 . + +#pragma once + +#include "twa/twagraph.hh" + +namespace spot +{ + /// \brief Whether the Inf and Fin numbers are disjoints + SPOT_API bool + has_separate_sets(const const_twa_graph_ptr& aut); + + /// \brief Separate the Fin and Inf sets used by an automaton + /// + /// This makes sure that the numbers used a Fin and Inf are + /// disjoints. + SPOT_API twa_graph_ptr + separate_sets_here(const twa_graph_ptr& aut); +}