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:
Jonah Romero 2023-08-08 12:08:28 +02:00 committed by Alexandre Duret-Lutz
parent d1c5b2efdf
commit ad22eb3e65
5 changed files with 123 additions and 6 deletions

View file

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

View file

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