complement: add a complement() function

* spot/twaalgos/complement.cc,
spot/twaalgos/complement.hh (complement): New function.
* bin/autfilt.cc, spot/twa/twa.cc, spot/twaalgos/contains.cc,
spot/twaalgos/powerset.cc, spot/twaalgos/stutter.cc: Use it.
* tests/core/complement.test: Adjust.
* NEWS: Mention it.
This commit is contained in:
Alexandre Duret-Lutz 2019-04-05 22:23:02 +02:00
parent 4bb4aeb372
commit 948f99bc4e
9 changed files with 82 additions and 86 deletions

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2015, 2017-2018 Laboratoire de Recherche et
// Copyright (C) 2013-2015, 2017-2019 Laboratoire de Recherche et
// Développement de l'Epita.
//
// This file is part of Spot, a model checking library.
@ -23,6 +23,9 @@
#include <spot/twaalgos/complement.hh>
#include <spot/twaalgos/dualize.hh>
#include <spot/twaalgos/isdet.hh>
#include <spot/twaalgos/alternation.hh>
#include <spot/twaalgos/postproc.hh>
#include <spot/twaalgos/strength.hh>
#include <spot/twaalgos/sccinfo.hh>
namespace spot
@ -506,4 +509,19 @@ namespace spot
auto ncsb = ncsb_complementation(aut, show_names);
return ncsb.run();
}
twa_graph_ptr
complement(const const_twa_graph_ptr& aut)
{
if (!aut->is_existential() || is_universal(aut))
return dualize(aut);
if (is_very_weak_automaton(aut))
return remove_alternation(dualize(aut));
// Determinize
spot::postprocessor p;
p.set_type(spot::postprocessor::Generic);
p.set_pref(spot::postprocessor::Deterministic);
p.set_level(spot::postprocessor::Low);
return dualize(p.run(std::const_pointer_cast<twa_graph>(aut)));
}
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013-2015, 2017 Laboratoire de Recherche et
// Copyright (C) 2013-2015, 2017, 2019 Laboratoire de Recherche et
// Développement de l'Epita.
//
// This file is part of Spot, a model checking library.
@ -52,4 +52,26 @@ namespace spot
/// 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);
/// \brief Complement a TωA
///
/// This employs different complementation strategies depending
/// on the type of the automaton.
///
/// If the input is alternating, the output may be alternating and
/// is simply the result of calling dualize().
///
/// If the input is not alternating, the output will not be
/// alternating, but could have any acceptance condition.
/// - deterministic inputs are passed to dualize()
/// - very weak automata are also dualized, and then
/// passed to remove_alternation() to obtain a TGBA
/// - any other type of input is determized before
/// complementation.
///
/// complement_semidet() is not yet used.
SPOT_API twa_graph_ptr
complement(const const_twa_graph_ptr& aut);
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2018 Laboratoire de Recherche et Développement de
// Copyright (C) 2018, 2019 Laboratoire de Recherche et Développement de
// l'Epita.
//
// This file is part of Spot, a model checking library.
@ -19,27 +19,14 @@
#include "config.h"
#include <spot/twaalgos/contains.hh>
#include <spot/twaalgos/postproc.hh>
#include <spot/twaalgos/complement.hh>
#include <spot/twaalgos/ltl2tgba_fm.hh>
#include <spot/twaalgos/isdet.hh>
#include <spot/twaalgos/dualize.hh>
namespace spot
{
namespace
{
static spot::const_twa_graph_ptr
ensure_deterministic(const spot::const_twa_graph_ptr& aut)
{
if (spot::is_deterministic(aut))
return aut;
spot::postprocessor p;
p.set_type(spot::postprocessor::Generic);
p.set_pref(spot::postprocessor::Deterministic);
p.set_level(spot::postprocessor::Low);
return p.run(std::const_pointer_cast<twa_graph>(aut));
}
static spot::const_twa_graph_ptr
translate(formula f, const bdd_dict_ptr& dict)
{
@ -49,25 +36,22 @@ namespace spot
bool contains(const_twa_graph_ptr left, const_twa_graph_ptr right)
{
return !right->intersects(dualize(ensure_deterministic(left)));
return !complement(left)->intersects(right);
}
bool contains(const_twa_graph_ptr left, formula right)
{
auto right_aut = translate(right, left->get_dict());
return !right_aut->intersects(dualize(ensure_deterministic(left)));
return contains(left, translate(right, left->get_dict()));
}
bool contains(formula left, const_twa_graph_ptr right)
{
return !right->intersects(translate(formula::Not(left), right->get_dict()));
return !translate(formula::Not(left), right->get_dict())->intersects(right);
}
bool contains(formula left, formula right)
{
auto dict = make_bdd_dict();
auto right_aut = translate(right, dict);
return !right_aut->intersects(translate(formula::Not(left), dict));
return contains(left, translate(right, make_bdd_dict()));
}
bool are_equivalent(const_twa_graph_ptr left, const_twa_graph_ptr right)

View file

@ -463,12 +463,9 @@ namespace spot
neg_aut = scc_filter(neg_aut, true);
}
if (product(det, neg_aut)->is_empty())
// Complement the DBA.
if (product(aut, remove_fin(dualize(det)))->is_empty())
// Finally, we are now sure that it was safe
// to determinize the automaton.
return det;
if (!det->intersects(neg_aut) && !aut->intersects(dualize(det)))
// Determinization was safe.
return det;
return aut;
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014-2018 Laboratoire de Recherche et Développement de
// Copyright (C) 2014-2019 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -28,9 +28,8 @@
#include <spot/twaalgos/product.hh>
#include <spot/twaalgos/ltl2tgba_fm.hh>
#include <spot/twaalgos/isdet.hh>
#include <spot/twaalgos/dualize.hh>
#include <spot/twaalgos/complement.hh>
#include <spot/twaalgos/remfin.hh>
#include <spot/twaalgos/postproc.hh>
#include <spot/twaalgos/sccinfo.hh>
#include <spot/twa/twaproduct.hh>
#include <spot/twa/bddprint.hh>
@ -602,16 +601,7 @@ namespace spot
bool own_nf = false;
if (!aut_nf)
{
twa_graph_ptr tmp = aut_f;
if (!is_deterministic(aut_f))
{
spot::postprocessor p;
p.set_type(spot::postprocessor::Generic);
p.set_pref(spot::postprocessor::Deterministic);
p.set_level(spot::postprocessor::Low);
tmp = p.run(aut_f);
}
aut_nf = dualize(std::move(tmp));
aut_nf = complement(aut_f);
own_nf = true;
}
bool res = do_si_check(aut_f, own_f,
@ -709,13 +699,7 @@ namespace spot
return res;
if (neg == nullptr)
{
spot::postprocessor p;
p.set_type(spot::postprocessor::Generic);
p.set_pref(spot::postprocessor::Deterministic);
p.set_level(spot::postprocessor::Low);
neg = dualize(p.run(std::const_pointer_cast<twa_graph>(pos)));
}
neg = complement(pos);
auto product_states = [](const const_twa_graph_ptr& a)
{
@ -782,13 +766,7 @@ namespace spot
return res;
if (neg == nullptr)
{
spot::postprocessor p;
p.set_type(spot::postprocessor::Generic);
p.set_pref(spot::postprocessor::Deterministic);
p.set_level(spot::postprocessor::Low);
neg = dualize(p.run(std::const_pointer_cast<twa_graph>(pos)));
}
neg = complement(pos);
auto product_states = [](const const_twa_graph_ptr& a)
{