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

@ -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: