move spot/bin/ and spot/tests/ up by one level
* spot/bin/: Move... * bin/: ... here. * spot/tests/: Move... * tests/: ... here. * Makefile.am, README, bench/stutter/Makefile.am, bench/stutter/stutter_invariance_formulas.cc, doc/Makefile.am, configure.ac, debian/rules, spot/Makefile.am, spot/ltsmin/Makefile.am, spot/ltsmin/kripke.test, spot/sanity/style.test, python/tests/run.in: Adjust.
This commit is contained in:
parent
ff4837f4f2
commit
134dfc73de
220 changed files with 35 additions and 30 deletions
|
|
@ -26,7 +26,7 @@ AUTOMAKE_OPTIONS = subdir-objects
|
|||
# end, after building '.' (since the current directory contains
|
||||
# libspot.la needed by the tests)
|
||||
SUBDIRS = misc priv tl graph twa twaalgos ta taalgos kripke \
|
||||
parseaut parsetl . bin tests ltsmin sanity
|
||||
parseaut parsetl . ltsmin sanity
|
||||
|
||||
lib_LTLIBRARIES = libspot.la
|
||||
libspot_la_SOURCES =
|
||||
|
|
|
|||
16
spot/bin/.gitignore
vendored
16
spot/bin/.gitignore
vendored
|
|
@ -1,16 +0,0 @@
|
|||
autfilt
|
||||
dstar2tgba
|
||||
genltl
|
||||
ltl2tgba
|
||||
ltl2tgta
|
||||
ltlcross
|
||||
ltldo
|
||||
ltlfilt
|
||||
ltlgrind
|
||||
randaut
|
||||
randltl
|
||||
spot-x
|
||||
*.a
|
||||
*.1
|
||||
*.7
|
||||
lck-*
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
## Développement de l'Epita (LRDE).
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SUBDIRS = . man
|
||||
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) $(BUDDY_CPPFLAGS) \
|
||||
-I$(top_builddir)/lib -I$(top_srcdir)/lib
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS)
|
||||
LDADD = libcommon.a $(top_builddir)/lib/libgnu.la ../libspot.la
|
||||
|
||||
noinst_LIBRARIES = libcommon.a
|
||||
libcommon_a_SOURCES = \
|
||||
common_aoutput.cc \
|
||||
common_aoutput.hh \
|
||||
common_conv.hh \
|
||||
common_conv.cc \
|
||||
common_cout.hh \
|
||||
common_cout.cc \
|
||||
common_file.cc \
|
||||
common_file.hh \
|
||||
common_finput.cc \
|
||||
common_finput.hh \
|
||||
common_hoaread.cc \
|
||||
common_hoaread.hh \
|
||||
common_output.cc \
|
||||
common_output.hh \
|
||||
common_post.cc \
|
||||
common_post.hh \
|
||||
common_range.cc \
|
||||
common_range.hh \
|
||||
common_r.cc \
|
||||
common_r.hh \
|
||||
common_setup.cc \
|
||||
common_setup.hh \
|
||||
common_sys.hh \
|
||||
common_trans.cc \
|
||||
common_trans.hh
|
||||
|
||||
bin_PROGRAMS = \
|
||||
autfilt \
|
||||
dstar2tgba \
|
||||
genltl \
|
||||
ltl2tgba \
|
||||
ltl2tgta \
|
||||
ltlcross \
|
||||
ltldo \
|
||||
ltlfilt \
|
||||
ltlgrind \
|
||||
randaut \
|
||||
randltl
|
||||
|
||||
# Dummy program used just to generate man/spot-x.7 in a way that is
|
||||
# consistent with the other man pages (e.g., with a version number that
|
||||
# is automatically updated).
|
||||
noinst_PROGRAMS = spot-x
|
||||
|
||||
autfilt_SOURCES = autfilt.cc
|
||||
ltlfilt_SOURCES = ltlfilt.cc
|
||||
genltl_SOURCES = genltl.cc
|
||||
randaut_SOURCES = randaut.cc
|
||||
randltl_SOURCES = randltl.cc
|
||||
ltl2tgba_SOURCES = ltl2tgba.cc
|
||||
ltl2tgta_SOURCES = ltl2tgta.cc
|
||||
ltlcross_SOURCES = ltlcross.cc
|
||||
ltlgrind_SOURCES = ltlgrind.cc
|
||||
ltldo_SOURCES = ltldo.cc
|
||||
dstar2tgba_SOURCES = dstar2tgba.cc
|
||||
spot_x_SOURCES = spot-x.cc
|
||||
ltlcross_LDADD = $(LDADD) $(LIB_GETHRXTIME)
|
||||
|
||||
EXTRA_DIST = options.py
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
This directory contains the source of some command-line tools that
|
||||
expose some of Spot's algorithms to Unix users.
|
||||
|
||||
Man pages are generated from the --help output of each tool,
|
||||
supplemented by any text in the man/*.x files. Usually the extra text
|
||||
contains either some bibliographical references, some formal
|
||||
definitions or some examples that are too long for --help. Having a
|
||||
few short examples at the end of --help is good.
|
||||
|
||||
This directory also build some non-installed binaries, like spot-x,
|
||||
whose purpose is just to generate a man-page with the same format as
|
||||
the other man pages (this includes keeping the version number
|
||||
up-to-date).
|
||||
|
||||
There is also a script called 'options.py' that summerizes how the
|
||||
different short options are used among the tools.
|
||||
|
||||
Routines that are shared by multiple command-line tools are stored in
|
||||
files called common_*.{cc,hh}.
|
||||
|
||||
|
||||
Recommendations when adding new tools or features:
|
||||
--------------------------------------------------
|
||||
|
||||
- Tools should be designed to work on multiple inputs (e.g., read
|
||||
different outputs from multiple files, and accept many inputs from
|
||||
the same file, including stdin). They should also all be designed
|
||||
to produce several outputs, usually one per input. This way they
|
||||
can be piped one onto the other easily.
|
||||
|
||||
- When naming an option, seek inspiration from the POSIX standard, or
|
||||
from GNU extensions. For instance ltlfilt and autfilt both have a
|
||||
-v option to invert the filter; this is inspired from grep's -v
|
||||
option. The long version of this option (--invert-match) is also
|
||||
the same as in grep.
|
||||
|
||||
- When adding a new option, implement only the --long-option by
|
||||
default. Do not add a short version unless
|
||||
(1) you are sure it will be frequently used interactively
|
||||
(if it is only used in scripts, then a long option is enough)
|
||||
(2) this option can be shared by multiple tools.
|
||||
|
||||
- As much as possible, use the same option names across tools. Use
|
||||
the script options.py in this directory to check what short options
|
||||
are used. It's OK if the same short option correspond to different
|
||||
long names in the various tools, as long as the intent is similar.
|
||||
For instance -n has different long options depending on the tool:
|
||||
autfilt -n N means --max-count=N
|
||||
randltl -n N means --formulas=N
|
||||
randaut -n N means --automata=N
|
||||
but in all cases, the intent is to specify the number of items
|
||||
to output.
|
||||
|
|
@ -1,782 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
#include <argp.h>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_range.hh"
|
||||
#include "common_post.hh"
|
||||
#include "common_conv.hh"
|
||||
#include "common_hoaread.hh"
|
||||
|
||||
#include <spot/twaalgos/product.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
#include <spot/twaalgos/stutter.hh>
|
||||
#include <spot/twaalgos/isunamb.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
#include <spot/misc/random.hh>
|
||||
#include <spot/parseaut/public.hh>
|
||||
#include <spot/tl/exclusive.hh>
|
||||
#include <spot/twaalgos/remprop.hh>
|
||||
#include <spot/twaalgos/randomize.hh>
|
||||
#include <spot/twaalgos/are_isomorphic.hh>
|
||||
#include <spot/twaalgos/canonicalize.hh>
|
||||
#include <spot/twaalgos/mask.hh>
|
||||
#include <spot/twaalgos/sepsets.hh>
|
||||
#include <spot/twaalgos/stripacc.hh>
|
||||
#include <spot/twaalgos/remfin.hh>
|
||||
#include <spot/twaalgos/cleanacc.hh>
|
||||
#include <spot/twaalgos/dtwasat.hh>
|
||||
#include <spot/twaalgos/complement.hh>
|
||||
#include <spot/twaalgos/strength.hh>
|
||||
|
||||
static const char argp_program_doc[] ="\
|
||||
Convert, transform, and filter omega-automata.\v\
|
||||
Exit status:\n\
|
||||
0 if some automata were output\n\
|
||||
1 if no automata were output (no match)\n\
|
||||
2 if any error has been reported";
|
||||
|
||||
// Keep this list sorted
|
||||
enum {
|
||||
OPT_ACC_SETS = 256,
|
||||
OPT_ARE_ISOMORPHIC,
|
||||
OPT_CLEAN_ACC,
|
||||
OPT_CNF_ACC,
|
||||
OPT_COMPLEMENT,
|
||||
OPT_COMPLEMENT_ACC,
|
||||
OPT_COUNT,
|
||||
OPT_DECOMPOSE_STRENGTH,
|
||||
OPT_DESTUT,
|
||||
OPT_DNF_ACC,
|
||||
OPT_EDGES,
|
||||
OPT_EXCLUSIVE_AP,
|
||||
OPT_GENERIC,
|
||||
OPT_INSTUT,
|
||||
OPT_INTERSECT,
|
||||
OPT_IS_COMPLETE,
|
||||
OPT_IS_DETERMINISTIC,
|
||||
OPT_IS_EMPTY,
|
||||
OPT_IS_UNAMBIGUOUS,
|
||||
OPT_IS_TERMINAL,
|
||||
OPT_IS_WEAK,
|
||||
OPT_IS_INHERENTLY_WEAK,
|
||||
OPT_KEEP_STATES,
|
||||
OPT_MASK_ACC,
|
||||
OPT_MERGE,
|
||||
OPT_PRODUCT_AND,
|
||||
OPT_PRODUCT_OR,
|
||||
OPT_RANDOMIZE,
|
||||
OPT_REM_AP,
|
||||
OPT_REM_DEAD,
|
||||
OPT_REM_UNREACH,
|
||||
OPT_REM_FIN,
|
||||
OPT_SAT_MINIMIZE,
|
||||
OPT_SEED,
|
||||
OPT_SEP_SETS,
|
||||
OPT_SIMPLIFY_EXCLUSIVE_AP,
|
||||
OPT_STATES,
|
||||
OPT_STRIPACC,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Input:", 1 },
|
||||
{ "file", 'F', "FILENAME", 0,
|
||||
"process the automaton in FILENAME", 0 },
|
||||
/**************************************************/
|
||||
{ "count", 'c', nullptr, 0, "print only a count of matched automata", 3 },
|
||||
{ "max-count", 'n', "NUM", 0, "output at most NUM automata", 3 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Transformations:", 5 },
|
||||
{ "merge-transitions", OPT_MERGE, nullptr, 0,
|
||||
"merge transitions with same destination and acceptance", 0 },
|
||||
{ "product", OPT_PRODUCT_AND, "FILENAME", 0,
|
||||
"build the product with the automaton in FILENAME "
|
||||
"to intersect languages", 0 },
|
||||
{ "product-and", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||
{ "product-or", OPT_PRODUCT_OR, "FILENAME", 0,
|
||||
"build the product with the automaton in FILENAME "
|
||||
"to sum languages", 0 },
|
||||
{ "randomize", OPT_RANDOMIZE, "s|t", OPTION_ARG_OPTIONAL,
|
||||
"randomize states and transitions (specify 's' or 't' to "
|
||||
"randomize only states or transitions)", 0 },
|
||||
{ "instut", OPT_INSTUT, "1|2", OPTION_ARG_OPTIONAL,
|
||||
"allow more stuttering (two possible algorithms)", 0 },
|
||||
{ "destut", OPT_DESTUT, nullptr, 0, "allow less stuttering", 0 },
|
||||
{ "mask-acc", OPT_MASK_ACC, "NUM[,NUM...]", 0,
|
||||
"remove all transitions in specified acceptance sets", 0 },
|
||||
{ "strip-acceptance", OPT_STRIPACC, nullptr, 0,
|
||||
"remove the acceptance condition and all acceptance sets", 0 },
|
||||
{ "keep-states", OPT_KEEP_STATES, "NUM[,NUM...]", 0,
|
||||
"only keep specified states. The first state will be the new "\
|
||||
"initial state. Implies --remove-unreachable-states.", 0 },
|
||||
{ "dnf-acceptance", OPT_DNF_ACC, nullptr, 0,
|
||||
"put the acceptance condition in Disjunctive Normal Form", 0 },
|
||||
{ "cnf-acceptance", OPT_CNF_ACC, nullptr, 0,
|
||||
"put the acceptance condition in Conjunctive Normal Form", 0 },
|
||||
{ "remove-fin", OPT_REM_FIN, nullptr, 0,
|
||||
"rewrite the automaton without using Fin acceptance", 0 },
|
||||
{ "cleanup-acceptance", OPT_CLEAN_ACC, nullptr, 0,
|
||||
"remove unused acceptance sets from the automaton", 0 },
|
||||
{ "complement", OPT_COMPLEMENT, nullptr, 0,
|
||||
"complement each automaton (currently support only deterministic "
|
||||
"automata)", 0 },
|
||||
{ "complement-acceptance", OPT_COMPLEMENT_ACC, nullptr, 0,
|
||||
"complement the acceptance condition (without touching the automaton)",
|
||||
0 },
|
||||
{ "decompose-strength", OPT_DECOMPOSE_STRENGTH, "t|w|s", 0,
|
||||
"extract the (t) terminal, (w) weak, or (s) strong part of an automaton"
|
||||
" (letters may be combined to combine more strengths in the output)", 0 },
|
||||
{ "exclusive-ap", OPT_EXCLUSIVE_AP, "AP,AP,...", 0,
|
||||
"if any of those APs occur in the automaton, restrict all edges to "
|
||||
"ensure two of them may not be true at the same time. Use this option "
|
||||
"multiple times to declare independent groups of exclusive "
|
||||
"propositions.", 0 },
|
||||
{ "simplify-exclusive-ap", OPT_SIMPLIFY_EXCLUSIVE_AP, nullptr, 0,
|
||||
"if --exclusive-ap is used, assume those AP groups are actually exclusive"
|
||||
" in the system to simplify the expression of transition labels (implies "
|
||||
"--merge-transitions)", 0 },
|
||||
{ "remove-ap", OPT_REM_AP, "AP[=0|=1][,AP...]", 0,
|
||||
"remove atomic propositions either by existential quantification, or "
|
||||
"by assigning them 0 or 1", 0 },
|
||||
{ "remove-unreachable-states", OPT_REM_UNREACH, nullptr, 0,
|
||||
"remove states that are unreachable from the initial state", 0 },
|
||||
{ "remove-dead-states", OPT_REM_DEAD, nullptr, 0,
|
||||
"remove states that are unreachable, or that cannot belong to an "
|
||||
"infinite path", 0 },
|
||||
{ "separate-sets", OPT_SEP_SETS, nullptr, 0,
|
||||
"if both Inf(x) and Fin(x) appear in the acceptance condition, replace "
|
||||
"Fin(x) by a new Fin(y) and adjust the automaton", 0 },
|
||||
{ "sat-minimize", OPT_SAT_MINIMIZE, "options", OPTION_ARG_OPTIONAL,
|
||||
"minimize the automaton using a SAT solver (only work for deterministic"
|
||||
" automata)", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Filtering options:", 6 },
|
||||
{ "are-isomorphic", OPT_ARE_ISOMORPHIC, "FILENAME", 0,
|
||||
"keep automata that are isomorphic to the automaton in FILENAME", 0 },
|
||||
{ "isomorphic", 0, nullptr, OPTION_ALIAS | OPTION_HIDDEN, nullptr, 0 },
|
||||
{ "unique", 'u', nullptr, 0,
|
||||
"do not output the same automaton twice (same in the sense that they "\
|
||||
"are isomorphic)", 0 },
|
||||
{ "is-complete", OPT_IS_COMPLETE, nullptr, 0,
|
||||
"keep complete automata", 0 },
|
||||
{ "is-deterministic", OPT_IS_DETERMINISTIC, nullptr, 0,
|
||||
"keep deterministic automata", 0 },
|
||||
{ "is-empty", OPT_IS_EMPTY, nullptr, 0,
|
||||
"keep automata with an empty language", 0 },
|
||||
{ "is-unambiguous", OPT_IS_UNAMBIGUOUS, nullptr, 0,
|
||||
"keep only unambiguous automata", 0 },
|
||||
{ "is-terminal", OPT_IS_TERMINAL, nullptr, 0,
|
||||
"keep only terminal automata", 0 },
|
||||
{ "is-weak", OPT_IS_WEAK, nullptr, 0,
|
||||
"keep only weak automata", 0 },
|
||||
{ "is-inherently-weak", OPT_IS_INHERENTLY_WEAK, nullptr, 0,
|
||||
"keep only inherently weak automata", 0 },
|
||||
{ "intersect", OPT_INTERSECT, "FILENAME", 0,
|
||||
"keep automata whose languages have an non-empty intersection with"
|
||||
" the automaton from FILENAME", 0 },
|
||||
{ "invert-match", 'v', nullptr, 0, "select non-matching automata", 0 },
|
||||
{ "states", OPT_STATES, "RANGE", 0,
|
||||
"keep automata whose number of states are in RANGE", 0 },
|
||||
{ "edges", OPT_EDGES, "RANGE", 0,
|
||||
"keep automata whose number of edges are in RANGE", 0 },
|
||||
{ "acc-sets", OPT_ACC_SETS, "RANGE", 0,
|
||||
"keep automata whose number of acceptance sets are in RANGE", 0 },
|
||||
RANGE_DOC_FULL,
|
||||
{ nullptr, 0, nullptr, 0,
|
||||
"If any option among --small, --deterministic, or --any is given, "
|
||||
"then the simplification level defaults to --high unless specified "
|
||||
"otherwise. If any option among --low, --medium, or --high is given, "
|
||||
"then the simplification goal defaults to --small unless specified "
|
||||
"otherwise. If none of those options are specified, then autfilt "
|
||||
"acts as is --any --low were given: these actually disable the "
|
||||
"simplification routines.", 22 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ "extra-options", 'x', "OPTS", 0,
|
||||
"fine-tuning options (see spot-x (7))", 0 },
|
||||
{ "seed", OPT_SEED, "INT", 0,
|
||||
"seed for the random number generator (0)", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static const struct argp_child children[] =
|
||||
{
|
||||
{ &hoaread_argp, 0, nullptr, 0 },
|
||||
{ &aoutput_argp, 0, nullptr, 0 },
|
||||
{ &aoutput_io_format_argp, 0, nullptr, 4 },
|
||||
{ &post_argp_disabled, 0, nullptr, 0 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
typedef spot::twa_graph::graph_t::edge_storage_t tr_t;
|
||||
typedef std::set<std::vector<tr_t>> unique_aut_t;
|
||||
static long int match_count = 0;
|
||||
static spot::option_map extra_options;
|
||||
static bool randomize_st = false;
|
||||
static bool randomize_tr = false;
|
||||
static int opt_seed = 0;
|
||||
|
||||
// We want all these variable to be destroyed when we exit main, to
|
||||
// make sure it happens before all other global variables (like the
|
||||
// atomic propositions maps) are destroyed. Otherwise we risk
|
||||
// accessing deleted stuff.
|
||||
static struct opt_t
|
||||
{
|
||||
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
||||
spot::twa_graph_ptr product_and = nullptr;
|
||||
spot::twa_graph_ptr product_or = nullptr;
|
||||
spot::twa_graph_ptr intersect = nullptr;
|
||||
spot::twa_graph_ptr are_isomorphic = nullptr;
|
||||
std::unique_ptr<spot::isomorphism_checker>
|
||||
isomorphism_checker = nullptr;
|
||||
std::unique_ptr<unique_aut_t> uniq = nullptr;
|
||||
}* opt;
|
||||
|
||||
static bool opt_merge = false;
|
||||
static bool opt_is_complete = false;
|
||||
static bool opt_is_deterministic = false;
|
||||
static bool opt_is_unambiguous = false;
|
||||
static bool opt_is_terminal = false;
|
||||
static bool opt_is_weak = false;
|
||||
static bool opt_is_inherently_weak = false;
|
||||
static bool opt_invert = false;
|
||||
static range opt_states = { 0, std::numeric_limits<int>::max() };
|
||||
static range opt_edges = { 0, std::numeric_limits<int>::max() };
|
||||
static range opt_accsets = { 0, std::numeric_limits<int>::max() };
|
||||
static int opt_max_count = -1;
|
||||
static bool opt_destut = false;
|
||||
static char opt_instut = 0;
|
||||
static bool opt_is_empty = false;
|
||||
static bool opt_stripacc = false;
|
||||
static bool opt_dnf_acc = false;
|
||||
static bool opt_cnf_acc = false;
|
||||
static bool opt_rem_fin = false;
|
||||
static bool opt_clean_acc = false;
|
||||
static bool opt_complement = false;
|
||||
static bool opt_complement_acc = false;
|
||||
static char* opt_decompose_strength = nullptr;
|
||||
static spot::acc_cond::mark_t opt_mask_acc = 0U;
|
||||
static std::vector<bool> opt_keep_states = {};
|
||||
static unsigned int opt_keep_states_initial = 0;
|
||||
static spot::exclusive_ap excl_ap;
|
||||
static spot::remove_ap rem_ap;
|
||||
static bool opt_simplify_exclusive_ap = false;
|
||||
static bool opt_rem_dead = false;
|
||||
static bool opt_rem_unreach = false;
|
||||
static bool opt_sep_sets = false;
|
||||
static const char* opt_sat_minimize = nullptr;
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'c':
|
||||
automaton_format = Count;
|
||||
break;
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
case 'n':
|
||||
opt_max_count = to_pos_int(arg);
|
||||
break;
|
||||
case 'u':
|
||||
opt->uniq =
|
||||
std::unique_ptr<unique_aut_t>(new std::set<std::vector<tr_t>>());
|
||||
break;
|
||||
case 'v':
|
||||
opt_invert = true;
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
const char* opt = extra_options.parse_options(arg);
|
||||
if (opt)
|
||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||
}
|
||||
break;
|
||||
case OPT_ACC_SETS:
|
||||
opt_accsets = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||
break;
|
||||
case OPT_ARE_ISOMORPHIC:
|
||||
opt->are_isomorphic = read_automaton(arg, opt->dict);
|
||||
break;
|
||||
case OPT_CLEAN_ACC:
|
||||
opt_clean_acc = true;
|
||||
break;
|
||||
case OPT_CNF_ACC:
|
||||
opt_dnf_acc = false;
|
||||
opt_cnf_acc = true;
|
||||
break;
|
||||
case OPT_COMPLEMENT:
|
||||
opt_complement = true;
|
||||
break;
|
||||
case OPT_COMPLEMENT_ACC:
|
||||
opt_complement_acc = true;
|
||||
break;
|
||||
case OPT_DECOMPOSE_STRENGTH:
|
||||
opt_decompose_strength = arg;
|
||||
break;
|
||||
case OPT_DESTUT:
|
||||
opt_destut = true;
|
||||
break;
|
||||
case OPT_DNF_ACC:
|
||||
opt_dnf_acc = true;
|
||||
opt_cnf_acc = false;
|
||||
break;
|
||||
case OPT_EDGES:
|
||||
opt_edges = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||
break;
|
||||
case OPT_EXCLUSIVE_AP:
|
||||
excl_ap.add_group(arg);
|
||||
break;
|
||||
case OPT_INSTUT:
|
||||
if (!arg || (arg[0] == '1' && arg[1] == 0))
|
||||
opt_instut = 1;
|
||||
else if (arg[0] == '2' && arg[1] == 0)
|
||||
opt_instut = 2;
|
||||
else
|
||||
error(2, 0, "unknown argument for --instut: %s", arg);
|
||||
break;
|
||||
case OPT_INTERSECT:
|
||||
opt->intersect = read_automaton(arg, opt->dict);
|
||||
break;
|
||||
case OPT_IS_COMPLETE:
|
||||
opt_is_complete = true;
|
||||
break;
|
||||
case OPT_IS_DETERMINISTIC:
|
||||
opt_is_deterministic = true;
|
||||
break;
|
||||
case OPT_IS_EMPTY:
|
||||
opt_is_empty = true;
|
||||
break;
|
||||
case OPT_IS_INHERENTLY_WEAK:
|
||||
opt_is_inherently_weak = true;
|
||||
break;
|
||||
case OPT_IS_UNAMBIGUOUS:
|
||||
opt_is_unambiguous = true;
|
||||
break;
|
||||
case OPT_IS_TERMINAL:
|
||||
opt_is_terminal = true;
|
||||
break;
|
||||
case OPT_IS_WEAK:
|
||||
opt_is_weak = true;
|
||||
break;
|
||||
case OPT_MERGE:
|
||||
opt_merge = true;
|
||||
break;
|
||||
case OPT_MASK_ACC:
|
||||
{
|
||||
for (auto res : to_longs(arg))
|
||||
{
|
||||
if (res < 0)
|
||||
error(2, 0, "acceptance sets should be non-negative:"
|
||||
" --mask-acc=%ld", res);
|
||||
if (static_cast<unsigned long>(res)
|
||||
> sizeof(spot::acc_cond::mark_t::value_t))
|
||||
error(2, 0, "this implementation does not support that many"
|
||||
" acceptance sets: --mask-acc=%ld", res);
|
||||
opt_mask_acc.set(res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OPT_KEEP_STATES:
|
||||
{
|
||||
std::vector<long> values = to_longs(arg);
|
||||
if (!values.empty())
|
||||
opt_keep_states_initial = values[0];
|
||||
for (auto res : values)
|
||||
{
|
||||
if (res < 0)
|
||||
error(2, 0, "state ids should be non-negative:"
|
||||
" --mask-acc=%ld", res);
|
||||
// We don't know yet how many states the automata contain.
|
||||
if (opt_keep_states.size() <= static_cast<unsigned long>(res))
|
||||
opt_keep_states.resize(res + 1, false);
|
||||
opt_keep_states[res] = true;
|
||||
}
|
||||
opt_rem_unreach = true;
|
||||
break;
|
||||
}
|
||||
case OPT_PRODUCT_AND:
|
||||
{
|
||||
auto a = read_automaton(arg, opt->dict);
|
||||
if (!opt->product_and)
|
||||
opt->product_and = std::move(a);
|
||||
else
|
||||
opt->product_and = spot::product(std::move(opt->product_and),
|
||||
std::move(a));
|
||||
}
|
||||
break;
|
||||
case OPT_PRODUCT_OR:
|
||||
{
|
||||
auto a = read_automaton(arg, opt->dict);
|
||||
if (!opt->product_or)
|
||||
opt->product_or = std::move(a);
|
||||
else
|
||||
opt->product_or = spot::product_or(std::move(opt->product_or),
|
||||
std::move(a));
|
||||
}
|
||||
break;
|
||||
case OPT_RANDOMIZE:
|
||||
if (arg)
|
||||
{
|
||||
for (auto p = arg; *p; ++p)
|
||||
switch (*p)
|
||||
{
|
||||
case 's':
|
||||
randomize_st = true;
|
||||
break;
|
||||
case 't':
|
||||
randomize_tr = true;
|
||||
break;
|
||||
default:
|
||||
error(2, 0, "unknown argument for --randomize: '%c'", *p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
randomize_tr = true;
|
||||
randomize_st = true;
|
||||
}
|
||||
break;
|
||||
case OPT_REM_AP:
|
||||
rem_ap.add_ap(arg);
|
||||
break;
|
||||
case OPT_REM_DEAD:
|
||||
opt_rem_dead = true;
|
||||
break;
|
||||
case OPT_REM_FIN:
|
||||
opt_rem_fin = true;
|
||||
break;
|
||||
case OPT_REM_UNREACH:
|
||||
opt_rem_unreach = true;
|
||||
break;
|
||||
case OPT_SAT_MINIMIZE:
|
||||
opt_sat_minimize = arg ? arg : "";
|
||||
break;
|
||||
case OPT_SEED:
|
||||
opt_seed = to_int(arg);
|
||||
break;
|
||||
case OPT_SEP_SETS:
|
||||
opt_sep_sets = true;
|
||||
break;
|
||||
case OPT_SIMPLIFY_EXCLUSIVE_AP:
|
||||
opt_simplify_exclusive_ap = true;
|
||||
opt_merge = true;
|
||||
break;
|
||||
case OPT_STATES:
|
||||
opt_states = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||
break;
|
||||
case OPT_STRIPACC:
|
||||
opt_stripacc = true;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class hoa_processor: public job_processor
|
||||
{
|
||||
private:
|
||||
spot::postprocessor& post;
|
||||
automaton_printer printer;
|
||||
public:
|
||||
|
||||
hoa_processor(spot::postprocessor& post)
|
||||
: post(post), printer(aut_input)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
process_formula(spot::formula, const char*, int)
|
||||
{
|
||||
SPOT_UNREACHABLE();
|
||||
}
|
||||
|
||||
int
|
||||
process_automaton(const spot::const_parsed_aut_ptr& haut,
|
||||
const char* filename)
|
||||
{
|
||||
spot::stopwatch sw;
|
||||
sw.start();
|
||||
|
||||
// If --stats or --name is used, duplicate the automaton so we
|
||||
// never modify the original automaton (e.g. with
|
||||
// merge_edges()) and the statistics about it make sense.
|
||||
auto aut = ((automaton_format == Stats) || opt_name)
|
||||
? spot::make_twa_graph(haut->aut, spot::twa::prop_set::all())
|
||||
: haut->aut;
|
||||
|
||||
// Preprocessing.
|
||||
|
||||
if (opt_stripacc)
|
||||
spot::strip_acceptance_here(aut);
|
||||
if (opt_merge)
|
||||
aut->merge_edges();
|
||||
if (opt_clean_acc || opt_rem_fin)
|
||||
cleanup_acceptance_here(aut);
|
||||
if (opt_sep_sets)
|
||||
separate_sets_here(aut);
|
||||
if (opt_complement_acc)
|
||||
aut->set_acceptance(aut->acc().num_sets(),
|
||||
aut->get_acceptance().complement());
|
||||
if (opt_complement)
|
||||
{
|
||||
if (!spot::is_deterministic(aut))
|
||||
{
|
||||
std::cerr << filename << ':'
|
||||
<< haut->loc << (": --complement currently supports "
|
||||
"only deterministic automata\n");
|
||||
exit(2);
|
||||
}
|
||||
aut = spot::dtwa_complement(aut);
|
||||
}
|
||||
if (opt_rem_fin)
|
||||
aut = remove_fin(aut);
|
||||
if (opt_dnf_acc)
|
||||
aut->set_acceptance(aut->acc().num_sets(),
|
||||
aut->get_acceptance().to_dnf());
|
||||
if (opt_cnf_acc)
|
||||
aut->set_acceptance(aut->acc().num_sets(),
|
||||
aut->get_acceptance().to_cnf());
|
||||
|
||||
// Filters.
|
||||
|
||||
bool matched = true;
|
||||
|
||||
matched &= opt_states.contains(aut->num_states());
|
||||
matched &= opt_edges.contains(aut->num_edges());
|
||||
matched &= opt_accsets.contains(aut->acc().num_sets());
|
||||
if (opt_is_complete)
|
||||
matched &= is_complete(aut);
|
||||
if (opt_is_deterministic)
|
||||
matched &= is_deterministic(aut);
|
||||
if (opt_is_deterministic)
|
||||
matched &= is_deterministic(aut);
|
||||
else if (opt_is_unambiguous)
|
||||
matched &= is_unambiguous(aut);
|
||||
if (opt_is_terminal)
|
||||
matched &= is_terminal_automaton(aut);
|
||||
else if (opt_is_weak)
|
||||
matched &= is_weak_automaton(aut);
|
||||
else if (opt_is_inherently_weak)
|
||||
matched &= is_inherently_weak_automaton(aut);
|
||||
if (opt->are_isomorphic)
|
||||
matched &= opt->isomorphism_checker->is_isomorphic(aut);
|
||||
if (opt_is_empty)
|
||||
matched &= aut->is_empty();
|
||||
if (opt->intersect)
|
||||
matched &= !spot::product(aut, opt->intersect)->is_empty();
|
||||
|
||||
// Drop or keep matched automata depending on the --invert option
|
||||
if (matched == opt_invert)
|
||||
return 0;
|
||||
|
||||
// Postprocessing.
|
||||
|
||||
if (opt_mask_acc)
|
||||
aut = mask_acc_sets(aut, opt_mask_acc & aut->acc().all_sets());
|
||||
|
||||
if (!excl_ap.empty())
|
||||
aut = excl_ap.constrain(aut, opt_simplify_exclusive_ap);
|
||||
|
||||
if (!rem_ap.empty())
|
||||
aut = rem_ap.strip(aut);
|
||||
|
||||
if (opt_destut)
|
||||
aut = spot::closure(std::move(aut));
|
||||
if (opt_instut == 1)
|
||||
aut = spot::sl(std::move(aut));
|
||||
else if (opt_instut == 2)
|
||||
aut = spot::sl2(std::move(aut));
|
||||
|
||||
if (!opt_keep_states.empty())
|
||||
aut = mask_keep_states(aut, opt_keep_states, opt_keep_states_initial);
|
||||
if (opt_rem_dead)
|
||||
aut->purge_dead_states();
|
||||
else if (opt_rem_unreach)
|
||||
aut->purge_unreachable_states();
|
||||
|
||||
if (opt->product_and)
|
||||
aut = spot::product(std::move(aut), opt->product_and);
|
||||
if (opt->product_or)
|
||||
aut = spot::product_or(std::move(aut), opt->product_or);
|
||||
|
||||
if (opt_decompose_strength)
|
||||
{
|
||||
aut = decompose_strength(aut, opt_decompose_strength);
|
||||
if (!aut)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (opt_sat_minimize)
|
||||
{
|
||||
aut = spot::sat_minimize(aut, opt_sat_minimize, sbacc);
|
||||
if (!aut)
|
||||
return 0;
|
||||
}
|
||||
|
||||
aut = post.run(aut, nullptr);
|
||||
|
||||
if (randomize_st || randomize_tr)
|
||||
spot::randomize(aut, randomize_st, randomize_tr);
|
||||
|
||||
const double conversion_time = sw.stop();
|
||||
|
||||
if (opt->uniq)
|
||||
{
|
||||
auto tmp =
|
||||
spot::canonicalize(make_twa_graph(aut,
|
||||
spot::twa::prop_set::all()));
|
||||
if (!opt->uniq->emplace(tmp->edge_vector().begin() + 1,
|
||||
tmp->edge_vector().end()).second)
|
||||
return 0;
|
||||
}
|
||||
|
||||
++match_count;
|
||||
|
||||
printer.print(aut, nullptr, filename, -1, conversion_time, haut);
|
||||
|
||||
if (opt_max_count >= 0 && match_count >= opt_max_count)
|
||||
abort_run = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
aborted(const spot::const_parsed_aut_ptr& h, const char* filename)
|
||||
{
|
||||
std::cerr << filename << ':' << h->loc << ": aborted input automaton\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
int
|
||||
process_file(const char* filename)
|
||||
{
|
||||
auto hp = spot::automaton_stream_parser(filename, opt_parse);
|
||||
int err = 0;
|
||||
while (!abort_run)
|
||||
{
|
||||
auto haut = hp.parse(opt->dict);
|
||||
if (!haut->aut && haut->errors.empty())
|
||||
break;
|
||||
if (haut->format_errors(std::cerr))
|
||||
err = 2;
|
||||
if (!haut->aut)
|
||||
error(2, 0, "failed to read automaton from %s", filename);
|
||||
else if (haut->aborted)
|
||||
err = std::max(err, aborted(haut, filename));
|
||||
else
|
||||
process_automaton(haut, filename);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[FILENAMES...]",
|
||||
argp_program_doc, children, nullptr, nullptr };
|
||||
|
||||
try
|
||||
{
|
||||
// This will ensure that all objects stored in this struct are
|
||||
// destroyed before global variables.
|
||||
opt_t o;
|
||||
opt = &o;
|
||||
|
||||
// Disable post-processing as much as possible by default.
|
||||
level = spot::postprocessor::Low;
|
||||
pref = spot::postprocessor::Any;
|
||||
type = spot::postprocessor::Generic;
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (level_set && !pref_set)
|
||||
pref = spot::postprocessor::Small;
|
||||
if (pref_set && !level_set)
|
||||
level = spot::postprocessor::High;
|
||||
|
||||
if (jobs.empty())
|
||||
jobs.emplace_back("-", true);
|
||||
|
||||
if (opt->are_isomorphic)
|
||||
{
|
||||
if (opt_merge)
|
||||
opt->are_isomorphic->merge_edges();
|
||||
opt->isomorphism_checker = std::unique_ptr<spot::isomorphism_checker>
|
||||
(new spot::isomorphism_checker(opt->are_isomorphic));
|
||||
}
|
||||
|
||||
|
||||
spot::srand(opt_seed);
|
||||
|
||||
spot::postprocessor post(&extra_options);
|
||||
post.set_pref(pref | comp | sbacc);
|
||||
post.set_type(type);
|
||||
post.set_level(level);
|
||||
|
||||
hoa_processor processor(post);
|
||||
if (processor.run())
|
||||
return 2;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
catch (const std::invalid_argument& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
|
||||
if (automaton_format == Count)
|
||||
std::cout << match_count << std::endl;
|
||||
|
||||
return !match_count;
|
||||
}
|
||||
|
|
@ -1,368 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include "error.h"
|
||||
#include "argmatch.h"
|
||||
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_post.hh"
|
||||
#include "common_cout.hh"
|
||||
|
||||
#include <spot/twa/bddprint.hh>
|
||||
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/lbtt.hh>
|
||||
#include <spot/twaalgos/hoa.hh>
|
||||
#include <spot/twaalgos/neverclaim.hh>
|
||||
#include <spot/twaalgos/stutter.hh>
|
||||
#include <spot/twaalgos/isunamb.hh>
|
||||
#include <spot/twaalgos/strength.hh>
|
||||
|
||||
automaton_format_t automaton_format = Dot;
|
||||
static const char* opt_dot = nullptr;
|
||||
static const char* opt_never = nullptr;
|
||||
static const char* hoa_opt = nullptr;
|
||||
static const char* opt_lbtt = nullptr;
|
||||
const char* opt_name = nullptr;
|
||||
static const char* opt_output = nullptr;
|
||||
static const char* stats = "";
|
||||
enum check_type
|
||||
{
|
||||
check_unambiguous = (1 << 0),
|
||||
check_stutter = (1 << 1),
|
||||
check_strength = (1 << 2),
|
||||
check_all = -1U,
|
||||
};
|
||||
static char const *const check_args[] =
|
||||
{
|
||||
"unambiguous",
|
||||
"stutter-invariant", "stuttering-invariant",
|
||||
"stutter-insensitive", "stuttering-insensitive",
|
||||
"stutter-sensitive", "stuttering-sensitive",
|
||||
"strength", "weak", "terminal",
|
||||
"all",
|
||||
nullptr
|
||||
};
|
||||
static check_type const check_types[] =
|
||||
{
|
||||
check_unambiguous,
|
||||
check_stutter, check_stutter,
|
||||
check_stutter, check_stutter,
|
||||
check_stutter, check_stutter,
|
||||
check_strength, check_strength, check_strength,
|
||||
check_all
|
||||
};
|
||||
ARGMATCH_VERIFY(check_args, check_types);
|
||||
unsigned opt_check = 0U;
|
||||
|
||||
enum {
|
||||
OPT_DOT = 1,
|
||||
OPT_LBTT,
|
||||
OPT_NAME,
|
||||
OPT_STATS,
|
||||
OPT_CHECK,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output format:", 3 },
|
||||
{ "dot", OPT_DOT, "1|a|b|B|c|e|f(FONT)|h|n|N|o|r|R|s|t|v|+INT",
|
||||
OPTION_ARG_OPTIONAL,
|
||||
"GraphViz's format (default). Add letters for "
|
||||
"(1) force numbered states, "
|
||||
"(a) acceptance display, (b) acceptance sets as bullets, "
|
||||
"(B) bullets except for Büchi/co-Büchi automata, "
|
||||
"(c) force circular nodes, (e) force elliptic nodes, "
|
||||
"(f(FONT)) use FONT, (h) horizontal layout, "
|
||||
"(v) vertical layout, (n) with name, (N) without name, "
|
||||
"(o) ordered transitions, "
|
||||
"(r) rainbow colors for acceptance sets, "
|
||||
"(R) color acceptance sets by Inf/Fin, (s) with SCCs, "
|
||||
"(t) force transition-based acceptance, "
|
||||
"(+INT) add INT to all set numbers", 0 },
|
||||
{ "hoaf", 'H', "i|l|m|s|t|v", OPTION_ARG_OPTIONAL,
|
||||
"Output the automaton in HOA format. Add letters to select "
|
||||
"(i) use implicit labels for complete deterministic automata, "
|
||||
"(s) prefer state-based acceptance when possible [default], "
|
||||
"(t) force transition-based acceptance, "
|
||||
"(m) mix state and transition-based acceptance, "
|
||||
"(k) use state labels when possible, "
|
||||
"(l) single-line output, "
|
||||
"(v) verbose properties", 0 },
|
||||
{ "lbtt", OPT_LBTT, "t", OPTION_ARG_OPTIONAL,
|
||||
"LBTT's format (add =t to force transition-based acceptance even"
|
||||
" on Büchi automata)", 0 },
|
||||
{ "name", OPT_NAME, "FORMAT", 0,
|
||||
"set the name of the output automaton", 0 },
|
||||
{ "output", 'o', "FORMAT", 0,
|
||||
"send output to a file named FORMAT instead of standard output. The"
|
||||
" first automaton sent to a file truncates it unless FORMAT starts"
|
||||
" with '>>'.", 0 },
|
||||
{ "quiet", 'q', nullptr, 0, "suppress all normal output", 0 },
|
||||
{ "spin", 's', "6|c", OPTION_ARG_OPTIONAL, "Spin neverclaim (implies --ba)."
|
||||
" Add letters to select (6) Spin's 6.2.4 style, (c) comments on states",
|
||||
0 },
|
||||
{ "utf8", '8', nullptr, 0, "enable UTF-8 characters in output "
|
||||
"(ignored with --lbtt or --spin)", 0 },
|
||||
{ "stats", OPT_STATS, "FORMAT", 0,
|
||||
"output statistics about the automaton", 0 },
|
||||
{ "check", OPT_CHECK, "PROP", OPTION_ARG_OPTIONAL,
|
||||
"test for the additional property PROP and output the result "
|
||||
"in the HOA format (implies -H). PROP may be any prefix of "
|
||||
"'all' (default), 'unambiguous', 'stutter-invariant', or 'strength'.",
|
||||
0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp aoutput_argp = { options, parse_opt_aoutput, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr };
|
||||
|
||||
// Those can be overridden by individual tools. E.g. randaut has no
|
||||
// notion of input file, so %F and %L represent something else.
|
||||
char F_doc[32] = "name of the input file";
|
||||
char L_doc[32] = "location in the input file";
|
||||
|
||||
static const argp_option io_options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Any FORMAT string may use "\
|
||||
"the following interpreted sequences (capitals for input,"
|
||||
" minuscules for output):", 4 },
|
||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, F_doc, 0 },
|
||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, L_doc, 0 },
|
||||
{ "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"name of the automaton", 0 },
|
||||
{ "%S, %s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of states", 0 },
|
||||
{ "%E, %e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of edges", 0 },
|
||||
{ "%T, %t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of transitions", 0 },
|
||||
{ "%A, %a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of acceptance sets", 0 },
|
||||
{ "%G, %g", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"acceptance condition (in HOA syntax)", 0 },
|
||||
{ "%C, %c", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of SCCs", 0 },
|
||||
{ "%n", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of nondeterministic states in output", 0 },
|
||||
{ "%d", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"1 if the output is deterministic, 0 otherwise", 0 },
|
||||
{ "%p", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"1 if the output is complete, 0 otherwise", 0 },
|
||||
{ "%r", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"processing time (excluding parsing) in seconds", 0 },
|
||||
{ "%w", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"one word accepted by the output automaton", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"a single %", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp aoutput_io_format_argp = { io_options, nullptr, nullptr,
|
||||
nullptr, nullptr,
|
||||
nullptr, nullptr };
|
||||
|
||||
static const argp_option o_options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Any FORMAT string may use "\
|
||||
"the following interpreted sequences:", 4 },
|
||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, F_doc, 0 },
|
||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, L_doc, 0 },
|
||||
{ "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"name of the automaton", 0 },
|
||||
{ "%s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of states", 0 },
|
||||
{ "%e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of edges", 0 },
|
||||
{ "%t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of transitions", 0 },
|
||||
{ "%a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of acceptance sets", 0 },
|
||||
{ "%g", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"acceptance condition (in HOA syntax)", 0 },
|
||||
{ "%c", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of SCCs", 0 },
|
||||
{ "%n", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of nondeterministic states in output", 0 },
|
||||
{ "%d", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"1 if the output is deterministic, 0 otherwise", 0 },
|
||||
{ "%p", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"1 if the output is complete, 0 otherwise", 0 },
|
||||
{ "%r", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"processing time (excluding parsing) in seconds", 0 },
|
||||
{ "%w", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"one word accepted by the output automaton", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"a single %", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp aoutput_o_format_argp = { o_options,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr };
|
||||
|
||||
int parse_opt_aoutput(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case '8':
|
||||
spot::enable_utf8();
|
||||
break;
|
||||
case 'H':
|
||||
automaton_format = Hoa;
|
||||
hoa_opt = arg;
|
||||
break;
|
||||
case 'q':
|
||||
automaton_format = Quiet;
|
||||
break;
|
||||
case 's':
|
||||
automaton_format = Spin;
|
||||
if (type != spot::postprocessor::Monitor)
|
||||
type = spot::postprocessor::BA;
|
||||
if (arg)
|
||||
opt_never = arg;
|
||||
break;
|
||||
case 'o':
|
||||
opt_output = arg;
|
||||
break;
|
||||
case OPT_CHECK:
|
||||
automaton_format = Hoa;
|
||||
if (arg)
|
||||
opt_check |= XARGMATCH("--check", arg, check_args, check_types);
|
||||
else
|
||||
opt_check |= check_all;
|
||||
break;
|
||||
case OPT_DOT:
|
||||
automaton_format = Dot;
|
||||
opt_dot = arg;
|
||||
break;
|
||||
case OPT_LBTT:
|
||||
automaton_format = Lbtt;
|
||||
opt_lbtt = arg;
|
||||
// This test could be removed when more options are added,
|
||||
// because print_lbtt will raise an exception anyway. The
|
||||
// error message is slightly better in the current way.
|
||||
if (arg && (arg[0] != 't' || arg[1] != 0))
|
||||
error(2, 0, "unknown argument for --lbtt: '%s'", arg);
|
||||
break;
|
||||
case OPT_NAME:
|
||||
opt_name = arg;
|
||||
break;
|
||||
case OPT_STATS:
|
||||
if (!*arg)
|
||||
error(2, 0, "empty format string for --stats");
|
||||
stats = arg;
|
||||
automaton_format = Stats;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
automaton_printer::automaton_printer(stat_style input)
|
||||
: statistics(std::cout, stats, input),
|
||||
namer(name, opt_name, input),
|
||||
outputnamer(outputname, opt_output, input)
|
||||
{
|
||||
if (automaton_format == Count && opt_output)
|
||||
throw std::runtime_error
|
||||
("options --output and --count are incompatible");
|
||||
}
|
||||
|
||||
void
|
||||
automaton_printer::print(const spot::twa_graph_ptr& aut,
|
||||
spot::formula f,
|
||||
// Input location for errors and statistics.
|
||||
const char* filename,
|
||||
int loc,
|
||||
// Time and input automaton for statistics
|
||||
double time,
|
||||
const spot::const_parsed_aut_ptr& haut)
|
||||
{
|
||||
if (opt_check)
|
||||
{
|
||||
if (opt_check & check_stutter)
|
||||
spot::check_stutter_invariance(aut, f);
|
||||
if (opt_check & check_unambiguous)
|
||||
spot::check_unambiguous(aut);
|
||||
if (opt_check & check_strength)
|
||||
spot::check_strength(aut);
|
||||
}
|
||||
|
||||
// Name the output automaton.
|
||||
if (opt_name)
|
||||
{
|
||||
name.str("");
|
||||
namer.print(haut, aut, f, filename, loc, time);
|
||||
aut->set_named_prop("automaton-name", new std::string(name.str()));
|
||||
}
|
||||
|
||||
std::ostream* out = &std::cout;
|
||||
if (opt_output)
|
||||
{
|
||||
outputname.str("");
|
||||
outputnamer.print(haut, aut, f, filename, loc, time);
|
||||
std::string fname = outputname.str();
|
||||
auto p = outputfiles.emplace(fname, nullptr);
|
||||
if (p.second)
|
||||
p.first->second.reset(new output_file(fname.c_str()));
|
||||
out = &p.first->second->ostream();
|
||||
}
|
||||
|
||||
// Output it.
|
||||
switch (automaton_format)
|
||||
{
|
||||
case Count:
|
||||
case Quiet:
|
||||
// Do not output anything.
|
||||
break;
|
||||
case Dot:
|
||||
spot::print_dot(*out, aut, opt_dot);
|
||||
break;
|
||||
case Lbtt:
|
||||
spot::print_lbtt(*out, aut, opt_lbtt);
|
||||
break;
|
||||
case Hoa:
|
||||
spot::print_hoa(*out, aut, hoa_opt) << '\n';
|
||||
break;
|
||||
case Spin:
|
||||
spot::print_never_claim(*out, aut, opt_never);
|
||||
break;
|
||||
case Stats:
|
||||
statistics.set_output(*out);
|
||||
statistics.print(haut, aut, f, filename, loc, time) << '\n';
|
||||
break;
|
||||
}
|
||||
flush_cout();
|
||||
}
|
||||
|
||||
void automaton_printer::add_stat(char c, const spot::printable* p)
|
||||
{
|
||||
namer.declare(c, p);
|
||||
statistics.declare(c, p);
|
||||
outputnamer.declare(c, p);
|
||||
}
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <argp.h>
|
||||
#include <memory>
|
||||
|
||||
#include <spot/parseaut/public.hh>
|
||||
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include <spot/twaalgos/sccinfo.hh>
|
||||
#include <spot/twaalgos/gtec/gtec.hh>
|
||||
#include <spot/twaalgos/word.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
#include "common_file.hh"
|
||||
|
||||
|
||||
// Format for automaton output
|
||||
enum automaton_format_t {
|
||||
Dot,
|
||||
Lbtt,
|
||||
Spin,
|
||||
Stats,
|
||||
Hoa,
|
||||
Quiet,
|
||||
Count,
|
||||
};
|
||||
|
||||
// The format to use in output_automaton()
|
||||
extern automaton_format_t automaton_format;
|
||||
// Set to the argument of --name, else nullptr.
|
||||
extern const char* opt_name;
|
||||
// Output options
|
||||
extern const struct argp aoutput_argp;
|
||||
|
||||
// help text for %F and %L
|
||||
extern char F_doc[32];
|
||||
extern char L_doc[32];
|
||||
|
||||
// FORMAT help text
|
||||
extern const struct argp aoutput_io_format_argp;
|
||||
extern const struct argp aoutput_o_format_argp;
|
||||
|
||||
// Parse output options
|
||||
int parse_opt_aoutput(int key, char* arg, struct argp_state* state);
|
||||
|
||||
|
||||
enum stat_style { no_input, aut_input, ltl_input };
|
||||
|
||||
/// \brief prints various statistics about a TGBA
|
||||
///
|
||||
/// This object can be configured to display various statistics
|
||||
/// about a TGBA. Some %-sequence of characters are interpreted in
|
||||
/// the format string, and replaced by the corresponding statistics.
|
||||
class hoa_stat_printer: protected spot::stat_printer
|
||||
{
|
||||
public:
|
||||
hoa_stat_printer(std::ostream& os, const char* format,
|
||||
stat_style input = no_input)
|
||||
: spot::stat_printer(os, format)
|
||||
{
|
||||
if (input == aut_input)
|
||||
{
|
||||
declare('A', &haut_acc_);
|
||||
declare('C', &haut_scc_);
|
||||
declare('E', &haut_edges_);
|
||||
declare('G', &haut_gen_acc_);
|
||||
declare('M', &haut_name_);
|
||||
declare('S', &haut_states_);
|
||||
declare('T', &haut_trans_);
|
||||
}
|
||||
declare('F', &filename_);
|
||||
declare('L', &location_);
|
||||
if (input != ltl_input)
|
||||
declare('f', &filename_); // Override the formula printer.
|
||||
declare('m', &aut_name_);
|
||||
declare('w', &aut_word_);
|
||||
}
|
||||
|
||||
using spot::formater::declare;
|
||||
using spot::formater::set_output;
|
||||
|
||||
/// \brief print the configured statistics.
|
||||
///
|
||||
/// The \a f argument is not needed if the Formula does not need
|
||||
/// to be output.
|
||||
std::ostream&
|
||||
print(const spot::const_parsed_aut_ptr& haut,
|
||||
const spot::const_twa_graph_ptr& aut,
|
||||
spot::formula f,
|
||||
const char* filename, int loc, double run_time)
|
||||
{
|
||||
filename_ = filename ? filename : "";
|
||||
if (loc >= 0 && has('L'))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << loc;
|
||||
location_ = os.str();
|
||||
}
|
||||
if (haut)
|
||||
{
|
||||
if (loc < 0 && has('L'))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << haut->loc;
|
||||
location_ = os.str();
|
||||
}
|
||||
|
||||
if (has('T'))
|
||||
{
|
||||
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
|
||||
haut_states_ = s.states;
|
||||
haut_edges_ = s.edges;
|
||||
haut_trans_ = s.transitions;
|
||||
}
|
||||
else if (has('E'))
|
||||
{
|
||||
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
|
||||
haut_states_ = s.states;
|
||||
haut_edges_ = s.edges;
|
||||
}
|
||||
if (has('M'))
|
||||
{
|
||||
auto n = haut->aut->get_named_prop<std::string>("automaton-name");
|
||||
if (n)
|
||||
haut_name_ = *n;
|
||||
else
|
||||
haut_name_.val().clear();
|
||||
}
|
||||
if (has('S'))
|
||||
haut_states_ = haut->aut->num_states();
|
||||
|
||||
if (has('A'))
|
||||
haut_acc_ = haut->aut->acc().num_sets();
|
||||
|
||||
if (has('C'))
|
||||
haut_scc_ = spot::scc_info(haut->aut).scc_count();
|
||||
|
||||
if (has('G'))
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << haut->aut->get_acceptance();
|
||||
haut_gen_acc_ = os.str();
|
||||
}
|
||||
}
|
||||
|
||||
if (has('m'))
|
||||
{
|
||||
auto n = aut->get_named_prop<std::string>("automaton-name");
|
||||
if (n)
|
||||
aut_name_ = *n;
|
||||
else
|
||||
aut_name_.val().clear();
|
||||
}
|
||||
if (has('w'))
|
||||
{
|
||||
auto res = spot::couvreur99(aut)->check();
|
||||
if (res)
|
||||
{
|
||||
auto run = res->accepting_run();
|
||||
assert(run);
|
||||
spot::twa_word w(run->reduce());
|
||||
w.simplify();
|
||||
std::ostringstream out;
|
||||
out << w;
|
||||
aut_word_ = out.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
aut_word_.val().clear();
|
||||
}
|
||||
}
|
||||
|
||||
return this->spot::stat_printer::print(aut, f, run_time);
|
||||
}
|
||||
|
||||
private:
|
||||
spot::printable_value<const char*> filename_;
|
||||
spot::printable_value<std::string> location_;
|
||||
spot::printable_value<std::string> haut_name_;
|
||||
spot::printable_value<std::string> aut_name_;
|
||||
spot::printable_value<std::string> aut_word_;
|
||||
spot::printable_value<std::string> haut_gen_acc_;
|
||||
spot::printable_value<unsigned> haut_states_;
|
||||
spot::printable_value<unsigned> haut_edges_;
|
||||
spot::printable_value<unsigned> haut_trans_;
|
||||
spot::printable_value<unsigned> haut_acc_;
|
||||
spot::printable_value<unsigned> haut_scc_;
|
||||
};
|
||||
|
||||
|
||||
class automaton_printer
|
||||
{
|
||||
hoa_stat_printer statistics;
|
||||
std::ostringstream name;
|
||||
hoa_stat_printer namer;
|
||||
std::ostringstream outputname;
|
||||
hoa_stat_printer outputnamer;
|
||||
std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
||||
|
||||
public:
|
||||
|
||||
automaton_printer(stat_style input = no_input);
|
||||
|
||||
void
|
||||
print(const spot::twa_graph_ptr& aut,
|
||||
spot::formula f = nullptr,
|
||||
// Input location for errors and statistics.
|
||||
const char* filename = nullptr,
|
||||
int loc = -1,
|
||||
// Time and input automaton for statistics
|
||||
double time = 0.0,
|
||||
const spot::const_parsed_aut_ptr& haut = nullptr);
|
||||
|
||||
void add_stat(char c, const spot::printable* p);
|
||||
};
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_conv.hh"
|
||||
#include <cstdlib>
|
||||
#include "error.h"
|
||||
|
||||
int
|
||||
to_int(const char* s)
|
||||
{
|
||||
char* endptr;
|
||||
int res = strtol(s, &endptr, 10);
|
||||
if (*endptr)
|
||||
error(2, 0, "failed to parse '%s' as an integer.", s);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
to_pos_int(const char* s)
|
||||
{
|
||||
int res = to_int(s);
|
||||
if (res < 0)
|
||||
error(2, 0, "%d is not positive", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
unsigned
|
||||
to_unsigned (const char *s)
|
||||
{
|
||||
char* endptr;
|
||||
unsigned res = strtoul(s, &endptr, 10);
|
||||
if (*endptr)
|
||||
error(2, 0, "failed to parse '%s' as an unsigned integer.", s);
|
||||
return res;
|
||||
}
|
||||
|
||||
float
|
||||
to_float(const char* s)
|
||||
{
|
||||
char* endptr;
|
||||
float res = strtof(s, &endptr);
|
||||
if (*endptr)
|
||||
error(2, 0, "failed to parse '%s' as a float.", s);
|
||||
return res;
|
||||
}
|
||||
|
||||
float
|
||||
to_probability(const char* s)
|
||||
{
|
||||
float res = to_float(s);
|
||||
if (res < 0.0 || res > 1.0)
|
||||
error(2, 0, "%f is not between 0 and 1.", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<long>
|
||||
to_longs(const char* arg)
|
||||
{
|
||||
std::vector<long> res;
|
||||
while (*arg)
|
||||
{
|
||||
char* endptr;
|
||||
long value = strtol(arg, &endptr, 10);
|
||||
if (endptr == arg)
|
||||
error(2, 0, "failed to parse '%s' as an integer.", arg);
|
||||
res.push_back(value);
|
||||
while (*endptr == ' ' || *endptr == ',')
|
||||
++endptr;
|
||||
arg = endptr;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <spot/twa/twagraph.hh>
|
||||
|
||||
int to_int(const char* s);
|
||||
int to_pos_int(const char* s);
|
||||
unsigned to_unsigned (const char *s);
|
||||
float to_float(const char* s);
|
||||
float to_probability(const char* s);
|
||||
|
||||
// Parse the comma or space seperate string of numbers.
|
||||
std::vector<long> to_longs(const char* s);
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include "common_cout.hh"
|
||||
#include <iostream>
|
||||
#include "error.h"
|
||||
|
||||
void check_cout()
|
||||
{
|
||||
// Make sure we abort if we can't write to std::cout anymore
|
||||
// (like disk full or broken pipe with SIGPIPE ignored).
|
||||
if (!std::cout)
|
||||
error(2, 0, "error writing to standard output");
|
||||
}
|
||||
|
||||
void flush_cout()
|
||||
{
|
||||
std::cout.flush();
|
||||
check_cout();
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
void check_cout();
|
||||
void flush_cout();
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_file.hh"
|
||||
#include <error.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
output_file::output_file(const char* name)
|
||||
{
|
||||
std::ios_base::openmode mode = std::ios_base::trunc;
|
||||
if (name[0] == '>' && name[1] == '>')
|
||||
{
|
||||
mode = std::ios_base::app;
|
||||
append_ = true;
|
||||
name += 2;
|
||||
}
|
||||
if (name[0] == '-' && name[1] == 0)
|
||||
{
|
||||
os_ = &std::cout;
|
||||
return;
|
||||
}
|
||||
of_ = new std::ofstream(name, mode);
|
||||
if (!*of_)
|
||||
error(2, errno, "cannot open '%s'", name);
|
||||
os_ = of_;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <iosfwd>
|
||||
#include <fstream>
|
||||
|
||||
class output_file
|
||||
{
|
||||
std::ostream* os_;
|
||||
std::ofstream* of_ = nullptr;
|
||||
bool append_ = false;
|
||||
public:
|
||||
// Open a file for output. "-" is interpreted as stdout.
|
||||
// Names that start with ">>" are opened for append.
|
||||
// The function calls error() on... error.
|
||||
output_file(const char* name);
|
||||
|
||||
~output_file()
|
||||
{
|
||||
delete of_;
|
||||
}
|
||||
|
||||
bool append() const
|
||||
{
|
||||
return append_;
|
||||
}
|
||||
|
||||
std::ostream& ostream()
|
||||
{
|
||||
return *os_;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,356 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_finput.hh"
|
||||
#include "error.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
|
||||
enum {
|
||||
OPT_LBT = 1,
|
||||
OPT_LENIENT,
|
||||
};
|
||||
|
||||
jobs_t jobs;
|
||||
bool lbt_input = false;
|
||||
static bool lenient = false;
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
{ nullptr, 0, nullptr, 0, "Input options:", 1 },
|
||||
{ "formula", 'f', "STRING", 0, "process the formula STRING", 0 },
|
||||
{ "file", 'F', "FILENAME[/COL]", 0,
|
||||
"process each line of FILENAME as a formula; if COL is a "
|
||||
"positive integer, assume a CSV file and read column COL; use "
|
||||
"a negative COL to drop the first line of the CSV file", 0 },
|
||||
{ "lbt-input", OPT_LBT, nullptr, 0,
|
||||
"read all formulas using LBT's prefix syntax", 0 },
|
||||
{ "lenient", OPT_LENIENT, nullptr, 0,
|
||||
"parenthesized blocks that cannot be parsed as subformulas "
|
||||
"are considered as atomic properties", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp finput_argp = { options, parse_opt_finput,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr };
|
||||
|
||||
int
|
||||
parse_opt_finput(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'f':
|
||||
jobs.emplace_back(arg, false);
|
||||
break;
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
case OPT_LBT:
|
||||
lbt_input = true;
|
||||
break;
|
||||
case OPT_LENIENT:
|
||||
lenient = true;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
spot::formula
|
||||
parse_formula(const std::string& s, spot::parse_error_list& pel)
|
||||
{
|
||||
if (lbt_input)
|
||||
return spot::parse_prefix_ltl(s, pel);
|
||||
else
|
||||
return spot::parse_infix_psl
|
||||
(s, pel, spot::default_environment::instance(), false, lenient);
|
||||
}
|
||||
|
||||
job_processor::job_processor()
|
||||
: abort_run(false), real_filename(nullptr),
|
||||
col_to_read(0), prefix(nullptr), suffix(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
job_processor::~job_processor()
|
||||
{
|
||||
if (real_filename)
|
||||
free(real_filename);
|
||||
if (prefix)
|
||||
free(prefix);
|
||||
if (suffix)
|
||||
free(suffix);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
job_processor::process_string(const std::string& input,
|
||||
const char* filename,
|
||||
int linenum)
|
||||
{
|
||||
spot::parse_error_list pel;
|
||||
auto f = parse_formula(input, pel);
|
||||
|
||||
if (!f || !pel.empty())
|
||||
{
|
||||
if (filename)
|
||||
error_at_line(0, 0, filename, linenum, "parse error:");
|
||||
spot::format_parse_errors(std::cerr, input, pel);
|
||||
return 1;
|
||||
}
|
||||
return process_formula(f, filename, linenum);
|
||||
}
|
||||
|
||||
int
|
||||
job_processor::process_stream(std::istream& is,
|
||||
const char* filename)
|
||||
{
|
||||
int error = 0;
|
||||
int linenum = 1;
|
||||
std::string line;
|
||||
|
||||
// Discard the first line of a CSV file if requested.
|
||||
if (col_to_read < 0)
|
||||
{
|
||||
std::getline(is, line);
|
||||
col_to_read = -col_to_read;
|
||||
++linenum;
|
||||
}
|
||||
|
||||
// Each line of the file and send them to process_string,
|
||||
// optionally extracting a column of a CSV file.
|
||||
while (!abort_run && std::getline(is, line))
|
||||
if (!line.empty())
|
||||
{
|
||||
if (col_to_read == 0)
|
||||
{
|
||||
error |= process_string(line, filename, linenum++);
|
||||
}
|
||||
else // We are reading column COL_TO_READ in a CSV file.
|
||||
{
|
||||
// If the line we have read contains an odd number
|
||||
// of double-quotes, then it is an incomplete CSV line
|
||||
// that should be completed by the next lines.
|
||||
unsigned dquotes = 0;
|
||||
std::string fullline;
|
||||
unsigned csvlines = 0;
|
||||
do
|
||||
{
|
||||
++csvlines;
|
||||
size_t s = line.size();
|
||||
for (unsigned i = 0; i < s; ++i)
|
||||
dquotes += line[i] == '"';
|
||||
if (fullline.empty())
|
||||
fullline = line;
|
||||
else
|
||||
(fullline += '\n') += line;
|
||||
if (!(dquotes &= 1))
|
||||
break;
|
||||
}
|
||||
while (std::getline(is, line));
|
||||
if (dquotes)
|
||||
error_at_line(2, errno, filename, linenum,
|
||||
"mismatched double-quote, "
|
||||
"reached EOF while parsing this line");
|
||||
|
||||
// Now that we have a full CSV line, extract the right
|
||||
// column.
|
||||
|
||||
const char* str = fullline.c_str();
|
||||
const char* col1_start = str;
|
||||
// Delimiters for the extracted column.
|
||||
const char* coln_start = str;
|
||||
const char* coln_end = nullptr;
|
||||
// The current column. (1-based)
|
||||
int colnum = 1;
|
||||
// Whether we are parsing a double-quoted string.
|
||||
bool instring = false;
|
||||
// Note that RFC 4180 has strict rules about
|
||||
// double-quotes: ① if a field is double-quoted, the first
|
||||
// and last characters of the field should be
|
||||
// double-quotes; ② if a field contains a double-quote
|
||||
// then it should be double quoted, and the occurrences
|
||||
// of double-quotes should be doubled. Therefore a CSV file
|
||||
// may no contain a line such as:
|
||||
// foo,bar"ba""z",12
|
||||
// Tools have different interpretation of such a line.
|
||||
// For instance Python's pandas.read_csv() function will
|
||||
// load the second field verbatim as the string 'bar"ba""z"',
|
||||
// while R's read.csv() function will load it as the
|
||||
// string 'barba"z'. We use this second interpretation, because
|
||||
// it also makes it possible to parse CSVs fields formatted
|
||||
// with leading spaces (often for cosmetic purpose). When
|
||||
// extracting the second field of
|
||||
// foo, "ba""z", 12
|
||||
// we will return ' baz' and the leading space will be ignored
|
||||
// by our LTL formula parser.
|
||||
while (*str)
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case '"':
|
||||
// Doubled double-quotes are used to escape
|
||||
// double-quotes.
|
||||
if (instring && str[1] == '"')
|
||||
++str;
|
||||
else
|
||||
instring = !instring;
|
||||
break;
|
||||
case ',':
|
||||
if (!instring)
|
||||
{
|
||||
if (col_to_read == colnum)
|
||||
coln_end = str;
|
||||
++colnum;
|
||||
if (col_to_read == colnum)
|
||||
coln_start = str + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Once we have the end delimiter for our target
|
||||
// column, we have all we need.
|
||||
if (coln_end)
|
||||
break;
|
||||
++str;
|
||||
}
|
||||
if (!*str)
|
||||
{
|
||||
if (colnum != col_to_read)
|
||||
// Skip this line as it has no enough columns.
|
||||
continue;
|
||||
else
|
||||
// The target columns ends at the end of the line.
|
||||
coln_end = str;
|
||||
}
|
||||
|
||||
// Skip the line if it has an empty field.
|
||||
if (coln_start == coln_end)
|
||||
continue;
|
||||
|
||||
// save the contents before and after that columns for the
|
||||
// %< and %> escapes (ignoring the trailing and leading
|
||||
// commas).
|
||||
prefix = (col_to_read != 1) ?
|
||||
strndup(col1_start, coln_start - col1_start - 1) : nullptr;
|
||||
suffix = (*coln_end != 0) ? strdup(coln_end + 1) : nullptr;
|
||||
std::string field(coln_start, coln_end);
|
||||
// Remove double-quotes if any.
|
||||
if (field.find('"') != std::string::npos)
|
||||
{
|
||||
unsigned dst = 0;
|
||||
bool instring = false;
|
||||
for (; coln_start != coln_end; ++coln_start)
|
||||
if (*coln_start == '"')
|
||||
// A doubled double-quote instead a double-quoted
|
||||
// string is an escaped double-quote.
|
||||
if (instring && coln_start[1] == '"')
|
||||
field[dst++] = *++coln_start;
|
||||
else
|
||||
instring = !instring;
|
||||
else
|
||||
field[dst++] = *coln_start;
|
||||
field.resize(dst);
|
||||
}
|
||||
error |= process_string(field, filename, linenum);
|
||||
linenum += csvlines;
|
||||
if (prefix)
|
||||
{
|
||||
free(prefix);
|
||||
prefix = nullptr;
|
||||
}
|
||||
if (suffix)
|
||||
{
|
||||
free(suffix);
|
||||
suffix = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
job_processor::process_file(const char* filename)
|
||||
{
|
||||
// Special case for stdin.
|
||||
if (filename[0] == '-' && filename[1] == 0)
|
||||
return process_stream(std::cin, filename);
|
||||
|
||||
errno = 0;
|
||||
std::ifstream input(filename);
|
||||
if (input)
|
||||
return process_stream(input, filename);
|
||||
int saved_errno = errno;
|
||||
|
||||
// If we have a filename like "foo/NN" such
|
||||
// that:
|
||||
// ① foo/NN is not a file (already the case),
|
||||
// ② NN is a number > 0,
|
||||
// ③ foo is a file,
|
||||
// then it means we want to open foo as
|
||||
// a CSV file and process column NN.
|
||||
|
||||
if (const char* slash = strrchr(filename, '/'))
|
||||
{
|
||||
char* end;
|
||||
errno = 0;
|
||||
long int col = strtol(slash + 1, &end, 10);
|
||||
// strtol ate all remaining characters and NN is positive
|
||||
if (errno == 0 && !*end && col != 0)
|
||||
{
|
||||
col_to_read = col;
|
||||
if (real_filename)
|
||||
free(real_filename);
|
||||
real_filename = strndup(filename, slash - filename);
|
||||
|
||||
// Special case for stdin.
|
||||
if (real_filename[0] == '-' && real_filename[1] == 0)
|
||||
return process_stream(std::cin, real_filename);
|
||||
|
||||
std::ifstream input(real_filename);
|
||||
if (input)
|
||||
return process_stream(input, real_filename);
|
||||
|
||||
error(2, errno, "cannot open '%s' nor '%s'",
|
||||
filename, real_filename);
|
||||
}
|
||||
}
|
||||
|
||||
error(2, saved_errno, "cannot open '%s'", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
job_processor::run()
|
||||
{
|
||||
int error = 0;
|
||||
for (auto& j: jobs)
|
||||
{
|
||||
if (!j.file_p)
|
||||
error |= process_string(j.str);
|
||||
else
|
||||
error |= process_file(j.str);
|
||||
if (abort_run)
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <argp.h>
|
||||
#include <vector>
|
||||
#include <spot/tl/parse.hh>
|
||||
|
||||
struct job
|
||||
{
|
||||
const char* str;
|
||||
bool file_p; // true if str is a filename, false if it is a formula
|
||||
|
||||
job(const char* str, bool file_p)
|
||||
: str(str), file_p(file_p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<job> jobs_t;
|
||||
extern jobs_t jobs;
|
||||
extern bool lbt_input;
|
||||
|
||||
extern const struct argp finput_argp;
|
||||
|
||||
int parse_opt_finput(int key, char* arg, struct argp_state* state);
|
||||
|
||||
spot::formula
|
||||
parse_formula(const std::string& s, spot::parse_error_list& error_list);
|
||||
|
||||
|
||||
class job_processor
|
||||
{
|
||||
protected:
|
||||
bool abort_run; // Set to true in process_formula() to abort run().
|
||||
public:
|
||||
job_processor();
|
||||
|
||||
virtual ~job_processor();
|
||||
|
||||
virtual int
|
||||
process_formula(spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0) = 0;
|
||||
|
||||
virtual int
|
||||
process_string(const std::string& str,
|
||||
const char* filename = nullptr, int linenum = 0);
|
||||
virtual int
|
||||
process_stream(std::istream& is, const char* filename);
|
||||
|
||||
virtual int
|
||||
process_file(const char* filename);
|
||||
|
||||
virtual int
|
||||
run();
|
||||
|
||||
char* real_filename;
|
||||
long int col_to_read;
|
||||
char* prefix;
|
||||
char* suffix;
|
||||
};
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_hoaread.hh"
|
||||
#include "argmatch.h"
|
||||
#include "error.h"
|
||||
|
||||
enum
|
||||
{
|
||||
OPT_TRUST_HOA = 1,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
{ "trust-hoa", OPT_TRUST_HOA, "BOOL", 0,
|
||||
"If False, properties listed in HOA files are ignored, "
|
||||
"unless they can be easily verified. If True (the default) "
|
||||
"any supported property is trusted.", 1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
spot::automaton_parser_options opt_parse;
|
||||
|
||||
spot::twa_graph_ptr
|
||||
read_automaton(const char* filename, spot::bdd_dict_ptr& dict)
|
||||
{
|
||||
auto p = spot::parse_aut(filename, dict,
|
||||
spot::default_environment::instance(),
|
||||
opt_parse);
|
||||
if (p->format_errors(std::cerr))
|
||||
error(2, 0, "failed to read automaton from %s", filename);
|
||||
if (p->aborted)
|
||||
error(2, 0, "failed to read automaton from %s (--ABORT-- read)", filename);
|
||||
return std::move(p->aut);
|
||||
}
|
||||
|
||||
static bool parse_bool(const char* opt, const char* arg)
|
||||
{
|
||||
enum bool_type { bool_false, bool_true };
|
||||
static char const *const bool_args[] =
|
||||
{
|
||||
"false", "no", "0",
|
||||
"true", "yes", "1",
|
||||
nullptr
|
||||
};
|
||||
static bool_type const bool_types[] =
|
||||
{
|
||||
bool_false, bool_false, bool_false,
|
||||
bool_true, bool_true, bool_true,
|
||||
};
|
||||
ARGMATCH_VERIFY(bool_args, bool_types);
|
||||
bool_type bt = XARGMATCH(opt, arg, bool_args, bool_types);
|
||||
return bt == bool_true;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_opt_hoaread(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case OPT_TRUST_HOA:
|
||||
opt_parse.trust_hoa = parse_bool("--trust-hoa", arg);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct argp hoaread_argp = { options, parse_opt_hoaread,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr };
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <argp.h>
|
||||
|
||||
#include <spot/parseaut/public.hh>
|
||||
|
||||
|
||||
extern const struct argp hoaread_argp;
|
||||
|
||||
extern spot::automaton_parser_options opt_parse;
|
||||
|
||||
spot::twa_graph_ptr
|
||||
read_automaton(const char* filename, spot::bdd_dict_ptr& dict);
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include "common_output.hh"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/misc/formater.hh>
|
||||
#include <spot/misc/escape.hh>
|
||||
#include "common_cout.hh"
|
||||
#include "error.h"
|
||||
|
||||
enum {
|
||||
OPT_CSV = 1,
|
||||
OPT_FORMAT,
|
||||
OPT_LATEX,
|
||||
OPT_SPOT,
|
||||
OPT_WRING,
|
||||
};
|
||||
|
||||
output_format_t output_format = spot_output;
|
||||
bool full_parenth = false;
|
||||
bool escape_csv = false;
|
||||
char output_terminator = '\n';
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
{ "full-parentheses", 'p', nullptr, 0,
|
||||
"output fully-parenthesized formulas", -20 },
|
||||
{ "spin", 's', nullptr, 0, "output in Spin's syntax", -20 },
|
||||
{ "spot", OPT_SPOT, nullptr, 0, "output in Spot's syntax (default)", -20 },
|
||||
{ "lbt", 'l', nullptr, 0, "output in LBT's syntax", -20 },
|
||||
{ "wring", OPT_WRING, nullptr, 0, "output in Wring's syntax", -20 },
|
||||
{ "utf8", '8', nullptr, 0, "output using UTF-8 characters", -20 },
|
||||
{ "latex", OPT_LATEX, nullptr, 0, "output using LaTeX macros", -20 },
|
||||
{ "csv-escape", OPT_CSV, nullptr, 0,
|
||||
"quote the formula for use in a CSV file", -20 },
|
||||
{ "format", OPT_FORMAT, "FORMAT", 0,
|
||||
"specify how each line should be output (default: \"%f\")", -20 },
|
||||
{ "output", 'o', "FORMAT", 0,
|
||||
"send output to a file named FORMAT instead of standard output. The"
|
||||
" first formula sent to a file truncates it unless FORMAT starts"
|
||||
" with '>>'.", 0 },
|
||||
{ "zero-terminated-output", '0', nullptr, 0,
|
||||
"separate output formulas with \\0 instead of \\n "
|
||||
"(for use with xargs -0)", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp output_argp = { options, parse_opt_output,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr };
|
||||
|
||||
static
|
||||
void
|
||||
report_not_ltl(spot::formula f,
|
||||
const char* filename, int linenum, const char* syn)
|
||||
{
|
||||
std::string s = spot::str_psl(f);
|
||||
static const char msg[] =
|
||||
"formula '%s' cannot be written %s's syntax because it is not LTL";
|
||||
if (filename)
|
||||
error_at_line(2, 0, filename, linenum, msg, s.c_str(), syn);
|
||||
else
|
||||
error(2, 0, msg, s.c_str(), syn);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
stream_formula(std::ostream& out,
|
||||
spot::formula f, const char* filename, int linenum)
|
||||
{
|
||||
switch (output_format)
|
||||
{
|
||||
case lbt_output:
|
||||
if (f.is_ltl_formula())
|
||||
spot::print_lbt_ltl(out, f);
|
||||
else
|
||||
report_not_ltl(f, filename, linenum, "LBT");
|
||||
break;
|
||||
case spot_output:
|
||||
spot::print_psl(out, f, full_parenth);
|
||||
break;
|
||||
case spin_output:
|
||||
if (f.is_ltl_formula())
|
||||
spot::print_spin_ltl(out, f, full_parenth);
|
||||
else
|
||||
report_not_ltl(f, filename, linenum, "Spin");
|
||||
break;
|
||||
case wring_output:
|
||||
if (f.is_ltl_formula())
|
||||
spot::print_wring_ltl(out, f);
|
||||
else
|
||||
report_not_ltl(f, filename, linenum, "Wring");
|
||||
break;
|
||||
case utf8_output:
|
||||
spot::print_utf8_psl(out, f, full_parenth);
|
||||
break;
|
||||
case latex_output:
|
||||
spot::print_latex_psl(out, f, full_parenth);
|
||||
break;
|
||||
case count_output:
|
||||
case quiet_output:
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
stream_escapable_formula(std::ostream& os,
|
||||
spot::formula f,
|
||||
const char* filename, int linenum)
|
||||
{
|
||||
if (escape_csv)
|
||||
{
|
||||
std::ostringstream out;
|
||||
stream_formula(out, f, filename, linenum);
|
||||
os << '"';
|
||||
spot::escape_rfc4180(os, out.str());
|
||||
os << '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_formula(os, f, filename, linenum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
struct formula_with_location
|
||||
{
|
||||
spot::formula f;
|
||||
const char* filename;
|
||||
int line;
|
||||
const char* prefix;
|
||||
const char* suffix;
|
||||
};
|
||||
|
||||
class printable_formula:
|
||||
public spot::printable_value<const formula_with_location*>
|
||||
{
|
||||
public:
|
||||
printable_formula&
|
||||
operator=(const formula_with_location* new_val)
|
||||
{
|
||||
val_ = new_val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void
|
||||
print(std::ostream& os, const char*) const
|
||||
{
|
||||
stream_escapable_formula(os, val_->f, val_->filename, val_->line);
|
||||
}
|
||||
};
|
||||
|
||||
class formula_printer: protected spot::formater
|
||||
{
|
||||
public:
|
||||
formula_printer(std::ostream& os, const char* format)
|
||||
: format_(format)
|
||||
{
|
||||
declare('f', &fl_);
|
||||
declare('F', &filename_);
|
||||
declare('L', &line_);
|
||||
declare('<', &prefix_);
|
||||
declare('>', &suffix_);
|
||||
set_output(os);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
print(const formula_with_location& fl)
|
||||
{
|
||||
fl_ = &fl;
|
||||
filename_ = fl.filename ? fl.filename : "";
|
||||
line_ = fl.line;
|
||||
prefix_ = fl.prefix ? fl.prefix : "";
|
||||
suffix_ = fl.suffix ? fl.suffix : "";
|
||||
return format(format_);
|
||||
}
|
||||
|
||||
private:
|
||||
const char* format_;
|
||||
printable_formula fl_;
|
||||
spot::printable_value<const char*> filename_;
|
||||
spot::printable_value<int> line_;
|
||||
spot::printable_value<const char*> prefix_;
|
||||
spot::printable_value<const char*> suffix_;
|
||||
};
|
||||
}
|
||||
|
||||
static formula_printer* format = nullptr;
|
||||
static std::ostringstream outputname;
|
||||
static formula_printer* outputnamer = nullptr;
|
||||
static std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
||||
|
||||
int
|
||||
parse_opt_output(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case '0':
|
||||
output_terminator = 0;
|
||||
break;
|
||||
case '8':
|
||||
output_format = utf8_output;
|
||||
break;
|
||||
case 'l':
|
||||
output_format = lbt_output;
|
||||
break;
|
||||
case 'o':
|
||||
outputnamer = new formula_printer(outputname, arg);
|
||||
break;
|
||||
case 'p':
|
||||
full_parenth = true;
|
||||
break;
|
||||
case 's':
|
||||
output_format = spin_output;
|
||||
break;
|
||||
case OPT_CSV:
|
||||
escape_csv = true;
|
||||
break;
|
||||
case OPT_LATEX:
|
||||
output_format = latex_output;
|
||||
break;
|
||||
case OPT_SPOT:
|
||||
output_format = spot_output;
|
||||
break;
|
||||
case OPT_WRING:
|
||||
output_format = wring_output;
|
||||
break;
|
||||
case OPT_FORMAT:
|
||||
delete format;
|
||||
format = new formula_printer(std::cout, arg);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
output_formula(std::ostream& out,
|
||||
spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0,
|
||||
const char* prefix = nullptr, const char* suffix = nullptr)
|
||||
{
|
||||
if (!format)
|
||||
{
|
||||
if (prefix)
|
||||
out << prefix << ',';
|
||||
stream_escapable_formula(out, f, filename, linenum);
|
||||
if (suffix)
|
||||
out << ',' << suffix;
|
||||
}
|
||||
else
|
||||
{
|
||||
formula_with_location fl = { f, filename, linenum, prefix, suffix };
|
||||
format->print(fl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
::printable_formula::print(std::ostream& os, const char*) const
|
||||
{
|
||||
output_formula(os, val_);
|
||||
}
|
||||
|
||||
void
|
||||
output_formula_checked(spot::formula f,
|
||||
const char* filename, int linenum,
|
||||
const char* prefix, const char* suffix)
|
||||
{
|
||||
if (output_format == count_output)
|
||||
{
|
||||
if (outputnamer)
|
||||
throw std::runtime_error
|
||||
("options --output and --count are incompatible");
|
||||
return;
|
||||
}
|
||||
if (output_format == quiet_output)
|
||||
return;
|
||||
std::ostream* out = &std::cout;
|
||||
if (outputnamer)
|
||||
{
|
||||
outputname.str("");
|
||||
formula_with_location fl = { f, filename, linenum, prefix, suffix };
|
||||
outputnamer->print(fl);
|
||||
std::string fname = outputname.str();
|
||||
auto p = outputfiles.emplace(fname, nullptr);
|
||||
if (p.second)
|
||||
p.first->second.reset(new output_file(fname.c_str()));
|
||||
out = &p.first->second->ostream();
|
||||
}
|
||||
output_formula(*out, f, filename, linenum, prefix, suffix);
|
||||
*out << output_terminator;
|
||||
// Make sure we abort if we can't write to std::cout anymore
|
||||
// (like disk full or broken pipe with SIGPIPE ignored).
|
||||
check_cout();
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <argp.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <spot/tl/formula.hh>
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include "common_output.hh"
|
||||
#include "common_file.hh"
|
||||
|
||||
enum output_format_t { spot_output, spin_output, utf8_output,
|
||||
lbt_output, wring_output, latex_output,
|
||||
quiet_output, count_output };
|
||||
extern output_format_t output_format;
|
||||
extern bool full_parenth;
|
||||
extern bool escape_csv;
|
||||
|
||||
extern const struct argp output_argp;
|
||||
|
||||
int parse_opt_output(int key, char* arg, struct argp_state* state);
|
||||
|
||||
// Low-level output
|
||||
std::ostream&
|
||||
stream_formula(std::ostream& out,
|
||||
spot::formula f, const char* filename, int linenum);
|
||||
|
||||
void output_formula_checked(spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0,
|
||||
const char* prefix = nullptr,
|
||||
const char* suffix = nullptr);
|
||||
|
||||
|
||||
class printable_formula:
|
||||
public spot::printable_value<spot::formula>
|
||||
{
|
||||
public:
|
||||
printable_formula&
|
||||
operator=(spot::formula new_val)
|
||||
{
|
||||
val_ = new_val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void
|
||||
print(std::ostream& os, const char*) const;
|
||||
};
|
||||
|
||||
class aut_stat_printer: protected spot::stat_printer
|
||||
{
|
||||
public:
|
||||
aut_stat_printer(std::ostream& os, const char* format)
|
||||
: spot::stat_printer(os, format)
|
||||
{
|
||||
declare('f', &formula_); // Override the formula printer.
|
||||
}
|
||||
|
||||
using spot::formater::set_output;
|
||||
|
||||
std::ostream&
|
||||
print(const spot::const_twa_graph_ptr& aut,
|
||||
spot::formula f = nullptr,
|
||||
double run_time = -1.)
|
||||
{
|
||||
formula_ = f;
|
||||
return this->spot::stat_printer::print(aut, f, run_time);
|
||||
}
|
||||
|
||||
printable_formula formula_;
|
||||
};
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_post.hh"
|
||||
#include "common_r.hh"
|
||||
#include "common_aoutput.hh"
|
||||
#include "error.h"
|
||||
|
||||
spot::postprocessor::output_type type = spot::postprocessor::TGBA;
|
||||
spot::postprocessor::output_pref pref = spot::postprocessor::Small;
|
||||
spot::postprocessor::output_pref comp = spot::postprocessor::Any;
|
||||
spot::postprocessor::output_pref sbacc = spot::postprocessor::Any;
|
||||
spot::postprocessor::optimization_level level = spot::postprocessor::High;
|
||||
|
||||
bool level_set = false;
|
||||
bool pref_set = false;
|
||||
|
||||
enum {
|
||||
OPT_GENERIC = 1,
|
||||
OPT_HIGH,
|
||||
OPT_LOW,
|
||||
OPT_MEDIUM,
|
||||
OPT_SMALL,
|
||||
OPT_TGBA,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output automaton type:", 2 },
|
||||
{ "tgba", OPT_TGBA, nullptr, 0,
|
||||
"Transition-based Generalized Büchi Automaton (default)", 0 },
|
||||
{ "ba", 'B', nullptr, 0,
|
||||
"Büchi Automaton (implies -S)", 0 },
|
||||
{ "monitor", 'M', nullptr, 0, "Monitor (accepts all finite prefixes "
|
||||
"of the given property)", 0 },
|
||||
{ "complete", 'C', nullptr, 0, "output a complete automaton", 0 },
|
||||
{ "state-based-acceptance", 'S', nullptr, 0,
|
||||
"define the acceptance using states", 0 },
|
||||
{ "sbacc", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Simplification goal:", 20 },
|
||||
{ "small", OPT_SMALL, nullptr, 0, "prefer small automata (default)", 0 },
|
||||
{ "deterministic", 'D', nullptr, 0, "prefer deterministic automata", 0 },
|
||||
{ "any", 'a', nullptr, 0, "no preference, do not bother making it small "
|
||||
"or deterministic", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Simplification level:", 21 },
|
||||
{ "low", OPT_LOW, nullptr, 0, "minimal optimizations (fast)", 0 },
|
||||
{ "medium", OPT_MEDIUM, nullptr, 0, "moderate optimizations", 0 },
|
||||
{ "high", OPT_HIGH, nullptr, 0,
|
||||
"all available optimizations (slow, default)", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static const argp_option options_disabled[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output automaton type:", 2 },
|
||||
{ "generic", OPT_GENERIC, nullptr, 0,
|
||||
"any acceptance is allowed (default)", 0 },
|
||||
{ "tgba", OPT_TGBA, nullptr, 0,
|
||||
"Transition-based Generalized Büchi Automaton", 0 },
|
||||
{ "ba", 'B', nullptr, 0,
|
||||
"Büchi Automaton (with state-based acceptance)", 0 },
|
||||
{ "monitor", 'M', nullptr, 0, "Monitor (accepts all finite prefixes "
|
||||
"of the given property)", 0 },
|
||||
{ "complete", 'C', nullptr, 0, "output a complete automaton", 0 },
|
||||
{ "state-based-acceptance", 'S', nullptr, 0,
|
||||
"define the acceptance using states", 0 },
|
||||
{ "sbacc", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Simplification goal:", 20 },
|
||||
{ "small", OPT_SMALL, nullptr, 0, "prefer small automata", 0 },
|
||||
{ "deterministic", 'D', nullptr, 0, "prefer deterministic automata", 0 },
|
||||
{ "any", 'a', nullptr, 0, "no preference, do not bother making it small "
|
||||
"or deterministic", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Simplification level:", 21 },
|
||||
{ "low", OPT_LOW, nullptr, 0, "minimal optimizations (fast)", 0 },
|
||||
{ "medium", OPT_MEDIUM, nullptr, 0, "moderate optimizations", 0 },
|
||||
{ "high", OPT_HIGH, nullptr, 0,
|
||||
"all available optimizations (slow)", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
parse_opt_post(int key, char*, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'a':
|
||||
pref = spot::postprocessor::Any;
|
||||
pref_set = true;
|
||||
break;
|
||||
case 'B':
|
||||
type = spot::postprocessor::BA;
|
||||
break;
|
||||
case 'C':
|
||||
comp = spot::postprocessor::Complete;
|
||||
break;
|
||||
case 'D':
|
||||
pref = spot::postprocessor::Deterministic;
|
||||
pref_set = true;
|
||||
break;
|
||||
case 'M':
|
||||
type = spot::postprocessor::Monitor;
|
||||
break;
|
||||
case 'S':
|
||||
sbacc = spot::postprocessor::SBAcc;
|
||||
break;
|
||||
case OPT_GENERIC:
|
||||
type = spot::postprocessor::Generic;
|
||||
break;
|
||||
case OPT_HIGH:
|
||||
level = spot::postprocessor::High;
|
||||
simplification_level = 3;
|
||||
level_set = true;
|
||||
break;
|
||||
case OPT_LOW:
|
||||
level = spot::postprocessor::Low;
|
||||
simplification_level = 1;
|
||||
level_set = true;
|
||||
break;
|
||||
case OPT_MEDIUM:
|
||||
level = spot::postprocessor::Medium;
|
||||
simplification_level = 2;
|
||||
level_set = true;
|
||||
break;
|
||||
case OPT_SMALL:
|
||||
pref = spot::postprocessor::Small;
|
||||
pref_set = true;
|
||||
break;
|
||||
case OPT_TGBA:
|
||||
if (automaton_format == Spin)
|
||||
error(2, 0, "--spin and --tgba are incompatible");
|
||||
type = spot::postprocessor::TGBA;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct argp post_argp = { options, parse_opt_post,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
const struct argp post_argp_disabled = { options_disabled, parse_opt_post,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr };
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <spot/twaalgos/postproc.hh>
|
||||
#include <argp.h>
|
||||
|
||||
extern const struct argp post_argp; // postprocessing enabled
|
||||
extern const struct argp post_argp_disabled; // postprocessing disabled
|
||||
|
||||
extern spot::postprocessor::output_type type;
|
||||
extern spot::postprocessor::output_pref pref;
|
||||
extern spot::postprocessor::output_pref comp;
|
||||
extern spot::postprocessor::output_pref sbacc;
|
||||
extern spot::postprocessor::optimization_level level;
|
||||
// True if --low, --medium, or --high has been given
|
||||
extern bool level_set;
|
||||
// True if --any, --small, or --deterministic has been given
|
||||
extern bool pref_set;
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include "error.h"
|
||||
#include "common_r.hh"
|
||||
|
||||
int simplification_level = 0;
|
||||
|
||||
void
|
||||
parse_r(const char* arg)
|
||||
{
|
||||
if (!arg)
|
||||
{
|
||||
simplification_level = 3;
|
||||
return;
|
||||
}
|
||||
if (arg[1] == 0 && arg[0] >= '0' && arg[0] <= '3')
|
||||
{
|
||||
simplification_level = arg[0] - '0';
|
||||
return;
|
||||
}
|
||||
error(2, 0, "invalid simplification level '%s'", arg);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <spot/tl/simplify.hh>
|
||||
|
||||
#define OPT_R 'r'
|
||||
|
||||
#define DECLARE_OPT_R \
|
||||
{ "simplify", OPT_R, "LEVEL", OPTION_ARG_OPTIONAL, \
|
||||
"simplify formulas according to LEVEL (see below); LEVEL is " \
|
||||
"set to 3 if omitted", 0 }
|
||||
|
||||
#define LEVEL_DOC(g) \
|
||||
{ nullptr, 0, nullptr, 0, \
|
||||
"The simplification LEVEL may be set as follows.", g }, \
|
||||
{ " 0", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
|
||||
"No rewriting", 0 }, \
|
||||
{ " 1", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
|
||||
"basic rewritings and eventual/universal rules", 0 }, \
|
||||
{ " 2", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
|
||||
"additional syntactic implication rules", 0 }, \
|
||||
{ " 3", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
|
||||
"better implications using containment", 0 }
|
||||
|
||||
extern int simplification_level;
|
||||
|
||||
void parse_r(const char* arg);
|
||||
spot::tl_simplifier_options simplifier_options();
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2014 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include "error.h"
|
||||
|
||||
#include "common_range.hh"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
// The range should have the form INT..INT or INT:INT, with
|
||||
// "42" standing for "42..42",
|
||||
// "..42" meaning "missing_left..42".
|
||||
// and "42.." meaning "42..missing_right".
|
||||
//
|
||||
// As an exception, if missing_right is 0, then missing right bounds
|
||||
// are disallowed.
|
||||
range
|
||||
parse_range(const char* str, int missing_left, int missing_right)
|
||||
{
|
||||
range res;
|
||||
char* end;
|
||||
res.min = strtol(str, &end, 10);
|
||||
if (end == str)
|
||||
{
|
||||
// No leading number. It's OK as long as the string is not
|
||||
// empty.
|
||||
if (!*end)
|
||||
error(1, 0, "invalid empty range");
|
||||
res.min = missing_left;
|
||||
}
|
||||
if (!*end)
|
||||
{
|
||||
// Only one number.
|
||||
res.max = res.min;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip : or ..
|
||||
if (end[0] == ':')
|
||||
++end;
|
||||
else if (end[0] == '.' && end[1] == '.')
|
||||
end += 2;
|
||||
|
||||
if (!*end && missing_right != 0)
|
||||
{
|
||||
res.max = missing_right;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse the next integer.
|
||||
char* end2;
|
||||
res.max = strtol(end, &end2, 10);
|
||||
if (end == end2)
|
||||
error(1, 0, "invalid range '%s' (missing end?)", str);
|
||||
if (*end2)
|
||||
error(1, 0, "invalid range '%s' (trailing garbage?)", str);
|
||||
}
|
||||
}
|
||||
|
||||
if (res.min < 0 || res.max < 0)
|
||||
error(1, 0, "invalid range '%s': values must be positive", str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define RANGE_DOC \
|
||||
{ nullptr, 0, nullptr, 0, \
|
||||
"RANGE may have one of the following forms: 'INT', " \
|
||||
"'INT..INT', or '..INT'.\nIn the latter case, the missing number " \
|
||||
"is assumed to be 1.", 0 }
|
||||
|
||||
#define RANGE_DOC_FULL \
|
||||
{ nullptr, 0, nullptr, 0, \
|
||||
"RANGE may have one of the following forms: 'INT', " \
|
||||
"'INT..INT', '..INT', or 'INT..'", 0 }
|
||||
|
||||
struct range
|
||||
{
|
||||
int min;
|
||||
int max;
|
||||
|
||||
bool contains(int val)
|
||||
{
|
||||
return val >= min && val <= max;
|
||||
}
|
||||
};
|
||||
|
||||
// INT, INT..INT, ..INT, or INT..
|
||||
//
|
||||
// The missing_left and missing_right argument gives the default bound
|
||||
// values. Additionally, if missing_right == 0, then the INT.. form
|
||||
// is disallowed.
|
||||
range parse_range(const char* str,
|
||||
int missing_left = 1, int missing_right = 0);
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "argp.h"
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <spot/misc/tmpfile.hh>
|
||||
|
||||
const char* argp_program_bug_address = "<" PACKAGE_BUGREPORT ">";
|
||||
|
||||
static void
|
||||
display_version(FILE *stream, struct argp_state*)
|
||||
{
|
||||
fputs(program_name, stream);
|
||||
fputs(" (" PACKAGE_STRING ")\n\
|
||||
\n\
|
||||
Copyright (C) 2015 Laboratoire de Recherche et Développement de l'Epita.\n\
|
||||
License GPLv3+: \
|
||||
GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
|
||||
This is free software: you are free to change and redistribute it.\n\
|
||||
There is NO WARRANTY, to the extent permitted by law.\n", stream);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static void sig_handler(int sig)
|
||||
{
|
||||
spot::cleanup_tmpfiles();
|
||||
// Send the signal again, this time to the default handler, so that
|
||||
// we return a meaningful error code.
|
||||
raise(sig);
|
||||
}
|
||||
|
||||
static void setup_sig_handler()
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = sig_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESETHAND;
|
||||
// Catch termination signals, so we can cleanup temporary files.
|
||||
sigaction(SIGALRM, &sa, nullptr);
|
||||
sigaction(SIGHUP, &sa, nullptr);
|
||||
sigaction(SIGINT, &sa, nullptr);
|
||||
sigaction(SIGPIPE, &sa, nullptr);
|
||||
sigaction(SIGQUIT, &sa, nullptr);
|
||||
sigaction(SIGTERM, &sa, nullptr);
|
||||
}
|
||||
#else
|
||||
# define setup_sig_handler() while (0);
|
||||
#endif
|
||||
|
||||
void
|
||||
setup(char** argv)
|
||||
{
|
||||
// Simplify the program name, because argp() uses it to report
|
||||
// errors and display help text.
|
||||
set_program_name(argv[0]);
|
||||
argv[0] = const_cast<char*>(program_name);
|
||||
|
||||
argp_program_version_hook = display_version;
|
||||
|
||||
argp_err_exit_status = 2;
|
||||
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
|
||||
setup_sig_handler();
|
||||
}
|
||||
|
||||
|
||||
// argp's default behavior of offering -? for --help is just too silly.
|
||||
// I mean, come on, why not also add -* to Darwinise more shell users?
|
||||
// We disable this option as well as -V (because --version don't need
|
||||
// a short version).
|
||||
enum {
|
||||
OPT_HELP = 1,
|
||||
OPT_USAGE,
|
||||
OPT_VERSION,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
{ "version", OPT_VERSION, nullptr, 0, "print program version", -1 },
|
||||
{ "help", OPT_HELP, nullptr, 0, "print this help", -1 },
|
||||
// We support this option just in case, but we don't advertise it.
|
||||
{ "usage", OPT_USAGE, nullptr, OPTION_HIDDEN, "show short usage", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static const argp_option options_hidden[] =
|
||||
{
|
||||
{ "version", OPT_VERSION, nullptr, OPTION_HIDDEN,
|
||||
"print program version", -1 },
|
||||
{ "help", OPT_HELP, nullptr, OPTION_HIDDEN, "print this help", -1 },
|
||||
// We support this option just in case, but we don't advertise it.
|
||||
{ "usage", OPT_USAGE, nullptr, OPTION_HIDDEN, "show short usage", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
parse_opt_misc(int key, char*, struct argp_state* state)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case OPT_HELP:
|
||||
argp_state_help(state, state->out_stream, ARGP_HELP_STD_HELP);
|
||||
break;
|
||||
case OPT_USAGE:
|
||||
argp_state_help(state, state->out_stream,
|
||||
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
|
||||
break;
|
||||
case OPT_VERSION:
|
||||
display_version(state->out_stream, state);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const struct argp misc_argp = { options, parse_opt_misc,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
|
||||
const struct argp misc_argp_hidden = { options_hidden, parse_opt_misc,
|
||||
nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr };
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include "progname.h"
|
||||
|
||||
void setup(char** progname);
|
||||
|
||||
extern const struct argp misc_argp;
|
||||
extern const struct argp misc_argp_hidden;
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
|
@ -1,440 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_trans.hh"
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#include <spot/tl/print.hh>
|
||||
#include "common_conv.hh"
|
||||
#include <spot/misc/escape.hh>
|
||||
|
||||
// A set of tools for which we know the correct output
|
||||
static struct shorthands_t
|
||||
{
|
||||
const char* prefix;
|
||||
const char* suffix;
|
||||
}
|
||||
shorthands[] = {
|
||||
{ "lbt", " <%L>%O" },
|
||||
{ "ltl2ba", " -f %s>%O" },
|
||||
{ "ltl2dstar", " --output-format=hoa %L %O"},
|
||||
{ "ltl2tgba", " -H %f>%O" },
|
||||
{ "ltl3ba", " -f %s>%O" },
|
||||
{ "ltl3dra", " -f %s>%O" },
|
||||
{ "modella", " %L %O" },
|
||||
{ "spin", " -f %s>%O" },
|
||||
};
|
||||
|
||||
static void show_shorthands()
|
||||
{
|
||||
std::cout
|
||||
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
|
||||
"the following words, then the string on the right is appended.\n\n");
|
||||
for (auto& s: shorthands)
|
||||
std::cout << " "
|
||||
<< std::left << std::setw(12) << s.prefix
|
||||
<< s.suffix << '\n';
|
||||
std::cout
|
||||
<< ("\nAny {name} and directory component is skipped for the purpose of\n"
|
||||
"matching those prefixes. So for instance\n"
|
||||
" '{DRA} ~/mytools/ltl2dstar-0.5.2'\n"
|
||||
"will changed into\n"
|
||||
" '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %L %O'\n");
|
||||
}
|
||||
|
||||
|
||||
translator_spec::translator_spec(const char* spec)
|
||||
: spec(spec), cmd(spec), name(spec)
|
||||
{
|
||||
if (*cmd == '{')
|
||||
{
|
||||
// Match the closing '}'
|
||||
const char* pos = cmd;
|
||||
unsigned count = 1;
|
||||
while (*++pos)
|
||||
{
|
||||
if (*pos == '{')
|
||||
++count;
|
||||
else if (*pos == '}')
|
||||
if (!--count)
|
||||
{
|
||||
name = strndup(cmd + 1, pos - cmd - 1);
|
||||
cmd = pos + 1;
|
||||
while (*cmd == ' ' || *cmd == '\t')
|
||||
++cmd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there is no % in the string, look for a known
|
||||
// command from our shorthand list. If we find it,
|
||||
// add the suffix.
|
||||
bool allocated = false;
|
||||
if (!strchr(cmd, '%'))
|
||||
{
|
||||
// Skip any leading directory name.
|
||||
auto basename = cmd;
|
||||
auto pos = cmd;
|
||||
while (*pos)
|
||||
{
|
||||
if (*pos == '/')
|
||||
basename = pos + 1;
|
||||
else if (*pos == ' ')
|
||||
break;
|
||||
++pos;
|
||||
}
|
||||
// Match a shorthand.
|
||||
for (auto& p: shorthands)
|
||||
{
|
||||
int n = strlen(p.prefix);
|
||||
if (strncmp(basename, p.prefix, n) == 0)
|
||||
{
|
||||
int m = strlen(p.suffix);
|
||||
int q = strlen(cmd);
|
||||
char* tmp = static_cast<char*>(malloc(q + m + 1));
|
||||
strcpy(tmp, cmd);
|
||||
strcpy(tmp + q, p.suffix);
|
||||
cmd = tmp;
|
||||
allocated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allocated)
|
||||
cmd = strdup(cmd);
|
||||
}
|
||||
|
||||
translator_spec::translator_spec(const translator_spec& other)
|
||||
: spec(other.spec), cmd(other.cmd), name(other.name)
|
||||
{
|
||||
if (name != spec)
|
||||
name = strdup(name);
|
||||
if (cmd != spec)
|
||||
cmd = strdup(cmd);
|
||||
}
|
||||
|
||||
translator_spec::~translator_spec()
|
||||
{
|
||||
if (name != spec)
|
||||
free(const_cast<char*>(name));
|
||||
if (cmd != spec)
|
||||
free(const_cast<char*>(cmd));
|
||||
}
|
||||
|
||||
std::vector<translator_spec> translators;
|
||||
|
||||
void
|
||||
quoted_string::print(std::ostream& os, const char*) const
|
||||
{
|
||||
spot::quote_shell_string(os, val().c_str());
|
||||
}
|
||||
|
||||
printable_result_filename::printable_result_filename()
|
||||
{
|
||||
val_ = nullptr;
|
||||
}
|
||||
|
||||
printable_result_filename::~printable_result_filename()
|
||||
{
|
||||
delete val_;
|
||||
}
|
||||
|
||||
void printable_result_filename::reset(unsigned n)
|
||||
{
|
||||
translator_num = n;
|
||||
}
|
||||
|
||||
void printable_result_filename::cleanup()
|
||||
{
|
||||
delete val_;
|
||||
val_ = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
printable_result_filename::print(std::ostream& os, const char*) const
|
||||
{
|
||||
char prefix[30];
|
||||
snprintf(prefix, sizeof prefix, "lcr-o%u-", translator_num);
|
||||
const_cast<printable_result_filename*>(this)->val_ =
|
||||
spot::create_tmpfile(prefix);
|
||||
spot::quote_shell_string(os, val()->name());
|
||||
}
|
||||
|
||||
|
||||
translator_runner::translator_runner(spot::bdd_dict_ptr dict,
|
||||
bool no_output_allowed)
|
||||
: dict(dict)
|
||||
{
|
||||
declare('f', &string_ltl_spot);
|
||||
declare('s', &string_ltl_spin);
|
||||
declare('l', &string_ltl_lbt);
|
||||
declare('w', &string_ltl_wring);
|
||||
declare('F', &filename_ltl_spot);
|
||||
declare('S', &filename_ltl_spin);
|
||||
declare('L', &filename_ltl_lbt);
|
||||
declare('W', &filename_ltl_wring);
|
||||
declare('D', &output);
|
||||
declare('H', &output);
|
||||
declare('N', &output);
|
||||
declare('T', &output);
|
||||
declare('O', &output);
|
||||
|
||||
size_t s = translators.size();
|
||||
assert(s);
|
||||
for (size_t n = 0; n < s; ++n)
|
||||
{
|
||||
// Check that each translator uses at least one input and
|
||||
// one output.
|
||||
std::vector<bool> has(256);
|
||||
const translator_spec& t = translators[n];
|
||||
scan(t.cmd, has);
|
||||
if (!(has['f'] || has['s'] || has['l'] || has['w']
|
||||
|| has['F'] || has['S'] || has['L'] || has['W']))
|
||||
error(2, 0, "no input %%-sequence in '%s'.\n Use "
|
||||
"one of %%f,%%s,%%l,%%w,%%F,%%S,%%L,%%W to indicate how "
|
||||
"to pass the formula.", t.spec);
|
||||
if (!no_output_allowed
|
||||
&& !(has['O'] ||
|
||||
// backward-compatibility
|
||||
has['D'] || has['N'] || has['T'] || has['H']))
|
||||
error(2, 0, "no output %%-sequence in '%s'.\n Use "
|
||||
"%%O to indicate where the automaton is output.",
|
||||
t.spec);
|
||||
// Remember the %-sequences used by all translators.
|
||||
prime(t.cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
translator_runner::string_to_tmp(std::string& str, unsigned n,
|
||||
std::string& tmpname)
|
||||
{
|
||||
char prefix[30];
|
||||
snprintf(prefix, sizeof prefix, "lcr-i%u-", n);
|
||||
spot::open_temporary_file* tmpfile = spot::create_open_tmpfile(prefix);
|
||||
tmpname = tmpfile->name();
|
||||
int fd = tmpfile->fd();
|
||||
ssize_t s = str.size();
|
||||
if (write(fd, str.c_str(), s) != s
|
||||
|| write(fd, "\n", 1) != 1)
|
||||
error(2, errno, "failed to write into %s", tmpname.c_str());
|
||||
tmpfile->close();
|
||||
}
|
||||
|
||||
const std::string&
|
||||
translator_runner::formula() const
|
||||
{
|
||||
// Pick the most readable format we have...
|
||||
if (!string_ltl_spot.val().empty())
|
||||
return string_ltl_spot;
|
||||
if (!string_ltl_spin.val().empty())
|
||||
return string_ltl_spin;
|
||||
if (!string_ltl_wring.val().empty())
|
||||
return string_ltl_wring;
|
||||
if (!string_ltl_lbt.val().empty())
|
||||
return string_ltl_lbt;
|
||||
SPOT_UNREACHABLE();
|
||||
return string_ltl_spot;
|
||||
}
|
||||
|
||||
void
|
||||
translator_runner::round_formula(spot::formula f, unsigned serial)
|
||||
{
|
||||
if (has('f') || has('F'))
|
||||
string_ltl_spot = spot::str_psl(f, true);
|
||||
if (has('s') || has('S'))
|
||||
string_ltl_spin = spot::str_spin_ltl(f, true);
|
||||
if (has('l') || has('L'))
|
||||
string_ltl_lbt = spot::str_lbt_ltl(f);
|
||||
if (has('w') || has('W'))
|
||||
string_ltl_wring = spot::str_wring_ltl(f);
|
||||
if (has('F'))
|
||||
string_to_tmp(string_ltl_spot, serial, filename_ltl_spot);
|
||||
if (has('S'))
|
||||
string_to_tmp(string_ltl_spin, serial, filename_ltl_spin);
|
||||
if (has('L'))
|
||||
string_to_tmp(string_ltl_lbt, serial, filename_ltl_lbt);
|
||||
if (has('W'))
|
||||
string_to_tmp(string_ltl_wring, serial, filename_ltl_wring);
|
||||
}
|
||||
|
||||
|
||||
|
||||
volatile bool timed_out = false;
|
||||
unsigned timeout_count = 0;
|
||||
|
||||
static unsigned timeout = 0;
|
||||
#if ENABLE_TIMEOUT
|
||||
static volatile int alarm_on = 0;
|
||||
static int child_pid = -1;
|
||||
|
||||
static void
|
||||
sig_handler(int sig)
|
||||
{
|
||||
if (child_pid == 0)
|
||||
error(2, 0, "received signal %d before starting child", sig);
|
||||
|
||||
if (sig == SIGALRM && alarm_on)
|
||||
{
|
||||
timed_out = true;
|
||||
if (--alarm_on)
|
||||
{
|
||||
// Send SIGTERM to children.
|
||||
kill(-child_pid, SIGTERM);
|
||||
// Try again later if it didn't work. (alarm() will be reset
|
||||
// if it did work and the call to wait() returns)
|
||||
alarm(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// After a few gentle tries, really kill that child.
|
||||
kill(-child_pid, SIGKILL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// forward signal
|
||||
kill(-child_pid, sig);
|
||||
// cleanup files
|
||||
spot::cleanup_tmpfiles();
|
||||
// and die verbosely
|
||||
error(2, 0, "received signal %d", sig);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setup_sig_handler()
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = sig_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART; // So that wait() doesn't get aborted by SIGALRM.
|
||||
sigaction(SIGALRM, &sa, nullptr);
|
||||
// Catch termination signals, so we can kill the subprocess.
|
||||
sigaction(SIGHUP, &sa, nullptr);
|
||||
sigaction(SIGINT, &sa, nullptr);
|
||||
sigaction(SIGQUIT, &sa, nullptr);
|
||||
sigaction(SIGTERM, &sa, nullptr);
|
||||
}
|
||||
|
||||
int
|
||||
exec_with_timeout(const char* cmd)
|
||||
{
|
||||
int status;
|
||||
|
||||
timed_out = false;
|
||||
|
||||
child_pid = fork();
|
||||
if (child_pid == -1)
|
||||
error(2, errno, "failed to fork()");
|
||||
|
||||
if (child_pid == 0)
|
||||
{
|
||||
setpgid(0, 0);
|
||||
execlp("sh", "sh", "-c", cmd, nullptr);
|
||||
error(2, errno, "failed to run 'sh'");
|
||||
// never reached
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
alarm(timeout);
|
||||
// Upon SIGALRM, the child will receive up to 3
|
||||
// signals: SIGTERM, SIGTERM, SIGKILL.
|
||||
alarm_on = 3;
|
||||
int w = waitpid(child_pid, &status, 0);
|
||||
alarm_on = 0;
|
||||
|
||||
if (w == -1)
|
||||
error(2, errno, "error during wait()");
|
||||
|
||||
alarm(0);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif // ENABLE_TIMEOUT
|
||||
|
||||
enum {
|
||||
OPT_LIST = 1,
|
||||
};
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Specifying translators to call:", 2 },
|
||||
{ "translator", 't', "COMMANDFMT", 0,
|
||||
"register one translator to call", 0 },
|
||||
{ "timeout", 'T', "NUMBER", 0, "kill translators after NUMBER seconds", 0 },
|
||||
{ "list-shorthands", OPT_LIST, nullptr, 0,
|
||||
"list availabled shorthands to use in COMMANDFMT", 0},
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0,
|
||||
"COMMANDFMT should specify input and output arguments using the "
|
||||
"following character sequences:", 3 },
|
||||
{ "%f,%s,%l,%w", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula as a (quoted) string in Spot, Spin, LBT, or Wring's syntax",
|
||||
0 },
|
||||
{ "%F,%S,%L,%W", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula as a file in Spot, Spin, LBT, or Wring's syntax", 0 },
|
||||
{ "%O", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the automaton is output in HOA, never claim, LBTT, or ltl2dstar's "
|
||||
"format", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, "a single %", 0 },
|
||||
{ nullptr, 0, nullptr, 0,
|
||||
"If either %l, %L, or %T are used, any input formula that does "
|
||||
"not use LBT-style atomic propositions (i.e. p0, p1, ...) will be "
|
||||
"relabeled automatically.\n"
|
||||
"Furthermore, if COMMANDFMT has the form \"{NAME}CMD\", then only CMD "
|
||||
"will be passed to the shell, and NAME will be used to name the tool "
|
||||
"in the output.", 4 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static int parse_opt_trans(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 't':
|
||||
translators.push_back(arg);
|
||||
break;
|
||||
case 'T':
|
||||
timeout = to_pos_int(arg);
|
||||
#if !ENABLE_TIMEOUT
|
||||
std::cerr << "warning: setting a timeout is not supported "
|
||||
<< "on your platform" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
case OPT_LIST:
|
||||
show_shorthands();
|
||||
exit(0);
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct argp trans_argp = { options, parse_opt_trans, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr };
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <vector>
|
||||
#include <argp.h>
|
||||
|
||||
#include <spot/misc/formater.hh>
|
||||
#include <spot/misc/tmpfile.hh>
|
||||
#include <spot/twa/twagraph.hh>
|
||||
|
||||
|
||||
extern const struct argp trans_argp;
|
||||
|
||||
struct translator_spec
|
||||
{
|
||||
// The translator command, as specified on the command-line.
|
||||
// If this has the form of
|
||||
// {name}cmd
|
||||
// then it is split in two components.
|
||||
// Otherwise, spec=cmd=name.
|
||||
const char* spec;
|
||||
// actual shell command (or spec)
|
||||
const char* cmd;
|
||||
// name of the translator (or spec)
|
||||
const char* name;
|
||||
|
||||
translator_spec(const char* spec);
|
||||
translator_spec(const translator_spec& other);
|
||||
~translator_spec();
|
||||
};
|
||||
|
||||
extern std::vector<translator_spec> translators;
|
||||
|
||||
struct quoted_string final: public spot::printable_value<std::string>
|
||||
{
|
||||
using spot::printable_value<std::string>::operator=;
|
||||
void print(std::ostream& os, const char* pos) const override;
|
||||
};
|
||||
|
||||
struct printable_result_filename final:
|
||||
public spot::printable_value<spot::temporary_file*>
|
||||
{
|
||||
unsigned translator_num;
|
||||
|
||||
printable_result_filename();
|
||||
~printable_result_filename();
|
||||
void reset(unsigned n);
|
||||
void cleanup();
|
||||
|
||||
void print(std::ostream& os, const char* pos) const override;
|
||||
};
|
||||
|
||||
|
||||
class translator_runner: protected spot::formater
|
||||
{
|
||||
protected:
|
||||
spot::bdd_dict_ptr dict;
|
||||
// Round-specific variables
|
||||
quoted_string string_ltl_spot;
|
||||
quoted_string string_ltl_spin;
|
||||
quoted_string string_ltl_lbt;
|
||||
quoted_string string_ltl_wring;
|
||||
quoted_string filename_ltl_spot;
|
||||
quoted_string filename_ltl_spin;
|
||||
quoted_string filename_ltl_lbt;
|
||||
quoted_string filename_ltl_wring;
|
||||
// Run-specific variables
|
||||
printable_result_filename output;
|
||||
public:
|
||||
using spot::formater::has;
|
||||
|
||||
translator_runner(spot::bdd_dict_ptr dict,
|
||||
// whether we accept the absence of output
|
||||
// specifier
|
||||
bool no_output_allowed = false);
|
||||
void string_to_tmp(std::string& str, unsigned n, std::string& tmpname);
|
||||
const std::string& formula() const;
|
||||
void round_formula(spot::formula f, unsigned serial);
|
||||
};
|
||||
|
||||
|
||||
// Disable handling of timeout on systems that miss kill() or alarm().
|
||||
// For instance MinGW.
|
||||
#if HAVE_KILL && HAVE_ALARM
|
||||
# define ENABLE_TIMEOUT 1
|
||||
#else
|
||||
# define ENABLE_TIMEOUT 0
|
||||
#endif
|
||||
|
||||
extern volatile bool timed_out;
|
||||
extern unsigned timeout_count;
|
||||
#if ENABLE_TIMEOUT
|
||||
void setup_sig_handler();
|
||||
int exec_with_timeout(const char* cmd);
|
||||
#else // !ENABLE_TIMEOUT
|
||||
#define exec_with_timeout(cmd) system(cmd)
|
||||
#define setup_sig_handler() while (0);
|
||||
#endif // !ENABLE_TIMEOUT
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <argp.h>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_post.hh"
|
||||
#include "common_file.hh"
|
||||
#include "common_hoaread.hh"
|
||||
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/lbtt.hh>
|
||||
#include <spot/twaalgos/hoa.hh>
|
||||
#include <spot/twaalgos/neverclaim.hh>
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include <spot/twaalgos/totgba.hh>
|
||||
#include <spot/twa/bddprint.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
#include <spot/parseaut/public.hh>
|
||||
#include <spot/twaalgos/sccinfo.hh>
|
||||
|
||||
static const char argp_program_doc[] ="\
|
||||
Convert automata with any acceptance condition into variants of \
|
||||
Büchi automata.\n\nThis reads automata into any supported format \
|
||||
(HOA, LBTT, ltl2dstar, never claim) and outputs a \
|
||||
Transition-based Generalized Büchi Automata in GraphViz's format by default. \
|
||||
Each supplied file may contain multiple automata.";
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Input:", 1 },
|
||||
{ "file", 'F', "FILENAME", 0,
|
||||
"process the automaton in FILENAME", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ "extra-options", 'x', "OPTS", 0,
|
||||
"fine-tuning options (see spot-x (7))", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static const struct argp_child children[] =
|
||||
{
|
||||
{ &hoaread_argp, 0, nullptr, 0 },
|
||||
{ &aoutput_argp, 0, nullptr, 0 },
|
||||
{ &aoutput_io_format_argp, 0, nullptr, 4 },
|
||||
{ &post_argp, 0, nullptr, 0 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static spot::option_map extra_options;
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
const char* opt = extra_options.parse_options(arg);
|
||||
if (opt)
|
||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||
}
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class dstar_processor: public job_processor
|
||||
{
|
||||
public:
|
||||
spot::postprocessor& post;
|
||||
automaton_printer printer;
|
||||
|
||||
dstar_processor(spot::postprocessor& post)
|
||||
: post(post), printer(aut_input)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
process_formula(spot::formula, const char*, int)
|
||||
{
|
||||
SPOT_UNREACHABLE();
|
||||
}
|
||||
|
||||
int
|
||||
process_automaton(const spot::const_parsed_aut_ptr& haut,
|
||||
const char* filename)
|
||||
{
|
||||
spot::stopwatch sw;
|
||||
sw.start();
|
||||
auto nba = spot::to_generalized_buchi(haut->aut);
|
||||
auto aut = post.run(nba, nullptr);
|
||||
const double conversion_time = sw.stop();
|
||||
|
||||
printer.print(aut, nullptr, filename, -1, conversion_time, haut);
|
||||
flush_cout();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
aborted(const spot::const_parsed_aut_ptr& h, const char* filename)
|
||||
{
|
||||
std::cerr << filename << ':' << h->loc << ": aborted input automaton\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
int
|
||||
process_file(const char* filename)
|
||||
{
|
||||
auto hp = spot::automaton_stream_parser(filename, opt_parse);
|
||||
int err = 0;
|
||||
while (!abort_run)
|
||||
{
|
||||
auto haut = hp.parse(spot::make_bdd_dict());
|
||||
if (!haut->aut && haut->errors.empty())
|
||||
break;
|
||||
if (haut->format_errors(std::cerr))
|
||||
err = 2;
|
||||
if (!haut->aut)
|
||||
error(2, 0, "failed to read automaton from %s", filename);
|
||||
else if (haut->aborted)
|
||||
err = std::max(err, aborted(haut, filename));
|
||||
else
|
||||
process_automaton(haut, filename);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[FILENAMES...]",
|
||||
argp_program_doc, children, nullptr, nullptr };
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
jobs.emplace_back("-", true);
|
||||
|
||||
spot::postprocessor post(&extra_options);
|
||||
post.set_pref(pref | comp | sbacc);
|
||||
post.set_type(type);
|
||||
post.set_level(level);
|
||||
|
||||
try
|
||||
{
|
||||
dstar_processor processor(post);
|
||||
if (processor.run())
|
||||
return 2;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,834 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Families defined here come from the following papers:
|
||||
//
|
||||
// @InProceedings{cichon.09.depcos,
|
||||
// author = {Jacek Cicho{\'n} and Adam Czubak and Andrzej Jasi{\'n}ski},
|
||||
// title = {Minimal {B\"uchi} Automata for Certain Classes of {LTL} Formulas},
|
||||
// booktitle = {Proceedings of the Fourth International Conference on
|
||||
// Dependability of Computer Systems},
|
||||
// pages = {17--24},
|
||||
// year = 2009,
|
||||
// publisher = {IEEE Computer Society},
|
||||
// }
|
||||
//
|
||||
// @InProceedings{geldenhuys.06.spin,
|
||||
// author = {Jaco Geldenhuys and Henri Hansen},
|
||||
// title = {Larger Automata and Less Work for LTL Model Checking},
|
||||
// booktitle = {Proceedings of the 13th International SPIN Workshop},
|
||||
// year = {2006},
|
||||
// pages = {53--70},
|
||||
// series = {Lecture Notes in Computer Science},
|
||||
// volume = {3925},
|
||||
// publisher = {Springer}
|
||||
// }
|
||||
//
|
||||
// @InProceedings{gastin.01.cav,
|
||||
// author = {Paul Gastin and Denis Oddoux},
|
||||
// title = {Fast {LTL} to {B\"u}chi Automata Translation},
|
||||
// booktitle = {Proceedings of the 13th International Conference on
|
||||
// Computer Aided Verification (CAV'01)},
|
||||
// pages = {53--65},
|
||||
// year = 2001,
|
||||
// editor = {G. Berry and H. Comon and A. Finkel},
|
||||
// volume = {2102},
|
||||
// series = {Lecture Notes in Computer Science},
|
||||
// address = {Paris, France},
|
||||
// publisher = {Springer-Verlag}
|
||||
// }
|
||||
//
|
||||
// @InProceedings{rozier.07.spin,
|
||||
// author = {Kristin Y. Rozier and Moshe Y. Vardi},
|
||||
// title = {LTL Satisfiability Checking},
|
||||
// booktitle = {Proceedings of the 12th International SPIN Workshop on
|
||||
// Model Checking of Software (SPIN'07)},
|
||||
// pages = {149--167},
|
||||
// year = {2007},
|
||||
// volume = {4595},
|
||||
// series = {Lecture Notes in Computer Science},
|
||||
// publisher = {Springer-Verlag}
|
||||
// }
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <argp.h>
|
||||
#include <cstdlib>
|
||||
#include "error.h"
|
||||
#include <vector>
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_output.hh"
|
||||
#include "common_range.hh"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <spot/tl/formula.hh>
|
||||
#include <spot/tl/relabel.hh>
|
||||
|
||||
using namespace spot;
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
Generate temporal logic formulas from predefined scalable patterns.";
|
||||
|
||||
enum {
|
||||
OPT_AND_F = 1,
|
||||
OPT_AND_FG,
|
||||
OPT_AND_GF,
|
||||
OPT_CCJ_ALPHA,
|
||||
OPT_CCJ_BETA,
|
||||
OPT_CCJ_BETA_PRIME,
|
||||
OPT_GH_Q,
|
||||
OPT_GH_R,
|
||||
OPT_GO_THETA,
|
||||
OPT_OR_FG,
|
||||
OPT_OR_G,
|
||||
OPT_OR_GF,
|
||||
OPT_R_LEFT,
|
||||
OPT_R_RIGHT,
|
||||
OPT_RV_COUNTER,
|
||||
OPT_RV_COUNTER_CARRY,
|
||||
OPT_RV_COUNTER_CARRY_LINEAR,
|
||||
OPT_RV_COUNTER_LINEAR,
|
||||
OPT_U_LEFT,
|
||||
OPT_U_RIGHT,
|
||||
LAST_CLASS,
|
||||
};
|
||||
|
||||
const char* const class_name[LAST_CLASS] =
|
||||
{
|
||||
"and-f",
|
||||
"and-fg",
|
||||
"and-gf",
|
||||
"ccj-alpha",
|
||||
"ccj-beta",
|
||||
"ccj-beta-prime",
|
||||
"gh-q",
|
||||
"gh-r",
|
||||
"go-theta",
|
||||
"or-fg",
|
||||
"or-g",
|
||||
"or-gf",
|
||||
"or-r-left",
|
||||
"or-r-right",
|
||||
"rv-counter",
|
||||
"rv-counter-carry",
|
||||
"rv-counter-carry-linear",
|
||||
"rv-counter-linear",
|
||||
"u-left",
|
||||
"u-right",
|
||||
};
|
||||
|
||||
|
||||
#define OPT_ALIAS(o) { #o, 0, nullptr, OPTION_ALIAS, nullptr, 0 }
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
// Keep this alphabetically sorted (expect for aliases).
|
||||
{ nullptr, 0, nullptr, 0, "Pattern selection:", 1},
|
||||
// J. Geldenhuys and H. Hansen (Spin'06): Larger automata and less
|
||||
// work for LTL model checking.
|
||||
{ "and-f", OPT_AND_F, "RANGE", 0, "F(p1)&F(p2)&...&F(pn)", 0 },
|
||||
OPT_ALIAS(gh-e),
|
||||
{ "and-fg", OPT_AND_FG, "RANGE", 0, "FG(p1)&FG(p2)&...&FG(pn)", 0 },
|
||||
{ "and-gf", OPT_AND_GF, "RANGE", 0, "GF(p1)&GF(p2)&...&GF(pn)", 0 },
|
||||
OPT_ALIAS(ccj-phi),
|
||||
OPT_ALIAS(gh-c2),
|
||||
{ "ccj-alpha", OPT_CCJ_ALPHA, "RANGE", 0,
|
||||
"F(p1&F(p2&F(p3&...F(pn)))) & F(q1&F(q2&F(q3&...F(qn))))", 0 },
|
||||
{ "ccj-beta", OPT_CCJ_BETA, "RANGE", 0,
|
||||
"F(p&X(p&X(p&...X(p)))) & F(q&X(q&X(q&...X(q))))", 0 },
|
||||
{ "ccj-beta-prime", OPT_CCJ_BETA_PRIME, "RANGE", 0,
|
||||
"F(p&(Xp)&(XXp)&...(X...X(p))) & F(q&(Xq)&(XXq)&...(X...X(q)))", 0 },
|
||||
{ "gh-q", OPT_GH_Q, "RANGE", 0,
|
||||
"(F(p1)|G(p2))&(F(p2)|G(p3))&... &(F(pn)|G(p{n+1}))", 0 },
|
||||
{ "gh-r", OPT_GH_R, "RANGE", 0,
|
||||
"(GF(p1)|FG(p2))&(GF(p2)|FG(p3))&... &(GF(pn)|FG(p{n+1}))", 0},
|
||||
{ "go-theta", OPT_GO_THETA, "RANGE", 0,
|
||||
"!((GF(p1)&GF(p2)&...&GF(pn)) -> G(q->F(r)))", 0 },
|
||||
{ "or-fg", OPT_OR_FG, "RANGE", 0, "FG(p1)|FG(p2)|...|FG(pn)", 0 },
|
||||
OPT_ALIAS(ccj-xi),
|
||||
{ "or-g", OPT_OR_G, "RANGE", 0, "G(p1)|G(p2)|...|G(pn)", 0 },
|
||||
OPT_ALIAS(gh-s),
|
||||
{ "or-gf", OPT_OR_GF, "RANGE", 0, "GF(p1)|GF(p2)|...|GF(pn)", 0 },
|
||||
OPT_ALIAS(gh-c1),
|
||||
{ "r-left", OPT_R_LEFT, "RANGE", 0, "(((p1 R p2) R p3) ... R pn)", 0 },
|
||||
{ "r-right", OPT_R_RIGHT, "RANGE", 0, "(p1 R (p2 R (... R pn)))", 0 },
|
||||
{ "rv-counter", OPT_RV_COUNTER, "RANGE", 0,
|
||||
"n-bit counter", 0 },
|
||||
{ "rv-counter-carry", OPT_RV_COUNTER_CARRY, "RANGE", 0,
|
||||
"n-bit counter w/ carry", 0 },
|
||||
{ "rv-counter-carry-linear", OPT_RV_COUNTER_CARRY_LINEAR, "RANGE", 0,
|
||||
"n-bit counter w/ carry (linear size)", 0 },
|
||||
{ "rv-counter-linear", OPT_RV_COUNTER_LINEAR, "RANGE", 0,
|
||||
"n-bit counter (linear size)", 0 },
|
||||
{ "u-left", OPT_U_LEFT, "RANGE", 0, "(((p1 U p2) U p3) ... U pn)", 0 },
|
||||
OPT_ALIAS(gh-u),
|
||||
{ "u-right", OPT_U_RIGHT, "RANGE", 0, "(p1 U (p2 U (... U pn)))", 0 },
|
||||
OPT_ALIAS(gh-u2),
|
||||
OPT_ALIAS(go-phi),
|
||||
RANGE_DOC,
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", -20 },
|
||||
{ nullptr, 0, nullptr, 0, "The FORMAT string passed to --format may use "
|
||||
"the following interpreted sequences:", -19 },
|
||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula (in the selected syntax)", 0 },
|
||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the name of the pattern", 0 },
|
||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the argument of the pattern", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"a single %", 0 },
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
struct job
|
||||
{
|
||||
int pattern;
|
||||
struct range range;
|
||||
};
|
||||
|
||||
typedef std::vector<job> jobs_t;
|
||||
static jobs_t jobs;
|
||||
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &output_argp, 0, nullptr, -20 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
enqueue_job(int pattern, const char* range_str)
|
||||
{
|
||||
job j;
|
||||
j.pattern = pattern;
|
||||
j.range = parse_range(range_str);
|
||||
jobs.push_back(j);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case OPT_AND_F:
|
||||
case OPT_AND_FG:
|
||||
case OPT_AND_GF:
|
||||
case OPT_CCJ_ALPHA:
|
||||
case OPT_CCJ_BETA:
|
||||
case OPT_CCJ_BETA_PRIME:
|
||||
case OPT_GH_Q:
|
||||
case OPT_GH_R:
|
||||
case OPT_GO_THETA:
|
||||
case OPT_OR_FG:
|
||||
case OPT_OR_G:
|
||||
case OPT_OR_GF:
|
||||
case OPT_R_LEFT:
|
||||
case OPT_R_RIGHT:
|
||||
case OPT_RV_COUNTER:
|
||||
case OPT_RV_COUNTER_CARRY:
|
||||
case OPT_RV_COUNTER_CARRY_LINEAR:
|
||||
case OPT_RV_COUNTER_LINEAR:
|
||||
case OPT_U_LEFT:
|
||||
case OPT_U_RIGHT:
|
||||
enqueue_job(key, arg);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define G_(x) formula::G(x)
|
||||
#define F_(x) formula::F(x)
|
||||
#define X_(x) formula::X(x)
|
||||
#define Not_(x) formula::Not(x)
|
||||
|
||||
#define Implies_(x, y) formula::Implies((x), (y))
|
||||
#define Equiv_(x, y) formula::Equiv((x), (y))
|
||||
#define And_(x, y) formula::And({(x), (y)})
|
||||
#define Or_(x, y) formula::Or({(x), (y)})
|
||||
#define U_(x, y) formula::U((x), (y))
|
||||
|
||||
// F(p_1 & F(p_2 & F(p_3 & ... F(p_n))))
|
||||
static formula
|
||||
E_n(std::string name, int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
return formula::tt();
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
for (; n > 0; --n)
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << n;
|
||||
formula f = formula::ap(p.str());
|
||||
if (result)
|
||||
result = And_(f, result);
|
||||
else
|
||||
result = f;
|
||||
result = F_(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// p & X(p & X(p & ... X(p)))
|
||||
static formula
|
||||
phi_n(std::string name, int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
return formula::tt();
|
||||
|
||||
formula result = nullptr;
|
||||
formula p = formula::ap(name);
|
||||
for (; n > 0; --n)
|
||||
{
|
||||
if (result)
|
||||
result = And_(p, X_(result));
|
||||
else
|
||||
result = p;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static formula
|
||||
N_n(std::string name, int n)
|
||||
{
|
||||
return formula::F(phi_n(name, n));
|
||||
}
|
||||
|
||||
// p & X(p) & XX(p) & XXX(p) & ... X^n(p)
|
||||
static formula
|
||||
phi_prime_n(std::string name, int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
return formula::tt();
|
||||
|
||||
formula result = nullptr;
|
||||
formula p = formula::ap(name);
|
||||
for (; n > 0; --n)
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
p = X_(p);
|
||||
result = And_(result, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = p;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static formula
|
||||
N_prime_n(std::string name, int n)
|
||||
{
|
||||
return F_(phi_prime_n(name, n));
|
||||
}
|
||||
|
||||
|
||||
// GF(p_1) & GF(p_2) & ... & GF(p_n) if conj == true
|
||||
// GF(p_1) | GF(p_2) | ... | GF(p_n) if conj == false
|
||||
static formula
|
||||
GF_n(std::string name, int n, bool conj = true)
|
||||
{
|
||||
if (n <= 0)
|
||||
return conj ? formula::tt() : formula::ff();
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
op o = conj ? op::And : op::Or;
|
||||
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << i;
|
||||
formula f = G_(F_(formula::ap(p.str())));
|
||||
|
||||
if (result)
|
||||
result = formula::multop(o, {f, result});
|
||||
else
|
||||
result = f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// FG(p_1) | FG(p_2) | ... | FG(p_n) if conj == false
|
||||
// FG(p_1) & FG(p_2) & ... & FG(p_n) if conj == true
|
||||
static formula
|
||||
FG_n(std::string name, int n, bool conj = false)
|
||||
{
|
||||
if (n <= 0)
|
||||
return conj ? formula::tt() : formula::ff();
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
op o = conj ? op::And : op::Or;
|
||||
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << i;
|
||||
formula f = F_(G_(formula::ap(p.str())));
|
||||
|
||||
if (result)
|
||||
result = formula::multop(o, {f, result});
|
||||
else
|
||||
result = f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// (((p1 OP p2) OP p3)...OP pn) if right_assoc == false
|
||||
// (p1 OP (p2 OP (p3 OP (... pn) if right_assoc == true
|
||||
static formula
|
||||
bin_n(std::string name, int n, op o, bool right_assoc = false)
|
||||
{
|
||||
if (n <= 0)
|
||||
n = 1;
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << (right_assoc ? (n + 1 - i) : i);
|
||||
formula f = formula::ap(p.str());
|
||||
if (!result)
|
||||
result = f;
|
||||
else if (right_assoc)
|
||||
result = formula::binop(o, f, result);
|
||||
else
|
||||
result = formula::binop(o, result, f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// (GF(p1)|FG(p2))&(GF(p2)|FG(p3))&...&(GF(pn)|FG(p{n+1}))"
|
||||
static formula
|
||||
R_n(std::string name, int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
return formula::tt();
|
||||
|
||||
formula pi;
|
||||
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << 1;
|
||||
pi = formula::ap(p.str());
|
||||
}
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
formula gf = G_(F_(pi));
|
||||
std::ostringstream p;
|
||||
p << name << i + 1;
|
||||
pi = formula::ap(p.str());
|
||||
|
||||
formula fg = F_(G_(pi));
|
||||
|
||||
formula f = Or_(gf, fg);
|
||||
|
||||
if (result)
|
||||
result = And_(f, result);
|
||||
else
|
||||
result = f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// (F(p1)|G(p2))&(F(p2)|G(p3))&...&(F(pn)|G(p{n+1}))"
|
||||
static formula
|
||||
Q_n(std::string name, int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
return formula::tt();
|
||||
|
||||
formula pi;
|
||||
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << 1;
|
||||
pi = formula::ap(p.str());
|
||||
}
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
formula f = F_(pi);
|
||||
|
||||
std::ostringstream p;
|
||||
p << name << i + 1;
|
||||
pi = formula::ap(p.str());
|
||||
|
||||
formula g = G_(pi);
|
||||
|
||||
f = Or_(f, g);
|
||||
|
||||
if (result)
|
||||
result = And_(f, result);
|
||||
else
|
||||
result = f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// OP(p1) | OP(p2) | ... | OP(Pn) if conj == false
|
||||
// OP(p1) & OP(p2) & ... & OP(Pn) if conj == true
|
||||
static formula
|
||||
combunop_n(std::string name, int n, op o, bool conj = false)
|
||||
{
|
||||
if (n <= 0)
|
||||
return conj ? formula::tt() : formula::ff();
|
||||
|
||||
formula result = nullptr;
|
||||
|
||||
op cop = conj ? op::And : op::Or;
|
||||
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
std::ostringstream p;
|
||||
p << name << i;
|
||||
formula f = formula::unop(o, formula::ap(p.str()));
|
||||
|
||||
if (result)
|
||||
result = formula::multop(cop, {f, result});
|
||||
else
|
||||
result = f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// !((GF(p1)&GF(p2)&...&GF(pn))->G(q -> F(r)))
|
||||
// From "Fast LTL to Büchi Automata Translation" [gastin.01.cav]
|
||||
static formula
|
||||
fair_response(std::string p, std::string q, std::string r, int n)
|
||||
{
|
||||
formula fair = GF_n(p, n);
|
||||
formula resp = G_(Implies_(formula::ap(q), F_(formula::ap(r))));
|
||||
return Not_(Implies_(fair, resp));
|
||||
}
|
||||
|
||||
|
||||
// Builds X(X(...X(p))) with n occurrences of X.
|
||||
static formula
|
||||
X_n(formula p, int n)
|
||||
{
|
||||
assert(n >= 0);
|
||||
formula res = p;
|
||||
while (n--)
|
||||
res = X_(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Based on LTLcounter.pl from Kristin Rozier.
|
||||
// http://shemesh.larc.nasa.gov/people/kyr/benchmarking_scripts/
|
||||
static formula
|
||||
ltl_counter(std::string bit, std::string marker, int n, bool linear)
|
||||
{
|
||||
formula b = formula::ap(bit);
|
||||
formula neg_b = Not_(b);
|
||||
formula m = formula::ap(marker);
|
||||
formula neg_m = Not_(m);
|
||||
|
||||
std::vector<formula> res(4);
|
||||
|
||||
// The marker starts with "1", followed by n-1 "0", then "1" again,
|
||||
// n-1 "0", etc.
|
||||
if (!linear)
|
||||
{
|
||||
// G(m -> X(!m)&XX(!m)&XXX(m)) [if n = 3]
|
||||
std::vector<formula> v(n);
|
||||
for (int i = 0; i + 1 < n; ++i)
|
||||
v[i] = X_n(neg_m, i + 1);
|
||||
v[n - 1] = X_n(m, n);
|
||||
res[0] = And_(m, G_(Implies_(m, formula::And(std::move(v)))));
|
||||
}
|
||||
else
|
||||
{
|
||||
// G(m -> X(!m & X(!m X(m)))) [if n = 3]
|
||||
formula p = m;
|
||||
for (int i = n - 1; i > 0; --i)
|
||||
p = And_(neg_m, X_(p));
|
||||
res[0] = And_(m, G_(Implies_(m, X_(p))));
|
||||
}
|
||||
|
||||
// All bits are initially zero.
|
||||
if (!linear)
|
||||
{
|
||||
// !b & X(!b) & XX(!b) [if n = 3]
|
||||
std::vector<formula> v2(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
v2[i] = X_n(neg_b, i);
|
||||
res[1] = formula::And(std::move(v2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// !b & X(!b & X(!b)) [if n = 3]
|
||||
formula p = neg_b;
|
||||
for (int i = n - 1; i > 0; --i)
|
||||
p = And_(neg_b, X_(p));
|
||||
res[1] = p;
|
||||
}
|
||||
|
||||
#define AndX_(x, y) (linear ? X_(And_((x), (y))) : And_(X_(x), X_(y)))
|
||||
|
||||
// If the least significant bit is 0, it will be 1 at the next time,
|
||||
// and other bits stay the same.
|
||||
formula Xnm1_b = X_n(b, n - 1);
|
||||
formula Xn_b = X_(Xnm1_b);
|
||||
res[2] = G_(Implies_(And_(m, neg_b),
|
||||
AndX_(Xnm1_b, U_(And_(Not_(m), Equiv_(b, Xn_b)), m))));
|
||||
|
||||
// From the least significant bit to the first 0, all the bits
|
||||
// are flipped on the next value. Remaining bits are identical.
|
||||
formula Xnm1_negb = X_n(neg_b, n - 1);
|
||||
formula Xn_negb = X_(Xnm1_negb);
|
||||
res[3] = G_(Implies_(And_(m, b),
|
||||
AndX_(Xnm1_negb,
|
||||
U_(And_(And_(b, neg_m), Xn_negb),
|
||||
Or_(m, And_(And_(neg_m, neg_b),
|
||||
AndX_(Xnm1_b,
|
||||
U_(And_(neg_m,
|
||||
Equiv_(b, Xn_b)),
|
||||
m))))))));
|
||||
return formula::And(std::move(res));
|
||||
}
|
||||
|
||||
static formula
|
||||
ltl_counter_carry(std::string bit, std::string marker,
|
||||
std::string carry, int n, bool linear)
|
||||
{
|
||||
formula b = formula::ap(bit);
|
||||
formula neg_b = Not_(b);
|
||||
formula m = formula::ap(marker);
|
||||
formula neg_m = Not_(m);
|
||||
formula c = formula::ap(carry);
|
||||
formula neg_c = Not_(c);
|
||||
|
||||
std::vector<formula> res(6);
|
||||
|
||||
// The marker starts with "1", followed by n-1 "0", then "1" again,
|
||||
// n-1 "0", etc.
|
||||
if (!linear)
|
||||
{
|
||||
// G(m -> X(!m)&XX(!m)&XXX(m)) [if n = 3]
|
||||
std::vector<formula> v(n);
|
||||
for (int i = 0; i + 1 < n; ++i)
|
||||
v[i] = X_n(neg_m, i + 1);
|
||||
v[n - 1] = X_n(m, n);
|
||||
res[0] = And_(m, G_(Implies_(m, formula::And(std::move(v)))));
|
||||
}
|
||||
else
|
||||
{
|
||||
// G(m -> X(!m & X(!m X(m)))) [if n = 3]
|
||||
formula p = m;
|
||||
for (int i = n - 1; i > 0; --i)
|
||||
p = And_(neg_m, X_(p));
|
||||
res[0] = And_(m, G_(Implies_(m, X_(p))));
|
||||
}
|
||||
|
||||
// All bits are initially zero.
|
||||
if (!linear)
|
||||
{
|
||||
// !b & X(!b) & XX(!b) [if n = 3]
|
||||
std::vector<formula> v2(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
v2[i] = X_n(neg_b, i);
|
||||
res[1] = formula::And(std::move(v2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// !b & X(!b & X(!b)) [if n = 3]
|
||||
formula p = neg_b;
|
||||
for (int i = n - 1; i > 0; --i)
|
||||
p = And_(neg_b, X_(p));
|
||||
res[1] = p;
|
||||
}
|
||||
|
||||
formula Xn_b = X_n(b, n);
|
||||
formula Xn_negb = X_n(neg_b, n);
|
||||
|
||||
// If m is 1 and b is 0 then c is 0 and n steps later b is 1.
|
||||
res[2] = G_(Implies_(And_(m, neg_b), And_(neg_c, Xn_b)));
|
||||
|
||||
// If m is 1 and b is 1 then c is 1 and n steps later b is 0.
|
||||
res[3] = G_(Implies_(And_(m, b), And_(c, Xn_negb)));
|
||||
|
||||
if (!linear)
|
||||
{
|
||||
// If there's no carry, then all of the bits stay the same n steps later.
|
||||
res[4] = G_(Implies_(And_(neg_c, X_(neg_m)),
|
||||
And_(X_(Not_(c)), Equiv_(X_(b), X_(Xn_b)))));
|
||||
|
||||
// If there's a carry, then add one: flip the bits of b and
|
||||
// adjust the carry.
|
||||
res[5] = G_(Implies_(c, And_(Implies_(X_(neg_b),
|
||||
And_(X_(neg_c), X_(Xn_b))),
|
||||
Implies_(X_(b),
|
||||
And_(X_(c), X_(Xn_negb))))));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there's no carry, then all of the bits stay the same n steps later.
|
||||
res[4] = G_(Implies_(And_(neg_c, X_(neg_m)),
|
||||
X_(And_(Not_(c), Equiv_(b, Xn_b)))));
|
||||
// If there's a carry, then add one: flip the bits of b and
|
||||
// adjust the carry.
|
||||
res[5] = G_(Implies_(c, X_(And_(Implies_(neg_b, And_(neg_c, Xn_b)),
|
||||
Implies_(b, And_(c, Xn_negb))))));
|
||||
}
|
||||
return formula::And(std::move(res));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
output_pattern(int pattern, int n)
|
||||
{
|
||||
formula f = nullptr;
|
||||
switch (pattern)
|
||||
{
|
||||
// Keep this alphabetically-ordered!
|
||||
case OPT_AND_F:
|
||||
f = combunop_n("p", n, op::F, true);
|
||||
break;
|
||||
case OPT_AND_FG:
|
||||
f = FG_n("p", n, true);
|
||||
break;
|
||||
case OPT_AND_GF:
|
||||
f = GF_n("p", n, true);
|
||||
break;
|
||||
case OPT_CCJ_ALPHA:
|
||||
f = formula::And({E_n("p", n), E_n("q", n)});
|
||||
break;
|
||||
case OPT_CCJ_BETA:
|
||||
f = formula::And({N_n("p", n), N_n("q", n)});
|
||||
break;
|
||||
case OPT_CCJ_BETA_PRIME:
|
||||
f = formula::And({N_prime_n("p", n), N_prime_n("q", n)});
|
||||
break;
|
||||
case OPT_GH_Q:
|
||||
f = Q_n("p", n);
|
||||
break;
|
||||
case OPT_GH_R:
|
||||
f = R_n("p", n);
|
||||
break;
|
||||
case OPT_GO_THETA:
|
||||
f = fair_response("p", "q", "r", n);
|
||||
break;
|
||||
case OPT_OR_FG:
|
||||
f = FG_n("p", n, false);
|
||||
break;
|
||||
case OPT_OR_G:
|
||||
f = combunop_n("p", n, op::G, false);
|
||||
break;
|
||||
case OPT_OR_GF:
|
||||
f = GF_n("p", n, false);
|
||||
break;
|
||||
case OPT_R_LEFT:
|
||||
f = bin_n("p", n, op::R, false);
|
||||
break;
|
||||
case OPT_R_RIGHT:
|
||||
f = bin_n("p", n, op::R, true);
|
||||
break;
|
||||
case OPT_RV_COUNTER_CARRY:
|
||||
f = ltl_counter_carry("b", "m", "c", n, false);
|
||||
break;
|
||||
case OPT_RV_COUNTER_CARRY_LINEAR:
|
||||
f = ltl_counter_carry("b", "m", "c", n, true);
|
||||
break;
|
||||
case OPT_RV_COUNTER:
|
||||
f = ltl_counter("b", "m", n, false);
|
||||
break;
|
||||
case OPT_RV_COUNTER_LINEAR:
|
||||
f = ltl_counter("b", "m", n, true);
|
||||
break;
|
||||
case OPT_U_LEFT:
|
||||
f = bin_n("p", n, op::U, false);
|
||||
break;
|
||||
case OPT_U_RIGHT:
|
||||
f = bin_n("p", n, op::U, true);
|
||||
break;
|
||||
default:
|
||||
error(100, 0, "internal error: pattern not implemented");
|
||||
}
|
||||
|
||||
// Make sure we use only "p42"-style of atomic propositions
|
||||
// in lbt's output.
|
||||
if (output_format == lbt_output && !f.has_lbt_atomic_props())
|
||||
f = relabel(f, Pnn);
|
||||
|
||||
output_formula_checked(f, class_name[pattern - 1], n);
|
||||
}
|
||||
|
||||
static void
|
||||
run_jobs()
|
||||
{
|
||||
for (auto& j: jobs)
|
||||
{
|
||||
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
||||
int n = j.range.min;
|
||||
for (;;)
|
||||
{
|
||||
output_pattern(j.pattern, n);
|
||||
if (n == j.range.max)
|
||||
break;
|
||||
n += inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, nullptr, argp_program_doc,
|
||||
children, nullptr, nullptr };
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
error(1, 0, "Nothing to do. Try '%s --help' for more information.",
|
||||
program_name);
|
||||
|
||||
run_jobs();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <argp.h>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_r.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_output.hh"
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_post.hh"
|
||||
|
||||
#include <spot/tl/formula.hh>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/twaalgos/translate.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
|
||||
static const char argp_program_doc[] ="\
|
||||
Translate linear-time formulas (LTL/PSL) into Büchi automata.\n\n\
|
||||
By default it will apply all available optimizations to output \
|
||||
the smallest Transition-based Generalized Büchi Automata, \
|
||||
in GraphViz's format.\n\
|
||||
If multiple formulas are supplied, several automata will be output.";
|
||||
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula, in Spot's syntax", 4 },
|
||||
/**************************************************/
|
||||
{ "unambiguous", 'U', nullptr, 0, "output unambiguous automata", 2 },
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ "extra-options", 'x', "OPTS", 0,
|
||||
"fine-tuning options (see spot-x (7))", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &finput_argp, 0, nullptr, 1 },
|
||||
{ &aoutput_argp, 0, nullptr, 0 },
|
||||
{ &aoutput_o_format_argp, 0, nullptr, 0 },
|
||||
{ &post_argp, 0, nullptr, 0 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static spot::option_map extra_options;
|
||||
static spot::postprocessor::output_pref unambig = 0;
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'U':
|
||||
unambig = spot::postprocessor::Unambiguous;
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
const char* opt = extra_options.parse_options(arg);
|
||||
if (opt)
|
||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||
}
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
jobs.emplace_back(arg, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class trans_processor: public job_processor
|
||||
{
|
||||
public:
|
||||
spot::translator& trans;
|
||||
automaton_printer printer;
|
||||
|
||||
trans_processor(spot::translator& trans)
|
||||
: trans(trans), printer(ltl_input)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
process_formula(spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0)
|
||||
{
|
||||
// This should not happen, because the parser we use can only
|
||||
// read PSL/LTL formula, but since our formula type can
|
||||
// represent more than PSL formula, let's make this
|
||||
// future-proof.
|
||||
if (!f.is_psl_formula())
|
||||
{
|
||||
std::string s = spot::str_psl(f);
|
||||
error_at_line(2, 0, filename, linenum,
|
||||
"formula '%s' is not an LTL or PSL formula",
|
||||
s.c_str());
|
||||
}
|
||||
|
||||
spot::stopwatch sw;
|
||||
sw.start();
|
||||
auto aut = trans.run(&f);
|
||||
const double translation_time = sw.stop();
|
||||
|
||||
printer.print(aut, f, filename, linenum, translation_time, nullptr);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
// By default we name automata using the formula.
|
||||
opt_name = "%f";
|
||||
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[FORMULA...]",
|
||||
argp_program_doc, children, nullptr, nullptr };
|
||||
|
||||
simplification_level = 3;
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
error(2, 0, "No formula to translate? Run '%s --help' for usage.",
|
||||
program_name);
|
||||
|
||||
spot::translator trans(&extra_options);
|
||||
trans.set_pref(pref | comp | sbacc | unambig);
|
||||
trans.set_type(type);
|
||||
trans.set_level(level);
|
||||
|
||||
try
|
||||
{
|
||||
trans_processor processor(trans);
|
||||
if (processor.run())
|
||||
return 2;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,242 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <argp.h>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_r.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_post.hh"
|
||||
|
||||
#include <spot/tl/parse.hh>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/translate.hh>
|
||||
#include <spot/twa/bddprint.hh>
|
||||
|
||||
#include <spot/taalgos/tgba2ta.hh>
|
||||
#include <spot/taalgos/dot.hh>
|
||||
#include <spot/taalgos/minimize.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
Translate linear-time formulas (LTL/PSL) into Testing Automata.\n\n\
|
||||
By default it outputs a transition-based generalized Testing Automaton \
|
||||
the smallest Transition-based Generalized Büchi Automata, \
|
||||
in GraphViz's format. The input formula is assumed to be \
|
||||
stuttering-insensitive.";
|
||||
|
||||
enum {
|
||||
OPT_GTA = 1,
|
||||
OPT_INIT,
|
||||
OPT_SPLV,
|
||||
OPT_SPNO,
|
||||
OPT_TA,
|
||||
OPT_TGTA,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Automaton type:", 1 },
|
||||
{ "tgta", OPT_TGTA, nullptr, 0,
|
||||
"Transition-based Generalized Testing Automaton (default)", 0 },
|
||||
{ "ta", OPT_TA, nullptr, 0, "Testing Automaton", 0 },
|
||||
{ "gta", OPT_GTA, nullptr, 0, "Generalized Testing Automaton", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Options for TA and GTA creation:", 3 },
|
||||
{ "single-pass-lv", OPT_SPLV, nullptr, 0,
|
||||
"add an artificial livelock state to obtain a single-pass (G)TA", 0 },
|
||||
{ "single-pass", OPT_SPNO, nullptr, 0,
|
||||
"create a single-pass (G)TA without artificial livelock state", 0 },
|
||||
{ "multiple-init", OPT_INIT, nullptr, 0,
|
||||
"do not create the fake initial state", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", 4 },
|
||||
{ "utf8", '8', nullptr, 0, "enable UTF-8 characters in output", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ "extra-options", 'x', "OPTS", 0,
|
||||
"fine-tuning options (see spot-x (7))", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &finput_argp, 0, nullptr, 1 },
|
||||
{ &post_argp, 0, nullptr, 20 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
enum ta_types { TGTA, GTA, TA };
|
||||
ta_types ta_type = TGTA;
|
||||
|
||||
bool utf8 = false;
|
||||
const char* stats = "";
|
||||
spot::option_map extra_options;
|
||||
bool opt_with_artificial_initial_state = true;
|
||||
bool opt_single_pass_emptiness_check = false;
|
||||
bool opt_with_artificial_livelock = false;
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case '8':
|
||||
spot::enable_utf8();
|
||||
break;
|
||||
case 'B':
|
||||
type = spot::postprocessor::BA;
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
const char* opt = extra_options.parse_options(arg);
|
||||
if (opt)
|
||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||
}
|
||||
break;
|
||||
case OPT_TGTA:
|
||||
ta_type = TGTA;
|
||||
type = spot::postprocessor::TGBA;
|
||||
break;
|
||||
case OPT_GTA:
|
||||
ta_type = GTA;
|
||||
type = spot::postprocessor::TGBA;
|
||||
break;
|
||||
case OPT_TA:
|
||||
ta_type = TA;
|
||||
type = spot::postprocessor::BA;
|
||||
break;
|
||||
case OPT_INIT:
|
||||
opt_with_artificial_initial_state = false;
|
||||
break;
|
||||
case OPT_SPLV:
|
||||
opt_with_artificial_livelock = true;
|
||||
break;
|
||||
case OPT_SPNO:
|
||||
opt_single_pass_emptiness_check = true;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
jobs.emplace_back(arg, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class trans_processor: public job_processor
|
||||
{
|
||||
public:
|
||||
spot::translator& trans;
|
||||
|
||||
trans_processor(spot::translator& trans)
|
||||
: trans(trans)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
process_formula(spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0)
|
||||
{
|
||||
auto aut = trans.run(&f);
|
||||
|
||||
// This should not happen, because the parser we use can only
|
||||
// read PSL/LTL formula, but since our formula type can
|
||||
// represent more than PSL formula, let's make this
|
||||
// future-proof.
|
||||
if (!f.is_psl_formula())
|
||||
{
|
||||
std::string s = spot::str_psl(f);
|
||||
error_at_line(2, 0, filename, linenum,
|
||||
"formula '%s' is not an LTL or PSL formula",
|
||||
s.c_str());
|
||||
}
|
||||
|
||||
bdd ap_set = atomic_prop_collect_as_bdd(f, aut);
|
||||
|
||||
if (ta_type != TGTA)
|
||||
{
|
||||
auto testing_automaton =
|
||||
tgba_to_ta(aut, ap_set, type == spot::postprocessor::BA,
|
||||
opt_with_artificial_initial_state,
|
||||
opt_single_pass_emptiness_check,
|
||||
opt_with_artificial_livelock);
|
||||
if (level != spot::postprocessor::Low)
|
||||
testing_automaton = spot::minimize_ta(testing_automaton);
|
||||
spot::print_dot(std::cout, testing_automaton);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tgta = tgba_to_tgta(aut, ap_set);
|
||||
if (level != spot::postprocessor::Low)
|
||||
tgta = spot::minimize_tgta(tgta);
|
||||
spot::print_dot(std::cout, tgta->get_ta());
|
||||
}
|
||||
flush_cout();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[FORMULA...]",
|
||||
argp_program_doc, children, nullptr, nullptr };
|
||||
|
||||
simplification_level = 3;
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
error(2, 0, "No formula to translate? Run '%s --help' for usage.",
|
||||
program_name);
|
||||
|
||||
spot::translator trans(&extra_options);
|
||||
trans.set_pref(pref | comp | sbacc);
|
||||
trans.set_type(type);
|
||||
trans.set_level(level);
|
||||
|
||||
trans_processor processor(trans);
|
||||
if (processor.run())
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
1479
spot/bin/ltlcross.cc
1479
spot/bin/ltlcross.cc
File diff suppressed because it is too large
Load diff
|
|
@ -1,337 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_conv.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_post.hh"
|
||||
#include "common_trans.hh"
|
||||
#include "common_hoaread.hh"
|
||||
|
||||
#include <spot/tl/relabel.hh>
|
||||
#include <spot/misc/bareword.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
#include <spot/twaalgos/lbtt.hh>
|
||||
#include <spot/twaalgos/relabel.hh>
|
||||
#include <spot/twaalgos/totgba.hh>
|
||||
#include <spot/parseaut/public.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
Run LTL/PSL formulas through another program, performing conversion\n\
|
||||
of input and output as required.";
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
|
||||
static const argp_option more_o_format[] =
|
||||
{
|
||||
{ "%R", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"serial number of the formula translated", 0 },
|
||||
{ "%T", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"tool used for translation", 0 },
|
||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"formula translated", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
// This is not very elegant, but we need to add the above %-escape
|
||||
// sequences to those of aoutput_o_fromat_argp for the --help output.
|
||||
// So far I've failed to instruct argp to merge those two lists into a
|
||||
// single block.
|
||||
static const struct argp*
|
||||
build_percent_list()
|
||||
{
|
||||
const argp_option* iter = aoutput_o_format_argp.options;
|
||||
unsigned count = 0;
|
||||
while (iter->name || iter->doc)
|
||||
{
|
||||
++count;
|
||||
++iter;
|
||||
}
|
||||
|
||||
unsigned s = count * sizeof(argp_option);
|
||||
argp_option* d =
|
||||
static_cast<argp_option*>(malloc(sizeof(more_o_format) + s));
|
||||
memcpy(d, aoutput_o_format_argp.options, s);
|
||||
memcpy(d + count, more_o_format, sizeof(more_o_format));
|
||||
|
||||
static const struct argp more_o_format_argp =
|
||||
{ d, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
|
||||
return &more_o_format_argp;
|
||||
}
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &hoaread_argp, 0, "Parsing of automata:", 3 },
|
||||
{ &finput_argp, 0, nullptr, 1 },
|
||||
{ &trans_argp, 0, nullptr, 3 },
|
||||
{ &aoutput_argp, 0, nullptr, 4 },
|
||||
{ build_percent_list(), 0, nullptr, 5 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case ARGP_KEY_ARG:
|
||||
translators.push_back(arg);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class xtranslator_runner: public translator_runner
|
||||
{
|
||||
public:
|
||||
xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||
: translator_runner(dict, true)
|
||||
{
|
||||
}
|
||||
|
||||
spot::twa_graph_ptr
|
||||
translate(unsigned int translator_num, bool& problem, double& duration)
|
||||
{
|
||||
output.reset(translator_num);
|
||||
|
||||
std::ostringstream command;
|
||||
format(command, translators[translator_num].cmd);
|
||||
|
||||
std::string cmd = command.str();
|
||||
//std::cerr << "Running [" << l << translator_num << "]: "
|
||||
// << cmd << std::endl;
|
||||
spot::stopwatch sw;
|
||||
sw.start();
|
||||
int es = exec_with_timeout(cmd.c_str());
|
||||
duration = sw.stop();
|
||||
|
||||
spot::twa_graph_ptr res = nullptr;
|
||||
if (timed_out)
|
||||
{
|
||||
problem = false; // A timeout is considered benign
|
||||
std::cerr << "warning: timeout during execution of command \""
|
||||
<< cmd << "\"\n";
|
||||
++timeout_count;
|
||||
}
|
||||
else if (WIFSIGNALED(es))
|
||||
{
|
||||
problem = true;
|
||||
es = WTERMSIG(es);
|
||||
std::cerr << "error: execution of command \"" << cmd
|
||||
<< "\" terminated by signal " << es << ".\n";
|
||||
}
|
||||
else if (WIFEXITED(es) && WEXITSTATUS(es) != 0)
|
||||
{
|
||||
problem = true;
|
||||
es = WEXITSTATUS(es);
|
||||
std::cerr << "error: execution of command \"" << cmd
|
||||
<< "\" returned exit code " << es << ".\n";
|
||||
}
|
||||
else if (output.val())
|
||||
{
|
||||
problem = false;
|
||||
auto aut = spot::parse_aut(output.val()->name(), dict,
|
||||
spot::default_environment::instance(),
|
||||
opt_parse);
|
||||
if (!aut->errors.empty())
|
||||
{
|
||||
problem = true;
|
||||
std::cerr << "error: failed to parse the automaton "
|
||||
"produced by \"" << cmd << "\".\n";
|
||||
aut->format_errors(std::cerr);
|
||||
res = nullptr;
|
||||
}
|
||||
else if (aut->aborted)
|
||||
{
|
||||
problem = true;
|
||||
std::cerr << "error: command \"" << cmd
|
||||
<< "\" aborted its output.\n";
|
||||
res = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = aut->aut;
|
||||
}
|
||||
}
|
||||
else // No automaton output
|
||||
{
|
||||
problem = false;
|
||||
res = nullptr;
|
||||
}
|
||||
|
||||
output.cleanup();
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class processor: public job_processor
|
||||
{
|
||||
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
||||
xtranslator_runner runner;
|
||||
automaton_printer printer;
|
||||
spot::postprocessor& post;
|
||||
spot::printable_value<std::string> cmdname;
|
||||
spot::printable_value<unsigned> roundval;
|
||||
spot::printable_value<std::string> inputf;
|
||||
|
||||
public:
|
||||
processor(spot::postprocessor& post)
|
||||
: runner(dict), post(post)
|
||||
{
|
||||
printer.add_stat('T', &cmdname);
|
||||
printer.add_stat('R', &roundval);
|
||||
printer.add_stat('f', &inputf);
|
||||
}
|
||||
|
||||
~processor()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
process_string(const std::string& input,
|
||||
const char* filename,
|
||||
int linenum)
|
||||
{
|
||||
spot::parse_error_list pel;
|
||||
spot::formula f = parse_formula(input, pel);
|
||||
|
||||
if (!f || !pel.empty())
|
||||
{
|
||||
if (filename)
|
||||
error_at_line(0, 0, filename, linenum, "parse error:");
|
||||
spot::format_parse_errors(std::cerr, input, pel);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inputf = input;
|
||||
process_formula(f, filename, linenum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
process_formula(spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0)
|
||||
{
|
||||
std::unique_ptr<spot::relabeling_map> relmap;
|
||||
|
||||
// If atomic propositions are incompatible with one of the
|
||||
// output, relabel the formula.
|
||||
if ((!f.has_lbt_atomic_props() &&
|
||||
(runner.has('l') || runner.has('L') || runner.has('T')))
|
||||
|| (!f.has_spin_atomic_props() &&
|
||||
(runner.has('s') || runner.has('S'))))
|
||||
{
|
||||
relmap.reset(new spot::relabeling_map);
|
||||
f = spot::relabel(f, spot::Pnn, relmap.get());
|
||||
}
|
||||
|
||||
static unsigned round = 1;
|
||||
runner.round_formula(f, round);
|
||||
|
||||
unsigned ts = translators.size();
|
||||
for (unsigned t = 0; t < ts; ++t)
|
||||
{
|
||||
bool problem;
|
||||
double translation_time;
|
||||
auto aut = runner.translate(t, problem, translation_time);
|
||||
if (problem)
|
||||
error_at_line(2, 0, filename, linenum, "aborting here");
|
||||
if (aut)
|
||||
{
|
||||
if (relmap)
|
||||
relabel_here(aut, relmap.get());
|
||||
aut = post.run(aut, f);
|
||||
cmdname = translators[t].name;
|
||||
roundval = round;
|
||||
printer.print(aut, f, filename, linenum, translation_time,
|
||||
nullptr);
|
||||
};
|
||||
}
|
||||
spot::cleanup_tmpfiles();
|
||||
++round;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[COMMANDFMT...]",
|
||||
argp_program_doc, children, nullptr, nullptr };
|
||||
|
||||
// Disable post-processing as much as possible by default.
|
||||
level = spot::postprocessor::Low;
|
||||
pref = spot::postprocessor::Any;
|
||||
type = spot::postprocessor::Generic;
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
jobs.emplace_back("-", 1);
|
||||
|
||||
if (translators.empty())
|
||||
error(2, 0, "No translator to run? Run '%s --help' for usage.",
|
||||
program_name);
|
||||
|
||||
setup_sig_handler();
|
||||
|
||||
spot::postprocessor post;
|
||||
post.set_pref(pref | comp | sbacc);
|
||||
post.set_type(type);
|
||||
post.set_level(level);
|
||||
|
||||
try
|
||||
{
|
||||
processor p(post);
|
||||
if (p.run())
|
||||
return 2;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,665 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <argp.h>
|
||||
#include <cstring>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_output.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_conv.hh"
|
||||
#include "common_r.hh"
|
||||
|
||||
#include <spot/misc/hash.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/tl/length.hh>
|
||||
#include <spot/tl/relabel.hh>
|
||||
#include <spot/tl/unabbrev.hh>
|
||||
#include <spot/tl/remove_x.hh>
|
||||
#include <spot/tl/apcollect.hh>
|
||||
#include <spot/tl/exclusive.hh>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/minimize.hh>
|
||||
#include <spot/twaalgos/strength.hh>
|
||||
#include <spot/twaalgos/stutter.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
Read a list of formulas and output them back after some optional processing.\v\
|
||||
Exit status:\n\
|
||||
0 if some formulas were output (skipped syntax errors do not count)\n\
|
||||
1 if no formulas were output (no match)\n\
|
||||
2 if any error has been reported";
|
||||
|
||||
enum {
|
||||
OPT_AP_N = 256,
|
||||
OPT_BOOLEAN,
|
||||
OPT_BOOLEAN_TO_ISOP,
|
||||
OPT_BSIZE_MAX,
|
||||
OPT_BSIZE_MIN,
|
||||
OPT_DEFINE,
|
||||
OPT_DROP_ERRORS,
|
||||
OPT_EQUIVALENT_TO,
|
||||
OPT_EXCLUSIVE_AP,
|
||||
OPT_EVENTUAL,
|
||||
OPT_GUARANTEE,
|
||||
OPT_IGNORE_ERRORS,
|
||||
OPT_IMPLIED_BY,
|
||||
OPT_IMPLY,
|
||||
OPT_LTL,
|
||||
OPT_NEGATE,
|
||||
OPT_NNF,
|
||||
OPT_OBLIGATION,
|
||||
OPT_RELABEL,
|
||||
OPT_RELABEL_BOOL,
|
||||
OPT_REMOVE_WM,
|
||||
OPT_REMOVE_X,
|
||||
OPT_SAFETY,
|
||||
OPT_SIZE_MAX,
|
||||
OPT_SIZE_MIN,
|
||||
OPT_SKIP_ERRORS,
|
||||
OPT_STUTTER_INSENSITIVE,
|
||||
OPT_SYNTACTIC_GUARANTEE,
|
||||
OPT_SYNTACTIC_OBLIGATION,
|
||||
OPT_SYNTACTIC_PERSISTENCE,
|
||||
OPT_SYNTACTIC_RECURRENCE,
|
||||
OPT_SYNTACTIC_SAFETY,
|
||||
OPT_SYNTACTIC_SI,
|
||||
OPT_UNABBREVIATE,
|
||||
OPT_UNIVERSAL,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Error handling:", 2 },
|
||||
{ "skip-errors", OPT_SKIP_ERRORS, nullptr, 0,
|
||||
"output erroneous lines as-is without processing", 0 },
|
||||
{ "drop-errors", OPT_DROP_ERRORS, nullptr, 0,
|
||||
"discard erroneous lines (default)", 0 },
|
||||
{ "ignore-errors", OPT_IGNORE_ERRORS, nullptr, 0,
|
||||
"do not report syntax errors", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Transformation options:", 3 },
|
||||
{ "negate", OPT_NEGATE, nullptr, 0, "negate each formula", 0 },
|
||||
{ "nnf", OPT_NNF, nullptr, 0,
|
||||
"rewrite formulas in negative normal form", 0 },
|
||||
{ "relabel", OPT_RELABEL, "abc|pnn", OPTION_ARG_OPTIONAL,
|
||||
"relabel all atomic propositions, alphabetically unless " \
|
||||
"specified otherwise", 0 },
|
||||
{ "relabel-bool", OPT_RELABEL_BOOL, "abc|pnn", OPTION_ARG_OPTIONAL,
|
||||
"relabel Boolean subexpressions, alphabetically unless " \
|
||||
"specified otherwise", 0 },
|
||||
{ "define", OPT_DEFINE, "FILENAME", OPTION_ARG_OPTIONAL,
|
||||
"when used with --relabel or --relabel-bool, output the relabeling map "
|
||||
"using #define statements", 0 },
|
||||
{ "remove-wm", OPT_REMOVE_WM, nullptr, 0,
|
||||
"rewrite operators W and M using U and R (this is an alias for "
|
||||
"--unabbreviate=WM)", 0 },
|
||||
{ "boolean-to-isop", OPT_BOOLEAN_TO_ISOP, nullptr, 0,
|
||||
"rewrite Boolean subformulas as irredundant sum of products "
|
||||
"(implies at least -r1)", 0 },
|
||||
{ "remove-x", OPT_REMOVE_X, nullptr, 0,
|
||||
"remove X operators (valid only for stutter-insensitive properties)",
|
||||
0 },
|
||||
{ "unabbreviate", OPT_UNABBREVIATE, "STR", OPTION_ARG_OPTIONAL,
|
||||
"remove all occurrences of the operators specified by STR, which "
|
||||
"must be a substring of \"eFGiMRW^\", where 'e', 'i', and '^' stand "
|
||||
"respectively for <->, ->, and xor. If no argument is passed, "
|
||||
"the subset \"eFGiMW^\" is used.", 0 },
|
||||
{ "exclusive-ap", OPT_EXCLUSIVE_AP, "AP,AP,...", 0,
|
||||
"if any of those APs occur in the formula, add a term ensuring "
|
||||
"two of them may not be true at the same time. Use this option "
|
||||
"multiple times to declare independent groups of exclusive "
|
||||
"propositions.", 0 },
|
||||
DECLARE_OPT_R,
|
||||
LEVEL_DOC(4),
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0,
|
||||
"Filtering options (matching is done after transformation):", 5 },
|
||||
{ "ltl", OPT_LTL, nullptr, 0,
|
||||
"match only LTL formulas (no PSL operator)", 0 },
|
||||
{ "boolean", OPT_BOOLEAN, nullptr, 0, "match Boolean formulas", 0 },
|
||||
{ "eventual", OPT_EVENTUAL, nullptr, 0, "match pure eventualities", 0 },
|
||||
{ "universal", OPT_UNIVERSAL, nullptr, 0,
|
||||
"match purely universal formulas", 0 },
|
||||
{ "syntactic-safety", OPT_SYNTACTIC_SAFETY, nullptr, 0,
|
||||
"match syntactic-safety formulas", 0 },
|
||||
{ "syntactic-guarantee", OPT_SYNTACTIC_GUARANTEE, nullptr, 0,
|
||||
"match syntactic-guarantee formulas", 0 },
|
||||
{ "syntactic-obligation", OPT_SYNTACTIC_OBLIGATION, nullptr, 0,
|
||||
"match syntactic-obligation formulas", 0 },
|
||||
{ "syntactic-recurrence", OPT_SYNTACTIC_RECURRENCE, nullptr, 0,
|
||||
"match syntactic-recurrence formulas", 0 },
|
||||
{ "syntactic-persistence", OPT_SYNTACTIC_PERSISTENCE, nullptr, 0,
|
||||
"match syntactic-persistence formulas", 0 },
|
||||
{ "syntactic-stutter-invariant", OPT_SYNTACTIC_SI, nullptr, 0,
|
||||
"match stutter-invariant formulas syntactically (LTL-X or siPSL)", 0 },
|
||||
{ "nox", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||
{ "safety", OPT_SAFETY, nullptr, 0,
|
||||
"match safety formulas (even pathological)", 0 },
|
||||
{ "guarantee", OPT_GUARANTEE, nullptr, 0,
|
||||
"match guarantee formulas (even pathological)", 0 },
|
||||
{ "obligation", OPT_OBLIGATION, nullptr, 0,
|
||||
"match obligation formulas (even pathological)", 0 },
|
||||
{ "size-max", OPT_SIZE_MAX, "INT", 0,
|
||||
"match formulas with size <= INT", 0 },
|
||||
{ "size-min", OPT_SIZE_MIN, "INT", 0,
|
||||
"match formulas with size >= INT", 0 },
|
||||
{ "bsize-max", OPT_BSIZE_MAX, "INT", 0,
|
||||
"match formulas with Boolean size <= INT", 0 },
|
||||
{ "bsize-min", OPT_BSIZE_MIN, "INT", 0,
|
||||
"match formulas with Boolean size >= INT", 0 },
|
||||
{ "implied-by", OPT_IMPLIED_BY, "FORMULA", 0,
|
||||
"match formulas implied by FORMULA", 0 },
|
||||
{ "imply", OPT_IMPLY, "FORMULA", 0,
|
||||
"match formulas implying FORMULA", 0 },
|
||||
{ "equivalent-to", OPT_EQUIVALENT_TO, "FORMULA", 0,
|
||||
"match formulas equivalent to FORMULA", 0 },
|
||||
{ "stutter-insensitive", OPT_STUTTER_INSENSITIVE, nullptr, 0,
|
||||
"match stutter-insensitive LTL formulas", 0 },
|
||||
{ "stutter-invariant", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||
{ "ap", OPT_AP_N, "N", 0,
|
||||
"match formulas which use exactly N atomic propositions", 0 },
|
||||
{ "invert-match", 'v', nullptr, 0, "select non-matching formulas", 0},
|
||||
{ "unique", 'u', nullptr, 0,
|
||||
"drop formulas that have already been output (not affected by -v)", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", -20 },
|
||||
{ "count", 'c', nullptr, 0, "print only a count of matched formulas", 0 },
|
||||
{ "quiet", 'q', nullptr, 0, "suppress all normal output", 0 },
|
||||
{ "max-count", 'n', "NUM", 0, "output at most NUM formulas", 0 },
|
||||
{ nullptr, 0, nullptr, 0, "The FORMAT string passed to --format may use "\
|
||||
"the following interpreted sequences:", -19 },
|
||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula (in the selected syntax)", 0 },
|
||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the name of the input file", 0 },
|
||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the original line number in the input file", 0 },
|
||||
{ "%<", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the part of the line before the formula if it "
|
||||
"comes from a column extracted from a CSV file", 0 },
|
||||
{ "%>", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the part of the line after the formula if it "
|
||||
"comes from a column extracted from a CSV file", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"a single %", 0 },
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &finput_argp, 0, nullptr, 1 },
|
||||
{ &output_argp, 0, nullptr, -20 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static bool one_match = false;
|
||||
|
||||
enum error_style_t { drop_errors, skip_errors };
|
||||
static error_style_t error_style = drop_errors;
|
||||
static bool ignore_errors = false;
|
||||
static bool nnf = false;
|
||||
static bool negate = false;
|
||||
static bool boolean_to_isop = false;
|
||||
static bool unique = false;
|
||||
static bool psl = false;
|
||||
static bool ltl = false;
|
||||
static bool invert = false;
|
||||
static bool boolean = false;
|
||||
static bool universal = false;
|
||||
static bool eventual = false;
|
||||
static bool syntactic_safety = false;
|
||||
static bool syntactic_guarantee = false;
|
||||
static bool syntactic_obligation = false;
|
||||
static bool syntactic_recurrence = false;
|
||||
static bool syntactic_persistence = false;
|
||||
static bool syntactic_si = false;
|
||||
static bool safety = false;
|
||||
static bool guarantee = false;
|
||||
static bool obligation = false;
|
||||
static int size_min = -1;
|
||||
static int size_max = -1;
|
||||
static int bsize_min = -1;
|
||||
static int bsize_max = -1;
|
||||
enum relabeling_mode { NoRelabeling = 0, ApRelabeling, BseRelabeling };
|
||||
static relabeling_mode relabeling = NoRelabeling;
|
||||
static spot::relabeling_style style = spot::Abc;
|
||||
static bool remove_x = false;
|
||||
static bool stutter_insensitive = false;
|
||||
static bool ap = false;
|
||||
static unsigned ap_n = 0;
|
||||
static int opt_max_count = -1;
|
||||
static long int match_count = 0;
|
||||
static spot::exclusive_ap excl_ap;
|
||||
static std::unique_ptr<output_file> output_define = nullptr;
|
||||
static std::string unabbreviate;
|
||||
|
||||
static spot::formula implied_by = nullptr;
|
||||
static spot::formula imply = nullptr;
|
||||
static spot::formula equivalent_to = nullptr;
|
||||
|
||||
static spot::formula
|
||||
parse_formula_arg(const std::string& input)
|
||||
{
|
||||
spot::parse_error_list pel;
|
||||
spot::formula f = parse_formula(input, pel);
|
||||
if (spot::format_parse_errors(std::cerr, input, pel))
|
||||
error(2, 0, "parse error when parsing an argument");
|
||||
return f;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'c':
|
||||
output_format = count_output;
|
||||
break;
|
||||
case 'n':
|
||||
opt_max_count = to_pos_int(arg);
|
||||
break;
|
||||
case 'q':
|
||||
output_format = quiet_output;
|
||||
break;
|
||||
case OPT_R:
|
||||
parse_r(arg);
|
||||
break;
|
||||
case 'u':
|
||||
unique = true;
|
||||
break;
|
||||
case 'v':
|
||||
invert = true;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
case OPT_BOOLEAN:
|
||||
boolean = true;
|
||||
break;
|
||||
case OPT_BOOLEAN_TO_ISOP:
|
||||
boolean_to_isop = true;
|
||||
break;
|
||||
case OPT_BSIZE_MIN:
|
||||
bsize_min = to_int(arg);
|
||||
break;
|
||||
case OPT_BSIZE_MAX:
|
||||
bsize_max = to_int(arg);
|
||||
break;
|
||||
case OPT_DEFINE:
|
||||
output_define.reset(new output_file(arg ? arg : "-"));
|
||||
break;
|
||||
case OPT_DROP_ERRORS:
|
||||
error_style = drop_errors;
|
||||
break;
|
||||
case OPT_EVENTUAL:
|
||||
eventual = true;
|
||||
break;
|
||||
case OPT_EQUIVALENT_TO:
|
||||
{
|
||||
if (equivalent_to)
|
||||
error(2, 0, "only one --equivalent-to option can be given");
|
||||
equivalent_to = parse_formula_arg(arg);
|
||||
break;
|
||||
}
|
||||
case OPT_EXCLUSIVE_AP:
|
||||
excl_ap.add_group(arg);
|
||||
break;
|
||||
case OPT_GUARANTEE:
|
||||
guarantee = obligation = true;
|
||||
break;
|
||||
case OPT_IGNORE_ERRORS:
|
||||
ignore_errors = true;
|
||||
break;
|
||||
case OPT_IMPLIED_BY:
|
||||
{
|
||||
spot::formula i = parse_formula_arg(arg);
|
||||
// a→c∧b→c ≡ (a∨b)→c
|
||||
implied_by = spot::formula::Or({implied_by, i});
|
||||
break;
|
||||
}
|
||||
case OPT_IMPLY:
|
||||
{
|
||||
// a→b∧a→c ≡ a→(b∧c)
|
||||
spot::formula i = parse_formula_arg(arg);
|
||||
imply = spot::formula::And({imply, i});
|
||||
break;
|
||||
}
|
||||
case OPT_LTL:
|
||||
ltl = true;
|
||||
break;
|
||||
case OPT_NEGATE:
|
||||
negate = true;
|
||||
break;
|
||||
case OPT_NNF:
|
||||
nnf = true;
|
||||
break;
|
||||
case OPT_OBLIGATION:
|
||||
obligation = true;
|
||||
break;
|
||||
case OPT_RELABEL:
|
||||
case OPT_RELABEL_BOOL:
|
||||
relabeling = (key == OPT_RELABEL_BOOL ? BseRelabeling : ApRelabeling);
|
||||
if (!arg || !strncasecmp(arg, "abc", 6))
|
||||
style = spot::Abc;
|
||||
else if (!strncasecmp(arg, "pnn", 4))
|
||||
style = spot::Pnn;
|
||||
else
|
||||
error(2, 0, "invalid argument for --relabel%s: '%s'",
|
||||
(key == OPT_RELABEL_BOOL ? "-bool" : ""),
|
||||
arg);
|
||||
break;
|
||||
case OPT_REMOVE_WM:
|
||||
unabbreviate += "MW";
|
||||
break;
|
||||
case OPT_REMOVE_X:
|
||||
remove_x = true;
|
||||
break;
|
||||
case OPT_SAFETY:
|
||||
safety = obligation = true;
|
||||
break;
|
||||
case OPT_SIZE_MIN:
|
||||
size_min = to_int(arg);
|
||||
break;
|
||||
case OPT_SIZE_MAX:
|
||||
size_max = to_int(arg);
|
||||
break;
|
||||
case OPT_SKIP_ERRORS:
|
||||
error_style = skip_errors;
|
||||
break;
|
||||
case OPT_STUTTER_INSENSITIVE:
|
||||
stutter_insensitive = true;
|
||||
break;
|
||||
case OPT_UNABBREVIATE:
|
||||
if (arg)
|
||||
unabbreviate += arg;
|
||||
else
|
||||
unabbreviate += spot::default_unabbrev_string;
|
||||
break;
|
||||
case OPT_AP_N:
|
||||
ap = true;
|
||||
ap_n = to_int(arg);
|
||||
break;
|
||||
case OPT_SYNTACTIC_SAFETY:
|
||||
syntactic_safety = true;
|
||||
break;
|
||||
case OPT_SYNTACTIC_GUARANTEE:
|
||||
syntactic_guarantee = true;
|
||||
break;
|
||||
case OPT_SYNTACTIC_OBLIGATION:
|
||||
syntactic_obligation = true;
|
||||
break;
|
||||
case OPT_SYNTACTIC_RECURRENCE:
|
||||
syntactic_recurrence = true;
|
||||
break;
|
||||
case OPT_SYNTACTIC_PERSISTENCE:
|
||||
syntactic_persistence = true;
|
||||
break;
|
||||
case OPT_SYNTACTIC_SI:
|
||||
syntactic_si = true;
|
||||
break;
|
||||
case OPT_UNIVERSAL:
|
||||
universal = true;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef
|
||||
std::unordered_set<spot::formula> fset_t;
|
||||
|
||||
namespace
|
||||
{
|
||||
class ltl_processor: public job_processor
|
||||
{
|
||||
public:
|
||||
spot::tl_simplifier& simpl;
|
||||
fset_t unique_set;
|
||||
spot::relabeling_map relmap;
|
||||
|
||||
ltl_processor(spot::tl_simplifier& simpl)
|
||||
: simpl(simpl)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
process_string(const std::string& input,
|
||||
const char* filename = nullptr, int linenum = 0)
|
||||
{
|
||||
spot::parse_error_list pel;
|
||||
spot::formula f = parse_formula(input, pel);
|
||||
|
||||
if (!f || pel.size() > 0)
|
||||
{
|
||||
if (!ignore_errors)
|
||||
{
|
||||
if (filename)
|
||||
error_at_line(0, 0, filename, linenum, "parse error:");
|
||||
spot::format_parse_errors(std::cerr, input, pel);
|
||||
}
|
||||
|
||||
if (error_style == skip_errors)
|
||||
std::cout << input << std::endl;
|
||||
else
|
||||
assert(error_style == drop_errors);
|
||||
check_cout();
|
||||
return !ignore_errors;
|
||||
}
|
||||
try
|
||||
{
|
||||
return process_formula(f, filename, linenum);
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error_at_line(2, 0, filename, linenum, "%s", e.what());
|
||||
SPOT_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
process_formula(spot::formula f,
|
||||
const char* filename = nullptr, int linenum = 0)
|
||||
{
|
||||
if (opt_max_count >= 0 && match_count >= opt_max_count)
|
||||
{
|
||||
abort_run = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (negate)
|
||||
f = spot::formula::Not(f);
|
||||
|
||||
if (remove_x)
|
||||
{
|
||||
// If simplification are enabled, we do them before and after.
|
||||
if (simplification_level)
|
||||
f = simpl.simplify(f);
|
||||
f = spot::remove_x(f);
|
||||
}
|
||||
|
||||
if (simplification_level || boolean_to_isop)
|
||||
f = simpl.simplify(f);
|
||||
|
||||
if (nnf)
|
||||
f = simpl.negative_normal_form(f);
|
||||
|
||||
switch (relabeling)
|
||||
{
|
||||
case ApRelabeling:
|
||||
{
|
||||
relmap.clear();
|
||||
f = spot::relabel(f, style, &relmap);
|
||||
break;
|
||||
}
|
||||
case BseRelabeling:
|
||||
{
|
||||
relmap.clear();
|
||||
f = spot::relabel_bse(f, style, &relmap);
|
||||
break;
|
||||
}
|
||||
case NoRelabeling:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!unabbreviate.empty())
|
||||
f = spot::unabbreviate(f, unabbreviate.c_str());
|
||||
|
||||
if (!excl_ap.empty())
|
||||
f = excl_ap.constrain(f);
|
||||
|
||||
bool matched = true;
|
||||
|
||||
matched &= !ltl || f.is_ltl_formula();
|
||||
matched &= !psl || f.is_psl_formula();
|
||||
matched &= !boolean || f.is_boolean();
|
||||
matched &= !universal || f.is_universal();
|
||||
matched &= !eventual || f.is_eventual();
|
||||
matched &= !syntactic_safety || f.is_syntactic_safety();
|
||||
matched &= !syntactic_guarantee || f.is_syntactic_guarantee();
|
||||
matched &= !syntactic_obligation || f.is_syntactic_obligation();
|
||||
matched &= !syntactic_recurrence || f.is_syntactic_recurrence();
|
||||
matched &= !syntactic_persistence || f.is_syntactic_persistence();
|
||||
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
|
||||
matched &= !ap || atomic_prop_collect(f)->size() == ap_n;
|
||||
|
||||
if (matched && (size_min > 0 || size_max >= 0))
|
||||
{
|
||||
int l = spot::length(f);
|
||||
matched &= (size_min <= 0) || (l >= size_min);
|
||||
matched &= (size_max < 0) || (l <= size_max);
|
||||
}
|
||||
|
||||
if (matched && (bsize_min > 0 || bsize_max >= 0))
|
||||
{
|
||||
int l = spot::length_boolone(f);
|
||||
matched &= (bsize_min <= 0) || (l >= bsize_min);
|
||||
matched &= (bsize_max < 0) || (l <= bsize_max);
|
||||
}
|
||||
|
||||
matched &= !implied_by || simpl.implication(implied_by, f);
|
||||
matched &= !imply || simpl.implication(f, imply);
|
||||
matched &= !equivalent_to || simpl.are_equivalent(f, equivalent_to);
|
||||
matched &= !stutter_insensitive || spot::is_stutter_invariant(f);
|
||||
|
||||
// Match obligations and subclasses using WDBA minimization.
|
||||
// Because this is costly, we compute it later, so that we don't
|
||||
// have to compute it on formulas that have been discarded for
|
||||
// other reasons.
|
||||
if (matched && obligation)
|
||||
{
|
||||
auto aut = ltl_to_tgba_fm(f, simpl.get_dict());
|
||||
auto min = minimize_obligation(aut, f);
|
||||
assert(min);
|
||||
if (aut == min)
|
||||
{
|
||||
// Not an obligation
|
||||
matched = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
matched &= !guarantee || is_terminal_automaton(min);
|
||||
matched &= !safety || is_safety_mwdba(min);
|
||||
}
|
||||
}
|
||||
|
||||
matched ^= invert;
|
||||
|
||||
if (unique && !unique_set.insert(f).second)
|
||||
matched = false;
|
||||
|
||||
if (matched)
|
||||
{
|
||||
if (output_define
|
||||
&& output_format != count_output
|
||||
&& output_format != quiet_output)
|
||||
{
|
||||
// Sort the formulas alphabetically.
|
||||
std::map<std::string, spot::formula> m;
|
||||
for (auto& p: relmap)
|
||||
m.emplace(str_psl(p.first), p.second);
|
||||
for (auto& p: m)
|
||||
stream_formula(output_define->ostream()
|
||||
<< "#define " << p.first << " (",
|
||||
p.second, filename, linenum) << ")\n";
|
||||
}
|
||||
one_match = true;
|
||||
output_formula_checked(f, filename, linenum, prefix, suffix);
|
||||
++match_count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[FILENAME[/COL]...]",
|
||||
argp_program_doc, children, nullptr, nullptr };
|
||||
|
||||
try
|
||||
{
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
jobs.emplace_back("-", 1);
|
||||
|
||||
if (boolean_to_isop && simplification_level == 0)
|
||||
simplification_level = 1;
|
||||
spot::tl_simplifier_options opt(simplification_level);
|
||||
opt.boolean_to_isop = boolean_to_isop;
|
||||
spot::tl_simplifier simpl(opt);
|
||||
|
||||
ltl_processor processor(simpl);
|
||||
if (processor.run())
|
||||
return 2;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
catch (const std::invalid_argument& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
|
||||
if (output_format == count_output)
|
||||
std::cout << match_count << std::endl;
|
||||
|
||||
return one_match ? 0 : 1;
|
||||
}
|
||||
|
|
@ -1,199 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <argp.h>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_output.hh"
|
||||
#include "common_conv.hh"
|
||||
|
||||
#include <spot/tl/mutation.hh>
|
||||
|
||||
enum {
|
||||
OPT_AP2CONST = 1,
|
||||
OPT_SIMPLIFY_BOUNDS,
|
||||
OPT_REMOVE_MULTOP_OPERANDS,
|
||||
OPT_REMOVE_OPS,
|
||||
OPT_SPLIT_OPS,
|
||||
OPT_REWRITE_OPS,
|
||||
OPT_REMOVE_ONE_AP,
|
||||
OPT_SORT,
|
||||
};
|
||||
|
||||
static unsigned mutation_nb = 1;
|
||||
static unsigned max_output = -1U;
|
||||
|
||||
static unsigned opt_all = spot::Mut_All;
|
||||
static unsigned mut_opts = 0;
|
||||
static bool opt_sort = false;
|
||||
|
||||
static const char * argp_program_doc =
|
||||
"List formulas that are similar to but simpler than a given formula.";
|
||||
|
||||
static const argp_option options[] = {
|
||||
{ nullptr, 0, nullptr, 0,
|
||||
"Mutation rules (all enabled unless those options are used):", 15},
|
||||
{ "ap-to-const", OPT_AP2CONST, nullptr, 0,
|
||||
"atomic propositions are replaced with true/false", 15 },
|
||||
{ "remove-one-ap", OPT_REMOVE_ONE_AP, nullptr, 0,
|
||||
"all occurrences of an atomic proposition are replaced with another " \
|
||||
"atomic proposition used in the formula", 15 },
|
||||
{ "remove-multop-operands", OPT_REMOVE_MULTOP_OPERANDS, nullptr, 0,
|
||||
"remove one operand from multops", 15 },
|
||||
{ "remove-ops", OPT_REMOVE_OPS, nullptr, 0,
|
||||
"replace unary/binary operators with one of their operands", 15 },
|
||||
{ "split-ops", OPT_SPLIT_OPS, nullptr, 0,
|
||||
"when an operator can be expressed as a conjunction/disjunction using "
|
||||
"simpler operators, each term of the conjunction/disjunction is a "
|
||||
"mutation. e.g. a <-> b can be written as ((a & b) | (!a & !b)) or as "
|
||||
"((a -> b) & (b -> a)) so those four terms can be a mutation of a <-> b",
|
||||
0 },
|
||||
{ "rewrite-ops", OPT_REWRITE_OPS, nullptr, 0,
|
||||
"rewrite operators that have a semantically simpler form: a U b becomes "
|
||||
"a W b, etc.", 0 },
|
||||
{ "simplify-bounds", OPT_SIMPLIFY_BOUNDS, nullptr, 0,
|
||||
"on a bounded unary operator, decrement one of the bounds, or set min to "
|
||||
"0 or max to unbounded", 15 },
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", 20 },
|
||||
{ "max-count", 'n', "NUM", 0, "maximum number of mutations to output", 20 },
|
||||
{ "mutations", 'm', "NUM", 0, "number of mutations to apply to the "
|
||||
"formulae (default: 1)", 0 },
|
||||
{ "sort", OPT_SORT, nullptr, 0, "sort the result by formula size", 0 },
|
||||
{ nullptr, 0, nullptr, 0, "The FORMAT string passed to --format may use "
|
||||
"the following interpreted sequences:", 21 },
|
||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula (in the selected syntax)", 0 },
|
||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the name of the input file", 0 },
|
||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the original line number in the input file", 0 },
|
||||
{ "%<", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the part of the line before the formula if it "
|
||||
"comes from a column extracted from a CSV file", 0 },
|
||||
{ "%>", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the part of the line after the formula if it "
|
||||
"comes from a column extracted from a CSV file", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"a single %", 0 },
|
||||
{nullptr, 0, nullptr, 0, "Miscellaneous options:", -1},
|
||||
{nullptr, 0, nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
static const argp_child children[] = {
|
||||
{ &finput_argp, 0, nullptr, 10 },
|
||||
{ &output_argp, 0, nullptr, 20 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
class mutate_processor: public job_processor
|
||||
{
|
||||
public:
|
||||
int
|
||||
process_formula(spot::formula f, const char* filename = nullptr,
|
||||
int linenum = 0)
|
||||
{
|
||||
auto mutations =
|
||||
spot::mutate(f, mut_opts, max_output, mutation_nb, opt_sort);
|
||||
for (auto g: mutations)
|
||||
output_formula_checked(g, filename, linenum, prefix, suffix);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case 'm':
|
||||
mutation_nb = to_unsigned(arg);
|
||||
break;
|
||||
case 'n':
|
||||
max_output = to_int(arg);
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
jobs.emplace_back(arg, true);
|
||||
break;
|
||||
case OPT_AP2CONST:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Ap2Const;
|
||||
break;
|
||||
case OPT_REMOVE_ONE_AP:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Remove_One_Ap;
|
||||
break;
|
||||
case OPT_REMOVE_MULTOP_OPERANDS:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Remove_Multop_Operands;
|
||||
break;
|
||||
case OPT_REMOVE_OPS:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Remove_Ops;
|
||||
break;
|
||||
case OPT_SPLIT_OPS:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Split_Ops;
|
||||
break;
|
||||
case OPT_REWRITE_OPS:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Rewrite_Ops;
|
||||
break;
|
||||
case OPT_SIMPLIFY_BOUNDS:
|
||||
opt_all = 0;
|
||||
mut_opts |= spot::Mut_Simplify_Bounds;
|
||||
break;
|
||||
case OPT_SORT:
|
||||
opt_sort = true;
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "[FILENAME[/COL]...]", argp_program_doc,
|
||||
children, nullptr, nullptr };
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
mut_opts |= opt_all;
|
||||
|
||||
if (jobs.empty())
|
||||
jobs.push_back(job("-", true));
|
||||
|
||||
mutate_processor processor;
|
||||
if (processor.run())
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
## Développement de l'Epita (LRDE).
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
common_dep = $(top_srcdir)/configure.ac
|
||||
x_to_1 = $(top_builddir)/tools/x-to-1
|
||||
convman = ARGP_HELP_FMT=header-col=0 $(SHELL) "$(x_to_1)" \
|
||||
"$(PERL)" "$(top_srcdir)/tools/help2man -N -L 'en_US.UTF-8'"
|
||||
convman7 = ARGP_HELP_FMT=header-col=0 $(SHELL) "$(x_to_1)" \
|
||||
"$(PERL)" "$(top_srcdir)/tools/help2man -s7 -N -L 'en_US.UTF-8'"
|
||||
|
||||
dist_man1_MANS = \
|
||||
autfilt.1 \
|
||||
dstar2tgba.1 \
|
||||
genltl.1 \
|
||||
ltl2tgba.1 \
|
||||
ltl2tgta.1 \
|
||||
ltlcross.1 \
|
||||
ltldo.1 \
|
||||
ltlfilt.1 \
|
||||
ltlgrind.1 \
|
||||
randaut.1 \
|
||||
randltl.1
|
||||
dist_man7_MANS = \
|
||||
spot-x.7
|
||||
|
||||
MAINTAINERCLEANFILES = $(dist_man1_MANS) $(dist_man7_MANS)
|
||||
EXTRA_DIST = $(dist_man1_MANS:.1=.x) $(dist_man7_MANS:.7=.x)
|
||||
|
||||
autfilt.1: $(common_dep) $(srcdir)/autfilt.x $(srcdir)/../autfilt.cc
|
||||
$(convman) ../autfilt$(EXEEXT) $(srcdir)/autfilt.x $@
|
||||
|
||||
dstar2tgba.1: $(common_dep) $(srcdir)/dstar2tgba.x $(srcdir)/../dstar2tgba.cc
|
||||
$(convman) ../dstar2tgba$(EXEEXT) $(srcdir)/dstar2tgba.x $@
|
||||
|
||||
ltl2tgba.1: $(common_dep) $(srcdir)/ltl2tgba.x $(srcdir)/../ltl2tgba.cc
|
||||
$(convman) ../ltl2tgba$(EXEEXT) $(srcdir)/ltl2tgba.x $@
|
||||
|
||||
ltl2tgta.1: $(common_dep) $(srcdir)/ltl2tgta.x $(srcdir)/../ltl2tgta.cc
|
||||
$(convman) ../ltl2tgta$(EXEEXT) $(srcdir)/ltl2tgta.x $@
|
||||
|
||||
ltlcross.1: $(common_dep) $(srcdir)/ltlcross.x $(srcdir)/../ltlcross.cc
|
||||
$(convman) ../ltlcross$(EXEEXT) $(srcdir)/ltlcross.x $@
|
||||
|
||||
ltldo.1: $(common_dep) $(srcdir)/ltlcross.x $(srcdir)/../ltldo.cc
|
||||
$(convman) ../ltldo$(EXEEXT) $(srcdir)/ltldo.x $@
|
||||
|
||||
ltlfilt.1: $(common_dep) $(srcdir)/ltlfilt.x $(srcdir)/../ltlfilt.cc
|
||||
$(convman) ../ltlfilt$(EXEEXT) $(srcdir)/ltlfilt.x $@
|
||||
|
||||
genltl.1: $(common_dep) $(srcdir)/genltl.x $(srcdir)/../genltl.cc
|
||||
$(convman) ../genltl$(EXEEXT) $(srcdir)/genltl.x $@
|
||||
|
||||
randltl.1: $(common_dep) $(srcdir)/randltl.x $(srcdir)/../randltl.cc
|
||||
$(convman) ../randltl$(EXEEXT) $(srcdir)/randltl.x $@
|
||||
|
||||
randaut.1: $(common_dep) $(srcdir)/randaut.x $(srcdir)/../randaut.cc
|
||||
$(convman) ../randaut$(EXEEXT) $(srcdir)/randaut.x $@
|
||||
|
||||
spot-x.7: $(common_dep) $(srcdir)/spot-x.x $(srcdir)/../spot-x.cc
|
||||
$(convman7) ../spot-x$(EXEEXT) $(srcdir)/spot-x.x $@
|
||||
|
||||
ltlgrind.1: $(common_dep) $(srcdir)/ltlgrind.x $(srcdir)/../ltlgrind.cc
|
||||
$(convman) ../ltlgrind$(EXEEXT) $(srcdir)/ltlgrind.x $@
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
.\" -*- coding: utf-8 -*-
|
||||
[NAME]
|
||||
autfilt \- filter, convert, and transform omega-automata
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[BIBLIOGRAPHY]
|
||||
The following papers are related to some of the transformations implemented
|
||||
in autfilt.
|
||||
|
||||
.TP
|
||||
\(bu
|
||||
Etienne Renault, Alexandre Duret-Lutz, Fabrice Kordon, and Denis Poitrenaud:
|
||||
Strength-based decomposition of the property Büchi automaton for faster
|
||||
model checking. Proceedings of TACAS'13. LNCS 7795.
|
||||
|
||||
The \fB\-\-strength\-decompose\fR option implements the definitions
|
||||
given in the above paper.
|
||||
.TP
|
||||
\(bu
|
||||
František Blahoudek, Alexandre Duret-Lutz, Vojtčech Rujbr, and Jan Strejček:
|
||||
On refinement of Büchi automata for explicit model checking.
|
||||
Proceedings of SPIN'15. LNCS 9232.
|
||||
|
||||
That paper gives the motivation for options \fB\-\-exclusive\-ap\fR
|
||||
and \fB\-\-simplify\-exclusive\-ap\fR.
|
||||
.TP
|
||||
\(bu
|
||||
Thibaud Michaud and Alexandre Duret-Lutz:
|
||||
Practical stutter-invariance checks for ω-regular languages.
|
||||
Proceedings of SPIN'15. LNCS 9232.
|
||||
|
||||
Describes the algorithms used by the \fB\-\-destut\fR and
|
||||
\fB\-\-instut\fR options. These options correpond respectively to
|
||||
cl() and sl() in the paper.
|
||||
.TP
|
||||
\(bu
|
||||
Souheib Baarir and Alexandre Duret-Lutz: SAT-based minimization of
|
||||
deterministic ω-automata. Proceedings of LPAR'15 (a.k.a LPAR-20).
|
||||
LNCS 9450.
|
||||
|
||||
Describes the \fB\-\-sat\-minimize\fR option.
|
||||
[SEE ALSO]
|
||||
.BR spot-x (7)
|
||||
.BR dstar2tgba (1)
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
[NAME]
|
||||
dstar2tgba \- convert automata into Büchi automata
|
||||
[HISTORY]
|
||||
.B dstar2tgba
|
||||
was introduced in Spot 1.2 as a command that reads automata
|
||||
in
|
||||
.BR ltl2dstar 's
|
||||
format, and converts them into TGBA. At this time it was
|
||||
the only command-line tool being able to read automata.
|
||||
.PP
|
||||
In Spot 1.99.1 the
|
||||
.B autfilt
|
||||
command was introduced, but could only read automata
|
||||
in the HOA format, or in
|
||||
.BR lbtt 's
|
||||
format, or as never claims. So
|
||||
.B dstar2tgba
|
||||
was still the only way to process automata
|
||||
in
|
||||
.BR ltl2dstar 's
|
||||
format.
|
||||
.PP
|
||||
In Spot 1.99.4 the parser for
|
||||
.BR ltl2dstar 's
|
||||
format was finally merged with the parser
|
||||
used by
|
||||
.B autfilt
|
||||
for reading the other format. This implies not only
|
||||
that
|
||||
.B autfilt
|
||||
can now read
|
||||
.BR ltl2dstar's
|
||||
format, but also that
|
||||
.B dstar2tgba
|
||||
can read the other formats as well.
|
||||
|
||||
Nowadays, the command
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% dstar2tgba some files
|
||||
.fi
|
||||
.PP
|
||||
can be used as a shorthand for
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% autfilt \-\-tgba \-\-high \-\-small some files
|
||||
.fi
|
||||
.PP
|
||||
The name
|
||||
.B dstar2tgba
|
||||
is kept for backward compatibility and because it is used
|
||||
in at least one published paper, but naming this tool
|
||||
.B aut2tgba
|
||||
would make more sense.
|
||||
|
||||
[BIBLIOGRAPHY]
|
||||
.TP
|
||||
1.
|
||||
<http://www.ltl2dstar.de/docs/ltl2dstar.html>
|
||||
|
||||
Documents the output format of ltl2dstar.
|
||||
|
||||
.TP
|
||||
2.
|
||||
Chistof Löding: Mehods for the Transformation of ω-Automata:
|
||||
Complexity and Connection to Second Order Logic. Diploma Thesis.
|
||||
University of Kiel. 1998.
|
||||
|
||||
Describes various tranformations from non-deterministic Rabin and
|
||||
Streett automata to Büchi automata. Slightly optimized variants of
|
||||
these transformations are used by dstar2tgba for the general cases.
|
||||
|
||||
.TP
|
||||
3.
|
||||
Sriram C. Krishnan, Anuj Puri, and Robert K. Brayton: Deterministic
|
||||
ω-automata vis-a-vis Deterministic Büchi Automata. ISAAC'94.
|
||||
|
||||
Explains how to preserve the determinism of Rabin and Streett automata
|
||||
when the property can be repreted by a Deterministic automaton.
|
||||
dstar2tgba implements this for the Rabin case only. In other words,
|
||||
translating a deterministic Rabin automaton with dstar2tgba will
|
||||
produce a deterministic TGBA or BA if such a automaton exists.
|
||||
|
||||
.TP
|
||||
4.
|
||||
Souheib Baarir and Alexandre Duret-Lutz: Mechanizing the minimization
|
||||
of deterministic generalized Büchi automata. Proceedings of FORTE'14.
|
||||
LNCS 8461.
|
||||
|
||||
Explains the SAT-based minimization techniques that can be used (on
|
||||
request only) by dstar2tgba to minimize deterministic Büchi automata.
|
||||
|
||||
.TP
|
||||
5.
|
||||
Souheib Baarir and Alexandre Duret-Lutz: SAT-based minimization of
|
||||
deterministic ω-automata. Proceedings of LPAR'15 (a.k.a LPAR-20).
|
||||
LNCS 9450.
|
||||
|
||||
Extends the previous paper by allowing arbitrary acceptance
|
||||
conditions.
|
||||
[SEE ALSO]
|
||||
.BR spot-x (7),
|
||||
.BR autfilt (1)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
[NAME]
|
||||
genltl \- generate LTL formulas from scalable patterns
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[BIBLIOGRAPHY]
|
||||
If you would like to give a reference to this tool in an article,
|
||||
we suggest you cite the following paper:
|
||||
.TP
|
||||
\(bu
|
||||
Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0.
|
||||
Proceedings of ATVA'13. LNCS 8172.
|
||||
.PP
|
||||
Prefixes used in pattern names refer to the following papers:
|
||||
.TP
|
||||
gh
|
||||
J. Geldenhuys and H. Hansen: Larger automata and less
|
||||
work for LTL model checking. Proceedings of Spin'06. LNCS 3925.
|
||||
.TP
|
||||
ccj
|
||||
J. Cichoń, A. Czubak, and A. Jasiński (DepCoS'09): Minimal Büchi
|
||||
Automata for Certain Classes of LTL Formulas. Proceedings of DepCoS'09.
|
||||
.TP
|
||||
go
|
||||
P. Gastin and D. Oddoux: Fast LTL to Büchi Automata Translation.
|
||||
Proceedings of CAV'01. LNCS 2102.
|
||||
.TP
|
||||
rv
|
||||
K. Rozier and M. Vardi: LTL Satisfiability Checking.
|
||||
Proceedings of Spin'07. LNCS 4595.
|
||||
[SEE ALSO]
|
||||
.BR randltl (1)
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
.\" -*- coding: utf-8 -*-
|
||||
[NAME]
|
||||
ltl2tgba \- translate LTL/PSL formulas into Büchi automata
|
||||
[NOTE ON TGBA]
|
||||
TGBA stands for Transition-based Generalized Büchi Automaton. The
|
||||
name was coined by Dimitra Giannakopoulou and Flavio Lerda in their
|
||||
FORTE'02 paper (From States to Transitions: Improving Translation of
|
||||
LTL Formulae to Büchi Automata), although similar automata have been
|
||||
used under different names long before that.
|
||||
.PP
|
||||
As its name implies a TGBA uses a generalized Büchi acceptance
|
||||
condition, meanings that a run of the automaton is accepted iff it
|
||||
visits ininitely often multiple acceptance sets, and it also uses
|
||||
transition-based acceptance, i.e., those acceptance sets are sets of
|
||||
transitions. TGBA are often more consise than traditional Büchi
|
||||
automata. For instance the LTL formula \f(CWGFa & GFb\fR can be
|
||||
translated into a single-state TGBA while a traditional Büchi
|
||||
automaton would need 3 states. Compare
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% ltl2tgba 'GFa & GFb'
|
||||
.fi
|
||||
.PP
|
||||
with
|
||||
.PP
|
||||
.in +4n
|
||||
.ft C
|
||||
.nf
|
||||
% ltl2tgba --ba 'GFa & GFb'
|
||||
.fi
|
||||
.PP
|
||||
In the dot output produced by the above commands, the membership of
|
||||
the transitions to the various acceptance sets is denoted using names
|
||||
in braces. The actuall names do not really matter as they may be
|
||||
produced by the translation algorithm or altered by any latter
|
||||
postprocessing.
|
||||
.PP
|
||||
When the \fB\-\-ba\fR option is used to request a Büchi automaton, Spot
|
||||
builds a TGBA with a single acceptance set, and in which for any state
|
||||
either all outgoing transitions are accepting (this is equivalent to
|
||||
the state being accepting) or none of them are. Double circles are
|
||||
used to highlight accepting states in the output, but the braces
|
||||
denoting the accepting transitions are still shown because the
|
||||
underling structure really is a TGBA.
|
||||
|
||||
[NOTE ON LBTT'S FORMAT]
|
||||
.UR http://www.tcs.hut.fi/Software/lbtt/doc/html/Format-for-automata.html
|
||||
LBTT's format
|
||||
.UE
|
||||
has support for both transition-based and state based generalized acceptance.
|
||||
.PP
|
||||
Because Spot uses transition-based generalized Büchi automata
|
||||
internally, it will normally use the transition-based flavor of that
|
||||
format, indicated with a 't' flag after the number of acceptance sets.
|
||||
For instance:
|
||||
.PP
|
||||
.in +4n
|
||||
.ft C
|
||||
.nf
|
||||
% ltl2tgba --lbtt 'GFp0 & GFp1 & FGp2'
|
||||
2 2t // 2 states, 2 transition-based acceptance sets
|
||||
0 1 // state 0: initial
|
||||
0 -1 t // trans. to state 0, no acc., label: true
|
||||
1 -1 | & p0 p2 & p1 p2 // trans. to state 1, no acc., label: (p0&p2)|(p1&p2)
|
||||
-1 // end of state 0
|
||||
1 0 // state 1: not initial
|
||||
1 0 1 -1 & & p0 p1 p2 // trans. to state 1, acc. 0 and 1, label: p0&p1&p2
|
||||
1 0 -1 & & p1 p2 ! p0 // trans. to state 1, acc. 0, label: !p0&p1&p2
|
||||
1 1 -1 & & p0 p2 ! p1 // trans. to state 1, acc. 1, label: p0&!p1&p2
|
||||
1 -1 & & p2 ! p0 ! p1 // trans. to state 1, no acc., label: !p0&!p1&p2
|
||||
-1 // end if state 1
|
||||
.fi
|
||||
.PP
|
||||
Here, the two acceptance sets are represented by the numbers 0 and 1,
|
||||
and they each contain two transitions (the first transition of state 1
|
||||
belongs to both sets).
|
||||
.PP
|
||||
When both \fB\-\-ba\fR and \fB\-\-lbtt\fR options are used,
|
||||
the state-based flavor of
|
||||
the format is used instead. Note that the LBTT format supports
|
||||
generalized acceptance conditions on states, but Spot only use this
|
||||
format for Büchi automata, where there is always only one acceptance
|
||||
set. Unlike in the LBTT documentation, we do not use the
|
||||
optional '\fBs\fR' flag to indicate the state-based acceptance, this way our
|
||||
output is also compatible with that of
|
||||
.UR http://www.tcs.hut.fi/Software/maria/tools/lbt/
|
||||
LBT
|
||||
.UE .
|
||||
.PP
|
||||
.in +4n
|
||||
.ft C
|
||||
.nf
|
||||
% ltl2tgba --ba --lbtt FGp0
|
||||
2 1 // 2 states, 1 (state-based) accepance set
|
||||
0 1 -1 // state 0: initial, non-accepting
|
||||
0 t // trans. to state 0, label: true
|
||||
1 p0 // trans. to state 1, label: p0
|
||||
-1 // end of state 0
|
||||
1 0 0 -1 // state 1: not initial, in acceptance set 0
|
||||
1 p0 // trans. to state 0, label: p0
|
||||
-1 // end if state 1
|
||||
.fi
|
||||
.PP
|
||||
You can force ltl2tgba to use the transition-based flavor of the
|
||||
format even for Büchi automaton using \fB\-\-lbtt=t\fR.
|
||||
.PP
|
||||
.in +4n
|
||||
.ft C
|
||||
.nf
|
||||
% ltl2tgba --ba --lbtt=t FGp0
|
||||
2 1t // 2 states, 1 transition-based accepance set.
|
||||
0 1 // state 0: initial
|
||||
0 -1 t // trans. to state 0, no acc., label: true
|
||||
1 -1 p0 // trans. to state 1, no acc., label: p0
|
||||
-1 // end of state 0
|
||||
1 0 // state 1: not initial
|
||||
1 0 -1 p0 // trans. to state 1, acc. 0, label: p0
|
||||
-1 // end if state 1
|
||||
.fi
|
||||
.PP
|
||||
When representing a Büchi automaton using transition-based acceptance,
|
||||
all transitions leaving accepting states are put into the acceptance set.
|
||||
.PP
|
||||
A final note concerns the name of the atomic propositions. The
|
||||
original LBTT and LBT formats require these atomic propositions to
|
||||
have names such as '\fBp0\fR', '\fBp32\fR', ... We extend the format to accept
|
||||
atomic proposition with arbitrary names that do not conflict with
|
||||
LBT's operators (e.g. '\fBi\fR' is the symbol of the implication operator so
|
||||
it may not be used as an atomic proposition), or as double-quoted
|
||||
strings. Spot will always output atomic-proposition that do not match
|
||||
\fBp[0-9]+\fR as double-quoted strings.
|
||||
.PP
|
||||
.in +4n
|
||||
.ft C
|
||||
.nf
|
||||
% ltl2tgba --lbtt 'GFa & GFb'
|
||||
1 2t
|
||||
0 1
|
||||
0 0 1 -1 & "a" "b"
|
||||
0 0 -1 & "b" ! "a"
|
||||
0 1 -1 & "a" ! "b"
|
||||
0 -1 & ! "b" ! "a"
|
||||
-1
|
||||
.fi
|
||||
|
||||
[NOTE ON GENERATING MONITORS]
|
||||
The monitors generated with option \fB\-M\fR are finite state automata
|
||||
used to reject finite words that cannot be extended to infinite words
|
||||
compatible with the supplied formula. The idea is that the monitor
|
||||
should progress alongside the system, and can only make decisions
|
||||
based on the finite prefix read so far.
|
||||
.PP
|
||||
Monitors can be seen as Büchi automata in which all recognized runs are
|
||||
accepting. As such, the only infinite words they can reject are those
|
||||
are not recognized, i.e., infinite words that start with a bad prefix.
|
||||
.PP
|
||||
Because of this limited expressiveness, a monitor for some given LTL
|
||||
or PSL formula may accept a larger language than the one specified by
|
||||
the formula. For instance a monitor for the LTL formula \f(CWa U b\fR
|
||||
will reject (for instance) any word starting with \f(CW!a&!b\fR as
|
||||
there is no way such a word can validate the formula, but it will not
|
||||
reject a finite prefix repeating only \f(CWa&!b\fR as such a prefix
|
||||
could be extented in a way that is comptible with \f(CWa U b\fR.
|
||||
.PP
|
||||
For more information about monitors, we refer the readers to the
|
||||
following two papers (the first paper describes the construction of
|
||||
the second paper in a more concise way):
|
||||
.TP
|
||||
\(bu
|
||||
Deian Tabakov and Moshe Y. Vardi: Optimized Temporal Monitors for SystemC.
|
||||
Proceedings of RV'10. LNCS 6418.
|
||||
.TP
|
||||
\(bu
|
||||
Marcelo d’Amorim and Grigoire Roşu: Efficient monitoring of
|
||||
ω-languages. Proceedings of CAV'05. LNCS 3576.
|
||||
|
||||
[BIBLIOGRAPHY]
|
||||
If you would like to give a reference to this tool in an article,
|
||||
we suggest you cite one of the following papers:
|
||||
.TP
|
||||
\(bu
|
||||
Alexandre Duret-Lutz: LTL translation improvements in Spot 1.0.
|
||||
Int. J. on Critical Computer-Based Systems, 5(1/2):31--54, March 2014.
|
||||
.TP
|
||||
\(bu
|
||||
Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0.
|
||||
Proceedings of ATVA'13. LNCS 8172.
|
||||
.TP
|
||||
\(bu
|
||||
Tomáš Babiak, Thomas Badie, Alexandre Duret-Lutz, Mojmír Křetínský,
|
||||
and Jan Strejček: Compositional approach to suspension and other
|
||||
improvements to LTL translation. Proceedings of SPIN'13. LNCS 7976.
|
||||
.TP
|
||||
\(bu
|
||||
Souheib Baarir and Alexandre Duret-Lutz: Mechanizing the minimization
|
||||
of deterministic generalized Büchi automata. Proceedings of FORTE'14.
|
||||
LNCS 8461.
|
||||
|
||||
[SEE ALSO]
|
||||
.BR spot-x (7)
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
[NAME]
|
||||
ltl2tgta \- translate LTL/PSL formulas into Testing Automata
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[BIBLIOGRAPHY]
|
||||
If you would like to give a reference to this tool in an article,
|
||||
we suggest you cite the following paper:
|
||||
.TP
|
||||
\(bu
|
||||
Ala Eddine Ben Salem, Alexandre Duret-Lutz, and Fabrice Kordon: Model
|
||||
checking using generalized testing automata. Transactions on Petri
|
||||
Nets and Other Models of Concurrency (ToPNoC VI), 7400:94-112, 2012.
|
||||
[SEE ALSO]
|
||||
.BR spot-x (7)
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
.\" -*- coding: utf-8 -*-
|
||||
[NAME]
|
||||
ltlcross \- cross-compare LTL/PSL translators to Büchi automata
|
||||
[EXAMPLES]
|
||||
The following commands compare never claims produced by
|
||||
.BR ltl2tgba (1),
|
||||
.BR spin (1),
|
||||
and
|
||||
.B lbt
|
||||
for 100 random formulas, using a timeout of 2 minutes. Because
|
||||
.B ltlcross
|
||||
knows those tools, there is no need to specify their input and
|
||||
output. A trace of the execution of the two tools, including any
|
||||
potential issue detected, is reported on standard error, while
|
||||
statistics are written to \f(CWresults.json\fR.
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% randltl \-n100 \-\-tree\-size=20..30 a b c | \e
|
||||
ltlcross \-T120 ltl2tgba spin lbt \-\-json=results.json
|
||||
.fi
|
||||
.PP
|
||||
The next command compares
|
||||
.BR lbt ,
|
||||
.BR ltl3ba ,
|
||||
and
|
||||
.BR ltl2tgba (1)
|
||||
on a set of formulas saved in file \f(CWinput.ltl\fR.
|
||||
Statistics are again writen
|
||||
as CSV into \f(CWresults.csv\fR. This examples specify the
|
||||
input and output for each tool, to show how this can be done.
|
||||
Note the use of \f(CW%L\fR to indicate that the formula passed t
|
||||
for the formula in
|
||||
.BR spin (1)'s
|
||||
format, and \f(CW%f\fR for the
|
||||
formula in Spot's format. Each of these tool produces an
|
||||
automaton in a different format (respectively, LBTT's format,
|
||||
Spin's never claims, and HOA format), but Spot's parser can
|
||||
distinguish and understand these three formats.
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% ltlcross \-F input.ltl \-\-csv=results.csv \e
|
||||
'lbt <%L >%O' \e
|
||||
'ltl3ba \-f %s >%O' \e
|
||||
'ltl2tgba \-H %f >%O'
|
||||
.fi
|
||||
.PP
|
||||
Rabin or Streett automata output by
|
||||
.B ltl2dstar
|
||||
in its historical format can be read from a
|
||||
file specified with \f(CW%D\fR instead of \f(CW%O\fR. For instance:
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% ltlcross \-F input.ltl \e
|
||||
'ltl2dstar \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %D' \e
|
||||
'ltl2dstar \-\-automata=streett \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %D' \e
|
||||
.fi
|
||||
.PP
|
||||
However, we now recommand to use the HOA output of
|
||||
.BR ltl2dstar ,
|
||||
as supported since version 0.5.2:
|
||||
.PP
|
||||
.in +4n
|
||||
.nf
|
||||
.ft C
|
||||
% ltlcross \-F input.ltl \e
|
||||
'ltl2dstar \-\-output\-format=hoa \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %O' \e
|
||||
'ltl2dstar \-\-output\-format=hoa \-\-automata=streett \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %O' \e
|
||||
.fi
|
||||
.PP
|
||||
In more recent versions of ltl2dstar, \fB\-\-output\-format=hoa\fR can
|
||||
be abbreviated \fB-H\fR.
|
||||
|
||||
[ENVIRONMENT VARIABLES]
|
||||
.TP
|
||||
\fBSPOT_TMPDIR\fR, \fBTMPDIR\fR
|
||||
These variables control in which directory temporary files (e.g.,
|
||||
those who contain the input and output when interfacing with
|
||||
translators) are created. \fBTMPDIR\fR is only read if
|
||||
\fBSPOT_TMPDIR\fR does not exist. If none of these environment
|
||||
variables exist, or if their value is empty, files are created in the
|
||||
current directory.
|
||||
.TP
|
||||
\fBSPOT_TMPKEEP\fR
|
||||
When this variable is defined, temporary files are not removed.
|
||||
This is mostly useful for debugging.
|
||||
|
||||
[OUTPUT DATA]
|
||||
The following columns are output in the CSV or JSON files.
|
||||
.TP
|
||||
\fBformula\fR
|
||||
The formula translated.
|
||||
.TP
|
||||
\fBtool\fR
|
||||
The tool used to translate this formula. This is either the value of the
|
||||
full \fICOMMANDFMT\fR string specified on the command-line, or,
|
||||
if \fICOMMANDFMT\fR has the form \f(CW{\fISHORTNAME\fR\f(CW}\fR\fICMD\fR,
|
||||
the value of \fISHORTNAME\fR.
|
||||
.TP
|
||||
\fBexit_status\fR, \fBexit_code\fR
|
||||
Information about how the execution of the translator went. If the
|
||||
option \fB\-\-omit\-missing\fR is given, these two columns are omitted
|
||||
and only the lines corresponding to successful translation are output.
|
||||
Otherwise, \fBexit_status\fR is a string that can take the following
|
||||
values:
|
||||
.RS
|
||||
.TP
|
||||
\f(CW"ok"\fR
|
||||
The translator ran succesfully (this does not imply that the produced
|
||||
automaton is correct) and ltlcross could parse the resulting
|
||||
automaton. In this case \fBexit_code\fR is always 0.
|
||||
.TP
|
||||
\f(CW"timeout"\fR
|
||||
The translator ran for more than the number of seconds
|
||||
specified with the \fB\-\-timeout\fR option. In this
|
||||
case \fBexit_code\fR is always -1.
|
||||
.TP
|
||||
\f(CW"exit code"\fR
|
||||
The translator terminated with a non-zero exit code.
|
||||
\fBexit_code\fR contains that value.
|
||||
.TP
|
||||
\f(CW"signal"\fR
|
||||
The translator terminated with a signal.
|
||||
\fBexit_code\fR contains that signal's number.
|
||||
.TP
|
||||
\f(CW"parse error"\fR
|
||||
The translator terminated normally, but ltlcross could not
|
||||
parse its output. In this case \fBexit_code\fR is always -1.
|
||||
.TP
|
||||
\f(CW"no output"\fR
|
||||
The translator terminated normally, but without creating the specified
|
||||
output file. In this case \fBexit_code\fR is always -1.
|
||||
.RE
|
||||
.TP
|
||||
\fBtime\fR
|
||||
A floating point number giving the run time of the translator in seconds.
|
||||
This is reported for all executions, even failling ones.
|
||||
.PP
|
||||
Unless the \fB\-\-omit\-missing\fR option is used, data for all the
|
||||
following columns might be missing.
|
||||
.TP
|
||||
\fBstates\fR, \fBedges\fR, \fBtransitions\fR, \fBacc\fR
|
||||
The number of states, edges, transitions, and acceptance sets in the
|
||||
translated automaton. Column \fBedges\fR counts the number of edges
|
||||
(labeled by Boolean formulas) in the automaton seen as a graph, while
|
||||
\fBtransitions\fR counts the number of assignment-labeled transitions
|
||||
that might have been merged into a formula-labeled edge. For instance
|
||||
an edge labeled by \f(CWtrue\fR will be counted as 2^3=8 transitions if
|
||||
the automaton mention 3 atomic propositions.
|
||||
.PP
|
||||
If the translator produced a Streett or Rabin automaton, these columns
|
||||
contains the size of a TGBA (or BA) produced by ltlcross from that
|
||||
Streett or Rabin automaton. Check \fBin_states\fR, \fBin_edges\fR,
|
||||
\fBin_transitions\fR, and \fBin_acc\fR for statistics about the actual
|
||||
input automaton.
|
||||
.TP
|
||||
\fBscc\fR, \fBnonacc_scc\fR, \fBterminal_scc\fR, \fBweak_scc\fR, \fBstrong_scc\fR
|
||||
The number of strongly connected components in the automaton. The
|
||||
\fBscc\fR column gives the total number, while the other columns only
|
||||
count the SCCs that are non-accepting (a.k.a. transiant), terminal
|
||||
(recognizes and accepts all words), weak (do not recognize all words,
|
||||
but accepts all recognized words), or strong (accept some words, but
|
||||
reject some recognized words).
|
||||
.TP
|
||||
\fBnondet_states\fR, \fBnondet_aut\fR
|
||||
The number of nondeterministic states, and a Boolean indicating whether the
|
||||
automaton is nondeterministic.
|
||||
.TP
|
||||
\fBterminal_aut\fR, \fBweak_aut\fR, \fBstrong_aut\fR
|
||||
Three Boolean used to indicate whether the automaton is terminal (no
|
||||
weak nor strong SCCs), weak (some weak SCCs but no strong SCCs), or strong
|
||||
(some strong SCCs).
|
||||
.TP
|
||||
\fBproduct_states\fR, \fBproduct_transitions\fR, \fBproduct_scc\fR
|
||||
Size of the product between the translated automaton and a randomly
|
||||
generated state-space. For a given formula, the same state-space is
|
||||
of course used the result of each translator. When the
|
||||
\fB\-\-products\fR=\fIN\fR option is used, these values are averaged
|
||||
over the \fIN\fR products performed.
|
||||
|
||||
[DEPRECATED OUTPUT SPECIFIERS]
|
||||
Until version 1.2.6, the output of translators was specifed using the
|
||||
following escape sequences.
|
||||
.PP
|
||||
.TP
|
||||
%N
|
||||
An output file containing a never claim.
|
||||
.TP
|
||||
%T
|
||||
An output file in \fBlbtt\fR's format.
|
||||
.TP
|
||||
%D
|
||||
An output file in \fBltl2dstar\fR's format.
|
||||
.PP
|
||||
Some development versions leading to 1.99.1 also featured
|
||||
.PP
|
||||
.TP
|
||||
%H
|
||||
An output file in the HOA format.
|
||||
.PP
|
||||
Different specifiers were needed because Spot implemented
|
||||
different parsers for these formats. Nowadays, these parsers
|
||||
have been merged into a single parser that is able to
|
||||
distinguish these four formats automatically.
|
||||
.B ltlcross
|
||||
officially supports only one output specifier:
|
||||
.TP
|
||||
%O
|
||||
An output file in either \fBlbtt\fR's format, \fBltl2dstar\fR's format,
|
||||
as a never claim, or in the HOA format
|
||||
.P
|
||||
For backward compatibility, the sequences %D, %H, %N, and %T, are
|
||||
still supported (as aliases for %O), but are deprecated.
|
||||
|
||||
[SEE ALSO]
|
||||
.BR randltl (1),
|
||||
.BR genltl (1),
|
||||
.BR ltlfilt (1),
|
||||
.BR ltl2tgba (1),
|
||||
.BR ltldo (1)
|
||||
|
||||
[BIBLIOGRAPHY]
|
||||
If you would like to give a reference to this tool in an article,
|
||||
we suggest you cite the following paper:
|
||||
.PP
|
||||
.TP
|
||||
\(bu
|
||||
Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0.
|
||||
Proceedings of ATVA'13. LNCS 8172.
|
||||
.PP
|
||||
.B ltlcross
|
||||
is a Spot-based reimplementation of a tool called LBTT. LBTT
|
||||
was developped by Heikki Tauriainen at the Helsinki University of
|
||||
Technology. The main motivation for the reimplementation was to
|
||||
support PSL, and output more statistics about the translations.
|
||||
.PP
|
||||
The sanity checks performed on the result of each translator (by
|
||||
either LBTT or ltlcross) are described in the following paper:
|
||||
.PP
|
||||
.TP
|
||||
\(bu
|
||||
H. Tauriainen and K. Heljanko: Testing LTL formula translation into
|
||||
Büchi automata. Int. J. on Software Tools for Technology Transfer.
|
||||
Volume 4, number 1, October 2002.
|
||||
.PP
|
||||
LBTT did not implement Test 2 described in this paper. ltlcross
|
||||
implements a slight variation: when an automaton produced by some
|
||||
translator is deterministic, its complement is built and used for
|
||||
additional cross-comparisons with other tools. If the translation P1
|
||||
of the positive formula and the translation N1 of the negative formula
|
||||
both yield deterministic automata (this may only happen for obligation
|
||||
properties) then the emptiness check of Comp(P1)*Comp(N1) is
|
||||
equivalent to Test 2 of Tauriainen and Heljanko. If only one
|
||||
automaton is deterministic, say P1, it can still be used to check we
|
||||
can be used to check the result of another translators, for instance
|
||||
checking the emptiness of Comp(P1)*P2.
|
||||
.PP
|
||||
Our implementation will detect and reports problems (like
|
||||
inconsistencies between two translations) but unlike LBTT it does not
|
||||
offer an interactive mode to investigate such problems.
|
||||
.PP
|
||||
Another major difference with LBTT is that ltlcross is
|
||||
not restricted to generalized Büchi acceptance. It supports
|
||||
Rabin and Streett automata via ltl2dstar's format, and automata
|
||||
with arbitrary acceptance conditions via the HOA format.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[NAME]
|
||||
ltldo \- run LTL/PSL formulas through other tools
|
||||
[SEE ALSO]
|
||||
.BR randltl (1),
|
||||
.BR genltl (1),
|
||||
.BR ltlfilt (1),
|
||||
.BR ltl2tgba (1),
|
||||
.BR ltldo (1)
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
[NAME]
|
||||
ltlfilt \- filter files or lists of LTL/PSL formulas
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[BIBLIOGRAPHY]
|
||||
If you would like to give a reference to this tool in an article,
|
||||
we suggest you cite the following paper:
|
||||
.TP
|
||||
\(bu
|
||||
Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0.
|
||||
Proceedings of ATVA'13. LNCS 8172.
|
||||
.PP
|
||||
The following papers describe algorithms used by ltlfilt:
|
||||
.TP
|
||||
\(bu
|
||||
Kousha Etessami: A note on a question of Peled and Wilke regarding
|
||||
stutter-invariant LTL. Information Processing Letters 75(6): 261-263
|
||||
(2000).
|
||||
|
||||
Describes the transformation behind the \fB\-\-remove\-x\fR option.
|
||||
.TP
|
||||
\(bu
|
||||
Thibaud Michaud and Alexandre Duret-Lutz:
|
||||
Practical stutter-invariance checks for ω-regular languages.
|
||||
Proceedings of SPIN'15. LNCS 9232.
|
||||
|
||||
Describes the algorithm used by \fB\-\-stutter\-insensitive\fR option.
|
||||
.TP
|
||||
\(bu
|
||||
Christian Dax, Jochen Eisinger, Felix Klaedtke: Mechanizing the
|
||||
Powerset Construction for Restricted Classes of
|
||||
ω-Automata. Proceedings of ATVA'07. LNCS 4762.
|
||||
|
||||
Describes the checks implemented by the \fB\-\-safety\fR,
|
||||
\fB\-\-guarantee\fR, and \fB\-\-obligation\fR options.
|
||||
.TP
|
||||
\(bu
|
||||
Ivana Černá, Radek Pelánek: Relating Hierarchy of Temporal Properties
|
||||
to Model Checking. Proceedings of MFCS'03. LNCS 2747.
|
||||
|
||||
Describes the syntactic LTL classes matched by the
|
||||
\fB\-\-syntactic\-safety\fR, \fB\-\-syntactic\-guarantee\fR,
|
||||
\fB\-\-syntactic\-obligation\fR options,
|
||||
\fB\-\-syntactic\-persistence\fR, and \fB\-\-syntactic\-recurrence\fR
|
||||
options.
|
||||
.TP
|
||||
\(bu
|
||||
Kousha Etessami, Gerard J. Holzmann: Optimizing Büchi
|
||||
Automata. Proceedings of CONCUR'00. LNCS 1877.
|
||||
|
||||
Describe the syntactic LTL classes matched by \fB\-\-eventual\fR, and
|
||||
\fB\-\-universal\fR.
|
||||
[SEE ALSO]
|
||||
.BR randltl (1),
|
||||
.BR ltldo (1)
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
[NAME]
|
||||
ltlgrind \- list mutations of a formula.
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[SEE ALSO]
|
||||
.BR ltlcross (1)
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
[NAME]
|
||||
randaut \- generate random automata
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[SEE ALSO]
|
||||
.BR randltl (1),
|
||||
.BR autfilt (1)
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
[NAME]
|
||||
randltl \- generate random LTL/PSL formulas
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[BIBLIOGRAPHY]
|
||||
If you would like to give a reference to this tool in an article,
|
||||
we suggest you cite the following paper:
|
||||
.TP
|
||||
\(bu
|
||||
Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0.
|
||||
Proceedings of ATVA'13. LNCS 8172.
|
||||
[SEE ALSO]
|
||||
.BR genltl (1),
|
||||
.BR ltlfilt (1),
|
||||
.BR randaut (1)
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
[NAME]
|
||||
spot-x \- Common fine-tuning options.
|
||||
|
||||
[SYNOPSIS]
|
||||
.B \-\-extra-options STRING
|
||||
.br
|
||||
.B \-x STRING
|
||||
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
|
||||
[ENVIRONMENT VARIABLES]
|
||||
|
||||
.TP
|
||||
\fBSPOT_DOTDEFAULT\fR
|
||||
Whenever the \f(CW--dot\fR option is used without argument (even
|
||||
implicitely), the contents of this variable is used as default
|
||||
argument. If you have some default setting in \fBSPOT_DOTDEFAULT\fR
|
||||
but want to alter them temporarily for one call, use
|
||||
\f(CW--dot=.yyy\fR: the dot character will be replaced by the contents
|
||||
of the \f(CWSPOT_DOTDEFAULT\fR environment variable.
|
||||
|
||||
.TP
|
||||
\fBSPOT_DOTEXTRA\fR
|
||||
The contents of this variable is added to any dot output, immediately
|
||||
before the first state is output. This makes it easy to override
|
||||
global attributes of the graph.
|
||||
|
||||
.TP
|
||||
\fBSPOT_SATLOG\fR
|
||||
If set to a filename, the SAT-based minimization routines will append
|
||||
statistics about each iteration to the named file. Each line lists
|
||||
the following comma-separated values: requested number of states,
|
||||
number of reachable states in the output, number of edges in the
|
||||
output, number of transitions in the output, number of variables in
|
||||
the SAT problem, number of clauses in the SAT problem, user time for
|
||||
encoding the SAT problem, system time for encoding the SAT problem,
|
||||
user time for solving the SAT problem, system time for solving the SAT
|
||||
problem.
|
||||
|
||||
.TP
|
||||
\fBSPOT_SATSOLVER\fR
|
||||
If set, this variable should indicate how to call a SAT\-solver. This
|
||||
is used by the sat\-minimize option described above. The default
|
||||
value is \f(CW"glucose -verb=0 -model %I >%O"\fR, it is correct for
|
||||
glucose version 3.0 (for older versions, remove the \fCW(-model\fR
|
||||
option). The escape sequences \f(CW%I\fR and \f(CW%O\fR respectively
|
||||
denote the names of the input and output files. These temporary files
|
||||
are created in the directory specified by \fBSPOT_TMPDIR\fR or
|
||||
\fBTMPDIR\fR (see below). The SAT-solver should follow the convention
|
||||
of the SAT Competition for its input and output format.
|
||||
|
||||
.TP
|
||||
\fBSPOT_STREETT_CONV_MIN\fR
|
||||
The number of Streett pairs above which conversion from Streett
|
||||
acceptance to generalized-Büchi acceptance should be made with a
|
||||
dedicated algorithm. By default this is 3, i.e., if a Streett
|
||||
automaton with 3 acceptance pairs or more has to be converted into
|
||||
generalized-Büchi, the dedicated algorithm is used. This algorithm is
|
||||
close to the classical conversion from Streett to Büchi, but with
|
||||
several tweaks. When this algorithm is not used, the standard
|
||||
"Fin-removal" approach is used instead: first the acceptance condition
|
||||
is converted into disjunctive normal form (DNF), then Fin acceptance
|
||||
is removed like for Rabin automata, yielding a disjuction of
|
||||
generalized Büchi acceptance, and the result is finally converted into
|
||||
conjunctive normal form (CNF) to obtain a generalized Büchi
|
||||
acceptance. Both algorithms have a worst-case size that is
|
||||
exponential in the number of Streett pairs, but in practice the
|
||||
dedicated algorithm works better for most Streett automata with 3 or
|
||||
more pairs (and many 2-pair Streett automata as well, but the
|
||||
difference here is less clear). Setting this variable to 0 will
|
||||
disable the dedicated algorithm. Setting it to 1 will enable it for
|
||||
all Streett automata, however we do not recommand setting it to less
|
||||
than 2, because the "Fin-removal" approach is better for single-pair
|
||||
Streett automata.
|
||||
|
||||
.TP
|
||||
\fBSPOT_TMPDIR\fR, \fBTMPDIR\fR
|
||||
These variables control in which directory temporary files (e.g.,
|
||||
those who contain the input and output when interfacing with
|
||||
translators) are created. \fBTMPDIR\fR is only read if
|
||||
\fBSPOT_TMPDIR\fR does not exist. If none of these environment
|
||||
variables exist, or if their value is empty, files are created in the
|
||||
current directory.
|
||||
|
||||
.TP
|
||||
\fBSPOT_TMPKEEP\fR
|
||||
When this variable is defined, temporary files are not removed.
|
||||
This is mostly useful for debugging.
|
||||
|
||||
[BIBLIOGRAPHY]
|
||||
.TP
|
||||
1.
|
||||
Christian Dax, Jochen Eisinger, Felix Klaedtke: Mechanizing the
|
||||
Powerset Construction for Restricted Classes of
|
||||
ω-Automata. Proceedings of ATVA'07. LNCS 4762.
|
||||
|
||||
Describes the WDBA-minimization algorithm implemented in Spot. The
|
||||
algorithm used for the tba-det options is also a generalization (to
|
||||
TBA instead of BA) of what they describe in sections 3.2 and 3.3.
|
||||
|
||||
.TP
|
||||
2.
|
||||
Tomáš Babiak, Thomas Badie, Alexandre Duret-Lutz, Mojmír Křetínský,
|
||||
Jan Strejček: Compositional Approach to Suspension and Other
|
||||
Improvements to LTL Translation. Proceedings of SPIN'13. LNCS 7976.
|
||||
|
||||
Describes the compositional suspension, the simulation-based
|
||||
reductions, and the SCC-based simplifications.
|
||||
|
||||
.TP
|
||||
3.
|
||||
Rüdiger Ehlers: Minimising Deterministic Büchi Automata Precisely using
|
||||
SAT Solving. Proceedings of SAT'10. LNCS 6175.
|
||||
|
||||
Our SAT-based minimization procedures are generalizations of this
|
||||
paper to deal with TBA or TGBA.
|
||||
|
||||
[SEE ALSO]
|
||||
.BR ltl2tgba (1)
|
||||
.BR ltl2tgta (1)
|
||||
.BR dstar2tgba (1)
|
||||
.BR autfilt (1)
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# Run all binaries, and collect the long option associated to each
|
||||
# short option for easy comparison.
|
||||
# This script should work with both Python 2 and 3.
|
||||
|
||||
from sys import stdout as out
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
with open('Makefile.am', 'r') as mf:
|
||||
lines = mf.read()
|
||||
|
||||
lines = re.sub('\s*\\\\\s*', ' ', lines)
|
||||
bin_programs = re.search('bin_PROGRAMS\s*=([\w \t]*)', lines).group(1).split()
|
||||
|
||||
optre = re.compile('(-\w), (--[\w=-]+)')
|
||||
|
||||
d = {}
|
||||
|
||||
for tool in bin_programs:
|
||||
args = ('./' + tool, '--help')
|
||||
try:
|
||||
popen = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
except OSError:
|
||||
print("Cannot execute " + tool + ", is it compiled?")
|
||||
exit(1)
|
||||
popen.wait()
|
||||
output = popen.communicate()[0].decode('utf-8')
|
||||
|
||||
for match in optre.finditer(output):
|
||||
shortname, longname = match.group(1), match.group(2)
|
||||
if not shortname in d:
|
||||
d[shortname] = { longname: tool }
|
||||
elif not longname in d[shortname]:
|
||||
d[shortname][longname] = tool
|
||||
else:
|
||||
w = ('%29s' % '') + d[shortname][longname]
|
||||
w = w[w.rfind('\n') + 1 : -1]
|
||||
if len(w + ' ' + tool) < 80:
|
||||
d[shortname][longname] += ' ' + tool
|
||||
else:
|
||||
d[shortname][longname] += '\n%29s%s' % ('', tool)
|
||||
|
||||
# The lambda function works around the fact that x might be an str or
|
||||
# a unicode object depending on the Python implementation.
|
||||
for shortname in sorted(d, key=lambda x: x.lower()):
|
||||
out.write(shortname)
|
||||
first=''
|
||||
for longname in sorted(d[shortname]):
|
||||
out.write('%s %-24s %s\n' % (first, longname, d[shortname][longname]))
|
||||
first=' '
|
||||
|
|
@ -1,397 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <argp.h>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include "error.h"
|
||||
#include "argmatch.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_range.hh"
|
||||
#include "common_cout.hh"
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_conv.hh"
|
||||
|
||||
#include <spot/misc/timer.hh>
|
||||
#include <spot/misc/random.hh>
|
||||
|
||||
#include <spot/twa/bddprint.hh>
|
||||
#include <spot/twaalgos/randomgraph.hh>
|
||||
#include <spot/twaalgos/canonicalize.hh>
|
||||
|
||||
|
||||
const char argp_program_doc[] = "\
|
||||
Generate random connected automata.\n\n\
|
||||
The automata are built over the atomic propositions named by PROPS...\n\
|
||||
or, if N is a nonnegative number, using N arbitrary names.\n\
|
||||
If the density is set to D, and the number of states to Q, the degree\n\
|
||||
of each state follows a normal distribution with mean 1+(Q-1)D and\n\
|
||||
variance (Q-1)D(1-D). In particular, for D=0 all states have a single\n\
|
||||
successor, while for D=1 all states are interconnected.\v\
|
||||
Examples:\n\
|
||||
\n\
|
||||
This builds a random neverclaim with 4 states and labeled using the two\n\
|
||||
atomic propositions \"a\" and \"b\":\n\
|
||||
% randaut --spin -Q4 a b\n\
|
||||
\n\
|
||||
This builds three random, complete, and deterministic TGBA with 5 to 10\n\
|
||||
states, 1 to 3 acceptance sets, and three atomic propositions:\n\
|
||||
% randaut -n3 -D -H -Q5..10 -A1..3 3\n\
|
||||
\n\
|
||||
Build 3 random, complete, and deterministic Rabin automata\n\
|
||||
with 2 to 3 acceptance pairs, state-based acceptance, 8 states, \n\
|
||||
a high density of edges, and 3 to 4 atomic propositions:\n\
|
||||
% randaut -n3 -D -H -Q8 -d.8 -S -A 'Rabin 2..3' 3..4\n\
|
||||
";
|
||||
|
||||
enum {
|
||||
OPT_SEED = 1,
|
||||
OPT_COLORED,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Generation:", 1 },
|
||||
{ "acceptance", 'A', "ACCEPTANCE", 0,
|
||||
"specify the acceptance type of the automaton", 0 },
|
||||
{ "acc-probability", 'a', "FLOAT", 0,
|
||||
"probability that an edge belongs to one acceptance set (0.2)", 0 },
|
||||
{ "automata", 'n', "INT", 0, "number of automata to output (1)\n"\
|
||||
"use a negative value for unbounded generation", 0 },
|
||||
{ "ba", 'B', nullptr, 0,
|
||||
"build a Buchi automaton (implies --acceptance=Buchi --state-acc)", 0 },
|
||||
{ "colored", OPT_COLORED, nullptr, 0,
|
||||
"build an automaton in which each edge (or state if combined with "
|
||||
"-S) belong to a single acceptance set", 0 },
|
||||
{ "density", 'd', "FLOAT", 0, "density of the edges (0.2)", 0 },
|
||||
{ "deterministic", 'D', nullptr, 0,
|
||||
"build a complete, deterministic automaton ", 0 },
|
||||
{ "unique", 'u', nullptr, 0,
|
||||
"do not output the same automaton twice (same in the sense that they "\
|
||||
"are isomorphic)", 0 },
|
||||
{ "seed", OPT_SEED, "INT", 0,
|
||||
"seed for the random number generator (0)", 0 },
|
||||
{ "states", 'Q', "RANGE", 0, "number of states to output (10)", 0 },
|
||||
{ "state-based-acceptance", 'S', nullptr, 0,
|
||||
"used state-based acceptance", 0 },
|
||||
{ "sbacc", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||
RANGE_DOC,
|
||||
{ nullptr, 0, nullptr, 0, "ACCEPTANCE may be either a RANGE (in which case "
|
||||
"generalized Büchi is assumed), or an arbitrary acceptance formula "
|
||||
"such as 'Fin(0)|Inf(1)&Fin(2)' in the same syntax as in the HOA "
|
||||
"format, or one of the following patterns:\n"
|
||||
" none\n"
|
||||
" all\n"
|
||||
" Buchi\n"
|
||||
" co-Buchi\n"
|
||||
" generalized-Buchi RANGE\n"
|
||||
" generalized-co-Buchi RANGE\n"
|
||||
" Rabin RANGE\n"
|
||||
" Streett RANGE\n"
|
||||
" generalized-Rabin INT RANGE RANGE ... RANGE\n"
|
||||
" parity (min|max|rand) (odd|even|rand) RANGE\n"
|
||||
" random RANGE\n"
|
||||
" random RANGE PROBABILITY\n"
|
||||
"The random acceptance condition uses each set only once, "
|
||||
"unless a probability (to reuse the set again every time it is used) "
|
||||
"is given.", 2 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
|
||||
static const struct argp_child children[] =
|
||||
{
|
||||
{ &aoutput_argp, 0, nullptr, 3 },
|
||||
{ &aoutput_o_format_argp, 0, nullptr, 4 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
static const char* opt_acceptance = nullptr;
|
||||
typedef spot::twa_graph::graph_t::edge_storage_t tr_t;
|
||||
typedef std::set<std::vector<tr_t>> unique_aut_t;
|
||||
static spot::atomic_prop_set aprops;
|
||||
static range ap_count_given = {-1, -2}; // Must be two different negative val
|
||||
static int opt_seed = 0;
|
||||
static const char* opt_seed_str = "0";
|
||||
static int opt_automata = 1;
|
||||
static range opt_states = { 10, 10 };
|
||||
static float opt_density = 0.2;
|
||||
static range opt_acc_sets = { -1, 0 };
|
||||
static float opt_acc_prob = 0.2;
|
||||
static bool opt_deterministic = false;
|
||||
static bool opt_state_acc = false;
|
||||
static bool opt_colored = false;
|
||||
static bool ba_wanted = false;
|
||||
static bool generic_wanted = false;
|
||||
static bool gba_wanted = false;
|
||||
static std::unique_ptr<unique_aut_t> opt_uniq = nullptr;
|
||||
|
||||
static void
|
||||
ba_options()
|
||||
{
|
||||
opt_acc_sets = { 1, 1 };
|
||||
opt_state_acc = true;
|
||||
}
|
||||
|
||||
// Range should have the form 12..34 or 12:34, maybe with spaces. The
|
||||
// characters between '.' and ':' include all digits plus '/', but the
|
||||
// parser will later choke on '/' if it is used, so let's not worry
|
||||
// here.
|
||||
static bool
|
||||
looks_like_a_range(const char* str)
|
||||
{
|
||||
while (*str == ' ' || (*str >= '.' && *str <= ':'))
|
||||
++str;
|
||||
return !*str;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state* as)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case '8':
|
||||
spot::enable_utf8();
|
||||
break;
|
||||
case 'a':
|
||||
opt_acc_prob = to_float(arg);
|
||||
if (opt_acc_prob < 0.0 || opt_acc_prob > 1.0)
|
||||
error(2, 0, "probability of acceptance set membership "
|
||||
"should be between 0.0 and 1.0");
|
||||
break;
|
||||
case 'A':
|
||||
if (looks_like_a_range(arg))
|
||||
{
|
||||
opt_acc_sets = parse_range(arg);
|
||||
if (opt_acc_sets.min > opt_acc_sets.max)
|
||||
std::swap(opt_acc_sets.min, opt_acc_sets.max);
|
||||
if (opt_acc_sets.min < 0)
|
||||
error(2, 0, "number of acceptance sets should be positive");
|
||||
gba_wanted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt_acceptance = arg;
|
||||
generic_wanted = true;
|
||||
}
|
||||
break;
|
||||
case 'B':
|
||||
ba_options();
|
||||
ba_wanted = true;
|
||||
break;
|
||||
case 'd':
|
||||
opt_density = to_float(arg);
|
||||
if (opt_density < 0.0 || opt_density > 1.0)
|
||||
error(2, 0, "density should be between 0.0 and 1.0");
|
||||
break;
|
||||
case 'D':
|
||||
opt_deterministic = true;
|
||||
break;
|
||||
case 'n':
|
||||
opt_automata = to_int(arg);
|
||||
break;
|
||||
case 'Q':
|
||||
opt_states = parse_range(arg);
|
||||
if (opt_states.min > opt_states.max)
|
||||
std::swap(opt_states.min, opt_states.max);
|
||||
if (opt_states.min == 0)
|
||||
error(1, 0, "cannot build an automaton with 0 states");
|
||||
break;
|
||||
case 'S':
|
||||
opt_state_acc = true;
|
||||
break;
|
||||
case 'u':
|
||||
opt_uniq =
|
||||
std::unique_ptr<unique_aut_t>(new std::set<std::vector<tr_t>>());
|
||||
break;
|
||||
case OPT_COLORED:
|
||||
opt_colored = true;
|
||||
break;
|
||||
case OPT_SEED:
|
||||
opt_seed = to_int(arg);
|
||||
opt_seed_str = arg;
|
||||
break;
|
||||
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 && looks_like_a_range(arg))
|
||||
{
|
||||
ap_count_given = parse_range(arg);
|
||||
// Create the set once if the count is fixed.
|
||||
if (ap_count_given.min == ap_count_given.max)
|
||||
aprops = spot::create_atomic_prop_set(ap_count_given.min);
|
||||
break;
|
||||
}
|
||||
aprops.insert(spot::formula::ap(arg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
strcpy(F_doc, "seed number");
|
||||
strcpy(L_doc, "automaton number");
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "N|PROP...", argp_program_doc,
|
||||
children, nullptr, nullptr };
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
// running 'randaut 0' is one way to generate automata using no
|
||||
// atomic propositions so do not complain in that case.
|
||||
if (aprops.empty() && ap_count_given.max < 0)
|
||||
error(2, 0, "No atomic proposition supplied? Run '%s --help' for usage.",
|
||||
program_name);
|
||||
|
||||
if (generic_wanted && automaton_format == Spin)
|
||||
error(2, 0, "--spin implies --ba so should not be used with --acceptance");
|
||||
if (generic_wanted && ba_wanted)
|
||||
error(2, 0, "--acceptance and --ba may not be used together");
|
||||
|
||||
if (automaton_format == Spin && opt_acc_sets.max > 1)
|
||||
error(2, 0, "--spin is incompatible with --acceptance=%d..%d",
|
||||
opt_acc_sets.min, opt_acc_sets.max);
|
||||
if (ba_wanted && opt_acc_sets.min != 1 && opt_acc_sets.max != 1)
|
||||
error(2, 0, "--ba is incompatible with --acceptance=%d..%d",
|
||||
opt_acc_sets.min, opt_acc_sets.max);
|
||||
if (ba_wanted && generic_wanted)
|
||||
error(2, 0, "--ba is incompatible with --acceptance=%s", opt_acceptance);
|
||||
|
||||
if (automaton_format == Spin)
|
||||
ba_options();
|
||||
|
||||
if (opt_colored && opt_acc_sets.min == -1 && !generic_wanted)
|
||||
error(2, 0, "--colored requires at least one acceptance set; "
|
||||
"use --acceptance");
|
||||
if (opt_colored && opt_acc_sets.min == 0)
|
||||
error(2, 0, "--colored requires at least one acceptance set; "
|
||||
"fix the range of --acceptance");
|
||||
|
||||
if (opt_acc_sets.min == -1)
|
||||
opt_acc_sets.min = 0;
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
spot::srand(opt_seed);
|
||||
auto d = spot::make_bdd_dict();
|
||||
|
||||
automaton_printer printer;
|
||||
|
||||
constexpr unsigned max_trials = 10000;
|
||||
unsigned trials = max_trials;
|
||||
|
||||
int automaton_num = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
spot::stopwatch sw;
|
||||
sw.start();
|
||||
|
||||
if (ap_count_given.max > 0
|
||||
&& ap_count_given.min != ap_count_given.max)
|
||||
{
|
||||
int c = spot::rrand(ap_count_given.min, ap_count_given.max);
|
||||
aprops = spot::create_atomic_prop_set(c);
|
||||
}
|
||||
|
||||
int size = opt_states.min;
|
||||
if (size != opt_states.max)
|
||||
size = spot::rrand(size, opt_states.max);
|
||||
|
||||
int accs = opt_acc_sets.min;
|
||||
if (accs != opt_acc_sets.max)
|
||||
accs = spot::rrand(accs, opt_acc_sets.max);
|
||||
|
||||
spot::acc_cond::acc_code code;
|
||||
if (opt_acceptance)
|
||||
{
|
||||
code = spot::acc_cond::acc_code(opt_acceptance);
|
||||
accs = code.used_sets().max_set();
|
||||
if (opt_colored && accs == 0)
|
||||
error(2, 0, "--colored requires at least one acceptance set; "
|
||||
"fix the range of --acceptance");
|
||||
}
|
||||
|
||||
auto aut =
|
||||
spot::random_graph(size, opt_density, &aprops, d,
|
||||
accs, opt_acc_prob, 0.5,
|
||||
opt_deterministic, opt_state_acc,
|
||||
opt_colored);
|
||||
|
||||
if (opt_acceptance)
|
||||
aut->set_acceptance(accs, code);
|
||||
|
||||
if (opt_uniq)
|
||||
{
|
||||
auto tmp = spot::canonicalize
|
||||
(make_twa_graph(aut, spot::twa::prop_set::all()));
|
||||
std::vector<tr_t> trans(tmp->edge_vector().begin() + 1,
|
||||
tmp->edge_vector().end());
|
||||
if (!opt_uniq->emplace(trans).second)
|
||||
{
|
||||
--trials;
|
||||
if (trials == 0)
|
||||
error(2, 0, "failed to generate a new unique automaton"
|
||||
" after %d trials", max_trials);
|
||||
continue;
|
||||
}
|
||||
trials = max_trials;
|
||||
}
|
||||
|
||||
auto runtime = sw.stop();
|
||||
|
||||
printer.print(aut, nullptr,
|
||||
opt_seed_str, automaton_num, runtime, nullptr);
|
||||
|
||||
++automaton_num;
|
||||
if (opt_automata > 0 && automaton_num >= opt_automata)
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,317 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <argp.h>
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include "error.h"
|
||||
|
||||
#include "common_setup.hh"
|
||||
#include "common_output.hh"
|
||||
#include "common_range.hh"
|
||||
#include "common_r.hh"
|
||||
#include "common_conv.hh"
|
||||
|
||||
#include <sstream>
|
||||
#include <spot/tl/randomltl.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/misc/random.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
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\
|
||||
\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\
|
||||
% randltl -n10 a b c\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\
|
||||
The following disables xor, implies, and equiv, and multiply the probability\n\
|
||||
of X to occur by 10.\n\
|
||||
% randltl --ltl-priorities='xor=0, implies=0, equiv=0, X=10' -n10 a b c\n\
|
||||
";
|
||||
|
||||
enum {
|
||||
OPT_BOOLEAN_PRIORITIES = 1,
|
||||
OPT_DUMP_PRIORITIES,
|
||||
OPT_DUPS,
|
||||
OPT_LTL_PRIORITIES,
|
||||
OPT_PSL_PRIORITIES,
|
||||
OPT_SEED,
|
||||
OPT_SERE_PRIORITIES,
|
||||
OPT_TREE_SIZE,
|
||||
OPT_WF,
|
||||
};
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
// Keep this alphabetically sorted (expect for aliases).
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Type of formula to generate:", 1 },
|
||||
{ "boolean", 'B', nullptr, 0, "generate Boolean formulas", 0 },
|
||||
{ "ltl", 'L', nullptr, 0, "generate LTL formulas (default)", 0 },
|
||||
{ "sere", 'S', nullptr, 0, "generate SERE", 0 },
|
||||
{ "psl", 'P', nullptr, 0, "generate PSL formulas", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Generation:", 2 },
|
||||
{ "weak-fairness", OPT_WF, nullptr, 0,
|
||||
"append some weak-fairness conditions", 0 },
|
||||
{ "formulas", 'n', "INT", 0, "number of formulas to output (1)\n"\
|
||||
"use a negative value for unbounded generation", 0 },
|
||||
{ "seed", OPT_SEED, "INT", 0,
|
||||
"seed for the random number generator (0)", 0 },
|
||||
{ "tree-size", OPT_TREE_SIZE, "RANGE", 0,
|
||||
"tree size of the formulas generated, before mandatory "\
|
||||
"trivial simplifications (15)", 0 },
|
||||
{ "allow-dups", OPT_DUPS, nullptr, 0,
|
||||
"allow duplicate formulas to be output", 0 },
|
||||
DECLARE_OPT_R,
|
||||
RANGE_DOC,
|
||||
LEVEL_DOC(3),
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Adjusting probabilities:", 4 },
|
||||
{ "dump-priorities", OPT_DUMP_PRIORITIES, nullptr, 0,
|
||||
"show current priorities, do not generate any formula", 0 },
|
||||
{ "ltl-priorities", OPT_LTL_PRIORITIES, "STRING", 0,
|
||||
"set priorities for LTL formulas", 0 },
|
||||
{ "sere-priorities", OPT_SERE_PRIORITIES, "STRING", 0,
|
||||
"set priorities for SERE formulas", 0 },
|
||||
{ "boolean-priorities", OPT_BOOLEAN_PRIORITIES, "STRING", 0,
|
||||
"set priorities for Boolean formulas", 0 },
|
||||
{ nullptr, 0, nullptr, 0, "STRING should be a comma-separated list of "
|
||||
"assignments, assigning integer priorities to the tokens "
|
||||
"listed by --dump-priorities.", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", -20 },
|
||||
{ nullptr, 0, nullptr, 0, "The FORMAT string passed to --format may use "
|
||||
"the following interpreted sequences:", -19 },
|
||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the formula (in the selected syntax)", 0 },
|
||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"the (serial) number of the formula", 0 },
|
||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"a single %", 0 },
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &output_argp, 0, nullptr, -20 },
|
||||
{ &misc_argp, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
spot::atomic_prop_set aprops;
|
||||
static int output = OUTPUTLTL;
|
||||
static char* opt_pL = nullptr;
|
||||
static char* opt_pS = nullptr;
|
||||
static char* opt_pB = nullptr;
|
||||
static bool opt_dump_priorities = false;
|
||||
static int opt_formulas = 1;
|
||||
static int opt_seed = 0;
|
||||
static range opt_tree_size = { 15, 15 };
|
||||
static bool opt_unique = true;
|
||||
static bool opt_wf = false;
|
||||
static bool ap_count_given = false;
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state* as)
|
||||
{
|
||||
// This switch is alphabetically-ordered.
|
||||
switch (key)
|
||||
{
|
||||
case 'B':
|
||||
output = OUTPUTBOOL;
|
||||
break;
|
||||
case 'L':
|
||||
output = OUTPUTLTL;
|
||||
break;
|
||||
case 'n':
|
||||
opt_formulas = to_int(arg);
|
||||
break;
|
||||
case 'P':
|
||||
output = OUTPUTPSL;
|
||||
break;
|
||||
case OPT_R:
|
||||
parse_r(arg);
|
||||
break;
|
||||
case 'S':
|
||||
output = OUTPUTSERE;
|
||||
break;
|
||||
case OPT_BOOLEAN_PRIORITIES:
|
||||
opt_pB = arg;
|
||||
break;
|
||||
case OPT_DUPS:
|
||||
opt_unique = false;
|
||||
break;
|
||||
case OPT_LTL_PRIORITIES:
|
||||
opt_pL = arg;
|
||||
break;
|
||||
case OPT_DUMP_PRIORITIES:
|
||||
opt_dump_priorities = true;
|
||||
break;
|
||||
// case OPT_PSL_PRIORITIES: break;
|
||||
case OPT_SERE_PRIORITIES:
|
||||
opt_pS = arg;
|
||||
break;
|
||||
case OPT_SEED:
|
||||
opt_seed = to_int(arg);
|
||||
break;
|
||||
case OPT_TREE_SIZE:
|
||||
opt_tree_size = parse_range(arg);
|
||||
if (opt_tree_size.min > opt_tree_size.max)
|
||||
std::swap(opt_tree_size.min, opt_tree_size.max);
|
||||
break;
|
||||
case OPT_WF:
|
||||
opt_wf = true;
|
||||
break;
|
||||
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;
|
||||
aprops = spot::create_atomic_prop_set(res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
aprops.insert(spot::default_environment::instance().require(arg));
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, parse_opt, "N|PROP...", argp_program_doc,
|
||||
children, nullptr, nullptr };
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
// 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.",
|
||||
program_name);
|
||||
|
||||
spot::srand(opt_seed);
|
||||
try
|
||||
{
|
||||
spot::randltlgenerator rg
|
||||
(aprops,
|
||||
[&] (){
|
||||
spot::option_map opts;
|
||||
opts.set("output", output);
|
||||
opts.set("tree_size_min", opt_tree_size.min);
|
||||
opts.set("tree_size_max", opt_tree_size.max);
|
||||
opts.set("wf", opt_wf);
|
||||
opts.set("seed", opt_seed);
|
||||
opts.set("simplification_level", simplification_level);
|
||||
return opts;
|
||||
}(), opt_pL, opt_pS, opt_pB);
|
||||
|
||||
if (opt_dump_priorities)
|
||||
{
|
||||
switch (output)
|
||||
{
|
||||
case OUTPUTLTL:
|
||||
std::cout <<
|
||||
"Use --ltl-priorities to set the following LTL priorities:\n";
|
||||
rg.dump_ltl_priorities(std::cout);
|
||||
break;
|
||||
case OUTPUTBOOL:
|
||||
std::cout <<
|
||||
"Use --boolean-priorities to set the following Boolean "
|
||||
"formula priorities:\n";
|
||||
rg.dump_bool_priorities(std::cout);
|
||||
break;
|
||||
case OUTPUTPSL:
|
||||
std::cout <<
|
||||
"Use --ltl-priorities to set the following LTL priorities:\n";
|
||||
rg.dump_psl_priorities(std::cout);
|
||||
// Fall through.
|
||||
case OUTPUTSERE:
|
||||
std::cout <<
|
||||
"Use --sere-priorities to set the following SERE priorities:\n";
|
||||
rg.dump_sere_priorities(std::cout);
|
||||
std::cout <<
|
||||
"Use --boolean-priorities to set the following Boolean "
|
||||
"formula priorities:\n";
|
||||
rg.dump_sere_bool_priorities(std::cout);
|
||||
break;
|
||||
default:
|
||||
error(2, 0, "internal error: unknown type of output");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
while (opt_formulas < 0 || opt_formulas--)
|
||||
{
|
||||
static int count = 0;
|
||||
spot::formula f = rg.next();
|
||||
if (!f)
|
||||
{
|
||||
error(2, 0, "failed to generate a new unique formula after %d " \
|
||||
"trials", MAX_TRIALS);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_formula_checked(f, nullptr, ++count);
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
catch (const std::invalid_argument& e)
|
||||
{
|
||||
error(2, 0, "%s", e.what());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "common_sys.hh"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <argp.h>
|
||||
#include "common_setup.hh"
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
Common fine-tuning options for binaries built with Spot.\n\
|
||||
\n\
|
||||
The argument of -x or --extra-options is a comma-separated list of KEY=INT \
|
||||
assignments that are passed to the post-processing routines (they may \
|
||||
be passed to other algorithms in the future). These options are \
|
||||
mostly used for benchmarking and debugging purpose. KEYR (without any \
|
||||
value) is a shorthand for KEY=1, while !KEY is a shorthand for KEY=0.";
|
||||
|
||||
#define DOC(NAME, TXT) NAME, 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, TXT, 0
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
{ nullptr, 0, nullptr, 0, "Translation options:", 0 },
|
||||
{ DOC("comp-susp", "Set to 1 to enable compositional suspension, \
|
||||
as described in our SPIN'13 paper (see Bibliography below). Set to 2, \
|
||||
to build only the skeleton TGBA without composing it. Set to 0 (the \
|
||||
default) to disable.") },
|
||||
{ DOC("early-susp", "When set to 1, start compositional suspension on \
|
||||
the transitions that enter accepting SCCs, and not only on the transitions \
|
||||
inside accepting SCCs. This option defaults to 0, and is only used when \
|
||||
comp-susp=1.") },
|
||||
{ DOC("skel-simul", "Default to 1. Set to 0 to disable simulation \
|
||||
on the skeleton automaton during compositional suspension. Only used when \
|
||||
comp-susp=1.") },
|
||||
{ DOC("skel-wdba", "Set to 0 to disable WDBA \
|
||||
minimization on the skeleton automaton during compositional suspension. \
|
||||
Set to 1 always WDBA-minimize the skeleton . Set to 2 to keep the WDBA \
|
||||
only if it is smaller than the original skeleton. This option is only \
|
||||
used when comp-susp=1 and default to 1 or 2 depending on whether --small \
|
||||
or --deterministic is specified.") },
|
||||
{ nullptr, 0, nullptr, 0, "Postprocessing options:", 0 },
|
||||
{ DOC("scc-filter", "Set to 1 (the default) to enable \
|
||||
SCC-pruning and acceptance simplification at the beginning of \
|
||||
post-processing. Transitions that are outside of accepting SCC are \
|
||||
removed from accepting sets, except those that enter into an accepting \
|
||||
SCC. Set to 2 to remove even these entering transition from the \
|
||||
accepting sets. Set to 0 to disable this SCC-pruning and acceptance \
|
||||
simpification pass.") },
|
||||
{ DOC("degen-reset", "If non-zero (the default), the \
|
||||
degeneralization algorithm will reset its level any time it exits \
|
||||
an SCC.") },
|
||||
{ DOC("degen-lcache", "If non-zero (the default is 1), whenever the \
|
||||
degeneralization algorithm enters an SCC on a state that has already \
|
||||
been associated to a level elsewhere, it should reuse that level. \
|
||||
Different values can be used to select which level to reuse: 1 always \
|
||||
uses the first level created, 2 uses the minimum level seen so far, and \
|
||||
3 uses the maximum level seen so far. The \"lcache\" stands for \
|
||||
\"level cache\".") },
|
||||
{ DOC("degen-order", "If non-zero, the degeneralization algorithm \
|
||||
will compute an independent degeneralization order for each SCC it \
|
||||
processes. This is currently disabled by default.") },
|
||||
{ DOC("degen-lskip", "If non-zero (the default), the degeneralization \
|
||||
algorithm will skip as much levels as possible for each transition. This \
|
||||
is enabled by default as it very often reduce the number of resulting \
|
||||
states. A consequence of skipping levels is that the degeneralized \
|
||||
automaton tends to have smaller cycles around the accepting states. \
|
||||
Disabling skipping will produce automata with large cycles, and often \
|
||||
with more states.") },
|
||||
{ DOC("degen-lowinit", "Whenever the degeneralization algorihm enters \
|
||||
a new SCC (or starts from the initial state), it starts on some level L that \
|
||||
is compatible with all outgoing transitions. If degen-lowinit is zero \
|
||||
(the default) and the corresponding state (in the generalized automaton) \
|
||||
has an accepting self-loop, then level L is replaced by the accepting \
|
||||
level, as it might favor finding accepting cycles earlier. If \
|
||||
degen-lowinit is non-zero, then level L is always used without looking \
|
||||
for the presence of an accepting self-loop.") },
|
||||
{ DOC("simul", "Set to 0 to disable simulation-based reductions. \
|
||||
Set to 1 to use only direct simulation. Set to 2 to use only reverse \
|
||||
simulation. Set to 3 to iterate both direct and reverse simulations. \
|
||||
The default is 3, except when option --low is specified, in which case \
|
||||
the default is 1.") },
|
||||
{ DOC("ba-simul", "Set to 0 to disable simulation-based reductions \
|
||||
on the Büchi automaton (i.e., after degeneralization has been performed). \
|
||||
Set to 1 to use only direct simulation. Set to 2 to use only reverse \
|
||||
simulation. Set to 3 to iterate both direct and reverse simulations. \
|
||||
The default is 3 in --high mode, and 0 otherwise.") },
|
||||
{ DOC("wdba-minimize", "Set to 0 to disable WDBA-minimization. \
|
||||
Enabled by default.") },
|
||||
{ DOC("tba-det", "Set to 1 to attempt a powerset determinization \
|
||||
if the TGBA is not already deterministic. Doing so will degeneralize \
|
||||
the automaton. This is disabled by default, unless sat-minimize is set.") },
|
||||
{ DOC("sat-minimize",
|
||||
"Set to 1 to enable SAT-based minimization of deterministic \
|
||||
TGBA: it starts with the number of states of the input, and iteratively \
|
||||
tries to find a deterministic TGBA with one less state. Set to 2 to perform \
|
||||
a binary search instead. Disabled (0) by default. The sat solver to use \
|
||||
can be set with the SPOT_SATSOLVER environment variable (see below). By \
|
||||
default the procedure looks for a TGBA with the same number of acceptance \
|
||||
set; this can be changed with the sat-acc option, or of course by using -B \
|
||||
to construct a Büchi automaton. Enabling SAT-based minimization will \
|
||||
also enable tba-det.") },
|
||||
{ DOC("sat-states",
|
||||
"When this is set to some positive integer, the SAT-based \
|
||||
minimization will attempt to construct a TGBA with the given number of \
|
||||
states. It may however return an automaton with less states if some of \
|
||||
these are unreachable or useless. Setting sat-states automatically \
|
||||
enables sat-minimize, but no iteration is performed. If no equivalent \
|
||||
automaton could be constructed with the given number of states, the original \
|
||||
automaton is returned.") },
|
||||
{ DOC("sat-acc",
|
||||
"When this is set to some positive integer, the SAT-based will \
|
||||
attempt to construct a TGBA with the given number of acceptance sets. \
|
||||
states. It may however return an automaton with less acceptance sets if \
|
||||
some of these are useless. Setting sat-acc automatically \
|
||||
sets sat-minimize to 1 if not set differently.") },
|
||||
{ DOC("state-based",
|
||||
"Set to 1 to instruct the SAT-minimization procedure to produce \
|
||||
a TGBA where all outgoing transition of a state have the same acceptance \
|
||||
sets. By default this is only enabled when option -B is used.") },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
{ &misc_argp_hidden, 0, nullptr, -1 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
setup(argv);
|
||||
|
||||
const argp ap = { options, nullptr, nullptr, argp_program_doc, children,
|
||||
nullptr, nullptr };
|
||||
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
std::cerr << "This binary serves no purpose other than generating"
|
||||
<< " the spot-x.7 manpage.\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -42,10 +42,10 @@ check_SCRIPTS = defs
|
|||
TESTS = check.test finite.test finite2.test kripke.test
|
||||
EXTRA_DIST = $(TESTS) beem-peterson.4.dve finite.dve finite.pm
|
||||
|
||||
kripke.test: $(top_builddir)/spot/tests/parse_print$(EXEEXT)
|
||||
kripke.test: $(top_builddir)/tests/parse_print$(EXEEXT)
|
||||
|
||||
$(top_builddir)/spot/tests/parse_print$(EXEEXT):
|
||||
cd $(top_builddir)/spot/tests && \
|
||||
$(top_builddir)/tests/parse_print$(EXEEXT):
|
||||
cd $(top_builddir)/tests && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) parse_print$(EXEEXT)
|
||||
|
||||
distclean-local:
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ fi
|
|||
|
||||
set -e
|
||||
|
||||
run 0 ../modelcheck -gK ${srcdir}/finite.dve 'F("P.a > 5")' > output
|
||||
run 0 ${top_builddir}/spot/tests/parse_print output | tr -d '"' > output2
|
||||
run 0 ../modelcheck -gK $srcdir/finite.dve 'F("P.a > 5")' > output
|
||||
run 0 $top_builddir/tests/parse_print output | tr -d '"' > output2
|
||||
tr -d '"' < output >outputF
|
||||
cmp outputF output2
|
||||
|
||||
../modelcheck -gK $srcdir/beem-peterson.4.dve '!G("pos[1] < 3")' > outputP
|
||||
${top_builddir}/spot/tests/ikwiad -e -KPoutputP '!G("pos[1] < 3")'
|
||||
$top_builddir/tests/ikwiad -e -KPoutputP '!G("pos[1] < 3")'
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ tmp=incltest.tmp
|
|||
# We used to loop over more directories before the source tree was
|
||||
# rearranged. So there is only one left today, but we keep the loop
|
||||
# in case we want to add more in the future.
|
||||
for dir in "${INCDIR-..}"; do
|
||||
for dir in "${INCDIR-..}" "${INCDIR-..}/../bin" "${INCDIR-..}/../tests"; do
|
||||
|
||||
find "$dir" \( -name "${1-*}.hh" \
|
||||
-o -name "${1-*}.hxx" \
|
||||
|
|
@ -329,7 +329,7 @@ done
|
|||
|
||||
|
||||
# Rules for Makefiles.
|
||||
for dir in "${INCDIR-..}"; do
|
||||
for dir in "${INCDIR-..}" "${INCDIR-..}/../bin" "${INCDIR-..}/../tests"; do
|
||||
|
||||
find "$dir" -name "Makefile.am" -a -type f -a -print |
|
||||
while read file; do
|
||||
|
|
|
|||
70
spot/tests/.gitignore
vendored
70
spot/tests/.gitignore
vendored
|
|
@ -1,70 +0,0 @@
|
|||
acc
|
||||
apcollect
|
||||
bddprod
|
||||
bitvect
|
||||
blue_counter
|
||||
checkpsl
|
||||
checkta
|
||||
complement
|
||||
consterm
|
||||
defs
|
||||
.deps
|
||||
*.dot
|
||||
eltl2tgba
|
||||
emptchk
|
||||
defs
|
||||
equals
|
||||
expect
|
||||
expldot
|
||||
explicit
|
||||
explicit2
|
||||
explicit3
|
||||
explprod
|
||||
graph
|
||||
genltl
|
||||
input
|
||||
intvcomp
|
||||
intvcmp2
|
||||
kind
|
||||
length
|
||||
.libs
|
||||
ikwiad
|
||||
ltl2dot
|
||||
ltl2text
|
||||
ltlmagic
|
||||
ltlprod
|
||||
ltlrel
|
||||
lunabbrev
|
||||
Makefile
|
||||
Makefile.in
|
||||
maskacc
|
||||
mixprod
|
||||
nequals
|
||||
nenoform
|
||||
ngraph
|
||||
output1
|
||||
output2
|
||||
parse_print
|
||||
powerset
|
||||
*.ps
|
||||
randltl
|
||||
randtgba
|
||||
readsat
|
||||
readsave
|
||||
reduc
|
||||
reduceu
|
||||
reductau
|
||||
reductaustr
|
||||
reduccmp
|
||||
reductgba
|
||||
stdout
|
||||
spotlbtt
|
||||
syntimpl
|
||||
taatgba
|
||||
tgbagraph
|
||||
tgbaread
|
||||
tostring
|
||||
tripprod
|
||||
tunabbrev
|
||||
tunenoform
|
||||
unabbrevwm
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de
|
||||
## Recherche et Développement de l'Epita (LRDE).
|
||||
## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
|
||||
## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
## Université Pierre et Marie Curie.
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
## Spot is free software; you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
## License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) $(BUDDY_CPPFLAGS)
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS)
|
||||
LDADD = ../libspot.la
|
||||
|
||||
# These are the most used test programs, and they are also useful
|
||||
# to run manually outside the test suite. Always build them.
|
||||
noinst_PROGRAMS = ikwiad randtgba
|
||||
|
||||
check_SCRIPTS = defs
|
||||
# Keep this sorted alphabetically.
|
||||
check_PROGRAMS = \
|
||||
acc \
|
||||
bitvect \
|
||||
complement \
|
||||
checkpsl \
|
||||
checkta \
|
||||
consterm \
|
||||
emptchk \
|
||||
equals \
|
||||
graph \
|
||||
kind \
|
||||
length \
|
||||
intvcomp \
|
||||
intvcmp2 \
|
||||
ltlprod \
|
||||
ltl2dot \
|
||||
ltl2text \
|
||||
ltlrel \
|
||||
lunabbrev \
|
||||
nequals \
|
||||
nenoform \
|
||||
ngraph \
|
||||
parse_print \
|
||||
readsat \
|
||||
reduc \
|
||||
reduccmp \
|
||||
reduceu \
|
||||
reductaustr \
|
||||
syntimpl \
|
||||
taatgba \
|
||||
tgbagraph \
|
||||
tostring \
|
||||
tunabbrev \
|
||||
tunenoform
|
||||
|
||||
# Keep this sorted alphabetically.
|
||||
acc_SOURCES = acc.cc
|
||||
bitvect_SOURCES = bitvect.cc
|
||||
checkpsl_SOURCES = checkpsl.cc
|
||||
checkta_SOURCES = checkta.cc
|
||||
complement_SOURCES = complementation.cc
|
||||
emptchk_SOURCES = emptchk.cc
|
||||
graph_SOURCES = graph.cc
|
||||
ikwiad_SOURCES = ikwiad.cc
|
||||
intvcomp_SOURCES = intvcomp.cc
|
||||
intvcmp2_SOURCES = intvcmp2.cc
|
||||
ltlprod_SOURCES = ltlprod.cc
|
||||
ngraph_SOURCES = ngraph.cc
|
||||
parse_print_SOURCES = parse_print_test.cc
|
||||
randtgba_SOURCES = randtgba.cc
|
||||
readsat_SOURCES = readsat.cc
|
||||
taatgba_SOURCES = taatgba.cc
|
||||
tgbagraph_SOURCES = twagraph.cc
|
||||
consterm_SOURCES = consterm.cc
|
||||
equals_SOURCES = equalsf.cc
|
||||
kind_SOURCES = kind.cc
|
||||
length_SOURCES = length.cc
|
||||
ltl2dot_SOURCES = readltl.cc
|
||||
ltl2dot_CPPFLAGS = $(AM_CPPFLAGS) -DDOTTY
|
||||
ltl2text_SOURCES = readltl.cc
|
||||
ltlrel_SOURCES = ltlrel.cc
|
||||
lunabbrev_SOURCES = equalsf.cc
|
||||
lunabbrev_CPPFLAGS = $(AM_CPPFLAGS) -DUNABBREV='"^ie"'
|
||||
nenoform_SOURCES = equalsf.cc
|
||||
nenoform_CPPFLAGS = $(AM_CPPFLAGS) -DNENOFORM
|
||||
nequals_SOURCES = equalsf.cc
|
||||
nequals_CPPFLAGS = $(AM_CPPFLAGS) -DNEGATE
|
||||
reduc_SOURCES = reduc.cc
|
||||
reduccmp_SOURCES = equalsf.cc
|
||||
reduccmp_CPPFLAGS = $(AM_CPPFLAGS) -DREDUC
|
||||
reduceu_SOURCES = equalsf.cc
|
||||
reduceu_CPPFLAGS = $(AM_CPPFLAGS) -DREDUC -DEVENT_UNIV
|
||||
reductaustr_SOURCES = equalsf.cc
|
||||
reductaustr_CPPFLAGS = $(AM_CPPFLAGS) -DREDUC_TAUSTR
|
||||
syntimpl_SOURCES = syntimpl.cc
|
||||
tostring_SOURCES = tostring.cc
|
||||
tunabbrev_SOURCES = equalsf.cc
|
||||
tunabbrev_CPPFLAGS = $(AM_CPPFLAGS) -DUNABBREV='"^ieFG"'
|
||||
tunenoform_SOURCES = equalsf.cc
|
||||
tunenoform_CPPFLAGS = $(AM_CPPFLAGS) -DNENOFORM -DUNABBREV='"^ieFG"'
|
||||
|
||||
|
||||
# Keep this sorted by STRENGTH. Test basic things first,
|
||||
# because such failures will be easier to diagnose and fix.
|
||||
TESTS = $(TESTS_ltl) $(TESTS_graph) $(TESTS_kripke) $(TESTS_twa)
|
||||
|
||||
TESTS_ltl = \
|
||||
bare.test \
|
||||
parse.test \
|
||||
parseerr.test \
|
||||
utf8.test \
|
||||
length.test \
|
||||
equals.test \
|
||||
tostring.test \
|
||||
lunabbrev.test \
|
||||
tunabbrev.test \
|
||||
nenoform.test \
|
||||
tunenoform.test \
|
||||
unabbrevwm.test \
|
||||
consterm.test \
|
||||
kind.test \
|
||||
remove_x.test \
|
||||
ltlrel.test \
|
||||
ltlgrind.test \
|
||||
ltlcrossgrind.test \
|
||||
ltlfilt.test \
|
||||
exclusive-ltl.test \
|
||||
latex.test \
|
||||
lbt.test \
|
||||
lenient.test \
|
||||
rand.test \
|
||||
isop.test \
|
||||
syntimpl.test \
|
||||
reduc.test \
|
||||
reduc0.test \
|
||||
reducpsl.test \
|
||||
reduccmp.test \
|
||||
uwrm.test \
|
||||
eventuniv.test \
|
||||
stutter-ltl.test
|
||||
|
||||
TESTS_graph = \
|
||||
graph.test \
|
||||
ngraph.test \
|
||||
tgbagraph.test
|
||||
|
||||
TESTS_kripke = \
|
||||
kripke.test
|
||||
|
||||
TESTS_twa = \
|
||||
acc.test \
|
||||
acc2.test \
|
||||
intvcomp.test \
|
||||
bitvect.test \
|
||||
ltlcross3.test \
|
||||
taatgba.test \
|
||||
renault.test \
|
||||
nondet.test \
|
||||
det.test \
|
||||
neverclaimread.test \
|
||||
parseaut.test \
|
||||
optba.test \
|
||||
complete.test \
|
||||
complement.test \
|
||||
remfin.test \
|
||||
dstar.test \
|
||||
readsave.test \
|
||||
ltldo.test \
|
||||
ltldo2.test \
|
||||
maskacc.test \
|
||||
maskkeep.test \
|
||||
prodor.test \
|
||||
simdet.test \
|
||||
sim2.test \
|
||||
sim3.test \
|
||||
ltl2tgba.test \
|
||||
ltl2neverclaim.test \
|
||||
ltl2neverclaim-lbtt.test \
|
||||
ltlprod.test \
|
||||
explprod.test \
|
||||
explpro2.test \
|
||||
explpro3.test \
|
||||
explpro4.test \
|
||||
tripprod.test \
|
||||
dupexp.test \
|
||||
exclusive-tgba.test \
|
||||
remprop.test \
|
||||
degendet.test \
|
||||
degenid.test \
|
||||
degenlskip.test \
|
||||
randomize.test \
|
||||
lbttparse.test \
|
||||
scc.test \
|
||||
sccdot.test \
|
||||
sccsimpl.test \
|
||||
sepsets.test \
|
||||
dbacomp.test \
|
||||
obligation.test \
|
||||
wdba.test \
|
||||
wdba2.test \
|
||||
babiak.test \
|
||||
monitor.test \
|
||||
dra2dba.test \
|
||||
unambig.test \
|
||||
ltlcross4.test \
|
||||
ltl3dra.test \
|
||||
ltl2dstar.test \
|
||||
ltl2dstar2.test \
|
||||
ltl2dstar3.test \
|
||||
ltl2dstar4.test \
|
||||
ltl2ta.test \
|
||||
ltl2ta2.test \
|
||||
randaut.test \
|
||||
randtgba.test \
|
||||
isomorph.test \
|
||||
uniq.test \
|
||||
sbacc.test \
|
||||
stutter-tgba.test \
|
||||
strength.test \
|
||||
emptchk.test \
|
||||
emptchke.test \
|
||||
dfs.test \
|
||||
ltlcrossce.test \
|
||||
ltlcrossce2.test \
|
||||
emptchkr.test \
|
||||
ltlcounter.test \
|
||||
basimul.test \
|
||||
satmin.test \
|
||||
satmin2.test \
|
||||
spotlbtt.test \
|
||||
ltlcross.test \
|
||||
spotlbtt2.test \
|
||||
ltlcross2.test \
|
||||
complementation.test \
|
||||
randpsl.test \
|
||||
cycles.test
|
||||
|
||||
EXTRA_DIST = $(TESTS)
|
||||
|
||||
distclean-local:
|
||||
rm -rf $(TESTS:.test=.dir)
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <spot/twa/acc.hh>
|
||||
|
||||
static void check(spot::acc_cond& ac, spot::acc_cond::mark_t m)
|
||||
{
|
||||
std::cout << '#' << m.count() << ": " << ac.format(m);
|
||||
if (!m)
|
||||
std::cout << "empty";
|
||||
if (ac.accepting(m))
|
||||
std::cout << " accepting";
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
static void print(const std::vector<std::vector<int>>& res)
|
||||
{
|
||||
for (auto& v: res)
|
||||
{
|
||||
std::cout << '{';
|
||||
const char* comma = "";
|
||||
for (int s: v)
|
||||
{
|
||||
std::cout << comma;
|
||||
if (s < 0)
|
||||
std::cout << '!' << (-s - 1);
|
||||
else
|
||||
std::cout << s;
|
||||
comma = ", ";
|
||||
}
|
||||
std::cout << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
spot::acc_cond ac(4);
|
||||
ac.set_generalized_buchi();
|
||||
std::cout << ac.get_acceptance() << '\n';
|
||||
|
||||
auto m1 = spot::acc_cond::mark_t({0, 2});
|
||||
auto m2 = spot::acc_cond::mark_t({0, 3});
|
||||
auto m3 = spot::acc_cond::mark_t({2, 1});
|
||||
|
||||
check(ac, m1);
|
||||
check(ac, m2);
|
||||
check(ac, m3);
|
||||
check(ac, m1 | m2);
|
||||
check(ac, m2 & m1);
|
||||
check(ac, m1 | m2 | m3);
|
||||
|
||||
ac.add_set();
|
||||
ac.set_generalized_buchi();
|
||||
|
||||
check(ac, m1);
|
||||
check(ac, m2);
|
||||
check(ac, m3);
|
||||
check(ac, m1 | m2);
|
||||
check(ac, m2 & m1);
|
||||
check(ac, m1 | m2 | m3);
|
||||
|
||||
check(ac, m2 & m3);
|
||||
check(ac, ac.comp(m2 & m3));
|
||||
|
||||
spot::acc_cond ac2(ac.num_sets());
|
||||
ac2.set_generalized_buchi();
|
||||
check(ac2, m3);
|
||||
|
||||
spot::acc_cond ac3(ac.num_sets() + ac2.num_sets());
|
||||
ac3.set_generalized_buchi();
|
||||
std::cout << ac.num_sets() << " + "
|
||||
<< ac2.num_sets() << " = " << ac3.num_sets() << '\n';
|
||||
auto m5 = m2 | (m3 << ac.num_sets());
|
||||
check(ac3, m5);
|
||||
auto m6 = ac.comp(m2 & m3) | (m3 << ac.num_sets());
|
||||
check(ac3, m6);
|
||||
auto m7 = ac.comp(m2 & m3) | (ac.all_sets() << ac.num_sets());
|
||||
check(ac3, m7);
|
||||
|
||||
const char* comma = "";
|
||||
for (auto i: m7.sets())
|
||||
{
|
||||
std::cout << comma << i;
|
||||
comma = ",";
|
||||
};
|
||||
std::cout << '\n';
|
||||
|
||||
spot::acc_cond ac4;
|
||||
ac4.set_generalized_buchi();
|
||||
check(ac4, ac4.all_sets());
|
||||
check(ac4, ac4.comp(ac4.all_sets()));
|
||||
|
||||
check(ac, (m1 | m2).remove_some(2));
|
||||
|
||||
std::vector<spot::acc_cond::mark_t> s = { m1, m2, m3 };
|
||||
check(ac, ac.useless(s.begin(), s.end()));
|
||||
s.push_back(ac.mark(4));
|
||||
auto u = ac.useless(s.begin(), s.end());
|
||||
check(ac, u);
|
||||
std::cout << "stripping\n";
|
||||
for (auto& v: s)
|
||||
{
|
||||
check(ac, v);
|
||||
check(ac, v.strip(u));
|
||||
}
|
||||
|
||||
|
||||
auto code1 = ac.inf({0, 1, 3});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
code1 |= ac.fin({2});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
code1 |= ac.fin({0});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
code1 |= ac.fin({});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
code1 &= ac.inf({});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
auto code2 = code1;
|
||||
code1 &= ac.fin({0, 1});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
code1 &= ac.fin({});
|
||||
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
|
||||
code2 |= ac.fin({0, 1});
|
||||
std::cout << code2.size() << ' ' << code2 << ' ' << code2.is_dnf() << '\n';
|
||||
auto code3 = ac.inf({0, 1});
|
||||
code3 &= ac.fin({2, 3});
|
||||
std::cout << code3.size() << ' ' << code3 << ' ' << code3.is_dnf() << '\n';
|
||||
|
||||
// code3 == (Fin(2)|Fin(3)) & (Inf(0)&Inf(1))
|
||||
// {0}
|
||||
// {1}
|
||||
// {2, 3}
|
||||
std::cout << code3 << ' ' << "{0} true\n";
|
||||
spot::acc_cond::mark_t m = 0U;
|
||||
m.set(0);
|
||||
print(code3.missing(m, true));
|
||||
std::cout << code3 << ' ' << "{0} false\n";
|
||||
print(code3.missing(m, false));
|
||||
|
||||
std::cout << spot::acc_cond::acc_code("t") << '\n';
|
||||
std::cout << spot::acc_cond::acc_code("f") << '\n';
|
||||
std::cout << spot::acc_cond::acc_code("Fin(2)") << '\n';
|
||||
std::cout << spot::acc_cond::acc_code("Inf(2)") << '\n';
|
||||
std::cout << spot::acc_cond::acc_code("Fin(2) | Inf(2)") << '\n';
|
||||
std::cout << spot::acc_cond::acc_code("Inf(2) & Fin(2)") << '\n';
|
||||
auto c1 = spot::acc_cond::acc_code("Fin(0)|Inf(1)&Fin(2)|Fin(3)");
|
||||
auto c2 = spot::acc_cond::acc_code
|
||||
("( Fin ( 0 )) | (Inf ( 1) & Fin(2 ))| Fin (3) ");
|
||||
std::cout << c1 << '\n';
|
||||
std::cout << c2 << '\n';
|
||||
assert(c1 == c2);
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat >expect <<EOF
|
||||
Inf(0)&Inf(1)&Inf(2)&Inf(3)
|
||||
#2: {0,2}
|
||||
#2: {0,3}
|
||||
#2: {1,2}
|
||||
#3: {0,2,3}
|
||||
#1: {0}
|
||||
#4: {0,1,2,3} accepting
|
||||
#2: {0,2}
|
||||
#2: {0,3}
|
||||
#2: {1,2}
|
||||
#3: {0,2,3}
|
||||
#1: {0}
|
||||
#4: {0,1,2,3}
|
||||
#0: empty
|
||||
#5: {0,1,2,3,4} accepting
|
||||
#2: {1,2}
|
||||
5 + 5 = 10
|
||||
#4: {0,3,6,7}
|
||||
#7: {0,1,2,3,4,6,7}
|
||||
#10: {0,1,2,3,4,5,6,7,8,9} accepting
|
||||
0,1,2,3,4,5,6,7,8,9
|
||||
#0: empty accepting
|
||||
#0: empty accepting
|
||||
#1: {3}
|
||||
#4: {0,1,2,3}
|
||||
#2: {0,2}
|
||||
stripping
|
||||
#2: {0,2}
|
||||
#0: empty
|
||||
#2: {0,3}
|
||||
#1: {1}
|
||||
#2: {1,2}
|
||||
#1: {0}
|
||||
#1: {4}
|
||||
#1: {2}
|
||||
2 Inf(0)&Inf(1)&Inf(3) 1
|
||||
5 Fin(2) | (Inf(0)&Inf(1)&Inf(3)) 1
|
||||
7 Fin(0) | Fin(2) | (Inf(0)&Inf(1)&Inf(3)) 1
|
||||
7 Fin(0) | Fin(2) | (Inf(0)&Inf(1)&Inf(3)) 1
|
||||
7 Fin(0) | Fin(2) | (Inf(0)&Inf(1)&Inf(3)) 1
|
||||
10 (Fin(0)|Fin(1)) & (Fin(0) | Fin(2) | (Inf(0)&Inf(1)&Inf(3))) 0
|
||||
2 f 1
|
||||
9 (Fin(0)|Fin(1)) | Fin(0) | Fin(2) | (Inf(0)&Inf(1)&Inf(3)) 1
|
||||
5 (Fin(2)|Fin(3)) & (Inf(0)&Inf(1)) 0
|
||||
(Fin(2)|Fin(3)) & (Inf(0)&Inf(1)) {0} true
|
||||
{1}
|
||||
{!2, !3}
|
||||
(Fin(2)|Fin(3)) & (Inf(0)&Inf(1)) {0} false
|
||||
{!1, 2}
|
||||
{!1, 3}
|
||||
t
|
||||
f
|
||||
Fin(2)
|
||||
Inf(2)
|
||||
Fin(2) | Inf(2)
|
||||
Fin(2) & Inf(2)
|
||||
Fin(0) | (Fin(2) & Inf(1)) | Fin(3)
|
||||
Fin(0) | (Fin(2) & Inf(1)) | Fin(3)
|
||||
EOF
|
||||
|
||||
run 0 ../acc | tee stdout
|
||||
diff stdout expect
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
../../bin/ltl2tgba -H 'GFa & GFb' > in
|
||||
grep 'Acceptance:' in > expected
|
||||
../../bin/ltl2tgba -H 'GFa & GFb' --stats='Acceptance: %a %g' > out1
|
||||
../../bin/autfilt -H in --stats='Acceptance: %A %G' > out2
|
||||
diff out1 expected
|
||||
diff out2 expected
|
||||
|
||||
cat >header <<EOF
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
EOF
|
||||
|
||||
cat >body <<EOF
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&1] 0 {0 1}
|
||||
[!0&!1] 0
|
||||
[!0&1] 0 {1}
|
||||
[0&!1] 0 {0}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
#------------- DNF -------------
|
||||
|
||||
res="(Fin(1) & Fin(2) & Inf(0)) | (Inf(0)&Inf(1)&Inf(3))"
|
||||
cat >acceptances<<EOF
|
||||
2 Inf(0)&Inf(1), 2 Inf(0)&Inf(1)
|
||||
2 Fin(0) & Inf(1), 2 Fin(0) & Inf(1)
|
||||
2 t, 2 t
|
||||
2 f, 2 f
|
||||
3 (Inf(1) | Fin(2)) & Inf(0), 3 (Inf(0)&Inf(1)) | (Fin(2) & Inf(0))
|
||||
4 (Inf(1) | Fin(2)) & (Fin(1) | Inf(3)) & Inf(0), 4 $res
|
||||
4 $res, 4 $res
|
||||
3 (Fin(0)|Fin(1)) & Fin(2), 3 (Fin(0) & Fin(2)) | (Fin(1) & Fin(2))
|
||||
EOF
|
||||
|
||||
while IFS=, read a b
|
||||
do
|
||||
(cat header; echo 'Acceptance:' $a; cat body) |
|
||||
../../bin/autfilt -H --dnf-acc --stats '%A %G, %a %g'
|
||||
done < acceptances > output
|
||||
|
||||
diff acceptances output
|
||||
|
||||
#------------- CNF -------------
|
||||
|
||||
res="(Fin(2) | Inf(1)) & (Fin(1) | Inf(3)) & Inf(0)"
|
||||
cat >acceptances<<EOF
|
||||
2 Inf(0)&Inf(1), 2 Inf(0)&Inf(1)
|
||||
2 Fin(0) & Inf(1), 2 Fin(0) & Inf(1)
|
||||
2 t, 2 t
|
||||
2 f, 2 f
|
||||
3 (Inf(1) | Fin(2)) & Inf(0), 3 (Fin(2) | Inf(1)) & Inf(0)
|
||||
4 (Fin(1) & Fin(2) & Inf(0)) | (Inf(0)&Inf(1)&Inf(3)), 4 $res
|
||||
4 $res, 4 $res
|
||||
3 (Fin(0) & Fin(2)) | (Fin(1) & Fin(2)), 3 (Fin(0)|Fin(1)) & Fin(2)
|
||||
EOF
|
||||
|
||||
while IFS=, read a b
|
||||
do
|
||||
(cat header; echo 'Acceptance:' $a; cat body) |
|
||||
../../bin/autfilt -H --cnf-acc --stats '%A %G, %a %g'
|
||||
done < acceptances > output
|
||||
|
||||
diff acceptances output
|
||||
|
||||
#------------- COMP -------------
|
||||
|
||||
a="(Inf(1) | Fin(2)) & (Fin(1) | Inf(3)) & Inf(0)"
|
||||
b="(Fin(1) & Inf(2)) | (Fin(3) & Inf(1)) | Fin(0)"
|
||||
cat >acceptances<<EOF
|
||||
2 Inf(0)&Inf(1), 2 Fin(0)|Fin(1)
|
||||
2 Fin(0) & Inf(1), 2 Inf(0) | Fin(1)
|
||||
2 t, 2 f
|
||||
2 f, 2 t
|
||||
3 (Inf(1) | Fin(2)) & Inf(0), 3 (Fin(1) & Inf(2)) | Fin(0)
|
||||
4 $a, 4 $b
|
||||
4 $b, 4 (Inf(1) | Fin(2)) & (Inf(3) | Fin(1)) & Inf(0)
|
||||
3 (Fin(0)|Fin(1)) & Fin(2), 3 (Inf(0)&Inf(1)) | Inf(2)
|
||||
EOF
|
||||
|
||||
while IFS=, read a b
|
||||
do
|
||||
(cat header; echo 'Acceptance:' $a; cat body) |
|
||||
../../bin/autfilt -H --complement-acc --stats '%A %G, %a %g'
|
||||
done < acceptances > output
|
||||
|
||||
diff acceptances output
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2011, 2012, 2013 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# While running some benchmark, Tomáš Babiak found that Spot took too
|
||||
# much time (i.e. >1h) to translate those six formulae. It turns out
|
||||
# that the WDBA minimization was performed after the degeneralization
|
||||
# algorithm, while this is not necessary (WDBA will produce a BA, so
|
||||
# we may as well skip degeneralization). Translating these formulae
|
||||
# in the test-suite ensure that they don't take too much time (the
|
||||
# buildfarm will timeout if it does).
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat >formulae <<EOF
|
||||
(p6 V X(G(F(F(X X(F X(F((G X F p1)|((F p5)U p1))))U((F p4)&(!p2|(G p0))))))))
|
||||
(F((G 1)&(!p6 V X!p2)))V((F((G X(!p1 V!p3))V F!p2))U(X((G p3)U(p6 U p7))V X p5))
|
||||
(((F p0)V((F p3)&!p4))V((((!p0|!p5)V X!p5)V p6)U(p5|(!p3 U(G(p1 U p2))))))
|
||||
(G(((F((p3 &!p3)|(G((G!p2)V!p5))))|(p1 V!p4))U((X(G((F!p0)U!p6))U X!p2)|!p7)))
|
||||
X((X(!p1 V F!p6)V F!p4)U p2)&(F(G((0 U(F p6))U((p1 U(G(p4 U F p0)))U X p7))))
|
||||
(G(G(((F p5)U((((F!p1)V(p2 &!p4))|!p2)|((X!p7 U!p4)V(F(F((G p2)&p5))))))U p6)))
|
||||
EOF
|
||||
|
||||
ltl2tgba=../ikwiad
|
||||
|
||||
../../bin/ltlcross <formulae \
|
||||
"$ltl2tgba -t %f >%T" \
|
||||
"$ltl2tgba -N -r4 -R3f %f >%N" \
|
||||
"$ltl2tgba -N -r7 -R3 -x -Rm %f >%N" \
|
||||
"$ltl2tgba -t -r7 -R3 -f -x -DS -Rm %f >%T"
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2012, 2015 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
set -e
|
||||
|
||||
test "`../../bin/ltlfilt -p -f 'GFP_0.b_c'`" = "G(F(P_0.b_c))"
|
||||
test "`../../bin/ltlfilt -f 'GFP_0.b_c'`" = "GFP_0.b_c"
|
||||
foo=`../../bin/ltlfilt -p -f 'GF"P_0.b_c"'`
|
||||
test "$foo" = "G(F(P_0.b_c))"
|
||||
|
||||
foo=`../../bin/ltlfilt -p -f '"a.b" U c.d.e'`
|
||||
test "$foo" = "(a.b) U (c.d.e)"
|
||||
|
||||
foo=`../../bin/ltlfilt -f '"a.b" U c.d.e'`
|
||||
test "$foo" = "a.b U c.d.e"
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
ltl2tgba=../../bin/ltl2tgba
|
||||
|
||||
|
||||
# This bug was found while working on the state-based acceptance
|
||||
# output for the LBTT format. Using ba-simul=2 causes reverse
|
||||
# simulation to be applied to the BA automaton obtained after
|
||||
# degeneralization. Unfortunately in Spot 1.1, reverse simulation is
|
||||
# only implemented on TGBA, and when applied to a TGBA that is a BA,
|
||||
# it may merge one state that is accepting with one state that is not
|
||||
# accepting, just because they have the same incoming transitions.
|
||||
# (Applying direct simulation on a TGBA that is a BA is not a problem,
|
||||
# since an accepting state will never have the same outgoing
|
||||
# transitions as a BA.)
|
||||
|
||||
# In previous tests, we did not notice the bug because the --lbtt
|
||||
# output was always using transition-based acceptance (the equivalent
|
||||
# of --lbtt=t today), so the result of the reverse-simulation on the
|
||||
# BA was output as a TGBA with a single acceptance set, and some state
|
||||
# had both accepting and non-accepting transitions because of the
|
||||
# merge. Unfortunately, this is not a Büchi automaton. Using the
|
||||
# --spin output, or the new (state-based) --lbtt output highlights the
|
||||
# bug.
|
||||
|
||||
# In the cases below, the following configurations used to fail
|
||||
# cross-comparison with the other "sane" configurations, at least
|
||||
# with the first formula. (The other three formulas were added because
|
||||
# they also triggered related issues while debugging the first one.)
|
||||
# --lbtt -x ba-simul=2
|
||||
# --lbtt -x ba-simul=3
|
||||
# --spin -x ba-simul=2
|
||||
# --spin -x ba-simul=3
|
||||
|
||||
../../bin/ltlcross --seed=0 --products=5 --json=out.json \
|
||||
-f 'X((F(Xa | b) W c) U (Xc W (a & d)))' \
|
||||
-f '((<> p5 V ((p0 U p1) <-> (p5 \/ p1))) -> ((<> p4 V p2) M p2))' \
|
||||
-f '!p2 & (Fp5 R (((p0 U p1) & (p5 | p1)) | (!p5 & (!p0 R !p1))))' \
|
||||
-f '! ((p0 /\ p4) <-> ! ((! p0 U (p0 W p4)) /\ (X p5 -> ([] p3 /\ p5))))' \
|
||||
-f '(X <> (<> X p0 /\ X (p5 <-> p0)) W (p3 W p0))' \
|
||||
"$ltl2tgba --ba --high --lbtt=t -x ba-simul=0 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt=t -x ba-simul=1 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt=t -x ba-simul=2 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt=t -x ba-simul=3 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt -x ba-simul=0 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt -x ba-simul=1 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt -x ba-simul=2 %f >%T" \
|
||||
"$ltl2tgba --ba --high --lbtt -x ba-simul=3 %f >%T" \
|
||||
"$ltl2tgba --ba --high --spin -x ba-simul=0 %f >%N" \
|
||||
"$ltl2tgba --ba --high --spin -x ba-simul=1 %f >%N" \
|
||||
"$ltl2tgba --ba --high --spin -x ba-simul=2 %f >%N" \
|
||||
"$ltl2tgba --ba --high --spin -x ba-simul=3 %f >%N"
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <spot/misc/bitvect.hh>
|
||||
|
||||
static void ruler()
|
||||
{
|
||||
std::cout << "\n ";
|
||||
for (size_t x = 0; x < 76; ++x)
|
||||
if (x % 10 == 0)
|
||||
std::cout << x / 10;
|
||||
else
|
||||
std::cout << '_';
|
||||
std::cout << "\n ";
|
||||
for (size_t x = 0; x < 76; ++x)
|
||||
std::cout << x % 10;
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
|
||||
#define ECHO(name) std::cout << #name": " << *name << '\n'
|
||||
|
||||
int main()
|
||||
{
|
||||
ruler();
|
||||
spot::bitvect* v = spot::make_bitvect(15);
|
||||
ECHO(v);
|
||||
v->set(10);
|
||||
v->set(7);
|
||||
v->set(12);
|
||||
ECHO(v);
|
||||
|
||||
ruler();
|
||||
spot::bitvect* w = spot::make_bitvect(42);
|
||||
w->set(30);
|
||||
w->set(41);
|
||||
w->set(13);
|
||||
w->set(7);
|
||||
ECHO(w);
|
||||
*w ^= *v;
|
||||
ECHO(w);
|
||||
|
||||
ruler();
|
||||
spot::bitvect* x = spot::make_bitvect(75);
|
||||
x->set(70);
|
||||
x->set(60);
|
||||
ECHO(x);
|
||||
*x |= *w;
|
||||
ECHO(x);
|
||||
|
||||
std::cout << "subset? " << w->is_subset_of(*x)
|
||||
<< ' ' << v->is_subset_of(*w) << '\n';
|
||||
|
||||
for (size_t i = 0; i < 30; ++i)
|
||||
w->push_back((i & 3) == 0);
|
||||
ECHO(w);
|
||||
*x &= *w;
|
||||
ECHO(x);
|
||||
x->set_all();
|
||||
ECHO(x);
|
||||
|
||||
ruler();
|
||||
|
||||
w->push_back(0x09, 4);
|
||||
ECHO(w);
|
||||
spot::bitvect* y = w->extract_range(0, 71);
|
||||
ECHO(y);
|
||||
delete y;
|
||||
y = w->extract_range(0, 64);
|
||||
ECHO(y);
|
||||
delete y;
|
||||
y = w->extract_range(64, 75);
|
||||
ECHO(y);
|
||||
delete y;
|
||||
y = w->extract_range(0, 75);
|
||||
ECHO(y);
|
||||
delete y;
|
||||
y = w->extract_range(7, 64);
|
||||
ECHO(y);
|
||||
delete y;
|
||||
y = w->extract_range(7, 72);
|
||||
ECHO(y);
|
||||
delete y;
|
||||
|
||||
delete v;
|
||||
delete w;
|
||||
delete x;
|
||||
|
||||
ruler();
|
||||
|
||||
spot::bitvect_array* a = spot::make_bitvect_array(60, 10);
|
||||
for (size_t y = 0; y < a->size(); ++y)
|
||||
for (size_t x = 0; x < 60; ++x)
|
||||
{
|
||||
if (((x ^ y) & 3) < 2)
|
||||
a->at(y).set(x);
|
||||
}
|
||||
std::cout << *a;
|
||||
|
||||
ruler();
|
||||
|
||||
for (size_t i = 0; i < 12; ++i)
|
||||
a->at(4).push_back((i & 2) == 0);
|
||||
a->at(6) = a->at(4);
|
||||
a->at(8) = a->at(7);
|
||||
a->at(6) ^= a->at(8);
|
||||
|
||||
std::cout << *a;
|
||||
|
||||
std::cout << "Comp: "
|
||||
<< (a->at(0) == a->at(1))
|
||||
<< (a->at(0) == a->at(2))
|
||||
<< (a->at(1) != a->at(2))
|
||||
<< (a->at(0) < a->at(2))
|
||||
<< (a->at(0) > a->at(2))
|
||||
<< (a->at(3) < a->at(4))
|
||||
<< (a->at(5) > a->at(6)) << std::endl;
|
||||
|
||||
delete a;
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2015 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
run 0 ../bitvect | tee stderr
|
||||
cat >expected <<EOF
|
||||
|
||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
|
||||
v: 000000000000000
|
||||
v: 000000010010100
|
||||
|
||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
|
||||
w: 000000010000010000000000000000100000000001
|
||||
w: 000000000010110000000000000000100000000001
|
||||
|
||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
|
||||
x: 000000000000000000000000000000000000000000000000000000000000100000000010000
|
||||
x: 000000000010110000000000000000100000000001000000000000000000100000000010000
|
||||
subset? 1 0
|
||||
w: 000000000010110000000000000000100000000001100010001000100010001000100010
|
||||
x: 000000000010110000000000000000100000000001000000000000000000000000000010000
|
||||
x: 111111111111111111111111111111111111111111111111111111111111111111111111111
|
||||
|
||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
|
||||
w: 0000000000101100000000000000001000000000011000100010001000100010001000101001
|
||||
y: 00000000001011000000000000000010000000000110001000100010001000100010001
|
||||
y: 0000000000101100000000000000001000000000011000100010001000100010
|
||||
y: 00100010100
|
||||
y: 000000000010110000000000000000100000000001100010001000100010001000100010100
|
||||
y: 000101100000000000000001000000000011000100010001000100010
|
||||
y: 00010110000000000000000100000000001100010001000100010001000100010
|
||||
|
||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
|
||||
0: 110011001100110011001100110011001100110011001100110011001100
|
||||
1: 110011001100110011001100110011001100110011001100110011001100
|
||||
2: 001100110011001100110011001100110011001100110011001100110011
|
||||
3: 001100110011001100110011001100110011001100110011001100110011
|
||||
4: 110011001100110011001100110011001100110011001100110011001100
|
||||
5: 110011001100110011001100110011001100110011001100110011001100
|
||||
6: 001100110011001100110011001100110011001100110011001100110011
|
||||
7: 001100110011001100110011001100110011001100110011001100110011
|
||||
8: 110011001100110011001100110011001100110011001100110011001100
|
||||
9: 110011001100110011001100110011001100110011001100110011001100
|
||||
|
||||
0_________1_________2_________3_________4_________5_________6_________7_____
|
||||
0123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
|
||||
0: 110011001100110011001100110011001100110011001100110011001100
|
||||
1: 110011001100110011001100110011001100110011001100110011001100
|
||||
2: 001100110011001100110011001100110011001100110011001100110011
|
||||
3: 001100110011001100110011001100110011001100110011001100110011
|
||||
4: 110011001100110011001100110011001100110011001100110011001100110011001100
|
||||
5: 110011001100110011001100110011001100110011001100110011001100
|
||||
6: 111111111111111111111111111111111111111111111111111111111111110011001100
|
||||
7: 001100110011001100110011001100110011001100110011001100110011
|
||||
8: 001100110011001100110011001100110011001100110011001100110011
|
||||
9: 110011001100110011001100110011001100110011001100110011001100
|
||||
Comp: 1011010
|
||||
EOF
|
||||
|
||||
diff expected stderr
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <spot/tl/parse.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/ltl2taa.hh>
|
||||
#include <spot/twaalgos/sccfilter.hh>
|
||||
#include <spot/twaalgos/product.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
|
||||
static void
|
||||
syntax(char* prog)
|
||||
{
|
||||
std::cerr << prog << " file" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
syntax(argv[0]);
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
std::cerr << "failed to open " << argv[1] << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
auto d = spot::make_bdd_dict();
|
||||
|
||||
std::string s;
|
||||
unsigned line = 0;
|
||||
while (std::getline(input, s))
|
||||
{
|
||||
++line;
|
||||
std::cerr << line << ": " << s << '\n';
|
||||
if (s.empty() || s[0] == '#') // Skip comments
|
||||
continue;
|
||||
|
||||
spot::parse_error_list pe;
|
||||
auto fpos = spot::parse_infix_psl(s, pe);
|
||||
|
||||
if (spot::format_parse_errors(std::cerr, s, pe))
|
||||
return 2;
|
||||
|
||||
auto fneg = spot::formula::Not(fpos);
|
||||
|
||||
{
|
||||
auto apos = scc_filter(ltl_to_tgba_fm(fpos, d));
|
||||
auto aneg = scc_filter(ltl_to_tgba_fm(fneg, d));
|
||||
if (!spot::product(apos, aneg)->is_empty())
|
||||
{
|
||||
std::cerr << "non-empty intersection between pos and neg (FM)\n";
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto apos = scc_filter(ltl_to_tgba_fm(fpos, d, true));
|
||||
auto aneg = scc_filter(ltl_to_tgba_fm(fneg, d, true));
|
||||
if (!spot::product(apos, aneg)->is_empty())
|
||||
{
|
||||
std::cerr << "non-empty intersection between pos and neg (FM -x)\n";
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (fpos.is_ltl_formula())
|
||||
{
|
||||
auto apos =
|
||||
scc_filter(make_twa_graph(ltl_to_taa(fpos, d),
|
||||
spot::twa::prop_set::all()));
|
||||
auto aneg =
|
||||
scc_filter(make_twa_graph(ltl_to_taa(fneg, d),
|
||||
spot::twa::prop_set::all()));
|
||||
if (!spot::product(apos, aneg)->is_empty())
|
||||
{
|
||||
std::cerr << "non-empty intersection between pos and neg (TAA)\n";
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(spot::fnode::instances_check());
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,227 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <spot/tl/parse.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/sccfilter.hh>
|
||||
#include <spot/twaalgos/degen.hh>
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include <spot/taalgos/minimize.hh>
|
||||
#include <spot/taalgos/tgba2ta.hh>
|
||||
#include <spot/taalgos/dot.hh>
|
||||
#include <spot/taalgos/stats.hh>
|
||||
|
||||
static void
|
||||
syntax(char* prog)
|
||||
{
|
||||
std::cerr << prog << " file" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
static void
|
||||
stats(std::string title, const spot::ta_ptr& ta)
|
||||
{
|
||||
auto s = stats_reachable(ta);
|
||||
|
||||
std::cout << std::left << std::setw(20) << title << " | "
|
||||
<< std::right << std::setw(6) << s.states << " | "
|
||||
<< std::setw(6) << s.edges << " | "
|
||||
<< std::setw(6) << s.acceptance_states << '\n';
|
||||
}
|
||||
|
||||
static void
|
||||
stats(std::string title, const spot::twa_ptr& tg)
|
||||
{
|
||||
auto s = stats_reachable(tg);
|
||||
|
||||
std::cout << std::left << std::setw(20) << title << " | "
|
||||
<< std::right << std::setw(6) << s.states << " | "
|
||||
<< std::setw(6) << s.edges << " | "
|
||||
<< std::setw(6) << "XXX" << '\n';
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
syntax(argv[0]);
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
std::cerr << "failed to open " << argv[1] << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
auto d = spot::make_bdd_dict();
|
||||
|
||||
std::string s;
|
||||
while (std::getline(input, s))
|
||||
{
|
||||
std::cout << "in: " << s << '\n';
|
||||
if (s.empty() || s[0] == '#') // Skip comments
|
||||
continue;
|
||||
|
||||
spot::parse_error_list pe;
|
||||
auto f = spot::parse_infix_psl(s, pe);
|
||||
|
||||
if (spot::format_parse_errors(std::cerr, s, pe))
|
||||
return 2;
|
||||
|
||||
|
||||
{
|
||||
auto a = ltl_to_tgba_fm(f, d);
|
||||
bdd ap_set = atomic_prop_collect_as_bdd(f, a);
|
||||
|
||||
// run 0 ../ikwiad -TGTA -ks "$1"
|
||||
// run 0 ../ikwiad -TGTA -RT -ks "$1"
|
||||
{
|
||||
auto t = spot::tgba_to_tgta(a, ap_set);
|
||||
stats("-TGTA", t);
|
||||
stats("-TGTA -RT", minimize_tgta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -ks "$1"
|
||||
// run 0 ../ikwiad -TA -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
false, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
false, // single_pass (-sp),
|
||||
false); // artificial_livelock (-lv)
|
||||
stats("-TA", t);
|
||||
stats("-TA -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -lv -ks "$1"
|
||||
// run 0 ../ikwiad -TA -lv -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
false, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
false, // single_pass (-sp),
|
||||
true); // artificial_livelock (-lv)
|
||||
stats("-TA -lv", t);
|
||||
stats("-TA -lv -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -sp -ks "$1"
|
||||
// run 0 ../ikwiad -TA -sp -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
false, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
true, // single_pass (-sp),
|
||||
false); // artificial_livelock (-lv)
|
||||
stats("-TA -sp", t);
|
||||
stats("-TA -sp -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -lv -sp -ks "$1"
|
||||
// run 0 ../ikwiad -TA -lv -sp -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
false, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
true, // single_pass (-sp),
|
||||
true); // artificial_livelock (-lv)
|
||||
stats("-TA -lv -sp", t);
|
||||
stats("-TA -lv -sp -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
a = spot::degeneralize(a);
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -DS -ks "$1"
|
||||
// run 0 ../ikwiad -TA -DS -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
true, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
false, // single_pass (-sp),
|
||||
false); // artificial_livelock (-lv)
|
||||
stats("-TA -DS", t);
|
||||
stats("-TA -DS -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -DS -lv -ks "$1"
|
||||
// run 0 ../ikwiad -TA -DS -lv -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
true, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
false, // single_pass (-sp),
|
||||
true); // artificial_livelock (-lv)
|
||||
stats("-TA -DS -lv", t);
|
||||
stats("-TA -DS -lv -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -DS -sp -ks "$1"
|
||||
// run 0 ../ikwiad -TA -DS -sp -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
true, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
true, // single_pass (-sp),
|
||||
false); // artificial_livelock (-lv)
|
||||
stats("-TA -DS -sp", t);
|
||||
stats("-TA -DS -sp -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -TA -DS -lv -sp -ks "$1"
|
||||
// run 0 ../ikwiad -TA -DS -lv -sp -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
true, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
true, // single_pass (-sp),
|
||||
true); // artificial_livelock (-lv)
|
||||
stats("-TA -DS -lv -sp", t);
|
||||
stats("-TA -DS -lv -sp -RT", minimize_ta(t));
|
||||
}
|
||||
}
|
||||
// Some cases with -x -R3 -DS -in
|
||||
{
|
||||
auto a = spot::degeneralize(scc_filter(ltl_to_tgba_fm(f, d, true)));
|
||||
bdd ap_set = atomic_prop_collect_as_bdd(f, a);
|
||||
|
||||
{
|
||||
// run 0 ../ikwiad -x -R3 -DS -TA -in -ks "$1"
|
||||
// run 0 ../ikwiad -x -R3 -DS -TA -in -RT -ks "$1"
|
||||
auto t = spot::tgba_to_ta(a, ap_set,
|
||||
true, // degen (-DS)
|
||||
false, // artificial_initial_state (-in)
|
||||
false, // single_pass (-sp),
|
||||
true); // artificial_livelock (-lv)
|
||||
stats("-x -TA -DS -in", t);
|
||||
stats("-x -TA -DS -in -RT", minimize_ta(t));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
assert(spot::fnode::instances_check());
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
autfilt=../../bin/autfilt
|
||||
ltl2tgba=../../bin/ltl2tgba
|
||||
randaut=../../bin/randaut
|
||||
|
||||
$randaut -H -A 'random 0..4' -Q1..10 -D -n 50 0..2 >aut
|
||||
run 0 $autfilt --complement -H aut >/dev/null
|
||||
|
||||
cat >in <<EOF
|
||||
HOA: v1
|
||||
States: 0
|
||||
Acceptance: 0 t
|
||||
--BODY--
|
||||
--END--
|
||||
EOF
|
||||
$autfilt --complement -H in >out
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: all
|
||||
Acceptance: 0 t
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 0
|
||||
--END--
|
||||
EOF
|
||||
diff out expected
|
||||
|
||||
|
||||
$ltl2tgba -H 'GFa & GFb' Xa | $autfilt --complement -H >out
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: generalized-co-Buchi 2
|
||||
Acceptance: 2 Fin(0)|Fin(1)
|
||||
properties: trans-labels explicit-labels trans-acc complete
|
||||
properties: deterministic stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&1] 0 {0 1}
|
||||
[!0&!1] 0
|
||||
[!0&1] 0 {1}
|
||||
[0&!1] 0 {0}
|
||||
--END--
|
||||
HOA: v1
|
||||
States: 4
|
||||
Start: 1
|
||||
AP: 1 "a"
|
||||
acc-name: co-Buchi
|
||||
Acceptance: 1 Fin(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic terminal
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 2
|
||||
[!0] 3
|
||||
State: 1
|
||||
[t] 0
|
||||
State: 2 {0}
|
||||
[t] 2
|
||||
State: 3
|
||||
[t] 3
|
||||
--END--
|
||||
EOF
|
||||
diff out expected
|
||||
|
||||
|
||||
$ltl2tgba -H 'FGa' | $autfilt --complement 2>out && exit 1
|
||||
grep 'deterministic' out
|
||||
|
|
@ -1,258 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire
|
||||
// de Recherche et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/hoa.hh>
|
||||
#include <spot/parseaut/public.hh>
|
||||
#include <spot/twa/twaproduct.hh>
|
||||
#include <spot/twaalgos/gtec/gtec.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/tl/parse.hh>
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include <spot/twaalgos/emptiness.hh>
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include <spot/twaalgos/emptiness_stats.hh>
|
||||
#include <spot/twaalgos/degen.hh>
|
||||
|
||||
#include <spot/twa/twasafracomplement.hh>
|
||||
|
||||
static void usage(const char* prog)
|
||||
{
|
||||
std::cout << "usage: " << prog << " [options]" << std::endl;
|
||||
std::cout << "with options" << std::endl
|
||||
<< "-H Output in HOA\n"
|
||||
<< "-s buchi_automaton display the safra automaton\n"
|
||||
<< "-a buchi_automaton display the complemented automaton\n"
|
||||
<< "-astat buchi_automaton statistics for !a\n"
|
||||
<< "-fstat formula statistics for !A_f\n"
|
||||
<< "-f formula test !A_f and !A_!f\n"
|
||||
<< "-p formula print the automaton for f\n";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char *file = nullptr;
|
||||
bool print_safra = false;
|
||||
bool print_automaton = false;
|
||||
//bool check = false;
|
||||
int return_value = 0;
|
||||
bool stats = false;
|
||||
bool formula = false;
|
||||
bool print_formula = false;
|
||||
bool save_hoa = false;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (strcmp(argv[i] + 1, "H") == 0)
|
||||
{
|
||||
save_hoa = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(argv[i] + 1, "astat") == 0)
|
||||
{
|
||||
stats = true;
|
||||
formula = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(argv[i] + 1, "fstat") == 0)
|
||||
{
|
||||
stats = true;
|
||||
formula = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case 's':
|
||||
print_safra = true; break;
|
||||
case 'a':
|
||||
print_automaton = true; break;
|
||||
case 'f':
|
||||
//check = true;
|
||||
break;
|
||||
case 'p':
|
||||
print_formula = true; break;
|
||||
default:
|
||||
std::cerr << "unrecognized option `-" << argv[i][1]
|
||||
<< '\'' << std::endl;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
file = argv[i];
|
||||
}
|
||||
|
||||
if (!file)
|
||||
{
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto dict = spot::make_bdd_dict();
|
||||
if (print_automaton || print_safra)
|
||||
{
|
||||
spot::environment& env(spot::default_environment::instance());
|
||||
auto h = spot::parse_aut(file, dict, env);
|
||||
if (h->format_errors(std::cerr))
|
||||
return 2;
|
||||
spot::twa_graph_ptr a = h->aut;
|
||||
|
||||
spot::twa_ptr complement = nullptr;
|
||||
|
||||
complement = spot::make_safra_complement(a);
|
||||
|
||||
if (print_automaton)
|
||||
{
|
||||
if (save_hoa)
|
||||
spot::print_hoa(std::cout, complement, nullptr);
|
||||
else
|
||||
spot::print_dot(std::cout, complement);
|
||||
}
|
||||
|
||||
if (print_safra)
|
||||
{
|
||||
auto safra_complement =
|
||||
std::dynamic_pointer_cast<spot::tgba_safra_complement>(complement);
|
||||
spot::display_safra(safra_complement);
|
||||
}
|
||||
}
|
||||
else if (print_formula)
|
||||
{
|
||||
spot::parse_error_list p1;
|
||||
auto f1 = spot::parse_infix_psl(file, p1);
|
||||
|
||||
if (spot::format_parse_errors(std::cerr, file, p1))
|
||||
return 2;
|
||||
|
||||
auto a = spot::ltl_to_tgba_fm(f1, dict);
|
||||
spot::twa_ptr complement = nullptr;
|
||||
complement = spot::make_safra_complement(a);
|
||||
|
||||
spot::print_dot(std::cout, complement);
|
||||
}
|
||||
else if (stats)
|
||||
{
|
||||
spot::twa_graph_ptr a;
|
||||
spot::formula f1 = nullptr;
|
||||
|
||||
if (formula)
|
||||
{
|
||||
spot::parse_error_list p1;
|
||||
f1 = spot::parse_infix_psl(file, p1);
|
||||
|
||||
if (spot::format_parse_errors(std::cerr, file, p1))
|
||||
return 2;
|
||||
|
||||
a = spot::ltl_to_tgba_fm(f1, dict);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto h = spot::parse_aut(file, dict);
|
||||
if (h->format_errors(std::cerr))
|
||||
return 2;
|
||||
a = h->aut;
|
||||
}
|
||||
|
||||
auto safra_complement = spot::make_safra_complement(a);
|
||||
|
||||
spot::twa_statistics a_size = spot::stats_reachable(a);
|
||||
std::cout << "Original: "
|
||||
<< a_size.states << ", "
|
||||
<< a_size.edges << ", "
|
||||
<< a->acc().num_sets()
|
||||
<< std::endl;
|
||||
|
||||
auto buchi = spot::degeneralize(a);
|
||||
std::cout << "Buchi: "
|
||||
<< buchi->num_states()
|
||||
<< buchi->num_edges()
|
||||
<< buchi->acc().num_sets()
|
||||
<< std::endl;
|
||||
|
||||
spot::twa_statistics b_size = spot::stats_reachable(safra_complement);
|
||||
std::cout << "Safra Complement: "
|
||||
<< b_size.states << ", "
|
||||
<< b_size.edges << ", "
|
||||
<< safra_complement->acc().num_sets()
|
||||
<< std::endl;
|
||||
|
||||
if (formula)
|
||||
{
|
||||
auto a2 = spot::ltl_to_tgba_fm(spot::formula::Not(f1), dict);
|
||||
spot::twa_statistics a_size = spot::stats_reachable(a2);
|
||||
std::cout << "Not Formula: "
|
||||
<< a_size.states << ", "
|
||||
<< a_size.edges << ", "
|
||||
<< a2->acc().num_sets()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spot::parse_error_list p1;
|
||||
auto f1 = spot::parse_infix_psl(file, p1);
|
||||
|
||||
if (spot::format_parse_errors(std::cerr, file, p1))
|
||||
return 2;
|
||||
|
||||
auto Af = spot::ltl_to_tgba_fm(f1, dict);
|
||||
auto nf1 = spot::formula::Not(f1);
|
||||
auto Anf = spot::ltl_to_tgba_fm(nf1, dict);
|
||||
auto nAf = spot::make_safra_complement(Af);
|
||||
auto nAnf = spot::make_safra_complement(Anf);
|
||||
auto ec = spot::couvreur99(spot::otf_product(nAf, nAnf));
|
||||
auto res = ec->check();
|
||||
spot::twa_statistics a_size = spot::stats_reachable(ec->automaton());
|
||||
std::cout << "States: "
|
||||
<< a_size.states << std::endl
|
||||
<< "Transitions: "
|
||||
<< a_size.edges << std::endl
|
||||
<< "Acc Cond: "
|
||||
<< ec->automaton()->acc().num_sets()
|
||||
<< std::endl;
|
||||
if (res)
|
||||
{
|
||||
std::cout << "FAIL\n";
|
||||
return_value = 1;
|
||||
if (auto run = res->accepting_run())
|
||||
{
|
||||
spot::print_dot(std::cout, ec->automaton());
|
||||
std::cout << run;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "OK\n";
|
||||
}
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2011, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
while read f; do
|
||||
run 0 ../complement -f "$f"
|
||||
done <<EOF
|
||||
GFa
|
||||
FGa
|
||||
<>p1->p0
|
||||
<>p1->(p0 U p1)
|
||||
[](p0-><>p3)
|
||||
a U b
|
||||
GFa&&FGa
|
||||
[] ((p2 && ! p1) -> (p0 U (p1 || [] p0)))
|
||||
[] (p2 -> ((! p0 && ! p1) U (p1 || ((p0 && ! p1) U (p1 || ((! p0 && ! p1) \
|
||||
U (p1 || ((p0 && ! p1) U ((p1 || (! p0 U (p1 || [] ! p0))) || [] p0)))))))))
|
||||
EOF
|
||||
|
||||
# The following test-case was supplied by Martin Dieguez Lodeiro to
|
||||
# demonstrate a bug in our Safra implementation.
|
||||
cat >x.hoa <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 1 "p"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc complete
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[t] 1
|
||||
[0] 2 {0}
|
||||
State: 2
|
||||
[t] 1
|
||||
[0] 2 {0}
|
||||
--END--
|
||||
EOF
|
||||
# x.tgba accepts some run
|
||||
run 0 ../ikwiad -XH -e x.hoa
|
||||
# so does its complement
|
||||
run 0 ../complement -H -a x.hoa > nx.hoa
|
||||
run 0 ../ikwiad -XH -e nx.hoa
|
||||
# however the intersection of both should not
|
||||
# accept any run.
|
||||
run 1 ../../bin/autfilt -q nx.hoa --intersect x.hoa
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
#! /bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs || exit 1
|
||||
|
||||
set -e
|
||||
|
||||
cat >automaton <<EOF
|
||||
HOA: v1
|
||||
States: 2
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
Acceptance: 1 Fin(0)
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[0] 1
|
||||
--END--
|
||||
HOA: v1
|
||||
States: 2
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
Acceptance: 2 t
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[0] 1
|
||||
--END--
|
||||
HOA: v1
|
||||
States: 2
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
Acceptance: 0 f
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[0] 1
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: co-Buchi
|
||||
Acceptance: 1 Fin(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
[!0] 2
|
||||
State: 1
|
||||
[0] 1
|
||||
[!0] 2
|
||||
State: 2 {0}
|
||||
[t] 2
|
||||
--END--
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0] 1
|
||||
[!0] 2
|
||||
State: 1 {0}
|
||||
[0] 1
|
||||
[!0] 2
|
||||
State: 2
|
||||
[t] 2
|
||||
--END--
|
||||
HOA: v1
|
||||
States: 2
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: none
|
||||
Acceptance: 0 f
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
properties: deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
[!0] 1
|
||||
State: 1
|
||||
[0] 1
|
||||
[!0] 1
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt -CH automaton >out
|
||||
cat out
|
||||
diff out expected
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2010, 2011, 2012, 2015 Laboratoire de Recherche et
|
||||
// Dévelopement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <spot/tl/parse.hh>
|
||||
|
||||
static void
|
||||
syntax(char *prog)
|
||||
{
|
||||
std::cerr << prog << " formula" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
syntax(argv[0]);
|
||||
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
std::cerr << "failed to open " << argv[1] << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::string s;
|
||||
while (std::getline(input, s))
|
||||
{
|
||||
if (s[0] == '#') // Skip comments
|
||||
{
|
||||
std::cerr << s << '\n';
|
||||
continue;
|
||||
}
|
||||
std::istringstream ss(s);
|
||||
std::string form;
|
||||
bool expected;
|
||||
std::getline(ss, form, ',');
|
||||
ss >> expected;
|
||||
|
||||
spot::parse_error_list p1;
|
||||
auto f1 = spot::parse_infix_sere(form, p1);
|
||||
if (spot::format_parse_errors(std::cerr, form, p1))
|
||||
return 2;
|
||||
|
||||
bool b = f1.accepts_eword();
|
||||
std::cout << form << ',' << b << '\n';
|
||||
if (b != expected)
|
||||
{
|
||||
std::cerr << "computed '" << b
|
||||
<< "' but expected '" << expected << "'\n";
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
assert(spot::fnode::instances_check());
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#! /bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2010, 2015 Laboratoire de Recherche et Devéloppement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# Check for the constant_term visitor
|
||||
|
||||
. ./defs || exit 1
|
||||
|
||||
set -e
|
||||
|
||||
cat >input2 <<EOF
|
||||
1,0
|
||||
0,0
|
||||
[*0],1
|
||||
a*,1
|
||||
0*,1
|
||||
a[*0],1
|
||||
a[*0..],1
|
||||
a[*0..3],1
|
||||
a[*1..3],0
|
||||
a[*3],0
|
||||
a[*..4][*3],1
|
||||
a[*1..4][*3],0
|
||||
a[*1..4][*0..3],1
|
||||
((a ; b) + c),0
|
||||
((a ; b) + [*0]),1
|
||||
((a ; b) + [*0]) & e,0
|
||||
((a ; b) + [*0]) & [*0],1
|
||||
((a ; b) + [*0]) & (a* + b),1
|
||||
# test braces
|
||||
{{a ; b} + {[*0]}} & {a* + b},1
|
||||
(a + [*0]);(b + [*0]);(c + [*0]),1
|
||||
(a + [*0]);(b + e);(c + [*0]),0
|
||||
(a + [*0]);(b + e)*;(c + [*0]),1
|
||||
EOF
|
||||
|
||||
run 0 ../consterm input2
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2012, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
set -e
|
||||
|
||||
# Fig.1 from Johnson's SIAM J. Comput. 1975 paper.
|
||||
cat >johnson-fig1.hoa <<EOF
|
||||
HOA: v1
|
||||
States: 12
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: all
|
||||
Acceptance: 0 t
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
[t] 3
|
||||
[t] 4
|
||||
State: 1
|
||||
[t] 2
|
||||
State: 2
|
||||
[t] 5
|
||||
[t] 6
|
||||
State: 3
|
||||
[t] 2
|
||||
State: 4
|
||||
[t] 2
|
||||
State: 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
State: 6
|
||||
[t] 8
|
||||
[t] 10
|
||||
[t] 11
|
||||
State: 7
|
||||
[t] 0
|
||||
[t] 6
|
||||
State: 8
|
||||
[t] 2
|
||||
[t] 9
|
||||
State: 9
|
||||
[t] 6
|
||||
State: 10
|
||||
[t] 9
|
||||
State: 11
|
||||
[t] 9
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -KC -XH johnson-fig1.hoa > out
|
||||
test `wc -l < out` -eq 10
|
||||
|
||||
run 0 ../ikwiad -KW '(Ga -> Gb) W c' > out
|
||||
test `grep 'is weak' out | wc -l` -eq 4
|
||||
test `grep 'is not weak' out | wc -l` -eq 1
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
set -e
|
||||
|
||||
# This automaton used to trigger a bug in the complementation: its
|
||||
# intersection with the complement was not empty!
|
||||
cat >input.hoa <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 4 "a" "d" "b" "c"
|
||||
acc-name: generalized-Buchi 3
|
||||
Acceptance: 3 Inf(0)&Inf(1)&Inf(2)
|
||||
properties: trans-labels explicit-labels trans-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&1 | 0&2] 0 {1 2}
|
||||
[!0&1 | !0&2] 0 {0 1 2}
|
||||
[0&!1&!2&!3] 1
|
||||
[!0&!1&!2&!3] 1 {0}
|
||||
State: 1
|
||||
[0&2&3] 0 {1 2}
|
||||
[!0&2&3] 0 {0 1 2}
|
||||
[0&!2&!3] 1
|
||||
[!0&!2&!3] 1 {0}
|
||||
[0&2&!3] 2 {1}
|
||||
[!0&2&!3] 2 {0 1}
|
||||
State: 2
|
||||
[0&1&3 | 0&2&3] 0 {1 2}
|
||||
[!0&1&3 | !0&2&3] 0 {0 1 2}
|
||||
[0&!1&!2&!3] 1
|
||||
[!0&!1&!2&!3] 1 {0}
|
||||
[0&1&!3 | 0&2&!3] 2 {1}
|
||||
[!0&1&!3 | !0&2&!3] 2 {0 1}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
# Check emptiness of product with complement.
|
||||
run 0 ../ikwiad -H -DC -C -XH input.hoa > output.hoa
|
||||
run 1 ../../bin/autfilt -q input.hoa --intersect output.hoa
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
# -*- mode: shell-script; coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2010, 2012, 2013, 2015 Laboratoire de Recherche
|
||||
# et Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
# et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Ensure we are running from the right directory.
|
||||
test -f ./defs || {
|
||||
echo "defs: not found in current directory" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# If srcdir is not set, then we are not running from `make check'.
|
||||
if test -z "$srcdir"; then
|
||||
# compute $srcdir.
|
||||
srcdir=`echo "$0" | sed -e 's,/[^\\/]*$,,'`
|
||||
test $srcdir = $0 && srcdir=.
|
||||
fi
|
||||
|
||||
# Ensure $srcdir is set correctly.
|
||||
test -f $srcdir/defs.in || {
|
||||
echo "$srcdir/defs.in not found, check \$srcdir" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "== Running test $0"
|
||||
|
||||
me=`echo "$0" | sed -e 's,.*[\\/],,;s/\.test$//'`
|
||||
|
||||
testSubDir=$me.dir
|
||||
chmod -R a+rwx $testSubDir > /dev/null 2>&1
|
||||
rm -rf $testSubDir > /dev/null 2>&1
|
||||
mkdir $testSubDir
|
||||
cd $testSubDir
|
||||
|
||||
# Adjust srcdir now that we are in a subdirectory. We still want
|
||||
# $srcdir to point to the source directory corresponding to the build
|
||||
# directory that contains $testSubDir.
|
||||
case $srcdir in
|
||||
[\\/$]* | ?:[\\/]* );;
|
||||
*) srcdir=../$srcdir
|
||||
esac
|
||||
|
||||
DOT='@DOT@'
|
||||
top_builddir='../@top_builddir@'
|
||||
LBTT="@LBTT@"
|
||||
LBTT_TRANSLATE="@LBTT_TRANSLATE@"
|
||||
VALGRIND='@VALGRIND@'
|
||||
SPIN='@SPIN@'
|
||||
LTL2BA='@LTL2BA@'
|
||||
PYTHON='@PYTHON@'
|
||||
top_srcdir='../@top_srcdir@'
|
||||
|
||||
# The test cases assume these variable are undefined
|
||||
unset SPOT_DOTEXTRA
|
||||
unset SPOT_DOTDEFAULT
|
||||
|
||||
need_lbtt()
|
||||
{
|
||||
# LBTT may not have been installed or compiled.
|
||||
("$LBTT" --version) || exit 77
|
||||
}
|
||||
|
||||
run()
|
||||
{
|
||||
expected_exitcode=$1
|
||||
shift
|
||||
exitcode=0
|
||||
if test -n "$VALGRIND"; then
|
||||
exec 6>valgrind.err
|
||||
GLIBCPP_FORCE_NEW=1 \
|
||||
../../../libtool --mode=execute \
|
||||
$VALGRIND --tool=memcheck --leak-check=yes --log-fd=6 -q "$@" ||
|
||||
exitcode=$?
|
||||
cat valgrind.err 1>&2
|
||||
test -z "`sed 1q valgrind.err`" || exit 50
|
||||
rm -f valgrind.err
|
||||
else
|
||||
"$@" || exitcode=$?
|
||||
fi
|
||||
test $exitcode = $expected_exitcode || exit 1
|
||||
}
|
||||
|
||||
set -x
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2011, 2015 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
# The following command, reported by Tomáš Babiak, used to output many
|
||||
# different automata, because state addresses were used to order the
|
||||
# successors in the degeneralization.
|
||||
|
||||
# Make sure all these runs output the same automaton.
|
||||
|
||||
# With valgrind
|
||||
run 0 ../ikwiad -r7 -x -R3 -N "XF(Gp2 | F(p0 U (p1 & (! p4 | p3))))" > out1
|
||||
# Without valgrind
|
||||
for i in 2 3 4 5; do
|
||||
../ikwiad -r7 -x -R3 -N "XF(Gp2 | F(p0 U (p1 & (! p4 | p3))))" > out
|
||||
cmp out out1 || exit 1
|
||||
done
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2011, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
# Make sure degeneralization is idempotent
|
||||
|
||||
for f in 'FGa|GFb' 'GFa & GFb & GFc' 'GF(a->FGb)&GF(c->FGd)'; do
|
||||
for opt in -DS -DT; do
|
||||
../ikwiad $opt -H "$f" > autX.spot
|
||||
../ikwiad -XH -kt autX.spot > base.size
|
||||
cat base.size
|
||||
for x in X XX XXX; do
|
||||
../ikwiad -XH $opt -H aut$x.spot > autX$x.spot
|
||||
../ikwiad -XH -kt autX$x.spot > new.size
|
||||
cat new.size
|
||||
cmp base.size new.size
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
# This is another 6-state degeneralized automaton that
|
||||
# we used the "redegeneralize" to a 8-state BA...
|
||||
cat > bug <<EOF
|
||||
HOA: v1
|
||||
States: 6
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[!0 | !1] 1
|
||||
[0&1] 2
|
||||
State: 1 {0}
|
||||
[!0&1] 1
|
||||
[!0&!1] 3
|
||||
[0] 4
|
||||
State: 2
|
||||
[0&!1] 0
|
||||
[!0&!1] 1
|
||||
[0&1] 2
|
||||
[!0&1] 5
|
||||
State: 3
|
||||
[0&1] 0
|
||||
[!0&1] 1
|
||||
[!0&!1] 3
|
||||
[0&!1] 4
|
||||
State: 4
|
||||
[1] 0
|
||||
[0&!1] 2
|
||||
[!0&!1] 5
|
||||
State: 5
|
||||
[!1] 0
|
||||
[!0&1] 3
|
||||
[0&1] 4
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -ks -XH -DS bug > out
|
||||
grep 'states: 6' out
|
||||
|
||||
|
||||
# This 8-state degeneralized automaton used
|
||||
# to be "degeneralized" to a 9-state BA...
|
||||
cat > bug2 <<EOF
|
||||
HOA: v1
|
||||
States: 8
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
State: 1 {0}
|
||||
[t] 2
|
||||
State: 2
|
||||
[0&!1] 2
|
||||
[0&1] 3
|
||||
[!0&!1] 4
|
||||
[!0&1] 5
|
||||
State: 3 {0}
|
||||
[0] 2
|
||||
[!0] 4
|
||||
State: 4
|
||||
[0&!1] 2
|
||||
[0&1] 3
|
||||
[!0&1] 5
|
||||
[!0&!1] 6
|
||||
State: 5 {0}
|
||||
[0&!1] 2
|
||||
[0&1] 3
|
||||
[!0&1] 5
|
||||
[!0&!1] 6
|
||||
State: 6
|
||||
[0&!1] 2
|
||||
[0&1] 3
|
||||
[!0&!1] 6
|
||||
[!0&1] 7
|
||||
State: 7
|
||||
[0] 3
|
||||
[!0] 7
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -ks -XH -DS bug2 >out
|
||||
grep 'states: 8' out
|
||||
|
||||
|
||||
# This automaton should have a 3-state BA, but it's really
|
||||
# easy to obtain a 4-state BA when tweaking the degeneralization
|
||||
# to ignore arc entering an SCC.
|
||||
test 3 = "`../../bin/ltl2tgba -B 'G(a|G(b|Fc))' --stats=%s`"
|
||||
|
||||
|
||||
# This 7-state DRA (built with
|
||||
# ltlfilt -f 'F(a & GFb) | (Fc & Fa & F(c & GF!b))' -l |
|
||||
# ltl2dstar --ltl2nba=spin:ltl2tgba@-sD - -
|
||||
# should be converted in into a 5-state DBA.
|
||||
cat >in.dra <<EOF
|
||||
DRA v2 explicit
|
||||
Comment: "Union{Safra[NBA=3],Safra[NBA=5]}"
|
||||
States: 7
|
||||
Acceptance-Pairs: 2
|
||||
Start: 5
|
||||
AP: 3 "a" "b" "c"
|
||||
---
|
||||
State: 0
|
||||
Acc-Sig: +0 +1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
State: 1
|
||||
Acc-Sig: +1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
State: 2
|
||||
Acc-Sig: +0
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
State: 3
|
||||
Acc-Sig: +0
|
||||
6
|
||||
6
|
||||
3
|
||||
3
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
State: 4
|
||||
Acc-Sig:
|
||||
4
|
||||
0
|
||||
4
|
||||
0
|
||||
4
|
||||
0
|
||||
4
|
||||
0
|
||||
State: 5
|
||||
Acc-Sig:
|
||||
5
|
||||
3
|
||||
5
|
||||
3
|
||||
4
|
||||
0
|
||||
4
|
||||
0
|
||||
State: 6
|
||||
Acc-Sig:
|
||||
6
|
||||
6
|
||||
3
|
||||
3
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/dstar2tgba in.dra -BD --stats=%s > out.stat
|
||||
test 5 = "`cat out.stat`"
|
||||
|
||||
# Only one state should be accepting. In spot 1.2.x an initial state
|
||||
# in a trivial SCC was marked as accepting: this is superfluous.
|
||||
../../bin/ltl2tgba -BH 'a & GFb & GFc' > out
|
||||
cat out
|
||||
cat >expected<<EOF
|
||||
HOA: v1
|
||||
name: "a & G(Fb & Fc)"
|
||||
States: 4
|
||||
Start: 0
|
||||
AP: 3 "a" "b" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
properties: stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1 {0}
|
||||
[1&2] 1
|
||||
[!1&2] 2
|
||||
[!2] 3
|
||||
State: 2
|
||||
[1] 1
|
||||
[!1] 2
|
||||
State: 3
|
||||
[1&2] 1
|
||||
[!1&2] 2
|
||||
[!2] 3
|
||||
--END--
|
||||
EOF
|
||||
diff out expected
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
# Make sure degen-skip=0 and degen-skip=1 produce the expected
|
||||
# automata for 'GFa & GFb'
|
||||
|
||||
../../bin/ltl2tgba -B 'GFa & GFb' --hoa > out1
|
||||
../../bin/ltl2tgba -B -x degen-lskip=1 'GFa & GFb' --hoa > out2
|
||||
../../bin/ltl2tgba -B -x degen-lskip=0 'GFa & GFb' --hoa > out3
|
||||
../../bin/ltl2tgba -B -x degen-lskip=1,degen-lowinit=1 'GFa & GFb' --hoa > out4
|
||||
../../bin/ltl2tgba -B -x degen-lskip=0,degen-lowinit=1 'GFa & GFb' --hoa > out5
|
||||
|
||||
diff out1 out2
|
||||
cmp out2 out3 && exit 1
|
||||
|
||||
cat <<EOF >expected2
|
||||
HOA: v1
|
||||
name: "G(Fa & Fb)"
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0&1] 0
|
||||
[!1] 1
|
||||
[!0&1] 2
|
||||
State: 1
|
||||
[0&1] 0
|
||||
[!1] 1
|
||||
[!0&1] 2
|
||||
State: 2
|
||||
[0] 0
|
||||
[!0] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
|
||||
cat <<EOF >expected3
|
||||
HOA: v1
|
||||
name: "G(Fa & Fb)"
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 1
|
||||
State: 1
|
||||
[!1] 1
|
||||
[1] 2
|
||||
State: 2
|
||||
[0] 0
|
||||
[!0] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat <<EOF >expected4
|
||||
HOA: v1
|
||||
name: "G(Fa & Fb)"
|
||||
States: 3
|
||||
Start: 1
|
||||
AP: 2 "a" "b"
|
||||
Acceptance: 1 Inf(0)
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0&1] 0
|
||||
[!1] 1
|
||||
[!0&1] 2
|
||||
State: 1
|
||||
[0&1] 0
|
||||
[!1] 1
|
||||
[!0&1] 2
|
||||
State: 2
|
||||
[0] 0
|
||||
[!0] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat <<EOF >expected5
|
||||
HOA: v1
|
||||
name: "G(Fa & Fb)"
|
||||
States: 3
|
||||
Start: 2
|
||||
AP: 2 "a" "b"
|
||||
Acceptance: 1 Inf(0)
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 2
|
||||
State: 1
|
||||
[0] 0
|
||||
[!0] 1
|
||||
State: 2
|
||||
[1] 1
|
||||
[!1] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
|
||||
run 0 ../../bin/autfilt -q -F out2 --isomorph expected2
|
||||
run 0 ../../bin/autfilt -q -F out3 --isomorph expected3
|
||||
|
||||
cat out4 out5
|
||||
|
||||
../../bin/autfilt -q out4 --isomorph expected2 && exit 1
|
||||
../../bin/autfilt -q out5 --isomorph expected3 && exit 1
|
||||
|
||||
../../bin/autfilt -q out4 --isomorph expected4
|
||||
../../bin/autfilt -q out5 --isomorph expected5
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
set -e
|
||||
|
||||
ltl2tgba=../../bin/ltl2tgba
|
||||
|
||||
cat >formulas <<'EOF'
|
||||
1,13,X((a M F((!b & !c) | (b & c))) W (G!c U b))
|
||||
1,5,X(((a & b) R (!a U !c)) R b)
|
||||
1,9,XXG(Fa U Xb)
|
||||
1,5,(!a M !b) W F!c
|
||||
1,3,(b & Fa & GFc) R a
|
||||
1,2,(a R (b W a)) W G(!a M (b | c))
|
||||
1,11,(Fa W b) R (!a | Fc)
|
||||
1,7,X(G(!a M !b) | G(a | G!a))
|
||||
1,2,Fa W Gb
|
||||
1,3,Ga | GFb
|
||||
1,9,G((G!a & ((!b & X!c) | (b & Xc))) | (Fa & ((!b & Xc) | (b & X!c))))
|
||||
1,5,a M G(F!b | X!a)
|
||||
1,4,G!a R XFb
|
||||
1,4,XF(!a | GFb)
|
||||
1,6,G(F!a U !a) U Xa
|
||||
1,5,(a | G(a M !b)) W Fc
|
||||
1,6,Fa W Xb
|
||||
1,10,X(a R ((!b & F!c) M X!a))
|
||||
1,2,XG!a R Fb
|
||||
1,4,GFc | (a & Fb)
|
||||
1,6,X(a R (Fb R F!b))
|
||||
1,2,G(Xa M Fa)
|
||||
1,4,X(Gb | GFa)
|
||||
1,9,X(Gc | XG((b & Ga) | (!b & F!a)))
|
||||
1,2,Ga R Fb
|
||||
1,3,G(a U (b | X((!a & !c) | (a & c))))
|
||||
1,5,XG((G!a & F!b) | (Fa & (a | Gb)))
|
||||
1,10,(a U X!a) | XG(!b & XFc)
|
||||
1,4,X(G!a | GFa)
|
||||
1,4,G(G!a | F!c | G!b)
|
||||
EOF
|
||||
|
||||
$ltl2tgba -x tba-det --det --stats '%d,%s,%f' -F formulas/3 > out
|
||||
diff formulas out
|
||||
|
||||
cat >in.hoa <<'EOF'
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 0
|
||||
[0] 1 {0}
|
||||
State: 1
|
||||
[!0] 0
|
||||
[0] 2 {0}
|
||||
State: 2
|
||||
[!0] 0
|
||||
[0] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >ex.hoa <<'EOF'
|
||||
HOA: v1
|
||||
States: 5
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc inherently-weak
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 0
|
||||
[0] 1
|
||||
[!0] 3
|
||||
State: 1
|
||||
[!0] 0
|
||||
[0] 2
|
||||
[!0] 3
|
||||
State: 2
|
||||
[!0] 0
|
||||
[0] 2
|
||||
[!0] 3
|
||||
[0] 4
|
||||
State: 3 {0}
|
||||
[!0] 3
|
||||
State: 4 {0}
|
||||
[!0] 3
|
||||
[0] 4
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -H -DC -XH in.hoa > out.hoa
|
||||
run 1 ../../bin/autfilt -q --are-isomorph in.hoa out.hoa
|
||||
run 0 ../../bin/autfilt -q --are-isomorph ex.hoa out.hoa
|
||||
|
||||
run 0 ../ikwiad -x -DC 'GFa & XGFb' > out.tgba
|
||||
cat >ex.tgba <<EOF
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 0
|
||||
0 [label="0"]
|
||||
0 -> 1 [label="1"]
|
||||
1 [label="1"]
|
||||
1 -> 1 [label="1"]
|
||||
1 -> 2 [label="!a"]
|
||||
1 -> 3 [label="!b"]
|
||||
2 [label="2", peripheries=2]
|
||||
2 -> 2 [label="!a"]
|
||||
3 [label="3", peripheries=2]
|
||||
3 -> 3 [label="!b"]
|
||||
}
|
||||
EOF
|
||||
diff out.tgba ex.tgba
|
||||
|
||||
|
||||
# This formula produce a co-deterministic automaton that is not deterministic,
|
||||
# and a bug in the cosimulation caused the result to be marked as deterministic.
|
||||
run 0 ../../bin/ltl2tgba -H '(0 R Xa) R (a xor Fa)' > out.hoa
|
||||
grep deterministic out.hoa && exit 1
|
||||
|
||||
|
||||
# These highlighted a bug in the bitvector routines because their
|
||||
# state count is a multiple of 64.
|
||||
cat >input <<EOF
|
||||
G(!a | Xa),2
|
||||
G(!a | XXa),4
|
||||
G(!a | XXXa),8
|
||||
G(!a | XXXXa),16
|
||||
G(!a | XXXXXa),32
|
||||
G(!a | XXXXXXa),64
|
||||
G(!a | XXXXXXXa),128
|
||||
G(!a | XXXXXXXXa),256
|
||||
EOF
|
||||
run 0 ../../bin/ltl2tgba -D -F input/1 --stats='%f,%s' > output
|
||||
cat output
|
||||
diff input output
|
||||
|
||||
true
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2010, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
||||
# Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
# Université Pierre et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
# All examples are TBA (i.e. they have a unique
|
||||
# acceptance condition). Accepting arcs are
|
||||
# represented by double arrows.
|
||||
#
|
||||
# s1=>s2->s3->(large composant from s4 to s9)
|
||||
# ^ |
|
||||
# |_______|
|
||||
|
||||
cat >blue_counter <<'EOF'
|
||||
HOA: v1
|
||||
States: 9
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[t] 1
|
||||
State: 1
|
||||
[t] 2
|
||||
State: 2
|
||||
[t] 0
|
||||
[t] 3
|
||||
State: 3
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 4
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 5
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 6
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 7
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 8
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -CR -eSE05 -XH blue_counter
|
||||
run 0 ../ikwiad -CR -eTau03_opt -XH blue_counter
|
||||
|
||||
# s1->s2->s3->(large composant from s4 to s9)
|
||||
# ^ ||
|
||||
# ||______||
|
||||
# ||______||
|
||||
|
||||
cat >blue_last <<'EOF'
|
||||
HOA: v1
|
||||
States: 9
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc complete
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
State: 1
|
||||
[t] 2
|
||||
State: 2
|
||||
[t] 0 {0}
|
||||
[t] 3
|
||||
State: 3
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 4
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 5
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 6
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 7
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 8
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -CR -eSE05 -XH blue_last
|
||||
run 0 ../ikwiad -CR -eTau03_opt -XH blue_last
|
||||
|
||||
# _______
|
||||
# | |
|
||||
# | v
|
||||
# s1->s2->s3->(large composant from s4 to s9)
|
||||
# || ^
|
||||
# ||______||
|
||||
# ||______||
|
||||
|
||||
cat >red <<'EOF'
|
||||
HOA: v1
|
||||
States: 9
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc complete
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
[t] 2 {0}
|
||||
State: 1
|
||||
[t] 2
|
||||
State: 2
|
||||
[t] 0
|
||||
[t] 3
|
||||
State: 3
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 4
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 5
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 6
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 7
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
State: 8
|
||||
[t] 3
|
||||
[t] 4
|
||||
[t] 5
|
||||
[t] 6
|
||||
[t] 7
|
||||
[t] 8
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -CR -eSE05 -XH red
|
||||
run 0 ../ikwiad -CR -eTau03_opt -XH red
|
||||
|
||||
rm -f red blue_counter blue_last
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
# This failure to produce a deterministic automaton was noticed by
|
||||
# Alexandre Lewkowicz.
|
||||
|
||||
# The following is the output of
|
||||
# ltlfilt -f 'G(F!a | (Fb U c))' -l |
|
||||
# ltl2dstar --ltl2nba=spin:$HOME/usr/bin/ltl2tgba@-s - -
|
||||
|
||||
cat > in.dra <<EOF
|
||||
DRA v2 explicit
|
||||
Comment: "Safra[NBA=8]"
|
||||
States: 29
|
||||
Acceptance-Pairs: 3
|
||||
Start: 7
|
||||
AP: 3 "a" "b" "c"
|
||||
---
|
||||
State: 0
|
||||
Acc-Sig: -2
|
||||
21
|
||||
0
|
||||
20
|
||||
1
|
||||
15
|
||||
4
|
||||
13
|
||||
22
|
||||
State: 1
|
||||
Acc-Sig: -2
|
||||
21
|
||||
0
|
||||
20
|
||||
1
|
||||
13
|
||||
22
|
||||
13
|
||||
22
|
||||
State: 2
|
||||
Acc-Sig: -2
|
||||
15
|
||||
3
|
||||
13
|
||||
12
|
||||
15
|
||||
2
|
||||
13
|
||||
14
|
||||
State: 3
|
||||
Acc-Sig: -2
|
||||
16
|
||||
3
|
||||
20
|
||||
12
|
||||
15
|
||||
2
|
||||
13
|
||||
14
|
||||
State: 4
|
||||
Acc-Sig: -2
|
||||
15
|
||||
3
|
||||
13
|
||||
12
|
||||
15
|
||||
4
|
||||
13
|
||||
22
|
||||
State: 5
|
||||
Acc-Sig: -2
|
||||
15
|
||||
17
|
||||
13
|
||||
12
|
||||
15
|
||||
5
|
||||
13
|
||||
14
|
||||
State: 6
|
||||
Acc-Sig: -2
|
||||
28
|
||||
6
|
||||
20
|
||||
18
|
||||
15
|
||||
5
|
||||
13
|
||||
14
|
||||
State: 7
|
||||
Acc-Sig: -1 -2
|
||||
13
|
||||
19
|
||||
13
|
||||
18
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
State: 8
|
||||
Acc-Sig: -1 -2
|
||||
23
|
||||
9
|
||||
13
|
||||
1
|
||||
23
|
||||
8
|
||||
13
|
||||
22
|
||||
State: 9
|
||||
Acc-Sig: -1 -2
|
||||
24
|
||||
9
|
||||
20
|
||||
1
|
||||
23
|
||||
8
|
||||
13
|
||||
22
|
||||
State: 10
|
||||
Acc-Sig: -1 -2
|
||||
26
|
||||
11
|
||||
25
|
||||
10
|
||||
13
|
||||
22
|
||||
13
|
||||
22
|
||||
State: 11
|
||||
Acc-Sig: -1 -2
|
||||
26
|
||||
11
|
||||
25
|
||||
10
|
||||
23
|
||||
8
|
||||
13
|
||||
22
|
||||
State: 12
|
||||
Acc-Sig: +0 -1 -2
|
||||
21
|
||||
0
|
||||
20
|
||||
1
|
||||
13
|
||||
22
|
||||
13
|
||||
22
|
||||
State: 13
|
||||
Acc-Sig: +0 -1 -2
|
||||
13
|
||||
11
|
||||
13
|
||||
10
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
State: 14
|
||||
Acc-Sig: +0 -1 -2
|
||||
13
|
||||
19
|
||||
13
|
||||
18
|
||||
13
|
||||
22
|
||||
13
|
||||
22
|
||||
State: 15
|
||||
Acc-Sig: +0 -1 -2
|
||||
23
|
||||
6
|
||||
13
|
||||
18
|
||||
23
|
||||
23
|
||||
13
|
||||
13
|
||||
State: 16
|
||||
Acc-Sig: +0 -1 -2
|
||||
24
|
||||
6
|
||||
20
|
||||
18
|
||||
23
|
||||
23
|
||||
13
|
||||
13
|
||||
State: 17
|
||||
Acc-Sig: +0 -1 -2
|
||||
24
|
||||
9
|
||||
20
|
||||
1
|
||||
23
|
||||
8
|
||||
13
|
||||
22
|
||||
State: 18
|
||||
Acc-Sig: +0 -1 -2
|
||||
26
|
||||
11
|
||||
25
|
||||
10
|
||||
13
|
||||
22
|
||||
13
|
||||
22
|
||||
State: 19
|
||||
Acc-Sig: +0 -1 -2
|
||||
26
|
||||
11
|
||||
25
|
||||
10
|
||||
23
|
||||
8
|
||||
13
|
||||
22
|
||||
State: 20
|
||||
Acc-Sig: +0 -1 -2
|
||||
26
|
||||
19
|
||||
25
|
||||
18
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
State: 21
|
||||
Acc-Sig: +0 -1 -2
|
||||
26
|
||||
19
|
||||
25
|
||||
18
|
||||
23
|
||||
23
|
||||
13
|
||||
13
|
||||
State: 22
|
||||
Acc-Sig: +1 -2
|
||||
13
|
||||
19
|
||||
13
|
||||
18
|
||||
13
|
||||
22
|
||||
13
|
||||
22
|
||||
State: 23
|
||||
Acc-Sig: +1 -2
|
||||
23
|
||||
6
|
||||
13
|
||||
18
|
||||
23
|
||||
23
|
||||
13
|
||||
13
|
||||
State: 24
|
||||
Acc-Sig: +1 -2
|
||||
24
|
||||
6
|
||||
20
|
||||
18
|
||||
23
|
||||
23
|
||||
13
|
||||
13
|
||||
State: 25
|
||||
Acc-Sig: +1 -2
|
||||
26
|
||||
19
|
||||
25
|
||||
18
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
State: 26
|
||||
Acc-Sig: +1 -2
|
||||
26
|
||||
19
|
||||
25
|
||||
18
|
||||
23
|
||||
23
|
||||
13
|
||||
13
|
||||
State: 27
|
||||
Acc-Sig: +1 -2
|
||||
28
|
||||
6
|
||||
20
|
||||
18
|
||||
15
|
||||
5
|
||||
13
|
||||
14
|
||||
State: 28
|
||||
Acc-Sig: +2
|
||||
28
|
||||
27
|
||||
20
|
||||
18
|
||||
15
|
||||
15
|
||||
13
|
||||
13
|
||||
EOF
|
||||
|
||||
test `../../bin/dstar2tgba -D in.dra --stats="%d:%s:%e"` = "1:23:143"
|
||||
|
||||
|
|
@ -1,299 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Do some quick translations to make sure the neverclaims produced by
|
||||
# spot actually look correct! We do that by parsing them via ltlcross.
|
||||
# ltl2neverclaim-lbtt.test does the same with LBTT if it is installed.
|
||||
|
||||
. ./defs
|
||||
set -e
|
||||
|
||||
|
||||
# DRA generated with
|
||||
# ltlfilt -f 'a U b' -l | ltl2dstar --ltl2nba=spin:path/ltl2tgba@-s - -
|
||||
cat >dra.dstar <<EOF
|
||||
DRA v2 explicit
|
||||
Comment: "Safra[NBA=2]"
|
||||
States: 3
|
||||
Acceptance-Pairs: 1
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
---
|
||||
State: 0
|
||||
Acc-Sig:
|
||||
1
|
||||
0
|
||||
2
|
||||
2
|
||||
State: 1
|
||||
Acc-Sig: -0
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
State: 2
|
||||
Acc-Sig: +0
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -XD dra.dstar | tee stdout
|
||||
|
||||
cat >expected <<EOF
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 0
|
||||
0 [label="0"]
|
||||
0 -> 0 [label="a & !b"]
|
||||
0 -> 1 [label="!a & !b"]
|
||||
0 -> 2 [label="b"]
|
||||
1 [label="1\n{0}"]
|
||||
1 -> 1 [label="1"]
|
||||
2 [label="2\n{1}"]
|
||||
2 -> 2 [label="1"]
|
||||
}
|
||||
EOF
|
||||
|
||||
diff expected stdout
|
||||
|
||||
|
||||
run 0 ../ikwiad -XDB -R3 dra.dstar | tee stdout
|
||||
|
||||
cat >expected <<EOF
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 0
|
||||
0 [label="0"]
|
||||
0 -> 0 [label="a & !b"]
|
||||
0 -> 1 [label="b"]
|
||||
1 [label="1", peripheries=2]
|
||||
1 -> 1 [label="1"]
|
||||
}
|
||||
EOF
|
||||
|
||||
diff expected stdout
|
||||
|
||||
|
||||
|
||||
# DSA generated with
|
||||
# ltlfilt -f 'FGa' -l |
|
||||
# ltl2dstar --automata=streett --ltl2nba=spin:path/ltl2tgba@-s - -
|
||||
cat >dsa.dstar <<EOF
|
||||
DSA v2 explicit
|
||||
Comment: "Streett{Safra[NBA=2]}"
|
||||
States: 3
|
||||
Acceptance-Pairs: 1
|
||||
Start: 1
|
||||
AP: 1 "a"
|
||||
---
|
||||
State: 0
|
||||
Acc-Sig: +0
|
||||
0
|
||||
2
|
||||
State: 1
|
||||
Acc-Sig:
|
||||
0
|
||||
0
|
||||
State: 2
|
||||
Acc-Sig:
|
||||
0
|
||||
2
|
||||
EOF
|
||||
|
||||
run 0 ../ikwiad -XDB dsa.dstar | tee stdout
|
||||
|
||||
cat >expected <<EOF
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 1
|
||||
0 [label="0"]
|
||||
0 -> 0 [label="!a"]
|
||||
0 -> 2 [label="a"]
|
||||
1 [label="1"]
|
||||
1 -> 0 [label="1"]
|
||||
2 [label="2"]
|
||||
2 -> 0 [label="!a"]
|
||||
2 -> 2 [label="a"]
|
||||
2 -> 3 [label="a"]
|
||||
3 [label="3", peripheries=2]
|
||||
3 -> 3 [label="a"]
|
||||
}
|
||||
EOF
|
||||
|
||||
diff expected stdout
|
||||
|
||||
# These one could be reduced to 2 5 0 0 and 3 8 1 0
|
||||
test "`../../bin/dstar2tgba -D dsa.dstar --stats '%s %t %p %d'`" = "4 8 0 0"
|
||||
test "`../../bin/dstar2tgba -DC dsa.dstar --stats '%s %t %p %d'`" = "5 11 1 0"
|
||||
|
||||
|
||||
|
||||
# DRA generated with
|
||||
# ltlfilt -f 'Ga | Fb' -l | ltl2dstar --ltl2nba=spin:path/ltl2tgba@-Ds - -
|
||||
# (State name and comments added by hand to test the parser.)
|
||||
cat >dra.dstar <<EOF
|
||||
DRA v2 explicit
|
||||
Comment: "Union{Safra[NBA=1],Safra[NBA=2]}"
|
||||
States: 5
|
||||
Acceptance-Pairs: 2
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
---
|
||||
State: 0 "bla"
|
||||
Acc-Sig:
|
||||
1
|
||||
2 /* This is a comment */
|
||||
3
|
||||
4
|
||||
State: 1 "foo"
|
||||
Acc-Sig: -0
|
||||
1
|
||||
1 // This is another comment.
|
||||
3
|
||||
3
|
||||
State: 2 "baz"
|
||||
Acc-Sig: +0
|
||||
1
|
||||
2
|
||||
// more
|
||||
/// comment
|
||||
3
|
||||
4
|
||||
State: 3 "str\n\"ing"
|
||||
Acc-Sig: -0 +1
|
||||
3 /***
|
||||
**** Some multiline comment
|
||||
***/
|
||||
3
|
||||
3
|
||||
3
|
||||
State: 4 "more\"string\""
|
||||
Acc-Sig: +0 +1
|
||||
3
|
||||
4
|
||||
3
|
||||
4
|
||||
/* Same automaton with DSA instead of DRA, no comments, and less \n */
|
||||
DSA v2 explicit
|
||||
States: 5
|
||||
Acceptance-Pairs: 2
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
---
|
||||
State: 0 "bla" Acc-Sig: 1 2 3 4
|
||||
State: 1 "foo" Acc-Sig: -0 1 1 3 3
|
||||
State: 2 "baz" Acc-Sig: +0 1 2 3 4
|
||||
State: 3 "str\n\"ing" Acc-Sig: -0 +1 3 3 3 3
|
||||
State: 4 "more\"string\"" Acc-Sig: +0 +1 3 4 3 4
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt -B dra.dstar | tee stdout
|
||||
|
||||
cat >expected <<EOF
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 0
|
||||
0 [label="0"]
|
||||
0 -> 1 [label="!a & !b"]
|
||||
0 -> 2 [label="a & !b"]
|
||||
0 -> 3 [label="!a & b"]
|
||||
0 -> 4 [label="a & b"]
|
||||
1 [label="1"]
|
||||
1 -> 1 [label="!b"]
|
||||
1 -> 3 [label="b"]
|
||||
2 [label="2", peripheries=2]
|
||||
2 -> 1 [label="!a & !b"]
|
||||
2 -> 2 [label="a & !b"]
|
||||
2 -> 3 [label="!a & b"]
|
||||
2 -> 4 [label="a & b"]
|
||||
3 [label="3", peripheries=2]
|
||||
3 -> 3 [label="1"]
|
||||
4 [label="4", peripheries=2]
|
||||
4 -> 3 [label="!a"]
|
||||
4 -> 4 [label="a"]
|
||||
}
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 0
|
||||
0 [label="0"]
|
||||
0 -> 1 [label="!a & !b"]
|
||||
0 -> 2 [label="a & !b"]
|
||||
1 [label="1", peripheries=2]
|
||||
1 -> 1 [label="!b"]
|
||||
2 [label="2"]
|
||||
2 -> 1 [label="!a & !b"]
|
||||
2 -> 2 [label="a & !b"]
|
||||
}
|
||||
EOF
|
||||
|
||||
diff expected stdout
|
||||
|
||||
cat >expected <<EOF
|
||||
3 12 1 1 dra.dstar:1.1-42.70
|
||||
2 4 0 1 dra.dstar:43.1-54.1
|
||||
EOF
|
||||
|
||||
../../bin/dstar2tgba --name=%F:%L -D dra.dstar --stats '%s %t %p %d %m' > out
|
||||
cat out
|
||||
diff expected out
|
||||
|
||||
|
||||
# This has caused a crash at some point when dealing with 0-sized
|
||||
# bitsets to represent acceptance sets.
|
||||
cat >aut.dsa <<EOF
|
||||
DSA v2 explicit
|
||||
Comment: "Streett{Safra[NBA=1]}"
|
||||
States: 1
|
||||
Acceptance-Pairs: 0
|
||||
Start: 0
|
||||
AP: 0
|
||||
---
|
||||
State: 0
|
||||
Acc-Sig:
|
||||
0
|
||||
EOF
|
||||
run 0 ../../bin/dstar2tgba --name=%F --dot=nt aut.dsa | tee stdout
|
||||
|
||||
cat >expected<<EOF
|
||||
digraph G {
|
||||
rankdir=LR
|
||||
label="aut.dsa"
|
||||
labelloc="t"
|
||||
node [shape="circle"]
|
||||
I [label="", style=invis, width=0]
|
||||
I -> 0
|
||||
0 [label="0"]
|
||||
0 -> 0 [label="1\n{0}"]
|
||||
}
|
||||
EOF
|
||||
|
||||
diff expected stdout
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
# et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
dorun()
|
||||
{
|
||||
run 0 ../ikwiad -f "$1" >output1
|
||||
run 0 ../ikwiad -f -S "$1" >output2
|
||||
test `wc -l <output1` = `wc -l <output2`
|
||||
}
|
||||
|
||||
dorun 'a'
|
||||
dorun 'a U b'
|
||||
dorun 'X a'
|
||||
dorun 'a & b & c'
|
||||
dorun 'a | b | (c U (d & (g U (h ^ i))))'
|
||||
dorun 'Xa & (b U !a) & (b U !a)'
|
||||
dorun 'Fa & Xb & GFc & Gd'
|
||||
dorun 'Fa & Xa & GFc & Gc'
|
||||
dorun 'Fc & X(a | Xb) & GF(a | Xb) & Gc'
|
||||
dorun '!((FF a) <=> (F x))'
|
||||
dorun '!((FF a) <=> (F a))'
|
||||
dorun 'Xa && (!a U b) && !b && X!b'
|
||||
dorun '(a U !b) && Gb'
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <spot/tl/parse.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/ltl2taa.hh>
|
||||
#include <spot/twaalgos/sccfilter.hh>
|
||||
#include <spot/twaalgos/degen.hh>
|
||||
#include <spot/twa/twaproduct.hh>
|
||||
#include <spot/twaalgos/gtec/gtec.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/emptiness.hh>
|
||||
|
||||
static void
|
||||
syntax(char* prog)
|
||||
{
|
||||
std::cerr << prog << " file" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
syntax(argv[0]);
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
std::cerr << "failed to open " << argv[1] << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
auto d = spot::make_bdd_dict();
|
||||
|
||||
std::string s;
|
||||
unsigned line = 0;
|
||||
while (std::getline(input, s))
|
||||
{
|
||||
++line;
|
||||
std::cout << "========================================================\n";
|
||||
std::cout << line << ": " << s << '\n';
|
||||
if (s.empty() || s[0] == '#') // Skip comments
|
||||
continue;
|
||||
|
||||
std::vector<std::string> tokens;
|
||||
{
|
||||
std::istringstream ss(s);
|
||||
std::string form;
|
||||
while (std::getline(ss, form, ','))
|
||||
{
|
||||
std::string tmp;
|
||||
while (form.size() > 0 && form.back() == '\\'
|
||||
&& std::getline(ss, tmp, ','))
|
||||
{
|
||||
form.back() = ',';
|
||||
form += tmp;
|
||||
}
|
||||
tokens.push_back(form);
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens.size() != 2)
|
||||
{
|
||||
std::cerr << "Expecting two tokens on input line.\n";
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int runs = atoi(tokens[0].c_str());
|
||||
|
||||
spot::parse_error_list pe;
|
||||
auto f = spot::parse_infix_psl(tokens[1], pe);
|
||||
if (spot::format_parse_errors(std::cerr, tokens[1], pe))
|
||||
return 2;
|
||||
|
||||
auto d = spot::make_bdd_dict();
|
||||
|
||||
// Build many different automata from this formula.
|
||||
spot::const_twa_ptr aut[4];
|
||||
{
|
||||
auto a = spot::ltl_to_taa(f, d);
|
||||
aut[0] = a;
|
||||
auto all = spot::twa::prop_set::all();
|
||||
aut[1] = spot::degeneralize_tba(spot::make_twa_graph(a, all));
|
||||
}
|
||||
{
|
||||
auto a = spot::ltl_to_tgba_fm(f, d);
|
||||
aut[2] = a;
|
||||
aut[3] = spot::degeneralize(a);
|
||||
}
|
||||
|
||||
const char* algos[] = {
|
||||
"Cou99", "Cou99(shy)",
|
||||
"CVWY90", "CVWY90(bsh=10M)", "CVWY90(repeated)",
|
||||
"SE05", "SE05(bsh=10M)", "SE05(repeated)",
|
||||
"Tau03_opt", "GV04",
|
||||
};
|
||||
|
||||
for (auto& algo: algos)
|
||||
{
|
||||
const char* err;
|
||||
auto i = spot::make_emptiness_check_instantiator(algo, &err);
|
||||
if (!i)
|
||||
{
|
||||
std::cerr << "Failed to parse `" << err << '\'' << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < sizeof(aut)/sizeof(*aut); ++j)
|
||||
{
|
||||
auto a = aut[j];
|
||||
std::cout << "** Testing aut[" << j << "] using " << algo << '\n';
|
||||
unsigned n_acc = a->acc().num_sets();
|
||||
unsigned n_max = i->max_acceptance_conditions();
|
||||
if (n_max < n_acc)
|
||||
{
|
||||
std::cout << "Skipping because automaton has " << n_acc
|
||||
<< " acceptance sets, and " << algo
|
||||
<< " accepts at most " << n_max << ".\n";
|
||||
continue;
|
||||
}
|
||||
unsigned n_min = i->min_acceptance_conditions();
|
||||
if (n_min > n_acc)
|
||||
{
|
||||
std::cout << "Skipping because automaton has " << n_acc
|
||||
<< " acceptance sets, and " << algo
|
||||
<< " wants at least " << n_min << ".\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
auto ec = i->instantiate(a);
|
||||
bool search_many = i->options().get("repeated");
|
||||
assert(ec);
|
||||
int ce_found = 0;
|
||||
do
|
||||
{
|
||||
if (auto res = ec->check())
|
||||
{
|
||||
++ce_found;
|
||||
std::cout << ce_found << " counterexample found\n";
|
||||
if (auto run = res->accepting_run())
|
||||
{
|
||||
spot::print_dot(std::cout, run->as_twa());
|
||||
}
|
||||
std::cout << '\n';
|
||||
if (runs == 0)
|
||||
{
|
||||
std::cerr << "ERROR: Expected no counterexample.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ce_found)
|
||||
std::cout << "No more counterexample found.\n\n";
|
||||
else
|
||||
std::cout << "No counterexample found.\n\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (search_many);
|
||||
|
||||
// The expected number of runs is only for TAA translations
|
||||
if (search_many && runs > ce_found && j < 2)
|
||||
{
|
||||
std::cerr << "ERROR: only " << ce_found
|
||||
<< " counterexamples founds, expected at least "
|
||||
<< runs << '\n';
|
||||
exit(1);
|
||||
}
|
||||
if (!search_many && ec->safe() && runs && !ce_found)
|
||||
{
|
||||
std::cerr << "ERROR: expected a counterexample.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(spot::fnode::instances_check());
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2008, 2009, 2010, 2014 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
||||
# Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
# Université Pierre et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat > emptchk.txt <<EOF
|
||||
1, a
|
||||
1, a U b
|
||||
1, X a
|
||||
1, a & b & c
|
||||
1, a | b | (c U (d & (g U (h ^ i))))
|
||||
1, Xa & (b U !a) & (b U !a)
|
||||
1, Fa & Xb & GFc & Gd
|
||||
2, Fa & Xa & GFc & Gc
|
||||
1, Fc & X(a | Xb) & GF(a | Xb) & Gc
|
||||
2, !((FF a) <=> (F x))
|
||||
0, Xa && (!a U b) && !b && X!b
|
||||
0, (a U !b) && Gb
|
||||
EOF
|
||||
|
||||
run 0 ../emptchk emptchk.txt
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2010, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
||||
# Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
# Université Pierre et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
expect_ce()
|
||||
{
|
||||
run 0 ../ikwiad -CR -e -XH "$1"
|
||||
run 0 ../ikwiad -CR -e -DT -XH "$1"
|
||||
run 0 ../ikwiad -CR -e'Cou99(shy)' -XH "$1"
|
||||
run 0 ../ikwiad -CR -e'Cou99(shy)' -DT -XH "$1"
|
||||
run 0 ../ikwiad -CR -eCVWY90 -XH "$1"
|
||||
run 0 ../ikwiad -CR -eGV04 -XH "$1"
|
||||
run 0 ../ikwiad -CR -eSE05 -XH "$1"
|
||||
run 0 ../ikwiad -CR -eTau03 -XH "$1"
|
||||
}
|
||||
|
||||
cat >input <<'EOF'
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0 {0 1}
|
||||
[0&!1] 1
|
||||
State: 1 {0}
|
||||
[0] 2
|
||||
State: 2
|
||||
[t] 0
|
||||
--END--
|
||||
EOF
|
||||
|
||||
expect_ce input
|
||||
|
||||
# ________
|
||||
# / v
|
||||
# >a--->d--->g
|
||||
# /^ /^ /^
|
||||
# L | L | L |{A}
|
||||
# b->c e->f h->i
|
||||
#
|
||||
cat >input <<'EOF'
|
||||
HOA: v1
|
||||
States: 9
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc complete
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
[t] 3
|
||||
[t] 6
|
||||
State: 1
|
||||
[t] 2
|
||||
State: 2
|
||||
[t] 0
|
||||
State: 3
|
||||
[t] 4
|
||||
[t] 6
|
||||
State: 4
|
||||
[t] 5
|
||||
State: 5
|
||||
[t] 3
|
||||
State: 6
|
||||
[t] 7
|
||||
State: 7
|
||||
[t] 8
|
||||
State: 8 {0}
|
||||
[t] 6
|
||||
--END--
|
||||
EOF
|
||||
|
||||
expect_ce input
|
||||
|
||||
# v
|
||||
# d->a
|
||||
# ^ |
|
||||
# | v
|
||||
# c<-b<-.
|
||||
# ^ |A |B
|
||||
# B| v |
|
||||
# `--e->f
|
||||
#
|
||||
# The arcs are ordered so that Couvreur99 succeed after exploring
|
||||
# the following subgraph (which is one accepting SCC):
|
||||
#
|
||||
# v
|
||||
# d->a
|
||||
# ^ |
|
||||
# | v
|
||||
# c<-b<-.
|
||||
# |A |B
|
||||
# v |
|
||||
# e->f
|
||||
#
|
||||
# However when computing a counter-example the greedy BFS algorithm
|
||||
# will fail to return the minimal a->b->e->f->b run. Indeed it first
|
||||
# walks through a->b->e (which gives acceptance condition A), and
|
||||
# prefer to continue with e->c (because it gives acceptance condition B),
|
||||
# and finally closes the cycle with c->d->a
|
||||
#
|
||||
cat >input <<'EOF'
|
||||
HOA: v1
|
||||
States: 6
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc complete
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
State: 1
|
||||
[t] 2
|
||||
[t] 4 {0}
|
||||
State: 2
|
||||
[t] 3
|
||||
State: 3
|
||||
[t] 0
|
||||
State: 4
|
||||
[t] 2 {1}
|
||||
[t] 5
|
||||
State: 5
|
||||
[t] 1 {1}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
expect_ce input
|
||||
|
||||
|
||||
# This graph was randomly generated, and contains one accepting path.
|
||||
# It triggered a bug in our implementation of GV04 (that didn't see any
|
||||
# accepting path).
|
||||
cat >input <<EOF
|
||||
HOA: v1
|
||||
States: 20
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc
|
||||
--BODY--
|
||||
State: 0
|
||||
[t] 1
|
||||
State: 1
|
||||
[t] 2
|
||||
[t] 3
|
||||
State: 2
|
||||
[t] 4
|
||||
[t] 5 {0}
|
||||
[t] 6
|
||||
State: 3
|
||||
[t] 6
|
||||
[t] 7
|
||||
State: 4
|
||||
[t] 8
|
||||
State: 5
|
||||
[t] 9
|
||||
State: 6
|
||||
[t] 2
|
||||
State: 7
|
||||
[t] 10
|
||||
[t] 11
|
||||
State: 8
|
||||
[t] 12
|
||||
State: 9
|
||||
[t] 13
|
||||
State: 10
|
||||
[t] 13
|
||||
[t] 14
|
||||
[t] 15
|
||||
State: 11
|
||||
[t] 2
|
||||
State: 12
|
||||
[t] 3
|
||||
State: 13
|
||||
[t] 16
|
||||
State: 14
|
||||
State: 15
|
||||
[t] 4
|
||||
State: 16
|
||||
[t] 17
|
||||
State: 17
|
||||
[t] 18
|
||||
State: 18
|
||||
[t] 10
|
||||
[t] 19
|
||||
State: 19
|
||||
--END--
|
||||
EOF
|
||||
|
||||
expect_ce input
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2010, 2015 Laboratoire de Recherche de
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
# et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Emptiness check on randomly generated state spaces.
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
# With no acceptance condition, everyone should agree and find a run.
|
||||
# Do not spend to much time checking this.
|
||||
run 0 ../randtgba -e 10 -s 0 -r -m
|
||||
# Test some statistic output
|
||||
run 0 ../randtgba -z -e 10 -s 0 -r -m
|
||||
run 0 ../randtgba -1 -e 10 -s 0 -r -m
|
||||
|
||||
# One acceptance condition
|
||||
run 0 ../randtgba -e 100 -s 0 -r -m -a 1 0.1 -d 0.01
|
||||
run 0 ../randtgba -e 100 -s 50 -r -m -a 1 0.1 -d 0.02
|
||||
run 0 ../randtgba -e 100 -s 100 -r -m -a 1 0.1 -d 0.04
|
||||
run 0 ../randtgba -e 100 -s 150 -r -m -a 1 0.1 -d 0.08
|
||||
|
||||
# Four acceptance conditions
|
||||
run 0 ../randtgba -e 100 -s 200 -r -m -a 4 0.1 -d 0.01
|
||||
run 0 ../randtgba -e 100 -s 250 -r -m -a 4 0.1 -d 0.02
|
||||
run 0 ../randtgba -e 100 -s 300 -r -m -a 4 0.1 -d 0.04
|
||||
run 0 ../randtgba -e 100 -s 350 -r -m -a 4 0.1 -d 0.08
|
||||
run 0 ../randtgba -e 100 -s 400 -r -m -a 4 0.2 -d 0.01
|
||||
run 0 ../randtgba -e 100 -s 450 -r -m -a 4 0.2 -d 0.02
|
||||
run 0 ../randtgba -e 100 -s 500 -r -m -a 4 0.2 -d 0.04
|
||||
run 0 ../randtgba -e 100 -s 550 -r -m -a 4 0.2 -d 0.08
|
||||
|
||||
# Bigger automata. With valgrind this is slow, so we do less.
|
||||
run 0 ../randtgba -e 10 -s 0 -n 500 -r -m -a 1 0.0003 -d 0.01
|
||||
run 0 ../randtgba -e 10 -s 0 -n 500 -r -m -a 4 0.0011 -D -d 0.01
|
||||
|
|
@ -1,227 +0,0 @@
|
|||
#! /bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
# et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# Check for the equals visitor
|
||||
|
||||
. ./defs || exit 1
|
||||
set -e
|
||||
|
||||
cat >equal.txt <<\EOF
|
||||
# A few things which are equal
|
||||
a, a
|
||||
~a, !a
|
||||
1, 1
|
||||
0, 0
|
||||
a => b, a --> b
|
||||
a <-> b, a <--> b
|
||||
G a , G a
|
||||
a U b, a U b
|
||||
a & b, a & b
|
||||
a & b, b & a
|
||||
a & b & c, c & a && b
|
||||
a & b & c, b & c & a
|
||||
a && b & a, b & a & b
|
||||
a & b, b & a & b
|
||||
a & b, b & a & a
|
||||
a & b & (c |(f U g)|| e), b & a & a & (c | e |(f U g)| e | c) & b
|
||||
a & a, a
|
||||
a & a & true, a
|
||||
a & false & a, false
|
||||
a | false | a, a
|
||||
true | a | a, true
|
||||
Ga=1*Gb=0, (G(a)) & (G(!b))
|
||||
FFx, Fx
|
||||
FFFFFx, Fx
|
||||
GGx, Gx
|
||||
GGGGGx, Gx
|
||||
!!x, x
|
||||
!!!!!x, !x
|
||||
{[*0];x}<>->1, {x}<>->1
|
||||
{x;[*0]}<>->1, {x}<>-> 1
|
||||
{[*0];x;[*0];[*0]}<>->1, {x}<>->1
|
||||
{[*0];x;[*0];x;[*0]}<>->1, {x;x}<>->1
|
||||
{x;x;x;[*0];x;x}<>->1, {x;x;x;x;x}<>->1
|
||||
{x;0;x;x;x}<>->1, 0
|
||||
{x;0;x;x;x}[]->1, 1
|
||||
{0*;1}<>->x, x
|
||||
{[*0]*;1}<>->x, x
|
||||
{x;x}<>->FF(0), 0
|
||||
{x;x}<>->GX(1), {x;x}<>->1
|
||||
{x;x}[]->GX(1), 1
|
||||
{x;x}[]->FF(0), {x;x}[]->0
|
||||
{x;x}[]->y, {x;x}|->y
|
||||
{x;x}[]->y, {x;x}(y)
|
||||
{a*}!, {a*}<>->1
|
||||
{a -> b} (c), !(a->b)|c
|
||||
{a & !b}!, a & !b
|
||||
{a;[*0]}|->!Xb, !a | !Xb
|
||||
{{a;b}:b:c:d*:e:f}!, {{a;b}:{b && c }:d[*]:{e && f}}!
|
||||
{a:b:c}|->!Xb, !(a&&b&&c) | !Xb
|
||||
{a:b:c*}|->!Xb, {(a&&b):c*}|-> !Xb
|
||||
{a&b&c*}|->!Xb, {(a&&b)&c*}|-> !Xb
|
||||
{[*]&&a&&[*]}!, a
|
||||
{[*]||a||[*]}!, {[*]}!
|
||||
{0&{f;g*}}!, 0
|
||||
{1&{f;g*}}!, {f;g*}!
|
||||
# Precedence
|
||||
a & b ^ c | d, d | c ^ b & a
|
||||
|
||||
# Corner cases parsing
|
||||
FFG__GFF, F(F(G("__GFF")))
|
||||
|
||||
# Trivial simplifications
|
||||
{0*}<>->a, {[*0]}<>->a
|
||||
{[*0]*}<>->a, {[*0]}<>->a
|
||||
{Exp**}<>->a, {Exp*}<>->a
|
||||
FF(Exp), F(Exp)
|
||||
GG(Exp), G(Exp)
|
||||
F(0), 0
|
||||
G(0), 0
|
||||
F(1), 1
|
||||
G(1), 1
|
||||
F({[*0]}<>->1), F({[*0]}<>->1)
|
||||
G({[*0]}<>->1), G({[*0]}<>->1)
|
||||
F({1}<>->1), 1
|
||||
G({1}<>->1), 1
|
||||
!1, 0
|
||||
!0, 1
|
||||
!!Exp, Exp
|
||||
|
||||
(1 => Exp), Exp
|
||||
(0 => Exp), 1
|
||||
(Exp => 1), 1
|
||||
(Exp => 0), !Exp
|
||||
(Exp => Exp), 1
|
||||
(1 ^ Exp), !Exp
|
||||
(0 ^ Exp), Exp
|
||||
(Exp ^ Exp), 0
|
||||
(0 <=> Exp), !Exp
|
||||
(1 <=> Exp), Exp
|
||||
(Exp <=> Exp), 1
|
||||
(Exp U 1), 1
|
||||
(Exp U 0), 0
|
||||
(0 U Exp), Exp
|
||||
(Exp U Exp), Exp
|
||||
(Exp R 1), 1
|
||||
(Exp R 0), 0
|
||||
(Exp R Exp), Exp
|
||||
(1 R Exp), Exp
|
||||
(Exp W 1), 1
|
||||
(0 W Exp), Exp
|
||||
(1 W Exp), 1
|
||||
(Exp W Exp), Exp
|
||||
(Exp M 0), 0
|
||||
(1 M Exp), Exp
|
||||
(0 M Exp), 0
|
||||
(Exp M Exp), Exp
|
||||
|
||||
{1:{a;b}:1:c*}!, {{a;b}:c*}!
|
||||
{c*:1:{a;b}:1}!, {c*:{a;b}}!
|
||||
|
||||
{z;a*;b*;*;c;d;*;b*;e;a*;*;b*}, {z;[*];c;d;[*];e;[*]}
|
||||
{((a;b)|[*0]);[*];c}!, {[*];c}!
|
||||
{a;a;a*;a;b;b[*];c[*2:3];c[*4:5]}, {a[*3..];b[+];c[*6..8]}
|
||||
|
||||
{a[*0]}, {[*0]}
|
||||
{a[*..]}, {a[*]}
|
||||
{a[*2..3][*4..5]}, {a[*8..15]}
|
||||
{a[*4..5][*2..3]}, {a[*4..5][*2..3]}
|
||||
{a[*2:3][*]}, {a[*2 to 3][*]}
|
||||
{a[*1..3][*]}, {a[*]}
|
||||
{a[*][*2..3]}, {a[*]}
|
||||
{a[*..3][*2]}, {a[*..6]}
|
||||
{a[*..3][*to2]}, {a[*:6]}
|
||||
{a[*..3][*2..$]}, {a[*]}
|
||||
{a[*..3][*2:]}, {a[*:inf]}
|
||||
{a[*1..]}, {a[+]}
|
||||
{a[*1]}, {a}
|
||||
{a[+][*1..3]}, {a[+]}
|
||||
{a[*1..3][+]}, {a[+]}
|
||||
{[*2][+]}, {[*2][+]}
|
||||
{[+][*2]}, {[*2..inf]}
|
||||
|
||||
{0[=2]}, 0
|
||||
{0[=2..]}, 0
|
||||
{0[=1..10]}, 0
|
||||
{0[=0]}, {[*]}
|
||||
{0[=0..10]}, {*}
|
||||
{0[=0..]}, {*}
|
||||
{1[=0]}, {[*0]}
|
||||
{1[=1..2]}, {[*1\,2]}
|
||||
{1[=..4]}, {1[*..4]}
|
||||
{b[=0]}, {(!b)[*]}
|
||||
{b[=0to$]}, {*}
|
||||
|
||||
{0[->10..100];b}, 0
|
||||
{0[->1..];b}, 0
|
||||
{0[->0\,100];b}, b
|
||||
{0[->0..$];b}, b
|
||||
!{1[->0];b}, !b
|
||||
{1[->10\,20];b}, {[*10..20];b}
|
||||
{1[->..];b}, {[*1..];b}
|
||||
{{a&!c}[->0];b}, b
|
||||
|
||||
{(a|c)[:*0..3];d}, {1;d}
|
||||
{(a|c)[:*1..3];d}, {(a|c);d}
|
||||
{0[:*0..3];d}, {1;d}
|
||||
{0[:*1..3];d}, 0
|
||||
{1[:*0..3];d}, {1;d}
|
||||
{1[:*1..3];d}, {1;d}
|
||||
{[*0][:*0..3];d}, {1;d}
|
||||
{[*0][:*1..3];d}, 0
|
||||
{(a*;b|c)[:*1to3][:*2:4]}, {(a*;b|c)[:*2..12]}
|
||||
{(a*;b|c)[:*][:+]}, {(a*;b|c)[:*]}
|
||||
{(a*;b|c)[:*0]}, 1
|
||||
{(a*;b|c)[:*1]}, {(a*;b|c)}
|
||||
{(a;b):(a;b):(a;b)[:*2]:(a;b):b*:b*:(c;d)[:*1]}, {(a;b)[:*5]:b*[:*2]:(c;d)}
|
||||
EOF
|
||||
|
||||
|
||||
cat >nequal.txt <<\EOF
|
||||
# other formulae which are not
|
||||
a, b
|
||||
1, 0
|
||||
a => b, b => a
|
||||
a => b, a <=> b
|
||||
a => b, a U b
|
||||
a R b, a U b
|
||||
a & b & c, c & a
|
||||
b & c, c & a & b
|
||||
a & b & (c |(f U g)| e), b & a & a & (c | e |(g U g)| e | c) & b
|
||||
{a*}, {a*}<>->1
|
||||
!{a*}, {a*}<>->1
|
||||
{a*}, {a*}!
|
||||
!{a*}, {a*}!
|
||||
|
||||
# 1 should not be removed in the following two formulae
|
||||
{1&{g*}}!, {g*}!
|
||||
{1|{b;c}}<>->a, {b;c}<>->a
|
||||
# make sure twin arguments are not reduced in Fusion.
|
||||
{(a;!a)*:(a;!a)*:b}!, {(a;!a)*:b}!
|
||||
# make sure 1:a* is not reduced to a*.
|
||||
{(1:a*);b}!, {a*;b}!
|
||||
EOF
|
||||
|
||||
run 0 ../equals equal.txt
|
||||
run 0 ../nequals nequal.txt
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire de
|
||||
// Recherche et Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de
|
||||
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
// Université Pierre et Marie Curie.
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
// Spot is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
// License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <spot/tl/parse.hh>
|
||||
#include <spot/tl/unabbrev.hh>
|
||||
#include <spot/tl/nenoform.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/tl/print.hh>
|
||||
|
||||
static void
|
||||
syntax(char* prog)
|
||||
{
|
||||
std::cerr << prog << " [-E] file" << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
bool check_first = true;
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], "-E"))
|
||||
{
|
||||
check_first = false;
|
||||
argv[1] = argv[0];
|
||||
++argv;
|
||||
--argc;
|
||||
}
|
||||
if (argc != 2)
|
||||
syntax(argv[0]);
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
std::cerr << "failed to open " << argv[1] << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::string s;
|
||||
unsigned line = 0;
|
||||
while (std::getline(input, s))
|
||||
{
|
||||
++line;
|
||||
std::cerr << line << ": " << s << '\n';
|
||||
if (s[0] == '#') // Skip comments
|
||||
continue;
|
||||
std::vector<std::string> formulas;
|
||||
{
|
||||
std::istringstream ss(s);
|
||||
std::string form;
|
||||
while (std::getline(ss, form, ','))
|
||||
{
|
||||
std::string tmp;
|
||||
while (form.size() > 0 && form.back() == '\\'
|
||||
&& std::getline(ss, tmp, ','))
|
||||
{
|
||||
form.back() = ',';
|
||||
form += tmp;
|
||||
}
|
||||
formulas.push_back(form);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned size = formulas.size();
|
||||
if (size == 0) // Skip empty lines
|
||||
continue;
|
||||
|
||||
if (size == 1)
|
||||
{
|
||||
std::cerr << "Not enough formulas on line " << line << '\n';
|
||||
return 2;
|
||||
}
|
||||
|
||||
spot::parse_error_list p2;
|
||||
auto f2 = spot::parse_infix_psl(formulas[size - 1], p2);
|
||||
|
||||
if (spot::format_parse_errors(std::cerr, formulas[size - 1], p2))
|
||||
return 2;
|
||||
|
||||
for (unsigned n = 0; n < size - 1; ++n)
|
||||
{
|
||||
|
||||
spot::parse_error_list p1;
|
||||
auto f1 = spot::parse_infix_psl(formulas[n], p1);
|
||||
|
||||
if (check_first &&
|
||||
spot::format_parse_errors(std::cerr, formulas[n], p1))
|
||||
return 2;
|
||||
|
||||
int exit_code = 0;
|
||||
|
||||
{
|
||||
#if defined UNABBREV || defined NENOFORM
|
||||
spot::formula tmp;
|
||||
#endif
|
||||
#ifdef UNABBREV
|
||||
tmp = f1;
|
||||
f1 = spot::unabbreviate(f1, UNABBREV);
|
||||
f1.dump(std::cout) << std::endl;
|
||||
#endif
|
||||
#ifdef NENOFORM
|
||||
tmp = f1;
|
||||
f1 = spot::negative_normal_form(f1);
|
||||
f1.dump(std::cout) << std::endl;
|
||||
#endif
|
||||
#ifdef REDUC
|
||||
spot::tl_simplifier_options opt(true, true, true,
|
||||
false, false);
|
||||
# ifdef EVENT_UNIV
|
||||
opt.favor_event_univ = true;
|
||||
# endif
|
||||
spot::tl_simplifier simp(opt);
|
||||
{
|
||||
spot::formula tmp;
|
||||
tmp = f1;
|
||||
f1 = simp.simplify(f1);
|
||||
|
||||
if (!simp.are_equivalent(f1, tmp))
|
||||
{
|
||||
std::cerr
|
||||
<< "Source and simplified formulae are not equivalent!\n";
|
||||
spot::print_psl(std::cerr << "Simplified: ", f1) << '\n';
|
||||
exit_code = 1;
|
||||
}
|
||||
}
|
||||
f1.dump(std::cout) << std::endl;
|
||||
#endif
|
||||
#ifdef REDUC_TAU
|
||||
spot::tl_simplifier_options opt(false, false, false,
|
||||
true, false);
|
||||
spot::tl_simplifier simp(opt);
|
||||
{
|
||||
spot::formula tmp;
|
||||
tmp = f1;
|
||||
f1 = simp.simplify(f1);
|
||||
|
||||
if (!simp.are_equivalent(f1, tmp))
|
||||
{
|
||||
std::cerr
|
||||
<< "Source and simplified formulae are not equivalent!\n";
|
||||
spot::print_psl(std::cerr << "Simplified: ", f1) << '\n';
|
||||
exit_code = 1;
|
||||
}
|
||||
}
|
||||
f1.dump(std::cout) << std::endl;
|
||||
#endif
|
||||
#ifdef REDUC_TAUSTR
|
||||
spot::tl_simplifier_options opt(false, false, false,
|
||||
true, true);
|
||||
spot::tl_simplifier simp(opt);
|
||||
{
|
||||
spot::formula tmp;
|
||||
tmp = f1;
|
||||
f1 = simp.simplify(f1);
|
||||
|
||||
if (!simp.are_equivalent(f1, tmp))
|
||||
{
|
||||
std::cerr
|
||||
<< "Source and simplified formulae are not equivalent!\n";
|
||||
spot::print_psl(std::cerr << "Simplified: ", f1) << '\n';
|
||||
exit_code = 1;
|
||||
}
|
||||
}
|
||||
f1.dump(std::cout) << std::endl;
|
||||
#endif
|
||||
|
||||
exit_code |= f1 != f2;
|
||||
|
||||
#if (!defined(REDUC) && !defined(REDUC_TAU) && !defined(REDUC_TAUSTR))
|
||||
spot::tl_simplifier simp;
|
||||
#endif
|
||||
|
||||
if (!simp.are_equivalent(f1, f2))
|
||||
{
|
||||
#if (!defined(REDUC) && !defined(REDUC_TAU) && !defined(REDUC_TAUSTR))
|
||||
std::cerr
|
||||
<< "Source and destination formulae are not equivalent!\n";
|
||||
#else
|
||||
std::cerr
|
||||
<< "Simpl. and destination formulae are not equivalent!\n";
|
||||
#endif
|
||||
exit_code = 1;
|
||||
}
|
||||
|
||||
#if NEGATE
|
||||
exit_code ^= 1;
|
||||
#endif
|
||||
if (exit_code)
|
||||
return exit_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(spot::fnode::instances_check());
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
#! /bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2012, 2013, 2014 Laboratoire de Recherche et
|
||||
# Developpement de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. ./defs || exit 1
|
||||
set -e
|
||||
|
||||
cat >reduceu.txt <<EOF
|
||||
Xa | GFb, Xa | GFb
|
||||
X(a | GXFb), Xa | GFb
|
||||
Xa & GFb, Xa & GFb
|
||||
X(a & GXFb), Xa & GFb
|
||||
|
||||
F(a & b & GFc & FGd), F(a & b) & G(Fc & FGd)
|
||||
Fa | Fb | GFc | GFd, F(a|b) | GF(c | d)
|
||||
Fa | Fb | GFc | GFd | FGe, F(a|b) | F(G(e) | GF(c | d))
|
||||
Ga | Gb | GFd | FGe | FGf, Ga | Gb | F(GFd | Ge | Gf)
|
||||
|
||||
G(Ga & Fb & c & GFd), G(a&c) & G(Fb & Fd)
|
||||
G(Ga & GFb & c & GFd), G(a&c) & G(Fb & Fd)
|
||||
G(a & GFb & c & GFd), G(a&c) & G(Fb & Fd)
|
||||
G(Ga & Fb & c & GFd & FGe), G(a & c) & G(Fb & Fd & FGe)
|
||||
G(Ga & XFGb & c & FGd & FGe), FG(b & d & e) & G(a & c)
|
||||
G(Ga & GXFb & c & FGd & FGe & Fc), G(Fb & FG(d & e)) & G(a & c)
|
||||
Ga & Gb & GFd & FGe & FGf, G(Fd & FG(e & f)) & G(a & b)
|
||||
G(Ga & Gb & GFd & FGe) & FGf, G(Fd & FG(e & f)) & G(a & b)
|
||||
|
||||
a U (b | Fc), (a U b) | Fc
|
||||
a W (b | Fc), (a W b) | Fc
|
||||
a U (b & GFc), (a U b) & GFc
|
||||
# Unchanged
|
||||
a W (b & GFc), a W (b & GFc)
|
||||
# Unchanged
|
||||
(a | Gc) W g, (a | Gc) W g
|
||||
# Unchanged
|
||||
(a | Gc) U g, (a | Gc) U g
|
||||
(a & GFc) M b, (a M b) & GFc
|
||||
# Unchanged
|
||||
(a | GFc) M b, (a | GFc) M b
|
||||
# Unchanged
|
||||
(a & GFc) R b, (a & GFc) R b
|
||||
# Unchanged
|
||||
(a | GFc) R b, (a | GFc) R b
|
||||
a R (b & Gc), (a R b) & Gc
|
||||
a M (b & Gc), (a M b) & Gc
|
||||
EOF
|
||||
|
||||
run 0 ../reduceu reduceu.txt
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
#! /bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs || exit 1
|
||||
|
||||
set -e
|
||||
|
||||
cat >formulas <<EOF
|
||||
GFa
|
||||
a U b
|
||||
a U b U c
|
||||
a U b U d U e
|
||||
a U b U c U d U e
|
||||
EOF
|
||||
|
||||
cat >expected <<EOF
|
||||
GFa
|
||||
(a U b) & G!(a & b)
|
||||
(a U (b U c)) & G(!(a & b) & !(a & c) & !(b & c))
|
||||
(a U (b U (d U e))) & G(!(a & b) & !(d & e))
|
||||
(a U (b U (c U (d U e)))) & G(!(a & b) & !(a & c) & !(b & c) & !(d & e))
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/ltlfilt --exclusive-ap=a,b,c --exclusive-ap=d,e formulas >out
|
||||
cat out
|
||||
diff out expected
|
||||
|
||||
run 0 ../../bin/ltlfilt --exclusive-ap='"a" ,b, "c" ' --exclusive-ap=' d , e' \
|
||||
formulas >out
|
||||
cat out
|
||||
diff out expected
|
||||
|
||||
../../bin/ltlfilt --exclusive-ap='"a","b' 2>stderr && exit 1
|
||||
grep 'missing closing ."' stderr
|
||||
../../bin/ltlfilt --exclusive-ap='a,,b' 2>stderr && exit 1
|
||||
grep "unexpected ',' in a,,b" stderr
|
||||
../../bin/ltlfilt --exclusive-ap='"a"b' 2>stderr && exit 1
|
||||
grep "unexpected character 'b' in \"a\"b" stderr
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
#! /bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2015 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs || exit 1
|
||||
|
||||
set -e
|
||||
|
||||
cat >automaton <<EOF
|
||||
HOA: v1
|
||||
States: 4
|
||||
Start: 0
|
||||
AP: 3 "a" "b" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[1] 2
|
||||
[2&!1] 2
|
||||
State: 2 {0}
|
||||
[1] 2
|
||||
[0&1] 1
|
||||
[1&2] 3
|
||||
State: 3
|
||||
[t] 3
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 3 "a" "b" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&!1&!2] 1
|
||||
State: 1
|
||||
[!0&1&!2] 2
|
||||
[!0&!1&2] 2
|
||||
State: 2 {0}
|
||||
[!0&1&!2] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected-simpl <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 3 "a" "b" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[1 | 2] 2
|
||||
State: 2 {0}
|
||||
[1] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt -H --exclusive-ap=a,b,c --exclusive-ap=d,e \
|
||||
automaton >out
|
||||
cat out
|
||||
diff out expected
|
||||
|
||||
run 0 ../../bin/autfilt -H --exclusive-ap=a,b,c --exclusive-ap=d,e \
|
||||
--simplify-exclusive-ap automaton >out2
|
||||
cat out2
|
||||
diff out2 expected-simpl
|
||||
|
||||
cat >automaton <<EOF
|
||||
HOA: v1
|
||||
States: 4
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[1] 2
|
||||
[0&!1] 2
|
||||
State: 2 {0}
|
||||
[1] 2
|
||||
[0&1] 1
|
||||
[1&0] 3
|
||||
State: 3
|
||||
[t] 3
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&!1] 1
|
||||
State: 1
|
||||
[!0&1] 2
|
||||
[0&!1] 2
|
||||
State: 2 {0}
|
||||
[!0&1] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected-simpl <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
State: 1
|
||||
[0 | 1] 2
|
||||
State: 2 {0}
|
||||
[1] 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt -H --exclusive-ap=a,b,c --exclusive-ap=d,e \
|
||||
automaton >out
|
||||
cat out
|
||||
diff out expected
|
||||
|
||||
run 0 ../../bin/autfilt -H --exclusive-ap=a,b,c --exclusive-ap=d,e \
|
||||
--simplify-exclusive-ap automaton >out2
|
||||
cat out2
|
||||
diff out2 expected-simpl
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Laboratoire
|
||||
# d'Informatique de Paris 6 (LIP6), département Systèmes Répartis
|
||||
# Coopératifs (SRC), Université Pierre et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat >input1 <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 1 {0}
|
||||
[!1] 2 {1}
|
||||
State: 1
|
||||
State: 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >input2 <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "b" "a"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1 {0}
|
||||
[1] 2 {1}
|
||||
State: 1
|
||||
State: 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<'EOF'
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "b" "a"
|
||||
acc-name: generalized-Buchi 4
|
||||
Acceptance: 4 Inf(0)&Inf(1)&Inf(2)&Inf(3)
|
||||
properties: trans-labels explicit-labels trans-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&!1] 1 {0 2}
|
||||
[!0&1] 2 {1 3}
|
||||
State: 1
|
||||
State: 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt input1 --product input2 --hoa | tee stdout
|
||||
run 0 ../../bin/autfilt -F stdout --isomorph expected
|
||||
|
||||
rm input1 input2 stdout expected
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2014 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
# et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat >input1 <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "a" "b"
|
||||
acc-name: all
|
||||
Acceptance: 0 t
|
||||
properties: trans-labels explicit-labels state-acc
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 1
|
||||
[!1] 2
|
||||
State: 1
|
||||
State: 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >input2 <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "b" "a"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1 {0}
|
||||
[1] 2 {1}
|
||||
State: 1
|
||||
State: 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 2 "b" "a"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0&!1] 1 {0}
|
||||
[!0&1] 2 {1}
|
||||
State: 1
|
||||
State: 2
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt input1 --product input2 --hoa | tee stdout
|
||||
run 0 ../../bin/autfilt -F stdout --isomorph expected
|
||||
rm input1 input2 stdout expected
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2009, 2014, 2015 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2006 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
# et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat >input1 <<EOF
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels trans-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 0
|
||||
[0] 0 {0}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >input2 <<EOF
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Fin(0)
|
||||
properties: trans-labels explicit-labels trans-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 0
|
||||
[!0] 0 {0}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<'EOF'
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
Acceptance: 2 Inf(0) & Fin(1)
|
||||
properties: trans-labels explicit-labels trans-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 0 {1}
|
||||
[0] 0 {0}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >unexpected <<'EOF'
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 1 "a"
|
||||
Acceptance: 2 Inf(0) & Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc complete deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0] 0 {1}
|
||||
[0] 0 {0}
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt input1 --product input2 --hoa | tee stdout
|
||||
run 0 ../../bin/autfilt -q stdout --isomorph expected
|
||||
run 1 ../../bin/autfilt -q stdout --isomorph unexpected
|
||||
|
||||
true
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
#!/bin/sh
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2008, 2009, 2013, 2014 Laboratoire de Recherche et
|
||||
# Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
||||
# Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
# Université Pierre et Marie Curie.
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
set -e
|
||||
|
||||
cat >input1 <<EOF
|
||||
HOA: v1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 3 "a" "b" "c"
|
||||
acc-name: Buchi
|
||||
Acceptance: 1 Inf(0)
|
||||
properties: trans-labels explicit-labels state-acc
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0] 1
|
||||
[1] 2
|
||||
State: 1
|
||||
State: 2 {0}
|
||||
[!0] 0
|
||||
[2] 1
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >input2 <<EOF
|
||||
HOA: v1
|
||||
States: 2
|
||||
Start: 0
|
||||
AP: 2 "b" "a"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0 {0}
|
||||
[0] 1
|
||||
State: 1 {1}
|
||||
[1] 0
|
||||
--END--
|
||||
EOF
|
||||
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 4
|
||||
Start: 0
|
||||
AP: 3 "b" "a" "c"
|
||||
acc-name: generalized-Buchi 3
|
||||
Acceptance: 3 Inf(0)&Inf(1)&Inf(2)
|
||||
properties: trans-labels explicit-labels state-acc
|
||||
--BODY--
|
||||
State: 0 {0 1}
|
||||
[0&1] 1
|
||||
[0] 2
|
||||
State: 1
|
||||
State: 2 {0 2}
|
||||
[1&2] 3
|
||||
State: 3
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt input1 --product input2 --hoa | tee stdout
|
||||
diff stdout expected
|
||||
|
||||
cat >expected <<EOF
|
||||
HOA: v1
|
||||
States: 1
|
||||
Start: 0
|
||||
AP: 0
|
||||
acc-name: all
|
||||
Acceptance: 0 t
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
--BODY--
|
||||
State: 0
|
||||
--END--
|
||||
EOF
|
||||
|
||||
run 0 ../../bin/autfilt input1 --product input2 --hoa --small | tee stdout
|
||||
run 0 ../../bin/autfilt -F stdout --isomorph expected
|
||||
|
||||
rm input1 input2 stdout expected
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue