10#ifndef MCRL2_LPS_SYMBOLIC_LTS_BISIM_H
11#define MCRL2_LPS_SYMBOLIC_LTS_BISIM_H
13#ifdef MCRL2_ENABLE_SYLVAN
19#include <sylvan_ldd.hpp>
29 sylvan::ldds::ldd projected;
30 std::size_t action_index;
36template <
typename Context>
37void project_transitions(WorkerP*, Task*, std::uint32_t* x, std::size_t n,
void* context)
39 using namespace sylvan::ldds;
41 auto pointer =
reinterpret_cast<Context*
>(context);
44 if (x[n-1] == p.action_index)
46 p.projected =
union_(p.projected, cube(x, n));
51std::size_t height(
const sylvan::ldds::ldd& x)
53 using namespace sylvan::ldds;
54 return sat_one_vector(x).size();
58sylvan::ldds::ldd project_transitions(
const sylvan::ldds::ldd& x, std::size_t height, std::size_t action_index)
60 using namespace sylvan::ldds;
62 if (x == empty_set() || x == empty_list())
70 if (x.value() < action_index)
72 return project_transitions(x.right(), height, action_index);
74 else if (x.value() == action_index)
76 return node(x.value());
85 return node(x.value(), project_transitions(x.down(), height - 1, action_index), project_transitions(x.right(), height, action_index));
89void bisim(
const symbolic_lts& lts)
91 using namespace sylvan::ldds;
95 std::vector<lps_summand_group> new_groups;
97 for (
const auto& group : lts.summand_groups)
99 for (
const auto& action : lts.action_index)
105 res.projected = project_transitions(group.L, height(group.L), lts.action_index.index(action));
107 if (res.projected != sylvan::ldds::empty_set())
109 new_groups.emplace_back(group);
110 new_groups.back().L = res.projected;
119 bool refined_block =
false;
120 bool refined_any_block =
false;
121 std::size_t iterations = 0;
126 refined_any_block =
false;
128 for (
const ldd& C : partition)
130 refined_block =
false;
132 for (
const ldd& C_prime : partition)
135 for (
const lps_summand_group& group : new_groups)
137 ldd A = relprev(C_prime, group.L, group.Ir, C);
138 if (A != sylvan::ldds::empty_set() && A != C)
143 refined_block =
true;
150 refined_any_block =
true;
161 swap(partition, new_partition);
162 new_partition.
clear();
165 mCRL2log(
log::verbose) <<
"found " << std::setw(12) << partition.
size() <<
" equivalence classes after " << std::setw(4) << iterations <<
" iterations." << std::endl;
167 while (refined_any_block);
171 for (
const ldd& C : partition)
A unordered_set with a subset of the interface of std::unordered_set that only stores a single pointe...
std::pair< iterator, bool > emplace(Args &&... args)
Inserts an element Key(args...) into the set if it did not already exist.
size_type size() const noexcept
void clear()
Removes all elements from the set.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
function_symbol union_(const sort_expression &s, const sort_expression &s0, const sort_expression &s1)
const function_symbol & false_()
Constructor for function symbol false.
function_symbol minus(const sort_expression &s0, const sort_expression &s1)
The main namespace for the LPS library.
void swap(action_summand &t1, action_summand &t2)
\brief swap overload