add enviroment variables for FORQ algorithm
* AUTHORS: added Jonah Romero
* bin/man/spot-x.x: Added the enviroment variables,
SPOT_EXCLUSIVE_WORD and SPOT_CONTAINMENT_CHECK
* doc/spot.bib: Added paper citation for FORQ inclusion algorithm
* spot/twa/twa.cc: Modified exclusive_word to also use FORQ
* spot/twaalgos/contains.cc: Modified contains to also use FORQ
This commit is contained in:
parent
d1c5b2efdf
commit
ad22eb3e65
5 changed files with 123 additions and 6 deletions
|
|
@ -28,6 +28,7 @@
|
|||
#include <spot/twaalgos/remfin.hh>
|
||||
#include <spot/twaalgos/alternation.hh>
|
||||
#include <spot/twa/twaproduct.hh>
|
||||
#include <spot/twaalgos/forq_contains.hh>
|
||||
#include <spot/twaalgos/complement.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
#include <spot/twaalgos/product.hh>
|
||||
|
|
@ -228,20 +229,57 @@ namespace spot
|
|||
return b->intersecting_run(complement(ensure_graph(a)));
|
||||
}
|
||||
|
||||
static bool
|
||||
is_buchi_automata(const_twa_graph_ptr const& aut)
|
||||
{
|
||||
return spot::acc_cond::acc_code::buchi() == aut->get_acceptance();
|
||||
}
|
||||
|
||||
twa_word_ptr
|
||||
twa::exclusive_word(const_twa_ptr other) const
|
||||
{
|
||||
const_twa_ptr a = shared_from_this();
|
||||
const_twa_ptr b = other;
|
||||
|
||||
enum class containment_type : unsigned { LEGACY = 0, FORQ };
|
||||
static containment_type containment = [&]()
|
||||
{
|
||||
char* s = getenv("SPOT_EXCLUSIVE_WORD");
|
||||
// We expect a single digit that represents a valid enumeration value
|
||||
if (!s)
|
||||
return containment_type::LEGACY;
|
||||
else if (*s == '\0' || *(s + 1) != '\0' || *s < '0' || *s > '1')
|
||||
throw std::runtime_error("Invalid value for enviroment variable: "
|
||||
"SPOT_EXCLUSIVE_WORD");
|
||||
else
|
||||
return static_cast<containment_type>(*s - '0');
|
||||
}();
|
||||
|
||||
// We have to find a word in A\B or in B\A. When possible, let's
|
||||
// make sure the first automaton we complement is deterministic.
|
||||
if (auto aa = std::dynamic_pointer_cast<const twa_graph>(a))
|
||||
if (is_deterministic(aa))
|
||||
auto a_twa_as_graph = std::dynamic_pointer_cast<const twa_graph>(a);
|
||||
auto b_twa_as_graph = std::dynamic_pointer_cast<const twa_graph>(a);
|
||||
if (a_twa_as_graph)
|
||||
if (is_deterministic(a_twa_as_graph))
|
||||
std::swap(a, b);
|
||||
if (auto word = a->intersecting_word(complement(ensure_graph(b))))
|
||||
return word;
|
||||
return b->intersecting_word(complement(ensure_graph(a)));
|
||||
|
||||
bool uses_buchi = is_buchi_automata(a_twa_as_graph)
|
||||
&& is_buchi_automata(b_twa_as_graph);
|
||||
if (containment == containment_type::FORQ
|
||||
&& uses_buchi
|
||||
&& a_twa_as_graph
|
||||
&& b_twa_as_graph)
|
||||
{
|
||||
if (auto word = difference_word_forq(a_twa_as_graph, b_twa_as_graph))
|
||||
return word;
|
||||
return difference_word_forq(b_twa_as_graph, a_twa_as_graph);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto word = a->intersecting_word(complement(ensure_graph(b))))
|
||||
return word;
|
||||
return b->intersecting_word(complement(ensure_graph(a)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include <spot/twaalgos/contains.hh>
|
||||
#include <spot/twaalgos/forq_contains.hh>
|
||||
#include <spot/twaalgos/complement.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
|
|
@ -34,9 +35,37 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
static bool is_buchi_automata(const_twa_graph_ptr const& aut)
|
||||
{
|
||||
return spot::acc_cond::acc_code::buchi() == aut->get_acceptance();
|
||||
}
|
||||
|
||||
bool contains(const_twa_graph_ptr left, const_twa_ptr right)
|
||||
{
|
||||
return !complement(left)->intersects(right);
|
||||
enum class containment_type : unsigned { LEGACY = 0, FORQ };
|
||||
static containment_type containment = [&]()
|
||||
{
|
||||
char* s = getenv("SPOT_CONTAINMENT_CHECK");
|
||||
// We expect a single digit that represents a valid enumeration value
|
||||
if (!s)
|
||||
return containment_type::LEGACY;
|
||||
else if (*s == '\0' || *(s + 1) != '\0' || *s < '0' || *s > '1')
|
||||
throw std::runtime_error("Invalid value for enviroment variable: "
|
||||
"SPOT_CONTAINMENT_CHECK");
|
||||
else
|
||||
return static_cast<containment_type>(*s - '0');
|
||||
}();
|
||||
|
||||
auto as_graph = std::dynamic_pointer_cast<const twa_graph>(right);
|
||||
bool uses_buchi = is_buchi_automata(left) && is_buchi_automata(as_graph);
|
||||
if (containment == containment_type::FORQ && uses_buchi && as_graph)
|
||||
{
|
||||
return contains_forq(left, as_graph);
|
||||
}
|
||||
else
|
||||
{
|
||||
return !complement(left)->intersects(right);
|
||||
}
|
||||
}
|
||||
|
||||
bool contains(const_twa_graph_ptr left, formula right)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue