psl: add support for the [:*i..j] operator
This operator is to ':' what [*i..j] is to ';'. Part of issue #51. * doc/tl/tl.tex: Document syntax, semantic, and trivial simplifications. * doc/tl/spotltl.sty: Add macros for new operators. * src/ltlast/bunop.cc, src/ltlast/bunop.hh: Implement it. * src/ltlast/multop.cc: Add some trivial simplifications. * src/ltlparse/ltlparse.yy, src/ltlparse/ltlscan.ll: Parse it. * src/ltltest/equals.test, src/ltltest/latex.test, src/tgbatest/ltl2tgba.test: Add more tests. * src/ltlvisit/randomltl.cc: Output this operator in random PSL formulas. * src/ltltest/rand.test: Adjust. * src/tgbaalgos/ltl2tgba_fm.cc: Add translation rules. * src/ltlvisit/tostring.cc: Add pretty printing code. * src/ltlvisit/simplify.cc, src/ltlvisit/snf.cc: Adjust switches. * NEWS: Mention the new operator.
This commit is contained in:
parent
eebbcac281
commit
a79db4eefe
17 changed files with 442 additions and 162 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire
|
||||
// de Recherche et Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2008, 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.
|
||||
|
|
@ -708,20 +708,30 @@ namespace spot
|
|||
unsigned max = bo->max();
|
||||
|
||||
assert(max > 0);
|
||||
bunop::type op = bo->op();
|
||||
|
||||
// we will interpret
|
||||
// c[*i..j]
|
||||
// or c[:*i..j]
|
||||
// as
|
||||
// c;c[*i-1..j-1]
|
||||
// or c:c[*i-1..j-1]
|
||||
// \........../
|
||||
// this is f
|
||||
unsigned min2 = (min == 0) ? 0 : (min - 1);
|
||||
unsigned max2 =
|
||||
(max == bunop::unbounded) ? bunop::unbounded : (max - 1);
|
||||
f = bunop::instance(op, bo->child()->clone(), min2, max2);
|
||||
|
||||
// If we have something to append, we can actually append it
|
||||
// to f. This is correct even in the case of FStar, as f
|
||||
// cannot accept [*0].
|
||||
if (to_concat_)
|
||||
f = multop::instance(multop::Concat, f, to_concat_->clone());
|
||||
|
||||
bunop::type op = bo->op();
|
||||
switch (op)
|
||||
{
|
||||
case bunop::Star:
|
||||
f = bunop::instance(op, bo->child()->clone(), min2, max2);
|
||||
|
||||
if (to_concat_)
|
||||
f = multop::instance(multop::Concat, f, to_concat_->clone());
|
||||
|
||||
if (!bo->child()->accepts_eword())
|
||||
{
|
||||
// f*;g -> f;f*;g | g
|
||||
|
|
@ -777,6 +787,57 @@ namespace spot
|
|||
res_ |= now_to_concat();
|
||||
}
|
||||
return;
|
||||
case bunop::FStar:
|
||||
{
|
||||
res_ = recurse(bo->child());
|
||||
bdd tail_bdd;
|
||||
bool tail_computed = false;
|
||||
|
||||
minato_isop isop(res_);
|
||||
bdd cube;
|
||||
res_ = bddfalse;
|
||||
if (min == 0)
|
||||
{
|
||||
// f[:*0..j];g can be satisfied by X(g).
|
||||
res_ = next_to_concat();
|
||||
}
|
||||
while ((cube = isop.next()) != bddfalse)
|
||||
{
|
||||
bdd label = bdd_exist(cube, dict_.next_set);
|
||||
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
|
||||
const formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
|
||||
|
||||
// The destination is a final state. Make sure we
|
||||
// can also exit if tail is satisfied. We do not
|
||||
// even have to check the tail if min == 0.
|
||||
if (dest->accepts_eword() && min != 0)
|
||||
{
|
||||
if (!tail_computed)
|
||||
{
|
||||
tail_bdd = recurse(f);
|
||||
tail_computed = true;
|
||||
}
|
||||
res_ |= label & tail_bdd;
|
||||
}
|
||||
|
||||
// If the destination is not 0 or [*0], it means it
|
||||
// can have successors. Fusion the tail.
|
||||
if (dest != constant::false_instance()
|
||||
&& dest != constant::empty_word_instance())
|
||||
{
|
||||
const formula* dest2 =
|
||||
multop::instance(multop::Fusion, dest, f->clone());
|
||||
if (dest2 != constant::false_instance())
|
||||
{
|
||||
int x = dict_.register_next_variable(dest2);
|
||||
dest2->destroy();
|
||||
res_ |= label & bdd_ithvar(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
f->destroy();
|
||||
}
|
||||
return;
|
||||
}
|
||||
SPOT_UNREACHABLE();
|
||||
}
|
||||
|
|
@ -961,8 +1022,8 @@ namespace spot
|
|||
// If the destination is not 0 or [*0], it means it
|
||||
// can have successors. Fusion the tail and append
|
||||
// anything to concatenate.
|
||||
if (dest->kind() != formula::Constant
|
||||
|| dest == ltl::constant::true_instance())
|
||||
if (dest != constant::false_instance()
|
||||
&& dest != constant::empty_word_instance())
|
||||
{
|
||||
const formula* dest2 =
|
||||
multop::instance(multop::Fusion, dest, tail->clone());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue