Translate Boolean formulae as BDD using the ltl_simplifier cache.
* src/ltlvisit/simplify.hh, src/ltlvisit/simplify.cc (ltl_simplifier::ltl_simplifier, ltl_simplifier::get_dict): Make it possible to supply and retrieve the dictionary used. (ltl_simplifier::as_bdd): New function, exported from the cache. * src/tgbaalgos/ltl2tgba_fm.cc (translate_dict): Store the ltl_simplifier object. (translate_dict::boolean_to_bdd): Call ltl_simplifier::as_bdd. (translate_ratexp): New wrapper around the ratexp_trad_visitor, calling boolean_to_bdd whenever possible. (ratexp_trad_visitor): Do not deal with negated formulae, there are necessarily Boolean and handled by translate_ratexp(). (ltl_visitor): Adjust to call translate_ratexp. (ltl_to_tgba_fm): Adjust passing of the ltl_simplifier to the translate_dict, and make sure everybody is using the same dictionary. * src/tgbatest/ltl2tgba.cc: Pass the dictionary to the ltl_simplifier.
This commit is contained in:
parent
369ad87e50
commit
07e40e706a
4 changed files with 149 additions and 77 deletions
|
|
@ -26,10 +26,8 @@
|
||||||
#define trace while (0) std::cerr
|
#define trace while (0) std::cerr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "simplify.hh"
|
#include "simplify.hh"
|
||||||
#include "misc/hash.hh"
|
#include "misc/hash.hh"
|
||||||
#include "tgba/bdddict.hh"
|
|
||||||
#include "ltlast/allnodes.hh"
|
#include "ltlast/allnodes.hh"
|
||||||
#include "ltlast/visitor.hh"
|
#include "ltlast/visitor.hh"
|
||||||
#include "ltlvisit/contain.hh"
|
#include "ltlvisit/contain.hh"
|
||||||
|
|
@ -52,7 +50,7 @@ namespace spot
|
||||||
typedef std::pair<const formula*, const formula*> pairf;
|
typedef std::pair<const formula*, const formula*> pairf;
|
||||||
typedef std::map<pairf, bool> syntimpl_cache_t;
|
typedef std::map<pairf, bool> syntimpl_cache_t;
|
||||||
public:
|
public:
|
||||||
bdd_dict dict;
|
bdd_dict* dict;
|
||||||
ltl_simplifier_options options;
|
ltl_simplifier_options options;
|
||||||
language_containment_checker lcc;
|
language_containment_checker lcc;
|
||||||
|
|
||||||
|
|
@ -98,16 +96,16 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_.unregister_all_my_variables(this);
|
dict->unregister_all_my_variables(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ltl_simplifier_cache()
|
ltl_simplifier_cache(bdd_dict* d)
|
||||||
: lcc(&dict, true, true, false, false)
|
: dict(d), lcc(d, true, true, false, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ltl_simplifier_cache(ltl_simplifier_options opt)
|
ltl_simplifier_cache(bdd_dict* d, ltl_simplifier_options opt)
|
||||||
: options(opt), lcc(&dict, true, true, false, false)
|
: dict(d), options(opt), lcc(d, true, true, false, false)
|
||||||
{
|
{
|
||||||
opt.containment_checks |= opt.containment_checks_stronger;
|
opt.containment_checks |= opt.containment_checks_stronger;
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +132,7 @@ namespace spot
|
||||||
assert(!"Unsupported operator");
|
assert(!"Unsupported operator");
|
||||||
break;
|
break;
|
||||||
case formula::AtomicProp:
|
case formula::AtomicProp:
|
||||||
result = bdd_ithvar(dict_.register_proposition(f, this));
|
result = bdd_ithvar(dict->register_proposition(f, this));
|
||||||
break;
|
break;
|
||||||
case formula::UnOp:
|
case formula::UnOp:
|
||||||
{
|
{
|
||||||
|
|
@ -185,9 +183,9 @@ namespace spot
|
||||||
result |= as_bdd(mo->nth(n));
|
result |= as_bdd(mo->nth(n));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case multop::AndNLM:
|
||||||
case multop::Concat:
|
case multop::Concat:
|
||||||
case multop::Fusion:
|
case multop::Fusion:
|
||||||
case multop::AndNLM:
|
|
||||||
assert(!"Unsupported operator");
|
assert(!"Unsupported operator");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -328,7 +326,6 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bdd_dict dict_;
|
|
||||||
f2b_map as_bdd_;
|
f2b_map as_bdd_;
|
||||||
f2f_map simplified_;
|
f2f_map simplified_;
|
||||||
f2f_map nenoform_;
|
f2f_map nenoform_;
|
||||||
|
|
@ -2592,19 +2589,42 @@ namespace spot
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// ltl_simplifier
|
// ltl_simplifier
|
||||||
|
|
||||||
ltl_simplifier::ltl_simplifier()
|
ltl_simplifier::ltl_simplifier(bdd_dict* d)
|
||||||
: cache_(new ltl_simplifier_cache)
|
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
{
|
||||||
|
d = new bdd_dict;
|
||||||
|
owndict = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
owndict = false;
|
||||||
|
}
|
||||||
|
cache_ = new ltl_simplifier_cache(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
ltl_simplifier::ltl_simplifier(ltl_simplifier_options& opt)
|
ltl_simplifier::ltl_simplifier(ltl_simplifier_options& opt, bdd_dict* d)
|
||||||
: cache_(new ltl_simplifier_cache(opt))
|
|
||||||
{
|
{
|
||||||
|
if (!d)
|
||||||
|
{
|
||||||
|
d = new bdd_dict;
|
||||||
|
owndict = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
owndict = false;
|
||||||
|
}
|
||||||
|
cache_ = new ltl_simplifier_cache(d, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
ltl_simplifier::~ltl_simplifier()
|
ltl_simplifier::~ltl_simplifier()
|
||||||
{
|
{
|
||||||
|
bdd_dict* todelete = 0;
|
||||||
|
if (owndict)
|
||||||
|
todelete = cache_->dict;
|
||||||
delete cache_;
|
delete cache_;
|
||||||
|
// It has to be deleted after the cache.
|
||||||
|
delete todelete;
|
||||||
}
|
}
|
||||||
|
|
||||||
formula*
|
formula*
|
||||||
|
|
@ -2644,5 +2664,17 @@ namespace spot
|
||||||
return cache_->lcc.equal(f, g);
|
return cache_->lcc.equal(f, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdd
|
||||||
|
ltl_simplifier::as_bdd(const formula* f)
|
||||||
|
{
|
||||||
|
return cache_->as_bdd(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
bdd_dict*
|
||||||
|
ltl_simplifier::get_dict() const
|
||||||
|
{
|
||||||
|
return cache_->dict;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "ltlast/formula.hh"
|
#include "ltlast/formula.hh"
|
||||||
#include "bdd.h"
|
#include "bdd.h"
|
||||||
|
#include "tgba/bdddict.hh"
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
|
@ -66,8 +67,8 @@ namespace spot
|
||||||
class ltl_simplifier
|
class ltl_simplifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ltl_simplifier();
|
ltl_simplifier(bdd_dict* dict = 0);
|
||||||
ltl_simplifier(ltl_simplifier_options& opt);
|
ltl_simplifier(ltl_simplifier_options& opt, bdd_dict* dict = 0);
|
||||||
~ltl_simplifier();
|
~ltl_simplifier();
|
||||||
|
|
||||||
/// Simplify the formula \a f (using options supplied to the
|
/// Simplify the formula \a f (using options supplied to the
|
||||||
|
|
@ -118,11 +119,20 @@ namespace spot
|
||||||
/// two products, and two emptiness checks.
|
/// two products, and two emptiness checks.
|
||||||
bool are_equivalent(const formula* f, const formula* g);
|
bool are_equivalent(const formula* f, const formula* g);
|
||||||
|
|
||||||
|
/// \brief Convert a Boolean formula as a BDD.
|
||||||
|
///
|
||||||
|
/// If you plan to use this method, be sure to pass a bdd_dict
|
||||||
|
/// to the constructor.
|
||||||
|
bdd as_bdd(const formula* f);
|
||||||
|
|
||||||
|
/// Return the bdd_dict used.
|
||||||
|
bdd_dict* get_dict() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ltl_simplifier_cache* cache_;
|
ltl_simplifier_cache* cache_;
|
||||||
// Copy disallowed.
|
// Copy disallowed.
|
||||||
ltl_simplifier(const ltl_simplifier&);
|
ltl_simplifier(const ltl_simplifier&);
|
||||||
|
bool owndict;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,9 @@ namespace spot
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
translate_dict(bdd_dict* dict)
|
translate_dict(bdd_dict* dict, ltl_simplifier* ls)
|
||||||
: dict(dict),
|
: dict(dict),
|
||||||
|
ls(ls),
|
||||||
a_set(bddtrue),
|
a_set(bddtrue),
|
||||||
var_set(bddtrue),
|
var_set(bddtrue),
|
||||||
next_set(bddtrue)
|
next_set(bddtrue)
|
||||||
|
|
@ -73,6 +74,7 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
bdd_dict* dict;
|
bdd_dict* dict;
|
||||||
|
ltl_simplifier* ls;
|
||||||
|
|
||||||
typedef bdd_dict::fv_map fv_map;
|
typedef bdd_dict::fv_map fv_map;
|
||||||
typedef bdd_dict::vf_map vf_map;
|
typedef bdd_dict::vf_map vf_map;
|
||||||
|
|
@ -154,6 +156,14 @@ namespace spot
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bdd
|
||||||
|
boolean_to_bdd(const formula* f)
|
||||||
|
{
|
||||||
|
bdd res = ls->as_bdd(f);
|
||||||
|
var_set &= bdd_support(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
formula*
|
formula*
|
||||||
conj_bdd_to_formula(bdd b, multop::type op = multop::And) const
|
conj_bdd_to_formula(bdd b, multop::type op = multop::And) const
|
||||||
{
|
{
|
||||||
|
|
@ -299,15 +309,17 @@ namespace spot
|
||||||
bdd res_;
|
bdd res_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bdd translate_ratexp(const formula* f, translate_dict& dict,
|
||||||
|
formula* to_concat = 0);
|
||||||
|
|
||||||
// Rewrite rule for rational operators.
|
// Rewrite rule for rational operators.
|
||||||
class ratexp_trad_visitor: public const_visitor
|
class ratexp_trad_visitor: public const_visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// negated should only be set for constants or atomic properties
|
// negated should only be set for constants or atomic properties
|
||||||
ratexp_trad_visitor(translate_dict& dict,
|
ratexp_trad_visitor(translate_dict& dict,
|
||||||
formula* to_concat = 0,
|
formula* to_concat = 0)
|
||||||
bool negated = false)
|
: dict_(dict), to_concat_(to_concat)
|
||||||
: dict_(dict), to_concat_(to_concat), negated_(negated)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,33 +363,13 @@ namespace spot
|
||||||
void
|
void
|
||||||
visit(const atomic_prop* node)
|
visit(const atomic_prop* node)
|
||||||
{
|
{
|
||||||
if (negated_)
|
res_ = bdd_ithvar(dict_.register_proposition(node));
|
||||||
res_ = bdd_nithvar(dict_.register_proposition(node));
|
|
||||||
else
|
|
||||||
res_ = bdd_ithvar(dict_.register_proposition(node));
|
|
||||||
res_ &= next_to_concat();
|
res_ &= next_to_concat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
visit(const constant* node)
|
visit(const constant* node)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (negated_)
|
|
||||||
{
|
|
||||||
switch (node->val())
|
|
||||||
{
|
|
||||||
case constant::True:
|
|
||||||
res_ = bddfalse;
|
|
||||||
return;
|
|
||||||
case constant::False:
|
|
||||||
res_ = next_to_concat();
|
|
||||||
return;
|
|
||||||
case constant::EmptyWord:
|
|
||||||
assert(!"EmptyWord should not be negated");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node->val())
|
switch (node->val())
|
||||||
{
|
{
|
||||||
case constant::True:
|
case constant::True:
|
||||||
|
|
@ -411,10 +403,10 @@ namespace spot
|
||||||
{
|
{
|
||||||
// Not can only appear in front of Boolean
|
// Not can only appear in front of Boolean
|
||||||
// expressions.
|
// expressions.
|
||||||
// propositions.
|
|
||||||
const formula* f = node->child();
|
const formula* f = node->child();
|
||||||
assert(f->is_boolean());
|
assert(f->is_boolean());
|
||||||
res_ = recurse_and_concat(f, true);
|
res_ = !recurse(f);
|
||||||
|
res_ &= next_to_concat();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -785,26 +777,62 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
bdd
|
bdd
|
||||||
recurse(const formula* f, formula* to_concat = 0, bool negated = false)
|
recurse(const formula* f, formula* to_concat = 0)
|
||||||
{
|
{
|
||||||
ratexp_trad_visitor v(dict_, to_concat, negated);
|
return translate_ratexp(f, dict_, to_concat);
|
||||||
f->accept(v);
|
|
||||||
return v.result();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bdd
|
bdd
|
||||||
recurse_and_concat(const formula* f, bool negated = false)
|
recurse_and_concat(const formula* f)
|
||||||
{
|
{
|
||||||
return recurse(f, to_concat_ ? to_concat_->clone() : 0, negated);
|
return translate_ratexp(f, dict_,
|
||||||
|
to_concat_ ? to_concat_->clone() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
translate_dict& dict_;
|
translate_dict& dict_;
|
||||||
bdd res_;
|
bdd res_;
|
||||||
formula* to_concat_;
|
formula* to_concat_;
|
||||||
bool negated_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bdd
|
||||||
|
translate_ratexp(const formula* f, translate_dict& dict,
|
||||||
|
formula* to_concat)
|
||||||
|
{
|
||||||
|
// static unsigned indent = 0;
|
||||||
|
// for (unsigned i = indent; i > 0; --i)
|
||||||
|
// std::cerr << "| ";
|
||||||
|
// std::cerr << "translate_ratexp[" << to_string(f);
|
||||||
|
// if (to_concat)
|
||||||
|
// std::cerr << ", " << to_string(to_concat);
|
||||||
|
// std::cerr << "]" << std::endl;
|
||||||
|
// ++indent;
|
||||||
|
bdd res;
|
||||||
|
if (!f->is_boolean())
|
||||||
|
{
|
||||||
|
ratexp_trad_visitor v(dict, to_concat);
|
||||||
|
f->accept(v);
|
||||||
|
res = v.result();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = dict.boolean_to_bdd(f);
|
||||||
|
// See comment for similar code in next_to_concat.
|
||||||
|
if (!to_concat)
|
||||||
|
to_concat = constant::empty_word_instance();
|
||||||
|
int x = dict.register_next_variable(to_concat);
|
||||||
|
res &= bdd_ithvar(x);
|
||||||
|
to_concat->destroy();
|
||||||
|
}
|
||||||
|
// --indent;
|
||||||
|
// for (unsigned i = indent; i > 0; --i)
|
||||||
|
// std::cerr << "| ";
|
||||||
|
// std::cerr << "\\ ";
|
||||||
|
// bdd_print_set(std::cerr, dict.dict, res) << std::endl;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// The rewrite rules used here are adapted from Jean-Michel
|
// The rewrite rules used here are adapted from Jean-Michel
|
||||||
// Couvreur's FM paper, augmented to support rational operators.
|
// Couvreur's FM paper, augmented to support rational operators.
|
||||||
|
|
@ -939,12 +967,9 @@ namespace spot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ratexp_trad_visitor v(dict_);
|
bdd f1 = translate_ratexp(node->child(), dict_);
|
||||||
node->child()->accept(v);
|
|
||||||
bdd f1 = v.result();
|
|
||||||
res_ = bddfalse;
|
res_ = bddfalse;
|
||||||
|
|
||||||
|
|
||||||
if (exprop_)
|
if (exprop_)
|
||||||
{
|
{
|
||||||
bdd var_set = bdd_existcomp(bdd_support(f1), dict_.var_set);
|
bdd var_set = bdd_existcomp(bdd_support(f1), dict_.var_set);
|
||||||
|
|
@ -985,6 +1010,10 @@ namespace spot
|
||||||
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_formula(dest_bdd);
|
||||||
|
|
||||||
|
// std::cerr << "dest_bdd=";
|
||||||
|
// bdd_print_set(std::cerr, dict_.dict, dest_bdd)
|
||||||
|
// << ", dest=" << to_string(dest) << std::endl;
|
||||||
|
|
||||||
const formula* dest2;
|
const formula* dest2;
|
||||||
if (dest->accepts_eword())
|
if (dest->accepts_eword())
|
||||||
{
|
{
|
||||||
|
|
@ -1016,9 +1045,7 @@ namespace spot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ratexp_trad_visitor v(dict_);
|
bdd f1 = translate_ratexp(node->child(), dict_);
|
||||||
node->child()->accept(v);
|
|
||||||
bdd f1 = v.result();
|
|
||||||
|
|
||||||
// trace_ltl_bdd(dict_, f1);
|
// trace_ltl_bdd(dict_, f1);
|
||||||
|
|
||||||
|
|
@ -1146,9 +1173,7 @@ namespace spot
|
||||||
// Recognize f2 on transitions going to destinations
|
// Recognize f2 on transitions going to destinations
|
||||||
// that accept the empty word.
|
// that accept the empty word.
|
||||||
bdd f2 = recurse(node->second());
|
bdd f2 = recurse(node->second());
|
||||||
ratexp_trad_visitor v(dict_);
|
bdd f1 = translate_ratexp(node->first(), dict_);
|
||||||
node->first()->accept(v);
|
|
||||||
bdd f1 = v.result();
|
|
||||||
res_ = bddfalse;
|
res_ = bddfalse;
|
||||||
|
|
||||||
if (mark_all_)
|
if (mark_all_)
|
||||||
|
|
@ -1221,9 +1246,7 @@ namespace spot
|
||||||
// word should recognize f2, and the automaton for f1
|
// word should recognize f2, and the automaton for f1
|
||||||
// should be understood as universal.
|
// should be understood as universal.
|
||||||
bdd f2 = recurse(node->second());
|
bdd f2 = recurse(node->second());
|
||||||
ratexp_trad_visitor v(dict_);
|
bdd f1 = translate_ratexp(node->first(), dict_);
|
||||||
node->first()->accept(v);
|
|
||||||
bdd f1 = v.result();
|
|
||||||
res_ = bddtrue;
|
res_ = bddtrue;
|
||||||
|
|
||||||
bdd var_set = bdd_existcomp(bdd_support(f1), dict_.var_set);
|
bdd var_set = bdd_existcomp(bdd_support(f1), dict_.var_set);
|
||||||
|
|
@ -1497,13 +1520,14 @@ namespace spot
|
||||||
t.has_rational = v_.has_rational();
|
t.has_rational = v_.has_rational();
|
||||||
t.has_marked = v_.has_marked();
|
t.has_marked = v_.has_marked();
|
||||||
|
|
||||||
// std::cerr << "-----" << std::endl;
|
// std::cerr << "-----" << std::endl;
|
||||||
// std::cerr << "Formula: " << to_string(f) << std::endl;
|
// std::cerr << "Formula: " << to_string(f) << std::endl;
|
||||||
// std::cerr << "Rational: " << t.has_rational << std::endl;
|
// std::cerr << "Rational: " << t.has_rational << std::endl;
|
||||||
// std::cerr << "Marked: " << t.has_marked << std::endl;
|
// std::cerr << "Marked: " << t.has_marked << std::endl;
|
||||||
// std::cerr << "Mark all: " << !has_mark(f) << 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(v_.get_dict(), t.symbolic);
|
||||||
|
// std::cerr << "-----" << std::endl;
|
||||||
|
|
||||||
if (t.has_rational)
|
if (t.has_rational)
|
||||||
{
|
{
|
||||||
|
|
@ -1636,13 +1660,14 @@ namespace spot
|
||||||
ltl_simplifier* simplifier)
|
ltl_simplifier* simplifier)
|
||||||
{
|
{
|
||||||
formula* f2;
|
formula* f2;
|
||||||
|
ltl_simplifier* s = simplifier;
|
||||||
|
|
||||||
// Simplify the formula, if requested.
|
// Simplify the formula, if requested.
|
||||||
if (simplifier)
|
if (s)
|
||||||
{
|
{
|
||||||
// This will normalize the formula regardless of the
|
// This will normalize the formula regardless of the
|
||||||
// configuration of the simplifier.
|
// configuration of the simplifier.
|
||||||
f2 = simplifier->simplify(f);
|
f2 = s->simplify(f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1650,14 +1675,16 @@ namespace spot
|
||||||
// negations on the atomic propositions. We also suppress
|
// negations on the atomic propositions. We also suppress
|
||||||
// logic abbreviations such as <=>, =>, or XOR, since they
|
// logic abbreviations such as <=>, =>, or XOR, since they
|
||||||
// would involve negations at the BDD level.
|
// would involve negations at the BDD level.
|
||||||
ltl_simplifier s;
|
s = new ltl_simplifier(dict);
|
||||||
f2 = s.negative_normal_form(f, false);
|
f2 = s->negative_normal_form(f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::set<const formula*, formula_ptr_less_than> set_type;
|
typedef std::set<const formula*, formula_ptr_less_than> set_type;
|
||||||
set_type formulae_to_translate;
|
set_type formulae_to_translate;
|
||||||
|
|
||||||
translate_dict d(dict);
|
assert(dict == s->get_dict());
|
||||||
|
|
||||||
|
translate_dict d(dict, s);
|
||||||
|
|
||||||
// Compute the set of all promises that can possibly occur
|
// Compute the set of all promises that can possibly occur
|
||||||
// inside the formula.
|
// inside the formula.
|
||||||
|
|
@ -1933,6 +1960,9 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!simplifier)
|
||||||
|
delete s;
|
||||||
|
|
||||||
// Turn all promises into real acceptance conditions.
|
// Turn all promises into real acceptance conditions.
|
||||||
a->complement_all_acceptance_conditions();
|
a->complement_all_acceptance_conditions();
|
||||||
return a;
|
return a;
|
||||||
|
|
|
||||||
|
|
@ -813,7 +813,7 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
spot::ltl::ltl_simplifier* simp = 0;
|
spot::ltl::ltl_simplifier* simp = 0;
|
||||||
if (simpltl)
|
if (simpltl)
|
||||||
simp = new spot::ltl::ltl_simplifier(redopt);
|
simp = new spot::ltl::ltl_simplifier(redopt, dict);
|
||||||
|
|
||||||
if (simp)
|
if (simp)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue