product: add a product_or variant
* src/twaalgos/product.cc, src/twaalgos/product.hh: Implement the variance. * src/bin/autfilt.cc: Expose it. * src/tests/prodor.test: New file. * src/tests/Makefile.am: Add it. * NEWS: Mention it.
This commit is contained in:
parent
b77f7e24c3
commit
51a3cfcede
6 changed files with 331 additions and 84 deletions
36
NEWS
36
NEWS
|
|
@ -5,6 +5,16 @@ New in spot 1.99.3a (not yet released)
|
||||||
exactly one acceptance sets. This is useful when targeting parity
|
exactly one acceptance sets. This is useful when targeting parity
|
||||||
acceptance.
|
acceptance.
|
||||||
|
|
||||||
|
* autfilt has a new --product-or option. This builds a synchronized
|
||||||
|
product of two (completed of needed) automata in order to
|
||||||
|
recognize the *sum* of their languages. This works by just using
|
||||||
|
the disjunction of their acceptance conditions (with appropriate
|
||||||
|
renumbering of the acceptance sets).
|
||||||
|
|
||||||
|
For consistency, the --product option (that builds a synchronized
|
||||||
|
product that recognizes the *intersection* of the languages) now
|
||||||
|
also has a --product-and alias.
|
||||||
|
|
||||||
* the parser for ltl2dstar's format has been merged with the parser
|
* the parser for ltl2dstar's format has been merged with the parser
|
||||||
for the other automata formats. This implies two things:
|
for the other automata formats. This implies two things:
|
||||||
- autfilt and dstar2tgba (despite its name) can now both read
|
- autfilt and dstar2tgba (despite its name) can now both read
|
||||||
|
|
@ -18,20 +28,18 @@ New in spot 1.99.3a (not yet released)
|
||||||
* The class hierarchy for temporal formulas has been entirely
|
* The class hierarchy for temporal formulas has been entirely
|
||||||
rewritten. This change is actually quite massive (~13200 lines
|
rewritten. This change is actually quite massive (~13200 lines
|
||||||
removed, ~8200 lines added), and brings some nice benefits:
|
removed, ~8200 lines added), and brings some nice benefits:
|
||||||
- LTL/PSL formulas are now represented by lightweight
|
- LTL/PSL formulas are now represented by lightweight ltl::formula
|
||||||
ltl::formula objects (instead of ltl::formula* pointers)
|
objects (instead of ltl::formula* pointers) that perform
|
||||||
that perform reference counting automatically.
|
reference counting automatically.
|
||||||
- There is no hierachy anymore: all operators are represented
|
- There is no hierachy anymore: all operators are represented by a
|
||||||
by a single type of node in the syntax tree, and an
|
single type of node in the syntax tree, and an enumerator is
|
||||||
enumerator is used to distinguish between operators.
|
used to distinguish between operators.
|
||||||
- Visitors have been replaced by member functions such
|
- Visitors have been replaced by member functions such as map() or
|
||||||
as map() or traverse(), that take a function (usually
|
traverse(), that take a function (usually written as a lambda
|
||||||
written as a lambda function) and apply it to the
|
function) and apply it to the nodes of the tree.
|
||||||
nodes of the tree.
|
- As a consequence, writing algorithms that manipulate formula is
|
||||||
- As a consequence, writing algorithms that manipulate
|
more friendly, and several algorithms that spanned a few pages
|
||||||
formula is more friendly, and several functions
|
have been reduced to a few lines.
|
||||||
algorithms that spanned a few pages have been
|
|
||||||
reduced to a few lines.
|
|
||||||
|
|
||||||
New in spot 1.99.3 (2015-08-26)
|
New in spot 1.99.3 (2015-08-26)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,8 @@ enum {
|
||||||
OPT_KEEP_STATES,
|
OPT_KEEP_STATES,
|
||||||
OPT_MASK_ACC,
|
OPT_MASK_ACC,
|
||||||
OPT_MERGE,
|
OPT_MERGE,
|
||||||
OPT_PRODUCT,
|
OPT_PRODUCT_AND,
|
||||||
|
OPT_PRODUCT_OR,
|
||||||
OPT_RANDOMIZE,
|
OPT_RANDOMIZE,
|
||||||
OPT_REM_AP,
|
OPT_REM_AP,
|
||||||
OPT_REM_DEAD,
|
OPT_REM_DEAD,
|
||||||
|
|
@ -122,8 +123,13 @@ static const argp_option options[] =
|
||||||
{ 0, 0, 0, 0, "Transformations:", 5 },
|
{ 0, 0, 0, 0, "Transformations:", 5 },
|
||||||
{ "merge-transitions", OPT_MERGE, 0, 0,
|
{ "merge-transitions", OPT_MERGE, 0, 0,
|
||||||
"merge transitions with same destination and acceptance", 0 },
|
"merge transitions with same destination and acceptance", 0 },
|
||||||
{ "product", OPT_PRODUCT, "FILENAME", 0,
|
{ "product", OPT_PRODUCT_AND, "FILENAME", 0,
|
||||||
"build the product with the automaton in FILENAME", 0 },
|
"build the product with the automaton in FILENAME "
|
||||||
|
"to intersect languages", 0 },
|
||||||
|
{ "product-and", 0, 0, OPTION_ALIAS, 0, 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", OPT_RANDOMIZE, "s|t", OPTION_ARG_OPTIONAL,
|
||||||
"randomize states and transitions (specify 's' or 't' to "
|
"randomize states and transitions (specify 's' or 't' to "
|
||||||
"randomize only states or transitions)", 0 },
|
"randomize only states or transitions)", 0 },
|
||||||
|
|
@ -231,7 +237,8 @@ static int opt_seed = 0;
|
||||||
static struct opt_t
|
static struct opt_t
|
||||||
{
|
{
|
||||||
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
||||||
spot::twa_graph_ptr product = nullptr;
|
spot::twa_graph_ptr product_and = nullptr;
|
||||||
|
spot::twa_graph_ptr product_or = nullptr;
|
||||||
spot::twa_graph_ptr intersect = nullptr;
|
spot::twa_graph_ptr intersect = nullptr;
|
||||||
spot::twa_graph_ptr are_isomorphic = nullptr;
|
spot::twa_graph_ptr are_isomorphic = nullptr;
|
||||||
std::unique_ptr<spot::isomorphism_checker>
|
std::unique_ptr<spot::isomorphism_checker>
|
||||||
|
|
@ -393,14 +400,24 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
opt_rem_unreach = true;
|
opt_rem_unreach = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_PRODUCT:
|
case OPT_PRODUCT_AND:
|
||||||
{
|
{
|
||||||
auto a = read_automaton(arg, opt->dict);
|
auto a = read_automaton(arg, opt->dict);
|
||||||
if (!opt->product)
|
if (!opt->product_and)
|
||||||
opt->product = std::move(a);
|
opt->product_and = std::move(a);
|
||||||
else
|
else
|
||||||
opt->product = spot::product(std::move(opt->product),
|
opt->product_and = spot::product(std::move(opt->product_and),
|
||||||
std::move(a));
|
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;
|
break;
|
||||||
case OPT_RANDOMIZE:
|
case OPT_RANDOMIZE:
|
||||||
|
|
@ -579,8 +596,10 @@ namespace
|
||||||
else if (opt_rem_unreach)
|
else if (opt_rem_unreach)
|
||||||
aut->purge_unreachable_states();
|
aut->purge_unreachable_states();
|
||||||
|
|
||||||
if (opt->product)
|
if (opt->product_and)
|
||||||
aut = spot::product(std::move(aut), opt->product);
|
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_sat_minimize)
|
if (opt_sat_minimize)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ TESTS_twa = \
|
||||||
ltldo2.test \
|
ltldo2.test \
|
||||||
maskacc.test \
|
maskacc.test \
|
||||||
maskkeep.test \
|
maskkeep.test \
|
||||||
|
prodor.test \
|
||||||
simdet.test \
|
simdet.test \
|
||||||
sim2.test \
|
sim2.test \
|
||||||
sim3.test \
|
sim3.test \
|
||||||
|
|
|
||||||
169
src/tests/prodor.test
Executable file
169
src/tests/prodor.test
Executable file
|
|
@ -0,0 +1,169 @@
|
||||||
|
#!/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
|
||||||
|
|
||||||
|
ltl2tgba=../../bin/ltl2tgba
|
||||||
|
autfilt=../../bin/autfilt
|
||||||
|
|
||||||
|
$ltl2tgba -DH 'GFa' > gfa.hoa
|
||||||
|
$ltl2tgba -DH 'FGb' > fgb.hoa
|
||||||
|
$autfilt --product-or gfa.hoa fgb.hoa -H > por.hoa
|
||||||
|
cat por.hoa
|
||||||
|
|
||||||
|
cat >exp <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 3
|
||||||
|
Start: 0
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
Acceptance: 2 Inf(0) | Inf(1)
|
||||||
|
properties: trans-labels explicit-labels trans-acc complete
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[0&1] 1 {1}
|
||||||
|
[!0&1] 1
|
||||||
|
[0] 0 {1}
|
||||||
|
[!0] 0
|
||||||
|
State: 1
|
||||||
|
[0&1] 1 {0 1}
|
||||||
|
[!0&1] 1 {0}
|
||||||
|
[0&!1] 2 {0 1}
|
||||||
|
[!0&!1] 2 {0}
|
||||||
|
State: 2
|
||||||
|
[0] 2 {1}
|
||||||
|
[!0] 2
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
diff por.hoa exp
|
||||||
|
|
||||||
|
test 2 = `$autfilt -c --intersect por.hoa gfa.hoa fgb.hoa`
|
||||||
|
|
||||||
|
$autfilt --product-and gfa.hoa fgb.hoa -H > pand.hoa
|
||||||
|
cat pand.hoa
|
||||||
|
|
||||||
|
cat >exp <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 2
|
||||||
|
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] 1 {1}
|
||||||
|
[!0&1] 1
|
||||||
|
[0] 0 {1}
|
||||||
|
[!0] 0
|
||||||
|
State: 1
|
||||||
|
[0&1] 1 {0 1}
|
||||||
|
[!0&1] 1 {0}
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
diff pand.hoa exp
|
||||||
|
|
||||||
|
test 2 = `$autfilt -c --intersect pand.hoa gfa.hoa fgb.hoa`
|
||||||
|
|
||||||
|
$ltl2tgba -BDH 'GFa' > gfa.hoa
|
||||||
|
$ltl2tgba -BDH 'Xb' > xb.hoa
|
||||||
|
$autfilt --product-or gfa.hoa xb.hoa -H > por.hoa
|
||||||
|
cat por.hoa
|
||||||
|
|
||||||
|
cat >exp <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 7
|
||||||
|
Start: 0
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
Acceptance: 2 Inf(0) | Inf(1)
|
||||||
|
properties: trans-labels explicit-labels state-acc complete
|
||||||
|
properties: deterministic
|
||||||
|
--BODY--
|
||||||
|
State: 0 {0 1}
|
||||||
|
[0] 1
|
||||||
|
[!0] 2
|
||||||
|
State: 1 {0 1}
|
||||||
|
[0&1] 3
|
||||||
|
[!0&1] 4
|
||||||
|
[0&!1] 5
|
||||||
|
[!0&!1] 6
|
||||||
|
State: 2 {0}
|
||||||
|
[0&1] 3
|
||||||
|
[!0&1] 4
|
||||||
|
[0&!1] 5
|
||||||
|
[!0&!1] 6
|
||||||
|
State: 3 {0 1}
|
||||||
|
[0] 3
|
||||||
|
[!0] 4
|
||||||
|
State: 4 {0}
|
||||||
|
[0] 3
|
||||||
|
[!0] 4
|
||||||
|
State: 5 {1}
|
||||||
|
[0] 5
|
||||||
|
[!0] 6
|
||||||
|
State: 6
|
||||||
|
[0] 5
|
||||||
|
[!0] 6
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
diff por.hoa exp
|
||||||
|
|
||||||
|
$ltl2tgba -BDH 'GFa' > gfa.hoa
|
||||||
|
$ltl2tgba -x '!wdba-minimize' -DH 'Xb' > xb.hoa
|
||||||
|
$autfilt --product-or gfa.hoa xb.hoa -H > por.hoa
|
||||||
|
cat por.hoa
|
||||||
|
|
||||||
|
cat >exp <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 7
|
||||||
|
Start: 0
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
Acceptance: 2 Inf(0) | Inf(1)
|
||||||
|
properties: trans-labels explicit-labels state-acc complete
|
||||||
|
properties: deterministic
|
||||||
|
--BODY--
|
||||||
|
State: 0 {0 1}
|
||||||
|
[0] 1
|
||||||
|
[!0] 2
|
||||||
|
State: 1 {0 1}
|
||||||
|
[0&1] 3
|
||||||
|
[!0&1] 4
|
||||||
|
[0&!1] 5
|
||||||
|
[!0&!1] 6
|
||||||
|
State: 2 {0}
|
||||||
|
[0&1] 3
|
||||||
|
[!0&1] 4
|
||||||
|
[0&!1] 5
|
||||||
|
[!0&!1] 6
|
||||||
|
State: 3 {0 1}
|
||||||
|
[0] 3
|
||||||
|
[!0] 4
|
||||||
|
State: 4 {0}
|
||||||
|
[0] 3
|
||||||
|
[!0] 4
|
||||||
|
State: 5 {1}
|
||||||
|
[0] 5
|
||||||
|
[!0] 6
|
||||||
|
State: 6
|
||||||
|
[0] 5
|
||||||
|
[!0] 6
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
diff por.hoa exp
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "product.hh"
|
#include "product.hh"
|
||||||
#include "twa/twagraph.hh"
|
#include "twa/twagraph.hh"
|
||||||
|
#include "twaalgos/complete.hh"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "misc/hash.hh"
|
#include "misc/hash.hh"
|
||||||
|
|
@ -37,77 +38,115 @@ namespace spot
|
||||||
return wang32_hash(s.first ^ wang32_hash(s.second));
|
return wang32_hash(s.first ^ wang32_hash(s.second));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
static
|
||||||
|
twa_graph_ptr product_aux(const const_twa_graph_ptr& left,
|
||||||
|
const const_twa_graph_ptr& right,
|
||||||
|
unsigned left_state,
|
||||||
|
unsigned right_state,
|
||||||
|
bool and_acc)
|
||||||
|
{
|
||||||
|
std::unordered_map<product_state, unsigned, product_state_hash> s2n;
|
||||||
|
std::deque<std::pair<product_state, unsigned>> todo;
|
||||||
|
|
||||||
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
assert(left->get_dict() == right->get_dict());
|
||||||
const const_twa_graph_ptr& right,
|
auto res = make_twa_graph(left->get_dict());
|
||||||
unsigned left_state,
|
res->copy_ap_of(left);
|
||||||
unsigned right_state)
|
res->copy_ap_of(right);
|
||||||
{
|
auto left_num = left->num_sets();
|
||||||
std::unordered_map<product_state, unsigned, product_state_hash> s2n;
|
auto right_acc = right->get_acceptance();
|
||||||
std::deque<std::pair<product_state, unsigned>> todo;
|
right_acc.shift_left(left_num);
|
||||||
|
if (and_acc)
|
||||||
|
right_acc.append_and(left->get_acceptance());
|
||||||
|
else
|
||||||
|
right_acc.append_or(acc_cond::acc_code(left->get_acceptance()));
|
||||||
|
res->set_acceptance(left_num + right->num_sets(), right_acc);
|
||||||
|
|
||||||
assert(left->get_dict() == right->get_dict());
|
auto v = new product_states;
|
||||||
auto res = make_twa_graph(left->get_dict());
|
res->set_named_prop("product-states", v);
|
||||||
res->copy_ap_of(left);
|
|
||||||
res->copy_ap_of(right);
|
|
||||||
auto left_num = left->num_sets();
|
|
||||||
auto right_acc = right->get_acceptance();
|
|
||||||
right_acc.shift_left(left_num);
|
|
||||||
right_acc.append_and(left->get_acceptance());
|
|
||||||
res->set_acceptance(left_num + right->num_sets(), right_acc);
|
|
||||||
|
|
||||||
auto v = new product_states;
|
auto new_state =
|
||||||
res->set_named_prop("product-states", v);
|
[&](unsigned left_state, unsigned right_state) -> unsigned
|
||||||
|
{
|
||||||
auto new_state =
|
product_state x(left_state, right_state);
|
||||||
[&](unsigned left_state, unsigned right_state) -> unsigned
|
auto p = s2n.emplace(x, 0);
|
||||||
{
|
if (p.second) // This is a new state
|
||||||
product_state x(left_state, right_state);
|
|
||||||
auto p = s2n.emplace(x, 0);
|
|
||||||
if (p.second) // This is a new state
|
|
||||||
{
|
|
||||||
p.first->second = res->new_state();
|
|
||||||
todo.emplace_back(x, p.first->second);
|
|
||||||
assert(p.first->second == v->size());
|
|
||||||
v->push_back(x);
|
|
||||||
}
|
|
||||||
return p.first->second;
|
|
||||||
};
|
|
||||||
|
|
||||||
res->set_init_state(new_state(left_state, right_state));
|
|
||||||
if (right_acc.is_false())
|
|
||||||
// Do not bother doing any work if the resulting acceptance is
|
|
||||||
// false.
|
|
||||||
return res;
|
|
||||||
while (!todo.empty())
|
|
||||||
{
|
|
||||||
auto top = todo.front();
|
|
||||||
todo.pop_front();
|
|
||||||
for (auto& l: left->out(top.first.first))
|
|
||||||
for (auto& r: right->out(top.first.second))
|
|
||||||
{
|
{
|
||||||
auto cond = l.cond & r.cond;
|
p.first->second = res->new_state();
|
||||||
if (cond == bddfalse)
|
todo.emplace_back(x, p.first->second);
|
||||||
continue;
|
assert(p.first->second == v->size());
|
||||||
auto dst = new_state(l.dst, r.dst);
|
v->push_back(x);
|
||||||
res->new_edge(top.second, dst, cond,
|
|
||||||
res->acc().join(left->acc(), l.acc,
|
|
||||||
right->acc(), r.acc));
|
|
||||||
// If right is deterministic, we can abort immediately!
|
|
||||||
}
|
}
|
||||||
}
|
return p.first->second;
|
||||||
|
};
|
||||||
|
|
||||||
return res;
|
res->set_init_state(new_state(left_state, right_state));
|
||||||
|
if (right_acc.is_false())
|
||||||
|
// Do not bother doing any work if the resulting acceptance is
|
||||||
|
// false.
|
||||||
|
return res;
|
||||||
|
while (!todo.empty())
|
||||||
|
{
|
||||||
|
auto top = todo.front();
|
||||||
|
todo.pop_front();
|
||||||
|
for (auto& l: left->out(top.first.first))
|
||||||
|
for (auto& r: right->out(top.first.second))
|
||||||
|
{
|
||||||
|
auto cond = l.cond & r.cond;
|
||||||
|
if (cond == bddfalse)
|
||||||
|
continue;
|
||||||
|
auto dst = new_state(l.dst, r.dst);
|
||||||
|
res->new_edge(top.second, dst, cond,
|
||||||
|
res->acc().join(left->acc(), l.acc,
|
||||||
|
right->acc(), r.acc));
|
||||||
|
// If right is deterministic, we can abort immediately!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res->prop_deterministic(left->is_deterministic()
|
||||||
|
&& right->is_deterministic());
|
||||||
|
res->prop_stutter_invariant(left->is_stutter_invariant()
|
||||||
|
&& right->is_stutter_invariant());
|
||||||
|
res->prop_stutter_sensitive(left->is_stutter_sensitive()
|
||||||
|
&& right->is_stutter_sensitive());
|
||||||
|
res->prop_state_based_acc(left->has_state_based_acc()
|
||||||
|
&& right->has_state_based_acc());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
||||||
const const_twa_graph_ptr& right)
|
const const_twa_graph_ptr& right,
|
||||||
|
unsigned left_state,
|
||||||
|
unsigned right_state)
|
||||||
|
{
|
||||||
|
return product_aux(left, right, left_state, right_state, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
||||||
|
const const_twa_graph_ptr& right)
|
||||||
{
|
{
|
||||||
return product(left, right,
|
return product(left, right,
|
||||||
left->get_init_state_number(),
|
left->get_init_state_number(),
|
||||||
right->get_init_state_number());
|
right->get_init_state_number());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
twa_graph_ptr product_or(const const_twa_graph_ptr& left,
|
||||||
|
const const_twa_graph_ptr& right,
|
||||||
|
unsigned left_state,
|
||||||
|
unsigned right_state)
|
||||||
|
{
|
||||||
|
return product_aux(tgba_complete(left),
|
||||||
|
tgba_complete(right),
|
||||||
|
left_state, right_state, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
twa_graph_ptr product_or(const const_twa_graph_ptr& left,
|
||||||
|
const const_twa_graph_ptr& right)
|
||||||
|
{
|
||||||
|
return product_or(left, right,
|
||||||
|
left->get_init_state_number(),
|
||||||
|
right->get_init_state_number());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2014 Laboratoire de Recherche et
|
// Copyright (C) 2014, 2015 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.
|
||||||
|
|
@ -32,11 +32,22 @@ namespace spot
|
||||||
|
|
||||||
SPOT_API
|
SPOT_API
|
||||||
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
||||||
const const_twa_graph_ptr& right);
|
const const_twa_graph_ptr& right);
|
||||||
|
|
||||||
SPOT_API
|
SPOT_API
|
||||||
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
twa_graph_ptr product(const const_twa_graph_ptr& left,
|
||||||
|
const const_twa_graph_ptr& right,
|
||||||
|
unsigned left_state,
|
||||||
|
unsigned right_state);
|
||||||
|
|
||||||
|
SPOT_API
|
||||||
|
twa_graph_ptr product_or(const const_twa_graph_ptr& left,
|
||||||
|
const const_twa_graph_ptr& right);
|
||||||
|
|
||||||
|
SPOT_API
|
||||||
|
twa_graph_ptr product_or(const const_twa_graph_ptr& left,
|
||||||
const const_twa_graph_ptr& right,
|
const const_twa_graph_ptr& right,
|
||||||
unsigned left_state,
|
unsigned left_state,
|
||||||
unsigned right_state);
|
unsigned right_state);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue