You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							235 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							235 lines
						
					
					
						
							11 KiB
						
					
					
				
								/*
							 | 
						|
								 * DeterministicSparseTransitionParserTest.cpp
							 | 
						|
								 *
							 | 
						|
								 *  Created on: Feb 24, 2014
							 | 
						|
								 *      Author: Manuel Sascha Weiand
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#include "gtest/gtest.h"
							 | 
						|
								#include "storm-config.h"
							 | 
						|
								
							 | 
						|
								#include "src/parser/DeterministicSparseTransitionParser.h"
							 | 
						|
								#include "src/storage/SparseMatrix.h"
							 | 
						|
								#include "src/settings/SettingsManager.h"
							 | 
						|
								#include "src/settings/modules/MarkovChainSettings.h"
							 | 
						|
								#include "src/settings/SettingMemento.h"
							 | 
						|
								#include "src/exceptions/FileIoException.h"
							 | 
						|
								#include "src/exceptions/WrongFormatException.h"
							 | 
						|
								
							 | 
						|
								#include "src/exceptions/InvalidArgumentException.h"
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, NonExistingFile) {
							 | 
						|
								
							 | 
						|
								    // No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
							 | 
						|
								
							 | 
						|
								    storm::storage::SparseMatrix<double> nullMatrix;
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not", nullMatrix), storm::exceptions::FileIoException);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, BasicTransitionsParsing) {
							 | 
						|
								
							 | 
						|
								    // Parse a deterministic transitions file and test the resulting matrix.
							 | 
						|
								    storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
							 | 
						|
								
							 | 
						|
								    ASSERT_EQ(8ul, transitionMatrix.getColumnCount());
							 | 
						|
								    ASSERT_EQ(21ul, transitionMatrix.getEntryCount());
							 | 
						|
								
							 | 
						|
								    // Test every entry of the matrix.
							 | 
						|
								    storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(0);
							 | 
						|
								
							 | 
						|
								    ASSERT_EQ(0ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(1ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(1ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(2ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.5, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.5, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(2ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.4, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(4ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.4, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(5ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.2, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(4ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(4ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(5ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.7, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(0ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.9, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(5ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.224653, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(7ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.775347, cIter->getValue());
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, BasicTransitionsRewardsParsing) {
							 | 
						|
								
							 | 
						|
								    // First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
							 | 
						|
								    storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
							 | 
						|
								
							 | 
						|
								    storm::storage::SparseMatrix<double> rewardMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew", transitionMatrix);
							 | 
						|
								
							 | 
						|
								    ASSERT_EQ(8ul, rewardMatrix.getColumnCount());
							 | 
						|
								    ASSERT_EQ(17ul, rewardMatrix.getEntryCount());
							 | 
						|
								
							 | 
						|
								    // Test every entry of the matrix.
							 | 
						|
								    storm::storage::SparseMatrix<double>::const_iterator cIter = rewardMatrix.begin(0);
							 | 
						|
								
							 | 
						|
								    ASSERT_EQ(1ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(10, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(2ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(5, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(5.5, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(21.4, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(4ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(4, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(5ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(2, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(3ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(4ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1.1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(5ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(9.5, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(6.7, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(0ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(5ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(12, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(35.224653, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(7ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(9.875347, cIter->getValue());
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, Whitespaces) {
							 | 
						|
								
							 | 
						|
								    // Test the resilience of the parser against whitespaces.
							 | 
						|
								    // Do so by comparing the hash of the matrix resulting from the file without whitespaces with the hash of the matrix resulting from the file with whitespaces.
							 | 
						|
								    uint_fast64_t correctHash = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra").hash();
							 | 
						|
								    storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_whitespaces.tra");
							 | 
						|
								    ASSERT_EQ(correctHash, transitionMatrix.hash());
							 | 
						|
								
							 | 
						|
								    // Do the same for the corresponding transition rewards file (with and without whitespaces)
							 | 
						|
								    correctHash = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_general.trans.rew", transitionMatrix).hash();
							 | 
						|
								    ASSERT_EQ(correctHash, storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_whitespaces.trans.rew", transitionMatrix).hash());
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, MixedTransitionOrder) {
							 | 
						|
								
							 | 
						|
								    // Since the MatrixBuilder needs sequential input of new elements reordering of transitions or states should throw an exception.
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_mixedStateOrder.tra"), storm::exceptions::InvalidArgumentException);
							 | 
						|
								
							 | 
						|
								    storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_mixedStateOrder.trans.rew", transitionMatrix), storm::exceptions::InvalidArgumentException);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, FixDeadlocks) {
							 | 
						|
								    // Set the fixDeadlocks flag temporarily. It is set to its old value once the deadlockOption object is destructed.
							 | 
						|
								    std::unique_ptr<storm::settings::SettingMemento> fixDeadlocks = storm::settings::mutableMarkovChainSettings().overrideDontFixDeadlocksSet(false);
							 | 
						|
								
							 | 
						|
								    // Parse a transitions file with the fixDeadlocks Flag set and test if it works.
							 | 
						|
								    storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock.tra");
							 | 
						|
								
							 | 
						|
								    ASSERT_EQ(9ul, transitionMatrix.getColumnCount());
							 | 
						|
								    ASSERT_EQ(23ul, transitionMatrix.getEntryCount());
							 | 
						|
								
							 | 
						|
								    storm::storage::SparseMatrix<double>::const_iterator cIter = transitionMatrix.begin(7);
							 | 
						|
								    ASSERT_EQ(7ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(1, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(6ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.224653, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(7ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0.775347, cIter->getValue());
							 | 
						|
								    cIter++;
							 | 
						|
								    ASSERT_EQ(8ul, cIter->getColumn());
							 | 
						|
								    ASSERT_EQ(0, cIter->getValue());
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, DontFixDeadlocks) {
							 | 
						|
								    // Try to parse a transitions file containing a deadlock state with the fixDeadlocksFlag unset. This should throw an exception.
							 | 
						|
								    std::unique_ptr<storm::settings::SettingMemento> dontFixDeadlocks = storm::settings::mutableMarkovChainSettings().overrideDontFixDeadlocksSet(true);
							 | 
						|
								
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_deadlock.tra"), storm::exceptions::WrongFormatException);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, DoubledLines) {
							 | 
						|
								    // There is a redundant line in the transition file. As the transition already exists this should throw an exception.
							 | 
						|
								    // Note: If two consecutive lines are doubled no exception is thrown.
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_doubledLines.tra"), storm::exceptions::InvalidArgumentException);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								TEST(DeterministicSparseTransitionParserTest, RewardForNonExistentTransition) {
							 | 
						|
								    // First parse a transition file. Then parse a transition reward file for the resulting transition matrix.
							 | 
						|
								    storm::storage::SparseMatrix<double> transitionMatrix = storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitions(STORM_CPP_TESTS_BASE_PATH "/functional/parser/tra_files/dtmc_general.tra");
							 | 
						|
								
							 | 
						|
								    // There is a reward for a transition that does not exist in the transition matrix.
							 | 
						|
								    ASSERT_THROW(storm::parser::DeterministicSparseTransitionParser<>::parseDeterministicTransitionRewards(STORM_CPP_TESTS_BASE_PATH "/functional/parser/rew_files/dtmc_rewardForNonExTrans.trans.rew", transitionMatrix), storm::exceptions::WrongFormatException);
							 | 
						|
								}
							 |