introduce delay_branching_here
This is motivated by an example sent by Edmond Irani Liu, that will be tested in next patch. * spot/twaalgos/dbranch.cc, spot/twaalgos/dbranch.hh: New files. * python/spot/impl.i, spot/twaalgos/Makefile.am: Add them. * spot/twaalgos/translate.cc: Call delay_branching_here unconditionally. * spot/twa/twagraph.cc (defrag_states): Do not assume that games are alternating. * tests/core/genltl.test: Adjust expected numbers. * tests/python/dbranch.py: New file. * tests/Makefile.am: Add it.
This commit is contained in:
parent
aa7992c65f
commit
3efab05cf2
10 changed files with 378 additions and 24 deletions
9
NEWS
9
NEWS
|
|
@ -142,6 +142,15 @@ New in spot 2.10.6.dev (not yet released)
|
||||||
succesors, should be called before running simulation-based
|
succesors, should be called before running simulation-based
|
||||||
reductions.
|
reductions.
|
||||||
|
|
||||||
|
- A new function delay_branching_here(aut) can be used to simplify
|
||||||
|
some non-deterministic branching. If two transitions (q₁,ℓ,M,q₂)
|
||||||
|
and (q₁,ℓ,M,q₃) differ only by their destination state, and are
|
||||||
|
the only incoming transitions of their destination states, then q₂
|
||||||
|
and q₃ can be merged (taking the union of their outgoing
|
||||||
|
transitions). This is cheap function is automatically called by
|
||||||
|
spot::translate() after translation of a formula to GBA, before
|
||||||
|
further simplification.
|
||||||
|
|
||||||
- spot::parallel_policy is an object that can be passed to some
|
- spot::parallel_policy is an object that can be passed to some
|
||||||
algorithm to specify how many threads can be used if Spot has been
|
algorithm to specify how many threads can be used if Spot has been
|
||||||
compiled with --enable-pthread. Currently, only
|
compiled with --enable-pthread. Currently, only
|
||||||
|
|
|
||||||
|
|
@ -114,13 +114,14 @@
|
||||||
#include <spot/twaalgos/aiger.hh>
|
#include <spot/twaalgos/aiger.hh>
|
||||||
#include <spot/twaalgos/alternation.hh>
|
#include <spot/twaalgos/alternation.hh>
|
||||||
#include <spot/twaalgos/cleanacc.hh>
|
#include <spot/twaalgos/cleanacc.hh>
|
||||||
#include <spot/twaalgos/degen.hh>
|
|
||||||
#include <spot/twaalgos/dot.hh>
|
|
||||||
#include <spot/twaalgos/dualize.hh>
|
|
||||||
#include <spot/twaalgos/cobuchi.hh>
|
#include <spot/twaalgos/cobuchi.hh>
|
||||||
#include <spot/twaalgos/copy.hh>
|
#include <spot/twaalgos/copy.hh>
|
||||||
#include <spot/twaalgos/complete.hh>
|
#include <spot/twaalgos/complete.hh>
|
||||||
#include <spot/twaalgos/complement.hh>
|
#include <spot/twaalgos/complement.hh>
|
||||||
|
#include <spot/twaalgos/dbranch.hh>
|
||||||
|
#include <spot/twaalgos/degen.hh>
|
||||||
|
#include <spot/twaalgos/dot.hh>
|
||||||
|
#include <spot/twaalgos/dualize.hh>
|
||||||
#include <spot/twaalgos/emptiness.hh>
|
#include <spot/twaalgos/emptiness.hh>
|
||||||
#include <spot/twaalgos/gtec/gtec.hh>
|
#include <spot/twaalgos/gtec/gtec.hh>
|
||||||
#include <spot/twaalgos/genem.hh>
|
#include <spot/twaalgos/genem.hh>
|
||||||
|
|
@ -678,11 +679,14 @@ def state_is_accepting(self, src) -> "bool":
|
||||||
%include <spot/twaalgos/aiger.hh>
|
%include <spot/twaalgos/aiger.hh>
|
||||||
%include <spot/twaalgos/alternation.hh>
|
%include <spot/twaalgos/alternation.hh>
|
||||||
%include <spot/twaalgos/cleanacc.hh>
|
%include <spot/twaalgos/cleanacc.hh>
|
||||||
%include <spot/twaalgos/degen.hh>
|
|
||||||
%include <spot/twaalgos/dot.hh>
|
|
||||||
%include <spot/twaalgos/cobuchi.hh>
|
%include <spot/twaalgos/cobuchi.hh>
|
||||||
%include <spot/twaalgos/copy.hh>
|
%include <spot/twaalgos/copy.hh>
|
||||||
%include <spot/twaalgos/complete.hh>
|
%include <spot/twaalgos/complete.hh>
|
||||||
|
%include <spot/twaalgos/dbranch.hh>
|
||||||
|
%include <spot/twaalgos/degen.hh>
|
||||||
|
%include <spot/twaalgos/determinize.hh>
|
||||||
|
%include <spot/twaalgos/dot.hh>
|
||||||
|
%include <spot/twaalgos/dualize.hh>
|
||||||
%feature("flatnested") spot::twa_run::step;
|
%feature("flatnested") spot::twa_run::step;
|
||||||
%include <spot/twaalgos/emptiness.hh>
|
%include <spot/twaalgos/emptiness.hh>
|
||||||
%template(list_step) std::list<spot::twa_run::step>;
|
%template(list_step) std::list<spot::twa_run::step>;
|
||||||
|
|
@ -694,8 +698,6 @@ def state_is_accepting(self, src) -> "bool":
|
||||||
%include <spot/twaalgos/gfguarantee.hh>
|
%include <spot/twaalgos/gfguarantee.hh>
|
||||||
%include <spot/twaalgos/compsusp.hh>
|
%include <spot/twaalgos/compsusp.hh>
|
||||||
%include <spot/twaalgos/contains.hh>
|
%include <spot/twaalgos/contains.hh>
|
||||||
%include <spot/twaalgos/determinize.hh>
|
|
||||||
%include <spot/twaalgos/dualize.hh>
|
|
||||||
%include <spot/twaalgos/langmap.hh>
|
%include <spot/twaalgos/langmap.hh>
|
||||||
%include <spot/twaalgos/magic.hh>
|
%include <spot/twaalgos/magic.hh>
|
||||||
%include <spot/twaalgos/minimize.hh>
|
%include <spot/twaalgos/minimize.hh>
|
||||||
|
|
|
||||||
|
|
@ -1323,18 +1323,6 @@ namespace spot
|
||||||
}
|
}
|
||||||
init_number_ = newst[init_number_];
|
init_number_ = newst[init_number_];
|
||||||
g_.defrag_states(newst, used_states);
|
g_.defrag_states(newst, used_states);
|
||||||
// Make sure we did not mess up the structure
|
|
||||||
assert([&]()
|
|
||||||
{
|
|
||||||
if (auto sp = get_named_prop<std::vector<bool>>("state-player"))
|
|
||||||
{
|
|
||||||
for (const auto& e : edges())
|
|
||||||
if (sp->at(e.src) == sp->at(e.dst))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}() && "Game not alternating!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void twa_graph::remove_unused_ap()
|
void twa_graph::remove_unused_ap()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
## -*- coding: utf-8 -*-
|
## -*- coding: utf-8 -*-
|
||||||
## Copyright (C) 2008-2018, 2020-2021 Laboratoire de Recherche et
|
## Copyright (C) 2008-2018, 2020-2022 Laboratoire de Recherche et
|
||||||
## Développement de l'Epita (LRDE).
|
## Développement de l'Epita (LRDE).
|
||||||
## Copyright (C) 2003-2005 Laboratoire d'Informatique de Paris 6
|
## Copyright (C) 2003-2005 Laboratoire d'Informatique de Paris 6
|
||||||
## (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
## (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||||
|
|
@ -42,6 +42,7 @@ twaalgos_HEADERS = \
|
||||||
contains.hh \
|
contains.hh \
|
||||||
copy.hh \
|
copy.hh \
|
||||||
cycles.hh \
|
cycles.hh \
|
||||||
|
dbranch.hh \
|
||||||
degen.hh \
|
degen.hh \
|
||||||
determinize.hh \
|
determinize.hh \
|
||||||
dot.hh \
|
dot.hh \
|
||||||
|
|
@ -115,6 +116,7 @@ libtwaalgos_la_SOURCES = \
|
||||||
compsusp.cc \
|
compsusp.cc \
|
||||||
contains.cc \
|
contains.cc \
|
||||||
cycles.cc \
|
cycles.cc \
|
||||||
|
dbranch.cc \
|
||||||
degen.cc \
|
degen.cc \
|
||||||
determinize.cc \
|
determinize.cc \
|
||||||
dot.cc \
|
dot.cc \
|
||||||
|
|
|
||||||
163
spot/twaalgos/dbranch.cc
Normal file
163
spot/twaalgos/dbranch.cc
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2022 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 "config.h"
|
||||||
|
|
||||||
|
#include <spot/twaalgos/dbranch.hh>
|
||||||
|
#include <spot/misc/bddlt.hh>
|
||||||
|
#include <spot/priv/robin_hood.hh>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
typedef std::pair<bdd, acc_cond::mark_t> bdd_color;
|
||||||
|
|
||||||
|
struct bdd_color_hash
|
||||||
|
{
|
||||||
|
size_t
|
||||||
|
operator()(const bdd_color& bc) const noexcept
|
||||||
|
{
|
||||||
|
return bc.first.id() ^ bc.second.hash();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool is_game>
|
||||||
|
bool delay_branching_aux(const twa_graph_ptr& aut, std::vector<bool>* owner)
|
||||||
|
{
|
||||||
|
unsigned ns = aut->num_states();
|
||||||
|
// number of predecessors of each state
|
||||||
|
std::vector<unsigned> pred_count(ns, 0);
|
||||||
|
unsigned init = aut->get_init_state_number();
|
||||||
|
pred_count[init] = 2; // pretend the initial state has too many
|
||||||
|
// predecessors, so it does not get fused.
|
||||||
|
// for each state, number of successors that have a single predecessors
|
||||||
|
std::vector<unsigned> succ_cand(ns, 0);
|
||||||
|
for (auto& e: aut->edges())
|
||||||
|
for (unsigned d: aut->univ_dests(e))
|
||||||
|
{
|
||||||
|
// Note that e.dst might be a destination group in
|
||||||
|
// alternating automata.
|
||||||
|
unsigned pc = ++pred_count[d];
|
||||||
|
succ_cand[e.src] += (pc == 1) - (pc == 2);
|
||||||
|
}
|
||||||
|
bool changed = false;
|
||||||
|
typedef robin_hood::unordered_map<bdd_color, unsigned,
|
||||||
|
bdd_color_hash> hashmap_t;
|
||||||
|
hashmap_t first_dest[1 + is_game];
|
||||||
|
auto& g = aut->get_graph();
|
||||||
|
|
||||||
|
// setup a DFS
|
||||||
|
std::vector<bool> seen(ns);
|
||||||
|
std::stack<unsigned> todo;
|
||||||
|
auto push_state = [&](unsigned state)
|
||||||
|
{
|
||||||
|
todo.push(state);
|
||||||
|
seen[state] = true;
|
||||||
|
};
|
||||||
|
push_state(init);
|
||||||
|
|
||||||
|
while (!todo.empty())
|
||||||
|
{
|
||||||
|
unsigned src = todo.top();
|
||||||
|
todo.pop();
|
||||||
|
if (succ_cand[src] < 2) // nothing to merge
|
||||||
|
{
|
||||||
|
for (auto& e: aut->out(src))
|
||||||
|
for (unsigned d: aut->univ_dests(e))
|
||||||
|
if (!seen[d])
|
||||||
|
push_state(d);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
first_dest[0].clear();
|
||||||
|
if constexpr (is_game)
|
||||||
|
first_dest[1].clear();
|
||||||
|
auto it = g.out_iteraser(src);
|
||||||
|
while (it)
|
||||||
|
{
|
||||||
|
unsigned canddst = it->dst;
|
||||||
|
for (unsigned d: aut->univ_dests(canddst))
|
||||||
|
if (!seen[d])
|
||||||
|
push_state(d);
|
||||||
|
if (aut->is_univ_dest(canddst) || pred_count[canddst] != 1)
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (it->cond == bddfalse)
|
||||||
|
{
|
||||||
|
it.erase();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unsigned mapidx = is_game ? (*owner)[canddst] : 0;
|
||||||
|
auto [it2, inserted] =
|
||||||
|
first_dest[mapidx].emplace(bdd_color{it->cond, it->acc},
|
||||||
|
canddst);
|
||||||
|
if (inserted)
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unsigned mergedst = it2->second;
|
||||||
|
// we have to merge canddst into mergedst. This is as
|
||||||
|
// simple as:
|
||||||
|
// 1) connecting their list of transitions
|
||||||
|
unsigned& mergedfirst = g.state_storage(mergedst).succ;
|
||||||
|
unsigned& mergedlast = g.state_storage(mergedst).succ_tail;
|
||||||
|
unsigned& candfirst = g.state_storage(canddst).succ;
|
||||||
|
unsigned& candlast = g.state_storage(canddst).succ_tail;
|
||||||
|
if (mergedlast)
|
||||||
|
aut->edge_storage(mergedlast).next_succ = candfirst;
|
||||||
|
else // mergedst had now successor
|
||||||
|
mergedfirst = candfirst;
|
||||||
|
mergedlast = candlast;
|
||||||
|
// 2) updating the source of the merged transitions
|
||||||
|
for (unsigned e2 = candfirst; e2 != 0;)
|
||||||
|
{
|
||||||
|
auto& edge = aut->edge_storage(e2);
|
||||||
|
edge.src = mergedst;
|
||||||
|
e2 = edge.next_succ;
|
||||||
|
}
|
||||||
|
// 3) deleting the edge to canddst.
|
||||||
|
candfirst = candlast = 0;
|
||||||
|
it.erase();
|
||||||
|
// 4) updating succ_cand
|
||||||
|
succ_cand[mergedst] += succ_cand[canddst];
|
||||||
|
succ_cand[canddst] = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool delay_branching_here(const twa_graph_ptr& aut)
|
||||||
|
{
|
||||||
|
if (aut->prop_universal())
|
||||||
|
return false;
|
||||||
|
auto owner = aut->get_named_prop<std::vector<bool>>("state-player");
|
||||||
|
if (SPOT_UNLIKELY(owner))
|
||||||
|
return delay_branching_aux<true>(aut, owner);
|
||||||
|
else
|
||||||
|
return delay_branching_aux<false>(aut, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
spot/twaalgos/dbranch.hh
Normal file
36
spot/twaalgos/dbranch.hh
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
// -*- coding: utf-8 -*-
|
||||||
|
// Copyright (C) 2022 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 <spot/twa/twagraph.hh>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
/// \ingroup twa_algorithms
|
||||||
|
/// \brief Merge states to delay
|
||||||
|
///
|
||||||
|
/// If a state (x) has two outgoing transitions (x,l,m,y) and
|
||||||
|
/// (x,l,m,z) going to states (x) and (y) that have no other
|
||||||
|
/// incoming edges, then (y) and (z) can be merged (keeping the
|
||||||
|
/// union of their outgoing destinations).
|
||||||
|
///
|
||||||
|
/// \return true iff the automaton was modified.
|
||||||
|
SPOT_API bool delay_branching_here(const twa_graph_ptr& aut);
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2018, 2020-2021 Laboratoire de Recherche et
|
// Copyright (C) 2013-2018, 2020-2022 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <spot/twaalgos/product.hh>
|
#include <spot/twaalgos/product.hh>
|
||||||
#include <spot/twaalgos/sccinfo.hh>
|
#include <spot/twaalgos/sccinfo.hh>
|
||||||
#include <spot/twaalgos/hoa.hh>
|
#include <spot/twaalgos/hoa.hh>
|
||||||
|
#include <spot/twaalgos/dbranch.hh>
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
|
@ -401,6 +402,11 @@ namespace spot
|
||||||
aut = ltl_to_tgba_fm(r, simpl_->get_dict(), exprop,
|
aut = ltl_to_tgba_fm(r, simpl_->get_dict(), exprop,
|
||||||
true, false, false, nullptr, nullptr,
|
true, false, false, nullptr, nullptr,
|
||||||
unambiguous);
|
unambiguous);
|
||||||
|
if (delay_branching_here(aut))
|
||||||
|
{
|
||||||
|
aut->purge_unreachable_states();
|
||||||
|
aut->merge_edges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aut = this->postprocessor::run(aut, r);
|
aut = this->postprocessor::run(aut, r);
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,7 @@ TESTS_python = \
|
||||||
python/bddnqueen.py \
|
python/bddnqueen.py \
|
||||||
python/bugdet.py \
|
python/bugdet.py \
|
||||||
python/complement_semidet.py \
|
python/complement_semidet.py \
|
||||||
|
python/dbranch.py \
|
||||||
python/declenv.py \
|
python/declenv.py \
|
||||||
python/decompose_scc.py \
|
python/decompose_scc.py \
|
||||||
python/det.py \
|
python/det.py \
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2016-2021 Laboratoire de Recherche et Développement
|
# Copyright (C) 2016-2022 Laboratoire de Recherche et Développement
|
||||||
# de l'Epita (LRDE).
|
# de l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
|
|
@ -134,8 +134,8 @@ genltl --kr-n2=1..2 --kr-nlogn=1..2 --kr-n=1..2 --gxf-and=0..3 --fxg-or=0..3 \
|
||||||
--pps-arbiter-standard=2..3 --pps-arbiter-strict=2..3 --format=%F=%L,%f |
|
--pps-arbiter-standard=2..3 --pps-arbiter-strict=2..3 --format=%F=%L,%f |
|
||||||
ltl2tgba --low --det -F-/2 --stats='%<,%s' > out
|
ltl2tgba --low --det -F-/2 --stats='%<,%s' > out
|
||||||
cat >exp<<EOF
|
cat >exp<<EOF
|
||||||
kv-psi=1,10
|
kv-psi=1,9
|
||||||
kv-psi=2,24
|
kv-psi=2,19
|
||||||
kr-nlogn=1,16
|
kr-nlogn=1,16
|
||||||
kr-nlogn=2,44
|
kr-nlogn=2,44
|
||||||
kr-n=1,10
|
kr-n=1,10
|
||||||
|
|
|
||||||
147
tests/python/dbranch.py
Normal file
147
tests/python/dbranch.py
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2022 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/>.
|
||||||
|
|
||||||
|
# Test that the spot.gen package works, in particular, we want
|
||||||
|
# to make sure that the objects created from spot.gen methods
|
||||||
|
# are usable with methods from the spot package.
|
||||||
|
|
||||||
|
|
||||||
|
import spot
|
||||||
|
from unittest import TestCase
|
||||||
|
tc = TestCase()
|
||||||
|
|
||||||
|
aut5 = spot.automaton("""HOA: v1 States: 28 Start: 0 AP: 4 "alive" "b"
|
||||||
|
"a" "c" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels
|
||||||
|
explicit-labels state-acc very-weak --BODY-- State: 0 [0] 1 [0] 2 [0]
|
||||||
|
3 [0] 4 [0] 5 [0&!1] 6 [0] 7 State: 1 [0] 8 State: 2 [!0] 9 [0] 10
|
||||||
|
State: 3 [!0] 9 [0] 11 State: 4 [!0] 9 [0] 12 State: 5 [!0] 9 [0] 13
|
||||||
|
State: 6 [!0] 9 [0&!1] 14 State: 7 [!0] 9 [0&!1&!2] 14 State: 8 [0] 15
|
||||||
|
State: 9 {0} [!0] 9 State: 10 [!0] 9 [0] 16 State: 11 [!0] 9 [0] 17
|
||||||
|
State: 12 [!0] 9 [0] 18 State: 13 [!0] 9 [0&!1&!2] 19 State: 14 [!0] 9
|
||||||
|
[0&!1] 19 State: 15 [0] 20 State: 16 [!0] 9 [0] 21 State: 17 [!0] 9
|
||||||
|
[0] 22 State: 18 [!0] 9 [0&!1&!2] 23 State: 19 [!0] 9 [0&!1] 23 State:
|
||||||
|
20 [0] 24 State: 21 [!0] 9 [0] 25 State: 22 [!0] 9 [0&!1&!2] 26 State:
|
||||||
|
23 [!0] 9 [0&!1] 26 State: 24 [0&3] 27 State: 25 [!0] 9 [0&!1&!2] 27
|
||||||
|
State: 26 [!0] 9 [0&!1] 27 State: 27 [!0] 9 [0] 27 --END--""")
|
||||||
|
|
||||||
|
copy = spot.make_twa_graph(aut5, spot.twa_prop_set.all())
|
||||||
|
|
||||||
|
tc.assertFalse(spot.is_deterministic(aut5))
|
||||||
|
if spot.delay_branching_here(aut5):
|
||||||
|
aut5.purge_unreachable_states()
|
||||||
|
aut5.merge_edges()
|
||||||
|
tc.assertEqual(aut5.num_states(), 13)
|
||||||
|
tc.assertEqual(aut5.num_edges(), 29)
|
||||||
|
tc.assertTrue(spot.are_equivalent(copy, aut5))
|
||||||
|
|
||||||
|
a = spot.automaton("""HOA: v1 States: 8 Start: 0 AP: 3 "a" "b" "c"
|
||||||
|
Acceptance: 0 t --BODY-- State: 0 [0] 1 [0] 2 [0] 3 State: 1 [!1] 4&5
|
||||||
|
[1] 5&6 State: 2 [0] 4&6 State: 3 [0] 3&6 State: 4 [!0] 7 State: 5
|
||||||
|
[!0] 7 State: 6 [!0] 6 State: 7 [0] 7 --END--""")
|
||||||
|
|
||||||
|
copy = spot.make_twa_graph(a, spot.twa_prop_set.all())
|
||||||
|
if spot.delay_branching_here(a):
|
||||||
|
a.purge_unreachable_states()
|
||||||
|
a.merge_edges()
|
||||||
|
tc.assertEqual(a.to_str(), """HOA: v1
|
||||||
|
States: 7
|
||||||
|
Start: 0
|
||||||
|
AP: 3 "b" "a" "c"
|
||||||
|
acc-name: all
|
||||||
|
Acceptance: 0 t
|
||||||
|
properties: trans-labels explicit-labels state-acc univ-branch
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[1] 1
|
||||||
|
[1] 2
|
||||||
|
State: 1
|
||||||
|
[1] 3&5
|
||||||
|
[0] 4&5
|
||||||
|
[!0] 3&4
|
||||||
|
State: 2
|
||||||
|
[1] 2&5
|
||||||
|
State: 3
|
||||||
|
[!1] 6
|
||||||
|
State: 4
|
||||||
|
[!1] 6
|
||||||
|
State: 5
|
||||||
|
[!1] 5
|
||||||
|
State: 6
|
||||||
|
[1] 6
|
||||||
|
--END--""")
|
||||||
|
|
||||||
|
a = spot.automaton("""HOA: v1
|
||||||
|
States: 9
|
||||||
|
Start: 0 AP: 2 "a" "b"
|
||||||
|
spot.state-player: 0 1 1 0 0 0 0 1 1
|
||||||
|
Acceptance: 0 t
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[0] 1
|
||||||
|
[0] 2
|
||||||
|
[0] 3
|
||||||
|
[0] 4
|
||||||
|
State: 1
|
||||||
|
[1] 5
|
||||||
|
State: 2
|
||||||
|
[!1] 6
|
||||||
|
State: 3
|
||||||
|
[1] 7
|
||||||
|
State: 4
|
||||||
|
[!1] 8
|
||||||
|
State: 5
|
||||||
|
[t] 5
|
||||||
|
State: 6
|
||||||
|
[t] 6
|
||||||
|
State: 7
|
||||||
|
[t] 7
|
||||||
|
State: 8
|
||||||
|
[t] 8
|
||||||
|
--END--""")
|
||||||
|
copy = spot.make_twa_graph(a, spot.twa_prop_set.all())
|
||||||
|
if spot.delay_branching_here(a):
|
||||||
|
a.purge_unreachable_states()
|
||||||
|
tc.assertTrue(spot.are_equivalent(a, copy))
|
||||||
|
tc.assertEqual(a.to_str(), """HOA: v1
|
||||||
|
States: 7
|
||||||
|
Start: 0
|
||||||
|
AP: 2 "b" "a"
|
||||||
|
acc-name: all
|
||||||
|
Acceptance: 0 t
|
||||||
|
properties: trans-labels explicit-labels state-acc very-weak
|
||||||
|
spot-state-player: 0 1 0 0 0 1 1
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[1] 1
|
||||||
|
[1] 2
|
||||||
|
State: 1
|
||||||
|
[0] 3
|
||||||
|
[!0] 4
|
||||||
|
State: 2
|
||||||
|
[0] 5
|
||||||
|
[!0] 6
|
||||||
|
State: 3
|
||||||
|
[t] 3
|
||||||
|
State: 4
|
||||||
|
[t] 4
|
||||||
|
State: 5
|
||||||
|
[t] 5
|
||||||
|
State: 6
|
||||||
|
[t] 6
|
||||||
|
--END--""")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue