You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
10 KiB
205 lines
10 KiB
#include "GspnBuilder.h"
|
|
|
|
|
|
#include "storm/exceptions/IllegalFunctionCallException.h"
|
|
|
|
#include "storm/utility/macros.h"
|
|
#include "storm/exceptions/InvalidArgumentException.h"
|
|
#include "Place.h"
|
|
|
|
namespace storm {
|
|
namespace gspn {
|
|
void GspnBuilder::setGspnName(std::string const& name) {
|
|
gspnName = name;
|
|
}
|
|
|
|
uint_fast64_t GspnBuilder::addPlace(boost::optional<uint64_t> const& capacity, uint_fast64_t const& initialTokens, std::string const& name) {
|
|
auto newId = places.size();
|
|
auto place = storm::gspn::Place(newId);
|
|
place.setCapacity(capacity);
|
|
place.setNumberOfInitialTokens(initialTokens);
|
|
place.setName(name);
|
|
places.push_back(place);
|
|
placeNames.emplace(name, newId);
|
|
return newId;
|
|
}
|
|
|
|
|
|
void GspnBuilder::setPlaceLayoutInfo(uint64_t placeId, LayoutInfo const& layoutInfo) {
|
|
placeLayout[placeId] = layoutInfo;
|
|
}
|
|
|
|
void GspnBuilder::setTransitionLayoutInfo(uint64_t transitionId, LayoutInfo const& layoutInfo) {
|
|
transitionLayout[transitionId] = layoutInfo;
|
|
}
|
|
|
|
uint_fast64_t GspnBuilder::addImmediateTransition(uint_fast64_t const& priority, double const& weight, std::string const& name) {
|
|
auto trans = storm::gspn::ImmediateTransition<double>();
|
|
auto newId = GSPN::immediateTransitionIdToTransitionId(immediateTransitions.size());
|
|
trans.setName(name);
|
|
trans.setPriority(priority);
|
|
trans.setID(newId);
|
|
|
|
// ensure that the first partition is for the 'general/weighted' transitions
|
|
if(partitions.count(priority) == 0) {
|
|
TransitionPartition newPart;
|
|
newPart.priority = priority;
|
|
partitions[priority].push_back(newPart);
|
|
}
|
|
|
|
if(storm::utility::isZero(weight)) {
|
|
trans.setWeight(storm::utility::one<double>());
|
|
TransitionPartition newPart;
|
|
newPart.priority = priority;
|
|
newPart.transitions = {newId};
|
|
partitions.at(priority).push_back(newPart);
|
|
} else {
|
|
trans.setWeight(weight);
|
|
partitions.at(priority).front().transitions.push_back(newId);
|
|
|
|
|
|
}
|
|
immediateTransitions.push_back(trans);
|
|
|
|
transitionNames.emplace(name, newId);
|
|
return newId;
|
|
|
|
}
|
|
|
|
uint_fast64_t GspnBuilder::addTimedTransition(uint_fast64_t const &priority, double const &rate, std::string const& name) {
|
|
return addTimedTransition(priority, rate, 1, name);
|
|
}
|
|
|
|
uint_fast64_t GspnBuilder::addTimedTransition(uint_fast64_t const &priority, double const &rate, boost::optional<uint64_t> const& numServers, std::string const& name) {
|
|
auto trans = storm::gspn::TimedTransition<double>();
|
|
auto newId = GSPN::timedTransitionIdToTransitionId(timedTransitions.size());
|
|
trans.setName(name);
|
|
trans.setPriority(priority);
|
|
trans.setRate(rate);
|
|
if (numServers) {
|
|
trans.setKServerSemantics(numServers.get());
|
|
} else {
|
|
trans.setInfiniteServerSemantics();
|
|
}
|
|
trans.setID(newId);
|
|
timedTransitions.push_back(trans);
|
|
|
|
transitionNames.emplace(name, newId);
|
|
return newId;
|
|
}
|
|
|
|
|
|
void GspnBuilder::addInputArc(uint_fast64_t const &from, uint_fast64_t const &to,
|
|
uint_fast64_t const &multiplicity) {
|
|
STORM_LOG_THROW(from < places.size(), storm::exceptions::InvalidArgumentException, "No place with id " << from << " known.");
|
|
auto place = places.at(from);
|
|
getTransition(to).setInputArcMultiplicity(place, multiplicity);
|
|
}
|
|
|
|
void GspnBuilder::addInputArc(std::string const& from, std::string const& to, uint64_t multiplicity) {
|
|
STORM_LOG_THROW(placeNames.count(from) != 0, storm::exceptions::InvalidArgumentException, "Could not find a place with name '" << from << "'");
|
|
STORM_LOG_THROW(transitionNames.count(to) != 0, storm::exceptions::InvalidArgumentException, "Could not find a transition with name << '" << to << "'");
|
|
addInputArc(placeNames.at(from), transitionNames.at(to), multiplicity);
|
|
}
|
|
|
|
void GspnBuilder::addInhibitionArc(uint_fast64_t const& from, uint_fast64_t const& to, uint_fast64_t const& multiplicity) {
|
|
STORM_LOG_THROW(from < places.size(), storm::exceptions::InvalidArgumentException, "No place with id " << from << " known.");
|
|
auto place = places.at(from);
|
|
|
|
getTransition(to).setInhibitionArcMultiplicity(place, multiplicity);
|
|
}
|
|
|
|
void GspnBuilder::addInhibitionArc(std::string const& from, std::string const& to, uint64_t multiplicity) {
|
|
STORM_LOG_THROW(placeNames.count(from) != 0, storm::exceptions::InvalidArgumentException, "Could not find a place with name '" << from << "'");
|
|
STORM_LOG_THROW(transitionNames.count(to) != 0, storm::exceptions::InvalidArgumentException, "Could not find a transition with name << '" << to << "'");
|
|
addInhibitionArc(placeNames.at(from), transitionNames.at(to), multiplicity);
|
|
}
|
|
|
|
void GspnBuilder::addOutputArc(uint_fast64_t const& from, uint_fast64_t const& to, uint_fast64_t const& multiplicity) {
|
|
STORM_LOG_THROW(to < places.size(), storm::exceptions::InvalidArgumentException, "No place with id " << to << " known.");
|
|
auto place = places.at(to);
|
|
getTransition(from).setOutputArcMultiplicity(place, multiplicity);
|
|
}
|
|
|
|
void GspnBuilder::addOutputArc(std::string const& from, std::string const& to, uint64_t multiplicity) {
|
|
STORM_LOG_THROW(placeNames.count(to) != 0, storm::exceptions::InvalidArgumentException, "Could not find a place with name '" << to << "'");
|
|
STORM_LOG_THROW(transitionNames.count(from) != 0, storm::exceptions::InvalidArgumentException, "Could not find a transition with name << '" << from << "'");
|
|
addOutputArc(transitionNames.at(from), placeNames.at(to), multiplicity);
|
|
}
|
|
|
|
Transition& GspnBuilder::getTransition(uint64_t id) {
|
|
if (isTimedTransitionId(id)) {
|
|
return timedTransitions.at(GSPN::transitionIdToTimedTransitionId(id));
|
|
} else if(isImmediateTransitionId(id)) {
|
|
return immediateTransitions.at(id);
|
|
} else {
|
|
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "No transitition with id '" << id << "' known.");
|
|
}
|
|
}
|
|
|
|
void GspnBuilder::addNormalArc(std::string const& from, std::string const& to, uint64_t multiplicity) {
|
|
if (placeNames.count(from) > 0 && transitionNames.count(to) > 0) {
|
|
addInputArc(placeNames.at(from), transitionNames.at(to), multiplicity);
|
|
} else if (transitionNames.count(from) > 0 && placeNames.count(to) > 0) {
|
|
addOutputArc(transitionNames.at(from), placeNames.at(to), multiplicity);
|
|
} else {
|
|
// No suitable combination. Provide error message:
|
|
if (placeNames.count(from) > 0) {
|
|
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expected a transition with name " << to << " for arc from '" << from << "' to '" << to << "'.");
|
|
}
|
|
if (transitionNames.count(from) > 0) {
|
|
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expected a place named " << to << " for arc from '" << from << "' to '" << to << "'.");
|
|
}
|
|
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expected a place named " << from << " for arc from '" << from << "' to '" << to << "'.");
|
|
|
|
}
|
|
}
|
|
|
|
bool GspnBuilder::isTimedTransitionId(uint64_t tid) const {
|
|
if (tid >> 63) {
|
|
return GSPN::transitionIdToTimedTransitionId(tid) < timedTransitions.size();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool GspnBuilder::isImmediateTransitionId(uint64_t tid) const {
|
|
if (tid >> 63) {
|
|
return false;
|
|
}
|
|
return GSPN::transitionIdToImmediateTransitionId(tid) < immediateTransitions.size();
|
|
}
|
|
|
|
|
|
|
|
storm::gspn::GSPN* GspnBuilder::buildGspn(std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager, std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantsSubstitution) const {
|
|
std::shared_ptr<storm::expressions::ExpressionManager> actualExprManager;
|
|
if (exprManager) {
|
|
actualExprManager = exprManager;
|
|
} else {
|
|
actualExprManager = std::make_shared<storm::expressions::ExpressionManager>();
|
|
}
|
|
|
|
std::vector<TransitionPartition> orderedPartitions;
|
|
for(auto const& priorityPartitions : partitions) {
|
|
for (auto const& partition : priorityPartitions.second) {
|
|
// sanity check
|
|
assert(partition.priority == priorityPartitions.first);
|
|
|
|
if(partition.nrTransitions() > 0) {
|
|
orderedPartitions.push_back(partition);
|
|
}
|
|
}
|
|
|
|
}
|
|
std::reverse(orderedPartitions.begin(), orderedPartitions.end());
|
|
for(auto const& placeEntry : placeNames) {
|
|
actualExprManager->declareIntegerVariable(placeEntry.first, false);
|
|
}
|
|
|
|
GSPN* result = new GSPN(gspnName, places, immediateTransitions, timedTransitions, orderedPartitions, actualExprManager, constantsSubstitution);
|
|
result->setTransitionLayoutInfo(transitionLayout);
|
|
result->setPlaceLayoutInfo(placeLayout);
|
|
return result;
|
|
}
|
|
}
|
|
}
|