mCRL2
Loading...
Searching...
No Matches
data_property_map.h
Go to the documentation of this file.
1// Author(s): Jeroen van der Wulp and 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//
11
12#ifndef MCRL2_DATA_DETAIL_DATA_PROPERTY_MAP_H
13#define MCRL2_DATA_DETAIL_DATA_PROPERTY_MAP_H
14
15#include "mcrl2/data/variable.h"
16
17namespace mcrl2
18{
19
20namespace data
21{
22
23namespace detail
24{
25
32template < typename Derived = void >
34{
35 protected:
36
38 template < typename Container >
39 static std::string add_separators(std::string const& c, typename std::enable_if< atermpp::is_set< Container >::value >::type* = nullptr)
40 {
41 return "[" + c + "]";
42 }
43
45 template < typename Container >
46 static std::string add_separators(std::string const& c, typename std::enable_if< !atermpp::is_set< Container >::value >::type* = 0)
47 {
48 return "{" + c + "}";
49 }
50
52 std::map<std::string, std::string> m_data;
53
54 //--------------------------------------------//
55 // print functions
56 //--------------------------------------------//
57 std::string print(std::size_t n) const
58 {
59 std::ostringstream out;
60 out << n;
61 return out.str();
62 }
63
64 std::string print(std::string s) const
65 {
66 return s;
67 }
68
69 std::string print(const core::identifier_string& s) const
70 {
71 return s;
72 }
73
74 std::string print(const data::variable& v) const
75 {
76 return data::pp(v) + ":" + data::pp(v.sort());
77 }
78
79 template < typename Container >
80 std::string print(const Container& v, typename atermpp::enable_if_container< Container >::type* = nullptr) const
81 {
82 std::set<std::string> elements;
83
84 for (auto i = v.begin(); i != v.end(); ++i)
85 {
86 elements.insert(static_cast< Derived const& >(*this).print(*i));
87 }
88
89 return utilities::string_join(elements, ", ");
90 }
91
92 template < typename Container >
93 std::string print(const Container& v, bool print_separators, typename atermpp::enable_if_container< Container >::type* = nullptr) const
94 {
95 return (print_separators) ? add_separators< Container >(print(v)) : print(v);
96 }
97
98 //--------------------------------------------//
99 // parse functions
100 //--------------------------------------------//
101 unsigned int parse_unsigned_int(std::string const& text) const
102 {
103 return std::stoul(utilities::remove_whitespace(text)); // Transform string to an unsigned integer.
104 }
105
106 std::set<std::string> parse_set_string(std::string const& text) const
107 {
108 std::vector<std::string> v = utilities::split(text, ",");
109 std::for_each(v.begin(), v.end(), utilities::trim);
110 return std::set<std::string>(v.begin(), v.end());
111 }
112
113 std::set<std::multiset<std::string> > parse_set_multiset_string(std::string const& text) const
114 {
115 std::set<std::multiset<std::string> > result;
116 std::vector<std::string> multisets = utilities::split(text, ";");
117 for (const std::string& ms: multisets)
118 {
119 std::string s = utilities::regex_replace("[{}]", "", ms);
120 std::vector<std::string> v = utilities::split(s, ",");
121 std::for_each(v.begin(), v.end(), utilities::trim);
122 result.insert(std::multiset<std::string>(v.begin(), v.end()));
123 }
124 return result;
125 }
126
127 //--------------------------------------------//
128 // compare functions
129 //--------------------------------------------//
132 std::string compare(const std::string& property, unsigned int x, unsigned int y) const
133 {
134 if (x != y)
135 {
136 std::ostringstream out;
137 out << "Difference in property " << property << " detected: " << x << " versus " << y << "\n";
138 return out.str();
139 }
140 return "";
141 }
142
149 template <typename T>
150 std::string compare(const std::string& property, const std::set<T>& x, const std::set<T>& y) const
151 {
152 std::ostringstream out;
153
154 // compute elements in x but not in y
155 std::set<T> plus;
156 std::set_difference(x.begin(), x.end(), y.begin(), y.end(), std::inserter(plus, plus.end()));
157
158 // compute elements in y but not in x
159 std::set<T> minus;
160 std::set_difference(y.begin(), y.end(), x.begin(), x.end(), std::inserter(minus, minus.end()));
161
162 if (!plus.empty() || !minus.empty())
163 {
164 out << "Difference in property " << property << " detected:";
165 for (auto i = plus.begin(); i != plus.end(); ++i)
166 {
167 out << " +" << print(*i);
168 }
169 for (auto i = minus.begin(); i != minus.end(); ++i)
170 {
171 out << " -" << print(*i);
172 }
173 out << "\n";
174 return out.str();
175 }
176 return "";
177 }
178
183 std::string compare_property(const std::string& property, const std::string& /* x */, const std::string& /* y */) const
184 {
185 return "ERROR: unknown property " + property + " encountered!";
186 }
187
188 //--------------------------------------------//
189 // miscellaneous functions
190 //--------------------------------------------//
192 unsigned int max_key_length() const
193 {
194 unsigned int result = 0;
195 for (auto i = m_data.begin(); i != m_data.end(); ++i)
196 {
197 result = (std::max)(static_cast< std::size_t >(result), i->first.size());
198 }
199 return result;
200 }
201
202 std::string align(const std::string& s, unsigned int n) const
203 {
204 if (s.size() >= n)
205 {
206 return s;
207 }
208 return s + std::string(n - s.size(), ' ');
209 }
210
213 template <typename Container>
214 std::set<core::identifier_string> names(const Container& v) const
215 {
216 std::set<core::identifier_string> result;
217 for (auto i = v.begin(); i != v.end(); ++i)
218 {
219 result.insert(i->name());
220 }
221 return result;
222 }
223
226 {
227 }
228
231 void parse_text(const std::string& text)
232 {
233 for (const std::string& line: utilities::split(text, "\n"))
234 {
235 std::vector<std::string> words = utilities::split(line, "=");
236 if (words.size() == 2)
237 {
238 utilities::trim(words[0]);
239 utilities::trim(words[1]);
240 m_data[words[0]] = words[1];
241 }
242 }
243 }
244
245 public:
247 data_property_map(const std::string& text)
248 {
249 parse_text(text);
250 }
251
253 std::string to_string() const
254 {
255 unsigned int n = max_key_length();
256 std::vector<std::string> lines;
257 for (auto i = m_data.begin(); i != m_data.end(); ++i)
258 {
259 lines.push_back(align(i->first, n) + " = " + i->second);
260 }
261 return utilities::string_join(lines, "\n");
262 }
263
265 const std::map<std::string, std::string>& data() const
266 {
267 return m_data;
268 }
269
272 std::string operator[](const std::string& key) const
273 {
274 auto i = m_data.find(key);
275 if (i == m_data.end())
276 {
277 throw mcrl2::runtime_error("property_map: could not find key " + key);
278 }
279 return i->second;
280 }
281
286 std::string compare(const data_property_map& other) const
287 {
288 std::ostringstream out;
289 for (auto i = m_data.begin(); i != m_data.end(); ++i)
290 {
291 auto j = other.data().find(i->first);
292 if (j != other.data().end())
293 {
294 out << static_cast< Derived const& >(*this).compare_property(i->first, i->second, j->second);
295 }
296 }
297 return out.str();
298 }
299};
300
301template <typename PropertyMap>
302bool compare_property_maps(const std::string& message, const PropertyMap& map1, const std::string& expected_result)
303{
304 PropertyMap map2(expected_result);
305 std::string result = map1.compare(map2);
306 if (!result.empty())
307 {
308 std::cerr << "------------------------------" << std::endl;
309 std::cerr << " Failed test " << std::endl;
310 std::cerr << "------------------------------" << std::endl;
311 std::cerr << message << std::endl;
312 std::cerr << "--- expected result ---" << std::endl;
313 std::cerr << expected_result << std::endl;
314 std::cerr << "--- found result ---" << std::endl;
315 std::cerr << map1.to_string() << std::endl;
316 std::cerr << "--- differences ---" << std::endl;
317 std::cerr << result << std::endl;
318 }
319 return result.empty();
320}
321
322} // namespace detail
323
324} // namespace data
325
326} // namespace mcrl2
327
328#endif // MCRL2_DATA_DETAIL_DATA_PROPERTY_MAP_H
Term containing a string.
bool empty() const
Returns true if the term has no arguments.
Definition aterm.h:158
const_iterator end() const
const_iterator begin() const
Base class for storing properties of mCRL2 types. Properties are (key, value) pairs stored as strings...
data_property_map(const std::string &text)
The strings may appear in a random order, and not all of them need to be present.
std::string print(std::string s) const
unsigned int parse_unsigned_int(std::string const &text) const
const std::map< std::string, std::string > & data() const
Returns the stored properties.
std::set< core::identifier_string > names(const Container &v) const
Collects the names of the elements of the container. The name of element x is retrieved by x....
std::string compare(const std::string &property, unsigned int x, unsigned int y) const
Compares two integers, and returns a message if they are different. If if they are equal the empty st...
std::string print(const core::identifier_string &s) const
void parse_text(const std::string &text)
Initializes the property map with text containing lines in KEY = VALUE format.
std::string print(const data::variable &v) const
std::map< std::string, std::string > m_data
Contains a normalized string representation of the properties.
std::string compare(const data_property_map &other) const
Compares this property map with another property map. The function compare_property must be defined p...
std::string compare_property(const std::string &property, const std::string &, const std::string &) const
Compares two values x and y of a given property. This function should be redefined in derived classes...
std::string operator[](const std::string &key) const
Returns the value corresponding to key. Throws an exception if the key is not found.
unsigned int max_key_length() const
Returns the maximum length of the property names.
std::string print(std::size_t n) const
static std::string add_separators(std::string const &c, typename std::enable_if< !atermpp::is_set< Container >::value >::type *=0)
Add start/end separators for set container types.
std::set< std::multiset< std::string > > parse_set_multiset_string(std::string const &text) const
std::set< std::string > parse_set_string(std::string const &text) const
std::string to_string() const
Returns a string representation of the properties.
data_property_map()
Default constructor for derived types.
std::string align(const std::string &s, unsigned int n) const
std::string compare(const std::string &property, const std::set< T > &x, const std::set< T > &y) const
Compares two sets and returns a string with the differences encountered. Elements present in the firs...
static std::string add_separators(std::string const &c, typename std::enable_if< atermpp::is_set< Container >::value >::type *=nullptr)
Add start/end separators for non-set container types.
std::string print(const Container &v, typename atermpp::enable_if_container< Container >::type *=nullptr) const
std::string print(const Container &v, bool print_separators, typename atermpp::enable_if_container< Container >::type *=nullptr) const
\brief A data variable
Definition variable.h:28
const sort_expression & sort() const
Definition variable.h:43
Standard exception class for reporting runtime errors.
Definition exception.h:27
bool compare_property_maps(const std::string &message, const PropertyMap &map1, const std::string &expected_result)
std::string pp(const abstraction &x)
Definition data.cpp:39
std::string string_join(const Container &c, const std::string &separator)
Joins a sequence of strings. This is a replacement for boost::algorithm::join, since it gives stack o...
void trim(std::string &text)
Remove all trailing and leading spaces from the input.
std::string regex_replace(const std::string &src, const std::string &dest, const std::string &text)
Regular expression replacement in a string.
std::string remove_whitespace(const std::string &text)
Removes whitespace from a string.
std::vector< std::string > split(const std::string &line, const std::string &separators)
Split the text.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
The class variable.