Browse Source
			
			
			Allow to quickly check a benchmark from the Quantitative Verification Benchmark Set.
			
			
				main
			
			
		
		Allow to quickly check a benchmark from the Quantitative Verification Benchmark Set.
	
		
	
			
			
				main
			
			
		
				 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