sanity: Replace tabulars by spaces in *.cc *.hh *.hxx

* bin/autfilt.cc, bin/common_aoutput.cc, bin/common_aoutput.hh,
bin/common_finput.cc, bin/common_finput.hh, bin/common_hoaread.cc,
bin/common_output.cc, bin/common_output.hh, bin/common_post.cc,
bin/common_post.hh, bin/common_r.hh, bin/common_range.cc,
bin/common_range.hh, bin/common_setup.cc, bin/common_trans.cc,
bin/common_trans.hh, bin/dstar2tgba.cc, bin/genltl.cc,
bin/ltl2tgba.cc, bin/ltl2tgta.cc, bin/ltlcross.cc, bin/ltldo.cc,
bin/ltlfilt.cc, bin/ltlgrind.cc, bin/randaut.cc, bin/randltl.cc,
bin/spot-x.cc, spot/graph/graph.hh, spot/graph/ngraph.hh,
spot/kripke/kripkegraph.hh, spot/ltsmin/ltsmin.cc,
spot/ltsmin/ltsmin.hh, spot/misc/bareword.cc, spot/misc/bitvect.cc,
spot/misc/bitvect.hh, spot/misc/common.hh, spot/misc/escape.cc,
spot/misc/fixpool.hh, spot/misc/formater.cc, spot/misc/hash.hh,
spot/misc/intvcmp2.cc, spot/misc/intvcmp2.hh, spot/misc/intvcomp.cc,
spot/misc/intvcomp.hh, spot/misc/location.hh, spot/misc/minato.cc,
spot/misc/minato.hh, spot/misc/mspool.hh, spot/misc/optionmap.cc,
spot/misc/optionmap.hh, spot/misc/random.cc, spot/misc/random.hh,
spot/misc/satsolver.cc, spot/misc/satsolver.hh, spot/misc/timer.cc,
spot/misc/timer.hh, spot/misc/tmpfile.cc, spot/misc/trival.hh,
spot/parseaut/fmterror.cc, spot/parseaut/parsedecl.hh,
spot/parseaut/public.hh, spot/parsetl/fmterror.cc,
spot/parsetl/parsedecl.hh, spot/priv/accmap.hh, spot/priv/bddalloc.cc,
spot/priv/freelist.cc, spot/priv/trim.cc, spot/priv/weight.cc,
spot/priv/weight.hh, spot/ta/taexplicit.cc, spot/ta/taexplicit.hh,
spot/ta/taproduct.cc, spot/ta/taproduct.hh, spot/ta/tgtaexplicit.cc,
spot/ta/tgtaexplicit.hh, spot/ta/tgtaproduct.cc,
spot/ta/tgtaproduct.hh, spot/taalgos/dot.cc, spot/taalgos/dot.hh,
spot/taalgos/emptinessta.cc, spot/taalgos/emptinessta.hh,
spot/taalgos/minimize.cc, spot/taalgos/tgba2ta.cc,
spot/taalgos/tgba2ta.hh, spot/tl/apcollect.cc, spot/tl/contain.cc,
spot/tl/contain.hh, spot/tl/dot.cc, spot/tl/exclusive.cc,
spot/tl/exclusive.hh, spot/tl/formula.cc, spot/tl/formula.hh,
spot/tl/length.cc, spot/tl/mark.cc, spot/tl/mutation.cc,
spot/tl/mutation.hh, spot/tl/parse.hh, spot/tl/print.cc,
spot/tl/print.hh, spot/tl/randomltl.cc, spot/tl/randomltl.hh,
spot/tl/relabel.cc, spot/tl/relabel.hh, spot/tl/remove_x.cc,
spot/tl/simplify.cc, spot/tl/simplify.hh, spot/tl/snf.cc,
spot/tl/snf.hh, spot/tl/unabbrev.cc, spot/tl/unabbrev.hh,
spot/twa/acc.cc, spot/twa/acc.hh, spot/twa/bdddict.cc,
spot/twa/bdddict.hh, spot/twa/bddprint.cc, spot/twa/formula2bdd.cc,
spot/twa/formula2bdd.hh, spot/twa/taatgba.cc, spot/twa/taatgba.hh,
spot/twa/twa.cc, spot/twa/twa.hh, spot/twa/twagraph.cc,
spot/twa/twagraph.hh, spot/twa/twaproduct.cc, spot/twa/twaproduct.hh,
spot/twaalgos/are_isomorphic.cc, spot/twaalgos/are_isomorphic.hh,
spot/twaalgos/bfssteps.cc, spot/twaalgos/bfssteps.hh,
spot/twaalgos/cleanacc.cc, spot/twaalgos/complete.cc,
spot/twaalgos/compsusp.cc, spot/twaalgos/compsusp.hh,
spot/twaalgos/copy.cc, spot/twaalgos/cycles.cc,
spot/twaalgos/cycles.hh, spot/twaalgos/degen.cc,
spot/twaalgos/degen.hh, spot/twaalgos/determinize.cc,
spot/twaalgos/determinize.hh, spot/twaalgos/dot.cc,
spot/twaalgos/dot.hh, spot/twaalgos/dtbasat.cc,
spot/twaalgos/dtbasat.hh, spot/twaalgos/dtwasat.cc,
spot/twaalgos/dtwasat.hh, spot/twaalgos/emptiness.cc,
spot/twaalgos/emptiness.hh, spot/twaalgos/emptiness_stats.hh,
spot/twaalgos/gtec/ce.cc, spot/twaalgos/gtec/ce.hh,
spot/twaalgos/gtec/gtec.cc, spot/twaalgos/gtec/gtec.hh,
spot/twaalgos/gtec/sccstack.cc, spot/twaalgos/gtec/status.cc,
spot/twaalgos/gv04.cc, spot/twaalgos/hoa.cc, spot/twaalgos/hoa.hh,
spot/twaalgos/isdet.cc, spot/twaalgos/isunamb.cc,
spot/twaalgos/isweakscc.cc, spot/twaalgos/lbtt.cc,
spot/twaalgos/lbtt.hh, spot/twaalgos/ltl2taa.cc,
spot/twaalgos/ltl2taa.hh, spot/twaalgos/ltl2tgba_fm.cc,
spot/twaalgos/ltl2tgba_fm.hh, spot/twaalgos/magic.cc,
spot/twaalgos/magic.hh, spot/twaalgos/mask.cc, spot/twaalgos/mask.hh,
spot/twaalgos/minimize.cc, spot/twaalgos/minimize.hh,
spot/twaalgos/ndfs_result.hxx, spot/twaalgos/neverclaim.cc,
spot/twaalgos/neverclaim.hh, spot/twaalgos/postproc.cc,
spot/twaalgos/postproc.hh, spot/twaalgos/powerset.cc,
spot/twaalgos/powerset.hh, spot/twaalgos/product.cc,
spot/twaalgos/product.hh, spot/twaalgos/projrun.cc,
spot/twaalgos/projrun.hh, spot/twaalgos/randomgraph.cc,
spot/twaalgos/randomgraph.hh, spot/twaalgos/randomize.cc,
spot/twaalgos/randomize.hh, spot/twaalgos/reachiter.cc,
spot/twaalgos/reachiter.hh, spot/twaalgos/relabel.cc,
spot/twaalgos/relabel.hh, spot/twaalgos/remfin.cc,
spot/twaalgos/remprop.cc, spot/twaalgos/sbacc.cc,
spot/twaalgos/sccfilter.cc, spot/twaalgos/sccfilter.hh,
spot/twaalgos/sccinfo.cc, spot/twaalgos/sccinfo.hh,
spot/twaalgos/se05.cc, spot/twaalgos/se05.hh,
spot/twaalgos/sepsets.cc, spot/twaalgos/simulation.cc,
spot/twaalgos/simulation.hh, spot/twaalgos/stats.cc,
spot/twaalgos/stats.hh, spot/twaalgos/strength.cc,
spot/twaalgos/strength.hh, spot/twaalgos/stripacc.cc,
spot/twaalgos/stutter.cc, spot/twaalgos/stutter.hh,
spot/twaalgos/tau03.cc, spot/twaalgos/tau03opt.cc,
spot/twaalgos/tau03opt.hh, spot/twaalgos/totgba.cc,
spot/twaalgos/translate.cc, spot/twaalgos/word.cc, tests/core/acc.cc,
tests/core/bitvect.cc, tests/core/checkpsl.cc, tests/core/checkta.cc,
tests/core/consterm.cc, tests/core/emptchk.cc, tests/core/equalsf.cc,
tests/core/graph.cc, tests/core/ikwiad.cc, tests/core/intvcmp2.cc,
tests/core/intvcomp.cc, tests/core/kind.cc, tests/core/kripkecat.cc,
tests/core/ltlrel.cc, tests/core/ngraph.cc, tests/core/randtgba.cc,
tests/core/readltl.cc, tests/core/reduc.cc, tests/core/safra.cc,
tests/core/syntimpl.cc, tests/ltsmin/modelcheck.cc: Replace tabulars by
8 spaces.
* tests/sanity/style.test: Add checks for no tabulars in *.cc *.hh *.hxx
This commit is contained in:
Laurent XU 2016-03-09 00:23:20 +01:00 committed by Alexandre Duret-Lutz
parent 1eee12b8b4
commit f7e7b4f14e
239 changed files with 25359 additions and 25355 deletions

View file

@ -47,7 +47,7 @@ namespace spot
struct first_is_base_of<Of, Arg1, Args...>
{
static const bool value =
std::is_base_of<Of, typename std::decay<Arg1>::type>::value;
std::is_base_of<Of, typename std::decay<Arg1>::type>::value;
};
#endif
@ -65,11 +65,11 @@ namespace spot
#ifndef SWIG
template <typename... Args,
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: label{std::forward<Args>(args)...}
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: label{std::forward<Args>(args)...}
{
}
#endif
@ -77,23 +77,23 @@ namespace spot
// if Data is a POD type, G++ 4.8.2 wants default values for all
// label fields unless we define this default constructor here.
explicit boxed_label()
noexcept(std::is_nothrow_constructible<Data>::value)
noexcept(std::is_nothrow_constructible<Data>::value)
{
}
Data& data()
{
return label;
return label;
}
const Data& data() const
{
return label;
return label;
}
bool operator<(const boxed_label& other) const
{
return label < other.label;
return label < other.label;
}
};
@ -103,12 +103,12 @@ namespace spot
typedef std::tuple<> data_t;
std::tuple<>& data()
{
return *this;
return *this;
}
const std::tuple<>& data() const
{
return *this;
return *this;
}
};
@ -120,11 +120,11 @@ namespace spot
#ifndef SWIG
template <typename... Args,
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: Data{std::forward<Args>(args)...}
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: Data{std::forward<Args>(args)...}
{
}
#endif
@ -132,18 +132,18 @@ namespace spot
// if Data is a POD type, G++ 4.8.2 wants default values for all
// label fields unless we define this default constructor here.
explicit boxed_label()
noexcept(std::is_nothrow_constructible<Data>::value)
noexcept(std::is_nothrow_constructible<Data>::value)
{
}
Data& data()
{
return *this;
return *this;
}
const Data& data() const
{
return *this;
return *this;
}
};
@ -158,15 +158,15 @@ namespace spot
struct SPOT_API distate_storage final: public State_Data
{
Edge succ = 0; // First outgoing edge (used when iterating)
Edge succ_tail = 0; // Last outgoing edge (used for
// appending new edges)
Edge succ_tail = 0; // Last outgoing edge (used for
// appending new edges)
#ifndef SWIG
template <typename... Args,
typename = typename std::enable_if<
!first_is_base_of<distate_storage, Args...>::value>::type>
typename = typename std::enable_if<
!first_is_base_of<distate_storage, Args...>::value>::type>
distate_storage(Args&&... args)
noexcept(std::is_nothrow_constructible<State_Data, Args...>::value)
: State_Data{std::forward<Args>(args)...}
noexcept(std::is_nothrow_constructible<State_Data, Args...>::value)
: State_Data{std::forward<Args>(args)...}
{
}
#endif
@ -179,47 +179,47 @@ namespace spot
// Again two implementation: one with label, and one without.
template <typename StateIn,
typename StateOut, typename Edge, typename Edge_Data>
typename StateOut, typename Edge, typename Edge_Data>
struct SPOT_API edge_storage final: public Edge_Data
{
typedef Edge edge;
StateOut dst; // destination
Edge next_succ; // next outgoing edge with same
// source, or 0
StateIn src; // source
StateOut dst; // destination
Edge next_succ; // next outgoing edge with same
// source, or 0
StateIn src; // source
explicit edge_storage()
noexcept(std::is_nothrow_constructible<Edge_Data>::value)
: Edge_Data{}
noexcept(std::is_nothrow_constructible<Edge_Data>::value)
: Edge_Data{}
{
}
#ifndef SWIG
template <typename... Args>
edge_storage(StateOut dst, Edge next_succ,
StateIn src, Args&&... args)
noexcept(std::is_nothrow_constructible<Edge_Data, Args...>::value
&& std::is_nothrow_constructible<StateOut, StateOut>::value
&& std::is_nothrow_constructible<Edge, Edge>::value)
: Edge_Data{std::forward<Args>(args)...},
dst(dst), next_succ(next_succ), src(src)
StateIn src, Args&&... args)
noexcept(std::is_nothrow_constructible<Edge_Data, Args...>::value
&& std::is_nothrow_constructible<StateOut, StateOut>::value
&& std::is_nothrow_constructible<Edge, Edge>::value)
: Edge_Data{std::forward<Args>(args)...},
dst(dst), next_succ(next_succ), src(src)
{
}
#endif
bool operator<(const edge_storage& other) const
{
if (src < other.src)
return true;
if (src > other.src)
return false;
// This might be costly if the destination is a vector
if (dst < other.dst)
return true;
if (dst > other.dst)
return false;
return this->data() < other.data();
if (src < other.src)
return true;
if (src > other.src)
return false;
// This might be costly if the destination is a vector
if (dst < other.dst)
return true;
if (dst > other.dst)
return false;
return this->data() < other.data();
}
bool operator==(const edge_storage& other) const
@ -241,86 +241,86 @@ namespace spot
template <typename Graph>
class SPOT_API edge_iterator: public
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
{
typedef
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
public:
typedef typename Graph::edge edge;
edge_iterator() noexcept
: g_(nullptr), t_(0)
: g_(nullptr), t_(0)
{
}
edge_iterator(Graph* g, edge t) noexcept
: g_(g), t_(t)
: g_(g), t_(t)
{
}
bool operator==(edge_iterator o) const
{
return t_ == o.t_;
return t_ == o.t_;
}
bool operator!=(edge_iterator o) const
{
return t_ != o.t_;
return t_ != o.t_;
}
typename super::reference
operator*()
{
return g_->edge_storage(t_);
return g_->edge_storage(t_);
}
const typename super::reference
operator*() const
{
return g_->edge_storage(t_);
return g_->edge_storage(t_);
}
typename super::pointer
operator->()
{
return &g_->edge_storage(t_);
return &g_->edge_storage(t_);
}
const typename super::pointer
operator->() const
{
return &g_->edge_storage(t_);
return &g_->edge_storage(t_);
}
edge_iterator operator++()
{
t_ = operator*().next_succ;
return *this;
t_ = operator*().next_succ;
return *this;
}
edge_iterator operator++(int)
{
edge_iterator ti = *this;
t_ = operator*().next_succ;
return ti;
edge_iterator ti = *this;
t_ = operator*().next_succ;
return ti;
}
operator bool() const
{
return t_;
return t_;
}
edge trans() const
{
return t_;
return t_;
}
protected:
@ -337,52 +337,52 @@ namespace spot
typedef typename Graph::edge edge;
killer_edge_iterator(Graph* g, edge t, state_storage_t& src) noexcept
: super(g, t), src_(src), prev_(0)
: super(g, t), src_(src), prev_(0)
{
}
killer_edge_iterator operator++()
{
prev_ = this->t_;
this->t_ = this->operator*().next_succ;
return *this;
prev_ = this->t_;
this->t_ = this->operator*().next_succ;
return *this;
}
killer_edge_iterator operator++(int)
{
killer_edge_iterator ti = *this;
++*this;
return ti;
killer_edge_iterator ti = *this;
++*this;
return ti;
}
// Erase the current edge and advance the iterator.
void erase()
{
edge next = this->operator*().next_succ;
edge next = this->operator*().next_succ;
// Update source state and previous edges
if (prev_)
{
this->g_->edge_storage(prev_).next_succ = next;
}
else
{
if (src_.succ == this->t_)
src_.succ = next;
}
if (src_.succ_tail == this->t_)
{
src_.succ_tail = prev_;
assert(next == 0);
}
// Update source state and previous edges
if (prev_)
{
this->g_->edge_storage(prev_).next_succ = next;
}
else
{
if (src_.succ == this->t_)
src_.succ = next;
}
if (src_.succ_tail == this->t_)
{
src_.succ_tail = prev_;
assert(next == 0);
}
// Erased edges have themselves as next_succ.
this->operator*().next_succ = this->t_;
// Erased edges have themselves as next_succ.
this->operator*().next_succ = this->t_;
// Advance iterator to next edge.
this->t_ = next;
// Advance iterator to next edge.
this->t_ = next;
++this->g_->killed_edge_;
++this->g_->killed_edge_;
}
protected:
@ -403,23 +403,23 @@ namespace spot
public:
typedef typename Graph::edge edge;
state_out(Graph* g, edge t) noexcept
: g_(g), t_(t)
: g_(g), t_(t)
{
}
edge_iterator<Graph> begin()
{
return {g_, t_};
return {g_, t_};
}
edge_iterator<Graph> end()
{
return {};
return {};
}
void recycle(edge t)
{
t_ = t;
t_ = t;
}
protected:
@ -434,92 +434,92 @@ namespace spot
template <typename Graph>
class SPOT_API all_edge_iterator: public
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
{
typedef
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
typedef typename std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
unsigned t_;
tv_t& tv_;
void skip_()
{
unsigned s = tv_.size();
do
++t_;
while (t_ < s && tv_[t_].next_succ == t_);
unsigned s = tv_.size();
do
++t_;
while (t_ < s && tv_[t_].next_succ == t_);
}
public:
all_edge_iterator(unsigned pos, tv_t& tv) noexcept
: t_(pos), tv_(tv)
: t_(pos), tv_(tv)
{
skip_();
skip_();
}
all_edge_iterator(tv_t& tv) noexcept
: t_(tv.size()), tv_(tv)
: t_(tv.size()), tv_(tv)
{
}
all_edge_iterator& operator++()
{
skip_();
return *this;
skip_();
return *this;
}
all_edge_iterator operator++(int)
{
all_edge_iterator old = *this;
++*this;
return old;
all_edge_iterator old = *this;
++*this;
return old;
}
bool operator==(all_edge_iterator o) const
{
return t_ == o.t_;
return t_ == o.t_;
}
bool operator!=(all_edge_iterator o) const
{
return t_ != o.t_;
return t_ != o.t_;
}
typename super::reference
operator*()
{
return tv_[t_];
return tv_[t_];
}
const typename super::reference
operator*() const
{
return tv_[t_];
return tv_[t_];
}
const typename super::pointer
operator->()
{
return &tv_[t_];
return &tv_[t_];
}
typename super::pointer
operator->() const
{
return &tv_[t_];
return &tv_[t_];
}
};
@ -529,27 +529,27 @@ namespace spot
{
public:
typedef typename std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
typedef all_edge_iterator<Graph> iter_t;
private:
tv_t& tv_;
public:
all_trans(tv_t& tv) noexcept
: tv_(tv)
: tv_(tv)
{
}
iter_t begin()
{
return {0, tv_};
return {0, tv_};
}
iter_t end()
{
return {tv_};
return {tv_};
}
};
@ -586,14 +586,14 @@ namespace spot
// The type of an output state (when seen from a edge)
// depends on the kind of graph we build
typedef typename std::conditional<Alternating,
std::vector<state>,
state>::type out_state;
std::vector<state>,
state>::type out_state;
typedef internal::distate_storage<edge,
internal::boxed_label<State_Data>>
internal::boxed_label<State_Data>>
state_storage_t;
typedef internal::edge_storage<state, out_state, edge,
internal::boxed_label<Edge_Data>>
internal::boxed_label<Edge_Data>>
edge_storage_t;
typedef std::vector<state_storage_t> state_vector;
typedef std::vector<edge_storage_t> edge_vector_t;
@ -614,7 +614,7 @@ namespace spot
{
states_.reserve(max_states);
if (max_trans == 0)
max_trans = max_states * 2;
max_trans = max_states * 2;
edges_.reserve(max_trans + 1);
// Edge number 0 is not used, because we use this index
// to mark the absence of a edge.
@ -638,7 +638,7 @@ namespace spot
// Erased edges have their next_succ pointing to
// themselves.
return (t < edges_.size() &&
edges_[t].next_succ != t);
edges_[t].next_succ != t);
}
template <typename... Args>
@ -655,7 +655,7 @@ namespace spot
state s = states_.size();
states_.reserve(s + n);
while (n--)
states_.emplace_back(std::forward<Args>(args)...);
states_.emplace_back(std::forward<Args>(args)...);
return s;
}
@ -730,9 +730,9 @@ namespace spot
edge st = states_[src].succ_tail;
assert(st < t || !st);
if (!st)
states_[src].succ = t;
states_[src].succ = t;
else
edges_[st].next_succ = t;
edges_[st].next_succ = t;
states_[src].succ_tail = t;
return t;
}
@ -836,19 +836,19 @@ namespace spot
{
unsigned tend = edges_.size();
for (unsigned t = 1; t < tend; ++t)
{
o << 't' << t << ": (s"
<< edges_[t].src << ", s"
<< edges_[t].dst << ") t"
<< edges_[t].next_succ << '\n';
}
{
o << 't' << t << ": (s"
<< edges_[t].src << ", s"
<< edges_[t].dst << ") t"
<< edges_[t].next_succ << '\n';
}
unsigned send = states_.size();
for (unsigned s = 0; s < send; ++s)
{
o << 's' << s << ": t"
<< states_[s].succ << " t"
<< states_[s].succ_tail << '\n';
}
{
o << 's' << s << ": t"
<< states_[s].succ << " t"
<< states_[s].succ_tail << '\n';
}
}
// Remove all dead edges. The edges_ vector is left
@ -858,11 +858,11 @@ namespace spot
void remove_dead_edges_()
{
if (killed_edge_ == 0)
return;
return;
auto i = std::remove_if(edges_.begin() + 1, edges_.end(),
[this](const edge_storage_t& t) {
return this->is_dead_edge(t);
});
[this](const edge_storage_t& t) {
return this->is_dead_edge(t);
});
edges_.erase(i, edges_.end());
killed_edge_ = 0;
}
@ -885,38 +885,38 @@ namespace spot
state last_src = -1U;
edge tend = edges_.size();
for (edge t = 1; t < tend; ++t)
{
state src = edges_[t].src;
if (src != last_src)
{
states_[src].succ = t;
if (last_src != -1U)
{
states_[last_src].succ_tail = t - 1;
edges_[t - 1].next_succ = 0;
}
while (++last_src != src)
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
}
else
{
edges_[t - 1].next_succ = t;
}
}
{
state src = edges_[t].src;
if (src != last_src)
{
states_[src].succ = t;
if (last_src != -1U)
{
states_[last_src].succ_tail = t - 1;
edges_[t - 1].next_succ = 0;
}
while (++last_src != src)
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
}
else
{
edges_[t - 1].next_succ = t;
}
}
if (last_src != -1U)
{
states_[last_src].succ_tail = tend - 1;
edges_[tend - 1].next_succ = 0;
}
{
states_[last_src].succ_tail = tend - 1;
edges_[tend - 1].next_succ = 0;
}
unsigned send = states_.size();
while (++last_src != send)
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
//std::cerr << "\nafter\n";
//dump_storage(std::cerr);
}
@ -930,10 +930,10 @@ namespace spot
assert(newst.size() == states_.size());
unsigned tend = edges_.size();
for (unsigned t = 1; t < tend; t++)
{
edges_[t].dst = newst[edges_[t].dst];
edges_[t].src = newst[edges_[t].src];
}
{
edges_[t].dst = newst[edges_[t].dst];
edges_[t].src = newst[edges_[t].src];
}
}
void defrag_states(std::vector<unsigned>&& newst, unsigned used_states)
@ -947,22 +947,22 @@ namespace spot
// Shift all states in states_, as indicated by newst.
unsigned send = states_.size();
for (state s = 0; s < send; ++s)
{
state dst = newst[s];
if (dst == s)
continue;
if (dst == -1U)
{
// This is an erased state. Mark all its edges as
// dead (i.e., t.next_succ should point to t for each of
// them).
auto t = states_[s].succ;
while (t)
std::swap(t, edges_[t].next_succ);
continue;
}
states_[dst] = std::move(states_[s]);
}
{
state dst = newst[s];
if (dst == s)
continue;
if (dst == -1U)
{
// This is an erased state. Mark all its edges as
// dead (i.e., t.next_succ should point to t for each of
// them).
auto t = states_[s].succ;
while (t)
std::swap(t, edges_[t].next_succ);
continue;
}
states_[dst] = std::move(states_[s]);
}
states_.resize(used_states);
// Shift all edges in edges_. The algorithm is
@ -972,33 +972,33 @@ namespace spot
std::vector<edge> newidx(tend);
unsigned dest = 1;
for (edge t = 1; t < tend; ++t)
{
if (is_dead_edge(t))
continue;
if (t != dest)
edges_[dest] = std::move(edges_[t]);
newidx[t] = dest;
++dest;
}
{
if (is_dead_edge(t))
continue;
if (t != dest)
edges_[dest] = std::move(edges_[t]);
newidx[t] = dest;
++dest;
}
edges_.resize(dest);
killed_edge_ = 0;
// Adjust next_succ and dst pointers in all edges.
for (edge t = 1; t < dest; ++t)
{
auto& tr = edges_[t];
tr.next_succ = newidx[tr.next_succ];
tr.dst = newst[tr.dst];
tr.src = newst[tr.src];
assert(tr.dst != -1U);
}
{
auto& tr = edges_[t];
tr.next_succ = newidx[tr.next_succ];
tr.dst = newst[tr.dst];
tr.src = newst[tr.src];
assert(tr.dst != -1U);
}
// Adjust succ and succ_tails pointers in all states.
for (auto& s: states_)
{
s.succ = newidx[s.succ];
s.succ_tail = newidx[s.succ_tail];
}
{
s.succ = newidx[s.succ];
s.succ_tail = newidx[s.succ_tail];
}
//std::cerr << "\nafter defrag\n";
//dump_storage(std::cerr);

View file

@ -26,9 +26,9 @@
namespace spot
{
template <typename Graph,
typename State_Name,
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
typename State_Name,
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
class SPOT_API named_graph
{
protected:
@ -40,7 +40,7 @@ namespace spot
typedef State_Name name;
typedef std::unordered_map<name, state,
Name_Hash, Name_Equal> name_to_state_t;
Name_Hash, Name_Equal> name_to_state_t;
name_to_state_t name_to_state;
typedef std::vector<name> state_to_name_t;
state_to_name_t state_to_name;
@ -65,14 +65,14 @@ namespace spot
{
auto p = name_to_state.emplace(n, 0U);
if (p.second)
{
unsigned s = g_.new_state(std::forward<Args>(args)...);
p.first->second = s;
if (state_to_name.size() < s + 1)
state_to_name.resize(s + 1);
state_to_name[s] = n;
return s;
}
{
unsigned s = g_.new_state(std::forward<Args>(args)...);
p.first->second = s;
if (state_to_name.size() < s + 1)
state_to_name.resize(s + 1);
state_to_name[s] = n;
return s;
}
return p.first->second;
}
@ -85,27 +85,27 @@ namespace spot
{
auto p = name_to_state.emplace(newname, s);
if (!p.second)
{
// The state already exists. Change its number.
auto old = p.first->second;
p.first->second = s;
// Add the successor of OLD to those of S.
auto& trans = g_.edge_vector();
auto& states = g_.states();
trans[states[s].succ_tail].next_succ = states[old].succ;
states[s].succ_tail = states[old].succ_tail;
states[old].succ = 0;
states[old].succ_tail = 0;
// Remove all references to old in edges:
unsigned tend = trans.size();
for (unsigned t = 1; t < tend; ++t)
{
if (trans[t].src == old)
trans[t].src = s;
if (trans[t].dst == old)
trans[t].dst = s;
}
}
{
// The state already exists. Change its number.
auto old = p.first->second;
p.first->second = s;
// Add the successor of OLD to those of S.
auto& trans = g_.edge_vector();
auto& states = g_.states();
trans[states[s].succ_tail].next_succ = states[old].succ;
states[s].succ_tail = states[old].succ_tail;
states[old].succ = 0;
states[old].succ_tail = 0;
// Remove all references to old in edges:
unsigned tend = trans.size();
for (unsigned t = 1; t < tend; ++t)
{
if (trans[t].src == old)
trans[t].src = s;
if (trans[t].dst == old)
trans[t].dst = s;
}
}
return !p.second;
}
@ -134,7 +134,7 @@ namespace spot
new_edge(name src, name dst, Args&&... args)
{
return g_.new_edge(get_state(src), get_state(dst),
std::forward<Args>(args)...);
std::forward<Args>(args)...);
}
template <typename... Args>
@ -144,19 +144,19 @@ namespace spot
std::vector<State_Name> d;
d.reserve(dst.size());
for (auto n: dst)
d.push_back(get_state(n));
d.push_back(get_state(n));
return g_.new_edge(get_state(src), d, std::forward<Args>(args)...);
}
template <typename... Args>
edge
new_edge(name src,
const std::initializer_list<State_Name>& dst, Args&&... args)
const std::initializer_list<State_Name>& dst, Args&&... args)
{
std::vector<state> d;
d.reserve(dst.size());
for (auto n: dst)
d.push_back(get_state(n));
d.push_back(get_state(n));
return g_.new_edge(get_state(src), d, std::forward<Args>(args)...);
}
};

View file

@ -46,16 +46,16 @@ namespace spot
// Do not simply return "other - this", it might not fit in an int.
if (o < this)
return -1;
return -1;
if (o > this)
return 1;
return 1;
return 0;
}
virtual size_t hash() const override
{
return
reinterpret_cast<const char*>(this) - static_cast<const char*>(nullptr);
reinterpret_cast<const char*>(this) - static_cast<const char*>(nullptr);
}
virtual kripke_graph_state*
@ -93,7 +93,7 @@ namespace spot
edge p_;
public:
kripke_graph_succ_iterator(const Graph* g,
const typename Graph::state_storage_t* s):
const typename Graph::state_storage_t* s):
kripke_succ_iterator(s->cond()),
g_(g),
t_(s->succ)
@ -131,7 +131,7 @@ namespace spot
{
assert(!done());
return const_cast<kripke_graph_state*>
(&g_->state_data(g_->edge_storage(p_).dst));
(&g_->state_data(g_->edge_storage(p_).dst));
}
};
@ -176,14 +176,14 @@ namespace spot
graph_t::state get_init_state_number() const
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
const_cast<graph_t&>(g_).new_state();
return init_number_;
}
virtual const kripke_graph_state* get_init_state() const override
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
const_cast<graph_t&>(g_).new_state();
return state_from_number(init_number_);
}
@ -197,13 +197,13 @@ namespace spot
assert(!s->succ || g_.valid_trans(s->succ));
if (this->iter_cache_)
{
auto it =
down_cast<kripke_graph_succ_iterator<graph_t>*>(this->iter_cache_);
it->recycle(s);
this->iter_cache_ = nullptr;
return it;
}
{
auto it =
down_cast<kripke_graph_succ_iterator<graph_t>*>(this->iter_cache_);
it->recycle(s);
this->iter_cache_ = nullptr;
return it;
}
return new kripke_graph_succ_iterator<graph_t>(&g_, s);
}

File diff suppressed because it is too large Load diff

View file

@ -67,9 +67,9 @@ namespace spot
// to enable compression, 2 to enable a faster compression that only
// work if all variables are smaller than 2^28.
kripke_ptr kripke(const atomic_prop_set* to_observe,
bdd_dict_ptr dict,
formula dead = formula::tt(),
int compress = 0) const;
bdd_dict_ptr dict,
formula dead = formula::tt(),
int compress = 0) const;
/// Number of variables in a state
int state_size() const;

View file

@ -32,12 +32,12 @@ namespace spot
{
// Bare words cannot be empty and should start with a letter.
if (!*str
|| !(isalpha(*str) || *str == '_' || *str == '.'))
|| !(isalpha(*str) || *str == '_' || *str == '.'))
return false;
// The remaining of the word must be alphanumeric.
while (*++str)
if (!(isalnum(*str) || *str == '_' || *str == '.'))
return false;
return false;
return true;
}
@ -58,7 +58,7 @@ namespace spot
return false;
while (*++str)
if (!(isalnum(*str) || *str == '_'))
return false;
return false;
return true;
}

View file

@ -39,7 +39,7 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t n = (bitcount + bpb - 1) / bpb;
if (n < 1)
return 1;
return 1;
return n;
}
@ -60,12 +60,12 @@ namespace spot
{
static unsigned long init()
{
return 14695981039346656037UL;
return 14695981039346656037UL;
}
static unsigned long prime()
{
return 1099511628211UL;
return 1099511628211UL;
}
};
#endif
@ -76,12 +76,12 @@ namespace spot
{
static unsigned long init()
{
return 2166136261UL;
return 2166136261UL;
}
static unsigned long prime()
{
return 16777619UL;
return 16777619UL;
}
};
@ -109,7 +109,7 @@ namespace spot
// already contains one int of local_storage_, but
// we allocate n-1 more so that we store the table.
void* mem = operator new(sizeof(bitvect)
+ (n - 1) * sizeof(bitvect::block_t));
+ (n - 1) * sizeof(bitvect::block_t));
bitvect* res = new(mem) bitvect(size_, n, true);
memcpy(res->storage_, storage_, res->block_count_ * sizeof(block_t));
return res;
@ -125,8 +125,8 @@ namespace spot
return res;
for (i = 0; i < m - 1; ++i)
{
res ^= storage_[i];
res *= fnv<sizeof(block_t)>::prime();
res ^= storage_[i];
res *= fnv<sizeof(block_t)>::prime();
}
// Deal with the last block, that might not be fully used.
// Compute the number n of bits used in the last block.
@ -144,7 +144,7 @@ namespace spot
// already contains one int of local_storage_, but
// we allocate n-1 more so that we store the table.
void* mem = operator new(sizeof(bitvect)
+ (n - 1) * sizeof(bitvect::block_t));
+ (n - 1) * sizeof(bitvect::block_t));
return new(mem) bitvect(bitcount, n);
}
@ -176,16 +176,16 @@ namespace spot
size_t end = a.size();
if (end == 0)
{
os << "empty\n";
return os;
os << "empty\n";
return os;
}
int w = floor(log10(end - 1)) + 1;
for (size_t i = 0; i != end; ++i)
{
os.width(w);
os << i;
os.width(1);
os << ": " << a.at(i) << '\n';
os.width(w);
os << i;
os.width(1);
os << ": " << a.at(i) << '\n';
}
return os;
}

View file

@ -44,7 +44,7 @@ namespace spot
///
/// The resulting bitvect_array should be released with <code>delete</code>.
SPOT_API bitvect_array* make_bitvect_array(size_t bitcount,
size_t vectcount);
size_t vectcount);
/// \brief A bit vector
class SPOT_API bitvect
@ -85,14 +85,14 @@ namespace spot
reserve_blocks(other.block_count_);
size_ = other.size();
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = other.storage_[i];
storage_[i] = other.storage_[i];
return *this;
}
~bitvect()
{
if (storage_ != &local_storage_)
free(storage_);
free(storage_);
}
/// Grow the bitvector to \a new_block_count blocks.
@ -101,20 +101,20 @@ namespace spot
void reserve_blocks(size_t new_block_count)
{
if (new_block_count < block_count_)
return;
return;
if (storage_ == &local_storage_)
{
block_t* new_storage_ = static_cast<block_t*>
(malloc(new_block_count * sizeof(block_t)));
for (size_t i = 0; i < block_count_; ++i)
new_storage_[i] = storage_[i];
storage_ = new_storage_;
}
{
block_t* new_storage_ = static_cast<block_t*>
(malloc(new_block_count * sizeof(block_t)));
for (size_t i = 0; i < block_count_; ++i)
new_storage_[i] = storage_[i];
storage_ = new_storage_;
}
else
{
storage_ = static_cast<block_t*>
(realloc(storage_, new_block_count * sizeof(block_t)));
}
{
storage_ = static_cast<block_t*>
(realloc(storage_, new_block_count * sizeof(block_t)));
}
block_count_ = new_block_count;
}
@ -137,44 +137,44 @@ namespace spot
void push_back(bool val)
{
if (size() == capacity())
grow();
grow();
size_t pos = size_++;
if (val)
set(pos);
set(pos);
else
clear(pos);
clear(pos);
}
/// \brief Append the lowest \a count bits of \a data.
void push_back(block_t data, unsigned count)
{
if (size() + count > capacity())
grow();
grow();
const size_t bpb = 8 * sizeof(block_t);
// Clear the higher bits.
if (count != bpb)
data &= (1UL << count) - 1;
data &= (1UL << count) - 1;
size_t n = size() % bpb;
size_t i = size_ / bpb;
size_ += count;
if (n == 0) // Aligned on block_t boundary
{
storage_[i] = data;
}
else // Only (bpb-n) bits free in this block.
{
// Take the lower bpb-n bits of data...
block_t mask = (1UL << (bpb - n)) - 1;
block_t data1 = (data & mask) << n;
mask <<= n;
// ... write them on the higher bpb-n bits of last block.
storage_[i] = (storage_[i] & ~mask) | data1;
// Write the remaining bits in the next block.
if (bpb - n < count)
storage_[i + 1] = data >> (bpb - n);
}
if (n == 0) // Aligned on block_t boundary
{
storage_[i] = data;
}
else // Only (bpb-n) bits free in this block.
{
// Take the lower bpb-n bits of data...
block_t mask = (1UL << (bpb - n)) - 1;
block_t data1 = (data & mask) << n;
mask <<= n;
// ... write them on the higher bpb-n bits of last block.
storage_[i] = (storage_[i] & ~mask) | data1;
// Write the remaining bits in the next block.
if (bpb - n < count)
storage_[i + 1] = data >> (bpb - n);
}
}
size_t size() const
@ -199,7 +199,7 @@ namespace spot
void clear_all()
{
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = 0;
storage_[i] = 0;
}
bool is_fully_clear() const
@ -208,12 +208,12 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < block_count_ - !!rest; ++i)
if (storage_[i] != 0)
return false;
if (storage_[i] != 0)
return false;
// The last block might not be fully used, compare only the
// relevant portion.
if (!rest)
return true;
return true;
block_t mask = (1UL << rest) - 1;
return (storage_[i] & mask) == 0;
}
@ -224,10 +224,10 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < block_count_ - !!rest; ++i)
if (storage_[i] != -1UL)
return false;
if (storage_[i] != -1UL)
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
@ -237,13 +237,13 @@ namespace spot
void set_all()
{
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = -1UL;
storage_[i] = -1UL;
}
void flip_all()
{
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = ~storage_[i];
storage_[i] = ~storage_[i];
}
void set(size_t pos)
@ -273,7 +273,7 @@ namespace spot
assert(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i)
storage_[i] |= other.storage_[i];
storage_[i] |= other.storage_[i];
return *this;
}
@ -282,7 +282,7 @@ namespace spot
assert(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i)
storage_[i] &= other.storage_[i];
storage_[i] &= other.storage_[i];
return *this;
}
@ -291,7 +291,7 @@ namespace spot
assert(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i)
storage_[i] ^= other.storage_[i];
storage_[i] ^= other.storage_[i];
return *this;
}
@ -299,7 +299,7 @@ namespace spot
{
assert(other.block_count_ <= block_count_);
for (size_t i = 0; i < other.block_count_; ++i)
storage_[i] &= ~other.storage_[i];
storage_[i] &= ~other.storage_[i];
return *this;
}
@ -311,33 +311,33 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < block_count_ - !!rest; ++i)
if ((storage_[i] & other.storage_[i]) != other.storage_[i])
return false;
if ((storage_[i] & other.storage_[i]) != other.storage_[i])
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
return ((storage_[i] & mask & other.storage_[i])
== (other.storage_[i] & mask));
== (other.storage_[i] & mask));
}
bool operator==(const bitvect& other) const
{
if (other.size_ != size_)
return false;
return false;
if (size_ == 0)
return true;
return true;
size_t i;
size_t m = other.used_blocks();
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < m - !!rest; ++i)
if (storage_[i] != other.storage_[i])
return false;
if (storage_[i] != other.storage_[i])
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
@ -352,18 +352,18 @@ namespace spot
bool operator<(const bitvect& other) const
{
if (size_ != other.size_)
return size_ < other.size_;
return size_ < other.size_;
if (size_ == 0)
return false;
return false;
size_t i;
size_t m = other.used_blocks();
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < m - !!rest; ++i)
if (storage_[i] > other.storage_[i])
return false;
if (storage_[i] > other.storage_[i])
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
@ -398,7 +398,7 @@ namespace spot
res->make_empty();
if (end == begin)
return res;
return res;
const size_t bpb = 8 * sizeof(bitvect::block_t);
@ -407,32 +407,32 @@ namespace spot
size_t indexe = (end - 1) / bpb;
if (indexb == indexe)
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, count);
}
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, count);
}
else
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, bpb - bitb);
count -= bpb - bitb;
while (count >= bpb)
{
++indexb;
res->push_back(storage_[indexb], bpb);
count -= bpb;
assert(indexb != indexe || count == 0);
}
if (count > 0)
{
++indexb;
assert(indexb == indexe);
assert(count == end % bpb);
res->push_back(storage_[indexb], count);
}
}
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, bpb - bitb);
count -= bpb - bitb;
while (count >= bpb)
{
++indexb;
res->push_back(storage_[indexb], bpb);
count -= bpb;
assert(indexb != indexe || count == 0);
}
if (count > 0)
{
++indexb;
assert(indexb == indexe);
assert(count == end % bpb);
res->push_back(storage_[indexb], count);
}
}
return res;
}
@ -441,12 +441,12 @@ namespace spot
/// Print a bitvect.
friend SPOT_API std::ostream& operator<<(std::ostream&,
const bitvect&);
const bitvect&);
private:
friend SPOT_API bitvect_array*
::spot::make_bitvect_array(size_t bitcount,
size_t vectcount);
size_t vectcount);
size_t size_;
size_t block_count_;
@ -485,7 +485,7 @@ namespace spot
~bitvect_array()
{
for (size_t i = 0; i < size_; ++i)
at(i).~bitvect();
at(i).~bitvect();
}
/// The number of bitvect in the array.
@ -506,7 +506,7 @@ namespace spot
// FIXME: This could be changed into a large memset if the
// individual vectors where not allowed to be reallocated.
for (unsigned s = 0; s < size_; s++)
at(s).clear_all();
at(s).clear_all();
}
/// Return the bit-vector at \a index.
@ -518,12 +518,12 @@ namespace spot
friend SPOT_API bitvect_array*
::spot::make_bitvect_array(size_t bitcount,
size_t vectcount);
size_t vectcount);
/// Print a bitvect_array.
friend SPOT_API std::ostream& operator<<(std::ostream&,
const bitvect_array&);
const bitvect_array&);
private:
size_t size_;

View file

@ -93,9 +93,9 @@
// The extra parentheses in assert() is so that this
// pattern is not caught by the style checker.
#define SPOT_UNREACHABLE() do { \
assert(!("unreachable code reached")); \
SPOT_UNREACHABLE_BUILTIN(); \
#define SPOT_UNREACHABLE() do { \
assert(!("unreachable code reached")); \
SPOT_UNREACHABLE_BUILTIN(); \
} while (0)
#define SPOT_UNIMPLEMENTED() throw std::runtime_error("unimplemented");

View file

@ -33,14 +33,14 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '"':
os << "\"\"";
break;
default:
os << i;
break;
}
{
case '"':
os << "\"\"";
break;
default:
os << i;
break;
}
return os;
}
@ -49,28 +49,28 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '~':
os << "\\text{\\textasciitilde}";
break;
case '^':
os << "\\text{\\textasciicircum}";
break;
case '\\':
os << "\\text{\\textbackslash}";
break;
case '&':
case '%':
case '$':
case '#':
case '_':
case '{':
case '}':
os << '\\';
default:
os << i;
break;
}
{
case '~':
os << "\\text{\\textasciitilde}";
break;
case '^':
os << "\\text{\\textasciicircum}";
break;
case '\\':
os << "\\text{\\textbackslash}";
break;
case '&':
case '%':
case '$':
case '#':
case '_':
case '{':
case '}':
os << '\\';
default:
os << i;
break;
}
return os;
}
@ -79,23 +79,23 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '&':
os << "&amp;";
break;
case '"':
os << "&quot;";
break;
case '<':
os << "&lt;";
break;
case '>':
os << "&gt;";
break;
default:
os << i;
break;
}
{
case '&':
os << "&amp;";
break;
case '"':
os << "&quot;";
break;
case '<':
os << "&lt;";
break;
case '>':
os << "&gt;";
break;
default:
os << i;
break;
}
return os;
}
@ -104,20 +104,20 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '\\':
os << "\\\\";
break;
case '"':
os << "\\\"";
break;
case '\n':
os << "\\n";
break;
default:
os << i;
break;
}
{
case '\\':
os << "\\\\";
break;
case '"':
os << "\\\"";
break;
case '\n':
os << "\\n";
break;
default:
os << i;
break;
}
return os;
}
@ -135,26 +135,26 @@ namespace spot
// Single quotes are best, unless the string to quote contains one.
if (!strchr(str, '\''))
{
os << '\'' << str << '\'';
os << '\'' << str << '\'';
}
else
{
// In double quotes we have to escape $ ` " or \.
os << '"';
while (*str)
switch (*str)
{
case '$':
case '`':
case '"':
case '\\':
os << '\\';
// fall through
default:
os << *str++;
break;
}
os << '"';
// In double quotes we have to escape $ ` " or \.
os << '"';
while (*str)
switch (*str)
{
case '$':
case '`':
case '"':
case '\\':
os << '\\';
// fall through
default:
os << *str++;
break;
}
os << '"';
}
return os;
}

View file

@ -34,22 +34,22 @@ namespace spot
/// Create a pool allocating objects of \a size bytes.
fixed_size_pool(size_t size)
: freelist_(nullptr), free_start_(nullptr),
free_end_(nullptr), chunklist_(nullptr)
free_end_(nullptr), chunklist_(nullptr)
{
const size_t alignement = 2 * sizeof(size_t);
size_ = ((size >= sizeof(block_) ? size : sizeof(block_))
+ alignement - 1) & ~(alignement - 1);
+ alignement - 1) & ~(alignement - 1);
}
/// Free any memory allocated by this pool.
~fixed_size_pool()
{
while (chunklist_)
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
}
/// Allocate \a size bytes of memory.
@ -59,27 +59,27 @@ namespace spot
block_* f = freelist_;
// If we have free blocks available, return the first one.
if (f)
{
freelist_ = f->next;
return f;
}
{
freelist_ = f->next;
return f;
}
// Else, create a block out of the last chunk of allocated
// memory.
// If all the last chunk has been used, allocate one more.
if (free_start_ + size_ > free_end_)
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
free_start_ = c->data_ + size_;
free_end_ = c->data_ + requested;
}
free_start_ = c->data_ + size_;
free_end_ = c->data_ + requested;
}
void* res = free_start_;
free_start_ += size_;

View file

@ -28,12 +28,12 @@ namespace spot
{
for (const char* pos = fmt; *pos; ++pos)
if (*pos == '%')
{
char c = *++pos;
has[c] = true;
if (!c)
break;
}
{
char c = *++pos;
has[c] = true;
if (!c)
break;
}
}
void
@ -46,17 +46,17 @@ namespace spot
formater::format(const char* fmt)
{
for (const char* pos = fmt; *pos; ++pos)
if (*pos != '%')
{
*output_ << *pos;
}
else
{
char c = *++pos;
call_[c]->print(*output_, pos);
if (!c)
break;
}
if (*pos != '%')
{
*output_ << *pos;
}
else
{
char c = *++pos;
call_[c]->print(*output_, pos);
if (!c)
break;
}
return *output_;
}
}

View file

@ -49,7 +49,7 @@ namespace spot
size_t operator()(const T* p) const
{
return knuth32_hash(reinterpret_cast<const char*>(p)
- static_cast<const char*>(nullptr));
- static_cast<const char*>(nullptr));
}
};
@ -85,7 +85,7 @@ namespace spot
std::hash<U> uh;
return wang32_hash(static_cast<size_t>(th(p.first)) ^
static_cast<size_t>(uh(p.second)));
static_cast<size_t>(uh(p.second)));
}
};
}

View file

@ -43,270 +43,270 @@ namespace spot
{
public:
stream_compression_base(size_t size)
: size_(size)
: size_(size)
{
}
void run()
{
static const unsigned bits_width[7] = { 1, 3, 5, 7, 9, 14, 28 };
static const unsigned max_count[8] = { 30, 10, 6, 4, 3, 2, 1, 0 };
static const unsigned max_allowed[8] = { 1,
(1 << 3) - 1,
(1 << 5) - 1,
(1 << 7) - 1,
(1 << 9) - 1,
(1 << 14) - 1,
(1 << 28) - 1,
-1U };
// If we have only X data to compress and they fit with the
// current bit width, the following table tells us we should
// use bits_width[count_to_level[X - 1]] to limit the number
// of trailing zeros we encode. E.g. count_to_level[5 - 1]
// is 2, which mean that 5 values should be encoded with
// bits_width[2] == 5 bits.
static const unsigned count_to_level[30] =
{
6, // 1
5, // 2
4, // 3
3, // 4
2, // 5
2, // 6
1, // 7
1, // 8
1, // 9
1, // 10
0, 0, 0, 0, 0, // 11-15
0, 0, 0, 0, 0, // 16-20
0, 0, 0, 0, 0, // 21-25
0, 0, 0, 0, 0, // 26-30
};
static const unsigned bits_width[7] = { 1, 3, 5, 7, 9, 14, 28 };
static const unsigned max_count[8] = { 30, 10, 6, 4, 3, 2, 1, 0 };
static const unsigned max_allowed[8] = { 1,
(1 << 3) - 1,
(1 << 5) - 1,
(1 << 7) - 1,
(1 << 9) - 1,
(1 << 14) - 1,
(1 << 28) - 1,
-1U };
// If we have only X data to compress and they fit with the
// current bit width, the following table tells us we should
// use bits_width[count_to_level[X - 1]] to limit the number
// of trailing zeros we encode. E.g. count_to_level[5 - 1]
// is 2, which mean that 5 values should be encoded with
// bits_width[2] == 5 bits.
static const unsigned count_to_level[30] =
{
6, // 1
5, // 2
4, // 3
3, // 4
2, // 5
2, // 6
1, // 7
1, // 8
1, // 9
1, // 10
0, 0, 0, 0, 0, // 11-15
0, 0, 0, 0, 0, // 16-20
0, 0, 0, 0, 0, // 21-25
0, 0, 0, 0, 0, // 26-30
};
while (size_ > 0)
{
unsigned id = 0; // Current level in the above two tables.
unsigned curmax_allowed = max_allowed[id];
unsigned compressable = 0; // Number of integers ready to pack.
do
{
unsigned int val = self().data_at(compressable);
++compressable;
while (val > curmax_allowed)
{
curmax_allowed = max_allowed[++id];
while (size_ > 0)
{
unsigned id = 0; // Current level in the above two tables.
unsigned curmax_allowed = max_allowed[id];
unsigned compressable = 0; // Number of integers ready to pack.
do
{
unsigned int val = self().data_at(compressable);
++compressable;
while (val > curmax_allowed)
{
curmax_allowed = max_allowed[++id];
if (compressable > max_count[id])
goto fast_encode;
}
if (compressable >= max_count[id])
goto fast_encode;
}
while (SPOT_LIKELY(compressable < size_));
if (compressable > max_count[id])
goto fast_encode;
}
if (compressable >= max_count[id])
goto fast_encode;
}
while (SPOT_LIKELY(compressable < size_));
assert(compressable < max_count[id]);
assert(compressable < max_count[id]);
// Since we have less data than the current "id" allows,
// try to use more bits so we can encode faster.
// Since we have less data than the current "id" allows,
// try to use more bits so we can encode faster.
id = count_to_level[compressable - 1];
id = count_to_level[compressable - 1];
if (compressable == max_count[id])
goto fast_encode;
if (compressable == max_count[id])
goto fast_encode;
// Slow compression for situations where we have
// compressable < max_count[id]. We can only be in
// one of the 3 first "id" (1, 3, or 5 bits);
{
assert(id <= 2);
unsigned bits = bits_width[id];
unsigned finalshifts = (max_count[id] - compressable) * bits;
size_t pos = 0;
unsigned output = self().data_at(pos);
while (--compressable)
{
output <<= bits;
output += self().data_at(++pos);
}
output <<= finalshifts;
output += id << 30;
self().push_data(output);
return;
}
// Slow compression for situations where we have
// compressable < max_count[id]. We can only be in
// one of the 3 first "id" (1, 3, or 5 bits);
{
assert(id <= 2);
unsigned bits = bits_width[id];
unsigned finalshifts = (max_count[id] - compressable) * bits;
size_t pos = 0;
unsigned output = self().data_at(pos);
while (--compressable)
{
output <<= bits;
output += self().data_at(++pos);
}
output <<= finalshifts;
output += id << 30;
self().push_data(output);
return;
}
fast_encode:
switch (id)
{
case 0: // 30 1-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 1;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*2]
//
// This optimization is the reason why we use 'output +='
// instead of the more intuitive 'output |=' everywhere in
// this file.
fast_encode:
switch (id)
{
case 0: // 30 1-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 1;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*2]
//
// This optimization is the reason why we use 'output +='
// instead of the more intuitive 'output |=' everywhere in
// this file.
unsigned int output = 0x00 << 1; // 00
output += self().data_at(0);
output <<= 1;
output += self().data_at(1);
output <<= 1;
output += self().data_at(2);
output <<= 1;
output += self().data_at(3);
output <<= 1;
output += self().data_at(4);
output <<= 1;
output += self().data_at(5);
output <<= 1;
output += self().data_at(6);
output <<= 1;
output += self().data_at(7);
output <<= 1;
output += self().data_at(8);
output <<= 1;
output += self().data_at(9);
output <<= 1;
output += self().data_at(10);
output <<= 1;
output += self().data_at(11);
output <<= 1;
output += self().data_at(12);
output <<= 1;
output += self().data_at(13);
output <<= 1;
output += self().data_at(14);
output <<= 1;
output += self().data_at(15);
output <<= 1;
output += self().data_at(16);
output <<= 1;
output += self().data_at(17);
output <<= 1;
output += self().data_at(18);
output <<= 1;
output += self().data_at(19);
output <<= 1;
output += self().data_at(20);
output <<= 1;
output += self().data_at(21);
output <<= 1;
output += self().data_at(22);
output <<= 1;
output += self().data_at(23);
output <<= 1;
output += self().data_at(24);
output <<= 1;
output += self().data_at(25);
output <<= 1;
output += self().data_at(26);
output <<= 1;
output += self().data_at(27);
output <<= 1;
output += self().data_at(28);
output <<= 1;
output += self().data_at(29);
self().push_data(output);
}
break;
case 1: // 10 3-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 3;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*8]
unsigned int output = 0x00 << 1; // 00
output += self().data_at(0);
output <<= 1;
output += self().data_at(1);
output <<= 1;
output += self().data_at(2);
output <<= 1;
output += self().data_at(3);
output <<= 1;
output += self().data_at(4);
output <<= 1;
output += self().data_at(5);
output <<= 1;
output += self().data_at(6);
output <<= 1;
output += self().data_at(7);
output <<= 1;
output += self().data_at(8);
output <<= 1;
output += self().data_at(9);
output <<= 1;
output += self().data_at(10);
output <<= 1;
output += self().data_at(11);
output <<= 1;
output += self().data_at(12);
output <<= 1;
output += self().data_at(13);
output <<= 1;
output += self().data_at(14);
output <<= 1;
output += self().data_at(15);
output <<= 1;
output += self().data_at(16);
output <<= 1;
output += self().data_at(17);
output <<= 1;
output += self().data_at(18);
output <<= 1;
output += self().data_at(19);
output <<= 1;
output += self().data_at(20);
output <<= 1;
output += self().data_at(21);
output <<= 1;
output += self().data_at(22);
output <<= 1;
output += self().data_at(23);
output <<= 1;
output += self().data_at(24);
output <<= 1;
output += self().data_at(25);
output <<= 1;
output += self().data_at(26);
output <<= 1;
output += self().data_at(27);
output <<= 1;
output += self().data_at(28);
output <<= 1;
output += self().data_at(29);
self().push_data(output);
}
break;
case 1: // 10 3-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 3;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*8]
unsigned int output = 0x01 << 3; // 01
output += self().data_at(0);
output <<= 3;
output += self().data_at(1);
output <<= 3;
output += self().data_at(2);
output <<= 3;
output += self().data_at(3);
output <<= 3;
output += self().data_at(4);
output <<= 3;
output += self().data_at(5);
output <<= 3;
output += self().data_at(6);
output <<= 3;
output += self().data_at(7);
output <<= 3;
output += self().data_at(8);
output <<= 3;
output += self().data_at(9);
self().push_data(output);
}
break;
case 2: // 6 5-bit values
{
unsigned int output = 0x02U << 30; // 10
output += self().data_at(0) << 25;
output += self().data_at(1) << 20;
output += self().data_at(2) << 15;
output += self().data_at(3) << 10;
output += self().data_at(4) << 5;
output += self().data_at(5);
self().push_data(output);
}
break;
case 3: // 4 7-bit values
{
unsigned int output = 0x0CU << 28; // 1100
output += self().data_at(0) << 21;
output += self().data_at(1) << 14;
output += self().data_at(2) << 7;
output += self().data_at(3);
self().push_data(output);
}
break;
case 4: // 3 9-bit values
{
unsigned int output = 0x0DU << 28; // 1101x (1 bit lost)
output += self().data_at(0) << 18;
output += self().data_at(1) << 9;
output += self().data_at(2);
self().push_data(output);
}
break;
case 5: // 2 14-bit values
{
unsigned int output = 0x0EU << 28; // 1110
output += self().data_at(0) << 14;
output += self().data_at(1);
self().push_data(output);
}
break;
case 6: // one 28-bit value
{
unsigned int output = 0x0FU << 28; // 1111
output += self().data_at(0);
self().push_data(output);
}
break;
}
self().forward(max_count[id]);
size_ -= max_count[id];
}
unsigned int output = 0x01 << 3; // 01
output += self().data_at(0);
output <<= 3;
output += self().data_at(1);
output <<= 3;
output += self().data_at(2);
output <<= 3;
output += self().data_at(3);
output <<= 3;
output += self().data_at(4);
output <<= 3;
output += self().data_at(5);
output <<= 3;
output += self().data_at(6);
output <<= 3;
output += self().data_at(7);
output <<= 3;
output += self().data_at(8);
output <<= 3;
output += self().data_at(9);
self().push_data(output);
}
break;
case 2: // 6 5-bit values
{
unsigned int output = 0x02U << 30; // 10
output += self().data_at(0) << 25;
output += self().data_at(1) << 20;
output += self().data_at(2) << 15;
output += self().data_at(3) << 10;
output += self().data_at(4) << 5;
output += self().data_at(5);
self().push_data(output);
}
break;
case 3: // 4 7-bit values
{
unsigned int output = 0x0CU << 28; // 1100
output += self().data_at(0) << 21;
output += self().data_at(1) << 14;
output += self().data_at(2) << 7;
output += self().data_at(3);
self().push_data(output);
}
break;
case 4: // 3 9-bit values
{
unsigned int output = 0x0DU << 28; // 1101x (1 bit lost)
output += self().data_at(0) << 18;
output += self().data_at(1) << 9;
output += self().data_at(2);
self().push_data(output);
}
break;
case 5: // 2 14-bit values
{
unsigned int output = 0x0EU << 28; // 1110
output += self().data_at(0) << 14;
output += self().data_at(1);
self().push_data(output);
}
break;
case 6: // one 28-bit value
{
unsigned int output = 0x0FU << 28; // 1111
output += self().data_at(0);
self().push_data(output);
}
break;
}
self().forward(max_count[id]);
size_ -= max_count[id];
}
}
protected:
@ -315,12 +315,12 @@ namespace spot
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
};
@ -331,29 +331,29 @@ namespace spot
{
public:
int_array_array_compression(const int* array, size_t n,
int* dest, size_t& dest_n)
: stream_compression_base<int_array_array_compression>(n),
array_(array), result_size_(dest_n),
result_(dest), result_end_(dest + dest_n)
int* dest, size_t& dest_n)
: stream_compression_base<int_array_array_compression>(n),
array_(array), result_size_(dest_n),
result_(dest), result_end_(dest + dest_n)
{
result_size_ = 0; // this resets dest_n.
result_size_ = 0; // this resets dest_n.
}
void push_data(unsigned int i)
{
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
}
unsigned int data_at(size_t offset)
{
return static_cast<unsigned int>(array_[offset]);
return static_cast<unsigned int>(array_[offset]);
}
void forward(size_t offset)
{
array_ += offset;
array_ += offset;
}
protected:
@ -368,7 +368,7 @@ namespace spot
void
int_array_array_compress2(const int* array, size_t n,
int* dest, size_t& dest_size)
int* dest, size_t& dest_size)
{
int_array_array_compression c(array, n, dest, dest_size);
c.run();
@ -386,113 +386,113 @@ namespace spot
void run()
{
while (SPOT_LIKELY(self().have_comp_data()))
{
unsigned val = self().next_comp_data();
while (SPOT_LIKELY(self().have_comp_data()))
{
unsigned val = self().next_comp_data();
unsigned id = val >> 28;
switch (id)
{
case 0x00: // 00xx - 30 1-bit values.
case 0x01:
case 0x02:
case 0x03:
self().write_data_at(0, !!(val & (1 << 29)));
self().write_data_at(1, !!(val & (1 << 28)));
self().write_data_at(2, !!(val & (1 << 27)));
self().write_data_at(3, !!(val & (1 << 26)));
self().write_data_at(4, !!(val & (1 << 25)));
self().write_data_at(5, !!(val & (1 << 24)));
self().write_data_at(6, !!(val & (1 << 23)));
self().write_data_at(7, !!(val & (1 << 22)));
self().write_data_at(8, !!(val & (1 << 21)));
self().write_data_at(9, !!(val & (1 << 20)));
self().write_data_at(10, !!(val & (1 << 19)));
self().write_data_at(11, !!(val & (1 << 18)));
self().write_data_at(12, !!(val & (1 << 17)));
self().write_data_at(13, !!(val & (1 << 16)));
self().write_data_at(14, !!(val & (1 << 15)));
self().write_data_at(15, !!(val & (1 << 14)));
self().write_data_at(16, !!(val & (1 << 13)));
self().write_data_at(17, !!(val & (1 << 12)));
self().write_data_at(18, !!(val & (1 << 11)));
self().write_data_at(19, !!(val & (1 << 10)));
self().write_data_at(20, !!(val & (1 << 9)));
self().write_data_at(21, !!(val & (1 << 8)));
self().write_data_at(22, !!(val & (1 << 7)));
self().write_data_at(23, !!(val & (1 << 6)));
self().write_data_at(24, !!(val & (1 << 5)));
self().write_data_at(25, !!(val & (1 << 4)));
self().write_data_at(26, !!(val & (1 << 3)));
self().write_data_at(27, !!(val & (1 << 2)));
self().write_data_at(28, !!(val & (1 << 1)));
self().write_data_at(29, !!(val & (1 << 0)));
self().forward(30);
break;
case 0x04: // 01xx - 10 3-bit values.
case 0x05:
case 0x06:
case 0x07:
self().write_data_at(0, (val >> 27) & 0x07);
self().write_data_at(1, (val >> 24) & 0x07);
self().write_data_at(2, (val >> 21) & 0x07);
self().write_data_at(3, (val >> 18) & 0x07);
self().write_data_at(4, (val >> 15) & 0x07);
self().write_data_at(5, (val >> 12) & 0x07);
self().write_data_at(6, (val >> 9) & 0x07);
self().write_data_at(7, (val >> 6) & 0x07);
self().write_data_at(8, (val >> 3) & 0x07);
self().write_data_at(9, (val >> 0) & 0x07);
self().forward(10);
break;
case 0x08: // 10xx - 6 5-bit values.
case 0x09:
case 0x0A:
case 0x0B:
self().write_data_at(0, (val >> 25) & 0x1F);
self().write_data_at(1, (val >> 20) & 0x1F);
self().write_data_at(2, (val >> 15) & 0x1F);
self().write_data_at(3, (val >> 10) & 0x1F);
self().write_data_at(4, (val >> 5) & 0x1F);
self().write_data_at(5, (val >> 0) & 0x1F);
self().forward(6);
break;
case 0x0C: // 1100 - 4 7-bit values
self().write_data_at(0, (val >> 21) & 0x7F);
self().write_data_at(1, (val >> 14) & 0x7F);
self().write_data_at(2, (val >> 7) & 0x7F);
self().write_data_at(3, (val >> 0) & 0x7F);
self().forward(4);
break;
case 0x0D: // 1101x - 3 9-bit values.
self().write_data_at(0, (val >> 18) & 0x1FF);
self().write_data_at(1, (val >> 9) & 0x1FF);
self().write_data_at(2, (val >> 0) & 0x1FF);
self().forward(3);
break;
case 0x0E: // 110x - 2 14-bit values.
self().write_data_at(0, (val >> 14) & 0x3FFF);
self().write_data_at(1, (val >> 0) & 0x3FFF);
self().forward(2);
break;
case 0x0F: // 1100 - 1 28-bit value.
self().write_data_at(0, val & 0xFFFFFFF);
self().forward(1);
break;
}
}
unsigned id = val >> 28;
switch (id)
{
case 0x00: // 00xx - 30 1-bit values.
case 0x01:
case 0x02:
case 0x03:
self().write_data_at(0, !!(val & (1 << 29)));
self().write_data_at(1, !!(val & (1 << 28)));
self().write_data_at(2, !!(val & (1 << 27)));
self().write_data_at(3, !!(val & (1 << 26)));
self().write_data_at(4, !!(val & (1 << 25)));
self().write_data_at(5, !!(val & (1 << 24)));
self().write_data_at(6, !!(val & (1 << 23)));
self().write_data_at(7, !!(val & (1 << 22)));
self().write_data_at(8, !!(val & (1 << 21)));
self().write_data_at(9, !!(val & (1 << 20)));
self().write_data_at(10, !!(val & (1 << 19)));
self().write_data_at(11, !!(val & (1 << 18)));
self().write_data_at(12, !!(val & (1 << 17)));
self().write_data_at(13, !!(val & (1 << 16)));
self().write_data_at(14, !!(val & (1 << 15)));
self().write_data_at(15, !!(val & (1 << 14)));
self().write_data_at(16, !!(val & (1 << 13)));
self().write_data_at(17, !!(val & (1 << 12)));
self().write_data_at(18, !!(val & (1 << 11)));
self().write_data_at(19, !!(val & (1 << 10)));
self().write_data_at(20, !!(val & (1 << 9)));
self().write_data_at(21, !!(val & (1 << 8)));
self().write_data_at(22, !!(val & (1 << 7)));
self().write_data_at(23, !!(val & (1 << 6)));
self().write_data_at(24, !!(val & (1 << 5)));
self().write_data_at(25, !!(val & (1 << 4)));
self().write_data_at(26, !!(val & (1 << 3)));
self().write_data_at(27, !!(val & (1 << 2)));
self().write_data_at(28, !!(val & (1 << 1)));
self().write_data_at(29, !!(val & (1 << 0)));
self().forward(30);
break;
case 0x04: // 01xx - 10 3-bit values.
case 0x05:
case 0x06:
case 0x07:
self().write_data_at(0, (val >> 27) & 0x07);
self().write_data_at(1, (val >> 24) & 0x07);
self().write_data_at(2, (val >> 21) & 0x07);
self().write_data_at(3, (val >> 18) & 0x07);
self().write_data_at(4, (val >> 15) & 0x07);
self().write_data_at(5, (val >> 12) & 0x07);
self().write_data_at(6, (val >> 9) & 0x07);
self().write_data_at(7, (val >> 6) & 0x07);
self().write_data_at(8, (val >> 3) & 0x07);
self().write_data_at(9, (val >> 0) & 0x07);
self().forward(10);
break;
case 0x08: // 10xx - 6 5-bit values.
case 0x09:
case 0x0A:
case 0x0B:
self().write_data_at(0, (val >> 25) & 0x1F);
self().write_data_at(1, (val >> 20) & 0x1F);
self().write_data_at(2, (val >> 15) & 0x1F);
self().write_data_at(3, (val >> 10) & 0x1F);
self().write_data_at(4, (val >> 5) & 0x1F);
self().write_data_at(5, (val >> 0) & 0x1F);
self().forward(6);
break;
case 0x0C: // 1100 - 4 7-bit values
self().write_data_at(0, (val >> 21) & 0x7F);
self().write_data_at(1, (val >> 14) & 0x7F);
self().write_data_at(2, (val >> 7) & 0x7F);
self().write_data_at(3, (val >> 0) & 0x7F);
self().forward(4);
break;
case 0x0D: // 1101x - 3 9-bit values.
self().write_data_at(0, (val >> 18) & 0x1FF);
self().write_data_at(1, (val >> 9) & 0x1FF);
self().write_data_at(2, (val >> 0) & 0x1FF);
self().forward(3);
break;
case 0x0E: // 110x - 2 14-bit values.
self().write_data_at(0, (val >> 14) & 0x3FFF);
self().write_data_at(1, (val >> 0) & 0x3FFF);
self().forward(2);
break;
case 0x0F: // 1100 - 1 28-bit value.
self().write_data_at(0, val & 0xFFFFFFF);
self().forward(1);
break;
}
}
}
protected:
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
};
@ -502,30 +502,30 @@ namespace spot
{
public:
int_array_array_decompression(const int* array,
size_t array_size,
int* res)
: array_(array), n_(array_size), pos_(0), result_(res)
size_t array_size,
int* res)
: array_(array), n_(array_size), pos_(0), result_(res)
{
}
void write_data_at(size_t pos, unsigned int i)
{
result_[pos] = i;
result_[pos] = i;
}
void forward(size_t i)
{
result_ += i;
result_ += i;
}
bool have_comp_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_comp_data()
{
return array_[pos_++];
return array_[pos_++];
}
protected:
@ -540,7 +540,7 @@ namespace spot
void
int_array_array_decompress2(const int* array, size_t array_size, int* res,
size_t)
size_t)
{
int_array_array_decompression c(array, array_size, res);
c.run();

View file

@ -36,7 +36,7 @@ namespace spot
/// filled in \a dest
SPOT_API void
int_array_array_compress2(const int* array, size_t n,
int* dest, size_t& dest_size);
int* dest, size_t& dest_size);
/// \brief Uncompress an int array of size \a array_size into a int
/// array of size \a size.
@ -44,7 +44,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_array_array_decompress2(const int* array, size_t array_size,
int* res, size_t size);
int* res, size_t size);
/// @}
}

View file

@ -55,129 +55,129 @@ namespace spot
public:
stream_compression_base()
: cur_(0), bits_left_(max_bits)
: cur_(0), bits_left_(max_bits)
{
}
void emit(unsigned int val)
{
if (val == 0)
{
self().push_bits(0x0, 2, 0x3);
}
else if (val == 1)
{
self().push_bits(0x2, 3, 0x7);
}
else if (val >= 2 && val <= 5)
{
self().push_bits(0x3, 3, 0x7);
self().push_bits(val - 2, 2, 0x3);
}
else if (val >= 6 && val <= 22)
{
self().push_bits(0x4, 3, 0x7);
self().push_bits(val - 6, 4, 0xf);
}
else
{
assert(val > 22);
self().push_bits(0x7, 3, 0x7);
self().push_bits(val, 32, -1U);
}
if (val == 0)
{
self().push_bits(0x0, 2, 0x3);
}
else if (val == 1)
{
self().push_bits(0x2, 3, 0x7);
}
else if (val >= 2 && val <= 5)
{
self().push_bits(0x3, 3, 0x7);
self().push_bits(val - 2, 2, 0x3);
}
else if (val >= 6 && val <= 22)
{
self().push_bits(0x4, 3, 0x7);
self().push_bits(val - 6, 4, 0xf);
}
else
{
assert(val > 22);
self().push_bits(0x7, 3, 0x7);
self().push_bits(val, 32, -1U);
}
}
void run()
{
unsigned int last_val = 0;
unsigned int last_val = 0;
while (SPOT_LIKELY(self().have_data()))
{
unsigned int val = self().next_data();
// Repeated value? Try to find more.
if (val == last_val)
{
unsigned int count = 1;
while (count < 40 && self().skip_if(val))
++count;
while (SPOT_LIKELY(self().have_data()))
{
unsigned int val = self().next_data();
// Repeated value? Try to find more.
if (val == last_val)
{
unsigned int count = 1;
while (count < 40 && self().skip_if(val))
++count;
if ((val == 0 && count < 3) || (val == 1 && count == 1))
{
// it is more efficient to emit 0 once or twice directly
// (e.g., 00 00 vs. 011 11)
// for value 1, repetition is worthwhile for count > 1
// (e.g., 010 010 vs. 011 00)
while (count--)
emit(val);
}
else if (count < 9)
{
self().push_bits(0x5, 3, 0x7);
self().push_bits(count - 1, 3, 0x7);
}
else
{
self().push_bits(0x6, 3, 0x7);
self().push_bits(count - 9, 5, 0x1f);
}
}
else
{
emit(val);
last_val = val;
}
}
flush();
if ((val == 0 && count < 3) || (val == 1 && count == 1))
{
// it is more efficient to emit 0 once or twice directly
// (e.g., 00 00 vs. 011 11)
// for value 1, repetition is worthwhile for count > 1
// (e.g., 010 010 vs. 011 00)
while (count--)
emit(val);
}
else if (count < 9)
{
self().push_bits(0x5, 3, 0x7);
self().push_bits(count - 1, 3, 0x7);
}
else
{
self().push_bits(0x6, 3, 0x7);
self().push_bits(count - 9, 5, 0x1f);
}
}
else
{
emit(val);
last_val = val;
}
}
flush();
}
// This version assumes there is at least n bits free in cur_.
void
push_bits_unchecked(unsigned int bits, unsigned int n, unsigned int mask)
{
cur_ <<= n;
cur_ |= (bits & mask);
if (SPOT_LIKELY(bits_left_ -= n))
return;
cur_ <<= n;
cur_ |= (bits & mask);
if (SPOT_LIKELY(bits_left_ -= n))
return;
self().push_data(cur_);
cur_ = 0;
bits_left_ = max_bits;
self().push_data(cur_);
cur_ = 0;
bits_left_ = max_bits;
}
void
push_bits(unsigned int bits, unsigned int n, unsigned int mask)
{
if (SPOT_LIKELY(n <= bits_left_))
{
push_bits_unchecked(bits, n, mask);
return;
}
if (SPOT_LIKELY(n <= bits_left_))
{
push_bits_unchecked(bits, n, mask);
return;
}
// bits_left_ < n
// bits_left_ < n
unsigned int right_bit_count = n - bits_left_;
unsigned int left = bits >> right_bit_count;
push_bits_unchecked(left, bits_left_, (1 << bits_left_) - 1);
push_bits_unchecked(bits, right_bit_count, (1 << right_bit_count) - 1);
unsigned int right_bit_count = n - bits_left_;
unsigned int left = bits >> right_bit_count;
push_bits_unchecked(left, bits_left_, (1 << bits_left_) - 1);
push_bits_unchecked(bits, right_bit_count, (1 << right_bit_count) - 1);
}
void flush()
{
if (bits_left_ == max_bits)
return;
cur_ <<= bits_left_;
self().push_data(cur_);
if (bits_left_ == max_bits)
return;
cur_ <<= bits_left_;
self().push_data(cur_);
}
protected:
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
unsigned int cur_;
@ -189,41 +189,41 @@ namespace spot
{
public:
int_array_vector_compression(const int* array, size_t n)
: array_(array), n_(n), pos_(0), result_(new std::vector<unsigned int>)
: array_(array), n_(n), pos_(0), result_(new std::vector<unsigned int>)
{
}
void push_data(unsigned int i)
{
result_->push_back(i);
result_->push_back(i);
}
const std::vector<unsigned int>*
result() const
{
return result_;
return result_;
}
bool have_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_data()
{
return static_cast<unsigned int>(array_[pos_++]);
return static_cast<unsigned int>(array_[pos_++]);
}
bool skip_if(unsigned int val)
{
if (SPOT_UNLIKELY(!have_data()))
return false;
if (SPOT_UNLIKELY(!have_data()))
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
++pos_;
return true;
++pos_;
return true;
}
protected:
@ -238,36 +238,36 @@ namespace spot
{
public:
int_vector_vector_compression(const std::vector<int>& input,
std::vector<unsigned int>& output)
: input_(input), pos_(input.begin()), end_(input.end()), output_(output)
std::vector<unsigned int>& output)
: input_(input), pos_(input.begin()), end_(input.end()), output_(output)
{
}
void push_data(unsigned int i)
{
output_.push_back(i);
output_.push_back(i);
}
bool have_data() const
{
return pos_ < end_;
return pos_ < end_;
}
unsigned int next_data()
{
return static_cast<unsigned int>(*pos_++);
return static_cast<unsigned int>(*pos_++);
}
bool skip_if(unsigned int val)
{
if (SPOT_UNLIKELY(!have_data()))
return false;
if (SPOT_UNLIKELY(!have_data()))
return false;
if (static_cast<unsigned int>(*pos_) != val)
return false;
if (static_cast<unsigned int>(*pos_) != val)
return false;
++pos_;
return true;
++pos_;
return true;
}
protected:
@ -282,40 +282,40 @@ namespace spot
{
public:
int_array_array_compression(const int* array, size_t n,
int* dest, size_t& dest_n)
: array_(array), n_(n), pos_(0),
result_size_(dest_n), result_(dest), result_end_(dest + dest_n)
int* dest, size_t& dest_n)
: array_(array), n_(n), pos_(0),
result_size_(dest_n), result_(dest), result_end_(dest + dest_n)
{
result_size_ = 0; // this resets dest_n.
result_size_ = 0; // this resets dest_n.
}
void push_data(unsigned int i)
{
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
}
bool have_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_data()
{
return static_cast<unsigned int>(array_[pos_++]);
return static_cast<unsigned int>(array_[pos_++]);
}
bool skip_if(unsigned int val)
{
if (SPOT_UNLIKELY(!have_data()))
return false;
if (SPOT_UNLIKELY(!have_data()))
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
++pos_;
return true;
++pos_;
return true;
}
protected:
@ -330,7 +330,7 @@ namespace spot
void
int_vector_vector_compress(const std::vector<int>& input,
std::vector<unsigned>& output)
std::vector<unsigned>& output)
{
int_vector_vector_compression c(input, output);
c.run();
@ -346,7 +346,7 @@ namespace spot
void
int_array_array_compress(const int* array, size_t n,
int* dest, size_t& dest_size)
int* dest, size_t& dest_size)
{
int_array_array_compression c(array, n, dest, dest_size);
c.run();
@ -365,154 +365,154 @@ namespace spot
public:
void refill()
{
if (SPOT_UNLIKELY(look_bits_ == 0))
{
look_bits_ = max_bits;
look_ = buffer_;
if (SPOT_UNLIKELY(look_bits_ == 0))
{
look_bits_ = max_bits;
look_ = buffer_;
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
if (SPOT_LIKELY(buffer_bits_ != max_bits))
{
unsigned int fill_size = max_bits - buffer_bits_;
look_ <<= fill_size;
look_ |= buffer_ >> buffer_bits_;
}
}
else
{
unsigned int fill_size = max_bits - look_bits_;
if (fill_size > buffer_bits_)
fill_size = buffer_bits_;
if (SPOT_LIKELY(buffer_bits_ != max_bits))
{
unsigned int fill_size = max_bits - buffer_bits_;
look_ <<= fill_size;
look_ |= buffer_ >> buffer_bits_;
}
}
else
{
unsigned int fill_size = max_bits - look_bits_;
if (fill_size > buffer_bits_)
fill_size = buffer_bits_;
look_ <<= fill_size;
buffer_bits_ -= fill_size;
look_ |= (buffer_ >> buffer_bits_) & ((1 << fill_size) - 1);
look_bits_ += fill_size;
look_ <<= fill_size;
buffer_bits_ -= fill_size;
look_ |= (buffer_ >> buffer_bits_) & ((1 << fill_size) - 1);
look_bits_ += fill_size;
if (buffer_bits_ == 0)
{
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
if (buffer_bits_ == 0)
{
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
unsigned int left = max_bits - look_bits_;
if (left != 0)
{
look_ <<= left;
look_ |= buffer_ >> look_bits_;
buffer_bits_ = look_bits_;
look_bits_ = max_bits;
}
else
{
buffer_bits_ = max_bits;
}
}
}
unsigned int left = max_bits - look_bits_;
if (left != 0)
{
look_ <<= left;
look_ |= buffer_ >> look_bits_;
buffer_bits_ = look_bits_;
look_bits_ = max_bits;
}
else
{
buffer_bits_ = max_bits;
}
}
}
}
unsigned int look_n_bits(unsigned int n)
{
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
assert(n <= look_bits_);
return (look_ >> (look_bits_ - n)) & ((1 << n) - 1);
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
assert(n <= look_bits_);
return (look_ >> (look_bits_ - n)) & ((1 << n) - 1);
}
void skip_n_bits(unsigned int n)
{
assert (n <= look_bits_);
look_bits_ -= n;
assert (n <= look_bits_);
look_bits_ -= n;
}
unsigned int get_n_bits(unsigned int n)
{
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
look_bits_ -= n;
return (look_ >> look_bits_) & ((1 << n) - 1);
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
look_bits_ -= n;
return (look_ >> look_bits_) & ((1 << n) - 1);
}
unsigned int get_32_bits()
{
// std::cerr << "get_32" << std::endl;
if (SPOT_LIKELY(look_bits_ < 32))
refill();
unsigned int val = look_;
look_bits_ = 0;
refill();
return val;
// std::cerr << "get_32" << std::endl;
if (SPOT_LIKELY(look_bits_ < 32))
refill();
unsigned int val = look_;
look_bits_ = 0;
refill();
return val;
}
void run()
{
if (SPOT_UNLIKELY(!self().have_comp_data()))
return;
if (SPOT_UNLIKELY(!self().have_comp_data()))
return;
look_ = self().next_comp_data();
look_bits_ = max_bits;
if (SPOT_LIKELY(self().have_comp_data()))
{
buffer_ = self().next_comp_data();
buffer_bits_ = max_bits;
}
else
{
buffer_ = 0;
buffer_bits_ = 0;
}
look_ = self().next_comp_data();
look_bits_ = max_bits;
if (SPOT_LIKELY(self().have_comp_data()))
{
buffer_ = self().next_comp_data();
buffer_bits_ = max_bits;
}
else
{
buffer_ = 0;
buffer_bits_ = 0;
}
while (SPOT_LIKELY(!self().complete()))
{
unsigned int token = look_n_bits(3);
switch (token)
{
case 0x0: // 00[0]
case 0x1: // 00[1]
skip_n_bits(2);
self().push_data(0);
break;
case 0x2: // 010
skip_n_bits(3);
self().push_data(1);
break;
case 0x3: // 011
skip_n_bits(3);
self().push_data(2 + get_n_bits(2));
break;
case 0x4: // 100
skip_n_bits(3);
self().push_data(6 + get_n_bits(4));
break;
case 0x5: // 101
skip_n_bits(3);
self().repeat(1 + get_n_bits(3));
break;
case 0x6: // 110
skip_n_bits(3);
self().repeat(9 + get_n_bits(5));
break;
case 0x7: // 111
skip_n_bits(3);
self().push_data(get_32_bits());
break;
default:
SPOT_UNREACHABLE();
}
}
while (SPOT_LIKELY(!self().complete()))
{
unsigned int token = look_n_bits(3);
switch (token)
{
case 0x0: // 00[0]
case 0x1: // 00[1]
skip_n_bits(2);
self().push_data(0);
break;
case 0x2: // 010
skip_n_bits(3);
self().push_data(1);
break;
case 0x3: // 011
skip_n_bits(3);
self().push_data(2 + get_n_bits(2));
break;
case 0x4: // 100
skip_n_bits(3);
self().push_data(6 + get_n_bits(4));
break;
case 0x5: // 101
skip_n_bits(3);
self().repeat(1 + get_n_bits(3));
break;
case 0x6: // 110
skip_n_bits(3);
self().repeat(9 + get_n_bits(5));
break;
case 0x7: // 111
skip_n_bits(3);
self().push_data(get_32_bits());
break;
default:
SPOT_UNREACHABLE();
}
}
}
protected:
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
unsigned int look_;
@ -526,41 +526,41 @@ namespace spot
{
public:
int_vector_vector_decompression(const std::vector<unsigned int>& array,
std::vector<int>& res, size_t size)
: prev_(0), array_(array),
pos_(array.begin()), end_(array.end()),
result_(res), size_(size)
std::vector<int>& res, size_t size)
: prev_(0), array_(array),
pos_(array.begin()), end_(array.end()),
result_(res), size_(size)
{
result_.reserve(size);
result_.reserve(size);
}
bool complete() const
{
return size_ == 0;
return size_ == 0;
}
void push_data(int i)
{
prev_ = i;
result_.push_back(i);
--size_;
prev_ = i;
result_.push_back(i);
--size_;
}
void repeat(unsigned int i)
{
size_ -= i;
while (i--)
result_.push_back(prev_);
size_ -= i;
while (i--)
result_.push_back(prev_);
}
bool have_comp_data() const
{
return pos_ != end_;
return pos_ != end_;
}
unsigned int next_comp_data()
{
return *pos_++;
return *pos_++;
}
protected:
@ -577,40 +577,40 @@ namespace spot
{
public:
int_vector_array_decompression(const std::vector<unsigned int>* array,
int* res,
size_t size)
: prev_(0), array_(array), n_(array->size()), pos_(0), result_(res),
size_(size)
int* res,
size_t size)
: prev_(0), array_(array), n_(array->size()), pos_(0), result_(res),
size_(size)
{
}
bool complete() const
{
return size_ == 0;
return size_ == 0;
}
void push_data(int i)
{
prev_ = i;
*result_++ = i;
--size_;
prev_ = i;
*result_++ = i;
--size_;
}
void repeat(unsigned int i)
{
size_ -= i;
while (i--)
*result_++ = prev_;
size_ -= i;
while (i--)
*result_++ = prev_;
}
bool have_comp_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_comp_data()
{
return (*array_)[pos_++];
return (*array_)[pos_++];
}
protected:
@ -627,41 +627,41 @@ namespace spot
{
public:
int_array_array_decompression(const int* array,
size_t array_size,
int* res,
size_t size)
: prev_(0), array_(array), n_(array_size), pos_(0), result_(res),
size_(size)
size_t array_size,
int* res,
size_t size)
: prev_(0), array_(array), n_(array_size), pos_(0), result_(res),
size_(size)
{
}
bool complete() const
{
return size_ == 0;
return size_ == 0;
}
void push_data(int i)
{
prev_ = i;
*result_++ = i;
--size_;
prev_ = i;
*result_++ = i;
--size_;
}
void repeat(unsigned int i)
{
size_ -= i;
while (i--)
*result_++ = prev_;
size_ -= i;
while (i--)
*result_++ = prev_;
}
bool have_comp_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_comp_data()
{
return array_[pos_++];
return array_[pos_++];
}
protected:
@ -677,7 +677,7 @@ namespace spot
void
int_vector_vector_decompress(const std::vector<unsigned int>& input,
std::vector<int>& output, size_t size)
std::vector<int>& output, size_t size)
{
int_vector_vector_decompression c(input, output, size);
c.run();
@ -685,7 +685,7 @@ namespace spot
void
int_vector_array_decompress(const std::vector<unsigned int>* array, int* res,
size_t size)
size_t size)
{
int_vector_array_decompression c(array, res, size);
c.run();
@ -693,7 +693,7 @@ namespace spot
void
int_array_array_decompress(const int* array, size_t array_size,
int* res, size_t size)
int* res, size_t size)
{
int_array_array_decompression c(array, array_size, res, size);
c.run();

View file

@ -31,7 +31,7 @@ namespace spot
/// Compress an int vector into a vector of unsigned int.
SPOT_API void
int_vector_vector_compress(const std::vector<int>& input,
std::vector<unsigned int>& output);
std::vector<unsigned int>& output);
/// \brief Uncompress a vector of unsigned int into a vector of
/// size \a size.
@ -39,7 +39,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_vector_vector_decompress(const std::vector<unsigned int>& array,
std::vector<int>& output, size_t size);
std::vector<int>& output, size_t size);
/// Compress an int array if size \a n into a vector of unsigned int.
SPOT_API const std::vector<unsigned int>*
@ -51,7 +51,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_vector_array_decompress(const std::vector<unsigned int>* array,
int* res, size_t size);
int* res, size_t size);
/// \brief Compress an int array of size \a n into a int array.
///
@ -61,7 +61,7 @@ namespace spot
/// filled in \a dest
SPOT_API void
int_array_array_compress(const int* array, size_t n,
int* dest, size_t& dest_size);
int* dest, size_t& dest_size);
/// \brief Uncompress an int array of size \a array_size into a int
/// array of size \a size.
@ -69,7 +69,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_array_array_decompress(const int* array, size_t array_size,
int* res, size_t size);
int* res, size_t size);
/// @}
}

View file

@ -157,8 +157,8 @@ namespace spot
position last = loc.end - 1;
ostr << loc.begin;
if (last.filename
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
ostr << '-' << last;
else if (loc.begin.line != last.line)
ostr << '-' << last.line << '.' << last.column;

View file

@ -51,12 +51,12 @@ namespace spot
{
if (input_min == input_max)
{
cube_.push(bdd_satprefix(input_min));
input_max = input_min;
cube_.push(bdd_satprefix(input_min));
input_max = input_min;
}
else
{
cube_.push(bddtrue);
cube_.push(bddtrue);
}
bdd common = input_min & input_max;
todo_.emplace(input_min, input_max, bdd_support(common));
@ -67,110 +67,110 @@ namespace spot
{
while (!todo_.empty())
{
local_vars& l = todo_.top();
switch (l.step)
{
case local_vars::FirstStep:
next_var:
{
if (l.f_min == bddfalse)
{
ret_ = bddfalse;
todo_.pop();
continue;
}
if (l.vars == bddtrue || l.f_max == bddtrue)
{
ret_ = l.f_max;
todo_.pop();
return cube_.top() & ret_;
}
assert(l.vars != bddfalse);
local_vars& l = todo_.top();
switch (l.step)
{
case local_vars::FirstStep:
next_var:
{
if (l.f_min == bddfalse)
{
ret_ = bddfalse;
todo_.pop();
continue;
}
if (l.vars == bddtrue || l.f_max == bddtrue)
{
ret_ = l.f_max;
todo_.pop();
return cube_.top() & ret_;
}
assert(l.vars != bddfalse);
// Pick the first variable in VARS that is used by F_MIN
// or F_MAX. We know that VARS, F_MIN or F_MAX are not
// constants (bddtrue or bddfalse) because one of the
// two above `if' would have matched; so it's ok to call
// bdd_var().
int v = bdd_var(l.vars);
l.vars = bdd_high(l.vars);
int v_min = bdd_var(l.f_min);
int v_max = bdd_var(l.f_max);
if (v < v_min && v < v_max)
// Do not use a while() for this goto, because we want
// `continue' to be relative to the outermost while().
goto next_var;
// Pick the first variable in VARS that is used by F_MIN
// or F_MAX. We know that VARS, F_MIN or F_MAX are not
// constants (bddtrue or bddfalse) because one of the
// two above `if' would have matched; so it's ok to call
// bdd_var().
int v = bdd_var(l.vars);
l.vars = bdd_high(l.vars);
int v_min = bdd_var(l.f_min);
int v_max = bdd_var(l.f_max);
if (v < v_min && v < v_max)
// Do not use a while() for this goto, because we want
// `continue' to be relative to the outermost while().
goto next_var;
l.step = local_vars::SecondStep;
l.step = local_vars::SecondStep;
bdd v0 = bdd_nithvar(v);
l.v1 = bdd_ithvar(v);
bdd v0 = bdd_nithvar(v);
l.v1 = bdd_ithvar(v);
// All the following should be equivalent to
// f0_min = bdd_restrict(f_min, v0);
// f0_max = bdd_restrict(f_max, v0);
// f1_min = bdd_restrict(f_min, v1);
// f1_max = bdd_restrict(f_max, v1);
// but we try to avoid bdd_restrict when possible.
if (v == v_min)
{
l.f0_min = bdd_low(l.f_min);
l.f1_min = bdd_high(l.f_min);
}
else if (v_min < v)
{
l.f0_min = bdd_restrict(l.f_min, v0);
l.f1_min = bdd_restrict(l.f_min, l.v1);
}
else
{
l.f1_min = l.f0_min = l.f_min;
}
if (v == v_max)
{
l.f0_max = bdd_low(l.f_max);
l.f1_max = bdd_high(l.f_max);
}
else if (v_max < v)
{
l.f0_max = bdd_restrict(l.f_max, v0);
l.f1_max = bdd_restrict(l.f_max, l.v1);
}
else
{
l.f1_max = l.f0_max = l.f_max;
}
// All the following should be equivalent to
// f0_min = bdd_restrict(f_min, v0);
// f0_max = bdd_restrict(f_max, v0);
// f1_min = bdd_restrict(f_min, v1);
// f1_max = bdd_restrict(f_max, v1);
// but we try to avoid bdd_restrict when possible.
if (v == v_min)
{
l.f0_min = bdd_low(l.f_min);
l.f1_min = bdd_high(l.f_min);
}
else if (v_min < v)
{
l.f0_min = bdd_restrict(l.f_min, v0);
l.f1_min = bdd_restrict(l.f_min, l.v1);
}
else
{
l.f1_min = l.f0_min = l.f_min;
}
if (v == v_max)
{
l.f0_max = bdd_low(l.f_max);
l.f1_max = bdd_high(l.f_max);
}
else if (v_max < v)
{
l.f0_max = bdd_restrict(l.f_max, v0);
l.f1_max = bdd_restrict(l.f_max, l.v1);
}
else
{
l.f1_max = l.f0_max = l.f_max;
}
cube_.push(cube_.top() & v0);
todo_.emplace(l.f0_min - l.f1_max, l.f0_max, l.vars);
}
continue;
cube_.push(cube_.top() & v0);
todo_.emplace(l.f0_min - l.f1_max, l.f0_max, l.vars);
}
continue;
case local_vars::SecondStep:
l.step = local_vars::ThirdStep;
l.g0 = ret_;
cube_.pop();
cube_.push(cube_.top() & l.v1);
todo_.emplace(l.f1_min - l.f0_max, l.f1_max, l.vars);
continue;
case local_vars::SecondStep:
l.step = local_vars::ThirdStep;
l.g0 = ret_;
cube_.pop();
cube_.push(cube_.top() & l.v1);
todo_.emplace(l.f1_min - l.f0_max, l.f1_max, l.vars);
continue;
case local_vars::ThirdStep:
l.step = local_vars::FourthStep;
l.g1 = ret_;
cube_.pop();
{
bdd fs_max = l.f0_max & l.f1_max;
bdd fs_min = fs_max & ((l.f0_min - l.g0) | (l.f1_min - l.g1));
todo_.emplace(fs_min, fs_max, l.vars);
}
continue;
case local_vars::ThirdStep:
l.step = local_vars::FourthStep;
l.g1 = ret_;
cube_.pop();
{
bdd fs_max = l.f0_max & l.f1_max;
bdd fs_min = fs_max & ((l.f0_min - l.g0) | (l.f1_min - l.g1));
todo_.emplace(fs_min, fs_max, l.vars);
}
continue;
case local_vars::FourthStep:
ret_ |= (l.g0 - l.v1) | (l.g1 & l.v1);
todo_.pop();
continue;
}
SPOT_UNREACHABLE();
case local_vars::FourthStep:
ret_ |= (l.g0 - l.v1) | (l.g1 & l.v1);
todo_.pop();
continue;
}
SPOT_UNREACHABLE();
}
return bddfalse;
}

View file

@ -91,7 +91,7 @@ namespace spot
bdd f1_min, f1_max;
bdd g0, g1;
local_vars(bdd f_min, bdd f_max, bdd vars)
: f_min(f_min), f_max(f_max), step(FirstStep), vars(vars) {}
: f_min(f_min), f_max(f_max), step(FirstStep), vars(vars) {}
};
std::stack<local_vars> todo_;
std::stack<bdd> cube_;

View file

@ -43,17 +43,17 @@ namespace spot
~multiple_size_pool()
{
while (chunklist_)
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
}
size_t fixsize(size_t size) const
{
if (size < sizeof(block_))
size = sizeof(block_);
size = sizeof(block_);
return (size + alignment_ - 1) & ~(alignment_ - 1);
}
@ -67,28 +67,28 @@ namespace spot
block_*& f = freelist_[size];
// If we have free blocks available, return the first one.
if (f)
{
block_* first = f;
f = f->next;
return first;
}
{
block_* first = f;
f = f->next;
return first;
}
// Else, create a block out of the last chunk of allocated
// memory.
// If all the last chunk has been used, allocate one more.
if (free_start_ + size > free_end_)
{
const size_t requested = (size > 128 ? size : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
{
const size_t requested = (size > 128 ? size : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
free_start_ = c->data_ + size;
free_end_ = c->data_ + requested;
}
free_start_ = c->data_ + size;
free_end_ = c->data_ + requested;
}
void* res = free_start_;
free_start_ += size;

View file

@ -33,96 +33,96 @@ namespace spot
{
while (*options)
{
// Skip leading separators.
while (*options && strchr(" \t\n,;", *options))
++options;
// Skip leading separators.
while (*options && strchr(" \t\n,;", *options))
++options;
// `!foo' is a shorthand for `foo=0'.
const char* negated = nullptr;
if (*options == '!')
{
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
negated = options++;
}
// `!foo' is a shorthand for `foo=0'.
const char* negated = nullptr;
if (*options == '!')
{
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
negated = options++;
}
if (!*options)
{
if (negated)
return negated;
else
break;
}
if (!*options)
{
if (negated)
return negated;
else
break;
}
const char* name_start = options;
const char* name_start = options;
// Find the end of the name.
while (*options && !strchr(", \t\n;=", *options))
++options;
// Find the end of the name.
while (*options && !strchr(", \t\n;=", *options))
++options;
std::string name(name_start, options);
std::string name(name_start, options);
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
if (*options != '=')
{
options_[name] = (negated ? 0 : 1);
}
else if (negated)
{
return negated;
}
else
{
++options;
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
if (!*options)
return name_start;
if (*options != '=')
{
options_[name] = (negated ? 0 : 1);
}
else if (negated)
{
return negated;
}
else
{
++options;
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
if (!*options)
return name_start;
if (*options == '\'' || *options == '"')
{
auto sep = *options;
auto start = options + 1;
do
++options;
while (*options && *options != sep);
if (*options != sep)
return start - 1;
std::string val(start, options);
options_str_[name] = val;
if (*options)
++options;
}
else
{
char* val_end;
int val = strtol(options, &val_end, 10);
if (val_end == options)
return name_start;
if (*options == '\'' || *options == '"')
{
auto sep = *options;
auto start = options + 1;
do
++options;
while (*options && *options != sep);
if (*options != sep)
return start - 1;
std::string val(start, options);
options_str_[name] = val;
if (*options)
++options;
}
else
{
char* val_end;
int val = strtol(options, &val_end, 10);
if (val_end == options)
return name_start;
if (*val_end == 'K')
{
val *= 1024;
++val_end;
}
else if (*val_end == 'M')
{
val *= 1024 * 1024;
++val_end;
}
else if (*val_end && !strchr(" \t\n,;", *val_end))
{
return options;
}
options = val_end;
options_[name] = val;
}
}
if (*val_end == 'K')
{
val *= 1024;
++val_end;
}
else if (*val_end == 'M')
{
val *= 1024 * 1024;
++val_end;
}
else if (*val_end && !strchr(" \t\n,;", *val_end))
{
return options;
}
options = val_end;
options_[name] = val;
}
}
}
return nullptr;
}

View file

@ -84,7 +84,7 @@ namespace spot
/// \return The previous value associated to \a option if declared,
/// or \a def otherwise.
std::string set_str(const char* option,
std::string val, std::string def = {});
std::string val, std::string def = {});
/// Acquire all the settings of \a o.
void set(const option_map& o);

View file

@ -96,8 +96,8 @@ namespace spot
if (has_next)
{
has_next = false;
return next;
has_next = false;
return next;
}
double x;
@ -105,9 +105,9 @@ namespace spot
double r;
do
{
x = 2.0 * drand() - 1.0;
y = 2.0 * drand() - 1.0;
r = x * x + y * y;
x = 2.0 * drand() - 1.0;
y = 2.0 * drand() - 1.0;
r = x * x + y * y;
}
while (r >= 1.0 || r == 0.0);
r = sqrt(-2 * log(r) / r);
@ -124,8 +124,8 @@ namespace spot
while (s < p)
{
s -= log(1.0 - drand());
++x;
s -= log(1.0 - drand());
++x;
}
return x - 1;
}

View file

@ -97,12 +97,12 @@ namespace spot
rand() const
{
for (;;)
{
int x = round(gen() * s_ + m_);
if (x < 0)
continue;
{
int x = round(gen() * s_ + m_);
if (x < 0)
continue;
if (x <= n_)
return x;
return x;
}
SPOT_UNREACHABLE();
return 0;
@ -128,11 +128,11 @@ namespace spot
auto d = std::distance(first, last);
if (d > 1)
{
for (--last; first < last; ++first, --d)
{
auto i = mrand(d);
std::swap(*first, *(first + i));
}
for (--last; first < last; ++first, --d)
{
auto i = mrand(d);
std::swap(*first, *(first + i));
}
}
}
/// @}

View file

@ -37,48 +37,48 @@ namespace spot
satsolver_command()
{
satsolver = getenv("SPOT_SATSOLVER");
if (!satsolver)
{
satsolver = "glucose -verb=0 -model %I >%O";
return;
}
prime(satsolver);
if (!has('I'))
throw std::runtime_error("SPOT_SATSOLVER should contain %I to "
"indicate how to use the input filename.");
if (!has('O'))
throw std::runtime_error("SPOT_SATSOLVER should contain %O to "
"indicate how to use the output filename.");
satsolver = getenv("SPOT_SATSOLVER");
if (!satsolver)
{
satsolver = "glucose -verb=0 -model %I >%O";
return;
}
prime(satsolver);
if (!has('I'))
throw std::runtime_error("SPOT_SATSOLVER should contain %I to "
"indicate how to use the input filename.");
if (!has('O'))
throw std::runtime_error("SPOT_SATSOLVER should contain %O to "
"indicate how to use the output filename.");
}
int
run(printable* in, printable* out)
{
declare('I', in);
declare('O', out);
std::ostringstream s;
format(s, satsolver);
int res = system(s.str().c_str());
if (res < 0 || (WIFEXITED(res) && WEXITSTATUS(res) == 127))
{
s << ": failed to execute";
throw std::runtime_error(s.str());
}
// For POSIX shells, "The exit status of a command that
// terminated because it received a signal shall be reported
// as greater than 128."
if (WIFEXITED(res) && WEXITSTATUS(res) >= 128)
{
s << ": terminated by signal";
throw std::runtime_error(s.str());
}
if (WIFSIGNALED(res))
{
s << ": terminated by signal " << WTERMSIG(res);
throw std::runtime_error(s.str());
}
return res;
declare('I', in);
declare('O', out);
std::ostringstream s;
format(s, satsolver);
int res = system(s.str().c_str());
if (res < 0 || (WIFEXITED(res) && WEXITSTATUS(res) == 127))
{
s << ": failed to execute";
throw std::runtime_error(s.str());
}
// For POSIX shells, "The exit status of a command that
// terminated because it received a signal shall be reported
// as greater than 128."
if (WIFEXITED(res) && WEXITSTATUS(res) >= 128)
{
s << ": terminated by signal";
throw std::runtime_error(s.str());
}
if (WIFSIGNALED(res))
{
s << ": terminated by signal " << WTERMSIG(res);
throw std::runtime_error(s.str());
}
return res;
}
};
}
@ -96,25 +96,25 @@ namespace spot
int c;
while ((c = in->get()) != EOF)
{
// If a line does not start with 'v ', ignore it.
if (c != 'v' || in->get() != ' ')
{
in->ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
// Otherwise, read integers one by one.
int i;
while (*in >> i)
{
if (i == 0)
goto done;
sol.push_back(i);
}
if (!in->eof())
// If we haven't reached end-of-file, then we just attempted
// to extract something that wasn't an integer. Clear the
// fail bit so that will loop over.
in->clear();
// If a line does not start with 'v ', ignore it.
if (c != 'v' || in->get() != ' ')
{
in->ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
// Otherwise, read integers one by one.
int i;
while (*in >> i)
{
if (i == 0)
goto done;
sol.push_back(i);
}
if (!in->eof())
// If we haven't reached end-of-file, then we just attempted
// to extract something that wasn't an integer. Clear the
// fail bit so that will loop over.
in->clear();
}
done:
if (in != &std::cin)
@ -149,7 +149,7 @@ namespace spot
satsolver::solution_pair
satsolver::get_solution()
{
delete cnf_stream_; // Close the file.
delete cnf_stream_; // Close the file.
cnf_stream_ = nullptr;
temporary_file* output = create_tmpfile("sat-", ".out");

View file

@ -43,7 +43,7 @@ namespace spot
void check() const
{
if (count_ < 0)
throw std::runtime_error("too many SAT clauses (more than INT_MAX)");
throw std::runtime_error("too many SAT clauses (more than INT_MAX)");
}
clause_counter& operator++()

View file

@ -37,8 +37,8 @@ namespace spot
time_info total;
for (tm_type::const_iterator i = tm.begin(); i != tm.end(); ++i)
{
total.utime += i->second.first.utime();
total.stime += i->second.first.stime();
total.utime += i->second.first.utime();
total.stime += i->second.first.stime();
}
clock_t grand_total = total.utime + total.stime;
@ -52,30 +52,30 @@ namespace spot
<< std::endl;
for (tm_type::const_iterator i = tm.begin(); i != tm.end(); ++i)
{
// truncate long keys
std::string name = i->first;
if (name.size() > 22)
name.erase(22);
// truncate long keys
std::string name = i->first;
if (name.size() > 22)
name.erase(22);
const spot::timer& t = i->second.first;
const char* sep = t.is_running() ? "+|" : " |";
const spot::timer& t = i->second.first;
const char* sep = t.is_running() ? "+|" : " |";
os << std::setw(22) << name << sep
<< std::setw(6) << t.utime() << ' '
<< std::setw(8) << (total.utime ?
100.0 * t.utime() / total.utime : 0.)
<< sep
<< std::setw(6) << t.stime() << ' '
<< std::setw(8) << (total.stime ?
100.0 * t.stime() / total.stime : 0.)
<< sep
<< std::setw(6) << t.utime() + t.stime() << ' '
<< std::setw(8) << (grand_total ?
(100.0 * (t.utime() + t.stime()) /
grand_total) : 0.)
<< sep
<< std::setw(4) << i->second.second
<< std::endl;
os << std::setw(22) << name << sep
<< std::setw(6) << t.utime() << ' '
<< std::setw(8) << (total.utime ?
100.0 * t.utime() / total.utime : 0.)
<< sep
<< std::setw(6) << t.stime() << ' '
<< std::setw(8) << (total.stime ?
100.0 * t.stime() / total.stime : 0.)
<< sep
<< std::setw(6) << t.utime() + t.stime() << ' '
<< std::setw(8) << (grand_total ?
(100.0 * (t.utime() + t.stime()) /
grand_total) : 0.)
<< sep
<< std::setw(4) << i->second.second
<< std::endl;
}
os << std::setw(79) << std::setfill('-') << "" << std::setfill(' ')
<< std::endl

View file

@ -197,7 +197,7 @@ namespace spot
assert(i != tm.end());
assert(0 < i->second.second);
if (0 == --i->second.second)
tm.erase(i);
tm.erase(i);
}
/// Return the timer \a name.

View file

@ -35,14 +35,14 @@ namespace spot
{
const char* res = secure_getenv("SPOT_TMPDIR");
if (res)
return res;
return res;
return secure_getenv("TMPDIR");
}
static int
create_temporary_file(const char* prefix,
const char* suffix,
char** name)
const char* suffix,
char** name)
throw(std::bad_alloc, std::runtime_error)
{
static const char* tmpdir = get_tmpdir();
@ -51,30 +51,30 @@ namespace spot
size_t len = strlen(prefix);
size_t slen = 0;
if (suffix)
len += slen = strlen(suffix);
len += slen = strlen(suffix);
char* x = *name = static_cast<char*>(malloc(tmpdirlen + 1 + len + 6 + 1));
if (!x)
throw std::bad_alloc();
throw std::bad_alloc();
if (tmpdir)
{
x = stpcpy(x, tmpdir);
if (x[-1] != '/')
*x++ = '/';
}
{
x = stpcpy(x, tmpdir);
if (x[-1] != '/')
*x++ = '/';
}
x = stpcpy(x, prefix);
x = stpcpy(x, "XXXXXX");
int fd;
if (suffix)
{
stpcpy(x, suffix);
fd = mkstemps(*name, slen);
}
{
stpcpy(x, suffix);
fd = mkstemps(*name, slen);
}
else
{
fd = mkstemp(*name);
}
{
fd = mkstemp(*name);
}
if (fd < 0)
throw std::runtime_error(std::string("failed to create ") + *name);
throw std::runtime_error(std::string("failed to create ") + *name);
return fd;
}
}

View file

@ -113,8 +113,8 @@ namespace spot
constexpr trival operator!() const
{
return trival((val_ == yes_value) ? no_value :
(val_ == no_value) ? yes_value :
maybe_value);
(val_ == no_value) ? yes_value :
maybe_value);
}
};
@ -171,8 +171,8 @@ namespace spot
inline std::ostream& operator<<(std::ostream& os, trival v)
{
return os << ((v.val() == trival::no_value) ? "no"
: (v.val() == trival::maybe_value) ? "maybe"
: "yes");
: (v.val() == trival::maybe_value) ? "maybe"
: "yes");
}
/// @}

View file

@ -29,11 +29,11 @@ namespace spot
spot::parse_aut_error_list::iterator it;
for (auto& err : errors)
{
if (!filename.empty() && filename != "-")
os << filename << ':';
os << err.first << ": ";
os << err.second << std::endl;
printed = true;
if (!filename.empty() && filename != "-")
os << filename << ':';
os << err.first << ": ";
os << err.second << std::endl;
printed = true;
}
return printed;
}

View file

@ -25,8 +25,8 @@
# define YY_DECL \
int hoayylex(hoayy::parser::semantic_type *yylval, \
spot::location *yylloc, \
spot::parse_aut_error_list& error_list)
spot::location *yylloc, \
spot::parse_aut_error_list& error_list)
YY_DECL;
namespace spot

View file

@ -91,11 +91,11 @@ namespace spot
struct automaton_parser_options final
{
bool ignore_abort = false; ///< Skip aborted automata
bool debug = false; ///< Run the parser in debug mode?
bool trust_hoa = true; ///< Trust properties in HOA files
bool raise_errors = false; ///< Raise errors as exceptions.
bool want_kripke = false; ///< Parse as a Kripke structure.
bool ignore_abort = false; ///< Skip aborted automata
bool debug = false; ///< Run the parser in debug mode?
bool trust_hoa = true; ///< Trust properties in HOA files
bool raise_errors = false; ///< Raise errors as exceptions.
bool want_kripke = false; ///< Parse as a Kripke structure.
};
/// \brief Parse a stream of automata
@ -128,7 +128,7 @@ namespace spot
/// \param filename The file to read from.
/// \param opts Parser options.
automaton_stream_parser(const std::string& filename,
automaton_parser_options opts = {});
automaton_parser_options opts = {});
/// \brief Parse from an already opened file descriptor.
///
@ -136,7 +136,7 @@ namespace spot
/// \param filename What to display in error messages.
/// \param opts Parser options.
automaton_stream_parser(int fd, const std::string& filename,
automaton_parser_options opts = {});
automaton_parser_options opts = {});
/// \brief Parse from a buffer
///
@ -144,8 +144,8 @@ namespace spot
/// \param filename What to display in error messages.
/// \param opts Parser options.
automaton_stream_parser(const char* data,
const std::string& filename,
automaton_parser_options opts = {});
const std::string& filename,
automaton_parser_options opts = {});
~automaton_stream_parser();
@ -165,8 +165,8 @@ namespace spot
///
/// \warning This function is not reentrant.
parsed_aut_ptr parse(const bdd_dict_ptr& dict,
environment& env =
default_environment::instance());
environment& env =
default_environment::instance());
};
/// \brief Read the first spot::twa_graph from a file.
@ -187,8 +187,8 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API parsed_aut_ptr
parse_aut(const std::string& filename,
const bdd_dict_ptr& dict,
environment& env = default_environment::instance(),
automaton_parser_options opts = {});
const bdd_dict_ptr& dict,
environment& env = default_environment::instance(),
automaton_parser_options opts = {});
/// @}
}

View file

@ -30,7 +30,7 @@ namespace spot
{
void
fix_utf8_locations(const std::string& ltl_string,
parse_error_list& error_list)
parse_error_list& error_list)
{
// LUT to convert byte positions to utf8 positions.
// (The +2 is to account for position 0, not used,
@ -42,15 +42,15 @@ namespace spot
std::string::const_iterator i = b;
std::string::const_iterator e = ltl_string.end();
unsigned n = 0; // number of current utf8 character
unsigned prev = 0; // last byte of previous utf8 character
unsigned n = 0; // number of current utf8 character
unsigned prev = 0; // last byte of previous utf8 character
while (i != e)
{
utf8::next(i, e);
++n;
unsigned d = std::distance(b, i);
while (prev < d)
b2u[++prev] = n;
utf8::next(i, e);
++n;
unsigned d = std::distance(b, i);
while (prev < d)
b2u[++prev] = n;
}
b2u[++prev] = ++n;
@ -58,9 +58,9 @@ namespace spot
parse_error_list::iterator it;
for (it = error_list.begin(); it != error_list.end(); ++it)
{
location& l = it->first;
l.begin.column = b2u[l.begin.column];
l.end.column = b2u[l.end.column];
location& l = it->first;
l.begin.column = b2u[l.begin.column];
l.end.column = b2u[l.end.column];
}
}
@ -68,45 +68,45 @@ namespace spot
{
static bool
format_parse_errors_aux(std::ostream& os,
const std::string& ltl_string,
const parse_error_list& error_list,
unsigned shift)
const std::string& ltl_string,
const parse_error_list& error_list,
unsigned shift)
{
bool printed = false;
for (auto it: error_list)
{
os << ">>> " << ltl_string << '\n';
const location& l = it.first;
{
os << ">>> " << ltl_string << '\n';
const location& l = it.first;
unsigned n = 1;
for (; n < 4 + l.begin.column + shift; ++n)
os << ' ';
// Write at least one '^', even if begin==end.
os << '^';
++n;
for (; n < 4 + l.end.column + shift; ++n)
os << '^';
os << '\n' << it.second << "\n\n";
printed = true;
}
unsigned n = 1;
for (; n < 4 + l.begin.column + shift; ++n)
os << ' ';
// Write at least one '^', even if begin==end.
os << '^';
++n;
for (; n < 4 + l.end.column + shift; ++n)
os << '^';
os << '\n' << it.second << "\n\n";
printed = true;
}
return printed;
}
}
bool
parsed_formula::format_errors(std::ostream& os,
const std::string& real_input,
unsigned shift)
const std::string& real_input,
unsigned shift)
{
if (utf8::is_valid(input.begin(), input.end()))
{
parse_error_list fixed = errors;
fix_utf8_locations(input, fixed);
return format_parse_errors_aux(os, real_input, fixed, shift);
parse_error_list fixed = errors;
fix_utf8_locations(input, fixed);
return format_parse_errors_aux(os, real_input, fixed, shift);
}
else
{
return format_parse_errors_aux(os, real_input, errors, shift);
return format_parse_errors_aux(os, real_input, errors, shift);
}
}

View file

@ -27,8 +27,8 @@
# define YY_DECL \
int tlyylex (tlyy::parser::semantic_type *yylval, \
spot::location *yylloc, \
spot::parse_error_list& error_list)
spot::location *yylloc, \
spot::parse_error_list& error_list)
YY_DECL;
void flex_set_buffer(const std::string& buf, int start_tok, bool lenient);

View file

@ -53,7 +53,7 @@ namespace spot
{
auto i = map_.find(name);
if (i != map_.end())
return true;
return true;
auto v = aut_->acc().add_set();
map_[name] = v;
return true;
@ -63,7 +63,7 @@ namespace spot
{
auto p = map_.find(name);
if (p == map_.end())
return std::make_pair(false, 0U);
return std::make_pair(false, 0U);
return std::make_pair(true, acc_cond::mark_t({p->second}));
}
};
@ -83,9 +83,9 @@ namespace spot
std::pair<bool, acc_cond::mark_t> lookup(unsigned n)
{
if (n < aut_->acc().num_sets())
return std::make_pair(true, acc_cond::mark_t({n}));
return std::make_pair(true, acc_cond::mark_t({n}));
else
return std::make_pair(false, 0U);
return std::make_pair(false, 0U);
}
};
@ -106,13 +106,13 @@ namespace spot
{
auto p = map_.find(n);
if (p != map_.end())
return std::make_pair(true, p->second);
return std::make_pair(true, p->second);
if (used_ < aut_->acc().num_sets())
{
auto res = acc_cond::mark_t({used_++});
map_[n] = res;
return std::make_pair(true, res);
}
{
auto res = acc_cond::mark_t({used_++});
map_[n] = res;
return std::make_pair(true, res);
}
return std::make_pair(false, 0U);
}
};

View file

@ -67,15 +67,15 @@ namespace spot
// externally), use the new variables.
if (lvarnum < varnum)
{
more -= varnum - lvarnum;
lvarnum = varnum;
more -= varnum - lvarnum;
lvarnum = varnum;
}
// If we still need more variable, do allocate them.
if (more > 0)
{
bdd_extvarnum(more);
varnum += more;
lvarnum = varnum;
bdd_extvarnum(more);
varnum += more;
lvarnum = varnum;
}
}
@ -98,19 +98,19 @@ namespace spot
// of the variable space, allocate just the difference.
if (!fl.empty() && fl.back().first + fl.back().second == lvarnum)
{
int res = fl.back().first;
int endvar = fl.back().second;
assert(n > endvar);
extvarnum(n - endvar);
fl.pop_back();
return res;
int res = fl.back().first;
int endvar = fl.back().second;
assert(n > endvar);
extvarnum(n - endvar);
fl.pop_back();
return res;
}
else
{
// Otherwise, allocate as much variables as we need.
int res = lvarnum;
extvarnum(n);
return res;
// Otherwise, allocate as much variables as we need.
int res = lvarnum;
extvarnum(n);
return res;
}
}
}

View file

@ -41,24 +41,24 @@ namespace spot
free_list_type::iterator cur;
for (cur = fl.begin(); cur != fl.end(); ++cur)
{
if (cur->second < n)
continue;
if (n == cur->second)
{
best = cur;
break;
}
if (best == fl.end()
|| cur->second < best->second)
best = cur;
if (cur->second < n)
continue;
if (n == cur->second)
{
best = cur;
break;
}
if (best == fl.end()
|| cur->second < best->second)
best = cur;
}
// We have found enough free variables.
if (best != fl.end())
{
int result = best->first;
remove(best, result, n);
return result;
int result = best->first;
remove(best, result, n);
return result;
}
// We haven't found enough adjacent free variables;
@ -73,67 +73,67 @@ namespace spot
int end = base + n;
for (cur = fl.begin(); cur != fl.end(); ++cur)
{
int cend = cur->first + cur->second;
// cur [...]
// to insert [...]
// -----------------------
// result [...] [...]
// (Insert a new range, unconnected.)
if (cur->first > end)
{
break;
}
// cur [...]
// to insert [...]
// -----------------------
// result unknown : we should look at the rest of the freelist.
else if (base > cend)
{
continue;
}
// cur [....[ [......[
// to insert [....[ [..[
// ----------------------------------
// result [......[ [......[
else if (cur->first <= base)
{
if (cend >= end)
// second case : nothing to do
return;
// cur->second is set below.
}
// cur [....[ [..[
// to insert [....[ [.......[
// ----------------------------------
// result [......[ [.......[
else
{
cur->first = base;
// cur->second is set below.
}
int cend = cur->first + cur->second;
// cur [...]
// to insert [...]
// -----------------------
// result [...] [...]
// (Insert a new range, unconnected.)
if (cur->first > end)
{
break;
}
// cur [...]
// to insert [...]
// -----------------------
// result unknown : we should look at the rest of the freelist.
else if (base > cend)
{
continue;
}
// cur [....[ [......[
// to insert [....[ [..[
// ----------------------------------
// result [......[ [......[
else if (cur->first <= base)
{
if (cend >= end)
// second case : nothing to do
return;
// cur->second is set below.
}
// cur [....[ [..[
// to insert [....[ [.......[
// ----------------------------------
// result [......[ [.......[
else
{
cur->first = base;
// cur->second is set below.
}
// We get here in one of these three situations:
//
// cur [....[ [....[ [..[
// to insert [....[ [....[ [.......[
// -------------------------------------------
// result [......[ [......[ [.......[
//
// cur->first is already set, be cur->second has yet to be.
end = std::max(cend, end);
cur->second = end - cur->first;
// Since we have extended the current range, maybe the next
// items on the list should be merged.
free_list_type::iterator next = cur;
++next;
while (next != fl.end() && next->first <= end)
{
end = std::max(next->first + next->second, end);
cur->second = end - cur->first;
free_list_type::iterator next2 = next++;
fl.erase(next2);
}
return;
// We get here in one of these three situations:
//
// cur [....[ [....[ [..[
// to insert [....[ [....[ [.......[
// -------------------------------------------
// result [......[ [......[ [.......[
//
// cur->first is already set, be cur->second has yet to be.
end = std::max(cend, end);
cur->second = end - cur->first;
// Since we have extended the current range, maybe the next
// items on the list should be merged.
free_list_type::iterator next = cur;
++next;
while (next != fl.end() && next->first <= end)
{
end = std::max(next->first + next->second, end);
cur->second = end - cur->first;
free_list_type::iterator next2 = next++;
fl.erase(next2);
}
return;
}
// We reach this place either because a new unconnected range
@ -148,15 +148,15 @@ namespace spot
int end = base + n;
while (cur != fl.end() && cur->first < end)
{
int cend = cur->first + cur->second;
// Remove may invalidate the current iterator, so advance it first.
free_list_type::iterator old = cur++;
if (cend >= base)
{
int newbase = std::max(base, old->first);
int q = std::min(cend, end) - newbase;
remove(old, newbase, q);
}
int cend = cur->first + cur->second;
// Remove may invalidate the current iterator, so advance it first.
free_list_type::iterator old = cur++;
if (cend >= base)
{
int newbase = std::max(base, old->first);
int q = std::min(cend, end) - newbase;
remove(old, newbase, q);
}
}
}
@ -165,31 +165,31 @@ namespace spot
{
if (base == i->first)
{
// Removing at the beginning of the range
i->second -= n;
assert(i->second >= 0);
// Erase the range if it's now empty.
if (i->second == 0)
fl.erase(i);
else
i->first += n;
// Removing at the beginning of the range
i->second -= n;
assert(i->second >= 0);
// Erase the range if it's now empty.
if (i->second == 0)
fl.erase(i);
else
i->first += n;
}
else if (base + n == i->first + i->second)
{
// Removing at the end of the range
i->second -= n;
assert(i->second > 0); // cannot be empty because base != i->first
// Removing at the end of the range
i->second -= n;
assert(i->second > 0); // cannot be empty because base != i->first
}
else
{
// Removing in the middle of a range.
int b1 = i->first;
int n1 = base - i->first;
int n2 = i->first + i->second - base - n;
assert(n1 > 0);
assert(n2 > 0);
*i = pos_lenght_pair(base + n, n2);
fl.insert(i, pos_lenght_pair(b1, n1));
// Removing in the middle of a range.
int b1 = i->first;
int n1 = base - i->first;
int n2 = i->first + i->second - base - n;
assert(n1 > 0);
assert(n2 > 0);
*i = pos_lenght_pair(base + n, n2);
fl.insert(i, pos_lenght_pair(b1, n1));
}
}

View file

@ -29,11 +29,11 @@ namespace spot
trim(std::string& str)
{
str.erase(std::find_if(str.rbegin(), str.rend(),
std::not1(std::ptr_fun<int, int>
(std::isspace))).base(),
str.end());
std::not1(std::ptr_fun<int, int>
(std::isspace))).base(),
str.end());
str.erase(str.begin(),
std::find_if(str.begin(), str.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
std::find_if(str.begin(), str.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
}

View file

@ -42,7 +42,7 @@ namespace spot
{
for (auto s: a.sets())
if (m[s] > 0)
--m[s];
--m[s];
return *this;
}
@ -52,7 +52,7 @@ namespace spot
std::vector<unsigned> res;
for (unsigned n = 0; n < max; ++n)
if (m[n] > w.m[n])
res.push_back(n);
res.push_back(n);
return acc_cond::mark_t(res.begin(), res.end());
}

View file

@ -48,7 +48,7 @@ namespace spot
/// the corresponding counter in w.
acc_cond::mark_t diff(const acc_cond& acc, const weight& w) const;
friend std::ostream& operator<<(std::ostream& os,
const weight& w);
const weight& w);
private:
std::vector<int> m;

View file

@ -276,7 +276,7 @@ namespace spot
bool is_stuttering_transition = (get_tgba_condition()
== (dest)->get_tgba_condition());
bool dest_is_livelock_accepting =
dest->is_livelock_accepting_state();
dest->is_livelock_accepting_state();
//Before deleting stuttering transitions, propaged back livelock
//and initial state's properties
@ -319,7 +319,7 @@ namespace spot
// they are not cloned.
if (trans)
for (auto& t: *trans)
delete t;
delete t;
delete trans;
std::unordered_map<int, transitions*, std::hash<int> >::iterator i =
@ -338,8 +338,8 @@ namespace spot
ta_explicit::ta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state):
unsigned n_acc,
state_ta_explicit* artificial_initial_state):
ta(tgba->get_dict()),
tgba_(tgba),
artificial_initial_state_(artificial_initial_state)
@ -351,7 +351,7 @@ namespace spot
{
auto is = add_state(artificial_initial_state);
assert(is == artificial_initial_state);
(void)is;
(void)is;
}
}
@ -361,8 +361,8 @@ namespace spot
for (it = states_set_.begin(); it != states_set_.end(); ++it)
{
auto* s = const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(*it));
assert(s);
(down_cast<const state_ta_explicit*>(*it));
assert(s);
s->free_transitions();
s->get_tgba_state()->destroy();
delete s;
@ -390,11 +390,11 @@ namespace spot
auto add_state = initial_states_set_.insert(s);
if (get_artificial_initial_state())
if (add_state.second)
{
auto i =
down_cast<state_ta_explicit*>(get_artificial_initial_state());
create_transition(i, condition, 0U, s);
}
{
auto i =
down_cast<state_ta_explicit*>(get_artificial_initial_state());
create_transition(i, condition, 0U, s);
}
}
void
@ -411,9 +411,9 @@ namespace spot
void
ta_explicit::create_transition(state_ta_explicit* source, bdd condition,
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning)
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning)
{
state_ta_explicit::transition* t = new state_ta_explicit::transition;
t->dest = dest;

View file

@ -41,8 +41,8 @@ namespace spot
{
public:
ta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr);
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr);
const_twa_ptr
get_tgba() const;
@ -55,9 +55,9 @@ namespace spot
void
create_transition(state_ta_explicit* source, bdd condition,
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning = false);
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning = false);
void
delete_stuttering_transitions();
@ -142,10 +142,10 @@ namespace spot
typedef std::list<transition*> transitions;
state_ta_explicit(const state* tgba_state, const bdd tgba_condition,
bool is_initial_state = false,
bool is_accepting_state = false,
bool is_livelock_accepting_state = false,
transitions* trans = nullptr) :
bool is_initial_state = false,
bool is_accepting_state = false,
bool is_livelock_accepting_state = false,
transitions* trans = nullptr) :
tgba_state_(tgba_state), tgba_condition_(tgba_condition),
is_initial_state_(is_initial_state), is_accepting_state_(
is_accepting_state), is_livelock_accepting_state_(
@ -246,8 +246,8 @@ namespace spot
inline ta_explicit_ptr
make_ta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr)
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr)
{
return std::make_shared<ta_explicit>(tgba, n_acc, artificial_initial_state);
}

View file

@ -67,8 +67,8 @@ namespace spot
////////////////////////////////////////////////////////////
// ta_succ_iterator_product
ta_succ_iterator_product::ta_succ_iterator_product(const state_ta_product* s,
const ta* t,
const kripke* k)
const ta* t,
const kripke* k)
: source_(s), ta_(t), kripke_(k)
{
kripke_source_condition = kripke_->state_condition(s->get_kripke_state());
@ -243,7 +243,7 @@ namespace spot
ta_product::ta_product(const const_ta_ptr& testing_automata,
const const_kripke_ptr& kripke_structure):
const const_kripke_ptr& kripke_structure):
ta(testing_automata->get_dict()),
dict_(testing_automata->get_dict()),
ta_(testing_automata),
@ -292,9 +292,9 @@ namespace spot
for (auto s: ta_init_states_set)
if (artificial_initial_state ||
(kripke_init_condition == ta_->get_state_condition(s)))
initial_states_set.insert(new state_ta_product(s,
kripke_init->clone()));
(kripke_init_condition == ta_->get_state_condition(s)))
initial_states_set.insert(new state_ta_product(s,
kripke_init->clone()));
kripke_init->destroy();
return initial_states_set;
@ -316,8 +316,8 @@ namespace spot
const state_ta_product* stp = down_cast<const state_ta_product*> (s);
assert(s);
return new ta_succ_iterator_product_by_changeset(stp,
ta_.get(), kripke_.get(),
changeset);
ta_.get(), kripke_.get(),
changeset);
}
@ -402,7 +402,7 @@ namespace spot
ta_succ_iterator_product_by_changeset::
ta_succ_iterator_product_by_changeset(const state_ta_product* s, const ta* t,
const kripke* k, bdd changeset)
const kripke* k, bdd changeset)
: ta_succ_iterator_product(s, t, k)
{
current_condition_ = changeset;

View file

@ -131,7 +131,7 @@ namespace spot
/// \param testing_automaton The TA component in the product.
/// \param kripke_structure The Kripke component in the product.
ta_product(const const_ta_ptr& testing_automaton,
const const_kripke_ptr& kripke_structure);
const const_kripke_ptr& kripke_structure);
virtual
~ta_product();
@ -197,7 +197,7 @@ namespace spot
typedef std::shared_ptr<ta_product> ta_product_ptr;
typedef std::shared_ptr<const ta_product> const_ta_product_ptr;
inline ta_product_ptr product(const const_ta_ptr& testing_automaton,
const const_kripke_ptr& kripke_structure)
const const_kripke_ptr& kripke_structure)
{
return std::make_shared<ta_product>(testing_automaton, kripke_structure);
}
@ -207,8 +207,8 @@ namespace spot
{
public:
ta_succ_iterator_product_by_changeset(const state_ta_product* s,
const ta* t, const kripke* k,
bdd changeset);
const ta* t, const kripke* k,
bdd changeset);
/// \brief Move to the next successor in the Kripke structure
void next_kripke_dest();

View file

@ -25,8 +25,8 @@ namespace spot
{
tgta_explicit::tgta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state) :
unsigned n_acc,
state_ta_explicit* artificial_initial_state) :
tgta(tgba->get_dict()),
ta_(make_ta_explicit(tgba, n_acc, artificial_initial_state))
{

View file

@ -38,8 +38,8 @@ namespace spot
{
public:
tgta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state);
unsigned n_acc,
state_ta_explicit* artificial_initial_state);
// tgba interface
virtual spot::state* get_init_state() const override;
@ -63,9 +63,9 @@ namespace spot
inline tgta_explicit_ptr
make_tgta_explicit(const const_twa_ptr& tgba, unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr)
state_ta_explicit* artificial_initial_state = nullptr)
{
return std::make_shared<tgta_explicit>(tgba, n_acc,
artificial_initial_state);
artificial_initial_state);
}
}

View file

@ -44,7 +44,7 @@ namespace spot
// tgta_product
tgta_product::tgta_product(const const_kripke_ptr& left,
const const_tgta_ptr& right):
const const_tgta_ptr& right):
twa_product(left, right)
{
}
@ -207,7 +207,7 @@ namespace spot
kripke_current_dest_state->clone(),
tgta_succ_it_->dst(), pool_);
current_acceptance_conditions_
= tgta_succ_it_->acc();
= tgta_succ_it_->acc();
return true;
}

View file

@ -33,7 +33,7 @@ namespace spot
{
public:
tgta_product(const const_kripke_ptr& left,
const const_tgta_ptr& right);
const const_tgta_ptr& right);
virtual const state* get_init_state() const override;
@ -42,7 +42,7 @@ namespace spot
};
inline twa_ptr product(const const_kripke_ptr& left,
const const_tgta_ptr& right)
const const_tgta_ptr& right)
{
return std::make_shared<tgta_product>(left, right);
}
@ -52,9 +52,9 @@ namespace spot
{
public:
tgta_succ_iterator_product(const state_product* s,
const const_kripke_ptr& k,
const const_tgta_ptr& tgta,
fixed_size_pool* pool);
const const_kripke_ptr& k,
const const_tgta_ptr& tgta,
fixed_size_pool* pool);
virtual
~tgta_succ_iterator_product();

View file

@ -35,109 +35,109 @@ namespace spot
void
parse_opts(const char* options)
{
const char* orig = options;
while (char c = *options++)
switch (c)
{
case '.':
{
// Copy the value in a string, so future calls to
// parse_opts do not fail if the environment has
// changed. (This matters particularly in an ipython
// notebook, where it is tempting to redefine
// SPOT_DOTDEFAULT.)
static std::string def = []()
{
auto s = getenv("SPOT_DOTDEFAULT");
return s ? s : "";
}();
// Prevent infinite recursions...
if (orig == def.c_str())
throw std::runtime_error
(std::string("SPOT_DOTDEFAULT should not contain '.'"));
if (!def.empty())
parse_opts(def.c_str());
break;
}
case 'A':
opt_hide_sets_ = true;
break;
case 'c':
opt_circles_ = true;
break;
case 'C':
if (*options != '(')
throw std::runtime_error
("invalid node color specification for print_dot()");
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
("invalid node color specification for print_dot()");
opt_node_color_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'h':
opt_horizontal_ = true;
break;
case 'f':
if (*options != '(')
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
opt_font_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'v':
opt_horizontal_ = false;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'B':
case 'e':
case 'n':
case 'N':
case 'o':
case 'r':
case 'R':
case 's':
case 't':
case '+':
case '<':
case '#':
// All these options are implemented by dotty() on TGBA,
// but are not implemented here. We simply ignore them,
// because raising an exception if they are in
// SPOT_DEFAULT would be annoying.
break;
default:
throw std::runtime_error
(std::string("unknown option for dotty(): ") + c);
}
const char* orig = options;
while (char c = *options++)
switch (c)
{
case '.':
{
// Copy the value in a string, so future calls to
// parse_opts do not fail if the environment has
// changed. (This matters particularly in an ipython
// notebook, where it is tempting to redefine
// SPOT_DOTDEFAULT.)
static std::string def = []()
{
auto s = getenv("SPOT_DOTDEFAULT");
return s ? s : "";
}();
// Prevent infinite recursions...
if (orig == def.c_str())
throw std::runtime_error
(std::string("SPOT_DOTDEFAULT should not contain '.'"));
if (!def.empty())
parse_opts(def.c_str());
break;
}
case 'A':
opt_hide_sets_ = true;
break;
case 'c':
opt_circles_ = true;
break;
case 'C':
if (*options != '(')
throw std::runtime_error
("invalid node color specification for print_dot()");
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
("invalid node color specification for print_dot()");
opt_node_color_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'h':
opt_horizontal_ = true;
break;
case 'f':
if (*options != '(')
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
opt_font_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'v':
opt_horizontal_ = false;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'B':
case 'e':
case 'n':
case 'N':
case 'o':
case 'r':
case 'R':
case 's':
case 't':
case '+':
case '<':
case '#':
// All these options are implemented by dotty() on TGBA,
// but are not implemented here. We simply ignore them,
// because raising an exception if they are in
// SPOT_DEFAULT would be annoying.
break;
default:
throw std::runtime_error
(std::string("unknown option for dotty(): ") + c);
}
}
public:
dotty_bfs(std::ostream& os, const const_ta_ptr& a,
const char* opt) :
const char* opt) :
ta_reachable_iterator_breadth_first(a), os_(os)
{
parse_opts(opt ? opt : ".");
parse_opts(opt ? opt : ".");
}
void
@ -145,56 +145,56 @@ namespace spot
{
os_ << "digraph G {\n";
if (opt_horizontal_)
os_ << " rankdir=LR\n";
if (opt_circles_)
os_ << " node [shape=\"circle\"]\n";
if (!opt_node_color_.empty())
os_ << " node [style=\"filled\", fillcolor=\""
<< opt_node_color_ << "\"]\n";
if (!opt_font_.empty())
os_ << " fontname=\"" << opt_font_
<< "\"\n node [fontname=\"" << opt_font_
<< "\"]\n edge [fontname=\"" << opt_font_
<< "\"]\n";
if (opt_horizontal_)
os_ << " rankdir=LR\n";
if (opt_circles_)
os_ << " node [shape=\"circle\"]\n";
if (!opt_node_color_.empty())
os_ << " node [style=\"filled\", fillcolor=\""
<< opt_node_color_ << "\"]\n";
if (!opt_font_.empty())
os_ << " fontname=\"" << opt_font_
<< "\"\n node [fontname=\"" << opt_font_
<< "\"]\n edge [fontname=\"" << opt_font_
<< "\"]\n";
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string extra = []()
{
auto s = getenv("SPOT_DOTEXTRA");
return s ? s : "";
}();
// Any extra text passed in the SPOT_DOTEXTRA environment
// variable should be output at the end of the "header", so
// that our setup can be overridden.
if (!extra.empty())
os_ << " " << extra << '\n';
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string extra = []()
{
auto s = getenv("SPOT_DOTEXTRA");
return s ? s : "";
}();
// Any extra text passed in the SPOT_DOTEXTRA environment
// variable should be output at the end of the "header", so
// that our setup can be overridden.
if (!extra.empty())
os_ << " " << extra << '\n';
artificial_initial_state_ = t_automata_->get_artificial_initial_state();
ta::const_states_set_t init_states_set;
if (artificial_initial_state_)
{
init_states_set.insert(artificial_initial_state_);
os_ << " 0 [label=\"\", style=invis, height=0]\n 0 -> 1\n";
}
{
init_states_set.insert(artificial_initial_state_);
os_ << " 0 [label=\"\", style=invis, height=0]\n 0 -> 1\n";
}
else
{
int n = 0;
init_states_set = t_automata_->get_initial_states_set();
for (auto s: init_states_set)
{
bdd init_condition = t_automata_->get_state_condition(s);
std::string label = bdd_format_formula(t_automata_->get_dict(),
init_condition);
++n;
os_ << " " << -n << " [label=\"\", style=invis, height=0]\n "
<< -n << " -> " << n << " [label=\"" << label << "\"]\n";
}
}
{
int n = 0;
init_states_set = t_automata_->get_initial_states_set();
for (auto s: init_states_set)
{
bdd init_condition = t_automata_->get_state_condition(s);
std::string label = bdd_format_formula(t_automata_->get_dict(),
init_condition);
++n;
os_ << " " << -n << " [label=\"\", style=invis, height=0]\n "
<< -n << " -> " << n << " [label=\"" << label << "\"]\n";
}
}
}
void
@ -209,41 +209,41 @@ namespace spot
std::string style;
if (t_automata_->is_accepting_state(s))
style = ",peripheries=2";
style = ",peripheries=2";
if (t_automata_->is_livelock_accepting_state(s))
style += ",shape=box";
if (t_automata_->is_livelock_accepting_state(s))
style += ",shape=box";
os_ << " " << n << " [label=";
if (s == artificial_initial_state_)
os_ << "init";
else
os_ << quote_unless_bare_word(t_automata_->format_state(s));
os_ << style << "]\n";
os_ << " " << n << " [label=";
if (s == artificial_initial_state_)
os_ << "init";
else
os_ << quote_unless_bare_word(t_automata_->format_state(s));
os_ << style << "]\n";
}
void
process_link(int in, int out, const ta_succ_iterator* si)
{
bdd_dict_ptr d = t_automata_->get_dict();
std::string label =
((in == 1 && artificial_initial_state_)
? bdd_format_formula(d, si->cond())
: bdd_format_accset(d, si->cond()));
bdd_dict_ptr d = t_automata_->get_dict();
std::string label =
((in == 1 && artificial_initial_state_)
? bdd_format_formula(d, si->cond())
: bdd_format_accset(d, si->cond()));
if (label.empty())
label = "{}";
if (label.empty())
label = "{}";
if (!opt_hide_sets_)
{
label += "\n";
label += t_automata_->acc().
format(si->acc());
}
if (!opt_hide_sets_)
{
label += "\n";
label += t_automata_->acc().
format(si->acc());
}
os_ << " " << in << " -> " << out << " [label=\"";
escape_str(os_, label);
os_ << "\"]\n";
escape_str(os_, label);
os_ << "\"]\n";
}
private:

View file

@ -26,5 +26,5 @@ namespace spot
{
SPOT_API std::ostream&
print_dot(std::ostream& os, const const_ta_ptr& a,
const char* opt = nullptr);
const char* opt = nullptr);
}

View file

@ -102,10 +102,10 @@ namespace spot
(ta_init_it_->dst()), kripke_init_state->clone());
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
{
init->destroy();
continue;
}
scc.push(++num);
arc.push(0U);
@ -146,7 +146,7 @@ namespace spot
}
// fill rem with any component removed,
auto i = h.find(curr);
auto i = h.find(curr);
assert(i != h.end());
scc.rem().push_front(curr);
@ -168,7 +168,7 @@ namespace spot
{
// removing states
for (auto j: scc.rem())
h[j] = -1;
h[j] = -1;
dec_depth(scc.rem().size());
scc.pop();
assert(!arc.empty());
@ -209,7 +209,7 @@ namespace spot
// We do not need SUCC from now on.
// Are we going to a new state?
auto p = h.emplace(dest, num + 1);
auto p = h.emplace(dest, num + 1);
if (p.second)
{
// Number it, stack it, and register its successors
@ -277,23 +277,23 @@ namespace spot
scc.rem().splice(scc.rem().end(), rem);
bool is_accepting_sscc = scc.top().is_accepting
|| a_->acc().accepting(scc.top().condition);
|| a_->acc().accepting(scc.top().condition);
if (is_accepting_sscc)
{
trace
<< "PASS 1: SUCCESS: a_->is_livelock_accepting_state(curr): "
<< a_->is_livelock_accepting_state(curr) << '\n';
<< "PASS 1: SUCCESS: a_->is_livelock_accepting_state(curr): "
<< a_->is_livelock_accepting_state(curr) << '\n';
trace
<< "PASS 1: scc.top().condition : "
<< scc.top().condition << '\n';
<< scc.top().condition << '\n';
trace
<< "PASS 1: a_->acc().all_sets() : "
<< (a_->acc().all_sets()) << '\n';
<< (a_->acc().all_sets()) << '\n';
trace
<< ("PASS 1 CYCLE and accepting? ")
<< a_->acc().accepting(scc.top().condition)
<< std::endl;
<< ("PASS 1 CYCLE and accepting? ")
<< a_->acc().accepting(scc.top().condition)
<< std::endl;
clear(h, todo, ta_init_it_);
return true;
}
@ -315,19 +315,19 @@ namespace spot
h_livelock_root = h[livelock_roots.top()];
if (heuristic_livelock_detection(dest, h, h_livelock_root,
liveset_curr))
liveset_curr))
{
clear(h, todo, ta_init_it_);
return true;
}
for (const state* succ: liveset_dest)
if (heuristic_livelock_detection(succ, h, h_livelock_root,
liveset_curr))
{
clear(h, todo, ta_init_it_);
return true;
}
if (heuristic_livelock_detection(succ, h, h_livelock_root,
liveset_curr))
{
clear(h, todo, ta_init_it_);
return true;
}
}
}
@ -403,11 +403,11 @@ namespace spot
auto init = ta_init_it_.front();
ta_init_it_.pop();
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
sscc.push(num);
sscc.top().is_accepting = t->is_livelock_accepting_state(init);
@ -435,7 +435,7 @@ namespace spot
trace << "PASS 2 : backtrack\n";
// fill rem with any component removed,
auto i = h.find(curr);
auto i = h.find(curr);
assert(i != h.end());
sscc.rem().push_front(curr);
@ -449,7 +449,7 @@ namespace spot
{
// removing states
for (auto j: sscc.rem())
h[j] = -1;
h[j] = -1;
dec_depth(sscc.rem().size());
sscc.pop();
}
@ -498,10 +498,10 @@ namespace spot
inc_depth();
continue;
}
else
{
dest->destroy();
}
else
{
dest->destroy();
}
// If we have reached a dead component, ignore it.
if (i->second == -1)
@ -509,12 +509,12 @@ namespace spot
//self loop state
if (!curr->compare(i->first))
if (t->is_livelock_accepting_state(curr))
{
clear(h, todo, ta_init_it_);
trace << "PASS 2: SUCCESS\n";
return true;
}
if (t->is_livelock_accepting_state(curr))
{
clear(h, todo, ta_init_it_);
trace << "PASS 2: SUCCESS\n";
return true;
}
// Now this is the most interesting case. We have reached a
// state S1 which is already part of a non-dead SSCC. Any such

View file

@ -34,7 +34,7 @@ namespace spot
namespace
{
typedef std::pair<const spot::state*,
ta_succ_iterator_product*> pair_state_iter;
ta_succ_iterator_product*> pair_state_iter;
}
/// \addtogroup ta_emptiness_check Emptiness-checks
@ -111,7 +111,7 @@ namespace spot
/// this heuristic is described in the paper cited above
bool
check(bool disable_second_pass = false,
bool disable_heuristic_for_livelock_detection = false);
bool disable_heuristic_for_livelock_detection = false);
/// \brief Check whether the product automaton contains
/// a livelock-accepting run

View file

@ -47,8 +47,8 @@ namespace spot
{
static std::ostream&
dump_hash_set(const hash_set* hs,
const const_ta_ptr& aut,
std::ostream& out)
const const_ta_ptr& aut,
std::ostream& out)
{
out << '{';
const char* sep = "";
@ -73,7 +73,7 @@ namespace spot
// automaton
static void
build_result(const const_ta_ptr& a, std::list<hash_set*>& sets,
twa_graph_ptr result_tgba, const ta_explicit_ptr& result)
twa_graph_ptr result_tgba, const ta_explicit_ptr& result)
{
// For each set, create a state in the tgbaulting automaton.
// For a state s, state_num[s] is the number of the state in the minimal
@ -82,103 +82,103 @@ namespace spot
std::list<hash_set*>::iterator sit;
unsigned num = 0;
for (sit = sets.begin(); sit != sets.end(); ++sit)
{
hash_set::iterator hit;
hash_set* h = *sit;
for (hit = h->begin(); hit != h->end(); ++hit)
state_num[*hit] = num;
result_tgba->new_state();
++num;
}
{
hash_set::iterator hit;
hash_set* h = *sit;
for (hit = h->begin(); hit != h->end(); ++hit)
state_num[*hit] = num;
result_tgba->new_state();
++num;
}
// For each transition in the initial automaton, add the corresponding
// transition in ta.
for (sit = sets.begin(); sit != sets.end(); ++sit)
{
hash_set::iterator hit;
hash_set* h = *sit;
hit = h->begin();
const state* src = *hit;
unsigned src_num = state_num[src];
{
hash_set::iterator hit;
hash_set* h = *sit;
hit = h->begin();
const state* src = *hit;
unsigned src_num = state_num[src];
bdd tgba_condition = bddtrue;
bool is_initial_state = a->is_initial_state(src);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(src);
bool is_accepting_state = a->is_accepting_state(src);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(src);
bdd tgba_condition = bddtrue;
bool is_initial_state = a->is_initial_state(src);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(src);
bool is_accepting_state = a->is_accepting_state(src);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(src);
state_ta_explicit* new_src =
new state_ta_explicit(result_tgba->state_from_number(src_num),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* new_src =
new state_ta_explicit(result_tgba->state_from_number(src_num),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* ta_src = result->add_state(new_src);
state_ta_explicit* ta_src = result->add_state(new_src);
if (ta_src != new_src)
{
delete new_src;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == src)
result->set_artificial_initial_state(new_src);
}
else if (is_initial_state)
{
result->add_to_initial_states_set(new_src);
}
if (ta_src != new_src)
{
delete new_src;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == src)
result->set_artificial_initial_state(new_src);
}
else if (is_initial_state)
{
result->add_to_initial_states_set(new_src);
}
ta_succ_iterator* succit = a->succ_iter(src);
ta_succ_iterator* succit = a->succ_iter(src);
for (succit->first(); !succit->done(); succit->next())
{
const state* dst = succit->dst();
hash_map::const_iterator i = state_num.find(dst);
for (succit->first(); !succit->done(); succit->next())
{
const state* dst = succit->dst();
hash_map::const_iterator i = state_num.find(dst);
if (i == state_num.end()) // Ignore useless destinations.
continue;
if (i == state_num.end()) // Ignore useless destinations.
continue;
bdd tgba_condition = bddtrue;
is_initial_state = a->is_initial_state(dst);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(dst);
bool is_accepting_state = a->is_accepting_state(dst);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(dst);
bdd tgba_condition = bddtrue;
is_initial_state = a->is_initial_state(dst);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(dst);
bool is_accepting_state = a->is_accepting_state(dst);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(dst);
state_ta_explicit* new_dst =
new state_ta_explicit
(result_tgba->state_from_number(i->second),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* new_dst =
new state_ta_explicit
(result_tgba->state_from_number(i->second),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* ta_dst = result->add_state(new_dst);
state_ta_explicit* ta_dst = result->add_state(new_dst);
if (ta_dst != new_dst)
{
delete new_dst;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == dst)
result->set_artificial_initial_state(new_dst);
}
if (ta_dst != new_dst)
{
delete new_dst;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == dst)
result->set_artificial_initial_state(new_dst);
}
else if (is_initial_state)
result->add_to_initial_states_set(new_dst);
else if (is_initial_state)
result->add_to_initial_states_set(new_dst);
result->create_transition
(ta_src, succit->cond(),
succit->acc(),
ta_dst);
}
delete succit;
}
result->create_transition
(ta_src, succit->cond(),
succit->acc(),
ta_dst);
}
delete succit;
}
}
static partition_t
@ -187,22 +187,22 @@ namespace spot
unsigned num_sets = ta_->acc().num_sets();
std::map<acc_cond::mark_t, bdd> m2b;
int acc_vars = ta_->get_dict()->register_anonymous_variables(num_sets,
&m2b);
&m2b);
auto mark_to_bdd = [&](acc_cond::mark_t m) -> bdd
{
auto i = m2b.find(m);
if (i != m2b.end())
return i->second;
{
auto i = m2b.find(m);
if (i != m2b.end())
return i->second;
bdd res = bddtrue;
for (unsigned n = 0; n < num_sets; ++n)
if (m.has(n))
res &= bdd_ithvar(acc_vars + n);
else
res &= bdd_nithvar(acc_vars + n);
m2b.emplace_hint(i, m, res);
return res;
};
bdd res = bddtrue;
for (unsigned n = 0; n < num_sets; ++n)
if (m.has(n))
res &= bdd_ithvar(acc_vars + n);
else
res &= bdd_nithvar(acc_vars + n);
m2b.emplace_hint(i, m, res);
return res;
};
partition_t cur_run;
partition_t next_run;
@ -231,22 +231,22 @@ namespace spot
auto artificial_initial_state = ta_->get_artificial_initial_state();
for (it = states_set.begin(); it != states_set.end(); ++it)
{
const state* s = *it;
if (s == artificial_initial_state)
I->insert(s);
else if (!artificial_initial_state && ta_->is_initial_state(s))
I->insert(s);
else if (ta_->is_livelock_accepting_state(s)
&& ta_->is_accepting_state(s))
G_F->insert(s);
else if (ta_->is_accepting_state(s))
F->insert(s);
else if (ta_->is_livelock_accepting_state(s))
G->insert(s);
else
S->insert(s);
}
{
const state* s = *it;
if (s == artificial_initial_state)
I->insert(s);
else if (!artificial_initial_state && ta_->is_initial_state(s))
I->insert(s);
else if (ta_->is_livelock_accepting_state(s)
&& ta_->is_accepting_state(s))
G_F->insert(s);
else if (ta_->is_accepting_state(s))
F->insert(s);
else if (ta_->is_livelock_accepting_state(s))
G->insert(s);
else
S->insert(s);
}
hash_map state_set_map;
@ -255,103 +255,103 @@ namespace spot
// Use bdd variables to number sets. set_num is the first variable
// available.
unsigned set_num =
ta_->get_dict()->register_anonymous_variables(size, &m2b);
ta_->get_dict()->register_anonymous_variables(size, &m2b);
std::set<int> free_var;
for (unsigned i = set_num; i < set_num + size; ++i)
free_var.insert(i);
free_var.insert(i);
std::map<int, int> used_var;
for (hash_set::const_iterator i = I->begin(); i != I->end(); ++i)
{
hash_set* cI = new hash_set;
cI->insert(*i);
done.push_back(cI);
{
hash_set* cI = new hash_set;
cI->insert(*i);
done.push_back(cI);
used_var[set_num] = 1;
free_var.erase(set_num);
state_set_map[*i] = set_num;
++set_num;
used_var[set_num] = 1;
free_var.erase(set_num);
state_set_map[*i] = set_num;
++set_num;
}
}
delete I;
if (!G->empty())
{
unsigned s = G->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G);
else
done.push_back(G);
for (hash_set::const_iterator i = G->begin(); i != G->end(); ++i)
state_set_map[*i] = num;
{
unsigned s = G->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G);
else
done.push_back(G);
for (hash_set::const_iterator i = G->begin(); i != G->end(); ++i)
state_set_map[*i] = num;
}
}
else
{
delete G;
}
{
delete G;
}
if (!F->empty())
{
unsigned s = F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(F);
else
done.push_back(F);
for (hash_set::const_iterator i = F->begin(); i != F->end(); ++i)
state_set_map[*i] = num;
}
{
unsigned s = F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(F);
else
done.push_back(F);
for (hash_set::const_iterator i = F->begin(); i != F->end(); ++i)
state_set_map[*i] = num;
}
else
{
delete F;
}
{
delete F;
}
if (!G_F->empty())
{
unsigned s = G_F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G_F);
else
done.push_back(G_F);
for (hash_set::const_iterator i = G_F->begin(); i != G_F->end(); ++i)
state_set_map[*i] = num;
}
{
unsigned s = G_F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G_F);
else
done.push_back(G_F);
for (hash_set::const_iterator i = G_F->begin(); i != G_F->end(); ++i)
state_set_map[*i] = num;
}
else
{
delete G_F;
}
{
delete G_F;
}
if (!S->empty())
{
unsigned s = S->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(S);
else
done.push_back(S);
for (hash_set::const_iterator i = S->begin(); i != S->end(); ++i)
state_set_map[*i] = num;
}
{
unsigned s = S->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(S);
else
done.push_back(S);
for (hash_set::const_iterator i = S->begin(); i != S->end(); ++i)
state_set_map[*i] = num;
}
else
{
delete S;
}
{
delete S;
}
// A bdd_states_map is a list of formulae (in a BDD form)
@ -366,132 +366,132 @@ namespace spot
bdd bdd_false_acceptance_condition = bdd_ithvar(num);
while (did_split)
{
did_split = false;
while (!cur_run.empty())
{
// Get a set to process.
hash_set* cur = cur_run.front();
cur_run.pop_front();
{
did_split = false;
while (!cur_run.empty())
{
// Get a set to process.
hash_set* cur = cur_run.front();
cur_run.pop_front();
trace
<< "processing " << format_hash_set(cur, ta_) << std::endl;
trace
<< "processing " << format_hash_set(cur, ta_) << std::endl;
hash_set::iterator hi;
bdd_states_map bdd_map;
for (hi = cur->begin(); hi != cur->end(); ++hi)
{
const state* src = *hi;
bdd f = bddfalse;
ta_succ_iterator* si = ta_->succ_iter(src);
trace << "+src: " << src << std::endl;
for (si->first(); !si->done(); si->next())
{
const state* dst = si->dst();
hash_map::const_iterator i = state_set_map.find(dst);
hash_set::iterator hi;
bdd_states_map bdd_map;
for (hi = cur->begin(); hi != cur->end(); ++hi)
{
const state* src = *hi;
bdd f = bddfalse;
ta_succ_iterator* si = ta_->succ_iter(src);
trace << "+src: " << src << std::endl;
for (si->first(); !si->done(); si->next())
{
const state* dst = si->dst();
hash_map::const_iterator i = state_set_map.find(dst);
assert(i != state_set_map.end());
auto curacc =
mark_to_bdd(si->acc());
f |= (bdd_ithvar(i->second)
& si->cond() & curacc);
trace
<< "+f: " << bdd_format_accset(ta_->get_dict(), f)
<< "\n -bdd_ithvar(i->second): "
<< bdd_format_accset(ta_->get_dict(),
bdd_ithvar(i->second))
<< "\n -si->cond(): "
<< bdd_format_accset(ta_->get_dict(),
si->cond())
<< "\n -current_acceptance_conditions: "
<< si->acc()
<< std::endl;
}
delete si;
assert(i != state_set_map.end());
auto curacc =
mark_to_bdd(si->acc());
f |= (bdd_ithvar(i->second)
& si->cond() & curacc);
trace
<< "+f: " << bdd_format_accset(ta_->get_dict(), f)
<< "\n -bdd_ithvar(i->second): "
<< bdd_format_accset(ta_->get_dict(),
bdd_ithvar(i->second))
<< "\n -si->cond(): "
<< bdd_format_accset(ta_->get_dict(),
si->cond())
<< "\n -current_acceptance_conditions: "
<< si->acc()
<< std::endl;
}
delete si;
// Have we already seen this formula ?
bdd_states_map::iterator bsi = bdd_map.find(f);
if (bsi == bdd_map.end())
{
// No, create a new set.
hash_set* new_set = new hash_set;
new_set->insert(src);
bdd_map[f] = new_set;
}
else
{
// Yes, add the current state to the set.
bsi->second->insert(src);
}
}
// Have we already seen this formula ?
bdd_states_map::iterator bsi = bdd_map.find(f);
if (bsi == bdd_map.end())
{
// No, create a new set.
hash_set* new_set = new hash_set;
new_set->insert(src);
bdd_map[f] = new_set;
}
else
{
// Yes, add the current state to the set.
bsi->second->insert(src);
}
}
bdd_states_map::iterator bsi = bdd_map.begin();
if (bdd_map.size() == 1)
{
// The set was not split.
trace
<< "set " << format_hash_set(bsi->second, ta_)
<< " was not split" << std::endl;
next_run.push_back(bsi->second);
}
else
{
did_split = true;
for (; bsi != bdd_map.end(); ++bsi)
{
hash_set* set = bsi->second;
// Free the number associated to these states.
unsigned num = state_set_map[*set->begin()];
assert(used_var.find(num) != used_var.end());
unsigned left = (used_var[num] -= set->size());
// Make sure LEFT does not become negative
// (hence bigger than SIZE when read as unsigned)
assert(left < size);
if (left == 0)
{
used_var.erase(num);
free_var.insert(num);
}
// Pick a free number
assert(!free_var.empty());
num = *free_var.begin();
free_var.erase(free_var.begin());
used_var[num] = set->size();
for (hash_set::iterator hit = set->begin();
hit != set->end(); ++hit)
state_set_map[*hit] = num;
// Trivial sets can't be splitted any further.
if (set->size() == 1)
{
trace
<< "set " << format_hash_set(set, ta_)
<< " is minimal" << std::endl;
done.push_back(set);
}
else
{
trace
<< "set " << format_hash_set(set, ta_)
<< " should be processed further" << std::endl;
next_run.push_back(set);
}
}
}
delete cur;
}
if (did_split)
trace
<< "splitting did occur during this pass." << std::endl;
bdd_states_map::iterator bsi = bdd_map.begin();
if (bdd_map.size() == 1)
{
// The set was not split.
trace
<< "set " << format_hash_set(bsi->second, ta_)
<< " was not split" << std::endl;
next_run.push_back(bsi->second);
}
else
{
did_split = true;
for (; bsi != bdd_map.end(); ++bsi)
{
hash_set* set = bsi->second;
// Free the number associated to these states.
unsigned num = state_set_map[*set->begin()];
assert(used_var.find(num) != used_var.end());
unsigned left = (used_var[num] -= set->size());
// Make sure LEFT does not become negative
// (hence bigger than SIZE when read as unsigned)
assert(left < size);
if (left == 0)
{
used_var.erase(num);
free_var.insert(num);
}
// Pick a free number
assert(!free_var.empty());
num = *free_var.begin();
free_var.erase(free_var.begin());
used_var[num] = set->size();
for (hash_set::iterator hit = set->begin();
hit != set->end(); ++hit)
state_set_map[*hit] = num;
// Trivial sets can't be splitted any further.
if (set->size() == 1)
{
trace
<< "set " << format_hash_set(set, ta_)
<< " is minimal" << std::endl;
done.push_back(set);
}
else
{
trace
<< "set " << format_hash_set(set, ta_)
<< " should be processed further" << std::endl;
next_run.push_back(set);
}
}
}
delete cur;
}
if (did_split)
trace
<< "splitting did occur during this pass." << std::endl;
std::swap(cur_run, next_run);
}
std::swap(cur_run, next_run);
}
done.splice(done.end(), cur_run);
#ifdef TRACE
trace << "Final partition: ";
for (partition_t::const_iterator i = done.begin(); i != done.end(); ++i)
trace << format_hash_set(*i, ta_) << ' ';
trace << format_hash_set(*i, ta_) << ' ';
trace << std::endl;
#endif

View file

@ -51,17 +51,17 @@ namespace spot
{
if (artificial_livelock_acc_state)
{
auto artificial_livelock_acc_state_added =
{
auto artificial_livelock_acc_state_added =
testing_automata->add_state(artificial_livelock_acc_state);
// unique artificial_livelock_acc_state
assert(artificial_livelock_acc_state_added
== artificial_livelock_acc_state);
(void)artificial_livelock_acc_state_added;
artificial_livelock_acc_state->set_livelock_accepting_state(true);
artificial_livelock_acc_state->free_transitions();
}
// unique artificial_livelock_acc_state
assert(artificial_livelock_acc_state_added
== artificial_livelock_acc_state);
(void)artificial_livelock_acc_state_added;
artificial_livelock_acc_state->set_livelock_accepting_state(true);
artificial_livelock_acc_state->free_transitions();
}
ta::states_set_t states_set = testing_automata->get_states_set();
ta::states_set_t::iterator it;
@ -70,86 +70,86 @@ namespace spot
new state_ta_explicit::transitions;
for (it = states_set.begin(); it != states_set.end(); ++it)
{
auto source = const_cast<state_ta_explicit*>
(static_cast<const state_ta_explicit*>(*it));
{
auto source = const_cast<state_ta_explicit*>
(static_cast<const state_ta_explicit*>(*it));
transitions_to_livelock_states->clear();
transitions_to_livelock_states->clear();
state_ta_explicit::transitions* trans = source->get_transitions();
state_ta_explicit::transitions::iterator it_trans;
state_ta_explicit::transitions* trans = source->get_transitions();
state_ta_explicit::transitions::iterator it_trans;
if (trans)
for (it_trans = trans->begin(); it_trans != trans->end();)
{
auto dest = const_cast<state_ta_explicit*>((*it_trans)->dest);
if (trans)
for (it_trans = trans->begin(); it_trans != trans->end();)
{
auto dest = const_cast<state_ta_explicit*>((*it_trans)->dest);
state_ta_explicit::transitions* dest_trans =
dest->get_transitions();
bool dest_trans_empty = !dest_trans || dest_trans->empty();
state_ta_explicit::transitions* dest_trans =
dest->get_transitions();
bool dest_trans_empty = !dest_trans || dest_trans->empty();
//select transitions where a destination is a livelock state
// which isn't a Buchi accepting state and has successors
if (dest->is_livelock_accepting_state()
&& (!dest->is_accepting_state()) && (!dest_trans_empty))
transitions_to_livelock_states->push_front(*it_trans);
//select transitions where a destination is a livelock state
// which isn't a Buchi accepting state and has successors
if (dest->is_livelock_accepting_state()
&& (!dest->is_accepting_state()) && (!dest_trans_empty))
transitions_to_livelock_states->push_front(*it_trans);
// optimization to have, after minimization, an unique
// livelock state which has no successors
if (dest->is_livelock_accepting_state() && (dest_trans_empty))
dest->set_accepting_state(false);
// optimization to have, after minimization, an unique
// livelock state which has no successors
if (dest->is_livelock_accepting_state() && (dest_trans_empty))
dest->set_accepting_state(false);
++it_trans;
}
++it_trans;
}
if (transitions_to_livelock_states)
{
state_ta_explicit::transitions::iterator it_trans;
if (transitions_to_livelock_states)
{
state_ta_explicit::transitions::iterator it_trans;
for (it_trans = transitions_to_livelock_states->begin();
it_trans != transitions_to_livelock_states->end();
++it_trans)
{
if (artificial_livelock_acc_state)
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
artificial_livelock_acc_state, true);
}
else
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
((*it_trans)->dest)->stuttering_reachable_livelock,
true);
}
}
}
}
for (it_trans = transitions_to_livelock_states->begin();
it_trans != transitions_to_livelock_states->end();
++it_trans)
{
if (artificial_livelock_acc_state)
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
artificial_livelock_acc_state, true);
}
else
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
((*it_trans)->dest)->stuttering_reachable_livelock,
true);
}
}
}
}
delete transitions_to_livelock_states;
for (it = states_set.begin(); it != states_set.end(); ++it)
{
state_ta_explicit* state = static_cast<state_ta_explicit*> (*it);
state_ta_explicit::transitions* state_trans =
{
state_ta_explicit* state = static_cast<state_ta_explicit*> (*it);
state_ta_explicit::transitions* state_trans =
(state)->get_transitions();
bool state_trans_empty = !state_trans || state_trans->empty();
bool state_trans_empty = !state_trans || state_trans->empty();
if (state->is_livelock_accepting_state()
&& (!state->is_accepting_state()) && (!state_trans_empty))
state->set_livelock_accepting_state(false);
}
if (state->is_livelock_accepting_state()
&& (!state->is_accepting_state()) && (!state_trans_empty))
state->set_livelock_accepting_state(false);
}
}
static void
compute_livelock_acceptance_states(const ta_explicit_ptr& testing_aut,
bool single_pass_emptiness_check,
state_ta_explicit*
artificial_livelock_acc_state)
bool single_pass_emptiness_check,
state_ta_explicit*
artificial_livelock_acc_state)
{
// We use five main data in this algorithm:
// * sscc: a stack of strongly stuttering-connected components (SSCC)
@ -177,234 +177,234 @@ namespace spot
std::stack<const state*> init_set;
for (auto s: testing_aut->get_initial_states_set())
init_set.push(s);
init_set.push(s);
while (!init_set.empty())
{
// Setup depth-first search from initial states.
{
// Setup depth-first search from initial states.
{
auto init = down_cast<const state_ta_explicit*> (init_set.top());
init_set.pop();
{
auto init = down_cast<const state_ta_explicit*> (init_set.top());
init_set.pop();
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
sscc.push(++num);
arc.push(0U);
sscc.top().is_accepting
sscc.push(++num);
arc.push(0U);
sscc.top().is_accepting
= testing_aut->is_accepting_state(init);
twa_succ_iterator* iter = testing_aut->succ_iter(init);
iter->first();
todo.emplace(init, iter);
}
twa_succ_iterator* iter = testing_aut->succ_iter(init);
iter->first();
todo.emplace(init, iter);
}
while (!todo.empty())
{
auto curr = todo.top().first;
while (!todo.empty())
{
auto curr = todo.top().first;
auto i = h.find(curr);
// If we have reached a dead component, ignore it.
if (i != h.end() && i->second == -1)
{
todo.pop();
continue;
}
auto i = h.find(curr);
// If we have reached a dead component, ignore it.
if (i != h.end() && i->second == -1)
{
todo.pop();
continue;
}
// We are looking at the next successor in SUCC.
twa_succ_iterator* succ = todo.top().second;
// We are looking at the next successor in SUCC.
twa_succ_iterator* succ = todo.top().second;
// If there is no more successor, backtrack.
if (succ->done())
{
// We have explored all successors of state CURR.
// If there is no more successor, backtrack.
if (succ->done())
{
// We have explored all successors of state CURR.
// Backtrack TODO.
todo.pop();
// Backtrack TODO.
todo.pop();
// fill rem with any component removed,
assert(i != h.end());
sscc.rem().push_front(curr);
// fill rem with any component removed,
assert(i != h.end());
sscc.rem().push_front(curr);
// When backtracking the root of an SSCC, we must also
// remove that SSCC from the ROOT stacks. We must
// discard from H all reachable states from this SSCC.
assert(!sscc.empty());
if (sscc.top().index == i->second)
{
// removing states
bool is_livelock_accepting_sscc = (sscc.rem().size() > 1)
&& ((sscc.top().is_accepting) ||
(testing_aut->acc().
accepting(sscc.top().condition)));
trace << "*** sscc.size() = ***" << sscc.size() << '\n';
for (auto j: sscc.rem())
{
h[j] = -1;
// When backtracking the root of an SSCC, we must also
// remove that SSCC from the ROOT stacks. We must
// discard from H all reachable states from this SSCC.
assert(!sscc.empty());
if (sscc.top().index == i->second)
{
// removing states
bool is_livelock_accepting_sscc = (sscc.rem().size() > 1)
&& ((sscc.top().is_accepting) ||
(testing_aut->acc().
accepting(sscc.top().condition)));
trace << "*** sscc.size() = ***" << sscc.size() << '\n';
for (auto j: sscc.rem())
{
h[j] = -1;
if (is_livelock_accepting_sscc)
{
// if it is an accepting sscc add the state to
// G (=the livelock-accepting states set)
trace << "*** sscc.size() > 1: states: ***"
<< testing_aut->format_state(j)
<< '\n';
auto livelock_accepting_state =
const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(j));
if (is_livelock_accepting_sscc)
{
// if it is an accepting sscc add the state to
// G (=the livelock-accepting states set)
trace << "*** sscc.size() > 1: states: ***"
<< testing_aut->format_state(j)
<< '\n';
auto livelock_accepting_state =
const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(j));
livelock_accepting_state->
set_livelock_accepting_state(true);
livelock_accepting_state->
set_livelock_accepting_state(true);
if (single_pass_emptiness_check)
{
livelock_accepting_state
->set_accepting_state(true);
livelock_accepting_state
->stuttering_reachable_livelock
= livelock_accepting_state;
}
}
}
if (single_pass_emptiness_check)
{
livelock_accepting_state
->set_accepting_state(true);
livelock_accepting_state
->stuttering_reachable_livelock
= livelock_accepting_state;
}
}
}
assert(!arc.empty());
sscc.pop();
arc.pop();
}
assert(!arc.empty());
sscc.pop();
arc.pop();
}
// automata reduction
testing_aut->delete_stuttering_and_hole_successors(curr);
// automata reduction
testing_aut->delete_stuttering_and_hole_successors(curr);
delete succ;
// Do not delete CURR: it is a key in H.
continue;
}
delete succ;
// Do not delete CURR: it is a key in H.
continue;
}
// Fetch the values destination state we are interested in...
auto dest = succ->dst();
// Fetch the values destination state we are interested in...
auto dest = succ->dst();
auto acc_cond = succ->acc();
// ... and point the iterator to the next successor, for
// the next iteration.
succ->next();
// We do not need SUCC from now on.
auto acc_cond = succ->acc();
// ... and point the iterator to the next successor, for
// the next iteration.
succ->next();
// We do not need SUCC from now on.
// Are we going to a new state through a stuttering transition?
bool is_stuttering_transition =
testing_aut->get_state_condition(curr)
== testing_aut->get_state_condition(dest);
auto id = h.find(dest);
// Are we going to a new state through a stuttering transition?
bool is_stuttering_transition =
testing_aut->get_state_condition(curr)
== testing_aut->get_state_condition(dest);
auto id = h.find(dest);
// Is this a new state?
if (id == h.end())
{
if (!is_stuttering_transition)
{
init_set.push(dest);
dest->destroy();
continue;
}
// Is this a new state?
if (id == h.end())
{
if (!is_stuttering_transition)
{
init_set.push(dest);
dest->destroy();
continue;
}
// Number it, stack it, and register its successors
// for later processing.
h[dest] = ++num;
sscc.push(num);
arc.push(acc_cond);
sscc.top().is_accepting =
testing_aut->is_accepting_state(dest);
// Number it, stack it, and register its successors
// for later processing.
h[dest] = ++num;
sscc.push(num);
arc.push(acc_cond);
sscc.top().is_accepting =
testing_aut->is_accepting_state(dest);
twa_succ_iterator* iter = testing_aut->succ_iter(dest);
iter->first();
todo.emplace(dest, iter);
continue;
}
dest->destroy();
twa_succ_iterator* iter = testing_aut->succ_iter(dest);
iter->first();
todo.emplace(dest, iter);
continue;
}
dest->destroy();
// If we have reached a dead component, ignore it.
if (id->second == -1)
continue;
// If we have reached a dead component, ignore it.
if (id->second == -1)
continue;
trace << "***compute_livelock_acceptance_states: CYCLE***\n";
trace << "***compute_livelock_acceptance_states: CYCLE***\n";
if (!curr->compare(id->first))
{
auto self_loop_state = const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(curr));
assert(self_loop_state);
if (!curr->compare(id->first))
{
auto self_loop_state = const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(curr));
assert(self_loop_state);
if (testing_aut->is_accepting_state(self_loop_state)
|| (testing_aut->acc().accepting(acc_cond)))
{
self_loop_state->set_livelock_accepting_state(true);
if (single_pass_emptiness_check)
{
self_loop_state->set_accepting_state(true);
self_loop_state->stuttering_reachable_livelock
= self_loop_state;
}
}
if (testing_aut->is_accepting_state(self_loop_state)
|| (testing_aut->acc().accepting(acc_cond)))
{
self_loop_state->set_livelock_accepting_state(true);
if (single_pass_emptiness_check)
{
self_loop_state->set_accepting_state(true);
self_loop_state->stuttering_reachable_livelock
= self_loop_state;
}
}
trace
<< "***compute_livelock_acceptance_states: CYCLE: "
<< "self_loop_state***\n";
}
trace
<< "***compute_livelock_acceptance_states: CYCLE: "
<< "self_loop_state***\n";
}
// Now this is the most interesting case. We have reached a
// state S1 which is already part of a non-dead SSCC. Any such
// non-dead SSCC has necessarily been crossed by our path to
// this state: there is a state S2 in our path which belongs
// to this SSCC too. We are going to merge all states between
// this S1 and S2 into this SSCC.
//
// This merge is easy to do because the order of the SSCC in
// ROOT is ascending: we just have to merge all SSCCs from the
// top of ROOT that have an index greater to the one of
// the SSCC of S2 (called the "threshold").
int threshold = id->second;
std::list<const state*> rem;
bool acc = false;
// Now this is the most interesting case. We have reached a
// state S1 which is already part of a non-dead SSCC. Any such
// non-dead SSCC has necessarily been crossed by our path to
// this state: there is a state S2 in our path which belongs
// to this SSCC too. We are going to merge all states between
// this S1 and S2 into this SSCC.
//
// This merge is easy to do because the order of the SSCC in
// ROOT is ascending: we just have to merge all SSCCs from the
// top of ROOT that have an index greater to the one of
// the SSCC of S2 (called the "threshold").
int threshold = id->second;
std::list<const state*> rem;
bool acc = false;
while (threshold < sscc.top().index)
{
assert(!sscc.empty());
assert(!arc.empty());
acc |= sscc.top().is_accepting;
acc_cond |= sscc.top().condition;
acc_cond |= arc.top();
rem.splice(rem.end(), sscc.rem());
sscc.pop();
arc.pop();
}
while (threshold < sscc.top().index)
{
assert(!sscc.empty());
assert(!arc.empty());
acc |= sscc.top().is_accepting;
acc_cond |= sscc.top().condition;
acc_cond |= arc.top();
rem.splice(rem.end(), sscc.rem());
sscc.pop();
arc.pop();
}
// Note that we do not always have
// threshold == sscc.top().index
// after this loop, the SSCC whose index is threshold might have
// been merged with a lower SSCC.
// Note that we do not always have
// threshold == sscc.top().index
// after this loop, the SSCC whose index is threshold might have
// been merged with a lower SSCC.
// Accumulate all acceptance conditions into the merged SSCC.
sscc.top().is_accepting |= acc;
sscc.top().condition |= acc_cond;
// Accumulate all acceptance conditions into the merged SSCC.
sscc.top().is_accepting |= acc;
sscc.top().condition |= acc_cond;
sscc.rem().splice(sscc.rem().end(), rem);
sscc.rem().splice(sscc.rem().end(), rem);
}
}
}
}
if (artificial_livelock_acc_state || single_pass_emptiness_check)
transform_to_single_pass_automaton(testing_aut,
artificial_livelock_acc_state);
transform_to_single_pass_automaton(testing_aut,
artificial_livelock_acc_state);
}
ta_explicit_ptr
build_ta(const ta_explicit_ptr& ta, bdd atomic_propositions_set_,
bool degeneralized,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
bool degeneralized,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
{
std::stack<state_ta_explicit*> todo;
@ -414,140 +414,140 @@ namespace spot
auto tgba_init_state = tgba_->get_init_state();
bdd tgba_condition = [&]()
{
bdd cond = bddfalse;
for (auto i: tgba_->succ(tgba_init_state))
cond |= i->cond();
return cond;
}();
{
bdd cond = bddfalse;
for (auto i: tgba_->succ(tgba_init_state))
cond |= i->cond();
return cond;
}();
bool is_acc = false;
if (degeneralized)
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_init_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_init_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
bdd satone_tgba_condition;
while ((satone_tgba_condition = bdd_satoneset(tgba_condition,
atomic_propositions_set_,
bddtrue)) != bddfalse)
{
tgba_condition -= satone_tgba_condition;
state_ta_explicit* init_state = new
state_ta_explicit(tgba_init_state->clone(),
satone_tgba_condition, true, is_acc);
state_ta_explicit* s = ta->add_state(init_state);
assert(s == init_state);
ta->add_to_initial_states_set(s);
atomic_propositions_set_,
bddtrue)) != bddfalse)
{
tgba_condition -= satone_tgba_condition;
state_ta_explicit* init_state = new
state_ta_explicit(tgba_init_state->clone(),
satone_tgba_condition, true, is_acc);
state_ta_explicit* s = ta->add_state(init_state);
assert(s == init_state);
ta->add_to_initial_states_set(s);
todo.push(init_state);
}
todo.push(init_state);
}
tgba_init_state->destroy();
while (!todo.empty())
{
state_ta_explicit* source = todo.top();
todo.pop();
{
state_ta_explicit* source = todo.top();
todo.pop();
twa_succ_iterator* twa_succ_it =
tgba_->succ_iter(source->get_tgba_state());
for (twa_succ_it->first(); !twa_succ_it->done();
twa_succ_it->next())
{
const state* tgba_state = twa_succ_it->dst();
bdd tgba_condition = twa_succ_it->cond();
acc_cond::mark_t tgba_acceptance_conditions =
twa_succ_iterator* twa_succ_it =
tgba_->succ_iter(source->get_tgba_state());
for (twa_succ_it->first(); !twa_succ_it->done();
twa_succ_it->next())
{
const state* tgba_state = twa_succ_it->dst();
bdd tgba_condition = twa_succ_it->cond();
acc_cond::mark_t tgba_acceptance_conditions =
twa_succ_it->acc();
bdd satone_tgba_condition;
while ((satone_tgba_condition =
bdd_satoneset(tgba_condition,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
tgba_condition -= satone_tgba_condition;
bdd satone_tgba_condition;
while ((satone_tgba_condition =
bdd_satoneset(tgba_condition,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
tgba_condition -= satone_tgba_condition;
bdd all_props = bddtrue;
bdd dest_condition;
bdd all_props = bddtrue;
bdd dest_condition;
bool is_acc = false;
if (degeneralized)
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
bool is_acc = false;
if (degeneralized)
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
if (satone_tgba_condition == source->get_tgba_condition())
while ((dest_condition =
bdd_satoneset(all_props,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
all_props -= dest_condition;
state_ta_explicit* new_dest =
new state_ta_explicit(tgba_state->clone(),
dest_condition, false, is_acc);
state_ta_explicit* dest = ta->add_state(new_dest);
if (satone_tgba_condition == source->get_tgba_condition())
while ((dest_condition =
bdd_satoneset(all_props,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
all_props -= dest_condition;
state_ta_explicit* new_dest =
new state_ta_explicit(tgba_state->clone(),
dest_condition, false, is_acc);
state_ta_explicit* dest = ta->add_state(new_dest);
if (dest != new_dest)
{
// the state dest already exists in the automaton
new_dest->get_tgba_state()->destroy();
delete new_dest;
}
else
{
todo.push(dest);
}
if (dest != new_dest)
{
// the state dest already exists in the automaton
new_dest->get_tgba_state()->destroy();
delete new_dest;
}
else
{
todo.push(dest);
}
bdd cs = bdd_setxor(source->get_tgba_condition(),
dest->get_tgba_condition());
ta->create_transition(source, cs,
tgba_acceptance_conditions, dest);
}
}
tgba_state->destroy();
}
delete twa_succ_it;
}
bdd cs = bdd_setxor(source->get_tgba_condition(),
dest->get_tgba_condition());
ta->create_transition(source, cs,
tgba_acceptance_conditions, dest);
}
}
tgba_state->destroy();
}
delete twa_succ_it;
}
if (no_livelock)
return ta;
return ta;
state_ta_explicit* artificial_livelock_acc_state = nullptr;
trace << "*** build_ta: artificial_livelock_acc_state_mode = ***"
<< artificial_livelock_state_mode << std::endl;
<< artificial_livelock_state_mode << std::endl;
if (artificial_livelock_state_mode)
{
single_pass_emptiness_check = true;
artificial_livelock_acc_state =
new state_ta_explicit(ta->get_tgba()->get_init_state(), bddtrue,
false, false, true, nullptr);
trace
<< "*** build_ta: artificial_livelock_acc_state = ***"
<< artificial_livelock_acc_state << std::endl;
}
{
single_pass_emptiness_check = true;
artificial_livelock_acc_state =
new state_ta_explicit(ta->get_tgba()->get_init_state(), bddtrue,
false, false, true, nullptr);
trace
<< "*** build_ta: artificial_livelock_acc_state = ***"
<< artificial_livelock_acc_state << std::endl;
}
compute_livelock_acceptance_states(ta, single_pass_emptiness_check,
artificial_livelock_acc_state);
artificial_livelock_acc_state);
return ta;
}
}
ta_explicit_ptr
tgba_to_ta(const const_twa_ptr& tgba_, bdd atomic_propositions_set_,
bool degeneralized, bool artificial_initial_state_mode,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
bool degeneralized, bool artificial_initial_state_mode,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
{
ta_explicit_ptr ta;
@ -555,10 +555,10 @@ namespace spot
if (artificial_initial_state_mode)
{
state_ta_explicit* artificial_init_state =
new state_ta_explicit(tgba_init_state->clone(), bddfalse, true);
new state_ta_explicit(tgba_init_state->clone(), bddfalse, true);
ta = make_ta_explicit(tgba_, tgba_->acc().num_sets(),
artificial_init_state);
artificial_init_state);
}
else
{
@ -568,8 +568,8 @@ namespace spot
// build ta automaton
build_ta(ta, atomic_propositions_set_, degeneralized,
single_pass_emptiness_check, artificial_livelock_state_mode,
no_livelock);
single_pass_emptiness_check, artificial_livelock_state_mode,
no_livelock);
// (degeneralized=true) => TA
if (degeneralized)
@ -589,8 +589,8 @@ namespace spot
state_ta_explicit::transitions::iterator it_trans;
for (it_trans = trans->begin(); it_trans != trans->end();
++it_trans)
(*it_trans)->acceptance_conditions = ta->acc().all_sets();
++it_trans)
(*it_trans)->acceptance_conditions = ta->acc().all_sets();
state->set_accepting_state(false);
}
@ -604,11 +604,11 @@ namespace spot
{
auto tgba_init_state = tgba_->get_init_state();
auto artificial_init_state = new state_ta_explicit(tgba_init_state->clone(),
bddfalse, true);
bddfalse, true);
tgba_init_state->destroy();
auto tgta = make_tgta_explicit(tgba_, tgba_->acc().num_sets(),
artificial_init_state);
artificial_init_state);
// build a Generalized TA automaton involving a single_pass_emptiness_check
// (without an artificial livelock state):
@ -625,14 +625,14 @@ namespace spot
initial_states_iter->first();
if (initial_states_iter->done())
{
delete initial_states_iter;
return tgta;
delete initial_states_iter;
return tgta;
}
bdd first_state_condition = initial_states_iter->cond();
delete initial_states_iter;
bdd bdd_stutering_transition = bdd_setxor(first_state_condition,
first_state_condition);
first_state_condition);
for (it = states_set.begin(); it != states_set.end(); ++it)
{
@ -645,13 +645,13 @@ namespace spot
if (trans_empty || state->is_accepting_state())
{
ta->create_transition(state, bdd_stutering_transition,
ta->acc().all_sets(), state);
ta->acc().all_sets(), state);
}
}
if (state->compare(ta->get_artificial_initial_state()))
ta->create_transition(state, bdd_stutering_transition,
0U, state);
0U, state);
state->set_livelock_accepting_state(false);
state->set_accepting_state(false);

View file

@ -83,11 +83,11 @@ namespace spot
/// TGBA \a tgba_to_convert.
SPOT_API ta_explicit_ptr
tgba_to_ta(const const_twa_ptr& tgba_to_convert, bdd atomic_propositions_set,
bool degeneralized = true,
bool artificial_initial_state_mode = true,
bool single_pass_emptiness_check = false,
bool artificial_livelock_state_mode = false,
bool no_livelock = false);
bool degeneralized = true,
bool artificial_initial_state_mode = true,
bool single_pass_emptiness_check = false,
bool artificial_livelock_state_mode = false,
bool no_livelock = false);
/// \ingroup tgba_ta
/// \brief Build a spot::tgta_explicit* (TGTA) from an LTL formula.
@ -100,5 +100,5 @@ namespace spot
/// language as the TGBA \a tgba_to_convert.
SPOT_API tgta_explicit_ptr
tgba_to_tgta(const const_twa_ptr& tgba_to_convert,
bdd atomic_propositions_set);
bdd atomic_propositions_set);
}

View file

@ -31,9 +31,9 @@ namespace spot
atomic_prop_set res;
for (unsigned i = 0; i < n; ++i)
{
std::ostringstream p;
p << 'p' << i;
res.insert(formula::ap(p.str()));
std::ostringstream p;
p << 'p' << i;
res.insert(formula::ap(p.str()));
}
return res;
}
@ -44,11 +44,11 @@ namespace spot
if (!s)
s = new atomic_prop_set;
f.traverse([&](const formula& f)
{
if (f.is(op::ap))
s->insert(f);
return false;
});
{
if (f.is(op::ap))
s->insert(f);
return false;
});
return s;
}

View file

@ -65,7 +65,7 @@ namespace spot
// Check whether L(l) is a subset of L(g).
bool
language_containment_checker::contained(formula l,
formula g)
formula g)
{
if (l == g)
return true;
@ -77,7 +77,7 @@ namespace spot
// Check whether L(!l) is a subset of L(g).
bool
language_containment_checker::neg_contained(formula l,
formula g)
formula g)
{
if (l == g)
return false;
@ -92,7 +92,7 @@ namespace spot
// Check whether L(l) is a subset of L(!g).
bool
language_containment_checker::contained_neg(formula l,
formula g)
formula g)
{
if (l == g)
return false;
@ -122,7 +122,7 @@ namespace spot
return &i->second;
auto e = ltl_to_tgba_fm(f, dict_, exprop_, symb_merge_,
branching_postponement_, fair_loop_approx_);
branching_postponement_, fair_loop_approx_);
record_& r = translated_[f];
r.translation = e;
return &r;

View file

@ -43,9 +43,9 @@ namespace spot
/// This class uses spot::ltl_to_tgba_fm to translate LTL
/// formulae. See that function for the meaning of these options.
language_containment_checker(const bdd_dict_ptr& dict, bool exprop,
bool symb_merge,
bool branching_postponement,
bool fair_loop_approx);
bool symb_merge,
bool branching_postponement,
bool fair_loop_approx);
~language_containment_checker();

View file

@ -37,94 +37,94 @@ namespace spot
std::ostringstream* sinks_;
dot_printer(std::ostream& os, formula f)
: os_(os), sinks_(new std::ostringstream)
{
os_ << "digraph G {\n";
rec(f);
os_ << " subgraph atoms {\n rank=sink;\n"
<< sinks_->str() << " }\n}\n";
}
: os_(os), sinks_(new std::ostringstream)
{
os_ << "digraph G {\n";
rec(f);
os_ << " subgraph atoms {\n rank=sink;\n"
<< sinks_->str() << " }\n}\n";
}
~dot_printer()
{
delete sinks_;
}
{
delete sinks_;
}
int rec(formula f)
{
auto i = node_.emplace(f, node_.size());
int src = i.first->second;
if (!i.second)
return src;
auto i = node_.emplace(f, node_.size());
int src = i.first->second;
if (!i.second)
return src;
op o = f.kind();
std::string str = (o == op::ap) ? f.ap_name() : f.kindstr();
op o = f.kind();
std::string str = (o == op::ap) ? f.ap_name() : f.kindstr();
if (o == op::ap || f.is_constant())
*sinks_ << " " << src << " [label=\""
<< str << "\", shape=box];\n";
else
os_ << " " << src << " [label=\"" << str << "\"];\n";
if (o == op::ap || f.is_constant())
*sinks_ << " " << src << " [label=\""
<< str << "\", shape=box];\n";
else
os_ << " " << src << " [label=\"" << str << "\"];\n";
int childnum = 0;
switch (o)
{
case op::ff:
case op::tt:
case op::eword:
case op::ap:
case op::Not:
case op::X:
case op::F:
case op::G:
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Star:
case op::FStar:
childnum = 0; // No number for children
break;
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
childnum = -2; // L and R markers
break;
case op::Concat:
case op::Fusion:
childnum = 1; // Numbered children
break;
}
int childnum = 0;
switch (o)
{
case op::ff:
case op::tt:
case op::eword:
case op::ap:
case op::Not:
case op::X:
case op::F:
case op::G:
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Star:
case op::FStar:
childnum = 0; // No number for children
break;
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
childnum = -2; // L and R markers
break;
case op::Concat:
case op::Fusion:
childnum = 1; // Numbered children
break;
}
for (auto c: f)
{
// Do not merge the next two lines, as there is no
// guarantee that rec will be called before we start
// printing the transition.
int dst = rec(c);
os_ << " " << src << " -> " << dst;
if (childnum > 0)
os_ << " [taillabel=\"" << childnum << "\"]";
if (childnum == -2)
os_ << " [taillabel=\"L\"]";
else if (childnum == -1)
os_ << " [taillabel=\"R\"]";
os_ << ";\n";
++childnum;
}
for (auto c: f)
{
// Do not merge the next two lines, as there is no
// guarantee that rec will be called before we start
// printing the transition.
int dst = rec(c);
os_ << " " << src << " -> " << dst;
if (childnum > 0)
os_ << " [taillabel=\"" << childnum << "\"]";
if (childnum == -2)
os_ << " [taillabel=\"L\"]";
else if (childnum == -1)
os_ << " [taillabel=\"R\"]";
os_ << ";\n";
++childnum;
}
return src;
return src;
}
};
}

View file

@ -33,66 +33,66 @@ namespace spot
std::vector<formula> group;
auto start = arg;
while (*start)
{
while (*start == ' ' || *start == '\t')
++start;
if (!*start)
break;
if (*start == ',')
{
std::string s = "unexpected ',' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*start == '"')
{
++start;
auto end = start;
while (*end && *end != '"')
{
if (*end == '\\')
++end;
++end;
}
if (!*end)
{
std::string s = "missing closing '\"' in ";
s += arg;
throw std::invalid_argument(s);
}
std::string ap(start, end - start);
group.emplace_back(formula::ap(ap));
do
++end;
while (*end == ' ' || *end == '\t');
if (*end && *end != ',')
{
std::string s = "unexpected character '";
s += *end;
s += "' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*end == ',')
++end;
start = end;
}
else
{
auto end = start;
while (*end && *end != ',')
++end;
auto rend = end;
while (rend > start && (rend[-1] == ' ' || rend[-1] == '\t'))
--rend;
std::string ap(start, rend - start);
group.emplace_back(formula::ap(ap));
if (*end == ',')
start = end + 1;
else
break;
}
}
{
while (*start == ' ' || *start == '\t')
++start;
if (!*start)
break;
if (*start == ',')
{
std::string s = "unexpected ',' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*start == '"')
{
++start;
auto end = start;
while (*end && *end != '"')
{
if (*end == '\\')
++end;
++end;
}
if (!*end)
{
std::string s = "missing closing '\"' in ";
s += arg;
throw std::invalid_argument(s);
}
std::string ap(start, end - start);
group.emplace_back(formula::ap(ap));
do
++end;
while (*end == ' ' || *end == '\t');
if (*end && *end != ',')
{
std::string s = "unexpected character '";
s += *end;
s += "' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*end == ',')
++end;
start = end;
}
else
{
auto end = start;
while (*end && *end != ',')
++end;
auto rend = end;
while (rend > start && (rend[-1] == ' ' || rend[-1] == '\t'))
--rend;
std::string ap(start, rend - start);
group.emplace_back(formula::ap(ap));
if (*end == ',')
start = end + 1;
else
break;
}
}
return group;
}
}
@ -126,16 +126,16 @@ namespace spot
for (auto& g: groups)
{
group.clear();
group.clear();
for (auto ap: g)
if (s->find(ap) != s->end())
group.push_back(ap);
for (auto ap: g)
if (s->find(ap) != s->end())
group.push_back(ap);
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
v.push_back(nand(group[j], group[k]));
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
v.push_back(nand(group[j], group[k]));
};
delete s;
@ -143,15 +143,15 @@ namespace spot
}
twa_graph_ptr exclusive_ap::constrain(const_twa_graph_ptr aut,
bool simplify_guards) const
bool simplify_guards) const
{
// Compute the support of the automaton.
bdd support = bddtrue;
{
std::set<int> bdd_seen;
for (auto& t: aut->edges())
if (bdd_seen.insert(t.cond.id()).second)
support &= bdd_support(t.cond);
if (bdd_seen.insert(t.cond.id()).second)
support &= bdd_support(t.cond);
}
bdd restrict = bddtrue;
@ -160,19 +160,19 @@ namespace spot
std::vector<bdd> group;
for (auto& g: groups)
{
group.clear();
group.clear();
for (auto ap: g)
{
int v = d->has_registered_proposition(ap, aut);
if (v >= 0)
group.push_back(bdd_nithvar(v));
}
for (auto ap: g)
{
int v = d->has_registered_proposition(ap, aut);
if (v >= 0)
group.push_back(bdd_nithvar(v));
}
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
restrict &= group[j] | group[k];
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
restrict &= group[j] | group[k];
}
twa_graph_ptr res = make_twa_graph(aut->get_dict());
@ -181,26 +181,26 @@ namespace spot
res->copy_acceptance_of(aut);
if (simplify_guards)
{
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
minato_isop isop(cond & restrict,
cond | !restrict,
true);
bdd res = bddfalse;
bdd cube = bddfalse;
while ((cube = isop.next()) != bddfalse)
res |= cube;
cond = res;
});
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
minato_isop isop(cond & restrict,
cond | !restrict,
true);
bdd res = bddfalse;
bdd cube = bddfalse;
while ((cube = isop.next()) != bddfalse)
res |= cube;
cond = res;
});
}
else
{
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
cond &= restrict;
});
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
cond &= restrict;
});
}
return res;
}

View file

@ -41,6 +41,6 @@ namespace spot
formula constrain(formula f) const;
twa_graph_ptr constrain(const_twa_graph_ptr aut,
bool simplify_guards = false) const;
bool simplify_guards = false) const;
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -30,14 +30,14 @@ namespace spot
{
int len = 0;
f.traverse([&len](const formula& x)
{
auto s = x.size();
if (s > 1)
len += s - 1;
else
++len;
return false;
});
{
auto s = x.size();
if (s > 1)
len += s - 1;
else
++len;
return false;
});
return len;
}
@ -46,31 +46,31 @@ namespace spot
{
int len = 0;
f.traverse([&len](const formula& x)
{
if (x.is_boolean())
{
++len;
return true;
}
auto s = x.size();
if (s > 2)
{
int b = 0;
for (const auto& y: x)
if (y.is_boolean())
++b;
len += s - b * 2 + 1;
}
else if (s > 1)
{
len += s - 1;
}
else
{
++len;
}
return false;
});
{
if (x.is_boolean())
{
++len;
return true;
}
auto s = x.size();
if (s > 2)
{
int b = 0;
for (const auto& y: x)
if (y.is_boolean())
++b;
len += s - b * 2 + 1;
}
else if (s > 1)
{
len += s - 1;
}
else
{
++len;
}
return false;
});
return len;
}

View file

@ -58,25 +58,25 @@ namespace spot
case op::UConcat:
case op::Concat:
case op::Fusion:
res = f;
break;
res = f;
break;
case op::NegClosure:
res = formula::NegClosureMarked(f[0]);
break;
res = formula::NegClosureMarked(f[0]);
break;
case op::EConcat:
res = formula::EConcatMarked(f[0], f[1]);
break;
res = formula::EConcatMarked(f[0], f[1]);
break;
case op::Or:
case op::And:
res = f.map([this](formula f)
{
return this->mark_concat_ops(f);
});
break;
res = f.map([this](formula f)
{
return this->mark_concat_ops(f);
});
break;
case op::Xor:
case op::Implies:
case op::Equiv:
SPOT_UNIMPLEMENTED();
SPOT_UNIMPLEMENTED();
}
markops_[f] = res;
@ -95,7 +95,7 @@ namespace spot
auto recurse = [this](formula f)
{
return this->simplify_mark(f);
return this->simplify_mark(f);
};
formula res;
@ -119,58 +119,58 @@ namespace spot
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
res = f;
break;
res = f;
break;
case op::Or:
res = f.map(recurse);
break;
res = f.map(recurse);
break;
case op::And:
{
std::set<std::pair<formula, formula>> empairs;
std::set<formula> nmset;
std::vector<formula> elist;
std::vector<formula> nlist;
std::vector<formula> v;
{
std::set<std::pair<formula, formula>> empairs;
std::set<formula> nmset;
std::vector<formula> elist;
std::vector<formula> nlist;
std::vector<formula> v;
for (auto c: f)
{
if (c.is(op::EConcatMarked))
{
empairs.emplace(c[0], c[1]);
v.push_back(c.map(recurse));
}
else if (c.is(op::EConcat))
{
elist.push_back(c);
}
else if (c.is(op::NegClosureMarked))
{
nmset.insert(c[0]);
v.push_back(c.map(recurse));
}
else if (c.is(op::NegClosure))
{
nlist.push_back(c);
}
else
{
v.push_back(c);
}
}
// Keep only the non-marked EConcat for which we
// have not seen a similar EConcatMarked.
for (auto e: elist)
if (empairs.find(std::make_pair(e[0], e[1]))
== empairs.end())
v.push_back(e);
// Keep only the non-marked NegClosure for which we
// have not seen a similar NegClosureMarked.
for (auto n: nlist)
if (nmset.find(n[0]) == nmset.end())
v.push_back(n);
res = formula::And(v);
}
break;
for (auto c: f)
{
if (c.is(op::EConcatMarked))
{
empairs.emplace(c[0], c[1]);
v.push_back(c.map(recurse));
}
else if (c.is(op::EConcat))
{
elist.push_back(c);
}
else if (c.is(op::NegClosureMarked))
{
nmset.insert(c[0]);
v.push_back(c.map(recurse));
}
else if (c.is(op::NegClosure))
{
nlist.push_back(c);
}
else
{
v.push_back(c);
}
}
// Keep only the non-marked EConcat for which we
// have not seen a similar EConcatMarked.
for (auto e: elist)
if (empairs.find(std::make_pair(e[0], e[1]))
== empairs.end())
v.push_back(e);
// Keep only the non-marked NegClosure for which we
// have not seen a similar NegClosureMarked.
for (auto n: nlist)
if (nmset.find(n[0]) == nmset.end())
v.push_back(n);
res = formula::And(v);
}
break;
case op::Xor:
case op::Implies:
case op::Equiv:
@ -181,7 +181,7 @@ namespace spot
case op::FStar:
case op::Concat:
case op::Fusion:
SPOT_UNIMPLEMENTED();
SPOT_UNIMPLEMENTED();
}
simpmark_[f] = res;

View file

@ -37,12 +37,12 @@ namespace spot
formula substitute_ap(formula f, formula ap_src, formula ap_dst)
{
return f.map([&](formula f)
{
if (f == ap_src)
return ap_dst;
else
return substitute_ap(f, ap_src, ap_dst);
});
{
if (f == ap_src)
return ap_dst;
else
return substitute_ap(f, ap_src, ap_dst);
});
}
typedef std::vector<formula> vec;
@ -58,229 +58,229 @@ namespace spot
formula mutate(formula f)
{
auto recurse = [this](formula f)
{
return this->mutate(f);
};
auto recurse = [this](formula f)
{
return this->mutate(f);
};
switch (f.kind())
{
case op::ff:
case op::tt:
case op::eword:
return f;
case op::ap:
if (opts_ & Mut_Ap2Const)
{
if (mutation_counter_-- == 0)
return formula::tt();
if (mutation_counter_-- == 0)
return formula::ff();
}
return f;
case op::Not:
case op::X:
case op::F:
case op::G:
if ((opts_ & Mut_Remove_Ops)
&& mutation_counter_-- == 0)
return f[0];
// fall through
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Concat:
case op::Fusion:
{
int mos = f.size();
if (opts_ & Mut_Remove_Multop_Operands)
{
for (int i = 0; i < mos; ++i)
if (mutation_counter_-- == 0)
return f.all_but(i);
}
switch (f.kind())
{
case op::ff:
case op::tt:
case op::eword:
return f;
case op::ap:
if (opts_ & Mut_Ap2Const)
{
if (mutation_counter_-- == 0)
return formula::tt();
if (mutation_counter_-- == 0)
return formula::ff();
}
return f;
case op::Not:
case op::X:
case op::F:
case op::G:
if ((opts_ & Mut_Remove_Ops)
&& mutation_counter_-- == 0)
return f[0];
// fall through
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Concat:
case op::Fusion:
{
int mos = f.size();
if (opts_ & Mut_Remove_Multop_Operands)
{
for (int i = 0; i < mos; ++i)
if (mutation_counter_-- == 0)
return f.all_but(i);
}
if (opts_ & Mut_Split_Ops && f.is(op::AndNLM))
{
if (mutation_counter_ >= 0
&& mutation_counter_ < 2 * (mos - 1))
{
vec v1;
vec v2;
v1.push_back(f[0]);
bool reverse = false;
int i = 1;
while (i < mos)
{
if (mutation_counter_-- == 0)
break;
if (mutation_counter_-- == 0)
{
reverse = true;
break;
}
v1.push_back(f[i++]);
}
for (; i < mos; ++i)
v2.push_back(f[i]);
formula first = AndNLM_(v1);
formula second = AndNLM_(v2);
formula ost = formula::one_star();
if (!reverse)
return AndRat_(Concat_(first, ost), second);
else
return AndRat_(Concat_(second, ost), first);
}
else
{
mutation_counter_ -= 2 * (mos - 1);
}
}
if (opts_ & Mut_Split_Ops && f.is(op::AndNLM))
{
if (mutation_counter_ >= 0
&& mutation_counter_ < 2 * (mos - 1))
{
vec v1;
vec v2;
v1.push_back(f[0]);
bool reverse = false;
int i = 1;
while (i < mos)
{
if (mutation_counter_-- == 0)
break;
if (mutation_counter_-- == 0)
{
reverse = true;
break;
}
v1.push_back(f[i++]);
}
for (; i < mos; ++i)
v2.push_back(f[i]);
formula first = AndNLM_(v1);
formula second = AndNLM_(v2);
formula ost = formula::one_star();
if (!reverse)
return AndRat_(Concat_(first, ost), second);
else
return AndRat_(Concat_(second, ost), first);
}
else
{
mutation_counter_ -= 2 * (mos - 1);
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
{
formula first = f[0];
formula second = f[1];
op o = f.kind();
bool left_is_sere = o == op::EConcat
|| o == op::EConcatMarked
|| o == op::UConcat;
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
{
formula first = f[0];
formula second = f[1];
op o = f.kind();
bool left_is_sere = o == op::EConcat
|| o == op::EConcatMarked
|| o == op::UConcat;
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
{
if (!left_is_sere)
return first;
else if (o == op::UConcat)
return formula::NegClosure(first);
else // EConcat or EConcatMarked
return formula::Closure(first);
}
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return second;
if (opts_ & Mut_Rewrite_Ops)
{
switch (o)
{
case op::U:
if (mutation_counter_-- == 0)
return formula::W(first, second);
break;
case op::M:
if (mutation_counter_-- == 0)
return formula::R(first, second);
if (mutation_counter_-- == 0)
return formula::U(second, first);
break;
case op::R:
if (mutation_counter_-- == 0)
return formula::W(second, first);
break;
default:
break;
}
}
if (opts_ & Mut_Split_Ops)
{
switch (o)
{
case op::Equiv:
if (mutation_counter_-- == 0)
return formula::Implies(first, second);
if (mutation_counter_-- == 0)
return formula::Implies(second, first);
if (mutation_counter_-- == 0)
return formula::And({first, second});
if (mutation_counter_-- == 0)
{
// Negate the two argument sequentially (in this
// case right before left, otherwise different
// compilers will make different choices.
auto right = formula::Not(second);
return formula::And({formula::Not(first), right});
}
break;
case op::Xor:
if (mutation_counter_-- == 0)
return formula::And({first, formula::Not(second)});
if (mutation_counter_-- == 0)
return formula::And({formula::Not(first), second});
break;
default:
break;
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Star:
case op::FStar:
{
formula c = f[0];
op o = f.kind();
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return c;
if (opts_ & Mut_Simplify_Bounds)
{
auto min = f.min();
auto max = f.max();
if (min > 0)
{
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min - 1, max);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, 0, max);
}
if (max != formula::unbounded())
{
if (max > min && mutation_counter_-- == 0)
return formula::bunop(o, c, min, max - 1);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min,
formula::unbounded());
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
}
SPOT_UNREACHABLE();
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
{
if (!left_is_sere)
return first;
else if (o == op::UConcat)
return formula::NegClosure(first);
else // EConcat or EConcatMarked
return formula::Closure(first);
}
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return second;
if (opts_ & Mut_Rewrite_Ops)
{
switch (o)
{
case op::U:
if (mutation_counter_-- == 0)
return formula::W(first, second);
break;
case op::M:
if (mutation_counter_-- == 0)
return formula::R(first, second);
if (mutation_counter_-- == 0)
return formula::U(second, first);
break;
case op::R:
if (mutation_counter_-- == 0)
return formula::W(second, first);
break;
default:
break;
}
}
if (opts_ & Mut_Split_Ops)
{
switch (o)
{
case op::Equiv:
if (mutation_counter_-- == 0)
return formula::Implies(first, second);
if (mutation_counter_-- == 0)
return formula::Implies(second, first);
if (mutation_counter_-- == 0)
return formula::And({first, second});
if (mutation_counter_-- == 0)
{
// Negate the two argument sequentially (in this
// case right before left, otherwise different
// compilers will make different choices.
auto right = formula::Not(second);
return formula::And({formula::Not(first), right});
}
break;
case op::Xor:
if (mutation_counter_-- == 0)
return formula::And({first, formula::Not(second)});
if (mutation_counter_-- == 0)
return formula::And({formula::Not(first), second});
break;
default:
break;
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Star:
case op::FStar:
{
formula c = f[0];
op o = f.kind();
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return c;
if (opts_ & Mut_Simplify_Bounds)
{
auto min = f.min();
auto max = f.max();
if (min > 0)
{
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min - 1, max);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, 0, max);
}
if (max != formula::unbounded())
{
if (max > min && mutation_counter_-- == 0)
return formula::bunop(o, c, min, max - 1);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min,
formula::unbounded());
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
}
SPOT_UNREACHABLE();
}
formula
get_mutation(int n)
{
mutation_counter_ = n;
formula mut = mutate(f_);
if (mut == f_)
return nullptr;
return mut;
mutation_counter_ = n;
formula mut = mutate(f_);
if (mut == f_)
return nullptr;
return mut;
}
};
@ -291,13 +291,13 @@ namespace spot
assert(left != nullptr);
assert(right != nullptr);
if (left == right)
return false;
return false;
auto ll = length(left);
auto lr = length(right);
if (ll < lr)
return true;
return true;
if (ll > lr)
return false;
return false;
return left < right;
}
@ -305,55 +305,55 @@ namespace spot
void
single_mutation_rec(formula f, fset_t& mutations, unsigned opts,
unsigned& n, unsigned m)
unsigned& n, unsigned m)
{
if (m == 0)
{
if (mutations.insert(f).second)
--n;
}
{
if (mutations.insert(f).second)
--n;
}
else
{
formula mut;
int i = 0;
mutator mv(f, opts);
while (n > 0 && ((mut = mv.get_mutation(i++)) != nullptr))
single_mutation_rec(mut, mutations, opts, n, m - 1);
}
{
formula mut;
int i = 0;
mutator mv(f, opts);
while (n > 0 && ((mut = mv.get_mutation(i++)) != nullptr))
single_mutation_rec(mut, mutations, opts, n, m - 1);
}
}
void
replace_ap_rec(formula f, fset_t& mutations, unsigned opts,
unsigned& n, unsigned m)
unsigned& n, unsigned m)
{
if (m == 0)
{
if (mutations.insert(f).second)
--n;
}
{
if (mutations.insert(f).second)
--n;
}
else
{
if (!n)
return;
auto aps =
std::unique_ptr<atomic_prop_set>(atomic_prop_collect(f));
for (auto ap1: *aps)
for (auto ap2: *aps)
{
if (ap1 == ap2)
continue;
auto mut = substitute_ap(f, ap1, ap2);
replace_ap_rec(mut, mutations, opts, n, m - 1);
if (!n)
return;
}
}
{
if (!n)
return;
auto aps =
std::unique_ptr<atomic_prop_set>(atomic_prop_collect(f));
for (auto ap1: *aps)
for (auto ap2: *aps)
{
if (ap1 == ap2)
continue;
auto mut = substitute_ap(f, ap1, ap2);
replace_ap_rec(mut, mutations, opts, n, m - 1);
if (!n)
return;
}
}
}
}
std::vector<formula>
mutate(formula f, unsigned opts, unsigned max_output,
unsigned mutation_count, bool sort)
unsigned mutation_count, bool sort)
{
fset_t mutations;
single_mutation_rec(f, mutations, opts, max_output, mutation_count);

View file

@ -38,8 +38,8 @@ namespace spot
SPOT_API
std::vector<formula> mutate(formula f,
unsigned opts = Mut_All,
unsigned max_output = -1U,
unsigned mutation_count = 1,
bool sort = true);
unsigned opts = Mut_All,
unsigned max_output = -1U,
unsigned mutation_count = 1,
bool sort = true);
}

View file

@ -94,8 +94,8 @@ namespace spot
/// \param shift how many characters to add to the error locations
/// \return \c true iff any diagnostic was output.
bool format_errors(std::ostream& os,
const std::string& input,
unsigned shift);
const std::string& input,
unsigned shift);
};
@ -119,10 +119,10 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_infix_psl(const std::string& ltl_string,
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
/// \brief Build a Boolean formula from a string.
/// \param ltl_string The string to parse.
@ -142,10 +142,10 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_infix_boolean(const std::string& ltl_string,
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
/// \brief Build a formula from an LTL string in LBT's format.
/// \param ltl_string The string to parse.
@ -167,9 +167,9 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_prefix_ltl(const std::string& ltl_string,
environment& env =
default_environment::instance(),
bool debug = false);
environment& env =
default_environment::instance(),
bool debug = false);
/// \brief A simple wrapper to parse_infix_psl() and parse_prefix_ltl().
///
@ -179,7 +179,7 @@ namespace spot
/// parse_infix_psl() as a parse_error exception.
SPOT_API formula
parse_formula(const std::string& ltl_string,
environment& env = default_environment::instance());
environment& env = default_environment::instance());
/// \brief Build a formula from a string representing a SERE.
/// \param sere_string The string to parse.
@ -200,10 +200,10 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_infix_sere(const std::string& sere_string,
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
/// \brief Fix location of diagnostics assuming the input is utf8.
///
@ -230,7 +230,7 @@ namespace spot
SPOT_API
void
fix_utf8_locations(const std::string& input_string,
parse_error_list& error_list);
parse_error_list& error_list);
/// @}
}

File diff suppressed because it is too large Load diff

View file

@ -34,14 +34,14 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_psl(std::ostream& os, formula f, bool full_parent = false);
/// \brief Convert a PSL formula into a string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_psl(formula f, bool full_parent = false);
@ -49,15 +49,15 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_utf8_psl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Convert a PSL formula into a utf-8 string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_utf8_psl(formula f, bool full_parent = false);
@ -65,14 +65,14 @@ namespace spot
/// \param f The formula to translate.
/// \param os The stream where it should be output.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_sere(std::ostream& os, formula f, bool full_parent = false);
/// \brief Convert a SERE formula into a string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_sere(formula f, bool full_parent = false);
@ -80,15 +80,15 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_utf8_sere(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Convert a SERE formula into a string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_utf8_sere(formula f, bool full_parent = false);
@ -96,15 +96,15 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_spin_ltl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Convert an LTL formula into a string parsable by Spin.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_spin_ltl(formula f, bool full_parent = false);
@ -123,16 +123,16 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_latex_psl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a formula as a LaTeX string which is parsable.
/// unless the formula contains automaton operators (used in ELTL formulae).
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_latex_psl(formula f, bool full_parent = false);
@ -140,16 +140,16 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_latex_sere(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a SERE formula as a LaTeX string which is parsable.
/// unless the formula contains automaton operators (used in ELTL formulae).
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_latex_sere(formula f, bool full_parent = false);
@ -159,17 +159,17 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_sclatex_psl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a PSL formula as a self-contained LaTeX string.
///
/// The result cannot be parsed bacl.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_sclatex_psl(formula f, bool full_parent = false);
@ -179,17 +179,17 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_sclatex_sere(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a SERE formula as a self-contained LaTeX string.
///
/// The result cannot be parsed bacl.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_sclatex_sere(formula f, bool full_parent = false);

View file

@ -183,24 +183,24 @@ namespace spot
total_2_and_more_ = 0.0;
for (unsigned i = 0; i < proba_size_; ++i)
{
if (proba_[i].min_n == 1)
{
total_1_ += proba_[i].proba;
if (proba_ + i >= proba_2_)
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n == 2)
{
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n > 2)
total_2_and_more_ += proba_[i].proba;
else
SPOT_UNREACHABLE(); // unexpected max_n
if (proba_[i].min_n == 1)
{
total_1_ += proba_[i].proba;
if (proba_ + i >= proba_2_)
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n == 2)
{
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n > 2)
total_2_and_more_ += proba_[i].proba;
else
SPOT_UNREACHABLE(); // unexpected max_n
}
assert(total_2_and_more_ >= total_2_);
}
@ -216,48 +216,48 @@ namespace spot
// Approximate impossible cases.
if (n == 1 && total_1_ == 0.0)
{
if (total_2_ != 0.0)
n = 2;
else
n = 3;
if (total_2_ != 0.0)
n = 2;
else
n = 3;
}
else if (n == 2 && total_2_ == 0.0)
{
if (total_1_ != 0.0)
n = 1;
else
n = 3;
if (total_1_ != 0.0)
n = 1;
else
n = 3;
}
else if (n > 2 && total_2_and_more_ == 0.0)
{
if (total_1_ != 0.0)
n = 1;
else
assert(total_2_ == 0.0);
if (total_1_ != 0.0)
n = 1;
else
assert(total_2_ == 0.0);
}
if (n == 1)
{
r *= total_1_;
p = proba_;
r *= total_1_;
p = proba_;
}
else if (n == 2)
{
r *= total_2_;
p = proba_2_;
r *= total_2_;
p = proba_2_;
}
else
{
r *= total_2_and_more_;
p = proba_2_or_more_;
r *= total_2_and_more_;
p = proba_2_or_more_;
}
double s = p->proba;
while (s < r)
{
++p;
s += p->proba;
++p;
s += p->proba;
}
return p->build(this, n);
@ -271,30 +271,30 @@ namespace spot
char* key = strtok(options, "=\t, :;");
while (key)
{
char* value = strtok(nullptr, "=\t, :;");
if (!value)
return key;
char* value = strtok(nullptr, "=\t, :;");
if (!value)
return key;
char* endptr;
double res = strtod(value, &endptr);
if (*endptr)
return value;
char* endptr;
double res = strtod(value, &endptr);
if (*endptr)
return value;
unsigned i;
for (i = 0; i < proba_size_; ++i)
{
if (('a' <= *proba_[i].name && *proba_[i].name <= 'z'
&& !strcasecmp(proba_[i].name, key))
|| !strcmp(proba_[i].name, key))
{
proba_[i].proba = res;
break;
}
}
if (i == proba_size_)
return key;
unsigned i;
for (i = 0; i < proba_size_; ++i)
{
if (('a' <= *proba_[i].name && *proba_[i].name <= 'z'
&& !strcasecmp(proba_[i].name, key))
|| !strcmp(proba_[i].name, key))
{
proba_[i].proba = res;
break;
}
}
if (i == proba_size_)
return key;
key = strtok(nullptr, "=\t, :;");
key = strtok(nullptr, "=\t, :;");
}
update_sums();
return nullptr;
@ -393,7 +393,7 @@ namespace spot
{
// FIXME: This looks very fragile.
memmove(proba_ + 8, proba_ + 7,
((proba_ + 16) - (proba_ + 7)) * sizeof(*proba_));
((proba_ + 16) - (proba_ + 7)) * sizeof(*proba_));
proba_[7].setup("Closure", 2, closure_builder);
proba_[17].setup("EConcat", 3, binop_SERELTL_builder<op::EConcat>);
@ -402,10 +402,10 @@ namespace spot
}
randltlgenerator::randltlgenerator(atomic_prop_set aprops,
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
{
aprops_ = aprops;
output_ = opts.get("output", OUTPUTLTL);
@ -423,51 +423,51 @@ namespace spot
switch (output_)
{
case OUTPUTLTL:
rf_ = new random_ltl(&aprops_);
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities with "
"LTL output");
if (opt_pB)
throw std::invalid_argument("Cannot set boolean priorities with "
"LTL output");
tok_pL = rf_->parse_options(opt_pL);
break;
rf_ = new random_ltl(&aprops_);
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities with "
"LTL output");
if (opt_pB)
throw std::invalid_argument("Cannot set boolean priorities with "
"LTL output");
tok_pL = rf_->parse_options(opt_pL);
break;
case OUTPUTBOOL:
rf_ = new random_boolean(&aprops_);
tok_pB = rf_->parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities with "
"Boolean output");
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities "
"with Boolean output");
break;
rf_ = new random_boolean(&aprops_);
tok_pB = rf_->parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities with "
"Boolean output");
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities "
"with Boolean output");
break;
case OUTPUTSERE:
rf_ = rs_ = new random_sere(&aprops_);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities "
"with SERE output");
break;
rf_ = rs_ = new random_sere(&aprops_);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities "
"with SERE output");
break;
case OUTPUTPSL:
rf_ = rp_ = new random_psl(&aprops_);
rs_ = &rp_->rs;
tok_pL = rp_->parse_options(opt_pL);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
break;
rf_ = rp_ = new random_psl(&aprops_);
rs_ = &rp_->rs;
tok_pL = rp_->parse_options(opt_pL);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
break;
}
if (tok_pL)
throw std::invalid_argument("failed to parse LTL priorities near "
+ std::string(tok_pL));
+ std::string(tok_pL));
if (tok_pS)
throw std::invalid_argument("failed to parse SERE priorities near "
+ std::string(tok_pS));
+ std::string(tok_pS));
if (tok_pB)
throw std::invalid_argument("failed to parse Boolean priorities near "
+ std::string(tok_pB));
+ std::string(tok_pB));
spot::srand(opt_seed_);
tl_simplifier_options simpl_opts(opt_simpl_level_);
@ -475,12 +475,12 @@ namespace spot
}
randltlgenerator::randltlgenerator(int aprops_n,
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
: randltlgenerator(create_atomic_prop_set(aprops_n), opts,
opt_pL, opt_pS, opt_pB)
opt_pL, opt_pS, opt_pB)
{
}
@ -496,24 +496,24 @@ namespace spot
formula f = nullptr;
do
{
ignore = false;
int size = opt_tree_size_min_;
if (size != opt_tree_size_max_)
size = spot::rrand(size, opt_tree_size_max_);
f = rf_->generate(size);
ignore = false;
int size = opt_tree_size_min_;
if (size != opt_tree_size_max_)
size = spot::rrand(size, opt_tree_size_max_);
f = rf_->generate(size);
if (opt_wf_)
{
atomic_prop_set s = aprops_;
remove_some_props(s);
f = formula::And({f, GF_n()});
}
if (opt_wf_)
{
atomic_prop_set s = aprops_;
remove_some_props(s);
f = formula::And({f, GF_n()});
}
if (opt_simpl_level_)
f = simpl_.simplify(f);
if (opt_simpl_level_)
f = simpl_.simplify(f);
if (opt_unique_ && !unique_set_.insert(f).second)
ignore = true;
if (opt_unique_ && !unique_set_.insert(f).second)
ignore = true;
} while (ignore && --trials);
if (trials <= 0)
return nullptr;
@ -529,9 +529,9 @@ namespace spot
while (n--)
{
auto i = s.begin();
std::advance(i, spot::mrand(s.size()));
s.erase(i);
auto i = s.begin();
std::advance(i, spot::mrand(s.size()));
s.erase(i);
}
}
@ -542,11 +542,11 @@ namespace spot
formula res = nullptr;
for (auto v: aprops_)
{
formula f = formula::G(formula::F(v));
if (res)
res = formula::And({f, res});
else
res = f;
formula f = formula::G(formula::F(v));
if (res)
res = formula::And({f, res});
else
res = f;
}
return res;
}

View file

@ -44,7 +44,7 @@ namespace spot
{
public:
random_formula(unsigned proba_size,
const atomic_prop_set* ap):
const atomic_prop_set* ap):
proba_size_(proba_size), proba_(new op_proba[proba_size_]), ap_(ap)
{
}
@ -125,23 +125,23 @@ namespace spot
/// The default priorities are defined as follows:
///
/** \verbatim
ap n
false 1
true 1
not 1
F 1
G 1
X 1
equiv 1
implies 1
xor 1
R 1
U 1
W 1
M 1
and 1
or 1
\endverbatim */
ap n
false 1
true 1
not 1
F 1
G 1
X 1
equiv 1
implies 1
xor 1
R 1
U 1
W 1
M 1
and 1
or 1
\endverbatim */
///
/// Where \c n is the number of atomic propositions in the
/// set passed to the constructor.
@ -176,16 +176,16 @@ namespace spot
/// The default priorities are defined as follows:
///
/** \verbatim
ap n
false 1
true 1
not 1
equiv 1
implies 1
xor 1
and 1
or 1
\endverbatim */
ap n
false 1
true 1
not 1
equiv 1
implies 1
xor 1
and 1
or 1
\endverbatim */
///
/// Where \c n is the number of atomic propositions in the
/// set passed to the constructor.
@ -215,18 +215,18 @@ namespace spot
/// The default priorities are defined as follows:
///
/** \verbatim
eword 1
boolform 1
star 1
star_b 1
equal_b 1
goto_b 1
and 1
andNLM 1
or 1
concat 1
fusion 1
\endverbatim */
eword 1
boolform 1
star 1
star_b 1
equal_b 1
goto_b 1
and 1
andNLM 1
or 1
concat 1
fusion 1
\endverbatim */
///
/// Where "boolfrom" designates a Boolean formula generated
/// by random_boolean.
@ -260,26 +260,26 @@ namespace spot
/// The default priorities are defined as follows:
///
/** \verbatim
ap n
false 1
true 1
not 1
F 1
G 1
X 1
Closure 1
equiv 1
implies 1
xor 1
R 1
U 1
W 1
M 1
and 1
or 1
EConcat 1
UConcat 1
\endverbatim */
ap n
false 1
true 1
not 1
F 1
G 1
X 1
Closure 1
equiv 1
implies 1
xor 1
R 1
U 1
W 1
M 1
and 1
or 1
EConcat 1
UConcat 1
\endverbatim */
///
/// Where \c n is the number of atomic propositions in the
/// set passed to the constructor.
@ -306,14 +306,14 @@ namespace spot
public:
randltlgenerator(int aprops_n, const option_map& opts,
char* opt_pL = nullptr,
char* opt_pS = nullptr,
char* opt_pB = nullptr);
char* opt_pL = nullptr,
char* opt_pS = nullptr,
char* opt_pB = nullptr);
randltlgenerator(atomic_prop_set aprops, const option_map& opts,
char* opt_pL = nullptr,
char* opt_pS = nullptr,
char* opt_pB = nullptr);
char* opt_pL = nullptr,
char* opt_pS = nullptr,
char* opt_pB = nullptr);
~randltlgenerator();

View file

@ -43,15 +43,15 @@ namespace spot
{
unsigned nn;
pnn_generator()
: nn(0)
{
}
: nn(0)
{
}
virtual formula next() override
{
std::ostringstream s;
s << 'p' << nn++;
return formula::ap(s.str());
std::ostringstream s;
s << 'p' << nn++;
return formula::ap(s.str());
}
};
@ -59,23 +59,23 @@ namespace spot
{
public:
abc_generator()
: nn(0)
{
}
: nn(0)
{
}
unsigned nn;
virtual formula next() override
{
std::string s;
unsigned n = nn++;
do
{
s.push_back('a' + (n % 26));
n /= 26;
}
while (n);
return formula::ap(s);
std::string s;
unsigned n = nn++;
do
{
s.push_back('a' + (n % 26));
n /= 26;
}
while (n);
return formula::ap(s);
}
};
@ -89,42 +89,42 @@ namespace spot
relabeling_map* oldnames;
relabeler(ap_generator* gen, relabeling_map* m)
: gen(gen), oldnames(m)
: gen(gen), oldnames(m)
{
}
~relabeler()
{
delete gen;
delete gen;
}
formula rename(formula old)
{
auto r = newname.emplace(old, nullptr);
if (!r.second)
{
return r.first->second;
}
else
{
formula res = gen->next();
r.first->second = res;
if (oldnames)
(*oldnames)[res] = old;
return res;
}
auto r = newname.emplace(old, nullptr);
if (!r.second)
{
return r.first->second;
}
else
{
formula res = gen->next();
r.first->second = res;
if (oldnames)
(*oldnames)[res] = old;
return res;
}
}
formula
visit(formula f)
{
if (f.is(op::ap))
return rename(f);
else
return f.map([this](formula f)
{
return this->visit(f);
});
if (f.is(op::ap))
return rename(f);
else
return f.map([this](formula f)
{
return this->visit(f);
});
}
};
@ -139,11 +139,11 @@ namespace spot
switch (style)
{
case Pnn:
gen = new pnn_generator;
break;
gen = new pnn_generator;
break;
case Abc:
gen = new abc_generator;
break;
gen = new abc_generator;
break;
}
relabeler r(gen, m);
@ -236,67 +236,67 @@ namespace spot
std::stack<formula> s;
formula_to_fgraph(fgraph& g):
g(g)
{
}
g(g)
{
}
~formula_to_fgraph()
{
}
{
}
void
visit(formula f)
visit(formula f)
{
{
// Connect to parent
auto in = g.emplace(f, succ_vec());
if (!s.empty())
{
formula top = s.top();
in.first->second.push_back(top);
g[top].push_back(f);
if (!in.second)
return;
}
else
{
assert(in.second);
}
}
s.push(f);
{
// Connect to parent
auto in = g.emplace(f, succ_vec());
if (!s.empty())
{
formula top = s.top();
in.first->second.push_back(top);
g[top].push_back(f);
if (!in.second)
return;
}
else
{
assert(in.second);
}
}
s.push(f);
unsigned sz = f.size();
unsigned i = 0;
if (sz > 2 && !f.is_boolean())
{
/// If we have a formula like (a & b & Xc), consider
/// it as ((a & b) & Xc) in the graph to isolate the
/// Boolean operands as a single node.
formula b = f.boolean_operands(&i);
if (b)
visit(b);
}
for (; i < sz; ++i)
visit(f[i]);
if (sz > 1 && f.is_boolean())
{
// For Boolean nodes, connect all children in a
// loop. This way the node can only be a cut-point
// if it separates all children from the reset of
// the graph (not only one).
formula pred = f[0];
for (i = 1; i < sz; ++i)
{
formula next = f[i];
// Note that we only add an edge in one
// direction, because we are building a cycle
// between all children anyway.
g[pred].push_back(next);
pred = next;
}
g[pred].push_back(f[0]);
}
s.pop();
unsigned sz = f.size();
unsigned i = 0;
if (sz > 2 && !f.is_boolean())
{
/// If we have a formula like (a & b & Xc), consider
/// it as ((a & b) & Xc) in the graph to isolate the
/// Boolean operands as a single node.
formula b = f.boolean_operands(&i);
if (b)
visit(b);
}
for (; i < sz; ++i)
visit(f[i]);
if (sz > 1 && f.is_boolean())
{
// For Boolean nodes, connect all children in a
// loop. This way the node can only be a cut-point
// if it separates all children from the reset of
// the graph (not only one).
formula pred = f[0];
for (i = 1; i < sz; ++i)
{
formula next = f[i];
// Note that we only add an edge in one
// direction, because we are building a cycle
// between all children anyway.
g[pred].push_back(next);
pred = next;
}
g[pred].push_back(f[0]);
}
s.pop();
}
};
@ -307,7 +307,7 @@ namespace spot
unsigned num; // serial number, in pre-order
unsigned low; // lowest number accessible via unstacked descendants
data_entry(unsigned num = 0, unsigned low = 0)
: num(num), low(low)
: num(num), low(low)
{
}
};
@ -315,7 +315,7 @@ namespace spot
struct stack_entry
{
formula grand_parent;
formula parent; // current node
formula parent; // current node
succ_vec::const_iterator current_child;
succ_vec::const_iterator last_child;
};
@ -347,58 +347,58 @@ namespace spot
s.push(e);
while (!s.empty())
{
stack_entry& e = s.top();
if (e.current_child != e.last_child)
{
// Skip the edge if it is just the reverse of the one
// we took.
formula child = *e.current_child;
if (child == e.grand_parent)
{
++e.current_child;
continue;
}
auto i = data.emplace(std::piecewise_construct,
std::forward_as_tuple(child),
std::forward_as_tuple(num, num));
if (i.second) // New destination.
{
++num;
const succ_vec& children = g.find(child)->second;
stack_entry newe = { e.parent, child,
children.begin(), children.end() };
s.push(newe);
}
else // Destination exists.
{
data_entry& dparent = data[e.parent];
data_entry& dchild = i.first->second;
// If this is a back-edge, update
// the low field of the parent.
if (dchild.num <= dparent.num)
if (dparent.low > dchild.num)
dparent.low = dchild.num;
}
++e.current_child;
}
else
{
formula grand_parent = e.grand_parent;
formula parent = e.parent;
s.pop();
if (!s.empty())
{
data_entry& dparent = data[parent];
data_entry& dgrand_parent = data[grand_parent];
if (dparent.low >= dgrand_parent.num // cut-point
&& grand_parent.is_boolean())
c.insert(grand_parent);
if (dparent.low < dgrand_parent.low)
dgrand_parent.low = dparent.low;
}
}
}
{
stack_entry& e = s.top();
if (e.current_child != e.last_child)
{
// Skip the edge if it is just the reverse of the one
// we took.
formula child = *e.current_child;
if (child == e.grand_parent)
{
++e.current_child;
continue;
}
auto i = data.emplace(std::piecewise_construct,
std::forward_as_tuple(child),
std::forward_as_tuple(num, num));
if (i.second) // New destination.
{
++num;
const succ_vec& children = g.find(child)->second;
stack_entry newe = { e.parent, child,
children.begin(), children.end() };
s.push(newe);
}
else // Destination exists.
{
data_entry& dparent = data[e.parent];
data_entry& dchild = i.first->second;
// If this is a back-edge, update
// the low field of the parent.
if (dchild.num <= dparent.num)
if (dparent.low > dchild.num)
dparent.low = dchild.num;
}
++e.current_child;
}
else
{
formula grand_parent = e.grand_parent;
formula parent = e.parent;
s.pop();
if (!s.empty())
{
data_entry& dparent = data[parent];
data_entry& dgrand_parent = data[grand_parent];
if (dparent.low >= dgrand_parent.num // cut-point
&& grand_parent.is_boolean())
c.insert(grand_parent);
if (dparent.low < dgrand_parent.low)
dgrand_parent.low = dparent.low;
}
}
}
}
@ -407,44 +407,44 @@ namespace spot
public:
fset& c;
bse_relabeler(ap_generator* gen, fset& c,
relabeling_map* m)
: relabeler(gen, m), c(c)
relabeling_map* m)
: relabeler(gen, m), c(c)
{
}
using relabeler::visit;
formula
visit(formula f)
visit(formula f)
{
if (f.is(op::ap) || (c.find(f) != c.end()))
return rename(f);
if (f.is(op::ap) || (c.find(f) != c.end()))
return rename(f);
unsigned sz = f.size();
if (sz <= 2)
return f.map([this](formula f)
{
return visit(f);
});
unsigned sz = f.size();
if (sz <= 2)
return f.map([this](formula f)
{
return visit(f);
});
unsigned i = 0;
std::vector<formula> res;
/// If we have a formula like (a & b & Xc), consider
/// it as ((a & b) & Xc) in the graph to isolate the
/// Boolean operands as a single node.
formula b = f.boolean_operands(&i);
if (b)
{
res.reserve(sz - i + 1);
res.push_back(visit(b));
}
else
{
res.reserve(sz);
}
for (; i < sz; ++i)
res.push_back(visit(f[i]));
return formula::multop(f.kind(), res);
unsigned i = 0;
std::vector<formula> res;
/// If we have a formula like (a & b & Xc), consider
/// it as ((a & b) & Xc) in the graph to isolate the
/// Boolean operands as a single node.
formula b = f.boolean_operands(&i);
if (b)
{
res.reserve(sz - i + 1);
res.push_back(visit(b));
}
else
{
res.reserve(sz);
}
for (; i < sz; ++i)
res.push_back(visit(f[i]));
return formula::multop(f.kind(), res);
}
};
}
@ -471,11 +471,11 @@ namespace spot
switch (style)
{
case Pnn:
gen = new pnn_generator;
break;
gen = new pnn_generator;
break;
case Abc:
gen = new abc_generator;
break;
gen = new abc_generator;
break;
}
bse_relabeler rel(gen, c, m);
return rel.visit(f);

View file

@ -36,7 +36,7 @@ namespace spot
/// between the new names (keys) and the old names (values).
SPOT_API
formula relabel(formula f, relabeling_style style,
relabeling_map* m = nullptr);
relabeling_map* m = nullptr);
/// \ingroup tl_rewriting
@ -47,5 +47,5 @@ namespace spot
/// between the new names (keys) and the old names (values).
SPOT_API
formula relabel_bse(formula f, relabeling_style style,
relabeling_map* m = nullptr);
relabeling_map* m = nullptr);
}

View file

@ -29,59 +29,59 @@ namespace spot
remove_x_rec(formula f, atomic_prop_set& aps)
{
if (f.is_syntactic_stutter_invariant())
return f;
return f;
auto rec = [&aps](formula f)
{
return remove_x_rec(f, aps);
};
{
return remove_x_rec(f, aps);
};
if (!f.is(op::X))
return f.map(rec);
return f.map(rec);
formula c = rec(f[0]);
std::vector<formula> vo;
for (auto i: aps)
{
// First line
std::vector<formula> va1;
formula npi = formula::Not(i);
va1.push_back(i);
va1.push_back(formula::U(i, formula::And({npi, c})));
{
// First line
std::vector<formula> va1;
formula npi = formula::Not(i);
va1.push_back(i);
va1.push_back(formula::U(i, formula::And({npi, c})));
for (auto j: aps)
if (j != i)
{
// make sure the arguments of OR are created in a
// deterministic order
auto tmp = formula::U(formula::Not(j), npi);
va1.push_back(formula::Or({formula::U(j, npi), tmp}));
}
vo.push_back(formula::And(va1));
// Second line
std::vector<formula> va2;
va2.push_back(npi);
va2.push_back(formula::U(npi, formula::And({i, c})));
for (auto j: aps)
if (j != i)
{
// make sure the arguments of OR are created in a
// deterministic order
auto tmp = formula::U(formula::Not(j), i);
va2.push_back(formula::Or({formula::U(j, i), tmp}));
}
vo.push_back(formula::And(va2));
}
for (auto j: aps)
if (j != i)
{
// make sure the arguments of OR are created in a
// deterministic order
auto tmp = formula::U(formula::Not(j), npi);
va1.push_back(formula::Or({formula::U(j, npi), tmp}));
}
vo.push_back(formula::And(va1));
// Second line
std::vector<formula> va2;
va2.push_back(npi);
va2.push_back(formula::U(npi, formula::And({i, c})));
for (auto j: aps)
if (j != i)
{
// make sure the arguments of OR are created in a
// deterministic order
auto tmp = formula::U(formula::Not(j), i);
va2.push_back(formula::Or({formula::U(j, i), tmp}));
}
vo.push_back(formula::And(va2));
}
// Third line
std::vector<formula> va3;
for (auto i: aps)
{
// make sure the arguments of OR are created in a
// deterministic order
auto tmp = formula::G(formula::Not(i));
va3.push_back(formula::Or({formula::G(i), tmp}));
}
{
// make sure the arguments of OR are created in a
// deterministic order
auto tmp = formula::G(formula::Not(i));
va3.push_back(formula::Or({formula::G(i), tmp}));
}
va3.push_back(c);
vo.push_back(formula::And(va3));
return formula::Or(vo);

File diff suppressed because it is too large Load diff

View file

@ -30,23 +30,23 @@ namespace spot
{
public:
tl_simplifier_options(bool basics = true,
bool synt_impl = true,
bool event_univ = true,
bool containment_checks = false,
bool containment_checks_stronger = false,
bool nenoform_stop_on_boolean = false,
bool reduce_size_strictly = false,
bool boolean_to_isop = false,
bool favor_event_univ = false)
bool synt_impl = true,
bool event_univ = true,
bool containment_checks = false,
bool containment_checks_stronger = false,
bool nenoform_stop_on_boolean = false,
bool reduce_size_strictly = false,
bool boolean_to_isop = false,
bool favor_event_univ = false)
: reduce_basics(basics),
synt_impl(synt_impl),
event_univ(event_univ),
containment_checks(containment_checks),
containment_checks_stronger(containment_checks_stronger),
nenoform_stop_on_boolean(nenoform_stop_on_boolean),
reduce_size_strictly(reduce_size_strictly),
boolean_to_isop(boolean_to_isop),
favor_event_univ(favor_event_univ)
synt_impl(synt_impl),
event_univ(event_univ),
containment_checks(containment_checks),
containment_checks_stronger(containment_checks_stronger),
nenoform_stop_on_boolean(nenoform_stop_on_boolean),
reduce_size_strictly(reduce_size_strictly),
boolean_to_isop(boolean_to_isop),
favor_event_univ(favor_event_univ)
{
}
@ -54,21 +54,21 @@ namespace spot
tl_simplifier_options(false, false, false)
{
switch (level)
{
case 3:
containment_checks = true;
containment_checks_stronger = true;
// fall through
case 2:
synt_impl = true;
// fall through
case 1:
reduce_basics = true;
event_univ = true;
// fall through
default:
break;
}
{
case 3:
containment_checks = true;
containment_checks_stronger = true;
// fall through
case 2:
synt_impl = true;
// fall through
case 1:
reduce_basics = true;
event_univ = true;
// fall through
default:
break;
}
}
bool reduce_basics;
@ -99,7 +99,7 @@ namespace spot
public:
tl_simplifier(const bdd_dict_ptr& dict = make_bdd_dict());
tl_simplifier(const tl_simplifier_options& opt,
bdd_dict_ptr dict = make_bdd_dict());
bdd_dict_ptr dict = make_bdd_dict());
~tl_simplifier();
/// Simplify the formula \a f (using options supplied to the
@ -123,18 +123,18 @@ namespace spot
///
/// This is adapted from
/** \verbatim
@InProceedings{ somenzi.00.cav,
author = {Fabio Somenzi and Roderick Bloem},
title = {Efficient {B\"u}chi Automata for {LTL} Formulae},
booktitle = {Proceedings of the 12th International Conference on
Computer Aided Verification (CAV'00)},
pages = {247--263},
year = {2000},
volume = {1855},
series = {Lecture Notes in Computer Science},
publisher = {Springer-Verlag}
}
\endverbatim */
@InProceedings{ somenzi.00.cav,
author = {Fabio Somenzi and Roderick Bloem},
title = {Efficient {B\"u}chi Automata for {LTL} Formulae},
booktitle = {Proceedings of the 12th International Conference on
Computer Aided Verification (CAV'00)},
pages = {247--263},
year = {2000},
volume = {1855},
series = {Lecture Notes in Computer Science},
publisher = {Springer-Verlag}
}
\endverbatim */
///
bool syntactic_implication(formula f, formula g);
/// \brief Syntactic implication with one negated argument.
@ -143,7 +143,7 @@ namespace spot
/// \a f implies !\a g. If \a right is false, this returns
/// whether !\a f implies \a g.
bool syntactic_implication_neg(formula f, formula g,
bool right);
bool right);
/// \brief check whether two formulae are equivalent.
///

View file

@ -33,97 +33,97 @@ namespace spot
snf_cache* cache_;
public:
snf_visitor(snf_cache* c)
: cache_(c)
: cache_(c)
{
}
formula visit(formula f)
{
if (!f.accepts_eword())
return f;
if (!f.accepts_eword())
return f;
snf_cache::const_iterator i = cache_->find(f);
if (i != cache_->end())
return i->second;
snf_cache::const_iterator i = cache_->find(f);
if (i != cache_->end())
return i->second;
formula out;
switch (f.kind())
{
case op::eword:
out = formula::ff();
break;
case op::Star:
if (!bounded)
out = visit(f[0]); // Strip the star.
else
out = formula::Star(visit(f[0]),
std::max(unsigned(f.min()), 1U), f.max());
break;
case op::Concat:
if (bounded)
{
out = f;
break;
}
// Fall through
case op::OrRat:
case op::AndNLM:
// Let F designate expressions that accept [*0],
// and G designate expressions that do not.
formula out;
switch (f.kind())
{
case op::eword:
out = formula::ff();
break;
case op::Star:
if (!bounded)
out = visit(f[0]); // Strip the star.
else
out = formula::Star(visit(f[0]),
std::max(unsigned(f.min()), 1U), f.max());
break;
case op::Concat:
if (bounded)
{
out = f;
break;
}
// Fall through
case op::OrRat:
case op::AndNLM:
// Let F designate expressions that accept [*0],
// and G designate expressions that do not.
// (G₁;G₂;G₃)° = G₁;G₂;G₃
// (G₁;F₂;G₃)° = (G₁°);F₂;(G₃°) = G₁;F₂;G₃
// because there is nothing to do recursively on a G.
//
// AndNLM can be dealt with similarly.
//
// The above cases are already handled by the
// accepts_eword() tests at the top of this method. So
// we reach this switch, we only have to deal with...
//
// (F₁;F₂;F₃)° = (F₁°)|(F₂°)|(F₃°)
// (F₁&F₂&F₃)° = (F₁°)|(F₂°)|(F₃°)
// (F₁|G₂|F₃)° = (F₁°)|(G₂°)|(F₃°)
{
unsigned s = f.size();
std::vector<formula> v;
v.reserve(s);
for (unsigned pos = 0; pos < s; ++pos)
v.emplace_back(visit(f[pos]));
out = formula::OrRat(v);
break;
}
case op::ff:
case op::tt:
case op::ap:
case op::Not:
case op::X:
case op::F:
case op::G:
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
case op::Fusion:
case op::Or:
case op::And:
SPOT_UNREACHABLE();
case op::AndRat: // Can AndRat be handled better?
case op::FStar: // Can FStar be handled better?
out = f;
break;
}
// (G₁;G₂;G₃)° = G₁;G₂;G₃
// (G₁;F₂;G₃)° = (G₁°);F₂;(G₃°) = G₁;F₂;G₃
// because there is nothing to do recursively on a G.
//
// AndNLM can be dealt with similarly.
//
// The above cases are already handled by the
// accepts_eword() tests at the top of this method. So
// we reach this switch, we only have to deal with...
//
// (F₁;F₂;F₃)° = (F₁°)|(F₂°)|(F₃°)
// (F₁&F₂&F₃)° = (F₁°)|(F₂°)|(F₃°)
// (F₁|G₂|F₃)° = (F₁°)|(G₂°)|(F₃°)
{
unsigned s = f.size();
std::vector<formula> v;
v.reserve(s);
for (unsigned pos = 0; pos < s; ++pos)
v.emplace_back(visit(f[pos]));
out = formula::OrRat(v);
break;
}
case op::ff:
case op::tt:
case op::ap:
case op::Not:
case op::X:
case op::F:
case op::G:
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
case op::Fusion:
case op::Or:
case op::And:
SPOT_UNREACHABLE();
case op::AndRat: // Can AndRat be handled better?
case op::FStar: // Can FStar be handled better?
out = f;
break;
}
return (*cache_)[f] = out;
return (*cache_)[f] = out;
}
};
}

View file

@ -33,13 +33,13 @@ namespace spot
/// paper.
///
/** \verbatim
@Article{ bruggeman.96.tcs,
author = {Anne Br{\"u}ggemann-Klein},
title = {Regular Expressions into Finite Automata},
journal = {Theoretical Computer Science},
year = {1996},
volume = {120},
pages = {87--98}
@Article{ bruggeman.96.tcs,
author = {Anne Br{\"u}ggemann-Klein},
title = {Regular Expressions into Finite Automata},
journal = {Theoretical Computer Science},
year = {1996},
volume = {120},
pages = {87--98}
}
\endverbatim */
///

View file

@ -26,44 +26,44 @@ namespace spot
{
while (*opt)
switch (char c = *opt++)
{
case 'e':
re_e_ = true;
re_some_bool_ = true;
break;
case 'F':
re_f_ = true;
re_some_f_g_ = true;
break;
case 'G':
re_g_ = true;
re_some_f_g_ = true;
break;
case 'i':
re_i_ = true;
re_some_bool_ = true;
break;
case 'M':
re_m_ = true;
re_some_other_ = true;
break;
case 'R':
re_r_ = true;
re_some_other_ = true;
break;
case 'W':
re_w_ = true;
re_some_other_ = true;
break;
case '^':
re_xor_ = true;
re_some_bool_ = true;
break;
default:
throw std::runtime_error
(std::string("unknown unabbreviation option: ")
+ c);
}
{
case 'e':
re_e_ = true;
re_some_bool_ = true;
break;
case 'F':
re_f_ = true;
re_some_f_g_ = true;
break;
case 'G':
re_g_ = true;
re_some_f_g_ = true;
break;
case 'i':
re_i_ = true;
re_some_bool_ = true;
break;
case 'M':
re_m_ = true;
re_some_other_ = true;
break;
case 'R':
re_r_ = true;
re_some_other_ = true;
break;
case 'W':
re_w_ = true;
re_some_other_ = true;
break;
case '^':
re_xor_ = true;
re_some_bool_ = true;
break;
default:
throw std::runtime_error
(std::string("unknown unabbreviation option: ")
+ c);
}
}
formula unabbreviator::run(formula in)
@ -76,12 +76,12 @@ namespace spot
bool no_boolean_rewrite = !re_some_bool_ || in.is_sugar_free_boolean();
bool no_f_g_rewrite = !re_some_f_g_ || in.is_sugar_free_ltl();
if (no_boolean_rewrite
&& (in.is_boolean() || (no_f_g_rewrite && !re_some_other_)))
&& (in.is_boolean() || (no_f_g_rewrite && !re_some_other_)))
return entry.first->second = in;
auto rec = [this](formula f)
{
return this->run(f);
return this->run(f);
};
formula out = in;
@ -112,132 +112,132 @@ namespace spot
case op::Fusion:
case op::Star:
case op::FStar:
break;
break;
case op::F:
// F f = true U f
if (!re_f_)
break;
out = formula::U(formula::tt(), out[0]);
break;
// F f = true U f
if (!re_f_)
break;
out = formula::U(formula::tt(), out[0]);
break;
case op::G:
// G f = false R f
// G f = f W false
// G f = !F!f
// G f = !(true U !f)
if (!re_g_)
break;
if (!re_r_)
{
out = formula::R(formula::ff(), out[0]);
break;
}
if (!re_w_)
{
out = formula::W(out[0], formula::ff());
break;
}
{
auto nc = formula::Not(out[0]);
if (!re_f_)
{
out = formula::Not(formula::F(nc));
break;
}
out = formula::Not(formula::U(formula::tt(), nc));
break;
}
// G f = false R f
// G f = f W false
// G f = !F!f
// G f = !(true U !f)
if (!re_g_)
break;
if (!re_r_)
{
out = formula::R(formula::ff(), out[0]);
break;
}
if (!re_w_)
{
out = formula::W(out[0], formula::ff());
break;
}
{
auto nc = formula::Not(out[0]);
if (!re_f_)
{
out = formula::Not(formula::F(nc));
break;
}
out = formula::Not(formula::U(formula::tt(), nc));
break;
}
case op::Xor:
// f1 ^ f2 == !(f1 <-> f2)
// f1 ^ f2 == (f1 & !f2) | (f2 & !f1)
if (!re_xor_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
if (!re_e_)
{
out = formula::Not(formula::Equiv(f1, f2));
}
else
{
auto a = formula::And({f1, formula::Not(f2)});
auto b = formula::And({f2, formula::Not(f1)});
out = formula::Or({a, b});
}
}
break;
// f1 ^ f2 == !(f1 <-> f2)
// f1 ^ f2 == (f1 & !f2) | (f2 & !f1)
if (!re_xor_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
if (!re_e_)
{
out = formula::Not(formula::Equiv(f1, f2));
}
else
{
auto a = formula::And({f1, formula::Not(f2)});
auto b = formula::And({f2, formula::Not(f1)});
out = formula::Or({a, b});
}
}
break;
case op::Implies:
// f1 => f2 == !f1 | f2
if (!re_i_)
break;
out = formula::Or({formula::Not(out[0]), out[1]});
break;
// f1 => f2 == !f1 | f2
if (!re_i_)
break;
out = formula::Or({formula::Not(out[0]), out[1]});
break;
case op::Equiv:
// f1 <=> f2 == (f1 & f2) | (!f1 & !f2)
if (!re_e_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
auto nf1 = formula::Not(f1);
auto nf2 = formula::Not(f2);
auto term1 = formula::And({f1, f2});
auto term2 = formula::And({nf1, nf2});
out = formula::Or({term1, term2});
break;
}
// f1 <=> f2 == (f1 & f2) | (!f1 & !f2)
if (!re_e_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
auto nf1 = formula::Not(f1);
auto nf2 = formula::Not(f2);
auto term1 = formula::And({f1, f2});
auto term2 = formula::And({nf1, nf2});
out = formula::Or({term1, term2});
break;
}
case op::R:
// f1 R f2 = f2 W (f1 & f2)
// f1 R f2 = f2 U ((f1 & f2) | Gf2)
// f1 R f2 = f2 U ((f1 & f2) | !F!f2)
// f1 R f2 = f2 U ((f1 & f2) | !(1 U !f2))
if (!re_r_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
auto f12 = formula::And({f1, f2});
if (!re_w_)
{
out = formula::W(f2, f12);
break;
}
auto gf2 = formula::G(f2);
if (re_g_)
gf2 = run(gf2);
out = formula::U(f2, formula::Or({f12, gf2}));
break;
}
// f1 R f2 = f2 W (f1 & f2)
// f1 R f2 = f2 U ((f1 & f2) | Gf2)
// f1 R f2 = f2 U ((f1 & f2) | !F!f2)
// f1 R f2 = f2 U ((f1 & f2) | !(1 U !f2))
if (!re_r_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
auto f12 = formula::And({f1, f2});
if (!re_w_)
{
out = formula::W(f2, f12);
break;
}
auto gf2 = formula::G(f2);
if (re_g_)
gf2 = run(gf2);
out = formula::U(f2, formula::Or({f12, gf2}));
break;
}
case op::W:
// f1 W f2 = f2 R (f2 | f1)
// f1 W f2 = f1 U (f2 | G f1)
// f1 W f2 = f1 U (f2 | !F !f1)
// f1 W f2 = f1 U (f2 | !(1 U !f1))
if (!re_w_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
if (!re_r_)
{
out = formula::R(f2, formula::Or({f2, f1}));
break;
}
auto gf1 = formula::G(f1);
if (re_g_)
gf1 = run(gf1);
out = formula::U(f1, formula::Or({f2, gf1}));
break;
}
// f1 W f2 = f2 R (f2 | f1)
// f1 W f2 = f1 U (f2 | G f1)
// f1 W f2 = f1 U (f2 | !F !f1)
// f1 W f2 = f1 U (f2 | !(1 U !f1))
if (!re_w_)
break;
{
auto f1 = out[0];
auto f2 = out[1];
if (!re_r_)
{
out = formula::R(f2, formula::Or({f2, f1}));
break;
}
auto gf1 = formula::G(f1);
if (re_g_)
gf1 = run(gf1);
out = formula::U(f1, formula::Or({f2, gf1}));
break;
}
case op::M:
// f1 M f2 = f2 U (g2 & f1)
if (!re_m_)
break;
{
auto f2 = out[1];
out = formula::U(f2, formula::And({f2, out[0]}));
break;
}
// f1 M f2 = f2 U (g2 & f1)
if (!re_m_)
break;
{
auto f2 = out[1];
out = formula::U(f2, formula::And({f2, out[0]}));
break;
}
}
return entry.first->second = out;
}

View file

@ -41,9 +41,9 @@ namespace spot
bool re_r_ = false;
bool re_w_ = false;
bool re_xor_ = false;
bool re_some_bool_ = false; // rewrite xor, i, or e
bool re_some_f_g_ = false; // rewrite F or G
bool re_some_other_ = false; // rewrite W, M, or R
bool re_some_bool_ = false; // rewrite xor, i, or e
bool re_some_f_g_ = false; // rewrite F or G
bool re_some_other_ = false; // rewrite W, M, or R
// Cache of rewritten subformulas
std::unordered_map<formula, formula> cache_;
public:

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -50,21 +50,21 @@ namespace spot
// a hash; but we should ensure that no object in the hash is
// constructed with p==0.
anon_free_list(bdd_dict_priv* p = nullptr)
: priv_(p)
: priv_(p)
{
}
virtual int
extend(int n) override
{
assert(priv_);
int b = priv_->allocate_variables(n);
free_anonymous_list_of_type::iterator i;
for (i = priv_->free_anonymous_list_of.begin();
i != priv_->free_anonymous_list_of.end(); ++i)
if (&i->second != this)
i->second.insert(b, n);
return b;
assert(priv_);
int b = priv_->allocate_variables(n);
free_anonymous_list_of_type::iterator i;
for (i = priv_->free_anonymous_list_of.begin();
i != priv_->free_anonymous_list_of.end(); ++i)
if (&i->second != this)
i->second.insert(b, n);
return b;
}
private:
@ -102,15 +102,15 @@ namespace spot
fv_map::iterator sii = var_map.find(f);
if (sii != var_map.end())
{
num = sii->second;
num = sii->second;
}
else
{
num = priv_->allocate_variables(1);
var_map[f] = num;
bdd_map.resize(bdd_varnum());
bdd_map[num].type = var;
bdd_map[num].f = f;
num = priv_->allocate_variables(1);
var_map[f] = num;
bdd_map.resize(bdd_varnum());
bdd_map[num].type = var;
bdd_map[num].f = f;
}
bdd_map[num].refs.insert(for_me);
return num;
@ -118,7 +118,7 @@ namespace spot
int
bdd_dict::has_registered_proposition(formula f,
const void* me)
const void* me)
{
auto ssi = var_map.find(f);
if (ssi == var_map.end())
@ -132,24 +132,24 @@ namespace spot
int
bdd_dict::register_acceptance_variable(formula f,
const void* for_me)
const void* for_me)
{
int num;
// Do not build an acceptance variable that already exists.
fv_map::iterator sii = acc_map.find(f);
if (sii != acc_map.end())
{
num = sii->second;
num = sii->second;
}
else
{
num = priv_->allocate_variables(1);
acc_map[f] = num;
bdd_map.resize(bdd_varnum());
bdd_info& i = bdd_map[num];
i.type = acc;
i.f = f;
i.clone_counts = 0;
num = priv_->allocate_variables(1);
acc_map[f] = num;
bdd_map.resize(bdd_varnum());
bdd_info& i = bdd_map[num];
i.type = acc;
i.f = f;
i.clone_counts = 0;
}
bdd_map[num].refs.insert(for_me);
return num;
@ -163,9 +163,9 @@ namespace spot
if (i == priv_->free_anonymous_list_of.end())
{
i = (priv_->free_anonymous_list_of.insert
(fal::value_type(for_me,
priv_->free_anonymous_list_of[nullptr]))).first;
i = (priv_->free_anonymous_list_of.insert
(fal::value_type(for_me,
priv_->free_anonymous_list_of[nullptr]))).first;
}
int res = i->second.register_n(n);
@ -173,8 +173,8 @@ namespace spot
while (n--)
{
bdd_map[res + n].type = anon;
bdd_map[res + n].refs.insert(for_me);
bdd_map[res + n].type = anon;
bdd_map[res + n].refs.insert(for_me);
}
return res;
@ -183,7 +183,7 @@ namespace spot
void
bdd_dict::register_all_variables_of(const void* from_other,
const void* for_me)
const void* for_me)
{
auto j = priv_->free_anonymous_list_of.find(from_other);
if (j != priv_->free_anonymous_list_of.end())
@ -191,24 +191,24 @@ namespace spot
for (auto& i: bdd_map)
{
ref_set& s = i.refs;
if (s.find(from_other) != s.end())
s.insert(for_me);
ref_set& s = i.refs;
if (s.find(from_other) != s.end())
s.insert(for_me);
}
}
void
bdd_dict::register_all_propositions_of(const void* from_other,
const void* for_me)
const void* for_me)
{
for (auto& i: bdd_map)
{
if (i.type != var_type::var)
continue;
ref_set& s = i.refs;
if (s.find(from_other) != s.end())
s.insert(for_me);
if (i.type != var_type::var)
continue;
ref_set& s = i.refs;
if (s.find(from_other) != s.end())
s.insert(for_me);
}
}
@ -241,24 +241,24 @@ namespace spot
switch (bdd_map[v].type)
{
case var:
f = bdd_map[v].f;
var_map.erase(f);
break;
f = bdd_map[v].f;
var_map.erase(f);
break;
case acc:
f = bdd_map[v].f;
acc_map.erase(f);
break;
f = bdd_map[v].f;
acc_map.erase(f);
break;
case anon:
{
bdd_dict_priv::free_anonymous_list_of_type::iterator i;
// Nobody use this variable as an anonymous variable
// anymore, so remove it entirely from the anonymous
// free list so it can be used for something else.
for (i = priv_->free_anonymous_list_of.begin();
i != priv_->free_anonymous_list_of.end(); ++i)
i->second.remove(v, n);
break;
}
{
bdd_dict_priv::free_anonymous_list_of_type::iterator i;
// Nobody use this variable as an anonymous variable
// anymore, so remove it entirely from the anonymous
// free list so it can be used for something else.
for (i = priv_->free_anonymous_list_of.begin();
i != priv_->free_anonymous_list_of.end(); ++i)
i->second.remove(v, n);
break;
}
}
// Actually release the associated BDD variables, and the
// formula itself.
@ -283,39 +283,39 @@ namespace spot
unsigned s = bdd_map.size();
for (unsigned i = 0; i < s; ++i)
{
os << ' ' << i << ' ';
const bdd_info& r = bdd_map[i];
switch (r.type)
{
case anon:
os << (r.refs.empty() ? "Free" : "Anon");
break;
case acc:
os << "Acc[";
print_psl(os, r.f) << ']';
break;
case var:
os << "Var[";
print_psl(os, r.f) << ']';
break;
}
if (!r.refs.empty())
{
os << " x" << r.refs.size() << " {";
for (ref_set::const_iterator si = r.refs.begin();
si != r.refs.end(); ++si)
os << ' ' << *si;
os << " }";
}
os << '\n';
os << ' ' << i << ' ';
const bdd_info& r = bdd_map[i];
switch (r.type)
{
case anon:
os << (r.refs.empty() ? "Free" : "Anon");
break;
case acc:
os << "Acc[";
print_psl(os, r.f) << ']';
break;
case var:
os << "Var[";
print_psl(os, r.f) << ']';
break;
}
if (!r.refs.empty())
{
os << " x" << r.refs.size() << " {";
for (ref_set::const_iterator si = r.refs.begin();
si != r.refs.end(); ++si)
os << ' ' << *si;
os << " }";
}
os << '\n';
}
os << "Anonymous lists:\n";
bdd_dict_priv::free_anonymous_list_of_type::const_iterator ai;
for (ai = priv_->free_anonymous_list_of.begin();
ai != priv_->free_anonymous_list_of.end(); ++ai)
ai != priv_->free_anonymous_list_of.end(); ++ai)
{
os << " [" << ai->first << "] ";
ai->second.dump_free_list(os) << std::endl;
os << " [" << ai->first << "] ";
ai->second.dump_free_list(os) << std::endl;
}
os << "Free list:\n";
priv_->dump_free_list(os);
@ -334,42 +334,42 @@ namespace spot
unsigned s = bdd_map.size();
for (unsigned i = 0; i < s; ++i)
{
switch (bdd_map[i].type)
{
case var:
var_seen = true;
break;
case acc:
acc_seen = true;
break;
case anon:
break;
}
refs_seen |= !bdd_map[i].refs.empty();
switch (bdd_map[i].type)
{
case var:
var_seen = true;
break;
case acc:
acc_seen = true;
break;
case anon:
break;
}
refs_seen |= !bdd_map[i].refs.empty();
}
if (var_map.empty() && acc_map.empty())
{
if (var_seen)
{
std::cerr << "var_map is empty but Var in map" << std::endl;
fail = true;
}
if (acc_seen)
{
std::cerr << "acc_map is empty but Acc in map" << std::endl;
fail = true;
}
if (refs_seen)
{
std::cerr << "maps are empty but var_refs is not" << std::endl;
fail = true;
}
if (!fail)
return;
if (var_seen)
{
std::cerr << "var_map is empty but Var in map" << std::endl;
fail = true;
}
if (acc_seen)
{
std::cerr << "acc_map is empty but Acc in map" << std::endl;
fail = true;
}
if (refs_seen)
{
std::cerr << "maps are empty but var_refs is not" << std::endl;
fail = true;
}
if (!fail)
return;
}
else
{
std::cerr << "some maps are not empty" << std::endl;
std::cerr << "some maps are not empty" << std::endl;
}
dump(std::cerr);
abort();

View file

@ -70,8 +70,8 @@ namespace spot
/// BDD-variable-to-formula maps.
typedef std::map<int, formula> vf_map;
fv_map var_map; ///< Maps atomic propositions to BDD variables
fv_map acc_map; ///< Maps acceptance conditions to BDD variables
fv_map var_map; ///< Maps atomic propositions to BDD variables
fv_map acc_map; ///< Maps acceptance conditions to BDD variables
/// BDD-variable reference counts.
typedef std::set<const void*> ref_set;
@ -80,7 +80,7 @@ namespace spot
struct bdd_info {
bdd_info() : type(anon) {}
var_type type;
formula f; // Used unless t==anon.
formula f; // Used unless t==anon.
ref_set refs;
int clone_counts;
};
@ -180,21 +180,21 @@ namespace spot
template <typename T>
void register_all_variables_of(const void* from_other,
std::shared_ptr<T> for_me)
std::shared_ptr<T> for_me)
{
register_all_variables_of(from_other, for_me.get());
}
template <typename T>
void register_all_variables_of(std::shared_ptr<T> from_other,
const void* for_me)
const void* for_me)
{
register_all_variables_of(from_other.get(), for_me);
}
template <typename T, typename U>
void register_all_variables_of(std::shared_ptr<T> from_other,
std::shared_ptr<U> for_me)
std::shared_ptr<U> for_me)
{
register_all_variables_of(from_other.get(), for_me.get());
}
@ -209,25 +209,25 @@ namespace spot
/// is still alive.
/// @{
void register_all_propositions_of(const void* from_other,
const void* for_me);
const void* for_me);
template <typename T>
void register_all_propositions_of(const void* from_other,
std::shared_ptr<T> for_me)
std::shared_ptr<T> for_me)
{
register_all_propositions_of(from_other, for_me.get());
}
template <typename T>
void register_all_propositions_of(std::shared_ptr<T> from_other,
const void* for_me)
const void* for_me)
{
register_all_propositions_of(from_other.get(), for_me);
}
template <typename T, typename U>
void register_all_propositions_of(std::shared_ptr<T> from_other,
std::shared_ptr<U> for_me)
std::shared_ptr<U> for_me)
{
register_all_propositions_of(from_other.get(), for_me.get());
}

View file

@ -58,22 +58,22 @@ namespace spot
switch (ref.type)
{
case bdd_dict::var:
print_(o, ref.f);
break;
print_(o, ref.f);
break;
case bdd_dict::acc:
if (want_acc)
{
o << "Acc[";
print_(o, ref.f) << ']';
}
else
{
o << '"';
print_(o, ref.f) << '"';
}
break;
if (want_acc)
{
o << "Acc[";
print_(o, ref.f) << ']';
}
else
{
o << '"';
print_(o, ref.f) << '"';
}
break;
case bdd_dict::anon:
o << '?' << v;
o << '?' << v;
}
}
@ -85,15 +85,15 @@ namespace spot
bool not_first = false;
for (int v = 0; v < size; ++v)
{
if (varset[v] < 0)
continue;
if (not_first)
*where << ' ';
else
not_first = true;
if (varset[v] == 0)
*where << "! ";
print_handler(*where, v);
if (varset[v] < 0)
continue;
if (not_first)
*where << ' ';
else
not_first = true;
if (varset[v] == 0)
*where << "! ";
print_handler(*where, v);
}
}
@ -114,11 +114,11 @@ namespace spot
{
for (int v = 0; v < size; ++v)
if (varset[v] > 0)
{
*where << (first_done ? ", " : "{");
print_handler(*where, v);
first_done = true;
}
{
*where << (first_done ? ", " : "{");
print_handler(*where, v);
first_done = true;
}
}
std::ostream&

View file

@ -33,30 +33,30 @@ namespace spot
conj_to_formula(bdd b, const bdd_dict_ptr d)
{
if (b == bddfalse)
return formula::ff();
return formula::ff();
std::vector<formula> v;
while (b != bddtrue)
{
int var = bdd_var(b);
const bdd_dict::bdd_info& i = d->bdd_map[var];
assert(i.type == bdd_dict::var);
formula res = i.f;
{
int var = bdd_var(b);
const bdd_dict::bdd_info& i = d->bdd_map[var];
assert(i.type == bdd_dict::var);
formula res = i.f;
bdd high = bdd_high(b);
if (high == bddfalse)
{
res = formula::Not(res);
b = bdd_low(b);
}
else
{
// If bdd_low is not false, then b was not a conjunction.
assert(bdd_low(b) == bddfalse);
b = high;
}
assert(b != bddfalse);
v.push_back(res);
}
bdd high = bdd_high(b);
if (high == bddfalse)
{
res = formula::Not(res);
b = bdd_low(b);
}
else
{
// If bdd_low is not false, then b was not a conjunction.
assert(bdd_low(b) == bddfalse);
b = high;
}
assert(b != bddfalse);
v.push_back(res);
}
return formula::And(v);
}
} // anonymous
@ -66,14 +66,14 @@ namespace spot
{
auto recurse = [&d, owner](formula f)
{
return formula_to_bdd(f, d, owner);
return formula_to_bdd(f, d, owner);
};
switch (f.kind())
{
case op::ff:
return bddfalse;
return bddfalse;
case op::tt:
return bddtrue;
return bddtrue;
case op::eword:
case op::Star:
case op::FStar:
@ -95,32 +95,32 @@ namespace spot
case op::AndNLM:
case op::OrRat:
case op::AndRat:
SPOT_UNIMPLEMENTED();
SPOT_UNIMPLEMENTED();
case op::ap:
return bdd_ithvar(d->register_proposition(f, owner));
return bdd_ithvar(d->register_proposition(f, owner));
case op::Not:
return bdd_not(recurse(f[0]));
return bdd_not(recurse(f[0]));
case op::Xor:
return bdd_apply(recurse(f[0]), recurse(f[1]), bddop_xor);
return bdd_apply(recurse(f[0]), recurse(f[1]), bddop_xor);
case op::Implies:
return bdd_apply(recurse(f[0]), recurse(f[1]), bddop_imp);
return bdd_apply(recurse(f[0]), recurse(f[1]), bddop_imp);
case op::Equiv:
return bdd_apply(recurse(f[0]), recurse(f[1]), bddop_biimp);
return bdd_apply(recurse(f[0]), recurse(f[1]), bddop_biimp);
case op::And:
case op::Or:
{
int o = bddop_and;
bdd res = bddtrue;
if (f.is(op::Or))
{
o = bddop_or;
res = bddfalse;
}
unsigned s = f.size();
for (unsigned n = 0; n < s; ++n)
res = bdd_apply(res, recurse(f[n]), o);
return res;
}
{
int o = bddop_and;
bdd res = bddtrue;
if (f.is(op::Or))
{
o = bddop_or;
res = bddfalse;
}
unsigned s = f.size();
for (unsigned n = 0; n < s; ++n)
res = bdd_apply(res, recurse(f[n]), o);
return res;
}
}
SPOT_UNREACHABLE();
return bddfalse;

View file

@ -44,7 +44,7 @@ namespace spot
template<typename T>
SPOT_API bdd
formula_to_bdd(formula f, const bdd_dict_ptr& d,
const std::shared_ptr<T>& for_me)
const std::shared_ptr<T>& for_me)
{
return formula_to_bdd(f, d, for_me.get());
}

View file

@ -94,7 +94,7 @@ namespace spot
{
int i = *it1++ - *it2++;
if (i != 0)
return i;
return i;
}
return 0;
}
@ -162,14 +162,14 @@ namespace spot
unsigned p;
for (p = 0; p < pos.size() && t->condition != bddfalse; ++p)
{
taa_tgba::state_set::const_iterator j;
for (j = (*pos[p])->dst->begin(); j != (*pos[p])->dst->end(); ++j)
if ((*j)->size() > 0) // Remove sink states.
ss->insert(*j);
taa_tgba::state_set::const_iterator j;
for (j = (*pos[p])->dst->begin(); j != (*pos[p])->dst->end(); ++j)
if ((*j)->size() > 0) // Remove sink states.
ss->insert(*j);
// Fill the new transition.
t->condition &= (*pos[p])->condition;
t->acceptance_conditions |= (*pos[p])->acceptance_conditions;
// Fill the new transition.
t->condition &= (*pos[p])->condition;
t->acceptance_conditions |= (*pos[p])->acceptance_conditions;
} // If p != pos.size() we have found a contradiction
assert(p > 0);
t->dst = ss;
@ -182,54 +182,54 @@ namespace spot
std::vector<taa_tgba::transition*>::iterator j;
if (t->condition != bddfalse)
{
i = seen_.find(b);
if (i != seen_.end())
for (j = i->second.begin(); j != i->second.end(); ++j)
{
taa_tgba::transition* current = *j;
if (*current->dst == *t->dst
&& current->condition == t->condition)
{
current->acceptance_conditions &= t->acceptance_conditions;
break;
}
if (*current->dst == *t->dst
&& current->acceptance_conditions == t->acceptance_conditions)
{
current->condition |= t->condition;
break;
}
}
i = seen_.find(b);
if (i != seen_.end())
for (j = i->second.begin(); j != i->second.end(); ++j)
{
taa_tgba::transition* current = *j;
if (*current->dst == *t->dst
&& current->condition == t->condition)
{
current->acceptance_conditions &= t->acceptance_conditions;
break;
}
if (*current->dst == *t->dst
&& current->acceptance_conditions == t->acceptance_conditions)
{
current->condition |= t->condition;
break;
}
}
}
// Mark the new transition as seen and keep it if we have not
// found any contradiction and no other transition to merge
// with, or delete it otherwise.
if (t->condition != bddfalse
&& (i == seen_.end() || j == i->second.end()))
&& (i == seen_.end() || j == i->second.end()))
{
seen_[b].push_back(t);
if (i != seen_.end())
delete b;
succ_.push_back(t);
seen_[b].push_back(t);
if (i != seen_.end())
delete b;
succ_.push_back(t);
}
else
{
delete t->dst;
delete t;
delete b;
delete t->dst;
delete t;
delete b;
}
for (int i = pos.size() - 1; i >= 0; --i)
{
if ((i < int(p))
&& (std::distance(pos[i], bounds[i].second) > 1
|| (i == 0 && std::distance(pos[i], bounds[i].second) == 1)))
{
++pos[i];
break;
}
else
pos[i] = bounds[i].first;
if ((i < int(p))
&& (std::distance(pos[i], bounds[i].second) > 1
|| (i == 0 && std::distance(pos[i], bounds[i].second) == 1)))
{
++pos[i];
break;
}
else
pos[i] = bounds[i].first;
}
}
}

View file

@ -88,7 +88,7 @@ namespace spot
virtual ~set_state()
{
if (delete_me_)
delete s_;
delete s_;
}
const taa_tgba::state_set* get_state() const;
@ -118,18 +118,18 @@ namespace spot
typedef std::pair<iterator, iterator> iterator_pair;
typedef std::vector<iterator_pair> bounds_t;
typedef std::unordered_map<const spot::set_state*,
std::vector<taa_tgba::transition*>,
state_ptr_hash, state_ptr_equal> seen_map;
std::vector<taa_tgba::transition*>,
state_ptr_hash, state_ptr_equal> seen_map;
struct distance_sort :
public std::binary_function<const iterator_pair&,
const iterator_pair&, bool>
const iterator_pair&, bool>
{
bool
operator()(const iterator_pair& lhs, const iterator_pair& rhs) const
{
return std::distance(lhs.first, lhs.second) <
std::distance(rhs.first, rhs.second);
return std::distance(lhs.first, lhs.second) <
std::distance(rhs.first, rhs.second);
}
};
@ -150,11 +150,11 @@ namespace spot
~taa_tgba_labelled()
{
for (auto i: name_state_map_)
{
for (auto i2: *i.second)
delete i2;
delete i.second;
}
{
for (auto i2: *i.second)
delete i2;
delete i.second;
}
}
void set_init_state(const label& s)
@ -170,7 +170,7 @@ namespace spot
transition*
create_transition(const label& s,
const std::vector<label>& d)
const std::vector<label>& d)
{
state* src = add_state(s);
state_set* dst = add_state_set(d);
@ -194,7 +194,7 @@ namespace spot
{
auto p = acc_map_.emplace(f, 0);
if (p.second)
p.first->second = acc_cond::mark_t({acc().add_set()});
p.first->second = acc_cond::mark_t({acc().add_set()});
t->acceptance_conditions |= p.first->second;
}
@ -220,14 +220,14 @@ namespace spot
typename ns_map::const_iterator i;
for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
{
taa_tgba::state::const_iterator i2;
os << "State: " << label_to_string(i->first) << std::endl;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2)
{
os << ' ' << format_state_set((*i2)->dst)
<< ", C:" << (*i2)->condition
<< ", A:" << (*i2)->acceptance_conditions << std::endl;
}
taa_tgba::state::const_iterator i2;
os << "State: " << label_to_string(i->first) << std::endl;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2)
{
os << ' ' << format_state_set((*i2)->dst)
<< ", C:" << (*i2)->condition
<< ", A:" << (*i2)->acceptance_conditions << std::endl;
}
}
}
@ -236,7 +236,7 @@ namespace spot
typedef std::unordered_map<label, taa_tgba::state*> ns_map;
typedef std::unordered_map<const taa_tgba::state*, label,
ptr_hash<taa_tgba::state> > sn_map;
ptr_hash<taa_tgba::state> > sn_map;
ns_map name_state_map_;
sn_map state_name_map_;
@ -252,10 +252,10 @@ namespace spot
typename ns_map::iterator i = name_state_map_.find(name);
if (i == name_state_map_.end())
{
taa_tgba::state* s = new taa_tgba::state;
name_state_map_[name] = s;
state_name_map_[s] = name;
return s;
taa_tgba::state* s = new taa_tgba::state;
name_state_map_[name] = s;
state_name_map_[s] = name;
return s;
}
return i->second;
}
@ -265,7 +265,7 @@ namespace spot
{
state_set* ss = new state_set;
for (unsigned i = 0; i < names.size(); ++i)
ss->insert(add_state(names[i]));
ss->insert(add_state(names[i]));
state_set_vec_.push_back(ss);
return ss;
}
@ -275,25 +275,25 @@ namespace spot
state_set::const_iterator i1 = ss->begin();
typename sn_map::const_iterator i2;
if (ss->empty())
return std::string("{}");
return std::string("{}");
if (ss->size() == 1)
{
i2 = state_name_map_.find(*i1);
assert(i2 != state_name_map_.end());
return "{" + label_to_string(i2->second) + "}";
i2 = state_name_map_.find(*i1);
assert(i2 != state_name_map_.end());
return "{" + label_to_string(i2->second) + "}";
}
else
{
std::string res("{");
while (i1 != ss->end())
{
i2 = state_name_map_.find(*i1++);
assert(i2 != state_name_map_.end());
res += label_to_string(i2->second);
res += ",";
}
res[res.size() - 1] = '}';
return res;
std::string res("{");
while (i1 != ss->end())
{
i2 = state_name_map_.find(*i1++);
assert(i2 != state_name_map_.end());
res += label_to_string(i2->second);
res += ",";
}
res[res.size() - 1] = '}';
return res;
}
}
};

View file

@ -45,7 +45,7 @@ namespace spot
state*
twa::project_state(const state* s,
const const_twa_ptr& t) const
const const_twa_ptr& t) const
{
if (t.get() == this)
return s->clone();
@ -61,25 +61,25 @@ namespace spot
auto a = shared_from_this();
if (a->acc().uses_fin_acceptance())
{
auto aa = std::dynamic_pointer_cast<const twa_graph>(a);
if (!aa)
aa = make_twa_graph(a, prop_set::all());
a = remove_fin(aa);
auto aa = std::dynamic_pointer_cast<const twa_graph>(a);
if (!aa)
aa = make_twa_graph(a, prop_set::all());
a = remove_fin(aa);
}
return !couvreur99(a)->check();
}
void
twa::set_named_prop(std::string s,
void* val, std::function<void(void*)> destructor)
void* val, std::function<void(void*)> destructor)
{
auto p = named_prop_.emplace(std::piecewise_construct,
std::forward_as_tuple(s),
std::forward_as_tuple(val, destructor));
std::forward_as_tuple(s),
std::forward_as_tuple(val, destructor));
if (!p.second)
{
p.first->second.second(p.first->second.first);
p.first->second = std::make_pair(val, destructor);
p.first->second.second(p.first->second.first);
p.first->second = std::make_pair(val, destructor);
}
}

View file

@ -180,14 +180,14 @@ namespace spot
///
/// \see state_unicity_table
typedef std::unordered_set<const state*,
state_ptr_hash, state_ptr_equal> state_set;
state_ptr_hash, state_ptr_equal> state_set;
/// \brief Unordered map of abstract states
///
/// Destroying each state if needed is the user's responsibility.
template<class val>
using state_map = std::unordered_map<const state*, val,
state_ptr_hash, state_ptr_equal>;
state_ptr_hash, state_ptr_equal>;
/// \ingroup twa_essentials
/// \brief Render state pointers unique via a hash table.
@ -208,7 +208,7 @@ namespace spot
{
auto p = m.insert(s);
if (!p.second)
s->destroy();
s->destroy();
return *p.first;
}
@ -220,22 +220,22 @@ namespace spot
{
auto p = m.insert(s);
if (!p.second)
{
s->destroy();
return nullptr;
}
{
s->destroy();
return nullptr;
}
return *p.first;
}
~state_unicity_table()
{
for (state_set::iterator i = m.begin(); i != m.end();)
{
// Advance the iterator before destroying its key. This
// avoid issues with old g++ implementations.
state_set::iterator old = i++;
(*old)->destroy();
}
{
// Advance the iterator before destroying its key. This
// avoid issues with old g++ implementations.
state_set::iterator old = i++;
(*old)->destroy();
}
}
size_t
@ -336,8 +336,8 @@ namespace spot
/// Unordered set of shared states
typedef std::unordered_set<shared_state,
state_shared_ptr_hash,
state_shared_ptr_equal> shared_state_set;
state_shared_ptr_hash,
state_shared_ptr_equal> shared_state_set;
/// \ingroup twa_essentials
/// \brief Iterate over the successors of a state.
@ -483,29 +483,29 @@ namespace spot
public:
succ_iterator(twa_succ_iterator* it):
it_(it)
it_(it)
{
}
bool operator==(succ_iterator o) const
{
return it_ == o.it_;
return it_ == o.it_;
}
bool operator!=(succ_iterator o) const
{
return it_ != o.it_;
return it_ != o.it_;
}
const twa_succ_iterator* operator*() const
{
return it_;
return it_;
}
void operator++()
{
if (!it_->next())
it_ = nullptr;
if (!it_->next())
it_ = nullptr;
}
};
}
@ -597,30 +597,30 @@ namespace spot
twa_succ_iterator* it_;
public:
succ_iterable(const twa* aut, twa_succ_iterator* it)
: aut_(aut), it_(it)
: aut_(aut), it_(it)
{
}
succ_iterable(succ_iterable&& other)
: aut_(other.aut_), it_(other.it_)
: aut_(other.aut_), it_(other.it_)
{
other.it_ = nullptr;
other.it_ = nullptr;
}
~succ_iterable()
{
if (it_)
aut_->release_iter(it_);
if (it_)
aut_->release_iter(it_);
}
internal::succ_iterator begin()
{
return it_->first() ? it_ : nullptr;
return it_->first() ? it_ : nullptr;
}
internal::succ_iterator end()
{
return nullptr;
return nullptr;
}
};
#endif
@ -682,9 +682,9 @@ namespace spot
void release_iter(twa_succ_iterator* i) const
{
if (iter_cache_)
delete i;
delete i;
else
iter_cache_ = i;
iter_cache_ = i;
}
/// \brief Get the dictionary associated to the automaton.
@ -724,11 +724,11 @@ namespace spot
{
int res = dict_->has_registered_proposition(ap, this);
if (res < 0)
{
aps_.push_back(ap);
res = dict_->register_proposition(ap, this);
bddaps_ &= bdd_ithvar(res);
}
{
aps_.push_back(ap);
res = dict_->register_proposition(ap, this);
bddaps_ &= bdd_ithvar(res);
}
return res;
}
@ -773,7 +773,7 @@ namespace spot
/// or a new \c state* (the projected state) that must be
/// destroyed by the caller.
virtual state* project_state(const state* s,
const const_twa_ptr& t) const;
const const_twa_ptr& t) const;
///@{
/// \brief The acceptance condition of the automaton.
@ -797,10 +797,10 @@ namespace spot
void set_num_sets_(unsigned num)
{
if (num < acc_.num_sets())
{
acc_.~acc_cond();
new (&acc_) acc_cond;
}
{
acc_.~acc_cond();
new (&acc_) acc_cond;
}
acc_.add_sets(num - acc_.num_sets());
}
@ -826,7 +826,7 @@ namespace spot
set_num_sets_(num);
acc_.set_acceptance(c);
if (num == 0)
prop_state_acc(true);
prop_state_acc(true);
}
/// Copy the acceptance condition of another TωA.
@ -835,14 +835,14 @@ namespace spot
acc_ = a->acc();
unsigned num = acc_.num_sets();
if (num == 0)
prop_state_acc(true);
prop_state_acc(true);
}
/// Copy the atomic propositions of another TωA
void copy_ap_of(const const_twa_ptr& a)
{
for (auto f: a->ap())
this->register_ap(f);
this->register_ap(f);
}
/// \brief Set generalized Büchi acceptance
@ -862,7 +862,7 @@ namespace spot
set_num_sets_(num);
acc_.set_generalized_buchi();
if (num == 0)
prop_state_acc(true);
prop_state_acc(true);
}
/// \brief Set Büchi acceptance.
@ -895,8 +895,8 @@ namespace spot
{
trival::repr_t state_based_acc:2; // State-based acceptance.
trival::repr_t inherently_weak:2; // Inherently Weak automaton.
trival::repr_t weak:2; // Weak automaton.
trival::repr_t terminal:2; // Terminal automaton.
trival::repr_t weak:2; // Weak automaton.
trival::repr_t terminal:2; // Terminal automaton.
trival::repr_t deterministic:2; // Deterministic automaton.
trival::repr_t unambiguous:2; // Unambiguous automaton.
trival::repr_t stutter_invariant:2; // Stutter invariant language.
@ -910,8 +910,8 @@ namespace spot
#ifndef SWIG
// Dynamic properties, are given with a name and a destructor function.
std::unordered_map<std::string,
std::pair<void*,
std::function<void(void*)>>> named_prop_;
std::pair<void*,
std::function<void(void*)>>> named_prop_;
#endif
void* get_named_prop_(std::string s) const;
@ -930,7 +930,7 @@ namespace spot
/// When the automaton is destroyed, the \a destructor function will
/// be called to destroy the attached object.
void set_named_prop(std::string s,
void* val, std::function<void(void*)> destructor);
void* val, std::function<void(void*)> destructor);
/// \brief Declare a named property
///
@ -966,7 +966,7 @@ namespace spot
{
void* p = get_named_prop_(s);
if (!p)
return nullptr;
return nullptr;
return static_cast<T*>(p);
}
#endif
@ -979,7 +979,7 @@ namespace spot
{
// Destroy all named properties.
for (auto& np: named_prop_)
np.second.second(np.second.first);
np.second.second(np.second.first);
named_prop_.clear();
}
@ -1036,7 +1036,7 @@ namespace spot
{
is.inherently_weak = val.val();
if (!val)
is.terminal = is.weak = val.val();
is.terminal = is.weak = val.val();
}
/// \brief Whether the automaton is terminal.
@ -1064,7 +1064,7 @@ namespace spot
{
is.terminal = val.val();
if (val)
is.inherently_weak = is.weak = val.val();
is.inherently_weak = is.weak = val.val();
}
/// \brief Whether the automaton is weak.
@ -1091,9 +1091,9 @@ namespace spot
{
is.weak = val.val();
if (val)
is.inherently_weak = val.val();
is.inherently_weak = val.val();
if (!val)
is.terminal = val.val();
is.terminal = val.val();
}
/// \brief Whether the automaton is deterministic.
@ -1122,8 +1122,8 @@ namespace spot
{
is.deterministic = val.val();
if (val)
// deterministic implies unambiguous
is.unambiguous = val.val();
// deterministic implies unambiguous
is.unambiguous = val.val();
}
/// \brief Whether the automaton is unambiguous
@ -1154,7 +1154,7 @@ namespace spot
{
is.unambiguous = val.val();
if (!val)
is.deterministic = val.val();
is.deterministic = val.val();
}
/// \brief Whether the automaton is stutter-invariant.
@ -1215,10 +1215,10 @@ namespace spot
/// \see prop_copy
struct prop_set
{
bool state_based; ///< preserve state-based acceptnace
bool inherently_weak; ///< preserve inherently weak, weak, & terminal
bool deterministic; ///< preserve deterministic and unambiguous
bool stutter_inv; ///< preserve stutter invariance
bool state_based; ///< preserve state-based acceptnace
bool inherently_weak; ///< preserve inherently weak, weak, & terminal
bool deterministic; ///< preserve deterministic and unambiguous
bool stutter_inv; ///< preserve stutter invariance
/// \brief An all-true \c prop_set
///
@ -1237,7 +1237,7 @@ namespace spot
/// algorithm X, in case that new property is not preserved.
static prop_set all()
{
return { true, true, true, true };
return { true, true, true, true };
}
};
@ -1254,20 +1254,20 @@ namespace spot
void prop_copy(const const_twa_ptr& other, prop_set p)
{
if (p.state_based)
prop_state_acc(other->prop_state_acc());
prop_state_acc(other->prop_state_acc());
if (p.inherently_weak)
{
prop_terminal(other->prop_terminal());
prop_weak(other->prop_weak());
prop_inherently_weak(other->prop_inherently_weak());
}
{
prop_terminal(other->prop_terminal());
prop_weak(other->prop_weak());
prop_inherently_weak(other->prop_inherently_weak());
}
if (p.deterministic)
{
prop_deterministic(other->prop_deterministic());
prop_unambiguous(other->prop_unambiguous());
}
{
prop_deterministic(other->prop_deterministic());
prop_unambiguous(other->prop_unambiguous());
}
if (p.stutter_inv)
prop_stutter_invariant(other->prop_stutter_invariant());
prop_stutter_invariant(other->prop_stutter_invariant());
}
/// \brief Keep only a subset of properties of the current
@ -1278,20 +1278,20 @@ namespace spot
void prop_keep(prop_set p)
{
if (!p.state_based)
prop_state_acc(trival::maybe());
prop_state_acc(trival::maybe());
if (!p.inherently_weak)
{
prop_terminal(trival::maybe());
prop_weak(trival::maybe());
prop_inherently_weak(trival::maybe());
}
{
prop_terminal(trival::maybe());
prop_weak(trival::maybe());
prop_inherently_weak(trival::maybe());
}
if (!p.deterministic)
{
prop_deterministic(trival::maybe());
prop_unambiguous(trival::maybe());
}
{
prop_deterministic(trival::maybe());
prop_unambiguous(trival::maybe());
}
if (!p.stutter_inv)
prop_stutter_invariant(trival::maybe());
prop_stutter_invariant(trival::maybe());
}
};

View file

@ -24,21 +24,21 @@ namespace spot
{
void
twa_graph::release_formula_namer(namer<formula>* namer,
bool keep_names)
bool keep_names)
{
if (keep_names)
{
auto v = new std::vector<std::string>(num_states());
auto& n = namer->names();
unsigned ns = n.size();
assert(n.size() <= v->size());
for (unsigned i = 0; i < ns; ++i)
{
auto f = n[i];
if (f)
(*v)[i] = str_psl(f);
}
set_named_prop("state-names", v);
auto v = new std::vector<std::string>(num_states());
auto& n = namer->names();
unsigned ns = n.size();
assert(n.size() <= v->size());
for (unsigned i = 0; i < ns; ++i)
{
auto f = n[i];
if (f)
(*v)[i] = str_psl(f);
}
set_named_prop("state-names", v);
}
delete namer;
}
@ -49,19 +49,19 @@ namespace spot
typedef graph_t::edge_storage_t tr_t;
g_.sort_edges_([](const tr_t& lhs, const tr_t& rhs)
{
if (lhs.src < rhs.src)
return true;
if (lhs.src > rhs.src)
return false;
if (lhs.dst < rhs.dst)
return true;
if (lhs.dst > rhs.dst)
return false;
return lhs.acc < rhs.acc;
// Do not sort on conditions, we'll merge
// them.
});
{
if (lhs.src < rhs.src)
return true;
if (lhs.src > rhs.src)
return false;
if (lhs.dst < rhs.dst)
return true;
if (lhs.dst > rhs.dst)
return false;
return lhs.acc < rhs.acc;
// Do not sort on conditions, we'll merge
// them.
});
auto& trans = this->edge_vector();
unsigned tend = trans.size();
@ -72,30 +72,30 @@ namespace spot
++in;
if (in < tend)
{
++out;
if (out != in)
trans[out] = trans[in];
for (++in; in < tend; ++in)
{
if (trans[in].cond == bddfalse) // Unusable edge
continue;
// Merge edges with the same source, destination, and
// acceptance. (We test the source last, because this is the
// most likely test to be true as edges are ordered by
// sources and then destinations.)
if (trans[out].dst == trans[in].dst
&& trans[out].acc == trans[in].acc
&& trans[out].src == trans[in].src)
{
trans[out].cond |= trans[in].cond;
}
else
{
++out;
if (in != out)
trans[out] = trans[in];
}
}
++out;
if (out != in)
trans[out] = trans[in];
for (++in; in < tend; ++in)
{
if (trans[in].cond == bddfalse) // Unusable edge
continue;
// Merge edges with the same source, destination, and
// acceptance. (We test the source last, because this is the
// most likely test to be true as edges are ordered by
// sources and then destinations.)
if (trans[out].dst == trans[in].dst
&& trans[out].acc == trans[in].acc
&& trans[out].src == trans[in].src)
{
trans[out].cond |= trans[in].cond;
}
else
{
++out;
if (in != out)
trans[out] = trans[in];
}
}
}
if (++out != tend)
trans.resize(out);
@ -109,42 +109,42 @@ namespace spot
// both as Inf and Fin)
if ((in < tend) && !acc().uses_fin_acceptance())
{
typedef graph_t::edge_storage_t tr_t;
g_.sort_edges_([](const tr_t& lhs, const tr_t& rhs)
{
if (lhs.src < rhs.src)
return true;
if (lhs.src > rhs.src)
return false;
if (lhs.dst < rhs.dst)
return true;
if (lhs.dst > rhs.dst)
return false;
return lhs.cond.id() < rhs.cond.id();
// Do not sort on acceptance, we'll merge
// them.
});
typedef graph_t::edge_storage_t tr_t;
g_.sort_edges_([](const tr_t& lhs, const tr_t& rhs)
{
if (lhs.src < rhs.src)
return true;
if (lhs.src > rhs.src)
return false;
if (lhs.dst < rhs.dst)
return true;
if (lhs.dst > rhs.dst)
return false;
return lhs.cond.id() < rhs.cond.id();
// Do not sort on acceptance, we'll merge
// them.
});
for (; in < tend; ++in)
{
// Merge edges with the same source, destination,
// and conditions. (We test the source last, for the
// same reason as above.)
if (trans[out].dst == trans[in].dst
&& trans[out].cond.id() == trans[in].cond.id()
&& trans[out].src == trans[in].src)
{
trans[out].acc |= trans[in].acc;
}
else
{
++out;
if (in != out)
trans[out] = trans[in];
}
}
if (++out != tend)
trans.resize(out);
for (; in < tend; ++in)
{
// Merge edges with the same source, destination,
// and conditions. (We test the source last, for the
// same reason as above.)
if (trans[out].dst == trans[in].dst
&& trans[out].cond.id() == trans[in].cond.id()
&& trans[out].src == trans[in].src)
{
trans[out].acc |= trans[in].acc;
}
else
{
++out;
if (in != out)
trans[out] = trans[in];
}
}
if (++out != tend)
trans.resize(out);
}
g_.chain_edges_();
@ -170,25 +170,25 @@ namespace spot
unsigned todo_pos = 1;
do
{
unsigned cur = todo[--todo_pos] & mask;
todo[todo_pos] ^= cur; // Zero the state
for (auto& t: g_.out(cur))
if (!(todo[t.dst] & seen))
{
todo[t.dst] |= seen;
todo[todo_pos++] |= t.dst;
}
unsigned cur = todo[--todo_pos] & mask;
todo[todo_pos] ^= cur; // Zero the state
for (auto& t: g_.out(cur))
if (!(todo[t.dst] & seen))
{
todo[t.dst] |= seen;
todo[todo_pos++] |= t.dst;
}
}
while (todo_pos > 0);
// Now renumber each used state.
unsigned current = 0;
for (auto& v: todo)
if (!(v & seen))
v = -1U;
v = -1U;
else
v = current++;
v = current++;
if (current == todo.size())
return; // No unreachable state.
return; // No unreachable state.
init_number_ = todo[init_number_];
defrag_states(std::move(todo), current);
}
@ -209,46 +209,46 @@ namespace spot
todo.emplace_back(init_number_, g_.state_storage(init_number_).succ);
do
{
unsigned src;
unsigned tid;
std::tie(src, tid) = todo.back();
if (tid == 0U)
{
todo.pop_back();
order.push_back(src);
continue;
}
auto& t = g_.edge_storage(tid);
todo.back().second = t.next_succ;
unsigned dst = t.dst;
if (useful[dst] != 1)
{
todo.emplace_back(dst, g_.state_storage(dst).succ);
useful[dst] = 1;
}
unsigned src;
unsigned tid;
std::tie(src, tid) = todo.back();
if (tid == 0U)
{
todo.pop_back();
order.push_back(src);
continue;
}
auto& t = g_.edge_storage(tid);
todo.back().second = t.next_succ;
unsigned dst = t.dst;
if (useful[dst] != 1)
{
todo.emplace_back(dst, g_.state_storage(dst).succ);
useful[dst] = 1;
}
}
while (!todo.empty());
// Process states in topological order
for (auto s: order)
{
auto t = g_.out_iteraser(s);
bool useless = true;
while (t)
{
// Erase any edge to a useless state.
if (!useful[t->dst])
{
t.erase();
continue;
}
// if we have a edge to a useful state, then the
// state is useful.
useless = false;
++t;
}
if (useless)
useful[s] = 0;
auto t = g_.out_iteraser(s);
bool useless = true;
while (t)
{
// Erase any edge to a useless state.
if (!useful[t->dst])
{
t.erase();
continue;
}
// if we have a edge to a useful state, then the
// state is useful.
useless = false;
++t;
}
if (useless)
useful[s] = 0;
}
// Make sure the initial state is useful (even if it has been
@ -260,30 +260,30 @@ namespace spot
unsigned current = 0;
for (unsigned s = 0; s < num_states; ++s)
if (useful[s])
useful[s] = current++;
useful[s] = current++;
else
useful[s] = -1U;
useful[s] = -1U;
if (current == num_states)
return; // No useless state.
return; // No useless state.
init_number_ = useful[init_number_];
defrag_states(std::move(useful), current);
}
void twa_graph::defrag_states(std::vector<unsigned>&& newst,
unsigned used_states)
unsigned used_states)
{
auto* names = get_named_prop<std::vector<std::string>>("state-names");
if (names)
{
unsigned size = names->size();
for (unsigned s = 0; s < size; ++s)
{
unsigned dst = newst[s];
if (dst == s || dst == -1U)
continue;
(*names)[dst] = std::move((*names)[s]);
}
names->resize(used_states);
unsigned size = names->size();
for (unsigned s = 0; s < size; ++s)
{
unsigned dst = newst[s];
if (dst == s || dst == -1U)
continue;
(*names)[dst] = std::move((*names)[s]);
}
names->resize(used_states);
}
g_.defrag_states(std::move(newst), used_states);
}

View file

@ -49,16 +49,16 @@ namespace spot
// Do not simply return "other - this", it might not fit in an int.
if (o < this)
return -1;
return -1;
if (o > this)
return 1;
return 1;
return 0;
}
virtual size_t hash() const override
{
return
reinterpret_cast<const char*>(this) - static_cast<const char*>(nullptr);
reinterpret_cast<const char*>(this) - static_cast<const char*>(nullptr);
}
virtual twa_graph_state*
@ -90,9 +90,9 @@ namespace spot
bool operator<(const twa_graph_edge_data& other) const
{
if (cond.id() < other.cond.id())
return true;
return true;
if (cond.id() > other.cond.id())
return false;
return false;
return acc < other.acc;
}
@ -178,7 +178,7 @@ namespace spot
// handle graph_t::state as an abstract type.
typedef unsigned state_num;
static_assert(std::is_same<typename graph_t::state, state_num>::value,
"type mismatch");
"type mismatch");
protected:
graph_t g_;
@ -187,7 +187,7 @@ namespace spot
public:
twa_graph(const bdd_dict_ptr& dict)
: twa(dict),
init_number_(0)
init_number_(0)
{
}
@ -195,9 +195,9 @@ namespace spot
: twa(other->get_dict()),
g_(other->g_), init_number_(other->init_number_)
{
copy_acceptance_of(other);
copy_ap_of(other);
prop_copy(other, p);
copy_acceptance_of(other);
copy_ap_of(other);
prop_copy(other, p);
}
virtual ~twa_graph()
@ -206,13 +206,13 @@ namespace spot
#ifndef SWIG
template <typename State_Name,
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
using namer = named_graph<graph_t, State_Name, Name_Hash, Name_Equal>;
template <typename State_Name,
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
namer<State_Name, Name_Hash, Name_Equal>*
create_namer()
{
@ -263,14 +263,14 @@ namespace spot
state_num get_init_state_number() const
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
const_cast<graph_t&>(g_).new_state();
return init_number_;
}
virtual const twa_graph_state* get_init_state() const override
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
const_cast<graph_t&>(g_).new_state();
return state_from_number(init_number_);
}
@ -282,13 +282,13 @@ namespace spot
assert(!s->succ || g_.valid_trans(s->succ));
if (this->iter_cache_)
{
auto it =
down_cast<twa_graph_succ_iterator<graph_t>*>(this->iter_cache_);
it->recycle(s->succ);
this->iter_cache_ = nullptr;
return it;
}
{
auto it =
down_cast<twa_graph_succ_iterator<graph_t>*>(this->iter_cache_);
it->recycle(s->succ);
this->iter_cache_ = nullptr;
return it;
}
return new twa_graph_succ_iterator<graph_t>(&g_, s->succ);
}
@ -374,18 +374,18 @@ namespace spot
}
unsigned new_edge(unsigned src, unsigned dst,
bdd cond, acc_cond::mark_t acc = 0U)
bdd cond, acc_cond::mark_t acc = 0U)
{
return g_.new_edge(src, dst, cond, acc);
}
unsigned new_acc_edge(unsigned src, unsigned dst,
bdd cond, bool acc = true)
bdd cond, bool acc = true)
{
if (acc)
return g_.new_edge(src, dst, cond, this->acc().all_sets());
return g_.new_edge(src, dst, cond, this->acc().all_sets());
else
return g_.new_edge(src, dst, cond);
return g_.new_edge(src, dst, cond);
}
#ifndef SWIG
@ -445,9 +445,9 @@ namespace spot
{
assert((bool)prop_state_acc() || num_sets() == 0);
for (auto& t: g_.out(s))
// Stop at the first edge, since the remaining should be
// labeled identically.
return t.acc;
// Stop at the first edge, since the remaining should be
// labeled identically.
return t.acc;
return 0U;
}
@ -455,9 +455,9 @@ namespace spot
{
assert((bool)prop_state_acc() || num_sets() == 0);
for (auto& t: g_.out(s))
// Stop at the first edge, since the remaining should be
// labeled identically.
return acc().accepting(t.acc);
// Stop at the first edge, since the remaining should be
// labeled identically.
return acc().accepting(t.acc);
return false;
}
@ -487,19 +487,19 @@ namespace spot
}
inline twa_graph_ptr make_twa_graph(const twa_graph_ptr& aut,
twa::prop_set p)
twa::prop_set p)
{
return std::make_shared<twa_graph>(aut, p);
}
inline twa_graph_ptr make_twa_graph(const const_twa_graph_ptr& aut,
twa::prop_set p)
twa::prop_set p)
{
return std::make_shared<twa_graph>(aut, p);
}
inline twa_graph_ptr make_twa_graph(const const_twa_ptr& aut,
twa::prop_set p)
twa::prop_set p)
{
auto a = std::dynamic_pointer_cast<const twa_graph>(aut);
if (a)

View file

@ -83,58 +83,58 @@ namespace spot
{
public:
twa_succ_iterator_product_common(twa_succ_iterator* left,
twa_succ_iterator* right,
const twa_product* prod,
fixed_size_pool* pool)
: left_(left), right_(right), prod_(prod), pool_(pool)
twa_succ_iterator* right,
const twa_product* prod,
fixed_size_pool* pool)
: left_(left), right_(right), prod_(prod), pool_(pool)
{
}
void recycle(const const_twa_ptr& l, twa_succ_iterator* left,
const_twa_ptr r, twa_succ_iterator* right)
const_twa_ptr r, twa_succ_iterator* right)
{
l->release_iter(left_);
left_ = left;
r->release_iter(right_);
right_ = right;
l->release_iter(left_);
left_ = left;
r->release_iter(right_);
right_ = right;
}
virtual ~twa_succ_iterator_product_common()
{
delete left_;
delete right_;
delete left_;
delete right_;
}
virtual bool next_non_false_() = 0;
bool first()
{
if (!right_)
return false;
if (!right_)
return false;
// If one of the two successor sets is empty initially, we
// reset right_, so that done() can detect this situation
// easily. (We choose to reset right_ because this variable
// is already used by done().)
if (!(left_->first() && right_->first()))
{
delete right_;
right_ = nullptr;
return false;
}
return next_non_false_();
// If one of the two successor sets is empty initially, we
// reset right_, so that done() can detect this situation
// easily. (We choose to reset right_ because this variable
// is already used by done().)
if (!(left_->first() && right_->first()))
{
delete right_;
right_ = nullptr;
return false;
}
return next_non_false_();
}
bool done() const
{
return !right_ || right_->done();
return !right_ || right_->done();
}
const state_product* dst() const
{
return new(pool_->allocate()) state_product(left_->dst(),
right_->dst(),
pool_);
return new(pool_->allocate()) state_product(left_->dst(),
right_->dst(),
pool_);
}
protected:
@ -151,10 +151,10 @@ namespace spot
{
public:
twa_succ_iterator_product(twa_succ_iterator* left,
twa_succ_iterator* right,
const twa_product* prod,
fixed_size_pool* pool)
: twa_succ_iterator_product_common(left, right, prod, pool)
twa_succ_iterator* right,
const twa_product* prod,
fixed_size_pool* pool)
: twa_succ_iterator_product_common(left, right, prod, pool)
{
}
@ -164,46 +164,46 @@ namespace spot
bool step_()
{
if (left_->next())
return true;
left_->first();
return right_->next();
if (left_->next())
return true;
left_->first();
return right_->next();
}
bool next_non_false_()
{
assert(!done());
do
{
bdd l = left_->cond();
bdd r = right_->cond();
bdd current_cond = l & r;
assert(!done());
do
{
bdd l = left_->cond();
bdd r = right_->cond();
bdd current_cond = l & r;
if (current_cond != bddfalse)
{
current_cond_ = current_cond;
return true;
}
}
while (step_());
return false;
if (current_cond != bddfalse)
{
current_cond_ = current_cond;
return true;
}
}
while (step_());
return false;
}
bool next()
{
if (step_())
return next_non_false_();
return false;
if (step_())
return next_non_false_();
return false;
}
bdd cond() const
{
return current_cond_;
return current_cond_;
}
acc_cond::mark_t acc() const
{
return left_->acc() | (right_->acc() << prod_->left_acc().num_sets());
return left_->acc() | (right_->acc() << prod_->left_acc().num_sets());
}
protected:
@ -217,10 +217,10 @@ namespace spot
{
public:
twa_succ_iterator_product_kripke(twa_succ_iterator* left,
twa_succ_iterator* right,
const twa_product* prod,
fixed_size_pool* pool)
: twa_succ_iterator_product_common(left, right, prod, pool)
twa_succ_iterator* right,
const twa_product* prod,
fixed_size_pool* pool)
: twa_succ_iterator_product_common(left, right, prod, pool)
{
}
@ -230,43 +230,43 @@ namespace spot
bool next_non_false_()
{
// All the transitions of left_ iterator have the
// same label, because it is a Kripke structure.
bdd l = left_->cond();
assert(!right_->done());
do
{
bdd r = right_->cond();
bdd current_cond = l & r;
// All the transitions of left_ iterator have the
// same label, because it is a Kripke structure.
bdd l = left_->cond();
assert(!right_->done());
do
{
bdd r = right_->cond();
bdd current_cond = l & r;
if (current_cond != bddfalse)
{
current_cond_ = current_cond;
return true;
}
}
while (right_->next());
return false;
if (current_cond != bddfalse)
{
current_cond_ = current_cond;
return true;
}
}
while (right_->next());
return false;
}
bool next()
{
if (left_->next())
return true;
left_->first();
if (right_->next())
return next_non_false_();
return false;
if (left_->next())
return true;
left_->first();
if (right_->next())
return next_non_false_();
return false;
}
bdd cond() const
{
return current_cond_;
return current_cond_;
}
acc_cond::mark_t acc() const
{
return right_->acc();
return right_->acc();
}
protected:
@ -279,13 +279,13 @@ namespace spot
// twa_product
twa_product::twa_product(const const_twa_ptr& left,
const const_twa_ptr& right)
const const_twa_ptr& right)
: twa(left->get_dict()), left_(left), right_(right),
pool_(sizeof(state_product))
{
if (left->get_dict() != right->get_dict())
throw std::runtime_error("twa_product: left and right automata should "
"share their bdd_dict");
"share their bdd_dict");
assert(get_dict() == right_->get_dict());
// If one of the side is a Kripke structure, it is easier to deal
@ -293,16 +293,16 @@ namespace spot
// computing the successors can be improved a bit).
if (dynamic_cast<const kripke*>(left_.get()))
{
left_kripke_ = true;
left_kripke_ = true;
}
else if (dynamic_cast<const kripke*>(right_.get()))
{
std::swap(left_, right_);
left_kripke_ = true;
std::swap(left_, right_);
left_kripke_ = true;
}
else
{
left_kripke_ = false;
left_kripke_ = false;
}
auto d = get_dict();
@ -329,7 +329,7 @@ namespace spot
{
fixed_size_pool* p = const_cast<fixed_size_pool*>(&pool_);
return new(p->allocate()) state_product(left_->get_init_state(),
right_->get_init_state(), p);
right_->get_init_state(), p);
}
twa_succ_iterator*
@ -342,11 +342,11 @@ namespace spot
if (iter_cache_)
{
twa_succ_iterator_product_common* it =
down_cast<twa_succ_iterator_product_common*>(iter_cache_);
it->recycle(left_, li, right_, ri);
iter_cache_ = nullptr;
return it;
twa_succ_iterator_product_common* it =
down_cast<twa_succ_iterator_product_common*>(iter_cache_);
it->recycle(left_, li, right_, ri);
iter_cache_ = nullptr;
return it;
}
fixed_size_pool* p = const_cast<fixed_size_pool*>(&pool_);
@ -372,8 +372,8 @@ namespace spot
const state_product* s = down_cast<const state_product*>(state);
assert(s);
return (left_->format_state(s->left())
+ " * "
+ right_->format_state(s->right()));
+ " * "
+ right_->format_state(s->right()));
}
state*
@ -393,9 +393,9 @@ namespace spot
// twa_product_init
twa_product_init::twa_product_init(const const_twa_ptr& left,
const const_twa_ptr& right,
const state* left_init,
const state* right_init)
const const_twa_ptr& right,
const state* left_init,
const state* right_init)
: twa_product(left, right),
left_init_(left_init), right_init_(right_init)
{
@ -408,7 +408,7 @@ namespace spot
{
fixed_size_pool* p = const_cast<fixed_size_pool*>(&pool_);
return new(p->allocate()) state_product(left_init_->clone(),
right_init_->clone(), p);
right_init_->clone(), p);
}
}

View file

@ -43,9 +43,9 @@ namespace spot
/// These states are acquired by spot::state_product, and will
/// be destroyed on destruction.
state_product(const state* left,
const state* right,
fixed_size_pool* pool)
: left_(left), right_(right), count_(1), pool_(pool)
const state* right,
fixed_size_pool* pool)
: left_(left), right_(right), count_(1), pool_(pool)
{
}
@ -68,8 +68,8 @@ namespace spot
virtual state_product* clone() const override;
private:
const state* left_; ///< State from the left automaton.
const state* right_; ///< State from the right automaton.
const state* left_; ///< State from the left automaton.
const state* right_; ///< State from the right automaton.
mutable unsigned count_;
fixed_size_pool* pool_;
@ -120,7 +120,7 @@ namespace spot
{
public:
twa_product_init(const const_twa_ptr& left, const const_twa_ptr& right,
const state* left_init, const state* right_init);
const state* left_init, const state* right_init);
virtual const state* get_init_state() const override;
protected:
const state* left_init_;
@ -129,18 +129,18 @@ namespace spot
/// \brief on-the-fly TGBA product
inline twa_product_ptr otf_product(const const_twa_ptr& left,
const const_twa_ptr& right)
const const_twa_ptr& right)
{
return std::make_shared<twa_product>(left, right);
}
/// \brief on-the-fly TGBA product with forced initial states
inline twa_product_ptr otf_product_at(const const_twa_ptr& left,
const const_twa_ptr& right,
const state* left_init,
const state* right_init)
const const_twa_ptr& right,
const state* left_init,
const state* right_init)
{
return std::make_shared<twa_product_init>(left, right,
left_init, right_init);
left_init, right_init);
}
}

View file

@ -116,13 +116,13 @@ namespace spot
trival prop_det = ref_->prop_deterministic();
if (prop_det)
{
ref_deterministic_ = true;
ref_deterministic_ = true;
}
else
{
// Count the number of state even if we know that the
// automaton is non-deterministic, as this can be used to
// decide if two automata are non-isomorphic.
// Count the number of state even if we know that the
// automaton is non-deterministic, as this can be used to
// decide if two automata are non-isomorphic.
nondet_states_ = spot::count_nondet_states(ref_);
ref_deterministic_ = (nondet_states_ == 0);
}
@ -136,12 +136,12 @@ namespace spot
if (ref_deterministic_)
{
if (autdet || (!autdet && spot::is_deterministic(aut)))
return are_isomorphic_det(ref_, aut);
return are_isomorphic_det(ref_, aut);
}
else
{
if (autdet || nondet_states_ != spot::count_nondet_states(aut))
return false;
return false;
}
auto tmp = make_twa_graph(aut, twa::prop_set::all());
@ -159,7 +159,7 @@ namespace spot
bool
isomorphism_checker::are_isomorphic(const const_twa_graph_ptr ref,
const const_twa_graph_ptr aut)
const const_twa_graph_ptr aut)
{
if (trivially_different(ref, aut))
return false;

View file

@ -49,7 +49,7 @@ namespace spot
/// \ingroup twa_misc
/// \brief Check whether two automata are isomorphic.
static bool are_isomorphic(const const_twa_graph_ptr ref,
const const_twa_graph_ptr aut);
const const_twa_graph_ptr aut);
private:
bool is_isomorphic_(const const_twa_graph_ptr aut);

Some files were not shown because too many files have changed in this diff Show more