mCRL2
Loading...
Searching...
No Matches
lps_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_LPS_LPS_SUMMAND_GROUP_H
11#define MCRL_LPS_LPS_SUMMAND_GROUP_H
12
13#ifdef MCRL2_ENABLE_SYLVAN
14
20
21#include <functional>
22#include <set>
23
24namespace mcrl2::lps
25{
26
29inline std::vector<boost::dynamic_bitset<>> compute_read_write_patterns(const lps::specification& lpsspec);
30
31struct lps_summand_group: public symbolic::summand_group
32{
33 lps_summand_group(
34 const lps::specification& lpsspec,
35 const data::variable_list& process_parameters, // the reordered process parameters
36 const std::set<std::size_t>& group_indices,
37 const boost::dynamic_bitset<>& group_pattern,
38 const std::vector<boost::dynamic_bitset<>>& read_write_patterns,
39 const std::vector<std::size_t> variable_order // a permutation of [0 .. |process_parameters| - 1]
40 )
41 : summand_group(process_parameters, group_pattern, true)
42 {
43 using symbolic::project;
44 using utilities::detail::as_vector;
45 using utilities::detail::as_set;
46 using utilities::detail::set_union;
47
48 std::set<std::size_t> used;
49 for (std::size_t j: read)
50 {
51 used.insert(2*j);
52 }
53 for (std::size_t j: write)
54 {
55 used.insert(2*j + 1);
56 }
57
58 const auto& lps_summands = lpsspec.process().action_summands();
59 for (std::size_t i: group_indices)
60 {
61 std::vector<int> copy;
62 for (std::size_t j: used)
63 {
64 bool b = read_write_patterns[i][j];
65 copy.push_back(b ? 0 : 1);
66 }
67 copy.push_back(0); // Add one additional copy for the action label (needed by union_cube_copy).
68
69 const auto& smd = lps_summands[i];
70 actions.emplace_back(smd.multi_action());
71 summands.emplace_back(smd.condition(), smd.summation_variables(), project(as_vector(symbolic::permute_copy(smd.next_state(lpsspec.process().process_parameters()), variable_order)), write), copy);
72 }
73 }
74
75 lps_summand_group(const data::variable_list& process_parameters, std::vector<data::variable> _read_parameters, std::vector<data::variable> _write_parameters)
76 : summand_group(process_parameters, _read_parameters, _write_parameters, true)
77 {}
78
79 std::vector<lps::multi_action> actions;
80};
81
82namespace
83{
84
86inline
87std::pair<std::set<data::variable>, std::set<data::variable>> read_write_parameters(const lps::action_summand& summand, const std::set<data::variable>& process_parameters)
88{
91
92 // TODO: multi-action free variables are only necessary when actions are rewritten.
93 std::set<data::variable> read_parameters = set_union(data::find_free_variables(summand.condition()), lps::find_free_variables(summand.multi_action()));
94 std::set<data::variable> write_parameters;
95
96 for (const auto& assignment: summand.assignments())
97 {
98 if (assignment.lhs() != assignment.rhs())
99 {
100 write_parameters.insert(assignment.lhs());
101 data::find_free_variables(assignment.rhs(), std::inserter(read_parameters, read_parameters.end()));
102 }
103 }
104
105 return { set_intersection(read_parameters, process_parameters), set_intersection(write_parameters, process_parameters) };
106}
107
109inline
110std::map<data::variable, std::size_t> process_parameter_index(const lps::specification& lpsspec)
111{
112 std::map<data::variable, std::size_t> result;
113 std::size_t i = 0;
114 for (const data::variable& v: lpsspec.process().process_parameters())
115 {
116 result[v] = i++;
117 }
118 return result;
119}
120
121} // internal
122
123std::vector<boost::dynamic_bitset<>> compute_read_write_patterns(const lps::specification& lpsspec)
124{
126
127 std::vector<boost::dynamic_bitset<>> result;
128
129 auto process_parameters = as_set(lpsspec.process().process_parameters());
130 std::size_t n = process_parameters.size();
131 std::map<data::variable, std::size_t> index = process_parameter_index(lpsspec);
132
133 for (const auto& summand: lpsspec.process().action_summands())
134 {
135 auto [read_parameters, write_parameters] = read_write_parameters(summand, process_parameters);
136 auto read = symbolic::parameter_indices(read_parameters, index);
137 auto write = symbolic::parameter_indices(write_parameters, index);
138 boost::dynamic_bitset<> rw(2*n);
139 for (std::size_t j: read)
140 {
141 rw[2*j] = true;
142 }
143 for (std::size_t j: write)
144 {
145 rw[2*j + 1] = true;
146 }
147 result.push_back(rw);
148 }
149
150 return result;
151}
152
153} // namespace mcrl2::lps
154
155#endif // MCRL2_ENABLE_SYLVAN
156
157#endif // MCRL_LPS_LPS_SUMMAND_GROUP_H
add your file description here.
The class data_expression.
std::set< T > as_set(const atermpp::term_list< T > &x)
Converts the given term list to a set.
Definition aterm_list.h:555
std::vector< T > as_vector(const atermpp::term_list< T > &x)
Converts the given term list to a vector.
Definition aterm_list.h:548
variable_list set_intersection(const variable_list &x, const variable_list &y)
Returns the intersection of two unordered sets, that are stored in ATerm lists.
std::set< data::variable > find_free_variables(const data::data_expression &x)
Definition data.cpp:99
The main namespace for the LPS library.
std::set< data::variable > find_free_variables(const lps::deadlock &x)
Definition lps.cpp:54
vertex_set set_union(const vertex_set &V, const vertex_set &W)
std::set< std::size_t > parameter_indices(const std::set< data::variable > &parameters, const std::map< data::variable, std::size_t > &index)
Definition ordering.h:414
std::set< T > set_union(const std::set< T > &x, const std::set< T > &y)
Returns the union of two sets.
std::set< T > as_set(const std::vector< T > &x)
std::set< T > set_intersection(const std::set< T > &x, const std::set< T > &y)
Returns the intersection of two sets.
The class specification.