Browse Source
Allow to quickly check a benchmark from the Quantitative Verification Benchmark Set.
tempestpy_adaptions
Allow to quickly check a benchmark from the Quantitative Verification Benchmark Set.
tempestpy_adaptions
Tim Quatmann
6 years ago
5 changed files with 252 additions and 19 deletions
-
1CHANGELOG.md
-
66src/storm-cli-utilities/model-handling.h
-
12src/storm/settings/modules/IOSettings.cpp
-
149src/storm/storage/Qvbs.cpp
-
43src/storm/storage/Qvbs.h
@ -0,0 +1,149 @@ |
|||||
|
#include "storm/storage/Qvbs.h"
|
||||
|
|
||||
|
#include <algorithm>
|
||||
|
|
||||
|
#include "storm/utility/macros.h"
|
||||
|
#include "storm/utility/file.h"
|
||||
|
#include "storm/utility/string.h"
|
||||
|
#include "storm/settings/SettingsManager.h"
|
||||
|
#include "storm/settings/modules/IOSettings.h"
|
||||
|
#include "storm/exceptions/WrongFormatException.h"
|
||||
|
#include "storm/exceptions/InvalidArgumentException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
|
||||
|
modernjson::json readQvbsJsonFile(std::string const& filePath) { |
||||
|
STORM_LOG_THROW(storm::utility::fileExistsAndIsReadable(filePath), storm::exceptions::WrongFormatException, "QVBS json file " << filePath << " was not found."); |
||||
|
modernjson::json result; |
||||
|
std::ifstream file; |
||||
|
storm::utility::openFile(filePath, file); |
||||
|
result << file; |
||||
|
storm::utility::closeFile(file); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
std::string getString(modernjson::json const& structure, std::string const& errorInfo = "") { |
||||
|
if (structure.is_number_integer()) { |
||||
|
return std::to_string(structure.get<int64_t>()); |
||||
|
} else if (structure.is_number_float()) { |
||||
|
return std::to_string(structure.get<double>()); |
||||
|
} else if (structure.is_string()) { |
||||
|
return structure.get<std::string>(); |
||||
|
} else if (structure.is_boolean()) { |
||||
|
return structure.get<bool>() ? "true" : "false"; |
||||
|
} else { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Expected a string, number, or bool, got '" << structure.dump() << "' " << errorInfo); |
||||
|
} |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
std::string findModelPath(std::string const& modelName) { |
||||
|
std::string rootIndexFile = storm::settings::getModule<storm::settings::modules::IOSettings>().getQvbsRoot() + "/index.json"; |
||||
|
|
||||
|
auto modelPaths = readQvbsJsonFile(rootIndexFile); |
||||
|
storm::utility::string::SimilarStrings similarNames(modelName, 0.6, false); |
||||
|
for (auto const& pathJson : modelPaths) { |
||||
|
STORM_LOG_THROW(pathJson.count("path") == 1, storm::exceptions::WrongFormatException, "QVBS file " << rootIndexFile << " has unexpected format."); |
||||
|
std::string path = getString(pathJson["path"], "Path entry in QVBS file " + rootIndexFile); |
||||
|
std::string currModelName = path.substr(path.find("/") + 1); |
||||
|
if (currModelName == modelName) { |
||||
|
return storm::settings::getModule<storm::settings::modules::IOSettings>().getQvbsRoot() + "/" + path; |
||||
|
} else { |
||||
|
similarNames.add(currModelName); |
||||
|
} |
||||
|
} |
||||
|
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "QVBS model '" + modelName + "' was not found. " + similarNames.toDidYouMeanString()); |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
QvbsBenchmark::QvbsBenchmark(std::string const& modelName) { |
||||
|
std::string actualModelName = modelName; |
||||
|
std::transform(actualModelName.begin(), actualModelName.end(), actualModelName.begin(), ::tolower); |
||||
|
modelPath = findModelPath(actualModelName); |
||||
|
std::string indexPath = modelPath + "/index.json"; |
||||
|
modelData = readQvbsJsonFile(indexPath); |
||||
|
|
||||
|
STORM_LOG_THROW(modelData.count("files") == 1, storm::exceptions::WrongFormatException, "No files in " + indexPath + "."); |
||||
|
for (auto const& fileJson : modelData["files"]) { |
||||
|
std::string janiFileName = getString(fileJson["file"], "file of " + indexPath + "."); |
||||
|
if (fileJson.count("open-parameter-values") == 1 && fileJson["open-parameter-values"].size() > 0) { |
||||
|
for (auto const& openParJson : fileJson["open-parameter-values"]) { |
||||
|
std::string constantDefString = ""; |
||||
|
if (openParJson.count("values") == 1) { |
||||
|
for (auto const& valueJson : openParJson["values"]) { |
||||
|
if (constantDefString != "") { |
||||
|
constantDefString += ","; |
||||
|
} |
||||
|
constantDefString += getString(valueJson["name"], "open-parameter-values in files in " + indexPath + ".") + "="; |
||||
|
constantDefString += getString(valueJson["value"], "open-parameter-values in files in " + indexPath + "."); |
||||
|
} |
||||
|
} |
||||
|
constantDefinitions.push_back(constantDefString); |
||||
|
janiFiles.push_back(modelPath + "/" + janiFileName); |
||||
|
instanceInfos.push_back(janiFileName + " \t" + constantDefString); |
||||
|
if (openParJson.count("states") == 1 && openParJson["states"].size() > 0) { |
||||
|
uint64_t states = 0; |
||||
|
for (auto const& statesJson : openParJson["states"]) { |
||||
|
auto note = getString(statesJson["note"]); |
||||
|
if (note.find("Storm") != std::string::npos) { |
||||
|
states = statesJson["number"].get<uint64_t>(); |
||||
|
} |
||||
|
} |
||||
|
if (states > 0) { |
||||
|
instanceInfos.back() += " \t(" + std::to_string(states) + " states)"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
constantDefinitions.push_back(""); |
||||
|
janiFiles.push_back(janiFileName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
std::string const& QvbsBenchmark::getJaniFile(uint64_t instanceIndex ) const { |
||||
|
STORM_LOG_THROW(instanceIndex < janiFiles.size(), storm::exceptions::InvalidArgumentException, "Instance index " << instanceIndex << " is too high."); |
||||
|
return janiFiles[instanceIndex]; |
||||
|
} |
||||
|
|
||||
|
std::string const& QvbsBenchmark::getConstantDefinition(uint64_t instanceIndex) const { |
||||
|
STORM_LOG_THROW(instanceIndex < constantDefinitions.size(), storm::exceptions::InvalidArgumentException, "Instance index " << instanceIndex << " is too high."); |
||||
|
return constantDefinitions[instanceIndex]; |
||||
|
} |
||||
|
|
||||
|
std::string QvbsBenchmark::getInfo(uint64_t instanceIndex, boost::optional<std::vector<std::string>> propertyFilter) const { |
||||
|
std::stringstream s; |
||||
|
s << "--------------------------------------------------------------" << std::endl; |
||||
|
s << "QVBS " << getString(modelData["type"]) << "-Benchmark: " << getString(modelData["name"]) << " (" << getString(modelData["short"]) << ") v" << getString(modelData["version"]) << std::endl; |
||||
|
if (instanceInfos.size() == 1) { |
||||
|
s << "1 instance:" << std::endl; |
||||
|
} else if (instanceInfos.size() > 1) { |
||||
|
s << instanceInfos.size() << " instances:" << std::endl; |
||||
|
} |
||||
|
for (uint64_t i = 0; i < instanceInfos.size(); ++ i) { |
||||
|
s << "\t" << (i==instanceIndex ? "*" : " ") << i << "\t" << instanceInfos[i] << std::endl; |
||||
|
} |
||||
|
if (modelData.count("properties") == 1) { |
||||
|
if (modelData["properties"].size() == 1) { |
||||
|
s << "1 property:" << std::endl; |
||||
|
} else if (modelData["properties"].size() > 1) { |
||||
|
s << modelData["properties"].size() << " properties:" << std::endl; |
||||
|
} |
||||
|
for (auto const& property : modelData["properties"]) { |
||||
|
std::string propertyName = getString(property["name"]); |
||||
|
s << "\t"; |
||||
|
if (!propertyFilter.is_initialized() || std::find(propertyFilter->begin(), propertyFilter->end(), propertyName) != propertyFilter->end()) { |
||||
|
s << "*"; |
||||
|
} else { |
||||
|
s << " "; |
||||
|
} |
||||
|
s << propertyName << " \t(" << getString(property["type"]) << ")" << std::endl; |
||||
|
} |
||||
|
} |
||||
|
s << "--------------------------------------------------------------" << std::endl; |
||||
|
return s.str(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <string> |
||||
|
#include <vector> |
||||
|
#include <boost/optional.hpp> |
||||
|
|
||||
|
// JSON parser |
||||
|
#include "json.hpp" |
||||
|
namespace modernjson { |
||||
|
using json = nlohmann::json; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
|
||||
|
/*! |
||||
|
* This class provides easy access to a benchmark of the Quantitative Verification Benchmark Set |
||||
|
* http://qcomp.org/benchmarks/ |
||||
|
*/ |
||||
|
class QvbsBenchmark { |
||||
|
public: |
||||
|
/*! |
||||
|
* @param modelName the (short) model name of the considered model. |
||||
|
*/ |
||||
|
QvbsBenchmark(std::string const& modelName); |
||||
|
|
||||
|
std::string const& getJaniFile(uint64_t instanceIndex = 0) const; |
||||
|
std::string const& getConstantDefinition(uint64_t instanceIndex = 0) const; |
||||
|
|
||||
|
std::string getInfo(uint64_t instanceIndex = 0, boost::optional<std::vector<std::string>> propertyFilter = boost::none) const; |
||||
|
private: |
||||
|
|
||||
|
std::vector<std::string> janiFiles; |
||||
|
std::vector<std::string> constantDefinitions; |
||||
|
std::vector<std::string> instanceInfos; |
||||
|
|
||||
|
std::string modelPath; |
||||
|
modernjson::json modelData; |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue