10#include "mcrl2/atermpp/aterm_io_binary.h"
11#include "mcrl2/atermpp/standard_containers/stack.h"
59 m_function_symbols.insert(function_symbol(
"end_of_stream", 0));
63 m_stream->write_bits(0, 8);
64 m_stream->write_bits(BAF_MAGIC, 16);
65 m_stream->write_bits(BAF_VERSION, 16);
75 m_stream->write_bits(
static_cast<std::size_t>(packet_type::aterm), packet_bits);
76 m_stream->write_bits(0, function_symbol_index_width());
89 void mark(std::stack<std::reference_wrapper<detail::_aterm>>& todo)
const
95void binary_aterm_ostream::
put(
const aterm& term)
98 atermpp::stack<write_todo> stack;
99 stack.emplace(
static_cast<
const aterm&>(term));
103 write_todo& current = stack.top();
104 aterm transformed = m_transformer(
static_cast<
const aterm&>(
static_cast<
const aterm&>(current.term)));
107 bool is_output = stack.size() == 1;
108 if (m_terms.index(current.term) >= m_terms.size() || is_output)
112 if (transformed.type_is_int())
117 m_stream->write_bits(
static_cast<std::size_t>(packet_type::aterm_int_output), packet_bits);
118 m_stream->write_integer(
static_cast<
const aterm_int&>(
static_cast<
const aterm&>(current.term)).value());
122 std::size_t symbol_index = write_function_symbol(transformed.function());
125 m_stream->write_bits(
static_cast<std::size_t>(packet_type::aterm), packet_bits);
126 m_stream->write_bits(symbol_index, function_symbol_index_width());
127 m_stream->write_integer(
static_cast<
const aterm_int&>(
static_cast<
const aterm&>(current.term)).value());
132 std::size_t symbol_index = write_function_symbol(transformed.function());
135 m_stream->write_bits(
static_cast<std::size_t>(is_output ? packet_type::aterm_output : packet_type::aterm), packet_bits);
136 m_stream->write_bits(symbol_index, function_symbol_index_width());
138 for (
const aterm& argument : transformed)
140 std::size_t index = m_terms.index(argument);
141 assert(index < m_terms.size());
142 m_stream->write_bits(index, term_index_width());
149 bool assigned = m_terms.insert(current.term).second;
150 assert(assigned); mcrl2_unused(assigned);
151 m_term_index_width =
static_cast<std::uint8_t>(std::log2(m_terms.size()) + 1);
159 for (
const aterm& argument : transformed)
161 const aterm& term =
static_cast<
const aterm&>(argument);
162 if (m_terms.index(term) >= m_terms.size())
169 current.write =
true;
178 while (!stack.empty());
183 assert(m_term_index_width ==
static_cast<
unsigned int>(std::log2(m_terms.size()) + 1));
189 assert(m_function_symbol_index_width ==
static_cast<
unsigned int>(std::log2(m_function_symbols.size()) + 1));
197 m_function_symbols.emplace_back();
201 if (m_stream->read_bits(8) != 0 || m_stream->read_bits(16) != BAF_MAGIC)
203 throw mcrl2::runtime_error(
"Error while reading: missing the BAF_MAGIC control sequence.");
206 std::size_t version = m_stream->read_bits(16);
209 throw mcrl2::
runtime_error(
"The BAF version (" +
std::to_string(version) +
") of the input file is incompatible with the version (" +
std::to_string(
BAF_VERSION) +
210 ") of this tool. The input file must be regenerated. ");
220 std::size_t result = m_function_symbols.index(symbol);
222 if (result < m_function_symbols.size())
229 m_stream->write_bits(
static_cast<std::size_t>(packet_type::function_symbol), packet_bits);
230 m_stream->write_string(symbol.name());
231 m_stream->write_integer(symbol.arity());
233 auto result = m_function_symbols.insert(symbol);
234 m_function_symbol_index_width =
static_cast<
unsigned int>(std::log2(m_function_symbols.size()) + 1);
245 std::size_t header = m_stream->read_bits(packet_bits);
251 std::string name = m_stream->read_string();
252 std::size_t arity = m_stream->read_integer();
253 m_function_symbols.emplace_back(name, arity);
254 m_function_symbol_index_width =
static_cast<
unsigned int>(std::log2(m_function_symbols.size()) + 1);
259 std::size_t value = m_stream->read_integer();
266 function_symbol symbol = m_function_symbols[m_stream->read_bits(function_symbol_index_width())];
277 std::size_t value = m_stream->read_integer();
278 m_terms.emplace_back(aterm_int(value));
279 m_term_index_width =
static_cast<
unsigned int>(std::log2(m_terms.size()) + 1);
284 std::vector<aterm> arguments(symbol.arity());
285 for (
std::size_t argument = 0; argument < symbol
.arity(); ++argument)
287 arguments[argument] = m_terms[m_stream->read_bits(term_index_width())];
291 aterm transformed = m_transformer(aterm(symbol, arguments.begin(), arguments.end()));
302 m_terms.emplace_back(transformed);
303 m_term_index_width =
static_cast<
unsigned int>(std::log2(m_terms.size()) + 1);
312 assert(m_term_index_width ==
static_cast<
unsigned int>(std::log2(m_terms.size()) + 1));
318 assert(m_function_symbol_index_width ==
static_cast<
unsigned int>(std::log2(m_function_symbols.size()) + 1));
324 binary_aterm_ostream
(os
) << t;
An integer term stores a single std::size_t value. It carries no arguments.
aterm()
Default constructor.
aterm & operator=(const aterm &other) noexcept=default
aterm & operator=(aterm &&other) noexcept=default
unsigned int m_function_symbol_index_width
caches the result of function_symbol_index_width().
unsigned int function_symbol_index_width()
unsigned int term_index_width()
binary_aterm_istream(std::istream &is)
Provide the input stream from which terms are read.
unsigned int m_term_index_width
caches the result of term_index_width().
void get(aterm &t) override
Reads an aterm from this stream.
binary_aterm_istream(std::shared_ptr< mcrl2::utilities::ibitstream > stream)
unsigned int m_term_index_width
caches the result of term_index_width().
~binary_aterm_ostream() override
std::size_t write_function_symbol(const function_symbol &symbol)
Write a function symbol to the output stream.
binary_aterm_ostream(std::ostream &os)
Provide the output stream to which the terms are written.
binary_aterm_ostream(std::shared_ptr< mcrl2::utilities::obitstream > stream)
unsigned int m_function_symbol_index_width
caches the result of function_symbol_index_width().
unsigned int term_index_width()
void put(const aterm &term) override
Writes an aterm in a compact binary format where subterms are shared. The term that is written itself...
unsigned int function_symbol_index_width()
bool operator==(const function_symbol &f) const
Equality test.
std::size_t arity() const
Return the arity (number of arguments) of the function symbol (function_symbol).
Standard exception class for reporting runtime errors.
The counterpart of obitstream, guarantees that the same data is read as has been written when calling...
A bitstream provides per bit writing of data to any stream (including stdout).
function_symbol g_as_int
These function symbols are used to indicate integer, list and empty list terms.
The main namespace for the aterm++ library.
static constexpr unsigned int packet_bits
The number of bits needed to store an element of packet_type.
void write_term_to_binary_stream(const aterm &t, std::ostream &os)
Writes term t to a stream in binary aterm format.
static constexpr std::uint16_t BAF_MAGIC
The magic value for a binary aterm format stream.
void read_term_from_binary_stream(std::istream &is, aterm &t)
Reads a term from a stream in binary aterm format.
packet_type
Each packet has a header consisting of a type.
void make_aterm_int(aterm_int &target, std::size_t value)
Constructs an integer term from a value.
static constexpr std::uint16_t BAF_VERSION
The BAF_VERSION constant is the version number of the ATerms written in BAF format....
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Keep track of whether the term can be written to the stream.
void mark(std::stack< std::reference_wrapper< detail::_aterm > > &todo) const
detail::reference_aterm< aterm > term
write_todo(const aterm &term)
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const