8 changed files with 359 additions and 232 deletions
			
			
		- 
					4resources/3rdparty/CMakeLists.txt
 - 
					2src/CMakeLists.txt
 - 
					41src/generator/DftNextStateGenerator.cpp
 - 
					5src/generator/DftNextStateGenerator.h
 - 
					201src/modelchecker/DFTAnalyser.h
 - 
					214src/modelchecker/dft/DFTModelChecker.cpp
 - 
					104src/modelchecker/dft/DFTModelChecker.h
 - 
					20src/storm-dyftee.cpp
 
@ -1,201 +0,0 @@ | 
				
			|||
#pragma once | 
				
			|||
 | 
				
			|||
#include "src/logic/Formula.h" | 
				
			|||
#include "src/parser/DFTGalileoParser.h" | 
				
			|||
#include "src/builder/ExplicitDFTModelBuilder.h" | 
				
			|||
#include "src/builder/ExplicitDFTModelBuilderApprox.h" | 
				
			|||
#include "src/modelchecker/results/CheckResult.h" | 
				
			|||
#include "src/utility/storm.h" | 
				
			|||
#include "src/storage/dft/DFTIsomorphism.h" | 
				
			|||
#include "src/settings/modules/DFTSettings.h" | 
				
			|||
#include "src/utility/bitoperations.h" | 
				
			|||
 | 
				
			|||
 | 
				
			|||
#include <chrono> | 
				
			|||
 | 
				
			|||
template<typename ValueType> | 
				
			|||
class DFTAnalyser { | 
				
			|||
     | 
				
			|||
    std::chrono::duration<double> buildingTime = std::chrono::duration<double>::zero(); | 
				
			|||
    std::chrono::duration<double> explorationTime = std::chrono::duration<double>::zero(); | 
				
			|||
    std::chrono::duration<double> bisimulationTime = std::chrono::duration<double>::zero(); | 
				
			|||
    std::chrono::duration<double> modelCheckingTime = std::chrono::duration<double>::zero(); | 
				
			|||
    std::chrono::duration<double> totalTime = std::chrono::duration<double>::zero(); | 
				
			|||
    ValueType checkResult = storm::utility::zero<ValueType>(); | 
				
			|||
public: | 
				
			|||
    void check(storm::storage::DFT<ValueType> const& origDft , std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true, bool enableDC = true) { | 
				
			|||
         | 
				
			|||
        // Building DFT | 
				
			|||
        std::chrono::high_resolution_clock::time_point totalStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
         | 
				
			|||
         | 
				
			|||
        // Optimizing DFT | 
				
			|||
        storm::storage::DFT<ValueType> dft = origDft.optimize(); | 
				
			|||
        checkResult = checkHelper(dft, formula, symred, allowModularisation, enableDC); | 
				
			|||
        totalTime = std::chrono::high_resolution_clock::now() - totalStart; | 
				
			|||
             | 
				
			|||
         | 
				
			|||
             | 
				
			|||
    } | 
				
			|||
     | 
				
			|||
private: | 
				
			|||
    ValueType checkHelper(storm::storage::DFT<ValueType> const& dft , std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true, bool enableDC = true)  { | 
				
			|||
        STORM_LOG_TRACE("Check helper called"); | 
				
			|||
        bool invResults = false; | 
				
			|||
        std::vector<storm::storage::DFT<ValueType>> dfts = {dft}; | 
				
			|||
        std::vector<ValueType> res; | 
				
			|||
        size_t nrK = 0; // K out of M  | 
				
			|||
        size_t nrM = 0; // K out of M | 
				
			|||
         | 
				
			|||
        if(allowModularisation) { | 
				
			|||
            if(dft.topLevelType() == storm::storage::DFTElementType::AND) { | 
				
			|||
                STORM_LOG_TRACE("top modularisation called AND"); | 
				
			|||
                dfts = dft.topModularisation(); | 
				
			|||
                STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); | 
				
			|||
                nrK = dfts.size(); | 
				
			|||
                nrM = dfts.size(); | 
				
			|||
            } | 
				
			|||
            if(dft.topLevelType() == storm::storage::DFTElementType::OR) { | 
				
			|||
                STORM_LOG_TRACE("top modularisation called OR"); | 
				
			|||
                dfts = dft.topModularisation(); | 
				
			|||
                STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); | 
				
			|||
                nrK = 0; | 
				
			|||
                nrM = dfts.size(); | 
				
			|||
                invResults = true; | 
				
			|||
            } | 
				
			|||
            if(dft.topLevelType() == storm::storage::DFTElementType::VOT) { | 
				
			|||
                STORM_LOG_TRACE("top modularisation called VOT"); | 
				
			|||
                dfts = dft.topModularisation(); | 
				
			|||
                STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); | 
				
			|||
                nrK = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dft.getTopLevelGate())->threshold(); | 
				
			|||
                nrM = dfts.size(); | 
				
			|||
                if(nrK <= nrM/2) { | 
				
			|||
                    nrK -= 1; | 
				
			|||
                    invResults = true; | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
            if(dfts.size() > 1) { | 
				
			|||
                STORM_LOG_TRACE("Recursive CHECK Call"); | 
				
			|||
                for(auto const ft : dfts) { | 
				
			|||
                    res.push_back(checkHelper(ft, formula, symred, allowModularisation)); | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
        }  | 
				
			|||
        if(res.empty()) { | 
				
			|||
            // Model based modularisation. | 
				
			|||
            auto const& models = buildMarkovModels(dfts, formula, symred, enableDC); | 
				
			|||
 | 
				
			|||
 | 
				
			|||
            for (auto const& model : models) { | 
				
			|||
                // Model checking | 
				
			|||
                STORM_LOG_INFO("Model checking..."); | 
				
			|||
                std::chrono::high_resolution_clock::time_point modelCheckingStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
                std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formula)); | 
				
			|||
                STORM_LOG_INFO("Model checking done."); | 
				
			|||
                STORM_LOG_ASSERT(result, "Result does not exist."); | 
				
			|||
                result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); | 
				
			|||
                modelCheckingTime += std::chrono::high_resolution_clock::now() -  modelCheckingStart; | 
				
			|||
                res.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); | 
				
			|||
            } | 
				
			|||
        } | 
				
			|||
        if(nrM <= 1) { | 
				
			|||
            // No modularisation done. | 
				
			|||
            STORM_LOG_ASSERT(res.size()==1, "Result size not 1."); | 
				
			|||
            return res[0]; | 
				
			|||
        } | 
				
			|||
         | 
				
			|||
        STORM_LOG_TRACE("Combining all results... K=" << nrK << "; M=" << nrM << "; invResults=" << (invResults?"On":"Off")); | 
				
			|||
        ValueType result = storm::utility::zero<ValueType>(); | 
				
			|||
        int limK = invResults ? -1 : nrM+1; | 
				
			|||
        int chK = invResults ? -1 : 1; | 
				
			|||
        for(int cK = nrK; cK != limK; cK += chK ) { | 
				
			|||
            STORM_LOG_ASSERT(cK >= 0, "ck negative."); | 
				
			|||
            size_t permutation = smallestIntWithNBitsSet(static_cast<size_t>(cK)); | 
				
			|||
            do { | 
				
			|||
                STORM_LOG_TRACE("Permutation="<<permutation); | 
				
			|||
                ValueType permResult = storm::utility::one<ValueType>(); | 
				
			|||
                for(size_t i = 0; i < res.size(); ++i) { | 
				
			|||
                    if(permutation & (1 << i)) { | 
				
			|||
                        permResult *= res[i]; | 
				
			|||
                    } else { | 
				
			|||
                        permResult *= storm::utility::one<ValueType>() - res[i]; | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                STORM_LOG_TRACE("Result for permutation:"<<permResult); | 
				
			|||
                permutation = nextBitPermutation(permutation); | 
				
			|||
                result += permResult; | 
				
			|||
            } while(permutation < (1 << nrM) && permutation != 0); | 
				
			|||
        } | 
				
			|||
        if(invResults) { | 
				
			|||
            return storm::utility::one<ValueType>() - result; | 
				
			|||
        } | 
				
			|||
        return result; | 
				
			|||
    } | 
				
			|||
     | 
				
			|||
     | 
				
			|||
    std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> buildMarkovModels(std::vector<storm::storage::DFT<ValueType>> const&  dfts,   std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC) { | 
				
			|||
        std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> models; | 
				
			|||
        for(auto& dft : dfts) { | 
				
			|||
            std::chrono::high_resolution_clock::time_point buildingStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
 | 
				
			|||
            std::map<size_t, std::vector<std::vector<size_t>>> emptySymmetry; | 
				
			|||
            storm::storage::DFTIndependentSymmetries symmetries(emptySymmetry); | 
				
			|||
            if(symred) { | 
				
			|||
                auto colouring = dft.colourDFT(); | 
				
			|||
                symmetries = dft.findSymmetries(colouring); | 
				
			|||
                STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); | 
				
			|||
                STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); | 
				
			|||
            } | 
				
			|||
            std::chrono::high_resolution_clock::time_point buildingEnd = std::chrono::high_resolution_clock::now(); | 
				
			|||
            buildingTime += buildingEnd - buildingStart; | 
				
			|||
             | 
				
			|||
            // Building Markov Automaton | 
				
			|||
            STORM_LOG_INFO("Building Model..."); | 
				
			|||
            std::shared_ptr<storm::models::sparse::Model<ValueType>> model; | 
				
			|||
            // TODO Matthias: use only one builder if everything works again | 
				
			|||
            if (storm::settings::getModule<storm::settings::modules::DFTSettings>().computeApproximation()) { | 
				
			|||
                storm::builder::ExplicitDFTModelBuilderApprox<ValueType> builder(dft, symmetries, enableDC); | 
				
			|||
                typename storm::builder::ExplicitDFTModelBuilderApprox<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula | 
				
			|||
                model = builder.buildModel(labeloptions); | 
				
			|||
            } else { | 
				
			|||
                storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); | 
				
			|||
                typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula | 
				
			|||
                model = builder.buildModel(labeloptions); | 
				
			|||
            } | 
				
			|||
            //model->printModelInformationToStream(std::cout); | 
				
			|||
            STORM_LOG_INFO("No. states (Explored): " << model->getNumberOfStates()); | 
				
			|||
            STORM_LOG_INFO("No. transitions (Explored): " << model->getNumberOfTransitions()); | 
				
			|||
            std::chrono::high_resolution_clock::time_point explorationEnd = std::chrono::high_resolution_clock::now(); | 
				
			|||
            explorationTime += explorationEnd -buildingEnd; | 
				
			|||
 | 
				
			|||
            // Bisimulation | 
				
			|||
            if (model->isOfType(storm::models::ModelType::Ctmc) && storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) { | 
				
			|||
                STORM_LOG_INFO("Bisimulation..."); | 
				
			|||
                model =  storm::performDeterministicSparseBisimulationMinimization<storm::models::sparse::Ctmc<ValueType>>(model->template as<storm::models::sparse::Ctmc<ValueType>>(), {formula}, storm::storage::BisimulationType::Weak)->template as<storm::models::sparse::Ctmc<ValueType>>(); | 
				
			|||
                //model->printModelInformationToStream(std::cout); | 
				
			|||
            } | 
				
			|||
            STORM_LOG_INFO("No. states (Bisimulation): " << model->getNumberOfStates()); | 
				
			|||
            STORM_LOG_INFO("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); | 
				
			|||
            bisimulationTime += std::chrono::high_resolution_clock::now() - explorationEnd; | 
				
			|||
            models.push_back(model); | 
				
			|||
        } | 
				
			|||
        return models; | 
				
			|||
    } | 
				
			|||
     | 
				
			|||
public: | 
				
			|||
    void printTimings(std::ostream& os = std::cout) { | 
				
			|||
        os << "Times:" << std::endl; | 
				
			|||
        os << "Building:\t" << buildingTime.count() << std::endl; | 
				
			|||
        os << "Exploration:\t" << explorationTime.count() << std::endl; | 
				
			|||
        os << "Bisimulation:\t" << bisimulationTime.count() << std::endl; | 
				
			|||
        os << "Modelchecking:\t" << modelCheckingTime.count() << std::endl; | 
				
			|||
        os << "Total:\t\t" << totalTime.count() << std::endl; | 
				
			|||
    } | 
				
			|||
     | 
				
			|||
    void printResult(std::ostream& os = std::cout) { | 
				
			|||
         | 
				
			|||
        os << "Result: ["; | 
				
			|||
        os << checkResult << "]" << std::endl; | 
				
			|||
    } | 
				
			|||
     | 
				
			|||
}; | 
				
			|||
@ -0,0 +1,214 @@ | 
				
			|||
#include "src/modelchecker/dft/DFTModelChecker.h"
 | 
				
			|||
 | 
				
			|||
#include "src/builder/ExplicitDFTModelBuilder.h"
 | 
				
			|||
#include "src/builder/ExplicitDFTModelBuilderApprox.h"
 | 
				
			|||
#include "src/storage/dft/DFTIsomorphism.h"
 | 
				
			|||
#include "src/settings/modules/DFTSettings.h"
 | 
				
			|||
#include "src/utility/bitoperations.h"
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        DFTModelChecker<ValueType>::DFTModelChecker() { | 
				
			|||
            // Intentionally left empty.
 | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        void DFTModelChecker<ValueType>::check(storm::storage::DFT<ValueType> const& origDft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool allowModularisation, bool enableDC) { | 
				
			|||
            std::chrono::high_resolution_clock::time_point totalStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
            // Optimizing DFT
 | 
				
			|||
            storm::storage::DFT<ValueType> dft = origDft.optimize(); | 
				
			|||
            checkResult = checkHelper(dft, formula, symred, allowModularisation, enableDC); | 
				
			|||
            totalTime = std::chrono::high_resolution_clock::now() - totalStart; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        ValueType DFTModelChecker<ValueType>::checkHelper(storm::storage::DFT<ValueType> const& dft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool allowModularisation, bool enableDC)  { | 
				
			|||
            STORM_LOG_TRACE("Check helper called"); | 
				
			|||
            bool invResults = false; | 
				
			|||
            std::vector<storm::storage::DFT<ValueType>> dfts = {dft}; | 
				
			|||
            std::vector<ValueType> res; | 
				
			|||
            size_t nrK = 0; // K out of M
 | 
				
			|||
            size_t nrM = 0; // K out of M
 | 
				
			|||
 | 
				
			|||
            // Try modularisation
 | 
				
			|||
            if(allowModularisation) { | 
				
			|||
                if(dft.topLevelType() == storm::storage::DFTElementType::AND) { | 
				
			|||
                    STORM_LOG_TRACE("top modularisation called AND"); | 
				
			|||
                    dfts = dft.topModularisation(); | 
				
			|||
                    STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); | 
				
			|||
                    nrK = dfts.size(); | 
				
			|||
                    nrM = dfts.size(); | 
				
			|||
                } | 
				
			|||
                if(dft.topLevelType() == storm::storage::DFTElementType::OR) { | 
				
			|||
                    STORM_LOG_TRACE("top modularisation called OR"); | 
				
			|||
                    dfts = dft.topModularisation(); | 
				
			|||
                    STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); | 
				
			|||
                    nrK = 0; | 
				
			|||
                    nrM = dfts.size(); | 
				
			|||
                    invResults = true; | 
				
			|||
                } | 
				
			|||
                if(dft.topLevelType() == storm::storage::DFTElementType::VOT) { | 
				
			|||
                    STORM_LOG_TRACE("top modularisation called VOT"); | 
				
			|||
                    dfts = dft.topModularisation(); | 
				
			|||
                    STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); | 
				
			|||
                    nrK = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dft.getTopLevelGate())->threshold(); | 
				
			|||
                    nrM = dfts.size(); | 
				
			|||
                    if(nrK <= nrM/2) { | 
				
			|||
                        nrK -= 1; | 
				
			|||
                        invResults = true; | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
                if(dfts.size() > 1) { | 
				
			|||
                    STORM_LOG_TRACE("Recursive CHECK Call"); | 
				
			|||
                    for(auto const ft : dfts) { | 
				
			|||
                        res.push_back(checkHelper(ft, formula, symred, allowModularisation, enableDC)); | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            if(res.empty()) { | 
				
			|||
                // Model based modularisation.
 | 
				
			|||
                auto const& models = buildMarkovModels(dfts, formula, symred, enableDC); | 
				
			|||
                 | 
				
			|||
                for (auto const& model : models) { | 
				
			|||
                    // Model checking
 | 
				
			|||
                    STORM_LOG_INFO("Model checking..."); | 
				
			|||
                    std::chrono::high_resolution_clock::time_point modelCheckingStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
                    std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formula)); | 
				
			|||
                    STORM_LOG_INFO("Model checking done."); | 
				
			|||
                    STORM_LOG_ASSERT(result, "Result does not exist."); | 
				
			|||
                    result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); | 
				
			|||
                    modelCheckingTime += std::chrono::high_resolution_clock::now() -  modelCheckingStart; | 
				
			|||
                    res.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
            if(nrM <= 1) { | 
				
			|||
                // No modularisation done.
 | 
				
			|||
                STORM_LOG_ASSERT(res.size()==1, "Result size not 1."); | 
				
			|||
                return res[0]; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            STORM_LOG_TRACE("Combining all results... K=" << nrK << "; M=" << nrM << "; invResults=" << (invResults?"On":"Off")); | 
				
			|||
            ValueType result = storm::utility::zero<ValueType>(); | 
				
			|||
            int limK = invResults ? -1 : nrM+1; | 
				
			|||
            int chK = invResults ? -1 : 1; | 
				
			|||
            for(int cK = nrK; cK != limK; cK += chK ) { | 
				
			|||
                STORM_LOG_ASSERT(cK >= 0, "ck negative."); | 
				
			|||
                size_t permutation = smallestIntWithNBitsSet(static_cast<size_t>(cK)); | 
				
			|||
                do { | 
				
			|||
                    STORM_LOG_TRACE("Permutation="<<permutation); | 
				
			|||
                    ValueType permResult = storm::utility::one<ValueType>(); | 
				
			|||
                    for(size_t i = 0; i < res.size(); ++i) { | 
				
			|||
                        if(permutation & (1 << i)) { | 
				
			|||
                            permResult *= res[i]; | 
				
			|||
                        } else { | 
				
			|||
                            permResult *= storm::utility::one<ValueType>() - res[i]; | 
				
			|||
                        } | 
				
			|||
                    } | 
				
			|||
                    STORM_LOG_TRACE("Result for permutation:"<<permResult); | 
				
			|||
                    permutation = nextBitPermutation(permutation); | 
				
			|||
                    result += permResult; | 
				
			|||
                } while(permutation < (1 << nrM) && permutation != 0); | 
				
			|||
            } | 
				
			|||
            if(invResults) { | 
				
			|||
                return storm::utility::one<ValueType>() - result; | 
				
			|||
            } | 
				
			|||
            return result; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        std::vector<ValueType> DFTModelChecker<ValueType>::checkModel(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError) { | 
				
			|||
            std::vector<ValueType> results; | 
				
			|||
 | 
				
			|||
            auto const& models = buildMarkovModels(dfts, formula, symred, enableDC); | 
				
			|||
 | 
				
			|||
            for (auto const& model : models) { | 
				
			|||
                // Model checking
 | 
				
			|||
                STORM_LOG_INFO("Model checking..."); | 
				
			|||
                std::chrono::high_resolution_clock::time_point modelCheckingStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
                std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formula)); | 
				
			|||
                STORM_LOG_INFO("Model checking done."); | 
				
			|||
                STORM_LOG_ASSERT(result, "Result does not exist."); | 
				
			|||
                result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); | 
				
			|||
                modelCheckingTime += std::chrono::high_resolution_clock::now() -  modelCheckingStart; | 
				
			|||
                results.push_back(result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second); | 
				
			|||
            } | 
				
			|||
            return results; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> DFTModelChecker<ValueType>::buildMarkovModels(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError) { | 
				
			|||
            std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> models; | 
				
			|||
            for(auto& dft : dfts) { | 
				
			|||
                std::chrono::high_resolution_clock::time_point buildingStart = std::chrono::high_resolution_clock::now(); | 
				
			|||
 | 
				
			|||
                std::map<size_t, std::vector<std::vector<size_t>>> emptySymmetry; | 
				
			|||
                storm::storage::DFTIndependentSymmetries symmetries(emptySymmetry); | 
				
			|||
                if(symred) { | 
				
			|||
                    auto colouring = dft.colourDFT(); | 
				
			|||
                    symmetries = dft.findSymmetries(colouring); | 
				
			|||
                    STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); | 
				
			|||
                    STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); | 
				
			|||
                } | 
				
			|||
                std::chrono::high_resolution_clock::time_point buildingEnd = std::chrono::high_resolution_clock::now(); | 
				
			|||
                buildingTime += buildingEnd - buildingStart; | 
				
			|||
 | 
				
			|||
                // Building Markov Automaton
 | 
				
			|||
                STORM_LOG_INFO("Building Model..."); | 
				
			|||
                std::shared_ptr<storm::models::sparse::Model<ValueType>> model; | 
				
			|||
                // TODO Matthias: use only one builder if everything works again
 | 
				
			|||
                if (storm::settings::getModule<storm::settings::modules::DFTSettings>().computeApproximation()) { | 
				
			|||
                    storm::builder::ExplicitDFTModelBuilderApprox<ValueType> builder(dft, symmetries, enableDC); | 
				
			|||
                    typename storm::builder::ExplicitDFTModelBuilderApprox<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula
 | 
				
			|||
                    model = builder.buildModel(labeloptions); | 
				
			|||
                } else { | 
				
			|||
                    storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); | 
				
			|||
                    typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions; // TODO initialize this with the formula
 | 
				
			|||
                    model = builder.buildModel(labeloptions); | 
				
			|||
                } | 
				
			|||
                //model->printModelInformationToStream(std::cout);
 | 
				
			|||
                STORM_LOG_INFO("No. states (Explored): " << model->getNumberOfStates()); | 
				
			|||
                STORM_LOG_INFO("No. transitions (Explored): " << model->getNumberOfTransitions()); | 
				
			|||
                std::chrono::high_resolution_clock::time_point explorationEnd = std::chrono::high_resolution_clock::now(); | 
				
			|||
                explorationTime += explorationEnd -buildingEnd; | 
				
			|||
 | 
				
			|||
                // Bisimulation
 | 
				
			|||
                if (model->isOfType(storm::models::ModelType::Ctmc) && storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) { | 
				
			|||
                    STORM_LOG_INFO("Bisimulation..."); | 
				
			|||
                    model =  storm::performDeterministicSparseBisimulationMinimization<storm::models::sparse::Ctmc<ValueType>>(model->template as<storm::models::sparse::Ctmc<ValueType>>(), {formula}, storm::storage::BisimulationType::Weak)->template as<storm::models::sparse::Ctmc<ValueType>>(); | 
				
			|||
                    //model->printModelInformationToStream(std::cout);
 | 
				
			|||
                } | 
				
			|||
                STORM_LOG_INFO("No. states (Bisimulation): " << model->getNumberOfStates()); | 
				
			|||
                STORM_LOG_INFO("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); | 
				
			|||
                bisimulationTime += std::chrono::high_resolution_clock::now() - explorationEnd; | 
				
			|||
                models.push_back(model); | 
				
			|||
            } | 
				
			|||
            return models; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        void DFTModelChecker<ValueType>::printTimings(std::ostream& os) { | 
				
			|||
            os << "Times:" << std::endl; | 
				
			|||
            os << "Building:\t" << buildingTime.count() << std::endl; | 
				
			|||
            os << "Exploration:\t" << explorationTime.count() << std::endl; | 
				
			|||
            os << "Bisimulation:\t" << bisimulationTime.count() << std::endl; | 
				
			|||
            os << "Modelchecking:\t" << modelCheckingTime.count() << std::endl; | 
				
			|||
            os << "Total:\t\t" << totalTime.count() << std::endl; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        template<typename ValueType> | 
				
			|||
        void DFTModelChecker<ValueType>::printResult(std::ostream& os) { | 
				
			|||
            os << "Result: ["; | 
				
			|||
            os << checkResult << "]" << std::endl; | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
 | 
				
			|||
        template class DFTModelChecker<double>; | 
				
			|||
 | 
				
			|||
#ifdef STORM_HAVE_CARL
 | 
				
			|||
        template class DFTModelChecker<storm::RationalFunction>; | 
				
			|||
#endif
 | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,104 @@ | 
				
			|||
#ifndef STORM_MODELCHECKER_DFT_DFTMODELCHECKER_H_ | 
				
			|||
 | 
				
			|||
#include "src/logic/Formula.h" | 
				
			|||
#include "src/modelchecker/results/CheckResult.h" | 
				
			|||
#include "src/storage/dft/DFT.h" | 
				
			|||
#include "src/utility/storm.h" | 
				
			|||
 | 
				
			|||
#include <chrono> | 
				
			|||
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace modelchecker { | 
				
			|||
 | 
				
			|||
        /** | 
				
			|||
         * Analyser for DFTs. | 
				
			|||
         */ | 
				
			|||
        template<typename ValueType> | 
				
			|||
        class DFTModelChecker { | 
				
			|||
 | 
				
			|||
        public: | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Constructor. | 
				
			|||
             */ | 
				
			|||
            DFTModelChecker(); | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Main method for checking DFTs. | 
				
			|||
             * | 
				
			|||
             * @param origDft             Original DFT | 
				
			|||
             * @param formula             Formula to check for | 
				
			|||
             * @param symred              Flag indicating if symmetry reduction should be used | 
				
			|||
             * @param allowModularisation Flag indication if modularisation is allowed | 
				
			|||
             * @param enableDC            Flag indicating if dont care propagation should be used | 
				
			|||
             */ | 
				
			|||
            void check(storm::storage::DFT<ValueType> const& origDft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred = true, bool allowModularisation = true, bool enableDC = true); | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Print timings of all operations to stream. | 
				
			|||
             * | 
				
			|||
             * @param os Output stream to write to. | 
				
			|||
             */ | 
				
			|||
            void printTimings(std::ostream& os = std::cout); | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Print result to stream. | 
				
			|||
             * | 
				
			|||
             * @param os Output stream to write to. | 
				
			|||
             */ | 
				
			|||
            void printResult(std::ostream& os = std::cout); | 
				
			|||
 | 
				
			|||
        private: | 
				
			|||
            // Timing values | 
				
			|||
            std::chrono::duration<double> buildingTime = std::chrono::duration<double>::zero(); | 
				
			|||
            std::chrono::duration<double> explorationTime = std::chrono::duration<double>::zero(); | 
				
			|||
            std::chrono::duration<double> bisimulationTime = std::chrono::duration<double>::zero(); | 
				
			|||
            std::chrono::duration<double> modelCheckingTime = std::chrono::duration<double>::zero(); | 
				
			|||
            std::chrono::duration<double> totalTime = std::chrono::duration<double>::zero(); | 
				
			|||
            // Model checking result | 
				
			|||
            ValueType checkResult = storm::utility::zero<ValueType>(); | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Internal helper for model checking a DFT. | 
				
			|||
             * | 
				
			|||
             * @param dft                 DFT | 
				
			|||
             * @param formula             Formula to check for | 
				
			|||
             * @param symred              Flag indicating if symmetry reduction should be used | 
				
			|||
             * @param allowModularisation Flag indication if modularisation is allowed | 
				
			|||
             * @param enableDC            Flag indicating if dont care propagation should be used | 
				
			|||
             * | 
				
			|||
             * @return Model checking result | 
				
			|||
             */ | 
				
			|||
            ValueType checkHelper(storm::storage::DFT<ValueType> const& dft, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool allowModularisation, bool enableDC); | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Check the Dfts via model checking. | 
				
			|||
             * | 
				
			|||
             * @param dfts               Vector of Dfts | 
				
			|||
             * @param formula            Formula to check for | 
				
			|||
             * @param symred             Flag indicating if symmetry reduction should be used | 
				
			|||
             * @param enableDC           Flag indicating if dont care propagation should be used | 
				
			|||
             * @param approximationError Error allowed for approximation. Value 0 indicates no approximation | 
				
			|||
             * | 
				
			|||
             * @return Vector of results for each model | 
				
			|||
             */ | 
				
			|||
            std::vector<ValueType> checkModel(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError = 0.0); | 
				
			|||
 | 
				
			|||
            /** | 
				
			|||
             * Build markov models from DFTs. | 
				
			|||
             * | 
				
			|||
             * @param dfts               Vector of Dfts | 
				
			|||
             * @param formula            Formula to check for | 
				
			|||
             * @param symred             Flag indicating if symmetry reduction should be used | 
				
			|||
             * @param enableDC           Flag indicating if dont care propagation should be used | 
				
			|||
             * @param approximationError Error allowed for approximation. Value 0 indicates no approximation | 
				
			|||
             * | 
				
			|||
             * @return Vector of markov models corresponding to DFTs. | 
				
			|||
             */ | 
				
			|||
            std::vector<std::shared_ptr<storm::models::sparse::Model<ValueType>>> buildMarkovModels(std::vector<storm::storage::DFT<ValueType>> const& dfts, std::shared_ptr<const storm::logic::Formula> const& formula, bool symred, bool enableDC, double approximationError = 0.0); | 
				
			|||
 | 
				
			|||
        }; | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
#endif /* STORM_MODELCHECKER_DFT_DFTMODELCHECKER_H_ */ | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue