Browse Source

minor cleanups, added documentation.

tempestpy_adaptions
gereon 12 years ago
parent
commit
ad0c802fcc
  1. 44
      src/parser/parser.h
  2. 110
      src/parser/readLabFile.cpp
  3. 14
      src/parser/readLabFile.h
  4. 80
      src/parser/readTraFile.cpp
  5. 19
      src/parser/readTraFile.h

44
src/parser/parser.h

@ -15,20 +15,47 @@
#include <pantheios/pantheios.hpp> #include <pantheios/pantheios.hpp>
#include "src/exceptions/file_IO_exception.h" #include "src/exceptions/file_IO_exception.h"
namespace mrmc
{
namespace parser
{
namespace mrmc {
namespace parser {
/*!
* @brief Opens a file and maps it to memory providing a char*
* containing the file content.
*
* This class is a very simple interface to read files efficiently.
* The given file is opened and mapped to memory using mmap().
* The public member data is a pointer to the actual file content.
* Using this method, the kernel will take care of all buffering. This is
* most probably much more efficient than doing this manually.
*/
class MappedFile class MappedFile
{ {
private: private:
/*!
* @brief file descriptor obtained by open().
*/
int file; int file;
/*!
* @brief stat information about the file.
*/
struct stat st; struct stat st;
public: public:
/*!
* @brief pointer to actual file content.
*/
char* data; char* data;
/*!
* @brief Constructor of MappedFile.
*
* Will stat the given file, open it and map it to memory.
* If anything of this fails, an appropriate exception is raised
* and a log entry is written.
* @filename file to be opened
*/
MappedFile(const char* filename) MappedFile(const char* filename)
{ {
if (stat(filename, &(this->st)) != 0) if (stat(filename, &(this->st)) != 0)
@ -53,6 +80,11 @@ namespace parser
} }
} }
/*!
* @brief Destructor of MappedFile.
*
* Will unmap the data and close the file.
*/
~MappedFile() ~MappedFile()
{ {
munmap(this->data, this->st.st_size); munmap(this->data, this->st.st_size);
@ -60,5 +92,5 @@ namespace parser
} }
}; };
}
}
} // namespace parser
} // namespace mrmc

110
src/parser/readLabFile.cpp

@ -1,4 +1,4 @@
/*
/*!
* readLabFile.cpp * readLabFile.cpp
* *
* Created on: 21.11.2012 * Created on: 21.11.2012
@ -28,12 +28,11 @@
#include <pantheios/inserters/integer.hpp> #include <pantheios/inserters/integer.hpp>
namespace mrmc { namespace mrmc {
namespace parser { namespace parser {
/*! /*!
* Reads a .lab file and puts the result in a labeling structure.
* Reads a label file and puts the result in a labeling structure.
* *
* Labelings created with this method have to be freed with the delete operator. * Labelings created with this method have to be freed with the delete operator.
* @param node_count the number of states. * @param node_count the number of states.
@ -42,62 +41,125 @@ namespace parser {
*/ */
mrmc::models::AtomicPropositionsLabeling * readLabFile(int node_count, const char * filename) mrmc::models::AtomicPropositionsLabeling * readLabFile(int node_count, const char * filename)
{ {
/*
* open file
*/
MappedFile file(filename); MappedFile file(filename);
char* buf = file.data; char* buf = file.data;
char sep[] = " \n\t";
/*
* first run: obtain number of propositions
*/
char separator[] = " \n\t";
uint_fast32_t proposition_count = 0; uint_fast32_t proposition_count = 0;
{
size_t cnt = 0; size_t cnt = 0;
do {
do
{
buf += cnt; buf += cnt;
cnt = strcspn(buf, sep);
if (cnt > 0) {
cnt = strcspn(buf, separator); // position of next separator
if (cnt > 0)
{
/*
* next token is #DECLARATION: just skip it
* next token is #END: stop search
* otherwise increase proposition_count
*/
if (strncmp(buf, "#DECLARATION", cnt) == 0) continue; if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
if (strncmp(buf, "#END", cnt) == 0) break; if (strncmp(buf, "#END", cnt) == 0) break;
proposition_count++; proposition_count++;
} }
else cnt = 1;
else cnt = 1; // next char is separator, one step forward
} while (cnt > 0); } while (cnt > 0);
}
printf("node count %d\n", node_count);
/*
* create labeling object with given node and proposition count
*/
mrmc::models::AtomicPropositionsLabeling* result = new mrmc::models::AtomicPropositionsLabeling(node_count, proposition_count); mrmc::models::AtomicPropositionsLabeling* result = new mrmc::models::AtomicPropositionsLabeling(node_count, proposition_count);
char proposition[128];
/*
* second run: add propositions and node labels to labeling
*
* first thing to do: reset file pointer
*/
buf = file.data; buf = file.data;
cnt = 0;
do {
{
/*
* load propositions
*/
char proposition[128]; // buffer for proposition names
size_t cnt = 0;
do
{
buf += cnt; buf += cnt;
cnt = strcspn(buf, sep);
if (cnt > 0) {
cnt = strcspn(buf, separator); // position of next separator
if (cnt > 0)
{
/*
* next token is: #DECLARATION: just skip it
* next token is: #END: stop search
* otherwise: copy token to buffer, append trailing null byte and hand it to labeling
*/
if (strncmp(buf, "#DECLARATION", cnt) == 0) continue; if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
if (strncmp(buf, "#END", cnt) == 0) break; if (strncmp(buf, "#END", cnt) == 0) break;
strncpy(proposition, buf, cnt); strncpy(proposition, buf, cnt);
proposition[cnt] = '\0'; proposition[cnt] = '\0';
result->addAtomicProposition(proposition); result->addAtomicProposition(proposition);
} }
else cnt = 1;
else cnt = 1; // next char is separator, one step forward
} while (cnt > 0); } while (cnt > 0);
/*
* Right here, the buf pointer is still pointing to our last token,
* i.e. to #END. We want to skip this one...
*/
buf += 4; buf += 4;
}
{
/*
* now parse node label assignments
*/
uint_fast32_t node; uint_fast32_t node;
do {
node = strtol(buf, &buf, 10);
while (*buf != '\0') {
cnt = strcspn(buf, sep);
if (cnt == 0) buf++;
char proposition[128];
size_t cnt;
do
{
node = strtol(buf, &buf, 10); // parse node number
while (*buf != '\0') // while not at end of file
{
cnt = strcspn(buf, separator); // position of next separator
if (cnt == 0) buf++; // next char is separator, one step forward
else break; else break;
} }
if (cnt > 0) {
/*
* if cnt > 0, buf points to the next proposition
* otherwise, we have reached the end of the file
*/
if (cnt > 0)
{
/*
* copy proposition to buffer, add assignment to labeling
*/
strncpy(proposition, buf, cnt); strncpy(proposition, buf, cnt);
proposition[cnt] = '\0'; proposition[cnt] = '\0';
result->addAtomicPropositionToState(proposition, node); result->addAtomicPropositionToState(proposition, node);
} }
else if (node == 0)
{
/*
* If this is executed, we could read a number but there
* was no proposition after that. This strongly suggests a
* broken file, but it's not fatal...
*/
pantheios::log_WARNING("The label file ended on a node number. Is the file malformated?");
}
buf += cnt; buf += cnt;
} while (cnt > 0); } while (cnt > 0);
}
return result; return result;
} }
} //namespace parser } //namespace parser
} //namespace mrmc } //namespace mrmc

14
src/parser/readLabFile.h

@ -1,19 +1,15 @@
/*
* read_lab_file.h
*
*/
#pragma once #pragma once
#include "src/models/atomic_propositions_labeling.h" #include "src/models/atomic_propositions_labeling.h"
namespace mrmc { namespace mrmc {
namespace parser { namespace parser {
/*!
* @brief Load label file and return initialized AtomicPropositionsLabeling object.
*/
mrmc::models::AtomicPropositionsLabeling * readLabFile(int node_count, const char * filename); mrmc::models::AtomicPropositionsLabeling * readLabFile(int node_count, const char * filename);
}
}
} // namespace parser
} // namespace mrmc

80
src/parser/readTraFile.cpp

@ -1,7 +1,5 @@
/*! read_tra_file.cpp
* Provides functions for reading a *.tra file describing the transition
* system of a Markov chain (DTMC) and saving it into a corresponding
* matrix.
/*!
* readTraFile.cpp
* *
* Created on: 20.11.2012 * Created on: 20.11.2012
* Author: Gereon Kremer * Author: Gereon Kremer
@ -30,9 +28,13 @@
#include <pantheios/inserters/real.hpp> #include <pantheios/inserters/real.hpp>
namespace mrmc { namespace mrmc {
namespace parser{ namespace parser{
/*!
* Skips all whitespaces and returns new pointer.
*
* @todo should probably be replaced by strspn et.al.
*/
char* skipWS(char* buf) char* skipWS(char* buf)
{ {
while(1) while(1)
@ -43,20 +45,25 @@ char* skipWS(char* buf)
} }
/*! /*!
* @brief Perform first pass through the file and obtain number of
* non-zero cells and maximum node id.
*
* This method does the first pass through the .tra file and computes * This method does the first pass through the .tra file and computes
* the number of non-zero elements that are not diagonal elements, * the number of non-zero elements that are not diagonal elements,
* which correspondents to the number of transitions that are not * which correspondents to the number of transitions that are not
* self-loops. * self-loops.
* (Diagonal elements are treated in a special way). * (Diagonal elements are treated in a special way).
* It also calculates the maximum node id and stores it in maxnode.
* *
* @return The number of non-zero elements that are not on the diagonal * @return The number of non-zero elements that are not on the diagonal
* @param buf Data to scan. Is expected to be some char array. * @param buf Data to scan. Is expected to be some char array.
* @param maxnode Is set to highest id of all nodes.
*/ */
static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode) static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode)
{ {
uint_fast32_t non_zero = 0; uint_fast32_t non_zero = 0;
/*!
/*
* check file header and extract number of transitions * check file header and extract number of transitions
*/ */
if (strncmp(buf, "STATES ", 7) != 0) return 0; if (strncmp(buf, "STATES ", 7) != 0) return 0;
@ -67,7 +74,7 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode)
buf += 12; // skip "TRANSITIONS " buf += 12; // skip "TRANSITIONS "
if ((non_zero = strtol(buf, &buf, 10)) == 0) return 0; if ((non_zero = strtol(buf, &buf, 10)) == 0) return 0;
/*!
/*
* check all transitions for non-zero diagonal entrys * check all transitions for non-zero diagonal entrys
*/ */
uint_fast32_t row, col; uint_fast32_t row, col;
@ -75,10 +82,20 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode)
maxnode = 0; maxnode = 0;
while (1) while (1)
{ {
/*
* read row and column
*/
row = strtol(buf, &buf, 10); row = strtol(buf, &buf, 10);
if (row > maxnode) maxnode = row;
col = strtol(buf, &buf, 10); col = strtol(buf, &buf, 10);
/*
* check if one is larger than the current maximum id
*/
if (row > maxnode) maxnode = row;
if (col > maxnode) maxnode = col; if (col > maxnode) maxnode = col;
/*
* read value. if value is zero, we have reached the end of the file.
* if row == col, we have a diagonal element which is treated seperately and this non_zero must be decreased.
*/
val = strtod(buf, &buf); val = strtod(buf, &buf);
if (val == 0.0) break; if (val == 0.0) break;
if (row == col) non_zero--; if (row == col) non_zero--;
@ -89,7 +106,8 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode)
/*!Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
/*!
* Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
* *
* Matrices created with this method have to be freed with the delete operator. * Matrices created with this method have to be freed with the delete operator.
* @param filename input .tra file's name. * @param filename input .tra file's name.
@ -97,36 +115,35 @@ static uint_fast32_t makeFirstPass(char* buf, uint_fast32_t &maxnode)
*/ */
sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) { sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) {
/*!
/*
* enforce locale where decimal point is '.' * enforce locale where decimal point is '.'
*/ */
setlocale( LC_NUMERIC, "C" ); setlocale( LC_NUMERIC, "C" );
/*
* open file
*/
MappedFile file(filename); MappedFile file(filename);
char* buf = file.data;
/*!
/*
* perform first pass, i.e. count entries that are not zero and not on the diagonal * perform first pass, i.e. count entries that are not zero and not on the diagonal
*/ */
uint_fast32_t maxnode; uint_fast32_t maxnode;
uint_fast32_t non_zero = makeFirstPass(file.data, maxnode); uint_fast32_t non_zero = makeFirstPass(file.data, maxnode);
if (non_zero == 0)
{
/*!
* first pass returned zero, this means the file format was wrong
/*
* if first pass returned zer, the file format was wrong
*/ */
throw mrmc::exceptions::wrong_file_format();
return NULL;
}
if (non_zero == 0) throw mrmc::exceptions::wrong_file_format();
/*!
/*
* perform second pass * perform second pass
* *
* from here on, we already know that the file header is correct * from here on, we already know that the file header is correct
*/ */
char* buf = file.data;
sparse::StaticSparseMatrix<double> *sp = NULL; sparse::StaticSparseMatrix<double> *sp = NULL;
/*!
/*
* read file header, extract number of states * read file header, extract number of states
*/ */
buf += 7; // skip "STATES " buf += 7; // skip "STATES "
@ -139,29 +156,27 @@ sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) {
pantheios::integer(maxnode + 1), " maxnodes and ", pantheios::integer(maxnode + 1), " maxnodes and ",
pantheios::integer(non_zero), " Non-Zero-Elements"); pantheios::integer(non_zero), " Non-Zero-Elements");
/*!
/*
* Creating matrix * Creating matrix
* Memory for diagonal elements is automatically allocated, hence only the number of non-diagonal * Memory for diagonal elements is automatically allocated, hence only the number of non-diagonal
* non-zero elements has to be specified (which is non_zero, computed by make_first_pass) * non-zero elements has to be specified (which is non_zero, computed by make_first_pass)
*/ */
sp = new sparse::StaticSparseMatrix<double>(maxnode + 1); sp = new sparse::StaticSparseMatrix<double>(maxnode + 1);
if (sp == NULL)
{
/*!
* creating the matrix failed
*/
throw std::bad_alloc();
return NULL;
}
if (sp == NULL) throw std::bad_alloc();
sp->initialize(non_zero); sp->initialize(non_zero);
uint_fast64_t row, col; uint_fast64_t row, col;
double val; double val;
/*!
/*
* read all transitions from file * read all transitions from file
*/ */
while (1) while (1)
{ {
/*
* read row, col and value. if value == 0.0, we have reached the
* end of the file.
*/
row = strtol(buf, &buf, 10); row = strtol(buf, &buf, 10);
col = strtol(buf, &buf, 10); col = strtol(buf, &buf, 10);
val = strtod(buf, &buf); val = strtod(buf, &buf);
@ -174,7 +189,7 @@ sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) {
sp->addNextValue(row,col,val); sp->addNextValue(row,col,val);
} }
/*!
/*
* clean up * clean up
*/ */
pantheios::log_DEBUG("Finalizing Matrix"); pantheios::log_DEBUG("Finalizing Matrix");
@ -183,5 +198,4 @@ sparse::StaticSparseMatrix<double> * readTraFile(const char * filename) {
} }
} //namespace parser } //namespace parser
} //namespace mrmc } //namespace mrmc

19
src/parser/readTraFile.h

@ -1,19 +1,16 @@
/*
* read_tra_file.h
*
* Created on: 15.08.2012
* Author: Thomas Heinemann
*/
#pragma once #pragma once
#include "src/sparse/static_sparse_matrix.h" #include "src/sparse/static_sparse_matrix.h"
namespace mrmc { namespace mrmc {
namespace parser {
namespace parser {
mrmc::sparse::StaticSparseMatrix<double> * readTraFile(const char * filename);
/*!
* @brief Load transition system from file and return initialized
* StaticSparseMatrix object.
*/
mrmc::sparse::StaticSparseMatrix<double> * readTraFile(const char * filename);
}
}
} // namespace parser
} // namespace mrmc
Loading…
Cancel
Save