Trivially reduce f;f to f[*2], f[*1..3];f to f[*2..4], etc.

* src/ltlast/multop.cc (instance): Implement the reduction.
* src/ltlast/multop.hh, doc/tl/tl.tex: Document it.
* src/ltltest/equals.test: Add a test.
This commit is contained in:
Alexandre Duret-Lutz 2012-04-25 15:14:14 +02:00
parent 4a775a17a3
commit e7cf7b422d
4 changed files with 88 additions and 8 deletions

View file

@ -501,6 +501,75 @@ namespace spot
v->swap(tmp);
}
}
else if (op == Concat)
{
// Perform an extra loop to merge starable items.
// f;f -> f[*2]
// f;f[*i..j] -> f[*i+1..j+1]
// f[*i..j];f -> f[*i+1..j+1]
// f[*i..j];f[*k..l] -> f[*i+k..j+l]
i = v->begin();
while (i != v->end())
{
vec::iterator fpos = i;
formula* f;
unsigned min;
unsigned max;
bool changed = false;
if (bunop* is = is_Star(*i))
{
f = is->child();
min = is->min();
max = is->max();
}
else
{
f = *i;
min = max = 1;
}
++i;
while (i != v->end())
{
formula* f2;
unsigned min2;
unsigned max2;
if (bunop* is = is_Star(*i))
{
f2 = is->child();
if (f2 != f)
break;
min2 = is->min();
max2 = is->max();
}
else
{
f2 = *i;
if (f2 != f)
break;
min2 = max2 = 1;
}
if (min2 == bunop::unbounded)
min = bunop::unbounded;
else if (min != bunop::unbounded)
min += min2;
if (max2 == bunop::unbounded)
max = bunop::unbounded;
else if (max != bunop::unbounded)
max += max2;
(*i)->destroy();
i = v->erase(i);
changed = true;
}
if (changed)
{
formula* newfs = bunop::instance(bunop::Star, f->clone(),
min, max);
(*fpos)->destroy();
*fpos = newfs;
}
}
}
}
vec::size_type s = v->size();

View file

@ -111,6 +111,8 @@ namespace spot
/// - Concat(Exps1...,FExps2...,1[*],FExps3...,Exps4) =
/// Concat(Exps1...,1[*],Exps4) if FExps2...FExps3... all accept [*0]
/// - Concat(Exp) = Exp
/// - Concat(Exps1...,E,E[*i..j],E[*k..l],Exps2...) =
/// Concat(Exps1...,E[*1+i+k..j+l],Exps2...) and similar forms
/// - Fusion(Exps1...1,Exps2...) = Fusion(Exps1...,Exps2...)
/// if at least one exp reject [*0]
/// - Fusion(Exps1...,0,Exps2...) = 0