randltl: fix generation without unary operators
* spot/tl/randomltl.hh (has_unary_ops): New method. * spot/tl/randomltl.cc: Avoid creating subformulas of even size when we do not have unary operators. * tests/core/randpsl.test: Test it. * NEWS: Mention it.
This commit is contained in:
parent
436e5a2d7f
commit
baf2778c9a
4 changed files with 62 additions and 5 deletions
5
NEWS
5
NEWS
|
|
@ -36,6 +36,11 @@ New in spot 2.12.0.dev (not yet released)
|
||||||
were missing the rule "[*0]|f ≡ f" when f already accepts the
|
were missing the rule "[*0]|f ≡ f" when f already accepts the
|
||||||
empty word. (Issue #545.)
|
empty word. (Issue #545.)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
- Generating random formula without any unary opertors would very
|
||||||
|
often create formulas much smaller than asked.
|
||||||
|
|
||||||
New in spot 2.12 (2024-05-16)
|
New in spot 2.12 (2024-05-16)
|
||||||
|
|
||||||
Build:
|
Build:
|
||||||
|
|
|
||||||
|
|
@ -92,14 +92,20 @@ namespace spot
|
||||||
{
|
{
|
||||||
assert(n >= 3);
|
assert(n >= 3);
|
||||||
--n;
|
--n;
|
||||||
int l = rrand(1, n - 1);
|
int l; // size of left
|
||||||
|
if ((n & 1) | rl->has_unary_ops())
|
||||||
|
l = rrand(1, n - 1);
|
||||||
|
else
|
||||||
|
// if we do not have unary ops, we must split n in two odd sizes
|
||||||
|
l = rrand(0, n/2 - 1)*2 + 1;
|
||||||
|
|
||||||
// Force the order of generation of operands to be right, then
|
// Force the order of generation of operands to be right, then
|
||||||
// left. This is historical, because gcc evaluates argument
|
// left. This is historical, because gcc evaluates argument
|
||||||
// from right to left and we used to make the two calls to
|
// from right to left and we used to make the two calls to
|
||||||
// generate() inside of the call to instance() before
|
// generate() inside of the call to instance() before
|
||||||
// discovering that clang would perform the nested calls from
|
// discovering that clang would perform the nested calls from
|
||||||
// left to right.
|
// left to right.
|
||||||
auto right = rl->generate(n - l);
|
formula right = rl->generate(n - l);
|
||||||
return formula::binop(Op, rl->generate(l), right);
|
return formula::binop(Op, rl->generate(l), right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +116,25 @@ namespace spot
|
||||||
assert(n >= 3);
|
assert(n >= 3);
|
||||||
--n;
|
--n;
|
||||||
const random_psl* rp = static_cast<const random_psl*>(rl);
|
const random_psl* rp = static_cast<const random_psl*>(rl);
|
||||||
int l = rrand(1, n - 1);
|
int l; // size of left
|
||||||
|
bool left_must_be_odd = !rp->rs.has_unary_ops();
|
||||||
|
bool right_must_be_odd = !rl->has_unary_ops();
|
||||||
|
if (n & 1)
|
||||||
|
{
|
||||||
|
if (left_must_be_odd && !right_must_be_odd)
|
||||||
|
l = rrand(0, n/2 - 1) * 2 + 1;
|
||||||
|
else if (!left_must_be_odd && right_must_be_odd)
|
||||||
|
l = rrand(1, n/2) * 2;
|
||||||
|
else
|
||||||
|
l = rrand(1, n - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (left_must_be_odd || right_must_be_odd)
|
||||||
|
l = rrand(0, n/2 - 1) * 2 + 1;
|
||||||
|
else
|
||||||
|
l = rrand(1, n - 1);
|
||||||
|
}
|
||||||
// See comment in binop_builder.
|
// See comment in binop_builder.
|
||||||
auto right = rl->generate(n - l);
|
auto right = rl->generate(n - l);
|
||||||
return formula::binop(Op, rp->rs.generate(l), right);
|
return formula::binop(Op, rp->rs.generate(l), right);
|
||||||
|
|
@ -152,9 +176,13 @@ namespace spot
|
||||||
{
|
{
|
||||||
assert(n >= 3);
|
assert(n >= 3);
|
||||||
--n;
|
--n;
|
||||||
int l = rrand(1, n - 1);
|
|
||||||
// See comment in binop_builder.
|
// See comment in binop_builder.
|
||||||
auto right = rl->generate(n - l);
|
int l; // size of left
|
||||||
|
if ((n & 1) | rl->has_unary_ops())
|
||||||
|
l = rrand(1, n - 1);
|
||||||
|
else
|
||||||
|
l = rrand(0, n/2 - 1)*2 + 1;
|
||||||
|
formula right = rl->generate(n - l);
|
||||||
return formula::multop(Op, {rl->generate(l), right});
|
return formula::multop(Op, {rl->generate(l), right});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,12 @@ namespace spot
|
||||||
/// occurrences of the \c F operator.
|
/// occurrences of the \c F operator.
|
||||||
const char* parse_options(char* options);
|
const char* parse_options(char* options);
|
||||||
|
|
||||||
|
/// \brief whether we can use unary operators
|
||||||
|
bool has_unary_ops() const
|
||||||
|
{
|
||||||
|
return total_2_ > 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void update_sums();
|
void update_sums();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,3 +36,21 @@ test `wc -l < formulas` = 50
|
||||||
|
|
||||||
|
|
||||||
randltl --psl --sere-priorities=first_match=10 -n 100 2 | grep first_match
|
randltl --psl --sere-priorities=first_match=10 -n 100 2 | grep first_match
|
||||||
|
|
||||||
|
# the random generator had trouble generating formulas of the proper size when
|
||||||
|
# unary operators were disabled
|
||||||
|
P=true=0,false=0,not=0
|
||||||
|
randltl --tree-size=19 -B --boolean-prio=$P 1000 -n10 --stats=%a >out
|
||||||
|
cat >expected <<EOF
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
10
|
||||||
|
EOF
|
||||||
|
diff expected out
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue