Commit c717b588 authored by Antoine Martin's avatar Antoine Martin

implement NCSB complementation

* spot/twaalgos/isdet.cc,spot/twaalgos/isdet.hh: Two new functions to
highlight deterministic SCCs
* spot/twaalgos/complement.cc,spot/twaalgos/complement.hh:
Implementation of the NCSB complementation algorithm
* tests/Makefile.am, tests/python/complement_semidet.py: Test the
implementation
* NEWS: document function
parent 8d233692
Pipeline #2725 failed with stages
in 124 minutes and 55 seconds
......@@ -201,6 +201,12 @@ New in spot 2.5.3.dev (not yet released)
looking for differences. See also
https://spot.lrde.epita.fr/ipynb/contains.html
- spot::complement_semidet(aut) is a new function that returns the
complement of aut, where aut is a semideterministic automaton. The
function uses the NCSB complementation algorithm proposed by
F. Blahoudek, M. Heizmann, S. Schewe, J. Strejček, and MH. Tsai
(TACAS'16).
- spot::remove_alternation() was slightly improved on very-weak
alternating automata: the labeling of the outgoing transitions in
the resulting TGBA makes it more likely that simulation-based
......
This diff is collapsed.
......@@ -43,4 +43,13 @@ namespace spot
SPOT_DEPRECATED("use spot::dualize() instead")
SPOT_API twa_graph_ptr
dtwa_complement(const const_twa_graph_ptr& aut);
/// \brief Complement a semideterministic TωA
///
/// The automaton \a aut should be semideterministic.
///
/// Uses the NCSB algorithm described by F. Blahoudek, M. Heizmann,
/// S. Schewe, J. Strejček, and MH. Tsai (TACAS'16).
SPOT_API twa_graph_ptr
complement_semidet(const const_twa_graph_ptr& aut, bool show_names = false);
}
......@@ -138,6 +138,24 @@ namespace spot
aut->prop_universal(universal);
}
void highlight_semidet_sccs(scc_info& si, unsigned color)
{
auto det_sccs = semidet_sccs(si);
if (det_sccs.empty())
return;
auto aut = si.get_aut();
auto* highlight = std::const_pointer_cast<twa_graph>(aut)
->get_or_set_named_prop<std::map<unsigned, unsigned>>("highlight-states");
for (unsigned scc = 0; scc < si.scc_count(); scc++)
{
if (det_sccs[scc])
{
for (auto& t : si.states_of(scc))
(*highlight)[t] = color;
}
}
}
bool
is_complete(const const_twa_graph_ptr& aut)
{
......@@ -238,6 +256,49 @@ namespace spot
}
}
std::vector<bool> semidet_sccs(scc_info& si)
{
const_twa_graph_ptr aut = si.get_aut();
trival sd = aut->prop_semi_deterministic();
if (sd.is_known() && sd.is_false())
return std::vector<bool>();
si.determine_unknown_acceptance();
unsigned nscc = si.scc_count();
assert(nscc);
std::vector<bool> reachable_from_acc(nscc);
std::vector<bool> res(nscc);
bool semi_det = true;
do // iterator of SCCs in reverse topological order
{
--nscc;
if (si.is_accepting_scc(nscc) || reachable_from_acc[nscc])
{
for (unsigned succ: si.succ(nscc))
reachable_from_acc[succ] = true;
for (unsigned src: si.states_of(nscc))
{
bdd available = bddtrue;
for (auto& t: aut->out(src))
if (!bdd_implies(t.cond, available))
{
semi_det = false;
goto done;
}
else
{
available -= t.cond;
}
}
res[nscc] = true;
}
}
while (nscc);
done:
if (!semi_det)
return std::vector<bool>();
return res;
}
bool
is_semi_deterministic(const const_twa_graph_ptr& aut)
{
......
......@@ -19,6 +19,7 @@
#pragma once
#include <spot/twaalgos/sccinfo.hh>
#include <spot/twa/twagraph.hh>
namespace spot
......@@ -77,6 +78,16 @@ namespace spot
highlight_nondet_edges(twa_graph_ptr& aut, unsigned color);
/// @}
/// \brief Highlight the deterministic part of the automaton
///
/// In the case of a semideterministic automaton, highlights the
/// states reachable from any accepting SCC.
///
/// \param aut the automaton to process
/// \param color the color to give to states reachable from accepting SCCs.
SPOT_API void
highlight_semidet_sccs(scc_info& si, unsigned color);
/// \brief Return true iff \a aut is complete.
///
/// An automaton is complete if its translation relation is total,
......@@ -91,6 +102,10 @@ namespace spot
SPOT_API bool
is_semi_deterministic(const const_twa_graph_ptr& aut);
/// \brief Whether an SCC is in the deterministic part of an automaton
SPOT_API std::vector<bool>
semidet_sccs(scc_info& si);
/// \brief Set the deterministic and semi-deterministic properties
/// appropriately.
SPOT_API void check_determinism(twa_graph_ptr aut);
......
......@@ -366,6 +366,7 @@ TESTS_python = \
python/bdditer.py \
python/bddnqueen.py \
python/bugdet.py \
python/complement_semidet.py \
python/declenv.py \
python/_word.ipynb \
python/decompose_scc.py \
......
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
import spot
import buddy
def complement(aut):
return spot.dualize(aut.postprocess('det', 'gen'))
n = 10000
for aut in spot.automata(
"randltl -n-1 a b "
"| ltl2tgba "
"| autfilt --is-semi-deterministic --acceptance-is=Buchi -n{} |"
.format(n)):
comp = complement(aut)
semidet_comp = spot.complement_semidet(aut, True)
assert(comp.equivalent_to(semidet_comp))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment