TimQu
8 years ago
17 changed files with 610 additions and 183 deletions
-
8resources/examples/testfiles/lab/nondet.choicelab
-
11src/storm/models/sparse/ChoiceLabeling.cpp
-
3src/storm/models/sparse/ChoiceLabeling.h
-
23src/storm/models/sparse/ItemLabeling.cpp
-
11src/storm/models/sparse/ItemLabeling.h
-
4src/storm/models/sparse/StateLabeling.cpp
-
1src/storm/models/sparse/StateLabeling.h
-
6src/storm/parser/AutoParser.cpp
-
24src/storm/parser/DeterministicModelParser.cpp
-
17src/storm/parser/DeterministicModelParser.h
-
28src/storm/parser/MarkovAutomatonParser.cpp
-
3src/storm/parser/MarkovAutomatonParser.h
-
8src/storm/parser/NondeterministicModelParser.cpp
-
254src/storm/parser/SparseItemLabelingParser.cpp
-
82src/storm/parser/SparseItemLabelingParser.h
-
145src/test/parser/AtomicPropositionLabelingParserTest.cpp
-
165src/test/parser/SparseItemLabelingParserTest.cpp
@ -0,0 +1,8 @@ |
|||
#DECLARATION |
|||
alpha beta gamma delta |
|||
#END |
|||
0 0 alpha |
|||
0 1 alpha beta |
|||
0 2 gamma |
|||
1 0 beta |
|||
3 2 beta |
@ -0,0 +1,254 @@ |
|||
#include "storm/parser/SparseItemLabelingParser.h"
|
|||
|
|||
#include <cstring>
|
|||
#include <string>
|
|||
#include <iostream>
|
|||
|
|||
#include "storm/utility/cstring.h"
|
|||
#include "storm/parser/MappedFile.h"
|
|||
|
|||
#include "storm/utility/macros.h"
|
|||
#include "storm/exceptions/WrongFormatException.h"
|
|||
#include "storm/exceptions/FileIoException.h"
|
|||
|
|||
namespace storm { |
|||
namespace parser { |
|||
|
|||
using namespace storm::utility::cstring; |
|||
|
|||
storm::models::sparse::StateLabeling SparseItemLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const & filename) { |
|||
MappedFile file(filename.c_str()); |
|||
checkSyntax(filename, file); |
|||
|
|||
// Create labeling object with given node and label count.
|
|||
storm::models::sparse::StateLabeling labeling(stateCount); |
|||
|
|||
// initialize the buffer
|
|||
char const* buf = file.getData(); |
|||
|
|||
// add the labels to the labeling
|
|||
parseLabelNames(filename, labeling, buf); |
|||
|
|||
// Now parse the assignments of labels to states.
|
|||
parseDeterministicLabelAssignments(filename, labeling, buf); |
|||
|
|||
return labeling; |
|||
} |
|||
|
|||
storm::models::sparse::ChoiceLabeling SparseItemLabelingParser::parseChoiceLabeling(uint_fast64_t choiceCount, std::string const& filename, boost::optional<std::vector<uint_fast64_t>> const& nondeterministicChoiceIndices) { |
|||
MappedFile file(filename.c_str()); |
|||
checkSyntax(filename, file); |
|||
|
|||
// Create labeling object with given node and label count.
|
|||
storm::models::sparse::ChoiceLabeling labeling(choiceCount); |
|||
|
|||
// initialize the buffer
|
|||
char const* buf = file.getData(); |
|||
|
|||
// add the labels to the labeling
|
|||
parseLabelNames(filename, labeling, buf); |
|||
|
|||
// Now parse the assignments of labels to states.
|
|||
if (nondeterministicChoiceIndices) { |
|||
parseNonDeterministicLabelAssignments(filename, labeling, nondeterministicChoiceIndices.get(), buf); |
|||
} else { |
|||
parseDeterministicLabelAssignments(filename, labeling, buf); |
|||
} |
|||
|
|||
return labeling; |
|||
} |
|||
|
|||
|
|||
void SparseItemLabelingParser::checkSyntax(std::string const & filename, storm::parser::MappedFile const& file) { |
|||
char const* buf = file.getData(); |
|||
|
|||
// First pass: Count the number of propositions.
|
|||
bool foundDecl = false, foundEnd = false; |
|||
size_t cnt = 0; |
|||
|
|||
// Iterate over tokens until we hit #END or the end of the file.
|
|||
while(buf[0] != '\0') { |
|||
|
|||
//Move the buffer to the beginning of the next word.
|
|||
buf += cnt; |
|||
buf = trimWhitespaces(buf); |
|||
|
|||
// Get the number of characters until the next separator.
|
|||
cnt = skipWord(buf) - buf; |
|||
if (cnt > 0) { |
|||
|
|||
// If the next token is #DECLARATION: Just skip it.
|
|||
// If the next token is #END: Stop the search.
|
|||
// Otherwise increase proposition_count.
|
|||
if (strncmp(buf, "#DECLARATION", cnt) == 0) { |
|||
foundDecl = true; |
|||
continue; |
|||
} else if (strncmp(buf, "#END", cnt) == 0) { |
|||
foundEnd = true; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// If #DECLARATION or #END have not been found, the file format is wrong.
|
|||
STORM_LOG_THROW(foundDecl, storm::exceptions::WrongFormatException, "Error while parsing " << filename << ": File header is corrupted (Token #DECLARATION missing - case sensitive)."); |
|||
STORM_LOG_THROW(foundEnd, storm::exceptions::WrongFormatException, "Error while parsing " << filename << ": File header is corrupted (Token #END missing - case sensitive)."); |
|||
} |
|||
|
|||
|
|||
void SparseItemLabelingParser::parseLabelNames(std::string const & filename, storm::models::sparse::ItemLabeling& labeling, char const*& buf) { |
|||
// Prepare a buffer for proposition names.
|
|||
char proposition[128]; |
|||
size_t cnt = 0; |
|||
|
|||
// Parse proposition names.
|
|||
// As we already checked the file header, we know that #DECLARATION and #END are tokens in the character stream.
|
|||
while(buf[0] != '\0') { |
|||
|
|||
//Move the buffer to the beginning of the next word.
|
|||
buf += cnt; |
|||
buf = trimWhitespaces(buf); |
|||
|
|||
// Get the number of characters until the next separator.
|
|||
cnt = skipWord(buf) - buf; |
|||
|
|||
if (cnt >= sizeof(proposition)) { |
|||
|
|||
// if token is longer than our buffer, the following strncpy code might get risky...
|
|||
STORM_LOG_ERROR("Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found."); |
|||
throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found."; |
|||
|
|||
} else if (cnt > 0) { |
|||
|
|||
// If the next token is #DECLARATION: Just skip it.
|
|||
if (strncmp(buf, "#DECLARATION", cnt) == 0) continue; |
|||
|
|||
// If the next token is #END: Stop the search.
|
|||
if (strncmp(buf, "#END", cnt) == 0) break; |
|||
|
|||
// Otherwise copy the token to the buffer, append a trailing null byte and hand it to labeling.
|
|||
strncpy(proposition, buf, cnt); |
|||
proposition[cnt] = '\0'; |
|||
labeling.addLabel(proposition); |
|||
} |
|||
} |
|||
|
|||
// At this point, the pointer buf is still pointing to our last token, i.e. to #END.
|
|||
// We want to skip it.
|
|||
buf += 4; |
|||
|
|||
// Now eliminate remaining whitespaces such as empty lines and start parsing.
|
|||
buf = trimWhitespaces(buf); |
|||
} |
|||
|
|||
void SparseItemLabelingParser::parseDeterministicLabelAssignments(std::string const & filename, storm::models::sparse::ItemLabeling& labeling, char const*& buf) { |
|||
uint_fast64_t state = 0; |
|||
uint_fast64_t lastState = (uint_fast64_t)-1; |
|||
uint_fast64_t const startIndexComparison = lastState; |
|||
size_t cnt = 0; |
|||
char proposition[128]; |
|||
|
|||
while (buf[0] != '\0') { |
|||
|
|||
// Parse the state number and iterate over its labels (atomic propositions).
|
|||
// Stop at the end of the line.
|
|||
state = checked_strtol(buf, &buf); |
|||
|
|||
// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
|
|||
if (state <= lastState && lastState != startIndexComparison) { |
|||
STORM_LOG_ERROR("Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."); |
|||
throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously."; |
|||
} |
|||
|
|||
while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) { |
|||
cnt = skipWord(buf) - buf; |
|||
if (cnt == 0) { |
|||
|
|||
// The next character is a separator.
|
|||
// If it is a line separator, we continue with next node.
|
|||
// Otherwise, we skip it and try again.
|
|||
if (buf[0] == '\n' || buf[0] == '\r') break; |
|||
buf++; |
|||
} else { |
|||
|
|||
// Copy the label to the buffer, null terminate it and add it to labeling.
|
|||
strncpy(proposition, buf, cnt); |
|||
proposition[cnt] = '\0'; |
|||
|
|||
// Has the label been declared in the header?
|
|||
if(!labeling.containsLabel(proposition)) { |
|||
STORM_LOG_ERROR("Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared."); |
|||
throw storm::exceptions::WrongFormatException() << "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared."; |
|||
} |
|||
if (labeling.isStateLabeling()) { |
|||
labeling.asStateLabeling().addLabelToState(proposition, state); |
|||
} else { |
|||
STORM_LOG_ASSERT(labeling.isChoiceLabeling(), "Unexpected labeling type"); |
|||
labeling.asChoiceLabeling().addLabelToChoice(proposition, state); |
|||
} |
|||
buf += cnt; |
|||
} |
|||
} |
|||
buf = trimWhitespaces(buf); |
|||
lastState = state; |
|||
} |
|||
} |
|||
|
|||
void SparseItemLabelingParser::parseNonDeterministicLabelAssignments(std::string const & filename, storm::models::sparse::ChoiceLabeling& labeling, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, char const*& buf) { |
|||
uint_fast64_t const startIndexComparison = (uint_fast64_t)-1; |
|||
uint_fast64_t state = 0; |
|||
uint_fast64_t lastState = startIndexComparison; |
|||
uint_fast64_t localChoice = 0; |
|||
uint_fast64_t lastLocalChoice = startIndexComparison; |
|||
size_t cnt = 0; |
|||
char proposition[128]; |
|||
|
|||
while (buf[0] != '\0') { |
|||
|
|||
// Parse the state and choice number and iterate over its labels (atomic propositions).
|
|||
// Stop at the end of the line.
|
|||
state = checked_strtol(buf, &buf); |
|||
localChoice = checked_strtol(buf, &buf); |
|||
|
|||
// If we see this state for the first time, reset the last choice
|
|||
if (state != lastState) { |
|||
lastLocalChoice = startIndexComparison; |
|||
} |
|||
|
|||
// If the state-choice pair has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
|
|||
STORM_LOG_THROW(state >= lastState || lastState == startIndexComparison, storm::exceptions::WrongFormatException, "Error while parsing " << filename << ": State " << state << " and Choice " << localChoice << " were found but the state has already been read or skipped previously."); |
|||
STORM_LOG_THROW(state != lastState || localChoice > lastLocalChoice || lastLocalChoice == startIndexComparison, storm::exceptions::WrongFormatException, "Error while parsing " << filename << ": State " << state << " and Choice " << localChoice << " were found but the choice has already been read or skipped previously."); |
|||
|
|||
uint_fast64_t const globalChoice = nondeterministicChoiceIndices[state] + localChoice; |
|||
STORM_LOG_THROW(globalChoice < nondeterministicChoiceIndices[state + 1], storm::exceptions::WrongFormatException, "Error while parsing " << filename << ": Invalid choice index " << localChoice << " at state " << state << "."); |
|||
|
|||
while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) { |
|||
cnt = skipWord(buf) - buf; |
|||
if (cnt == 0) { |
|||
|
|||
// The next character is a separator.
|
|||
// If it is a line separator, we continue with next node.
|
|||
// Otherwise, we skip it and try again.
|
|||
if (buf[0] == '\n' || buf[0] == '\r') break; |
|||
buf++; |
|||
} else { |
|||
|
|||
// Copy the label to the buffer, null terminate it and add it to labeling.
|
|||
strncpy(proposition, buf, cnt); |
|||
proposition[cnt] = '\0'; |
|||
|
|||
// Has the label been declared in the header?
|
|||
STORM_LOG_THROW(labeling.containsLabel(proposition), storm::exceptions::WrongFormatException, "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared."); |
|||
|
|||
labeling.addLabelToChoice(proposition, globalChoice); |
|||
buf += cnt; |
|||
} |
|||
} |
|||
buf = trimWhitespaces(buf); |
|||
lastState = state; |
|||
lastLocalChoice = localChoice; |
|||
} |
|||
} |
|||
|
|||
} // namespace parser
|
|||
} // namespace storm
|
@ -0,0 +1,82 @@ |
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <cstdint> |
|||
#include <boost/optional.hpp> |
|||
|
|||
#include "storm/parser/MappedFile.h" |
|||
#include "storm/models/sparse/StateLabeling.h" |
|||
#include "storm/models/sparse/ChoiceLabeling.h" |
|||
|
|||
|
|||
namespace storm { |
|||
namespace parser { |
|||
|
|||
/*! |
|||
* This class can be used to parse a labeling file. |
|||
*/ |
|||
class SparseItemLabelingParser { |
|||
|
|||
public: |
|||
|
|||
/*! |
|||
* Parses the given file and returns the resulting state labeling. |
|||
* |
|||
* @param stateCount The number of states of the model to be labeled. |
|||
* @param filename The path and name of the labeling (.lab) file. |
|||
* @return The parsed labeling as a StateLabeling object. |
|||
*/ |
|||
static storm::models::sparse::StateLabeling parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const &filename); |
|||
|
|||
/*! |
|||
* Parses the given file and returns the resulting choice labeling. |
|||
* |
|||
* @param choiceCount the number of choices of the model. |
|||
* @param filename The name of the file to parse. |
|||
* @param nondeterministicChoiceIndices if given, the choices are assumed to be nondeterministic, i.e., |
|||
* a choice is specified by a tuple of state index and (local) choice index. |
|||
* @return The resulting choice labeling. |
|||
*/ |
|||
static storm::models::sparse::ChoiceLabeling parseChoiceLabeling(uint_fast64_t choiceCount, std::string const& filename, boost::optional<std::vector<uint_fast64_t>> const& nondeterministicChoiceIndices = boost::none); |
|||
|
|||
private: |
|||
|
|||
/*! |
|||
* Perform syntax checks of the file |
|||
* @param file The mapped file |
|||
*/ |
|||
static void checkSyntax(std::string const & filename, storm::parser::MappedFile const& file); |
|||
|
|||
/*! |
|||
* Parses the file header (i.e. the #DECLARATION ... #END construct) and adds the label names to the given labeling |
|||
* |
|||
* @param labeling the labeling to which label names are added |
|||
* @param buf the reference to the file contents |
|||
*/ |
|||
static void parseLabelNames(std::string const & filename, storm::models::sparse::ItemLabeling& labeling, char const*& buf); |
|||
|
|||
|
|||
/*! |
|||
* Parses the label assignments assuming that each item is uniquely specified by a single index, e.g., |
|||
* * 42 label1 label2 label3 |
|||
* |
|||
* @param labeling the labeling to which file assignments are added |
|||
* @param buf the reference to the file contents |
|||
*/ |
|||
static void parseDeterministicLabelAssignments(std::string const & filename, storm::models::sparse::ItemLabeling& labeling, char const*& buf); |
|||
|
|||
/*! |
|||
* Parses the label assignments assuming that each item is specified by a tuple of indices, e.g., |
|||
* * 42 0 label1 label2 |
|||
* * 42 1 label2 label3 |
|||
* |
|||
* @param labeling the labeling to which file assignments are added |
|||
* @param nondeterministicChoiceIndices The indices at which the choices of the states begin. |
|||
* @param buf the reference to the file contents |
|||
*/ |
|||
static void parseNonDeterministicLabelAssignments(std::string const & filename, storm::models::sparse::ChoiceLabeling& labeling, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, char const*& buf); |
|||
|
|||
}; |
|||
|
|||
} // namespace parser |
|||
} // namespace storm |
@ -1,145 +0,0 @@ |
|||
/*
|
|||
* AtomicPropositionLabelingParserTest.cpp |
|||
* |
|||
* Created on: 03.03.2014 |
|||
* Author: Manuel Sascha Weiand |
|||
*/ |
|||
|
|||
#include "gtest/gtest.h"
|
|||
#include "storm-config.h"
|
|||
#include "storm/models/sparse/StateLabeling.h"
|
|||
#include "storm/parser/AtomicPropositionLabelingParser.h"
|
|||
#include "storm/exceptions/FileIoException.h"
|
|||
#include "storm/exceptions/WrongFormatException.h"
|
|||
#include "storm/exceptions/OutOfRangeException.h"
|
|||
|
|||
#include <memory>
|
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, NonExistingFile) { |
|||
// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(0,STORM_TEST_RESOURCES_DIR "/nonExistingFile.not"), storm::exceptions::FileIoException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, BasicParsing) { |
|||
// This test is based on a test case from the original MRMC.
|
|||
|
|||
// Parsing the file
|
|||
storm::models::sparse::StateLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_TEST_RESOURCES_DIR "/lab/pctl_general.lab"); |
|||
|
|||
// Checking whether all propositions are in the labelling
|
|||
|
|||
char phi[] = "phi", psi[] = "psi", smth[] = "smth"; |
|||
|
|||
ASSERT_TRUE(labeling.containsLabel(phi)); |
|||
ASSERT_TRUE(labeling.containsLabel(psi)); |
|||
ASSERT_TRUE(labeling.containsLabel(smth)); |
|||
|
|||
// Testing whether all and only the correct nodes are labeled with "phi"
|
|||
ASSERT_TRUE(labeling.getStateHasLabel(phi,0)); |
|||
ASSERT_TRUE(labeling.getStateHasLabel(phi,1)); |
|||
ASSERT_TRUE(labeling.getStateHasLabel(phi,2)); |
|||
|
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,3)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,4)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,5)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,6)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,7)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,8)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,9)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,10)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,11)); |
|||
|
|||
//Testing whether all and only the correct nodes are labeled with "psi"
|
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,0)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,1)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,2)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,3)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,4)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,5)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,6)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,7)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,8)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,9)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,10)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,11)); |
|||
|
|||
//Testing whether all and only the correct nodes are labeled with "smth"
|
|||
ASSERT_TRUE(labeling.getStateHasLabel(smth,2)); |
|||
|
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,0)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,1)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,3)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,4)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,5)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,6)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,7)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,8)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,9)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,10)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,11)); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, NoDeclarationTagHeader) { |
|||
// No #DECLARATION tag in file
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/noDeclarationTag.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, NoEndTagHeader) { |
|||
// No #END tag in file.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/noEndTag.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, MisspelledDeclarationTagHeader) { |
|||
// The #DECLARATION tag is misspelled.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/declarationMisspell.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, MisspelledEndTagHeader) { |
|||
// The #END tag is misspelled.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/endMisspell.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, NoLabelDeclaredNoneGiven) { |
|||
// No label between #DECLARATION and #END and no labels given.
|
|||
storm::models::sparse::StateLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_TEST_RESOURCES_DIR "/lab/noLabelsDecNoneGiven.lab"); |
|||
ASSERT_EQ(0ul, labeling.getNumberOfLabels()); |
|||
for(uint_fast64_t i = 0; i < 13; i++) { |
|||
ASSERT_TRUE(labeling.getLabelsOfState(i).empty()); |
|||
} |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, UndeclaredLabelsGiven) { |
|||
// Undeclared labels given.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/undeclaredLabelsGiven.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, LabelForNonExistentState) { |
|||
// The index of one of the state that are to be labeled is higher than the number of states in the model.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/labelForNonexistentState.lab"), storm::exceptions::OutOfRangeException); |
|||
} |
|||
|
|||
// Note: As implemented at the moment, each label given for a state in any line is set to true for that state (logical or over all lines for that state).
|
|||
// This behavior might not be ideal as multiple lines for one state are not necessary and might indicate a corrupt or wrong file.
|
|||
TEST(AtomicPropositionLabelingParserTest, DoubledLines) { |
|||
// There are multiple lines attributing labels to the same state.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_TEST_RESOURCES_DIR "/lab/doubledLines.lab"), storm::exceptions::WrongFormatException); |
|||
|
|||
// There is a line for a state that has been skipped.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(6, STORM_TEST_RESOURCES_DIR "/lab/doubledLinesSkipped.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, WrongProposition) { |
|||
// Swapped the state index and the label at one entry.
|
|||
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/swappedStateAndProposition.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(AtomicPropositionLabelingParserTest, Whitespaces) { |
|||
// Different configurations of allowed whitespaces are tested.
|
|||
|
|||
// First parse the labeling file without added whitespaces and obtain the hash of its parsed representation.
|
|||
storm::models::sparse::StateLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_TEST_RESOURCES_DIR "/lab/withoutWhitespaces.lab"); |
|||
|
|||
// Now parse the labeling file with the added whitespaces and compare the hashes.
|
|||
storm::models::sparse::StateLabeling labeling2 = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(13, STORM_TEST_RESOURCES_DIR "/lab/withWhitespaces.lab"); |
|||
ASSERT_TRUE(labeling == labeling2); |
|||
} |
@ -0,0 +1,165 @@ |
|||
#include "gtest/gtest.h"
|
|||
#include "storm-config.h"
|
|||
#include "storm/models/sparse/StateLabeling.h"
|
|||
#include "storm/parser/SparseItemLabelingParser.h"
|
|||
#include "storm/exceptions/FileIoException.h"
|
|||
#include "storm/exceptions/WrongFormatException.h"
|
|||
#include "storm/exceptions/OutOfRangeException.h"
|
|||
|
|||
#include <memory>
|
|||
|
|||
TEST(SparseItemLabelingParserTest, NonExistingFile) { |
|||
// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(0,STORM_TEST_RESOURCES_DIR "/nonExistingFile.not"), storm::exceptions::FileIoException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, BasicDeterministicParsing) { |
|||
// This test is based on a test case from the original MRMC.
|
|||
|
|||
// Parsing the file
|
|||
storm::models::sparse::StateLabeling labeling = storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(12, STORM_TEST_RESOURCES_DIR "/lab/pctl_general.lab"); |
|||
|
|||
// Checking whether all propositions are in the labelling
|
|||
|
|||
char phi[] = "phi", psi[] = "psi", smth[] = "smth"; |
|||
|
|||
ASSERT_TRUE(labeling.containsLabel(phi)); |
|||
ASSERT_TRUE(labeling.containsLabel(psi)); |
|||
ASSERT_TRUE(labeling.containsLabel(smth)); |
|||
|
|||
// Testing whether all and only the correct nodes are labeled with "phi"
|
|||
ASSERT_TRUE(labeling.getStateHasLabel(phi,0)); |
|||
ASSERT_TRUE(labeling.getStateHasLabel(phi,1)); |
|||
ASSERT_TRUE(labeling.getStateHasLabel(phi,2)); |
|||
|
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,3)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,4)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,5)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,6)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,7)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,8)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,9)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,10)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(phi,11)); |
|||
|
|||
//Testing whether all and only the correct nodes are labeled with "psi"
|
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,0)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,1)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,2)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,3)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,4)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,5)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,6)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,7)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,8)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,9)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,10)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(psi,11)); |
|||
|
|||
//Testing whether all and only the correct nodes are labeled with "smth"
|
|||
ASSERT_TRUE(labeling.getStateHasLabel(smth,2)); |
|||
|
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,0)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,1)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,3)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,4)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,5)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,6)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,7)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,8)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,9)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,10)); |
|||
ASSERT_FALSE(labeling.getStateHasLabel(smth,11)); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, BasicNondeterministicParsing) { |
|||
|
|||
std::vector<uint_fast64_t> choiceIndices {0, 3, 5, 6, 9, 11}; |
|||
|
|||
// Parsing the file
|
|||
storm::models::sparse::ChoiceLabeling labeling = storm::parser::SparseItemLabelingParser::parseChoiceLabeling(11, STORM_TEST_RESOURCES_DIR "/lab/nondet.choicelab", choiceIndices); |
|||
|
|||
// Checking whether the parsed labeling is correct
|
|||
ASSERT_TRUE(labeling.containsLabel("alpha")); |
|||
EXPECT_EQ(2, labeling.getChoices("alpha").getNumberOfSetBits()); |
|||
EXPECT_TRUE(labeling.getChoiceHasLabel("alpha", 0)); |
|||
EXPECT_TRUE(labeling.getChoiceHasLabel("alpha", 1)); |
|||
|
|||
ASSERT_TRUE(labeling.containsLabel("beta")); |
|||
EXPECT_EQ(3, labeling.getChoices("beta").getNumberOfSetBits()); |
|||
EXPECT_TRUE(labeling.getChoiceHasLabel("beta", 1)); |
|||
EXPECT_TRUE(labeling.getChoiceHasLabel("beta", 3)); |
|||
EXPECT_TRUE(labeling.getChoiceHasLabel("beta", 8)); |
|||
|
|||
ASSERT_TRUE(labeling.containsLabel("gamma")); |
|||
EXPECT_EQ(1, labeling.getChoices("gamma").getNumberOfSetBits()); |
|||
EXPECT_TRUE(labeling.getChoiceHasLabel("gamma", 2)); |
|||
|
|||
ASSERT_TRUE(labeling.containsLabel("delta")); |
|||
EXPECT_TRUE(labeling.getChoices("delta").empty()); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, NoDeclarationTagHeader) { |
|||
// No #DECLARATION tag in file
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/noDeclarationTag.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, NoEndTagHeader) { |
|||
// No #END tag in file.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/noEndTag.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, MisspelledDeclarationTagHeader) { |
|||
// The #DECLARATION tag is misspelled.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/declarationMisspell.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, MisspelledEndTagHeader) { |
|||
// The #END tag is misspelled.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/endMisspell.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, NoLabelDeclaredNoneGiven) { |
|||
// No label between #DECLARATION and #END and no labels given.
|
|||
storm::models::sparse::StateLabeling labeling = storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(13, STORM_TEST_RESOURCES_DIR "/lab/noLabelsDecNoneGiven.lab"); |
|||
ASSERT_EQ(0ul, labeling.getNumberOfLabels()); |
|||
for(uint_fast64_t i = 0; i < 13; i++) { |
|||
ASSERT_TRUE(labeling.getLabelsOfState(i).empty()); |
|||
} |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, UndeclaredLabelsGiven) { |
|||
// Undeclared labels given.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/undeclaredLabelsGiven.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, LabelForNonExistentState) { |
|||
// The index of one of the state that are to be labeled is higher than the number of states in the model.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/labelForNonexistentState.lab"), storm::exceptions::OutOfRangeException); |
|||
} |
|||
|
|||
// Note: As implemented at the moment, each label given for a state in any line is set to true for that state (logical or over all lines for that state).
|
|||
// This behavior might not be ideal as multiple lines for one state are not necessary and might indicate a corrupt or wrong file.
|
|||
TEST(SparseItemLabelingParserTest, DoubledLines) { |
|||
// There are multiple lines attributing labels to the same state.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(6, STORM_TEST_RESOURCES_DIR "/lab/doubledLines.lab"), storm::exceptions::WrongFormatException); |
|||
|
|||
// There is a line for a state that has been skipped.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(6, STORM_TEST_RESOURCES_DIR "/lab/doubledLinesSkipped.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, WrongProposition) { |
|||
// Swapped the state index and the label at one entry.
|
|||
ASSERT_THROW(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(3, STORM_TEST_RESOURCES_DIR "/lab/swappedStateAndProposition.lab"), storm::exceptions::WrongFormatException); |
|||
} |
|||
|
|||
TEST(SparseItemLabelingParserTest, Whitespaces) { |
|||
// Different configurations of allowed whitespaces are tested.
|
|||
|
|||
// First parse the labeling file without added whitespaces and obtain the hash of its parsed representation.
|
|||
storm::models::sparse::StateLabeling labeling = storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(13, STORM_TEST_RESOURCES_DIR "/lab/withoutWhitespaces.lab"); |
|||
|
|||
// Now parse the labeling file with the added whitespaces and compare the hashes.
|
|||
storm::models::sparse::StateLabeling labeling2 = storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(13, STORM_TEST_RESOURCES_DIR "/lab/withWhitespaces.lab"); |
|||
ASSERT_TRUE(labeling == labeling2); |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue