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:
Alexandre Duret-Lutz 2019-05-06 14:59:05 +02:00
parent caf1eaa4ce
commit 6fac026454
24 changed files with 359 additions and 162 deletions

View file

@ -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:

View file

@ -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;
}
}

View file

@ -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:

View file

@ -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:

View file

@ -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];

View file

@ -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)

View file

@ -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();
}

View file

@ -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:
{

View file

@ -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;
}

View file

@ -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