mCRL2
Loading...
Searching...
No Matches
pbes_summand_group.h
Go to the documentation of this file.
1// Author(s): Wieger Wesselink
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9
10#ifndef MCRL_PBES_PBES_SUMMAND_GROUP_H
11#define MCRL_PBES_PBES_SUMMAND_GROUP_H
12
13#ifdef MCRL2_ENABLE_SYLVAN
14
15#include "mcrl2/data/data_expression.h"
16#include "mcrl2/data/variable.h"
17#include "mcrl2/pbes/srf_pbes.h"
18#include "mcrl2/symbolic/summand_group.h"
19
20#include <functional>
21#include <set>
22#include <vector>
23
24namespace mcrl2::pbes_system
25{
26
27/// \brief Computes the parameters read and written for the given pbes equation.
28inline
29std::pair<std::set<data::variable>, std::set<data::variable>> read_write_parameters(
30 const pbes_system::srf_equation& equation,
31 const pbes_system::srf_summand& summand,
32 const data::variable_list& process_parameters)
33{
34 using utilities::detail::set_union;
35 using utilities::detail::set_intersection;
36 using utilities::detail::as_set;
37
38 std::set<data::variable> read_parameters = data::find_free_variables(summand.condition());
39 std::set<data::variable> write_parameters;
40
41 // We need special handling for the first parameter, since the clause 'propvar == X' is not in the condition yet
42 read_parameters.insert(process_parameters.front());
43 if (equation.variable().name() != summand.variable().name())
44 {
45 write_parameters.insert(process_parameters.front());
46 }
47
48 const data::data_expression_list& expressions = summand.variable().parameters();
49 auto pi = ++process_parameters.begin(); // skip the first parameter
50 auto ei = expressions.begin();
51 for (; ei != expressions.end(); ++pi, ++ei)
52 {
53 if (*pi != *ei)
54 {
55 write_parameters.insert(*pi);
56 data::find_free_variables(*ei, std::inserter(read_parameters, read_parameters.end()));
57 }
58 }
59
60 auto process_parameter_set = as_set(process_parameters);
61 return { set_intersection(read_parameters, process_parameter_set), set_intersection(write_parameters, process_parameter_set) };
62}
63
64/// \brief Computes a mapping from parameter to the index in the parameter list.
65inline
66std::map<data::variable, std::size_t> process_parameter_index(const data::variable_list& process_parameters)
67{
68 std::map<data::variable, std::size_t> result;
69 std::size_t i = 0;
70 for (const data::variable& v: process_parameters)
71 {
72 result[v] = i++;
73 }
74 return result;
75}
76
77/// \brief Computes a vector of bitsets where every entry of the vector corresponds to a pbes equation in the specification.
78/// Given a list of parameters p_0, ..., p_n then for parameter p_i the bit 2*i is true iff p_i is read and bit 2*i+1 is true iff p_i is written based on syntactic occurrences.
79inline
80std::vector<boost::dynamic_bitset<>> compute_read_write_patterns(const pbes_system::srf_pbes& pbesspec, const data::variable_list& process_parameters)
81{
82 std::vector<boost::dynamic_bitset<>> result;
83
84 std::size_t n = process_parameters.size();
85 std::map<data::variable, std::size_t> index = process_parameter_index(process_parameters);
86
87 for (const detail::pre_srf_equation<false>& equation: pbesspec.equations())
88 {
89 for (const detail::pre_srf_summand<false>& summand: equation.summands())
90 {
91 auto [read_parameters, write_parameters] = read_write_parameters(equation, summand, process_parameters);
92 auto read = symbolic::parameter_indices(read_parameters, index);
93 auto write = symbolic::parameter_indices(write_parameters, index);
94 boost::dynamic_bitset<> rw(2*n);
95 for (std::size_t j: read)
96 {
97 rw[2*j] = true;
98 }
99 for (std::size_t j: write)
100 {
101 rw[2*j + 1] = true;
102 }
103 result.push_back(rw);
104 }
105 }
106
107 return result;
108}
109
110/// \brief A convenience function to add the propositional variable index in front of the state vector.
111inline
112data::data_expression_list make_state(const pbes_system::propositional_variable_instantiation& x, const std::unordered_map<core::identifier_string, data::data_expression>& propvar_map)
113{
114 data::data_expression_list result = x.parameters();
115 result.push_front(propvar_map.at(x.name()));
116 return result;
117}
118
119
120struct pbes_summand_group: public symbolic::summand_group
121{
122 pbes_summand_group(
123 const pbes_system::srf_pbes& pbesspec,
124 const data::variable_list& process_parameters, // the reordered process parameters
125 const std::unordered_map<core::identifier_string, data::data_expression>& propvar_map,
126 const std::set<std::size_t>& summand_group_indices,
127 const boost::dynamic_bitset<>& read_write_pattern,
128 const std::vector<boost::dynamic_bitset<>>& read_write_patterns,
129 const std::vector<std::size_t> variable_order // a permutation of [0 .. |process_parameters| - 1]
130 )
131 : symbolic::summand_group(process_parameters, read_write_pattern, false)
132 {
133 using symbolic::project;
134 using utilities::detail::as_vector;
135 using utilities::detail::as_set;
136 using utilities::detail::set_union;
137 using utilities::detail::contains;
138
139 std::set<std::size_t> used;
140 for (std::size_t j: read)
141 {
142 used.insert(2*j);
143 }
144 for (std::size_t j: write)
145 {
146 used.insert(2*j + 1);
147 }
148
149 const auto& equations = pbesspec.equations();
150 std::size_t k = 0;
151 for (const auto& equation : equations)
152 {
153 const core::identifier_string& X_i = equation.variable().name();
154 const auto& equation_summands = equation.summands();
155 for (std::size_t j = 0; j < equation_summands.size(); j++, k++)
156 {
157 if (contains(summand_group_indices, k))
158 {
159 std::vector<int> copy;
160 for (std::size_t q: used)
161 {
162 bool b = read_write_patterns[k][q];
163 copy.push_back(b ? 0 : 1);
164 }
165 const pbes_system::srf_summand& smd = equation_summands[j];
166 auto next_state = make_state(smd.variable(), propvar_map);
167 next_state = symbolic::permute_copy(next_state, variable_order);
168 summands.emplace_back(data::and_(data::equal_to(process_parameters.front(), propvar_map.at(X_i)), smd.condition()), smd.parameters(), project(as_vector(next_state), write), copy);
169 }
170 }
171 }
172 }
173};
174
175} // namespace mcrl2::pbes_system
176
177#endif // MCRL2_ENABLE_SYLVAN
178
179#endif // MCRL_PBES_PBES_SUMMAND_GROUP_H