randaut: add option --acc-type=random
Fixes #71. * src/bin/randaut.cc: Implement option --acc-type. * src/tgbaalgos/randomgraph.cc, src/tgbaalgos/randomgraph.hh (random_acceptance): New function. * src/tgbatest/randaut.test, wrap/python/tests/randaut.ipynb: Test it.
This commit is contained in:
parent
d3ee61979c
commit
2f42c1c9bf
5 changed files with 2017 additions and 1830 deletions
|
|
@ -26,6 +26,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "argmatch.h"
|
||||||
|
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
#include "common_range.hh"
|
#include "common_range.hh"
|
||||||
|
|
@ -64,12 +65,16 @@ states, 1 to 3 acceptance sets, and three atomic propositions:\n\
|
||||||
enum {
|
enum {
|
||||||
OPT_SEED = 1,
|
OPT_SEED = 1,
|
||||||
OPT_STATE_ACC,
|
OPT_STATE_ACC,
|
||||||
|
OPT_ACC_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const argp_option options[] =
|
static const argp_option options[] =
|
||||||
{
|
{
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ 0, 0, 0, 0, "Generation:", 2 },
|
{ 0, 0, 0, 0, "Generation:", 2 },
|
||||||
|
{ "acc-type", OPT_ACC_TYPE, "buchi|random", 0,
|
||||||
|
"use a generalized buchi acceptance condition (default), or a "
|
||||||
|
"random acceptance condition", 0 },
|
||||||
{ "acc-sets", 'A', "RANGE", 0, "number of acceptance sets (0)", 0 },
|
{ "acc-sets", 'A', "RANGE", 0, "number of acceptance sets (0)", 0 },
|
||||||
{ "acc-probability", 'a', "FLOAT", 0,
|
{ "acc-probability", 'a', "FLOAT", 0,
|
||||||
"probability that a transition belong to one acceptance set (0.2)", 0 },
|
"probability that a transition belong to one acceptance set (0.2)", 0 },
|
||||||
|
|
@ -102,6 +107,23 @@ static const struct argp_child children[] =
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum acc_type { acc_buchi, acc_random };
|
||||||
|
|
||||||
|
static char const *const acc_args[] =
|
||||||
|
{
|
||||||
|
"buchi", "ba", "gba",
|
||||||
|
"random",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
static acc_type const acc_types[] =
|
||||||
|
{
|
||||||
|
acc_buchi, acc_buchi, acc_buchi,
|
||||||
|
acc_random,
|
||||||
|
};
|
||||||
|
ARGMATCH_VERIFY(acc_args, acc_types);
|
||||||
|
|
||||||
|
|
||||||
|
static acc_type opt_acc = acc_buchi;
|
||||||
typedef spot::tgba_digraph::graph_t::trans_storage_t tr_t;
|
typedef spot::tgba_digraph::graph_t::trans_storage_t tr_t;
|
||||||
typedef std::set<std::vector<tr_t>> unique_aut_t;
|
typedef std::set<std::vector<tr_t>> unique_aut_t;
|
||||||
static spot::ltl::atomic_prop_set aprops;
|
static spot::ltl::atomic_prop_set aprops;
|
||||||
|
|
@ -171,6 +193,9 @@ parse_opt(int key, char* arg, struct argp_state* as)
|
||||||
opt_uniq =
|
opt_uniq =
|
||||||
std::unique_ptr<unique_aut_t>(new std::set<std::vector<tr_t>>());
|
std::unique_ptr<unique_aut_t>(new std::set<std::vector<tr_t>>());
|
||||||
break;
|
break;
|
||||||
|
case OPT_ACC_TYPE:
|
||||||
|
opt_acc = XARGMATCH("--acc-type", arg, acc_args, acc_types);
|
||||||
|
break;
|
||||||
case OPT_SEED:
|
case OPT_SEED:
|
||||||
opt_seed = to_int(arg);
|
opt_seed = to_int(arg);
|
||||||
opt_seed_str = arg;
|
opt_seed_str = arg;
|
||||||
|
|
@ -229,9 +254,15 @@ main(int argc, char** argv)
|
||||||
if (automaton_format == Spin && opt_acc_sets.max > 1)
|
if (automaton_format == Spin && opt_acc_sets.max > 1)
|
||||||
error(2, 0, "--spin is incompatible with --acc-sets=%d..%d",
|
error(2, 0, "--spin is incompatible with --acc-sets=%d..%d",
|
||||||
opt_acc_sets.min, opt_acc_sets.max);
|
opt_acc_sets.min, opt_acc_sets.max);
|
||||||
|
if (automaton_format == Spin && opt_acc != acc_buchi)
|
||||||
|
error(2, 0,
|
||||||
|
"--spin implies --acc-type=buchi but a different --acc-type is used");
|
||||||
if (ba_wanted && opt_acc_sets.min != 1 && opt_acc_sets.max != 1)
|
if (ba_wanted && opt_acc_sets.min != 1 && opt_acc_sets.max != 1)
|
||||||
error(2, 0, "--ba is incompatible with --acc-sets=%d..%d",
|
error(2, 0, "--ba is incompatible with --acc-sets=%d..%d",
|
||||||
opt_acc_sets.min, opt_acc_sets.max);
|
opt_acc_sets.min, opt_acc_sets.max);
|
||||||
|
if (ba_wanted && opt_acc != acc_buchi)
|
||||||
|
error(2, 0,
|
||||||
|
"--ba implies --acc-type=buchi but a different --acc-type is used");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -263,6 +294,16 @@ main(int argc, char** argv)
|
||||||
accs, opt_acc_prob, 0.5,
|
accs, opt_acc_prob, 0.5,
|
||||||
opt_deterministic, opt_state_acc);
|
opt_deterministic, opt_state_acc);
|
||||||
|
|
||||||
|
switch (opt_acc)
|
||||||
|
{
|
||||||
|
case acc_buchi:
|
||||||
|
// Random_graph builds a GBA by default
|
||||||
|
break;
|
||||||
|
case acc_random:
|
||||||
|
aut->set_acceptance(accs, spot::random_acceptance(accs));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_uniq)
|
if (opt_uniq)
|
||||||
{
|
{
|
||||||
auto tmp = spot::canonicalize
|
auto tmp = spot::canonicalize
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Laboratoire de
|
// Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014, 2015 Laboratoire de
|
||||||
// Recherche et Développement de l'Epita (LRDE).
|
// Recherche et Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2004, 2005, 2007 Laboratoire d'Informatique de
|
// Copyright (C) 2004, 2005, 2007 Laboratoire d'Informatique de
|
||||||
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||||
|
|
@ -241,4 +241,41 @@ namespace spot
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acc_cond::acc_code random_acceptance(unsigned n_accs)
|
||||||
|
{
|
||||||
|
// With 0 acceptance sets, we always generate the true acceptance.
|
||||||
|
// (Working with false is somehow pointless, and the formulas we
|
||||||
|
// generate for n_accs>0 are always satisfiable, so it makes sense
|
||||||
|
// that it should be satisfiable for n_accs=0 as well.)
|
||||||
|
if (n_accs == 0)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
acc_cond acc(n_accs);
|
||||||
|
std::vector<acc_cond::acc_code> codes;
|
||||||
|
codes.reserve(n_accs);
|
||||||
|
for (unsigned i = 0; i < n_accs; ++i)
|
||||||
|
if (drand() < 0.5)
|
||||||
|
codes.push_back(acc.inf(acc.mark(i)));
|
||||||
|
else
|
||||||
|
codes.push_back(acc.fin(acc.mark(i)));
|
||||||
|
|
||||||
|
int s = codes.size();
|
||||||
|
while (s > 1)
|
||||||
|
{
|
||||||
|
// Pick a random code and put it at the end
|
||||||
|
int p1 = mrand(s--);
|
||||||
|
std::swap(codes[p1], codes[s]);
|
||||||
|
// and another one
|
||||||
|
int p2 = mrand(s);
|
||||||
|
|
||||||
|
if (drand() < 0.5)
|
||||||
|
codes[p2].append_or(std::move(codes.back()));
|
||||||
|
else
|
||||||
|
codes[p2].append_and(std::move(codes.back()));
|
||||||
|
|
||||||
|
codes.pop_back();
|
||||||
|
}
|
||||||
|
return codes[0];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2011, 2013, 2014 Laboratoire de Recherche et
|
// Copyright (C) 2011, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "ltlvisit/apcollect.hh"
|
#include "ltlvisit/apcollect.hh"
|
||||||
#include "ltlenv/defaultenv.hh"
|
#include "ltlenv/defaultenv.hh"
|
||||||
#include "tgba/bdddict.hh"
|
#include "tgba/bdddict.hh"
|
||||||
|
#include "tgba/acc.hh"
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
|
@ -81,4 +82,7 @@ namespace spot
|
||||||
const ltl::atomic_prop_set* ap, const bdd_dict_ptr& dict,
|
const ltl::atomic_prop_set* ap, const bdd_dict_ptr& dict,
|
||||||
unsigned n_accs = 0, float a = 0.1, float t = 0.5,
|
unsigned n_accs = 0, float a = 0.1, float t = 0.5,
|
||||||
bool deterministic = false, bool state_acc = false);
|
bool deterministic = false, bool state_acc = false);
|
||||||
|
|
||||||
|
/// Build a random acceptance where each acceptance sets is used once.
|
||||||
|
SPOT_API acc_cond::acc_code random_acceptance(unsigned n_accs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,3 +81,20 @@ test 6 = `$autfilt -c out-det1.hoa`
|
||||||
|
|
||||||
$autfilt -H out.hoa -o foo -c 2>stderr && exit 1
|
$autfilt -H out.hoa -o foo -c 2>stderr && exit 1
|
||||||
grep 'autfilt: options --output and --count are incompatible' stderr
|
grep 'autfilt: options --output and --count are incompatible' stderr
|
||||||
|
|
||||||
|
$randaut -n 2 -S5 -A4 -H 2 | grep Acceptance: > output
|
||||||
|
$randaut --acc-type=random -n 2 -S5 -A4 -H 2 | grep Acceptance: >> output
|
||||||
|
cat output
|
||||||
|
|
||||||
|
cat >expected <<EOF
|
||||||
|
Acceptance: 4 Inf(0)&Inf(1)&Inf(2)&Inf(3)
|
||||||
|
Acceptance: 4 Inf(0)&Inf(1)&Inf(2)&Inf(3)
|
||||||
|
Acceptance: 4 (Fin(2) & Inf(3)) | Inf(0) | Fin(1)
|
||||||
|
Acceptance: 4 ((Inf(0) | Inf(1)) & Fin(3)) | Inf(2)
|
||||||
|
EOF
|
||||||
|
diff output expected
|
||||||
|
|
||||||
|
$randaut --spin --acc-type=random 2 2>stderr && exit 1
|
||||||
|
grep 'randaut: --spin.*--acc-type' stderr
|
||||||
|
$randaut --ba --acc-type=random 2 2>stderr && exit 1
|
||||||
|
grep 'randaut: --ba.*--acc-type' stderr
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue