implement SVA's first_match operator
* NEWS, doc/tl/tl.tex, doc/tl/tl.bib: Document it. * spot/parsetl/parsetl.yy, spot/parsetl/scantl.ll: Parse it. * spot/tl/formula.cc, spot/tl/formula.hh, spot/tl/dot.cc, spot/tl/mutation.cc, spot/tl/print.cc, spot/tl/randomltl.cc, spot/twaalgos/ltl2tgba_fm.cc: Adjust to support first_match. * spot/tl/mark.cc, spot/tl/simplify.cc, spot/tl/snf.cc, spot/tl/unabbrev.cc, spot/twa/formula2bdd.cc, spot/twaalgos/ltl2taa.cc: Ignore it. * tests/core/acc_word.test, tests/core/randpsl.test: Add more tests. * tests/core/rand.test, tests/core/unambig.test, tests/python/randltl.ipynb: Adjust. * tests/python/formulas.ipynb: Show first_match.
This commit is contained in:
parent
caf1eaa4ce
commit
6fac026454
24 changed files with 359 additions and 162 deletions
|
|
@ -224,6 +224,7 @@ using namespace spot;
|
|||
%token OP_ECONCAT "existential concat operator"
|
||||
%token OP_UCONCAT_NONO "universal non-overlapping concat operator"
|
||||
%token OP_ECONCAT_NONO "existential non-overlapping concat operator"
|
||||
%token OP_FIRST_MATCH "first_match"
|
||||
%token <str> ATOMIC_PROP "atomic proposition"
|
||||
%token OP_CONCAT "concat operator" OP_FUSION "fusion operator"
|
||||
%token CONST_TRUE "constant true" CONST_FALSE "constant false"
|
||||
|
|
@ -678,6 +679,8 @@ sere: booleanatom
|
|||
}
|
||||
| sere OP_EQUIV error
|
||||
{ missing_right_binop($$, $1, @2, "equivalent operator"); }
|
||||
| OP_FIRST_MATCH PAR_OPEN sere PAR_CLOSE
|
||||
{ $$ = fnode::unop(op::first_match, $3); }
|
||||
|
||||
bracedsere: BRACE_OPEN sere BRACE_CLOSE
|
||||
{ $$ = $2; }
|
||||
|
|
|
|||
|
|
@ -217,6 +217,8 @@ eol2 (\n\r)+|(\r\n)+
|
|||
/* ~ comes from Goal, ! from everybody else */
|
||||
{NOT} BEGIN(0); return token::OP_NOT;
|
||||
|
||||
"first_match" BEGIN(0); return token::OP_FIRST_MATCH;
|
||||
|
||||
/* SVA operators */
|
||||
"##"[0-9]+ {
|
||||
errno = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2009-2015, 2018 Laboratoire de Recherche et
|
||||
// Copyright (C) 2009-2015, 2018-2019 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é
|
||||
|
|
@ -88,6 +88,7 @@ namespace spot
|
|||
case op::AndNLM:
|
||||
case op::Star:
|
||||
case op::FStar:
|
||||
case op::first_match:
|
||||
childnum = 0; // No number for children
|
||||
break;
|
||||
case op::Xor:
|
||||
|
|
|
|||
|
|
@ -241,6 +241,7 @@ namespace spot
|
|||
C(Fusion);
|
||||
C(Star);
|
||||
C(FStar);
|
||||
C(first_match);
|
||||
#undef C
|
||||
}
|
||||
SPOT_UNREACHABLE();
|
||||
|
|
@ -826,6 +827,18 @@ namespace spot
|
|||
if (f->is_boolean())
|
||||
return unop(op::Not, f);
|
||||
break;
|
||||
case op::first_match:
|
||||
// first_match(first_match(sere)) = first_match(sere);
|
||||
// first_match(b) = b
|
||||
if (f->is(o) || f->is_boolean())
|
||||
return f;
|
||||
// first_match(r*) = [*0]
|
||||
if (f->accepts_eword())
|
||||
{
|
||||
f->destroy();
|
||||
return eword();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SPOT_UNREACHABLE();
|
||||
}
|
||||
|
|
@ -1617,6 +1630,23 @@ namespace spot
|
|||
}
|
||||
}
|
||||
break;
|
||||
case op::first_match:
|
||||
props = children[0]->props;
|
||||
// If first_match(r) == r && !(r;[*]), then it should follow
|
||||
// that if r is stutter-inv, then first_match(r) is
|
||||
// stutter-inv, so we do not reset the syntactic_si bit.
|
||||
assert(is_.sere_formula);
|
||||
is_.boolean = false;
|
||||
is_.ltl_formula = false;
|
||||
is_.psl_formula = false;
|
||||
is_.eventual = false;
|
||||
is_.universal = false;
|
||||
is_.syntactic_safety = false;
|
||||
is_.syntactic_guarantee = false;
|
||||
is_.syntactic_obligation = false;
|
||||
is_.syntactic_recurrence = false;
|
||||
is_.syntactic_persistence = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ namespace spot
|
|||
// star-like operators
|
||||
Star, ///< Star
|
||||
FStar, ///< Fustion Star
|
||||
first_match, ///< first_match(sere)
|
||||
};
|
||||
|
||||
#ifndef SWIG
|
||||
|
|
@ -942,6 +943,11 @@ namespace spot
|
|||
/// @{
|
||||
SPOT_DEF_UNOP(NegClosureMarked);
|
||||
/// @}
|
||||
|
||||
/// \brief Construct first_match(sere)
|
||||
/// @{
|
||||
SPOT_DEF_UNOP(first_match);
|
||||
/// @}
|
||||
#undef SPOT_DEF_UNOP
|
||||
|
||||
/// @{
|
||||
|
|
@ -1680,6 +1686,7 @@ namespace spot
|
|||
case op::Closure:
|
||||
case op::NegClosure:
|
||||
case op::NegClosureMarked:
|
||||
case op::first_match:
|
||||
return unop(o, trans((*this)[0], std::forward<Args>(args)...));
|
||||
case op::Xor:
|
||||
case op::Implies:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2010, 2012, 2014, 2015, 2018 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2010, 2012, 2014-2015, 2018-2019 Laboratoire de
|
||||
// Recherche et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -59,6 +59,7 @@ namespace spot
|
|||
case op::UConcat:
|
||||
case op::Concat:
|
||||
case op::Fusion:
|
||||
case op::first_match:
|
||||
res = f;
|
||||
break;
|
||||
case op::NegClosure:
|
||||
|
|
@ -120,6 +121,7 @@ namespace spot
|
|||
case op::EConcat:
|
||||
case op::EConcatMarked:
|
||||
case op::UConcat:
|
||||
case op::first_match:
|
||||
res = f;
|
||||
break;
|
||||
case op::Or:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014-2016, 2018 Laboratoire de Recherche et
|
||||
// Copyright (C) 2014-2016, 2018-2019 Laboratoire de Recherche et
|
||||
// Developpement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -83,6 +83,7 @@ namespace spot
|
|||
case op::X:
|
||||
case op::F:
|
||||
case op::G:
|
||||
case op::first_match:
|
||||
if ((opts_ & Mut_Remove_Ops)
|
||||
&& mutation_counter_-- == 0)
|
||||
return f[0];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2008, 2010, 2012-2016, 2018 Laboratoire de
|
||||
// Copyright (C) 2008, 2010, 2012-2016, 2018, 2019 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
|
||||
|
|
@ -71,6 +71,7 @@ namespace spot
|
|||
KFPlusBunop,
|
||||
KEqualBunop,
|
||||
KGotoBunop,
|
||||
KFirstMatch,
|
||||
};
|
||||
|
||||
const char* spot_kw[] = {
|
||||
|
|
@ -110,6 +111,7 @@ namespace spot
|
|||
"[:+]",
|
||||
"[=",
|
||||
"[->",
|
||||
"first_match",
|
||||
};
|
||||
|
||||
const char* spin_kw[] = {
|
||||
|
|
@ -149,6 +151,7 @@ namespace spot
|
|||
"[:+]", // not supported
|
||||
"[=", // not supported
|
||||
"[->", // not supported
|
||||
"first_match", // not supported
|
||||
};
|
||||
|
||||
const char* wring_kw[] = {
|
||||
|
|
@ -188,6 +191,7 @@ namespace spot
|
|||
"[:+]", // not supported
|
||||
"[=", // not supported
|
||||
"[->", // not supported
|
||||
"first_match", // not supported
|
||||
};
|
||||
|
||||
const char* utf8_kw[] = {
|
||||
|
|
@ -227,6 +231,7 @@ namespace spot
|
|||
"[:+]",
|
||||
"[=",
|
||||
"[->",
|
||||
"first_match",
|
||||
};
|
||||
|
||||
const char* latex_kw[] = {
|
||||
|
|
@ -266,6 +271,7 @@ namespace spot
|
|||
"\\SereFPlus{}",
|
||||
"\\SereEqual{",
|
||||
"\\SereGoto{",
|
||||
"\\FirstMatch",
|
||||
};
|
||||
|
||||
const char* sclatex_kw[] = {
|
||||
|
|
@ -309,6 +315,7 @@ namespace spot
|
|||
"^{\\mathsf{:}+}",
|
||||
"^{=",
|
||||
"^{\\to",
|
||||
"\\mathsf{first\\_match}",
|
||||
};
|
||||
|
||||
static bool
|
||||
|
|
@ -840,6 +847,13 @@ namespace spot
|
|||
}
|
||||
}
|
||||
break;
|
||||
case op::first_match:
|
||||
emit(KFirstMatch);
|
||||
os_ << '(';
|
||||
top_level_ = true;
|
||||
visit(f[0]);
|
||||
os_ << ')';
|
||||
break;
|
||||
}
|
||||
if (want_par)
|
||||
closep();
|
||||
|
|
@ -1113,6 +1127,7 @@ namespace spot
|
|||
case op::Fusion:
|
||||
case op::Star:
|
||||
case op::FStar:
|
||||
case op::first_match:
|
||||
SPOT_UNIMPLEMENTED();
|
||||
}
|
||||
for (auto c: f)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2008-2012, 2014-2016, 2018 Laboratoire de Recherche
|
||||
// Copyright (C) 2008-2012, 2014-2016, 2018-2019 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2005 Laboratoire d'Informatique de Paris 6
|
||||
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||
|
|
@ -311,7 +311,7 @@ namespace spot
|
|||
|
||||
// SEREs
|
||||
random_sere::random_sere(const atomic_prop_set* ap)
|
||||
: random_formula(11, ap), rb(ap)
|
||||
: random_formula(12, ap), rb(ap)
|
||||
{
|
||||
proba_[0].setup("eword", 1, eword_builder);
|
||||
proba_2_ = proba_ + 1;
|
||||
|
|
@ -321,11 +321,12 @@ namespace spot
|
|||
proba_[3].setup("star_b", 2, bunop_bounded_builder<op::Star>);
|
||||
proba_[4].setup("fstar", 2, bunop_unbounded_builder<op::FStar>);
|
||||
proba_[5].setup("fstar_b", 2, bunop_bounded_builder<op::FStar>);
|
||||
proba_[6].setup("and", 3, multop_builder<op::AndRat>);
|
||||
proba_[7].setup("andNLM", 3, multop_builder<op::AndNLM>);
|
||||
proba_[8].setup("or", 3, multop_builder<op::OrRat>);
|
||||
proba_[9].setup("concat", 3, multop_builder<op::Concat>);
|
||||
proba_[10].setup("fusion", 3, multop_builder<op::Fusion>);
|
||||
proba_[6].setup("first_match", 2, unop_builder<op::first_match>);
|
||||
proba_[7].setup("and", 3, multop_builder<op::AndRat>);
|
||||
proba_[8].setup("andNLM", 3, multop_builder<op::AndNLM>);
|
||||
proba_[9].setup("or", 3, multop_builder<op::OrRat>);
|
||||
proba_[10].setup("concat", 3, multop_builder<op::Concat>);
|
||||
proba_[11].setup("fusion", 3, multop_builder<op::Fusion>);
|
||||
|
||||
update_sums();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2011-2018 Laboratoire de Recherche et Developpement
|
||||
// Copyright (C) 2011-2019 Laboratoire de Recherche et Developpement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -498,6 +498,7 @@ namespace spot
|
|||
case op::Fusion:
|
||||
case op::Star:
|
||||
case op::FStar:
|
||||
case op::first_match:
|
||||
// !(a*) etc. should never occur.
|
||||
{
|
||||
assert(!negated);
|
||||
|
|
@ -855,6 +856,7 @@ namespace spot
|
|||
case op::ap:
|
||||
case op::Not:
|
||||
case op::FStar:
|
||||
case op::first_match:
|
||||
return f;
|
||||
case op::X:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2014, 2015, 2016, 2018 Laboratoire de Recherche
|
||||
// Copyright (C) 2012, 2014, 2015, 2016, 2018, 2019 Laboratoire de Recherche
|
||||
// et Developpement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -35,7 +35,6 @@ namespace spot
|
|||
class snf_visitor final
|
||||
{
|
||||
protected:
|
||||
formula result_;
|
||||
snf_cache* cache_;
|
||||
public:
|
||||
snf_visitor(snf_cache* c)
|
||||
|
|
@ -125,6 +124,7 @@ namespace spot
|
|||
SPOT_UNREACHABLE();
|
||||
case op::AndRat: // Can AndRat be handled better?
|
||||
case op::FStar: // Can FStar be handled better?
|
||||
case op::first_match: // Can first_match be handled better?
|
||||
out = f;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2018 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2015, 2018-2019 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -113,6 +113,7 @@ namespace spot
|
|||
case op::Fusion:
|
||||
case op::Star:
|
||||
case op::FStar:
|
||||
case op::first_match:
|
||||
break;
|
||||
case op::F:
|
||||
// F e = e if e eventual
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2009-2018 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2009-2019 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),
|
||||
|
|
@ -99,6 +99,7 @@ namespace spot
|
|||
case op::AndNLM:
|
||||
case op::OrRat:
|
||||
case op::AndRat:
|
||||
case op::first_match:
|
||||
SPOT_UNIMPLEMENTED();
|
||||
case op::ap:
|
||||
return bdd_ithvar(d->register_proposition(f, owner));
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ namespace spot
|
|||
case op::AndNLM:
|
||||
case op::AndRat:
|
||||
case op::OrRat:
|
||||
case op::first_match:
|
||||
SPOT_UNIMPLEMENTED();
|
||||
|
||||
case op::U:
|
||||
|
|
|
|||
|
|
@ -867,6 +867,35 @@ namespace spot
|
|||
}
|
||||
return res;
|
||||
}
|
||||
case op::first_match:
|
||||
{
|
||||
assert(f.size() == 1);
|
||||
assert(!f.accepts_eword());
|
||||
// Build deterministic successors, and
|
||||
// rewrite each destination D as first_match(D).
|
||||
// This will handle the semantic of the operator automatically,
|
||||
// since first_match(D) = [*0] if D accepts [*0].
|
||||
bdd res_ndet = recurse(f[0]);
|
||||
bdd res_det = bddfalse;
|
||||
bdd var_set = bdd_existcomp(bdd_support(res_ndet), dict_.var_set);
|
||||
bdd all_props = bdd_existcomp(res_ndet, dict_.var_set);
|
||||
while (all_props != bddfalse)
|
||||
{
|
||||
bdd label = bdd_satoneset(all_props, var_set, bddtrue);
|
||||
all_props -= label;
|
||||
|
||||
formula dest =
|
||||
dict_.bdd_to_sere(bdd_appex(res_ndet, label, bddop_and,
|
||||
dict_.var_set));
|
||||
dest = formula::first_match(dest);
|
||||
if (to_concat_)
|
||||
dest = formula::Concat({dest, to_concat_});
|
||||
if (!dest.is_ff())
|
||||
res_det |= label
|
||||
& bdd_ithvar(dict_.register_next_variable(dest));
|
||||
}
|
||||
return res_det;
|
||||
}
|
||||
}
|
||||
SPOT_UNREACHABLE();
|
||||
}
|
||||
|
|
@ -1311,6 +1340,7 @@ namespace spot
|
|||
}
|
||||
case op::Star:
|
||||
case op::FStar:
|
||||
case op::first_match:
|
||||
SPOT_UNREACHABLE(); // Not an LTL operator
|
||||
// r(f1 logical-op f2) = r(f1) logical-op r(f2)
|
||||
case op::Xor:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue