Commit 94cca9de authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

acc_cond: rename is_tt/is_ff as is_t/is_f and add printer

* spot/twa/acc.cc, spot/twa/acc.hh: Here.
* spot/parseaut/parseaut.yy, spot/twa/acc.hh,
spot/twaalgos/gtec/gtec.cc, spot/twaalgos/hoa.cc,
spot/twaalgos/neverclaim.cc, spot/twaalgos/product.cc,
spot/twaalgos/remfin.cc, spot/twaalgos/strength.cc: Adjust.
* NEWS: Mention the changes.
* wrap/python/spot_impl.i: Bind acc_cond the printer.
* wrap/python/tests/acc_cond.ipynb: Add more examples.
parent 2927cf38
...@@ -37,17 +37,22 @@ New in spot 1.99.6a (not yet released) ...@@ -37,17 +37,22 @@ New in spot 1.99.6a (not yet released)
shift_left() have been replaced by operators |=, &=, <<=, and for shift_left() have been replaced by operators |=, &=, <<=, and for
completeness the operators |, &, and << have been added. completeness the operators |, &, and << have been added.
* Several methods have been removed from the acc_cond class because * Several methods have been removed from the acc_cond
they were simply redundant with the methods of acc_cond::mark_t, class because they were simply redundant with the methods of
and more complex to use. acc_cond::mark_t, and more complex to use.
acc_cond::marks(...) -> use acc_cond::mark_t(...) directly acc_cond::marks(...) -> use acc_cond::mark_t(...)
acc_cond::sets(m) -> use m.sets() acc_cond::sets(m) -> use m.sets()
acc_cond::has(m, u) -> use m.has(u) directly acc_cond::has(m, u) -> use m.has(u)
acc_cond::cup(l, r) -> use l | r acc_cond::cup(l, r) -> use l | r
acc_cond::cap(l, r) -> use l & r acc_cond::cap(l, r) -> use l & r
acc_cond::set_minus(l, r) -> use l - r acc_cond::set_minus(l, r) -> use l - r
Additionally, the following methods have been renamed:
acc_cond::is_tt() -> acc_cond::is_t()
acc_cond::is_ff() -> acc_cond::is_f()
Python: Python:
* Iterating over the transitions leaving a state (the * Iterating over the transitions leaving a state (the
......
...@@ -572,7 +572,7 @@ header-item: "States:" INT ...@@ -572,7 +572,7 @@ header-item: "States:" INT
res.ignore_more_acc = true; res.ignore_more_acc = true;
// Not setting the acceptance in case of error will // Not setting the acceptance in case of error will
// force it to be true. // force it to be true.
if (res.opts.want_kripke && (!$4->is_tt() || $2 > 0)) if (res.opts.want_kripke && (!$4->is_t() || $2 > 0))
error(@2 + @4, error(@2 + @4,
"the acceptance for Kripke structure must be '0 t'"); "the acceptance for Kripke structure must be '0 t'");
else else
......
...@@ -51,6 +51,11 @@ namespace spot ...@@ -51,6 +51,11 @@ namespace spot
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const acc_cond& acc)
{
return os << '(' << acc.num_sets() << ", " << acc.get_acceptance() << ')';
}
namespace namespace
{ {
void default_set_printer(std::ostream& os, int v) void default_set_printer(std::ostream& os, int v)
...@@ -411,9 +416,9 @@ namespace spot ...@@ -411,9 +416,9 @@ namespace spot
int acc_cond::is_rabin() const int acc_cond::is_rabin() const
{ {
if (code_.is_ff()) if (code_.is_f())
return num_ == 0 ? 0 : -1; return num_ == 0 ? 0 : -1;
if ((num_ & 1) || code_.is_tt()) if ((num_ & 1) || code_.is_t())
return -1; return -1;
if (is_rs(code_, acc_op::Or, acc_op::And, all_sets())) if (is_rs(code_, acc_op::Or, acc_op::And, all_sets()))
...@@ -424,9 +429,9 @@ namespace spot ...@@ -424,9 +429,9 @@ namespace spot
int acc_cond::is_streett() const int acc_cond::is_streett() const
{ {
if (code_.is_tt()) if (code_.is_t())
return num_ == 0 ? 0 : -1; return num_ == 0 ? 0 : -1;
if ((num_ & 1) || code_.is_ff()) if ((num_ & 1) || code_.is_f())
return -1; return -1;
if (is_rs(code_, acc_op::And, acc_op::Or, all_sets())) if (is_rs(code_, acc_op::And, acc_op::Or, all_sets()))
...@@ -444,7 +449,7 @@ namespace spot ...@@ -444,7 +449,7 @@ namespace spot
pairs.resize(num_); pairs.resize(num_);
return true; return true;
} }
if (code_.is_tt() if (code_.is_t()
|| code_.back().op != acc_op::Or) || code_.back().op != acc_op::Or)
return false; return false;
...@@ -670,7 +675,7 @@ namespace spot ...@@ -670,7 +675,7 @@ namespace spot
if (sets == 0) if (sets == 0)
{ {
max = true; max = true;
odd = is_tt(); odd = is_t();
return true; return true;
} }
acc_cond::mark_t u_inf; acc_cond::mark_t u_inf;
...@@ -857,7 +862,7 @@ namespace spot ...@@ -857,7 +862,7 @@ namespace spot
std::pair<bool, acc_cond::mark_t> std::pair<bool, acc_cond::mark_t>
acc_cond::unsat_mark() const acc_cond::unsat_mark() const
{ {
if (is_tt()) if (is_t())
return {false, 0U}; return {false, 0U};
if (!uses_fin_acceptance()) if (!uses_fin_acceptance())
return {true, 0U}; return {true, 0U};
...@@ -1105,7 +1110,7 @@ namespace spot ...@@ -1105,7 +1110,7 @@ namespace spot
acc_cond::acc_code acc_cond::acc_code::complement() const acc_cond::acc_code acc_cond::acc_code::complement() const
{ {
if (is_tt()) if (is_t())
return acc_cond::acc_code::f(); return acc_cond::acc_code::f();
return complement_rec(&back()); return complement_rec(&back());
} }
...@@ -1165,7 +1170,7 @@ namespace spot ...@@ -1165,7 +1170,7 @@ namespace spot
acc_cond::acc_code acc_cond::acc_code
acc_cond::acc_code::strip(acc_cond::mark_t rem, bool missing) const acc_cond::acc_code::strip(acc_cond::mark_t rem, bool missing) const
{ {
if (is_tt() || is_ff()) if (is_t() || is_f())
return *this; return *this;
return strip_rec(&back(), rem, missing); return strip_rec(&back(), rem, missing);
} }
...@@ -1173,7 +1178,7 @@ namespace spot ...@@ -1173,7 +1178,7 @@ namespace spot
acc_cond::mark_t acc_cond::mark_t
acc_cond::acc_code::used_sets() const acc_cond::acc_code::used_sets() const
{ {
if (is_tt() || is_ff()) if (is_t() || is_f())
return 0U; return 0U;
acc_cond::mark_t used_in_cond = 0U; acc_cond::mark_t used_in_cond = 0U;
auto pos = &back(); auto pos = &back();
...@@ -1201,7 +1206,7 @@ namespace spot ...@@ -1201,7 +1206,7 @@ namespace spot
std::pair<acc_cond::mark_t, acc_cond::mark_t> std::pair<acc_cond::mark_t, acc_cond::mark_t>
acc_cond::acc_code::used_inf_fin_sets() const acc_cond::acc_code::used_inf_fin_sets() const
{ {
if (is_tt() || is_ff()) if (is_t() || is_f())
return {0U, 0U}; return {0U, 0U};
acc_cond::mark_t used_fin = 0U; acc_cond::mark_t used_fin = 0U;
......
...@@ -395,14 +395,14 @@ namespace spot ...@@ -395,14 +395,14 @@ namespace spot
return !(*this == other); return !(*this == other);
} }
bool is_tt() const bool is_t() const
{ {
unsigned s = size(); unsigned s = size();
return s == 0 return s == 0
|| ((*this)[s - 1].op == acc_op::Inf && (*this)[s - 2].mark == 0U); || ((*this)[s - 1].op == acc_op::Inf && (*this)[s - 2].mark == 0U);
} }
bool is_ff() const bool is_f() const
{ {
unsigned s = size(); unsigned s = size();
return s > 1 return s > 1
...@@ -557,12 +557,12 @@ namespace spot ...@@ -557,12 +557,12 @@ namespace spot
acc_code& operator&=(acc_code&& r) acc_code& operator&=(acc_code&& r)
{ {
if (is_tt() || r.is_ff()) if (is_t() || r.is_f())
{ {
*this = std::move(r); *this = std::move(r);
return *this; return *this;
} }
if (is_ff() || r.is_tt()) if (is_f() || r.is_t())
return *this; return *this;
unsigned s = size() - 1; unsigned s = size() - 1;
unsigned rs = r.size() - 1; unsigned rs = r.size() - 1;
...@@ -649,12 +649,12 @@ namespace spot ...@@ -649,12 +649,12 @@ namespace spot
acc_code& operator&=(const acc_code& r) acc_code& operator&=(const acc_code& r)
{ {
if (is_tt() || r.is_ff()) if (is_t() || r.is_f())
{ {
*this = r; *this = r;
return *this; return *this;
} }
if (is_ff() || r.is_tt()) if (is_f() || r.is_t())
return *this; return *this;
unsigned s = size() - 1; unsigned s = size() - 1;
unsigned rs = r.size() - 1; unsigned rs = r.size() - 1;
...@@ -754,9 +754,9 @@ namespace spot ...@@ -754,9 +754,9 @@ namespace spot
acc_code& operator|=(acc_code&& r) acc_code& operator|=(acc_code&& r)
{ {
if (is_tt() || r.is_ff()) if (is_t() || r.is_f())
return *this; return *this;
if (is_ff() || r.is_tt()) if (is_f() || r.is_t())
{ {
*this = std::move(r); *this = std::move(r);
return *this; return *this;
...@@ -930,14 +930,24 @@ namespace spot ...@@ -930,14 +930,24 @@ namespace spot
return uses_fin_acceptance_; return uses_fin_acceptance_;
} }
bool is_tt() const bool is_t() const
{ {
return code_.is_tt(); return code_.is_t();
} }
bool is_ff() const bool is_all() const
{ {
return code_.is_ff(); return num_ == 0 && is_t();
}
bool is_f() const
{
return code_.is_f();
}
bool is_none() const
{
return num_ == 0 && is_f();
} }
bool is_buchi() const bool is_buchi() const
...@@ -1158,6 +1168,7 @@ namespace spot ...@@ -1158,6 +1168,7 @@ namespace spot
mark_t::value_t all_; mark_t::value_t all_;
acc_code code_; acc_code code_;
bool uses_fin_acceptance_ = false; bool uses_fin_acceptance_ = false;
}; };
/// \brief Parse a string into an acc_code /// \brief Parse a string into an acc_code
...@@ -1179,6 +1190,9 @@ namespace spot ...@@ -1179,6 +1190,9 @@ namespace spot
/// ///
/// A spot::parse_error is thrown on syntax error. /// A spot::parse_error is thrown on syntax error.
SPOT_API acc_cond::acc_code parse_acc_code(const char* input); SPOT_API acc_cond::acc_code parse_acc_code(const char* input);
SPOT_API
std::ostream& operator<<(std::ostream& os, const acc_cond& acc);
} }
namespace std namespace std
......
...@@ -133,7 +133,7 @@ namespace spot ...@@ -133,7 +133,7 @@ namespace spot
{ {
{ {
auto acc = ecs_->aut->acc(); auto acc = ecs_->aut->acc();
if (acc.get_acceptance().is_ff()) if (acc.get_acceptance().is_f())
return nullptr; return nullptr;
if (acc.uses_fin_acceptance()) if (acc.uses_fin_acceptance())
throw std::runtime_error throw std::runtime_error
...@@ -395,7 +395,7 @@ namespace spot ...@@ -395,7 +395,7 @@ namespace spot
{ {
{ {
auto acc = ecs_->aut->acc(); auto acc = ecs_->aut->acc();
if (acc.get_acceptance().is_ff()) if (acc.get_acceptance().is_f())
return nullptr; return nullptr;
if (acc.uses_fin_acceptance()) if (acc.uses_fin_acceptance())
throw std::runtime_error throw std::runtime_error
......
...@@ -313,7 +313,7 @@ namespace spot ...@@ -313,7 +313,7 @@ namespace spot
acc_cond::acc_code acc_c = aut->acc().get_acceptance(); acc_cond::acc_code acc_c = aut->acc().get_acceptance();
if (aut->acc().is_generalized_buchi()) if (aut->acc().is_generalized_buchi())
{ {
if (aut->acc().is_tt()) if (aut->acc().is_all())
os << "acc-name: all"; os << "acc-name: all";
else if (aut->acc().is_buchi()) else if (aut->acc().is_buchi())
os << "acc-name: Buchi"; os << "acc-name: Buchi";
...@@ -323,7 +323,7 @@ namespace spot ...@@ -323,7 +323,7 @@ namespace spot
} }
else if (aut->acc().is_generalized_co_buchi()) else if (aut->acc().is_generalized_co_buchi())
{ {
if (aut->acc().is_ff()) if (aut->acc().is_none())
os << "acc-name: none"; os << "acc-name: none";
else if (aut->acc().is_co_buchi()) else if (aut->acc().is_co_buchi())
os << "acc-name: co-Buchi"; os << "acc-name: co-Buchi";
......
...@@ -205,7 +205,7 @@ namespace spot ...@@ -205,7 +205,7 @@ namespace spot
print_never_claim(std::ostream& os, const const_twa_ptr& g, print_never_claim(std::ostream& os, const const_twa_ptr& g,
const char* options) const char* options)
{ {
if (!(g->acc().is_buchi() || g->acc().is_tt())) if (!(g->acc().is_buchi() || g->acc().is_all()))
throw std::runtime_error throw std::runtime_error
("Never claim output only supports Büchi acceptance"); ("Never claim output only supports Büchi acceptance");
never_claim_output d(os, options); never_claim_output d(os, options);
......
...@@ -80,7 +80,7 @@ namespace spot ...@@ -80,7 +80,7 @@ namespace spot
}; };
res->set_init_state(new_state(left_state, right_state)); res->set_init_state(new_state(left_state, right_state));
if (right_acc.is_ff()) if (right_acc.is_f())
// Do not bother doing any work if the resulting acceptance is // Do not bother doing any work if the resulting acceptance is
// false. // false.
return res; return res;
......
...@@ -312,7 +312,7 @@ namespace spot ...@@ -312,7 +312,7 @@ namespace spot
auto code = aut->get_acceptance(); auto code = aut->get_acceptance();
if (code.is_tt()) if (code.is_t())
return nullptr; return nullptr;
acc_cond::mark_t inf_pairs = 0U; acc_cond::mark_t inf_pairs = 0U;
...@@ -640,7 +640,7 @@ namespace spot ...@@ -640,7 +640,7 @@ namespace spot
auto c = acc.inf(m); auto c = acc.inf(m);
for (unsigned i = 0; i < sz; ++i) for (unsigned i = 0; i < sz; ++i)
{ {
if (!code[i].is_tt()) if (!code[i].is_t())
continue; continue;
add[i] = m; add[i] = m;
code[i] &= std::move(c); code[i] &= std::move(c);
......
...@@ -126,7 +126,7 @@ namespace spot ...@@ -126,7 +126,7 @@ namespace spot
bool is_safety_mwdba(const const_twa_graph_ptr& aut) bool is_safety_mwdba(const const_twa_graph_ptr& aut)
{ {
if (!(aut->acc().is_buchi() || aut->acc().is_tt())) if (!(aut->acc().is_buchi() || aut->acc().is_all()))
throw std::runtime_error throw std::runtime_error
("is_safety_mwdba() should be called on a Buchi automaton"); ("is_safety_mwdba() should be called on a Buchi automaton");
......
...@@ -485,19 +485,35 @@ namespace std { ...@@ -485,19 +485,35 @@ namespace std {
return new spot::acc_cond::mark_t(f.begin(), f.end()); return new spot::acc_cond::mark_t(f.begin(), f.end());
} }
std::string __repr__()
{
std::ostringstream os;
os << *self;
return os.str();
}
std::string __str__() std::string __str__()
{ {
std::ostringstream os; std::ostringstream os;
os << *self; os << *self;
return os.str(); return os.str();
} }
}
%extend spot::acc_cond {
std::string __repr__() std::string __repr__()
{ {
std::ostringstream os; std::ostringstream os;
os << *self; os << *self;
return os.str(); return os.str();
} }
std::string __str__()
{
std::ostringstream os;
os << *self;
return os.str();
}
} }
%extend spot::twa_run { %extend spot::twa_run {
......
{ {
"metadata": { "metadata": {
"name": "", "kernelspec": {
"signature": "sha256:f11212c3a17ce302ae81974af32b21c1ebda4aa54d8930f03787ce7ed1c9e5f5" "display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.4.3+"
},
"name": ""
}, },
"nbformat": 3, "nbformat": 3,
"nbformat_minor": 0, "nbformat_minor": 0,
...@@ -920,7 +936,7 @@ ...@@ -920,7 +936,7 @@
"output_type": "pyout", "output_type": "pyout",
"prompt_number": 34, "prompt_number": 34,
"text": [ "text": [
"<spot_impl.acc_cond; proxy of <Swig Object of type 'spot::acc_cond *' at 0x7f19407487e0> >" "(4, (Fin(0) & Inf(1)) | (Fin(2) & Inf(3)))"
] ]
} }
], ],
...@@ -970,17 +986,176 @@ ...@@ -970,17 +986,176 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"To be continued..." "The `acc_cond` object can also be constructed using only a number of sets. In that case, the acceptance condition defaults to `t`, and it can be changed to something else later (using `set_acceptance()`). The number of acceptance sets can also be augmented with `add_sets()`."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"collapsed": false, "collapsed": false,
"input": [
"acc = spot.acc_cond(4)\n",
"acc"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 37,
"text": [
"(4, t)"
]
}
],
"prompt_number": 37
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"acc.add_sets(2)\n",
"acc"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 38,
"text": [
"(6, t)"
]
}
],
"prompt_number": 38
},
{
"cell_type": "code",
"collapsed": false,
"input": [