176 lines
5.9 KiB
C++
176 lines
5.9 KiB
C++
// -*- coding: utf-8 -*-
|
|
// Copyright (C) by the Spot authors, see the AUTHORS file for details.
|
|
//
|
|
// 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/>.
|
|
|
|
#pragma once
|
|
|
|
#include <spot/twa/twagraph.hh>
|
|
#include <spot/twaalgos/powerset.hh>
|
|
#include <utility>
|
|
|
|
namespace spot
|
|
{
|
|
/// \brief Helper class combine outgoing edges in alternating
|
|
/// automata
|
|
///
|
|
/// The idea is that you can call the operator() on some state to get an
|
|
/// BDD representation of its outgoing edges (labels and
|
|
/// destinations, but not acceptance marks). The BDD representation
|
|
/// of different states can combined using & or | to build a new
|
|
/// representation of some outgoing edges that can be attached to
|
|
/// some state with new_dests. The use of BDDs helps removing
|
|
/// superfluous edges.
|
|
///
|
|
/// Beware that new_dests() just *appends* the transitions to the
|
|
/// supplied state, it does not remove existing ones.
|
|
///
|
|
/// operator() can be called on states with universal branching
|
|
/// (that's actually the point), and can be called on state number
|
|
/// that designate groups of destination states (in that case the
|
|
/// conjunction of all those states are taken).
|
|
class SPOT_API outedge_combiner
|
|
{
|
|
private:
|
|
const twa_graph_ptr& aut_;
|
|
std::map<unsigned, int> state_to_var;
|
|
std::map<int, unsigned> var_to_state;
|
|
bdd vars_;
|
|
unsigned acc_sink_;
|
|
public:
|
|
outedge_combiner(const twa_graph_ptr& aut, unsigned sink = -1u);
|
|
~outedge_combiner();
|
|
bdd operator()(unsigned st, const std::vector<unsigned>& dst_filter = std::vector<unsigned>(),
|
|
bool remove_original_edges = false);
|
|
void new_dests(unsigned st, bdd out) const;
|
|
};
|
|
|
|
/// @{
|
|
/// \brief Combine two states in a conjunction.
|
|
///
|
|
/// This creates a new state whose outgoing transitions are the
|
|
/// conjunctions of the compatible transitions of s1 and s2.
|
|
///
|
|
/// Acceptance marks are dropped.
|
|
///
|
|
/// The results is very likely to be alternating.
|
|
/// @}
|
|
template<class I>
|
|
SPOT_API
|
|
unsigned states_and(const twa_graph_ptr& aut, I begin, I end)
|
|
{
|
|
if (begin == end)
|
|
throw std::runtime_error
|
|
("state_and() expects an non-empty list of states");
|
|
outedge_combiner combiner(aut);
|
|
bdd combination = bddtrue;
|
|
while (begin != end)
|
|
combination &= combiner(*begin++);
|
|
unsigned new_s = aut->new_state();
|
|
combiner.new_dests(new_s, combination);
|
|
return new_s;
|
|
}
|
|
|
|
template<class T>
|
|
SPOT_API
|
|
unsigned states_and(const twa_graph_ptr& aut,
|
|
const std::initializer_list<T>& il)
|
|
{
|
|
return states_and(aut, il.begin(), il.end());
|
|
}
|
|
/// @}
|
|
|
|
/// \brief Remove universal edges from an automaton.
|
|
///
|
|
/// This procedure is restricted to weak alternating automata as
|
|
/// input, and produces TGBAs as output. (Generalized Büchi
|
|
/// acceptance is only used in presence of size-1 rejecting-SCCs.)
|
|
///
|
|
/// \param named_states name each state for easier debugging
|
|
///
|
|
/// \param aborter Return nullptr if the built automaton would
|
|
/// be larger than the size specified by the \a aborter, or
|
|
/// if it would require too many acceptance sets.
|
|
///
|
|
/// \param raise_if_too_many_sets when set to false, return
|
|
/// nullptr in cases where we would need too many colors
|
|
/// @}
|
|
SPOT_API
|
|
twa_graph_ptr remove_alternation(const const_twa_graph_ptr& aut,
|
|
bool named_states = false,
|
|
const output_aborter* aborter = nullptr,
|
|
bool raise_if_too_many_sets = true);
|
|
|
|
|
|
// Remove universal edges on the fly.
|
|
|
|
class SPOT_API univ_remover_state: public state
|
|
{
|
|
protected:
|
|
std::set<unsigned> states_;
|
|
bool is_reset_;
|
|
|
|
public:
|
|
univ_remover_state(const std::set<unsigned>& states);
|
|
univ_remover_state(const univ_remover_state& other)
|
|
: states_(other.states_), is_reset_(other.is_reset_)
|
|
{
|
|
}
|
|
int compare(const state* other) const override;
|
|
size_t hash() const override;
|
|
state* clone() const override;
|
|
const std::set<unsigned>& states() const;
|
|
bool is_reset() const;
|
|
};
|
|
|
|
class SPOT_API twa_univ_remover: public twa
|
|
{
|
|
|
|
private:
|
|
const_twa_graph_ptr aut_;
|
|
std::vector<int> state_to_var_;
|
|
std::map<int, unsigned> var_to_state_;
|
|
bdd all_states_;
|
|
|
|
public:
|
|
twa_univ_remover(const const_twa_graph_ptr& aut);
|
|
void allocate_state_vars();
|
|
const state* get_init_state() const override;
|
|
twa_succ_iterator* succ_iter(const state* s) const override;
|
|
std::string format_state(const state* s) const override;
|
|
};
|
|
|
|
typedef std::shared_ptr<twa_univ_remover> twa_univ_remover_ptr;
|
|
|
|
/// \brief Remove universal edges on the fly from an automaton.
|
|
///
|
|
/// This function uses the Myiano & Hayashi (TCS 1984) breakpoint
|
|
/// algorithm to construct a non-deterministic Büchi automaton from an
|
|
/// alternating Büchi automaton on the fly.
|
|
///
|
|
/// \verbatim
|
|
/// @Article{ miyano.84.tcs,
|
|
/// title = "Alternating finite automata on ω-words",
|
|
/// journal = "Theoretical Computer Science",
|
|
/// volume = "32",
|
|
/// number = "3",
|
|
/// pages = "321 - 330",
|
|
/// year = "1984",
|
|
/// author = "Satoru Miyano and Takeshi Hayashi",
|
|
/// }
|
|
SPOT_API
|
|
twa_univ_remover_ptr remove_univ_otf(const const_twa_graph_ptr& aut);
|
|
}
|