Introduce AndRat and OrRat operator.

It was a mistake to try to overload And/Or LTL operator for these when
trivial simplification are performed.  The reason is so simple it is
embarassing: And(f,1)=f is a trivial identity that should not be
applied with AndRat.  E.g. AndRat(a;b, 1) is equal to 0, not a;b.

* src/ltlast/multop.hh, src/ltlast/multop.cc: Add the AndRat and OrRat
operators.
* src/ltlparse/ltlparse.yy: Build them.
* src/ltlvisit/mark.cc, src/ltlvisit/simplify.cc,
src/ltlvisit/tostring.cc, src/tgba/formula2bdd.cc,
src/tgbaalgos/eltl2tgba_lacim.cc, src/tgbaalgos/ltl2taa.cc,
src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/ltl2tgba_lacim.cc:
Adjust all switches.
This commit is contained in:
Alexandre Duret-Lutz 2012-04-18 19:20:43 +02:00
parent 35b41331f7
commit 691119c188
11 changed files with 916 additions and 759 deletions

View file

@ -47,11 +47,13 @@ namespace spot
is.accepting_eword = false; is.accepting_eword = false;
case Concat: case Concat:
case AndNLM: case AndNLM:
// Note: AndNLM(p1,p2) is a Boolean formula, but it is case AndRat:
// actually rewritten as And(p1,p2) by trivial identities // Note: AndNLM(p1,p2) and AndRat(p1,p2) are Boolean
// before this constructor is called. So at this point, // formulae, but there are actually rewritten as And(p1,p2)
// AndNLM is always used with at most one Boolean argument, // by trivial identities before this constructor is called.
// and the result is therefore NOT Boolean. // So at this point, AndNLM/AndRat are always used with at
// most one Boolean argument, and the result is therefore
// NOT Boolean.
is.boolean = false; is.boolean = false;
is.ltl_formula = false; is.ltl_formula = false;
is.eltl_formula = false; is.eltl_formula = false;
@ -62,6 +64,18 @@ namespace spot
for (unsigned i = 1; i < s; ++i) for (unsigned i = 1; i < s; ++i)
props &= (*v)[i]->get_props(); props &= (*v)[i]->get_props();
break; break;
case OrRat:
// Note: OrRat(p1,p2) is a Boolean formula, but its is
// actually rewritten as Or(p1,p2) by trivial identities
// before this constructor is called. So at this point,
// AndNLM is always used with at most one Boolean argument,
// and the result is therefore NOT Boolean.
is.boolean = false;
is.ltl_formula = false;
is.eltl_formula = false;
is.psl_formula = false;
is.eventual = false;
is.universal = false;
case Or: case Or:
{ {
bool ew = (*v)[0]->accepts_eword(); bool ew = (*v)[0]->accepts_eword();
@ -159,10 +173,14 @@ namespace spot
{ {
case And: case And:
return "And"; return "And";
case AndRat:
return "AndRat";
case AndNLM: case AndNLM:
return "AndNLM"; return "AndNLM";
case Or: case Or:
return "Or"; return "Or";
case OrRat:
return "OrRat";
case Concat: case Concat:
return "Concat"; return "Concat";
case Fusion: case Fusion:
@ -173,6 +191,37 @@ namespace spot
return 0; return 0;
} }
void
gather_bool(multop::vec* v, multop::type op)
{
// Gather all boolean terms.
multop::vec* b = new multop::vec;
multop::vec::iterator i = v->begin();
while (i != v->end())
{
if ((*i)->is_boolean())
{
b->push_back(*i);
i = v->erase(i);
}
else
{
++i;
}
}
// - AndNLM(Exps1...,Bool1,Exps2...,Bool2,Exps3...) =
// AndNLM(Exps1...,Exps2...,Exps3...,And(Bool1,Bool2))
// - AndRat(Exps1...,Bool1,Exps2...,Bool2,Exps3...) =
// AndRat(Exps1...,Exps2...,Exps3...,And(Bool1,Bool2))
// - OrRat(Exps1...,Bool1,Exps2...,Bool2,Exps3...) =
// AndRat(Exps1...,Exps2...,Exps3...,Or(Bool1,Bool2))
if (!b->empty())
v->push_back(multop::instance(op, b));
else
delete b;
}
multop::map multop::instances; multop::map multop::instances;
// We match equivalent formulae modulo "ACI rules" // We match equivalent formulae modulo "ACI rules"
@ -246,7 +295,15 @@ namespace spot
neutral2 = 0; neutral2 = 0;
abs = constant::false_instance(); abs = constant::false_instance();
abs2 = 0; abs2 = 0;
weak_abs = 0;
break;
case AndRat:
neutral = 0; /* FIXME: we should use 1[*] as neutral */
neutral2 = 0;
abs = constant::false_instance();
abs2 = 0;
weak_abs = constant::empty_word_instance(); weak_abs = constant::empty_word_instance();
gather_bool(v, And);
break; break;
case AndNLM: case AndNLM:
neutral = constant::true_instance(); neutral = constant::true_instance();
@ -254,30 +311,7 @@ namespace spot
abs = constant::false_instance(); abs = constant::false_instance();
abs2 = 0; abs2 = 0;
weak_abs = 0; weak_abs = 0;
gather_bool(v, And);
// Make a first pass to gather all boolean terms.
{
vec* b = new vec;
vec::iterator i = v->begin();
while (i != v->end())
{
if ((*i)->is_boolean())
{
b->push_back(*i);
i = v->erase(i);
}
else
{
++i;
}
}
// - AndNLM(Exps1...,Bool1,Exps2...,Bool2,Exps3...) =
// AndNLM(Exps1...,Exps2...,Exps3...,And(Bool1,Bool2))
if (!b->empty())
v->push_back(instance(And, b));
else
delete b;
}
break; break;
case Or: case Or:
neutral = constant::false_instance(); neutral = constant::false_instance();
@ -286,6 +320,14 @@ namespace spot
abs2 = 0; abs2 = 0;
weak_abs = 0; weak_abs = 0;
break; break;
case OrRat:
neutral = constant::false_instance();
neutral2 = 0;
abs = 0; // FIXME: should be 1[*].
abs2 = 0;
weak_abs = 0;
gather_bool(v, Or);
break;
case Concat: case Concat:
neutral = constant::empty_word_instance(); neutral = constant::empty_word_instance();
neutral2 = 0; neutral2 = 0;
@ -377,8 +419,8 @@ namespace spot
} }
} }
// We have a* & [*0] & c = 0 // We have a* && [*0] && c = 0
// and a* & [*0] & c* = [*0] // and a* && [*0] && c* = [*0]
// So if [*0] has been seen, check if alls term recognize the // So if [*0] has been seen, check if alls term recognize the
// empty word. // empty word.
if (weak_abs_seen) if (weak_abs_seen)

View file

@ -41,7 +41,7 @@ namespace spot
class multop : public ref_formula class multop : public ref_formula
{ {
public: public:
enum type { Or, And, AndNLM, Concat, Fusion }; enum type { Or, OrRat, And, AndRat, AndNLM, Concat, Fusion };
/// List of formulae. /// List of formulae.
typedef std::vector<formula*> vec; typedef std::vector<formula*> vec;
@ -68,24 +68,27 @@ namespace spot
/// has been passed to spot::ltl::multop. Inside the vector, /// has been passed to spot::ltl::multop. Inside the vector,
/// null pointers are ignored. /// null pointers are ignored.
/// ///
/// All operators (Or, And, Concat) are associative, and are /// Most operators (Or, OrRat, And, AndRat, Concat) are
/// automatically inlined. Or and And are commutative, so their /// associative, and are automatically inlined. Or, OrRat, And,
/// argument are also sorted, to ensure that "a & b" is equal to /// and AndRat are commutative, so their arguments are also
/// "b & a". For Or and And, duplicate arguments are also /// sorted, to ensure that "a & b" is equal to "b & a", also
/// removed. /// duplicate arguments are removed.
/// ///
/// Furthermore this function can perform slight optimizations /// Furthermore this function can perform slight optimizations
/// and may not return an ltl::multop object. For instance if /// and may not return an ltl::multop object. For instance if
/// the vector contains only one unique element, this this /// the vector contains only one unique element, this this
/// formula will be returned as-is. Neutral and absorbent element /// formula will be returned as-is. Neutral and absorbent element
/// are also taken care of. The following rewriting are performed /// are also taken care of. The following rewritings are performed
/// (the left patterns are rewritten as shown on the right): /// (the left patterns are rewritten as shown on the right):
/// ///
/// - And(Exps1...,1,Exps2...) = And(Exps1...,Exps2...) /// - And(Exps1...,1,Exps2...) = And(Exps1...,Exps2...)
/// - And(Exps1...,0,Exps2...) = 0 /// - And(Exps1...,0,Exps2...) = 0
/// - And(Exps1...,[*0],Exps2...) = [*0] if all Expi accept [*0]
/// - And(Exps1...,[*0],Exps2...) = 0 if some Expi reject [*0]
/// - And(Exp) = Exp /// - And(Exp) = Exp
/// - AndRat(Exps1...,0,Exps2...) = 0
/// - AndRat(Exps1...,BoolExp1,Exps2...,BoolExps2...) =
/// AndRat(Exps1...,Exps2...,And(BoolExp1,BoolExps2...))
/// - AndRat(Exps1...,[*0],Exps2...) = [*0] if all Expi accept [*0]
/// - AndRat(Exps1...,[*0],Exps2...) = 0 if some Expi reject [*0]
/// - AndNLM(Exps1...,1,Exps2...) = AndNLM(Exps1...,Exps2...) /// - AndNLM(Exps1...,1,Exps2...) = AndNLM(Exps1...,Exps2...)
/// - AndNLM(Exps1...,0,Exps2...) = 0 /// - AndNLM(Exps1...,0,Exps2...) = 0
/// - AndNLM(Exps1...,[*0],Exps2...) = AndNLM(Exps1...,Exps2...) /// - AndNLM(Exps1...,[*0],Exps2...) = AndNLM(Exps1...,Exps2...)
@ -93,8 +96,11 @@ namespace spot
/// - AndNLM(Exps1...,BoolExp1,Exps2...,BoolExp2,Exps3...) = /// - AndNLM(Exps1...,BoolExp1,Exps2...,BoolExp2,Exps3...) =
/// AndNLM(Exps1...,Exps2...,Exps3...,And(BoolExp1,BoolExp2)) /// AndNLM(Exps1...,Exps2...,Exps3...,And(BoolExp1,BoolExp2))
/// - Or(Exps1...,1,Exps2...) = 1 /// - Or(Exps1...,1,Exps2...) = 1
/// - Or(Exps1...,0,Exps2...) = And(Exps1...,Exps2...) /// - Or(Exps1...,0,Exps2...) = Or(Exps1...,Exps2...)
/// - Or(Exp) = Exp /// - Or(Exp) = Exp
/// - OrRat(Exps1...,0,Exps2...) = OrRat(Exps1...,Exps2...)
/// - OrRat(Exps1...,BoolExp1,Exps2...,BoolExps2...) =
/// OrRat(Exps1...,Exps2...,Or(BoolExp1,BoolExps2...))
/// - Concat(Exps1...,0,Exps2...) = 0 /// - Concat(Exps1...,0,Exps2...) = 0
/// - Concat(Exps1...,[*0],Exps2...) = Concat(Exps1...,Exps2...) /// - Concat(Exps1...,[*0],Exps2...) = Concat(Exps1...,Exps2...)
/// - Concat(Exp) = Exp /// - Concat(Exp) = Exp
@ -221,6 +227,26 @@ namespace spot
return is_multop(f, multop::And); return is_multop(f, multop::And);
} }
/// \brief Cast \a f into a multop if it is an AndRat.
///
/// Return 0 otherwise.
inline
multop*
is_AndRat(const formula* f)
{
return is_multop(f, multop::AndRat);
}
/// \brief Cast \a f into a multop if it is an AndNLM.
///
/// Return 0 otherwise.
inline
multop*
is_AndNLM(const formula* f)
{
return is_multop(f, multop::AndNLM);
}
/// \brief Cast \a f into a multop if it is an Or. /// \brief Cast \a f into a multop if it is an Or.
/// ///
/// Return 0 otherwise. /// Return 0 otherwise.
@ -231,6 +257,16 @@ namespace spot
return is_multop(f, multop::Or); return is_multop(f, multop::Or);
} }
/// \brief Cast \a f into a multop if it is an OrRat.
///
/// Return 0 otherwise.
inline
multop*
is_OrRat(const formula* f)
{
return is_multop(f, multop::OrRat);
}
/// \brief Cast \a f into a multop if it is a Concat. /// \brief Cast \a f into a multop if it is a Concat.
/// ///
/// Return 0 otherwise. /// Return 0 otherwise.

View file

@ -354,7 +354,7 @@ sere: booleanatom
$$ = constant::false_instance(); $$ = constant::false_instance();
} }
| sere OP_AND sere | sere OP_AND sere
{ $$ = multop::instance(multop::And, $1, $3); } { $$ = multop::instance(multop::AndRat, $1, $3); }
| sere OP_AND error | sere OP_AND error
{ missing_right_binop($$, $1, @2, { missing_right_binop($$, $1, @2,
"length-matching and operator"); } "length-matching and operator"); }
@ -364,7 +364,7 @@ sere: booleanatom
{ missing_right_binop($$, $1, @2, { missing_right_binop($$, $1, @2,
"non-length-matching and operator"); } "non-length-matching and operator"); }
| sere OP_OR sere | sere OP_OR sere
{ $$ = multop::instance(multop::Or, $1, $3); } { $$ = multop::instance(multop::OrRat, $1, $3); }
| sere OP_OR error | sere OP_OR error
{ missing_right_binop($$, $1, @2, "or operator"); } { missing_right_binop($$, $1, @2, "or operator"); }
| sere OP_CONCAT sere | sere OP_CONCAT sere

View file

@ -1,4 +1,4 @@
// Copyright (C) 2010 Laboratoire de Recherche et Développement // Copyright (C) 2010, 2012 Laboratoire de Recherche et Développement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -89,14 +89,17 @@ namespace spot
multop::vec* res = new multop::vec; multop::vec* res = new multop::vec;
switch (mo->op()) switch (mo->op())
{ {
case multop::Or: case multop::OrRat:
case multop::AndNLM:
case multop::AndRat:
case multop::Concat: case multop::Concat:
case multop::Fusion: case multop::Fusion:
assert(!"unexpected operator");
case multop::Or:
for (unsigned i = 0; i < mos; ++i) for (unsigned i = 0; i < mos; ++i)
res->push_back(recurse(mo->nth(i))); res->push_back(recurse(mo->nth(i)));
break; break;
case multop::And: case multop::And:
case multop::AndNLM:
{ {
typedef std::set<std::pair<formula*, formula*> > pset; typedef std::set<std::pair<formula*, formula*> > pset;
pset Epairs, EMpairs; pset Epairs, EMpairs;
@ -125,10 +128,12 @@ namespace spot
res->push_back(recurse(f)); res->push_back(recurse(f));
break; break;
case binop::EConcat: case binop::EConcat:
assert(mo->op() == multop::And);
Epairs.insert(std::make_pair(bo->first(), Epairs.insert(std::make_pair(bo->first(),
bo->second())); bo->second()));
break; break;
case binop::EConcatMarked: case binop::EConcatMarked:
assert(mo->op() == multop::And);
EMpairs.insert(std::make_pair(bo->first(), EMpairs.insert(std::make_pair(bo->first(),
bo->second())); bo->second()));
break; break;

File diff suppressed because it is too large Load diff

View file

@ -60,8 +60,9 @@ namespace spot
KF, KF,
KG, KG,
KOr, KOr,
KOrRat,
KAnd, KAnd,
KAndLM, KAndRat,
KAndNLM, KAndNLM,
KConcat, KConcat,
KFusion KFusion
@ -89,6 +90,7 @@ namespace spot
"F", "F",
"G", "G",
" | ", " | ",
" | ",
" & ", " & ",
" && ", " && ",
" & ", " & ",
@ -118,6 +120,7 @@ namespace spot
"<>", "<>",
"[]", "[]",
" || ", " || ",
" || ",
" && ", " && ",
" && ", // not supported " && ", // not supported
" & ", // not supported " & ", // not supported
@ -623,8 +626,14 @@ namespace spot
case multop::Or: case multop::Or:
k = KOr; k = KOr;
break; break;
case multop::OrRat:
k = KOrRat;
break;
case multop::And: case multop::And:
k = in_ratexp_ ? KAndLM : KAnd; k = in_ratexp_ ? KAndRat : KAnd;
break;
case multop::AndRat:
k = KAndRat;
break; break;
case multop::AndNLM: case multop::AndNLM:
k = KAndNLM; k = KAndNLM;

View file

@ -1,5 +1,5 @@
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement // Copyright (C) 2009, 2010, 2012 Laboratoire de Recherche et
// de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris // Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Université Pierre et Marie Curie. // Université Pierre et Marie Curie.
@ -152,6 +152,8 @@ namespace spot
case multop::Concat: case multop::Concat:
case multop::Fusion: case multop::Fusion:
case multop::AndNLM: case multop::AndNLM:
case multop::OrRat:
case multop::AndRat:
assert(!"unsupported operator"); assert(!"unsupported operator");
} }
assert(op != -1); assert(op != -1);

View file

@ -1,4 +1,4 @@
// Copyright (C) 2008, 2009, 2010 Laboratoire de Recherche et // Copyright (C) 2008, 2009, 2010, 2012 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -168,6 +168,8 @@ namespace spot
case multop::Concat: case multop::Concat:
case multop::Fusion: case multop::Fusion:
case multop::AndNLM: case multop::AndNLM:
case multop::AndRat:
case multop::OrRat:
assert(!"unsupported operator"); assert(!"unsupported operator");
} }
assert(op != -1); assert(op != -1);

View file

@ -1,5 +1,5 @@
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement // Copyright (C) 2009, 2010, 2012 Laboratoire de Recherche et
// de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -332,6 +332,8 @@ namespace spot
case multop::Concat: case multop::Concat:
case multop::Fusion: case multop::Fusion:
case multop::AndNLM: case multop::AndNLM:
case multop::AndRat:
case multop::OrRat:
assert(!"unsupported operator"); assert(!"unsupported operator");
return; return;
} }

View file

@ -243,6 +243,12 @@ namespace spot
return multop::instance(op, v); return multop::instance(op, v);
} }
formula*
conj_bdd_to_sere(bdd b) const
{
return conj_bdd_to_formula(b, multop::AndRat);
}
formula* formula*
bdd_to_formula(bdd f) bdd_to_formula(bdd f)
{ {
@ -259,6 +265,22 @@ namespace spot
return multop::instance(multop::Or, v); return multop::instance(multop::Or, v);
} }
formula*
bdd_to_sere(bdd f)
{
if (f == bddfalse)
return constant::false_instance();
multop::vec* v = new multop::vec;
minato_isop isop(f);
bdd cube;
while ((cube = isop.next()) != bddfalse)
v->push_back(conj_bdd_to_sere(cube));
return multop::instance(multop::OrRat, v);
}
void void
conj_bdd_to_acc(tgba_explicit_formula* a, bdd b, conj_bdd_to_acc(tgba_explicit_formula* a, bdd b,
state_explicit_formula::transition* t) state_explicit_formula::transition* t)
@ -429,7 +451,7 @@ namespace spot
{ {
bdd label = bdd_exist(cube, dict_.next_set); bdd label = bdd_exist(cube, dict_.next_set);
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set); bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
formula* dest = dict_.conj_bdd_to_formula(dest_bdd); formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
if (dest == constant::empty_word_instance()) if (dest == constant::empty_word_instance())
{ {
out |= label & next_to_concat(); out |= label & next_to_concat();
@ -537,12 +559,12 @@ namespace spot
} }
else else
{ {
// if "f" accepts the empty words, doing the above would // if "f" accepts the empty word, doing the above would
// lead to an infinite loop: // lead to an infinite loop:
// f*;g -> f;f*;g | g // f*;g -> f;f*;g | g
// f;f*;g -> f*;g | ... // f;f*;g -> f*;g | ...
// //
// So we do in two steps: // So we do it in three steps:
// 1. translate f, // 1. translate f,
// 2. append f*;g to all destinations // 2. append f*;g to all destinations
// 3. add |g // 3. add |g
@ -556,8 +578,7 @@ namespace spot
{ {
bdd label = bdd_exist(cube, dict_.next_set); bdd label = bdd_exist(cube, dict_.next_set);
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set); bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
formula* dest = formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
dict_.conj_bdd_to_formula(dest_bdd);
formula* dest2; formula* dest2;
int x; int x;
if (dest == constant::empty_word_instance()) if (dest == constant::empty_word_instance())
@ -623,7 +644,7 @@ namespace spot
{ {
delete non_final; delete non_final;
// (a* & b*);c = (a*|b*);c // (a* & b*);c = (a*|b*);c
formula* f = multop::instance(multop::Or, final); formula* f = multop::instance(multop::OrRat, final);
res_ = recurse_and_concat(f); res_ = recurse_and_concat(f);
f->destroy(); f->destroy();
break; break;
@ -635,7 +656,7 @@ namespace spot
// (F_1 & ... & F_n & N_1 & ... & N_m) // (F_1 & ... & F_n & N_1 & ... & N_m)
// = (F_1 | ... | F_n);[*] && (N_1 & ... & N_m) // = (F_1 | ... | F_n);[*] && (N_1 & ... & N_m)
// | (F_1 | ... | F_n) && (N_1 & ... & N_m);[*] // | (F_1 | ... | F_n) && (N_1 & ... & N_m);[*]
formula* f = multop::instance(multop::Or, final); formula* f = multop::instance(multop::OrRat, final);
formula* n = multop::instance(multop::AndNLM, non_final); formula* n = multop::instance(multop::AndNLM, non_final);
formula* t = bunop::instance(bunop::Star, formula* t = bunop::instance(bunop::Star,
constant::true_instance()); constant::true_instance());
@ -643,9 +664,9 @@ namespace spot
f->clone(), t->clone()); f->clone(), t->clone());
formula* nt = multop::instance(multop::Concat, formula* nt = multop::instance(multop::Concat,
n->clone(), t); n->clone(), t);
formula* ftn = multop::instance(multop::And, ft, n); formula* ftn = multop::instance(multop::AndRat, ft, n);
formula* fnt = multop::instance(multop::And, f, nt); formula* fnt = multop::instance(multop::AndRat, f, nt);
formula* all = multop::instance(multop::Or, ftn, fnt); formula* all = multop::instance(multop::OrRat, ftn, fnt);
res_ = recurse_and_concat(all); res_ = recurse_and_concat(all);
all->destroy(); all->destroy();
break; break;
@ -673,15 +694,15 @@ namespace spot
f, star->clone()); f, star->clone());
conj->push_back(f); conj->push_back(f);
} }
disj->push_back(multop::instance(multop::And, conj)); disj->push_back(multop::instance(multop::AndRat, conj));
} }
star->destroy(); star->destroy();
formula* all = multop::instance(multop::Or, disj); formula* all = multop::instance(multop::OrRat, disj);
res_ = recurse_and_concat(all); res_ = recurse_and_concat(all);
all->destroy(); all->destroy();
break; break;
} }
case multop::And: case multop::AndRat:
{ {
unsigned s = node->size(); unsigned s = node->size();
@ -707,7 +728,7 @@ namespace spot
node->destroy(); node->destroy();
break; break;
} }
case multop::Or: case multop::OrRat:
{ {
res_ = bddfalse; res_ = bddfalse;
unsigned s = node->size(); unsigned s = node->size();
@ -749,7 +770,7 @@ namespace spot
{ {
bdd label = bdd_exist(cube, dict_.next_set); bdd label = bdd_exist(cube, dict_.next_set);
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set); bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
formula* dest = dict_.conj_bdd_to_formula(dest_bdd); formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
if (dest->accepts_eword()) if (dest->accepts_eword())
{ {
@ -786,6 +807,9 @@ namespace spot
tail->destroy(); tail->destroy();
break; break;
} }
case multop::And:
case multop::Or:
assert(!"not a rational operator");
} }
} }
@ -814,10 +838,10 @@ namespace spot
{ {
// static unsigned indent = 0; // static unsigned indent = 0;
// for (unsigned i = indent; i > 0; --i) // for (unsigned i = indent; i > 0; --i)
// std::cerr << "| "; // std::cerr << "| ";
// std::cerr << "translate_ratexp[" << to_string(f); // std::cerr << "translate_ratexp[" << to_string(f);
// if (to_concat) // if (to_concat)
// std::cerr << ", " << to_string(to_concat); // std::cerr << ", " << to_string(to_concat);
// std::cerr << "]" << std::endl; // std::cerr << "]" << std::endl;
// ++indent; // ++indent;
bdd res; bdd res;
@ -839,7 +863,7 @@ namespace spot
} }
// --indent; // --indent;
// for (unsigned i = indent; i > 0; --i) // for (unsigned i = indent; i > 0; --i)
// std::cerr << "| "; // std::cerr << "| ";
// std::cerr << "\\ "; // std::cerr << "\\ ";
// bdd_print_set(std::cerr, dict.dict, res) << std::endl; // bdd_print_set(std::cerr, dict.dict, res) << std::endl;
return res; return res;
@ -891,7 +915,7 @@ namespace spot
all_props -= label; all_props -= label;
const formula* dest = const formula* dest =
dict_.bdd_to_formula(bdd_exist(res & label, dict_.var_set)); dict_.bdd_to_sere(bdd_exist(res & label, dict_.var_set));
f2a_t::const_iterator i = f2a_.find(dest); f2a_t::const_iterator i = f2a_.find(dest);
if (i != f2a_.end() && i->second == 0) if (i != f2a_.end() && i->second == 0)
@ -1218,8 +1242,7 @@ namespace spot
all_props -= label; all_props -= label;
formula* dest = formula* dest =
dict_.bdd_to_formula(bdd_exist(f1 & label, dict_.bdd_to_sere(bdd_exist(f1 & label, dict_.var_set));
dict_.var_set));
// !{ Exp } is false if Exp accepts the empty word. // !{ Exp } is false if Exp accepts the empty word.
if (dest->accepts_eword()) if (dest->accepts_eword())
@ -1347,8 +1370,8 @@ namespace spot
all_props -= label; all_props -= label;
formula* dest = formula* dest =
dict_.bdd_to_formula(bdd_exist(f1 & label, dict_.bdd_to_sere(bdd_exist(f1 & label,
dict_.var_set)); dict_.var_set));
const formula* dest2 = const formula* dest2 =
binop::instance(op, dest, node->second()->clone()); binop::instance(op, dest, node->second()->clone());
@ -1371,7 +1394,7 @@ namespace spot
{ {
bdd label = bdd_exist(cube, dict_.next_set); bdd label = bdd_exist(cube, dict_.next_set);
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set); bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
formula* dest = dict_.conj_bdd_to_formula(dest_bdd); formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
if (dest == constant::empty_word_instance()) if (dest == constant::empty_word_instance())
{ {
@ -1420,7 +1443,7 @@ namespace spot
{ {
bdd label = bdd_exist(cube, dict_.next_set); bdd label = bdd_exist(cube, dict_.next_set);
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set); bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
formula* dest = dict_.conj_bdd_to_formula(dest_bdd); formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
formula* dest2 = formula* dest2 =
binop::instance(op, dest, node->second()->clone()); binop::instance(op, dest, node->second()->clone());
@ -1478,6 +1501,8 @@ namespace spot
case multop::Concat: case multop::Concat:
case multop::Fusion: case multop::Fusion:
case multop::AndNLM: case multop::AndNLM:
case multop::AndRat:
case multop::OrRat:
assert(!"Not an LTL operator"); assert(!"Not an LTL operator");
break; break;
} }
@ -1699,7 +1724,7 @@ namespace spot
// std::cerr << "Marked: " << t.has_marked << std::endl; // std::cerr << "Marked: " << t.has_marked << std::endl;
// std::cerr << "Mark all: " << !f->is_marked() << std::endl; // std::cerr << "Mark all: " << !f->is_marked() << std::endl;
// std::cerr << "Transitions:" << std::endl; // std::cerr << "Transitions:" << std::endl;
// trace_ltl_bdd(v_.get_dict(), t.symbolic); // trace_ltl_bdd(d_, t.symbolic);
// std::cerr << "-----" << std::endl; // std::cerr << "-----" << std::endl;
if (t.has_rational) if (t.has_rational)

View file

@ -1,7 +1,8 @@
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement // -*- coding: utf-8 -*-
// de l'Epita (LRDE). // Copyright (C) 2009, 2010, 2012 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -103,7 +104,7 @@ namespace spot
/* /*
`x | next', doesn't actually encode the fact that x `x | next', doesn't actually encode the fact that x
should be fulfilled eventually. We ensure this by should be fulfilled eventually. We ensure this by
creating a new generalized Büchi acceptance set, Acc[x], creating a new generalized Büchi acceptance set, Acc[x],
and leave out of this set any transition going off NOW and leave out of this set any transition going off NOW
without checking X. Such acceptance conditions are without checking X. Such acceptance conditions are
checked for during the emptiness check. checked for during the emptiness check.
@ -266,6 +267,8 @@ namespace spot
case multop::Concat: case multop::Concat:
case multop::Fusion: case multop::Fusion:
case multop::AndNLM: case multop::AndNLM:
case multop::AndRat:
case multop::OrRat:
assert(!"unsupported operator"); assert(!"unsupported operator");
} }
assert(op != -1); assert(op != -1);