randltl: accept a number of atomic propositions
Suggested by Joachim Klein. * src/bin/randltl.cc: Implement it. * src/ltltest/rand.test: Test it. * doc/org/randltl.org, NEWS: Document it.
This commit is contained in:
parent
310a98c15a
commit
44fc323e7b
4 changed files with 84 additions and 12 deletions
2
NEWS
2
NEWS
|
|
@ -12,6 +12,8 @@ New in spot 1.2.4a (not yet released)
|
||||||
The corresponding C++ function is spot::hoaf_reachable() in
|
The corresponding C++ function is spot::hoaf_reachable() in
|
||||||
tgbaalgos/hoaf.hh.
|
tgbaalgos/hoaf.hh.
|
||||||
|
|
||||||
|
- 'randltl 4' is now a shorthand for 'randltl p0 p1 p2 p3'.
|
||||||
|
|
||||||
* Documentation:
|
* Documentation:
|
||||||
|
|
||||||
- The man page for ltl2tgba has some new notes and references
|
- The man page for ltl2tgba has some new notes and references
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ randltl a b c
|
||||||
|
|
||||||
Note that the result does not always use all atomic propositions.
|
Note that the result does not always use all atomic propositions.
|
||||||
|
|
||||||
|
If you do not care about how the atomic propositions are named,
|
||||||
|
you can give a nonnegative number instead:
|
||||||
|
|
||||||
|
#+BEGIN_SRC sh :results verbatim :exports both
|
||||||
|
randltl 3
|
||||||
|
#+END_SRC
|
||||||
|
#+RESULTS:
|
||||||
|
: G(Gp1 W (Gp1 M p2))
|
||||||
|
|
||||||
The syntax of the formula output can be changed using the
|
The syntax of the formula output can be changed using the
|
||||||
[[file:ioltl.org][common output options]]:
|
[[file:ioltl.org][common output options]]:
|
||||||
|
|
||||||
|
|
@ -40,16 +49,16 @@ like =p0=, =p1=, etc... (Atomic proposition named differently will be
|
||||||
output by Spot in double-quotes, but this is not supported by LBT.)
|
output by Spot in double-quotes, but this is not supported by LBT.)
|
||||||
|
|
||||||
#+BEGIN_SRC sh :results verbatim :exports both
|
#+BEGIN_SRC sh :results verbatim :exports both
|
||||||
randltl -l p1 p2 p3
|
randltl -l 3
|
||||||
randltl -8 p1 p2 p3
|
randltl -8 3
|
||||||
randltl -s p1 p2 p3
|
randltl -s 3
|
||||||
randltl --wring p1 p2 p3
|
randltl --wring 3
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
: G W G p2 M G p2 p3
|
: G W G p1 M G p1 p2
|
||||||
: □(□p2 W (□p2 M p3))
|
: □(□p1 W (□p1 M p2))
|
||||||
: []((p3 U (p3 && []p2)) V ([]p2 || (p3 U (p3 && []p2))))
|
: []((p2 U (p2 && []p1)) V ([]p1 || (p2 U (p2 && []p1))))
|
||||||
: (G(((p3=1) U ((p3=1) * (G(p2=1)))) R ((G(p2=1)) + ((p3=1) U ((p3=1) * (G(p2=1)))))))
|
: (G(((p2=1) U ((p2=1) * (G(p1=1)))) R ((G(p1=1)) + ((p2=1) U ((p2=1) * (G(p1=1)))))))
|
||||||
|
|
||||||
As you might guess from the above result, for a given set of atomic
|
As you might guess from the above result, for a given set of atomic
|
||||||
propositions (and on the same computer) the generated formula will
|
propositions (and on the same computer) the generated formula will
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,19 @@
|
||||||
#include "misc/hash.hh"
|
#include "misc/hash.hh"
|
||||||
|
|
||||||
const char argp_program_doc[] ="\
|
const char argp_program_doc[] ="\
|
||||||
Generate random temporal logic formulas.\v\
|
Generate random temporal logic formulas.\n\n\
|
||||||
|
The formulas are built over the atomic propositions named by PROPS...\n\
|
||||||
|
or, if N is a nonnegative number, using N arbitrary names.\v\
|
||||||
Examples:\n\
|
Examples:\n\
|
||||||
\n\
|
\n\
|
||||||
The following generates 10 random LTL formulas over the propositions a, b,\n\
|
The following generates 10 random LTL formulas over the propositions a, b,\n\
|
||||||
and c, with the default tree-size, and all available operators.\n\
|
and c, with the default tree-size, and all available operators.\n\
|
||||||
% randltl -n10 a b c\n\
|
% randltl -n10 a b c\n\
|
||||||
\n\
|
\n\
|
||||||
|
If you do not mind about the name of the atomic propositions, just give\n\
|
||||||
|
a number instead:\n\
|
||||||
|
% ./randltl -n10 3\n\
|
||||||
|
\n\
|
||||||
You can disable or favor certain operators by changing their priority.\n\
|
You can disable or favor certain operators by changing their priority.\n\
|
||||||
The following disables xor, implies, and equiv, and multiply the probability\n\
|
The following disables xor, implies, and equiv, and multiply the probability\n\
|
||||||
of X to occur by 10.\n\
|
of X to occur by 10.\n\
|
||||||
|
|
@ -139,6 +145,7 @@ static int opt_seed = 0;
|
||||||
static range opt_tree_size = { 15, 15 };
|
static range opt_tree_size = { 15, 15 };
|
||||||
static bool opt_unique = true;
|
static bool opt_unique = true;
|
||||||
static bool opt_wf = false;
|
static bool opt_wf = false;
|
||||||
|
static bool ap_count_given = false;
|
||||||
|
|
||||||
void
|
void
|
||||||
remove_some_props(spot::ltl::atomic_prop_set& s)
|
remove_some_props(spot::ltl::atomic_prop_set& s)
|
||||||
|
|
@ -185,7 +192,7 @@ to_int(const char* s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_opt(int key, char* arg, struct argp_state*)
|
parse_opt(int key, char* arg, struct argp_state* as)
|
||||||
{
|
{
|
||||||
// This switch is alphabetically-ordered.
|
// This switch is alphabetically-ordered.
|
||||||
switch (key)
|
switch (key)
|
||||||
|
|
@ -236,6 +243,32 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
opt_wf = true;
|
opt_wf = true;
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
|
// If this is the unique non-option argument, it can
|
||||||
|
// be a number of atomic propositions to build.
|
||||||
|
//
|
||||||
|
// argp reorganizes argv[] so that options always come before
|
||||||
|
// non-options. So if as->argc == as->next we know this is the
|
||||||
|
// last non-option argument, and if aprops.empty() we know this
|
||||||
|
// is the also the first one.
|
||||||
|
if (aprops.empty() && as->argc == as->next)
|
||||||
|
{
|
||||||
|
char* endptr;
|
||||||
|
int res = strtol(arg, &endptr, 10);
|
||||||
|
if (!*endptr && res >= 0) // arg is a number
|
||||||
|
{
|
||||||
|
ap_count_given = true;
|
||||||
|
spot::ltl::default_environment& e =
|
||||||
|
spot::ltl::default_environment::instance();
|
||||||
|
for (int i = 0; i < res; ++i)
|
||||||
|
{
|
||||||
|
std::ostringstream p;
|
||||||
|
p << 'p' << i;
|
||||||
|
aprops.insert(static_cast<const spot::ltl::atomic_prop*>
|
||||||
|
(e.require(p.str())));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
aprops.insert(static_cast<const spot::ltl::atomic_prop*>
|
aprops.insert(static_cast<const spot::ltl::atomic_prop*>
|
||||||
(spot::ltl::default_environment::instance().require(arg)));
|
(spot::ltl::default_environment::instance().require(arg)));
|
||||||
break;
|
break;
|
||||||
|
|
@ -250,7 +283,7 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
setup(argv);
|
setup(argv);
|
||||||
|
|
||||||
const argp ap = { options, parse_opt, "PROP...", argp_program_doc,
|
const argp ap = { options, parse_opt, "N|PROP...", argp_program_doc,
|
||||||
children, 0, 0 };
|
children, 0, 0 };
|
||||||
|
|
||||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, 0, 0))
|
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, 0, 0))
|
||||||
|
|
@ -340,7 +373,9 @@ main(int argc, char** argv)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aprops.empty())
|
// running 'randltl 0' is one way to generate formulas using no
|
||||||
|
// atomic propositions so do not complain in that case.
|
||||||
|
if (aprops.empty() && !ap_count_given)
|
||||||
error(2, 0, "No atomic proposition supplied? Run '%s --help' for usage.",
|
error(2, 0, "No atomic proposition supplied? Run '%s --help' for usage.",
|
||||||
program_name);
|
program_name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,3 +97,29 @@ c
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
diff expected out2
|
diff expected out2
|
||||||
|
|
||||||
|
|
||||||
|
# atomic proposition can be implicitly specified using a number
|
||||||
|
$randltl -n 1000 3 --tree-size=10..20 > out
|
||||||
|
grep -q p0 out
|
||||||
|
grep -q p1 out
|
||||||
|
grep -q p2 out
|
||||||
|
grep p3 out && exit 1
|
||||||
|
|
||||||
|
|
||||||
|
# We should be able to generate exactly two formulas with 0 atomic
|
||||||
|
# propositions.
|
||||||
|
run 0 $randltl -n2 0 | sort > out
|
||||||
|
cat >expected <<EOF
|
||||||
|
0
|
||||||
|
1
|
||||||
|
EOF
|
||||||
|
diff out expected
|
||||||
|
|
||||||
|
# requesting more formulas should fail
|
||||||
|
run 2 $randltl -n3 0
|
||||||
|
|
||||||
|
# If more numbers are given, there are interpreted as atomic propositions
|
||||||
|
run 0 $randltl -n1000 0 1 > out
|
||||||
|
grep -q '"0"' out
|
||||||
|
grep -q '"1"' out
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue