mCRL2
Loading...
Searching...
No Matches
io.cpp
Go to the documentation of this file.
1// Author(s): anonymous, Thomas Neele
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#include <ranges>
11
12#include "mcrl2/atermpp/aterm_io_binary.h"
13#include "mcrl2/core/load_aterm.h"
14#include "mcrl2/data/data_io.h"
15#include "mcrl2/pbes/algorithms.h"
16#include "mcrl2/pbes/detail/pbes_io.h"
17#include "mcrl2/pbes/io.h"
18#include "mcrl2/pbes/join.h"
19#include "mcrl2/pbes/parse.h"
20#include "mcrl2/pbes/normal_forms.h"
21
22
23
24namespace mcrl2::pbes_system
25{
26
28{
29 static std::vector<utilities::file_format> result;
30 if (result.empty())
31 {
32 result.emplace_back("pbes", "PBES in internal format", false);
33 result.back().add_extension("pbes");
34 result.emplace_back("text", "PBES in textual (mCRL2) format", true);
35 result.back().add_extension("txt");
36 result.emplace_back("bes", "BES in internal format", false);
37 result.back().add_extension("bes");
38 result.emplace_back("pgsolver", "BES in PGSolver format", true);
39 result.back().add_extension("gm");
40 result.back().add_extension("pg");
41 }
42 return result;
43}
44
45/// \brief Save a PBES in the format specified.
46/// \param pbes The PBES to be stored
47/// \param stream The stream to which the output is saved.
48/// \param format Determines the format in which the result is written. If unspecified, or
49/// pbes_file_unknown is specified, then a default format is chosen.
50void save_pbes(const pbes& pbes,
51 std::ostream& stream,
52 utilities::file_format format)
53{
54 if (format == utilities::file_format())
55 {
57 }
58 mCRL2log(log::verbose) << "Saving result in " << format.shortname() << " format..." << std::endl;
60 {
61 atermpp::binary_aterm_ostream(stream) << pbes;
62 }
64 {
65 save_bes_pgsolver(pbes, stream);
66 }
67 else if (format == pbes_format_text())
68 {
69 stream << pp(pbes);
70 }
71 else
72 {
73 throw mcrl2::runtime_error("Trying to save PBES in non-PBES format (" + format.shortname() + ")");
74 }
75}
76
77/// \brief Load a PBES from file.
78/// \param pbes The PBES to which the result is loaded.
79/// \param stream The stream from which to load the PBES.
80/// \param format The format that should be assumed for the file in infilename. If unspecified, or
81/// pbes_file_unknown is specified, then a default format is chosen.
82/// \param source The source from which the stream originates. Used for error messages.
83void load_pbes(pbes& pbes, std::istream& stream, utilities::file_format format, const std::string& /*source*/)
84{
85 if (format == utilities::file_format())
86 {
88 }
89 mCRL2log(log::verbose) << "Loading PBES in " << format.shortname() << " format..." << std::endl;
90 if (format == pbes_format_internal() || format == pbes_format_internal_bes())
91 {
92 atermpp::binary_aterm_istream(stream) >> pbes;
93 }
94 else
95 if (format == pbes_format_text())
96 {
97 stream >> pbes;
98 }
99 else
100 {
101 throw mcrl2::runtime_error("Trying to load PBES from non-PBES format (" + format.shortname() + ")");
102 }
103}
104
105/// \brief save_pbes Saves a PBES to a file.
106/// \param pbes The PBES to save.
107/// \param filename The file to save the PBES in.
108/// \param format The format in which to save the PBES.
109/// \param welltypedness_check If set to false, skips checking whether pbes is well typed before
110/// saving it to file.
111///
112/// The format of the file in infilename is guessed if format is not given or if it is equal to
113/// utilities::file_format().
114void save_pbes(const pbes& pbes, const std::string& filename,
115 utilities::file_format format,
116 bool welltypedness_check)
117{
118 if (welltypedness_check)
119 {
120 assert(pbes.is_well_typed());
121 }
122 if (format == utilities::file_format())
123 {
124 format = guess_format(filename);
125 }
126
127 if (filename.empty() || filename == "-")
128 {
129 save_pbes(pbes, std::cout, format);
130 }
131 else
132 {
133 std::ofstream filestream(filename,(format.text_format()?std::ios_base::out: std::ios_base::binary));
134 if (!filestream.good())
135 {
136 throw mcrl2::runtime_error("Could not open file " + filename);
137 }
138 save_pbes(pbes, filestream, format);
139 }
140}
141
142/// \brief Load pbes from file.
143/// \param pbes The pbes to which the result is loaded.
144/// \param filename The file from which to load the PBES.
145/// \param format The format in which the PBES is stored in the file.
146///
147/// The format of the file in infilename is guessed if format is not given or if it is equal to
148/// utilities::file_format().
149void load_pbes(pbes& pbes,
150 const std::string& filename,
151 utilities::file_format format)
152{
153 if (format == utilities::file_format())
154 {
155 format = guess_format(filename);
156 }
157 if (filename.empty() || filename == "-")
158 {
159 load_pbes(pbes, std::cin, format);
160 }
161 else
162 {
163 std::ifstream filestream(filename,(format.text_format()?std::ios_base::in: std::ios_base::binary));
164 if (!filestream.good())
165 {
166 throw mcrl2::runtime_error("Could not open file " + filename);
167 }
168 load_pbes(pbes, filestream, format, core::detail::file_source(filename));
169 }
170}
171
172// transforms OpId to OpIdNoIndex
174{
175 if (x.function() == core::detail::function_symbol_OpId())
176 {
177 return atermpp::aterm(core::detail::function_symbol_OpIdNoIndex(), x.begin(), --x.end());
178 }
179 return x;
180}
181
182// transforms OpIdNoIndex to OpId
184{
185 if (x.function() == core::detail::function_symbol_OpIdNoIndex())
186 {
187 const data::function_symbol& y = reinterpret_cast<const data::function_symbol&>(x);
189 }
190 return x;
191}
192
193inline atermpp::aterm_ostream& operator<<(atermpp::aterm_ostream& stream, const pbes_equation& equation)
194{
195 stream << equation.symbol();
196 stream << equation.variable();
197 stream << equation.formula();
198 return stream;
199}
200
202{
203 fixpoint_symbol symbol;
205 pbes_expression expression;
206
207 stream >> symbol;
208 stream >> var;
209 stream >> expression;
210
211 equation = pbes_equation(symbol, var, expression);
212
213 return stream;
214}
215
217{
218 return atermpp::aterm(atermpp::function_symbol("parameterised_boolean_equation_system", 0));
219}
220
221atermpp::aterm_ostream& operator<<(atermpp::aterm_ostream& stream, const pbes& pbes)
222{
223 atermpp::aterm_stream_state state(stream);
224 stream << remove_index_impl;
225
226 stream << pbes_marker();
227 stream << pbes.data();
228 stream << pbes.global_variables();
229 stream << pbes.equations();
230 stream << pbes.initial_state();
231 return stream;
232}
233
235{
236 atermpp::aterm_stream_state state(stream);
237 stream >> add_index_impl;
238
239 try
240 {
241 atermpp::aterm marker;
242 stream >> marker;
243
244 if (marker != pbes_marker())
245 {
246 throw mcrl2::runtime_error("Stream does not contain a parameterised boolean equation system (PBES).");
247 }
248
250 std::set<data::variable> global_variables;
251 std::vector<pbes_equation> equations;
253
254 stream >> data;
255 stream >> global_variables;
256 stream >> equations;
257 stream >> initial_state;
258
259 pbes = pbes_system::pbes(data, global_variables, equations, initial_state);
260
261 // Add all the sorts that are used in the specification
262 // to the data specification. This is important for those
263 // sorts that are built in, because these are not explicitly
264 // declared.
266 }
267 catch (std::exception& ex)
268 {
269 mCRL2log(log::error) << ex.what() << "\n";
270 throw mcrl2::runtime_error(std::string("Error reading parameterised boolean equation system (PBES)."));
271 }
272
273 return stream;
274}
275
276namespace detail
277{
278
279pbes load_pbes(const std::string& filename)
280{
281 pbes result;
282 if (filename.empty() || filename == "-")
283 {
284 atermpp::binary_aterm_istream(std::cin) >> result;
285 }
286 else
287 {
288 std::ifstream from(filename, std::ifstream::in | std::ifstream::binary);
289 atermpp::binary_aterm_istream(from) >> result;
290 }
291 return result;
292}
293
294void save_pbes(const pbes& pbesspec, const std::string& filename)
295{
296 if (filename.empty() || filename == "-")
297 {
298 atermpp::binary_aterm_ostream(std::cout) << pbesspec;
299 }
300 else
301 {
302 std::ofstream to(filename, std::ofstream::out | std::ofstream::binary);
303 if (!to.good())
304 {
305 throw mcrl2::runtime_error("Could not write to filename " + filename);
306 }
307 atermpp::binary_aterm_ostream(to) << pbesspec;
308 }
309}
310
311} // namespace detail
312
313/// \brief Conversion to atermappl.
314/// \return The PBES converted to aterm format.
316{
317 atermpp::aterm global_variables = atermpp::aterm(core::detail::function_symbol_GlobVarSpec(),
318 data::variable_list(p.global_variables().begin(),
319 p.global_variables().end()));
320
321 atermpp::aterm_list eqn_list;
322 const std::vector<pbes_equation>& eqn = p.equations();
323 for (const auto & i : std::ranges::reverse_view(eqn))
324 {
325 atermpp::aterm a = pbes_equation_to_aterm(i);
326 eqn_list.push_front(a);
327 }
328 atermpp::aterm equations = atermpp::aterm(core::detail::function_symbol_PBEqnSpec(), eqn_list);
329 atermpp::aterm initial_state = atermpp::aterm(core::detail::function_symbol_PBInit(), p.initial_state());
330 atermpp::aterm result;
331
332 result = atermpp::aterm(core::detail::function_symbol_PBES(),
333 data::detail::data_specification_to_aterm(p.data()),
334 global_variables,
335 equations,
336 initial_state);
337
338 return result;
339}
340
341} // namespace mcrl2::pbes_system
The interface for a class that reads aterm from a stream. The default constructed term aterm() indica...
Definition aterm_io.h:62
The interface for a class that writes aterm to a stream. Every written term is retrieved by the corre...
Definition aterm_io.h:51
A helper class to restore the state of the aterm_{i,o}stream objects upon destruction....
Definition aterm_io.h:104
aterm_stream_state(aterm_stream &stream)
Definition aterm_io.h:106
A unordered_map class in which aterms can be stored.
\brief A function symbol
function_symbol(const core::identifier_string &name, const sort_expression &sort)
Constructor.
const core::identifier_string & name() const
const sort_expression & sort() const
const pbes_expression & formula() const
Returns the predicate formula on the right hand side of the equation.
pbes_equation(const fixpoint_symbol &symbol, const propositional_variable &variable, const pbes_expression &expr)
Constructor.
const fixpoint_symbol & symbol() const
Returns the fixpoint symbol of the equation.
const propositional_variable & variable() const
Returns the pbes variable of the equation.
parameterized boolean equation system
Definition pbes.h:54
const propositional_variable_instantiation & initial_state() const
Returns the initial state.
Definition pbes.h:188
bool is_well_typed() const
Checks if the PBES is well typed.
Definition pbes.h:261
\brief A propositional variable instantiation
\brief A propositional variable declaration
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:393
aterm_istream & operator>>(aterm_istream &stream, aterm &term)
Read the given term from the stream, but for aterm_list we want to use a specific one that performs v...
Definition aterm_io.h:93
aterm_istream & operator>>(aterm_istream &stream, aterm_transformer transformer)
Sets the given transformer to be applied to following reads.
Definition aterm_io.h:73
atermpp::aterm_istream & operator>>(atermpp::aterm_istream &stream, data_specification &spec)
Reads a data specification from a stream.
Definition data_io.cpp:61
bool is_bes(const pbes &x)
Returns true if a PBES is in BES form.
Definition pbes.cpp:69
pbes load_pbes(const std::string &filename)
Loads a PBES from filename, or from stdin if filename equals "".
Definition io.cpp:279
void save_pbes(const pbes &pbesspec, const std::string &filename)
Saves an PBES to filename, or to stdout if filename equals "".
Definition io.cpp:294
The main namespace for the PBES library.
atermpp::aterm_istream & operator>>(atermpp::aterm_istream &stream, pbes &pbes)
Reads a pbes from a stream.
Definition io.cpp:234
static atermpp::aterm remove_index_impl(const atermpp::aterm &x)
Definition io.cpp:173
void load_pbes(pbes &pbes, std::istream &stream, utilities::file_format format, const std::string &)
Load a PBES from file.
Definition io.cpp:83
void save_pbes(const pbes &pbes, const std::string &filename, utilities::file_format format, bool welltypedness_check)
save_pbes Saves a PBES to a file.
Definition io.cpp:114
const utilities::file_format & pbes_format_internal_bes()
Definition io.h:43
atermpp::aterm pbes_marker()
Definition io.cpp:216
void load_pbes(pbes &pbes, const std::string &filename, utilities::file_format format)
Load pbes from file.
Definition io.cpp:149
const utilities::file_format & pbes_format_pgsolver()
Definition io.h:45
atermpp::aterm pbes_to_aterm(const pbes &p)
Conversion to atermappl.
Definition io.cpp:315
const std::vector< utilities::file_format > & pbes_file_formats()
Definition io.cpp:27
void save_pbes(const pbes &pbes, std::ostream &stream, utilities::file_format format)
Save a PBES in the format specified.
Definition io.cpp:50
void complete_data_specification(pbes &)
Adds all sorts that appear in the PBES p to the data specification of p.
Definition pbes.h:308
atermpp::aterm_istream & operator>>(atermpp::aterm_istream &stream, pbes_equation &equation)
Definition io.cpp:201
const utilities::file_format & pbes_format_internal()
Definition io.h:39
const utilities::file_format & pbes_format_text()
Definition io.h:41
static atermpp::aterm add_index_impl(const atermpp::aterm &x)
Definition io.cpp:183