Browse Source
			
			
			Merge branch 'gspn' into jani_gspn_support
			
				
		Merge branch 'gspn' into jani_gspn_support
	
		
	
			
				Former-commit-id:mainf5d1a9fb6a[formerly5fdac9a9f0] Former-commit-id:e8e48b198d
				 34 changed files with 138376 additions and 54 deletions
			
			
		- 
					1CMakeLists.txt
- 
					41034examples/gspn/HypercubeGrid/hc3k4p4b12.pnml
- 
					87274examples/gspn/HypercubeGrid/hc4k3p3b12.pnml
- 
					1examples/gspn/HypercubeGrid/hc5k3p3b15.pnml.REMOVED.git-id
- 
					5554examples/gspn/ibm319/IBM319.pnml
- 
					148examples/gspn/tiny/tiny01.pnml
- 
					1236examples/gspn/workflow_cluster/workflow_cluster.pnml
- 
					9src/CMakeLists.txt
- 
					14src/adapters/CarlAdapter.h
- 
					2src/builder/ExplicitDFTModelBuilder.cpp
- 
					326src/builder/ExplicitGspnModelBuilder.cpp
- 
					172src/builder/ExplicitGspnModelBuilder.h
- 
					573src/parser/GspnParser.cpp
- 
					165src/parser/GspnParser.h
- 
					10src/solver/stateelimination/EliminatorBase.cpp
- 
					516src/storage/gspn/GSPN.cpp
- 
					183src/storage/gspn/GSPN.h
- 
					90src/storage/gspn/GspnBuilder.cpp
- 
					89src/storage/gspn/GspnBuilder.h
- 
					43src/storage/gspn/ImmediateTransition.h
- 
					59src/storage/gspn/Marking.cpp
- 
					80src/storage/gspn/Marking.h
- 
					41src/storage/gspn/Place.cpp
- 
					87src/storage/gspn/Place.h
- 
					36src/storage/gspn/TimedTransition.h
- 
					195src/storage/gspn/Transition.cpp
- 
					240src/storage/gspn/Transition.h
- 
					153src/storm-gspn.cpp
- 
					55src/utility/constants.cpp
- 
					26src/utility/constants.h
- 
					1src/utility/storm.cpp
- 
					2src/utility/storm.h
- 
					13src/utility/vector.h
- 
					2storm-config.h.in
						
							
						
						
							41034
	
						
						examples/gspn/HypercubeGrid/hc3k4p4b12.pnml
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						
						
							
						
						
							87274
	
						
						examples/gspn/HypercubeGrid/hc4k3p3b12.pnml
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						| @ -0,0 +1 @@ | |||
| 1dcc3a0045e4d0f9358f9ee04e70c6f0107929be | |||
						
							
						
						
							5554
	
						
						examples/gspn/ibm319/IBM319.pnml
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						| @ -0,0 +1,148 @@ | |||
| <pnml> | |||
| 	<net id="tiny1"> | |||
| 		<place id="p1"> | |||
| 			<initialMarking> | |||
| 				<value>Default,1</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<place id="p2"> | |||
| 			<initialMarking> | |||
| 				<value>Default,1</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<place id="p3"> | |||
| 			<initialMarking> | |||
| 				<value>Default,0</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<place id="p4"> | |||
| 			<initialMarking> | |||
| 				<value>Default,0</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<place id="p5"> | |||
| 			<initialMarking> | |||
| 				<value>Default,0</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<place id="p6"> | |||
| 			<initialMarking> | |||
| 				<value>Default,0</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<place id="p7"> | |||
| 			<initialMarking> | |||
| 				<value>Default,0</value> | |||
| 			</initialMarking> | |||
| 		</place> | |||
| 		<transition id="t1"> | |||
| 			<rate> | |||
| 				<value>1</value> | |||
| 			</rate> | |||
| 			<timed> | |||
| 				<value>false</value> | |||
| 			</timed> | |||
| 		</transition> | |||
| 		<transition id="t2"> | |||
| 			<rate> | |||
| 				<value>2</value> | |||
| 			</rate> | |||
| 			<timed> | |||
| 				<value>false</value> | |||
| 			</timed> | |||
| 		</transition> | |||
| 		<transition id="t3"> | |||
| 			<rate> | |||
| 				<value>3</value> | |||
| 			</rate> | |||
| 			<timed> | |||
| 				<value>false</value> | |||
| 			</timed> | |||
| 		</transition> | |||
| 		<transition id="l1"> | |||
| 			<rate> | |||
| 				<value>4</value> | |||
| 			</rate> | |||
| 			<timed> | |||
| 				<value>true</value> | |||
| 			</timed> | |||
| 		</transition> | |||
| 		<transition id="l2"> | |||
| 			<rate> | |||
| 				<value>5</value> | |||
| 			</rate> | |||
| 			<timed> | |||
| 				<value>true</value> | |||
| 			</timed> | |||
| 			<priority> | |||
| 			    <text>2</text> | |||
| 			</priority> | |||
| 		</transition> | |||
| 		<arc id="arc1" source="p1" target="t1"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc2" source="t1" target="p3"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc3" source="p2" target="t2"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc4" source="t2" target="p5"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc5" source="p2" target="t3"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc6" source="p3" target="t3"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc7" source="t3" target="p4"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc8" source="p4" target="l1"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc9" source="l1" target="p6"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc10" source="p5" target="l2"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 		<arc id="arc11" source="l2" target="p7"> | |||
| 			<inscription> | |||
| 				<value>Default,1</value> | |||
| 			</inscription> | |||
| 			<type value="normal" /> | |||
| 		</arc> | |||
| 	</net> | |||
| </pnml> | |||
						
							
						
						
							1236
	
						
						examples/gspn/workflow_cluster/workflow_cluster.pnml
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						| @ -0,0 +1,326 @@ | |||
| #include "src/builder/ExplicitGspnModelBuilder.h"
 | |||
| 
 | |||
| #include "src/models/sparse/StandardRewardModel.h"
 | |||
| 
 | |||
| #include "src/utility/macros.h"
 | |||
| #include "src/exceptions/NotImplementedException.h"
 | |||
| #include "src/storage/expressions/ExpressionManager.h"
 | |||
| #include "src/parser/FormulaParser.h"
 | |||
| #include "src/storage/expressions/ExpressionEvaluator.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace builder { | |||
| 
 | |||
|         template<typename ValueType> | |||
|         storm::models::sparse::MarkovAutomaton<ValueType> ExplicitGspnModelBuilder<ValueType>::translateGspn(storm::gspn::GSPN const& gspn, std::string const& formula) { | |||
|             // set the given gspn and compute the limits of the net
 | |||
|             this->gspn = gspn; | |||
|             computeCapacities(gspn); | |||
| 
 | |||
|             // markings maps markings to their corresponding rowgroups (indices)
 | |||
|             markings = storm::storage::BitVectorHashMap<uint_fast64_t>(numberOfTotalBits, 100); | |||
|             builder = storm::storage::SparseMatrixBuilder<double>(0, 0, 0, false, true); | |||
| 
 | |||
|             // add initial marking to todo list
 | |||
|             auto bitvector = gspn.getInitialMarking(numberOfBits, numberOfTotalBits)->getBitVector(); | |||
|             findOrAddBitvectorToMarkings(*bitvector); | |||
|             currentRowIndex = 0; | |||
| 
 | |||
|             // vector marking markovian states (vector contains an 1 if the state is markovian)
 | |||
|             storm::storage::BitVector markovianStates(0); | |||
| 
 | |||
|             // vector containing the exit rates for the markovian states
 | |||
|             std::vector<ValueType> exitRates; | |||
| 
 | |||
| 
 | |||
|             while (!todo.empty()) { | |||
|                 // take next element from the todo list
 | |||
|                 auto currentBitvector = todo.front(); | |||
|                 todo.pop_front(); | |||
|                 auto currentMarking = storm::gspn::Marking(gspn.getNumberOfPlaces(), numberOfBits, *currentBitvector); | |||
| 
 | |||
|                 // increment list of states by one
 | |||
|                 markovianStates.resize(markovianStates.size() + 1, 0); | |||
| 
 | |||
|                 // create new row group for the current marking
 | |||
|                 builder.newRowGroup(markings.getValue(*currentBitvector)); | |||
| 
 | |||
|                 std::cout << "work on: " << *currentBitvector << std::endl; | |||
| 
 | |||
|                 auto enabledImmediateTransitions = getEnabledImmediateTransition(currentMarking); | |||
|                 if (!enabledImmediateTransitions.empty()) { | |||
|                     markovianStates.set(currentRowIndex, 0); | |||
|                     exitRates.push_back(0); | |||
| 
 | |||
|                     auto partitions = partitonEnabledImmediateTransitions(currentMarking, enabledImmediateTransitions); | |||
|                     addRowForPartitions(partitions, currentMarking); | |||
|                 } else { | |||
| 
 | |||
|                     auto enabledTimedTransitions = getEnabledTimedTransition(currentMarking); | |||
|                     if (!enabledTimedTransitions.empty()) { | |||
|                         markovianStates.set(currentRowIndex, 1); | |||
| 
 | |||
|                         auto accRate = getAccumulatedRate(enabledTimedTransitions); | |||
|                         std::cout << "\t\tacc. rate: " << accRate << std::endl; | |||
|                         exitRates.push_back(accRate); | |||
| 
 | |||
|                         addRowForTimedTransitions(enabledTimedTransitions, currentMarking, accRate); | |||
|                     } else { | |||
|                         markovianStates.set(currentRowIndex, 1); | |||
|                     } | |||
|                 } | |||
|                 ++currentRowIndex; | |||
|             } | |||
| 
 | |||
|             auto matrix = builder.build(); | |||
| 
 | |||
|             // create expression manager and add variables from the gspn
 | |||
|             auto expressionManager = std::make_shared<storm::expressions::ExpressionManager>(); | |||
|             for (auto& place : gspn.getPlaces()) { | |||
|                 expressionManager->declareIntegerVariable(place.getName()); | |||
|             } | |||
| 
 | |||
|             // parse formula
 | |||
|             storm::parser::FormulaParser formulaParser(expressionManager); | |||
|             auto formulaPtr = formulaParser.parseSingleFormulaFromString(formula); | |||
|             auto atomicFormulas = formulaPtr->getAtomicExpressionFormulas(); | |||
| 
 | |||
|             // create empty state labeling
 | |||
|             storm::models::sparse::StateLabeling labeling(markings.size()); | |||
|             storm::expressions::ExpressionEvaluator<double> expressionEvaluator(*expressionManager); | |||
| 
 | |||
|             std::cout << std::endl; | |||
|             std::cout << "build labeling:" << std::endl; | |||
|             for (auto& atomicFormula : atomicFormulas) { | |||
|                 std::cout << atomicFormula; | |||
|                 auto label = atomicFormula->toString(); | |||
|                 labeling.addLabel(label); | |||
| 
 | |||
|                 for (auto statePair : markings) { | |||
|                     auto marking = storm::gspn::Marking(gspn.getNumberOfPlaces(), numberOfBits, statePair.first); | |||
|                     for (auto& place : gspn.getPlaces()) { | |||
|                         auto variable = expressionManager->getVariable(place.getName()); | |||
|                         expressionEvaluator.setIntegerValue(variable, marking.getNumberOfTokensAt(place.getID())); | |||
|                     } | |||
|                     bool hold = expressionEvaluator.asBool(atomicFormula->getExpression()); | |||
|                     if (hold) { | |||
|                         labeling.addLabelToState(label, statePair.second); | |||
|                     } | |||
|                 } | |||
| 
 | |||
|             } | |||
| 
 | |||
|             //auto labeling = getStateLabeling();
 | |||
| 
 | |||
|             return storm::models::sparse::MarkovAutomaton<double>(matrix, labeling, markovianStates, exitRates); | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         void ExplicitGspnModelBuilder<ValueType>::addRowForPartitions(std::vector<std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>>> const& partitions, storm::gspn::Marking const& currentMarking) { | |||
|             for (auto& partition : partitions) { | |||
|                 std::cout << "\tnew partition:" << std::endl; | |||
|                 auto accWeight = getAccumulatedWeight(partition); | |||
|                 std::cout << "\t\tacc. weight: " << accWeight << std::endl; | |||
| 
 | |||
|                 std::map<uint_fast64_t , double, storm::builder::ExplicitGspnModelBuilder<ValueType>::cmpByIndex> weights; | |||
|                 for (auto& trans : partition) { | |||
|                     std::cout << "\t\ttransname: " << trans->getName() << std::endl; | |||
|                     auto newMarking = trans->fire(currentMarking); | |||
|                     std::cout << "\t\t\t target marking: " << *newMarking.getBitVector() << std::endl; | |||
| 
 | |||
|                     findOrAddBitvectorToMarkings(*newMarking.getBitVector()); | |||
| 
 | |||
|                     auto it = weights.find(markings.getValue(*newMarking.getBitVector())); | |||
|                     double currentWeight = 0; | |||
|                     if (it != weights.end()) { | |||
|                         currentWeight = weights.at(markings.getValue(*newMarking.getBitVector())); | |||
|                     } | |||
|                     currentWeight += trans->getWeight() / accWeight; | |||
|                     weights[markings.getValue(*newMarking.getBitVector())] = currentWeight; | |||
|                 } | |||
| 
 | |||
|                 addValuesToBuilder(weights); | |||
|             } | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         void ExplicitGspnModelBuilder<ValueType>::addRowForTimedTransitions(std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>> const& enabledTimedTransitions, storm::gspn::Marking const& currentMarking, double const& accRate) { | |||
|             std::map<uint_fast64_t , double, storm::builder::ExplicitGspnModelBuilder<ValueType>::cmpByIndex> rates; | |||
|             for (auto& trans : enabledTimedTransitions) { | |||
|                 std::cout << "\t\ttransname: " << trans->getName() << std::endl; | |||
|                 auto newMarking = trans->fire(currentMarking); | |||
|                 std::cout << "\t\t\t target marking: " << *newMarking.getBitVector() << std::endl; | |||
| 
 | |||
|                 findOrAddBitvectorToMarkings(*newMarking.getBitVector()); | |||
| 
 | |||
|                 auto it = rates.find(markings.getValue(*newMarking.getBitVector())); | |||
|                 double currentWeightRate = 0; | |||
|                 if (it != rates.end()) { | |||
|                     currentWeightRate = rates.at(markings.getValue(*newMarking.getBitVector())); | |||
|                 } | |||
|                 currentWeightRate += trans->getRate() / accRate; | |||
|                 rates[markings.getValue(*newMarking.getBitVector())] = currentWeightRate; | |||
| 
 | |||
|             } | |||
| 
 | |||
|             addValuesToBuilder(rates); | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         void ExplicitGspnModelBuilder<ValueType>::addValuesToBuilder(std::map<uint_fast64_t , double, storm::builder::ExplicitGspnModelBuilder<ValueType>::cmpByIndex> const& values) { | |||
|             for (auto& it : values) { | |||
|                 std::cout << "\t\tadd value \"" << it.second << "\" to " << getBitvector(it.first) << std::endl; | |||
|                 builder.addNextValue(currentRowIndex, it.first, it.second); | |||
|             } | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         std::vector<std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>>> ExplicitGspnModelBuilder<ValueType>::partitonEnabledImmediateTransitions( | |||
|                 storm::gspn::Marking const& marking, | |||
|                 std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> const& enabledImmediateTransitions) { | |||
|             decltype(partitonEnabledImmediateTransitions(marking, enabledImmediateTransitions)) result; | |||
| 
 | |||
|             std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> weightedTransitions; | |||
| 
 | |||
|             for (auto& trans : enabledImmediateTransitions) { | |||
|                 if (trans->noWeightAttached()) { | |||
|                     decltype(weightedTransitions) singleton; | |||
|                     singleton.push_back(trans); | |||
|                     result.push_back(singleton); | |||
|                 } else { | |||
|                     weightedTransitions.push_back(trans); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             if (weightedTransitions.size() != 0) { | |||
|                 result.push_back(weightedTransitions); | |||
|             } | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         double ExplicitGspnModelBuilder<ValueType>::getAccumulatedWeight(std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> const& vector) const { | |||
|             double result = 0; | |||
| 
 | |||
|             for (auto &trans : vector) { | |||
|                 result += trans->getWeight(); | |||
|             } | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         void ExplicitGspnModelBuilder<ValueType>::computeCapacities(storm::gspn::GSPN const& gspn) { | |||
|             uint_fast64_t sum = 0; | |||
|             for (auto& place : gspn.getPlaces()) {//TODO
 | |||
|                 numberOfBits[place.getID()] = 1; | |||
|                 sum += numberOfBits[place.getID()]; | |||
|             } | |||
| 
 | |||
|             // compute next multiple of 64
 | |||
|             uint_fast64_t rem = sum % 64; | |||
|             numberOfTotalBits = sum + 64 - rem; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>> ExplicitGspnModelBuilder<ValueType>::getEnabledTimedTransition( | |||
|                 storm::gspn::Marking const& marking) { | |||
|             std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>>result; | |||
| 
 | |||
|             uint_fast64_t highestSeenPriority = 0; | |||
| 
 | |||
|             for (auto& trans_ptr : gspn.getTimedTransitions()) { | |||
|                 if (trans_ptr->isEnabled(marking)) { | |||
|                     if (trans_ptr->getPriority() > highestSeenPriority) { | |||
|                         highestSeenPriority = trans_ptr->getPriority(); | |||
|                         result.clear(); | |||
|                     } | |||
|                     result.push_back(trans_ptr); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> ExplicitGspnModelBuilder<ValueType>::getEnabledImmediateTransition( | |||
|                 storm::gspn::Marking const& marking) { | |||
|             std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>>result; | |||
| 
 | |||
|             uint_fast64_t highestSeenPriority = 0; | |||
| 
 | |||
|             for (auto& trans_ptr : gspn.getImmediateTransitions()) { | |||
|                 if (trans_ptr->isEnabled(marking)) { | |||
|                     if (trans_ptr->getPriority() > highestSeenPriority) { | |||
|                         highestSeenPriority = trans_ptr->getPriority(); | |||
|                         result.clear(); | |||
|                     } | |||
|                     result.push_back(trans_ptr); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         double ExplicitGspnModelBuilder<ValueType>::getAccumulatedRate(std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>> const& vector) { | |||
|             double result = 0; | |||
|             for (auto trans_ptr : vector) { | |||
|                 result += trans_ptr->getRate(); | |||
|             } | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         storm::storage::BitVector ExplicitGspnModelBuilder<ValueType>::getBitvector(uint_fast64_t const& index) { | |||
|             for (auto it = markings.begin(); it != markings.end(); ++it) { | |||
|                 if (std::get<1>(*it) == index) { | |||
|                     return std::get<0>(*it); | |||
|                 } | |||
|             } | |||
|             return storm::storage::BitVector(); | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         uint_fast64_t ExplicitGspnModelBuilder<ValueType>::findOrAddBitvectorToMarkings(storm::storage::BitVector const &bitvector) { | |||
|             auto index = markings.findOrAdd(bitvector, nextRowGroupIndex); | |||
| 
 | |||
|             if (index == nextRowGroupIndex) { | |||
|                 // bitvector was not already in the map
 | |||
|                 ++nextRowGroupIndex; | |||
|                 // bitvector was also never in the todo list
 | |||
|                 todo.push_back(std::make_shared<storm::storage::BitVector>(bitvector)); | |||
|             } | |||
|             return index; | |||
|         } | |||
| 
 | |||
|         template<typename ValueType> | |||
|         storm::models::sparse::StateLabeling ExplicitGspnModelBuilder<ValueType>::getStateLabeling() const { | |||
|             storm::models::sparse::StateLabeling labeling(markings.size()); | |||
| 
 | |||
|             std::map<uint_fast64_t , std::string> idToName; | |||
|             for (auto& place : gspn.getPlaces()) { | |||
|                 idToName[place.getID()] = place.getName(); | |||
|                 labeling.addLabel(place.getName()); | |||
|             } | |||
| 
 | |||
|             auto it = markings.begin(); | |||
|             for ( ; it != markings.end() ; ++it) { | |||
|                 auto bitvector = std::get<0>(*it); | |||
|                 storm::gspn::Marking marking(gspn.getNumberOfPlaces(), numberOfBits, bitvector); | |||
|                 for (auto i = 0; i < marking.getNumberOfPlaces(); i++) { | |||
|                     if (marking.getNumberOfTokensAt(i) > 0) { | |||
|                         std::cout << i << std::endl; | |||
|                         labeling.addLabelToState(idToName.at(i), i); | |||
|                     } | |||
|                 } | |||
|             } | |||
| 
 | |||
|             return labeling; | |||
|         } | |||
| 
 | |||
|         template class ExplicitGspnModelBuilder<double>; | |||
|     } | |||
| } | |||
| @ -0,0 +1,172 @@ | |||
| #ifndef STORM_BUILDER_EXPLICITGSPNMODELBUILDER_H_ | |||
| #define STORM_BUILDER_EXPLICITGSPNMODELBUILDER_H_ | |||
| 
 | |||
| #include <string> | |||
| 
 | |||
| #include "src/models/sparse/MarkovAutomaton.h" | |||
| #include "src/models/sparse/StandardRewardModel.h" | |||
| #include "src/storage/BitVector.h" | |||
| #include "src/storage/BitVectorHashMap.h" | |||
| #include "src/storage/gspn/GSPN.h" | |||
| #include "src/storage/gspn/ImmediateTransition.h" | |||
| #include "src/storage/gspn/TimedTransition.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace builder { | |||
| 
 | |||
|         /*! | |||
|          * This class provides the facilities for building an markov automaton. | |||
|          */ | |||
|         template<typename ValueType=double> | |||
|         class ExplicitGspnModelBuilder { | |||
|         public: | |||
| 
 | |||
|             /*! | |||
|              * Builds an MarkovAutomaton from the given GSPN. | |||
|              * | |||
|              * @param gspn The gspn whose semantic is covered by the MarkovAutomaton | |||
|              * @return The resulting MarkovAutomaton | |||
|              */ | |||
|             storm::models::sparse::MarkovAutomaton<ValueType> translateGspn(storm::gspn::GSPN const& gspn, std::string const& formula); | |||
|         private: | |||
| 
 | |||
|             /*! | |||
|              * Add for each partition a new row in the probability matrix. | |||
|              * | |||
|              * @param partitions The partitioned immediate transitions. | |||
|              * @param currentMarking The current marking which is considered at the moment. | |||
|              */ | |||
|             void addRowForPartitions(std::vector<std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>>> const& partitions, storm::gspn::Marking const& currentMarking); | |||
| 
 | |||
| 
 | |||
|             /*! | |||
|              * Add row for a markovian state. | |||
|              * | |||
|              * @param enabledTimedTransitions List of enabled timed transitions. | |||
|              * @param currentMarking The current marking which is considered at the moment. | |||
|              * @param accRate The sum of all rates of the enabled timed transisitons | |||
|              */ | |||
|             void addRowForTimedTransitions(std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>> const& enabledTimedTransitions, storm::gspn::Marking const& currentMarking, double const& accRate); | |||
| 
 | |||
|             /*! | |||
|              * Struct for comparing unsigned integer for maps | |||
|              */ | |||
|             struct cmpByIndex { | |||
|                 bool operator()(const uint_fast64_t &a, const uint_fast64_t &b) const { | |||
|                     return a < b; | |||
|                 } | |||
|             }; | |||
| 
 | |||
|             /*! | |||
|              * This method insert the values from a map into the matrix | |||
|              * | |||
|              * @param values The values which are inserted | |||
|              */ | |||
|             void addValuesToBuilder(std::map<uint_fast64_t , double, storm::builder::ExplicitGspnModelBuilder<ValueType>::cmpByIndex> const& values); | |||
| 
 | |||
| 
 | |||
|             /*! | |||
|              * This method partitions all enabled immediate transitions w.r.t. a marking. | |||
|              * All enabled weighted immediate transitions are in one vector. Between these transitions | |||
|              * is chosen probabilistically by the weights. | |||
|              * | |||
|              * All other enabled non-weighted immediate transitions are in an singleton vector. | |||
|              * Between different vectors is chosen non-deterministically. | |||
|              * | |||
|              * @param marking The current marking which is considered. | |||
|              * @param enabledImmediateTransistions A vector of enabled immediate transitions. | |||
|              * @return The vector of vectors which is described above. | |||
|              */ | |||
|             std::vector<std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>>> partitonEnabledImmediateTransitions(storm::gspn::Marking const& marking, std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> const& enabledImmediateTransitions); | |||
| 
 | |||
|             /*! | |||
|              * Computes the accumulated weight of immediate transisions which are stored in a list. | |||
|              * | |||
|              * @param vector List of immediate transisitions. | |||
|              */ | |||
|             double getAccumulatedWeight(std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> const& vector) const; | |||
| 
 | |||
|             /*! | |||
|              * Compute the upper bound for the number of tokens in each place. | |||
|              * Also computes the number of bits which are used to store a marking. | |||
|              * | |||
|              * @param gspn The corresponding gspn. | |||
|              */ | |||
|             void computeCapacities(storm::gspn::GSPN const& gspn); | |||
| 
 | |||
|             /*! | |||
|              * Returns the vector of enabled timed transition with the highest priority. | |||
|              * | |||
|              * | |||
|              * @param marking The current marking which is considered. | |||
|              * @return The vector of enabled timed transitions. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>> getEnabledTimedTransition( | |||
|                     storm::gspn::Marking const& marking); | |||
| 
 | |||
|             /*! | |||
|              * Returns the vector of active immediate transition with the highest priority. | |||
|              * | |||
|              * @param marking The current marking which is considered. | |||
|              * @return The vector of enabled immediate transitions. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<double>>> getEnabledImmediateTransition( | |||
|                     storm::gspn::Marking const& marking); | |||
| 
 | |||
|             /*! | |||
|              * Computes the accumulated rate of a vector of timed transitions. | |||
|              * | |||
|              * @param vector The vector of timed transitions. | |||
|              * @return The accumulated rate. | |||
|              */ | |||
|             double getAccumulatedRate(std::vector<std::shared_ptr<storm::gspn::TimedTransition<double>>> const& vector); | |||
| 
 | |||
|             // is only needed for debugging purposes | |||
|             // since markings is injective, we can determine the bitvector | |||
|             storm::storage::BitVector getBitvector(uint_fast64_t const& index); | |||
| 
 | |||
|             /*! | |||
|              * Adds the bitvector to the marking-map. | |||
|              * If the bitvector corresponds to a new marking the bitvector is added to the todo list. | |||
|              * | |||
|              * @return The rowGroup index for the bitvector. | |||
|              */ | |||
|             uint_fast64_t findOrAddBitvectorToMarkings(storm::storage::BitVector const& bitvector); | |||
| 
 | |||
|             /*! | |||
|              * Computes the state labeling and returns it. | |||
|              * Every state is labeled with its name. | |||
|              * | |||
|              * @return The computed state labeling. | |||
|              */ | |||
|             storm::models::sparse::StateLabeling getStateLabeling() const; | |||
| 
 | |||
| 
 | |||
|             // contains the number of bits which are used the store the number of tokens at each place | |||
|             std::map<uint_fast64_t, uint_fast64_t> numberOfBits; | |||
| 
 | |||
|             // contains the number of bits used to create markings | |||
|             uint_fast64_t numberOfTotalBits; | |||
| 
 | |||
|             // maps bitvectors (markings w.r.t. the capacity) to their rowgroup | |||
|             storm::storage::BitVectorHashMap<uint_fast64_t> markings = storm::storage::BitVectorHashMap<uint_fast64_t>(64, 1); | |||
| 
 | |||
|             // a list of markings for which the outgoing edges need to be computed | |||
|             std::deque<std::shared_ptr<storm::storage::BitVector>> todo; | |||
| 
 | |||
|             //the gspn which is transformed | |||
|             storm::gspn::GSPN gspn; | |||
| 
 | |||
|             // the next index for a new rowgroup | |||
|             uint_fast64_t nextRowGroupIndex = 0; | |||
| 
 | |||
|             // builder object which is used to create the probability matrix | |||
|             storm::storage::SparseMatrixBuilder<double> builder; | |||
| 
 | |||
|             // contains the current row index during the computation | |||
|             uint_fast64_t currentRowIndex; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_BUILDER_EXPLICITGSPNMODELBUILDER_H_ | |||
| @ -0,0 +1,573 @@ | |||
| #include "src/parser/GspnParser.h"
 | |||
| 
 | |||
| #include <iostream>
 | |||
| 
 | |||
| #include <xercesc/dom/DOM.hpp>
 | |||
| #include <xercesc/sax/HandlerBase.hpp>
 | |||
| #include <xercesc/util/PlatformUtils.hpp>
 | |||
| 
 | |||
| #include "src/exceptions/UnexpectedException.h"
 | |||
| #include "src/storage/gspn/Place.h"
 | |||
| #include "src/storage/gspn/ImmediateTransition.h"
 | |||
| #include "src/utility/macros.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace parser { | |||
|         storm::gspn::GSPN const& GspnParser::parse(std::string const& filename) { | |||
|             // initialize parser
 | |||
|             newNode = 0; | |||
|             gspn = storm::gspn::GSPN(); | |||
| 
 | |||
|             // initialize xercesc
 | |||
|             try { | |||
|                 xercesc::XMLPlatformUtils::Initialize(); | |||
|             } | |||
|             catch (xercesc::XMLException const& toCatch) { | |||
|                 // Error occurred during the initialization process. Abort parsing since it is not possible.
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Failed to initialize xercesc\n"); | |||
|             } | |||
| 
 | |||
|             auto parser = new xercesc::XercesDOMParser(); | |||
|             parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always); | |||
|             parser->setDoNamespaces(false); | |||
|             parser->setDoSchema(false); | |||
|             parser->setLoadExternalDTD(false); | |||
|             parser->setIncludeIgnorableWhitespace(false); | |||
| 
 | |||
|             auto errHandler = (xercesc::ErrorHandler*) new xercesc::HandlerBase(); | |||
|             parser->setErrorHandler(errHandler); | |||
| 
 | |||
|             // parse file
 | |||
|             try { | |||
|                 parser->parse(filename.c_str()); | |||
|             } | |||
|             catch (xercesc::XMLException const& toCatch) { | |||
|                 auto message = xercesc::XMLString::transcode(toCatch.getMessage()); | |||
|                 // Error occurred while parsing the file. Abort constructing the gspn since the input file is not valid
 | |||
|                 // or the parser run into a problem.
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, message); | |||
|                 xercesc::XMLString::release(&message); | |||
|             } | |||
|             catch (const xercesc::DOMException& toCatch) { | |||
|                 auto message = xercesc::XMLString::transcode(toCatch.msg); | |||
|                 // Error occurred while parsing the file. Abort constructing the gspn since the input file is not valid
 | |||
|                 // or the parser run into a problem.
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, message); | |||
|                 xercesc::XMLString::release(&message); | |||
|             } | |||
|             catch (...) { | |||
|                 // Error occurred while parsing the file. Abort constructing the gspn since the input file is not valid
 | |||
|                 // or the parser run into a problem.
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Failed to parse pnml file.\n"); | |||
|             } | |||
| 
 | |||
|             // build gspn by traversing the DOM object
 | |||
|             parser->getDocument()->normalizeDocument(); | |||
|             xercesc::DOMElement* elementRoot = parser->getDocument()->getDocumentElement(); | |||
|             // If the top-level node is not a "pnml" node, then throw an exception.
 | |||
|             STORM_LOG_THROW(getName(elementRoot).compare("pnml") == 0, storm::exceptions::UnexpectedException, "Failed to identify the root element.\n"); | |||
|             traversePnmlElement(elementRoot); | |||
| 
 | |||
|             // clean up
 | |||
|             delete parser; | |||
|             delete errHandler; | |||
|             xercesc::XMLPlatformUtils::Terminate(); | |||
| 
 | |||
|             return gspn; | |||
|         } | |||
| 
 | |||
|         void GspnParser::traversePnmlElement(xercesc::DOMElement const* const element) { | |||
|             // traverse attributes
 | |||
|             for (uint_fast64_t i = 0; i < element->getAttributes()->getLength(); ++i) { | |||
|                 auto attr = element->getAttributes()->item(i); | |||
|                 auto name = getName(attr); | |||
| 
 | |||
|                 // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                 // Notify the user and continue the parsing.
 | |||
|                 STORM_PRINT_AND_LOG("unknown attribute (node=pnml): " + name + "\n"); | |||
|             } | |||
| 
 | |||
|             // traverse children
 | |||
|             for (uint_fast64_t i = 0; i < element->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = element->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
| 
 | |||
|                 if (name.compare("net") == 0) { | |||
|                     traverseNetOrPage(child); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=pnml): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|         } | |||
| 
 | |||
|         void GspnParser::traverseNetOrPage(xercesc::DOMNode const* const node) { | |||
|             // traverse attributes
 | |||
|             for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { | |||
|                 auto attr = node->getAttributes()->item(i); | |||
|                 auto name = getName(attr); | |||
| 
 | |||
|                 if (name.compare("id") == 0) { | |||
|                     gspn.setName(XMLtoString(attr->getNodeValue())); | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown attribute (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // traverse children
 | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
| 
 | |||
|                 if (name.compare("place") == 0) { | |||
|                     traversePlace(child); | |||
|                 } else if (name.compare("transition") == 0) { | |||
|                     traverseTransition(child); | |||
|                 } else if (name.compare("arc") == 0) { | |||
|                     traverseArc(child); | |||
|                 } else if (name.compare("page") == 0) { | |||
|                     // Some pnml files have a child named page.
 | |||
|                     // The page node has the same children like the net node (e.g., place, transition, arc)
 | |||
|                     traverseNetOrPage(child); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=" + XMLtoString(node->getNodeName()) + "): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|         } | |||
| 
 | |||
|         void GspnParser::traversePlace(xercesc::DOMNode const* const node) { | |||
|             std::string placeName; | |||
|             // the first entry is false if the corresponding information was not found in the pnml file
 | |||
|             std::pair<bool, uint_fast64_t> numberOfInitialTokens(false, defaultNumberOfInitialTokens); | |||
|             std::pair<bool, int_fast64_t> capacity(false, defaultCapacity); | |||
| 
 | |||
|             // traverse attributes
 | |||
|             for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { | |||
|                 auto attr = node->getAttributes()->item(i); | |||
|                 auto name = getName(attr); | |||
| 
 | |||
|                 if (name.compare("id") == 0) { | |||
|                     placeName = XMLtoString(attr->getNodeValue()); | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown attribute (node=place): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // traverse children
 | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
| 
 | |||
|                 if (name.compare("initialMarking") == 0) { | |||
|                     numberOfInitialTokens.first = true; | |||
|                     numberOfInitialTokens.second = traverseInitialMarking(child); | |||
|                 } else if(name.compare("capacity") == 0) { | |||
|                     capacity.first = true; | |||
|                     capacity.second = traverseCapacity(child); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else if (name.compare("name") == 0 || | |||
|                            name.compare("graphics") == 0) { | |||
|                     // ignore these tags
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=place): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // build place and add it to the gspn
 | |||
|             storm::gspn::Place place; | |||
|             place.setName(placeName); | |||
|             if (!numberOfInitialTokens.first) { | |||
|                 // no information about the number of initial tokens is found
 | |||
|                 // use the default number of initial tokens
 | |||
|                 STORM_PRINT_AND_LOG("unknown numberOfInitialTokens (place=" + placeName + ")\n"); | |||
|             } | |||
|             place.setNumberOfInitialTokens(numberOfInitialTokens.second); | |||
|             if (!capacity.first) { | |||
|                 // no information about the capacity is found
 | |||
|                 // use default capacity
 | |||
|                 STORM_PRINT_AND_LOG("unknown capacity (place=" + placeName + ")\n"); | |||
|             } | |||
|             place.setCapacity(capacity.second); | |||
|             place.setID(newNode); | |||
|             ++newNode; | |||
|             gspn.addPlace(place); | |||
|         } | |||
| 
 | |||
|         void GspnParser::traverseTransition(xercesc::DOMNode const* const node) { | |||
|             // the first entry is false if the corresponding information was not found in the pnml file
 | |||
|             std::pair<bool, bool> timed(false, defaultTransitionType); | |||
|             std::pair<bool, std::string> value(false, defaultTransitionValue); | |||
|             std::string id; | |||
|             uint_fast64_t priority = defaultPriority; | |||
| 
 | |||
|             // parse attributes
 | |||
|             for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { | |||
|                 auto attr = node->getAttributes()->item(i); | |||
|                 auto name = getName(attr); | |||
| 
 | |||
|                 if (name.compare("id") == 0) { | |||
|                     id = XMLtoString(attr->getNodeValue()); | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown attribute (node=transition): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // traverse children
 | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
| 
 | |||
|                 if (name.compare("rate") == 0) { | |||
|                     value.first = true; | |||
|                     value.second = traverseTransitionValue(child); | |||
|                 } else if (name.compare("timed") == 0) { | |||
|                     timed.first = true; | |||
|                     timed.second = traverseTransitionType(child); | |||
|                 } else if (name.compare("priority") == 0) { | |||
|                     priority = traversePriority(child); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else if (name.compare("graphics") == 0 || | |||
|                            name.compare("name") == 0 || | |||
|                            name.compare("orientation") == 0) { | |||
|                     // ignore these tags
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=transition): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // build transition and add it to the gspn
 | |||
|             if (!timed.first) { | |||
|                 // found unknown transition type
 | |||
|                 // abort parsing
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "unknown transition type (transition=" + id + ")\n"); | |||
|                 return; | |||
|             } | |||
| 
 | |||
|             if (timed.second) { | |||
|                 storm::gspn::TimedTransition<storm::gspn::GSPN::RateType> transition; | |||
|                 if (!value.first) { | |||
|                     // no information about the rate is found
 | |||
|                     // abort the parsing
 | |||
|                     STORM_LOG_THROW(false, storm::exceptions::UnexpectedException ,"unknown transition rate (transition=" + id + ")\n"); | |||
|                 } | |||
|                 transition.setRate(std::stod(value.second)); | |||
|                 transition.setName(id); | |||
|                 transition.setPriority(priority); | |||
|                 gspn.addTimedTransition(transition); | |||
|             } else { | |||
|                 storm::gspn::ImmediateTransition<storm::gspn::GSPN::WeightType> transition; | |||
|                 if (!value.first) { | |||
|                     // no information about the weight is found
 | |||
|                     // continue with the default weight
 | |||
|                     STORM_PRINT_AND_LOG("unknown transition weight (transition=" + id + ")\n"); | |||
|                 } | |||
|                 transition.setWeight(std::stod(value.second)); | |||
|                 transition.setName(id); | |||
|                 transition.setPriority(priority); | |||
|                 gspn.addImmediateTransition(transition); | |||
|             } | |||
|         } | |||
| 
 | |||
|         void GspnParser::traverseArc(xercesc::DOMNode const* const node) { | |||
|             // the first entry is false if the corresponding information was not found in the pnml file
 | |||
|             std::pair<bool, std::string> source(false, ""); | |||
|             std::pair<bool, std::string> target(false, ""); | |||
|             std::pair<bool, std::string> type(false, defaultArcType); | |||
|             std::pair<bool, uint_fast64_t> multiplicity(false, defaultMultiplicity); | |||
|             std::string id; | |||
| 
 | |||
|             // parse attributes
 | |||
|             for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { | |||
|                 auto attr = node->getAttributes()->item(i); | |||
|                 auto name = getName(attr); | |||
| 
 | |||
|                 if (name.compare("source") == 0) { | |||
|                     source.first = true; | |||
|                     source.second = XMLtoString(attr->getNodeValue()); | |||
|                 } else if (name.compare("target") == 0) { | |||
|                     target.first = true; | |||
|                     target.second = XMLtoString(attr->getNodeValue()); | |||
|                 } else if (name.compare("id") == 0) { | |||
|                     id = XMLtoString(attr->getNodeValue()); | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown attribute (node=arc): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // parse children
 | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("type") == 0) { | |||
|                     type.first = true; | |||
|                     type.second = traverseArcType(child); | |||
|                 } else if(name.compare("inscription") == 0) { | |||
|                     multiplicity.first = true; | |||
|                     multiplicity.second = traverseMultiplicity(child); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else if (name.compare("graphics") == 0 || | |||
|                            name.compare("arcpath") == 0 || | |||
|                            name.compare("tagged") == 0) { | |||
|                     // ignore these tags
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=arc): " + name + "\n"); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // check if all necessary information where stored in the pnml file
 | |||
|             if (!source.first) { | |||
|                 // could not find start of the arc
 | |||
|                 // abort parsing
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException ,"unknown arc source (arc=" + id + ")\n"); | |||
|             } | |||
|             if (!target.first) { | |||
|                 // could not find the target of the arc
 | |||
|                 // abort parsing
 | |||
|                 STORM_LOG_THROW(false, storm::exceptions::UnexpectedException ,"unknown arc target (arc=" + id + ")\n"); | |||
|             } | |||
|             if (!multiplicity.first) { | |||
|                 // no information about the multiplicity of the arc
 | |||
|                 // continue and use the default multiplicity
 | |||
|                 STORM_PRINT_AND_LOG("unknown multiplicity (node=arc): " + id + "\n"); | |||
|             } | |||
| 
 | |||
|             //determine if it is an outgoing or incoming arc
 | |||
|             { | |||
|                 auto place = gspn.getPlace(source.second); | |||
|                 auto trans = gspn.getTransition(target.second); | |||
|                 if (true == place.first && true == trans.first) { | |||
|                     if (!type.first) { | |||
|                         // no arc type found
 | |||
|                         // abport parsing
 | |||
|                         STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "unknown arc type (arc=" + id + ")\n"); | |||
|                     } | |||
| 
 | |||
|                     // incoming arc
 | |||
|                     if (type.second.compare("normal") == 0) { | |||
|                         trans.second->setInputArcMultiplicity(place.second, multiplicity.second); | |||
|                     } else if (type.second.compare("inhibition") == 0) { | |||
|                         trans.second->setInhibitionArcMultiplicity(place.second, multiplicity.second); | |||
|                     } else { | |||
|                         // unknown arc type
 | |||
|                         // abort parsing
 | |||
|                         STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "unknown arc type (arc=" + id + ")\n"); | |||
|                     } | |||
|                     return; | |||
|                 } | |||
|             } | |||
|             { | |||
|                 auto trans = gspn.getTransition(source.second); | |||
|                 auto place = gspn.getPlace(target.second); | |||
|                 if (true == place.first && true == trans.first) { | |||
|                     // outgoing arc
 | |||
|                     trans.second->setOutputArcMultiplicity(place.second, multiplicity.second); | |||
|                     return; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             // if we reach this line we could not find the corresponding place or transition
 | |||
|             STORM_LOG_THROW(false, storm::exceptions::UnexpectedException ,"unknown arc source or target (arc=" + id + ")\n"); | |||
|         } | |||
| 
 | |||
|         std::string GspnParser::getName(xercesc::DOMNode *node) { | |||
|             switch (node->getNodeType()) { | |||
|                 case xercesc::DOMNode::NodeType::ELEMENT_NODE: { | |||
|                     auto elementNode = (xercesc::DOMElement *) node; | |||
|                     return XMLtoString(elementNode->getTagName()); | |||
|                 } | |||
|                 case xercesc::DOMNode::NodeType::TEXT_NODE: { | |||
|                     return XMLtoString(node->getNodeValue()); | |||
|                 } | |||
|                 case xercesc::DOMNode::NodeType::ATTRIBUTE_NODE: { | |||
|                     return XMLtoString(node->getNodeName()); | |||
|                 } | |||
|                 default: { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown node type \n"); | |||
|                     return ""; | |||
|                 } | |||
|             } | |||
|         } | |||
| 
 | |||
|         uint_fast64_t GspnParser::traverseInitialMarking(xercesc::DOMNode const* const node) { | |||
|             uint_fast64_t result = defaultNumberOfInitialTokens; | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("text") == 0) { | |||
|                     result = std::stoull(getName(child->getFirstChild())); | |||
|                 } else if (name.compare("value") == 0) { | |||
|                     auto value = getName(child->getFirstChild()); | |||
|                     value = value.substr(std::string("Default,").length()); | |||
|                     result = std::stoull(value); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else if (name.compare("graphics") == 0) { | |||
|                     // ignore these tags
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=initialMarking): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         int_fast64_t GspnParser::traverseCapacity(xercesc::DOMNode const* const node) { | |||
|             int_fast64_t result= defaultCapacity; | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("value") == 0) { | |||
|                     auto value = getName(child->getFirstChild()); | |||
|                     if (value.find("Default,") == 0) { | |||
|                         value = value.substr(std::string("Default,").length()); | |||
|                     } | |||
|                     result = std::stoull(value); | |||
|                 } else if (name.compare("graphics") == 0) { | |||
|                     // ignore these nodes
 | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=capacity): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         uint_fast64_t GspnParser::traverseMultiplicity(xercesc::DOMNode const* const node) { | |||
|             uint_fast64_t result = defaultMultiplicity; | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("value") == 0) { | |||
|                     auto value = getName(child->getFirstChild()); | |||
|                     if (value.find("Default,") == 0) { | |||
|                         value = value.substr(std::string("Default,").length()); | |||
|                     } | |||
|                     result = std::stoull(value); | |||
|                 } else if (name.compare("graphics") == 0) { | |||
|                     // ignore these nodes
 | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=inscription): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return result; | |||
|         } | |||
| 
 | |||
| 
 | |||
|         std::string GspnParser::traverseTransitionValue(xercesc::DOMNode const* const node) { | |||
|             std::string result = defaultTransitionValue; | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("value") == 0) { | |||
|                     result = getName(child->getFirstChild()); | |||
|                 } else  if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=rate): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         bool GspnParser::traverseTransitionType(xercesc::DOMNode const* const node) { | |||
|             bool result; | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("value") == 0) { | |||
|                     result = getName(child->getFirstChild()).compare("true") == 0 ? true : false; | |||
|                 } else  if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=timed): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         std::string GspnParser::traverseArcType(xercesc::DOMNode const* const node) { | |||
|             for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { | |||
|                 auto attr = node->getAttributes()->item(i); | |||
|                 auto name = getName(attr); | |||
|                 if (name.compare("value") == 0) { | |||
|                     return XMLtoString(attr->getNodeValue()); | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=type): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return defaultArcType; | |||
|         } | |||
| 
 | |||
|         uint_fast64_t GspnParser::traversePriority(xercesc::DOMNode const* const node) { | |||
|             uint_fast64_t result = defaultPriority; | |||
|             for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) { | |||
|                 auto child = node->getChildNodes()->item(i); | |||
|                 auto name = getName(child); | |||
|                 if (name.compare("text") == 0) { | |||
|                     result = std::stoull(getName(child->getFirstChild())); | |||
|                 } else if (name.compare("value") == 0) { | |||
|                     auto value = getName(child->getFirstChild()); | |||
|                     value = value.substr(std::string("Default,").length()); | |||
|                     result = std::stoull(value); | |||
|                 } else if (std::all_of(name.begin(), name.end(), isspace)) { | |||
|                     // ignore node (contains only whitespace)
 | |||
|                 } else if (name.compare("graphics") == 0) { | |||
|                     // ignore these tags
 | |||
|                 } else { | |||
|                     // Found node or attribute which is at the moment nod handled by this parser.
 | |||
|                     // Notify the user and continue the parsing.
 | |||
|                     STORM_PRINT_AND_LOG("unknown child (node=priority): " + name + "\n"); | |||
|                 } | |||
|             } | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         std::string GspnParser::XMLtoString(const XMLCh *xmlString) { | |||
|             char* tmp = xercesc::XMLString::transcode(xmlString); | |||
|             auto result = std::string(tmp); | |||
|             delete tmp; | |||
|             return result; | |||
|         } | |||
|     } | |||
| } | |||
| 
 | |||
| @ -0,0 +1,165 @@ | |||
| #ifndef STORM_PARSER_GSPNPARSER_H_ | |||
| #define STORM_PARSER_GSPNPARSER_H_ | |||
| 
 | |||
| #include <string> | |||
| 
 | |||
| #include <xercesc/parsers/XercesDOMParser.hpp> | |||
| #include <xercesc/util/XMLString.hpp> | |||
| 
 | |||
| #include "src/storage/gspn/GSPN.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace parser { | |||
| 
 | |||
|         /* Parses a pnml-file to a gspn. | |||
|            IMPORTANT: The names of places, transitions and arcs must differ from each other. | |||
|          */ | |||
|         class GspnParser { | |||
|         public: | |||
| 
 | |||
|             /*! | |||
|              * Parses the given file into the GSPN. | |||
|              * | |||
|              * @param filename The name of the file to parse. | |||
|              * @return The resulting GSPN. | |||
|              */ | |||
|             storm::gspn::GSPN const& parse(std::string const& filename); | |||
|         private: | |||
| 
 | |||
|             /*! | |||
|              * Traverse the root element. | |||
|              * | |||
|              * @param element The root element of the DOM object. | |||
|              */ | |||
|             void traversePnmlElement(xercesc::DOMElement const* const element); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a net or page node. | |||
|              * | |||
|              * @param node The net or page node. | |||
|              */ | |||
|             void traverseNetOrPage(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a place node. | |||
|              * | |||
|              * @param node The place node. | |||
|              */ | |||
|             void traversePlace(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a transition node. | |||
|              * | |||
|              * @param node The transition node. | |||
|              */ | |||
|             void traverseTransition(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse an arc node. | |||
|              * | |||
|              * @param node The arc node. | |||
|              */ | |||
|             void traverseArc(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse an initial marking node. | |||
|              * | |||
|              * @param node the initial marking node. | |||
|              * @return The number of initial tokens. | |||
|              */ | |||
|             uint_fast64_t traverseInitialMarking(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a capacity node. | |||
|              * | |||
|              * @param node The capacity node. | |||
|              * @return The capacity for the place. | |||
|              */ | |||
|             int_fast64_t traverseCapacity(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a inscription node. | |||
|              * | |||
|              * @param node The inscription node. | |||
|              * @return The multiplicty for the arc. | |||
|              */ | |||
|             uint_fast64_t traverseMultiplicity(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a rate node. | |||
|              * | |||
|              * @param node The rate node. | |||
|              * @return The rate or weight of the transition. | |||
|              */ | |||
|             std::string traverseTransitionValue(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a timed node. | |||
|              * | |||
|              * @param node The timed node. | |||
|              * @return False if the tranisition is immediate | |||
|              */ | |||
|             bool traverseTransitionType(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Traverse a type node. | |||
|              * | |||
|              * @param node The type node. | |||
|              * @return Returns a string with the arc type. | |||
|              */ | |||
|             std::string traverseArcType(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /** | |||
|              * Traverse a priority node. | |||
|              * @param node The priority node. | |||
|              * @return Returns the priority of the transition. | |||
|              */ | |||
|             uint_fast64_t traversePriority(xercesc::DOMNode const* const node); | |||
| 
 | |||
|             /*! | |||
|              * Gives the name of the current node. | |||
|              * | |||
|              * @param node The node. | |||
|              * @return The name of the node. | |||
|              */ | |||
|             std::string getName(xercesc::DOMNode* node); | |||
| 
 | |||
|             /*! | |||
|             * Transforms the given XML String to a std::string. | |||
|             * | |||
|             * @param xmlString The given String in the XML format | |||
|             * @return The corresponding std::string. | |||
|             */ | |||
|             static std::string XMLtoString(const XMLCh* xmlString); | |||
| 
 | |||
|             // the constructed gspn | |||
|             storm::gspn::GSPN gspn; | |||
| 
 | |||
|             // contains the id for a new node | |||
|             uint_fast64_t newNode = 0; | |||
| 
 | |||
|             // default value for initial tokens | |||
|             uint_fast64_t defaultNumberOfInitialTokens = 0; | |||
| 
 | |||
|             // default value for capacities | |||
|             int_fast64_t defaultCapacity = -1; | |||
| 
 | |||
|             // default value for the transition type (false == immediate transition) | |||
|             bool defaultTransitionType = false; | |||
| 
 | |||
|             // default value for the transition weight or rate | |||
|             std::string defaultTransitionValue = "1"; // TODO set to 0 | |||
| 
 | |||
|             // default value for the arc type | |||
|             std::string defaultArcType = "normal"; | |||
| 
 | |||
|             // default multiplicity for arcs | |||
|             uint_fast64_t defaultMultiplicity = 1; | |||
| 
 | |||
|             //default priority for transitions | |||
|             uint_fast64_t defaultPriority = 0; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_PARSER_GSPNPARSER_H_ | |||
| @ -0,0 +1,516 @@ | |||
| #include "src/storage/gspn/GSPN.h"
 | |||
| #include <src/utility/macros.h>
 | |||
| #include <boost/lexical_cast.hpp>
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         void GSPN::addImmediateTransition(storm::gspn::ImmediateTransition<WeightType> const& transition) { | |||
|             this->immediateTransitions.push_back(std::make_shared<storm::gspn::ImmediateTransition<WeightType>>(transition)); | |||
|         } | |||
| 
 | |||
|         void GSPN::addTimedTransition(storm::gspn::TimedTransition<RateType> const& transition) { | |||
|             this->timedTransitions.push_back(std::make_shared<storm::gspn::TimedTransition<RateType>>(transition)); | |||
|         } | |||
| 
 | |||
|         void GSPN::addPlace(Place const& place) { | |||
|             this->places.push_back(place); | |||
|         } | |||
| 
 | |||
|         uint_fast64_t GSPN::getNumberOfPlaces() const { | |||
|             return places.size(); | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::TimedTransition<GSPN::RateType>>> const& GSPN::getTimedTransitions() const { | |||
|             return this->timedTransitions; | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<GSPN::WeightType>>> const& GSPN::getImmediateTransitions() const { | |||
|             return this->immediateTransitions; | |||
|         } | |||
| 
 | |||
|         std::vector<storm::gspn::Place> const& GSPN::getPlaces() const { | |||
|             return places; | |||
|         } | |||
| 
 | |||
|         std::shared_ptr<storm::gspn::Marking> GSPN::getInitialMarking(std::map<uint_fast64_t, uint_fast64_t>& numberOfBits, uint_fast64_t const& numberOfTotalBits) const { | |||
|             auto m = std::make_shared<storm::gspn::Marking>(getNumberOfPlaces(), numberOfBits, numberOfTotalBits); | |||
|             for (auto& place : getPlaces()) { | |||
|                 m->setNumberOfTokensAt(place.getID(), place.getNumberOfInitialTokens()); | |||
|             } | |||
|             return m; | |||
|         } | |||
| 
 | |||
|         std::pair<bool, storm::gspn::Place> GSPN::getPlace(std::string const& id) const { | |||
|             for (auto& place : places) { | |||
|                 if (id.compare(place.getName()) == 0) { | |||
|                     return std::make_pair<bool, storm::gspn::Place const&>(true, place); | |||
|                 } | |||
|             } | |||
|             return std::make_pair<bool, storm::gspn::Place>(false, storm::gspn::Place()); | |||
|         } | |||
| 
 | |||
|         std::pair<bool, std::shared_ptr<storm::gspn::TimedTransition<GSPN::RateType>> const> GSPN::getTimedTransition(std::string const& id) const { | |||
|             for (auto& trans : timedTransitions) { | |||
|                 if (id.compare(trans->getName()) == 0) { | |||
|                     return std::make_pair<bool, std::shared_ptr<storm::gspn::TimedTransition<GSPN::RateType>> const>(true, static_cast<std::shared_ptr<storm::gspn::TimedTransition<GSPN::RateType>> const>(trans)); | |||
|                 } | |||
|             } | |||
|             return std::make_pair<bool, std::shared_ptr<storm::gspn::TimedTransition<GSPN::RateType>> const>(false, nullptr); | |||
|         } | |||
| 
 | |||
|         std::pair<bool, std::shared_ptr<storm::gspn::ImmediateTransition<GSPN::WeightType>> const> GSPN::getImmediateTransition(std::string const& id) const { | |||
|             for (auto& trans : immediateTransitions) { | |||
|                 if (id.compare(trans->getName()) == 0) { | |||
|                     return std::make_pair<bool, std::shared_ptr<storm::gspn::ImmediateTransition<GSPN::WeightType>> const>(true, static_cast<std::shared_ptr<storm::gspn::ImmediateTransition<GSPN::WeightType>> const>(trans)); | |||
|                 } | |||
|             } | |||
|             return std::make_pair<bool, std::shared_ptr<storm::gspn::ImmediateTransition<GSPN::WeightType>> const>(false, nullptr); | |||
|         } | |||
| 
 | |||
|         std::pair<bool, std::shared_ptr<storm::gspn::Transition> const> GSPN::getTransition(std::string const& id) const { | |||
|             auto trans = getTimedTransition(id); | |||
|             if (trans.first == true) { | |||
|                 return trans; | |||
|             } | |||
| 
 | |||
|             return getImmediateTransition(id); | |||
|         } | |||
| 
 | |||
|         void GSPN::writeDotToStream(std::ostream& outStream) { | |||
|             outStream << "digraph " << this->getName() << " {" << std::endl; | |||
| 
 | |||
|             // print places with initial marking (not printed is the capacity)
 | |||
|             outStream << "\t" << "node [shape=ellipse]" << std::endl; | |||
|             for (auto& place : this->getPlaces()) { | |||
|                 outStream << "\t" << place.getName() << " [label=\"" << place.getName() << "(" << place.getNumberOfInitialTokens(); | |||
|                 outStream << ")\"];" << std::endl; | |||
|             } | |||
| 
 | |||
|             // print transitions with weight/rate
 | |||
|             outStream << "\t" << "node [shape=box]" << std::endl; | |||
|             for (auto& trans : this->getImmediateTransitions()) { | |||
|                 outStream << "\t" << trans->getName() << " [label=\"" << trans->getName(); | |||
|                 outStream << "(immediate:" << trans->getWeight() << ")\"];" << std::endl; | |||
|             } | |||
| 
 | |||
|             for (auto& trans : this->getTimedTransitions()) { | |||
|                 outStream << "\t" << trans->getName() << " [label=\"" << trans->getName(); | |||
|                 outStream << "(timed:" << trans->getRate() << ")\"];" << std::endl; | |||
|             } | |||
| 
 | |||
|             // print arcs
 | |||
|             for (auto& trans : this->getImmediateTransitions()) { | |||
|                 auto it = trans->getInputPlacesCBegin(); | |||
|                 while (it != trans->getInputPlacesCEnd()) { | |||
|                     outStream << "\t" << (**it).getName() << " -> " << trans->getName() << "[label=\"normal:" << | |||
|                             trans->getInputArcMultiplicity(**it); | |||
|                     outStream << "\"];" << std::endl; | |||
| 
 | |||
|                     ++it; | |||
|                 } | |||
| 
 | |||
|                 it = trans->getInhibitionPlacesCBegin(); | |||
|                 while (it != trans->getInhibitionPlacesCEnd()) { | |||
|                     outStream << "\t" << (**it).getName() << " -> " << trans->getName() << "[label=\"inhibition:" << | |||
|                             trans->getInhibitionArcMultiplicity(**it); | |||
|                     outStream << "\"];" << std::endl; | |||
|                     ++it; | |||
|                 } | |||
| 
 | |||
|                 it = trans->getOutputPlacesCBegin(); | |||
|                 while (it != trans->getOutputPlacesCEnd()) { | |||
|                     outStream << "\t" << trans->getName() << " -> " << (**it).getName() << "[label=\"" << | |||
|                             trans->getOutputArcMultiplicity(**it); | |||
|                     outStream << "\"];" << std::endl; | |||
|                     ++it; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             for (auto& trans : this->getTimedTransitions()) { | |||
|                 auto it = trans->getInputPlacesCBegin(); | |||
|                 while (it != trans->getInputPlacesCEnd()) { | |||
|                     outStream << "\t" << (**it).getName() << " -> " << trans->getName() << "[label=\"normal:" << | |||
|                             trans->getInputArcMultiplicity(**it); | |||
|                     outStream << "\"];" << std::endl; | |||
|                     ++it; | |||
|                 } | |||
| 
 | |||
| 
 | |||
|                 it = trans->getInhibitionPlacesCBegin(); | |||
|                 while (it != trans->getInhibitionPlacesCEnd()) { | |||
|                     outStream << "\t" << (**it).getName() << " -> " << trans->getName() << "[label=\"inhibition:" << | |||
|                             trans->getInhibitionArcMultiplicity(**it); | |||
|                     outStream << "\"];" << std::endl; | |||
|                     ++it; | |||
|                 } | |||
| 
 | |||
|                 it = trans->getOutputPlacesCBegin(); | |||
|                 while (it != trans->getOutputPlacesCEnd()) { | |||
|                     outStream << "\t" << trans->getName() << " -> " << (**it).getName() << "[label=\"" << | |||
|                             trans->getOutputArcMultiplicity(**it); | |||
|                     outStream << "\"];" << std::endl; | |||
|                     ++it; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             outStream << "}" << std::endl; | |||
|         } | |||
| 
 | |||
|         void GSPN::setName(std::string const& name) { | |||
|             this->name = name; | |||
|         } | |||
| 
 | |||
|         std::string const& GSPN::getName() const { | |||
|             return this->name; | |||
|         } | |||
| 
 | |||
|         bool GSPN::isValid() const { | |||
|             bool result = true; | |||
|             result |= testPlaces(); | |||
|             result |= testTransitions(); | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         bool GSPN::testPlaces() const { | |||
|             std::vector<std::string> namesOfPlaces; | |||
|             std::vector<uint_fast64_t> idsOfPlaces; | |||
|             bool result = true; | |||
| 
 | |||
|             for (auto const& place : this->getPlaces()) { | |||
| 
 | |||
|                 if (std::find(namesOfPlaces.begin(), namesOfPlaces.end(), place.getName()) != namesOfPlaces.end()) { | |||
|                     STORM_PRINT_AND_LOG("duplicates states with the name \"" + place.getName() + "\"\n") | |||
|                     result = false; | |||
|                 } | |||
| 
 | |||
|                 if (std::find(idsOfPlaces.begin(), idsOfPlaces.end(), place.getID()) != idsOfPlaces.end()) { | |||
|                     STORM_PRINT_AND_LOG("duplicates states with the id \"" + boost::lexical_cast<std::string>(place.getID()) + "\"\n") | |||
|                     result = false; | |||
|                 } | |||
| 
 | |||
|                 if (place.getNumberOfInitialTokens() > place.getNumberOfInitialTokens()) { | |||
|                     STORM_PRINT_AND_LOG("number of initial tokens is greater than the capacity for place \"" + place.getName() + "\"\n") | |||
|                     result = false; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         bool GSPN::testTransitions() const { | |||
|             bool result = true; | |||
| 
 | |||
|             for (auto const& transition : this->getImmediateTransitions()) { | |||
|                 if (transition->getInputPlacesCBegin() == transition->getInputPlacesCEnd() && | |||
|                     transition->getInhibitionPlacesCBegin() == transition->getInhibitionPlacesCEnd()) { | |||
|                     STORM_PRINT_AND_LOG("transition \"" + transition->getName() + "\" has no input or inhibition place\n") | |||
|                     result = false; | |||
|                 } | |||
| 
 | |||
|                 if (transition->getOutputPlacesCBegin() == transition->getOutputPlacesCEnd()) { | |||
|                     STORM_PRINT_AND_LOG("transition \"" + transition->getName() + "\" has no output place\n") | |||
|                     result = false; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             for (auto const& transition : this->getTimedTransitions()) { | |||
|                 if (transition->getInputPlacesCBegin() == transition->getInputPlacesCEnd() && | |||
|                     transition->getInhibitionPlacesCBegin() == transition->getInhibitionPlacesCEnd()) { | |||
|                     STORM_PRINT_AND_LOG("transition \"" + transition->getName() + "\" has no input or inhibition place\n") | |||
|                     result = false; | |||
|                 } | |||
| 
 | |||
|                 if (transition->getOutputPlacesCBegin() == transition->getOutputPlacesCEnd()) { | |||
|                     STORM_PRINT_AND_LOG("transition \"" + transition->getName() + "\" has no output place\n") | |||
|                     result = false; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             //test if places exists in the gspn
 | |||
|             for (auto const& transition : this->getImmediateTransitions()) { | |||
|                 for (auto it = transition->getInputPlacesCBegin(); it != transition->getInputPlacesCEnd(); ++it) { | |||
|                     bool foundPlace = false; | |||
|                     for (auto const& place : places) { | |||
|                         if (place.getName() == (*it)->getName()) { | |||
|                             foundPlace = true; | |||
|                         } | |||
|                     } | |||
|                     if (!foundPlace) { | |||
|                         STORM_PRINT_AND_LOG("input place \"" + (*it)->getName() + "\" of transition \"" + transition->getName() + "\" was not found \n") | |||
|                         result = false; | |||
|                     } | |||
|                 } | |||
| 
 | |||
|                 for (auto it = transition->getInhibitionPlacesCBegin(); it != transition->getInhibitionPlacesCEnd(); ++it) { | |||
|                     bool foundPlace = false; | |||
|                     for (auto const& place : places) { | |||
|                         if (place.getName() == (*it)->getName()) { | |||
|                             foundPlace = true; | |||
|                         } | |||
|                     } | |||
|                     if (!foundPlace) { | |||
|                         STORM_PRINT_AND_LOG("inhibition place \"" + (*it)->getName() + "\" of transition \"" + transition->getName() + "\" was not found \n") | |||
|                         result = false; | |||
|                     } | |||
|                 } | |||
| 
 | |||
|                 for (auto it = transition->getOutputPlacesCBegin(); it != transition->getOutputPlacesCEnd(); ++it) { | |||
|                     bool foundPlace = false; | |||
|                     for (auto const& place : places) { | |||
|                         if (place.getName() == (*it)->getName()) { | |||
|                             foundPlace = true; | |||
|                         } | |||
|                     } | |||
|                     if (!foundPlace) { | |||
|                         STORM_PRINT_AND_LOG("output place \"" + (*it)->getName() + "\" of transition \"" + transition->getName() + "\" was not found \n") | |||
|                         result = false; | |||
|                     } | |||
|                 } | |||
|             } | |||
| 
 | |||
|             for (auto const& transition : this->getTimedTransitions()) { | |||
|                 for (auto it = transition->getInputPlacesCBegin(); it != transition->getInputPlacesCEnd(); ++it) { | |||
|                     bool foundPlace = false; | |||
|                     for (auto const& place : places) { | |||
|                         if (place.getName() == (*it)->getName()) { | |||
|                             foundPlace = true; | |||
|                         } | |||
|                     } | |||
|                     if (!foundPlace) { | |||
|                         STORM_PRINT_AND_LOG("input place \"" + (*it)->getName() + "\" of transition \"" + transition->getName() + "\" was not found \n") | |||
|                         result = false; | |||
|                     } | |||
|                 } | |||
| 
 | |||
|                 for (auto it = transition->getInhibitionPlacesCBegin(); it != transition->getInhibitionPlacesCEnd(); ++it) { | |||
|                     bool foundPlace = false; | |||
|                     for (auto const& place : places) { | |||
|                         if (place.getName() == (*it)->getName()) { | |||
|                             foundPlace = true; | |||
|                         } | |||
|                     } | |||
|                     if (!foundPlace) { | |||
|                         STORM_PRINT_AND_LOG("inhibition place \"" + (*it)->getName() + "\" of transition \"" + transition->getName() + "\" was not found \n") | |||
|                         result = false; | |||
|                     } | |||
|                 } | |||
| 
 | |||
|                 for (auto it = transition->getOutputPlacesCBegin(); it != transition->getOutputPlacesCEnd(); ++it) { | |||
|                     bool foundPlace = false; | |||
|                     for (auto const& place : places) { | |||
|                         if (place.getName() == (*it)->getName()) { | |||
|                             foundPlace = true; | |||
|                         } | |||
|                     } | |||
|                     if (!foundPlace) { | |||
|                         STORM_PRINT_AND_LOG("output place \"" + (*it)->getName() + "\" of transition \"" + transition->getName() + "\" was not found \n") | |||
|                         result = false; | |||
|                     } | |||
|                 } | |||
|             } | |||
| 
 | |||
| 
 | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         void GSPN::toPnpro(std::ostream &stream) const { | |||
|             auto space = "  "; | |||
|             auto space2 = "    "; | |||
|             auto space3 = "      "; | |||
|             auto projectName = "storm-export"; // TODO add to args
 | |||
|             stream << "<project name=\"" << projectName << "\" version=\"121\">" << std::endl; | |||
|             stream << space << "<gspn name=\"" << getName() << "\" >" << std::endl; | |||
| 
 | |||
|             u_int32_t x = 1; | |||
|             stream << space2 << "<nodes>" << std::endl; | |||
|             for (auto& place : places) { | |||
|                 stream << space3 << "<place marking=\"" << place.getNumberOfInitialTokens() <<"\" "; | |||
|                 stream << "name =\"" << place.getName() << "\" "; | |||
|                 stream << "x=\"" << x << "\" "; | |||
|                 stream << "y=\"1\" "; | |||
|                 stream << "/>" << std::endl; | |||
|                 x = x + 3; | |||
|             } | |||
|             x = 1; | |||
|             for (auto& trans : timedTransitions) { | |||
|                 stream << space3 << "<transition name=\"" << trans->getName() << "\" "; | |||
|                 stream << "type=\"EXP\" "; | |||
|                 stream << "nservers-x=\"" << trans->getRate() << "\" "; | |||
|                 stream << "x=\"" << x << "\" "; | |||
|                 stream << "y=\"4\" "; | |||
|                 stream << "/>" << std::endl; | |||
|                 x = x + 3; | |||
|             } | |||
|             for (auto& trans : immediateTransitions) { | |||
|                 stream << space3 << "<transition name=\"" << trans->getName() << "\" "; | |||
|                 stream << "type=\"IMM\" "; | |||
|                 stream << "x=\"" << x << "\" "; | |||
|                 stream << "y=\"4\" "; | |||
|                 stream << "/>" << std::endl; | |||
|                 x = x + 3; | |||
|             } | |||
|             stream << space2 << "</nodes>" << std::endl; | |||
| 
 | |||
|             stream << space2 << "<edges>" << std::endl; | |||
|             for (auto& trans : timedTransitions) { | |||
|                 for (auto it = trans->getInputPlacesCBegin(); it != trans->getInputPlacesCEnd(); ++it) { | |||
|                     stream << space3 << "<arc "; | |||
|                     stream << "head=\"" << trans->getName() << "\" "; | |||
|                     stream << "tail=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "kind=\"INPUT\" "; | |||
|                     stream << "mult=\"" << trans->getInputArcMultiplicity(**it) << "\" "; | |||
|                     stream << "/>" << std::endl; | |||
|                 } | |||
|                 for (auto it = trans->getInhibitionPlacesCBegin(); it != trans->getInhibitionPlacesCEnd(); ++it) { | |||
|                     stream << space3 << "<arc "; | |||
|                     stream << "head=\"" << trans->getName() << "\" "; | |||
|                     stream << "tail=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "kind=\"INHIBITOR\" "; | |||
|                     stream << "mult=\"" << trans->getInhibitionArcMultiplicity(**it) << "\" "; | |||
|                     stream << "/>" << std::endl; | |||
|                 } | |||
|                 for (auto it = trans->getOutputPlacesCBegin(); it != trans->getOutputPlacesCEnd(); ++it) { | |||
|                     stream << space3 << "<arc "; | |||
|                     stream << "head=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "tail=\"" << trans->getName() << "\" "; | |||
|                     stream << "kind=\"OUTPUT\" "; | |||
|                     stream << "mult=\"" << trans->getOutputArcMultiplicity(**it) << "\" "; | |||
|                     stream << "/>" << std::endl; | |||
|                 } | |||
|             } | |||
|             for (auto& trans : immediateTransitions) { | |||
|                 for (auto it = trans->getInputPlacesCBegin(); it != trans->getInputPlacesCEnd(); ++it) { | |||
|                     stream << space3 << "<arc "; | |||
|                     stream << "head=\"" << trans->getName() << "\" "; | |||
|                     stream << "tail=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "kind=\"INPUT\" "; | |||
|                     stream << "mult=\"" << trans->getInputArcMultiplicity(**it) << "\" "; | |||
|                     stream << "/>" << std::endl; | |||
|                 } | |||
|                 for (auto it = trans->getInhibitionPlacesCBegin(); it != trans->getInhibitionPlacesCEnd(); ++it) { | |||
|                     stream << space3 << "<arc "; | |||
|                     stream << "head=\"" << trans->getName() << "\" "; | |||
|                     stream << "tail=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "kind=\"INHIBITOR\" "; | |||
|                     stream << "mult=\"" << trans->getInhibitionArcMultiplicity(**it) << "\" "; | |||
|                     stream << "/>" << std::endl; | |||
|                 } | |||
|                 for (auto it = trans->getOutputPlacesCBegin(); it != trans->getOutputPlacesCEnd(); ++it) { | |||
|                     stream << space3 << "<arc "; | |||
|                     stream << "head=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "tail=\"" << trans->getName() << "\" "; | |||
|                     stream << "kind=\"OUTPUT\" "; | |||
|                     stream << "mult=\"" << trans->getOutputArcMultiplicity(**it) << "\" "; | |||
|                     stream << "/>" << std::endl; | |||
|                 } | |||
|             } | |||
|             stream << space2 << "</edges>" << std::endl; | |||
|             stream << space << "</gspn>" << std::endl; | |||
|             stream << "</project>" << std::endl; | |||
|         } | |||
| 
 | |||
|         void GSPN::toPnml(std::ostream &stream) const { | |||
|             std::string space = "  "; | |||
|             std::string space2 = "    "; | |||
|             std::string space3 = "      "; | |||
|             std::string space4 = "        "; | |||
| 
 | |||
|             stream << "<pnml>" << std::endl; | |||
|             stream << space << "<net id=\"" << getName() << "\">" << std::endl; | |||
| 
 | |||
|             // add places
 | |||
|             for (const auto &place : places) { | |||
|                 stream << space2 << "<place id=\"" << place.getName() << "\">" << std::endl; | |||
|                 stream << space3 << "<initialMarking>" << std::endl; | |||
|                 stream << space4 << "<value>Default," << place.getNumberOfInitialTokens() << "</value>" << std::endl; | |||
|                 stream << space3 << "</initialMarking>" << std::endl; | |||
|                 stream << space2 << "</place>" << std::endl; | |||
|             } | |||
| 
 | |||
|             // add immediate transitions
 | |||
|             for (const auto &trans : immediateTransitions) { | |||
|                 stream << space2 << "<transition id=\"" << trans->getName() << "\">" << std::endl; | |||
|                 stream << space3 << "<rate>" << std::endl; | |||
|                 stream << space4 << "<value>" << trans->getWeight() << "</value>" << std::endl; | |||
|                 stream << space3 << "</rate>" << std::endl; | |||
|                 stream << space3 << "<timed>" << std::endl; | |||
|                 stream << space4 << "<value>false</value>" << std::endl; | |||
|                 stream << space3 << "</timed>" << std::endl; | |||
|                 stream << space2 << "</transition>" << std::endl; | |||
|             } | |||
| 
 | |||
|             // add timed transitions
 | |||
|             for (const auto &trans : timedTransitions) { | |||
|                 stream << space2 << "<transition id=\"" << trans->getName() << "\">" << std::endl; | |||
|                 stream << space3 << "<rate>" << std::endl; | |||
|                 stream << space4 << "<value>" << trans->getRate() << "</value>" << std::endl; | |||
|                 stream << space3 << "</rate>" << std::endl; | |||
|                 stream << space3 << "<timed>" << std::endl; | |||
|                 stream << space4 << "<value>true</value>" << std::endl; | |||
|                 stream << space3 << "</timed>" << std::endl; | |||
|                 stream << space2 << "</transition>" << std::endl; | |||
|             } | |||
| 
 | |||
|             uint_fast64_t i = 0; | |||
|             // add arcs for immediate transitions
 | |||
|             for (const auto &trans : immediateTransitions) { | |||
|                 // add input arcs
 | |||
|                 for (auto it = trans->getInputPlacesCBegin(); it != trans->getInputPlacesCEnd(); ++it) { | |||
|                     stream << space2 << "<arc "; | |||
|                     stream << "id=\"arc" << i++ << "\" "; | |||
|                     stream << "source=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "target=\"" << trans->getName() << "\" "; | |||
|                     stream << ">" << std::endl; | |||
| 
 | |||
|                     stream << space3 << "<inscription>" << std::endl; | |||
|                     stream << space4 << "<value>Default," << trans->getInputArcMultiplicity(**it) << "</value>" << std::endl; | |||
|                     stream << space3 << "</inscription>" << std::endl; | |||
| 
 | |||
|                     stream << space3 << "<type value=\"normal\" />" << std::endl; | |||
| 
 | |||
|                     stream << space2 << "</arc>" << std::endl; | |||
|                 } | |||
| 
 | |||
|                 // add inhibition arcs
 | |||
|                 for (auto it = trans->getInhibitionPlacesCBegin(); it != trans->getInhibitionPlacesCEnd(); ++it) { | |||
|                     stream << space2 << "<arc "; | |||
|                     stream << "id=\"arc" << i++ << "\" "; | |||
|                     stream << "source=\"" << (*it)->getName() << "\" "; | |||
|                     stream << "target=\"" << trans->getName() << "\" "; | |||
|                     stream << ">" << std::endl; | |||
| 
 | |||
|                     stream << space3 << "<inscription>" << std::endl; | |||
|                     stream << space4 << "<value>Default," << trans->getInputArcMultiplicity(**it) << "</value>" << std::endl; | |||
|                     stream << space3 << "</inscription>" << std::endl; | |||
| 
 | |||
|                     stream << space3 << "<type value=\"inhibition\" />" << std::endl; | |||
| 
 | |||
|                     stream << space2 << "</arc>" << std::endl; | |||
|                 } | |||
| 
 | |||
|                 // add output arcs
 | |||
|                 for (auto it = trans->getOutputPlacesCBegin(); it != trans->getOutputPlacesCEnd(); ++it) { | |||
|                     stream << space2 << "<arc "; | |||
|                     stream << "id=\"arc" << i++ << "\" "; | |||
|                     stream << "source=\"" << trans->getName() << "\" "; | |||
|                     stream << "target=\"" << (*it)->getName() << "\" "; | |||
|                     stream << ">" << std::endl; | |||
| 
 | |||
|                     stream << space3 << "<inscription>" << std::endl; | |||
|                     stream << space4 << "<value>Default," << trans->getInputArcMultiplicity(**it) << "</value>" << std::endl; | |||
|                     stream << space3 << "</inscription>" << std::endl; | |||
| 
 | |||
|                     stream << space3 << "<type value=\"normal\" />" << std::endl; | |||
| 
 | |||
|                     stream << space2 << "</arc>" << std::endl; | |||
|                 } | |||
|             } | |||
| 
 | |||
|             stream << space << "</net>" << std::endl; | |||
|             stream << "</pnml>" << std::endl; | |||
|         } | |||
|     } | |||
| } | |||
| 
 | |||
| 
 | |||
| @ -0,0 +1,183 @@ | |||
| #ifndef STORM_STORAGE_GSPN_GSPN_H | |||
| #define STORM_STORAGE_GSPN_GSPN_H | |||
| 
 | |||
| #include <iostream> | |||
| #include <stdint.h> | |||
| #include <vector> | |||
| #include <memory> | |||
| 
 | |||
| #include "src/storage/gspn/ImmediateTransition.h" | |||
| #include "src/storage/gspn/Marking.h" | |||
| #include "src/storage/gspn/Place.h" | |||
| #include "src/storage/gspn/TimedTransition.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         // Stores a GSPN | |||
|         class GSPN { | |||
|         public: | |||
|             // Later, the rates and probabilities type should become a template, for now, let it be doubles. | |||
|             typedef double RateType; | |||
|             typedef double WeightType; | |||
| 
 | |||
|             /*! | |||
|              * Adds an immediate transition to the gspn. | |||
|              * | |||
|              * @param transition The transition which is added to the gspn. | |||
|              */ | |||
|             void addImmediateTransition(ImmediateTransition<WeightType> const& transition); | |||
| 
 | |||
|             /*! | |||
|              * Adds a timed transition to the gspn. | |||
|              * | |||
|              * @param transition The transition which is added to the gspn. | |||
|              */ | |||
|             void addTimedTransition(TimedTransition<RateType> const& transition); | |||
| 
 | |||
|             /*! | |||
|              * Adds a place to the gspn. | |||
|              * | |||
|              * @param place The place which is added to the gspn. | |||
|              */ | |||
|             void addPlace(Place const& place); | |||
| 
 | |||
|             /*! | |||
|              * Returns the number of places in this gspn. | |||
|              * | |||
|              * @return The number of places. | |||
|              */ | |||
|             uint_fast64_t getNumberOfPlaces() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the vector of timed transitions in this gspn. | |||
|              * | |||
|              * @return The vector of timed transitions. | |||
|              */ | |||
|             std::vector<std::shared_ptr<TimedTransition<GSPN::RateType>>> const& getTimedTransitions() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the vector of immediate transitions in this gspn. | |||
|              * | |||
|              * @return The vector of immediate tansitions. | |||
|              */ | |||
|             std::vector<std::shared_ptr<ImmediateTransition<GSPN::WeightType>>> const& getImmediateTransitions() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the places of this gspn | |||
|              */ | |||
|             std::vector<storm::gspn::Place> const& getPlaces() const; | |||
| 
 | |||
|             /* | |||
|              * Computes the initial marking of the gspn. | |||
|              * | |||
|              * @param map The Map determines the number of bits for each place. | |||
|              * @return The initial Marking | |||
|              */ | |||
|             std::shared_ptr<storm::gspn::Marking> getInitialMarking(std::map<uint_fast64_t, uint_fast64_t>& numberOfBits, uint_fast64_t const& numberOfTotalBits) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the place with the corresponding id. | |||
|              * | |||
|              * @param id The ID of the place. | |||
|              * @return The first element is true if the place was found. | |||
|              *         If the first element is true, then the second element is the wanted place. | |||
|              *         If the first element is false, then the second element is not defined. | |||
|              */ | |||
|             std::pair<bool, storm::gspn::Place> getPlace(std::string const& id) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the timed transition with the corresponding id. | |||
|              * | |||
|              * @param id The ID of the timed transition. | |||
|              * @return The first element is true if the transition was found. | |||
|              *         If the first element is true, then the second element is the wanted transition. | |||
|              *         If the first element is false, then the second element is the nullptr. | |||
|              */ | |||
|             std::pair<bool, std::shared_ptr<storm::gspn::TimedTransition<GSPN::RateType>> const> getTimedTransition(std::string const& id) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the immediate transition with the corresponding id. | |||
|              * | |||
|              * @param id The ID of the timed transition. | |||
|              * @return The first element is true if the transition was found. | |||
|              *         If the first element is true, then the second element is the wanted transition. | |||
|              *         If the first element is false, then the second element is the nullptr. | |||
|              */ | |||
|             std::pair<bool, std::shared_ptr<storm::gspn::ImmediateTransition<GSPN::WeightType>> const> getImmediateTransition(std::string const& id) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the transition with the corresponding id. | |||
|              * | |||
|              * @param id The ID of the transition. | |||
|              * @return Pointer to the corresponding transition or nullptr if the place does not exists. | |||
|              */ | |||
|             //            std::shared_ptr<storm::gspn::Transition> getTransition(std::string const& id) const; | |||
|             std::pair<bool, std::shared_ptr<storm::gspn::Transition> const> getTransition(std::string const& id) const; | |||
| 
 | |||
|             /*! | |||
|              * Write the gspn in a dot(graphviz) configuration. | |||
|              * | |||
|              * @param outStream The stream to which the output is written to. | |||
|              */ | |||
|             void writeDotToStream(std::ostream& outStream); | |||
| 
 | |||
|             /*! | |||
|              * Set the name of the gspn to the given name. | |||
|              * | |||
|              * @param name The new name. | |||
|              */ | |||
|             void setName(std::string const& name); | |||
| 
 | |||
|             /*! | |||
|              * Returns the name of the gspn. | |||
|              * | |||
|              * @return The name. | |||
|              */ | |||
|             std::string const& getName() const; | |||
| 
 | |||
|             /*! | |||
|              * Performe some checks | |||
|              * - testPlaces() | |||
|              * - testTransitions() | |||
|              * | |||
|              * @return true if no errors are found | |||
|              */ | |||
|             bool isValid() const; | |||
|             // TODO doc | |||
|             void toPnpro(std::ostream &stream) const; | |||
|             // TODO doc | |||
|             void toPnml(std::ostream &stream) const; | |||
|         private: | |||
|             /*! | |||
|              * Test | |||
|              *  - if places are unique (ids and names) | |||
|              *  - if the capacity is greater than the number of initial tokens | |||
|              * | |||
|              * @return true if no errors found | |||
|              */ | |||
|             bool testPlaces() const; | |||
| 
 | |||
|             /*! | |||
|              * Test | |||
|              * - if transition have at least on input/inhibitor and one output place | |||
|              * | |||
|              * @return true if no errors found | |||
|              */ | |||
|             bool testTransitions() const; | |||
| 
 | |||
|             // set containing all immediate transitions | |||
|             std::vector<std::shared_ptr<storm::gspn::ImmediateTransition<WeightType>>> immediateTransitions; | |||
| 
 | |||
|             // set containing all timed transitions | |||
|             std::vector<std::shared_ptr<storm::gspn::TimedTransition<RateType>>> timedTransitions; | |||
| 
 | |||
|             // set containing all places | |||
|             std::vector<storm::gspn::Place> places; | |||
| 
 | |||
|             // name of the gspn | |||
|             std::string name; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_GSPN_H | |||
| @ -0,0 +1,90 @@ | |||
| #include <src/exceptions/IllegalFunctionCallException.h>
 | |||
| #include "GspnBuilder.h"
 | |||
| 
 | |||
| #include "src/utility/macros.h"
 | |||
| #include "src/exceptions/IllegalFunctionCallException.h"
 | |||
| #include "Place.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         void GspnBuilder::addPlace(uint_fast64_t const& id, int_fast64_t const& capacity, uint_fast64_t const& initialTokens) { | |||
|             addPlace(id, "place_" + std::to_string(id), capacity, initialTokens); | |||
|         } | |||
| 
 | |||
|         void GspnBuilder::addPlace(uint_fast64_t const& id, std::string const& name, int_fast64_t const& capacity, uint_fast64_t const& initialTokens) { | |||
|             auto place = storm::gspn::Place(); | |||
|             place.setCapacity(capacity); | |||
|             place.setID(id); | |||
|             place.setName(name); | |||
|             place.setNumberOfInitialTokens(initialTokens); | |||
| 
 | |||
|             idToPlaceName.insert(std::pair<uint_fast64_t const, std::string const>(id, name)); | |||
|             gspn.addPlace(place); | |||
|         } | |||
| 
 | |||
|         void GspnBuilder::addImmediateTransition(uint_fast64_t const& id, uint_fast64_t const& priority, double const& weight) { | |||
|             auto trans = storm::gspn::ImmediateTransition<double>(); | |||
|             trans.setName(std::to_string(id)); | |||
|             trans.setPriority(priority); | |||
|             trans.setWeight(weight); | |||
| 
 | |||
|             gspn.addImmediateTransition(trans); | |||
|         } | |||
| 
 | |||
|         void GspnBuilder::addTimedTransition(uint_fast64_t const &id, uint_fast64_t const &priority, double const &rate) { | |||
|             auto trans = storm::gspn::TimedTransition<double>(); | |||
|             trans.setName(std::to_string(id)); | |||
|             trans.setPriority(priority); | |||
|             trans.setRate(rate); | |||
| 
 | |||
|             gspn.addTimedTransition(trans); | |||
|         } | |||
| 
 | |||
|         void GspnBuilder::addInputArc(uint_fast64_t const &from, uint_fast64_t const &to, | |||
|                                       uint_fast64_t const &multiplicity) { | |||
|             auto transPair = gspn.getTransition(std::to_string(to)); | |||
|             if (!std::get<0>(transPair)) { | |||
|                 STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "The transition with the name \"" + std::to_string(to) + "\" does not exist."); | |||
|             } | |||
| 
 | |||
|             auto placePair = gspn.getPlace(idToPlaceName.at(from)); | |||
|             if (!std::get<0>(placePair)) { | |||
|                 STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "The place with the id \"" + std::to_string(from) + "\" does not exist."); | |||
|             } | |||
| 
 | |||
|             std::get<1>(transPair)->setInputArcMultiplicity(std::get<1>(placePair), multiplicity); | |||
|         } | |||
| 
 | |||
|         void GspnBuilder::addInhibitionArc(uint_fast64_t const& from, uint_fast64_t const& to, uint_fast64_t const& multiplicity) { | |||
|             auto transPair = gspn.getTransition(std::to_string(to)); | |||
|             if (!std::get<0>(transPair)) { | |||
|                 STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "The transition with the name \"" + std::to_string(to) + "\" does not exist."); | |||
|             } | |||
| 
 | |||
|             auto placePair = gspn.getPlace(idToPlaceName.at(from)); | |||
|             if (!std::get<0>(placePair)) { | |||
|                 STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "The place with the id \"" + std::to_string(from) + "\" does not exist."); | |||
|             } | |||
| 
 | |||
|             std::get<1>(transPair)->setInhibitionArcMultiplicity(std::get<1>(placePair), multiplicity); | |||
|         } | |||
| 
 | |||
|         void GspnBuilder::addOutputArc(uint_fast64_t const& from, uint_fast64_t const& to, uint_fast64_t const& multiplicity) { | |||
|             auto transPair = gspn.getTransition(std::to_string(from)); | |||
|             if (!std::get<0>(transPair)) { | |||
|                 STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "The transition with the name \"" + std::to_string(to) + "\" does not exist."); | |||
|             } | |||
| 
 | |||
|             auto placePair = gspn.getPlace(idToPlaceName.at(to)); | |||
|             if (!std::get<0>(placePair)) { | |||
|                 STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "The place with the id \"" + std::to_string(from) + "\" does not exist."); | |||
|             } | |||
| 
 | |||
|             std::get<1>(transPair)->setOutputArcMultiplicity(std::get<1>(placePair), multiplicity); | |||
|         } | |||
| 
 | |||
|         storm::gspn::GSPN const& GspnBuilder::buildGspn() const { | |||
|             return gspn; | |||
|         } | |||
|     } | |||
| } | |||
| @ -0,0 +1,89 @@ | |||
| #ifndef STORM_STORAGE_GSPN_GSPNBUILDER_H | |||
| #define STORM_STORAGE_GSPN_GSPNBUILDER_H | |||
| 
 | |||
| #include <map> | |||
| #include <string> | |||
| #include <vector> | |||
| 
 | |||
| #include "GSPN.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         class GspnBuilder { | |||
|         public: | |||
|             /** | |||
|              * Add a place to the gspn. | |||
|              * @param id The id must be unique for the gspn. | |||
|              * @param capacity The capacity is the limit of tokens in the place. | |||
|              *                 A capacity of -1 indicates an unbounded place. | |||
|              * @param initialTokens The number of inital tokens in the place. | |||
|              */ | |||
|             void addPlace(uint_fast64_t const& id, int_fast64_t const& capacity = 1, uint_fast64_t const& initialTokens = 0); | |||
| 
 | |||
|             /** | |||
|              * Add a place to the gspn. | |||
|              * @param id The id must be unique for the gspn. | |||
|              * @param name The name must be unique for the gspn. | |||
|              * @param capacity The capacity is the limit of tokens in the place. | |||
|              *                 A capacity of -1 indicates an unbounded place. | |||
|              * @param initialTokens The number of inital tokens in the place. | |||
|              */ | |||
|             void addPlace(uint_fast64_t const& id, std::string const& name, int_fast64_t const& capacity = 1, uint_fast64_t const& initialTokens = 0); | |||
| 
 | |||
|             /** | |||
|              * Adds an immediate transition to the gspn. | |||
|              * @param id The id must be unique for the gspn. | |||
|              * @param priority The priority for the transtion. | |||
|              * @param weight The weight for the transition. | |||
|              */ | |||
|             void addImmediateTransition(uint_fast64_t const& id, uint_fast64_t const& priority = 0, double const& weight = 0); | |||
| 
 | |||
|             /** | |||
|              * Adds an timed transition to the gspn. | |||
|              * @param id The name id be unique for the gspn. | |||
|              * @param priority The priority for the transtion. | |||
|              * @param weight The weight for the transition. | |||
|              */ | |||
|             void addTimedTransition(uint_fast64_t const &id, uint_fast64_t const &priority = 0, double const &rate = 0); | |||
| 
 | |||
|             /** | |||
|              * Adds an new input arc from a place to an transition. | |||
|              * @param from The place from which the arc is originating. | |||
|              * @param to The transtion to which the arc goes to. | |||
|              * @param multiplicity The multiplicity of the arc. | |||
|              */ | |||
|             void addInputArc(uint_fast64_t const &from, uint_fast64_t const &to, uint_fast64_t const &multiplicity = 1); | |||
| 
 | |||
|             /** | |||
|              * Adds an new input arc from a place to an transition. | |||
|              * @param from The place from which the arc is originating. | |||
|              * @param to The transtion to which the arc goes to. | |||
|              * @param multiplicity The multiplicity of the arc. | |||
|              */ | |||
|             void addInhibitionArc(uint_fast64_t const& from, uint_fast64_t const& to, uint_fast64_t const& multiplicity = 1); | |||
| 
 | |||
|             /** | |||
|              * Adds an new input arc from a place to an transition. | |||
|              * @param from The place from which the arc is originating. | |||
|              * @param to The transtion to which the arc goes to. | |||
|              * @param multiplicity The multiplicity of the arc. | |||
|              */ | |||
|             void addOutputArc(uint_fast64_t const& from, uint_fast64_t const& to, uint_fast64_t const& multiplicity = 1); | |||
| 
 | |||
|             /** | |||
|              * | |||
|              * @return The gspn which is constructed by the builder. | |||
|              */ | |||
|             storm::gspn::GSPN const& buildGspn() const; | |||
|         private: | |||
|             // gspn which is returned | |||
|             storm::gspn::GSPN gspn; | |||
|             // map from ids to names (for places) | |||
|             std::map<uint_fast64_t const, std::string const> idToPlaceName; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| 
 | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_GSPNBUILDER_H | |||
| @ -0,0 +1,43 @@ | |||
| #ifndef STORM_STORAGE_GSPN_IMMEDIATETRANSITION_H_ | |||
| #define STORM_STORAGE_GSPN_IMMEDIATETRANSITION_H_ | |||
| 
 | |||
| #include "src/storage/gspn/Transition.h" | |||
| #include "src/utility/constants.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         template <typename WeightType> | |||
|         class ImmediateTransition : public storm::gspn::Transition { | |||
|         public: | |||
|             /*! | |||
|              * Sets the weight of this transition to the given value. | |||
|              * | |||
|              * @param weight The new weight for this transition. | |||
|              */ | |||
|             void setWeight(WeightType const& weight) { | |||
|                 this->weight = weight; | |||
|             } | |||
| 
 | |||
|             /*! | |||
|              * Retrieves the weight of this transition. | |||
|              * | |||
|              * @return The weight of this transition. | |||
|              */ | |||
|             WeightType getWeight() const { | |||
|                 return this->weight; | |||
|             } | |||
| 
 | |||
|             /** | |||
|              * True iff no weight is attached. | |||
|              */ | |||
|             bool noWeightAttached() { | |||
|                 return storm::utility::isZero(weight); | |||
|             } | |||
|         private: | |||
|             // the weight of the transition. Must be positive, if zero, then no weight is attached. | |||
|            WeightType weight; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_IMMEDIATETRANSITION_H_ | |||
| @ -0,0 +1,59 @@ | |||
| #include <stdint.h>
 | |||
| #include "src/storage/gspn/Marking.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         Marking::Marking(uint_fast64_t const& numberOfPlaces, std::map<uint_fast64_t, uint_fast64_t> const& numberOfBits, uint_fast64_t const& numberOfTotalBits) { | |||
|             this->numberOfPlaces = numberOfPlaces; | |||
|             this->numberOfBits = numberOfBits; | |||
|             this->marking = storm::storage::BitVector(numberOfTotalBits); | |||
|         } | |||
| 
 | |||
|         Marking::Marking(uint_fast64_t const& numberOfPlaces, std::map<uint_fast64_t, uint_fast64_t> const& numberOfBits, storm::storage::BitVector const& bitvector) { | |||
|             this->numberOfPlaces = numberOfPlaces; | |||
|             this->numberOfBits = numberOfBits; | |||
|             this->marking = bitvector; | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Marking::getNumberOfPlaces() const { | |||
|             return this->numberOfPlaces; | |||
|         } | |||
| 
 | |||
|         void Marking::setNumberOfTokensAt(uint_fast64_t const& place, uint_fast64_t const& numberOfTokens) { | |||
|             uint_fast64_t index = 0; | |||
|             for (uint_fast64_t i=0; i < place; ++i) { | |||
|                 index += numberOfBits[i]; | |||
|             } | |||
|             marking.setFromInt(index, numberOfBits[place], numberOfTokens); | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Marking::getNumberOfTokensAt(uint_fast64_t const& place) const { | |||
|             uint_fast64_t index = 0; | |||
|             for (uint_fast64_t i=0; i < place; ++i) { | |||
|                 index += numberOfBits.at(i); | |||
|             } | |||
|             return marking.getAsInt(index, numberOfBits.at(place)); | |||
|         } | |||
| 
 | |||
|         std::shared_ptr<storm::storage::BitVector> Marking::getBitVector() const { | |||
|             auto result = std::make_shared<storm::storage::BitVector>(); | |||
|             *result = storm::storage::BitVector(marking); | |||
|             return result; | |||
|         } | |||
| 
 | |||
|         bool Marking::operator==(const Marking& other) const { | |||
|             if (getNumberOfPlaces() != other.getNumberOfPlaces()) { | |||
|                 return false; | |||
|             } | |||
|             if (&numberOfBits == &other.numberOfBits) { | |||
|                 return marking == other.marking; | |||
|             } | |||
|             for (uint_fast64_t i=0; i < getNumberOfPlaces(); ++i) { | |||
|                 if (getNumberOfTokensAt(i) != other.getNumberOfTokensAt(i)) { | |||
|                     return false; | |||
|                 } | |||
|             } | |||
|             return true; | |||
|         } | |||
|     } | |||
| } | |||
| @ -0,0 +1,80 @@ | |||
| #ifndef STORM_STORAGE_GSPN_MARKING_H_ | |||
| #define STORM_STORAGE_GSPN_MARKING_H_ | |||
| 
 | |||
| #include <cmath> | |||
| #include <map> | |||
| #include <memory> | |||
| #include "src/storage/BitVector.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         class Marking { | |||
|         public: | |||
| 
 | |||
|             /*! | |||
|              * Creates an empty marking (at all places contain 0 tokens). | |||
|              * | |||
|              * @param numberOfPlaces The number of places of the gspn. | |||
|              * @param numberOfBits The number of bits used to store the number of tokens for each place | |||
|              * @param numberOfTotalBits The length of the internal bitvector | |||
|              */ | |||
|             Marking(uint_fast64_t const& numberOfPlaces, std::map<uint_fast64_t, uint_fast64_t> const& numberOfBits, uint_fast64_t const& numberOfTotalBits); | |||
| 
 | |||
|             /*! | |||
|              * Create the marking described by the bitvector. | |||
|              * | |||
|              * @param numberOfPlaces The number of places of the gspn. | |||
|              * @param numberOfBits The number of bits used to store the number of tokens for each place | |||
|              * @param bitvector The bitvector encoding the marking. | |||
|              */ | |||
|             Marking(uint_fast64_t const&numberOfPlaces, std::map<uint_fast64_t, uint_fast64_t> const& numberOfBits, storm::storage::BitVector const& bitvector); | |||
| 
 | |||
|             /*! | |||
|              * Retrieves the number of places for which the tokens are stored. | |||
|              * | |||
|              * @return The number of places. | |||
|              */ | |||
|             uint_fast64_t getNumberOfPlaces() const; | |||
| 
 | |||
|             /*! | |||
|              * Set the number of tokens for the given place to the given amount. | |||
|              * | |||
|              * @param place Place must be a valid place for which the number of tokens is changed. | |||
|              * @param numberOfTokens The new number of tokens at the place. | |||
|              */ | |||
|             void setNumberOfTokensAt(uint_fast64_t const& place, uint_fast64_t const& numberOfTokens); | |||
| 
 | |||
|             /*! | |||
|              * Get the number of tokens for the given place. | |||
|              * | |||
|              * @param place The place from which the tokens are counted. | |||
|              * @return The number of tokens at the place. | |||
|              */ | |||
|             uint_fast64_t getNumberOfTokensAt(uint_fast64_t const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a copy of the bitvector | |||
|              * | |||
|              * @return The bitvector which encodes the marking | |||
|              */ | |||
|             std::shared_ptr<storm::storage::BitVector> getBitVector() const; | |||
| 
 | |||
|             /*! | |||
|              * Overload equality operator | |||
|              */ | |||
|             bool operator==(const Marking& other) const; | |||
|         private: | |||
|             // the maximal number of places in the gspn | |||
|             uint_fast64_t numberOfPlaces; | |||
| 
 | |||
|             // number of bits for each place | |||
|             std::map<uint_fast64_t, uint_fast64_t> numberOfBits; | |||
| 
 | |||
|             // contains the information of the marking | |||
|             storm::storage::BitVector marking; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_MARKING_H_ | |||
| @ -0,0 +1,41 @@ | |||
| #include "Place.h"
 | |||
| 
 | |||
| #include "src/exceptions/IllegalArgumentValueException.h"
 | |||
| #include "src/utility/macros.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         void Place::setName(std::string const& name) { | |||
|             this->name = name; | |||
|         } | |||
| 
 | |||
|         std::string Place::getName() const { | |||
|             return this->name; | |||
|         } | |||
| 
 | |||
|         void Place::setID(uint_fast64_t const& id) { | |||
|             this->id = id; | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Place::getID() const { | |||
|             return this->id; | |||
|         } | |||
| 
 | |||
|         void Place::setNumberOfInitialTokens(uint_fast64_t const& tokens) { | |||
|             this->numberOfInitialTokens = tokens; | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Place::getNumberOfInitialTokens() const { | |||
|             return this->numberOfInitialTokens; | |||
|         } | |||
| 
 | |||
|         void Place::setCapacity(int_fast64_t const& capacity) { | |||
|             STORM_LOG_THROW(capacity >= -1, storm::exceptions::IllegalArgumentValueException, "The capacity cannot be less than -1."); | |||
|             this->capacity = capacity; | |||
|         } | |||
| 
 | |||
|         int_fast64_t Place::getCapacity() const { | |||
|             return this->capacity; | |||
|         } | |||
|     } | |||
| } | |||
| @ -0,0 +1,87 @@ | |||
| #ifndef STORM_STORAGE_GSPN_PLACE_H_ | |||
| #define STORM_STORAGE_GSPN_PLACE_H_ | |||
| 
 | |||
| #include <string> | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         /*! | |||
|          * This class provides methods to store and retrieve data for a place in a gspn. | |||
|          */ | |||
|         class Place { | |||
|         public: | |||
|             /*! | |||
|              * Sets the name of this place. The name must be unique for a gspn. | |||
|              * | |||
|              * @param name The new name for the place. | |||
|              */ | |||
|             void setName(std::string const& name); | |||
| 
 | |||
|             /*! | |||
|              * Returns the name of this place. | |||
|              * | |||
|              * @return The name of this place. | |||
|              */ | |||
|             std::string getName() const; | |||
| 
 | |||
|             /*! | |||
|              * Sets the id of this place. The id must be unique for a gspn. | |||
|              * | |||
|              * @param id The new id of this place. | |||
|              */ | |||
|             void setID(uint_fast64_t const& id); | |||
| 
 | |||
|             /*! | |||
|              * Returns the id of this place. | |||
|              * | |||
|              * @return The id of this place. | |||
|              */ | |||
|             uint_fast64_t getID() const; | |||
| 
 | |||
|             /*! | |||
|              * Sets the number of initial tokens of this place. | |||
|              * | |||
|              * @param tokens The number of initial tokens. | |||
|              */ | |||
|             void setNumberOfInitialTokens(uint_fast64_t const& tokens); | |||
| 
 | |||
|             /*! | |||
|              * Returns the number of initial tokens of this place. | |||
|              * | |||
|              * @return The number of initial tokens of this place. | |||
|              */ | |||
|             uint_fast64_t getNumberOfInitialTokens() const; | |||
| 
 | |||
|             /*! | |||
|              * Sets the capacity of tokens of this place. | |||
|              * | |||
|              * @param capacity The capacity of this place. A non-negative number represents the capacity. | |||
|              *                 The value -1 indicates that the capacity is not set. | |||
|              */ | |||
|             void setCapacity(int_fast64_t const& capacity); | |||
| 
 | |||
|             /*! | |||
|              * Returns the capacity of tokens of this place. | |||
|              * | |||
|              * @return The capacity of the place. The value -1 indicates that the capacity is not set. | |||
|              */ | |||
|             int_fast64_t getCapacity() const; | |||
|         private: | |||
|             // contains the number of initial tokens of this place | |||
|             uint_fast64_t numberOfInitialTokens; | |||
| 
 | |||
|             // unique id (is used to refer to a specific place in a bitvector) | |||
|             uint_fast64_t id; | |||
| 
 | |||
|             // name which is used in pnml file | |||
|             std::string name; | |||
| 
 | |||
|             // capacity of this place | |||
|             // -1 indicates that the capacity is not set | |||
|             // other non-negative values represents the capacity | |||
|             int_fast64_t capacity; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_PLACE_H_ | |||
| @ -0,0 +1,36 @@ | |||
| #ifndef STORM_STORAGE_GSPN_TIMEDTRANSITION_H_ | |||
| #define STORM_STORAGE_GSPN_TIMEDTRANSITION_H_ | |||
| 
 | |||
| #include "src/storage/gspn/Transition.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         template <typename RateType> | |||
|         class TimedTransition : public storm::gspn::Transition { | |||
|         public: | |||
|             /*! | |||
|              * Sets the rate of this transition to the given value. | |||
|              * | |||
|              * @param rate The new rate for this transition. | |||
|              */ | |||
|             void setRate(RateType const& rate) { | |||
|                 this->rate = rate; | |||
|             } | |||
| 
 | |||
|             /*! | |||
|              * Retrieves the rate of this transition. | |||
|              * | |||
|              * @return The rate of this transition. | |||
|              */ | |||
|             RateType getRate() const { | |||
|                 return this->rate; | |||
|             } | |||
| 
 | |||
|         private: | |||
|             // the rate of the transition | |||
|             RateType rate; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_TIMEDTRANSITION_H_ | |||
| @ -0,0 +1,195 @@ | |||
| #include "src/storage/gspn/Transition.h"
 | |||
| 
 | |||
| #include "src/utility/macros.h"
 | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
| 
 | |||
|         void Transition::setInputArcMultiplicity(storm::gspn::Place const& place, uint_fast64_t multiplicity) { | |||
|             auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|             inputMultiplicities[ptr] = multiplicity; | |||
|             inputPlaces.push_back(ptr); | |||
|         } | |||
| 
 | |||
|         bool Transition::removeInputArc(storm::gspn::Place const& place) { | |||
|             if (existsInputArc(place)) { | |||
|                 auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|                 inputMultiplicities.erase(ptr); | |||
|                 inputPlaces.erase(std::find(inputPlaces.begin(), inputPlaces.end(), ptr)); | |||
|                 return true; | |||
|             } else { | |||
|                 return false; | |||
|             } | |||
|         } | |||
| 
 | |||
|         bool Transition::existsInputArc(storm::gspn::Place const& place) const { | |||
|             auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|             return inputMultiplicities.end() != inputMultiplicities.find(ptr); | |||
|         } | |||
| 
 | |||
|         void Transition::setOutputArcMultiplicity(storm::gspn::Place const& place, uint_fast64_t multiplicity) { | |||
|             auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|             outputMultiplicities[ptr] = multiplicity; | |||
|             outputPlaces.push_back(ptr); | |||
|         } | |||
| 
 | |||
|         bool Transition::removeOutputArc(storm::gspn::Place const& place) { | |||
|             if (existsOutputArc(place)) { | |||
|                 auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|                 outputMultiplicities.erase(ptr); | |||
|                 outputPlaces.erase(std::find(outputPlaces.begin(), outputPlaces.end(), ptr)); | |||
|                 return true; | |||
|             } else { | |||
|                 return false; | |||
|             } | |||
|         } | |||
| 
 | |||
|         bool Transition::existsOutputArc(storm::gspn::Place const& place) const { | |||
|             auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|             return outputMultiplicities.end() != outputMultiplicities.find(ptr); | |||
|         } | |||
| 
 | |||
|         void Transition::setInhibitionArcMultiplicity(storm::gspn::Place const& place, | |||
|                                                       uint_fast64_t multiplicity) { | |||
|             auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|             inhibitionMultiplicities[ptr] = multiplicity; | |||
|             inhibitionPlaces.push_back(ptr); | |||
|         } | |||
| 
 | |||
|         bool Transition::removeInhibitionArc(storm::gspn::Place const& place) { | |||
|             if (existsInhibitionArc(place)) { | |||
|                 auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|                 inhibitionMultiplicities.erase(ptr); | |||
|                 inhibitionPlaces.erase(std::find(inhibitionPlaces.begin(), inhibitionPlaces.end(), ptr)); | |||
|                 return true; | |||
|             } else { | |||
|                 return false; | |||
|             } | |||
|         } | |||
| 
 | |||
|         bool Transition::existsInhibitionArc(storm::gspn::Place const& place) const { | |||
|             auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|             return inhibitionMultiplicities.end() != inhibitionMultiplicities.find(ptr); | |||
|         } | |||
| 
 | |||
|         bool Transition::isEnabled(storm::gspn::Marking const& marking) const { | |||
|             auto inputIterator = inputMultiplicities.cbegin(); | |||
|             while (inputIterator != inputMultiplicities.cend()) { | |||
|                 if (marking.getNumberOfTokensAt(inputIterator->first->getID()) < inputIterator->second) { | |||
|                     return false; | |||
|                 } | |||
| 
 | |||
|                 ++inputIterator; | |||
|             } | |||
| 
 | |||
|             auto inhibitionIterator = inhibitionMultiplicities.cbegin(); | |||
|             while (inhibitionIterator != inhibitionMultiplicities.cend()) { | |||
|                 if (marking.getNumberOfTokensAt(inhibitionIterator->first->getID()) >= inhibitionIterator->second) { | |||
|                     return false; | |||
|                 } | |||
| 
 | |||
|                 ++inhibitionIterator; | |||
|             } | |||
| 
 | |||
|             auto outputIterator = outputMultiplicities.cbegin(); | |||
|             while (outputIterator != outputMultiplicities.cend()) { | |||
|                 if (outputIterator->first->getCapacity() >= 0) { | |||
|                     if (marking.getNumberOfTokensAt(outputIterator->first->getID()) + outputIterator->second > outputIterator->first->getCapacity()) { | |||
|                         return false; | |||
|                     } | |||
|                 } | |||
| 
 | |||
|                 ++outputIterator; | |||
|             } | |||
| 
 | |||
|             return true; | |||
|         } | |||
| 
 | |||
|         storm::gspn::Marking Transition::fire(storm::gspn::Marking const& marking) const { | |||
|             storm::gspn::Marking newMarking(marking); | |||
| 
 | |||
|             auto inputIterator = inputMultiplicities.cbegin(); | |||
|             while (inputIterator != inputMultiplicities.cend()) { | |||
|                 newMarking.setNumberOfTokensAt(inputIterator->first->getID(), | |||
|                                                newMarking.getNumberOfTokensAt(inputIterator->first->getID()) - inputIterator->second); | |||
|                 ++inputIterator; | |||
|             } | |||
| 
 | |||
|             auto outputIterator = outputMultiplicities.cbegin(); | |||
|             while (outputIterator != outputMultiplicities.cend()) { | |||
|                 newMarking.setNumberOfTokensAt(outputIterator->first->getID(), | |||
|                                                newMarking.getNumberOfTokensAt(outputIterator->first->getID()) + outputIterator->second); | |||
|                 ++outputIterator; | |||
|             } | |||
| 
 | |||
|             return newMarking; | |||
|         } | |||
| 
 | |||
|         void Transition::setName(std::string const& name) { | |||
|             this->name = name; | |||
|         } | |||
| 
 | |||
|         std::string const& Transition::getName() const { | |||
|             return this->name; | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator  Transition::getInputPlacesCBegin() const { | |||
|             return this->inputPlaces.cbegin(); | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator Transition::getInputPlacesCEnd() const { | |||
|             return this->inputPlaces.cend(); | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator Transition::getOutputPlacesCBegin() const { | |||
|             return this->outputPlaces.cbegin(); | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator Transition::getOutputPlacesCEnd() const { | |||
|             return this->outputPlaces.cend(); | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator Transition::getInhibitionPlacesCBegin() const { | |||
|             return this->inhibitionPlaces.cbegin(); | |||
|         } | |||
| 
 | |||
|         std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator Transition::getInhibitionPlacesCEnd() const { | |||
|             return this->inhibitionPlaces.cend(); | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Transition::getInputArcMultiplicity(storm::gspn::Place const& place) const { | |||
|             if (existsInputArc(place)) { | |||
|                 auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|                 return inputMultiplicities.at(ptr); | |||
|             } else { | |||
|                 return 0; | |||
|             } | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Transition::getInhibitionArcMultiplicity(storm::gspn::Place const& place) const { | |||
|             if (existsInhibitionArc(place)) { | |||
|                 auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|                 return inhibitionMultiplicities.at(ptr); | |||
|             } else { | |||
|                 return 0; | |||
|             } | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Transition::getOutputArcMultiplicity(storm::gspn::Place const& place) const { | |||
|             if (existsOutputArc(place)) { | |||
|                 auto ptr = std::make_shared<storm::gspn::Place>(place); | |||
|                 return outputMultiplicities.at(ptr); | |||
|             } else { | |||
|                 return 0; | |||
|             } | |||
|         } | |||
| 
 | |||
|         void Transition::setPriority(uint_fast64_t const& priority) { | |||
|             this->priority = priority; | |||
|         } | |||
| 
 | |||
|         uint_fast64_t Transition::getPriority() const { | |||
|             return this->priority; | |||
|         } | |||
|     } | |||
| } | |||
| @ -0,0 +1,240 @@ | |||
| #ifndef STORM_STORAGE_GSPN_TRANSITION_H_ | |||
| #define STORM_STORAGE_GSPN_TRANSITION_H_ | |||
| 
 | |||
| #include <map> | |||
| #include <vector> | |||
| #include "src/storage/gspn/Marking.h" | |||
| #include "src/storage/gspn/Place.h" | |||
| 
 | |||
| namespace storm { | |||
|     namespace gspn { | |||
|         /*! | |||
|          * This class represents a transition in a gspn. | |||
|          */ | |||
|         class Transition { | |||
|         public: | |||
|             /*! | |||
|              * Set the multiplicity of the input arc originating from the place. | |||
|              * If the arc already exists, the former multiplicity is overwritten. | |||
|              * If the arc does not yet exists, it is created. | |||
|              * | |||
|              * @param place The place connected by an input arc. | |||
|              * @param multiplicity The multiplicity of the specified arc. | |||
|              */ | |||
|             void setInputArcMultiplicity(storm::gspn::Place const& place, uint_fast64_t multiplicity); | |||
| 
 | |||
|             /*! | |||
|              * Removes an input arc connected to a given place. | |||
|              * | |||
|              * @param place The place from which the input arc is originating. | |||
|              * @return True if the arc existed. | |||
|              */ | |||
|             bool removeInputArc(storm::gspn::Place const& place); | |||
| 
 | |||
|             /*! | |||
|              * Checks whether the given place is connected to this transition via an input arc. | |||
|              * | |||
|              * @param place The place which is going to be checked. | |||
|              * @return True if the place is connected via an input arc. | |||
|              */ | |||
|             bool existsInputArc(storm::gspn::Place const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Set the multiplicity of the output arc going to the place. | |||
|              * If the arc already exists, the former multiplicity is overwritten. | |||
|              * If the arc does not yet exists, it is created. | |||
|              * | |||
|              * @param place The place connected by an output arc. | |||
|              * @param multiplicity The multiplicity of the specified arc. | |||
|              */ | |||
|             void setOutputArcMultiplicity(storm::gspn::Place const& place, uint_fast64_t multiplicity); | |||
| 
 | |||
|             /*! | |||
|              * Removes an output arc connected to a given place. | |||
|              * | |||
|              * @param place The place from which the output arc is leading to. | |||
|              * @return True if the arc existed. | |||
|              */ | |||
|             bool removeOutputArc(storm::gspn::Place const& place); | |||
| 
 | |||
|             /*! | |||
|              * Checks whether the given place is connected to this transition via an output arc. | |||
|              * | |||
|              * @param place The place which is going to be checked. | |||
|              * @return True if the place is connected via an output arc. | |||
|              */ | |||
|             bool existsOutputArc(storm::gspn::Place const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Set the multiplicity of the inhibition arc originating from the place. | |||
|              * If the arc already exists, the former multiplicity is overwritten. | |||
|              * If the arc does not yet exists, it is created. | |||
|              * | |||
|              * @param place The place connected by an inhibition arc. | |||
|              * @param multiplicity The multiplicity of the specified arc. | |||
|              */ | |||
|             void setInhibitionArcMultiplicity(storm::gspn::Place const& place, uint_fast64_t multiplicity); | |||
| 
 | |||
|             /*! | |||
|              * Removes an inhibition arc connected to a given place. | |||
|              * | |||
|              * @param place The place from which the inhibition arc is originating. | |||
|              * @return True if the arc existed. | |||
|              */ | |||
|             bool removeInhibitionArc(storm::gspn::Place const& place); | |||
| 
 | |||
|             /*! | |||
|              * Checks whether the given place is connected to this transition via an inhibition arc. | |||
|              * | |||
|              * @param place The place which is going to be checked. | |||
|              * @return True if the place is connected via an inhibition arc. | |||
|              */ | |||
|             bool existsInhibitionArc(storm::gspn::Place const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Checks if the given marking enables the transition. | |||
|              * | |||
|              * @return True if the transition is enabled. | |||
|              */ | |||
|             bool isEnabled(storm::gspn::Marking const& marking) const; | |||
| 
 | |||
|             /*! | |||
|              * Fire the transition if possible. | |||
|              * | |||
|              * @param marking The current marking before the transition is fired. | |||
|              * @return The marking after the transition was fired. | |||
|              */ | |||
|             storm::gspn::Marking fire(storm::gspn::Marking const& marking) const; | |||
| 
 | |||
|             /*! | |||
|              * Set the name of the transition. | |||
|              * | |||
|              * @param name New name of the transition. | |||
|              */ | |||
|             void setName(std::string const& name); | |||
| 
 | |||
|             /*! | |||
|              * Returns the name of the transition. | |||
|              * | |||
|              * @return The name of the transition. | |||
|              */ | |||
|             std::string const& getName() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a constant iterator to the begin of a vector which contains all input places. | |||
|              * | |||
|              * @return Returns iterator. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator getInputPlacesCBegin() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a constant iterator to the end of a vector which contains all input places. | |||
|              * | |||
|              * @return Returns iterator. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator getInputPlacesCEnd() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a constant iterator to the begin of a vector which contains all output places. | |||
|              * | |||
|              * @return Returns iterator. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator getOutputPlacesCBegin() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a constant iterator to the end of a vector which contains all output places. | |||
|              * | |||
|              * @return Returns iterator. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator getOutputPlacesCEnd() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a constant iterator to the begin of a vector which contains all inhibition places. | |||
|              * | |||
|              * @return Returns iterator. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator getInhibitionPlacesCBegin() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns a constant iterator to the end of a vector which contains all inhibition places. | |||
|              * | |||
|              * @return Returns iterator. | |||
|              */ | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>>::const_iterator getInhibitionPlacesCEnd() const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the corresponding multiplicity. | |||
|              * | |||
|              * @param place connected to this transition by an input arc | |||
|              * @return cardinality or 0 if the arc does not exists | |||
|              */ | |||
|             uint_fast64_t getInputArcMultiplicity(storm::gspn::Place const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the corresponding multiplicity. | |||
|              * | |||
|              * @param place connected to this transition by an inhibition arc | |||
|              * @return cardinality or 0 if the arc does not exists | |||
|              */ | |||
|             uint_fast64_t getInhibitionArcMultiplicity(storm::gspn::Place const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Returns the corresponding multiplicity. | |||
|              * | |||
|              * @param place connected to this transition by an output arc | |||
|              * @return cardinality or 0 if the arc does not exists | |||
|              */ | |||
|             uint_fast64_t getOutputArcMultiplicity(storm::gspn::Place const& place) const; | |||
| 
 | |||
|             /*! | |||
|              * Sets the priority of this transtion. | |||
|              * | |||
|              * @param priority The new priority. | |||
|              */ | |||
|             void setPriority(uint_fast64_t const& priority); | |||
| 
 | |||
|             /*! | |||
|              * Returns the priority of this transition. | |||
|              * | |||
|              * @return The priority. | |||
|              */ | |||
|             uint_fast64_t getPriority() const; | |||
|         private: | |||
|             /*! | |||
|              * Comparator which defines an total order on places. | |||
|              * A place is less than another place if the id is less than the id from the other place. | |||
|              */ | |||
|             struct PlaceComparator { | |||
|                 bool operator()(std::shared_ptr<storm::gspn::Place> const& lhs, std::shared_ptr<storm::gspn::Place> const& rhs) const { | |||
|                     return lhs->getID() < rhs->getID(); | |||
|                 } | |||
|             }; | |||
| 
 | |||
|             // maps places connected to this transition with an input arc to the corresponding multiplicity | |||
|             std::map<std::shared_ptr<storm::gspn::Place>, uint_fast64_t, storm::gspn::Transition::PlaceComparator> inputMultiplicities; | |||
| 
 | |||
|             // maps places connected to this transition with an output arc to the corresponding multiplicities | |||
|             std::map<std::shared_ptr<storm::gspn::Place>, uint_fast64_t, storm::gspn::Transition::PlaceComparator> outputMultiplicities; | |||
| 
 | |||
|             // maps places connected to this transition with an inhibition arc to the corresponding multiplicity | |||
|             std::map<std::shared_ptr<storm::gspn::Place>, uint_fast64_t, storm::gspn::Transition::PlaceComparator> inhibitionMultiplicities; | |||
| 
 | |||
|             // name of the transition | |||
|             std::string name; | |||
| 
 | |||
|             // list of all places connected to this transition via an input arc | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>> inputPlaces; | |||
| 
 | |||
|             // list of all places connected to this transition via an output arc | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>> outputPlaces; | |||
| 
 | |||
|             // list of all places connected to this transition via an inhibition arc | |||
|             std::vector<std::shared_ptr<storm::gspn::Place>> inhibitionPlaces; | |||
| 
 | |||
|             // priority of this transition | |||
|             uint_fast64_t priority; | |||
|         }; | |||
|     } | |||
| } | |||
| 
 | |||
| #endif //STORM_STORAGE_GSPN_TRANSITION_H_ | |||
| @ -0,0 +1,153 @@ | |||
| #include "src/builder/ExplicitGspnModelBuilder.h"
 | |||
| #include "src/exceptions/BaseException.h"
 | |||
| #include "src/parser/GspnParser.h"
 | |||
| #include "src/storage/gspn/GSPN.h"
 | |||
| #include "src/storage/gspn/GspnBuilder.h"
 | |||
| #include "src/utility/macros.h"
 | |||
| #include "src/utility/initialize.h"
 | |||
| #include <fstream>
 | |||
| #include <iostream>
 | |||
| #include <string>
 | |||
| // TODO clean-up includes after doing all other todos
 | |||
| 
 | |||
| /*!
 | |||
|  * Parses the arguments to storm-gspn | |||
|  * The read data is stored in the different arguments (e.g., inputFile, formula, ...) | |||
|  * | |||
|  * @param argc number of arguments passed to storm-gspn | |||
|  * @param argv array of arguments | |||
|  * @param inputFile the input file is stored in this object | |||
|  * @param formula the formula is stored in this object | |||
|  * @param outputFile the output file is stored in this object | |||
|  * @param outputType the output type is stored in this object | |||
|  * @return false if the help flag is set or the input file is missing | |||
|  */ | |||
| bool parseArguments(const int argc, const char **argv, std::string &inputFile, std::string &formula, | |||
|                     std::string &outputFile, std::string &outputType) { | |||
|     auto end = argv + argc; | |||
|     bool result = false; | |||
| 
 | |||
|     for (auto it = argv; it != end; ++it) { | |||
|         std::string currentArg = *it; | |||
| 
 | |||
|         // parse input file argument
 | |||
|         if (currentArg == "--input_file" || currentArg == "-i") { | |||
|             auto next = it + 1; | |||
|             if (next != end) { | |||
|                 return -1; | |||
|             } else { | |||
|                 inputFile = *next; | |||
|                 result = true; | |||
|             } | |||
|             break; | |||
|         } | |||
| 
 | |||
|         // parse formula argument
 | |||
|         if (currentArg == "--formula" || currentArg == "-f") { | |||
|             auto next = it + 1; | |||
|             if (next != end) { | |||
|                 return -1; | |||
|             } else { | |||
|                 formula = *next; | |||
|             } | |||
|             break; | |||
|         } | |||
| 
 | |||
|         // parse output file argument
 | |||
|         if (currentArg == "--output_file" || currentArg == "-o") { | |||
|             auto next = it + 1; | |||
|             if (next != end) { | |||
|                 return -1; | |||
|             } else { | |||
|                 outputFile = *next; | |||
|             } | |||
|             break; | |||
|         } | |||
| 
 | |||
|         // parse output file type argument
 | |||
|         if (currentArg == "--output_type" || currentArg == "-ot") { | |||
|             auto next = it + 1; | |||
|             if (next != end) { | |||
|                 return -1; | |||
|             } else { | |||
|                 outputType = *next; | |||
|             } | |||
|             break; | |||
|         } | |||
| 
 | |||
|         // parse help argument
 | |||
|         if (currentArg == "--help" || currentArg == "-h") { | |||
|             return false; | |||
|         } | |||
|     } | |||
| 
 | |||
|     return result; | |||
| } | |||
| 
 | |||
| /*!
 | |||
|  * Print the manual of storm-gspn | |||
|  */ | |||
| void printHelp() { | |||
|     std::cout << "storm-gspn -i input_file [-f formula] [-o output_file] [-ot output_type] [-h]" << std::endl; | |||
|     std::cout << std::endl; | |||
|     std::cout << "-i, --input_file:   file which contains the gspn" << std::endl; | |||
|     std::cout << "-f, --formula:      formula which should be checked on the gspn" << std::endl; | |||
|     std::cout << "-o, -output_file:   file in which the gspn/markov automaton should be stored" << std::endl | |||
|               << "                    requires the option -ot to be set" << std::endl; | |||
|     std::cout << "-ot, --output_type: possible output types are: pnml, pnpro or ma" << std::endl; | |||
| } | |||
| 
 | |||
| int main(const int argc, const char **argv) { | |||
|     std::string inputFile, formula, outputFile, outputType; | |||
|     if (!parseArguments(argc, argv, inputFile, formula, outputFile, outputType)) { | |||
|         printHelp(); | |||
|         return 1; | |||
|     } | |||
| 
 | |||
|     try { | |||
|         storm::utility::setUp(); | |||
| 
 | |||
|         // parse GSPN from file
 | |||
|         auto parser = storm::parser::GspnParser(); | |||
|         auto gspn = parser.parse(inputFile); | |||
| 
 | |||
|         // todo ------[marker]
 | |||
|         gspn.isValid(); | |||
| 
 | |||
|         storm::gspn::GspnBuilder builder2; | |||
|         builder2.addPlace(2); | |||
| 
 | |||
|         //
 | |||
|         //std::ofstream file;
 | |||
|         //file.open("/Users/thomas/Desktop/storm.dot");
 | |||
|         //gspn.writeDotToStream(file);
 | |||
|         //file.close();
 | |||
| 
 | |||
|         std::ofstream file; | |||
|         file.open("/Users/thomas/Desktop/gspn.pnpro"); | |||
|         gspn.toPnpro(file); | |||
|         file.close(); | |||
| 
 | |||
|         std::cout << "Parsing complete!" << std::endl; | |||
| 
 | |||
| 
 | |||
|         // Construct MA
 | |||
|         auto builder = storm::builder::ExplicitGspnModelBuilder<>(); | |||
|         auto ma = builder.translateGspn(gspn, argv[2]); | |||
|         std::cout << "Markov Automaton: " << std::endl; | |||
|         std::cout << "number of states: " << ma.getNumberOfStates() << std::endl; | |||
|         std::cout << "number of transitions: " << ma.getNumberOfTransitions() << std::endl << std::endl; | |||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | |||
| 
 | |||
|         // All operations have now been performed, so we clean up everything and terminate.
 | |||
|         storm::utility::cleanUp(); | |||
|         return 0; | |||
|     } catch (storm::exceptions::BaseException const& exception) { | |||
|         STORM_LOG_ERROR("An exception caused StoRM to terminate. The message of the exception is: " << exception.what()); | |||
|     } catch (std::exception const& exception) { | |||
|         STORM_LOG_ERROR("An unexpected exception occurred and caused StoRM to terminate. The message of this exception is: " << exception.what()); | |||
|     } | |||
| } | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue