* bin/README, bin/common_conv.hh, bin/common_trans.cc,
bin/ltlsynt.cc, bin/spot-x.cc, spot/gen/automata.hh,
spot/graph/graph.hh, spot/ltsmin/ltsmin.hh,
spot/ltsmin/spins_interface.hh, spot/ltsmin/spins_kripke.hh,
spot/mc/bloemen.hh, spot/mc/bloemen_ec.hh, spot/mc/cndfs.hh,
spot/mc/deadlock.hh, spot/mc/intersect.hh, spot/mc/lpar13.hh,
spot/mc/mc_instanciator.hh, spot/misc/bareword.cc,
spot/misc/fixpool.hh, spot/misc/formater.hh, spot/misc/minato.hh,
spot/misc/satsolver.hh, spot/misc/timer.hh,
spot/parseaut/public.hh, spot/priv/partitioned_relabel.cc,
spot/priv/satcommon.hh, spot/ta/ta.hh, spot/ta/taexplicit.cc,
spot/ta/taproduct.hh, spot/ta/tgta.hh, spot/taalgos/reachiter.hh,
spot/taalgos/tgba2ta.hh, spot/tl/apcollect.cc,
spot/tl/apcollect.hh, spot/tl/formula.cc, spot/tl/parse.hh,
spot/tl/randomltl.hh, spot/tl/relabel.hh, spot/tl/simplify.cc,
spot/twa/acc.hh, spot/twa/bddprint.hh, spot/twa/formula2bdd.cc,
spot/twa/twa.hh, spot/twa/twagraph.cc, spot/twa/twagraph.hh,
spot/twaalgos/aiger.cc, spot/twaalgos/aiger.hh,
spot/twaalgos/alternation.hh, spot/twaalgos/cleanacc.cc,
spot/twaalgos/cobuchi.cc, spot/twaalgos/contains.cc,
spot/twaalgos/couvreurnew.cc, spot/twaalgos/cycles.hh,
spot/twaalgos/degen.cc, spot/twaalgos/degen.hh,
spot/twaalgos/dot.hh, spot/twaalgos/dtbasat.cc,
spot/twaalgos/dtwasat.cc, spot/twaalgos/dtwasat.hh,
spot/twaalgos/dualize.cc, spot/twaalgos/emptiness.hh,
spot/twaalgos/emptiness_stats.hh, spot/twaalgos/game.cc,
spot/twaalgos/genem.hh, spot/twaalgos/hoa.hh,
spot/twaalgos/langmap.hh, spot/twaalgos/ltl2tgba_fm.hh,
spot/twaalgos/magic.cc, spot/twaalgos/magic.hh,
spot/twaalgos/mask.hh, spot/twaalgos/mealy_machine.cc,
spot/twaalgos/mealy_machine.hh,
spot/twaalgos/minimize.hh, spot/twaalgos/parity.cc,
spot/twaalgos/parity.hh, spot/twaalgos/postproc.cc,
spot/twaalgos/product.hh, spot/twaalgos/reachiter.hh,
spot/twaalgos/relabel.cc, spot/twaalgos/remfin.cc,
spot/twaalgos/remfin.hh, spot/twaalgos/sccfilter.cc,
spot/twaalgos/sccinfo.hh, spot/twaalgos/se05.cc,
spot/twaalgos/se05.hh, spot/twaalgos/simulation.hh,
spot/twaalgos/split.hh, spot/twaalgos/stats.hh,
spot/twaalgos/synthesis.cc, spot/twaalgos/synthesis.hh,
spot/twaalgos/tau03.hh, spot/twaalgos/tau03opt.hh,
spot/twaalgos/toparity.hh, spot/twaalgos/totgba.hh,
spot/twaalgos/translate.hh, spot/twaalgos/word.cc,
spot/twaalgos/word.hh, spot/twaalgos/zlktree.cc,
spot/twaalgos/zlktree.hh, spot/twacube/cube.hh,
spot/twacube/twacube.hh, tests/core/cube.cc,
tests/core/ltlsynt.test, tests/core/parity.cc,
tests/core/safra.cc, tests/core/twagraph.cc: here
549 lines
21 KiB
C++
549 lines
21 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 <iosfwd>
|
|
#include <spot/misc/common.hh>
|
|
#include <spot/misc/bddlt.hh>
|
|
#include <spot/twa/fwd.hh>
|
|
#include <spot/twa/bdddict.hh>
|
|
#include <spot/tl/formula.hh>
|
|
#include <spot/tl/apcollect.hh>
|
|
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
#include <set>
|
|
#include <memory>
|
|
#include <algorithm> // std::none_of
|
|
#include <sstream>
|
|
|
|
|
|
namespace spot
|
|
{
|
|
// Forward for synthesis
|
|
struct mealy_like;
|
|
|
|
class aig;
|
|
|
|
typedef std::shared_ptr<aig> aig_ptr;
|
|
typedef std::shared_ptr<const aig> const_aig_ptr;
|
|
|
|
/// \ingroup synthesis
|
|
/// \brief A class representing AIG circuits
|
|
///
|
|
/// AIG circuits consist of (named) inputs, (named) outputs, latches which
|
|
/// serve as memory, and gates and negations connecting them.
|
|
/// AIG circuits can be used to represent controllers, which is currently
|
|
/// their sole purpose within spot.
|
|
/// AIGs produce a output sequence based on the following rules:
|
|
/// 1) All latches are initialized to 0
|
|
/// 2) The next input is read.
|
|
/// 3) The output and the state of the latches for the next turn
|
|
/// are given by the gates as a function of the current latches and inputs
|
|
class SPOT_API aig
|
|
{
|
|
protected:
|
|
const unsigned num_inputs_;
|
|
const unsigned num_outputs_;
|
|
const unsigned num_latches_;
|
|
const std::vector<std::string> input_names_;
|
|
const std::vector<std::string> output_names_;
|
|
unsigned max_var_;
|
|
|
|
std::vector<unsigned> next_latches_;
|
|
std::vector<unsigned> outputs_;
|
|
std::vector<std::pair<unsigned, unsigned>> and_gates_;
|
|
bdd_dict_ptr dict_;
|
|
// Cache the function computed by each variable as a bdd.
|
|
// Bidirectional map
|
|
std::unordered_map<unsigned, bdd> var2bdd_;
|
|
std::unordered_map<int, unsigned> bdd2var_; //uses id
|
|
// First anonymous var marking the beginning of variables used
|
|
// as latches
|
|
int l0_;
|
|
|
|
bdd all_ins_;
|
|
bdd all_latches_;
|
|
|
|
// For simulation
|
|
std::vector<bool> state_;
|
|
|
|
public:
|
|
|
|
/// \brief Mark the beginning of a test translation
|
|
///
|
|
/// Sometimes different encodings produces more or less gates.
|
|
/// To improve performances, one can "safe" the current status
|
|
/// and revert changes afterwards if needed
|
|
using safe_point = std::pair<unsigned, unsigned>;
|
|
using safe_stash =
|
|
std::tuple<std::vector<std::pair<unsigned, unsigned>>,
|
|
std::vector<std::pair<unsigned, bdd>>,
|
|
std::vector<bdd>>;
|
|
|
|
/// \brief Constructing an "empty" aig, knowing only about the
|
|
/// necessary inputs, outputs and latches. A bdd_dict can
|
|
/// be handed to the circuit in order to allow for verification
|
|
/// against other automata after construction
|
|
aig(const std::vector<std::string>& inputs,
|
|
const std::vector<std::string>& outputs,
|
|
unsigned num_latches,
|
|
bdd_dict_ptr dict = make_bdd_dict());
|
|
|
|
/// \brief Constructing the circuit with generic names.
|
|
aig(unsigned num_inputs, unsigned num_outputs,
|
|
unsigned num_latches, bdd_dict_ptr dict = make_bdd_dict());
|
|
|
|
~aig()
|
|
{
|
|
dict_->unregister_all_my_variables(this);
|
|
}
|
|
|
|
protected:
|
|
/// \brief Register a new literal in both maps
|
|
void register_new_lit_(unsigned v, const bdd &b);
|
|
void register_latch_(unsigned i, const bdd& b);
|
|
void register_input_(unsigned i, const bdd& b);
|
|
/// \brief Remove a literal from both maps
|
|
void unregister_lit_(unsigned v);
|
|
|
|
/// \brief Internal function that split a bdd into a conjunction
|
|
/// hoping to increase reusage of gates
|
|
void split_cond_(const bdd& b, char so_mode,
|
|
std::vector<bdd>& cond_parts);
|
|
|
|
/// \brief Split-off common sub-expressions as cube
|
|
bdd accum_common_(const bdd& b) const;
|
|
|
|
/// Translate a cube into gates, using split-off optionally
|
|
unsigned cube2var_(const bdd& b, const int use_split_off);
|
|
|
|
public:
|
|
|
|
/// \brief Safe the current state of the circuit
|
|
/// \note This does not make a copy, so rolling back to
|
|
/// an older safe point invalidates all newer safepoints.
|
|
/// Also only concerns the gates, output and next_latch variables
|
|
/// will not change
|
|
/// This function is semi-public. Make sure you know what you are
|
|
/// doing when using it.
|
|
safe_point get_safe_point_() const;
|
|
|
|
/// \brief roll_back to the saved point.
|
|
///
|
|
/// \param sp The safe_point to revert back to
|
|
/// \param do_stash Whether or not to save the changes to be possibly
|
|
/// reapplied later on
|
|
/// \note This function is semi-public. Make sure you know what you are
|
|
/// doing when using it.
|
|
safe_stash roll_back_(safe_point sp,
|
|
bool do_stash = false);
|
|
/// \brief Reapply to stored changes on top of a safe_point
|
|
/// \note \a ss has to be obtained from `roll_back_(sp, true)`
|
|
/// This function is semi-public. Make sure you know what you are
|
|
/// doing when using it.
|
|
void reapply_(safe_point sp, const safe_stash& ss);
|
|
|
|
/// \brief Get the number of outputs
|
|
unsigned num_outputs() const
|
|
{
|
|
return num_outputs_;
|
|
}
|
|
/// \brief Get the variables associated to the outputs
|
|
/// \note Only available after a call to aig::set_output
|
|
const std::vector<unsigned>& outputs() const
|
|
{
|
|
SPOT_ASSERT(std::none_of(outputs_.begin(), outputs_.end(),
|
|
[](unsigned o){return o == -1u; }));
|
|
return outputs_;
|
|
}
|
|
|
|
/// \brief return the variable associated to output \a num
|
|
///
|
|
/// This will be equal to -1U if aig::set_output() hasn't been called.
|
|
unsigned output(unsigned num) const
|
|
{
|
|
return outputs_[num];
|
|
}
|
|
|
|
/// \brief Get the set of output names
|
|
const std::vector<std::string>& output_names() const
|
|
{
|
|
return output_names_;
|
|
}
|
|
|
|
/// \brief Get the number of inputs
|
|
unsigned num_inputs() const
|
|
{
|
|
return num_inputs_;
|
|
}
|
|
/// \brief Get the set of input names
|
|
const std::vector<std::string>& input_names() const
|
|
{
|
|
return input_names_;
|
|
}
|
|
|
|
/// \brief Get the number of latches in the circuit
|
|
unsigned num_latches() const
|
|
{
|
|
return num_latches_;
|
|
}
|
|
/// \brief Get the variables associated to the state of the latches
|
|
/// in the next iteration
|
|
/// \note Only available after call to aig::set_next_latch
|
|
const std::vector<unsigned>& next_latches() const
|
|
{
|
|
SPOT_ASSERT(std::none_of(next_latches_.begin(), next_latches_.end(),
|
|
[](unsigned o){return o == -1u; }));
|
|
return next_latches_;
|
|
};
|
|
|
|
/// \brief Get the total number of and gates
|
|
unsigned num_gates() const
|
|
{
|
|
return and_gates_.size();
|
|
};
|
|
/// \brief Access the underlying container
|
|
const std::vector<std::pair<unsigned, unsigned>>& gates() const
|
|
{
|
|
return and_gates_;
|
|
};
|
|
|
|
/// \brief Maximal variable index currently appearing in the circuit
|
|
unsigned max_var() const
|
|
{
|
|
return max_var_;
|
|
};
|
|
|
|
/// \brief Get the variable associated to the ith input
|
|
unsigned input_var(unsigned i, bool neg = false) const
|
|
{
|
|
SPOT_ASSERT(i < num_inputs_);
|
|
return (1 + i) * 2 + neg;
|
|
}
|
|
/// \brief Get the bdd associated to the ith input
|
|
bdd input_bdd(unsigned i, bool neg = false) const
|
|
{
|
|
return aigvar2bdd(input_var(i, neg));
|
|
}
|
|
|
|
/// \brief Get the variable associated to the ith latch
|
|
unsigned latch_var(unsigned i, bool neg = false) const
|
|
{
|
|
SPOT_ASSERT(i < num_latches_);
|
|
return (1 + num_inputs_ + i) * 2 + neg;
|
|
}
|
|
/// \brief Get the bdd associated to the ith latch
|
|
bdd latch_bdd(unsigned i, bool neg = false) const
|
|
{
|
|
return aigvar2bdd(latch_var(i, neg));
|
|
}
|
|
|
|
/// \brief Get the variable associated to the ith gate
|
|
unsigned gate_var(unsigned i, bool neg = false) const
|
|
{
|
|
SPOT_ASSERT(i < num_gates());
|
|
return (1 + num_inputs_ + num_latches_ + i) * 2 + neg;
|
|
}
|
|
/// \brief Get the bdd associated to the ith gate
|
|
bdd gate_bdd(unsigned i, bool neg = false) const
|
|
{
|
|
return aigvar2bdd(gate_var(i, neg));
|
|
}
|
|
|
|
/// \brief Get the bdd associated to a variable
|
|
/// \note Throws if non-existent
|
|
bdd aigvar2bdd(unsigned v, bool neg = false) const
|
|
{
|
|
return neg ? bdd_not(var2bdd_.at(v)) : var2bdd_.at(v);
|
|
}
|
|
|
|
/// \brief Get the variable associated to a bdd
|
|
/// \note Throws if non-existent
|
|
unsigned bdd2aigvar(const bdd& b) const
|
|
{
|
|
return bdd2var_.at(b.id());
|
|
}
|
|
|
|
/// \brief Add a bdd to the circuit using if-then-else normal form
|
|
unsigned bdd2INFvar(const bdd& b);
|
|
|
|
/// \brief Add a bdd to the circuit using isop normal form
|
|
unsigned bdd2ISOPvar(const bdd& b, const int use_split_off = 0);
|
|
|
|
/// \brief Add a bdd to the circuit
|
|
/// Assumes that all bdd's given in c_alt fulfill the same purpose,
|
|
/// that is, any of these conditions can be encoded and the
|
|
/// corresponding literal returned.
|
|
/// Multiple translation options are available whose main
|
|
/// goal is to minimize the necessary number of gates.
|
|
///
|
|
/// \param method How to translate the bdd. 0: If-then-else normal form,
|
|
/// 1: isop normal form, 2: try both and retain smaller
|
|
/// \param use_dual Encode the negations of the given bdds and
|
|
/// retain the smallest implementation
|
|
/// \param use_split_off 0: Use base algo
|
|
/// 1: Separate the different types of input signals
|
|
/// (like latches, inputs) to increase gate
|
|
/// re-usability and retain smallest circuit
|
|
/// 2: Actively search for subexpressions the
|
|
/// within expressions
|
|
unsigned encode_bdd(const std::vector<bdd>& c_alt,
|
|
char method = 1, bool use_dual = false,
|
|
int use_split_off = 0);
|
|
|
|
/// \brief Just like the vector version but with no alternatives given
|
|
unsigned encode_bdd(const bdd& b,
|
|
char method = 1, bool use_dual = false,
|
|
int use_split_off = 0);
|
|
|
|
/// \brief Associate the ith output to the variable v
|
|
void set_output(unsigned i, unsigned v);
|
|
|
|
/// \brief Associate the ith latch state after update to the variable v
|
|
void set_next_latch(unsigned i, unsigned v);
|
|
|
|
static constexpr unsigned aig_true() noexcept
|
|
{
|
|
return 1;
|
|
};
|
|
|
|
static constexpr unsigned aig_false() noexcept
|
|
{
|
|
return 0;
|
|
};
|
|
|
|
/// \brief Negate a variable
|
|
unsigned aig_not(unsigned v);
|
|
|
|
/// \brief Compute AND of v1 and v2
|
|
unsigned aig_and(unsigned v1, unsigned v2);
|
|
|
|
/// \brief Computes the AND of all vars
|
|
/// \note This function modifies the given vector to only contain the
|
|
/// result (at position zero) after the call
|
|
unsigned aig_and(std::vector<unsigned>& vs);
|
|
|
|
/// \brief Computes the OR of v1 and v2
|
|
unsigned aig_or(unsigned v1, unsigned v2);
|
|
|
|
/// \brief Computes the or of all vars
|
|
/// \note This function modifies the given vector to only contain the
|
|
/// result after call
|
|
unsigned aig_or(std::vector<unsigned>& vs);
|
|
|
|
/// \brief Returns the positive form of the given variable
|
|
unsigned aig_pos(unsigned v);
|
|
|
|
/// \brief Instead of successively adding bdds to the circuit,
|
|
/// one can also pass a vector of all bdds needed to the circuit.
|
|
/// In this case additional optimization steps are taken to minimize
|
|
/// the size of the circuit
|
|
/// \note This can be costly and did not bring about any advantages
|
|
/// in the SYNTCOMP cases
|
|
void encode_all_bdds(const std::vector<bdd>& all_bdd);
|
|
|
|
/// \brief Create a circuit from an aag file with restricted syntax.
|
|
///
|
|
/// \note Additional constraints are:
|
|
/// - inputs, latches, and gates have to appear in increasing order.
|
|
/// - Inputs are expected to have variable numbers from 2-2*n_i+1
|
|
/// with n_i being the number of inputs
|
|
/// - Latches cannot be named
|
|
static aig_ptr
|
|
parse_aag(const std::string& aig_file,
|
|
bdd_dict_ptr dict = make_bdd_dict());
|
|
|
|
static aig_ptr
|
|
parse_aag(const char* data,
|
|
const std::string& filename,
|
|
bdd_dict_ptr dict = make_bdd_dict());
|
|
|
|
static aig_ptr
|
|
parse_aag(std::istream& iss,
|
|
const std::string& filename,
|
|
bdd_dict_ptr dict = make_bdd_dict());
|
|
|
|
/// \brief Transform the circuit onto an equivalent monitor
|
|
/// \param keepsplit If as_automaton(true) is the same as
|
|
/// split_2step(as_automaton(false), outputs)
|
|
/// \note The complexity is exponential in the number of inputs!
|
|
twa_graph_ptr as_automaton(bool keepsplit = false) const;
|
|
|
|
/// \brief Gives access to the current state of the circuit.
|
|
///
|
|
/// Corresponds to a vector of booleans holding the truth value
|
|
/// for each literal. Note that within the vector we have the truth
|
|
/// value of a literal and its negation, so sim_state()[2*i+1] is
|
|
/// always the negation of sim_state()[2*i].
|
|
/// The variable index can be obtained using
|
|
/// input_var, latch_var or outputs
|
|
const std::vector<bool>& circ_state() const
|
|
{
|
|
SPOT_ASSERT(state_.size() == max_var_ + 2
|
|
&& "State vector does not have the correct size.\n"
|
|
"Forgot to initialize?");
|
|
return state_;
|
|
}
|
|
|
|
/// \brief Access to the state of a specific variable
|
|
bool circ_state_of(unsigned var) const
|
|
{
|
|
SPOT_ASSERT(var <= max_var_ + 1
|
|
&& "Variable out of range");
|
|
return circ_state()[var];
|
|
}
|
|
|
|
/// \brief (Re)initialize the stepwise evaluation of the circuit.
|
|
/// This sets all latches to 0 and clears the output
|
|
void circ_init();
|
|
|
|
/// \brief Performs the next discrete step of the circuit,
|
|
/// based on the inputs.
|
|
///
|
|
/// Updates the state of the aig such that circ_state holds the
|
|
/// values of output and latches AFTER reading the given input
|
|
/// \param inputs : Vector of booleans with size num_inputs()
|
|
void circ_step(const std::vector<bool>& inputs);
|
|
|
|
};
|
|
|
|
/// \ingroup synthesis
|
|
/// \brief Convert a mealy (like) machine into an aig relying on
|
|
/// the transformation described by \a mode.
|
|
/// \param mode This param has to be of the form
|
|
/// `ite|isop|both [+dc][+ud][+sub0|+sub1|+sub2]`
|
|
/// Where `ite` means encoded via if-then-else normal form,
|
|
/// `isop` means encoded via irredundant sum-of-products,
|
|
/// `both` means trying both encodings to keep the smaller one.
|
|
/// `+dc` is optional and tries to take advantage of "do not care"
|
|
/// outputs to minimize the encoding.
|
|
/// `+dual` is optional and indicates that the algorithm
|
|
/// should also try to encode the negation of each condition in
|
|
/// case its encoding is smaller.
|
|
/// `+subN` indicates that the conditions can be separated into
|
|
/// blocks with `sub0` being no separation, `sub1` separation into
|
|
/// input/latches/gates (`isop` only) and `sub2` tries to seek
|
|
/// common subformulas.
|
|
///
|
|
/// If \a ins and \a outs are specified, the named-property
|
|
/// synthesis-output is ignored and all properties in \a ins and \a
|
|
/// outs are guaranteed to appear in the aiger circuit.
|
|
///
|
|
/// If \a rs is given and is not empty, it can be used to specify how
|
|
/// unused output should be encoded by mapping them to some constant.
|
|
///@{
|
|
SPOT_API aig_ptr
|
|
mealy_machine_to_aig(const const_twa_graph_ptr& m, const char* mode);
|
|
SPOT_API aig_ptr
|
|
mealy_machine_to_aig(const twa_graph_ptr& m, const char *mode,
|
|
const std::vector<std::string>& ins,
|
|
const std::vector<std::string>& outs,
|
|
const realizability_simplifier* rs = nullptr);
|
|
|
|
SPOT_API aig_ptr
|
|
mealy_machine_to_aig(const mealy_like& m, const char* mode);
|
|
SPOT_API aig_ptr
|
|
mealy_machine_to_aig(mealy_like& m, const char *mode,
|
|
const std::vector<std::string>& ins,
|
|
const std::vector<std::string>& outs,
|
|
const realizability_simplifier* rs = nullptr);
|
|
///@}
|
|
|
|
/// \ingroup synthesis
|
|
/// \brief Convert multiple mealy machines into an aig relying on
|
|
/// the transformation described by mode.
|
|
/// \note The states of each machine are represented by a block of latches
|
|
/// not affected by the others. For this to work in a general setting,
|
|
/// the outputs must be disjoint.
|
|
///
|
|
/// Unless \a ins and \a outs are specified, only the propositions
|
|
/// actually used in the strategy appear in the aiger circuit. So it
|
|
/// can happen that, for instance, propositions marked as output
|
|
/// during the call to ltl_to_game() are absent.
|
|
/// If \a ins and \a outs are used, all properties they list are
|
|
/// guaranteed to appear in the aiger circuit.
|
|
///
|
|
/// If \a rs is given and is not empty, it can be used to specify how
|
|
/// unused output should be encoded by mapping them to some constant.
|
|
/// @{
|
|
SPOT_API aig_ptr
|
|
mealy_machines_to_aig(const std::vector<const_twa_graph_ptr>& m_vec,
|
|
const char* mode);
|
|
SPOT_API aig_ptr
|
|
mealy_machines_to_aig(const std::vector<mealy_like>& m_vec,
|
|
const char* mode);
|
|
SPOT_API aig_ptr
|
|
mealy_machines_to_aig(const std::vector<const_twa_graph_ptr>& m_vec,
|
|
const char* mode,
|
|
const std::vector<std::string>& ins,
|
|
const std::vector<std::vector<std::string>>& outs,
|
|
const realizability_simplifier* rs = nullptr);
|
|
SPOT_API aig_ptr
|
|
mealy_machines_to_aig(const std::vector<mealy_like>& m_vec,
|
|
const char* mode,
|
|
const std::vector<std::string>& ins,
|
|
const std::vector<std::vector<std::string>>& outs,
|
|
const realizability_simplifier* rs = nullptr);
|
|
/// @}
|
|
|
|
/// \ingroup twa_io
|
|
/// \brief Print the aig to stream in AIGER format
|
|
SPOT_API std::ostream&
|
|
print_aiger(std::ostream& os, const_aig_ptr circuit);
|
|
|
|
/// \ingroup twa_io
|
|
/// \brief Encode and print an automaton as an AIGER circuit.
|
|
///
|
|
/// The circuit actually encodes the transition relation of the automaton, not
|
|
/// its acceptance condition. Therefore, this function will reject automata
|
|
/// whose acceptance condition is not trivial (i.e. true).
|
|
/// States are encoded by latches (or registers) in the circuit. Atomic
|
|
/// propositions are encoded as inputs and outputs of the circuit. To know
|
|
/// which AP should be encoded as outputs, print_aiger() relies on the named
|
|
/// property "synthesis-outputs", which is a bdd containing the conjunction of
|
|
/// such output propositions. All other AP are encoded as inputs. If the named
|
|
/// property is not set, all AP are encoded as inputs, and the circuit has no
|
|
/// output.
|
|
///
|
|
/// \pre In order to ensure correctness, edge conditions have
|
|
/// to have the form (input cond) & (output cond). The output cond
|
|
/// does not need to be a minterm.
|
|
/// Correct graphs are generated by spot::unsplit_2step
|
|
///
|
|
/// \param os The output stream to print on.
|
|
/// \param aut The automaton to output.
|
|
/// \param mode This param has to be of the form
|
|
/// `ite|isop|both [+dc][+ud][+sub0|+sub1|+sub2]`
|
|
/// Where `ite` means encoded via if-then-else normal form,
|
|
/// `isop` means encoded via irredundant sum-of-products,
|
|
/// `both` means trying both encodings to keep the smaller one.
|
|
/// `+dc` is optional and tries to take advantage of "do not care"
|
|
/// outputs to minimize the encoding.
|
|
/// `+dual` is optional and indicates that the algorithm
|
|
/// should also try to encode the negation of each condition in
|
|
/// case its encoding is smaller.
|
|
/// `+subN` indicates that the conditions can be separated into
|
|
/// blocks with `sub0` being no separation, `sub1` separation into
|
|
/// input/latches/gates (`isop` only) and `sub2` tries to seek
|
|
/// common subformulas.
|
|
SPOT_API std::ostream&
|
|
print_aiger(std::ostream& os, const const_twa_graph_ptr& aut,
|
|
const char* mode);
|
|
}
|